From 2a68a1b35b1e4f799a3a753ed9018e2d469b77b5 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 8 Jul 2014 16:01:40 -0700 Subject: [PATCH 001/388] Special casing some VC++ traps. --- src/alloy/backend/ivm/ivm_intcode.cc | 9 ++++++++- src/alloy/backend/x64/x64_emitter.cc | 21 +++++++++++++++++---- src/alloy/backend/x64/x64_emitter.h | 2 +- src/alloy/backend/x64/x64_sequences.cc | 14 +++++++------- src/alloy/frontend/ppc/ppc_emit_control.cc | 8 +++++++- src/alloy/hir/hir_builder.cc | 10 +++++----- src/alloy/hir/hir_builder.h | 4 ++-- 7 files changed, 47 insertions(+), 21 deletions(-) diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index 1badeab7e..109bb19a9 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -309,8 +309,15 @@ int Translate_DEBUG_BREAK_TRUE(TranslationContext& ctx, Instr* i) { } uint32_t IntCode_TRAP(IntCodeState& ics, const IntCode* i) { - // 0x0FE00014 is a 'debug print' where r3 = buffer r4 = length // TODO(benvanik): post software interrupt to debugger. + switch (i->flags) { + case 20: + // 0x0FE00014 is a 'debug print' where r3 = buffer r4 = length + break; + case 22: + // Always trap? + break; + } __debugbreak(); return IA_NEXT; } diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index 0e2d55860..ab0d2123b 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -219,10 +219,23 @@ void X64Emitter::DebugBreak() { db(0xCC); } -void X64Emitter::Trap() { - // 0x0FE00014 is a 'debug print' where r3 = buffer r4 = length - // TODO(benvanik): post software interrupt to debugger. - db(0xCC); +void X64Emitter::Trap(uint16_t trap_type) { + switch (trap_type) { + case 20: + // 0x0FE00014 is a 'debug print' where r3 = buffer r4 = length + // TODO(benvanik): debug print at runtime. + break; + case 0: + case 22: + // Always trap? + // TODO(benvanik): post software interrupt to debugger. + db(0xCC); + break; + default: + XELOGW("Unknown trap type %d", trap_type); + db(0xCC); + break; + } } void X64Emitter::UnimplementedInstr(const hir::Instr* i) { diff --git a/src/alloy/backend/x64/x64_emitter.h b/src/alloy/backend/x64/x64_emitter.h index e6ea7b7b5..3bfe43a2b 100644 --- a/src/alloy/backend/x64/x64_emitter.h +++ b/src/alloy/backend/x64/x64_emitter.h @@ -117,7 +117,7 @@ public: void MarkSourceOffset(const hir::Instr* i); void DebugBreak(); - void Trap(); + void Trap(uint16_t trap_type = 0); void UnimplementedInstr(const hir::Instr* i); void UnimplementedExtern(const hir::Instr* i); diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index 689c8b3b3..e06f69a99 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -191,7 +191,7 @@ EMITTER_OPCODE_TABLE( // ============================================================================ EMITTER(TRAP, MATCH(I)) { static void Emit(X64Emitter& e, const EmitArgType& i) { - e.Trap(); + e.Trap(i.instr->flags); } }; EMITTER_OPCODE_TABLE( @@ -207,7 +207,7 @@ EMITTER(TRAP_TRUE_I8, MATCH(I>)) { e.test(i.src1, i.src1); Xbyak::Label skip; e.jz(skip); - e.Trap(); + e.Trap(i.instr->flags); e.L(skip); } }; @@ -216,7 +216,7 @@ EMITTER(TRAP_TRUE_I16, MATCH(I>)) { e.test(i.src1, i.src1); Xbyak::Label skip; e.jz(skip); - e.Trap(); + e.Trap(i.instr->flags); e.L(skip); } }; @@ -225,7 +225,7 @@ EMITTER(TRAP_TRUE_I32, MATCH(I>)) { e.test(i.src1, i.src1); Xbyak::Label skip; e.jz(skip); - e.Trap(); + e.Trap(i.instr->flags); e.L(skip); } }; @@ -234,7 +234,7 @@ EMITTER(TRAP_TRUE_I64, MATCH(I>)) { e.test(i.src1, i.src1); Xbyak::Label skip; e.jz(skip); - e.Trap(); + e.Trap(i.instr->flags); e.L(skip); } }; @@ -243,7 +243,7 @@ EMITTER(TRAP_TRUE_F32, MATCH(I>)) { e.vptest(i.src1, i.src1); Xbyak::Label skip; e.jz(skip); - e.Trap(); + e.Trap(i.instr->flags); e.L(skip); } }; @@ -252,7 +252,7 @@ EMITTER(TRAP_TRUE_F64, MATCH(I>)) { e.vptest(i.src1, i.src1); Xbyak::Label skip; e.jz(skip); - e.Trap(); + e.Trap(i.instr->flags); e.L(skip); } }; diff --git a/src/alloy/frontend/ppc/ppc_emit_control.cc b/src/alloy/frontend/ppc/ppc_emit_control.cc index 0365c849b..111be91a3 100644 --- a/src/alloy/frontend/ppc/ppc_emit_control.cc +++ b/src/alloy/frontend/ppc/ppc_emit_control.cc @@ -400,7 +400,7 @@ XEEMITTER(sc, 0x44000002, SC )(PPCHIRBuilder& f, InstrData& i) { // Trap (A-25) int InstrEmit_trap(PPCHIRBuilder& f, InstrData& i, - Value* va, Value* vb, uint32_t TO) { + Value* va, Value* vb, uint32_t TO) { // if (a < b) & TO[0] then TRAP // if (a > b) & TO[1] then TRAP // if (a = b) & TO[2] then TRAP @@ -482,6 +482,12 @@ XEEMITTER(twi, 0x0C000000, D )(PPCHIRBuilder& f, InstrData& i) { // if (a = EXTS(SI)) & TO[2] then TRAP // if (a u EXTS(SI)) & TO[4] then TRAP + if (i.D.RA == 0 && i.D.RT == 0x1F) { + // This is a special trap. Probably. + uint16_t type = (uint16_t)XEEXTS16(i.D.DS); + f.Trap(type); + return 0; + } Value* ra = f.SignExtend(f.Truncate( f.LoadGPR(i.D.RA), INT32_TYPE), INT64_TYPE); Value* rb = f.LoadConstant(XEEXTS16(i.D.DS)); diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index 158e08224..de0ce4a34 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -577,21 +577,21 @@ void HIRBuilder::DebugBreakTrue(Value* cond) { EndBlock(); } -void HIRBuilder::Trap() { - Instr* i = AppendInstr(OPCODE_TRAP_info, 0); +void HIRBuilder::Trap(uint16_t trap_code) { + Instr* i = AppendInstr(OPCODE_TRAP_info, trap_code); i->src1.value = i->src2.value = i->src3.value = NULL; EndBlock(); } -void HIRBuilder::TrapTrue(Value* cond) { +void HIRBuilder::TrapTrue(Value* cond, uint16_t trap_code) { if (cond->IsConstant()) { if (cond->IsConstantTrue()) { - Trap(); + Trap(trap_code); } return; } - Instr* i = AppendInstr(OPCODE_TRAP_TRUE_info, 0); + Instr* i = AppendInstr(OPCODE_TRAP_TRUE_info, trap_code); i->set_src1(cond); i->src2.value = i->src3.value = NULL; EndBlock(); diff --git a/src/alloy/hir/hir_builder.h b/src/alloy/hir/hir_builder.h index 6568a5a49..7703dc8f1 100644 --- a/src/alloy/hir/hir_builder.h +++ b/src/alloy/hir/hir_builder.h @@ -71,8 +71,8 @@ public: void DebugBreak(); void DebugBreakTrue(Value* cond); - void Trap(); - void TrapTrue(Value* cond); + void Trap(uint16_t trap_code = 0); + void TrapTrue(Value* cond, uint16_t trap_code = 0); void Call(runtime::FunctionInfo* symbol_info, uint32_t call_flags = 0); void CallTrue(Value* cond, runtime::FunctionInfo* symbol_info, From eb7987a63489f6f399688931f1a8dc194d38a525 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 8 Jul 2014 16:01:57 -0700 Subject: [PATCH 002/388] Setting default output values for pixel shaders. --- src/xenia/gpu/d3d11/d3d11_shader_translator.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/xenia/gpu/d3d11/d3d11_shader_translator.cc b/src/xenia/gpu/d3d11/d3d11_shader_translator.cc index 5bb28c6e6..b23c0d5a5 100644 --- a/src/xenia/gpu/d3d11/d3d11_shader_translator.cc +++ b/src/xenia/gpu/d3d11/d3d11_shader_translator.cc @@ -274,8 +274,11 @@ int D3D11ShaderTranslator::TranslatePixelShader( // Pixel shader main() header. append( "PS_OUTPUT main(VS_OUTPUT i) {\n" - " PS_OUTPUT o;\n" - " o.oC0 = float4(1.0, 0.0, 0.0, 1.0);\n"); + " PS_OUTPUT o;\n"); + for (uint32_t n = 0; n < alloc_counts.params; n++) { + append( + " o.oC%d = float4(1.0, 0.0, 0.0, 1.0);\n", n); + } // Add temporary registers. uint32_t temp_regs = program_cntl.vs_regs + program_cntl.ps_regs; From 0950e9f53cb3ddcd86475597cd18067238e22af6 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 8 Jul 2014 16:02:16 -0700 Subject: [PATCH 003/388] Calm some games down that hammer XMPGetStatus. --- src/xenia/kernel/xam_msg.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/xenia/kernel/xam_msg.cc b/src/xenia/kernel/xam_msg.cc index 7c288c492..7215e94d1 100644 --- a/src/xenia/kernel/xam_msg.cc +++ b/src/xenia/kernel/xam_msg.cc @@ -53,6 +53,9 @@ SHIM_CALL XMsgInProcessCall_shim( // arg1 = ? // arg2 = 0 } else if (message == 0x0007001B) { + // Some stupid games will hammer this on a thread - induce a delay + // here to keep from starving real threads. + Sleep(1); uint32_t a = SHIM_MEM_32(arg1 + 0); // 0x00000002 uint32_t b = SHIM_MEM_32(arg1 + 4); // out ptr to 4b - expect 0 XELOGD("XMPGetStatus(%.8X, %.8X)", a, b); From deaf8308fcb884cab0727d271856c40adaad77d6 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 8 Jul 2014 20:52:12 -0700 Subject: [PATCH 004/388] More UNPACK forms - likely right. --- src/alloy/backend/x64/x64_sequences.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index e06f69a99..6d513aae0 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -4891,16 +4891,20 @@ EMITTER(UNPACK, MATCH(I, V128<>>)) { e.vaddps(i.dest, e.GetXmmConstPtr(XMM3301)); } static void EmitS8_IN_16_LO(X64Emitter& e, const EmitArgType& i) { - XEASSERTALWAYS(); + e.vpunpckhbw(i.dest, i.src1, i.src1); + e.vpsrad(i.dest, 8); } static void EmitS8_IN_16_HI(X64Emitter& e, const EmitArgType& i) { - XEASSERTALWAYS(); + e.vpunpcklbw(i.dest, i.src1, i.src1); + e.vpsrad(i.dest, 8); } static void EmitS16_IN_32_LO(X64Emitter& e, const EmitArgType& i) { - XEASSERTALWAYS(); + e.vpunpckhwd(i.dest, i.src1, i.src1); + e.vpsrad(i.dest, 16); } static void EmitS16_IN_32_HI(X64Emitter& e, const EmitArgType& i) { - XEASSERTALWAYS(); + e.vpunpcklwd(i.dest, i.src1, i.src1); + e.vpsrad(i.dest, 16); } }; EMITTER_OPCODE_TABLE( From fd2a1f85a619fce0907b4df5a5a85ed87559521b Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 8 Jul 2014 21:47:31 -0700 Subject: [PATCH 005/388] Fixing #105 enough to get the games moving along. --- src/alloy/frontend/ppc/ppc_context.h | 62 +++++++++++------------ src/alloy/frontend/ppc/ppc_emit_fpu.cc | 23 +++++++-- src/alloy/frontend/ppc/ppc_hir_builder.cc | 9 ++++ src/alloy/frontend/ppc/ppc_hir_builder.h | 2 + src/alloy/frontend/ppc/ppc_instr.h | 4 +- 5 files changed, 63 insertions(+), 37 deletions(-) diff --git a/src/alloy/frontend/ppc/ppc_context.h b/src/alloy/frontend/ppc/ppc_context.h index 5bc5f159e..5e40b19f2 100644 --- a/src/alloy/frontend/ppc/ppc_context.h +++ b/src/alloy/frontend/ppc/ppc_context.h @@ -144,40 +144,40 @@ typedef struct XECACHEALIGN64 PPCContext_s { union { uint32_t value; struct { - uint8_t fx :1; // FP exception summary -- sticky - uint8_t fex :1; // FP enabled exception summary - uint8_t vx :1; // FP invalid operation exception summary - uint8_t ox :1; // FP overflow exception -- sticky - uint8_t ux :1; // FP underflow exception -- sticky - uint8_t zx :1; // FP zero divide exception -- sticky - uint8_t xx :1; // FP inexact exception -- sticky - uint8_t vxsnan :1; // FP invalid op exception: SNaN -- sticky - uint8_t vxisi :1; // FP invalid op exception: infinity - infinity -- sticky - uint8_t vxidi :1; // FP invalid op exception: infinity / infinity -- sticky - uint8_t vxzdz :1; // FP invalid op exception: 0 / 0 -- sticky - uint8_t vximz :1; // FP invalid op exception: infinity * 0 -- sticky - uint8_t vxvc :1; // FP invalid op exception: invalid compare -- sticky - uint8_t fr :1; // FP fraction rounded - uint8_t fi :1; // FP fraction inexact - uint8_t fprf_c :1; // FP result class - uint8_t fprf_lt :1; // FP result less than or negative (FL or <) - uint8_t fprf_gt :1; // FP result greater than or positive (FG or >) - uint8_t fprf_eq :1; // FP result equal or zero (FE or =) - uint8_t fprf_un :1; // FP result unordered or NaN (FU or ?) - uint8_t reserved :1; - uint8_t vxsoft :1; // FP invalid op exception: software request -- sticky - uint8_t vxsqrt :1; // FP invalid op exception: invalid sqrt -- sticky - uint8_t vxcvi :1; // FP invalid op exception: invalid integer convert -- sticky - uint8_t ve :1; // FP invalid op exception enable - uint8_t oe :1; // IEEE floating-point overflow exception enable - uint8_t ue :1; // IEEE floating-point underflow exception enable - uint8_t ze :1; // IEEE floating-point zero divide exception enable - uint8_t xe :1; // IEEE floating-point inexact exception enable - uint8_t ni :1; // Floating-point non-IEEE mode - uint8_t rn :2; // FP rounding control: 00 = nearest + uint32_t rn :2; // FP rounding control: 00 = nearest // 01 = toward zero // 10 = toward +infinity // 11 = toward -infinity + uint32_t ni :1; // Floating-point non-IEEE mode + uint32_t xe :1; // IEEE floating-point inexact exception enable + uint32_t ze :1; // IEEE floating-point zero divide exception enable + uint32_t ue :1; // IEEE floating-point underflow exception enable + uint32_t oe :1; // IEEE floating-point overflow exception enable + uint32_t ve :1; // FP invalid op exception enable + uint32_t vxcvi :1; // FP invalid op exception: invalid integer convert -- sticky + uint32_t vxsqrt :1; // FP invalid op exception: invalid sqrt -- sticky + uint32_t vxsoft :1; // FP invalid op exception: software request -- sticky + uint32_t reserved :1; + uint32_t fprf_un :1; // FP result unordered or NaN (FU or ?) + uint32_t fprf_eq :1; // FP result equal or zero (FE or =) + uint32_t fprf_gt :1; // FP result greater than or positive (FG or >) + uint32_t fprf_lt :1; // FP result less than or negative (FL or <) + uint32_t fprf_c :1; // FP result class + uint32_t fi :1; // FP fraction inexact + uint32_t fr :1; // FP fraction rounded + uint32_t vxvc :1; // FP invalid op exception: invalid compare -- sticky + uint32_t vximz :1; // FP invalid op exception: infinity * 0 -- sticky + uint32_t vxzdz :1; // FP invalid op exception: 0 / 0 -- sticky + uint32_t vxidi :1; // FP invalid op exception: infinity / infinity -- sticky + uint32_t vxisi :1; // FP invalid op exception: infinity - infinity -- sticky + uint32_t vxsnan :1; // FP invalid op exception: SNaN -- sticky + uint32_t xx :1; // FP inexact exception -- sticky + uint32_t zx :1; // FP zero divide exception -- sticky + uint32_t ux :1; // FP underflow exception -- sticky + uint32_t ox :1; // FP overflow exception -- sticky + uint32_t vx :1; // FP invalid operation exception summary + uint32_t fex :1; // FP enabled exception summary + uint32_t fx :1; // FP exception summary -- sticky } bits; } fpscr; // Floating-point status and control register diff --git a/src/alloy/frontend/ppc/ppc_emit_fpu.cc b/src/alloy/frontend/ppc/ppc_emit_fpu.cc index 683a2d3de..c09fea20f 100644 --- a/src/alloy/frontend/ppc/ppc_emit_fpu.cc +++ b/src/alloy/frontend/ppc/ppc_emit_fpu.cc @@ -426,8 +426,12 @@ XEEMITTER(mcrfs, 0xFC000080, X )(PPCHIRBuilder& f, InstrData& i) { } XEEMITTER(mffsx, 0xFC00048E, X )(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + if (i.X.Rc) { + XEINSTRNOTIMPLEMENTED(); + return 1; + } + f.StoreFPR(i.X.RT, f.Cast(f.LoadFPSCR(), FLOAT64_TYPE)); + return 0; } XEEMITTER(mtfsb0x, 0xFC00008C, X )(PPCHIRBuilder& f, InstrData& i) { @@ -441,8 +445,19 @@ XEEMITTER(mtfsb1x, 0xFC00004C, X )(PPCHIRBuilder& f, InstrData& i) { } XEEMITTER(mtfsfx, 0xFC00058E, XFL)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + if (i.XFL.Rc) { + XEINSTRNOTIMPLEMENTED(); + return 1; + } + if (i.XFL.L) { + // Move/shift. + XEINSTRNOTIMPLEMENTED(); + return 1; + } else { + // Directly store. + f.StoreFPSCR(f.Cast(f.LoadFPR(i.XFL.RB), INT64_TYPE)); + } + return 0; } XEEMITTER(mtfsfix, 0xFC00010C, X )(PPCHIRBuilder& f, InstrData& i) { diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index a8bec8435..db2f304b4 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -268,6 +268,15 @@ void PPCHIRBuilder::UpdateCR6(Value* src_value) { StoreContext(offsetof(PPCContext, cr6.cr6_none_equal), IsFalse(src_value)); } +Value* PPCHIRBuilder::LoadFPSCR() { + return LoadContext(offsetof(PPCContext, fpscr), INT64_TYPE); +} + +void PPCHIRBuilder::StoreFPSCR(Value* value) { + XEASSERT(value->type == INT64_TYPE); + StoreContext(offsetof(PPCContext, fpscr), value); +} + Value* PPCHIRBuilder::LoadXER() { XEASSERTALWAYS(); return NULL; diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.h b/src/alloy/frontend/ppc/ppc_hir_builder.h index b386d95a1..58560bf02 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.h +++ b/src/alloy/frontend/ppc/ppc_hir_builder.h @@ -49,6 +49,8 @@ public: void UpdateCR(uint32_t n, Value* lhs, bool is_signed = true); void UpdateCR(uint32_t n, Value* lhs, Value* rhs, bool is_signed = true); void UpdateCR6(Value* src_value); + Value* LoadFPSCR(); + void StoreFPSCR(Value* value); Value* LoadXER(); void StoreXER(Value* value); //void UpdateXERWithOverflow(); diff --git a/src/alloy/frontend/ppc/ppc_instr.h b/src/alloy/frontend/ppc/ppc_instr.h index b9c0c30f3..01026e7f6 100644 --- a/src/alloy/frontend/ppc/ppc_instr.h +++ b/src/alloy/frontend/ppc/ppc_instr.h @@ -177,9 +177,9 @@ typedef struct { uint32_t Rc : 1; uint32_t : 10; uint32_t RB : 5; - uint32_t : 1; + uint32_t W : 1; uint32_t FM : 8; - uint32_t : 1; + uint32_t L : 1; uint32_t : 6; } XFL; // kXEPPCInstrFormatXS From f3e7d0a4423094eb1a99d9ddb3060f75747df646 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 9 Jul 2014 20:56:52 -0700 Subject: [PATCH 006/388] Bumping xbyak version. --- third_party/xbyak | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/xbyak b/third_party/xbyak index df27af3e4..77d1346d0 160000 --- a/third_party/xbyak +++ b/third_party/xbyak @@ -1 +1 @@ -Subproject commit df27af3e4e7ded756bfbb23d0f663df728442935 +Subproject commit 77d1346d00dfa2066ea24aea0058cd2b47b546bf From 6b197c4c92331e2fcd1323f09c6f58a685ebeafb Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 9 Jul 2014 21:21:40 -0700 Subject: [PATCH 007/388] Removing the debugger and dependencies. Needs rethinking. --- .gitmodules | 6 - debugger/assets/styles/app.css | 468 ------------ debugger/assets/ui/apu/apu-tab.html | 1 - debugger/assets/ui/code/code-tab.html | 135 ---- debugger/assets/ui/code/code-tab.js | 93 --- debugger/assets/ui/code/function-view.html | 47 -- debugger/assets/ui/code/function-view.js | 268 ------- debugger/assets/ui/code/module-info.html | 218 ------ debugger/assets/ui/code/module-info.js | 52 -- debugger/assets/ui/code/thread-info.html | 35 - debugger/assets/ui/code/thread-info.js | 51 -- debugger/assets/ui/console/console.html | 26 - debugger/assets/ui/console/console.js | 34 - debugger/assets/ui/gpu/gpu-tab.html | 1 - debugger/assets/ui/kernel/kernel-tab.html | 1 - debugger/assets/ui/memory/memory-tab.html | 1 - debugger/assets/ui/navbar.html | 40 - debugger/assets/ui/navbar.js | 56 -- debugger/assets/ui/session.html | 1 - debugger/debugger.js | 8 - debugger/index.html | 42 -- debugger/src/app.js | 125 ---- debugger/src/base.js | 61 -- debugger/src/datasources.js | 317 -------- debugger/src/directives.js | 89 --- debugger/src/filters.js | 45 -- debugger/src/log.js | 45 -- debugger/src/router.js | 146 ---- debugger/src/session.js | 489 ------------- src/xenia/cpu/processor.cc | 684 +----------------- src/xenia/cpu/processor.h | 35 +- src/xenia/debug/debug_client.cc | 39 - src/xenia/debug/debug_client.h | 54 -- src/xenia/debug/debug_server.cc | 186 ----- src/xenia/debug/debug_server.h | 75 -- src/xenia/debug/debug_target.h | 48 -- src/xenia/debug/protocol.cc | 22 - src/xenia/debug/protocol.h | 40 - src/xenia/debug/protocols/gdb/gdb_client.cc | 456 ------------ src/xenia/debug/protocols/gdb/gdb_client.h | 84 --- src/xenia/debug/protocols/gdb/gdb_protocol.cc | 105 --- src/xenia/debug/protocols/gdb/gdb_protocol.h | 55 -- src/xenia/debug/protocols/gdb/message.cc | 90 --- src/xenia/debug/protocols/gdb/message.h | 70 -- src/xenia/debug/protocols/gdb/sources.gypi | 11 - src/xenia/debug/protocols/sources.gypi | 7 - src/xenia/debug/protocols/ws/simple_sha1.cc | 235 ------ src/xenia/debug/protocols/ws/simple_sha1.h | 35 - src/xenia/debug/protocols/ws/sources.gypi | 11 - src/xenia/debug/protocols/ws/ws_client.cc | 531 -------------- src/xenia/debug/protocols/ws/ws_client.h | 72 -- src/xenia/debug/protocols/ws/ws_protocol.cc | 104 --- src/xenia/debug/protocols/ws/ws_protocol.h | 55 -- src/xenia/debug/sources.gypi | 16 - src/xenia/emulator.cc | 19 - src/xenia/kernel/xboxkrnl_module.cc | 7 - src/xenia/sources.gypi | 1 - src/xenia/xenia.h | 1 - third_party/jansson | 1 - third_party/jansson.gypi | 59 -- third_party/wslay | 1 - third_party/wslay.gypi | 59 -- xenia.gyp | 6 - 63 files changed, 2 insertions(+), 6173 deletions(-) delete mode 100644 debugger/assets/styles/app.css delete mode 100644 debugger/assets/ui/apu/apu-tab.html delete mode 100644 debugger/assets/ui/code/code-tab.html delete mode 100644 debugger/assets/ui/code/code-tab.js delete mode 100644 debugger/assets/ui/code/function-view.html delete mode 100644 debugger/assets/ui/code/function-view.js delete mode 100644 debugger/assets/ui/code/module-info.html delete mode 100644 debugger/assets/ui/code/module-info.js delete mode 100644 debugger/assets/ui/code/thread-info.html delete mode 100644 debugger/assets/ui/code/thread-info.js delete mode 100644 debugger/assets/ui/console/console.html delete mode 100644 debugger/assets/ui/console/console.js delete mode 100644 debugger/assets/ui/gpu/gpu-tab.html delete mode 100644 debugger/assets/ui/kernel/kernel-tab.html delete mode 100644 debugger/assets/ui/memory/memory-tab.html delete mode 100644 debugger/assets/ui/navbar.html delete mode 100644 debugger/assets/ui/navbar.js delete mode 100644 debugger/assets/ui/session.html delete mode 100644 debugger/debugger.js delete mode 100644 debugger/index.html delete mode 100644 debugger/src/app.js delete mode 100644 debugger/src/base.js delete mode 100644 debugger/src/datasources.js delete mode 100644 debugger/src/directives.js delete mode 100644 debugger/src/filters.js delete mode 100644 debugger/src/log.js delete mode 100644 debugger/src/router.js delete mode 100644 debugger/src/session.js delete mode 100644 src/xenia/debug/debug_client.cc delete mode 100644 src/xenia/debug/debug_client.h delete mode 100644 src/xenia/debug/debug_server.cc delete mode 100644 src/xenia/debug/debug_server.h delete mode 100644 src/xenia/debug/debug_target.h delete mode 100644 src/xenia/debug/protocol.cc delete mode 100644 src/xenia/debug/protocol.h delete mode 100644 src/xenia/debug/protocols/gdb/gdb_client.cc delete mode 100644 src/xenia/debug/protocols/gdb/gdb_client.h delete mode 100644 src/xenia/debug/protocols/gdb/gdb_protocol.cc delete mode 100644 src/xenia/debug/protocols/gdb/gdb_protocol.h delete mode 100644 src/xenia/debug/protocols/gdb/message.cc delete mode 100644 src/xenia/debug/protocols/gdb/message.h delete mode 100644 src/xenia/debug/protocols/gdb/sources.gypi delete mode 100644 src/xenia/debug/protocols/sources.gypi delete mode 100644 src/xenia/debug/protocols/ws/simple_sha1.cc delete mode 100644 src/xenia/debug/protocols/ws/simple_sha1.h delete mode 100644 src/xenia/debug/protocols/ws/sources.gypi delete mode 100644 src/xenia/debug/protocols/ws/ws_client.cc delete mode 100644 src/xenia/debug/protocols/ws/ws_client.h delete mode 100644 src/xenia/debug/protocols/ws/ws_protocol.cc delete mode 100644 src/xenia/debug/protocols/ws/ws_protocol.h delete mode 100644 src/xenia/debug/sources.gypi delete mode 160000 third_party/jansson delete mode 100644 third_party/jansson.gypi delete mode 160000 third_party/wslay delete mode 100644 third_party/wslay.gypi diff --git a/.gitmodules b/.gitmodules index cfeadeb7d..2a1898d63 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,12 +13,6 @@ [submodule "third_party/beaengine"] path = third_party/beaengine url = https://github.com/benvanik/beaengine.git -[submodule "third_party/wslay"] - path = third_party/wslay - url = https://github.com/benvanik/wslay.git -[submodule "third_party/jansson"] - path = third_party/jansson - url = https://github.com/akheron/jansson.git [submodule "third_party/xbyak"] path = third_party/xbyak url = https://github.com/herumi/xbyak.git diff --git a/debugger/assets/styles/app.css b/debugger/assets/styles/app.css deleted file mode 100644 index a66515e68..000000000 --- a/debugger/assets/styles/app.css +++ /dev/null @@ -1,468 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -.full-width { - width: 100%; -} -.left-align { - text-align: left; -} - -body { - margin: 0; -} - -.app-main { - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; - overflow: hidden; - min-width: 900px; - min-height: 350px; - display: flex; - flex-flow: column nowrap; -} -.app-header { - order: 1; - flex: 0 0 auto; - align-self: auto; -} -.app-header .navbar { - border-radius: 0; - min-height: 0; - margin-bottom: 0; -} - -.app-body { - order: 2; - flex: 1 1 auto; - align-self: auto; - position: relative; - left: 0; - top: 0; - right: 0; - bottom: 0; -} -.disconnected .app-body { - opacity: 0.25; - pointer-events: none; -} -.tab-pane { - position: absolute; - left: 0; - top: 0; - right: 0; - bottom: 0; -} - -.app-console { - order: 3; - flex: 0 0 auto; - align-self: auto; - border-top-width: 2px; - border-top-style: solid; -} -.console { - display: flex; - flex-flow: column nowrap; - padding: 5px; -} -.console-part-log { - order: 1; - flex: 1 1 auto; - align-self: auto; -} -.console-log-outer { - position: relative; - left: 0; - top: 0; - right: 0; - bottom: 0; - border: 1px solid #ddd; - overflow-y: scroll; - height: 100px; -} -.console-part-input { - order: 2; - flex: 0 0 auto; - align-self: auto; - display: flex; - flex-flow: row nowrap; - padding-top: 5px; -} -.console-input-left { - order: 1; - flex: 0 0 auto; - min-width: 0; -} -.console-input-middle { - order: 2; - flex: 1 1 auto; -} -.console-input-right { - order: 3; - flex: 0 0 auto; - padding-left: 10px; -} - -.debugger-main { - position: absolute; - left: 0; - top: 0; - right: 0; - bottom: 0; - display: flex; - flex-flow: column nowrap; -} -.debugger-header { - order: 1; - flex: 0 0 auto; - align-self: auto; - border-bottom: 1px solid #ddd; - padding: 5px; -} -.debugger-body { - order: 2; - flex: 1 1 auto; - align-self: auto; - display: flex; - flex-flow: row nowrap; -} -.debugger-fnlist { - order: 1; - flex: 0 0 auto; - display: flex; - flex-flow: column nowrap; - min-width: 270px; -} -.debugger-fnlist-header { - order: 1; - flex: 0 0 auto; - padding: 5px; - display: flex; - flex-flow: row nowrap; -} -.debugger-fnlist-header-left { - order: 1; - flex: 1 1 auto; - padding-right: 5px; -} -.debugger-fnlist-header-right { - order: 2; - flex: 0 0 auto; -} -.debugger-fnlist-body { - order: 2; - flex: 1 1 auto; - padding: 5px; - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - position: relative; -} -.debugger-fnlist-list { - position: absolute; - left: 0; - top: 0; - right: 0; - bottom: 0; - padding: 5px; - overflow-x: auto; - overflow-y: scroll; -} -.debugger-fnlist-list > table > tbody > tr > td { - padding: 0; - line-height: 1.2em; - font-family: monospace; - border: 0; -} -.debugger-fnlist-footer { - order: 3; - flex: 0 0 auto; - padding: 5px; -} -.debugger-fnlist-footer .input-group { - width: 100%; -} -.debugger-fnview-outer { - order: 2; - flex: 1 1 auto; - position: relative; - border-left: 2px solid #ddd; - border-right: 2px solid #ddd; - min-width: 720px; -} -.debugger-fnview { - position: absolute; - left: 0; - top: 0; - bottom: 0; - right: 0; - display: flex; - flex-flow: column nowrap; -} -.debugger-fnview-header { - order: 1; - flex: 0 0 auto; - padding: 5px; - display: flex; - flex-flow: row nowrap; -} -.debugger-fnview-header-left { - order: 1; - flex: 1 1 auto; - padding: 5px; - line-height: 1; -} -.debugger-fnview-header-name { - font-size: 21px; - font-family: monospace; -} -.debugger-fnview-header-address { - font-family: monospace; -} -.debugger-fnview-header-right { - order: 2; - flex: 0 0 auto; - padding: 5px; - margin-top: 3px; -} -.debugger-fnview-body { - order: 2; - flex: 1 1 auto; - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - display: flex; - flex-flow: row nowrap; -} -.debugger-fnview-codeview { - order: 1; - flex: 1 1 auto; - position: relative; -} -.debugger-fnview-codeview .CodeMirror { - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; - height: 100%; -} -.debugger-fnview-gutter-icon { - width: 30px; -} -.debugger-fnview-gutter-icon-el { - padding-left: 7px; - position: relative; - top: -6px; - display: inline-block; - -webkit-font-smoothing: antialiased; - font-style: normal; - font-weight: normal; - line-height: 1; - font-size: 28px; -} -.debugger-fnview-gutter-addr { - width: 70px; -} -.debugger-fnview-gutter-addr-el { -} -.debugger-fnview-gutter-addr-el-inactive { - color: #999; -} -.debugger-fnview-gutter-code { - width: 76px; - background-color: #fff; - border-left: 1px solid #ddd; -} -.debugger-fnview-gutter-code-el { - padding-left: 6px; - color: #aaa; -} -.debugger-fnview-line-highlight-bg { - background-color: red; -} -.debugger-fnview-graphview { - order: 2; - flex: 0 0 auto; - position: relative; - border-left: 1px solid #ddd; - min-width: 100px; -} -.debugger-fnview-footer { - order: 3; - flex: 0 0 auto; - padding: 5px; -} -.debugger-tools { - order: 3; - flex: 0 0 auto; - display: flex; - flex-flow: column nowrap; - width: 40%; -} -.debugger-tools-threads { - order: 1; - flex: 0 0 auto; - padding: 5px; -} -.debugger-tools-threads { - order: 1; - flex: 0 0 auto; - padding: 5px; - display: flex; - flex-flow: row nowrap; -} -.debugger-tools-threads-header-left { - order: 1; - flex: 1 1 auto; - padding-right: 5px; -} -.debugger-tools-threads-header-right { - order: 2; - flex: 0 0 auto; -} -.debugger-tools-callstack { - order: 2; - flex: 0 0 auto; - padding: 5px; - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - position: relative; - height: 100px; -} -.debugger-tools-registers { - order: 3; - flex: 1 1 auto; - padding: 5px; - overflow-y: auto; -} -.debugger-tools-registers-container { - display: flex; - flex-direction: column; - flex-wrap: wrap; - justify-content: flex-start; - align-content: flex-start; - align-items: flex-start; - margin-bottom: 5px; -} -.debugger-tools-registers-entry { - flex: 0 0 auto; - font-family: monospace; - padding-right: 5px; - width: 160px; -} -.debugger-tools-registers-entry .name { - font-weight: bold; - width: 26px; - display: inline-block; - text-align: right; -} -.debugger-tools-registers-entry .value { -} -.debugger-tools-registers-container.special { - height: 46px; -} -.debugger-tools-registers-container.gpr { - height: 332px; -} -.special .debugger-tools-registers-entry, -.gpr .debugger-tools-registers-entry { - width: 300px; -} -.debugger-tools-registers-entry .hex-value { - border-style: none; - padding: 0; - width: 130px; - text-align: right; -} -.debugger-tools-registers-entry .int-value { - display: inline-block; - border-style: none; - padding: 0; - width: 92px; - text-align: right; -} -.debugger-tools-registers-container.fpr { - height: 172px; -} -.fpr .debugger-tools-registers-entry { - width: 170px; -} -.fpr .debugger-tools-registers-entry .value { - white-space: pre; -} -.vec .debugger-tools-registers-entry { - width: 160px; -} -.vec .debugger-tools-registers-entry .name { - width: 35px; -} - -.debugger-module-info { - display: block; - pointer-events: none; -} -.debugger-module-info .modal-dialog { - width: 60vw; -} -.debugger-module-info.fade .modal-dialog { - -webkit-transition: none; - -webkit-transform: translate(0,0); -} -.debugger-module-info div { - pointer-events: auto; -} -.debugger-module-info .modal-body { - max-width: 60vw; - max-height: 80vh; - overflow-y: auto; -} -.debugger-module-info-outer-table { -} -.debugger-module-info-outer-table tbody tr td:nth-child(1) { - width: 110px; -} -.debugger-module-info-inner-table { - width: 300px; -} -.debugger-module-info-inner-table td:nth-child(1) { - text-align: right; -} -.debugger-module-info-headers { - width: 400px; -} -.debugger-module-info-sections { - width: 400px; -} -.debugger-module-info-static-libraries { - width: 400px; -} -.debugger-module-info-imports { - width: 900px; -} -.debugger-module-info-imports td:nth-child(1) { - width: 40px; -} -.debugger-module-info-imports td:nth-child(2) { - width: 64px; -} -.debugger-module-info-imports td:nth-child(3) { - width: 60px; -} -.debugger-module-info-imports td:nth-child(4) { - width: 100%; -} -.debugger-module-info-imports td:nth-child(5) { - width: 80px; -} -.debugger-module-info-imports td:nth-child(6) { - width: 80px; -} diff --git a/debugger/assets/ui/apu/apu-tab.html b/debugger/assets/ui/apu/apu-tab.html deleted file mode 100644 index f57223d9b..000000000 --- a/debugger/assets/ui/apu/apu-tab.html +++ /dev/null @@ -1 +0,0 @@ -TODO: APU diff --git a/debugger/assets/ui/code/code-tab.html b/debugger/assets/ui/code/code-tab.html deleted file mode 100644 index b81d68ef3..000000000 --- a/debugger/assets/ui/code/code-tab.html +++ /dev/null @@ -1,135 +0,0 @@ -
-
-
- - -
-
- - -
-
-
-
-
-
- - -
-
- -
-
-
-
- - - - -
{{fn.name}}
-
-
- -
-
-
-
-
- - -
-
- -
-
-
- callstack -
-
-
-
- pc - -
-
- lr - -
-
- ctr - - -
-
-
-
- r{{$index}} - - -
-
-
-
- f{{$index}} - {{v|exp8}} -
-
-
-
- v{{$index}} - {{v}} -
-
-
-
-
-
diff --git a/debugger/assets/ui/code/code-tab.js b/debugger/assets/ui/code/code-tab.js deleted file mode 100644 index 07530a919..000000000 --- a/debugger/assets/ui/code/code-tab.js +++ /dev/null @@ -1,93 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -'use strict'; - -var module = angular.module('xe.ui.code', [ - 'ui.bootstrap', - 'xe.log', - 'xe.session' -]); - - -module.controller('CodeTabController', function( - $rootScope, $scope, $modal, app, log) { - $scope.app = app; - $scope.moduleList = []; - $scope.selectedModule = null; - $scope.functionList = []; - - function refresh() { - if (!app.session) { - $scope.moduleList = []; - return; - } - - $scope.moduleList = app.session.state.getModuleList(); - if (!$scope.selectedModule) { - if ($scope.moduleList.length) { - $scope.selectModule($scope.moduleList[0]); - } - } else { - $scope.selectModule($scope.selectedModule); - } - - console.log('refresh'); - }; - $rootScope.$on('refresh', refresh); - - $scope.selectModule = function(module) { - var moduleChange = module != $scope.selectedModule; - $scope.selectedModule = module; - - if (moduleChange) { - $scope.functionList = []; - } - - $scope.functionList = app.session.state.getFunctionList(module.name); - }; - - $scope.showModuleInfo = function() { - var modalInstance = $modal.open({ - templateUrl: 'assets/ui/code/module-info.html', - controller: 'ModuleInfoController', - windowClass: 'debugger-module-info', - resolve: { - moduleName: function() { - return $scope.selectedModule.name; - }, - moduleInfo: function() { - return app.session.state.getModule( - $scope.selectedModule.name); - } - } - }); - }; - - $scope.showThreadInfo = function() { - var modalInstance = $modal.open({ - templateUrl: 'assets/ui/code/thread-info.html', - controller: 'ThreadInfoController', - windowClass: 'debugger-module-info', - resolve: { - thread: function() { - return app.session.activeThread; - } - } - }); - }; - - $scope.showLocation = function() { - // - }; - - if (app.session.dataSource) { - refresh(); - } -}); diff --git a/debugger/assets/ui/code/function-view.html b/debugger/assets/ui/code/function-view.html deleted file mode 100644 index 7a530e296..000000000 --- a/debugger/assets/ui/code/function-view.html +++ /dev/null @@ -1,47 +0,0 @@ -
-
-
-
- (0x{{fn.startAddress | hex32}}-0x{{fn.endAddress | hex32}}) -
-
- -
-
-
-
- -
-
- graph! -
-
- -
diff --git a/debugger/assets/ui/code/function-view.js b/debugger/assets/ui/code/function-view.js deleted file mode 100644 index 6f42127b3..000000000 --- a/debugger/assets/ui/code/function-view.js +++ /dev/null @@ -1,268 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -'use strict'; - -var module = angular.module('xe.ui.code.functionView', [ - 'xe.log', - 'xe.session' -]); - - -module.controller('FunctionViewController', function( - $rootScope, $scope, $location, app, log, Breakpoint) { - $scope.codeType = 'source'; - $scope.highlightInfo = null; - - function refresh() { - if (!app.session) { - $scope.fn = null; - return; - } - app.session.state.fetchFunction($scope.functionAddress).then(function(fn) { - $scope.fn = fn; - updateCode(); - }, function(e) { - log.error('Unable to fetch function.'); - }); - }; - $rootScope.$on('refresh', refresh); - $scope.$watch('functionAddress', refresh); - - function updateHighlight(address) { - if (!$scope.sourceLines || $scope.codeType != 'source') { - return; - } - if ($scope.highlightInfo) { - if ($scope.highlightInfo.address == address) { - return; - } - var oldLine = $scope.highlightInfo.line; - if ($scope.highlightInfo.widget) { - $scope.highlightInfo.widget.clear(); - } - $scope.highlightInfo = null; - updateLine(oldLine); - } - // TODO(benvanik): a better mapping. - var line = -1; - for (var n = 0; n < $scope.sourceLines.length; n++) { - var sourceLine = $scope.sourceLines[n]; - if (sourceLine[0] == 'i' && - sourceLine[1] == address) { - line = n; - break; - } - } - if (line != -1) { - $scope.highlightInfo = { - address: address, - line: line, - widget: null - }; - updateLine(line); - } - }; - $scope.$watch(function() { - return $location.search(); - }, function(search) { - updateHighlight(parseInt(search.a, 16)); - }); - - var textArea = document.querySelector('.debugger-fnview-textarea'); - $scope.codeMirror = CodeMirror.fromTextArea(textArea, { - mode: 'javascript', - theme: 'default', - indentUnit: 2, - tabSize: 2, - lineNumbers: false, - gutters: [ - 'debugger-fnview-gutter-icon', - 'debugger-fnview-gutter-addr', - 'debugger-fnview-gutter-code' - ], - readOnly: true - }); - - function hex32(number) { - var str = "" + number.toString(16).toUpperCase(); - while (str.length < 8) str = "0" + str; - return str; - }; - - function updateSourceCode(fn) { - var cm = $scope.codeMirror; - if (!fn) { - $scope.sourceLines = []; - cm.setValue(''); - return; - } - - var doc = cm.getDoc(); - - var lines = fn.disasm.source.lines; - $scope.sourceLines = lines; - - var textContent = []; - for (var n = 0; n < lines.length; n++) { - var line = lines[n]; - textContent.push(line[3]); - } - cm.setValue(textContent.join('\n')); - - for (var n = 0; n < lines.length; n++) { - var line = lines[n]; - - var el = document.createElement('div'); - el.classList.add('debugger-fnview-gutter-addr-el'); - el.innerText = hex32(line[1]); - cm.setGutterMarker(n, 'debugger-fnview-gutter-addr', el); - if (line[0] != 'i') { - el.classList.add('debugger-fnview-gutter-addr-el-inactive'); - } - - if (line[0] == 'i') { - el = document.createElement('div'); - el.classList.add('debugger-fnview-gutter-code-el'); - el.innerText = hex32(line[2]); - cm.setGutterMarker(n, 'debugger-fnview-gutter-code', el); - - updateLine(n); - } - } - }; - function updateCode() { - var cm = $scope.codeMirror; - var fn = $scope.fn || null; - var codeType = $scope.codeType; - - var gutters; - switch (codeType) { - case 'source': - gutters = [ - 'debugger-fnview-gutter-icon', - 'debugger-fnview-gutter-addr', - 'debugger-fnview-gutter-code' - ]; - break; - default: - gutters = [ - 'debugger-fnview-gutter-icon', - 'debugger-fnview-gutter-addr' - ]; - break; - } - cm.setOption('gutters', gutters); - - cm.clearGutter('debugger-fnview-gutter-icon'); - cm.clearGutter('debugger-fnview-gutter-addr'); - cm.clearGutter('debugger-fnview-gutter-code'); - - // Set last to make all option changes stick. - switch (codeType) { - case 'source': - cm.operation(function() { - updateSourceCode(fn); - }); - break; - default: - var value = fn ? fn.disasm[codeType] : null; - cm.setValue(value || ''); - break; - } - }; - $scope.$watch('codeType', updateCode); - - function updateLine(line) { - var sourceLine = $scope.sourceLines[line]; - var cm = $scope.codeMirror; - if (sourceLine[0] != 'i') { - return; - } - var address = sourceLine[1]; - var breakpoint = app.session.breakpoints[address]; - var el; - if (breakpoint && breakpoint.type == 'code') { - el = document.createElement('span'); - el.classList.add('debugger-fnview-gutter-icon-el'); - if (breakpoint.enabled) { - el.innerHTML = '●'; - } else { - el.innerHTML = '◌'; - } - } else { - el = null; - } - cm.setGutterMarker(line, 'debugger-fnview-gutter-icon', el); - - var highlightInfo = $scope.highlightInfo; - if (highlightInfo && highlightInfo.line == line) { - /* - if (!highlightInfo.widget) { - el = document.createElement('div'); - el.style.width = '100%'; - el.style.height = '20px'; - el.style.backgroundColor = 'red'; - el.innerHTML = 'hi!'; - highlightInfo.widget = cm.addLineWidget(line, el, { - coverGutter: false - }); - cm.scrollIntoView(line, 50); - } - */ - cm.addLineClass(line, 'background', 'debugger-fnview-line-highlight-bg'); - } else { - cm.removeLineClass(line, 'background'); - } - }; - - function toggleBreakpoint(line, sourceLine, shiftKey) { - var address = sourceLine[1]; - var breakpoint = app.session.breakpoints[address]; - if (breakpoint) { - // Existing breakpoint - toggle or remove. - if (shiftKey || !breakpoint.enabled) { - app.session.toggleBreakpoint(breakpoint, !breakpoint.enabled); - } else { - app.session.removeBreakpoint(breakpoint); - } - } else { - // New breakpoint needed. - breakpoint = app.session.addCodeBreakpoint( - $scope.functionAddress, address); - } - - updateLine(line); - }; - - $scope.codeMirror.on('gutterClick', function( - instance, line, gutterClass, e) { - if (e.which == 1) { - if (gutterClass == 'debugger-fnview-gutter-icon' || - gutterClass == 'debugger-fnview-gutter-addr') { - var sourceLine = $scope.sourceLines[line]; - if (!sourceLine || sourceLine[0] != 'i') { - return; - } - e.preventDefault(); - toggleBreakpoint(line, sourceLine, e.shiftKey); - } - } - }); -// $scope.codeMirror.on('gutterContextMenu', function( -// instance, line, gutterClass, e) { -// console.log('context menu'); -// e.preventDefault(); -// }); -// $scope.codeMirror.on('contextmenu', function( -// instance, e) { -// console.log('context menu main'); -// e.preventDefault(); -// }); -}); diff --git a/debugger/assets/ui/code/module-info.html b/debugger/assets/ui/code/module-info.html deleted file mode 100644 index 018b604d9..000000000 --- a/debugger/assets/ui/code/module-info.html +++ /dev/null @@ -1,218 +0,0 @@ - diff --git a/debugger/assets/ui/code/module-info.js b/debugger/assets/ui/code/module-info.js deleted file mode 100644 index 8078d955e..000000000 --- a/debugger/assets/ui/code/module-info.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -'use strict'; - -var module = angular.module('xe.ui.code.moduleInfo', [ - 'ui.bootstrap', - 'xe.log', - 'xe.session' -]); - - -module.controller('ModuleInfoController', function( - $rootScope, $scope, $modal, log, moduleName, moduleInfo) { - $scope.moduleName = moduleName; - $scope.moduleInfo = moduleInfo; - - $scope.headerSort = { - column: 'key', - reverse: false - }; - $scope.sectionSort = { - column: 'startAddress', - reverse: false - }; - $scope.staticLibrarySort = { - column: 'name', - reverse: false - }; - $scope.importSort = { - column: 'ordinal', - reverse: false - }; - $scope.changeSort = function(sort, column) { - if (sort.column == column) { - sort.reverse = !sort.reverse; - } else { - sort.column = column; - sort.reverse = false; - } - }; - - $scope.close = function() { - $scope.$close(null); - }; -}); diff --git a/debugger/assets/ui/code/thread-info.html b/debugger/assets/ui/code/thread-info.html deleted file mode 100644 index 9d1c925af..000000000 --- a/debugger/assets/ui/code/thread-info.html +++ /dev/null @@ -1,35 +0,0 @@ - diff --git a/debugger/assets/ui/code/thread-info.js b/debugger/assets/ui/code/thread-info.js deleted file mode 100644 index bd48acfb6..000000000 --- a/debugger/assets/ui/code/thread-info.js +++ /dev/null @@ -1,51 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -'use strict'; - -var module = angular.module('xe.ui.code.threadInfo', [ - 'ui.bootstrap', - 'xe.log', - 'xe.session' -]); - - -module.controller('ThreadInfoController', function( - $rootScope, $scope, $modal, log, thread) { - $scope.thread = thread; - - $scope.headerSort = { - column: 'key', - reverse: false - }; - $scope.sectionSort = { - column: 'startAddress', - reverse: false - }; - $scope.staticLibrarySort = { - column: 'name', - reverse: false - }; - $scope.importSort = { - column: 'ordinal', - reverse: false - }; - $scope.changeSort = function(sort, column) { - if (sort.column == column) { - sort.reverse = !sort.reverse; - } else { - sort.column = column; - sort.reverse = false; - } - }; - - $scope.close = function() { - $scope.$close(null); - }; -}); diff --git a/debugger/assets/ui/console/console.html b/debugger/assets/ui/console/console.html deleted file mode 100644 index 2f674513b..000000000 --- a/debugger/assets/ui/console/console.html +++ /dev/null @@ -1,26 +0,0 @@ -
-
-
-
    -
  • {{line}}
  • -
-
-
-
-
-
-
-
- @ - -
-
-
-
- - - -
-
-
-
diff --git a/debugger/assets/ui/console/console.js b/debugger/assets/ui/console/console.js deleted file mode 100644 index 6a07556b2..000000000 --- a/debugger/assets/ui/console/console.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -'use strict'; - -var module = angular.module('xe.ui.console', [ - 'xe.log' -]); - - -module.controller('ConsoleController', function($scope, log) { - $scope.log = log; - - $scope.commandText = ''; - - $scope.issueCommand = function() { - var command = $scope.commandText; - $scope.commandText = ''; - if (!command) { - return; - } - - log.appendLine('@' + command); - - // TODO(benvanik): execute. - console.log(command); - }; -}); diff --git a/debugger/assets/ui/gpu/gpu-tab.html b/debugger/assets/ui/gpu/gpu-tab.html deleted file mode 100644 index cf32ac752..000000000 --- a/debugger/assets/ui/gpu/gpu-tab.html +++ /dev/null @@ -1 +0,0 @@ -TODO: GPU diff --git a/debugger/assets/ui/kernel/kernel-tab.html b/debugger/assets/ui/kernel/kernel-tab.html deleted file mode 100644 index 92d33f5ee..000000000 --- a/debugger/assets/ui/kernel/kernel-tab.html +++ /dev/null @@ -1 +0,0 @@ -TODO: kernel diff --git a/debugger/assets/ui/memory/memory-tab.html b/debugger/assets/ui/memory/memory-tab.html deleted file mode 100644 index f15b42831..000000000 --- a/debugger/assets/ui/memory/memory-tab.html +++ /dev/null @@ -1 +0,0 @@ -TODO: memory diff --git a/debugger/assets/ui/navbar.html b/debugger/assets/ui/navbar.html deleted file mode 100644 index c2a64c9ec..000000000 --- a/debugger/assets/ui/navbar.html +++ /dev/null @@ -1,40 +0,0 @@ - diff --git a/debugger/assets/ui/navbar.js b/debugger/assets/ui/navbar.js deleted file mode 100644 index 4ae3bcde2..000000000 --- a/debugger/assets/ui/navbar.js +++ /dev/null @@ -1,56 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -'use strict'; - -var module = angular.module('xe.ui.navbar', []); - - -module.controller('NavbarController', function( - $rootScope, $scope, $state, app, log) { - - $scope.refresh = function() { - $rootScope.$emit('refresh'); - }; - - $scope.connect = function() { - // TODO(benvanik): show a fancy dialog or something. - var oldSession = app.session; - app.connect().then(function(session) { - if (!oldSession || oldSession.id != session.id) { - $state.go('session', { - 'sessionId': session.id - }, { - notify: true - }); - } - }, function(e) { - $state.go('/', { - }, { - notify: true - }); - }); - }; - - $scope.open = function() { - var inputEl = document.createElement('input'); - inputEl.type = 'file'; - inputEl.accept = '.xe-trace,application/x-extension-xe-trace'; - inputEl.onchange = function(e) { - $scope.$apply(function() { - if (inputEl.files.length) { - //app.open(inputEl.files[0]); - log.info('Not implemented yet'); - } - }); - }; - inputEl.click(); - }; - -}); diff --git a/debugger/assets/ui/session.html b/debugger/assets/ui/session.html deleted file mode 100644 index 31800c0de..000000000 --- a/debugger/assets/ui/session.html +++ /dev/null @@ -1 +0,0 @@ -
diff --git a/debugger/debugger.js b/debugger/debugger.js deleted file mode 100644 index e8f39d267..000000000 --- a/debugger/debugger.js +++ /dev/null @@ -1,8 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ diff --git a/debugger/index.html b/debugger/index.html deleted file mode 100644 index 92e653ee4..000000000 --- a/debugger/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - Xenia Debugger - - - - - - - - - - -
-
-
- -
- - - - - - - - - - - - - - - - - - - - - - diff --git a/debugger/src/app.js b/debugger/src/app.js deleted file mode 100644 index 9cd2f4d45..000000000 --- a/debugger/src/app.js +++ /dev/null @@ -1,125 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -'use strict'; - -var module = angular.module('app', [ - 'ui.bootstrap', - 'ui.router', - 'xe.datasources', - 'xe.directives', - 'xe.filters', - 'xe.log', - 'xe.router', - 'xe.session', - 'xe.ui.code', - 'xe.ui.code.functionView', - 'xe.ui.code.moduleInfo', - 'xe.ui.code.threadInfo', - 'xe.ui.console', - 'xe.ui.navbar' -]); - - -module.controller('AppController', function($scope, app) { - this.app = app; -}); - - -module.service('app', function( - $rootScope, $q, $state, log, Session) { - var App = function() { - this.loading = false; - this.session = null; - }; - - App.prototype.setSession = function(session) { - this.close(); - - this.session = session; - $rootScope.$emit('refresh'); - }; - - App.prototype.close = function() { - this.loading = false; - if (this.session) { - this.session.dispose(); - this.session = null; - } - }; - - App.prototype.open = function(sessionId) { - var d = $q.defer(); - - // Ignore if already open. - if (this.session && this.session.id == sessionId) { - d.resolve(this.session); - return d.promise; - } - - // Close existing. - this.close(); - - this.loading = true; - - log.info('Opening session ' + sessionId); - - // Open session. - var session = new Session(sessionId); - this.loading = false; - this.setSession(session); - d.resolve(session); - - return d.promise; - }; - - App.prototype.connect = function(opt_host) { - this.close(); - - var d = $q.defer(); - this.loading = true; - - Session.query(opt_host).then((function(infos) { - var info = infos[0]; - var id = info.titleId; - if (id == '00000000') { - id = info.name; - } - var session = new Session(id); - var p = session.connect(opt_host); - p.then((function(session) { - this.loading = false; - this.setSession(session); - d.resolve(session); - }).bind(this), (function(e) { - this.loading = false; - d.reject(e); - }).bind(this), function(update) { - d.notify(update); - }); - }).bind(this), (function(e) { - this.loading = false; - log.info('No sessions found at ' + Session.getHost(opt_host)); - d.reject(e); - }).bind(this)); - - return d.promise; - }; - - return new App(); -}); - - -module.run(function($rootScope, $state, $stateParams, app, log) { - $rootScope.$state = $state; - $rootScope.$stateParams = $stateParams; - - $rootScope.app = app; - $rootScope.log = log; -}); diff --git a/debugger/src/base.js b/debugger/src/base.js deleted file mode 100644 index 172e9ae64..000000000 --- a/debugger/src/base.js +++ /dev/null @@ -1,61 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -'use strict'; - - -function inherits(childCtor, parentCtor) { - function tempCtor() {}; - tempCtor.prototype = parentCtor.prototype; - childCtor.superClass_ = parentCtor.prototype; - childCtor.prototype = new tempCtor(); - childCtor.prototype.constructor = childCtor; -}; - -var EventEmitter = function() { - this.events_ = {}; -}; -EventEmitter.prototype.dispose = function() { - this.events_ = {}; -}; -EventEmitter.prototype.on = function(name, listener, opt_scope) { - var listeners = this.events_[name]; - if (!listeners) { - listeners = this.events_[name] = []; - } - listeners.push({ - callback: listener, - scope: opt_scope || null - }); -}; -EventEmitter.prototype.off = function(name, listener, opt_scope) { - var listeners = this.events_[name]; - if (!listeners) { - return; - } - for (var n = 0; n < listeners.length; n++) { - if (listeners[n].callback == listener) { - listeners.splice(n, 1); - if (!listeners.length) { - delete this.events_[name]; - } - return; - } - } -} -EventEmitter.prototype.emit = function(name, args) { - var listeners = this.events_[name]; - if (!listeners) { - return; - } - for (var n = 0; n < listeners.length; n++) { - var listener = listeners[n]; - listener.callback.apply(listener.scope, args); - } -}; diff --git a/debugger/src/datasources.js b/debugger/src/datasources.js deleted file mode 100644 index 62e3e66bc..000000000 --- a/debugger/src/datasources.js +++ /dev/null @@ -1,317 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -'use strict'; - -var module = angular.module('xe.datasources', []); - - -module.service('Breakpoint', function() { - // http://stackoverflow.com/a/2117523/377392 - var uuidFormat = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'; - function uuid4() { - return uuidFormat.replace(/[xy]/g, function(c) { - var r = Math.random()*16|0, v = c === 'x' ? r : (r&0x3|0x8); - return v.toString(16); - }); - }; - - var Breakpoint = function(opt_id) { - this.id = opt_id || uuid4(); - this.type = Breakpoint.Type.TEMP; - this.fnAddress = 0; - this.address = 0; - this.enabled = true; - }; - Breakpoint.Type = { - TEMP: 'temp', - CODE: 'code' - }; - Breakpoint.fromJSON = function(json) { - var breakpoint = new Breakpoint(json.id); - breakpoint.type = json.type; - breakpoint.fnAddress = json.fnAddress; - breakpoint.address = json.address; - breakpoint.enabled = json.enabled; - return breakpoint; - }; - Breakpoint.prototype.toJSON = function() { - return { - 'id': this.id, - 'type': this.type, - 'fnAddress': this.fnAddress, - 'address': this.address, - 'enabled': this.enabled - }; - }; - return Breakpoint; -}); - - -module.service('DataSource', function($q) { - var DataSource = function(source, delegate) { - EventEmitter.call(this); - this.source = source; - this.delegate = delegate; - this.online = false; - this.status = 'disconnected'; - }; - inherits(DataSource, EventEmitter); - DataSource.prototype.open = function() {}; - DataSource.prototype.dispose = function() {}; - DataSource.prototype.issue = function(command) {}; - - DataSource.prototype.makeReady = function() { - return this.issue({ - command: 'debug.make_ready' - }); - }; - - DataSource.prototype.getModuleList = function() { - return this.issue({ - command: 'cpu.get_module_list' - }); - }; - - DataSource.prototype.getModule = function(moduleName) { - return this.issue({ - command: 'cpu.get_module', - module: moduleName - }); - }; - - DataSource.prototype.getFunctionList = function(moduleName, opt_since) { - return this.issue({ - command: 'cpu.get_function_list', - module: moduleName, - since: opt_since || 0 - }); - }; - - DataSource.prototype.getFunction = function(address) { - return this.issue({ - command: 'cpu.get_function', - address: address - }); - }; - - DataSource.prototype.getThreadStates = function() { - return this.issue({ - command: 'cpu.get_thread_states' - }); - }; - - // set registers/etc? - - DataSource.prototype.addBreakpoint = function(breakpoint) { - return this.addBreakpoints([breakpoint]); - }; - - DataSource.prototype.addBreakpoints = function(breakpoints) { - if (!breakpoints.length) { - var d = $q.defer(); - d.resolve(); - return d.promise; - } - return this.issue({ - command: 'cpu.add_breakpoints', - breakpoints: breakpoints.map(function(breakpoint) { - return breakpoint.toJSON(); - }) - }); - }; - - DataSource.prototype.removeBreakpoint = function(breakpointId) { - return this.removeBreakpoints([breakpointId]); - }; - - DataSource.prototype.removeBreakpoints = function(breakpointIds) { - return this.issue({ - command: 'cpu.remove_breakpoints', - breakpointIds: breakpointIds - }); - }; - - DataSource.prototype.removeAllBreakpoints = function() { - return this.issue({ - command: 'cpu.remove_all_breakpoints' - }); - }; - - DataSource.prototype.continueExecution = function() { - return this.issue({ - command: 'cpu.continue' - }); - }; - - DataSource.prototype.breakExecution = function() { - return this.issue({ - command: 'cpu.break' - }); - }; - - DataSource.prototype.stepNext = function(threadId) { - return this.issue({ - command: 'cpu.step', - threadId: threadId - }); - }; - - return DataSource; -}); - -module.service('RemoteDataSource', function( - $rootScope, $q, log, DataSource) { - var RemoteDataSource = function(url, delegate) { - DataSource.call(this, url, delegate); - this.url = url; - this.socket = null; - this.nextRequestId_ = 1; - this.pendingRequests_ = {}; - }; - inherits(RemoteDataSource, DataSource); - - RemoteDataSource.prototype.open = function() { - var url = this.url; - - this.online = false; - this.status = 'connecting'; - - var d = $q.defer(); - - this.socket = new WebSocket(url, []); - this.socket.onopen = (function() { - $rootScope.$apply((function() { - // TODO(benvanik): handshake - - this.online = true; - this.status = 'connected'; - this.emit('online'); - d.resolve(); - }).bind(this)); - }).bind(this); - - this.socket.onclose = (function(e) { - $rootScope.$apply((function() { - this.online = false; - if (this.status == 'connecting') { - this.status = 'disconnected'; - d.reject(e.code + ' ' + e.reason); - } else { - this.status = 'disconnected'; - log.info('Disconnected'); - this.emit('offline'); - } - }).bind(this)); - }).bind(this); - - this.socket.onerror = (function(e) { - // ? - }).bind(this); - - this.socket.onmessage = (function(e) { - $rootScope.$apply((function() { - this.socketMessage(e); - }).bind(this)); - }).bind(this); - - return d.promise; - }; - - RemoteDataSource.prototype.socketMessage = function(e) { - console.log('message', e.data); - var json = JSON.parse(e.data); - if (json.requestId) { - // Response to a previous request. - var request = this.pendingRequests_[json.requestId]; - if (request) { - delete this.pendingRequests_[json.requestId]; - if (json.status) { - request.deferred.resolve(json.result); - } else { - request.deferred.reject(json.result); - } - } - } else { - // Notification. - switch (json.type) { - case 'breakpoint': - this.delegate.onBreakpointHit( - json.breakpointId, json.threadId); - break; - default: - log.error('Unknown notification type: ' + json.type); - break; - } - } - }; - - RemoteDataSource.prototype.dispose = function() { - this.pendingRequests_ = {}; - this.online = false; - this.status = 'disconnected'; - if (this.socket) { - this.socket.close(); - this.socket = null; - } - DataSource.prototype.dispose.call(this); - }; - - RemoteDataSource.prototype.issue = function(command) { - var d = $q.defer(); - command.requestId = this.nextRequestId_++; - this.socket.send(JSON.stringify(command)); - command.deferred = d; - this.pendingRequests_[command.requestId] = command; - return d.promise; - }; - - return RemoteDataSource; -}); - - -module.service('FileDataSource', function($q, DataSource) { - var FileDataSource = function(file, delegate) { - DataSource.call(this, file.name, delegate); - this.file = file; - }; - inherits(FileDataSource, DataSource); - - FileDataSource.prototype.open = function() { - this.status = 'connecting'; - - var d = $q.defer(); - - var self = this; - window.setTimeout(function() { - $scope.$apply((function() { - // TODO(benvanik): scan/load trace - - this.online = true; - this.status = 'connected'; - d.resolve(); - }).bind(self)); - }); - - return d.promise; - }; - - FileDataSource.prototype.dispose = function() { - this.online = false; - if (this.file) { - if (this.file.close) { - this.file.close(); - } - this.file = null; - } - DataSource.prototype.dispose.call(this); - }; - - return FileDataSource; -}); diff --git a/debugger/src/directives.js b/debugger/src/directives.js deleted file mode 100644 index 30925723e..000000000 --- a/debugger/src/directives.js +++ /dev/null @@ -1,89 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -'use strict'; - -var module = angular.module('xe.directives', [ - 'ui.router' -]); - - -module.directive('uiEnter', function() { - return function($scope, element, attrs) { - element.bind('keydown keypress', function(e) { - if(e.which === 13) { - $scope.$apply(function(){ - $scope.$eval(attrs.uiEnter); - }); - e.preventDefault(); - } - }); - }; -}); - -module.directive('uiEscape', function() { - return function($scope, element, attrs) { - element.bind('keydown keypress', function(e) { - if(e.which === 27) { - $scope.$apply(function(){ - $scope.$eval(attrs.uiEscape); - }); - e.preventDefault(); - } - }); - }; -}); - -module.directive('uiScrollDownOn', function() { - return { - priority: 1, - link: function($scope, element, attrs) { - $scope.$watch(attrs.uiScrollDownOn, function() { - element[0].scrollTop = element[0].scrollHeight; - }); - } - }; -}); - -module.directive('xeCoderef', function($state) { - return { - priority: 1, - link: function($scope, element, attrs) { - var target = attrs.xeCoderef; - var stateName = 'session.code.function'; - var stateParams = { - function: target, - a: null - }; - element.attr('href', $state.href(stateName, stateParams)); - element.bind('click', function(e) { - e.preventDefault(); - $state.go(stateName, stateParams); - }); - } - }; -}); - -module.directive('xeMemref', function($state) { - return { - priority: 1, - link: function($scope, element, attrs) { - var target = attrs.xeMemref; - var stateName = 'session.memory'; - var stateParams = { - a: target - }; - element.attr('href', $state.href(stateName, stateParams)); - element.bind('click', function(e) { - e.preventDefault(); - $state.go(stateName, stateParams); - }); - } - }; -}); diff --git a/debugger/src/filters.js b/debugger/src/filters.js deleted file mode 100644 index d76fb4637..000000000 --- a/debugger/src/filters.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -'use strict'; - -var module = angular.module('xe.filters', []); - - -module.filter('hex16', function() { - return function(number) { - if (number !== null && number !== undefined) { - var str = '' + number.toString(16).toUpperCase(); - while (str.length < 4) str = '0' + str; - return str; - } - }; -}); - -module.filter('hex32', function() { - return function(number) { - if (number !== null && number !== undefined) { - var str = '' + number.toString(16).toUpperCase(); - while (str.length < 8) str = '0' + str; - return str; - } - }; -}); - -module.filter('exp8', function() { - return function(number) { - if (number !== null && number !== undefined) { - var str = number.toExponential(8); - if (number >= 0) { - str = ' ' + str; - } - return str; - } - } -}); diff --git a/debugger/src/log.js b/debugger/src/log.js deleted file mode 100644 index 5768e849c..000000000 --- a/debugger/src/log.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -'use strict'; - -var module = angular.module('xe.log', []); - - -module.service('log', function($rootScope) { - var Log = function() { - this.lines = []; - - this.progressActive = false; - this.progress = 0; - }; - - Log.prototype.appendLine = function(line) { - this.lines.push(line); - }; - - Log.prototype.info = function(line) { - this.appendLine('I ' + line); - }; - - Log.prototype.error = function(line) { - this.appendLine('E ' + line); - }; - - Log.prototype.setProgress = function(value) { - this.progressActive = true; - this.progress = value; - }; - - Log.prototype.clearProgress = function() { - this.progressActive = false; - }; - - return new Log(); -}); diff --git a/debugger/src/router.js b/debugger/src/router.js deleted file mode 100644 index b1953e300..000000000 --- a/debugger/src/router.js +++ /dev/null @@ -1,146 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -'use strict'; - -var module = angular.module('xe.router', [ - 'ui.router', -]); - - -module.config(function($stateProvider, $urlRouterProvider) { - $urlRouterProvider.otherwise('/'); - - $stateProvider.state('/', { - template: 'empty' - }); - - $stateProvider.state('session', { - url: '/:sessionId', - templateUrl: 'assets/ui/session.html', - resolve: { - app: 'app', - session: function($stateParams, $state, $q, - Session, app) { - // If we are given a session we assume the user is trying to connect to - // it. Attempt that now. If we fail we redirect to home, otherwise we - // check whether it's the same game down below. - var d = $q.defer(); - if ($stateParams.sessionId) { - if (!app.session || - app.session.id != $stateParams.sessionId) { - Session.query().then(function(infos) { - var id = (infos[0].titleId == '00000000') ? - infos[0].name : infos[0].titleId; - if (!app.session || app.session.id == id) { - // Same session, continue. - var p = app.connect(); - p.then(function(session) { - d.resolve(session); - }, function(e) { - $state.go('session', { - 'sessionId': session.id - }, { - notify: true - }); - d.reject(e); - }) - } else { - // Different session. Create without connection. - var p = app.open(id); - p.then(function(session) { - d.resolve(session); - }, function(e) { - d.reject(e); - }); - } - }, function(e) { - var p = app.open($stateParams.sessionId); - p.then(function(session) { - d.resolve(session); - }, function(e) { - d.reject(e); - }); - }); - } else { - var p = app.open($stateParams.sessionId); - p.then(function(session) { - d.resolve(session); - }, function(e) { - d.reject(e); - }); - } - } else { - d.resolve(null); - } - return d.promise; - } - }, - controller: function($scope, $stateParams, $q, app, session) { - }, - onEnter: function() { - }, - onExit: function() {} - }); - - $stateProvider.state('session.code', { - url: '/code', - templateUrl: 'assets/ui/code/code-tab.html', - controller: function($stateParams) { - }, - onEnter: function() {}, - onExit: function() {} - }); - $stateProvider.state('session.code.function', { - url: '/:function?a', - templateUrl: 'assets/ui/code/function-view.html', - controller: function($scope, $stateParams) { - $scope.functionAddress = parseInt($stateParams.function, 16); - $scope.highlightAddress = parseInt($stateParams.a, 16); - }, - onEnter: function() {}, - onExit: function() {} - }); - - $stateProvider.state('session.memory', { - url: '/memory?a', - templateUrl: 'assets/ui/memory/memory-tab.html', - controller: function($stateParams) { - }, - onEnter: function() {}, - onExit: function() {} - }); - - $stateProvider.state('session.kernel', { - url: '/kernel', - templateUrl: 'assets/ui/kernel/kernel-tab.html', - controller: function($stateParams) { - }, - onEnter: function() {}, - onExit: function() {} - }); - - $stateProvider.state('session.gpu', { - url: '/gpu', - templateUrl: 'assets/ui/gpu/gpu-tab.html', - controller: function($stateParams) { - }, - onEnter: function() {}, - onExit: function() {} - }); - - $stateProvider.state('session.apu', { - url: '/apu', - templateUrl: 'assets/ui/apu/apu-tab.html', - controller: function($stateParams) { - }, - onEnter: function() {}, - onExit: function() {} - }); -}); diff --git a/debugger/src/session.js b/debugger/src/session.js deleted file mode 100644 index 7676035ef..000000000 --- a/debugger/src/session.js +++ /dev/null @@ -1,489 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -'use strict'; - -var module = angular.module('xe.session', []); - - -module.service('Session', function( - $rootScope, $q, $http, $state, log, - Breakpoint, FileDataSource, RemoteDataSource) { - var State = function(session) { - this.session = session; - this.clear(); - }; - State.prototype.clear = function() { - this.cache_ = { - moduleList: [], - modules: {}, - moduleFunctionLists: {}, - functions: {}, - threadStates: {}, - threadList: [] - }; - }; - State.prototype.sync = function() { - var cache = this.cache_; - var dataSource = this.session.dataSource; - if (!dataSource) { - var d = $q.defer(); - d.resolve(); - return d.promise; - } - var ps = []; - - // Update all modules/functions. - var modulesUpdated = $q.defer(); - ps.push(modulesUpdated.promise); - dataSource.getModuleList().then((function(list) { - cache.moduleList = list; - - // Update module information. - var moduleFetches = []; - list.forEach(function(module) { - if (cache.modules[module.name]) { - return; - } - var moduleFetch = $q.defer(); - moduleFetches.push(moduleFetch.promise); - dataSource.getModule(module.name). - then(function(moduleInfo) { - cache.modules[module.name] = moduleInfo; - moduleFetch.resolve(); - }, function(e) { - moduleFetch.reject(e); - }); - }); - - // Update function lists for each module. - list.forEach(function(module) { - var cached = cache.moduleFunctionLists[module.name]; - var functionListFetch = $q.defer(); - moduleFetches.push(functionListFetch); - dataSource.getFunctionList(module.name, cached ? cached.version : 0). - then(function(result) { - if (cached) { - cached.version = result.version; - for (var n = 0; n < result.list.length; n++) { - cached.list.push(result.list[n]); - } - } else { - cached = cache.moduleFunctionLists[module.name] = { - version: result.version, - list: result.list - }; - } - functionListFetch.resolve(); - }, function(e) { - functionListFetch.reject(e); - }); - }); - - $q.all(moduleFetches).then(function() { - modulesUpdated.resolve(); - }, function(e) { - modulesUpdated.reject(); - }); - }).bind(this), function(e) { - modulesUpdated.reject(e); - }); - - // Update threads/thread states. - var threadsUpdated = $q.defer(); - ps.push(threadsUpdated.promise); - dataSource.getThreadStates().then((function(states) { - cache.threadStates = states; - cache.threadList = []; - for (var threadId in states) { - cache.threadList.push(states[threadId]); - } - threadsUpdated.resolve(); - }).bind(this), function(e) { - threadsUpdated.reject(e); - }); - - var d = $q.defer(); - $q.all(ps).then((function() { - d.resolve(); - }).bind(this), (function(e) { - d.reject(e); - }).bind(this)); - return d.promise; - }; - State.prototype.getModuleList = function() { - return this.cache_.moduleList; - }; - State.prototype.getModule = function(moduleName) { - return this.cache_.modules[moduleName] || null; - }; - State.prototype.getFunctionList = function(moduleName) { - var cached = this.cache_.moduleFunctionLists[moduleName]; - return cached ? cached.list : []; - }; - State.prototype.getFunction = function(address) { - return this.cache_.functions[address] || null; - }; - State.prototype.fetchFunction = function(address) { - var cache = this.cache_; - var d = $q.defer(); - var cached = cache.functions[address]; - if (cached) { - d.resolve(cached); - return d.promise; - } - var dataSource = this.session.dataSource; - if (!dataSource) { - d.reject(new Error('Not online.')); - return d.promise; - } - dataSource.getFunction(address).then(function(result) { - cache.functions[address] = result; - d.resolve(result); - }, function(e) { - d.reject(e); - }); - return d.promise; - } - Object.defineProperty(State.prototype, 'threadList', { - get: function() { - return this.cache_.threadList || []; - } - }); - State.prototype.getThreadStates = function() { - return this.cache_.threadStates || {}; - }; - State.prototype.getThreadState = function(threadId) { - return this.cache_.threadStates[threadId] || null; - }; - - var Session = function(id, opt_dataSource) { - this.id = id; - - this.breakpoints = {}; - this.breakpointsById = {}; - - this.dataSource = opt_dataSource || null; - this.state = new State(this); - - this.activeThread = null; - - this.paused = false; - - this.loadState(); - }; - - Session.prototype.dispose = function() { - this.saveState(); - this.disconnect(); - }; - - Session.prototype.loadState = function() { - var raw = window.localStorage[this.id]; - if (!raw) { - return; - } - var json = JSON.parse(raw); - if (!json) { - return; - } - - var breakpointList = json.breakpoints; - this.breakpoints = {}; - for (var n = 0; n < breakpointList.length; n++) { - var breakpointJson = breakpointList[n]; - var breakpoint = Breakpoint.fromJSON(breakpointJson); - this.breakpoints[breakpointJson.address] = breakpoint; - this.breakpointsById[breakpoint.id] = breakpoint; - } - }; - - Session.prototype.saveState = function() { - var json = { - id: this.id, - breakpoints: [] - }; - for (var key in this.breakpointsById) { - var breakpoint = this.breakpointsById[key]; - if (breakpoint.type != Breakpoint.TEMP) { - json.breakpoints.push(breakpoint.toJSON()); - } - } - window.localStorage[this.id] = JSON.stringify(json); - }; - - Session.DEFAULT_HOST = '127.0.0.1:6200'; - - Session.getHost = function(opt_host) { - return opt_host || Session.DEFAULT_HOST; - }; - - Session.query = function(opt_host) { - var url = 'http://' + Session.getHost(opt_host); - var p = $http({ - method: 'GET', - url: url + '/sessions', - cache: false, - timeout: 500, - responseType: 'json' - }); - var d = $q.defer(); - p.then(function(response) { - if (!response.data || !response.data.length) { - d.reject(new Error('No session data')); - return; - } - d.resolve(response.data); - }, function(e) { - d.reject(e); - }); - return d.promise; - }; - - Session.prototype.connect = function(opt_host) { - this.disconnect(); - - var url = 'ws://' + Session.getHost(opt_host); - - log.info('Connecting to ' + url + '...'); - log.setProgress(0); - - var d = $q.defer(); - - var dataSource = new RemoteDataSource(url, this); - var p = dataSource.open(); - p.then((function() { - log.info('Connected!'); - log.clearProgress(); - this.setDataSource(dataSource).then((function() { - d.resolve(this); - }).bind(this), (function(e) { - d.reject(e); - }).bind(this)); - }).bind(this), (function(e) { - log.error('Unable to connect: ' + e); - log.clearProgress(); - d.reject(e); - }).bind(this), function(update) { - log.setProgress(update.progress); - d.notify(update); - }); - - return d.promise; - }; - - Session.prototype.disconnect = function() { - this.setDataSource(null); - }; - - Session.prototype.setDataSource = function(dataSource) { - var self = this; - - var d = $q.defer(); - if (this.dataSource) { - this.dataSource.dispose(); - this.dataSource = null; - } - $rootScope.$emit('refresh'); - if (!dataSource) { - d.resolve(); - return d.promise; - } - this.state.clear(); - this.activeThread = null; - - this.dataSource = dataSource; - this.dataSource.on('online', function() { - // - }, this); - this.dataSource.on('offline', function() { - this.setDataSource(null); - }, this); - - var ps = []; - - // Add breakpoints. - var breakpointList = []; - for (var key in this.breakpoints) { - var breakpoint = this.breakpoints[key]; - if (breakpoint.enabled) { - breakpointList.push(breakpoint); - } - } - ps.push(this.dataSource.addBreakpoints(breakpointList)); - - // Perform a full sync. - var syncDeferred = $q.defer(); - ps.push(syncDeferred.promise); - this.state.sync().then((function() { - // Put a breakpoint at the entry point. - // TODO(benvanik): make an option? - var moduleList = this.state.getModuleList(); - if (!moduleList.length) { - log.error('No modules found!'); - syncDeferred.reject(new Error('No modules found.')); - return; - } - var moduleInfo = this.state.getModule(moduleList[0].name); - if (!moduleInfo) { - log.error('Main module not found!'); - syncDeferred.reject(new Error('Main module not found.')); - return; - } - var entryPoint = moduleInfo.exeEntryPoint; - self.addTempBreakpoint(entryPoint, entryPoint); - - syncDeferred.resolve(); - }).bind(this), (function(e) { - syncDeferred.reject(e); - }).bind(this)); - - $q.all(ps).then((function() { - this.dataSource.makeReady().then(function() { - d.resolve(); - }, function(e) { - log.error('Error making target ready: ' + e); - d.reject(e); - }); - }).bind(this), (function(e) { - log.error('Errors preparing target: ' + e); - this.disconnect(); - d.reject(e); - }).bind(this)); - - return d.promise; - }; - - Session.prototype.addBreakpoint = function(breakpoint) { - this.breakpoints[breakpoint.address] = breakpoint; - this.breakpointsById[breakpoint.id] = breakpoint; - if (this.dataSource) { - this.dataSource.addBreakpoint(breakpoint); - } - this.saveState(); - return breakpoint; - }; - - Session.prototype.addTempBreakpoint = function(fnAddress, address) { - var breakpoint = new Breakpoint(); - breakpoint.type = Breakpoint.Type.TEMP; - breakpoint.fnAddress = fnAddress; - breakpoint.address = address; - breakpoint.enabled = true; - return this.addBreakpoint(breakpoint); - }; - - Session.prototype.addCodeBreakpoint = function(fnAddress, address) { - var breakpoint = new Breakpoint(); - breakpoint.type = Breakpoint.Type.CODE; - breakpoint.fnAddress = fnAddress; - breakpoint.address = address; - breakpoint.enabled = true; - return this.addBreakpoint(breakpoint); - }; - - Session.prototype.removeBreakpoint = function(breakpoint) { - delete this.breakpoints[breakpoint.address]; - delete this.breakpointsById[breakpoint.id]; - if (this.dataSource) { - this.dataSource.removeBreakpoint(breakpoint.id); - } - this.saveState(); - }; - - Session.prototype.toggleBreakpoint = function(breakpoint, enabled) { - var oldEnabled = enabled; - breakpoint.enabled = enabled; - if (this.dataSource) { - if (breakpoint.enabled) { - this.dataSource.addBreakpoint(breakpoint); - } else { - this.dataSource.removeBreakpoint(breakpoint.id); - } - } - this.saveState(); - }; - - Session.prototype.onBreakpointHit = function(breakpointId, threadId) { - // Now paused! - this.paused = true; - - this.state.sync().then((function() { - // Switch active thread. - var thread = this.state.getThreadState(threadId); - this.activeThread = thread; - - if (!breakpointId) { - // Just a general pause. - log.info('Execution paused.'); - return; - } - - var breakpoint = this.breakpointsById[breakpointId]; - if (!breakpoint) { - log.error('Breakpoint hit but not found.'); - return; - } - - // TODO(benvanik): stash current breakpoint/thread/etc. - - log.info('Breakpoint hit at 0x' + - breakpoint.address.toString(16).toUpperCase() + '.'); - - $state.go('session.code.function', { - sessionId: this.id, - function: breakpoint.fnAddress.toString(16).toUpperCase(), - a: breakpoint.address.toString(16).toUpperCase() - }, { - notify: true, - reloadOnSearch: false - }); - }).bind(this), (function(e) { - log.error('Unable to synchronize state,'); - }).bind(this)); - }; - - Session.prototype.continueExecution = function() { - if (!this.dataSource) { - return; - } - this.paused = false; - this.dataSource.continueExecution().then(function() { - log.info('Execution resumed.'); - }, function(e) { - log.error('Unable to continue: ' + e); - }); - }; - - Session.prototype.breakExecution = function() { - if (!this.dataSource) { - return; - } - this.paused = true; - this.dataSource.breakExecution().then(function() { - log.info('Execution paused.'); - $rootScope.$emit('refresh'); - }, function(e) { - log.error('Unable to break: ' + e); - }); - }; - - Session.prototype.stepNext = function(threadId) { - if (!this.dataSource) { - return; - } - this.paused = false; - this.dataSource.stepNext(threadId).then(function() { - }, function(e) { - log.error('Unable to step: ' + e); - }); - }; - - return Session; -}); diff --git a/src/xenia/cpu/processor.cc b/src/xenia/cpu/processor.cc index 969907d96..7aa67ccdf 100644 --- a/src/xenia/cpu/processor.cc +++ b/src/xenia/cpu/processor.cc @@ -9,9 +9,6 @@ #include -#include - -#include #include #include #include @@ -56,28 +53,11 @@ Processor::Processor(Emulator* emulator) : emulator_(emulator), export_resolver_(emulator->export_resolver()), runtime_(0), memory_(emulator->memory()), interrupt_thread_lock_(NULL), interrupt_thread_state_(NULL), - interrupt_thread_block_(0), - DebugTarget(emulator->debug_server()) { + interrupt_thread_block_(0) { InitializeIfNeeded(); - - debug_client_states_lock_ = xe_mutex_alloc(); - - emulator_->debug_server()->AddTarget("cpu", this); } Processor::~Processor() { - emulator_->debug_server()->RemoveTarget("cpu"); - - xe_mutex_lock(debug_client_states_lock_); - for (auto it = debug_client_states_.begin(); - it != debug_client_states_.end(); ++it) { - DebugClientState* client_state = it->second; - delete client_state; - } - debug_client_states_.clear(); - xe_mutex_unlock(debug_client_states_lock_); - xe_mutex_free(debug_client_states_lock_); - if (interrupt_thread_block_) { memory_->HeapFree(interrupt_thread_block_, 2048); delete interrupt_thread_state_; @@ -105,31 +85,6 @@ int Processor::Setup() { return result; } - // Setup debugger events. - auto debugger = runtime_->debugger(); - auto debug_server = emulator_->debug_server(); - debugger->breakpoint_hit.AddListener( - [debug_server](BreakpointHitEvent& e) { - const char* breakpoint_id = e.breakpoint()->id(); - if (!breakpoint_id) { - // This is not a breakpoint we know about. Ignore. - return; - } - - json_t* event_json = json_object(); - json_t* type_json = json_string("breakpoint"); - json_object_set_new(event_json, "type", type_json); - - json_t* thread_id_json = json_integer(e.thread_state()->thread_id()); - json_object_set_new(event_json, "threadId", thread_id_json); - json_t* breakpoint_id_json = json_string(breakpoint_id); - json_object_set_new(event_json, "breakpointId", breakpoint_id_json); - - debug_server->BroadcastEvent(event_json); - - json_decref(event_json); - }); - interrupt_thread_lock_ = xe_mutex_alloc(10000); interrupt_thread_state_ = new XenonThreadState( runtime_, 0, 16 * 1024, 0); @@ -199,640 +154,3 @@ uint64_t Processor::ExecuteInterrupt( xe_mutex_unlock(interrupt_thread_lock_); return result; } - -void Processor::OnDebugClientConnected(uint32_t client_id) { - DebugClientState* client_state = new DebugClientState(runtime_); - xe_mutex_lock(debug_client_states_lock_); - debug_client_states_[client_id] = client_state; - xe_mutex_unlock(debug_client_states_lock_); -} - -void Processor::OnDebugClientDisconnected(uint32_t client_id) { - DebugClientState* client_state = debug_client_states_[client_id]; - xe_mutex_lock(debug_client_states_lock_); - debug_client_states_.erase(client_id); - xe_mutex_unlock(debug_client_states_lock_); - delete client_state; - - // Whenever we support multiple clients we will need to respect pause - // settings. For now, resume until running. - runtime_->debugger()->ResumeAllThreads(true); -} - -json_t* json_object_set_string_new( - json_t* object, const char* key, const char* value) { - json_t* value_json = json_string(value); - json_object_set_new(object, key, value_json); - return value_json; -} - -json_t* json_object_set_string_format_new( - json_t* object, const char* key, const char* format, ...) { - char buffer[1024]; - va_list args; - va_start(args, format); - xevsnprintfa(buffer, XECOUNT(buffer), format, args); - va_end(args); - json_t* value_json = json_string(buffer); - json_object_set_new(object, key, value_json); - return value_json; -} - -json_t* json_object_set_integer_new( - json_t* object, const char* key, json_int_t value) { - json_t* value_json = json_integer(value); - json_object_set_new(object, key, value_json); - return value_json; -} - -json_t* Processor::OnDebugRequest( - uint32_t client_id, const char* command, json_t* request, - bool& succeeded) { - xe_mutex_lock(debug_client_states_lock_); - DebugClientState* client_state = debug_client_states_[client_id]; - xe_mutex_unlock(debug_client_states_lock_); - XEASSERTNOTNULL(client_state); - - succeeded = true; - if (xestrcmpa(command, "get_module_list") == 0) { - json_t* list = json_array(); - Runtime::ModuleList modules = runtime_->GetModules(); - for (auto it = modules.begin(); it != modules.end(); ++it) { - XexModule* module = (XexModule*)(*it); - json_t* module_json = json_object(); - json_object_set_string_new(module_json, "name", module->name()); - json_array_append_new(list, module_json); - } - return list; - } else if (xestrcmpa(command, "get_module") == 0) { - json_t* module_name_json = json_object_get(request, "module"); - if (!module_name_json || !json_is_string(module_name_json)) { - succeeded = false; - return json_string("Module name not specified"); - } - const char* module_name = json_string_value(module_name_json); - XexModule* module = (XexModule*)runtime_->GetModule(module_name); - if (!module) { - succeeded = false; - return json_string("Module not found"); - } - return DumpModule(module, succeeded); - } else if (xestrcmpa(command, "get_function_list") == 0) { - json_t* module_name_json = json_object_get(request, "module"); - if (!module_name_json || !json_is_string(module_name_json)) { - succeeded = false; - return json_string("Module name not specified"); - } - const char* module_name = json_string_value(module_name_json); - XexModule* module = (XexModule*)runtime_->GetModule(module_name); - if (!module) { - succeeded = false; - return json_string("Module not found"); - } - json_t* since_json = json_object_get(request, "since"); - if (since_json && !json_is_number(since_json)) { - succeeded = false; - return json_string("Version since is an invalid type"); - } - size_t since = since_json ? - (size_t)json_number_value(since_json) : 0; - json_t* list = json_array(); - size_t version = 0; - module->ForEachFunction(since, version, [&](FunctionInfo* info) { - json_t* fn_json = json_object(); - const char* name = info->name(); - char name_buffer[32]; - if (!name) { - xesnprintfa(name_buffer, XECOUNT(name_buffer), "sub_%.8X", - info->address()); - name = name_buffer; - } - json_object_set_string_new(fn_json, "name", name); - json_object_set_integer_new(fn_json, "address", info->address()); - json_object_set_integer_new(fn_json, "linkStatus", info->status()); - json_array_append_new(list, fn_json); - }); - json_t* result = json_object(); - json_object_set_integer_new(result, "version", version); - json_object_set_new(result, "list", list); - return result; - } else if (xestrcmpa(command, "get_function") == 0) { - json_t* address_json = json_object_get(request, "address"); - if (!address_json || !json_is_number(address_json)) { - succeeded = false; - return json_string("Function address not specified"); - } - uint64_t address = (uint64_t)json_number_value(address_json); - return DumpFunction(address, succeeded); - } else if (xestrcmpa(command, "get_thread_states") == 0) { - json_t* result = json_object(); - runtime_->debugger()->ForEachThread([&](ThreadState* thread_state) { - json_t* state_json = DumpThreadState((XenonThreadState*)thread_state); - char threadIdString[32]; - xesnprintfa( - threadIdString, XECOUNT(threadIdString), - "%d", thread_state->thread_id()); - json_object_set_new(result, threadIdString, state_json); - }); - return result; - } else if (xestrcmpa(command, "add_breakpoints") == 0) { - // breakpoints: [{}] - json_t* breakpoints_json = json_object_get(request, "breakpoints"); - if (!breakpoints_json || !json_is_array(breakpoints_json)) { - succeeded = false; - return json_string("Breakpoints not specified"); - } - if (!json_array_size(breakpoints_json)) { - // No-op; - return json_null(); - } - for (size_t n = 0; n < json_array_size(breakpoints_json); n++) { - json_t* breakpoint_json = json_array_get(breakpoints_json, n); - if (!breakpoint_json || !json_is_object(breakpoint_json)) { - succeeded = false; - return json_string("Invalid breakpoint type"); - } - - json_t* breakpoint_id_json = json_object_get(breakpoint_json, "id"); - json_t* type_json = json_object_get(breakpoint_json, "type"); - json_t* address_json = json_object_get(breakpoint_json, "address"); - if (!breakpoint_id_json || !json_is_string(breakpoint_id_json) || - !type_json || !json_is_string(type_json) || - !address_json || !json_is_number(address_json)) { - succeeded = false; - return json_string("Invalid breakpoint members"); - } - const char* breakpoint_id = json_string_value(breakpoint_id_json); - const char* type_str = json_string_value(type_json); - uint64_t address = (uint64_t)json_number_value(address_json); - Breakpoint::Type type; - if (xestrcmpa(type_str, "temp") == 0) { - type = Breakpoint::TEMP_TYPE; - } else if (xestrcmpa(type_str, "code") == 0) { - type = Breakpoint::CODE_TYPE; - } else { - succeeded = false; - return json_string("Unknown breakpoint type"); - } - - Breakpoint* breakpoint = new Breakpoint( - type, address); - breakpoint->set_id(breakpoint_id); - if (client_state->AddBreakpoint(breakpoint_id, breakpoint)) { - succeeded = false; - return json_string("Error adding breakpoint"); - } - } - return json_null(); - } else if (xestrcmpa(command, "remove_breakpoints") == 0) { - // breakpointIds: ['id'] - json_t* breakpoint_ids_json = json_object_get(request, "breakpointIds"); - if (!breakpoint_ids_json || !json_is_array(breakpoint_ids_json)) { - succeeded = false; - return json_string("Breakpoint IDs not specified"); - } - if (!json_array_size(breakpoint_ids_json)) { - // No-op; - return json_null(); - } - for (size_t n = 0; n < json_array_size(breakpoint_ids_json); n++) { - json_t* breakpoint_id_json = json_array_get(breakpoint_ids_json, n); - if (!breakpoint_id_json || !json_is_string(breakpoint_id_json)) { - succeeded = false; - return json_string("Invalid breakpoint ID type"); - } - const char* breakpoint_id = json_string_value(breakpoint_id_json); - if (client_state->RemoveBreakpoint(breakpoint_id)) { - succeeded = false; - return json_string("Unable to remove breakpoints"); - } - } - return json_null(); - } else if (xestrcmpa(command, "remove_all_breakpoints") == 0) { - if (client_state->RemoveAllBreakpoints()) { - succeeded = false; - return json_string("Unable to remove breakpoints"); - } - return json_null(); - } else if (xestrcmpa(command, "continue") == 0) { - if (runtime_->debugger()->ResumeAllThreads()) { - succeeded = false; - return json_string("Unable to resume threads"); - } - return json_null(); - } else if (xestrcmpa(command, "break") == 0) { - if (runtime_->debugger()->SuspendAllThreads()) { - succeeded = false; - return json_string("Unable to suspend threads"); - } - return json_null(); - } else if (xestrcmpa(command, "step") == 0) { - // threadId - return json_null(); - } else { - succeeded = false; - return json_string("Unknown command"); - } -} - -json_t* Processor::DumpModule(XexModule* module, bool& succeeded) { - auto xex = module->xex(); - auto header = xe_xex2_get_header(xex); - - auto export_resolver = runtime_->export_resolver(); - - json_t* module_json = json_object(); - - json_object_set_integer_new( - module_json, "moduleFlags", header->module_flags); - json_object_set_integer_new( - module_json, "systemFlags", header->system_flags); - json_object_set_integer_new( - module_json, "exeAddress", header->exe_address); - json_object_set_integer_new( - module_json, "exeEntryPoint", header->exe_entry_point); - json_object_set_integer_new( - module_json, "exeStackSize", header->exe_stack_size); - json_object_set_integer_new( - module_json, "exeHeapSize", header->exe_heap_size); - - json_t* exec_info_json = json_object(); - json_object_set_integer_new( - exec_info_json, "mediaId", header->execution_info.media_id); - json_object_set_string_format_new( - exec_info_json, "version", "%d.%d.%d.%d", - header->execution_info.version.major, - header->execution_info.version.minor, - header->execution_info.version.build, - header->execution_info.version.qfe); - json_object_set_string_format_new( - exec_info_json, "baseVersion", "%d.%d.%d.%d", - header->execution_info.base_version.major, - header->execution_info.base_version.minor, - header->execution_info.base_version.build, - header->execution_info.base_version.qfe); - json_object_set_integer_new( - exec_info_json, "titleId", header->execution_info.title_id); - json_object_set_integer_new( - exec_info_json, "platform", header->execution_info.platform); - json_object_set_integer_new( - exec_info_json, "executableTable", header->execution_info.executable_table); - json_object_set_integer_new( - exec_info_json, "discNumber", header->execution_info.disc_number); - json_object_set_integer_new( - exec_info_json, "discCount", header->execution_info.disc_count); - json_object_set_integer_new( - exec_info_json, "savegameId", header->execution_info.savegame_id); - json_object_set_new(module_json, "executionInfo", exec_info_json); - - json_t* loader_info_json = json_object(); - json_object_set_integer_new( - loader_info_json, "imageFlags", header->loader_info.image_flags); - json_object_set_integer_new( - loader_info_json, "gameRegions", header->loader_info.game_regions); - json_object_set_integer_new( - loader_info_json, "mediaFlags", header->loader_info.media_flags); - json_object_set_new(module_json, "loaderInfo", loader_info_json); - - json_t* tls_info_json = json_object(); - json_object_set_integer_new( - tls_info_json, "slotCount", header->tls_info.slot_count); - json_object_set_integer_new( - tls_info_json, "dataSize", header->tls_info.data_size); - json_object_set_integer_new( - tls_info_json, "rawDataAddress", header->tls_info.raw_data_address); - json_object_set_integer_new( - tls_info_json, "rawDataSize", header->tls_info.raw_data_size); - json_object_set_new(module_json, "tlsInfo", tls_info_json); - - json_t* headers_json = json_array(); - for (size_t n = 0; n < header->header_count; n++) { - auto opt_header = &header->headers[n]; - json_t* header_entry_json = json_object(); - json_object_set_integer_new( - header_entry_json, "key", opt_header->key); - json_object_set_integer_new( - header_entry_json, "length", opt_header->length); - json_object_set_integer_new( - header_entry_json, "value", opt_header->value); - json_array_append_new(headers_json, header_entry_json); - } - json_object_set_new(module_json, "headers", headers_json); - - json_t* resource_infos_json = json_array(); - for (size_t n = 0; n < header->resource_info_count; n++) { - auto& res = header->resource_infos[n]; - json_t* resource_info_json = json_object(); - json_object_set_string_new( - resource_info_json, "name", res.name); - json_object_set_integer_new( - resource_info_json, "address", res.address); - json_object_set_integer_new( - resource_info_json, "size", res.size); - json_array_append_new(resource_infos_json, resource_info_json); - } - json_object_set_new(module_json, "resourceInfos", resource_infos_json); - - json_t* sections_json = json_array(); - for (size_t n = 0, i = 0; n < header->section_count; n++) { - const xe_xex2_section_t* section = &header->sections[n]; - const char* type = "unknown"; - switch (section->info.type) { - case XEX_SECTION_CODE: - type = "code"; - break; - case XEX_SECTION_DATA: - type = "rwdata"; - break; - case XEX_SECTION_READONLY_DATA: - type = "rodata"; - break; - } - const size_t start_address = - header->exe_address + (i * xe_xex2_section_length); - const size_t end_address = - start_address + (section->info.page_count * xe_xex2_section_length); - json_t* section_entry_json = json_object(); - json_object_set_string_new( - section_entry_json, "type", type); - json_object_set_integer_new( - section_entry_json, "pageCount", section->info.page_count); - json_object_set_integer_new( - section_entry_json, "startAddress", start_address); - json_object_set_integer_new( - section_entry_json, "endAddress", end_address); - json_object_set_integer_new( - section_entry_json, "totalLength", - section->info.page_count * xe_xex2_section_length); - json_array_append_new(sections_json, section_entry_json); - i += section->info.page_count; - } - json_object_set_new(module_json, "sections", sections_json); - - json_t* static_libraries_json = json_array(); - for (size_t n = 0; n < header->static_library_count; n++) { - const xe_xex2_static_library_t *library = &header->static_libraries[n]; - json_t* static_library_entry_json = json_object(); - json_object_set_string_new( - static_library_entry_json, "name", library->name); - json_object_set_string_format_new( - static_library_entry_json, "version", "%d.%d.%d.%d", - library->major, library->minor, library->build, library->qfe); - json_array_append_new(static_libraries_json, static_library_entry_json); - } - json_object_set_new(module_json, "staticLibraries", static_libraries_json); - - json_t* library_imports_json = json_array(); - for (size_t n = 0; n < header->import_library_count; n++) { - const xe_xex2_import_library_t* library = &header->import_libraries[n]; - xe_xex2_import_info_t* import_infos; - size_t import_info_count; - if (xe_xex2_get_import_infos( - xex, library, &import_infos, &import_info_count)) { - continue; - } - - json_t* import_library_json = json_object(); - json_object_set_string_new( - import_library_json, "name", library->name); - json_object_set_string_format_new( - import_library_json, "version", "%d.%d.%d.%d", - library->version.major, library->version.minor, - library->version.build, library->version.qfe); - json_object_set_string_format_new( - import_library_json, "minVersion", "%d.%d.%d.%d", - library->min_version.major, library->min_version.minor, - library->min_version.build, library->min_version.qfe); - - json_t* imports_json = json_array(); - for (size_t m = 0; m < import_info_count; m++) { - auto info = &import_infos[m]; - auto kernel_export = export_resolver->GetExportByOrdinal( - library->name, info->ordinal); - json_t* import_json = json_object(); - if (kernel_export) { - json_object_set_string_new( - import_json, "name", kernel_export->name); - json_object_set_new( - import_json, "implemented", - kernel_export->is_implemented ? json_true() : json_false()); - } else { - json_object_set_new(import_json, "name", json_null()); - json_object_set_new(import_json, "implemented", json_false()); - } - json_object_set_integer_new( - import_json, "ordinal", info->ordinal); - json_object_set_integer_new( - import_json, "valueAddress", info->value_address); - if (kernel_export && kernel_export->type == KernelExport::Variable) { - json_object_set_string_new( - import_json, "type", "variable"); - } else if (kernel_export) { - json_object_set_string_new( - import_json, "type", "function"); - json_object_set_integer_new( - import_json, "thunkAddress", info->thunk_address); - } else { - json_object_set_string_new( - import_json, "type", "unknown"); - } - json_array_append_new(imports_json, import_json); - } - json_object_set_new(import_library_json, "imports", imports_json); - - json_array_append_new(library_imports_json, import_library_json); - } - json_object_set_new(module_json, "libraryImports", library_imports_json); - - // TODO(benvanik): exports? - - return module_json; -} - -json_t* Processor::DumpFunction(uint64_t address, bool& succeeded) { - FunctionInfo* info; - if (runtime_->LookupFunctionInfo(address, &info)) { - succeeded = false; - return json_string("Function not found"); - } - - // Demand a new function with all debug info retained. - // If we ever wanted absolute x64 addresses/etc we could - // use the x64 from the function in the symbol table. - Function* fn; - if (runtime_->frontend()->DefineFunction( - info, DEBUG_INFO_ALL_DISASM, &fn)) { - succeeded = false; - return json_string("Unable to resolve function"); - } - DebugInfo* debug_info = fn->debug_info(); - if (!debug_info) { - succeeded = false; - return json_string("No debug info present for function"); - } - - json_t* fn_json = json_object(); - const char* name = info->name(); - char name_buffer[32]; - if (!name) { - xesnprintfa(name_buffer, XECOUNT(name_buffer), "sub_%.8X", - info->address()); - name = name_buffer; - } - json_t* name_json = json_string(name); - json_object_set_new(fn_json, "name", name_json); - json_t* start_address_json = json_integer(info->address()); - json_object_set_new(fn_json, "startAddress", start_address_json); - json_t* end_address_json = json_integer(info->end_address()); - json_object_set_new(fn_json, "endAddress", end_address_json); - json_t* link_status_json = json_integer(info->status()); - json_object_set_new(fn_json, "linkStatus", link_status_json); - - json_t* disasm_json = json_object(); - json_t* disasm_str_json; - disasm_str_json = json_loads(debug_info->source_disasm(), 0, NULL); - json_object_set_new(disasm_json, "source", disasm_str_json); - disasm_str_json = json_string(debug_info->raw_hir_disasm()); - json_object_set_new(disasm_json, "rawHir", disasm_str_json); - disasm_str_json = json_string(debug_info->hir_disasm()); - json_object_set_new(disasm_json, "hir", disasm_str_json); - disasm_str_json = json_string(debug_info->machine_code_disasm()); - json_object_set_new(disasm_json, "machineCode", disasm_str_json); - json_object_set_new(fn_json, "disasm", disasm_json); - - delete fn; - - succeeded = true; - return fn_json; -} - -json_t* Processor::DumpThreadState(XenonThreadState* thread_state) { - json_t* result = json_object(); - - json_object_set_integer_new(result, "id", thread_state->thread_id()); - json_object_set_string_new(result, "name", thread_state->name()); - json_object_set_integer_new( - result, "stackAddress", thread_state->stack_address()); - json_object_set_integer_new( - result, "stackSize", thread_state->stack_size()); - json_object_set_integer_new( - result, "threadStateAddress", thread_state->thread_state_address()); - - char value[32]; - - json_t* context_json = json_object(); - auto context = thread_state->context(); - - json_object_set_new( - context_json, "pc", json_integer(0)); - json_object_set_new( - context_json, "lr", json_integer(context->lr)); - - json_object_set_new( - context_json, "ctr", json_integer(context->ctr)); - xesnprintfa(value, XECOUNT(value), "%.16llX", context->ctr); - json_object_set_new( - context_json, "ctrh", json_string(value)); - xesnprintfa(value, XECOUNT(value), "%lld", context->ctr); - json_object_set_new( - context_json, "ctrs", json_string(value)); - - // xer - // cr* - // fpscr - - json_t* r_json = json_array(); - for (size_t n = 0; n < 32; n++) { - json_array_append_new(r_json, json_integer(context->r[n])); - } - json_object_set_new(context_json, "r", r_json); - json_t* rh_json = json_array(); - for (size_t n = 0; n < 32; n++) { - xesnprintfa(value, XECOUNT(value), "%.16llX", context->r[n]); - json_array_append_new(rh_json, json_string(value)); - } - json_object_set_new(context_json, "rh", rh_json); - json_t* rs_json = json_array(); - for (size_t n = 0; n < 32; n++) { - xesnprintfa(value, XECOUNT(value), "%lld", context->r[n]); - json_array_append_new(rs_json, json_string(value)); - } - json_object_set_new(context_json, "rs", rs_json); - - json_t* f_json = json_array(); - for (size_t n = 0; n < 32; n++) { - json_array_append_new(f_json, json_real(context->f[n])); - } - json_object_set_new(context_json, "f", f_json); - json_t* fh_json = json_array(); - for (size_t n = 0; n < 32; n++) { - union { - double f; - uint64_t i; - } fi = { context->f[n] }; - xesnprintfa(value, XECOUNT(value), "%.16llX", fi.i); - json_array_append_new(fh_json, json_string(value)); - } - json_object_set_new(context_json, "fh", fh_json); - - json_t* v_json = json_array(); - for (size_t n = 0; n < 128; n++) { - auto& v = context->v[n]; - json_t* vec4_json = json_array(); - json_array_append_new(vec4_json, json_integer(v.ix)); - json_array_append_new(vec4_json, json_integer(v.iy)); - json_array_append_new(vec4_json, json_integer(v.iz)); - json_array_append_new(vec4_json, json_integer(v.iw)); - json_array_append_new(v_json, vec4_json); - } - json_object_set_new(context_json, "v", v_json); - - json_object_set_new(result, "context", context_json); - - // TODO(benvanik): callstack - - return result; -} - -Processor::DebugClientState::DebugClientState(XenonRuntime* runtime) : - runtime_(runtime) { - breakpoints_lock_ = xe_mutex_alloc(10000); -} - -Processor::DebugClientState::~DebugClientState() { - RemoveAllBreakpoints(); - xe_mutex_free(breakpoints_lock_); -} - -int Processor::DebugClientState::AddBreakpoint( - const char* breakpoint_id, Breakpoint* breakpoint) { - xe_mutex_lock(breakpoints_lock_); - breakpoints_[breakpoint_id] = breakpoint; - int result = runtime_->debugger()->AddBreakpoint(breakpoint); - xe_mutex_unlock(breakpoints_lock_); - return result; -} - -int Processor::DebugClientState::RemoveBreakpoint(const char* breakpoint_id) { - xe_mutex_lock(breakpoints_lock_); - Breakpoint* breakpoint = breakpoints_[breakpoint_id]; - if (breakpoint) { - breakpoints_.erase(breakpoint_id); - runtime_->debugger()->RemoveBreakpoint(breakpoint); - delete breakpoint; - } - xe_mutex_unlock(breakpoints_lock_); - return 0; -} - -int Processor::DebugClientState::RemoveAllBreakpoints() { - xe_mutex_lock(breakpoints_lock_); - for (auto it = breakpoints_.begin(); it != breakpoints_.end(); ++it) { - Breakpoint* breakpoint = it->second; - runtime_->debugger()->RemoveBreakpoint(breakpoint); - delete breakpoint; - } - breakpoints_.clear(); - xe_mutex_unlock(breakpoints_lock_); - return 0; -} diff --git a/src/xenia/cpu/processor.h b/src/xenia/cpu/processor.h index 3ad8217db..f13587ef5 100644 --- a/src/xenia/cpu/processor.h +++ b/src/xenia/cpu/processor.h @@ -11,7 +11,6 @@ #define XENIA_CPU_PROCESSOR_H_ #include -#include #include @@ -28,7 +27,7 @@ namespace xe { namespace cpu { -class Processor : public debug::DebugTarget { +class Processor { public: Processor(Emulator* emulator); ~Processor(); @@ -48,17 +47,6 @@ public: uint64_t ExecuteInterrupt( uint32_t cpu, uint64_t address, uint64_t args[], size_t arg_count); - virtual void OnDebugClientConnected(uint32_t client_id); - virtual void OnDebugClientDisconnected(uint32_t client_id); - virtual json_t* OnDebugRequest( - uint32_t client_id, const char* command, json_t* request, - bool& succeeded); - -private: - json_t* DumpModule(XexModule* module, bool& succeeded); - json_t* DumpFunction(uint64_t address, bool& succeeded); - json_t* DumpThreadState(XenonThreadState* thread_state); - private: Emulator* emulator_; ExportResolver* export_resolver_; @@ -69,27 +57,6 @@ private: xe_mutex_t* interrupt_thread_lock_; XenonThreadState* interrupt_thread_state_; uint64_t interrupt_thread_block_; - - class DebugClientState { - public: - DebugClientState(XenonRuntime* runtime); - ~DebugClientState(); - - int AddBreakpoint(const char* breakpoint_id, - alloy::runtime::Breakpoint* breakpoint); - int RemoveBreakpoint(const char* breakpoint_id); - int RemoveAllBreakpoints(); - - private: - XenonRuntime* runtime_; - - xe_mutex_t* breakpoints_lock_; - typedef std::unordered_map BreakpointMap; - BreakpointMap breakpoints_; - }; - xe_mutex_t* debug_client_states_lock_; - typedef std::unordered_map DebugClientStateMap; - DebugClientStateMap debug_client_states_; }; diff --git a/src/xenia/debug/debug_client.cc b/src/xenia/debug/debug_client.cc deleted file mode 100644 index 40d482664..000000000 --- a/src/xenia/debug/debug_client.cc +++ /dev/null @@ -1,39 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include - - -using namespace xe; -using namespace xe::debug; - - -uint32_t DebugClient::next_client_id_ = 1; - - -DebugClient::DebugClient(DebugServer* debug_server) : - debug_server_(debug_server), - readied_(false) { - client_id_ = next_client_id_++; - debug_server_->AddClient(this); -} - -DebugClient::~DebugClient() { - debug_server_->RemoveClient(this); -} - -void DebugClient::MakeReady() { - if (readied_) { - return; - } - debug_server_->ReadyClient(this); - readied_ = true; -} diff --git a/src/xenia/debug/debug_client.h b/src/xenia/debug/debug_client.h deleted file mode 100644 index ad263e129..000000000 --- a/src/xenia/debug/debug_client.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_DEBUG_DEBUG_CLIENT_H_ -#define XENIA_DEBUG_DEBUG_CLIENT_H_ - -#include -#include - - -XEDECLARECLASS2(xe, debug, DebugServer); - -struct json_t; - - -namespace xe { -namespace debug { - - -class DebugClient { -public: - DebugClient(DebugServer* debug_server); - virtual ~DebugClient(); - - uint32_t client_id() const { return client_id_; } - - virtual int Setup() = 0; - virtual void Close() = 0; - - virtual void SendEvent(json_t* event_json) = 0; - -protected: - void MakeReady(); - -protected: - static uint32_t next_client_id_; - - DebugServer* debug_server_; - uint32_t client_id_; - bool readied_; -}; - - -} // namespace debug -} // namespace xe - - -#endif // XENIA_DEBUG_DEBUG_CLIENT_H_ diff --git a/src/xenia/debug/debug_server.cc b/src/xenia/debug/debug_server.cc deleted file mode 100644 index 3a5e6d87c..000000000 --- a/src/xenia/debug/debug_server.cc +++ /dev/null @@ -1,186 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include - -#include -#include -#include -#include -#include -#include - - -using namespace xe; -using namespace xe::debug; - - -DEFINE_bool(wait_for_debugger, false, - "Whether to wait for the debugger to attach before launching."); - - -DebugServer::DebugServer(Emulator* emulator) : - emulator_(emulator), lock_(0) { - lock_ = xe_mutex_alloc(10000); - - client_event_ = CreateEvent(NULL, FALSE, FALSE, NULL); - - protocols_.push_back( - new protocols::gdb::GDBProtocol(this)); - protocols_.push_back( - new protocols::ws::WSProtocol(this)); -} - -DebugServer::~DebugServer() { - Shutdown(); - - CloseHandle(client_event_); - - xe_free(lock_); - lock_ = 0; -} - -bool DebugServer::has_clients() { - xe_mutex_lock(lock_); - bool has_clients = clients_.size() > 0; - xe_mutex_unlock(lock_); - return has_clients; -} - -int DebugServer::Startup() { - return 0; -} - -int DebugServer::BeforeEntry() { - // HACK(benvanik): say we are ok even if we have no listener. - if (!protocols_.size()) { - return 0; - } - - // Start listeners. - // This may launch threads and such. - for (std::vector::iterator it = protocols_.begin(); - it != protocols_.end(); ++it) { - Protocol* protocol = *it; - if (protocol->Setup()) { - return 1; - } - } - - // If desired, wait until the first client connects. - if (FLAGS_wait_for_debugger) { - XELOGI("Waiting for debugger..."); - if (WaitForClient()) { - return 1; - } - XELOGI("Debugger attached, continuing..."); - } - - return 0; -} - -void DebugServer::Shutdown() { - xe_mutex_lock(lock_); - - std::vector clients(clients_.begin(), clients_.end()); - clients_.clear(); - for (std::vector::iterator it = clients.begin(); - it != clients.end(); ++it) { - delete *it; - } - - std::vector protocols(protocols_.begin(), protocols_.end()); - protocols_.clear(); - for (std::vector::iterator it = protocols.begin(); - it != protocols.end(); ++it) { - delete *it; - } - - xe_mutex_unlock(lock_); -} - -void DebugServer::AddTarget(const char* name, DebugTarget* target) { - xe_mutex_lock(lock_); - targets_[name] = target; - xe_mutex_unlock(lock_); -} - -void DebugServer::RemoveTarget(const char* name) { - xe_mutex_lock(lock_); - targets_[name] = NULL; - xe_mutex_unlock(lock_); -} - -DebugTarget* DebugServer::GetTarget(const char* name) { - xe_mutex_lock(lock_); - DebugTarget* target = targets_[name]; - xe_mutex_unlock(lock_); - return target; -} - -void DebugServer::BroadcastEvent(json_t* event_json) { - // TODO(benvanik): avoid lock somehow? - xe_mutex_lock(lock_); - for (auto client : clients_) { - client->SendEvent(event_json); - } - xe_mutex_unlock(lock_); -} - -int DebugServer::WaitForClient() { - while (!has_clients()) { - WaitForSingleObject(client_event_, INFINITE); - } - return 0; -} - -void DebugServer::AddClient(DebugClient* debug_client) { - xe_mutex_lock(lock_); - - // Only one debugger at a time right now. Kill any old one. - while (clients_.size()) { - DebugClient* old_client = clients_.back(); - clients_.pop_back(); - old_client->Close(); - } - - clients_.push_back(debug_client); - - // Notify targets. - for (auto it = targets_.begin(); it != targets_.end(); ++it) { - it->second->OnDebugClientConnected(debug_client->client_id()); - } - - xe_mutex_unlock(lock_); -} - -void DebugServer::ReadyClient(DebugClient* debug_client) { - SetEvent(client_event_); -} - -void DebugServer::RemoveClient(DebugClient* debug_client) { - xe_mutex_lock(lock_); - - // Notify targets. - for (auto it = targets_.begin(); it != targets_.end(); ++it) { - it->second->OnDebugClientDisconnected(debug_client->client_id()); - } - - for (std::vector::iterator it = clients_.begin(); - it != clients_.end(); ++it) { - if (*it == debug_client) { - clients_.erase(it); - break; - } - } - - xe_mutex_unlock(lock_); -} diff --git a/src/xenia/debug/debug_server.h b/src/xenia/debug/debug_server.h deleted file mode 100644 index 3c140de0c..000000000 --- a/src/xenia/debug/debug_server.h +++ /dev/null @@ -1,75 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_DEBUG_DEBUG_SERVER_H_ -#define XENIA_DEBUG_DEBUG_SERVER_H_ - -#include -#include - -#include - - -XEDECLARECLASS1(xe, Emulator); -XEDECLARECLASS2(xe, debug, DebugClient); -XEDECLARECLASS2(xe, debug, DebugTarget); -XEDECLARECLASS2(xe, debug, Protocol); - -struct json_t; - - -namespace xe { -namespace debug { - - -class DebugServer { -public: - DebugServer(Emulator* emulator); - virtual ~DebugServer(); - - Emulator* emulator() const { return emulator_; } - - bool has_clients(); - - int Startup(); - int BeforeEntry(); - void Shutdown(); - - void AddTarget(const char* name, DebugTarget* target); - void RemoveTarget(const char* name); - DebugTarget* GetTarget(const char* name); - - void BroadcastEvent(json_t* event_json); - - int WaitForClient(); - -private: - void AddClient(DebugClient* debug_client); - void ReadyClient(DebugClient* debug_client); - void RemoveClient(DebugClient* debug_client); - - friend class DebugClient; - -private: - Emulator* emulator_; - std::vector protocols_; - - xe_mutex_t* lock_; - typedef std::unordered_map TargetMap; - TargetMap targets_; - std::vector clients_; - HANDLE client_event_; -}; - - -} // namespace debug -} // namespace xe - - -#endif // XENIA_DEBUG_DEBUG_SERVER_H_ diff --git a/src/xenia/debug/debug_target.h b/src/xenia/debug/debug_target.h deleted file mode 100644 index 7f202757f..000000000 --- a/src/xenia/debug/debug_target.h +++ /dev/null @@ -1,48 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_DEBUG_DEBUG_TARGET_H_ -#define XENIA_DEBUG_DEBUG_TARGET_H_ - -#include -#include -#include - - -struct json_t; - - -namespace xe { -namespace debug { - - -class DebugTarget { -public: - DebugTarget(DebugServer* debug_server) : - debug_server_(debug_server) {} - virtual ~DebugTarget() {} - - DebugServer* debug_server() const { return debug_server_; } - - virtual void OnDebugClientConnected(uint32_t client_id) {} - virtual void OnDebugClientDisconnected(uint32_t client_id) {} - virtual json_t* OnDebugRequest( - uint32_t client_id, const char* command, json_t* request, - bool& succeeded) = 0; - -protected: - DebugServer* debug_server_; -}; - - -} // namespace debug -} // namespace xe - - -#endif // XENIA_DEBUG_DEBUG_TARGET_H_ diff --git a/src/xenia/debug/protocol.cc b/src/xenia/debug/protocol.cc deleted file mode 100644 index 190e7b53a..000000000 --- a/src/xenia/debug/protocol.cc +++ /dev/null @@ -1,22 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - - -using namespace xe; -using namespace xe::debug; - - -Protocol::Protocol(DebugServer* debug_server) : - debug_server_(debug_server) { -} - -Protocol::~Protocol() { -} diff --git a/src/xenia/debug/protocol.h b/src/xenia/debug/protocol.h deleted file mode 100644 index 5a0524317..000000000 --- a/src/xenia/debug/protocol.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_DEBUG_PROTOCOL_H_ -#define XENIA_DEBUG_PROTOCOL_H_ - -#include -#include - - -XEDECLARECLASS2(xe, debug, DebugServer); - - -namespace xe { -namespace debug { - - -class Protocol { -public: - Protocol(DebugServer* debug_server); - virtual ~Protocol(); - - virtual int Setup() = 0; - -protected: - DebugServer* debug_server_; -}; - - -} // namespace debug -} // namespace xe - - -#endif // XENIA_DEBUG_PROTOCOL_H_ diff --git a/src/xenia/debug/protocols/gdb/gdb_client.cc b/src/xenia/debug/protocols/gdb/gdb_client.cc deleted file mode 100644 index 52cb1524a..000000000 --- a/src/xenia/debug/protocols/gdb/gdb_client.cc +++ /dev/null @@ -1,456 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include -#include - - -using namespace xe; -using namespace xe::debug; -using namespace xe::debug::protocols::gdb; - - -GDBClient::GDBClient(DebugServer* debug_server, socket_t socket_id) : - DebugClient(debug_server), - thread_(NULL), - socket_id_(socket_id), - current_reader_(0), send_queue_stalled_(false) { - mutex_ = xe_mutex_alloc(1000); - - loop_ = xe_socket_loop_create(socket_id); -} - -GDBClient::~GDBClient() { - xe_mutex_t* mutex = mutex_; - xe_mutex_lock(mutex); - - mutex_ = NULL; - - delete current_reader_; - for (auto it = message_reader_pool_.begin(); - it != message_reader_pool_.end(); ++it) { - delete *it; - } - for (auto it = message_writer_pool_.begin(); - it != message_writer_pool_.end(); ++it) { - delete *it; - } - for (auto it = send_queue_.begin(); it != send_queue_.end(); ++it) { - delete *it; - } - - xe_socket_close(socket_id_); - socket_id_ = 0; - - xe_socket_loop_destroy(loop_); - loop_ = NULL; - - xe_mutex_unlock(mutex); - xe_mutex_free(mutex); - - xe_thread_release(thread_); -} - -int GDBClient::Setup() { - // Prep the socket. - xe_socket_set_keepalive(socket_id_, true); - xe_socket_set_nodelay(socket_id_, true); - - thread_ = xe_thread_create("GDB Debugger Client", StartCallback, this); - return xe_thread_start(thread_); -} - -void GDBClient::Close() { - xe_socket_close(socket_id_); - socket_id_ = 0; -} - -void GDBClient::StartCallback(void* param) { - GDBClient* client = reinterpret_cast(param); - client->EventThread(); -} - -int GDBClient::PerformHandshake() { - return 0; -} - -void GDBClient::EventThread() { - // Enable non-blocking IO on the socket. - xe_socket_set_nonblock(socket_id_, true); - - // First run the HTTP handshake. - // This will fail if the connection is not for websockets. - if (PerformHandshake()) { - delete this; - return; - } - - MakeReady(); - - // Loop forever. - while (true) { - // Wait on the event. - if (xe_socket_loop_poll(loop_, true, send_queue_stalled_)) { - break; - } - - // Handle any self-generated events to queue messages. - xe_mutex_lock(mutex_); - for (auto it = pending_messages_.begin(); - it != pending_messages_.end(); it++) { - MessageWriter* message = *it; - send_queue_.push_back(message); - } - pending_messages_.clear(); - xe_mutex_unlock(mutex_); - - // Handle websocket messages. - if (xe_socket_loop_check_socket_recv(loop_) && CheckReceive()) { - // Error handling the event. - XELOGE("Error handling WebSocket data"); - break; - } - if (!send_queue_stalled_ || xe_socket_loop_check_socket_send(loop_)) { - if (PumpSendQueue()) { - // Error handling the event. - XELOGE("Error handling WebSocket data"); - break; - } - } - } -} - -int GDBClient::CheckReceive() { - uint8_t buffer[4096]; - while (true) { - int error_code = 0; - int64_t r = xe_socket_recv( - socket_id_, buffer, sizeof(buffer), 0, &error_code); - if (r == -1) { - if (error_code == EAGAIN || error_code == EWOULDBLOCK) { - return 0; - } else { - return 1; - } - } else if (r == 0) { - return 1; - } else { - // Append current reader until #. - int64_t pos = 0; - if (current_reader_) { - for (; pos < r; pos++) { - if (buffer[pos] == '#') { - pos++; - current_reader_->Append(buffer, pos); - MessageReader* message = current_reader_; - current_reader_ = NULL; - DispatchMessage(message); - break; - } - } - } - - // Loop reading all messages in the buffer. - for (; pos < r; pos++) { - if (buffer[pos] == '$') { - if (message_reader_pool_.size()) { - current_reader_ = message_reader_pool_.back(); - message_reader_pool_.pop_back(); - current_reader_->Reset(); - } else { - current_reader_ = new MessageReader(); - } - size_t start_pos = pos; - - // Scan until next #. - bool found_end = false; - for (; pos < r; pos++) { - if (buffer[pos] == '#') { - pos++; - current_reader_->Append(buffer + start_pos, pos - start_pos); - MessageReader* message = current_reader_; - current_reader_ = NULL; - DispatchMessage(message); - found_end = true; - break; - } - } - if (!found_end) { - // Ran out of bytes before message ended, keep around. - current_reader_->Append(buffer + start_pos, r - start_pos); - } - break; - } - } - } - } - - return 0; -} - -void GDBClient::DispatchMessage(MessageReader* message) { - // $[message]# - const char* str = message->GetString(); - str++; // skip $ - - printf("GDB: %s", str); - - bool handled = false; - switch (str[0]) { - case '!': - // Enable extended mode. - Send("OK"); - handled = true; - break; - case 'v': - // Verbose packets. - if (strstr(str, "vRun") == str) { - Send("S05"); - handled = true; - } else if (strstr(str, "vCont") == str) { - Send("S05"); - handled = true; - } - break; - case 'q': - // Query packets. - switch (str[1]) { - case 'C': - // Get current thread ID. - Send("QC01"); - handled = true; - break; - case 'R': - // Command. - Send("OK"); - handled = true; - break; - default: - if (strstr(str, "qfThreadInfo") == str) { - // Start of thread list request. - Send("m01"); - handled = true; - } else if (strstr(str, "qsThreadInfo") == str) { - // Continuation of thread list. - Send("l"); // l = last - handled = true; - } - break; - } - break; - -#if 0 - case 'H': - // Set current thread. - break; -#endif - - case 'g': - // Read all registers. - HandleReadRegisters(str + 1); - handled = true; - break; - case 'G': - // Write all registers. - HandleWriteRegisters(str + 1); - handled = true; - break; - case 'p': - // Read register. - HandleReadRegister(str + 1); - handled = true; - break; - case 'P': - // Write register. - HandleWriteRegister(str + 1); - handled = true; - break; - - case 'm': - // Read memory. - HandleReadMemory(str + 1); - handled = true; - case 'M': - // Write memory. - HandleWriteMemory(str + 1); - handled = true; - break; - - case 'Z': - // Insert breakpoint. - HandleAddBreakpoint(str + 1); - handled = true; - break; - case 'z': - // Remove breakpoint. - HandleRemoveBreakpoint(str + 1); - handled = true; - break; - - case '?': - // Query halt reason. - Send("S05"); - handled = true; - break; - case 'c': - // Continue. - // Deprecated: vCont should be used instead. - // NOTE: reply is sent on halt, not right now. - Send("S05"); - handled = true; - break; - case 's': - // Single step. - // NOTE: reply is sent on halt, not right now. - Send("S05"); - handled = true; - break; - } - - if (!handled) { - // Unknown packet type. We should ACK just to keep IDA happy. - XELOGW("Unknown GDB packet type: %c", str[0]); - Send(""); - } -} - -int GDBClient::PumpSendQueue() { - send_queue_stalled_ = false; - for (auto it = send_queue_.begin(); it != send_queue_.end(); it++) { - MessageWriter* message = *it; - int error_code = 0; - int64_t r; - const uint8_t* data = message->buffer() + message->offset(); - size_t bytes_remaining = message->length(); - while (bytes_remaining) { - r = xe_socket_send( - socket_id_, data, bytes_remaining, 0, &error_code); - if (r == -1) { - if (error_code == EAGAIN || error_code == EWOULDBLOCK) { - // Message did not finish sending. - send_queue_stalled_ = true; - return 0; - } else { - return 1; - } - } else { - bytes_remaining -= r; - data += r; - message->set_offset(message->offset() + r); - } - } - if (!bytes_remaining) { - xe_mutex_lock(mutex_); - message_writer_pool_.push_back(message); - xe_mutex_unlock(mutex_); - } - } - return 0; -} - -MessageWriter* GDBClient::BeginSend() { - MessageWriter* message = NULL; - xe_mutex_lock(mutex_); - if (message_writer_pool_.size()) { - message = message_writer_pool_.back(); - message_writer_pool_.pop_back(); - } - xe_mutex_unlock(mutex_); - if (message) { - message->Reset(); - } else { - message = new MessageWriter(); - } - return message; -} - -void GDBClient::EndSend(MessageWriter* message) { - message->Finalize(); - - xe_mutex_lock(mutex_); - pending_messages_.push_back(message); - bool needs_signal = pending_messages_.size() == 1; - xe_mutex_unlock(mutex_); - - if (needs_signal) { - // Notify the poll(). - xe_socket_loop_set_queued_write(loop_); - } -} - -void GDBClient::Send(const char* format, ...) { - auto message = BeginSend(); - va_list args; - va_start(args, format); - message->AppendVarargs(format, args); - va_end(args); - EndSend(message); -} - -void GDBClient::HandleReadRegisters(const char* str) { - auto message = BeginSend(); - for (int32_t n = 0; n < 32; n++) { - // gpr - message->Append("%08X", n); - } - for (int64_t n = 0; n < 32; n++) { - // fpr - message->Append("%016llX", n); - } - message->Append("%08X", 0x8202FB40); // pc - message->Append("%08X", 65); // msr - message->Append("%08X", 66); // cr - message->Append("%08X", 67); // lr - message->Append("%08X", 68); // ctr - message->Append("%08X", 69); // xer - message->Append("%08X", 70); // fpscr - EndSend(message); -} - -void GDBClient::HandleWriteRegisters(const char* str) { - Send("OK"); -} - -void GDBClient::HandleReadRegister(const char* str) { - // p...HH - // HH = hex digit indicating register # - auto message = BeginSend(); - message->Append("%.8X", 0x8202FB40); - EndSend(message); -} - -void GDBClient::HandleWriteRegister(const char* str) { - Send("OK"); -} - -void GDBClient::HandleReadMemory(const char* str) { - // m...ADDR,SIZE - uint32_t addr; - uint32_t size; - scanf("%X,%X", &addr, &size); - auto message = BeginSend(); - for (size_t n = 0; n < size; n++) { - message->Append("00"); - } - EndSend(message); -} - -void GDBClient::HandleWriteMemory(const char* str) { - Send("OK"); -} - -void GDBClient::HandleAddBreakpoint(const char* str) { - Send("OK"); -} - -void GDBClient::HandleRemoveBreakpoint(const char* str) { - Send("OK"); -} diff --git a/src/xenia/debug/protocols/gdb/gdb_client.h b/src/xenia/debug/protocols/gdb/gdb_client.h deleted file mode 100644 index 53570cb75..000000000 --- a/src/xenia/debug/protocols/gdb/gdb_client.h +++ /dev/null @@ -1,84 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_DEBUG_PROTOCOLS_GDB_GDB_CLIENT_H_ -#define XENIA_DEBUG_PROTOCOLS_GDB_GDB_CLIENT_H_ - -#include -#include - -#include - -#include - - -namespace xe { -namespace debug { -namespace protocols { -namespace gdb { - -class MessageReader; -class MessageWriter; - - -class GDBClient : public DebugClient { -public: - GDBClient(DebugServer* debug_server, socket_t socket_id); - virtual ~GDBClient(); - - socket_t socket_id() const { return socket_id_; } - - virtual int Setup(); - virtual void Close(); - - virtual void SendEvent(json_t* event_json) {} - -private: - static void StartCallback(void* param); - - int PerformHandshake(); - void EventThread(); - int CheckReceive(); - void DispatchMessage(MessageReader* message); - int PumpSendQueue(); - MessageWriter* BeginSend(); - void EndSend(MessageWriter* message); - void Send(const char* format, ...); - - void HandleReadRegisters(const char* str); - void HandleWriteRegisters(const char* str); - void HandleReadRegister(const char* str); - void HandleWriteRegister(const char* str); - void HandleReadMemory(const char* str); - void HandleWriteMemory(const char* str); - void HandleAddBreakpoint(const char* str); - void HandleRemoveBreakpoint(const char* str); - - xe_thread_ref thread_; - - socket_t socket_id_; - xe_socket_loop_t* loop_; - xe_mutex_t* mutex_; - std::vector message_reader_pool_; - std::vector message_writer_pool_; - std::vector pending_messages_; - - MessageReader* current_reader_; - std::vector send_queue_; - bool send_queue_stalled_; -}; - - -} // namespace gdb -} // namespace protocols -} // namespace debug -} // namespace xe - - -#endif // XENIA_DEBUG_PROTOCOLS_GDB_GDB_CLIENT_H_ diff --git a/src/xenia/debug/protocols/gdb/gdb_protocol.cc b/src/xenia/debug/protocols/gdb/gdb_protocol.cc deleted file mode 100644 index dbf227cc7..000000000 --- a/src/xenia/debug/protocols/gdb/gdb_protocol.cc +++ /dev/null @@ -1,105 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include - -#include - - -DEFINE_int32(gdb_debug_port, 6201, - "Remote debugging port for GDB TCP connections."); - - -using namespace xe; -using namespace xe::debug; -using namespace xe::debug::protocols::gdb; - - -GDBProtocol::GDBProtocol(DebugServer* debug_server) : - port_(0), socket_id_(0), thread_(0), running_(false), - Protocol(debug_server) { - port_ = FLAGS_gdb_debug_port; -} - -GDBProtocol::~GDBProtocol() { - if (thread_) { - // Join thread. - running_ = false; - xe_thread_release(thread_); - thread_ = 0; - } - if (socket_id_) { - xe_socket_close(socket_id_); - } -} - -int GDBProtocol::Setup() { - if (port_ == 0 || port_ == -1) { - return 0; - } - - xe_socket_init(); - - socket_id_ = xe_socket_create_tcp(); - if (socket_id_ == XE_INVALID_SOCKET) { - return 1; - } - - xe_socket_set_keepalive(socket_id_, true); - xe_socket_set_reuseaddr(socket_id_, true); - xe_socket_set_nodelay(socket_id_, true); - - if (xe_socket_bind(socket_id_, port_)) { - XELOGE("Could not bind listen socket: %d", errno); - return 1; - } - - if (xe_socket_listen(socket_id_)) { - xe_socket_close(socket_id_); - return 1; - } - - thread_ = xe_thread_create("GDB Debugger Listener", StartCallback, this); - running_ = true; - return xe_thread_start(thread_); - - return 0; -} - -void GDBProtocol::StartCallback(void* param) { - GDBProtocol* protocol = reinterpret_cast(param); - protocol->AcceptThread(); -} - -void GDBProtocol::AcceptThread() { - while (running_) { - if (!socket_id_) { - break; - } - - // Accept the first connection we get. - xe_socket_connection_t client_info; - if (xe_socket_accept(socket_id_, &client_info)) { - XELOGE("WS debugger failed to accept connection"); - break; - } - - XELOGI("WS debugger connected from %s", client_info.addr); - - // Create the client object. - // Note that the client will delete itself when done. - GDBClient* client = new GDBClient(debug_server_, client_info.socket); - if (client->Setup()) { - // Client failed to setup - abort. - continue; - } - } -} diff --git a/src/xenia/debug/protocols/gdb/gdb_protocol.h b/src/xenia/debug/protocols/gdb/gdb_protocol.h deleted file mode 100644 index 8152ba21c..000000000 --- a/src/xenia/debug/protocols/gdb/gdb_protocol.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_DEBUG_PROTOCOLS_GDB_GDB_PROTOCOL_H_ -#define XENIA_DEBUG_PROTOCOLS_GDB_GDB_PROTOCOL_H_ - -#include -#include - -#include - - -XEDECLARECLASS2(xe, debug, DebugServer); - - -namespace xe { -namespace debug { -namespace protocols { -namespace gdb { - - -class GDBProtocol : public Protocol { -public: - GDBProtocol(DebugServer* debug_server); - virtual ~GDBProtocol(); - - virtual int Setup(); - -private: - static void StartCallback(void* param); - void AcceptThread(); - -protected: - uint32_t port_; - - socket_t socket_id_; - - xe_thread_ref thread_; - bool running_; -}; - - -} // namespace gdb -} // namespace protocols -} // namespace debug -} // namespace xe - - -#endif // XENIA_DEBUG_PROTOCOLS_GDB_GDB_PROTOCOL_H_ diff --git a/src/xenia/debug/protocols/gdb/message.cc b/src/xenia/debug/protocols/gdb/message.cc deleted file mode 100644 index 22fcbc05d..000000000 --- a/src/xenia/debug/protocols/gdb/message.cc +++ /dev/null @@ -1,90 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - - -using namespace xe; -using namespace xe::debug; -using namespace xe::debug::protocols::gdb; - - -MessageReader::MessageReader() { - Reset(); -} - -MessageReader::~MessageReader() { -} - -void MessageReader::Reset() { - buffer_.Reset(); -} - -void MessageReader::Append(const uint8_t* buffer, size_t length) { - buffer_.AppendBytes(buffer, length); -} - -bool MessageReader::CheckComplete() { - // TODO(benvanik): verify checksum. - return true; -} - -const char* MessageReader::GetString() { - return buffer_.GetString(); -} - - -MessageWriter::MessageWriter() : - offset_(0) { - Reset(); -} - -MessageWriter::~MessageWriter() { -} - -const uint8_t* MessageWriter::buffer() const { - return (const uint8_t*)buffer_.GetString(); -} - -size_t MessageWriter::length() const { - return buffer_.length() + 1; -} - -void MessageWriter::Reset() { - buffer_.Reset(); - buffer_.Append("$"); - offset_ = 0; -} - -void MessageWriter::Append(const char* format, ...) { - va_list args; - va_start(args, format); - buffer_.AppendVarargs(format, args); - va_end(args); -} - -void MessageWriter::AppendVarargs(const char* format, va_list args) { - buffer_.AppendVarargs(format, args); -} - -void MessageWriter::Finalize() { - uint8_t checksum = 0; - const uint8_t* data = (const uint8_t*)buffer_.GetString(); - data++; // skip $ - while (true) { - uint8_t c = *data; - if (!c) { - break; - } - checksum += c; - data++; - } - - buffer_.Append("#%.2X", checksum); -} diff --git a/src/xenia/debug/protocols/gdb/message.h b/src/xenia/debug/protocols/gdb/message.h deleted file mode 100644 index fa6d21055..000000000 --- a/src/xenia/debug/protocols/gdb/message.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_DEBUG_PROTOCOLS_GDB_MESSAGE_H_ -#define XENIA_DEBUG_PROTOCOLS_GDB_MESSAGE_H_ - -#include -#include - -#include - - -namespace xe { -namespace debug { -namespace protocols { -namespace gdb { - - -class MessageReader { -public: - MessageReader(); - ~MessageReader(); - - void Reset(); - void Append(const uint8_t* buffer, size_t length); - bool CheckComplete(); - - const char* GetString(); - -private: - alloy::StringBuffer buffer_; -}; - - -class MessageWriter { -public: - MessageWriter(); - ~MessageWriter(); - - const uint8_t* buffer() const; - size_t length() const; - size_t offset() const { return offset_; } - void set_offset(size_t value) { offset_ = value; } - - void Reset(); - - void Append(const char* format, ...); - void AppendVarargs(const char* format, va_list args); - - void Finalize(); - -private: - alloy::StringBuffer buffer_; - size_t offset_; -}; - - -} // namespace gdb -} // namespace protocols -} // namespace debug -} // namespace xe - - -#endif // XENIA_DEBUG_PROTOCOLS_GDB_MESSAGE_H_ diff --git a/src/xenia/debug/protocols/gdb/sources.gypi b/src/xenia/debug/protocols/gdb/sources.gypi deleted file mode 100644 index 20e23c21b..000000000 --- a/src/xenia/debug/protocols/gdb/sources.gypi +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright 2013 Ben Vanik. All Rights Reserved. -{ - 'sources': [ - 'gdb_client.cc', - 'gdb_client.h', - 'gdb_protocol.cc', - 'gdb_protocol.h', - 'message.cc', - 'message.h', - ], -} diff --git a/src/xenia/debug/protocols/sources.gypi b/src/xenia/debug/protocols/sources.gypi deleted file mode 100644 index aa87c61fd..000000000 --- a/src/xenia/debug/protocols/sources.gypi +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright 2013 Ben Vanik. All Rights Reserved. -{ - 'includes': [ - 'gdb/sources.gypi', - 'ws/sources.gypi', - ], -} diff --git a/src/xenia/debug/protocols/ws/simple_sha1.cc b/src/xenia/debug/protocols/ws/simple_sha1.cc deleted file mode 100644 index 868f23a2c..000000000 --- a/src/xenia/debug/protocols/ws/simple_sha1.cc +++ /dev/null @@ -1,235 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#if XE_PLATFORM_WIN32 -#include -#else -#include -#endif // WIN32 - - -using namespace xe; -using namespace xe::debug::protocols::ws; - - -namespace { - - -// http://git.kernel.org/?p=git/git.git;a=blob;f=block-sha1/sha1.c - -/* - * SHA1 routine optimized to do word accesses rather than byte accesses, - * and to avoid unnecessary copies into the context array. - * - * This was initially based on the Mozilla SHA1 implementation, although - * none of the original Mozilla code remains. - */ - -typedef struct { - size_t size; - uint32_t H[5]; - uint32_t W[16]; -} SHA_CTX; - -#define SHA_ROT(X,l,r) (((X) << (l)) | ((X) >> (r))) -#define SHA_ROL(X,n) SHA_ROT(X,n,32-(n)) -#define SHA_ROR(X,n) SHA_ROT(X,32-(n),n) - -#define setW(x, val) (*(volatile unsigned int *)&W(x) = (val)) - -#define get_be32(p) ntohl(*(unsigned int *)(p)) -#define put_be32(p, v) do { *(unsigned int *)(p) = htonl(v); } while (0) - -#define W(x) (array[(x)&15]) - -#define SHA_SRC(t) get_be32((unsigned char *) block + (t)*4) -#define SHA_MIX(t) SHA_ROL(W((t)+13) ^ W((t)+8) ^ W((t)+2) ^ W(t), 1); - -#define SHA_ROUND(t, input, fn, constant, A, B, C, D, E) do { \ - unsigned int TEMP = input(t); setW(t, TEMP); \ - E += TEMP + SHA_ROL(A,5) + (fn) + (constant); \ - B = SHA_ROR(B, 2); } while (0) - -#define T_0_15(t, A, B, C, D, E) SHA_ROUND(t, SHA_SRC, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E ) -#define T_16_19(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E ) -#define T_20_39(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0x6ed9eba1, A, B, C, D, E ) -#define T_40_59(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, ((B&C)+(D&(B^C))) , 0x8f1bbcdc, A, B, C, D, E ) -#define T_60_79(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0xca62c1d6, A, B, C, D, E ) - -static void SHA1_Block(SHA_CTX *ctx, const void *block) { - uint32_t A = ctx->H[0]; - uint32_t B = ctx->H[1]; - uint32_t C = ctx->H[2]; - uint32_t D = ctx->H[3]; - uint32_t E = ctx->H[4]; - - uint32_t array[16]; - - /* Round 1 - iterations 0-16 take their input from 'block' */ - T_0_15( 0, A, B, C, D, E); - T_0_15( 1, E, A, B, C, D); - T_0_15( 2, D, E, A, B, C); - T_0_15( 3, C, D, E, A, B); - T_0_15( 4, B, C, D, E, A); - T_0_15( 5, A, B, C, D, E); - T_0_15( 6, E, A, B, C, D); - T_0_15( 7, D, E, A, B, C); - T_0_15( 8, C, D, E, A, B); - T_0_15( 9, B, C, D, E, A); - T_0_15(10, A, B, C, D, E); - T_0_15(11, E, A, B, C, D); - T_0_15(12, D, E, A, B, C); - T_0_15(13, C, D, E, A, B); - T_0_15(14, B, C, D, E, A); - T_0_15(15, A, B, C, D, E); - - /* Round 1 - tail. Input from 512-bit mixing array */ - T_16_19(16, E, A, B, C, D); - T_16_19(17, D, E, A, B, C); - T_16_19(18, C, D, E, A, B); - T_16_19(19, B, C, D, E, A); - - /* Round 2 */ - T_20_39(20, A, B, C, D, E); - T_20_39(21, E, A, B, C, D); - T_20_39(22, D, E, A, B, C); - T_20_39(23, C, D, E, A, B); - T_20_39(24, B, C, D, E, A); - T_20_39(25, A, B, C, D, E); - T_20_39(26, E, A, B, C, D); - T_20_39(27, D, E, A, B, C); - T_20_39(28, C, D, E, A, B); - T_20_39(29, B, C, D, E, A); - T_20_39(30, A, B, C, D, E); - T_20_39(31, E, A, B, C, D); - T_20_39(32, D, E, A, B, C); - T_20_39(33, C, D, E, A, B); - T_20_39(34, B, C, D, E, A); - T_20_39(35, A, B, C, D, E); - T_20_39(36, E, A, B, C, D); - T_20_39(37, D, E, A, B, C); - T_20_39(38, C, D, E, A, B); - T_20_39(39, B, C, D, E, A); - - /* Round 3 */ - T_40_59(40, A, B, C, D, E); - T_40_59(41, E, A, B, C, D); - T_40_59(42, D, E, A, B, C); - T_40_59(43, C, D, E, A, B); - T_40_59(44, B, C, D, E, A); - T_40_59(45, A, B, C, D, E); - T_40_59(46, E, A, B, C, D); - T_40_59(47, D, E, A, B, C); - T_40_59(48, C, D, E, A, B); - T_40_59(49, B, C, D, E, A); - T_40_59(50, A, B, C, D, E); - T_40_59(51, E, A, B, C, D); - T_40_59(52, D, E, A, B, C); - T_40_59(53, C, D, E, A, B); - T_40_59(54, B, C, D, E, A); - T_40_59(55, A, B, C, D, E); - T_40_59(56, E, A, B, C, D); - T_40_59(57, D, E, A, B, C); - T_40_59(58, C, D, E, A, B); - T_40_59(59, B, C, D, E, A); - - /* Round 4 */ - T_60_79(60, A, B, C, D, E); - T_60_79(61, E, A, B, C, D); - T_60_79(62, D, E, A, B, C); - T_60_79(63, C, D, E, A, B); - T_60_79(64, B, C, D, E, A); - T_60_79(65, A, B, C, D, E); - T_60_79(66, E, A, B, C, D); - T_60_79(67, D, E, A, B, C); - T_60_79(68, C, D, E, A, B); - T_60_79(69, B, C, D, E, A); - T_60_79(70, A, B, C, D, E); - T_60_79(71, E, A, B, C, D); - T_60_79(72, D, E, A, B, C); - T_60_79(73, C, D, E, A, B); - T_60_79(74, B, C, D, E, A); - T_60_79(75, A, B, C, D, E); - T_60_79(76, E, A, B, C, D); - T_60_79(77, D, E, A, B, C); - T_60_79(78, C, D, E, A, B); - T_60_79(79, B, C, D, E, A); - - ctx->H[0] += A; - ctx->H[1] += B; - ctx->H[2] += C; - ctx->H[3] += D; - ctx->H[4] += E; -} - -void SHA1_Update(SHA_CTX *ctx, const void *data, unsigned long len) -{ - uint32_t lenW = ctx->size & 63; - ctx->size += len; - - if (lenW) { - uint32_t left = 64 - lenW; - if (len < left) { - left = len; - } - memcpy(lenW + (char *)ctx->W, data, left); - lenW = (lenW + left) & 63; - len -= left; - data = ((const char *)data + left); - if (lenW) { - return; - } - SHA1_Block(ctx, ctx->W); - } - while (len >= 64) { - SHA1_Block(ctx, data); - data = ((const char *)data + 64); - len -= 64; - } - if (len) { - memcpy(ctx->W, data, len); - } -} - -} - - -void xe::debug::protocols::ws::SHA1( - const uint8_t* data, size_t length, uint8_t out_hash[20]) { - static const uint8_t pad[64] = { 0x80 }; - - SHA_CTX ctx = { - 0, - { - 0x67452301, - 0xefcdab89, - 0x98badcfe, - 0x10325476, - 0xc3d2e1f0, - }, - { 0 } - }; - - SHA1_Update(&ctx, data, (unsigned long)length); - - uint32_t padlen[2] = { - htonl((uint32_t)(ctx.size >> 29)), - htonl((uint32_t)(ctx.size << 3)), - }; - - size_t i = ctx.size & 63; - SHA1_Update(&ctx, pad, 1 + (63 & (55 - i))); - SHA1_Update(&ctx, padlen, 8); - - for (size_t n = 0; n < 5; n++) { - put_be32(out_hash + n * 4, ctx.H[n]); - } -} diff --git a/src/xenia/debug/protocols/ws/simple_sha1.h b/src/xenia/debug/protocols/ws/simple_sha1.h deleted file mode 100644 index 25379799e..000000000 --- a/src/xenia/debug/protocols/ws/simple_sha1.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license = see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_DEBUG_PROTOCOLS_WS_SIMPLE_SHA1_H_ -#define XENIA_DEBUG_PROTOCOLS_WS_SIMPLE_SHA1_H_ - -#include -#include - - -namespace xe { -namespace debug { -namespace protocols { -namespace ws { - - -// This is a (likely) slow SHA1 designed for use on small values such as -// Websocket security keys. If we need something more complex it'd be best -// to use a real library. -void SHA1(const uint8_t* data, size_t length, uint8_t out_hash[20]); - - -} // namespace ws -} // namespace protocols -} // namespace debug -} // namespace xe - - -#endif // XENIA_DEBUG_PROTOCOLS_WS_SIMPLE_SHA1_H_ diff --git a/src/xenia/debug/protocols/ws/sources.gypi b/src/xenia/debug/protocols/ws/sources.gypi deleted file mode 100644 index f3313acf2..000000000 --- a/src/xenia/debug/protocols/ws/sources.gypi +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright 2013 Ben Vanik. All Rights Reserved. -{ - 'sources': [ - 'simple_sha1.cc', - 'simple_sha1.h', - 'ws_client.cc', - 'ws_client.h', - 'ws_protocol.cc', - 'ws_protocol.h', - ], -} diff --git a/src/xenia/debug/protocols/ws/ws_client.cc b/src/xenia/debug/protocols/ws/ws_client.cc deleted file mode 100644 index 64f7fe7d3..000000000 --- a/src/xenia/debug/protocols/ws/ws_client.cc +++ /dev/null @@ -1,531 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#if XE_PLATFORM_WIN32 -// Required for wslay. -typedef SSIZE_T ssize_t; -#endif // WIN32 -#include - - -using namespace std; -using namespace xe; -using namespace xe::debug; -using namespace xe::debug::protocols::ws; -using namespace xe::kernel; - - -WSClient::WSClient(DebugServer* debug_server, socket_t socket_id) : - thread_(NULL), - socket_id_(socket_id), - DebugClient(debug_server) { - mutex_ = xe_mutex_alloc(1000); - - loop_ = xe_socket_loop_create(socket_id); -} - -WSClient::~WSClient() { - xe_mutex_t* mutex = mutex_; - xe_mutex_lock(mutex); - - mutex_ = NULL; - - xe_socket_close(socket_id_); - socket_id_ = 0; - - xe_socket_loop_destroy(loop_); - loop_ = NULL; - - xe_mutex_unlock(mutex); - xe_mutex_free(mutex); - - xe_thread_release(thread_); -} - -int WSClient::Setup() { - // Prep the socket. - xe_socket_set_keepalive(socket_id_, true); - xe_socket_set_nodelay(socket_id_, true); - - thread_ = xe_thread_create("WS Debugger Client", StartCallback, this); - return xe_thread_start(thread_); -} - -void WSClient::Close() { - xe_socket_close(socket_id_); - socket_id_ = 0; -} - -void WSClient::StartCallback(void* param) { - WSClient* client = reinterpret_cast(param); - client->EventThread(); -} - -namespace { - -int64_t WSClientSendCallback(wslay_event_context_ptr ctx, - const uint8_t* data, size_t len, int flags, - void* user_data) { - WSClient* client = reinterpret_cast(user_data); - - int error_code = 0; - int64_t r; - while ((r = xe_socket_send(client->socket_id(), data, len, 0, - &error_code)) == -1 && error_code == EINTR); - if (r == -1) { - if (error_code == EAGAIN || error_code == EWOULDBLOCK) { - wslay_event_set_error(ctx, WSLAY_ERR_WOULDBLOCK); - } else { - wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE); - } - } - return r; -} - -int64_t WSClientRecvCallback(wslay_event_context_ptr ctx, - uint8_t* data, size_t len, int flags, - void* user_data) { - WSClient* client = reinterpret_cast(user_data); - - int error_code = 0; - int64_t r; - while ((r = xe_socket_recv(client->socket_id(), data, len, 0, - &error_code)) == -1 && error_code == EINTR); - if (r == -1) { - if (error_code == EAGAIN || error_code == EWOULDBLOCK) { - wslay_event_set_error(ctx, WSLAY_ERR_WOULDBLOCK); - } else { - wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE); - } - } else if (r == 0) { - wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE); - r = -1; - } - return r; -} - -void WSClientOnMsgCallback(wslay_event_context_ptr ctx, - const struct wslay_event_on_msg_recv_arg* arg, - void* user_data) { - if (wslay_is_ctrl_frame(arg->opcode)) { - // Ignore control frames. - return; - } - - WSClient* client = reinterpret_cast(user_data); - switch (arg->opcode) { - case WSLAY_TEXT_FRAME: - client->OnMessage(arg->msg, arg->msg_length); - break; - case WSLAY_BINARY_FRAME: - // Ignored. - break; - default: - // Unknown opcode - some frame stuff? - break; - } -} - -std::string EncodeBase64(const uint8_t* input, size_t length) { - static const char b64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - std::string result; - size_t remaining = length; - size_t n = 0; - while (remaining) { - result.push_back(b64[input[n] >> 2]); - result.push_back(b64[((input[n] & 0x03) << 4) | - ((input[n + 1] & 0xf0) >> 4)]); - remaining--; - if (remaining) { - result.push_back(b64[((input[n + 1] & 0x0f) << 2) | - ((input[n + 2] & 0xc0) >> 6)]); - remaining--; - } else { - result.push_back('='); - } - if (remaining) { - result.push_back(b64[input[n + 2] & 0x3f]); - remaining--; - } else { - result.push_back('='); - } - n += 3; - } - return result; -} - -} - -int WSClient::PerformHandshake() { - std::string headers; - uint8_t buffer[4096]; - int error_code = 0; - int64_t r; - while (true) { - while ((r = xe_socket_recv(socket_id_, buffer, sizeof(buffer), 0, - &error_code)) == -1 && error_code == EINTR); - if (r == -1) { - if (error_code == EWOULDBLOCK || error_code == EAGAIN) { - if (!headers.size()) { - // Nothing read yet - spin. - continue; - } - break; - } else { - XELOGE("HTTP header read failure"); - return 1; - } - } else if (r == 0) { - // EOF. - XELOGE("HTTP header EOF"); - return 2; - } else { - headers.append(buffer, buffer + r); - if (headers.size() > 8192) { - XELOGE("HTTP headers exceeded max buffer size"); - return 3; - } - } - } - - if (headers.find("\r\n\r\n") == std::string::npos) { - XELOGE("Incomplete HTTP headers: %s", headers.c_str()); - return 1; - } - - // If this is a get for the session list, just produce that and return. - // We could stub out better handling here, if we wanted. - if (headers.find("GET /sessions") != std::string::npos) { - Emulator* emulator = debug_server_->emulator(); - KernelState* kernel_state = emulator->xboxkrnl()->kernel_state(); - XUserModule* module = kernel_state->GetExecutableModule(); - const xe_xex2_header_t* header = module->xex_header(); - char title_id[9]; - xesnprintfa(title_id, XECOUNT(title_id), "%.8X", - header->execution_info.title_id); - - ostringstream response_body; - if (module) { - response_body << "[{"; - response_body << - "\"name\": \"" << module->name() << "\","; - response_body << - "\"titleId\": \"" << title_id << "\""; - response_body << "}]"; - } else { - response_body << - "[]"; - } - size_t content_length = response_body.str().length(); - ostringstream response; - response << - "HTTP/1.0 200 OK\r\n" - "Content-Type: application/json\r\n" - "Connection: close\r\n" - "Access-Control-Allow-Origin: *\r\n" - "Content-Length: " << content_length << "\r\n" - "\r\n"; - response << response_body.str(); - error_code = WriteResponse(response.str()); - if (error_code) { - return error_code; - } - - // Eh, we just kill the connection here. - return 1; - } - - // Parse the headers to verify its a websocket request. - std::string::size_type keyhdstart; - if (headers.find("Upgrade: websocket\r\n") == std::string::npos || - headers.find("Connection: Upgrade\r\n") == std::string::npos || - (keyhdstart = headers.find("Sec-WebSocket-Key: ")) == - std::string::npos) { - XELOGW("HTTP connection does not contain websocket headers"); - return 2; - } - keyhdstart += 19; - std::string::size_type keyhdend = headers.find("\r\n", keyhdstart); - std::string client_key = headers.substr(keyhdstart, keyhdend - keyhdstart); - std::string accept_key = client_key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; - uint8_t accept_sha[20]; - SHA1((uint8_t*)accept_key.c_str(), accept_key.size(), accept_sha); - accept_key = EncodeBase64(accept_sha, sizeof(accept_sha)); - - // Write the response to upgrade the connection. - std::string response = - "HTTP/1.1 101 Switching Protocols\r\n" - "Upgrade: websocket\r\n" - "Connection: Upgrade\r\n" - "Sec-WebSocket-Accept: " + accept_key + "\r\n" - "\r\n"; - return WriteResponse(response); -} - -int WSClient::WriteResponse(std::string& response) { - int error_code = 0; - int64_t r; - size_t write_offset = 0; - size_t write_length = response.size(); - while (true) { - while ((r = xe_socket_send(socket_id_, - (uint8_t*)response.c_str() + write_offset, - write_length, 0, &error_code)) == -1 && - error_code == EINTR); - if (r == -1) { - if (error_code == EAGAIN || error_code == EWOULDBLOCK) { - break; - } else { - XELOGE("HTTP response write failure"); - return 4; - } - } else { - write_offset += r; - write_length -= r; - if (!write_length) { - break; - } - } - } - return 0; -} - -void WSClient::EventThread() { - // Enable non-blocking IO on the socket. - xe_socket_set_nonblock(socket_id_, true); - - // First run the HTTP handshake. - // This will fail if the connection is not for websockets. - if (PerformHandshake()) { - delete this; - return; - } - - // Prep callbacks. - struct wslay_event_callbacks callbacks = { - (wslay_event_recv_callback)WSClientRecvCallback, - (wslay_event_send_callback)WSClientSendCallback, - NULL, - NULL, - NULL, - NULL, - WSClientOnMsgCallback, - }; - - // Prep the websocket server context. - wslay_event_context_ptr ctx; - wslay_event_context_server_init(&ctx, &callbacks, this); - - // Loop forever. - while (wslay_event_want_read(ctx) || wslay_event_want_write(ctx)) { - // Wait on the event. - if (xe_socket_loop_poll(loop_, - !!wslay_event_want_read(ctx), - !!wslay_event_want_write(ctx))) { - break; - } - - // Handle any self-generated events to queue messages. - if (xe_socket_loop_check_queued_write(loop_)) { - xe_mutex_lock(mutex_); - for (std::vector::iterator it = - pending_messages_.begin(); it != pending_messages_.end(); it++) { - struct wslay_event_msg* msg = &*it; - wslay_event_queue_msg(ctx, msg); - } - pending_messages_.clear(); - xe_mutex_unlock(mutex_); - } - - // Handle websocket messages. - if ((xe_socket_loop_check_socket_recv(loop_) && wslay_event_recv(ctx)) || - (xe_socket_loop_check_socket_send(loop_) && wslay_event_send(ctx))) { - // Error handling the event. - XELOGE("Error handling WebSocket data"); - break; - } - } - - wslay_event_context_free(ctx); - delete this; -} - -void WSClient::SendEvent(json_t* event_json) { - char* str = json_dumps(event_json, 0); - Write(str); -} - -void WSClient::Write(char* value) { - const uint8_t* buffers[] = { - (uint8_t*)value, - }; - size_t lengths[] = { - sizeof(char) * xestrlena(value), - }; - Write(buffers, lengths, XECOUNT(buffers), false); -} - -void WSClient::Write(const uint8_t** buffers, size_t* lengths, size_t count, - bool binary) { - if (!count) { - return; - } - - size_t combined_length; - uint8_t* combined_buffer; - if (count == 1) { - // Single buffer, just copy. - combined_length = lengths[0]; - combined_buffer = (uint8_t*)xe_malloc(lengths[0]); - XEIGNORE(xe_copy_memory(combined_buffer, combined_length, - buffers[0], lengths[0])); - } else { - // Multiple buffers, merge. - combined_length = 0; - for (size_t n = 0; n < count; n++) { - combined_length += lengths[n]; - } - combined_buffer = (uint8_t*)xe_malloc(combined_length); - for (size_t n = 0, offset = 0; n < count; n++) { - XEIGNORE(xe_copy_memory( - combined_buffer + offset, combined_length - offset, - buffers[n], lengths[n])); - offset += lengths[n]; - } - } - - struct wslay_event_msg msg = { - binary ? WSLAY_BINARY_FRAME : WSLAY_TEXT_FRAME, - combined_buffer, - combined_length, - }; - - xe_mutex_lock(mutex_); - pending_messages_.push_back(msg); - bool needs_signal = pending_messages_.size() == 1; - xe_mutex_unlock(mutex_); - - if (needs_signal) { - // Notify the poll(). - xe_socket_loop_set_queued_write(loop_); - } -} - -void WSClient::OnMessage(const uint8_t* data, size_t length) { - const char* s = (const char*)data; - - json_error_t error; - json_t* request = json_loadb( - (const char*)data, length, JSON_DECODE_INT_AS_REAL, &error); - if (!request) { - // Failed to parse. - XELOGE("Failed to parse JSON request: %d:%d %s %s", - error.line, error.column, - error.source, error.text); - return; - } - if (!json_is_object(request)) { - XELOGE("Expected JSON object"); - json_decref(request); - return; - } - - json_t* request_id_json = json_object_get(request, "requestId"); - if (!request_id_json || !json_is_number(request_id_json)) { - XELOGE("Need requestId field"); - json_decref(request); - return; - } - json_t* command_json = json_object_get(request, "command"); - if (!command_json || !json_is_string(command_json)) { - XELOGE("Need command field"); - json_decref(request); - return; - } - - // Handle command. - bool succeeded = false; - const char* command = json_string_value(command_json); - json_t* result_json = HandleMessage(command, request, succeeded); - if (!result_json) { - result_json = json_null(); - } - - // Prepare response. - json_t* response = json_object(); - json_object_set(response, "requestId", request_id_json); - json_t* status_json = succeeded ? json_true() : json_false(); - json_object_set_new(response, "status", status_json); - json_object_set_new(response, "result", result_json); - - // Encode response to string and send back. - // String freed by Write. - char* response_string = json_dumps(response, JSON_INDENT(2)); - Write(response_string); - - json_decref(request); - json_decref(response); -} - -json_t* WSClient::HandleMessage(const char* command, json_t* request, - bool& succeeded) { - succeeded = false; - - // Get target. - char target_name[16] = { 0 }; - const char* dot = xestrchra(command, '.'); - if (!dot) { - return json_string("No debug target specified."); - } - if (dot - command > XECOUNT(target_name)) { - return NULL; - } - xestrncpya(target_name, XECOUNT(target_name), - command, dot - command); - const char* sub_command = command + (dot - command + 1); - - // Check debugger meta commands. - if (xestrcmpa(target_name, "debug") == 0) { - succeeded = true; - if (xestrcmpa(sub_command, "ping") == 0) { - return json_true(); - } else if (xestrcmpa(sub_command, "make_ready") == 0) { - MakeReady(); - return json_true(); - } else { - succeeded = false; - return json_string("Unknown command"); - } - } - - // Lookup target. - DebugTarget* target = debug_server_->GetTarget(target_name); - if (!target) { - return json_string("Unknown debug target prefix."); - } - - // Dispatch. - return target->OnDebugRequest( - client_id(), sub_command, request, succeeded); -} diff --git a/src/xenia/debug/protocols/ws/ws_client.h b/src/xenia/debug/protocols/ws/ws_client.h deleted file mode 100644 index 32d265032..000000000 --- a/src/xenia/debug/protocols/ws/ws_client.h +++ /dev/null @@ -1,72 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_DEBUG_PROTOCOLS_WS_WS_CLIENT_H_ -#define XENIA_DEBUG_PROTOCOLS_WS_WS_CLIENT_H_ - -#include -#include - -#include - -#include - - -struct wslay_event_msg; -struct json_t; - - -namespace xe { -namespace debug { -namespace protocols { -namespace ws { - - -class WSClient : public DebugClient { -public: - WSClient(DebugServer* debug_server, socket_t socket_id); - virtual ~WSClient(); - - socket_t socket_id() const { return socket_id_; } - - virtual int Setup(); - virtual void Close(); - - virtual void SendEvent(json_t* event_json); - - void Write(char* value); - void Write(const uint8_t** buffers, size_t* lengths, size_t count, - bool binary = true); - - void OnMessage(const uint8_t* data, size_t length); - json_t* HandleMessage(const char* command, json_t* request, bool& succeeded); - -private: - static void StartCallback(void* param); - - int PerformHandshake(); - int WriteResponse(std::string& response); - void EventThread(); - - xe_thread_ref thread_; - - socket_t socket_id_; - xe_socket_loop_t* loop_; - xe_mutex_t* mutex_; - std::vector pending_messages_; -}; - - -} // namespace ws -} // namespace protocols -} // namespace debug -} // namespace xe - - -#endif // XENIA_DEBUG_PROTOCOLS_WS_WS_CLIENT_H_ diff --git a/src/xenia/debug/protocols/ws/ws_protocol.cc b/src/xenia/debug/protocols/ws/ws_protocol.cc deleted file mode 100644 index 668eb5c8c..000000000 --- a/src/xenia/debug/protocols/ws/ws_protocol.cc +++ /dev/null @@ -1,104 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include -#include - -#include - - -using namespace xe; -using namespace xe::debug; -using namespace xe::debug::protocols::ws; - - -DEFINE_int32(ws_debug_port, 6200, - "Remote debugging port for ws:// connections."); - - -WSProtocol::WSProtocol(DebugServer* debug_server) : - port_(0), socket_id_(0), thread_(0), running_(false), - Protocol(debug_server) { - port_ = FLAGS_ws_debug_port; -} - -WSProtocol::~WSProtocol() { - if (thread_) { - // Join thread. - running_ = false; - xe_thread_release(thread_); - thread_ = 0; - } - if (socket_id_) { - xe_socket_close(socket_id_); - } -} - -int WSProtocol::Setup() { - if (port_ == 0 || port_ == -1) { - return 0; - } - - xe_socket_init(); - - socket_id_ = xe_socket_create_tcp(); - if (socket_id_ == XE_INVALID_SOCKET) { - return 1; - } - - xe_socket_set_keepalive(socket_id_, true); - xe_socket_set_reuseaddr(socket_id_, true); - xe_socket_set_nodelay(socket_id_, true); - - if (xe_socket_bind(socket_id_, port_)) { - XELOGE("Could not bind listen socket: %d", errno); - return 1; - } - - if (xe_socket_listen(socket_id_)) { - xe_socket_close(socket_id_); - return 1; - } - - thread_ = xe_thread_create("WS Debugger Listener", StartCallback, this); - running_ = true; - return xe_thread_start(thread_); -} - -void WSProtocol::StartCallback(void* param) { - WSProtocol* protocol = reinterpret_cast(param); - protocol->AcceptThread(); -} - -void WSProtocol::AcceptThread() { - while (running_) { - if (!socket_id_) { - break; - } - - // Accept the first connection we get. - xe_socket_connection_t client_info; - if (xe_socket_accept(socket_id_, &client_info)) { - XELOGE("WS debugger failed to accept connection"); - break; - } - - XELOGI("WS debugger connected from %s", client_info.addr); - - // Create the client object. - // Note that the client will delete itself when done. - WSClient* client = new WSClient(debug_server_, client_info.socket); - if (client->Setup()) { - // Client failed to setup - abort. - continue; - } - } -} diff --git a/src/xenia/debug/protocols/ws/ws_protocol.h b/src/xenia/debug/protocols/ws/ws_protocol.h deleted file mode 100644 index b5cce87be..000000000 --- a/src/xenia/debug/protocols/ws/ws_protocol.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_DEBUG_PROTOCOLS_WS_WS_PROTOCOL_H_ -#define XENIA_DEBUG_PROTOCOLS_WS_WS_PROTOCOL_H_ - -#include -#include - -#include - - -XEDECLARECLASS2(xe, debug, DebugServer); - - -namespace xe { -namespace debug { -namespace protocols { -namespace ws { - - -class WSProtocol : public Protocol { -public: - WSProtocol(DebugServer* debug_server); - virtual ~WSProtocol(); - - virtual int Setup(); - -private: - static void StartCallback(void* param); - void AcceptThread(); - -protected: - uint32_t port_; - - socket_t socket_id_; - - xe_thread_ref thread_; - bool running_; -}; - - -} // namespace ws -} // namespace protocols -} // namespace debug -} // namespace xe - - -#endif // XENIA_DEBUG_PROTOCOLS_WS_WS_PROTOCOL_H_ diff --git a/src/xenia/debug/sources.gypi b/src/xenia/debug/sources.gypi deleted file mode 100644 index af6968004..000000000 --- a/src/xenia/debug/sources.gypi +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright 2013 Ben Vanik. All Rights Reserved. -{ - 'sources': [ - 'debug_client.cc', - 'debug_client.h', - 'debug_server.cc', - 'debug_server.h', - 'debug_target.h', - 'protocol.cc', - 'protocol.h', - ], - - 'includes': [ - 'protocols/sources.gypi', - ], -} diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index bb7f302ae..deb33c9c3 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -25,7 +24,6 @@ using namespace xe; using namespace xe::apu; using namespace xe::cpu; -using namespace xe::debug; using namespace xe::gpu; using namespace xe::hid; using namespace xe::kernel; @@ -36,7 +34,6 @@ using namespace xe::ui; Emulator::Emulator(const xechar_t* command_line) : main_window_(0), memory_(0), - debug_server_(0), processor_(0), audio_system_(0), graphics_system_(0), input_system_(0), export_resolver_(0), file_system_(0), @@ -51,11 +48,6 @@ Emulator::~Emulator() { main_window_->Close(); } - // Disconnect all debug clients first. - if (debug_server_) { - debug_server_->Shutdown(); - } - delete xam_; delete xboxkrnl_; delete kernel_state_; @@ -72,8 +64,6 @@ Emulator::~Emulator() { delete processor_; - delete debug_server_; - delete export_resolver_; } @@ -90,10 +80,6 @@ X_STATUS Emulator::Setup() { export_resolver_ = new ExportResolver(); XEEXPECTNOTNULL(export_resolver_); - // Create the debugger. - debug_server_ = new DebugServer(this); - XEEXPECTNOTNULL(debug_server_); - // Initialize the CPU. processor_ = new Processor(this); XEEXPECTNOTNULL(processor_); @@ -134,11 +120,6 @@ X_STATUS Emulator::Setup() { xam_ = new XamModule(this, kernel_state_); XEEXPECTNOTNULL(xam_); - // Prepare the debugger. - // This may pause waiting for connections. - result = debug_server_->Startup(); - XEEXPECTZERO(result); - return result; XECLEANUP: diff --git a/src/xenia/kernel/xboxkrnl_module.cc b/src/xenia/kernel/xboxkrnl_module.cc index 12ecd85ae..ae0612ff0 100644 --- a/src/xenia/kernel/xboxkrnl_module.cc +++ b/src/xenia/kernel/xboxkrnl_module.cc @@ -13,7 +13,6 @@ #include #include -#include #include #include #include @@ -164,12 +163,6 @@ int XboxkrnlModule::LaunchModule(const char* path) { return 0; } - // Spin up the debugger and let it know we are starting. - if (emulator_->debug_server()->BeforeEntry()) { - XELOGE("Debugger failed to startup."); - return 2; - } - // Launch the module. // NOTE: this won't return until the module exits. result_code = module->Launch(0); diff --git a/src/xenia/sources.gypi b/src/xenia/sources.gypi index 0d20898e0..9de67ac78 100644 --- a/src/xenia/sources.gypi +++ b/src/xenia/sources.gypi @@ -31,7 +31,6 @@ 'apu/sources.gypi', 'core/sources.gypi', 'cpu/sources.gypi', - 'debug/sources.gypi', 'gpu/sources.gypi', 'hid/sources.gypi', 'kernel/sources.gypi', diff --git a/src/xenia/xenia.h b/src/xenia/xenia.h index 9b18233d9..ebb04559d 100644 --- a/src/xenia/xenia.h +++ b/src/xenia/xenia.h @@ -17,7 +17,6 @@ #include #include -#include #include #include diff --git a/third_party/jansson b/third_party/jansson deleted file mode 160000 index 4e8c4bfbd..000000000 --- a/third_party/jansson +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4e8c4bfbd209e50cc7b13993bbd56adb9282c465 diff --git a/third_party/jansson.gypi b/third_party/jansson.gypi deleted file mode 100644 index 17559564d..000000000 --- a/third_party/jansson.gypi +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright 2013 Ben Vanik. All Rights Reserved. -{ - 'targets': [ - { - 'target_name': 'jansson', - 'type': '<(library)', - - 'direct_dependent_settings': { - 'include_dirs': [ - 'jansson/win32/', - 'jansson/src/', - ], - - 'defines': [ - ], - }, - - 'msvs_disabled_warnings': [4267], - - 'defines': [ - ], - - 'conditions': [ - ['OS != "win"', { - 'defines': [ - ], - }], - ['OS == "win"', { - 'defines': [ - ], - }], - ], - - 'include_dirs': [ - 'jansson/win32/', - 'jansson/src/', - ], - - 'sources': [ - 'jansson/win32/jansson_config.h', - 'jansson/src/dump.c', - 'jansson/src/error.c', - 'jansson/src/hashtable.c', - 'jansson/src/hashtable.h', - 'jansson/src/jansson.h', - 'jansson/src/jansson_private.h', - 'jansson/src/load.c', - 'jansson/src/memory.c', - 'jansson/src/pack_unpack.c', - 'jansson/src/strbuffer.c', - 'jansson/src/strbuffer.h', - 'jansson/src/strconv.c', - 'jansson/src/utf.c', - 'jansson/src/utf.h', - 'jansson/src/value.c', - ], - } - ] -} diff --git a/third_party/wslay b/third_party/wslay deleted file mode 160000 index b3571f1ed..000000000 --- a/third_party/wslay +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b3571f1ed27093e910ab8675d0c8333e5a2818ea diff --git a/third_party/wslay.gypi b/third_party/wslay.gypi deleted file mode 100644 index de99a01f1..000000000 --- a/third_party/wslay.gypi +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright 2013 Ben Vanik. All Rights Reserved. -{ - 'targets': [ - { - 'target_name': 'wslay', - 'type': '<(library)', - - 'direct_dependent_settings': { - 'include_dirs': [ - 'wslay/lib/includes/', - ], - - 'defines': [ - 'WSLAY_VERSION=1', - ], - - # libraries: ws2_32 on windows - }, - - 'defines': [ - 'WSLAY_VERSION="1"', - ], - - 'conditions': [ - ['OS != "win"', { - 'defines': [ - 'HAVE_ARPA_INET_H=1', - 'HAVE_NETINET_IN_H=1', - ], - }], - ['OS == "win"', { - 'defines': [ - 'HAVE_WINSOCK2_H=1', - 'ssize_t=long long', - ], - }], - ], - - 'include_dirs': [ - 'wslay/lib/', - 'wslay/lib/includes/', - ], - - 'sources': [ - 'wslay/lib/includes/wslay/wslay.h', - 'wslay/lib/wslay_event.c', - 'wslay/lib/wslay_event.h', - 'wslay/lib/wslay_frame.c', - 'wslay/lib/wslay_frame.h', - 'wslay/lib/wslay_net.c', - 'wslay/lib/wslay_net.h', - 'wslay/lib/wslay_queue.c', - 'wslay/lib/wslay_queue.h', - 'wslay/lib/wslay_stack.c', - 'wslay/lib/wslay_stack.h', - ], - } - ] -} diff --git a/xenia.gyp b/xenia.gyp index 8933eb750..28dfca299 100644 --- a/xenia.gyp +++ b/xenia.gyp @@ -4,10 +4,8 @@ 'tools/tools.gypi', 'third_party/beaengine.gypi', 'third_party/gflags.gypi', - 'third_party/jansson.gypi', 'third_party/llvm.gypi', 'third_party/sparsehash.gypi', - 'third_party/wslay.gypi', ], 'default_configuration': 'release', @@ -285,14 +283,10 @@ 'dependencies': [ 'gflags', - 'jansson', - 'wslay', 'alloy', ], 'export_dependent_settings': [ 'gflags', - 'jansson', - 'wslay', 'alloy', ], From f61c21506b73273846c8312ce57d4f8b3928ed34 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 9 Jul 2014 21:24:30 -0700 Subject: [PATCH 008/388] part 1: removing gyp (to switch repos). --- .gitmodules | 3 --- third_party/gyp | 1 - 2 files changed, 4 deletions(-) delete mode 160000 third_party/gyp diff --git a/.gitmodules b/.gitmodules index 2a1898d63..1a9c6bc89 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "third_party/ninja"] path = third_party/ninja url = https://github.com/martine/ninja.git -[submodule "third_party/gyp"] - path = third_party/gyp - url = https://github.com/benvanik/gyp.git [submodule "third_party/gflags"] path = third_party/gflags url = https://github.com/benvanik/gflags.git diff --git a/third_party/gyp b/third_party/gyp deleted file mode 160000 index 96c481840..000000000 --- a/third_party/gyp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 96c481840d532630a2828132a6e8f16a01504a53 From 0c3583f0e45a6a881da56c6d69c99e1510bcecf2 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 9 Jul 2014 21:33:14 -0700 Subject: [PATCH 009/388] part 2: latest gyp pointed at official git repo. --- .gitmodules | 3 +++ third_party/gyp | 1 + third_party/gyp.patch | 26 ++++++++++++++++++++++++++ 3 files changed, 30 insertions(+) create mode 160000 third_party/gyp create mode 100644 third_party/gyp.patch diff --git a/.gitmodules b/.gitmodules index 1a9c6bc89..439bccb76 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "third_party/xbyak"] path = third_party/xbyak url = https://github.com/herumi/xbyak.git +[submodule "third_party/gyp"] + path = third_party/gyp + url = https://chromium.googlesource.com/external/gyp diff --git a/third_party/gyp b/third_party/gyp new file mode 160000 index 000000000..867a23f4b --- /dev/null +++ b/third_party/gyp @@ -0,0 +1 @@ +Subproject commit 867a23f4b596b7406cce1231a23b44b47bc1a583 diff --git a/third_party/gyp.patch b/third_party/gyp.patch new file mode 100644 index 000000000..5f10b609c --- /dev/null +++ b/third_party/gyp.patch @@ -0,0 +1,26 @@ +diff --git a/pylib/gyp/generator/msvs.py b/pylib/gyp/generator/msvs.py +index 05783d6..539614c 100644 +--- a/pylib/gyp/generator/msvs.py ++++ b/pylib/gyp/generator/msvs.py +@@ -1963,13 +1963,17 @@ def _AppendFiltersForMSBuild(parent_filter_name, sources, + if isinstance(source, MSVSProject.Filter): + # We have a sub-filter. Create the name of that sub-filter. + if not parent_filter_name: +- filter_name = source.name ++ if source.name == '..': ++ filter_name = '' ++ else: ++ filter_name = source.name + else: + filter_name = '%s\\%s' % (parent_filter_name, source.name) + # Add the filter to the group. +- filter_group.append( +- ['Filter', {'Include': filter_name}, +- ['UniqueIdentifier', MSVSNew.MakeGuid(source.name)]]) ++ if filter_name: ++ filter_group.append( ++ ['Filter', {'Include': filter_name}, ++ ['UniqueIdentifier', MSVSNew.MakeGuid(source.name)]]) + # Recurse and add its dependents. + _AppendFiltersForMSBuild(filter_name, source.contents, + extension_to_rule_name, From 42c8289d04dd9067845ee97d7e9fedecdf4b9aba Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 9 Jul 2014 21:33:33 -0700 Subject: [PATCH 010/388] part 1: removing old ninja for repo switch. --- .gitmodules | 3 --- third_party/ninja | 1 - 2 files changed, 4 deletions(-) delete mode 160000 third_party/ninja diff --git a/.gitmodules b/.gitmodules index 439bccb76..f465ee16a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "third_party/ninja"] - path = third_party/ninja - url = https://github.com/martine/ninja.git [submodule "third_party/gflags"] path = third_party/gflags url = https://github.com/benvanik/gflags.git diff --git a/third_party/ninja b/third_party/ninja deleted file mode 160000 index a3c823c3d..000000000 --- a/third_party/ninja +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a3c823c3da70bd46d69341f13184cdae4c77645d From 1e19c6b1fd906b576175d47e542c76d349841316 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 9 Jul 2014 21:38:38 -0700 Subject: [PATCH 011/388] part 2: ninja from the official repo. --- .gitmodules | 3 +++ third_party/ninja | 1 + 2 files changed, 4 insertions(+) create mode 160000 third_party/ninja diff --git a/.gitmodules b/.gitmodules index f465ee16a..db77456b2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "third_party/gyp"] path = third_party/gyp url = https://chromium.googlesource.com/external/gyp +[submodule "third_party/ninja"] + path = third_party/ninja + url = https://chromium.googlesource.com/external/martine/ninja diff --git a/third_party/ninja b/third_party/ninja new file mode 160000 index 000000000..0917ff862 --- /dev/null +++ b/third_party/ninja @@ -0,0 +1 @@ +Subproject commit 0917ff862bc54626b68bcdc208551e9ab17a2e4a From 500647968c2159e03452e118e3953e594e44a8c0 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 9 Jul 2014 22:05:41 -0700 Subject: [PATCH 012/388] Prepping poly. --- src/alloy/alloy.h | 4 -- src/poly/poly-private.h | 19 ++++++++++ src/poly/poly.cc | 15 ++++++++ src/poly/poly.h | 17 +++++++++ src/poly/sources.gypi | 30 +++++++++++++++ xenia.gyp | 84 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 165 insertions(+), 4 deletions(-) create mode 100644 src/poly/poly-private.h create mode 100644 src/poly/poly.cc create mode 100644 src/poly/poly.h create mode 100644 src/poly/sources.gypi diff --git a/src/alloy/alloy.h b/src/alloy/alloy.h index f65e8d5a6..72dbf7c06 100644 --- a/src/alloy/alloy.h +++ b/src/alloy/alloy.h @@ -19,10 +19,6 @@ #include -// TODO(benvanik): based on platform/config/etc. -#include - - namespace alloy { } // namespace alloy diff --git a/src/poly/poly-private.h b/src/poly/poly-private.h new file mode 100644 index 000000000..d4095d575 --- /dev/null +++ b/src/poly/poly-private.h @@ -0,0 +1,19 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef POLY_POLY_PRIVATE_H_ +#define POLY_POLY_PRIVATE_H_ + +#include + +namespace poly { + +} // namespace poly + +#endif // POLY_POLY_PRIVATE_H_ diff --git a/src/poly/poly.cc b/src/poly/poly.cc new file mode 100644 index 000000000..51b85164e --- /dev/null +++ b/src/poly/poly.cc @@ -0,0 +1,15 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include +#include + +namespace poly { + +} // namespace poly diff --git a/src/poly/poly.h b/src/poly/poly.h new file mode 100644 index 000000000..061fd09c1 --- /dev/null +++ b/src/poly/poly.h @@ -0,0 +1,17 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef POLY_POLY_H_ +#define POLY_POLY_H_ + +namespace poly { + +} // namespace poly + +#endif // POLY_POLY_H_ diff --git a/src/poly/sources.gypi b/src/poly/sources.gypi new file mode 100644 index 000000000..91b1b6c4f --- /dev/null +++ b/src/poly/sources.gypi @@ -0,0 +1,30 @@ +# Copyright 2014 Ben Vanik. All Rights Reserved. +{ + 'sources': [ + 'poly-private.h', + 'poly.cc', + 'poly.h', + ], + + 'conditions': [ + ['OS == "mac" or OS == "linux"', { + 'sources': [ + ], + }], + ['OS == "linux"', { + 'sources': [ + ], + }], + ['OS == "mac"', { + 'sources': [ + ], + }], + ['OS == "win"', { + 'sources': [ + ], + }], + ], + + 'includes': [ + ], +} diff --git a/xenia.gyp b/xenia.gyp index 28dfca299..e00108f76 100644 --- a/xenia.gyp +++ b/xenia.gyp @@ -192,6 +192,86 @@ }, 'targets': [ + { + 'target_name': 'poly', + 'product_name': 'poly', + 'type': 'static_library', + + 'dependencies': [ + 'gflags', + ], + + 'conditions': [ + ['OS == "mac"', { + 'xcode_settings': { + 'OTHER_CFLAGS': [ + '-fno-operator-names', + ], + }, + }], + ['OS == "linux"', { + 'cflags': [ + '-fno-operator-names', + ], + }], + ], + + 'export_dependent_settings': [ + 'gflags', + ], + + 'direct_dependent_settings': { + 'include_dirs': [ + 'src/', + ], + + 'target_conditions': [ + ['_type=="shared_library"', { + 'cflags': [ + ], + }], + ['_type=="executable"', { + 'conditions': [ + ['OS == "win"', { + 'libraries': [ + 'kernel32', + 'user32', + 'ole32', + 'ntdll', + 'advapi32', + ], + }], + ['OS == "mac"', { + 'xcode_settings': { + 'OTHER_LDFLAGS': [ + ], + }, + }], + ['OS == "linux"', { + 'libraries': [ + '-lpthread', + '-ldl', + ], + }], + ], + }], + ], + }, + + 'cflags': [ + ], + + 'include_dirs': [ + '.', + 'src/', + '<(INTERMEDIATE_DIR)', + ], + + 'includes': [ + 'src/poly/sources.gypi', + ], + }, + { 'target_name': 'alloy', 'product_name': 'alloy', @@ -201,6 +281,7 @@ 'beaengine', 'gflags', 'llvm', + 'poly', ], 'conditions': [ @@ -222,6 +303,7 @@ 'beaengine', 'gflags', 'llvm', + 'poly', ], 'direct_dependent_settings': { @@ -284,10 +366,12 @@ 'dependencies': [ 'gflags', 'alloy', + 'poly', ], 'export_dependent_settings': [ 'gflags', 'alloy', + 'poly', ], 'direct_dependent_settings': { From c5f114018e638c4e7d2fd3c5a127b397ff4418cb Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 9 Jul 2014 22:28:51 -0700 Subject: [PATCH 013/388] Replacing alloy::Mutex with std::mutex. --- src/alloy/backend/x64/x64_code_cache.cc | 9 +- src/alloy/backend/x64/x64_code_cache.h | 4 +- src/alloy/core.h | 1 - src/alloy/delegate.h | 25 ++--- src/alloy/mutex.h | 32 ------ src/alloy/mutex_posix.cc | 65 ------------ src/alloy/mutex_win.cc | 55 ----------- src/alloy/runtime/debugger.cc | 109 ++++++++++----------- src/alloy/runtime/debugger.h | 9 +- src/alloy/runtime/entry_table.cc | 23 ++--- src/alloy/runtime/entry_table.h | 4 +- src/alloy/runtime/function.cc | 15 +-- src/alloy/runtime/function.h | 9 +- src/alloy/runtime/module.cc | 42 ++++---- src/alloy/runtime/module.h | 5 +- src/alloy/runtime/runtime.cc | 48 +++++---- src/alloy/runtime/runtime.h | 5 +- src/alloy/sources.gypi | 3 - src/alloy/tracing/channels/file_channel.cc | 11 +-- src/alloy/tracing/channels/file_channel.h | 4 +- src/alloy/type_pool.h | 28 +++--- src/xenia/cpu/xenon_memory.cc | 22 ++--- src/xenia/logging.cc | 13 +-- 23 files changed, 170 insertions(+), 371 deletions(-) delete mode 100644 src/alloy/mutex.h delete mode 100644 src/alloy/mutex_posix.cc delete mode 100644 src/alloy/mutex_win.cc diff --git a/src/alloy/backend/x64/x64_code_cache.cc b/src/alloy/backend/x64/x64_code_cache.cc index 9d1c2ce60..057fd771a 100644 --- a/src/alloy/backend/x64/x64_code_cache.cc +++ b/src/alloy/backend/x64/x64_code_cache.cc @@ -53,11 +53,10 @@ public: X64CodeCache::X64CodeCache(size_t chunk_size) : chunk_size_(chunk_size), head_chunk_(NULL), active_chunk_(NULL) { - lock_ = AllocMutex(); } X64CodeCache::~X64CodeCache() { - LockMutex(lock_); + std::lock_guard guard(lock_); auto chunk = head_chunk_; while (chunk) { auto next = chunk->next; @@ -65,8 +64,6 @@ X64CodeCache::~X64CodeCache() { chunk = next; } head_chunk_ = NULL; - UnlockMutex(lock_); - FreeMutex(lock_); } int X64CodeCache::Initialize() { @@ -84,7 +81,7 @@ void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size, // to 16b so that all offsets are aligned. code_size = XEROUNDUP(code_size, 16); - LockMutex(lock_); + lock_.lock(); if (active_chunk_) { if (active_chunk_->capacity - active_chunk_->offset < code_size) { @@ -106,7 +103,7 @@ void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size, // Add entry to fn table. active_chunk_->AddTableEntry(final_address, code_size, stack_size); - UnlockMutex(lock_); + lock_.unlock(); // Copy code. xe_copy_struct(final_address, machine_code, code_size); diff --git a/src/alloy/backend/x64/x64_code_cache.h b/src/alloy/backend/x64/x64_code_cache.h index 23ba2e639..f51df94a9 100644 --- a/src/alloy/backend/x64/x64_code_cache.h +++ b/src/alloy/backend/x64/x64_code_cache.h @@ -10,6 +10,8 @@ #ifndef ALLOY_BACKEND_X64_X64_CODE_CACHE_H_ #define ALLOY_BACKEND_X64_X64_CODE_CACHE_H_ +#include + #include @@ -34,7 +36,7 @@ public: private: const static size_t DEFAULT_CHUNK_SIZE = 4 * 1024 * 1024; - Mutex* lock_; + std::mutex lock_; size_t chunk_size_; X64CodeChunk* head_chunk_; X64CodeChunk* active_chunk_; diff --git a/src/alloy/core.h b/src/alloy/core.h index 3beb11ba4..cf8c95c44 100644 --- a/src/alloy/core.h +++ b/src/alloy/core.h @@ -15,7 +15,6 @@ #include #include -#include #include diff --git a/src/alloy/delegate.h b/src/alloy/delegate.h index 176ff4b6b..2cbfde0ac 100644 --- a/src/alloy/delegate.h +++ b/src/alloy/delegate.h @@ -11,10 +11,10 @@ #define ALLOY_DELEGATE_H_ #include +#include #include #include -#include namespace alloy { @@ -25,48 +25,37 @@ namespace alloy { template class Delegate { public: - Delegate() { - lock_ = AllocMutex(); - } - ~Delegate() { - FreeMutex(lock_); - } - typedef std::function listener_t; void AddListener(listener_t const& listener) { - LockMutex(lock_); + std::lock_guard guard(lock_); listeners_.push_back(listener); - UnlockMutex(lock_); } void RemoveListener(listener_t const& listener) { - LockMutex(lock_); + std::lock_guard guard(lock_); for (auto it = listeners_.begin(); it != listeners_.end(); ++it) { if (it == listener) { listeners_.erase(it); break; } } - UnlockMutex(lock_); } void RemoveAllListeners() { - LockMutex(lock_); + std::lock_guard guard(lock_); listeners_.clear(); - UnlockMutex(lock_); } - void operator()(T& e) const { - LockMutex(lock_); + void operator()(T& e) { + std::lock_guard guard(lock_); for (auto &listener : listeners_) { listener(e); } - UnlockMutex(lock_); } private: - alloy::Mutex* lock_; + std::mutex lock_; std::vector listeners_; }; diff --git a/src/alloy/mutex.h b/src/alloy/mutex.h deleted file mode 100644 index 3b6ed6391..000000000 --- a/src/alloy/mutex.h +++ /dev/null @@ -1,32 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_MUTEX_H_ -#define ALLOY_MUTEX_H_ - -#include - - -namespace alloy { - - -typedef struct Mutex_t Mutex; - -Mutex* AllocMutex(uint32_t spin_count = 10000); -void FreeMutex(Mutex* mutex); - -int LockMutex(Mutex* mutex); -int TryLockMutex(Mutex* mutex); -int UnlockMutex(Mutex* mutex); - - -} // namespace alloy - - -#endif // ALLOY_MUTEX_H_ diff --git a/src/alloy/mutex_posix.cc b/src/alloy/mutex_posix.cc deleted file mode 100644 index 8638e9446..000000000 --- a/src/alloy/mutex_posix.cc +++ /dev/null @@ -1,65 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -using namespace alloy; - - -namespace alloy { - struct Mutex_t { - pthread_mutex_t value; - }; -} // namespace alloy - - -Mutex* alloy::AllocMutex(uint32_t spin_count) { - Mutex* mutex = (Mutex*)calloc(1, sizeof(Mutex)); - - int result = pthread_mutex_init(&mutex->value, NULL); - switch (result) { - case ENOMEM: - case EINVAL: - xe_free(mutex); - return NULL; - } - - return mutex; -} - -void alloy::FreeMutex(Mutex* mutex) { - int result = pthread_mutex_destroy(&mutex->value); - switch (result) { - case EBUSY: - case EINVAL: - break; - default: - break; - } - free(mutex); -} - -int alloy::LockMutex(Mutex* mutex) { - return pthread_mutex_lock(&mutex->value) == EINVAL ? 1 : 0; -} - -int alloy::TryLockMutex(Mutex* mutex) { - int result = pthread_mutex_trylock(&mutex->value); - switch (result) { - case EBUSY: - case EINVAL: - return 1; - default: - return 0; - } -} - -int alloy::UnlockMutex(Mutex* mutex) { - return pthread_mutex_unlock(&mutex->value) == EINVAL ? 1 : 0; -} diff --git a/src/alloy/mutex_win.cc b/src/alloy/mutex_win.cc deleted file mode 100644 index da37247cc..000000000 --- a/src/alloy/mutex_win.cc +++ /dev/null @@ -1,55 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -using namespace alloy; - - -namespace alloy { - struct Mutex_t { - CRITICAL_SECTION value; - }; -} // namespace alloy - - -Mutex* alloy::AllocMutex(uint32_t spin_count) { - Mutex* mutex = (Mutex*)xe_calloc(sizeof(Mutex)); - - if (spin_count) { - XEIGNORE(InitializeCriticalSectionAndSpinCount(&mutex->value, spin_count)); - } else { - InitializeCriticalSection(&mutex->value); - } - - return mutex; -} - -void alloy::FreeMutex(Mutex* mutex) { - DeleteCriticalSection(&mutex->value); - free(mutex); -} - -int alloy::LockMutex(Mutex* mutex) { - EnterCriticalSection(&mutex->value); - return 0; -} - -int alloy::TryLockMutex(Mutex* mutex) { - if (TryEnterCriticalSection(&mutex->value) == TRUE) { - return 0; - } else { - return 1; - } -} - -int alloy::UnlockMutex(Mutex* mutex) { - LeaveCriticalSection(&mutex->value); - return 0; -} diff --git a/src/alloy/runtime/debugger.cc b/src/alloy/runtime/debugger.cc index 3dbb7b906..565a6d6cb 100644 --- a/src/alloy/runtime/debugger.cc +++ b/src/alloy/runtime/debugger.cc @@ -9,7 +9,8 @@ #include -#include +#include + #include using namespace alloy; @@ -24,34 +25,28 @@ Breakpoint::~Breakpoint() { } Debugger::Debugger(Runtime* runtime) : - runtime_(runtime) { - threads_lock_ = AllocMutex(); - breakpoints_lock_ = AllocMutex(); -} + runtime_(runtime) {} -Debugger::~Debugger() { - FreeMutex(breakpoints_lock_); - FreeMutex(threads_lock_); -} +Debugger::~Debugger() {} int Debugger::SuspendAllThreads(uint32_t timeout_ms) { + std::lock_guard guard(threads_lock_); + int result = 0; - LockMutex(threads_lock_); for (auto it = threads_.begin(); it != threads_.end(); ++it) { ThreadState* thread_state = it->second; if (thread_state->Suspend(timeout_ms)) { result = 1; } } - UnlockMutex(threads_lock_); return result; } int Debugger::ResumeThread(uint32_t thread_id) { - LockMutex(threads_lock_); + std::lock_guard guard(threads_lock_); + auto it = threads_.find(thread_id); if (it == threads_.end()) { - UnlockMutex(threads_lock_); return 1; } @@ -59,38 +54,38 @@ int Debugger::ResumeThread(uint32_t thread_id) { ThreadState* thread_state = it->second; int result = thread_state->Resume(); - UnlockMutex(threads_lock_); return result; } int Debugger::ResumeAllThreads(bool force) { + std::lock_guard guard(threads_lock_); + int result = 0; - LockMutex(threads_lock_); for (auto it = threads_.begin(); it != threads_.end(); ++it) { ThreadState* thread_state = it->second; if (thread_state->Resume(force)) { result = 1; } } - UnlockMutex(threads_lock_); return result; } void Debugger::ForEachThread(std::function callback) { - LockMutex(threads_lock_); + std::lock_guard guard(threads_lock_); + for (auto it = threads_.begin(); it != threads_.end(); ++it) { ThreadState* thread_state = it->second; callback(thread_state); } - UnlockMutex(threads_lock_); } int Debugger::AddBreakpoint(Breakpoint* breakpoint) { // Add to breakpoints map. - LockMutex(breakpoints_lock_); - breakpoints_.insert( - std::pair(breakpoint->address(), breakpoint)); - UnlockMutex(breakpoints_lock_); + { + std::lock_guard guard(breakpoints_lock_); + breakpoints_.insert( + std::pair(breakpoint->address(), breakpoint)); + } // Find all functions that contain the breakpoint address. auto fns = runtime_->FindFunctionsWithAddress(breakpoint->address()); @@ -108,23 +103,23 @@ int Debugger::AddBreakpoint(Breakpoint* breakpoint) { int Debugger::RemoveBreakpoint(Breakpoint* breakpoint) { // Remove from breakpoint map. - LockMutex(breakpoints_lock_); - auto range = breakpoints_.equal_range(breakpoint->address()); - if (range.first == range.second) { - UnlockMutex(breakpoints_lock_); - return 1; - } - bool found = false; - for (auto it = range.first; it != range.second; ++it) { - if (it->second == breakpoint) { - breakpoints_.erase(it); - found = true; - break; + { + std::lock_guard guard(breakpoints_lock_); + auto range = breakpoints_.equal_range(breakpoint->address()); + if (range.first == range.second) { + return 1; + } + bool found = false; + for (auto it = range.first; it != range.second; ++it) { + if (it->second == breakpoint) { + breakpoints_.erase(it); + found = true; + break; + } + } + if (!found) { + return 1; } - } - UnlockMutex(breakpoints_lock_); - if (!found) { - return 1; } // Find all functions that have the breakpoint set. @@ -141,13 +136,12 @@ int Debugger::RemoveBreakpoint(Breakpoint* breakpoint) { void Debugger::FindBreakpoints( uint64_t address, std::vector& out_breakpoints) { - out_breakpoints.clear(); + std::lock_guard guard(breakpoints_lock_); - LockMutex(breakpoints_lock_); + out_breakpoints.clear(); auto range = breakpoints_.equal_range(address); if (range.first == range.second) { - UnlockMutex(breakpoints_lock_); return; } @@ -155,42 +149,39 @@ void Debugger::FindBreakpoints( Breakpoint* breakpoint = it->second; out_breakpoints.push_back(breakpoint); } - - UnlockMutex(breakpoints_lock_); } void Debugger::OnThreadCreated(ThreadState* thread_state) { - LockMutex(threads_lock_); + std::lock_guard guard(threads_lock_); threads_[thread_state->thread_id()] = thread_state; - UnlockMutex(threads_lock_); } void Debugger::OnThreadDestroyed(ThreadState* thread_state) { - LockMutex(threads_lock_); + std::lock_guard guard(threads_lock_); auto it = threads_.find(thread_state->thread_id()); if (it != threads_.end()) { threads_.erase(it); } - UnlockMutex(threads_lock_); } void Debugger::OnFunctionDefined(FunctionInfo* symbol_info, Function* function) { // Man, I'd love not to take this lock. std::vector breakpoints; - LockMutex(breakpoints_lock_); - for (uint64_t address = symbol_info->address(); - address <= symbol_info->end_address(); address += 4) { - auto range = breakpoints_.equal_range(address); - if (range.first == range.second) { - continue; - } - for (auto it = range.first; it != range.second; ++it) { - Breakpoint* breakpoint = it->second; - breakpoints.push_back(breakpoint); + { + std::lock_guard guard(breakpoints_lock_); + for (uint64_t address = symbol_info->address(); + address <= symbol_info->end_address(); address += 4) { + auto range = breakpoints_.equal_range(address); + if (range.first == range.second) { + continue; + } + for (auto it = range.first; it != range.second; ++it) { + Breakpoint* breakpoint = it->second; + breakpoints.push_back(breakpoint); + } } } - UnlockMutex(breakpoints_lock_); if (breakpoints.size()) { // Breakpoints to add! @@ -210,4 +201,4 @@ void Debugger::OnBreakpointHit( breakpoint_hit(e); // Note that we stay suspended. -} \ No newline at end of file +} diff --git a/src/alloy/runtime/debugger.h b/src/alloy/runtime/debugger.h index c61381bfe..344cb80ab 100644 --- a/src/alloy/runtime/debugger.h +++ b/src/alloy/runtime/debugger.h @@ -10,9 +10,10 @@ #ifndef ALLOY_RUNTIME_DEBUGGER_H_ #define ALLOY_RUNTIME_DEBUGGER_H_ -#include - #include +#include + +#include namespace alloy { @@ -105,11 +106,11 @@ public: private: Runtime* runtime_; - Mutex* threads_lock_; + std::mutex threads_lock_; typedef std::unordered_map ThreadMap; ThreadMap threads_; - Mutex* breakpoints_lock_; + std::mutex breakpoints_lock_; typedef std::multimap BreakpointMultimap; BreakpointMultimap breakpoints_; }; diff --git a/src/alloy/runtime/entry_table.cc b/src/alloy/runtime/entry_table.cc index ebec56ea4..5238ec6ae 100644 --- a/src/alloy/runtime/entry_table.cc +++ b/src/alloy/runtime/entry_table.cc @@ -13,23 +13,19 @@ using namespace alloy; using namespace alloy::runtime; -EntryTable::EntryTable() { - lock_ = AllocMutex(10000); -} +EntryTable::EntryTable() = default; EntryTable::~EntryTable() { - LockMutex(lock_); + std::lock_guard guard(lock_); EntryMap::iterator it = map_.begin(); for (; it != map_.end(); ++it) { Entry* entry = it->second; delete entry; } - UnlockMutex(lock_); - FreeMutex(lock_); } Entry* EntryTable::Get(uint64_t address) { - LockMutex(lock_); + std::lock_guard guard(lock_); EntryMap::const_iterator it = map_.find(address); Entry* entry = it != map_.end() ? it->second : NULL; if (entry) { @@ -38,12 +34,11 @@ Entry* EntryTable::Get(uint64_t address) { entry = NULL; } } - UnlockMutex(lock_); return entry; } Entry::Status EntryTable::GetOrCreate(uint64_t address, Entry** out_entry) { - LockMutex(lock_); + lock_.lock(); EntryMap::const_iterator it = map_.find(address); Entry* entry = it != map_.end() ? it->second : NULL; Entry::Status status; @@ -52,10 +47,10 @@ Entry::Status EntryTable::GetOrCreate(uint64_t address, Entry** out_entry) { if (entry->status == Entry::STATUS_COMPILING) { // Still compiling, so spin. do { - UnlockMutex(lock_); + lock_.unlock(); // TODO(benvanik): sleep for less time? Sleep(0); - LockMutex(lock_); + lock_.lock(); } while (entry->status == Entry::STATUS_COMPILING); } status = entry->status; @@ -69,16 +64,15 @@ Entry::Status EntryTable::GetOrCreate(uint64_t address, Entry** out_entry) { map_[address] = entry; status = Entry::STATUS_NEW; } - UnlockMutex(lock_); + lock_.unlock(); *out_entry = entry; return status; } std::vector EntryTable::FindWithAddress(uint64_t address) { SCOPE_profile_cpu_f("alloy"); - + std::lock_guard guard(lock_); std::vector fns; - LockMutex(lock_); for (auto it = map_.begin(); it != map_.end(); ++it) { Entry* entry = it->second; if (address >= entry->address && @@ -88,6 +82,5 @@ std::vector EntryTable::FindWithAddress(uint64_t address) { } } } - UnlockMutex(lock_); return fns; } diff --git a/src/alloy/runtime/entry_table.h b/src/alloy/runtime/entry_table.h index acbabc26e..9ff7729b1 100644 --- a/src/alloy/runtime/entry_table.h +++ b/src/alloy/runtime/entry_table.h @@ -10,6 +10,8 @@ #ifndef ALLOY_RUNTIME_ENTRY_TABLE_H_ #define ALLOY_RUNTIME_ENTRY_TABLE_H_ +#include + #include @@ -46,7 +48,7 @@ public: private: // TODO(benvanik): replace with a better data structure. - Mutex* lock_; + std::mutex lock_; typedef std::unordered_map EntryMap; EntryMap map_; }; diff --git a/src/alloy/runtime/function.cc b/src/alloy/runtime/function.cc index 2dd0ddce5..a5993be99 100644 --- a/src/alloy/runtime/function.cc +++ b/src/alloy/runtime/function.cc @@ -20,16 +20,12 @@ using namespace alloy::runtime; Function::Function(FunctionInfo* symbol_info) : address_(symbol_info->address()), symbol_info_(symbol_info), debug_info_(0) { - // TODO(benvanik): create on demand? - lock_ = AllocMutex(); } -Function::~Function() { - FreeMutex(lock_); -} +Function::~Function() = default; int Function::AddBreakpoint(Breakpoint* breakpoint) { - LockMutex(lock_); + std::lock_guard guard(lock_); bool found = false; for (auto it = breakpoints_.begin(); it != breakpoints_.end(); ++it) { if (*it == breakpoint) { @@ -40,12 +36,11 @@ int Function::AddBreakpoint(Breakpoint* breakpoint) { breakpoints_.push_back(breakpoint); AddBreakpointImpl(breakpoint); } - UnlockMutex(lock_); return found ? 1 : 0; } int Function::RemoveBreakpoint(Breakpoint* breakpoint) { - LockMutex(lock_); + std::lock_guard guard(lock_); bool found = false; for (auto it = breakpoints_.begin(); it != breakpoints_.end(); ++it) { if (*it == breakpoint) { @@ -55,12 +50,11 @@ int Function::RemoveBreakpoint(Breakpoint* breakpoint) { break; } } - UnlockMutex(lock_); return found ? 0 : 1; } Breakpoint* Function::FindBreakpoint(uint64_t address) { - LockMutex(lock_); + std::lock_guard guard(lock_); Breakpoint* result = NULL; for (auto it = breakpoints_.begin(); it != breakpoints_.end(); ++it) { Breakpoint* breakpoint = *it; @@ -69,7 +63,6 @@ Breakpoint* Function::FindBreakpoint(uint64_t address) { break; } } - UnlockMutex(lock_); return result; } diff --git a/src/alloy/runtime/function.h b/src/alloy/runtime/function.h index 22f4df0aa..e34ff5119 100644 --- a/src/alloy/runtime/function.h +++ b/src/alloy/runtime/function.h @@ -10,6 +10,9 @@ #ifndef ALLOY_RUNTIME_FUNCTION_H_ #define ALLOY_RUNTIME_FUNCTION_H_ +#include +#include + #include #include @@ -46,12 +49,12 @@ protected: uint64_t return_address) = 0; protected: - uint64_t address_; + uint64_t address_; FunctionInfo* symbol_info_; - DebugInfo* debug_info_; + DebugInfo* debug_info_; // TODO(benvanik): move elsewhere? DebugData? - Mutex* lock_; + std::mutex lock_; std::vector breakpoints_; }; diff --git a/src/alloy/runtime/module.cc b/src/alloy/runtime/module.cc index 5e38c3902..4cd4550c9 100644 --- a/src/alloy/runtime/module.cc +++ b/src/alloy/runtime/module.cc @@ -19,19 +19,15 @@ using namespace alloy::runtime; Module::Module(Runtime* runtime) : - runtime_(runtime), memory_(runtime->memory()) { - lock_ = AllocMutex(10000); -} + runtime_(runtime), memory_(runtime->memory()) {} Module::~Module() { - LockMutex(lock_); + std::lock_guard guard(lock_); SymbolMap::iterator it = map_.begin(); for (; it != map_.end(); ++it) { SymbolInfo* symbol_info = it->second; delete symbol_info; } - UnlockMutex(lock_); - FreeMutex(lock_); } bool Module::ContainsAddress(uint64_t address) { @@ -39,7 +35,7 @@ bool Module::ContainsAddress(uint64_t address) { } SymbolInfo* Module::LookupSymbol(uint64_t address, bool wait) { - LockMutex(lock_); + lock_.lock(); SymbolMap::const_iterator it = map_.find(address); SymbolInfo* symbol_info = it != map_.end() ? it->second : NULL; if (symbol_info) { @@ -47,10 +43,10 @@ SymbolInfo* Module::LookupSymbol(uint64_t address, bool wait) { // Some other thread is declaring the symbol - wait. if (wait) { do { - UnlockMutex(lock_); + lock_.unlock(); // TODO(benvanik): sleep for less time? Sleep(0); - LockMutex(lock_); + lock_.lock(); } while (symbol_info->status() == SymbolInfo::STATUS_DECLARING); } else { // Immediate request, just return. @@ -58,31 +54,31 @@ SymbolInfo* Module::LookupSymbol(uint64_t address, bool wait) { } } } - UnlockMutex(lock_); + lock_.unlock(); return symbol_info; } SymbolInfo::Status Module::DeclareSymbol( SymbolInfo::Type type, uint64_t address, SymbolInfo** out_symbol_info) { *out_symbol_info = NULL; - LockMutex(lock_); + lock_.lock(); SymbolMap::const_iterator it = map_.find(address); SymbolInfo* symbol_info = it != map_.end() ? it->second : NULL; SymbolInfo::Status status; if (symbol_info) { // If we exist but are the wrong type, die. if (symbol_info->type() != type) { - UnlockMutex(lock_); + lock_.unlock(); return SymbolInfo::STATUS_FAILED; } // If we aren't ready yet spin and wait. if (symbol_info->status() == SymbolInfo::STATUS_DECLARING) { // Still declaring, so spin. do { - UnlockMutex(lock_); + lock_.unlock(); // TODO(benvanik): sleep for less time? Sleep(0); - LockMutex(lock_); + lock_.lock(); } while (symbol_info->status() == SymbolInfo::STATUS_DECLARING); } status = symbol_info->status(); @@ -100,7 +96,7 @@ SymbolInfo::Status Module::DeclareSymbol( list_.push_back(symbol_info); status = SymbolInfo::STATUS_NEW; } - UnlockMutex(lock_); + lock_.unlock(); *out_symbol_info = symbol_info; // Get debug info from providers, if this is new. @@ -130,7 +126,7 @@ SymbolInfo::Status Module::DeclareVariable( } SymbolInfo::Status Module::DefineSymbol(SymbolInfo* symbol_info) { - LockMutex(lock_); + lock_.lock(); SymbolInfo::Status status; if (symbol_info->status() == SymbolInfo::STATUS_DECLARED) { // Declared but undefined, so request caller define it. @@ -139,16 +135,16 @@ SymbolInfo::Status Module::DefineSymbol(SymbolInfo* symbol_info) { } else if (symbol_info->status() == SymbolInfo::STATUS_DEFINING) { // Still defining, so spin. do { - UnlockMutex(lock_); + lock_.unlock(); // TODO(benvanik): sleep for less time? Sleep(0); - LockMutex(lock_); + lock_.lock(); } while (symbol_info->status() == SymbolInfo::STATUS_DEFINING); status = symbol_info->status(); } else { status = symbol_info->status(); } - UnlockMutex(lock_); + lock_.unlock(); return status; } @@ -162,8 +158,7 @@ SymbolInfo::Status Module::DefineVariable(VariableInfo* symbol_info) { void Module::ForEachFunction(std::function callback) { SCOPE_profile_cpu_f("alloy"); - - LockMutex(lock_); + std::lock_guard guard(lock_); for (auto it = list_.begin(); it != list_.end(); ++it) { SymbolInfo* symbol_info = *it; if (symbol_info->type() == SymbolInfo::TYPE_FUNCTION) { @@ -171,14 +166,12 @@ void Module::ForEachFunction(std::function callback) { callback(info); } } - UnlockMutex(lock_); } void Module::ForEachFunction(size_t since, size_t& version, std::function callback) { SCOPE_profile_cpu_f("alloy"); - - LockMutex(lock_); + std::lock_guard guard(lock_); size_t count = list_.size(); version = count; for (size_t n = since; n < count; n++) { @@ -188,7 +181,6 @@ void Module::ForEachFunction(size_t since, size_t& version, callback(info); } } - UnlockMutex(lock_); } int Module::ReadMap(const char* file_name) { diff --git a/src/alloy/runtime/module.h b/src/alloy/runtime/module.h index c05e009ca..63ca706fe 100644 --- a/src/alloy/runtime/module.h +++ b/src/alloy/runtime/module.h @@ -11,6 +11,9 @@ #define ALLOY_RUNTIME_MODULE_H_ #include +#include +#include +#include #include #include @@ -61,7 +64,7 @@ protected: private: // TODO(benvanik): replace with a better data structure. - Mutex* lock_; + std::mutex lock_; typedef std::unordered_map SymbolMap; SymbolMap map_; typedef std::vector SymbolList; diff --git a/src/alloy/runtime/runtime.cc b/src/alloy/runtime/runtime.cc index 7be29dce1..cf9cce22c 100644 --- a/src/alloy/runtime/runtime.cc +++ b/src/alloy/runtime/runtime.cc @@ -27,18 +27,17 @@ DEFINE_string(runtime_backend, "any", Runtime::Runtime(Memory* memory) : memory_(memory), debugger_(0), backend_(0), frontend_(0) { tracing::Initialize(); - modules_lock_ = AllocMutex(10000); } Runtime::~Runtime() { - LockMutex(modules_lock_); - for (ModuleList::iterator it = modules_.begin(); - it != modules_.end(); ++it) { - Module* module = *it; - delete module; + { + std::lock_guard guard(modules_lock_); + for (ModuleList::iterator it = modules_.begin(); + it != modules_.end(); ++it) { + Module* module = *it; + delete module; + } } - UnlockMutex(modules_lock_); - FreeMutex(modules_lock_); delete frontend_; delete backend_; @@ -111,15 +110,14 @@ int Runtime::Initialize(Frontend* frontend, Backend* backend) { } int Runtime::AddModule(Module* module) { - LockMutex(modules_lock_); + std::lock_guard guard(modules_lock_); modules_.push_back(module); - UnlockMutex(modules_lock_); return 0; } Module* Runtime::GetModule(const char* name) { + std::lock_guard guard(modules_lock_); Module* result = NULL; - LockMutex(modules_lock_); for (ModuleList::iterator it = modules_.begin(); it != modules_.end(); ++it) { Module* module = *it; @@ -128,15 +126,12 @@ Module* Runtime::GetModule(const char* name) { break; } } - UnlockMutex(modules_lock_); return result; } Runtime::ModuleList Runtime::GetModules() { - ModuleList clone; - LockMutex(modules_lock_); - clone = modules_; - UnlockMutex(modules_lock_); + std::lock_guard guard(modules_lock_); + ModuleList clone = modules_; return clone; } @@ -188,18 +183,19 @@ int Runtime::LookupFunctionInfo( // Find the module that contains the address. Module* code_module = NULL; - LockMutex(modules_lock_); - // TODO(benvanik): sort by code address (if contiguous) so can bsearch. - // TODO(benvanik): cache last module low/high, as likely to be in there. - for (ModuleList::const_iterator it = modules_.begin(); - it != modules_.end(); ++it) { - Module* module = *it; - if (module->ContainsAddress(address)) { - code_module = module; - break; + { + std::lock_guard guard(modules_lock_); + // TODO(benvanik): sort by code address (if contiguous) so can bsearch. + // TODO(benvanik): cache last module low/high, as likely to be in there. + for (ModuleList::const_iterator it = modules_.begin(); + it != modules_.end(); ++it) { + Module* module = *it; + if (module->ContainsAddress(address)) { + code_module = module; + break; + } } } - UnlockMutex(modules_lock_); if (!code_module) { // No module found that could contain the address. return 1; diff --git a/src/alloy/runtime/runtime.h b/src/alloy/runtime/runtime.h index a6c506fc5..68d4f488d 100644 --- a/src/alloy/runtime/runtime.h +++ b/src/alloy/runtime/runtime.h @@ -10,6 +10,9 @@ #ifndef ALLOY_RUNTIME_RUNTIME_H_ #define ALLOY_RUNTIME_RUNTIME_H_ +#include +#include + #include #include #include @@ -65,7 +68,7 @@ protected: backend::Backend* backend_; EntryTable entry_table_; - Mutex* modules_lock_; + std::mutex modules_lock_; ModuleList modules_; }; diff --git a/src/alloy/sources.gypi b/src/alloy/sources.gypi index 808af15b8..89bca0b1d 100644 --- a/src/alloy/sources.gypi +++ b/src/alloy/sources.gypi @@ -10,7 +10,6 @@ 'delegate.h', 'memory.cc', 'memory.h', - 'mutex.h', 'string_buffer.cc', 'string_buffer.h', 'type_pool.h', @@ -19,7 +18,6 @@ 'conditions': [ ['OS == "mac" or OS == "linux"', { 'sources': [ - 'mutex_posix.cc', ], }], ['OS == "linux"', { @@ -32,7 +30,6 @@ }], ['OS == "win"', { 'sources': [ - 'mutex_win.cc', ], }], ], diff --git a/src/alloy/tracing/channels/file_channel.cc b/src/alloy/tracing/channels/file_channel.cc index 115f79387..7b2db652b 100644 --- a/src/alloy/tracing/channels/file_channel.cc +++ b/src/alloy/tracing/channels/file_channel.cc @@ -15,37 +15,32 @@ using namespace alloy::tracing::channels; FileChannel::FileChannel(const char* path) { - lock_ = AllocMutex(10000); path_ = xestrdupa(path); file_ = fopen(path, "wb"); } FileChannel::~FileChannel() { - LockMutex(lock_); + std::lock_guard guard(lock_); fclose(file_); file_ = 0; free(path_); path_ = 0; - UnlockMutex(lock_); - FreeMutex(lock_); } void FileChannel::Write( size_t buffer_count, size_t buffer_lengths[], const uint8_t* buffers[]) { - LockMutex(lock_); + std::lock_guard guard(lock_); if (file_) { for (size_t n = 0; n < buffer_count; n++) { fwrite(buffers[n], buffer_lengths[n], 1, file_); } } - UnlockMutex(lock_); } void FileChannel::Flush() { - LockMutex(lock_); + std::lock_guard guard(lock_); if (file_) { fflush(file_); } - UnlockMutex(lock_); } diff --git a/src/alloy/tracing/channels/file_channel.h b/src/alloy/tracing/channels/file_channel.h index 9f57fc4af..55e8e71fb 100644 --- a/src/alloy/tracing/channels/file_channel.h +++ b/src/alloy/tracing/channels/file_channel.h @@ -10,6 +10,8 @@ #ifndef ALLOY_TRACING_CHANNELS_FILE_CHANNEL_H_ #define ALLOY_TRACING_CHANNELS_FILE_CHANNEL_H_ +#include + #include #include @@ -34,7 +36,7 @@ public: private: char* path_; FILE* file_; - Mutex* lock_; + std::mutex lock_; }; diff --git a/src/alloy/type_pool.h b/src/alloy/type_pool.h index e88026399..beb9dbd43 100644 --- a/src/alloy/type_pool.h +++ b/src/alloy/type_pool.h @@ -10,6 +10,8 @@ #ifndef ALLOY_TYPE_POOL_H_ #define ALLOY_TYPE_POOL_H_ +#include + #include @@ -19,33 +21,28 @@ namespace alloy { template class TypePool { public: - TypePool() { - lock_ = AllocMutex(10000); - } - ~TypePool() { Reset(); - FreeMutex(lock_); } void Reset() { - LockMutex(lock_); + std::lock_guard guard(lock_); for (TList::iterator it = list_.begin(); it != list_.end(); ++it) { T* value = *it; delete value; } list_.clear(); - UnlockMutex(lock_); } T* Allocate(A arg0) { T* result = 0; - LockMutex(lock_); - if (list_.size()) { - result = list_.back(); - list_.pop_back(); + { + std::lock_guard guard(lock_); + if (list_.size()) { + result = list_.back(); + list_.pop_back(); + } } - UnlockMutex(lock_); if (!result) { result = new T(arg0); } @@ -53,15 +50,14 @@ public: } void Release(T* value) { - LockMutex(lock_); + std::lock_guard guard(lock_); list_.push_back(value); - UnlockMutex(lock_); } private: - Mutex* lock_; + std::mutex lock_; typedef std::vector TList; - TList list_; + TList list_; }; diff --git a/src/xenia/cpu/xenon_memory.cc b/src/xenia/cpu/xenon_memory.cc index 8e3bf6dc5..c20130fae 100644 --- a/src/xenia/cpu/xenon_memory.cc +++ b/src/xenia/cpu/xenon_memory.cc @@ -9,6 +9,8 @@ #include +#include + #include #include @@ -112,7 +114,7 @@ private: XenonMemory* memory_; uint32_t heap_id_; bool is_physical_; - Mutex* lock_; + std::mutex lock_; size_t size_; uint8_t* ptr_; mspace space_; @@ -615,19 +617,13 @@ uint32_t XenonMemory::QueryProtect(uint64_t address) { XenonMemoryHeap::XenonMemoryHeap(XenonMemory* memory, bool is_physical) : memory_(memory), is_physical_(is_physical) { heap_id_ = next_heap_id_++; - lock_ = AllocMutex(10000); } XenonMemoryHeap::~XenonMemoryHeap() { - if (lock_ && space_) { - LockMutex(lock_); + if (space_) { + std::lock_guard guard(lock_); destroy_mspace(space_); space_ = NULL; - UnlockMutex(lock_); - } - if (lock_) { - FreeMutex(lock_); - lock_ = NULL; } if (ptr_) { @@ -661,7 +657,7 @@ int XenonMemoryHeap::Initialize(uint64_t low, uint64_t high) { uint64_t XenonMemoryHeap::Alloc( uint64_t base_address, size_t size, uint32_t flags, uint32_t alignment) { - XEIGNORE(LockMutex(lock_)); + lock_.lock(); size_t alloc_size = size; size_t heap_guard_size = FLAGS_heap_guard_pages * 4096; if (heap_guard_size) { @@ -686,7 +682,7 @@ uint64_t XenonMemoryHeap::Alloc( if (FLAGS_log_heap) { Dump(); } - XEIGNORE(UnlockMutex(lock_)); + lock_.unlock(); if (!p) { return 0; } @@ -747,7 +743,7 @@ uint64_t XenonMemoryHeap::Free(uint64_t address, size_t size) { memset(p + heap_guard_size, 0xDC, size); } - XEIGNORE(LockMutex(lock_)); + lock_.lock(); if (FLAGS_heap_guard_pages) { DWORD old_protect; VirtualProtect( @@ -761,7 +757,7 @@ uint64_t XenonMemoryHeap::Free(uint64_t address, size_t size) { if (FLAGS_log_heap) { Dump(); } - XEIGNORE(UnlockMutex(lock_)); + lock_.unlock(); if (is_physical_) { // If physical, decommit from physical ranges too. diff --git a/src/xenia/logging.cc b/src/xenia/logging.cc index 3f9d840f9..77106bc54 100644 --- a/src/xenia/logging.cc +++ b/src/xenia/logging.cc @@ -9,8 +9,9 @@ #include +#include + #include -#include #include @@ -20,7 +21,7 @@ DEFINE_bool(fast_stdout, false, namespace { -xe_mutex_t* log_lock = xe_mutex_alloc(); +std::mutex log_lock; } // namespace @@ -69,7 +70,7 @@ void xe_log_line(const char* file_path, const uint32_t line_number, va_end(args); if (!FLAGS_fast_stdout) { - xe_mutex_lock(log_lock); + log_lock.lock(); } #if 0// defined(OutputDebugString) OutputDebugStringA(buffer); @@ -78,7 +79,7 @@ void xe_log_line(const char* file_path, const uint32_t line_number, fflush(stdout); #endif // OutputDebugString if (!FLAGS_fast_stdout) { - xe_mutex_unlock(log_lock); + log_lock.unlock(); } } @@ -94,7 +95,7 @@ void xe_handle_fatal( va_end(args); if (!FLAGS_fast_stdout) { - xe_mutex_lock(log_lock); + log_lock.lock(); } #if defined(OutputDebugString) OutputDebugStringA(buffer); @@ -103,7 +104,7 @@ void xe_handle_fatal( fflush(stderr); #endif // OutputDebugString if (!FLAGS_fast_stdout) { - xe_mutex_unlock(log_lock); + log_lock.unlock(); } #if XE_LIKE_WIN32 From 868803e03a2bfd6c44deffb8eb9b375fd2c470df Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 9 Jul 2014 22:31:14 -0700 Subject: [PATCH 014/388] Fixing file header. --- src/alloy/backend/x64/x64_thunk_emitter.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/alloy/backend/x64/x64_thunk_emitter.h b/src/alloy/backend/x64/x64_thunk_emitter.h index ae9c7b967..e472885ea 100644 --- a/src/alloy/backend/x64/x64_thunk_emitter.h +++ b/src/alloy/backend/x64/x64_thunk_emitter.h @@ -7,8 +7,8 @@ ****************************************************************************** */ -#ifndef XENIA_CPU_X64_X64_THUNK_EMITTER_H_ -#define XENIA_CPU_X64_X64_THUNK_EMITTER_H_ +#ifndef ALLOY_BACKEND_X64_X64_THUNK_EMITTER_H_ +#define ALLOY_BACKEND_X64_X64_THUNK_EMITTER_H_ #include #include @@ -111,7 +111,7 @@ namespace x64 { * ... locals ... * +------------------+ * | (return address) | - * +------------------+ + * +------------------+ * */ @@ -144,4 +144,4 @@ public: } // namespace alloy -#endif // XENIA_CPU_X64_X64_THUNK_EMITTER_H_ +#endif // ALLOY_BACKEND_X64_X64_THUNK_EMITTER_H_ From 0158380cfce8ad2a503988d4aa44329523a4b53b Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 9 Jul 2014 23:08:58 -0700 Subject: [PATCH 015/388] Fixing xenia-build on OSX. --- xenia-build.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/xenia-build.py b/xenia-build.py index 53bcf1cfc..248128236 100755 --- a/xenia-build.py +++ b/xenia-build.py @@ -285,7 +285,9 @@ class SetupCommand(Command): # Binutils. # TODO(benvanik): disable on Windows print('- binutils...') - if sys.platform == 'win32': + if True: + print('binutils disabled') + elif sys.platform == 'win32': print('WARNING: ignoring binutils on Windows... don\'t change tests!') else: if not os.path.exists('build/binutils'): @@ -364,7 +366,7 @@ def run_gyp(format): '--toplevel-dir=.', '--generator-output=build/xenia/', # Set the VS version. - '-G msvs_version=%s' % (os.environ['VSVERSION'] or 2013), + '-G msvs_version=%s' % (os.environ.get('VSVERSION', 2013)), #'-D windows_sdk_dir=%s' % (os.environ['WINDOWSSDKDIR']), '-D windows_sdk_dir="C:\\Program Files (x86)\\Windows Kits\\8.1"', 'xenia.gyp', From 7daa85179c8413b32bbd1807904c97d484c50637 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 10 Jul 2014 20:20:00 -0700 Subject: [PATCH 016/388] Running clang-format on alloy. All except x64_sequences, which needs work. --- src/alloy/alloy-private.h | 7 - src/alloy/alloy.cc | 12 +- src/alloy/alloy.h | 6 - src/alloy/arena.cc | 18 +- src/alloy/arena.h | 29 +- src/alloy/backend/assembler.cc | 22 +- src/alloy/backend/assembler.h | 22 +- src/alloy/backend/backend.cc | 26 +- src/alloy/backend/backend.h | 14 +- src/alloy/backend/ivm/ivm_assembler.cc | 42 +- src/alloy/backend/ivm/ivm_assembler.h | 22 +- src/alloy/backend/ivm/ivm_backend.cc | 45 +- src/alloy/backend/ivm/ivm_backend.h | 7 +- src/alloy/backend/ivm/ivm_function.cc | 33 +- src/alloy/backend/ivm/ivm_intcode.cc | 2346 +++++++++-------- src/alloy/backend/ivm/ivm_intcode.h | 96 +- src/alloy/backend/ivm/ivm_stack.cc | 24 +- src/alloy/backend/ivm/ivm_stack.h | 28 +- src/alloy/backend/ivm/tracing.h | 20 +- src/alloy/backend/machine_info.h | 4 - src/alloy/backend/tracing.h | 10 +- src/alloy/backend/x64/tracing.h | 20 +- src/alloy/backend/x64/x64_assembler.cc | 54 +- src/alloy/backend/x64/x64_assembler.h | 31 +- src/alloy/backend/x64/x64_backend.cc | 40 +- src/alloy/backend/x64/x64_backend.h | 9 +- src/alloy/backend/x64/x64_code_cache.cc | 104 +- src/alloy/backend/x64/x64_code_cache.h | 11 +- src/alloy/backend/x64/x64_emitter.cc | 230 +- src/alloy/backend/x64/x64_emitter.h | 48 +- src/alloy/backend/x64/x64_function.cc | 34 +- src/alloy/backend/x64/x64_function.h | 14 +- src/alloy/backend/x64/x64_sequences.h | 6 +- src/alloy/backend/x64/x64_thunk_emitter.cc | 23 +- src/alloy/backend/x64/x64_thunk_emitter.h | 9 +- src/alloy/backend/x64/x64_tracers.cc | 44 +- src/alloy/backend/x64/x64_tracers.h | 20 +- src/alloy/compiler/compiler.cc | 23 +- src/alloy/compiler/compiler.h | 14 +- src/alloy/compiler/compiler_pass.cc | 15 +- src/alloy/compiler/compiler_pass.h | 16 +- src/alloy/compiler/compiler_passes.h | 3 +- .../passes/constant_propagation_pass.cc | 720 ++--- .../passes/constant_propagation_pass.h | 8 +- .../compiler/passes/context_promotion_pass.cc | 34 +- .../compiler/passes/context_promotion_pass.h | 10 +- .../passes/control_flow_analysis_pass.cc | 26 +- .../passes/control_flow_analysis_pass.h | 8 +- .../passes/data_flow_analysis_pass.cc | 41 +- .../passes/dead_code_elimination_pass.cc | 54 +- .../compiler/passes/finalization_pass.cc | 23 +- src/alloy/compiler/passes/finalization_pass.h | 8 +- .../passes/register_allocation_pass.cc | 81 +- .../passes/register_allocation_pass.h | 10 +- .../compiler/passes/simplification_pass.cc | 30 +- .../compiler/passes/simplification_pass.h | 8 +- src/alloy/compiler/passes/validation_pass.cc | 29 +- src/alloy/compiler/passes/validation_pass.h | 8 +- .../compiler/passes/value_reduction_pass.cc | 25 +- .../compiler/passes/value_reduction_pass.h | 8 +- src/alloy/compiler/tracing.h | 10 +- src/alloy/core.h | 71 +- src/alloy/delegate.h | 10 +- src/alloy/frontend/context_info.cc | 15 +- src/alloy/frontend/context_info.h | 8 +- src/alloy/frontend/frontend.cc | 24 +- src/alloy/frontend/frontend.h | 25 +- src/alloy/frontend/ppc/ppc_context.cc | 25 +- src/alloy/frontend/ppc/ppc_disasm.cc | 371 ++- src/alloy/frontend/ppc/ppc_disasm.h | 4 - src/alloy/frontend/ppc/ppc_emit-private.h | 6 +- src/alloy/frontend/ppc/ppc_emit.h | 4 - src/alloy/frontend/ppc/ppc_emit_altivec.cc | 1648 ++++++------ src/alloy/frontend/ppc/ppc_emit_alu.cc | 493 ++-- src/alloy/frontend/ppc/ppc_emit_control.cc | 289 +- src/alloy/frontend/ppc/ppc_emit_fpu.cc | 264 +- src/alloy/frontend/ppc/ppc_emit_memory.cc | 404 ++- src/alloy/frontend/ppc/ppc_frontend.cc | 75 +- src/alloy/frontend/ppc/ppc_frontend.h | 16 +- src/alloy/frontend/ppc/ppc_hir_builder.cc | 95 +- src/alloy/frontend/ppc/ppc_hir_builder.h | 32 +- src/alloy/frontend/ppc/ppc_instr.cc | 156 +- src/alloy/frontend/ppc/ppc_instr.h | 605 +++-- src/alloy/frontend/ppc/ppc_instr_tables.h | 1409 ++++++---- src/alloy/frontend/ppc/ppc_scanner.cc | 69 +- src/alloy/frontend/ppc/ppc_scanner.h | 10 +- src/alloy/frontend/ppc/ppc_translator.cc | 65 +- src/alloy/frontend/ppc/ppc_translator.h | 25 +- src/alloy/frontend/tracing.h | 10 +- src/alloy/hir/block.cc | 8 +- src/alloy/hir/block.h | 12 +- src/alloy/hir/hir_builder.cc | 550 ++-- src/alloy/hir/hir_builder.h | 55 +- src/alloy/hir/instr.cc | 8 +- src/alloy/hir/instr.h | 36 +- src/alloy/hir/label.h | 12 +- src/alloy/hir/opcodes.cc | 8 +- src/alloy/hir/opcodes.h | 128 +- src/alloy/hir/tracing.h | 8 +- src/alloy/hir/value.cc | 816 +++--- src/alloy/hir/value.h | 333 +-- src/alloy/memory.cc | 27 +- src/alloy/memory.h | 30 +- src/alloy/runtime/debug_info.cc | 23 +- src/alloy/runtime/debug_info.h | 38 +- src/alloy/runtime/debugger.cc | 27 +- src/alloy/runtime/debugger.h | 48 +- src/alloy/runtime/entry_table.cc | 11 +- src/alloy/runtime/entry_table.h | 17 +- src/alloy/runtime/function.cc | 24 +- src/alloy/runtime/function.h | 13 +- src/alloy/runtime/instrument.cc | 41 +- src/alloy/runtime/instrument.h | 45 +- src/alloy/runtime/module.cc | 56 +- src/alloy/runtime/module.h | 28 +- src/alloy/runtime/raw_module.cc | 23 +- src/alloy/runtime/raw_module.h | 16 +- src/alloy/runtime/runtime.cc | 61 +- src/alloy/runtime/runtime.h | 26 +- src/alloy/runtime/symbol_info.cc | 37 +- src/alloy/runtime/symbol_info.h | 39 +- src/alloy/runtime/thread_state.cc | 30 +- src/alloy/runtime/thread_state.h | 20 +- src/alloy/runtime/tracing.h | 56 +- src/alloy/string_buffer.cc | 29 +- src/alloy/string_buffer.h | 14 +- src/alloy/tracing/channel.cc | 12 +- src/alloy/tracing/channel.h | 11 +- src/alloy/tracing/channels/file_channel.cc | 16 +- src/alloy/tracing/channels/file_channel.h | 13 +- src/alloy/tracing/event_type.h | 26 +- src/alloy/tracing/tracer.cc | 35 +- src/alloy/tracing/tracer.h | 12 +- src/alloy/tracing/tracing.cc | 36 +- src/alloy/tracing/tracing.h | 7 +- src/alloy/type_pool.h | 20 +- src/poly/poly-private.h | 4 - src/poly/poly.cc | 4 +- src/poly/poly.h | 4 +- 139 files changed, 6925 insertions(+), 6998 deletions(-) diff --git a/src/alloy/alloy-private.h b/src/alloy/alloy-private.h index a22be71c4..8888e7b1c 100644 --- a/src/alloy/alloy-private.h +++ b/src/alloy/alloy-private.h @@ -14,7 +14,6 @@ #include - DECLARE_bool(debug); DECLARE_bool(always_disasm); @@ -23,10 +22,4 @@ DECLARE_bool(validate_hir); DECLARE_uint64(break_on_instruction); DECLARE_uint64(break_on_memory); - -namespace alloy { - -} // namespace alloy - - #endif // ALLOY_ALLOY_PRIVATE_H_ diff --git a/src/alloy/alloy.cc b/src/alloy/alloy.cc index bae955976..e5b135a9e 100644 --- a/src/alloy/alloy.cc +++ b/src/alloy/alloy.cc @@ -12,7 +12,6 @@ using namespace alloy; - #if 0 && DEBUG #define DEFAULT_DEBUG_FLAG true #else @@ -20,15 +19,16 @@ using namespace alloy; #endif DEFINE_bool(debug, DEFAULT_DEBUG_FLAG, - "Allow debugging and retain debug information."); -DEFINE_bool(always_disasm, false, + "Allow debugging and retain debug information."); +DEFINE_bool( + always_disasm, false, "Always add debug info to functions, even when no debugger is attached."); DEFINE_bool(validate_hir, false, - "Perform validation checks on the HIR during compilation."); + "Perform validation checks on the HIR during compilation."); // Breakpoints: DEFINE_uint64(break_on_instruction, 0, - "int3 before the given guest address is executed."); + "int3 before the given guest address is executed."); DEFINE_uint64(break_on_memory, 0, - "int3 on read/write to the given memory address."); + "int3 on read/write to the given memory address."); diff --git a/src/alloy/alloy.h b/src/alloy/alloy.h index 72dbf7c06..f35589381 100644 --- a/src/alloy/alloy.h +++ b/src/alloy/alloy.h @@ -18,10 +18,4 @@ #include #include - -namespace alloy { - -} // namespace alloy - - #endif // ALLOY_ALLOY_H_ diff --git a/src/alloy/arena.cc b/src/alloy/arena.cc index fe08f8c31..638adeabf 100644 --- a/src/alloy/arena.cc +++ b/src/alloy/arena.cc @@ -9,13 +9,10 @@ #include -using namespace alloy; +namespace alloy { - -Arena::Arena(size_t chunk_size) : - chunk_size_(chunk_size), - head_chunk_(NULL), active_chunk_(NULL) { -} +Arena::Arena(size_t chunk_size) + : chunk_size_(chunk_size), head_chunk_(NULL), active_chunk_(NULL) {} Arena::~Arena() { Reset(); @@ -48,7 +45,7 @@ void* Arena::Alloc(size_t size) { if (active_chunk_->capacity - active_chunk_->offset < size + 4096) { Chunk* next = active_chunk_->next; if (!next) { - XEASSERT(size < chunk_size_); // need to support larger chunks + XEASSERT(size < chunk_size_); // need to support larger chunks next = new Chunk(chunk_size_); active_chunk_->next = next; } @@ -88,9 +85,8 @@ void* Arena::CloneContents() { return result; } -Arena::Chunk::Chunk(size_t chunk_size) : - next(NULL), - capacity(chunk_size), buffer(0), offset(0) { +Arena::Chunk::Chunk(size_t chunk_size) + : next(NULL), capacity(chunk_size), buffer(0), offset(0) { buffer = (uint8_t*)xe_malloc(capacity); } @@ -99,3 +95,5 @@ Arena::Chunk::~Chunk() { xe_free(buffer); } } + +} // namespace alloy diff --git a/src/alloy/arena.h b/src/alloy/arena.h index 2041f1375..862622deb 100644 --- a/src/alloy/arena.h +++ b/src/alloy/arena.h @@ -12,12 +12,10 @@ #include - namespace alloy { - class Arena { -public: + public: Arena(size_t chunk_size = 4 * 1024 * 1024); ~Arena(); @@ -25,33 +23,32 @@ public: void DebugFill(); void* Alloc(size_t size); - template T* Alloc() { + template + T* Alloc() { return (T*)Alloc(sizeof(T)); } void* CloneContents(); -private: + private: class Chunk { - public: + public: Chunk(size_t chunk_size); ~Chunk(); - Chunk* next; + Chunk* next; - size_t capacity; - uint8_t* buffer; - size_t offset; + size_t capacity; + uint8_t* buffer; + size_t offset; }; -private: - size_t chunk_size_; - Chunk* head_chunk_; - Chunk* active_chunk_; + private: + size_t chunk_size_; + Chunk* head_chunk_; + Chunk* active_chunk_; }; - } // namespace alloy - #endif // ALLOY_ARENA_H_ diff --git a/src/alloy/backend/assembler.cc b/src/alloy/backend/assembler.cc index 54e32c76a..935118fc3 100644 --- a/src/alloy/backend/assembler.cc +++ b/src/alloy/backend/assembler.cc @@ -11,22 +11,16 @@ #include -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::runtime; +namespace alloy { +namespace backend { +Assembler::Assembler(Backend* backend) : backend_(backend) {} -Assembler::Assembler(Backend* backend) : - backend_(backend) { -} +Assembler::~Assembler() { Reset(); } -Assembler::~Assembler() { - Reset(); -} +int Assembler::Initialize() { return 0; } -int Assembler::Initialize() { - return 0; -} +void Assembler::Reset() {} -void Assembler::Reset() { -} +} // namespace backend +} // namespace alloy diff --git a/src/alloy/backend/assembler.h b/src/alloy/backend/assembler.h index 9652bee37..b9f6ed788 100644 --- a/src/alloy/backend/assembler.h +++ b/src/alloy/backend/assembler.h @@ -12,27 +12,25 @@ #include - namespace alloy { namespace hir { class HIRBuilder; -} +} // namespace hir namespace runtime { class DebugInfo; class Function; class FunctionInfo; class Runtime; -} -} +} // namespace runtime +} // namespace alloy namespace alloy { namespace backend { class Backend; - class Assembler { -public: + public: Assembler(Backend* backend); virtual ~Assembler(); @@ -40,18 +38,16 @@ public: virtual void Reset(); - virtual int Assemble( - runtime::FunctionInfo* symbol_info, hir::HIRBuilder* builder, - uint32_t debug_info_flags, runtime::DebugInfo* debug_info, - runtime::Function** out_function) = 0; + virtual int Assemble(runtime::FunctionInfo* symbol_info, + hir::HIRBuilder* builder, uint32_t debug_info_flags, + runtime::DebugInfo* debug_info, + runtime::Function** out_function) = 0; -protected: + protected: Backend* backend_; }; - } // namespace backend } // namespace alloy - #endif // ALLOY_BACKEND_ASSEMBLER_H_ diff --git a/src/alloy/backend/backend.cc b/src/alloy/backend/backend.cc index d49fb713e..e28100522 100644 --- a/src/alloy/backend/backend.cc +++ b/src/alloy/backend/backend.cc @@ -11,26 +11,22 @@ #include -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::runtime; +namespace alloy { +namespace backend { +using alloy::runtime::Runtime; -Backend::Backend(Runtime* runtime) : - runtime_(runtime) { +Backend::Backend(Runtime* runtime) : runtime_(runtime) { xe_zero_struct(&machine_info_, sizeof(machine_info_)); } -Backend::~Backend() { -} +Backend::~Backend() {} -int Backend::Initialize() { - return 0; -} +int Backend::Initialize() { return 0; } -void* Backend::AllocThreadData() { - return NULL; -} +void* Backend::AllocThreadData() { return NULL; } -void Backend::FreeThreadData(void* thread_data) { -} +void Backend::FreeThreadData(void* thread_data) {} + +} // namespace backend +} // namespace alloy diff --git a/src/alloy/backend/backend.h b/src/alloy/backend/backend.h index b6c2c431e..7f3124646 100644 --- a/src/alloy/backend/backend.h +++ b/src/alloy/backend/backend.h @@ -13,17 +13,19 @@ #include #include - -namespace alloy { namespace runtime { class Runtime; } } +namespace alloy { +namespace runtime { +class Runtime; +} // namespace runtime +} // namespace alloy namespace alloy { namespace backend { class Assembler; - class Backend { -public: + public: Backend(runtime::Runtime* runtime); virtual ~Backend(); @@ -37,14 +39,12 @@ public: virtual Assembler* CreateAssembler() = 0; -protected: + protected: runtime::Runtime* runtime_; MachineInfo machine_info_; }; - } // namespace backend } // namespace alloy - #endif // ALLOY_BACKEND_BACKEND_H_ diff --git a/src/alloy/backend/ivm/ivm_assembler.cc b/src/alloy/backend/ivm/ivm_assembler.cc index 0431f7ab2..67d8c63b2 100644 --- a/src/alloy/backend/ivm/ivm_assembler.cc +++ b/src/alloy/backend/ivm/ivm_assembler.cc @@ -17,21 +17,19 @@ #include #include -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::backend::ivm; -using namespace alloy::hir; -using namespace alloy::runtime; +namespace alloy { +namespace backend { +namespace ivm { +using alloy::hir::HIRBuilder; +using alloy::runtime::Function; +using alloy::runtime::FunctionInfo; -IVMAssembler::IVMAssembler(Backend* backend) : - source_map_arena_(128 * 1024), - Assembler(backend) { -} +IVMAssembler::IVMAssembler(Backend* backend) + : source_map_arena_(128 * 1024), Assembler(backend) {} IVMAssembler::~IVMAssembler() { - alloy::tracing::WriteEvent(EventType::AssemblerDeinit({ - })); + alloy::tracing::WriteEvent(EventType::AssemblerDeinit({})); } int IVMAssembler::Initialize() { @@ -40,8 +38,7 @@ int IVMAssembler::Initialize() { return result; } - alloy::tracing::WriteEvent(EventType::AssemblerInit({ - })); + alloy::tracing::WriteEvent(EventType::AssemblerInit({})); return result; } @@ -53,10 +50,10 @@ void IVMAssembler::Reset() { Assembler::Reset(); } -int IVMAssembler::Assemble( - FunctionInfo* symbol_info, HIRBuilder* builder, - uint32_t debug_info_flags, runtime::DebugInfo* debug_info, - Function** out_function) { +int IVMAssembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder, + uint32_t debug_info_flags, + runtime::DebugInfo* debug_info, + Function** out_function) { IVMFunction* fn = new IVMFunction(symbol_info); fn->set_debug_info(debug_info); @@ -89,13 +86,13 @@ int IVMAssembler::Assemble( auto block = builder->first_block(); while (block) { - Label* label = block->label_head; + auto label = block->label_head; while (label) { label->tag = (void*)(0x80000000 | ctx.intcode_count); label = label->next; } - Instr* i = block->instr_head; + auto i = block->instr_head; while (i) { int result = TranslateIntCodes(ctx, i); i = i->next; @@ -108,7 +105,8 @@ int IVMAssembler::Assemble( // Fixup label references. LabelRef* label_ref = ctx.label_ref_head; while (label_ref) { - label_ref->instr->src1_reg = (uint32_t)(intptr_t)label_ref->label->tag & ~0x80000000; + label_ref->instr->src1_reg = + (uint32_t)(intptr_t)label_ref->label->tag & ~0x80000000; label_ref = label_ref->next; } @@ -117,3 +115,7 @@ int IVMAssembler::Assemble( *out_function = fn; return 0; } + +} // namespace ivm +} // namespace backend +} // namespace alloy diff --git a/src/alloy/backend/ivm/ivm_assembler.h b/src/alloy/backend/ivm/ivm_assembler.h index 5da5a2412..04f4c142d 100644 --- a/src/alloy/backend/ivm/ivm_assembler.h +++ b/src/alloy/backend/ivm/ivm_assembler.h @@ -14,14 +14,12 @@ #include - namespace alloy { namespace backend { namespace ivm { - class IVMAssembler : public Assembler { -public: + public: IVMAssembler(Backend* backend); virtual ~IVMAssembler(); @@ -29,21 +27,19 @@ public: virtual void Reset(); - virtual int Assemble( - runtime::FunctionInfo* symbol_info, hir::HIRBuilder* builder, - uint32_t debug_info_flags, runtime::DebugInfo* debug_info, - runtime::Function** out_function); + virtual int Assemble(runtime::FunctionInfo* symbol_info, + hir::HIRBuilder* builder, uint32_t debug_info_flags, + runtime::DebugInfo* debug_info, + runtime::Function** out_function); -private: - Arena intcode_arena_; - Arena source_map_arena_; - Arena scratch_arena_; + private: + Arena intcode_arena_; + Arena source_map_arena_; + Arena scratch_arena_; }; - } // namespace ivm } // namespace backend } // namespace alloy - #endif // ALLOY_BACKEND_IVM_IVM_ASSEMBLER_H_ diff --git a/src/alloy/backend/ivm/ivm_backend.cc b/src/alloy/backend/ivm/ivm_backend.cc index 67703f7d4..7f738142a 100644 --- a/src/alloy/backend/ivm/ivm_backend.cc +++ b/src/alloy/backend/ivm/ivm_backend.cc @@ -13,20 +13,15 @@ #include #include -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::backend::ivm; -using namespace alloy::runtime; +namespace alloy { +namespace backend { +namespace ivm { +using alloy::runtime::Runtime; -IVMBackend::IVMBackend(Runtime* runtime) : - Backend(runtime) { -} +IVMBackend::IVMBackend(Runtime* runtime) : Backend(runtime) {} -IVMBackend::~IVMBackend() { - alloy::tracing::WriteEvent(EventType::Deinit({ - })); -} +IVMBackend::~IVMBackend() { alloy::tracing::WriteEvent(EventType::Deinit({})); } int IVMBackend::Initialize() { int result = Backend::Initialize(); @@ -35,34 +30,28 @@ int IVMBackend::Initialize() { } machine_info_.register_sets[0] = { - 0, - "gpr", - MachineInfo::RegisterSet::INT_TYPES, - 16, + 0, "gpr", MachineInfo::RegisterSet::INT_TYPES, 16, }; machine_info_.register_sets[1] = { - 1, - "vec", - MachineInfo::RegisterSet::FLOAT_TYPES | - MachineInfo::RegisterSet::VEC_TYPES, - 16, + 1, "vec", MachineInfo::RegisterSet::FLOAT_TYPES | + MachineInfo::RegisterSet::VEC_TYPES, + 16, }; - alloy::tracing::WriteEvent(EventType::Init({ - })); + alloy::tracing::WriteEvent(EventType::Init({})); return result; } -void* IVMBackend::AllocThreadData() { - return new IVMStack(); -} +void* IVMBackend::AllocThreadData() { return new IVMStack(); } void IVMBackend::FreeThreadData(void* thread_data) { auto stack = (IVMStack*)thread_data; delete stack; } -Assembler* IVMBackend::CreateAssembler() { - return new IVMAssembler(this); -} +Assembler* IVMBackend::CreateAssembler() { return new IVMAssembler(this); } + +} // namespace ivm +} // namespace backend +} // namespace alloy diff --git a/src/alloy/backend/ivm/ivm_backend.h b/src/alloy/backend/ivm/ivm_backend.h index 8ed333838..5311e56f2 100644 --- a/src/alloy/backend/ivm/ivm_backend.h +++ b/src/alloy/backend/ivm/ivm_backend.h @@ -14,17 +14,14 @@ #include - namespace alloy { namespace backend { namespace ivm { - #define ALLOY_HAS_IVM_BACKEND 1 - class IVMBackend : public Backend { -public: + public: IVMBackend(runtime::Runtime* runtime); virtual ~IVMBackend(); @@ -36,10 +33,8 @@ public: virtual Assembler* CreateAssembler(); }; - } // namespace ivm } // namespace backend } // namespace alloy - #endif // ALLOY_BACKEND_IVM_IVM_BACKEND_H_ diff --git a/src/alloy/backend/ivm/ivm_function.cc b/src/alloy/backend/ivm/ivm_function.cc index 88306b228..4ed6a13b9 100644 --- a/src/alloy/backend/ivm/ivm_function.cc +++ b/src/alloy/backend/ivm/ivm_function.cc @@ -14,17 +14,21 @@ #include #include -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::backend::ivm; -using namespace alloy::runtime; +namespace alloy { +namespace backend { +namespace ivm { +using alloy::runtime::Breakpoint; +using alloy::runtime::FunctionInfo; +using alloy::runtime::ThreadState; -IVMFunction::IVMFunction(FunctionInfo* symbol_info) : - register_count_(0), intcode_count_(0), intcodes_(0), - source_map_count_(0), source_map_(0), - Function(symbol_info) { -} +IVMFunction::IVMFunction(FunctionInfo* symbol_info) + : register_count_(0), + intcode_count_(0), + intcodes_(0), + source_map_count_(0), + source_map_(0), + Function(symbol_info) {} IVMFunction::~IVMFunction() { xe_free(intcodes_); @@ -57,8 +61,7 @@ int IVMFunction::AddBreakpointImpl(Breakpoint* breakpoint) { } // TEMP breakpoints always overwrite normal ones. - if (!i->debug_flags || - breakpoint->type() == Breakpoint::TEMP_TYPE) { + if (!i->debug_flags || breakpoint->type() == Breakpoint::TEMP_TYPE) { uint64_t breakpoint_ptr = (uint64_t)breakpoint; i->src2_reg = (uint32_t)breakpoint_ptr; i->src3_reg = (uint32_t)(breakpoint_ptr >> 32); @@ -127,8 +130,8 @@ int IVMFunction::CallImpl(ThreadState* thread_state, uint64_t return_address) { volatile int* suspend_flag_address = thread_state->suspend_flag_address(); - // TODO(benvanik): DID_CARRY -- need HIR to set a OPCODE_FLAG_SET_CARRY - // or something so the fns can set an ics flag. +// TODO(benvanik): DID_CARRY -- need HIR to set a OPCODE_FLAG_SET_CARRY +// or something so the fns can set an ics flag. #ifdef TRACE_SOURCE_OFFSET size_t source_index = 0; @@ -177,3 +180,7 @@ int IVMFunction::CallImpl(ThreadState* thread_state, uint64_t return_address) { return 0; } + +} // namespace ivm +} // namespace backend +} // namespace alloy diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index 109bb19a9..27ea32345 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -14,26 +14,29 @@ #include #include -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::backend::ivm; -using namespace alloy::hir; -using namespace alloy::runtime; - - // TODO(benvanik): reimplement packing functions #include - // TODO(benvanik): make a compile time flag? //#define DYNAMIC_REGISTER_ACCESS_CHECK(address) false -#define DYNAMIC_REGISTER_ACCESS_CHECK(address) ((address & 0xFF000000) == 0x7F000000) - +#define DYNAMIC_REGISTER_ACCESS_CHECK(address) \ + ((address & 0xFF000000) == 0x7F000000) namespace alloy { namespace backend { namespace ivm { +// TODO(benvanik): remove when enums redefined. +using namespace alloy::hir; + +using alloy::hir::Instr; +using alloy::hir::Label; +using alloy::hir::OpcodeInfo; +using alloy::hir::OpcodeSignatureType; +using alloy::hir::TypeName; +using alloy::hir::Value; +using alloy::runtime::Function; +using alloy::runtime::FunctionInfo; #define IPRINT #define IFLUSH() @@ -46,27 +49,21 @@ namespace ivm { //#define DFLUSH() fflush(stdout) #if XE_CPU_BIGENDIAN -#define VECB16(v,n) (v.b16[n]) -#define VECS8(v,n) (v.s8[n]) -#define VECI4(v,n) (v.i4[n]) -#define VECF4(v,n) (v.f4[n]) +#define VECB16(v, n) (v.b16[n]) +#define VECS8(v, n) (v.s8[n]) +#define VECI4(v, n) (v.i4[n]) +#define VECF4(v, n) (v.f4[n]) #else static const uint8_t __vector_b16_table[16] = { - 3, 2, 1, 0, - 7, 6, 5, 4, - 11, 10, 9, 8, - 15, 14, 13, 12, + 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12, }; static const uint8_t __vector_s8_table[8] = { - 1, 0, - 3, 2, - 5, 4, - 7, 6, + 1, 0, 3, 2, 5, 4, 7, 6, }; -#define VECB16(v,n) (v.b16[__vector_b16_table[(n)]]) -#define VECS8(v,n) (v.s8[__vector_s8_table[(n)]]) -#define VECI4(v,n) (v.i4[(n)]) -#define VECF4(v,n) (v.f4[(n)]) +#define VECB16(v, n) (v.b16[__vector_b16_table[(n)]]) +#define VECS8(v, n) (v.s8[__vector_s8_table[(n)]]) +#define VECI4(v, n) (v.i4[(n)]) +#define VECF4(v, n) (v.f4[(n)]) #endif uint32_t IntCode_INT_LOAD_CONSTANT(IntCodeState& ics, const IntCode* i) { @@ -136,25 +133,25 @@ uint32_t AllocDynamicRegister(TranslationContext& ctx, Value* value) { } } -uint32_t AllocOpRegister( - TranslationContext& ctx, OpcodeSignatureType sig_type, Instr::Op* op) { +uint32_t AllocOpRegister(TranslationContext& ctx, OpcodeSignatureType sig_type, + Instr::Op* op) { switch (sig_type) { - case OPCODE_SIG_TYPE_X: - // Nothing. - return 0; - case OPCODE_SIG_TYPE_L: - return AllocLabel(ctx, op->label); - case OPCODE_SIG_TYPE_O: - return AllocConstant(ctx, (uint64_t)op->offset); - case OPCODE_SIG_TYPE_S: - return AllocConstant(ctx, (uint64_t)op->symbol_info); - case OPCODE_SIG_TYPE_V: - Value* value = op->value; - if (value->IsConstant()) { - return AllocConstant(ctx, value); - } else { - return AllocDynamicRegister(ctx, value); - } + case OPCODE_SIG_TYPE_X: + // Nothing. + return 0; + case OPCODE_SIG_TYPE_L: + return AllocLabel(ctx, op->label); + case OPCODE_SIG_TYPE_O: + return AllocConstant(ctx, (uint64_t)op->offset); + case OPCODE_SIG_TYPE_S: + return AllocConstant(ctx, (uint64_t)op->symbol_info); + case OPCODE_SIG_TYPE_V: + Value* value = op->value; + if (value->IsConstant()) { + return AllocConstant(ctx, value); + } else { + return AllocDynamicRegister(ctx, value); + } } return 0; } @@ -228,9 +225,7 @@ int Translate_COMMENT(TranslationContext& ctx, Instr* i) { return 0; } -uint32_t IntCode_NOP(IntCodeState& ics, const IntCode* i) { - return IA_NEXT; -} +uint32_t IntCode_NOP(IntCodeState& ics, const IntCode* i) { return IA_NEXT; } int Translate_NOP(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, IntCode_NOP); } @@ -297,13 +292,10 @@ uint32_t IntCode_DEBUG_BREAK_TRUE_F64(IntCodeState& ics, const IntCode* i) { } int Translate_DEBUG_BREAK_TRUE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_DEBUG_BREAK_TRUE_I8, - IntCode_DEBUG_BREAK_TRUE_I16, - IntCode_DEBUG_BREAK_TRUE_I32, - IntCode_DEBUG_BREAK_TRUE_I64, - IntCode_DEBUG_BREAK_TRUE_F32, - IntCode_DEBUG_BREAK_TRUE_F64, - IntCode_INVALID_TYPE, + IntCode_DEBUG_BREAK_TRUE_I8, IntCode_DEBUG_BREAK_TRUE_I16, + IntCode_DEBUG_BREAK_TRUE_I32, IntCode_DEBUG_BREAK_TRUE_I64, + IntCode_DEBUG_BREAK_TRUE_F32, IntCode_DEBUG_BREAK_TRUE_F64, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } @@ -311,12 +303,12 @@ int Translate_DEBUG_BREAK_TRUE(TranslationContext& ctx, Instr* i) { uint32_t IntCode_TRAP(IntCodeState& ics, const IntCode* i) { // TODO(benvanik): post software interrupt to debugger. switch (i->flags) { - case 20: - // 0x0FE00014 is a 'debug print' where r3 = buffer r4 = length - break; - case 22: - // Always trap? - break; + case 20: + // 0x0FE00014 is a 'debug print' where r3 = buffer r4 = length + break; + case 22: + // Always trap? + break; } __debugbreak(); return IA_NEXT; @@ -363,13 +355,9 @@ uint32_t IntCode_TRAP_TRUE_F64(IntCodeState& ics, const IntCode* i) { } int Translate_TRAP_TRUE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_TRAP_TRUE_I8, - IntCode_TRAP_TRUE_I16, - IntCode_TRAP_TRUE_I32, - IntCode_TRAP_TRUE_I64, - IntCode_TRAP_TRUE_F32, - IntCode_TRAP_TRUE_F64, - IntCode_INVALID_TYPE, + IntCode_TRAP_TRUE_I8, IntCode_TRAP_TRUE_I16, IntCode_TRAP_TRUE_I32, + IntCode_TRAP_TRUE_I64, IntCode_TRAP_TRUE_F32, IntCode_TRAP_TRUE_F64, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } @@ -435,18 +423,15 @@ uint32_t IntCode_CALL_TRUE_F64(IntCodeState& ics, const IntCode* i) { } int Translate_CALL_TRUE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_CALL_TRUE_I8, - IntCode_CALL_TRUE_I16, - IntCode_CALL_TRUE_I32, - IntCode_CALL_TRUE_I64, - IntCode_CALL_TRUE_F32, - IntCode_CALL_TRUE_F64, - IntCode_INVALID_TYPE, + IntCode_CALL_TRUE_I8, IntCode_CALL_TRUE_I16, IntCode_CALL_TRUE_I32, + IntCode_CALL_TRUE_I64, IntCode_CALL_TRUE_F32, IntCode_CALL_TRUE_F64, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } -uint32_t IntCode_CALL_INDIRECT_XX(IntCodeState& ics, const IntCode* i, uint32_t reg) { +uint32_t IntCode_CALL_INDIRECT_XX(IntCodeState& ics, const IntCode* i, + uint32_t reg) { uint64_t target = ics.rf[reg].u32; // Check if return address - if so, return. @@ -514,13 +499,10 @@ uint32_t IntCode_CALL_INDIRECT_TRUE_F64(IntCodeState& ics, const IntCode* i) { } int Translate_CALL_INDIRECT_TRUE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_CALL_INDIRECT_TRUE_I8, - IntCode_CALL_INDIRECT_TRUE_I16, - IntCode_CALL_INDIRECT_TRUE_I32, - IntCode_CALL_INDIRECT_TRUE_I64, - IntCode_CALL_INDIRECT_TRUE_F32, - IntCode_CALL_INDIRECT_TRUE_F64, - IntCode_INVALID_TYPE, + IntCode_CALL_INDIRECT_TRUE_I8, IntCode_CALL_INDIRECT_TRUE_I16, + IntCode_CALL_INDIRECT_TRUE_I32, IntCode_CALL_INDIRECT_TRUE_I64, + IntCode_CALL_INDIRECT_TRUE_F32, IntCode_CALL_INDIRECT_TRUE_F64, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } @@ -577,13 +559,9 @@ uint32_t IntCode_RETURN_TRUE_F64(IntCodeState& ics, const IntCode* i) { } int Translate_RETURN_TRUE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_RETURN_TRUE_I8, - IntCode_RETURN_TRUE_I16, - IntCode_RETURN_TRUE_I32, - IntCode_RETURN_TRUE_I64, - IntCode_RETURN_TRUE_F32, - IntCode_RETURN_TRUE_F64, - IntCode_INVALID_TYPE, + IntCode_RETURN_TRUE_I8, IntCode_RETURN_TRUE_I16, IntCode_RETURN_TRUE_I32, + IntCode_RETURN_TRUE_I64, IntCode_RETURN_TRUE_F32, IntCode_RETURN_TRUE_F64, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } @@ -644,13 +622,9 @@ uint32_t IntCode_BRANCH_TRUE_F64(IntCodeState& ics, const IntCode* i) { } int Translate_BRANCH_TRUE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_BRANCH_TRUE_I8, - IntCode_BRANCH_TRUE_I16, - IntCode_BRANCH_TRUE_I32, - IntCode_BRANCH_TRUE_I64, - IntCode_BRANCH_TRUE_F32, - IntCode_BRANCH_TRUE_F64, - IntCode_INVALID_TYPE, + IntCode_BRANCH_TRUE_I8, IntCode_BRANCH_TRUE_I16, IntCode_BRANCH_TRUE_I32, + IntCode_BRANCH_TRUE_I64, IntCode_BRANCH_TRUE_F32, IntCode_BRANCH_TRUE_F64, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } @@ -693,13 +667,10 @@ uint32_t IntCode_BRANCH_FALSE_F64(IntCodeState& ics, const IntCode* i) { } int Translate_BRANCH_FALSE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_BRANCH_FALSE_I8, - IntCode_BRANCH_FALSE_I16, - IntCode_BRANCH_FALSE_I32, - IntCode_BRANCH_FALSE_I64, - IntCode_BRANCH_FALSE_F32, - IntCode_BRANCH_FALSE_F64, - IntCode_INVALID_TYPE, + IntCode_BRANCH_FALSE_I8, IntCode_BRANCH_FALSE_I16, + IntCode_BRANCH_FALSE_I32, IntCode_BRANCH_FALSE_I64, + IntCode_BRANCH_FALSE_F32, IntCode_BRANCH_FALSE_F64, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } @@ -734,13 +705,9 @@ uint32_t IntCode_ASSIGN_V128(IntCodeState& ics, const IntCode* i) { } int Translate_ASSIGN(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_ASSIGN_I8, - IntCode_ASSIGN_I16, - IntCode_ASSIGN_I32, - IntCode_ASSIGN_I64, - IntCode_ASSIGN_F32, - IntCode_ASSIGN_F64, - IntCode_ASSIGN_V128, + IntCode_ASSIGN_I8, IntCode_ASSIGN_I16, IntCode_ASSIGN_I32, + IntCode_ASSIGN_I64, IntCode_ASSIGN_F32, IntCode_ASSIGN_F64, + IntCode_ASSIGN_V128, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -779,13 +746,31 @@ uint32_t IntCode_ZERO_EXTEND_I32_TO_I64(IntCodeState& ics, const IntCode* i) { } int Translate_ZERO_EXTEND(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_ASSIGN_I8, IntCode_ZERO_EXTEND_I8_TO_I16, IntCode_ZERO_EXTEND_I8_TO_I32, IntCode_ZERO_EXTEND_I8_TO_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_ASSIGN_I16, IntCode_ZERO_EXTEND_I16_TO_I32, IntCode_ZERO_EXTEND_I16_TO_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_ASSIGN_I32, IntCode_ZERO_EXTEND_I32_TO_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_ASSIGN_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_ASSIGN_I8, IntCode_ZERO_EXTEND_I8_TO_I16, + IntCode_ZERO_EXTEND_I8_TO_I32, IntCode_ZERO_EXTEND_I8_TO_I64, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_ASSIGN_I16, IntCode_ZERO_EXTEND_I16_TO_I32, + IntCode_ZERO_EXTEND_I16_TO_I64, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_ASSIGN_I32, IntCode_ZERO_EXTEND_I32_TO_I64, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_ASSIGN_I64, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; IntCodeFn fn = fns[i->src1.value->type * MAX_TYPENAME + i->dest->type]; return DispatchToC(ctx, i, fn); @@ -817,13 +802,31 @@ uint32_t IntCode_SIGN_EXTEND_I32_TO_I64(IntCodeState& ics, const IntCode* i) { } int Translate_SIGN_EXTEND(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_ASSIGN_I8, IntCode_SIGN_EXTEND_I8_TO_I16, IntCode_SIGN_EXTEND_I8_TO_I32, IntCode_SIGN_EXTEND_I8_TO_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_ASSIGN_I16, IntCode_SIGN_EXTEND_I16_TO_I32, IntCode_SIGN_EXTEND_I16_TO_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_ASSIGN_I32, IntCode_SIGN_EXTEND_I32_TO_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_ASSIGN_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_ASSIGN_I8, IntCode_SIGN_EXTEND_I8_TO_I16, + IntCode_SIGN_EXTEND_I8_TO_I32, IntCode_SIGN_EXTEND_I8_TO_I64, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_ASSIGN_I16, IntCode_SIGN_EXTEND_I16_TO_I32, + IntCode_SIGN_EXTEND_I16_TO_I64, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_ASSIGN_I32, IntCode_SIGN_EXTEND_I32_TO_I64, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_ASSIGN_I64, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; IntCodeFn fn = fns[i->src1.value->type * MAX_TYPENAME + i->dest->type]; return DispatchToC(ctx, i, fn); @@ -855,13 +858,31 @@ uint32_t IntCode_TRUNCATE_I64_TO_I32(IntCodeState& ics, const IntCode* i) { } int Translate_TRUNCATE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_ASSIGN_I8, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_TRUNCATE_I16_TO_I8, IntCode_ASSIGN_I16, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_TRUNCATE_I32_TO_I8, IntCode_TRUNCATE_I32_TO_I16, IntCode_ASSIGN_I32, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_TRUNCATE_I64_TO_I8, IntCode_TRUNCATE_I64_TO_I16, IntCode_TRUNCATE_I64_TO_I32, IntCode_ASSIGN_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_ASSIGN_I8, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_TRUNCATE_I16_TO_I8, + IntCode_ASSIGN_I16, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_TRUNCATE_I32_TO_I8, IntCode_TRUNCATE_I32_TO_I16, + IntCode_ASSIGN_I32, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_TRUNCATE_I64_TO_I8, + IntCode_TRUNCATE_I64_TO_I16, IntCode_TRUNCATE_I64_TO_I32, + IntCode_ASSIGN_I64, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; IntCodeFn fn = fns[i->src1.value->type * MAX_TYPENAME + i->dest->type]; return DispatchToC(ctx, i, fn); @@ -898,13 +919,31 @@ uint32_t IntCode_CONVERT_F64_TO_F32(IntCodeState& ics, const IntCode* i) { int Translate_CONVERT(TranslationContext& ctx, Instr* i) { // Can do more as needed. static IntCodeFn fns[] = { - IntCode_ASSIGN_I8, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_ASSIGN_I16, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_ASSIGN_I32, IntCode_INVALID_TYPE, IntCode_CONVERT_I32_TO_F32, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_ASSIGN_I64, IntCode_INVALID_TYPE, IntCode_CONVERT_I64_TO_F64, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_CONVERT_F32_TO_I32, IntCode_INVALID_TYPE, IntCode_ASSIGN_F32, IntCode_CONVERT_F32_TO_F64, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_CONVERT_F64_TO_I32, IntCode_CONVERT_F64_TO_I64, IntCode_CONVERT_F64_TO_F32, IntCode_ASSIGN_F64, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_ASSIGN_V128, + IntCode_ASSIGN_I8, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_ASSIGN_I16, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_ASSIGN_I32, IntCode_INVALID_TYPE, + IntCode_CONVERT_I32_TO_F32, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_ASSIGN_I64, IntCode_INVALID_TYPE, + IntCode_CONVERT_I64_TO_F64, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_CONVERT_F32_TO_I32, IntCode_INVALID_TYPE, + IntCode_ASSIGN_F32, IntCode_CONVERT_F32_TO_F64, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_CONVERT_F64_TO_I32, + IntCode_CONVERT_F64_TO_I64, IntCode_CONVERT_F64_TO_F32, + IntCode_ASSIGN_F64, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_ASSIGN_V128, }; IntCodeFn fn = fns[i->src1.value->type * MAX_TYPENAME + i->dest->type]; return DispatchToC(ctx, i, fn); @@ -914,18 +953,18 @@ uint32_t IntCode_ROUND_F32(IntCodeState& ics, const IntCode* i) { float src1 = ics.rf[i->src1_reg].f32; float dest = src1; switch (i->flags) { - case ROUND_TO_ZERO: - dest = truncf(src1); - break; - case ROUND_TO_NEAREST: - dest = roundf(src1); - break; - case ROUND_TO_MINUS_INFINITY: - dest = floorf(src1); - break; - case ROUND_TO_POSITIVE_INFINITY: - dest = ceilf(src1); - break; + case ROUND_TO_ZERO: + dest = truncf(src1); + break; + case ROUND_TO_NEAREST: + dest = roundf(src1); + break; + case ROUND_TO_MINUS_INFINITY: + dest = floorf(src1); + break; + case ROUND_TO_POSITIVE_INFINITY: + dest = ceilf(src1); + break; } ics.rf[i->dest_reg].f32 = dest; return IA_NEXT; @@ -934,18 +973,18 @@ uint32_t IntCode_ROUND_F64(IntCodeState& ics, const IntCode* i) { double src1 = ics.rf[i->src1_reg].f64; double dest = src1; switch (i->flags) { - case ROUND_TO_ZERO: - dest = trunc(src1); - break; - case ROUND_TO_NEAREST: - dest = round(src1); - break; - case ROUND_TO_MINUS_INFINITY: - dest = floor(src1); - break; - case ROUND_TO_POSITIVE_INFINITY: - dest = ceil(src1); - break; + case ROUND_TO_ZERO: + dest = trunc(src1); + break; + case ROUND_TO_NEAREST: + dest = round(src1); + break; + case ROUND_TO_MINUS_INFINITY: + dest = floor(src1); + break; + case ROUND_TO_POSITIVE_INFINITY: + dest = ceil(src1); + break; } ics.rf[i->dest_reg].f64 = dest; return IA_NEXT; @@ -966,7 +1005,8 @@ uint32_t IntCode_ROUND_V128_NEAREST(IntCodeState& ics, const IntCode* i) { } return IA_NEXT; } -uint32_t IntCode_ROUND_V128_MINUS_INFINITY(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_ROUND_V128_MINUS_INFINITY(IntCodeState& ics, + const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (size_t n = 0; n < 4; n++) { @@ -974,7 +1014,8 @@ uint32_t IntCode_ROUND_V128_MINUS_INFINITY(IntCodeState& ics, const IntCode* i) } return IA_NEXT; } -uint32_t IntCode_ROUND_V128_POSITIVE_INFINTIY(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_ROUND_V128_POSITIVE_INFINTIY(IntCodeState& ics, + const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (size_t n = 0; n < 4; n++) { @@ -985,21 +1026,15 @@ uint32_t IntCode_ROUND_V128_POSITIVE_INFINTIY(IntCodeState& ics, const IntCode* int Translate_ROUND(TranslationContext& ctx, Instr* i) { if (i->dest->type == VEC128_TYPE) { static IntCodeFn fns[] = { - IntCode_ROUND_V128_ZERO, - IntCode_ROUND_V128_NEAREST, - IntCode_ROUND_V128_MINUS_INFINITY, - IntCode_ROUND_V128_POSITIVE_INFINTIY, + IntCode_ROUND_V128_ZERO, IntCode_ROUND_V128_NEAREST, + IntCode_ROUND_V128_MINUS_INFINITY, IntCode_ROUND_V128_POSITIVE_INFINTIY, }; return DispatchToC(ctx, i, fns[i->flags]); } else { static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_ROUND_F32, - IntCode_ROUND_F64, - IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_ROUND_F32, IntCode_ROUND_F64, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -1008,19 +1043,19 @@ int Translate_ROUND(TranslationContext& ctx, Instr* i) { uint32_t IntCode_VECTOR_CONVERT_I2F_S(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; - VECF4(dest,0) = (float)(int32_t)VECI4(src1,0); - VECF4(dest,1) = (float)(int32_t)VECI4(src1,1); - VECF4(dest,2) = (float)(int32_t)VECI4(src1,2); - VECF4(dest,3) = (float)(int32_t)VECI4(src1,3); + VECF4(dest, 0) = (float)(int32_t)VECI4(src1, 0); + VECF4(dest, 1) = (float)(int32_t)VECI4(src1, 1); + VECF4(dest, 2) = (float)(int32_t)VECI4(src1, 2); + VECF4(dest, 3) = (float)(int32_t)VECI4(src1, 3); return IA_NEXT; } uint32_t IntCode_VECTOR_CONVERT_I2F_U(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; - VECF4(dest,0) = (float)(uint32_t)VECI4(src1,0); - VECF4(dest,1) = (float)(uint32_t)VECI4(src1,1); - VECF4(dest,2) = (float)(uint32_t)VECI4(src1,2); - VECF4(dest,3) = (float)(uint32_t)VECI4(src1,3); + VECF4(dest, 0) = (float)(uint32_t)VECI4(src1, 0); + VECF4(dest, 1) = (float)(uint32_t)VECI4(src1, 1); + VECF4(dest, 2) = (float)(uint32_t)VECI4(src1, 2); + VECF4(dest, 3) = (float)(uint32_t)VECI4(src1, 3); return IA_NEXT; } int Translate_VECTOR_CONVERT_I2F(TranslationContext& ctx, Instr* i) { @@ -1035,15 +1070,15 @@ uint32_t IntCode_VECTOR_CONVERT_F2I(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; if (i->flags & ARITHMETIC_UNSIGNED) { - VECI4(dest,0) = (uint32_t)VECF4(src1,0); - VECI4(dest,1) = (uint32_t)VECF4(src1,1); - VECI4(dest,2) = (uint32_t)VECF4(src1,2); - VECI4(dest,3) = (uint32_t)VECF4(src1,3); + VECI4(dest, 0) = (uint32_t)VECF4(src1, 0); + VECI4(dest, 1) = (uint32_t)VECF4(src1, 1); + VECI4(dest, 2) = (uint32_t)VECF4(src1, 2); + VECI4(dest, 3) = (uint32_t)VECF4(src1, 3); } else { - VECI4(dest,0) = (int32_t)VECF4(src1,0); - VECI4(dest,1) = (int32_t)VECF4(src1,1); - VECI4(dest,2) = (int32_t)VECF4(src1,2); - VECI4(dest,3) = (int32_t)VECF4(src1,3); + VECI4(dest, 0) = (int32_t)VECF4(src1, 0); + VECI4(dest, 1) = (int32_t)VECF4(src1, 1); + VECI4(dest, 2) = (int32_t)VECF4(src1, 2); + VECI4(dest, 3) = (int32_t)VECF4(src1, 3); } return IA_NEXT; } @@ -1054,26 +1089,26 @@ uint32_t IntCode_VECTOR_CONVERT_F2I_SAT(IntCodeState& ics, const IntCode* i) { for (int n = 0; n < 4; n++) { float src = src1.f4[n]; if (src < 0) { - VECI4(dest,n) = 0; + VECI4(dest, n) = 0; ics.did_saturate = 1; } else if (src > UINT_MAX) { - VECI4(dest,n) = UINT_MAX; + VECI4(dest, n) = UINT_MAX; ics.did_saturate = 1; } else { - VECI4(dest,n) = (uint32_t)src; + VECI4(dest, n) = (uint32_t)src; } } } else { for (int n = 0; n < 4; n++) { float src = src1.f4[n]; if (src < INT_MIN) { - VECI4(dest,n) = INT_MIN; + VECI4(dest, n) = INT_MIN; ics.did_saturate = 1; } else if (src > INT_MAX) { - VECI4(dest,n) = INT_MAX; + VECI4(dest, n) = INT_MAX; ics.did_saturate = 1; } else { - VECI4(dest,n) = (int32_t)src; + VECI4(dest, n) = (int32_t)src; } } } @@ -1088,49 +1123,49 @@ int Translate_VECTOR_CONVERT_F2I(TranslationContext& ctx, Instr* i) { } static uint8_t __lvsl_table[17][16] = { - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, - { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, - { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, - { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}, - { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}, - { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, - { 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}, - { 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}, - { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}, - { 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}, - {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}, - {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}, - {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27}, - {13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28}, - {14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}, - {15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}, - {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, + {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}, + {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}, + {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, + {6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}, + {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}, + {8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}, + {9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}, + {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}, + {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27}, + {13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28}, + {14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}, + {15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}, + {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, }; static uint8_t __lvsr_table[17][16] = { - {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, - {15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}, - {14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}, - {13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28}, - {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27}, - {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}, - {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}, - { 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}, - { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}, - { 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}, - { 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}, - { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, - { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}, - { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}, - { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, - { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, + {15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}, + {14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}, + {13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28}, + {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}, + {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}, + {9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}, + {8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}, + {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}, + {6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}, + {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, + {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}, + {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}, + {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, }; uint32_t IntCode_LOAD_VECTOR_SHL(IntCodeState& ics, const IntCode* i) { int8_t sh = MIN(16, ics.rf[i->src1_reg].i8); vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 16; n++) { - VECB16(dest,n) = __lvsl_table[sh][n]; + VECB16(dest, n) = __lvsl_table[sh][n]; } return IA_NEXT; } @@ -1142,7 +1177,7 @@ uint32_t IntCode_LOAD_VECTOR_SHR(IntCodeState& ics, const IntCode* i) { int8_t sh = MIN(16, ics.rf[i->src1_reg].i8); vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 16; n++) { - VECB16(dest,n) = __lvsr_table[sh][n]; + VECB16(dest, n) = __lvsr_table[sh][n]; } return IA_NEXT; } @@ -1188,18 +1223,15 @@ uint32_t IntCode_LOAD_LOCAL_F64(IntCodeState& ics, const IntCode* i) { return IA_NEXT; } uint32_t IntCode_LOAD_LOCAL_V128(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].v128 = *((vec128_t*)(ics.locals + ics.rf[i->src1_reg].u32)); + ics.rf[i->dest_reg].v128 = + *((vec128_t*)(ics.locals + ics.rf[i->src1_reg].u32)); return IA_NEXT; } int Translate_LOAD_LOCAL(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_LOAD_LOCAL_I8, - IntCode_LOAD_LOCAL_I16, - IntCode_LOAD_LOCAL_I32, - IntCode_LOAD_LOCAL_I64, - IntCode_LOAD_LOCAL_F32, - IntCode_LOAD_LOCAL_F64, - IntCode_LOAD_LOCAL_V128, + IntCode_LOAD_LOCAL_I8, IntCode_LOAD_LOCAL_I16, IntCode_LOAD_LOCAL_I32, + IntCode_LOAD_LOCAL_I64, IntCode_LOAD_LOCAL_F32, IntCode_LOAD_LOCAL_F64, + IntCode_LOAD_LOCAL_V128, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -1229,119 +1261,136 @@ uint32_t IntCode_STORE_LOCAL_F64(IntCodeState& ics, const IntCode* i) { return IA_NEXT; } uint32_t IntCode_STORE_LOCAL_V128(IntCodeState& ics, const IntCode* i) { - *((vec128_t*)(ics.locals + ics.rf[i->src1_reg].u32)) = ics.rf[i->src2_reg].v128; + *((vec128_t*)(ics.locals + ics.rf[i->src1_reg].u32)) = + ics.rf[i->src2_reg].v128; return IA_NEXT; } int Translate_STORE_LOCAL(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_STORE_LOCAL_I8, - IntCode_STORE_LOCAL_I16, - IntCode_STORE_LOCAL_I32, - IntCode_STORE_LOCAL_I64, - IntCode_STORE_LOCAL_F32, - IntCode_STORE_LOCAL_F64, - IntCode_STORE_LOCAL_V128, + IntCode_STORE_LOCAL_I8, IntCode_STORE_LOCAL_I16, + IntCode_STORE_LOCAL_I32, IntCode_STORE_LOCAL_I64, + IntCode_STORE_LOCAL_F32, IntCode_STORE_LOCAL_F64, + IntCode_STORE_LOCAL_V128, }; return DispatchToC(ctx, i, fns[i->src2.value->type]); } uint32_t IntCode_LOAD_CONTEXT_I8(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = *((int8_t*)(ics.context + ics.rf[i->src1_reg].u64)); - DPRINT("%d (%X) = ctx i8 +%d\n", ics.rf[i->dest_reg].i8, ics.rf[i->dest_reg].u8, ics.rf[i->src1_reg].u64); + DPRINT("%d (%X) = ctx i8 +%d\n", ics.rf[i->dest_reg].i8, + ics.rf[i->dest_reg].u8, ics.rf[i->src1_reg].u64); return IA_NEXT; } uint32_t IntCode_LOAD_CONTEXT_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = *((int16_t*)(ics.context + ics.rf[i->src1_reg].u64)); - DPRINT("%d (%X) = ctx i16 +%d\n", ics.rf[i->dest_reg].i16, ics.rf[i->dest_reg].u16, ics.rf[i->src1_reg].u64); + ics.rf[i->dest_reg].i16 = + *((int16_t*)(ics.context + ics.rf[i->src1_reg].u64)); + DPRINT("%d (%X) = ctx i16 +%d\n", ics.rf[i->dest_reg].i16, + ics.rf[i->dest_reg].u16, ics.rf[i->src1_reg].u64); return IA_NEXT; } uint32_t IntCode_LOAD_CONTEXT_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = *((int32_t*)(ics.context + ics.rf[i->src1_reg].u64)); - DPRINT("%d (%X) = ctx i32 +%d\n", ics.rf[i->dest_reg].i32, ics.rf[i->dest_reg].u32, ics.rf[i->src1_reg].u64); + ics.rf[i->dest_reg].i32 = + *((int32_t*)(ics.context + ics.rf[i->src1_reg].u64)); + DPRINT("%d (%X) = ctx i32 +%d\n", ics.rf[i->dest_reg].i32, + ics.rf[i->dest_reg].u32, ics.rf[i->src1_reg].u64); return IA_NEXT; } uint32_t IntCode_LOAD_CONTEXT_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = *((int64_t*)(ics.context + ics.rf[i->src1_reg].u64)); - DPRINT("%lld (%llX) = ctx i64 +%d\n", ics.rf[i->dest_reg].i64, ics.rf[i->dest_reg].u64, ics.rf[i->src1_reg].u64); + ics.rf[i->dest_reg].i64 = + *((int64_t*)(ics.context + ics.rf[i->src1_reg].u64)); + DPRINT("%lld (%llX) = ctx i64 +%d\n", ics.rf[i->dest_reg].i64, + ics.rf[i->dest_reg].u64, ics.rf[i->src1_reg].u64); return IA_NEXT; } uint32_t IntCode_LOAD_CONTEXT_F32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].f32 = *((float*)(ics.context + ics.rf[i->src1_reg].u64)); - DPRINT("%e (%X) = ctx f32 +%d\n", ics.rf[i->dest_reg].f32, ics.rf[i->dest_reg].u32, ics.rf[i->src1_reg].u64); + DPRINT("%e (%X) = ctx f32 +%d\n", ics.rf[i->dest_reg].f32, + ics.rf[i->dest_reg].u32, ics.rf[i->src1_reg].u64); return IA_NEXT; } uint32_t IntCode_LOAD_CONTEXT_F64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].f64 = *((double*)(ics.context + ics.rf[i->src1_reg].u64)); - DPRINT("%lle (%llX) = ctx f64 +%d\n", ics.rf[i->dest_reg].f64, ics.rf[i->dest_reg].u64, ics.rf[i->src1_reg].u64); + DPRINT("%lle (%llX) = ctx f64 +%d\n", ics.rf[i->dest_reg].f64, + ics.rf[i->dest_reg].u64, ics.rf[i->src1_reg].u64); return IA_NEXT; } uint32_t IntCode_LOAD_CONTEXT_V128(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].v128 = *((vec128_t*)(ics.context + ics.rf[i->src1_reg].u64)); + ics.rf[i->dest_reg].v128 = + *((vec128_t*)(ics.context + ics.rf[i->src1_reg].u64)); DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = ctx v128 +%d\n", - VECF4(ics.rf[i->dest_reg].v128,0), VECF4(ics.rf[i->dest_reg].v128,1), VECF4(ics.rf[i->dest_reg].v128,2), VECF4(ics.rf[i->dest_reg].v128,3), - VECI4(ics.rf[i->dest_reg].v128,0), VECI4(ics.rf[i->dest_reg].v128,1), VECI4(ics.rf[i->dest_reg].v128,2), VECI4(ics.rf[i->dest_reg].v128,3), + VECF4(ics.rf[i->dest_reg].v128, 0), VECF4(ics.rf[i->dest_reg].v128, 1), + VECF4(ics.rf[i->dest_reg].v128, 2), VECF4(ics.rf[i->dest_reg].v128, 3), + VECI4(ics.rf[i->dest_reg].v128, 0), VECI4(ics.rf[i->dest_reg].v128, 1), + VECI4(ics.rf[i->dest_reg].v128, 2), VECI4(ics.rf[i->dest_reg].v128, 3), ics.rf[i->src1_reg].u64); return IA_NEXT; } int Translate_LOAD_CONTEXT(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_LOAD_CONTEXT_I8, - IntCode_LOAD_CONTEXT_I16, - IntCode_LOAD_CONTEXT_I32, - IntCode_LOAD_CONTEXT_I64, - IntCode_LOAD_CONTEXT_F32, - IntCode_LOAD_CONTEXT_F64, - IntCode_LOAD_CONTEXT_V128, + IntCode_LOAD_CONTEXT_I8, IntCode_LOAD_CONTEXT_I16, + IntCode_LOAD_CONTEXT_I32, IntCode_LOAD_CONTEXT_I64, + IntCode_LOAD_CONTEXT_F32, IntCode_LOAD_CONTEXT_F64, + IntCode_LOAD_CONTEXT_V128, }; return DispatchToC(ctx, i, fns[i->dest->type]); } uint32_t IntCode_STORE_CONTEXT_I8(IntCodeState& ics, const IntCode* i) { *((int8_t*)(ics.context + ics.rf[i->src1_reg].u64)) = ics.rf[i->src2_reg].i8; - DPRINT("ctx i8 +%d = %d (%X)\n", ics.rf[i->src1_reg].u64, ics.rf[i->src2_reg].i8, ics.rf[i->src2_reg].u8); + DPRINT("ctx i8 +%d = %d (%X)\n", ics.rf[i->src1_reg].u64, + ics.rf[i->src2_reg].i8, ics.rf[i->src2_reg].u8); return IA_NEXT; } uint32_t IntCode_STORE_CONTEXT_I16(IntCodeState& ics, const IntCode* i) { - *((int16_t*)(ics.context + ics.rf[i->src1_reg].u64)) = ics.rf[i->src2_reg].i16; - DPRINT("ctx i16 +%d = %d (%X)\n", ics.rf[i->src1_reg].u64, ics.rf[i->src2_reg].i16, ics.rf[i->src2_reg].u16); + *((int16_t*)(ics.context + ics.rf[i->src1_reg].u64)) = + ics.rf[i->src2_reg].i16; + DPRINT("ctx i16 +%d = %d (%X)\n", ics.rf[i->src1_reg].u64, + ics.rf[i->src2_reg].i16, ics.rf[i->src2_reg].u16); return IA_NEXT; } uint32_t IntCode_STORE_CONTEXT_I32(IntCodeState& ics, const IntCode* i) { - *((int32_t*)(ics.context + ics.rf[i->src1_reg].u64)) = ics.rf[i->src2_reg].i32; - DPRINT("ctx i32 +%d = %d (%X)\n", ics.rf[i->src1_reg].u64, ics.rf[i->src2_reg].i32, ics.rf[i->src2_reg].u32); + *((int32_t*)(ics.context + ics.rf[i->src1_reg].u64)) = + ics.rf[i->src2_reg].i32; + DPRINT("ctx i32 +%d = %d (%X)\n", ics.rf[i->src1_reg].u64, + ics.rf[i->src2_reg].i32, ics.rf[i->src2_reg].u32); return IA_NEXT; } uint32_t IntCode_STORE_CONTEXT_I64(IntCodeState& ics, const IntCode* i) { - *((int64_t*)(ics.context + ics.rf[i->src1_reg].u64)) = ics.rf[i->src2_reg].i64; - DPRINT("ctx i64 +%d = %lld (%llX)\n", ics.rf[i->src1_reg].u64, ics.rf[i->src2_reg].i64, ics.rf[i->src2_reg].u64); + *((int64_t*)(ics.context + ics.rf[i->src1_reg].u64)) = + ics.rf[i->src2_reg].i64; + DPRINT("ctx i64 +%d = %lld (%llX)\n", ics.rf[i->src1_reg].u64, + ics.rf[i->src2_reg].i64, ics.rf[i->src2_reg].u64); return IA_NEXT; } uint32_t IntCode_STORE_CONTEXT_F32(IntCodeState& ics, const IntCode* i) { *((float*)(ics.context + ics.rf[i->src1_reg].u64)) = ics.rf[i->src2_reg].f32; - DPRINT("ctx f32 +%d = %e (%X)\n", ics.rf[i->src1_reg].u64, ics.rf[i->src2_reg].f32, ics.rf[i->src2_reg].u32); + DPRINT("ctx f32 +%d = %e (%X)\n", ics.rf[i->src1_reg].u64, + ics.rf[i->src2_reg].f32, ics.rf[i->src2_reg].u32); return IA_NEXT; } uint32_t IntCode_STORE_CONTEXT_F64(IntCodeState& ics, const IntCode* i) { *((double*)(ics.context + ics.rf[i->src1_reg].u64)) = ics.rf[i->src2_reg].f64; - DPRINT("ctx f64 +%d = %lle (%llX)\n", ics.rf[i->src1_reg].u64, ics.rf[i->src2_reg].f64, ics.rf[i->src2_reg].u64); + DPRINT("ctx f64 +%d = %lle (%llX)\n", ics.rf[i->src1_reg].u64, + ics.rf[i->src2_reg].f64, ics.rf[i->src2_reg].u64); return IA_NEXT; } uint32_t IntCode_STORE_CONTEXT_V128(IntCodeState& ics, const IntCode* i) { - *((vec128_t*)(ics.context + ics.rf[i->src1_reg].u64)) = ics.rf[i->src2_reg].v128; - DPRINT("ctx v128 +%d = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", ics.rf[i->src1_reg].u64, - VECF4(ics.rf[i->src2_reg].v128,0), VECF4(ics.rf[i->src2_reg].v128,1), VECF4(ics.rf[i->src2_reg].v128,2), VECF4(ics.rf[i->src2_reg].v128,3), - VECI4(ics.rf[i->src2_reg].v128,0), VECI4(ics.rf[i->src2_reg].v128,1), VECI4(ics.rf[i->src2_reg].v128,2), VECI4(ics.rf[i->src2_reg].v128,3)); + *((vec128_t*)(ics.context + ics.rf[i->src1_reg].u64)) = + ics.rf[i->src2_reg].v128; + DPRINT("ctx v128 +%d = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", + ics.rf[i->src1_reg].u64, VECF4(ics.rf[i->src2_reg].v128, 0), + VECF4(ics.rf[i->src2_reg].v128, 1), VECF4(ics.rf[i->src2_reg].v128, 2), + VECF4(ics.rf[i->src2_reg].v128, 3), VECI4(ics.rf[i->src2_reg].v128, 0), + VECI4(ics.rf[i->src2_reg].v128, 1), VECI4(ics.rf[i->src2_reg].v128, 2), + VECI4(ics.rf[i->src2_reg].v128, 3)); return IA_NEXT; } int Translate_STORE_CONTEXT(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_STORE_CONTEXT_I8, - IntCode_STORE_CONTEXT_I16, - IntCode_STORE_CONTEXT_I32, - IntCode_STORE_CONTEXT_I64, - IntCode_STORE_CONTEXT_F32, - IntCode_STORE_CONTEXT_F64, - IntCode_STORE_CONTEXT_V128, + IntCode_STORE_CONTEXT_I8, IntCode_STORE_CONTEXT_I16, + IntCode_STORE_CONTEXT_I32, IntCode_STORE_CONTEXT_I64, + IntCode_STORE_CONTEXT_F32, IntCode_STORE_CONTEXT_F64, + IntCode_STORE_CONTEXT_V128, }; return DispatchToC(ctx, i, fns[i->src2.value->type]); } @@ -1352,10 +1401,8 @@ uint32_t IntCode_LOAD_I8(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.thread_state->memory()->LoadI8(address); return IA_NEXT; } - DPRINT("%d (%X) = load.i8 %.8X\n", - *((int8_t*)(ics.membase + address)), - *((uint8_t*)(ics.membase + address)), - address); + DPRINT("%d (%X) = load.i8 %.8X\n", *((int8_t*)(ics.membase + address)), + *((uint8_t*)(ics.membase + address)), address); DFLUSH(); ics.rf[i->dest_reg].i8 = *((int8_t*)(ics.membase + address)); return IA_NEXT; @@ -1367,10 +1414,8 @@ uint32_t IntCode_LOAD_I16(IntCodeState& ics, const IntCode* i) { XESWAP16(ics.thread_state->memory()->LoadI16(address)); return IA_NEXT; } - DPRINT("%d (%X) = load.i16 %.8X\n", - *((int16_t*)(ics.membase + address)), - *((uint16_t*)(ics.membase + address)), - address); + DPRINT("%d (%X) = load.i16 %.8X\n", *((int16_t*)(ics.membase + address)), + *((uint16_t*)(ics.membase + address)), address); DFLUSH(); ics.rf[i->dest_reg].i16 = *((int16_t*)(ics.membase + address)); return IA_NEXT; @@ -1383,10 +1428,8 @@ uint32_t IntCode_LOAD_I32(IntCodeState& ics, const IntCode* i) { return IA_NEXT; } DFLUSH(); - DPRINT("%d (%X) = load.i32 %.8X\n", - *((int32_t*)(ics.membase + address)), - *((uint32_t*)(ics.membase + address)), - address); + DPRINT("%d (%X) = load.i32 %.8X\n", *((int32_t*)(ics.membase + address)), + *((uint32_t*)(ics.membase + address)), address); DFLUSH(); ics.rf[i->dest_reg].i32 = *((int32_t*)(ics.membase + address)); return IA_NEXT; @@ -1398,30 +1441,24 @@ uint32_t IntCode_LOAD_I64(IntCodeState& ics, const IntCode* i) { XESWAP64(ics.thread_state->memory()->LoadI64(address)); return IA_NEXT; } - DPRINT("%lld (%llX) = load.i64 %.8X\n", - *((int64_t*)(ics.membase + address)), - *((uint64_t*)(ics.membase + address)), - address); + DPRINT("%lld (%llX) = load.i64 %.8X\n", *((int64_t*)(ics.membase + address)), + *((uint64_t*)(ics.membase + address)), address); DFLUSH(); ics.rf[i->dest_reg].i64 = *((int64_t*)(ics.membase + address)); return IA_NEXT; } uint32_t IntCode_LOAD_F32(IntCodeState& ics, const IntCode* i) { uint32_t address = ics.rf[i->src1_reg].u32; - DPRINT("%e (%X) = load.f32 %.8X\n", - *((float*)(ics.membase + address)), - *((uint64_t*)(ics.membase + address)), - address); + DPRINT("%e (%X) = load.f32 %.8X\n", *((float*)(ics.membase + address)), + *((uint64_t*)(ics.membase + address)), address); DFLUSH(); ics.rf[i->dest_reg].f32 = *((float*)(ics.membase + address)); return IA_NEXT; } uint32_t IntCode_LOAD_F64(IntCodeState& ics, const IntCode* i) { uint32_t address = ics.rf[i->src1_reg].u32; - DPRINT("%lle (%llX) = load.f64 %.8X\n", - *((double*)(ics.membase + address)), - *((uint64_t*)(ics.membase + address)), - address); + DPRINT("%lle (%llX) = load.f64 %.8X\n", *((double*)(ics.membase + address)), + *((uint64_t*)(ics.membase + address)), address); DFLUSH(); ics.rf[i->dest_reg].f64 = *((double*)(ics.membase + address)); return IA_NEXT; @@ -1430,24 +1467,19 @@ uint32_t IntCode_LOAD_V128(IntCodeState& ics, const IntCode* i) { uint32_t address = ics.rf[i->src1_reg].u32; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - VECI4(dest,n) = *((uint32_t*)(ics.membase + address + n * 4)); + VECI4(dest, n) = *((uint32_t*)(ics.membase + address + n * 4)); } DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = load.v128 %.8X\n", - VECF4(dest,0), VECF4(dest,1), VECF4(dest,2), VECF4(dest,3), - VECI4(dest,0), VECI4(dest,1), VECI4(dest,2), VECI4(dest,3), + VECF4(dest, 0), VECF4(dest, 1), VECF4(dest, 2), VECF4(dest, 3), + VECI4(dest, 0), VECI4(dest, 1), VECI4(dest, 2), VECI4(dest, 3), address); DFLUSH(); return IA_NEXT; } int Translate_LOAD(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_LOAD_I8, - IntCode_LOAD_I16, - IntCode_LOAD_I32, - IntCode_LOAD_I64, - IntCode_LOAD_F32, - IntCode_LOAD_F64, - IntCode_LOAD_V128, + IntCode_LOAD_I8, IntCode_LOAD_I16, IntCode_LOAD_I32, IntCode_LOAD_I64, + IntCode_LOAD_F32, IntCode_LOAD_F64, IntCode_LOAD_V128, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -1462,8 +1494,8 @@ uint32_t IntCode_STORE_I8(IntCodeState& ics, const IntCode* i) { ics.thread_state->memory()->StoreI8(address, ics.rf[i->src2_reg].i8); return IA_NEXT; } - DPRINT("store.i8 %.8X = %d (%X)\n", - address, ics.rf[i->src2_reg].i8, ics.rf[i->src2_reg].u8); + DPRINT("store.i8 %.8X = %d (%X)\n", address, ics.rf[i->src2_reg].i8, + ics.rf[i->src2_reg].u8); DFLUSH(); *((int8_t*)(ics.membase + address)) = ics.rf[i->src2_reg].i8; MarkPageDirty(ics, address); @@ -1476,8 +1508,8 @@ uint32_t IntCode_STORE_I16(IntCodeState& ics, const IntCode* i) { XESWAP16(ics.rf[i->src2_reg].i16)); return IA_NEXT; } - DPRINT("store.i16 %.8X = %d (%X)\n", - address, ics.rf[i->src2_reg].i16, ics.rf[i->src2_reg].u16); + DPRINT("store.i16 %.8X = %d (%X)\n", address, ics.rf[i->src2_reg].i16, + ics.rf[i->src2_reg].u16); DFLUSH(); *((int16_t*)(ics.membase + address)) = ics.rf[i->src2_reg].i16; MarkPageDirty(ics, address); @@ -1490,8 +1522,8 @@ uint32_t IntCode_STORE_I32(IntCodeState& ics, const IntCode* i) { XESWAP32(ics.rf[i->src2_reg].i32)); return IA_NEXT; } - DPRINT("store.i32 %.8X = %d (%X)\n", - address, ics.rf[i->src2_reg].i32, ics.rf[i->src2_reg].u32); + DPRINT("store.i32 %.8X = %d (%X)\n", address, ics.rf[i->src2_reg].i32, + ics.rf[i->src2_reg].u32); DFLUSH(); *((int32_t*)(ics.membase + address)) = ics.rf[i->src2_reg].i32; MarkPageDirty(ics, address); @@ -1504,8 +1536,8 @@ uint32_t IntCode_STORE_I64(IntCodeState& ics, const IntCode* i) { XESWAP64(ics.rf[i->src2_reg].i64)); return IA_NEXT; } - DPRINT("store.i64 %.8X = %lld (%llX)\n", - address, ics.rf[i->src2_reg].i64, ics.rf[i->src2_reg].u64); + DPRINT("store.i64 %.8X = %lld (%llX)\n", address, ics.rf[i->src2_reg].i64, + ics.rf[i->src2_reg].u64); DFLUSH(); *((int64_t*)(ics.membase + address)) = ics.rf[i->src2_reg].i64; MarkPageDirty(ics, address); @@ -1513,8 +1545,8 @@ uint32_t IntCode_STORE_I64(IntCodeState& ics, const IntCode* i) { } uint32_t IntCode_STORE_F32(IntCodeState& ics, const IntCode* i) { uint32_t address = ics.rf[i->src1_reg].u32; - DPRINT("store.f32 %.8X = %e (%X)\n", - address, ics.rf[i->src2_reg].f32, ics.rf[i->src2_reg].u32); + DPRINT("store.f32 %.8X = %e (%X)\n", address, ics.rf[i->src2_reg].f32, + ics.rf[i->src2_reg].u32); DFLUSH(); *((float*)(ics.membase + address)) = ics.rf[i->src2_reg].f32; MarkPageDirty(ics, address); @@ -1522,8 +1554,8 @@ uint32_t IntCode_STORE_F32(IntCodeState& ics, const IntCode* i) { } uint32_t IntCode_STORE_F64(IntCodeState& ics, const IntCode* i) { uint32_t address = ics.rf[i->src1_reg].u32; - DPRINT("store.f64 %.8X = %lle (%llX)\n", - address, ics.rf[i->src2_reg].f64, ics.rf[i->src2_reg].u64); + DPRINT("store.f64 %.8X = %lle (%llX)\n", address, ics.rf[i->src2_reg].f64, + ics.rf[i->src2_reg].u64); DFLUSH(); *((double*)(ics.membase + address)) = ics.rf[i->src2_reg].f64; MarkPageDirty(ics, address); @@ -1532,9 +1564,11 @@ uint32_t IntCode_STORE_F64(IntCodeState& ics, const IntCode* i) { uint32_t IntCode_STORE_V128(IntCodeState& ics, const IntCode* i) { uint32_t address = ics.rf[i->src1_reg].u32; DPRINT("store.v128 %.8X = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", - address, - VECF4(ics.rf[i->src2_reg].v128,0), VECF4(ics.rf[i->src2_reg].v128,1), VECF4(ics.rf[i->src2_reg].v128,2), VECF4(ics.rf[i->src2_reg].v128,3), - VECI4(ics.rf[i->src2_reg].v128,0), VECI4(ics.rf[i->src2_reg].v128,1), VECI4(ics.rf[i->src2_reg].v128,2), VECI4(ics.rf[i->src2_reg].v128,3)); + address, VECF4(ics.rf[i->src2_reg].v128, 0), + VECF4(ics.rf[i->src2_reg].v128, 1), VECF4(ics.rf[i->src2_reg].v128, 2), + VECF4(ics.rf[i->src2_reg].v128, 3), VECI4(ics.rf[i->src2_reg].v128, 0), + VECI4(ics.rf[i->src2_reg].v128, 1), VECI4(ics.rf[i->src2_reg].v128, 2), + VECI4(ics.rf[i->src2_reg].v128, 3)); DFLUSH(); *((vec128_t*)(ics.membase + address)) = ics.rf[i->src2_reg].v128; MarkPageDirty(ics, address); @@ -1542,13 +1576,9 @@ uint32_t IntCode_STORE_V128(IntCodeState& ics, const IntCode* i) { } int Translate_STORE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_STORE_I8, - IntCode_STORE_I16, - IntCode_STORE_I32, - IntCode_STORE_I64, - IntCode_STORE_F32, - IntCode_STORE_F64, - IntCode_STORE_V128, + IntCode_STORE_I8, IntCode_STORE_I16, IntCode_STORE_I32, + IntCode_STORE_I64, IntCode_STORE_F32, IntCode_STORE_F64, + IntCode_STORE_V128, }; return DispatchToC(ctx, i, fns[i->src2.value->type]); } @@ -1561,22 +1591,26 @@ int Translate_PREFETCH(TranslationContext& ctx, Instr* i) { } uint32_t IntCode_MAX_I8_I8(IntCodeState& ics, const IntCode* i) { - int8_t a = ics.rf[i->src1_reg].i8; int8_t b = ics.rf[i->src2_reg].i8; + int8_t a = ics.rf[i->src1_reg].i8; + int8_t b = ics.rf[i->src2_reg].i8; ics.rf[i->dest_reg].i8 = MAX(a, b); return IA_NEXT; } uint32_t IntCode_MAX_I16_I16(IntCodeState& ics, const IntCode* i) { - int16_t a = ics.rf[i->src1_reg].i16; int16_t b = ics.rf[i->src2_reg].i16; + int16_t a = ics.rf[i->src1_reg].i16; + int16_t b = ics.rf[i->src2_reg].i16; ics.rf[i->dest_reg].i16 = MAX(a, b); return IA_NEXT; } uint32_t IntCode_MAX_I32_I32(IntCodeState& ics, const IntCode* i) { - int32_t a = ics.rf[i->src1_reg].i32; int32_t b = ics.rf[i->src2_reg].i32; + int32_t a = ics.rf[i->src1_reg].i32; + int32_t b = ics.rf[i->src2_reg].i32; ics.rf[i->dest_reg].i32 = MAX(a, b); return IA_NEXT; } uint32_t IntCode_MAX_I64_I64(IntCodeState& ics, const IntCode* i) { - int64_t a = ics.rf[i->src1_reg].i64; int64_t b = ics.rf[i->src2_reg].i64; + int64_t a = ics.rf[i->src1_reg].i64; + int64_t b = ics.rf[i->src2_reg].i64; ics.rf[i->dest_reg].i64 = MAX(a, b); return IA_NEXT; } @@ -1601,34 +1635,34 @@ uint32_t IntCode_MAX_V128_V128(IntCodeState& ics, const IntCode* i) { } int Translate_MAX(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_MAX_I8_I8, - IntCode_MAX_I16_I16, - IntCode_MAX_I32_I32, - IntCode_MAX_I64_I64, - IntCode_MAX_F32_F32, - IntCode_MAX_F64_F64, - IntCode_MAX_V128_V128, + IntCode_MAX_I8_I8, IntCode_MAX_I16_I16, IntCode_MAX_I32_I32, + IntCode_MAX_I64_I64, IntCode_MAX_F32_F32, IntCode_MAX_F64_F64, + IntCode_MAX_V128_V128, }; return DispatchToC(ctx, i, fns[i->dest->type]); } uint32_t IntCode_MIN_I8_I8(IntCodeState& ics, const IntCode* i) { - int8_t a = ics.rf[i->src1_reg].i8; int8_t b = ics.rf[i->src2_reg].i8; + int8_t a = ics.rf[i->src1_reg].i8; + int8_t b = ics.rf[i->src2_reg].i8; ics.rf[i->dest_reg].i8 = MIN(a, b); return IA_NEXT; } uint32_t IntCode_MIN_I16_I16(IntCodeState& ics, const IntCode* i) { - int16_t a = ics.rf[i->src1_reg].i16; int16_t b = ics.rf[i->src2_reg].i16; + int16_t a = ics.rf[i->src1_reg].i16; + int16_t b = ics.rf[i->src2_reg].i16; ics.rf[i->dest_reg].i16 = MIN(a, b); return IA_NEXT; } uint32_t IntCode_MIN_I32_I32(IntCodeState& ics, const IntCode* i) { - int32_t a = ics.rf[i->src1_reg].i32; int32_t b = ics.rf[i->src2_reg].i32; + int32_t a = ics.rf[i->src1_reg].i32; + int32_t b = ics.rf[i->src2_reg].i32; ics.rf[i->dest_reg].i32 = MIN(a, b); return IA_NEXT; } uint32_t IntCode_MIN_I64_I64(IntCodeState& ics, const IntCode* i) { - int64_t a = ics.rf[i->src1_reg].i64; int64_t b = ics.rf[i->src2_reg].i64; + int64_t a = ics.rf[i->src1_reg].i64; + int64_t b = ics.rf[i->src2_reg].i64; ics.rf[i->dest_reg].i64 = MIN(a, b); return IA_NEXT; } @@ -1653,61 +1687,53 @@ uint32_t IntCode_MIN_V128_V128(IntCodeState& ics, const IntCode* i) { } int Translate_MIN(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_MIN_I8_I8, - IntCode_MIN_I16_I16, - IntCode_MIN_I32_I32, - IntCode_MIN_I64_I64, - IntCode_MIN_F32_F32, - IntCode_MIN_F64_F64, - IntCode_MIN_V128_V128, + IntCode_MIN_I8_I8, IntCode_MIN_I16_I16, IntCode_MIN_I32_I32, + IntCode_MIN_I64_I64, IntCode_MIN_F32_F32, IntCode_MIN_F64_F64, + IntCode_MIN_V128_V128, }; return DispatchToC(ctx, i, fns[i->dest->type]); } uint32_t IntCode_SELECT_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 ? - ics.rf[i->src2_reg].i8 : ics.rf[i->src3_reg].i8; + ics.rf[i->dest_reg].i8 = + ics.rf[i->src1_reg].i8 ? ics.rf[i->src2_reg].i8 : ics.rf[i->src3_reg].i8; return IA_NEXT; } uint32_t IntCode_SELECT_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = ics.rf[i->src1_reg].i8 ? - ics.rf[i->src2_reg].i16 : ics.rf[i->src3_reg].i16; + ics.rf[i->dest_reg].i16 = ics.rf[i->src1_reg].i8 ? ics.rf[i->src2_reg].i16 + : ics.rf[i->src3_reg].i16; return IA_NEXT; } uint32_t IntCode_SELECT_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = ics.rf[i->src1_reg].i8 ? - ics.rf[i->src2_reg].i32 : ics.rf[i->src3_reg].i32; + ics.rf[i->dest_reg].i32 = ics.rf[i->src1_reg].i8 ? ics.rf[i->src2_reg].i32 + : ics.rf[i->src3_reg].i32; return IA_NEXT; } uint32_t IntCode_SELECT_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = ics.rf[i->src1_reg].i8 ? - ics.rf[i->src2_reg].i64 : ics.rf[i->src3_reg].i64; + ics.rf[i->dest_reg].i64 = ics.rf[i->src1_reg].i8 ? ics.rf[i->src2_reg].i64 + : ics.rf[i->src3_reg].i64; return IA_NEXT; } uint32_t IntCode_SELECT_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f32 = ics.rf[i->src1_reg].i8 ? - ics.rf[i->src2_reg].f32 : ics.rf[i->src3_reg].f32; + ics.rf[i->dest_reg].f32 = ics.rf[i->src1_reg].i8 ? ics.rf[i->src2_reg].f32 + : ics.rf[i->src3_reg].f32; return IA_NEXT; } uint32_t IntCode_SELECT_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f64 = ics.rf[i->src1_reg].i8 ? - ics.rf[i->src2_reg].f64 : ics.rf[i->src3_reg].f64; + ics.rf[i->dest_reg].f64 = ics.rf[i->src1_reg].i8 ? ics.rf[i->src2_reg].f64 + : ics.rf[i->src3_reg].f64; return IA_NEXT; } uint32_t IntCode_SELECT_V128(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].v128 = ics.rf[i->src1_reg].i8 ? - ics.rf[i->src2_reg].v128 : ics.rf[i->src3_reg].v128; + ics.rf[i->dest_reg].v128 = ics.rf[i->src1_reg].i8 ? ics.rf[i->src2_reg].v128 + : ics.rf[i->src3_reg].v128; return IA_NEXT; } int Translate_SELECT(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_SELECT_I8, - IntCode_SELECT_I16, - IntCode_SELECT_I32, - IntCode_SELECT_I64, - IntCode_SELECT_F32, - IntCode_SELECT_F64, - IntCode_SELECT_V128, + IntCode_SELECT_I8, IntCode_SELECT_I16, IntCode_SELECT_I32, + IntCode_SELECT_I64, IntCode_SELECT_F32, IntCode_SELECT_F64, + IntCode_SELECT_V128, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -1743,13 +1769,9 @@ uint32_t IntCode_IS_TRUE_V128(IntCodeState& ics, const IntCode* i) { } int Translate_IS_TRUE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_IS_TRUE_I8, - IntCode_IS_TRUE_I16, - IntCode_IS_TRUE_I32, - IntCode_IS_TRUE_I64, - IntCode_IS_TRUE_F32, - IntCode_IS_TRUE_F64, - IntCode_IS_TRUE_V128, + IntCode_IS_TRUE_I8, IntCode_IS_TRUE_I16, IntCode_IS_TRUE_I32, + IntCode_IS_TRUE_I64, IntCode_IS_TRUE_F32, IntCode_IS_TRUE_F64, + IntCode_IS_TRUE_V128, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } @@ -1785,203 +1807,349 @@ uint32_t IntCode_IS_FALSE_V128(IntCodeState& ics, const IntCode* i) { } int Translate_IS_FALSE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_IS_FALSE_I8, - IntCode_IS_FALSE_I16, - IntCode_IS_FALSE_I32, - IntCode_IS_FALSE_I64, - IntCode_IS_FALSE_F32, - IntCode_IS_FALSE_F64, - IntCode_IS_FALSE_V128, + IntCode_IS_FALSE_I8, IntCode_IS_FALSE_I16, IntCode_IS_FALSE_I32, + IntCode_IS_FALSE_I64, IntCode_IS_FALSE_F32, IntCode_IS_FALSE_F64, + IntCode_IS_FALSE_V128, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } -uint32_t IntCode_COMPARE_EQ_I8_I8(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 == ics.rf[i->src2_reg].i8; return IA_NEXT; } -uint32_t IntCode_COMPARE_EQ_I16_I16(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i16 == ics.rf[i->src2_reg].i16; return IA_NEXT; } -uint32_t IntCode_COMPARE_EQ_I32_I32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i32 == ics.rf[i->src2_reg].i32; return IA_NEXT; } -uint32_t IntCode_COMPARE_EQ_I64_I64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i64 == ics.rf[i->src2_reg].i64; return IA_NEXT; } -uint32_t IntCode_COMPARE_EQ_F32_F32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 == ics.rf[i->src2_reg].f32; return IA_NEXT; } -uint32_t IntCode_COMPARE_EQ_F64_F64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 == ics.rf[i->src2_reg].f64; return IA_NEXT; } +uint32_t IntCode_COMPARE_EQ_I8_I8(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 == ics.rf[i->src2_reg].i8; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_EQ_I16_I16(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i16 == ics.rf[i->src2_reg].i16; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_EQ_I32_I32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i32 == ics.rf[i->src2_reg].i32; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_EQ_I64_I64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i64 == ics.rf[i->src2_reg].i64; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_EQ_F32_F32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 == ics.rf[i->src2_reg].f32; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_EQ_F64_F64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 == ics.rf[i->src2_reg].f64; + return IA_NEXT; +} int Translate_COMPARE_EQ(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_COMPARE_EQ_I8_I8, - IntCode_COMPARE_EQ_I16_I16, - IntCode_COMPARE_EQ_I32_I32, - IntCode_COMPARE_EQ_I64_I64, - IntCode_COMPARE_EQ_F32_F32, - IntCode_COMPARE_EQ_F64_F64, - IntCode_INVALID_TYPE, + IntCode_COMPARE_EQ_I8_I8, IntCode_COMPARE_EQ_I16_I16, + IntCode_COMPARE_EQ_I32_I32, IntCode_COMPARE_EQ_I64_I64, + IntCode_COMPARE_EQ_F32_F32, IntCode_COMPARE_EQ_F64_F64, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } -uint32_t IntCode_COMPARE_NE_I8_I8(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 != ics.rf[i->src2_reg].i8; return IA_NEXT; } -uint32_t IntCode_COMPARE_NE_I16_I16(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i16 != ics.rf[i->src2_reg].i16; return IA_NEXT; } -uint32_t IntCode_COMPARE_NE_I32_I32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i32 != ics.rf[i->src2_reg].i32; return IA_NEXT; } -uint32_t IntCode_COMPARE_NE_I64_I64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i64 != ics.rf[i->src2_reg].i64; return IA_NEXT; } -uint32_t IntCode_COMPARE_NE_F32_F32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 != ics.rf[i->src2_reg].f32; return IA_NEXT; } -uint32_t IntCode_COMPARE_NE_F64_F64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 != ics.rf[i->src2_reg].f64; return IA_NEXT; } +uint32_t IntCode_COMPARE_NE_I8_I8(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 != ics.rf[i->src2_reg].i8; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_NE_I16_I16(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i16 != ics.rf[i->src2_reg].i16; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_NE_I32_I32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i32 != ics.rf[i->src2_reg].i32; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_NE_I64_I64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i64 != ics.rf[i->src2_reg].i64; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_NE_F32_F32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 != ics.rf[i->src2_reg].f32; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_NE_F64_F64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 != ics.rf[i->src2_reg].f64; + return IA_NEXT; +} int Translate_COMPARE_NE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_COMPARE_NE_I8_I8, - IntCode_COMPARE_NE_I16_I16, - IntCode_COMPARE_NE_I32_I32, - IntCode_COMPARE_NE_I64_I64, - IntCode_COMPARE_NE_F32_F32, - IntCode_COMPARE_NE_F64_F64, - IntCode_INVALID_TYPE, + IntCode_COMPARE_NE_I8_I8, IntCode_COMPARE_NE_I16_I16, + IntCode_COMPARE_NE_I32_I32, IntCode_COMPARE_NE_I64_I64, + IntCode_COMPARE_NE_F32_F32, IntCode_COMPARE_NE_F64_F64, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } -uint32_t IntCode_COMPARE_SLT_I8_I8(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 < ics.rf[i->src2_reg].i8; return IA_NEXT; } -uint32_t IntCode_COMPARE_SLT_I16_I16(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i16 < ics.rf[i->src2_reg].i16; return IA_NEXT; } -uint32_t IntCode_COMPARE_SLT_I32_I32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i32 < ics.rf[i->src2_reg].i32; return IA_NEXT; } -uint32_t IntCode_COMPARE_SLT_I64_I64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i64 < ics.rf[i->src2_reg].i64; return IA_NEXT; } -uint32_t IntCode_COMPARE_SLT_F32_F32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 < ics.rf[i->src2_reg].f32; return IA_NEXT; } -uint32_t IntCode_COMPARE_SLT_F64_F64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 < ics.rf[i->src2_reg].f64; return IA_NEXT; } +uint32_t IntCode_COMPARE_SLT_I8_I8(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 < ics.rf[i->src2_reg].i8; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_SLT_I16_I16(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i16 < ics.rf[i->src2_reg].i16; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_SLT_I32_I32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i32 < ics.rf[i->src2_reg].i32; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_SLT_I64_I64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i64 < ics.rf[i->src2_reg].i64; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_SLT_F32_F32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 < ics.rf[i->src2_reg].f32; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_SLT_F64_F64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 < ics.rf[i->src2_reg].f64; + return IA_NEXT; +} int Translate_COMPARE_SLT(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_COMPARE_SLT_I8_I8, - IntCode_COMPARE_SLT_I16_I16, - IntCode_COMPARE_SLT_I32_I32, - IntCode_COMPARE_SLT_I64_I64, - IntCode_COMPARE_SLT_F32_F32, - IntCode_COMPARE_SLT_F64_F64, - IntCode_INVALID_TYPE, + IntCode_COMPARE_SLT_I8_I8, IntCode_COMPARE_SLT_I16_I16, + IntCode_COMPARE_SLT_I32_I32, IntCode_COMPARE_SLT_I64_I64, + IntCode_COMPARE_SLT_F32_F32, IntCode_COMPARE_SLT_F64_F64, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } -uint32_t IntCode_COMPARE_SLE_I8_I8(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 <= ics.rf[i->src2_reg].i8; return IA_NEXT; } -uint32_t IntCode_COMPARE_SLE_I16_I16(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i16 <= ics.rf[i->src2_reg].i16; return IA_NEXT; } -uint32_t IntCode_COMPARE_SLE_I32_I32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i32 <= ics.rf[i->src2_reg].i32; return IA_NEXT; } -uint32_t IntCode_COMPARE_SLE_I64_I64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i64 <= ics.rf[i->src2_reg].i64; return IA_NEXT; } -uint32_t IntCode_COMPARE_SLE_F32_F32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 <= ics.rf[i->src2_reg].f32; return IA_NEXT; } -uint32_t IntCode_COMPARE_SLE_F64_F64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 <= ics.rf[i->src2_reg].f64; return IA_NEXT; } +uint32_t IntCode_COMPARE_SLE_I8_I8(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 <= ics.rf[i->src2_reg].i8; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_SLE_I16_I16(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i16 <= ics.rf[i->src2_reg].i16; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_SLE_I32_I32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i32 <= ics.rf[i->src2_reg].i32; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_SLE_I64_I64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i64 <= ics.rf[i->src2_reg].i64; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_SLE_F32_F32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 <= ics.rf[i->src2_reg].f32; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_SLE_F64_F64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 <= ics.rf[i->src2_reg].f64; + return IA_NEXT; +} int Translate_COMPARE_SLE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_COMPARE_SLE_I8_I8, - IntCode_COMPARE_SLE_I16_I16, - IntCode_COMPARE_SLE_I32_I32, - IntCode_COMPARE_SLE_I64_I64, - IntCode_COMPARE_SLE_F32_F32, - IntCode_COMPARE_SLE_F64_F64, - IntCode_INVALID_TYPE, + IntCode_COMPARE_SLE_I8_I8, IntCode_COMPARE_SLE_I16_I16, + IntCode_COMPARE_SLE_I32_I32, IntCode_COMPARE_SLE_I64_I64, + IntCode_COMPARE_SLE_F32_F32, IntCode_COMPARE_SLE_F64_F64, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } -uint32_t IntCode_COMPARE_SGT_I8_I8(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 > ics.rf[i->src2_reg].i8; return IA_NEXT; } -uint32_t IntCode_COMPARE_SGT_I16_I16(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i16 > ics.rf[i->src2_reg].i16; return IA_NEXT; } -uint32_t IntCode_COMPARE_SGT_I32_I32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i32 > ics.rf[i->src2_reg].i32; return IA_NEXT; } -uint32_t IntCode_COMPARE_SGT_I64_I64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i64 > ics.rf[i->src2_reg].i64; return IA_NEXT; } -uint32_t IntCode_COMPARE_SGT_F32_F32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 > ics.rf[i->src2_reg].f32; return IA_NEXT; } -uint32_t IntCode_COMPARE_SGT_F64_F64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 > ics.rf[i->src2_reg].f64; return IA_NEXT; } +uint32_t IntCode_COMPARE_SGT_I8_I8(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 > ics.rf[i->src2_reg].i8; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_SGT_I16_I16(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i16 > ics.rf[i->src2_reg].i16; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_SGT_I32_I32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i32 > ics.rf[i->src2_reg].i32; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_SGT_I64_I64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i64 > ics.rf[i->src2_reg].i64; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_SGT_F32_F32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 > ics.rf[i->src2_reg].f32; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_SGT_F64_F64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 > ics.rf[i->src2_reg].f64; + return IA_NEXT; +} int Translate_COMPARE_SGT(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_COMPARE_SGT_I8_I8, - IntCode_COMPARE_SGT_I16_I16, - IntCode_COMPARE_SGT_I32_I32, - IntCode_COMPARE_SGT_I64_I64, - IntCode_COMPARE_SGT_F32_F32, - IntCode_COMPARE_SGT_F64_F64, - IntCode_INVALID_TYPE, + IntCode_COMPARE_SGT_I8_I8, IntCode_COMPARE_SGT_I16_I16, + IntCode_COMPARE_SGT_I32_I32, IntCode_COMPARE_SGT_I64_I64, + IntCode_COMPARE_SGT_F32_F32, IntCode_COMPARE_SGT_F64_F64, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } -uint32_t IntCode_COMPARE_SGE_I8_I8(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 >= ics.rf[i->src2_reg].i8; return IA_NEXT; } -uint32_t IntCode_COMPARE_SGE_I16_I16(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i16 >= ics.rf[i->src2_reg].i16; return IA_NEXT; } -uint32_t IntCode_COMPARE_SGE_I32_I32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i32 >= ics.rf[i->src2_reg].i32; return IA_NEXT; } -uint32_t IntCode_COMPARE_SGE_I64_I64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i64 >= ics.rf[i->src2_reg].i64; return IA_NEXT; } -uint32_t IntCode_COMPARE_SGE_F32_F32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 >= ics.rf[i->src2_reg].f32; return IA_NEXT; } -uint32_t IntCode_COMPARE_SGE_F64_F64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 >= ics.rf[i->src2_reg].f64; return IA_NEXT; } +uint32_t IntCode_COMPARE_SGE_I8_I8(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 >= ics.rf[i->src2_reg].i8; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_SGE_I16_I16(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i16 >= ics.rf[i->src2_reg].i16; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_SGE_I32_I32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i32 >= ics.rf[i->src2_reg].i32; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_SGE_I64_I64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i64 >= ics.rf[i->src2_reg].i64; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_SGE_F32_F32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 >= ics.rf[i->src2_reg].f32; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_SGE_F64_F64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 >= ics.rf[i->src2_reg].f64; + return IA_NEXT; +} int Translate_COMPARE_SGE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_COMPARE_SGE_I8_I8, - IntCode_COMPARE_SGE_I16_I16, - IntCode_COMPARE_SGE_I32_I32, - IntCode_COMPARE_SGE_I64_I64, - IntCode_COMPARE_SGE_F32_F32, - IntCode_COMPARE_SGE_F64_F64, - IntCode_INVALID_TYPE, + IntCode_COMPARE_SGE_I8_I8, IntCode_COMPARE_SGE_I16_I16, + IntCode_COMPARE_SGE_I32_I32, IntCode_COMPARE_SGE_I64_I64, + IntCode_COMPARE_SGE_F32_F32, IntCode_COMPARE_SGE_F64_F64, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } -uint32_t IntCode_COMPARE_ULT_I8_I8(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u8 < ics.rf[i->src2_reg].u8; return IA_NEXT; } -uint32_t IntCode_COMPARE_ULT_I16_I16(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u16 < ics.rf[i->src2_reg].u16; return IA_NEXT; } -uint32_t IntCode_COMPARE_ULT_I32_I32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u32 < ics.rf[i->src2_reg].u32; return IA_NEXT; } -uint32_t IntCode_COMPARE_ULT_I64_I64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u64 < ics.rf[i->src2_reg].u64; return IA_NEXT; } -uint32_t IntCode_COMPARE_ULT_F32_F32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 < ics.rf[i->src2_reg].f32; return IA_NEXT; } -uint32_t IntCode_COMPARE_ULT_F64_F64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 < ics.rf[i->src2_reg].f64; return IA_NEXT; } +uint32_t IntCode_COMPARE_ULT_I8_I8(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u8 < ics.rf[i->src2_reg].u8; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_ULT_I16_I16(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u16 < ics.rf[i->src2_reg].u16; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_ULT_I32_I32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u32 < ics.rf[i->src2_reg].u32; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_ULT_I64_I64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u64 < ics.rf[i->src2_reg].u64; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_ULT_F32_F32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 < ics.rf[i->src2_reg].f32; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_ULT_F64_F64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 < ics.rf[i->src2_reg].f64; + return IA_NEXT; +} int Translate_COMPARE_ULT(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_COMPARE_ULT_I8_I8, - IntCode_COMPARE_ULT_I16_I16, - IntCode_COMPARE_ULT_I32_I32, - IntCode_COMPARE_ULT_I64_I64, - IntCode_COMPARE_ULT_F32_F32, - IntCode_COMPARE_ULT_F64_F64, - IntCode_INVALID_TYPE, + IntCode_COMPARE_ULT_I8_I8, IntCode_COMPARE_ULT_I16_I16, + IntCode_COMPARE_ULT_I32_I32, IntCode_COMPARE_ULT_I64_I64, + IntCode_COMPARE_ULT_F32_F32, IntCode_COMPARE_ULT_F64_F64, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } -uint32_t IntCode_COMPARE_ULE_I8_I8(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u8 <= ics.rf[i->src2_reg].u8; return IA_NEXT; } -uint32_t IntCode_COMPARE_ULE_I16_I16(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u16 <= ics.rf[i->src2_reg].u16; return IA_NEXT; } -uint32_t IntCode_COMPARE_ULE_I32_I32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u32 <= ics.rf[i->src2_reg].u32; return IA_NEXT; } -uint32_t IntCode_COMPARE_ULE_I64_I64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u64 <= ics.rf[i->src2_reg].u64; return IA_NEXT; } -uint32_t IntCode_COMPARE_ULE_F32_F32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 <= ics.rf[i->src2_reg].f32; return IA_NEXT; } -uint32_t IntCode_COMPARE_ULE_F64_F64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 <= ics.rf[i->src2_reg].f64; return IA_NEXT; } +uint32_t IntCode_COMPARE_ULE_I8_I8(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u8 <= ics.rf[i->src2_reg].u8; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_ULE_I16_I16(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u16 <= ics.rf[i->src2_reg].u16; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_ULE_I32_I32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u32 <= ics.rf[i->src2_reg].u32; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_ULE_I64_I64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u64 <= ics.rf[i->src2_reg].u64; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_ULE_F32_F32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 <= ics.rf[i->src2_reg].f32; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_ULE_F64_F64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 <= ics.rf[i->src2_reg].f64; + return IA_NEXT; +} int Translate_COMPARE_ULE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_COMPARE_ULE_I8_I8, - IntCode_COMPARE_ULE_I16_I16, - IntCode_COMPARE_ULE_I32_I32, - IntCode_COMPARE_ULE_I64_I64, - IntCode_COMPARE_ULE_F32_F32, - IntCode_COMPARE_ULE_F64_F64, - IntCode_INVALID_TYPE, + IntCode_COMPARE_ULE_I8_I8, IntCode_COMPARE_ULE_I16_I16, + IntCode_COMPARE_ULE_I32_I32, IntCode_COMPARE_ULE_I64_I64, + IntCode_COMPARE_ULE_F32_F32, IntCode_COMPARE_ULE_F64_F64, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } -uint32_t IntCode_COMPARE_UGT_I8_I8(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u8 > ics.rf[i->src2_reg].u8; return IA_NEXT; } -uint32_t IntCode_COMPARE_UGT_I16_I16(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u16 > ics.rf[i->src2_reg].u16; return IA_NEXT; } -uint32_t IntCode_COMPARE_UGT_I32_I32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u32 > ics.rf[i->src2_reg].u32; return IA_NEXT; } -uint32_t IntCode_COMPARE_UGT_I64_I64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u64 > ics.rf[i->src2_reg].u64; return IA_NEXT; } -uint32_t IntCode_COMPARE_UGT_F32_F32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 > ics.rf[i->src2_reg].f32; return IA_NEXT; } -uint32_t IntCode_COMPARE_UGT_F64_F64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 > ics.rf[i->src2_reg].f64; return IA_NEXT; } +uint32_t IntCode_COMPARE_UGT_I8_I8(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u8 > ics.rf[i->src2_reg].u8; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_UGT_I16_I16(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u16 > ics.rf[i->src2_reg].u16; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_UGT_I32_I32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u32 > ics.rf[i->src2_reg].u32; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_UGT_I64_I64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u64 > ics.rf[i->src2_reg].u64; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_UGT_F32_F32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 > ics.rf[i->src2_reg].f32; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_UGT_F64_F64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 > ics.rf[i->src2_reg].f64; + return IA_NEXT; +} int Translate_COMPARE_UGT(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_COMPARE_UGT_I8_I8, - IntCode_COMPARE_UGT_I16_I16, - IntCode_COMPARE_UGT_I32_I32, - IntCode_COMPARE_UGT_I64_I64, - IntCode_COMPARE_UGT_F32_F32, - IntCode_COMPARE_UGT_F64_F64, - IntCode_INVALID_TYPE, + IntCode_COMPARE_UGT_I8_I8, IntCode_COMPARE_UGT_I16_I16, + IntCode_COMPARE_UGT_I32_I32, IntCode_COMPARE_UGT_I64_I64, + IntCode_COMPARE_UGT_F32_F32, IntCode_COMPARE_UGT_F64_F64, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } -uint32_t IntCode_COMPARE_UGE_I8_I8(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u8 >= ics.rf[i->src2_reg].u8; return IA_NEXT; } -uint32_t IntCode_COMPARE_UGE_I16_I16(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u16 >= ics.rf[i->src2_reg].u16; return IA_NEXT; } -uint32_t IntCode_COMPARE_UGE_I32_I32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u32 >= ics.rf[i->src2_reg].u32; return IA_NEXT; } -uint32_t IntCode_COMPARE_UGE_I64_I64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u64 >= ics.rf[i->src2_reg].u64; return IA_NEXT; } -uint32_t IntCode_COMPARE_UGE_F32_F32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 >= ics.rf[i->src2_reg].f32; return IA_NEXT; } -uint32_t IntCode_COMPARE_UGE_F64_F64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 >= ics.rf[i->src2_reg].f64; return IA_NEXT; } +uint32_t IntCode_COMPARE_UGE_I8_I8(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u8 >= ics.rf[i->src2_reg].u8; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_UGE_I16_I16(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u16 >= ics.rf[i->src2_reg].u16; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_UGE_I32_I32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u32 >= ics.rf[i->src2_reg].u32; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_UGE_I64_I64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u64 >= ics.rf[i->src2_reg].u64; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_UGE_F32_F32(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 >= ics.rf[i->src2_reg].f32; + return IA_NEXT; +} +uint32_t IntCode_COMPARE_UGE_F64_F64(IntCodeState& ics, const IntCode* i) { + ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 >= ics.rf[i->src2_reg].f64; + return IA_NEXT; +} int Translate_COMPARE_UGE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_COMPARE_UGE_I8_I8, - IntCode_COMPARE_UGE_I16_I16, - IntCode_COMPARE_UGE_I32_I32, - IntCode_COMPARE_UGE_I64_I64, - IntCode_COMPARE_UGE_F32_F32, - IntCode_COMPARE_UGE_F64_F64, - IntCode_INVALID_TYPE, + IntCode_COMPARE_UGE_I8_I8, IntCode_COMPARE_UGE_I16_I16, + IntCode_COMPARE_UGE_I32_I32, IntCode_COMPARE_UGE_I64_I64, + IntCode_COMPARE_UGE_F32_F32, IntCode_COMPARE_UGE_F64_F64, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } @@ -2002,96 +2170,102 @@ int Translate_DID_SATURATE(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, IntCode_DID_SATURATE); } -#define VECTOR_COMPARER(type, value, dest_value, count, op) \ - const vec128_t& src1 = ics.rf[i->src1_reg].v128; \ - const vec128_t& src2 = ics.rf[i->src2_reg].v128; \ - vec128_t& dest = ics.rf[i->dest_reg].v128; \ - for (int n = 0; n < count; n++) { \ - dest.dest_value[n] = ((type)src1.value[n] op (type)src2.value[n]) ? 0xFFFFFFFF : 0; \ - } \ +#define VECTOR_COMPARER(type, value, dest_value, count, op) \ + const vec128_t& src1 = ics.rf[i->src1_reg].v128; \ + const vec128_t& src2 = ics.rf[i->src2_reg].v128; \ + vec128_t& dest = ics.rf[i->dest_reg].v128; \ + for (int n = 0; n < count; n++) { \ + dest.dest_value[n] = \ + ((type)src1.value[n] op(type) src2.value[n]) ? 0xFFFFFFFF : 0; \ + } \ return IA_NEXT; -uint32_t IntCode_VECTOR_COMPARE_EQ_I8(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(uint8_t, b16, b16, 16, ==) }; -uint32_t IntCode_VECTOR_COMPARE_EQ_I16(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(uint16_t, s8, s8, 8, ==) }; -uint32_t IntCode_VECTOR_COMPARE_EQ_I32(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(uint32_t, i4, i4, 4, ==) }; -uint32_t IntCode_VECTOR_COMPARE_EQ_F32(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(float, f4, i4, 4, ==) }; +uint32_t IntCode_VECTOR_COMPARE_EQ_I8(IntCodeState& ics, const IntCode* i) { + VECTOR_COMPARER(uint8_t, b16, b16, 16, == )}; +uint32_t IntCode_VECTOR_COMPARE_EQ_I16(IntCodeState& ics, const IntCode* i) { + VECTOR_COMPARER(uint16_t, s8, s8, 8, == )}; +uint32_t IntCode_VECTOR_COMPARE_EQ_I32(IntCodeState& ics, const IntCode* i) { + VECTOR_COMPARER(uint32_t, i4, i4, 4, == )}; +uint32_t IntCode_VECTOR_COMPARE_EQ_F32(IntCodeState& ics, const IntCode* i) { + VECTOR_COMPARER(float, f4, i4, 4, == )}; int Translate_VECTOR_COMPARE_EQ(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_VECTOR_COMPARE_EQ_I8, - IntCode_VECTOR_COMPARE_EQ_I16, - IntCode_VECTOR_COMPARE_EQ_I32, - IntCode_INVALID_TYPE, - IntCode_VECTOR_COMPARE_EQ_F32, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, + IntCode_VECTOR_COMPARE_EQ_I8, IntCode_VECTOR_COMPARE_EQ_I16, + IntCode_VECTOR_COMPARE_EQ_I32, IntCode_INVALID_TYPE, + IntCode_VECTOR_COMPARE_EQ_F32, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->flags]); } -uint32_t IntCode_VECTOR_COMPARE_SGT_I8(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(int8_t, b16, b16, 16, >) }; -uint32_t IntCode_VECTOR_COMPARE_SGT_I16(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(int16_t, s8, s8, 8, >) }; -uint32_t IntCode_VECTOR_COMPARE_SGT_I32(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(int32_t, i4, i4, 4, >) }; -uint32_t IntCode_VECTOR_COMPARE_SGT_F32(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(float, f4, i4, 4, >) }; +uint32_t IntCode_VECTOR_COMPARE_SGT_I8(IntCodeState& ics, const IntCode* i) { + VECTOR_COMPARER(int8_t, b16, b16, 16, > )}; +uint32_t IntCode_VECTOR_COMPARE_SGT_I16(IntCodeState& ics, const IntCode* i) { + VECTOR_COMPARER(int16_t, s8, s8, 8, > )}; +uint32_t IntCode_VECTOR_COMPARE_SGT_I32(IntCodeState& ics, const IntCode* i) { + VECTOR_COMPARER(int32_t, i4, i4, 4, > )}; +uint32_t IntCode_VECTOR_COMPARE_SGT_F32(IntCodeState& ics, const IntCode* i) { + VECTOR_COMPARER(float, f4, i4, 4, > )}; int Translate_VECTOR_COMPARE_SGT(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_VECTOR_COMPARE_SGT_I8, - IntCode_VECTOR_COMPARE_SGT_I16, - IntCode_VECTOR_COMPARE_SGT_I32, - IntCode_INVALID_TYPE, - IntCode_VECTOR_COMPARE_SGT_F32, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, + IntCode_VECTOR_COMPARE_SGT_I8, IntCode_VECTOR_COMPARE_SGT_I16, + IntCode_VECTOR_COMPARE_SGT_I32, IntCode_INVALID_TYPE, + IntCode_VECTOR_COMPARE_SGT_F32, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->flags]); } -uint32_t IntCode_VECTOR_COMPARE_SGE_I8(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(int8_t, b16, b16, 16, >=) }; -uint32_t IntCode_VECTOR_COMPARE_SGE_I16(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(int16_t, s8, s8, 8, >=) }; -uint32_t IntCode_VECTOR_COMPARE_SGE_I32(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(int32_t, i4, i4, 4, >=) }; -uint32_t IntCode_VECTOR_COMPARE_SGE_F32(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(float, f4, i4, 4, >=) }; +uint32_t IntCode_VECTOR_COMPARE_SGE_I8(IntCodeState& ics, const IntCode* i) { + VECTOR_COMPARER(int8_t, b16, b16, 16, >= )}; +uint32_t IntCode_VECTOR_COMPARE_SGE_I16(IntCodeState& ics, const IntCode* i) { + VECTOR_COMPARER(int16_t, s8, s8, 8, >= )}; +uint32_t IntCode_VECTOR_COMPARE_SGE_I32(IntCodeState& ics, const IntCode* i) { + VECTOR_COMPARER(int32_t, i4, i4, 4, >= )}; +uint32_t IntCode_VECTOR_COMPARE_SGE_F32(IntCodeState& ics, const IntCode* i) { + VECTOR_COMPARER(float, f4, i4, 4, >= )}; int Translate_VECTOR_COMPARE_SGE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_VECTOR_COMPARE_SGE_I8, - IntCode_VECTOR_COMPARE_SGE_I16, - IntCode_VECTOR_COMPARE_SGE_I32, - IntCode_INVALID_TYPE, - IntCode_VECTOR_COMPARE_SGE_F32, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, + IntCode_VECTOR_COMPARE_SGE_I8, IntCode_VECTOR_COMPARE_SGE_I16, + IntCode_VECTOR_COMPARE_SGE_I32, IntCode_INVALID_TYPE, + IntCode_VECTOR_COMPARE_SGE_F32, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->flags]); } -uint32_t IntCode_VECTOR_COMPARE_UGT_I8(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(uint8_t, b16, b16, 16, >) }; -uint32_t IntCode_VECTOR_COMPARE_UGT_I16(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(uint16_t, s8, s8, 8, >) }; -uint32_t IntCode_VECTOR_COMPARE_UGT_I32(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(uint32_t, i4, i4, 4, >) }; -uint32_t IntCode_VECTOR_COMPARE_UGT_F32(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(float, f4, i4, 4, >) }; +uint32_t IntCode_VECTOR_COMPARE_UGT_I8(IntCodeState& ics, const IntCode* i) { + VECTOR_COMPARER(uint8_t, b16, b16, 16, > )}; +uint32_t IntCode_VECTOR_COMPARE_UGT_I16(IntCodeState& ics, const IntCode* i) { + VECTOR_COMPARER(uint16_t, s8, s8, 8, > )}; +uint32_t IntCode_VECTOR_COMPARE_UGT_I32(IntCodeState& ics, const IntCode* i) { + VECTOR_COMPARER(uint32_t, i4, i4, 4, > )}; +uint32_t IntCode_VECTOR_COMPARE_UGT_F32(IntCodeState& ics, const IntCode* i) { + VECTOR_COMPARER(float, f4, i4, 4, > )}; int Translate_VECTOR_COMPARE_UGT(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_VECTOR_COMPARE_UGT_I8, - IntCode_VECTOR_COMPARE_UGT_I16, - IntCode_VECTOR_COMPARE_UGT_I32, - IntCode_INVALID_TYPE, - IntCode_VECTOR_COMPARE_UGT_F32, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, + IntCode_VECTOR_COMPARE_UGT_I8, IntCode_VECTOR_COMPARE_UGT_I16, + IntCode_VECTOR_COMPARE_UGT_I32, IntCode_INVALID_TYPE, + IntCode_VECTOR_COMPARE_UGT_F32, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->flags]); } -uint32_t IntCode_VECTOR_COMPARE_UGE_I8(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(uint8_t, b16, b16, 16, >=) }; -uint32_t IntCode_VECTOR_COMPARE_UGE_I16(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(uint16_t, s8, s8, 8, >=) }; -uint32_t IntCode_VECTOR_COMPARE_UGE_I32(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(uint32_t, i4, i4, 4, >=) }; -uint32_t IntCode_VECTOR_COMPARE_UGE_F32(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(float, f4, i4, 4, >=) }; +uint32_t IntCode_VECTOR_COMPARE_UGE_I8(IntCodeState& ics, const IntCode* i) { + VECTOR_COMPARER(uint8_t, b16, b16, 16, >= )}; +uint32_t IntCode_VECTOR_COMPARE_UGE_I16(IntCodeState& ics, const IntCode* i) { + VECTOR_COMPARER(uint16_t, s8, s8, 8, >= )}; +uint32_t IntCode_VECTOR_COMPARE_UGE_I32(IntCodeState& ics, const IntCode* i) { + VECTOR_COMPARER(uint32_t, i4, i4, 4, >= )}; +uint32_t IntCode_VECTOR_COMPARE_UGE_F32(IntCodeState& ics, const IntCode* i) { + VECTOR_COMPARER(float, f4, i4, 4, >= )}; int Translate_VECTOR_COMPARE_UGE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_VECTOR_COMPARE_UGE_I8, - IntCode_VECTOR_COMPARE_UGE_I16, - IntCode_VECTOR_COMPARE_UGE_I32, - IntCode_INVALID_TYPE, - IntCode_VECTOR_COMPARE_UGE_F32, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, + IntCode_VECTOR_COMPARE_UGE_I8, IntCode_VECTOR_COMPARE_UGE_I16, + IntCode_VECTOR_COMPARE_UGE_I32, IntCode_INVALID_TYPE, + IntCode_VECTOR_COMPARE_UGE_F32, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->flags]); } @@ -2099,7 +2273,8 @@ int Translate_VECTOR_COMPARE_UGE(TranslationContext& ctx, Instr* i) { #define CHECK_DID_CARRY(v1, v2) (((uint64_t)v2) > ~((uint64_t)v1)) #define ADD_DID_CARRY(a, b) CHECK_DID_CARRY(a, b) uint32_t IntCode_ADD_I8_I8(IntCodeState& ics, const IntCode* i) { - int8_t a = ics.rf[i->src1_reg].i8; int8_t b = ics.rf[i->src2_reg].i8; + int8_t a = ics.rf[i->src1_reg].i8; + int8_t b = ics.rf[i->src2_reg].i8; if (i->flags == ARITHMETIC_SET_CARRY) { ics.did_carry = ADD_DID_CARRY(a, b); } @@ -2107,7 +2282,8 @@ uint32_t IntCode_ADD_I8_I8(IntCodeState& ics, const IntCode* i) { return IA_NEXT; } uint32_t IntCode_ADD_I16_I16(IntCodeState& ics, const IntCode* i) { - int16_t a = ics.rf[i->src1_reg].i16; int16_t b = ics.rf[i->src2_reg].i16; + int16_t a = ics.rf[i->src1_reg].i16; + int16_t b = ics.rf[i->src2_reg].i16; if (i->flags == ARITHMETIC_SET_CARRY) { ics.did_carry = ADD_DID_CARRY(a, b); } @@ -2115,7 +2291,8 @@ uint32_t IntCode_ADD_I16_I16(IntCodeState& ics, const IntCode* i) { return IA_NEXT; } uint32_t IntCode_ADD_I32_I32(IntCodeState& ics, const IntCode* i) { - int32_t a = ics.rf[i->src1_reg].i32; int32_t b = ics.rf[i->src2_reg].i32; + int32_t a = ics.rf[i->src1_reg].i32; + int32_t b = ics.rf[i->src2_reg].i32; if (i->flags == ARITHMETIC_SET_CARRY) { ics.did_carry = ADD_DID_CARRY(a, b); } @@ -2123,7 +2300,8 @@ uint32_t IntCode_ADD_I32_I32(IntCodeState& ics, const IntCode* i) { return IA_NEXT; } uint32_t IntCode_ADD_I64_I64(IntCodeState& ics, const IntCode* i) { - int64_t a = ics.rf[i->src1_reg].i64; int64_t b = ics.rf[i->src2_reg].i64; + int64_t a = ics.rf[i->src1_reg].i64; + int64_t b = ics.rf[i->src2_reg].i64; if (i->flags == ARITHMETIC_SET_CARRY) { ics.did_carry = ADD_DID_CARRY(a, b); } @@ -2152,21 +2330,19 @@ uint32_t IntCode_ADD_V128_V128(IntCodeState& ics, const IntCode* i) { } int Translate_ADD(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_ADD_I8_I8, - IntCode_ADD_I16_I16, - IntCode_ADD_I32_I32, - IntCode_ADD_I64_I64, - IntCode_ADD_F32_F32, - IntCode_ADD_F64_F64, - IntCode_ADD_V128_V128, + IntCode_ADD_I8_I8, IntCode_ADD_I16_I16, IntCode_ADD_I32_I32, + IntCode_ADD_I64_I64, IntCode_ADD_F32_F32, IntCode_ADD_F64_F64, + IntCode_ADD_V128_V128, }; return DispatchToC(ctx, i, fns[i->dest->type]); } #define ADD_CARRY_DID_CARRY(a, b, c) \ - (CHECK_DID_CARRY(a, b) || ((c) != 0) && CHECK_DID_CARRY((a) + (b), c)) + (CHECK_DID_CARRY(a, b) || ((c) != 0) && CHECK_DID_CARRY((a) + (b), c)) uint32_t IntCode_ADD_CARRY_I8_I8(IntCodeState& ics, const IntCode* i) { - int8_t a = ics.rf[i->src1_reg].i8; int8_t b = ics.rf[i->src2_reg].i8; uint8_t c = ics.rf[i->src3_reg].u8; + int8_t a = ics.rf[i->src1_reg].i8; + int8_t b = ics.rf[i->src2_reg].i8; + uint8_t c = ics.rf[i->src3_reg].u8; if (i->flags == ARITHMETIC_SET_CARRY) { ics.did_carry = ADD_CARRY_DID_CARRY(a, b, c); } @@ -2174,7 +2350,9 @@ uint32_t IntCode_ADD_CARRY_I8_I8(IntCodeState& ics, const IntCode* i) { return IA_NEXT; } uint32_t IntCode_ADD_CARRY_I16_I16(IntCodeState& ics, const IntCode* i) { - int16_t a = ics.rf[i->src1_reg].i16; int16_t b = ics.rf[i->src2_reg].i16; uint8_t c = ics.rf[i->src3_reg].u8; + int16_t a = ics.rf[i->src1_reg].i16; + int16_t b = ics.rf[i->src2_reg].i16; + uint8_t c = ics.rf[i->src3_reg].u8; if (i->flags == ARITHMETIC_SET_CARRY) { ics.did_carry = ADD_CARRY_DID_CARRY(a, b, c); } @@ -2182,7 +2360,9 @@ uint32_t IntCode_ADD_CARRY_I16_I16(IntCodeState& ics, const IntCode* i) { return IA_NEXT; } uint32_t IntCode_ADD_CARRY_I32_I32(IntCodeState& ics, const IntCode* i) { - int32_t a = ics.rf[i->src1_reg].i32; int32_t b = ics.rf[i->src2_reg].i32; uint8_t c = ics.rf[i->src3_reg].u8; + int32_t a = ics.rf[i->src1_reg].i32; + int32_t b = ics.rf[i->src2_reg].i32; + uint8_t c = ics.rf[i->src3_reg].u8; if (i->flags == ARITHMETIC_SET_CARRY) { ics.did_carry = ADD_CARRY_DID_CARRY(a, b, c); } @@ -2190,7 +2370,9 @@ uint32_t IntCode_ADD_CARRY_I32_I32(IntCodeState& ics, const IntCode* i) { return IA_NEXT; } uint32_t IntCode_ADD_CARRY_I64_I64(IntCodeState& ics, const IntCode* i) { - int64_t a = ics.rf[i->src1_reg].i64; int64_t b = ics.rf[i->src2_reg].i64; uint8_t c = ics.rf[i->src3_reg].u8; + int64_t a = ics.rf[i->src1_reg].i64; + int64_t b = ics.rf[i->src2_reg].i64; + uint8_t c = ics.rf[i->src3_reg].u8; if (i->flags == ARITHMETIC_SET_CARRY) { ics.did_carry = ADD_CARRY_DID_CARRY(a, b, c); } @@ -2199,23 +2381,22 @@ uint32_t IntCode_ADD_CARRY_I64_I64(IntCodeState& ics, const IntCode* i) { } uint32_t IntCode_ADD_CARRY_F32_F32(IntCodeState& ics, const IntCode* i) { XEASSERT(!i->flags); - ics.rf[i->dest_reg].f32 = ics.rf[i->src1_reg].f32 + ics.rf[i->src2_reg].f32 + ics.rf[i->src3_reg].i8; + ics.rf[i->dest_reg].f32 = ics.rf[i->src1_reg].f32 + ics.rf[i->src2_reg].f32 + + ics.rf[i->src3_reg].i8; return IA_NEXT; } uint32_t IntCode_ADD_CARRY_F64_F64(IntCodeState& ics, const IntCode* i) { XEASSERT(!i->flags); - ics.rf[i->dest_reg].f64 = ics.rf[i->src1_reg].f64 + ics.rf[i->src2_reg].f64 + ics.rf[i->src3_reg].i8; + ics.rf[i->dest_reg].f64 = ics.rf[i->src1_reg].f64 + ics.rf[i->src2_reg].f64 + + ics.rf[i->src3_reg].i8; return IA_NEXT; } int Translate_ADD_CARRY(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_ADD_CARRY_I8_I8, - IntCode_ADD_CARRY_I16_I16, - IntCode_ADD_CARRY_I32_I32, - IntCode_ADD_CARRY_I64_I64, - IntCode_ADD_CARRY_F32_F32, - IntCode_ADD_CARRY_F64_F64, - IntCode_INVALID_TYPE, + IntCode_ADD_CARRY_I8_I8, IntCode_ADD_CARRY_I16_I16, + IntCode_ADD_CARRY_I32_I32, IntCode_ADD_CARRY_I64_I64, + IntCode_ADD_CARRY_F32_F32, IntCode_ADD_CARRY_F64_F64, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -2228,31 +2409,31 @@ uint32_t Translate_VECTOR_ADD_I8(IntCodeState& ics, const IntCode* i) { if (arithmetic_flags & ARITHMETIC_SATURATE) { if (arithmetic_flags & ARITHMETIC_UNSIGNED) { for (int n = 0; n < 16; n++) { - uint16_t v = VECB16(src1,n) + VECB16(src2,n); + uint16_t v = VECB16(src1, n) + VECB16(src2, n); if (v > 0xFF) { - VECB16(dest,n) = 0xFF; + VECB16(dest, n) = 0xFF; ics.did_saturate = 1; } else { - VECB16(dest,n) = (uint8_t)v; + VECB16(dest, n) = (uint8_t)v; } } } else { for (int n = 0; n < 16; n++) { - int16_t v = (int8_t)VECB16(src1,n) + (int8_t)VECB16(src2,n); + int16_t v = (int8_t)VECB16(src1, n) + (int8_t)VECB16(src2, n); if (v > 0x7F) { - VECB16(dest,n) = 0x7F; + VECB16(dest, n) = 0x7F; ics.did_saturate = 1; } else if (v < -0x80) { - VECB16(dest,n) = -0x80; + VECB16(dest, n) = -0x80; ics.did_saturate = 1; } else { - VECB16(dest,n) = (uint8_t)v; + VECB16(dest, n) = (uint8_t)v; } } } } else { for (int n = 0; n < 16; n++) { - VECB16(dest,n) = VECB16(src1,n) + VECB16(src2,n); + VECB16(dest, n) = VECB16(src1, n) + VECB16(src2, n); } } return IA_NEXT; @@ -2265,31 +2446,31 @@ uint32_t Translate_VECTOR_ADD_I16(IntCodeState& ics, const IntCode* i) { if (arithmetic_flags & ARITHMETIC_SATURATE) { if (arithmetic_flags & ARITHMETIC_UNSIGNED) { for (int n = 0; n < 8; n++) { - uint32_t v = VECS8(src1,n) + VECS8(src2,n); + uint32_t v = VECS8(src1, n) + VECS8(src2, n); if (v > 0xFFFF) { - VECS8(dest,n) = 0xFFFF; + VECS8(dest, n) = 0xFFFF; ics.did_saturate = 1; } else { - VECS8(dest,n) = (uint16_t)v; + VECS8(dest, n) = (uint16_t)v; } } } else { for (int n = 0; n < 8; n++) { - int32_t v = (int16_t)VECS8(src1,n) + (int16_t)VECS8(src2,n); + int32_t v = (int16_t)VECS8(src1, n) + (int16_t)VECS8(src2, n); if (v > 0x7FFF) { - VECS8(dest,n) = 0x7FFF; + VECS8(dest, n) = 0x7FFF; ics.did_saturate = 1; } else if (v < -0x8000) { - VECS8(dest,n) = -0x8000; + VECS8(dest, n) = -0x8000; ics.did_saturate = 1; } else { - VECS8(dest,n) = (uint16_t)v; + VECS8(dest, n) = (uint16_t)v; } } } } else { for (int n = 0; n < 8; n++) { - VECS8(dest,n) = VECS8(src1,n) + VECS8(src2,n); + VECS8(dest, n) = VECS8(src1, n) + VECS8(src2, n); } } return IA_NEXT; @@ -2302,31 +2483,31 @@ uint32_t Translate_VECTOR_ADD_I32(IntCodeState& ics, const IntCode* i) { if (arithmetic_flags & ARITHMETIC_SATURATE) { if (arithmetic_flags & ARITHMETIC_UNSIGNED) { for (int n = 0; n < 4; n++) { - uint64_t v = VECI4(src1,n) + VECI4(src2,n); + uint64_t v = VECI4(src1, n) + VECI4(src2, n); if (v > 0xFFFFFFFF) { - VECI4(dest,n) = 0xFFFFFFFF; + VECI4(dest, n) = 0xFFFFFFFF; ics.did_saturate = 1; } else { - VECI4(dest,n) = (uint32_t)v; + VECI4(dest, n) = (uint32_t)v; } } } else { for (int n = 0; n < 4; n++) { - int64_t v = (int32_t)VECI4(src1,n) + (int32_t)VECI4(src2,n); + int64_t v = (int32_t)VECI4(src1, n) + (int32_t)VECI4(src2, n); if (v > 0x7FFFFFFF) { - VECI4(dest,n) = 0x7FFFFFFF; + VECI4(dest, n) = 0x7FFFFFFF; ics.did_saturate = 1; } else if (v < -0x80000000ll) { - VECI4(dest,n) = 0x80000000; + VECI4(dest, n) = 0x80000000; ics.did_saturate = 1; } else { - VECI4(dest,n) = (uint32_t)v; + VECI4(dest, n) = (uint32_t)v; } } } } else { for (int n = 0; n < 4; n++) { - VECI4(dest,n) = VECI4(src1,n) + VECI4(src2,n); + VECI4(dest, n) = VECI4(src1, n) + VECI4(src2, n); } } return IA_NEXT; @@ -2343,21 +2524,18 @@ uint32_t Translate_VECTOR_ADD_F32(IntCodeState& ics, const IntCode* i) { int Translate_VECTOR_ADD(TranslationContext& ctx, Instr* i) { TypeName part_type = (TypeName)(i->flags & 0xFF); static IntCodeFn fns[] = { - Translate_VECTOR_ADD_I8, - Translate_VECTOR_ADD_I16, - Translate_VECTOR_ADD_I32, - IntCode_INVALID_TYPE, - Translate_VECTOR_ADD_F32, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, + Translate_VECTOR_ADD_I8, Translate_VECTOR_ADD_I16, + Translate_VECTOR_ADD_I32, IntCode_INVALID_TYPE, + Translate_VECTOR_ADD_F32, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[part_type]); } -#define SUB_DID_CARRY(a, b) \ - ((b) == 0) || CHECK_DID_CARRY(a, 0 - b) +#define SUB_DID_CARRY(a, b) ((b) == 0) || CHECK_DID_CARRY(a, 0 - b) uint32_t IntCode_SUB_I8_I8(IntCodeState& ics, const IntCode* i) { - int8_t a = ics.rf[i->src1_reg].i8; int8_t b = ics.rf[i->src2_reg].i8; + int8_t a = ics.rf[i->src1_reg].i8; + int8_t b = ics.rf[i->src2_reg].i8; if (i->flags == ARITHMETIC_SET_CARRY) { ics.did_carry = SUB_DID_CARRY(a, b); } @@ -2365,7 +2543,8 @@ uint32_t IntCode_SUB_I8_I8(IntCodeState& ics, const IntCode* i) { return IA_NEXT; } uint32_t IntCode_SUB_I16_I16(IntCodeState& ics, const IntCode* i) { - int16_t a = ics.rf[i->src1_reg].i16; int16_t b = ics.rf[i->src2_reg].i16; + int16_t a = ics.rf[i->src1_reg].i16; + int16_t b = ics.rf[i->src2_reg].i16; if (i->flags == ARITHMETIC_SET_CARRY) { ics.did_carry = SUB_DID_CARRY(a, b); } @@ -2373,7 +2552,8 @@ uint32_t IntCode_SUB_I16_I16(IntCodeState& ics, const IntCode* i) { return IA_NEXT; } uint32_t IntCode_SUB_I32_I32(IntCodeState& ics, const IntCode* i) { - int32_t a = ics.rf[i->src1_reg].i32; int32_t b = ics.rf[i->src2_reg].i32; + int32_t a = ics.rf[i->src1_reg].i32; + int32_t b = ics.rf[i->src2_reg].i32; if (i->flags == ARITHMETIC_SET_CARRY) { ics.did_carry = SUB_DID_CARRY(a, b); } @@ -2381,7 +2561,8 @@ uint32_t IntCode_SUB_I32_I32(IntCodeState& ics, const IntCode* i) { return IA_NEXT; } uint32_t IntCode_SUB_I64_I64(IntCodeState& ics, const IntCode* i) { - int64_t a = ics.rf[i->src1_reg].i64; int64_t b = ics.rf[i->src2_reg].i64; + int64_t a = ics.rf[i->src1_reg].i64; + int64_t b = ics.rf[i->src2_reg].i64; if (i->flags == ARITHMETIC_SET_CARRY) { ics.did_carry = SUB_DID_CARRY(a, b); } @@ -2409,13 +2590,9 @@ uint32_t IntCode_SUB_V128_V128(IntCodeState& ics, const IntCode* i) { } int Translate_SUB(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_SUB_I8_I8, - IntCode_SUB_I16_I16, - IntCode_SUB_I32_I32, - IntCode_SUB_I64_I64, - IntCode_SUB_F32_F32, - IntCode_SUB_F64_F64, - IntCode_SUB_V128_V128, + IntCode_SUB_I8_I8, IntCode_SUB_I16_I16, IntCode_SUB_I32_I32, + IntCode_SUB_I64_I64, IntCode_SUB_F32_F32, IntCode_SUB_F64_F64, + IntCode_SUB_V128_V128, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -2471,22 +2648,14 @@ uint32_t IntCode_MUL_I64_I64_U(IntCodeState& ics, const IntCode* i) { } int Translate_MUL(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_MUL_I8_I8, - IntCode_MUL_I16_I16, - IntCode_MUL_I32_I32, - IntCode_MUL_I64_I64, - IntCode_MUL_F32_F32, - IntCode_MUL_F64_F64, - IntCode_MUL_V128_V128, + IntCode_MUL_I8_I8, IntCode_MUL_I16_I16, IntCode_MUL_I32_I32, + IntCode_MUL_I64_I64, IntCode_MUL_F32_F32, IntCode_MUL_F64_F64, + IntCode_MUL_V128_V128, }; static IntCodeFn fns_unsigned[] = { - IntCode_MUL_I8_I8_U, - IntCode_MUL_I16_I16_U, - IntCode_MUL_I32_I32_U, - IntCode_MUL_I64_I64_U, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, + IntCode_MUL_I8_I8_U, IntCode_MUL_I16_I16_U, IntCode_MUL_I32_I32_U, + IntCode_MUL_I64_I64_U, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; if (i->flags & ARITHMETIC_UNSIGNED) { return DispatchToC(ctx, i, fns_unsigned[i->dest->type]); @@ -2496,10 +2665,10 @@ int Translate_MUL(TranslationContext& ctx, Instr* i) { } namespace { -uint64_t Mul128(uint64_t xi_low, uint64_t xi_high, - uint64_t yi_low, uint64_t yi_high) { - // 128bit multiply, simplified for two input 64bit integers. - // http://mrob.com/pub/math/int128.c.txt +uint64_t Mul128(uint64_t xi_low, uint64_t xi_high, uint64_t yi_low, + uint64_t yi_high) { +// 128bit multiply, simplified for two input 64bit integers. +// http://mrob.com/pub/math/int128.c.txt #define HI_WORD 0xFFFFFFFF00000000LL #define LO_WORD 0x00000000FFFFFFFFLL uint64_t d = xi_low & LO_WORD; @@ -2515,14 +2684,30 @@ uint64_t Mul128(uint64_t xi_low, uint64_t xi_high, acc >>= 32LL; uint64_t carry = 0; - uint64_t ac2 = acc + c * h; if (ac2 < acc) { carry++; } - acc = ac2 + d * g; if (acc < ac2) { carry++; } + uint64_t ac2 = acc + c * h; + if (ac2 < acc) { + carry++; + } + acc = ac2 + d * g; + if (acc < ac2) { + carry++; + } uint64_t rv2_lo = o1 | (acc << 32LL); - ac2 = (acc >> 32LL) | (carry << 32LL); carry = 0; + ac2 = (acc >> 32LL) | (carry << 32LL); + carry = 0; - acc = ac2 + b * h; if (acc < ac2) { carry++; } - ac2 = acc + c * g; if (ac2 < acc) { carry++; } - acc = ac2 + d * f; if (acc < ac2) { carry++; } + acc = ac2 + b * h; + if (acc < ac2) { + carry++; + } + ac2 = acc + c * g; + if (ac2 < acc) { + carry++; + } + acc = ac2 + d * f; + if (acc < ac2) { + carry++; + } uint64_t o2 = acc & LO_WORD; ac2 = (acc >> 32LL) | (carry << 32LL); @@ -2537,8 +2722,7 @@ uint64_t Mul128(uint64_t xi_low, uint64_t xi_high, } uint32_t IntCode_MUL_HI_I8_I8(IntCodeState& ics, const IntCode* i) { - int16_t v = - (int16_t)ics.rf[i->src1_reg].i8 * (int16_t)ics.rf[i->src2_reg].i8; + int16_t v = (int16_t)ics.rf[i->src1_reg].i8 * (int16_t)ics.rf[i->src2_reg].i8; ics.rf[i->dest_reg].i8 = (v >> 8); return IA_NEXT; } @@ -2608,22 +2792,15 @@ uint32_t IntCode_MUL_HI_I64_I64_U(IntCodeState& ics, const IntCode* i) { } int Translate_MUL_HI(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_MUL_HI_I8_I8, - IntCode_MUL_HI_I16_I16, - IntCode_MUL_HI_I32_I32, - IntCode_MUL_HI_I64_I64, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, + IntCode_MUL_HI_I8_I8, IntCode_MUL_HI_I16_I16, IntCode_MUL_HI_I32_I32, + IntCode_MUL_HI_I64_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; static IntCodeFn fns_unsigned[] = { - IntCode_MUL_HI_I8_I8_U, - IntCode_MUL_HI_I16_I16_U, - IntCode_MUL_HI_I32_I32_U, - IntCode_MUL_HI_I64_I64_U, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, + IntCode_MUL_HI_I8_I8_U, IntCode_MUL_HI_I16_I16_U, + IntCode_MUL_HI_I32_I32_U, IntCode_MUL_HI_I64_I64_U, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; if (i->flags & ARITHMETIC_UNSIGNED) { return DispatchToC(ctx, i, fns_unsigned[i->dest->type]); @@ -2683,22 +2860,14 @@ uint32_t IntCode_DIV_I64_I64_U(IntCodeState& ics, const IntCode* i) { } int Translate_DIV(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_DIV_I8_I8, - IntCode_DIV_I16_I16, - IntCode_DIV_I32_I32, - IntCode_DIV_I64_I64, - IntCode_DIV_F32_F32, - IntCode_DIV_F64_F64, - IntCode_DIV_V128_V128, + IntCode_DIV_I8_I8, IntCode_DIV_I16_I16, IntCode_DIV_I32_I32, + IntCode_DIV_I64_I64, IntCode_DIV_F32_F32, IntCode_DIV_F64_F64, + IntCode_DIV_V128_V128, }; static IntCodeFn fns_unsigned[] = { - IntCode_DIV_I8_I8_U, - IntCode_DIV_I16_I16_U, - IntCode_DIV_I32_I32_U, - IntCode_DIV_I64_I64_U, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, + IntCode_DIV_I8_I8_U, IntCode_DIV_I16_I16_U, IntCode_DIV_I32_I32_U, + IntCode_DIV_I64_I64_U, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; if (i->flags & ARITHMETIC_UNSIGNED) { return DispatchToC(ctx, i, fns_unsigned[i->dest->type]); @@ -2709,27 +2878,33 @@ int Translate_DIV(TranslationContext& ctx, Instr* i) { // TODO(benvanik): use intrinsics or something uint32_t IntCode_MUL_ADD_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 * ics.rf[i->src2_reg].i8 + ics.rf[i->src3_reg].i8; + ics.rf[i->dest_reg].i8 = + ics.rf[i->src1_reg].i8 * ics.rf[i->src2_reg].i8 + ics.rf[i->src3_reg].i8; return IA_NEXT; } uint32_t IntCode_MUL_ADD_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = ics.rf[i->src1_reg].i16 * ics.rf[i->src2_reg].i16 + ics.rf[i->src3_reg].i16; + ics.rf[i->dest_reg].i16 = ics.rf[i->src1_reg].i16 * ics.rf[i->src2_reg].i16 + + ics.rf[i->src3_reg].i16; return IA_NEXT; } uint32_t IntCode_MUL_ADD_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = ics.rf[i->src1_reg].i32 * ics.rf[i->src2_reg].i32 + ics.rf[i->src3_reg].i32; + ics.rf[i->dest_reg].i32 = ics.rf[i->src1_reg].i32 * ics.rf[i->src2_reg].i32 + + ics.rf[i->src3_reg].i32; return IA_NEXT; } uint32_t IntCode_MUL_ADD_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = ics.rf[i->src1_reg].i64 * ics.rf[i->src2_reg].i64 + ics.rf[i->src3_reg].i64; + ics.rf[i->dest_reg].i64 = ics.rf[i->src1_reg].i64 * ics.rf[i->src2_reg].i64 + + ics.rf[i->src3_reg].i64; return IA_NEXT; } uint32_t IntCode_MUL_ADD_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f32 = ics.rf[i->src1_reg].f32 * ics.rf[i->src2_reg].f32 + ics.rf[i->src3_reg].f32; + ics.rf[i->dest_reg].f32 = ics.rf[i->src1_reg].f32 * ics.rf[i->src2_reg].f32 + + ics.rf[i->src3_reg].f32; return IA_NEXT; } uint32_t IntCode_MUL_ADD_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f64 = ics.rf[i->src1_reg].f64 * ics.rf[i->src2_reg].f64 + ics.rf[i->src3_reg].f64; + ics.rf[i->dest_reg].f64 = ics.rf[i->src1_reg].f64 * ics.rf[i->src2_reg].f64 + + ics.rf[i->src3_reg].f64; return IA_NEXT; } uint32_t IntCode_MUL_ADD_V128(IntCodeState& ics, const IntCode* i) { @@ -2744,40 +2919,42 @@ uint32_t IntCode_MUL_ADD_V128(IntCodeState& ics, const IntCode* i) { } int Translate_MUL_ADD(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_MUL_ADD_I8, - IntCode_MUL_ADD_I16, - IntCode_MUL_ADD_I32, - IntCode_MUL_ADD_I64, - IntCode_MUL_ADD_F32, - IntCode_MUL_ADD_F64, - IntCode_MUL_ADD_V128, + IntCode_MUL_ADD_I8, IntCode_MUL_ADD_I16, IntCode_MUL_ADD_I32, + IntCode_MUL_ADD_I64, IntCode_MUL_ADD_F32, IntCode_MUL_ADD_F64, + IntCode_MUL_ADD_V128, }; return DispatchToC(ctx, i, fns[i->dest->type]); } // TODO(benvanik): use intrinsics or something uint32_t IntCode_MUL_SUB_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 * ics.rf[i->src2_reg].i8 - ics.rf[i->src3_reg].i8; + ics.rf[i->dest_reg].i8 = + ics.rf[i->src1_reg].i8 * ics.rf[i->src2_reg].i8 - ics.rf[i->src3_reg].i8; return IA_NEXT; } uint32_t IntCode_MUL_SUB_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = ics.rf[i->src1_reg].i16 * ics.rf[i->src2_reg].i16 - ics.rf[i->src3_reg].i16; + ics.rf[i->dest_reg].i16 = ics.rf[i->src1_reg].i16 * ics.rf[i->src2_reg].i16 - + ics.rf[i->src3_reg].i16; return IA_NEXT; } uint32_t IntCode_MUL_SUB_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = ics.rf[i->src1_reg].i32 * ics.rf[i->src2_reg].i32 - ics.rf[i->src3_reg].i32; + ics.rf[i->dest_reg].i32 = ics.rf[i->src1_reg].i32 * ics.rf[i->src2_reg].i32 - + ics.rf[i->src3_reg].i32; return IA_NEXT; } uint32_t IntCode_MUL_SUB_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = ics.rf[i->src1_reg].i64 * ics.rf[i->src2_reg].i64 - ics.rf[i->src3_reg].i64; + ics.rf[i->dest_reg].i64 = ics.rf[i->src1_reg].i64 * ics.rf[i->src2_reg].i64 - + ics.rf[i->src3_reg].i64; return IA_NEXT; } uint32_t IntCode_MUL_SUB_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f32 = ics.rf[i->src1_reg].f32 * ics.rf[i->src2_reg].f32 - ics.rf[i->src3_reg].f32; + ics.rf[i->dest_reg].f32 = ics.rf[i->src1_reg].f32 * ics.rf[i->src2_reg].f32 - + ics.rf[i->src3_reg].f32; return IA_NEXT; } uint32_t IntCode_MUL_SUB_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f64 = ics.rf[i->src1_reg].f64 * ics.rf[i->src2_reg].f64 - ics.rf[i->src3_reg].f64; + ics.rf[i->dest_reg].f64 = ics.rf[i->src1_reg].f64 * ics.rf[i->src2_reg].f64 - + ics.rf[i->src3_reg].f64; return IA_NEXT; } uint32_t IntCode_MUL_SUB_V128(IntCodeState& ics, const IntCode* i) { @@ -2792,13 +2969,9 @@ uint32_t IntCode_MUL_SUB_V128(IntCodeState& ics, const IntCode* i) { } int Translate_MUL_SUB(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_MUL_SUB_I8, - IntCode_MUL_SUB_I16, - IntCode_MUL_SUB_I32, - IntCode_MUL_SUB_I64, - IntCode_MUL_SUB_F32, - IntCode_MUL_SUB_F64, - IntCode_MUL_SUB_V128, + IntCode_MUL_SUB_I8, IntCode_MUL_SUB_I16, IntCode_MUL_SUB_I32, + IntCode_MUL_SUB_I64, IntCode_MUL_SUB_F32, IntCode_MUL_SUB_F64, + IntCode_MUL_SUB_V128, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -2837,13 +3010,8 @@ uint32_t IntCode_NEG_V128(IntCodeState& ics, const IntCode* i) { } int Translate_NEG(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_NEG_I8, - IntCode_NEG_I16, - IntCode_NEG_I32, - IntCode_NEG_I64, - IntCode_NEG_F32, - IntCode_NEG_F64, - IntCode_NEG_V128, + IntCode_NEG_I8, IntCode_NEG_I16, IntCode_NEG_I32, IntCode_NEG_I64, + IntCode_NEG_F32, IntCode_NEG_F64, IntCode_NEG_V128, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -2882,13 +3050,8 @@ uint32_t IntCode_ABS_V128(IntCodeState& ics, const IntCode* i) { } int Translate_ABS(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_ABS_I8, - IntCode_ABS_I16, - IntCode_ABS_I32, - IntCode_ABS_I64, - IntCode_ABS_F32, - IntCode_ABS_F64, - IntCode_ABS_V128, + IntCode_ABS_I8, IntCode_ABS_I16, IntCode_ABS_I32, IntCode_ABS_I64, + IntCode_ABS_F32, IntCode_ABS_F64, IntCode_ABS_V128, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -2902,13 +3065,9 @@ uint32_t IntCode_DOT_PRODUCT_3_V128(IntCodeState& ics, const IntCode* i) { } int Translate_DOT_PRODUCT_3(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_DOT_PRODUCT_3_V128, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_DOT_PRODUCT_3_V128, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } @@ -2916,19 +3075,15 @@ int Translate_DOT_PRODUCT_3(TranslationContext& ctx, Instr* i) { uint32_t IntCode_DOT_PRODUCT_4_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; const vec128_t& src2 = ics.rf[i->src2_reg].v128; - ics.rf[i->dest_reg].f32 = - (src1.x * src2.x) + (src1.y * src2.y) + (src1.z * src2.z) + (src1.w * src2.w); + ics.rf[i->dest_reg].f32 = (src1.x * src2.x) + (src1.y * src2.y) + + (src1.z * src2.z) + (src1.w * src2.w); return IA_NEXT; } int Translate_DOT_PRODUCT_4(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_DOT_PRODUCT_4_V128, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_DOT_PRODUCT_4_V128, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } @@ -2951,13 +3106,9 @@ uint32_t IntCode_SQRT_V128(IntCodeState& ics, const IntCode* i) { } int Translate_SQRT(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_SQRT_F32, - IntCode_SQRT_F64, - IntCode_SQRT_V128, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_SQRT_F32, IntCode_SQRT_F64, + IntCode_SQRT_V128, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -2972,13 +3123,9 @@ uint32_t IntCode_RSQRT_V128(IntCodeState& ics, const IntCode* i) { } int Translate_RSQRT(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_RSQRT_V128, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_RSQRT_V128, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } @@ -3001,13 +3148,9 @@ uint32_t IntCode_POW2_V128(IntCodeState& ics, const IntCode* i) { } int Translate_POW2(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_POW2_F32, - IntCode_POW2_F64, - IntCode_POW2_V128, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_POW2_F32, IntCode_POW2_F64, + IntCode_POW2_V128, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -3030,13 +3173,9 @@ uint32_t IntCode_LOG2_V128(IntCodeState& ics, const IntCode* i) { } int Translate_LOG2(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_LOG2_F32, - IntCode_LOG2_F64, - IntCode_LOG2_V128, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_LOG2_F32, IntCode_LOG2_F64, + IntCode_LOG2_V128, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -3062,19 +3201,15 @@ uint32_t IntCode_AND_V128_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - VECI4(dest,n) = VECI4(src1,n) & VECI4(src2,n); + VECI4(dest, n) = VECI4(src1, n) & VECI4(src2, n); } return IA_NEXT; } int Translate_AND(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_AND_I8_I8, - IntCode_AND_I16_I16, - IntCode_AND_I32_I32, - IntCode_AND_I64_I64, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_AND_V128_V128, + IntCode_AND_I8_I8, IntCode_AND_I16_I16, IntCode_AND_I32_I32, + IntCode_AND_I64_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_AND_V128_V128, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -3100,19 +3235,15 @@ uint32_t IntCode_OR_V128_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - VECI4(dest,n) = VECI4(src1,n) | VECI4(src2,n); + VECI4(dest, n) = VECI4(src1, n) | VECI4(src2, n); } return IA_NEXT; } int Translate_OR(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_OR_I8_I8, - IntCode_OR_I16_I16, - IntCode_OR_I32_I32, - IntCode_OR_I64_I64, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_OR_V128_V128, + IntCode_OR_I8_I8, IntCode_OR_I16_I16, IntCode_OR_I32_I32, + IntCode_OR_I64_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_OR_V128_V128, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -3138,19 +3269,15 @@ uint32_t IntCode_XOR_V128_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - VECI4(dest,n) = VECI4(src1,n) ^ VECI4(src2,n); + VECI4(dest, n) = VECI4(src1, n) ^ VECI4(src2, n); } return IA_NEXT; } int Translate_XOR(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_XOR_I8_I8, - IntCode_XOR_I16_I16, - IntCode_XOR_I32_I32, - IntCode_XOR_I64_I64, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_XOR_V128_V128, + IntCode_XOR_I8_I8, IntCode_XOR_I16_I16, IntCode_XOR_I32_I32, + IntCode_XOR_I64_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_XOR_V128_V128, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -3175,19 +3302,15 @@ uint32_t IntCode_NOT_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - VECI4(dest,n) = ~VECI4(src1,n); + VECI4(dest, n) = ~VECI4(src1, n); } return IA_NEXT; } int Translate_NOT(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_NOT_I8, - IntCode_NOT_I16, - IntCode_NOT_I32, - IntCode_NOT_I64, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_NOT_V128, + IntCode_NOT_I8, IntCode_NOT_I16, IntCode_NOT_I32, + IntCode_NOT_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_NOT_V128, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -3210,13 +3333,9 @@ uint32_t IntCode_SHL_I64(IntCodeState& ics, const IntCode* i) { } int Translate_SHL(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_SHL_I8, - IntCode_SHL_I16, - IntCode_SHL_I32, - IntCode_SHL_I64, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, + IntCode_SHL_I8, IntCode_SHL_I16, IntCode_SHL_I32, + IntCode_SHL_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -3226,7 +3345,7 @@ uint32_t IntCode_VECTOR_SHL_I8(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 16; n++) { - VECB16(dest,n) = VECB16(src1,n) << (VECB16(src2,n) & 0x7); + VECB16(dest, n) = VECB16(src1, n) << (VECB16(src2, n) & 0x7); } return IA_NEXT; } @@ -3235,7 +3354,7 @@ uint32_t IntCode_VECTOR_SHL_I16(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 8; n++) { - VECS8(dest,n) = VECS8(src1,n) << (VECS8(src2,n) & 0xF); + VECS8(dest, n) = VECS8(src1, n) << (VECS8(src2, n) & 0xF); } return IA_NEXT; } @@ -3244,19 +3363,15 @@ uint32_t IntCode_VECTOR_SHL_I32(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - VECI4(dest,n) = VECI4(src1,n) << (VECI4(src2,n) & 0x1F); + VECI4(dest, n) = VECI4(src1, n) << (VECI4(src2, n) & 0x1F); } return IA_NEXT; } int Translate_VECTOR_SHL(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_VECTOR_SHL_I8, - IntCode_VECTOR_SHL_I16, - IntCode_VECTOR_SHL_I32, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, + IntCode_VECTOR_SHL_I8, IntCode_VECTOR_SHL_I16, IntCode_VECTOR_SHL_I32, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->flags]); } @@ -3279,13 +3394,9 @@ uint32_t IntCode_SHR_I64(IntCodeState& ics, const IntCode* i) { } int Translate_SHR(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_SHR_I8, - IntCode_SHR_I16, - IntCode_SHR_I32, - IntCode_SHR_I64, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, + IntCode_SHR_I8, IntCode_SHR_I16, IntCode_SHR_I32, + IntCode_SHR_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -3295,7 +3406,7 @@ uint32_t IntCode_VECTOR_SHR_I8(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 16; n++) { - VECB16(dest,n) = VECB16(src1,n) >> (VECB16(src2,n) & 0x7); + VECB16(dest, n) = VECB16(src1, n) >> (VECB16(src2, n) & 0x7); } return IA_NEXT; } @@ -3304,7 +3415,7 @@ uint32_t IntCode_VECTOR_SHR_I16(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 8; n++) { - VECS8(dest,n) = VECS8(src1,n) >> (VECS8(src2,n) & 0xF); + VECS8(dest, n) = VECS8(src1, n) >> (VECS8(src2, n) & 0xF); } return IA_NEXT; } @@ -3313,19 +3424,15 @@ uint32_t IntCode_VECTOR_SHR_I32(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - VECI4(dest,n) = VECI4(src1,n) >> (VECI4(src2,n) & 0x1F); + VECI4(dest, n) = VECI4(src1, n) >> (VECI4(src2, n) & 0x1F); } return IA_NEXT; } int Translate_VECTOR_SHR(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_VECTOR_SHR_I8, - IntCode_VECTOR_SHR_I16, - IntCode_VECTOR_SHR_I32, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, + IntCode_VECTOR_SHR_I8, IntCode_VECTOR_SHR_I16, IntCode_VECTOR_SHR_I32, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->flags]); } @@ -3348,13 +3455,9 @@ uint32_t IntCode_SHA_I64(IntCodeState& ics, const IntCode* i) { } int Translate_SHA(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_SHA_I8, - IntCode_SHA_I16, - IntCode_SHA_I32, - IntCode_SHA_I64, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, + IntCode_SHA_I8, IntCode_SHA_I16, IntCode_SHA_I32, + IntCode_SHA_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -3364,7 +3467,7 @@ uint32_t IntCode_VECTOR_SHA_I8(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 16; n++) { - VECB16(dest,n) = int8_t(VECB16(src1,n)) >> (VECB16(src2,n) & 0x7); + VECB16(dest, n) = int8_t(VECB16(src1, n)) >> (VECB16(src2, n) & 0x7); } return IA_NEXT; } @@ -3373,7 +3476,7 @@ uint32_t IntCode_VECTOR_SHA_I16(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 8; n++) { - VECS8(dest,n) = int16_t(VECS8(src1,n)) >> (VECS8(src2,n) & 0xF); + VECS8(dest, n) = int16_t(VECS8(src1, n)) >> (VECS8(src2, n) & 0xF); } return IA_NEXT; } @@ -3382,54 +3485,50 @@ uint32_t IntCode_VECTOR_SHA_I32(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - VECI4(dest,n) = int32_t(VECI4(src1,n)) >> (VECI4(src2,n) & 0x1F); + VECI4(dest, n) = int32_t(VECI4(src1, n)) >> (VECI4(src2, n) & 0x1F); } return IA_NEXT; } int Translate_VECTOR_SHA(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_VECTOR_SHA_I8, - IntCode_VECTOR_SHA_I16, - IntCode_VECTOR_SHA_I32, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, + IntCode_VECTOR_SHA_I8, IntCode_VECTOR_SHA_I16, IntCode_VECTOR_SHA_I32, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->flags]); } -template +template T ROTL(T v, int8_t sh) { return (T(v) << sh) | (T(v) >> ((sizeof(T) * 8) - sh)); } uint32_t IntCode_ROTATE_LEFT_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ROTL(ics.rf[i->src1_reg].i8, ics.rf[i->src2_reg].i8); + ics.rf[i->dest_reg].i8 = + ROTL(ics.rf[i->src1_reg].i8, ics.rf[i->src2_reg].i8); return IA_NEXT; } uint32_t IntCode_ROTATE_LEFT_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = ROTL(ics.rf[i->src1_reg].i16, ics.rf[i->src2_reg].i8); + ics.rf[i->dest_reg].i16 = + ROTL(ics.rf[i->src1_reg].i16, ics.rf[i->src2_reg].i8); return IA_NEXT; } uint32_t IntCode_ROTATE_LEFT_I32(IntCodeState& ics, const IntCode* i) { // TODO(benvanik): use _rtol on vc++ - ics.rf[i->dest_reg].i32 = ROTL(ics.rf[i->src1_reg].i32, ics.rf[i->src2_reg].i8); + ics.rf[i->dest_reg].i32 = + ROTL(ics.rf[i->src1_reg].i32, ics.rf[i->src2_reg].i8); return IA_NEXT; } uint32_t IntCode_ROTATE_LEFT_I64(IntCodeState& ics, const IntCode* i) { // TODO(benvanik): use _rtol64 on vc++ - ics.rf[i->dest_reg].i64 = ROTL(ics.rf[i->src1_reg].i64, ics.rf[i->src2_reg].i8); + ics.rf[i->dest_reg].i64 = + ROTL(ics.rf[i->src1_reg].i64, ics.rf[i->src2_reg].i8); return IA_NEXT; } int Translate_ROTATE_LEFT(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_ROTATE_LEFT_I8, - IntCode_ROTATE_LEFT_I16, - IntCode_ROTATE_LEFT_I32, - IntCode_ROTATE_LEFT_I64, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, + IntCode_ROTATE_LEFT_I8, IntCode_ROTATE_LEFT_I16, IntCode_ROTATE_LEFT_I32, + IntCode_ROTATE_LEFT_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -3450,19 +3549,15 @@ uint32_t IntCode_BYTE_SWAP_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - VECI4(dest,n) = XESWAP32(VECI4(src1,n)); + VECI4(dest, n) = XESWAP32(VECI4(src1, n)); } return IA_NEXT; } int Translate_BYTE_SWAP(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, - IntCode_BYTE_SWAP_I16, - IntCode_BYTE_SWAP_I32, - IntCode_BYTE_SWAP_I64, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_BYTE_SWAP_V128, + IntCode_INVALID_TYPE, IntCode_BYTE_SWAP_I16, IntCode_BYTE_SWAP_I32, + IntCode_BYTE_SWAP_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_BYTE_SWAP_V128, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -3501,42 +3596,56 @@ uint32_t IntCode_CNTLZ_I64(IntCodeState& ics, const IntCode* i) { } int Translate_CNTLZ(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_CNTLZ_I8, - IntCode_CNTLZ_I16, - IntCode_CNTLZ_I32, - IntCode_CNTLZ_I64, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, + IntCode_CNTLZ_I8, IntCode_CNTLZ_I16, IntCode_CNTLZ_I32, + IntCode_CNTLZ_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } uint32_t IntCode_EXTRACT_INT8_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; - ics.rf[i->dest_reg].i8 = VECB16(src1,ics.rf[i->src2_reg].i8); + ics.rf[i->dest_reg].i8 = VECB16(src1, ics.rf[i->src2_reg].i8); return IA_NEXT; } uint32_t IntCode_EXTRACT_INT16_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; - ics.rf[i->dest_reg].i16 = VECS8(src1,ics.rf[i->src2_reg].i8); + ics.rf[i->dest_reg].i16 = VECS8(src1, ics.rf[i->src2_reg].i8); return IA_NEXT; } uint32_t IntCode_EXTRACT_INT32_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; - ics.rf[i->dest_reg].i32 = VECI4(src1,ics.rf[i->src2_reg].i8); + ics.rf[i->dest_reg].i32 = VECI4(src1, ics.rf[i->src2_reg].i8); return IA_NEXT; } int Translate_EXTRACT(TranslationContext& ctx, Instr* i) { // Can do more as needed. static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_EXTRACT_INT8_V128, IntCode_EXTRACT_INT16_V128, IntCode_EXTRACT_INT32_V128, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_EXTRACT_INT8_V128, IntCode_EXTRACT_INT16_V128, + IntCode_EXTRACT_INT32_V128, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; IntCodeFn fn = fns[i->src1.value->type * MAX_TYPENAME + i->dest->type]; return DispatchToC(ctx, i, fn); @@ -3548,7 +3657,7 @@ uint32_t IntCode_INSERT_INT8_V128(IntCodeState& ics, const IntCode* i) { const uint8_t part = ics.rf[i->src3_reg].i8; vec128_t& dest = ics.rf[i->dest_reg].v128; for (size_t n = 0; n < 16; n++) { - VECB16(dest,n) = (n == offset) ? part : VECB16(src1,n); + VECB16(dest, n) = (n == offset) ? part : VECB16(src1, n); } return IA_NEXT; } @@ -3558,7 +3667,7 @@ uint32_t IntCode_INSERT_INT16_V128(IntCodeState& ics, const IntCode* i) { const uint16_t part = ics.rf[i->src3_reg].i16; vec128_t& dest = ics.rf[i->dest_reg].v128; for (size_t n = 0; n < 8; n++) { - VECS8(dest,n) = (n == offset) ? part : VECS8(src1,n); + VECS8(dest, n) = (n == offset) ? part : VECS8(src1, n); } return IA_NEXT; } @@ -3568,20 +3677,38 @@ uint32_t IntCode_INSERT_INT32_V128(IntCodeState& ics, const IntCode* i) { const uint32_t part = ics.rf[i->src3_reg].i32; vec128_t& dest = ics.rf[i->dest_reg].v128; for (size_t n = 0; n < 4; n++) { - VECI4(dest,n) = (n == offset) ? part : VECI4(src1,n); + VECI4(dest, n) = (n == offset) ? part : VECI4(src1, n); } return IA_NEXT; } int Translate_INSERT(TranslationContext& ctx, Instr* i) { // Can do more as needed. static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INSERT_INT8_V128, IntCode_INSERT_INT16_V128, IntCode_INSERT_INT32_V128, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INSERT_INT8_V128, IntCode_INSERT_INT16_V128, + IntCode_INSERT_INT32_V128, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; IntCodeFn fn = fns[i->src1.value->type * MAX_TYPENAME + i->src3.value->type]; return DispatchToC(ctx, i, fn); @@ -3591,7 +3718,7 @@ uint32_t IntCode_SPLAT_V128_INT8(IntCodeState& ics, const IntCode* i) { int8_t src1 = ics.rf[i->src1_reg].i8; vec128_t& dest = ics.rf[i->dest_reg].v128; for (size_t i = 0; i < 16; i++) { - VECB16(dest,i) = src1; + VECB16(dest, i) = src1; } return IA_NEXT; } @@ -3599,7 +3726,7 @@ uint32_t IntCode_SPLAT_V128_INT16(IntCodeState& ics, const IntCode* i) { int16_t src1 = ics.rf[i->src1_reg].i16; vec128_t& dest = ics.rf[i->dest_reg].v128; for (size_t i = 0; i < 8; i++) { - VECS8(dest,i) = src1; + VECS8(dest, i) = src1; } return IA_NEXT; } @@ -3607,7 +3734,7 @@ uint32_t IntCode_SPLAT_V128_INT32(IntCodeState& ics, const IntCode* i) { int32_t src1 = ics.rf[i->src1_reg].i32; vec128_t& dest = ics.rf[i->dest_reg].v128; for (size_t i = 0; i < 4; i++) { - VECI4(dest,i) = src1; + VECI4(dest, i) = src1; } return IA_NEXT; } @@ -3622,13 +3749,31 @@ uint32_t IntCode_SPLAT_V128_FLOAT32(IntCodeState& ics, const IntCode* i) { int Translate_SPLAT(TranslationContext& ctx, Instr* i) { // Can do more as needed. static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_SPLAT_V128_INT8, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_SPLAT_V128_INT16, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_SPLAT_V128_INT32, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_SPLAT_V128_FLOAT32, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_SPLAT_V128_INT8, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_SPLAT_V128_INT16, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_SPLAT_V128_INT32, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_SPLAT_V128_FLOAT32, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; IntCodeFn fn = fns[i->src1.value->type * MAX_TYPENAME + i->dest->type]; return DispatchToC(ctx, i, fn); @@ -3641,9 +3786,7 @@ uint32_t IntCode_PERMUTE_V128_BY_INT32(IntCodeState& ics, const IntCode* i) { vec128_t& dest = ics.rf[i->dest_reg].v128; for (size_t i = 0; i < 4; i++) { size_t b = (table >> ((3 - i) * 8)) & 0x7; - VECI4(dest,i) = b < 4 ? - VECI4(src2,b) : - VECI4(src3,b-4); + VECI4(dest, i) = b < 4 ? VECI4(src2, b) : VECI4(src3, b - 4); } return IA_NEXT; } @@ -3654,23 +3797,40 @@ uint32_t IntCode_PERMUTE_V128_BY_V128(IntCodeState& ics, const IntCode* i) { vec128_t& dest = ics.rf[i->dest_reg].v128; dest.low = dest.high = 0; for (size_t n = 0; n < 16; n++) { - uint8_t index = VECB16(table,n) & 0x1F; - VECB16(dest,n) = index < 16 - ? VECB16(src2,index) - : VECB16(src3,index-16); + uint8_t index = VECB16(table, n) & 0x1F; + VECB16(dest, n) = + index < 16 ? VECB16(src2, index) : VECB16(src3, index - 16); } return IA_NEXT; } int Translate_PERMUTE(TranslationContext& ctx, Instr* i) { // Can do more as needed. static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_PERMUTE_V128_BY_INT32, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_PERMUTE_V128_BY_V128, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_PERMUTE_V128_BY_INT32, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_PERMUTE_V128_BY_V128, }; IntCodeFn fn = fns[i->src1.value->type * MAX_TYPENAME + i->dest->type]; return DispatchToC(ctx, i, fn); @@ -3680,21 +3840,17 @@ uint32_t IntCode_SWIZZLE_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; uint32_t swizzle_mask = ics.rf[i->src2_reg].u32; vec128_t& dest = ics.rf[i->dest_reg].v128; - VECI4(dest,0) = VECI4(src1,(swizzle_mask >> 6) & 0x3); - VECI4(dest,1) = VECI4(src1,(swizzle_mask >> 4) & 0x3); - VECI4(dest,2) = VECI4(src1,(swizzle_mask >> 2) & 0x3); - VECI4(dest,3) = VECI4(src1,(swizzle_mask) & 0x3); + VECI4(dest, 0) = VECI4(src1, (swizzle_mask >> 6) & 0x3); + VECI4(dest, 1) = VECI4(src1, (swizzle_mask >> 4) & 0x3); + VECI4(dest, 2) = VECI4(src1, (swizzle_mask >> 2) & 0x3); + VECI4(dest, 3) = VECI4(src1, (swizzle_mask)&0x3); return IA_NEXT; } int Translate_SWIZZLE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_SWIZZLE_V128, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_SWIZZLE_V128, }; return DispatchToC(ctx, i, fns[i->src1.value->type]); } @@ -3708,9 +3864,7 @@ uint32_t IntCode_PACK_D3DCOLOR(IntCodeState& ics, const IntCode* i) { float g = roundf(((src1.y < 0) ? 0 : ((1 < src1.y) ? 1 : src1.y)) * 255); float b = roundf(((src1.z < 0) ? 0 : ((1 < src1.z) ? 1 : src1.z)) * 255); float a = roundf(((src1.w < 0) ? 0 : ((1 < src1.w) ? 1 : src1.w)) * 255); - dest.iw = ((uint32_t)a << 24) | - ((uint32_t)r << 16) | - ((uint32_t)g << 8) | + dest.iw = ((uint32_t)a << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | ((uint32_t)b); return IA_NEXT; } @@ -3754,14 +3908,9 @@ uint32_t IntCode_PACK_SHORT_2(IntCodeState& ics, const IntCode* i) { } int Translate_PACK(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_PACK_D3DCOLOR, - IntCode_PACK_FLOAT16_2, - IntCode_PACK_FLOAT16_4, - IntCode_PACK_SHORT_2, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, + IntCode_PACK_D3DCOLOR, IntCode_PACK_FLOAT16_2, IntCode_PACK_FLOAT16_4, + IntCode_PACK_SHORT_2, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->flags]); } @@ -3813,63 +3962,59 @@ uint32_t IntCode_UNPACK_SHORT_2(IntCodeState& ics, const IntCode* i) { dest.f4[0] = 3.0f + ((float)sx / (float)(1 << 22)); dest.f4[1] = 3.0f + ((float)sy / (float)(1 << 22)); dest.f4[2] = 0.0f; - dest.f4[3] = 1.0f; // 3? + dest.f4[3] = 1.0f; // 3? return IA_NEXT; } uint32_t IntCode_UNPACK_S8_IN_16_LO(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; - VECS8(dest,0) = (int16_t)(int8_t)VECB16(src1,8+0); - VECS8(dest,1) = (int16_t)(int8_t)VECB16(src1,8+1); - VECS8(dest,2) = (int16_t)(int8_t)VECB16(src1,8+2); - VECS8(dest,3) = (int16_t)(int8_t)VECB16(src1,8+3); - VECS8(dest,4) = (int16_t)(int8_t)VECB16(src1,8+4); - VECS8(dest,5) = (int16_t)(int8_t)VECB16(src1,8+5); - VECS8(dest,6) = (int16_t)(int8_t)VECB16(src1,8+6); - VECS8(dest,7) = (int16_t)(int8_t)VECB16(src1,8+7); + VECS8(dest, 0) = (int16_t)(int8_t)VECB16(src1, 8 + 0); + VECS8(dest, 1) = (int16_t)(int8_t)VECB16(src1, 8 + 1); + VECS8(dest, 2) = (int16_t)(int8_t)VECB16(src1, 8 + 2); + VECS8(dest, 3) = (int16_t)(int8_t)VECB16(src1, 8 + 3); + VECS8(dest, 4) = (int16_t)(int8_t)VECB16(src1, 8 + 4); + VECS8(dest, 5) = (int16_t)(int8_t)VECB16(src1, 8 + 5); + VECS8(dest, 6) = (int16_t)(int8_t)VECB16(src1, 8 + 6); + VECS8(dest, 7) = (int16_t)(int8_t)VECB16(src1, 8 + 7); return IA_NEXT; } uint32_t IntCode_UNPACK_S8_IN_16_HI(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; - VECS8(dest,0) = (int16_t)(int8_t)VECB16(src1,0); - VECS8(dest,1) = (int16_t)(int8_t)VECB16(src1,1); - VECS8(dest,2) = (int16_t)(int8_t)VECB16(src1,2); - VECS8(dest,3) = (int16_t)(int8_t)VECB16(src1,3); - VECS8(dest,4) = (int16_t)(int8_t)VECB16(src1,4); - VECS8(dest,5) = (int16_t)(int8_t)VECB16(src1,5); - VECS8(dest,6) = (int16_t)(int8_t)VECB16(src1,6); - VECS8(dest,7) = (int16_t)(int8_t)VECB16(src1,7); + VECS8(dest, 0) = (int16_t)(int8_t)VECB16(src1, 0); + VECS8(dest, 1) = (int16_t)(int8_t)VECB16(src1, 1); + VECS8(dest, 2) = (int16_t)(int8_t)VECB16(src1, 2); + VECS8(dest, 3) = (int16_t)(int8_t)VECB16(src1, 3); + VECS8(dest, 4) = (int16_t)(int8_t)VECB16(src1, 4); + VECS8(dest, 5) = (int16_t)(int8_t)VECB16(src1, 5); + VECS8(dest, 6) = (int16_t)(int8_t)VECB16(src1, 6); + VECS8(dest, 7) = (int16_t)(int8_t)VECB16(src1, 7); return IA_NEXT; } uint32_t IntCode_UNPACK_S16_IN_32_LO(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; - VECI4(dest,0) = (int32_t)(int16_t)VECS8(src1,4+0); - VECI4(dest,1) = (int32_t)(int16_t)VECS8(src1,4+1); - VECI4(dest,2) = (int32_t)(int16_t)VECS8(src1,4+2); - VECI4(dest,3) = (int32_t)(int16_t)VECS8(src1,4+3); + VECI4(dest, 0) = (int32_t)(int16_t)VECS8(src1, 4 + 0); + VECI4(dest, 1) = (int32_t)(int16_t)VECS8(src1, 4 + 1); + VECI4(dest, 2) = (int32_t)(int16_t)VECS8(src1, 4 + 2); + VECI4(dest, 3) = (int32_t)(int16_t)VECS8(src1, 4 + 3); return IA_NEXT; } uint32_t IntCode_UNPACK_S16_IN_32_HI(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; - VECI4(dest,0) = (int32_t)(int16_t)VECS8(src1,0); - VECI4(dest,1) = (int32_t)(int16_t)VECS8(src1,1); - VECI4(dest,2) = (int32_t)(int16_t)VECS8(src1,2); - VECI4(dest,3) = (int32_t)(int16_t)VECS8(src1,3); + VECI4(dest, 0) = (int32_t)(int16_t)VECS8(src1, 0); + VECI4(dest, 1) = (int32_t)(int16_t)VECS8(src1, 1); + VECI4(dest, 2) = (int32_t)(int16_t)VECS8(src1, 2); + VECI4(dest, 3) = (int32_t)(int16_t)VECS8(src1, 3); return IA_NEXT; } int Translate_UNPACK(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_UNPACK_D3DCOLOR, - IntCode_UNPACK_FLOAT16_2, - IntCode_UNPACK_FLOAT16_4, - IntCode_UNPACK_SHORT_2, - IntCode_UNPACK_S8_IN_16_LO, - IntCode_UNPACK_S8_IN_16_HI, - IntCode_UNPACK_S16_IN_32_LO, - IntCode_UNPACK_S16_IN_32_HI, + IntCode_UNPACK_D3DCOLOR, IntCode_UNPACK_FLOAT16_2, + IntCode_UNPACK_FLOAT16_4, IntCode_UNPACK_SHORT_2, + IntCode_UNPACK_S8_IN_16_LO, IntCode_UNPACK_S8_IN_16_HI, + IntCode_UNPACK_S16_IN_32_LO, IntCode_UNPACK_S16_IN_32_HI, }; return DispatchToC(ctx, i, fns[i->flags]); } @@ -3890,136 +4035,70 @@ uint32_t IntCode_ATOMIC_EXCHANGE_I64(IntCodeState& ics, const IntCode* i) { } int Translate_ATOMIC_EXCHANGE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_ATOMIC_EXCHANGE_I32, - IntCode_ATOMIC_EXCHANGE_I64, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_ATOMIC_EXCHANGE_I32, IntCode_ATOMIC_EXCHANGE_I64, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->src2.value->type]); } typedef int (*TranslateFn)(TranslationContext& ctx, Instr* i); static const TranslateFn dispatch_table[] = { - Translate_COMMENT, - - Translate_NOP, - - Translate_SOURCE_OFFSET, - - Translate_DEBUG_BREAK, - Translate_DEBUG_BREAK_TRUE, - - Translate_TRAP, - Translate_TRAP_TRUE, - - Translate_CALL, - Translate_CALL_TRUE, - Translate_CALL_INDIRECT, - Translate_CALL_INDIRECT_TRUE, - Translate_CALL_EXTERN, - Translate_RETURN, - Translate_RETURN_TRUE, - Translate_SET_RETURN_ADDRESS, - - Translate_BRANCH, - Translate_BRANCH_TRUE, - Translate_BRANCH_FALSE, - - Translate_ASSIGN, - Translate_CAST, - Translate_ZERO_EXTEND, - Translate_SIGN_EXTEND, - Translate_TRUNCATE, - Translate_CONVERT, - Translate_ROUND, - Translate_VECTOR_CONVERT_I2F, - Translate_VECTOR_CONVERT_F2I, - - Translate_LOAD_VECTOR_SHL, - Translate_LOAD_VECTOR_SHR, - - Translate_LOAD_CLOCK, - - Translate_LOAD_LOCAL, - Translate_STORE_LOCAL, - - Translate_LOAD_CONTEXT, - Translate_STORE_CONTEXT, - - Translate_LOAD, - Translate_STORE, - Translate_PREFETCH, - - Translate_MAX, - Translate_MIN, - Translate_SELECT, - Translate_IS_TRUE, - Translate_IS_FALSE, - Translate_COMPARE_EQ, - Translate_COMPARE_NE, - Translate_COMPARE_SLT, - Translate_COMPARE_SLE, - Translate_COMPARE_SGT, - Translate_COMPARE_SGE, - Translate_COMPARE_ULT, - Translate_COMPARE_ULE, - Translate_COMPARE_UGT, - Translate_COMPARE_UGE, - Translate_DID_CARRY, - TranslateInvalid, //Translate_DID_OVERFLOW, - Translate_DID_SATURATE, - Translate_VECTOR_COMPARE_EQ, - Translate_VECTOR_COMPARE_SGT, - Translate_VECTOR_COMPARE_SGE, - Translate_VECTOR_COMPARE_UGT, - Translate_VECTOR_COMPARE_UGE, - - Translate_ADD, - Translate_ADD_CARRY, - Translate_VECTOR_ADD, - Translate_SUB, - Translate_MUL, - Translate_MUL_HI, - Translate_DIV, - Translate_MUL_ADD, - Translate_MUL_SUB, - Translate_NEG, - Translate_ABS, - Translate_SQRT, - Translate_RSQRT, - Translate_POW2, - Translate_LOG2, - Translate_DOT_PRODUCT_3, - Translate_DOT_PRODUCT_4, - - Translate_AND, - Translate_OR, - Translate_XOR, - Translate_NOT, - Translate_SHL, - Translate_VECTOR_SHL, - Translate_SHR, - Translate_VECTOR_SHR, - Translate_SHA, - Translate_VECTOR_SHA, - Translate_ROTATE_LEFT, - Translate_BYTE_SWAP, - Translate_CNTLZ, - Translate_INSERT, - Translate_EXTRACT, - Translate_SPLAT, - Translate_PERMUTE, - Translate_SWIZZLE, - Translate_PACK, - Translate_UNPACK, - - TranslateInvalid, //Translate_COMPARE_EXCHANGE, - Translate_ATOMIC_EXCHANGE, - TranslateInvalid, //Translate_ATOMIC_ADD, - TranslateInvalid, //Translate_ATOMIC_SUB, + Translate_COMMENT, Translate_NOP, + Translate_SOURCE_OFFSET, Translate_DEBUG_BREAK, + Translate_DEBUG_BREAK_TRUE, Translate_TRAP, + Translate_TRAP_TRUE, Translate_CALL, + Translate_CALL_TRUE, Translate_CALL_INDIRECT, + Translate_CALL_INDIRECT_TRUE, Translate_CALL_EXTERN, + Translate_RETURN, Translate_RETURN_TRUE, + Translate_SET_RETURN_ADDRESS, Translate_BRANCH, + Translate_BRANCH_TRUE, Translate_BRANCH_FALSE, + Translate_ASSIGN, Translate_CAST, + Translate_ZERO_EXTEND, Translate_SIGN_EXTEND, + Translate_TRUNCATE, Translate_CONVERT, + Translate_ROUND, Translate_VECTOR_CONVERT_I2F, + Translate_VECTOR_CONVERT_F2I, Translate_LOAD_VECTOR_SHL, + Translate_LOAD_VECTOR_SHR, Translate_LOAD_CLOCK, + Translate_LOAD_LOCAL, Translate_STORE_LOCAL, + Translate_LOAD_CONTEXT, Translate_STORE_CONTEXT, + Translate_LOAD, Translate_STORE, + Translate_PREFETCH, Translate_MAX, + Translate_MIN, Translate_SELECT, + Translate_IS_TRUE, Translate_IS_FALSE, + Translate_COMPARE_EQ, Translate_COMPARE_NE, + Translate_COMPARE_SLT, Translate_COMPARE_SLE, + Translate_COMPARE_SGT, Translate_COMPARE_SGE, + Translate_COMPARE_ULT, Translate_COMPARE_ULE, + Translate_COMPARE_UGT, Translate_COMPARE_UGE, + Translate_DID_CARRY, + TranslateInvalid, // Translate_DID_OVERFLOW, + Translate_DID_SATURATE, Translate_VECTOR_COMPARE_EQ, + Translate_VECTOR_COMPARE_SGT, Translate_VECTOR_COMPARE_SGE, + Translate_VECTOR_COMPARE_UGT, Translate_VECTOR_COMPARE_UGE, + Translate_ADD, Translate_ADD_CARRY, + Translate_VECTOR_ADD, Translate_SUB, + Translate_MUL, Translate_MUL_HI, + Translate_DIV, Translate_MUL_ADD, + Translate_MUL_SUB, Translate_NEG, + Translate_ABS, Translate_SQRT, + Translate_RSQRT, Translate_POW2, + Translate_LOG2, Translate_DOT_PRODUCT_3, + Translate_DOT_PRODUCT_4, Translate_AND, + Translate_OR, Translate_XOR, + Translate_NOT, Translate_SHL, + Translate_VECTOR_SHL, Translate_SHR, + Translate_VECTOR_SHR, Translate_SHA, + Translate_VECTOR_SHA, Translate_ROTATE_LEFT, + Translate_BYTE_SWAP, Translate_CNTLZ, + Translate_INSERT, Translate_EXTRACT, + Translate_SPLAT, Translate_PERMUTE, + Translate_SWIZZLE, Translate_PACK, + Translate_UNPACK, + TranslateInvalid, // Translate_COMPARE_EXCHANGE, + Translate_ATOMIC_EXCHANGE, + TranslateInvalid, // Translate_ATOMIC_ADD, + TranslateInvalid, // Translate_ATOMIC_SUB, }; int TranslateIntCodes(TranslationContext& ctx, Instr* i) { @@ -4027,7 +4106,6 @@ int TranslateIntCodes(TranslationContext& ctx, Instr* i) { return fn(ctx, i); } - } // namespace ivm } // namespace backend } // namespace alloy diff --git a/src/alloy/backend/ivm/ivm_intcode.h b/src/alloy/backend/ivm/ivm_intcode.h index 389ccbef2..bd982eef1 100644 --- a/src/alloy/backend/ivm/ivm_intcode.h +++ b/src/alloy/backend/ivm/ivm_intcode.h @@ -15,104 +15,96 @@ #include #include -namespace alloy { namespace runtime { class ThreadState; } } - +namespace alloy { +namespace runtime { +class ThreadState; +} +} namespace alloy { namespace backend { namespace ivm { - typedef union { - int8_t i8; - uint8_t u8; - int16_t i16; - uint16_t u16; - int32_t i32; - uint32_t u32; - int64_t i64; - uint64_t u64; - float f32; - double f64; - vec128_t v128; + int8_t i8; + uint8_t u8; + int16_t i16; + uint16_t u16; + int32_t i32; + uint32_t u32; + int64_t i64; + uint64_t u64; + float f32; + double f64; + vec128_t v128; } Register; - typedef struct { - Register* rf; - uint8_t* locals; - uint8_t* context; - uint8_t* membase; - uint8_t* page_table; - int8_t did_carry; - int8_t did_saturate; + Register* rf; + uint8_t* locals; + uint8_t* context; + uint8_t* membase; + uint8_t* page_table; + int8_t did_carry; + int8_t did_saturate; runtime::ThreadState* thread_state; - uint64_t return_address; - uint64_t call_return_address; + uint64_t return_address; + uint64_t call_return_address; } IntCodeState; - struct IntCode_s; -typedef uint32_t (*IntCodeFn)( - IntCodeState& ics, const struct IntCode_s* i); +typedef uint32_t (*IntCodeFn)(IntCodeState& ics, const struct IntCode_s* i); #define IA_RETURN 0xA0000000 -#define IA_NEXT 0xB0000000 - +#define IA_NEXT 0xB0000000 typedef struct IntCode_s { IntCodeFn intcode_fn; - uint16_t flags; - uint16_t debug_flags; + uint16_t flags; + uint16_t debug_flags; - uint32_t dest_reg; + uint32_t dest_reg; union { struct { - uint32_t src1_reg; - uint32_t src2_reg; - uint32_t src3_reg; + uint32_t src1_reg; + uint32_t src2_reg; + uint32_t src3_reg; // <4 bytes available> }; struct { - Register constant; + Register constant; }; }; // debugging info/etc } IntCode; - typedef struct LabelRef_s { hir::Label* label; - IntCode* instr; + IntCode* instr; LabelRef_s* next; } LabelRef; - typedef struct SourceMapEntry_s { - uint64_t source_offset; - uint64_t intcode_index; + uint64_t source_offset; + uint64_t intcode_index; } SourceMapEntry; - typedef struct { - uint32_t register_count; - size_t intcode_count; - Arena* intcode_arena; - size_t source_map_count; - Arena* source_map_arena; - Arena* scratch_arena; + uint32_t register_count; + size_t intcode_count; + Arena* intcode_arena; + size_t source_map_count; + Arena* source_map_arena; + Arena* scratch_arena; LabelRef* label_ref_head; - size_t stack_size; + size_t stack_size; } TranslationContext; - int TranslateIntCodes(TranslationContext& ctx, hir::Instr* i); - } // namespace ivm } // namespace backend } // namespace alloy - #endif // ALLOY_BACKEND_IVM_INTCODE_H_ diff --git a/src/alloy/backend/ivm/ivm_stack.cc b/src/alloy/backend/ivm/ivm_stack.cc index 4adb8c158..62eb85e20 100644 --- a/src/alloy/backend/ivm/ivm_stack.cc +++ b/src/alloy/backend/ivm/ivm_stack.cc @@ -9,15 +9,12 @@ #include -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::backend::ivm; +namespace alloy { +namespace backend { +namespace ivm { - -IVMStack::IVMStack() : - chunk_size_(2 * 1024 * 1024), - head_chunk_(NULL), active_chunk_(NULL) { -} +IVMStack::IVMStack() + : chunk_size_(2 * 1024 * 1024), head_chunk_(NULL), active_chunk_(NULL) {} IVMStack::~IVMStack() { Chunk* chunk = head_chunk_; @@ -35,7 +32,7 @@ Register* IVMStack::Alloc(size_t register_count) { if (active_chunk_->capacity - active_chunk_->offset < size) { Chunk* next = active_chunk_->next; if (!next) { - XEASSERT(size < chunk_size_); // need to support larger chunks + XEASSERT(size < chunk_size_); // need to support larger chunks next = new Chunk(chunk_size_); next->prev = active_chunk_; active_chunk_->next = next; @@ -66,9 +63,8 @@ void IVMStack::Free(size_t register_count) { } } -IVMStack::Chunk::Chunk(size_t chunk_size) : - prev(NULL), next(NULL), - capacity(chunk_size), buffer(0), offset(0) { +IVMStack::Chunk::Chunk(size_t chunk_size) + : prev(NULL), next(NULL), capacity(chunk_size), buffer(0), offset(0) { buffer = (uint8_t*)xe_malloc(capacity); } @@ -77,3 +73,7 @@ IVMStack::Chunk::~Chunk() { xe_free(buffer); } } + +} // namespace ivm +} // namespace backend +} // namespace alloy diff --git a/src/alloy/backend/ivm/ivm_stack.h b/src/alloy/backend/ivm/ivm_stack.h index f2e955265..1d447ffc7 100644 --- a/src/alloy/backend/ivm/ivm_stack.h +++ b/src/alloy/backend/ivm/ivm_stack.h @@ -14,44 +14,40 @@ #include - namespace alloy { namespace backend { namespace ivm { - class IVMStack { -public: + public: IVMStack(); ~IVMStack(); Register* Alloc(size_t register_count); void Free(size_t register_count); -private: + private: class Chunk { - public: + public: Chunk(size_t chunk_size); ~Chunk(); - Chunk* prev; - Chunk* next; + Chunk* prev; + Chunk* next; - size_t capacity; - uint8_t* buffer; - size_t offset; + size_t capacity; + uint8_t* buffer; + size_t offset; }; -private: - size_t chunk_size_; - Chunk* head_chunk_; - Chunk* active_chunk_; + private: + size_t chunk_size_; + Chunk* head_chunk_; + Chunk* active_chunk_; }; - } // namespace ivm } // namespace backend } // namespace alloy - #endif // ALLOY_BACKEND_IVM_IVM_STACK_H_ diff --git a/src/alloy/backend/ivm/tracing.h b/src/alloy/backend/ivm/tracing.h index 526aa912e..bf48319ae 100644 --- a/src/alloy/backend/ivm/tracing.h +++ b/src/alloy/backend/ivm/tracing.h @@ -12,24 +12,20 @@ #include - namespace alloy { namespace backend { namespace ivm { -const uint32_t ALLOY_BACKEND_IVM = - alloy::backend::EventType::ALLOY_BACKEND_IVM; - +const uint32_t ALLOY_BACKEND_IVM = alloy::backend::EventType::ALLOY_BACKEND_IVM; class EventType { -public: + public: enum { - ALLOY_BACKEND_IVM_INIT = ALLOY_BACKEND_IVM | (1), - ALLOY_BACKEND_IVM_DEINIT = ALLOY_BACKEND_IVM | (2), - - ALLOY_BACKEND_IVM_ASSEMBLER = ALLOY_BACKEND_IVM | (1 << 20), - ALLOY_BACKEND_IVM_ASSEMBLER_INIT = ALLOY_BACKEND_IVM_ASSEMBLER | (1), - ALLOY_BACKEND_IVM_ASSEMBLER_DEINIT = ALLOY_BACKEND_IVM_ASSEMBLER | (2), + ALLOY_BACKEND_IVM_INIT = ALLOY_BACKEND_IVM | (1), + ALLOY_BACKEND_IVM_DEINIT = ALLOY_BACKEND_IVM | (2), + ALLOY_BACKEND_IVM_ASSEMBLER = ALLOY_BACKEND_IVM | (1 << 20), + ALLOY_BACKEND_IVM_ASSEMBLER_INIT = ALLOY_BACKEND_IVM_ASSEMBLER | (1), + ALLOY_BACKEND_IVM_ASSEMBLER_DEINIT = ALLOY_BACKEND_IVM_ASSEMBLER | (2), }; typedef struct Init_s { @@ -47,10 +43,8 @@ public: } AssemblerDeinit; }; - } // namespace ivm } // namespace backend } // namespace alloy - #endif // ALLOY_BACKEND_IVM_TRACING_H_ diff --git a/src/alloy/backend/machine_info.h b/src/alloy/backend/machine_info.h index 2aa7add22..d041489e4 100644 --- a/src/alloy/backend/machine_info.h +++ b/src/alloy/backend/machine_info.h @@ -12,11 +12,9 @@ #include - namespace alloy { namespace backend { - struct MachineInfo { struct RegisterSet { enum Types { @@ -31,9 +29,7 @@ struct MachineInfo { } register_sets[8]; }; - } // namespace backend } // namespace alloy - #endif // ALLOY_BACKEND_MACHINE_INFO_H_ diff --git a/src/alloy/backend/tracing.h b/src/alloy/backend/tracing.h index 5aca2bd80..a7a8c934c 100644 --- a/src/alloy/backend/tracing.h +++ b/src/alloy/backend/tracing.h @@ -13,24 +13,20 @@ #include #include - namespace alloy { namespace backend { const uint32_t ALLOY_BACKEND = alloy::tracing::EventType::ALLOY_BACKEND; - class EventType { -public: + public: enum { - ALLOY_BACKEND_IVM = ALLOY_BACKEND | (1 << 24), - ALLOY_BACKEND_X64 = ALLOY_BACKEND | (2 << 24), + ALLOY_BACKEND_IVM = ALLOY_BACKEND | (1 << 24), + ALLOY_BACKEND_X64 = ALLOY_BACKEND | (2 << 24), }; }; - } // namespace backend } // namespace alloy - #endif // ALLOY_BACKEND_TRACING_H_ diff --git a/src/alloy/backend/x64/tracing.h b/src/alloy/backend/x64/tracing.h index e6689b830..5045f93f5 100644 --- a/src/alloy/backend/x64/tracing.h +++ b/src/alloy/backend/x64/tracing.h @@ -12,24 +12,20 @@ #include - namespace alloy { namespace backend { namespace x64 { -const uint32_t ALLOY_BACKEND_X64 = - alloy::backend::EventType::ALLOY_BACKEND_X64; - +const uint32_t ALLOY_BACKEND_X64 = alloy::backend::EventType::ALLOY_BACKEND_X64; class EventType { -public: + public: enum { - ALLOY_BACKEND_X64_INIT = ALLOY_BACKEND_X64 | (1), - ALLOY_BACKEND_X64_DEINIT = ALLOY_BACKEND_X64 | (2), - - ALLOY_BACKEND_X64_ASSEMBLER = ALLOY_BACKEND_X64 | (1 << 20), - ALLOY_BACKEND_X64_ASSEMBLER_INIT = ALLOY_BACKEND_X64_ASSEMBLER | (1), - ALLOY_BACKEND_X64_ASSEMBLER_DEINIT = ALLOY_BACKEND_X64_ASSEMBLER | (2), + ALLOY_BACKEND_X64_INIT = ALLOY_BACKEND_X64 | (1), + ALLOY_BACKEND_X64_DEINIT = ALLOY_BACKEND_X64 | (2), + ALLOY_BACKEND_X64_ASSEMBLER = ALLOY_BACKEND_X64 | (1 << 20), + ALLOY_BACKEND_X64_ASSEMBLER_INIT = ALLOY_BACKEND_X64_ASSEMBLER | (1), + ALLOY_BACKEND_X64_ASSEMBLER_DEINIT = ALLOY_BACKEND_X64_ASSEMBLER | (2), }; typedef struct Init_s { @@ -47,10 +43,8 @@ public: } AssemblerDeinit; }; - } // namespace x64 } // namespace backend } // namespace alloy - #endif // ALLOY_BACKEND_X64_TRACING_H_ diff --git a/src/alloy/backend/x64/x64_assembler.cc b/src/alloy/backend/x64/x64_assembler.cc index d70afe909..b274a7eca 100644 --- a/src/alloy/backend/x64/x64_assembler.cc +++ b/src/alloy/backend/x64/x64_assembler.cc @@ -21,22 +21,23 @@ namespace BE { #include } -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::backend::x64; -using namespace alloy::hir; +namespace alloy { +namespace backend { +namespace x64 { + +// TODO(benvanik): remove when enums redefined. using namespace alloy::runtime; +using alloy::hir::HIRBuilder; +using alloy::runtime::DebugInfo; +using alloy::runtime::Function; +using alloy::runtime::FunctionInfo; -X64Assembler::X64Assembler(X64Backend* backend) : - x64_backend_(backend), - emitter_(0), allocator_(0), - Assembler(backend) { -} +X64Assembler::X64Assembler(X64Backend* backend) + : x64_backend_(backend), emitter_(0), allocator_(0), Assembler(backend) {} X64Assembler::~X64Assembler() { - alloy::tracing::WriteEvent(EventType::AssemblerDeinit({ - })); + alloy::tracing::WriteEvent(EventType::AssemblerDeinit({})); delete emitter_; delete allocator_; @@ -51,8 +52,7 @@ int X64Assembler::Initialize() { allocator_ = new XbyakAllocator(); emitter_ = new X64Emitter(x64_backend_, allocator_); - alloy::tracing::WriteEvent(EventType::AssemblerInit({ - })); + alloy::tracing::WriteEvent(EventType::AssemblerInit({})); return result; } @@ -62,10 +62,9 @@ void X64Assembler::Reset() { Assembler::Reset(); } -int X64Assembler::Assemble( - FunctionInfo* symbol_info, HIRBuilder* builder, - uint32_t debug_info_flags, DebugInfo* debug_info, - Function** out_function) { +int X64Assembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder, + uint32_t debug_info_flags, DebugInfo* debug_info, + Function** out_function) { SCOPE_profile_cpu_f("alloy"); int result = 0; @@ -73,13 +72,12 @@ int X64Assembler::Assemble( // Lower HIR -> x64. void* machine_code = 0; size_t code_size = 0; - result = emitter_->Emit(builder, - debug_info_flags, debug_info, - machine_code, code_size); + result = emitter_->Emit(builder, debug_info_flags, debug_info, machine_code, + code_size); XEEXPECTZERO(result); // Stash generated machine code. - if (debug_info_flags & DEBUG_INFO_MACHINE_CODE_DISASM) { + if (debug_info_flags & DebugInfoFlags::DEBUG_INFO_MACHINE_CODE_DISASM) { DumpMachineCode(debug_info, machine_code, code_size, &string_buffer_); debug_info->set_machine_code_disasm(string_buffer_.ToString()); string_buffer_.Reset(); @@ -100,10 +98,8 @@ XECLEANUP: return result; } -void X64Assembler::DumpMachineCode( - DebugInfo* debug_info, - void* machine_code, size_t code_size, - StringBuffer* str) { +void X64Assembler::DumpMachineCode(DebugInfo* debug_info, void* machine_code, + size_t code_size, StringBuffer* str) { BE::DISASM disasm; xe_zero_struct(&disasm, sizeof(disasm)); disasm.Archi = 64; @@ -113,8 +109,8 @@ void X64Assembler::DumpMachineCode( uint64_t prev_source_offset = 0; while (disasm.EIP < eip_end) { // Look up source offset. - auto map_entry = debug_info->LookupCodeOffset( - disasm.EIP - (BE::UIntPtr)machine_code); + auto map_entry = + debug_info->LookupCodeOffset(disasm.EIP - (BE::UIntPtr)machine_code); if (map_entry) { if (map_entry->source_offset == prev_source_offset) { str->Append(" "); @@ -134,3 +130,7 @@ void X64Assembler::DumpMachineCode( disasm.EIP += len; } } + +} // namespace x64 +} // namespace backend +} // namespace alloy diff --git a/src/alloy/backend/x64/x64_assembler.h b/src/alloy/backend/x64/x64_assembler.h index 063e19c63..6cbf0c02c 100644 --- a/src/alloy/backend/x64/x64_assembler.h +++ b/src/alloy/backend/x64/x64_assembler.h @@ -14,7 +14,6 @@ #include - namespace alloy { namespace backend { namespace x64 { @@ -23,9 +22,8 @@ class X64Backend; class X64Emitter; class XbyakAllocator; - class X64Assembler : public Assembler { -public: + public: X64Assembler(X64Backend* backend); virtual ~X64Assembler(); @@ -33,28 +31,25 @@ public: virtual void Reset(); - virtual int Assemble( - runtime::FunctionInfo* symbol_info, hir::HIRBuilder* builder, - uint32_t debug_info_flags, runtime::DebugInfo* debug_info, - runtime::Function** out_function); + virtual int Assemble(runtime::FunctionInfo* symbol_info, + hir::HIRBuilder* builder, uint32_t debug_info_flags, + runtime::DebugInfo* debug_info, + runtime::Function** out_function); -private: - void DumpMachineCode(runtime::DebugInfo* debug_info, - void* machine_code, size_t code_size, - StringBuffer* str); + private: + void DumpMachineCode(runtime::DebugInfo* debug_info, void* machine_code, + size_t code_size, StringBuffer* str); -private: - X64Backend* x64_backend_; - X64Emitter* emitter_; - XbyakAllocator* allocator_; + private: + X64Backend* x64_backend_; + X64Emitter* emitter_; + XbyakAllocator* allocator_; - StringBuffer string_buffer_; + StringBuffer string_buffer_; }; - } // namespace x64 } // namespace backend } // namespace alloy - #endif // ALLOY_BACKEND_X64_X64_ASSEMBLER_H_ diff --git a/src/alloy/backend/x64/x64_backend.cc b/src/alloy/backend/x64/x64_backend.cc index 40283f6d2..3ec784599 100644 --- a/src/alloy/backend/x64/x64_backend.cc +++ b/src/alloy/backend/x64/x64_backend.cc @@ -15,20 +15,16 @@ #include #include -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::backend::x64; -using namespace alloy::runtime; +namespace alloy { +namespace backend { +namespace x64 { +using alloy::runtime::Runtime; -X64Backend::X64Backend(Runtime* runtime) : - code_cache_(0), - Backend(runtime) { -} +X64Backend::X64Backend(Runtime* runtime) : code_cache_(0), Backend(runtime) {} X64Backend::~X64Backend() { - alloy::tracing::WriteEvent(EventType::Deinit({ - })); + alloy::tracing::WriteEvent(EventType::Deinit({})); delete code_cache_; } @@ -41,17 +37,12 @@ int X64Backend::Initialize() { RegisterSequences(); machine_info_.register_sets[0] = { - 0, - "gpr", - MachineInfo::RegisterSet::INT_TYPES, - X64Emitter::GPR_COUNT, + 0, "gpr", MachineInfo::RegisterSet::INT_TYPES, X64Emitter::GPR_COUNT, }; machine_info_.register_sets[1] = { - 1, - "xmm", - MachineInfo::RegisterSet::FLOAT_TYPES | - MachineInfo::RegisterSet::VEC_TYPES, - X64Emitter::XMM_COUNT, + 1, "xmm", MachineInfo::RegisterSet::FLOAT_TYPES | + MachineInfo::RegisterSet::VEC_TYPES, + X64Emitter::XMM_COUNT, }; code_cache_ = new X64CodeCache(); @@ -67,12 +58,13 @@ int X64Backend::Initialize() { delete thunk_emitter; delete allocator; - alloy::tracing::WriteEvent(EventType::Init({ - })); + alloy::tracing::WriteEvent(EventType::Init({})); return result; } -Assembler* X64Backend::CreateAssembler() { - return new X64Assembler(this); -} +Assembler* X64Backend::CreateAssembler() { return new X64Assembler(this); } + +} // namespace x64 +} // namespace backend +} // namespace alloy diff --git a/src/alloy/backend/x64/x64_backend.h b/src/alloy/backend/x64/x64_backend.h index 0ff3018cd..f0ebfdd2a 100644 --- a/src/alloy/backend/x64/x64_backend.h +++ b/src/alloy/backend/x64/x64_backend.h @@ -14,22 +14,19 @@ #include - namespace alloy { namespace backend { namespace x64 { class X64CodeCache; - #define ALLOY_HAS_X64_BACKEND 1 - typedef void* (*HostToGuestThunk)(void* target, void* arg0, void* arg1); typedef void* (*GuestToHostThunk)(void* target, void* arg0, void* arg1); class X64Backend : public Backend { -public: + public: X64Backend(runtime::Runtime* runtime); virtual ~X64Backend(); @@ -41,16 +38,14 @@ public: virtual Assembler* CreateAssembler(); -private: + private: X64CodeCache* code_cache_; HostToGuestThunk host_to_guest_thunk_; GuestToHostThunk guest_to_host_thunk_; }; - } // namespace x64 } // namespace backend } // namespace alloy - #endif // ALLOY_BACKEND_X64_X64_BACKEND_H_ diff --git a/src/alloy/backend/x64/x64_code_cache.cc b/src/alloy/backend/x64/x64_code_cache.cc index 057fd771a..b3ea120c8 100644 --- a/src/alloy/backend/x64/x64_code_cache.cc +++ b/src/alloy/backend/x64/x64_code_cache.cc @@ -11,24 +11,20 @@ #include -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::backend::x64; - - namespace alloy { namespace backend { namespace x64 { class X64CodeChunk { -public: + public: X64CodeChunk(size_t chunk_size); ~X64CodeChunk(); -public: + + public: X64CodeChunk* next; - size_t capacity; - uint8_t* buffer; - size_t offset; + size_t capacity; + uint8_t* buffer; + size_t offset; // Estimate of function sized use to determine initial table capacity. const static uint32_t ESTIMATED_FN_SIZE = 512; @@ -36,24 +32,16 @@ public: // TODO(benvanik): move this to emitter. const static uint32_t UNWIND_INFO_SIZE = 4 + (2 * 1 + 2 + 2); - void* fn_table_handle; + void* fn_table_handle; RUNTIME_FUNCTION* fn_table; - uint32_t fn_table_count; - uint32_t fn_table_capacity; + uint32_t fn_table_count; + uint32_t fn_table_capacity; void AddTableEntry(uint8_t* code, size_t code_size, size_t stack_size); }; - -} // namespace x64 -} // namespace backend -} // namespace alloy - - -X64CodeCache::X64CodeCache(size_t chunk_size) : - chunk_size_(chunk_size), - head_chunk_(NULL), active_chunk_(NULL) { -} +X64CodeCache::X64CodeCache(size_t chunk_size) + : chunk_size_(chunk_size), head_chunk_(NULL), active_chunk_(NULL) {} X64CodeCache::~X64CodeCache() { std::lock_guard guard(lock_); @@ -66,9 +54,7 @@ X64CodeCache::~X64CodeCache() { head_chunk_ = NULL; } -int X64CodeCache::Initialize() { - return 0; -} +int X64CodeCache::Initialize() { return 0; } void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size, size_t stack_size) { @@ -87,7 +73,7 @@ void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size, if (active_chunk_->capacity - active_chunk_->offset < code_size) { auto next = active_chunk_->next; if (!next) { - XEASSERT(code_size < chunk_size_); // need to support larger chunks + XEASSERT(code_size < chunk_size_); // need to support larger chunks next = new X64CodeChunk(chunk_size_); active_chunk_->next = next; } @@ -113,25 +99,19 @@ void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size, return final_address; } -X64CodeChunk::X64CodeChunk(size_t chunk_size) : - next(NULL), - capacity(chunk_size), buffer(0), offset(0) { - buffer = (uint8_t*)VirtualAlloc( - NULL, capacity, - MEM_RESERVE | MEM_COMMIT, - PAGE_EXECUTE_READWRITE); +X64CodeChunk::X64CodeChunk(size_t chunk_size) + : next(NULL), capacity(chunk_size), buffer(0), offset(0) { + buffer = (uint8_t*)VirtualAlloc(NULL, capacity, MEM_RESERVE | MEM_COMMIT, + PAGE_EXECUTE_READWRITE); fn_table_capacity = (uint32_t)XEROUNDUP(capacity / ESTIMATED_FN_SIZE, 16); size_t table_size = fn_table_capacity * sizeof(RUNTIME_FUNCTION); fn_table = (RUNTIME_FUNCTION*)xe_malloc(table_size); fn_table_count = 0; fn_table_handle = 0; - RtlAddGrowableFunctionTable( - &fn_table_handle, - fn_table, - fn_table_count, - fn_table_capacity, - (ULONG_PTR)buffer, (ULONG_PTR)buffer + capacity); + RtlAddGrowableFunctionTable(&fn_table_handle, fn_table, fn_table_count, + fn_table_capacity, (ULONG_PTR)buffer, + (ULONG_PTR)buffer + capacity); } X64CodeChunk::~X64CodeChunk() { @@ -157,7 +137,7 @@ typedef enum _UNWIND_OP_CODES { UWOP_PUSH_MACHFRAME /* info == 0: no error-code, 1: error-code */ } UNWIND_CODE_OPS; class UNWIND_REGISTER { -public: + public: enum _ { RAX = 0, RCX = 1, @@ -182,25 +162,25 @@ typedef union _UNWIND_CODE { struct { uint8_t CodeOffset; uint8_t UnwindOp : 4; - uint8_t OpInfo : 4; + uint8_t OpInfo : 4; }; USHORT FrameOffset; } UNWIND_CODE, *PUNWIND_CODE; typedef struct _UNWIND_INFO { - uint8_t Version : 3; - uint8_t Flags : 5; + uint8_t Version : 3; + uint8_t Flags : 5; uint8_t SizeOfProlog; uint8_t CountOfCodes; uint8_t FrameRegister : 4; - uint8_t FrameOffset : 4; + uint8_t FrameOffset : 4; UNWIND_CODE UnwindCode[1]; -/* UNWIND_CODE MoreUnwindCode[((CountOfCodes + 1) & ~1) - 1]; -* union { -* OPTIONAL ULONG ExceptionHandler; -* OPTIONAL ULONG FunctionEntry; -* }; -* OPTIONAL ULONG ExceptionData[]; */ + /* UNWIND_CODE MoreUnwindCode[((CountOfCodes + 1) & ~1) - 1]; + * union { + * OPTIONAL ULONG ExceptionHandler; + * OPTIONAL ULONG FunctionEntry; + * }; + * OPTIONAL ULONG ExceptionData[]; */ } UNWIND_INFO, *PUNWIND_INFO; } // namespace @@ -215,19 +195,17 @@ void X64CodeChunk::AddTableEntry(uint8_t* code, size_t code_size, RtlDeleteGrowableFunctionTable(fn_table_handle); size_t old_size = fn_table_capacity * sizeof(RUNTIME_FUNCTION); size_t new_size = old_size * 2; - auto new_table = (RUNTIME_FUNCTION*)xe_realloc(fn_table, old_size, new_size); + auto new_table = + (RUNTIME_FUNCTION*)xe_realloc(fn_table, old_size, new_size); XEASSERTNOTNULL(new_table); if (!new_table) { return; } fn_table = new_table; fn_table_capacity *= 2; - RtlAddGrowableFunctionTable( - &fn_table_handle, - fn_table, - fn_table_count, - fn_table_capacity, - (ULONG_PTR)buffer, (ULONG_PTR)buffer + capacity); + RtlAddGrowableFunctionTable(&fn_table_handle, fn_table, fn_table_count, + fn_table_capacity, (ULONG_PTR)buffer, + (ULONG_PTR)buffer + capacity); } // Allocate unwind data. We know we have space because we overallocated. @@ -261,7 +239,8 @@ void X64CodeChunk::AddTableEntry(uint8_t* code, size_t code_size, // http://msdn.microsoft.com/en-us/library/ck9asaa9.aspx size_t co = 0; auto& unwind_code = unwind_info->UnwindCode[co++]; - unwind_code.CodeOffset = 14; // end of instruction + 1 == offset of next instruction + unwind_code.CodeOffset = + 14; // end of instruction + 1 == offset of next instruction unwind_code.UnwindOp = UWOP_ALLOC_SMALL; unwind_code.OpInfo = stack_size / 8 - 1; } else { @@ -280,7 +259,8 @@ void X64CodeChunk::AddTableEntry(uint8_t* code, size_t code_size, // http://msdn.microsoft.com/en-us/library/ck9asaa9.aspx size_t co = 0; auto& unwind_code = unwind_info->UnwindCode[co++]; - unwind_code.CodeOffset = 7; // end of instruction + 1 == offset of next instruction + unwind_code.CodeOffset = + 7; // end of instruction + 1 == offset of next instruction unwind_code.UnwindOp = UWOP_ALLOC_LARGE; unwind_code.OpInfo = 0; unwind_code = unwind_info->UnwindCode[co++]; @@ -296,3 +276,7 @@ void X64CodeChunk::AddTableEntry(uint8_t* code, size_t code_size, // Notify the function table that it has new entries. RtlGrowFunctionTable(fn_table_handle, fn_table_count); } + +} // namespace x64 +} // namespace backend +} // namespace alloy diff --git a/src/alloy/backend/x64/x64_code_cache.h b/src/alloy/backend/x64/x64_code_cache.h index f51df94a9..8a0953f15 100644 --- a/src/alloy/backend/x64/x64_code_cache.h +++ b/src/alloy/backend/x64/x64_code_cache.h @@ -14,7 +14,6 @@ #include - namespace alloy { namespace backend { namespace x64 { @@ -22,7 +21,7 @@ namespace x64 { class X64CodeChunk; class X64CodeCache { -public: + public: X64CodeCache(size_t chunk_size = DEFAULT_CHUNK_SIZE); virtual ~X64CodeCache(); @@ -34,18 +33,16 @@ public: void* PlaceCode(void* machine_code, size_t code_size, size_t stack_size); -private: + private: const static size_t DEFAULT_CHUNK_SIZE = 4 * 1024 * 1024; - std::mutex lock_; - size_t chunk_size_; + std::mutex lock_; + size_t chunk_size_; X64CodeChunk* head_chunk_; X64CodeChunk* active_chunk_; }; - } // namespace x64 } // namespace backend } // namespace alloy - #endif // ALLOY_BACKEND_X64_X64_CODE_CACHE_H_ diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index ab0d2123b..ee552c71a 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -20,18 +20,21 @@ #include #include -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::backend::x64; +namespace alloy { +namespace backend { +namespace x64 { + +// TODO(benvanik): remove when enums redefined. using namespace alloy::hir; using namespace alloy::runtime; using namespace Xbyak; - - -namespace alloy { -namespace backend { -namespace x64 { +using alloy::hir::HIRBuilder; +using alloy::hir::Instr; +using alloy::runtime::Function; +using alloy::runtime::FunctionInfo; +using alloy::runtime::SourceMapEntry; +using alloy::runtime::ThreadState; static const size_t MAX_CODE_SIZE = 1 * 1024 * 1024; @@ -42,41 +45,29 @@ static const size_t STASH_OFFSET = 32; // can get the value. #define STORE_EFLAGS 1 -} // namespace x64 -} // namespace backend -} // namespace alloy - - const uint32_t X64Emitter::gpr_reg_map_[X64Emitter::GPR_COUNT] = { - Operand::RBX, - Operand::R12, Operand::R13, Operand::R14, Operand::R15, + Operand::RBX, Operand::R12, Operand::R13, Operand::R14, Operand::R15, }; const uint32_t X64Emitter::xmm_reg_map_[X64Emitter::XMM_COUNT] = { - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, }; +X64Emitter::X64Emitter(X64Backend* backend, XbyakAllocator* allocator) + : runtime_(backend->runtime()), + backend_(backend), + code_cache_(backend->code_cache()), + allocator_(allocator), + current_instr_(0), + CodeGenerator(MAX_CODE_SIZE, AutoGrow, allocator) {} -X64Emitter::X64Emitter(X64Backend* backend, XbyakAllocator* allocator) : - runtime_(backend->runtime()), - backend_(backend), - code_cache_(backend->code_cache()), - allocator_(allocator), - current_instr_(0), - CodeGenerator(MAX_CODE_SIZE, AutoGrow, allocator) { -} +X64Emitter::~X64Emitter() {} -X64Emitter::~X64Emitter() { -} +int X64Emitter::Initialize() { return 0; } -int X64Emitter::Initialize() { - return 0; -} - -int X64Emitter::Emit( - HIRBuilder* builder, - uint32_t debug_info_flags, runtime::DebugInfo* debug_info, - void*& out_code_address, size_t& out_code_size) { +int X64Emitter::Emit(HIRBuilder* builder, uint32_t debug_info_flags, + runtime::DebugInfo* debug_info, void*& out_code_address, + size_t& out_code_size) { SCOPE_profile_cpu_f("alloy"); // Reset. @@ -99,8 +90,7 @@ int X64Emitter::Emit( // Stash source map. if (debug_info_flags & DEBUG_INFO_SOURCE_MAP) { debug_info->InitializeSourceMap( - source_map_count_, - (SourceMapEntry*)source_map_arena_.CloneContents()); + source_map_count_, (SourceMapEntry*)source_map_arena_.CloneContents()); } return 0; @@ -158,7 +148,7 @@ int X64Emitter::Emit(HIRBuilder* builder, size_t& out_stack_size) { mov(qword[rsp + StackLayout::GUEST_RCX_HOME], rcx); mov(qword[rsp + StackLayout::GUEST_RET_ADDR], rdx); mov(qword[rsp + StackLayout::GUEST_CALL_RET_ADDR], 0); - mov(rdx, qword[rcx + 8]); // membase + mov(rdx, qword[rcx + 8]); // membase } // Body. @@ -208,9 +198,9 @@ int X64Emitter::Emit(HIRBuilder* builder, size_t& out_stack_size) { void X64Emitter::MarkSourceOffset(const Instr* i) { auto entry = source_map_arena_.Alloc(); - entry->source_offset = i->src1.offset; - entry->hir_offset = uint32_t(i->block->ordinal << 16) | i->ordinal; - entry->code_offset = getSize(); + entry->source_offset = i->src1.offset; + entry->hir_offset = uint32_t(i->block->ordinal << 16) | i->ordinal; + entry->code_offset = getSize(); source_map_count_++; } @@ -221,20 +211,20 @@ void X64Emitter::DebugBreak() { void X64Emitter::Trap(uint16_t trap_type) { switch (trap_type) { - case 20: - // 0x0FE00014 is a 'debug print' where r3 = buffer r4 = length - // TODO(benvanik): debug print at runtime. - break; - case 0: - case 22: - // Always trap? - // TODO(benvanik): post software interrupt to debugger. - db(0xCC); - break; - default: - XELOGW("Unknown trap type %d", trap_type); - db(0xCC); - break; + case 20: + // 0x0FE00014 is a 'debug print' where r3 = buffer r4 = length + // TODO(benvanik): debug print at runtime. + break; + case 0: + case 22: + // Always trap? + // TODO(benvanik): post software interrupt to debugger. + db(0xCC); + break; + default: + XELOGW("Unknown trap type %d", trap_type); + db(0xCC); + break; } } @@ -258,7 +248,8 @@ const size_t ASM_OFFSET = 2 + 2 + 8 + 2 + 8; // 6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H // 7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H // 8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H -// 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00000000H] 66 0F 1F 84 00 00 00 00 00H +// 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00000000H] 66 0F 1F 84 00 00 00 00 +// 00H uint64_t ResolveFunctionSymbol(void* raw_context, uint64_t symbol_info_ptr) { // TODO(benvanik): generate this thunk at runtime? or a shim? @@ -275,7 +266,7 @@ uint64_t ResolveFunctionSymbol(void* raw_context, uint64_t symbol_info_ptr) { // Overwrite the call site. // The return address points to ReloadRCX work after the call. uint64_t return_address = reinterpret_cast(_ReturnAddress()); - #pragma pack(push, 1) +#pragma pack(push, 1) struct Asm { uint16_t mov_rax; uint64_t rax_constant; @@ -284,7 +275,7 @@ uint64_t ResolveFunctionSymbol(void* raw_context, uint64_t symbol_info_ptr) { uint16_t call_rax; uint8_t mov_rcx[5]; }; - #pragma pack(pop) +#pragma pack(pop) Asm* code = reinterpret_cast(return_address - ASM_OFFSET); code->rax_constant = addr; code->call_rax = 0x9066; @@ -293,7 +284,8 @@ uint64_t ResolveFunctionSymbol(void* raw_context, uint64_t symbol_info_ptr) { return addr; } -void X64Emitter::Call(const hir::Instr* instr, runtime::FunctionInfo* symbol_info) { +void X64Emitter::Call(const hir::Instr* instr, + runtime::FunctionInfo* symbol_info) { auto fn = reinterpret_cast(symbol_info->function()); // Resolve address to the function to call and store in rax. // TODO(benvanik): caching/etc. For now this makes debugging easier. @@ -372,12 +364,12 @@ void X64Emitter::CallIndirect(const hir::Instr* instr, const Reg64& reg) { uint64_t UndefinedCallExtern(void* raw_context, uint64_t symbol_info_ptr) { auto symbol_info = reinterpret_cast(symbol_info_ptr); - XELOGW("undefined extern call to %.8X %s", - symbol_info->address(), + XELOGW("undefined extern call to %.8X %s", symbol_info->address(), symbol_info->name()); return 0; } -void X64Emitter::CallExtern(const hir::Instr* instr, const FunctionInfo* symbol_info) { +void X64Emitter::CallExtern(const hir::Instr* instr, + const FunctionInfo* symbol_info) { XEASSERT(symbol_info->behavior() == FunctionInfo::BEHAVIOR_EXTERN); if (!symbol_info->extern_handler()) { CallNative(UndefinedCallExtern, reinterpret_cast(symbol_info)); @@ -405,21 +397,22 @@ void X64Emitter::CallNative(void* fn) { ReloadEDX(); } -void X64Emitter::CallNative(uint64_t(*fn)(void* raw_context)) { +void X64Emitter::CallNative(uint64_t (*fn)(void* raw_context)) { mov(rax, reinterpret_cast(fn)); call(rax); ReloadECX(); ReloadEDX(); } -void X64Emitter::CallNative(uint64_t(*fn)(void* raw_context, uint64_t arg0)) { +void X64Emitter::CallNative(uint64_t (*fn)(void* raw_context, uint64_t arg0)) { mov(rax, reinterpret_cast(fn)); call(rax); ReloadECX(); ReloadEDX(); } -void X64Emitter::CallNative(uint64_t(*fn)(void* raw_context, uint64_t arg0), uint64_t arg0) { +void X64Emitter::CallNative(uint64_t (*fn)(void* raw_context, uint64_t arg0), + uint64_t arg0) { mov(rdx, arg0); mov(rax, reinterpret_cast(fn)); call(rax); @@ -428,17 +421,17 @@ void X64Emitter::CallNative(uint64_t(*fn)(void* raw_context, uint64_t arg0), uin } void X64Emitter::CallNativeSafe(void* fn) { - // rcx = context - // rdx = target host function - // r8 = arg0 - // r9 = arg1 - mov(rdx, reinterpret_cast(fn)); - auto thunk = backend()->guest_to_host_thunk(); - mov(rax, reinterpret_cast(thunk)); - call(rax); - ReloadECX(); - ReloadEDX(); - // rax = host return + // rcx = context + // rdx = target host function + // r8 = arg0 + // r9 = arg1 + mov(rdx, reinterpret_cast(fn)); + auto thunk = backend()->guest_to_host_thunk(); + mov(rax, reinterpret_cast(thunk)); + call(rax); + ReloadECX(); + ReloadEDX(); + // rax = host return } void X64Emitter::SetReturnAddress(uint64_t value) { @@ -450,7 +443,7 @@ void X64Emitter::ReloadECX() { } void X64Emitter::ReloadEDX() { - mov(rdx, qword[rcx + 8]); // membase + mov(rdx, qword[rcx + 8]); // membase } void X64Emitter::LoadEflags() { @@ -459,7 +452,7 @@ void X64Emitter::LoadEflags() { push(rax); popf(); #else - // EFLAGS already present. +// EFLAGS already present. #endif // STORE_EFLAGS } @@ -468,8 +461,8 @@ void X64Emitter::StoreEflags() { pushf(); pop(qword[rsp + STASH_OFFSET]); #else - // EFLAGS should have CA set? - // (so long as we don't fuck with it) +// EFLAGS should have CA set? +// (so long as we don't fuck with it) #endif // STORE_EFLAGS } @@ -511,32 +504,51 @@ void X64Emitter::MovMem64(const RegExp& addr, uint64_t v) { Address X64Emitter::GetXmmConstPtr(XmmConst id) { static const vec128_t xmm_consts[] = { - /* XMMZero */ vec128f(0.0f, 0.0f, 0.0f, 0.0f), - /* XMMOne */ vec128f(1.0f, 1.0f, 1.0f, 1.0f), - /* XMMNegativeOne */ vec128f(-1.0f, -1.0f, -1.0f, -1.0f), - /* XMMMaskX16Y16 */ vec128i(0x0000FFFFu, 0xFFFF0000u, 0x00000000u, 0x00000000u), - /* XMMFlipX16Y16 */ vec128i(0x00008000u, 0x00000000u, 0x00000000u, 0x00000000u), - /* XMMFixX16Y16 */ vec128f(-32768.0f, 0.0f, 0.0f, 0.0f), - /* XMMNormalizeX16Y16 */ vec128f(1.0f / 32767.0f, 1.0f / (32767.0f * 65536.0f), 0.0f, 0.0f), - /* XMM0001 */ vec128f(0.0f, 0.0f, 0.0f, 1.0f), - /* XMM3301 */ vec128f(3.0f, 3.0f, 0.0f, 1.0f), - /* XMMSignMaskPS */ vec128i(0x80000000u, 0x80000000u, 0x80000000u, 0x80000000u), - /* XMMSignMaskPD */ vec128i(0x00000000u, 0x80000000u, 0x00000000u, 0x80000000u), - /* XMMAbsMaskPS */ vec128i(0x7FFFFFFFu, 0x7FFFFFFFu, 0x7FFFFFFFu, 0x7FFFFFFFu), - /* XMMAbsMaskPD */ vec128i(0xFFFFFFFFu, 0x7FFFFFFFu, 0xFFFFFFFFu, 0x7FFFFFFFu), - /* XMMByteSwapMask */ vec128i(0x00010203u, 0x04050607u, 0x08090A0Bu, 0x0C0D0E0Fu), - /* XMMPermuteControl15 */ vec128b(15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15), - /* XMMPackD3DCOLOR */ vec128i(0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x0C000408u), - /* XMMUnpackD3DCOLOR */ vec128i(0xFFFFFF0Eu, 0xFFFFFF0Du, 0xFFFFFF0Cu, 0xFFFFFF0Fu), - /* XMMOneOver255 */ vec128f(1.0f / 255.0f, 1.0f / 255.0f, 1.0f / 255.0f, 1.0f / 255.0f), - /* XMMShiftMaskPS */ vec128i(0x0000001Fu, 0x0000001Fu, 0x0000001Fu, 0x0000001Fu), - /* XMMShiftByteMask */ vec128i(0x000000FFu, 0x000000FFu, 0x000000FFu, 0x000000FFu), - /* XMMUnsignedDwordMax */ vec128i(0xFFFFFFFFu, 0x00000000u, 0xFFFFFFFFu, 0x00000000u), - /* XMM255 */ vec128f(255.0f, 255.0f, 255.0f, 255.0f), - /* XMMSignMaskI8 */ vec128i(0x80808080u, 0x80808080u, 0x80808080u, 0x80808080u), - /* XMMSignMaskI16 */ vec128i(0x80008000u, 0x80008000u, 0x80008000u, 0x80008000u), - /* XMMSignMaskI32 */ vec128i(0x80000000u, 0x80000000u, 0x80000000u, 0x80000000u), - /* XMMSignMaskF32 */ vec128i(0x80000000u, 0x80000000u, 0x80000000u, 0x80000000u), + /* XMMZero */ vec128f(0.0f, 0.0f, 0.0f, 0.0f), + /* XMMOne */ vec128f(1.0f, 1.0f, 1.0f, 1.0f), + /* XMMNegativeOne */ vec128f(-1.0f, -1.0f, -1.0f, -1.0f), + /* XMMMaskX16Y16 */ vec128i(0x0000FFFFu, 0xFFFF0000u, + 0x00000000u, 0x00000000u), + /* XMMFlipX16Y16 */ vec128i(0x00008000u, 0x00000000u, + 0x00000000u, 0x00000000u), + /* XMMFixX16Y16 */ vec128f(-32768.0f, 0.0f, 0.0f, 0.0f), + /* XMMNormalizeX16Y16 */ vec128f( + 1.0f / 32767.0f, 1.0f / (32767.0f * 65536.0f), 0.0f, 0.0f), + /* XMM0001 */ vec128f(0.0f, 0.0f, 0.0f, 1.0f), + /* XMM3301 */ vec128f(3.0f, 3.0f, 0.0f, 1.0f), + /* XMMSignMaskPS */ vec128i(0x80000000u, 0x80000000u, + 0x80000000u, 0x80000000u), + /* XMMSignMaskPD */ vec128i(0x00000000u, 0x80000000u, + 0x00000000u, 0x80000000u), + /* XMMAbsMaskPS */ vec128i(0x7FFFFFFFu, 0x7FFFFFFFu, + 0x7FFFFFFFu, 0x7FFFFFFFu), + /* XMMAbsMaskPD */ vec128i(0xFFFFFFFFu, 0x7FFFFFFFu, + 0xFFFFFFFFu, 0x7FFFFFFFu), + /* XMMByteSwapMask */ vec128i(0x00010203u, 0x04050607u, + 0x08090A0Bu, 0x0C0D0E0Fu), + /* XMMPermuteControl15 */ vec128b(15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15), + /* XMMPackD3DCOLOR */ vec128i(0xFFFFFFFFu, 0xFFFFFFFFu, + 0xFFFFFFFFu, 0x0C000408u), + /* XMMUnpackD3DCOLOR */ vec128i(0xFFFFFF0Eu, 0xFFFFFF0Du, + 0xFFFFFF0Cu, 0xFFFFFF0Fu), + /* XMMOneOver255 */ vec128f(1.0f / 255.0f, 1.0f / 255.0f, + 1.0f / 255.0f, 1.0f / 255.0f), + /* XMMShiftMaskPS */ vec128i(0x0000001Fu, 0x0000001Fu, + 0x0000001Fu, 0x0000001Fu), + /* XMMShiftByteMask */ vec128i(0x000000FFu, 0x000000FFu, + 0x000000FFu, 0x000000FFu), + /* XMMUnsignedDwordMax */ vec128i(0xFFFFFFFFu, 0x00000000u, + 0xFFFFFFFFu, 0x00000000u), + /* XMM255 */ vec128f(255.0f, 255.0f, 255.0f, 255.0f), + /* XMMSignMaskI8 */ vec128i(0x80808080u, 0x80808080u, + 0x80808080u, 0x80808080u), + /* XMMSignMaskI16 */ vec128i(0x80008000u, 0x80008000u, + 0x80008000u, 0x80008000u), + /* XMMSignMaskI32 */ vec128i(0x80000000u, 0x80000000u, + 0x80000000u, 0x80000000u), + /* XMMSignMaskF32 */ vec128i(0x80000000u, 0x80000000u, + 0x80000000u, 0x80000000u), }; // TODO(benvanik): cache base pointer somewhere? stack? It'd be nice to // prevent this move. @@ -568,7 +580,7 @@ void X64Emitter::LoadConstantXmm(Xbyak::Xmm dest, float v) { union { float f; uint32_t i; - } x = { v }; + } x = {v}; if (!v) { // 0 vpxor(dest, dest); @@ -587,7 +599,7 @@ void X64Emitter::LoadConstantXmm(Xbyak::Xmm dest, double v) { union { double d; uint64_t i; - } x = { v }; + } x = {v}; if (!v) { // 0 vpxor(dest, dest); @@ -614,3 +626,7 @@ Address X64Emitter::StashXmm(const vec128_t& v) { vmovups(addr, xmm0); return addr; } + +} // namespace x64 +} // namespace backend +} // namespace alloy diff --git a/src/alloy/backend/x64/x64_emitter.h b/src/alloy/backend/x64/x64_emitter.h index 3bfe43a2b..086a1d689 100644 --- a/src/alloy/backend/x64/x64_emitter.h +++ b/src/alloy/backend/x64/x64_emitter.h @@ -31,12 +31,12 @@ class X64Backend; class X64CodeCache; enum RegisterFlags { - REG_DEST = (1 << 0), - REG_ABCD = (1 << 1), + REG_DEST = (1 << 0), + REG_ABCD = (1 << 1), }; enum XmmConst { - XMMZero = 0, + XMMZero = 0, XMMOne, XMMNegativeOne, XMMMaskX16Y16, @@ -66,12 +66,12 @@ enum XmmConst { // Unfortunately due to the design of xbyak we have to pass this to the ctor. class XbyakAllocator : public Xbyak::Allocator { -public: - virtual bool useProtect() const { return false; } + public: + virtual bool useProtect() const { return false; } }; class X64Emitter : public Xbyak::CodeGenerator { -public: + public: X64Emitter(X64Backend* backend, XbyakAllocator* allocator); virtual ~X64Emitter(); @@ -80,11 +80,11 @@ public: int Initialize(); - int Emit(hir::HIRBuilder* builder, - uint32_t debug_info_flags, runtime::DebugInfo* debug_info, - void*& out_code_address, size_t& out_code_size); + int Emit(hir::HIRBuilder* builder, uint32_t debug_info_flags, + runtime::DebugInfo* debug_info, void*& out_code_address, + size_t& out_code_size); -public: + public: // Reserved: rsp // Scratch: rax/rcx/rdx // xmm0-2 (could be only xmm0 with some trickery) @@ -123,11 +123,13 @@ public: void Call(const hir::Instr* instr, runtime::FunctionInfo* symbol_info); void CallIndirect(const hir::Instr* instr, const Xbyak::Reg64& reg); - void CallExtern(const hir::Instr* instr, const runtime::FunctionInfo* symbol_info); + void CallExtern(const hir::Instr* instr, + const runtime::FunctionInfo* symbol_info); void CallNative(void* fn); - void CallNative(uint64_t(*fn)(void* raw_context)); - void CallNative(uint64_t(*fn)(void* raw_context, uint64_t arg0)); - void CallNative(uint64_t(*fn)(void* raw_context, uint64_t arg0), uint64_t arg0); + void CallNative(uint64_t (*fn)(void* raw_context)); + void CallNative(uint64_t (*fn)(void* raw_context, uint64_t arg0)); + void CallNative(uint64_t (*fn)(void* raw_context, uint64_t arg0), + uint64_t arg0); void CallNativeSafe(void* fn); void SetReturnAddress(uint64_t value); void ReloadECX(); @@ -153,31 +155,29 @@ public: size_t stack_size() const { return stack_size_; } -protected: + protected: void* Emplace(size_t stack_size); int Emit(hir::HIRBuilder* builder, size_t& out_stack_size); -protected: + protected: runtime::Runtime* runtime_; - X64Backend* backend_; - X64CodeCache* code_cache_; - XbyakAllocator* allocator_; + X64Backend* backend_; + X64CodeCache* code_cache_; + XbyakAllocator* allocator_; hir::Instr* current_instr_; - size_t source_map_count_; - Arena source_map_arena_; + size_t source_map_count_; + Arena source_map_arena_; - size_t stack_size_; + size_t stack_size_; static const uint32_t gpr_reg_map_[GPR_COUNT]; static const uint32_t xmm_reg_map_[XMM_COUNT]; }; - } // namespace x64 } // namespace backend } // namespace alloy - #endif // ALLOY_BACKEND_X64_X64_EMITTER_H_ diff --git a/src/alloy/backend/x64/x64_function.cc b/src/alloy/backend/x64/x64_function.cc index 71452ac14..5e20887ba 100644 --- a/src/alloy/backend/x64/x64_function.cc +++ b/src/alloy/backend/x64/x64_function.cc @@ -14,16 +14,17 @@ #include #include -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::backend::x64; -using namespace alloy::runtime; +namespace alloy { +namespace backend { +namespace x64 { +using alloy::runtime::Breakpoint; +using alloy::runtime::Function; +using alloy::runtime::FunctionInfo; +using alloy::runtime::ThreadState; -X64Function::X64Function(FunctionInfo* symbol_info) : - machine_code_(NULL), code_size_(0), - Function(symbol_info) { -} +X64Function::X64Function(FunctionInfo* symbol_info) + : machine_code_(NULL), code_size_(0), Function(symbol_info) {} X64Function::~X64Function() { // machine_code_ is freed by code cache. @@ -34,20 +35,17 @@ void X64Function::Setup(void* machine_code, size_t code_size) { code_size_ = code_size; } -int X64Function::AddBreakpointImpl(Breakpoint* breakpoint) { - return 0; -} +int X64Function::AddBreakpointImpl(Breakpoint* breakpoint) { return 0; } -int X64Function::RemoveBreakpointImpl(Breakpoint* breakpoint) { - return 0; -} +int X64Function::RemoveBreakpointImpl(Breakpoint* breakpoint) { return 0; } int X64Function::CallImpl(ThreadState* thread_state, uint64_t return_address) { auto backend = (X64Backend*)thread_state->runtime()->backend(); auto thunk = backend->host_to_guest_thunk(); - thunk( - machine_code_, - thread_state->raw_context(), - (void*)return_address); + thunk(machine_code_, thread_state->raw_context(), (void*)return_address); return 0; } + +} // namespace x64 +} // namespace backend +} // namespace alloy diff --git a/src/alloy/backend/x64/x64_function.h b/src/alloy/backend/x64/x64_function.h index 0f9659ca6..6e5812362 100644 --- a/src/alloy/backend/x64/x64_function.h +++ b/src/alloy/backend/x64/x64_function.h @@ -14,14 +14,12 @@ #include #include - namespace alloy { namespace backend { namespace x64 { - class X64Function : public runtime::Function { -public: + public: X64Function(runtime::FunctionInfo* symbol_info); virtual ~X64Function(); @@ -30,21 +28,19 @@ public: void Setup(void* machine_code, size_t code_size); -protected: + protected: virtual int AddBreakpointImpl(runtime::Breakpoint* breakpoint); virtual int RemoveBreakpointImpl(runtime::Breakpoint* breakpoint); virtual int CallImpl(runtime::ThreadState* thread_state, uint64_t return_address); -private: - void* machine_code_; - size_t code_size_; + private: + void* machine_code_; + size_t code_size_; }; - } // namespace x64 } // namespace backend } // namespace alloy - #endif // ALLOY_BACKEND_X64_X64_FUNCTION_H_ diff --git a/src/alloy/backend/x64/x64_sequences.h b/src/alloy/backend/x64/x64_sequences.h index 5a77e9987..79053e31e 100644 --- a/src/alloy/backend/x64/x64_sequences.h +++ b/src/alloy/backend/x64/x64_sequences.h @@ -20,14 +20,12 @@ namespace x64 { class X64Emitter; - void RegisterSequences(); -bool SelectSequence(X64Emitter& e, const hir::Instr* i, const hir::Instr** new_tail); - +bool SelectSequence(X64Emitter& e, const hir::Instr* i, + const hir::Instr** new_tail); } // namespace x64 } // namespace backend } // namespace alloy - #endif // ALLOY_BACKEND_X64_X64_SEQUENCES_H_ diff --git a/src/alloy/backend/x64/x64_thunk_emitter.cc b/src/alloy/backend/x64/x64_thunk_emitter.cc index 0e1922581..049377417 100644 --- a/src/alloy/backend/x64/x64_thunk_emitter.cc +++ b/src/alloy/backend/x64/x64_thunk_emitter.cc @@ -11,21 +11,16 @@ #include - -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::backend::x64; +namespace alloy { +namespace backend { +namespace x64 { using namespace Xbyak; +X64ThunkEmitter::X64ThunkEmitter(X64Backend* backend, XbyakAllocator* allocator) + : X64Emitter(backend, allocator) {} -X64ThunkEmitter::X64ThunkEmitter( - X64Backend* backend, XbyakAllocator* allocator) : - X64Emitter(backend, allocator) { -} - -X64ThunkEmitter::~X64ThunkEmitter() { -} +X64ThunkEmitter::~X64ThunkEmitter() {} HostToGuestThunk X64ThunkEmitter::EmitHostToGuestThunk() { // rcx = target @@ -101,7 +96,7 @@ GuestToHostThunk X64ThunkEmitter::EmitGuestToHostThunk() { // rdx = target function // r8 = arg0 // r9 = arg1 - + const size_t stack_size = StackLayout::THUNK_STACK_SIZE; // rsp + 0 = return address mov(qword[rsp + 8 * 2], rdx); @@ -143,3 +138,7 @@ GuestToHostThunk X64ThunkEmitter::EmitGuestToHostThunk() { void* fn = Emplace(stack_size); return (HostToGuestThunk)fn; } + +} // namespace x64 +} // namespace backend +} // namespace alloy diff --git a/src/alloy/backend/x64/x64_thunk_emitter.h b/src/alloy/backend/x64/x64_thunk_emitter.h index e472885ea..6e6b8d428 100644 --- a/src/alloy/backend/x64/x64_thunk_emitter.h +++ b/src/alloy/backend/x64/x64_thunk_emitter.h @@ -14,12 +14,10 @@ #include #include - namespace alloy { namespace backend { namespace x64 { - /** * Stack Layout * ---------------------------- @@ -116,7 +114,7 @@ namespace x64 { */ class StackLayout { -public: + public: const static size_t THUNK_STACK_SIZE = 120; const static size_t GUEST_STACK_SIZE = 88; @@ -125,9 +123,8 @@ public: const static size_t GUEST_CALL_RET_ADDR = 80; }; - class X64ThunkEmitter : public X64Emitter { -public: + public: X64ThunkEmitter(X64Backend* backend, XbyakAllocator* allocator); virtual ~X64ThunkEmitter(); @@ -138,10 +135,8 @@ public: GuestToHostThunk EmitGuestToHostThunk(); }; - } // namespace x64 } // namespace backend } // namespace alloy - #endif // ALLOY_BACKEND_X64_X64_THUNK_EMITTER_H_ diff --git a/src/alloy/backend/x64/x64_tracers.cc b/src/alloy/backend/x64/x64_tracers.cc index 0ebb699cb..29227db0d 100644 --- a/src/alloy/backend/x64/x64_tracers.cc +++ b/src/alloy/backend/x64/x64_tracers.cc @@ -27,9 +27,12 @@ namespace x64 { #define TARGET_THREAD 1 #define IFLUSH() fflush(stdout) -#define IPRINT if (thread_state->thread_id() == TARGET_THREAD) printf +#define IPRINT \ + if (thread_state->thread_id() == TARGET_THREAD) printf #define DFLUSH() fflush(stdout) -#define DPRINT DFLUSH(); if (thread_state->thread_id() == TARGET_THREAD) printf +#define DPRINT \ + DFLUSH(); \ + if (thread_state->thread_id() == TARGET_THREAD) printf uint32_t GetTracingMode() { uint32_t mode = 0; @@ -66,7 +69,8 @@ void TraceContextLoadI64(void* raw_context, uint64_t offset, uint64_t value) { } void TraceContextLoadF32(void* raw_context, uint64_t offset, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("%e (%X) = ctx f32 +%d\n", value.m128_f32[0], value.m128_i32[0], offset); + DPRINT("%e (%X) = ctx f32 +%d\n", value.m128_f32[0], value.m128_i32[0], + offset); } void TraceContextLoadF64(void* raw_context, uint64_t offset, __m128 value) { auto thread_state = *((ThreadState**)raw_context); @@ -80,9 +84,9 @@ void TraceContextLoadF64(void* raw_context, uint64_t offset, __m128 value) { void TraceContextLoadV128(void* raw_context, uint64_t offset, __m128 value) { auto thread_state = *((ThreadState**)raw_context); DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = ctx v128 +%d\n", - value.m128_f32[0], value.m128_f32[1], value.m128_f32[2], value.m128_f32[3], - value.m128_i32[0], value.m128_i32[1], value.m128_i32[2], value.m128_i32[3], - offset); + value.m128_f32[0], value.m128_f32[1], value.m128_f32[2], + value.m128_f32[3], value.m128_i32[0], value.m128_i32[1], + value.m128_i32[2], value.m128_i32[3], offset); } void TraceContextStoreI8(void* raw_context, uint64_t offset, uint8_t value) { @@ -103,7 +107,8 @@ void TraceContextStoreI64(void* raw_context, uint64_t offset, uint64_t value) { } void TraceContextStoreF32(void* raw_context, uint64_t offset, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("ctx f32 +%d = %e (%X)\n", offset, value.m128_i32[0], value.m128_f32[0]); + DPRINT("ctx f32 +%d = %e (%X)\n", offset, value.m128_i32[0], + value.m128_f32[0]); } void TraceContextStoreF64(void* raw_context, uint64_t offset, __m128 value) { auto thread_state = *((ThreadState**)raw_context); @@ -117,8 +122,9 @@ void TraceContextStoreF64(void* raw_context, uint64_t offset, __m128 value) { void TraceContextStoreV128(void* raw_context, uint64_t offset, __m128 value) { auto thread_state = *((ThreadState**)raw_context); DPRINT("ctx v128 +%d = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", offset, - value.m128_f32[0], value.m128_f32[1], value.m128_f32[2], value.m128_f32[3], - value.m128_i32[0], value.m128_i32[1], value.m128_i32[2], value.m128_i32[3]); + value.m128_f32[0], value.m128_f32[1], value.m128_f32[2], + value.m128_f32[3], value.m128_i32[0], value.m128_i32[1], + value.m128_i32[2], value.m128_i32[3]); } void TraceMemoryLoadI8(void* raw_context, uint64_t address, uint8_t value) { @@ -139,7 +145,8 @@ void TraceMemoryLoadI64(void* raw_context, uint64_t address, uint64_t value) { } void TraceMemoryLoadF32(void* raw_context, uint64_t address, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("%e (%X) = load.f32 %.8X\n", value.m128_f32[0], value.m128_i32[0], address); + DPRINT("%e (%X) = load.f32 %.8X\n", value.m128_f32[0], value.m128_i32[0], + address); } void TraceMemoryLoadF64(void* raw_context, uint64_t address, __m128 value) { auto thread_state = *((ThreadState**)raw_context); @@ -153,9 +160,9 @@ void TraceMemoryLoadF64(void* raw_context, uint64_t address, __m128 value) { void TraceMemoryLoadV128(void* raw_context, uint64_t address, __m128 value) { auto thread_state = *((ThreadState**)raw_context); DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = load.v128 %.8X\n", - value.m128_f32[0], value.m128_f32[1], value.m128_f32[2], value.m128_f32[3], - value.m128_i32[0], value.m128_i32[1], value.m128_i32[2], value.m128_i32[3], - address); + value.m128_f32[0], value.m128_f32[1], value.m128_f32[2], + value.m128_f32[3], value.m128_i32[0], value.m128_i32[1], + value.m128_i32[2], value.m128_i32[3], address); } void TraceMemoryStoreI8(void* raw_context, uint64_t address, uint8_t value) { @@ -176,7 +183,8 @@ void TraceMemoryStoreI64(void* raw_context, uint64_t address, uint64_t value) { } void TraceMemoryStoreF32(void* raw_context, uint64_t address, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("store.f32 %.8X = %e (%X)\n", address, value.m128_f32[0], value.m128_i32[0]); + DPRINT("store.f32 %.8X = %e (%X)\n", address, value.m128_f32[0], + value.m128_i32[0]); } void TraceMemoryStoreF64(void* raw_context, uint64_t address, __m128 value) { auto thread_state = *((ThreadState**)raw_context); @@ -189,12 +197,12 @@ void TraceMemoryStoreF64(void* raw_context, uint64_t address, __m128 value) { } void TraceMemoryStoreV128(void* raw_context, uint64_t address, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("store.v128 %.8X = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", address, - value.m128_f32[0], value.m128_f32[1], value.m128_f32[2], value.m128_f32[3], - value.m128_i32[0], value.m128_i32[1], value.m128_i32[2], value.m128_i32[3]); + DPRINT("store.v128 %.8X = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", + address, value.m128_f32[0], value.m128_f32[1], value.m128_f32[2], + value.m128_f32[3], value.m128_i32[0], value.m128_i32[1], + value.m128_i32[2], value.m128_i32[3]); } - } // namespace x64 } // namespace backend } // namespace alloy diff --git a/src/alloy/backend/x64/x64_tracers.h b/src/alloy/backend/x64/x64_tracers.h index 64c788ff3..8151b4305 100644 --- a/src/alloy/backend/x64/x64_tracers.h +++ b/src/alloy/backend/x64/x64_tracers.h @@ -16,19 +16,18 @@ #include #else typedef union __declspec(align(16)) __m128 { - float m128_f32[4]; - uint64_t m128_u64[2]; - int8_t m128_i8[16]; - int16_t m128_i16[8]; - int32_t m128_i32[4]; - int64_t m128_i64[2]; - uint8_t m128_u8[16]; - uint16_t m128_u16[8]; - uint32_t m128_u32[4]; + float m128_f32[4]; + uint64_t m128_u64[2]; + int8_t m128_i8[16]; + int16_t m128_i16[8]; + int32_t m128_i32[4]; + int64_t m128_i64[2]; + uint8_t m128_u8[16]; + uint16_t m128_u16[8]; + uint32_t m128_u32[4]; } __m128; #endif - namespace alloy { namespace backend { namespace x64 { @@ -81,5 +80,4 @@ void TraceMemoryStoreV128(void* raw_context, uint64_t address, __m128 value); } // namespace backend } // namespace alloy - #endif // ALLOY_BACKEND_X64_X64_TRACERS_H_ diff --git a/src/alloy/compiler/compiler.cc b/src/alloy/compiler/compiler.cc index 62c6e5a4b..2aff744db 100644 --- a/src/alloy/compiler/compiler.cc +++ b/src/alloy/compiler/compiler.cc @@ -12,18 +12,16 @@ #include #include -using namespace alloy; -using namespace alloy::compiler; -using namespace alloy::hir; -using namespace alloy::runtime; +namespace alloy { +namespace compiler { +using alloy::hir::HIRBuilder; +using alloy::runtime::Runtime; -Compiler::Compiler(Runtime* runtime) : - runtime_(runtime) { +Compiler::Compiler(Runtime* runtime) : runtime_(runtime) { scratch_arena_ = new Arena(); - alloy::tracing::WriteEvent(EventType::Init({ - })); + alloy::tracing::WriteEvent(EventType::Init({})); } Compiler::~Compiler() { @@ -36,8 +34,7 @@ Compiler::~Compiler() { delete scratch_arena_; - alloy::tracing::WriteEvent(EventType::Deinit({ - })); + alloy::tracing::WriteEvent(EventType::Deinit({})); } void Compiler::AddPass(CompilerPass* pass) { @@ -45,8 +42,7 @@ void Compiler::AddPass(CompilerPass* pass) { passes_.push_back(pass); } -void Compiler::Reset() { -} +void Compiler::Reset() {} int Compiler::Compile(HIRBuilder* builder) { SCOPE_profile_cpu_f("alloy"); @@ -63,3 +59,6 @@ int Compiler::Compile(HIRBuilder* builder) { return 0; } + +} // namespace compiler +} // namespace alloy diff --git a/src/alloy/compiler/compiler.h b/src/alloy/compiler/compiler.h index d2874cceb..82c13890b 100644 --- a/src/alloy/compiler/compiler.h +++ b/src/alloy/compiler/compiler.h @@ -13,17 +13,19 @@ #include #include -namespace alloy { namespace runtime { class Runtime; } } - +namespace alloy { +namespace runtime { +class Runtime; +} // namespace runtime +} // namespace alloy namespace alloy { namespace compiler { class CompilerPass; - class Compiler { -public: + public: Compiler(runtime::Runtime* runtime); ~Compiler(); @@ -36,7 +38,7 @@ public: int Compile(hir::HIRBuilder* builder); -private: + private: runtime::Runtime* runtime_; Arena* scratch_arena_; @@ -44,9 +46,7 @@ private: PassList passes_; }; - } // namespace compiler } // namespace alloy - #endif // ALLOY_COMPILER_COMPILER_H_ diff --git a/src/alloy/compiler/compiler_pass.cc b/src/alloy/compiler/compiler_pass.cc index 59f71902c..2c3e84afc 100644 --- a/src/alloy/compiler/compiler_pass.cc +++ b/src/alloy/compiler/compiler_pass.cc @@ -11,16 +11,12 @@ #include -using namespace alloy; -using namespace alloy::compiler; +namespace alloy { +namespace compiler { +CompilerPass::CompilerPass() : runtime_(0), compiler_(0) {} -CompilerPass::CompilerPass() : - runtime_(0), compiler_(0) { -} - -CompilerPass::~CompilerPass() { -} +CompilerPass::~CompilerPass() {} int CompilerPass::Initialize(Compiler* compiler) { runtime_ = compiler->runtime(); @@ -31,3 +27,6 @@ int CompilerPass::Initialize(Compiler* compiler) { Arena* CompilerPass::scratch_arena() const { return compiler_->scratch_arena(); } + +} // namespace compiler +} // namespace alloy diff --git a/src/alloy/compiler/compiler_pass.h b/src/alloy/compiler/compiler_pass.h index 4ba38b6c4..281d578f5 100644 --- a/src/alloy/compiler/compiler_pass.h +++ b/src/alloy/compiler/compiler_pass.h @@ -14,17 +14,19 @@ #include -namespace alloy { namespace runtime { class Runtime; } } - +namespace alloy { +namespace runtime { +class Runtime; +} // namespace runtime +} // namespace alloy namespace alloy { namespace compiler { class Compiler; - class CompilerPass { -public: + public: CompilerPass(); virtual ~CompilerPass(); @@ -32,17 +34,15 @@ public: virtual int Run(hir::HIRBuilder* builder) = 0; -protected: + protected: Arena* scratch_arena() const; -protected: + protected: runtime::Runtime* runtime_; Compiler* compiler_; }; - } // namespace compiler } // namespace alloy - #endif // ALLOY_COMPILER_COMPILER_PASS_H_ diff --git a/src/alloy/compiler/compiler_passes.h b/src/alloy/compiler/compiler_passes.h index 20ec91c66..a01896e44 100644 --- a/src/alloy/compiler/compiler_passes.h +++ b/src/alloy/compiler/compiler_passes.h @@ -15,7 +15,7 @@ #include #include #include - //#include +//#include #include #include #include @@ -49,7 +49,6 @@ // Block gets: // AddIncomingValue(Value* value, Block* src_block) ?? - // Potentially interesting passes: // // Run order: diff --git a/src/alloy/compiler/passes/constant_propagation_pass.cc b/src/alloy/compiler/passes/constant_propagation_pass.cc index 13001a904..9dcb8d3ec 100644 --- a/src/alloy/compiler/passes/constant_propagation_pass.cc +++ b/src/alloy/compiler/passes/constant_propagation_pass.cc @@ -12,18 +12,20 @@ #include #include -using namespace alloy; -using namespace alloy::compiler; -using namespace alloy::compiler::passes; +namespace alloy { +namespace compiler { +namespace passes { + +// TODO(benvanik): remove when enums redefined. using namespace alloy::hir; +using alloy::hir::HIRBuilder; +using alloy::hir::TypeName; +using alloy::hir::Value; -ConstantPropagationPass::ConstantPropagationPass() : - CompilerPass() { -} +ConstantPropagationPass::ConstantPropagationPass() : CompilerPass() {} -ConstantPropagationPass::~ConstantPropagationPass() { -} +ConstantPropagationPass::~ConstantPropagationPass() {} int ConstantPropagationPass::Run(HIRBuilder* builder) { SCOPE_profile_cpu_f("alloy"); @@ -55,379 +57,379 @@ int ConstantPropagationPass::Run(HIRBuilder* builder) { // v1 = 19 // v2 = 0 - Block* block = builder->first_block(); + auto block = builder->first_block(); while (block) { - Instr* i = block->instr_head; + auto i = block->instr_head; while (i) { - Value* v = i->dest; + auto v = i->dest; switch (i->opcode->num) { - case OPCODE_DEBUG_BREAK_TRUE: - if (i->src1.value->IsConstant()) { - if (i->src1.value->IsConstantTrue()) { - i->Replace(&OPCODE_DEBUG_BREAK_info, i->flags); - } else { - i->Remove(); + case OPCODE_DEBUG_BREAK_TRUE: + if (i->src1.value->IsConstant()) { + if (i->src1.value->IsConstantTrue()) { + i->Replace(&OPCODE_DEBUG_BREAK_info, i->flags); + } else { + i->Remove(); + } } - } - break; + break; - case OPCODE_TRAP_TRUE: - if (i->src1.value->IsConstant()) { - if (i->src1.value->IsConstantTrue()) { - i->Replace(&OPCODE_TRAP_info, i->flags); - } else { - i->Remove(); + case OPCODE_TRAP_TRUE: + if (i->src1.value->IsConstant()) { + if (i->src1.value->IsConstantTrue()) { + i->Replace(&OPCODE_TRAP_info, i->flags); + } else { + i->Remove(); + } } - } - break; + break; - case OPCODE_CALL_TRUE: - if (i->src1.value->IsConstant()) { - if (i->src1.value->IsConstantTrue()) { - auto symbol_info = i->src2.symbol_info; + case OPCODE_CALL_TRUE: + if (i->src1.value->IsConstant()) { + if (i->src1.value->IsConstantTrue()) { + auto symbol_info = i->src2.symbol_info; + i->Replace(&OPCODE_CALL_info, i->flags); + i->src1.symbol_info = symbol_info; + } else { + i->Remove(); + } + } + break; + case OPCODE_CALL_INDIRECT: + if (i->src1.value->IsConstant()) { + runtime::FunctionInfo* symbol_info; + if (runtime_->LookupFunctionInfo( + (uint32_t)i->src1.value->constant.i32, &symbol_info)) { + break; + } i->Replace(&OPCODE_CALL_info, i->flags); i->src1.symbol_info = symbol_info; - } else { + } + break; + case OPCODE_CALL_INDIRECT_TRUE: + if (i->src1.value->IsConstant()) { + if (i->src1.value->IsConstantTrue()) { + auto value = i->src2.value; + i->Replace(&OPCODE_CALL_INDIRECT_info, i->flags); + i->set_src1(value); + } else { + i->Remove(); + } + } + break; + + case OPCODE_BRANCH_TRUE: + if (i->src1.value->IsConstant()) { + if (i->src1.value->IsConstantTrue()) { + auto label = i->src2.label; + i->Replace(&OPCODE_BRANCH_info, i->flags); + i->src1.label = label; + } else { + i->Remove(); + } + } + break; + case OPCODE_BRANCH_FALSE: + if (i->src1.value->IsConstant()) { + if (i->src1.value->IsConstantFalse()) { + auto label = i->src2.label; + i->Replace(&OPCODE_BRANCH_info, i->flags); + i->src1.label = label; + } else { + i->Remove(); + } + } + break; + + case OPCODE_CAST: + if (i->src1.value->IsConstant()) { + TypeName target_type = v->type; + v->set_from(i->src1.value); + v->Cast(target_type); i->Remove(); } - } - break; - case OPCODE_CALL_INDIRECT: - if (i->src1.value->IsConstant()) { - runtime::FunctionInfo* symbol_info; - if (runtime_->LookupFunctionInfo( - (uint32_t)i->src1.value->constant.i32, &symbol_info)) { - break; - } - i->Replace(&OPCODE_CALL_info, i->flags); - i->src1.symbol_info = symbol_info; - } - break; - case OPCODE_CALL_INDIRECT_TRUE: - if (i->src1.value->IsConstant()) { - if (i->src1.value->IsConstantTrue()) { - auto value = i->src2.value; - i->Replace(&OPCODE_CALL_INDIRECT_info, i->flags); - i->set_src1(value); - } else { + break; + case OPCODE_ZERO_EXTEND: + if (i->src1.value->IsConstant()) { + TypeName target_type = v->type; + v->set_from(i->src1.value); + v->ZeroExtend(target_type); i->Remove(); } - } - break; - - case OPCODE_BRANCH_TRUE: - if (i->src1.value->IsConstant()) { - if (i->src1.value->IsConstantTrue()) { - auto label = i->src2.label; - i->Replace(&OPCODE_BRANCH_info, i->flags); - i->src1.label = label; - } else { + break; + case OPCODE_SIGN_EXTEND: + if (i->src1.value->IsConstant()) { + TypeName target_type = v->type; + v->set_from(i->src1.value); + v->SignExtend(target_type); i->Remove(); } - } - break; - case OPCODE_BRANCH_FALSE: - if (i->src1.value->IsConstant()) { - if (i->src1.value->IsConstantFalse()) { - auto label = i->src2.label; - i->Replace(&OPCODE_BRANCH_info, i->flags); - i->src1.label = label; - } else { + break; + case OPCODE_TRUNCATE: + if (i->src1.value->IsConstant()) { + TypeName target_type = v->type; + v->set_from(i->src1.value); + v->Truncate(target_type); i->Remove(); } - } - break; + break; - case OPCODE_CAST: - if (i->src1.value->IsConstant()) { - TypeName target_type = v->type; - v->set_from(i->src1.value); - v->Cast(target_type); - i->Remove(); - } - break; - case OPCODE_ZERO_EXTEND: - if (i->src1.value->IsConstant()) { - TypeName target_type = v->type; - v->set_from(i->src1.value); - v->ZeroExtend(target_type); - i->Remove(); - } - break; - case OPCODE_SIGN_EXTEND: - if (i->src1.value->IsConstant()) { - TypeName target_type = v->type; - v->set_from(i->src1.value); - v->SignExtend(target_type); - i->Remove(); - } - break; - case OPCODE_TRUNCATE: - if (i->src1.value->IsConstant()) { - TypeName target_type = v->type; - v->set_from(i->src1.value); - v->Truncate(target_type); - i->Remove(); - } - break; - - case OPCODE_SELECT: - if (i->src1.value->IsConstant()) { - if (i->src1.value->IsConstantTrue()) { - v->set_from(i->src2.value); - } else { - v->set_from(i->src3.value); + case OPCODE_SELECT: + if (i->src1.value->IsConstant()) { + if (i->src1.value->IsConstantTrue()) { + v->set_from(i->src2.value); + } else { + v->set_from(i->src3.value); + } + i->Remove(); } - i->Remove(); - } - break; - case OPCODE_IS_TRUE: - if (i->src1.value->IsConstant()) { - if (i->src1.value->IsConstantTrue()) { - v->set_constant((int8_t)1); - } else { - v->set_constant((int8_t)0); + break; + case OPCODE_IS_TRUE: + if (i->src1.value->IsConstant()) { + if (i->src1.value->IsConstantTrue()) { + v->set_constant((int8_t)1); + } else { + v->set_constant((int8_t)0); + } + i->Remove(); } - i->Remove(); - } - break; - case OPCODE_IS_FALSE: - if (i->src1.value->IsConstant()) { - if (i->src1.value->IsConstantFalse()) { - v->set_constant((int8_t)1); - } else { - v->set_constant((int8_t)0); + break; + case OPCODE_IS_FALSE: + if (i->src1.value->IsConstant()) { + if (i->src1.value->IsConstantFalse()) { + v->set_constant((int8_t)1); + } else { + v->set_constant((int8_t)0); + } + i->Remove(); } - i->Remove(); - } - break; + break; - // TODO(benvanik): compares - case OPCODE_COMPARE_EQ: - if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { - bool value = i->src1.value->IsConstantEQ(i->src2.value); - i->dest->set_constant(value); - i->Remove(); - } - break; - case OPCODE_COMPARE_NE: - if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { - bool value = i->src1.value->IsConstantNE(i->src2.value); - i->dest->set_constant(value); - i->Remove(); - } - break; - case OPCODE_COMPARE_SLT: - if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { - bool value = i->src1.value->IsConstantSLT(i->src2.value); - i->dest->set_constant(value); - i->Remove(); - } - break; - case OPCODE_COMPARE_SLE: - if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { - bool value = i->src1.value->IsConstantSLE(i->src2.value); - i->dest->set_constant(value); - i->Remove(); - } - break; - case OPCODE_COMPARE_SGT: - if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { - bool value = i->src1.value->IsConstantSGT(i->src2.value); - i->dest->set_constant(value); - i->Remove(); - } - break; - case OPCODE_COMPARE_SGE: - if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { - bool value = i->src1.value->IsConstantSGE(i->src2.value); - i->dest->set_constant(value); - i->Remove(); - } - break; - case OPCODE_COMPARE_ULT: - if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { - bool value = i->src1.value->IsConstantULT(i->src2.value); - i->dest->set_constant(value); - i->Remove(); - } - break; - case OPCODE_COMPARE_ULE: - if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { - bool value = i->src1.value->IsConstantULE(i->src2.value); - i->dest->set_constant(value); - i->Remove(); - } - break; - case OPCODE_COMPARE_UGT: - if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { - bool value = i->src1.value->IsConstantUGT(i->src2.value); - i->dest->set_constant(value); - i->Remove(); - } - break; - case OPCODE_COMPARE_UGE: - if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { - bool value = i->src1.value->IsConstantUGE(i->src2.value); - i->dest->set_constant(value); - i->Remove(); - } - break; - - case OPCODE_DID_CARRY: - XEASSERT(!i->src1.value->IsConstant()); - break; - case OPCODE_DID_OVERFLOW: - XEASSERT(!i->src1.value->IsConstant()); - break; - case OPCODE_DID_SATURATE: - XEASSERT(!i->src1.value->IsConstant()); - break; - - case OPCODE_ADD: - if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { - v->set_from(i->src1.value); - bool did_carry = v->Add(i->src2.value); - bool propagate_carry = !!(i->flags & ARITHMETIC_SET_CARRY); - i->Remove(); - - // If carry is set find the DID_CARRY and fix it. - if (propagate_carry) { - PropagateCarry(v, did_carry); + // TODO(benvanik): compares + case OPCODE_COMPARE_EQ: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + bool value = i->src1.value->IsConstantEQ(i->src2.value); + i->dest->set_constant(value); + i->Remove(); } - } - break; - // TODO(benvanik): ADD_CARRY (w/ ARITHMETIC_SET_CARRY) - case OPCODE_SUB: - if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { - v->set_from(i->src1.value); - bool did_carry = v->Sub(i->src2.value); - bool propagate_carry = !!(i->flags & ARITHMETIC_SET_CARRY); - i->Remove(); - - // If carry is set find the DID_CARRY and fix it. - if (propagate_carry) { - PropagateCarry(v, did_carry); + break; + case OPCODE_COMPARE_NE: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + bool value = i->src1.value->IsConstantNE(i->src2.value); + i->dest->set_constant(value); + i->Remove(); } - } - break; - case OPCODE_MUL: - if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { - v->set_from(i->src1.value); - v->Mul(i->src2.value); - i->Remove(); - } - break; - case OPCODE_DIV: - if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { - v->set_from(i->src1.value); - v->Div(i->src2.value); - i->Remove(); - } - break; - // case OPCODE_MUL_ADD: - // case OPCODE_MUL_SUB - case OPCODE_NEG: - if (i->src1.value->IsConstant()) { - v->set_from(i->src1.value); - v->Neg(); - i->Remove(); - } - break; - case OPCODE_ABS: - if (i->src1.value->IsConstant()) { - v->set_from(i->src1.value); - v->Abs(); - i->Remove(); - } - break; - case OPCODE_SQRT: - if (i->src1.value->IsConstant()) { - v->set_from(i->src1.value); - v->Sqrt(); - i->Remove(); - } - break; - case OPCODE_RSQRT: - if (i->src1.value->IsConstant()) { - v->set_from(i->src1.value); - v->RSqrt(); - i->Remove(); - } - break; + break; + case OPCODE_COMPARE_SLT: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + bool value = i->src1.value->IsConstantSLT(i->src2.value); + i->dest->set_constant(value); + i->Remove(); + } + break; + case OPCODE_COMPARE_SLE: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + bool value = i->src1.value->IsConstantSLE(i->src2.value); + i->dest->set_constant(value); + i->Remove(); + } + break; + case OPCODE_COMPARE_SGT: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + bool value = i->src1.value->IsConstantSGT(i->src2.value); + i->dest->set_constant(value); + i->Remove(); + } + break; + case OPCODE_COMPARE_SGE: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + bool value = i->src1.value->IsConstantSGE(i->src2.value); + i->dest->set_constant(value); + i->Remove(); + } + break; + case OPCODE_COMPARE_ULT: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + bool value = i->src1.value->IsConstantULT(i->src2.value); + i->dest->set_constant(value); + i->Remove(); + } + break; + case OPCODE_COMPARE_ULE: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + bool value = i->src1.value->IsConstantULE(i->src2.value); + i->dest->set_constant(value); + i->Remove(); + } + break; + case OPCODE_COMPARE_UGT: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + bool value = i->src1.value->IsConstantUGT(i->src2.value); + i->dest->set_constant(value); + i->Remove(); + } + break; + case OPCODE_COMPARE_UGE: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + bool value = i->src1.value->IsConstantUGE(i->src2.value); + i->dest->set_constant(value); + i->Remove(); + } + break; - case OPCODE_AND: - if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { - v->set_from(i->src1.value); - v->And(i->src2.value); - i->Remove(); - } - break; - case OPCODE_OR: - if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { - v->set_from(i->src1.value); - v->Or(i->src2.value); - i->Remove(); - } - break; - case OPCODE_XOR: - if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { - v->set_from(i->src1.value); - v->Xor(i->src2.value); - i->Remove(); - } - break; - case OPCODE_NOT: - if (i->src1.value->IsConstant()) { - v->set_from(i->src1.value); - v->Not(); - i->Remove(); - } - break; - case OPCODE_SHL: - if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { - v->set_from(i->src1.value); - v->Shl(i->src2.value); - i->Remove(); - } - break; - // TODO(benvanik): VECTOR_SHL - case OPCODE_SHR: - if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { - v->set_from(i->src1.value); - v->Shr(i->src2.value); - i->Remove(); - } - break; - case OPCODE_SHA: - if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { - v->set_from(i->src1.value); - v->Sha(i->src2.value); - i->Remove(); - } - break; - // TODO(benvanik): ROTATE_LEFT - case OPCODE_BYTE_SWAP: - if (i->src1.value->IsConstant()) { - v->set_from(i->src1.value); - v->ByteSwap(); - i->Remove(); - } - break; - case OPCODE_CNTLZ: - if (i->src1.value->IsConstant()) { - v->set_zero(v->type); - v->CountLeadingZeros(i->src1.value); - i->Remove(); - } - break; - // TODO(benvanik): INSERT/EXTRACT - // TODO(benvanik): SPLAT/PERMUTE/SWIZZLE - case OPCODE_SPLAT: - if (i->src1.value->IsConstant()) { - // Quite a few of these, from building vec128s. - } - break; + case OPCODE_DID_CARRY: + XEASSERT(!i->src1.value->IsConstant()); + break; + case OPCODE_DID_OVERFLOW: + XEASSERT(!i->src1.value->IsConstant()); + break; + case OPCODE_DID_SATURATE: + XEASSERT(!i->src1.value->IsConstant()); + break; + + case OPCODE_ADD: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + v->set_from(i->src1.value); + bool did_carry = v->Add(i->src2.value); + bool propagate_carry = !!(i->flags & ARITHMETIC_SET_CARRY); + i->Remove(); + + // If carry is set find the DID_CARRY and fix it. + if (propagate_carry) { + PropagateCarry(v, did_carry); + } + } + break; + // TODO(benvanik): ADD_CARRY (w/ ARITHMETIC_SET_CARRY) + case OPCODE_SUB: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + v->set_from(i->src1.value); + bool did_carry = v->Sub(i->src2.value); + bool propagate_carry = !!(i->flags & ARITHMETIC_SET_CARRY); + i->Remove(); + + // If carry is set find the DID_CARRY and fix it. + if (propagate_carry) { + PropagateCarry(v, did_carry); + } + } + break; + case OPCODE_MUL: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + v->set_from(i->src1.value); + v->Mul(i->src2.value); + i->Remove(); + } + break; + case OPCODE_DIV: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + v->set_from(i->src1.value); + v->Div(i->src2.value); + i->Remove(); + } + break; + // case OPCODE_MUL_ADD: + // case OPCODE_MUL_SUB + case OPCODE_NEG: + if (i->src1.value->IsConstant()) { + v->set_from(i->src1.value); + v->Neg(); + i->Remove(); + } + break; + case OPCODE_ABS: + if (i->src1.value->IsConstant()) { + v->set_from(i->src1.value); + v->Abs(); + i->Remove(); + } + break; + case OPCODE_SQRT: + if (i->src1.value->IsConstant()) { + v->set_from(i->src1.value); + v->Sqrt(); + i->Remove(); + } + break; + case OPCODE_RSQRT: + if (i->src1.value->IsConstant()) { + v->set_from(i->src1.value); + v->RSqrt(); + i->Remove(); + } + break; + + case OPCODE_AND: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + v->set_from(i->src1.value); + v->And(i->src2.value); + i->Remove(); + } + break; + case OPCODE_OR: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + v->set_from(i->src1.value); + v->Or(i->src2.value); + i->Remove(); + } + break; + case OPCODE_XOR: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + v->set_from(i->src1.value); + v->Xor(i->src2.value); + i->Remove(); + } + break; + case OPCODE_NOT: + if (i->src1.value->IsConstant()) { + v->set_from(i->src1.value); + v->Not(); + i->Remove(); + } + break; + case OPCODE_SHL: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + v->set_from(i->src1.value); + v->Shl(i->src2.value); + i->Remove(); + } + break; + // TODO(benvanik): VECTOR_SHL + case OPCODE_SHR: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + v->set_from(i->src1.value); + v->Shr(i->src2.value); + i->Remove(); + } + break; + case OPCODE_SHA: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + v->set_from(i->src1.value); + v->Sha(i->src2.value); + i->Remove(); + } + break; + // TODO(benvanik): ROTATE_LEFT + case OPCODE_BYTE_SWAP: + if (i->src1.value->IsConstant()) { + v->set_from(i->src1.value); + v->ByteSwap(); + i->Remove(); + } + break; + case OPCODE_CNTLZ: + if (i->src1.value->IsConstant()) { + v->set_zero(v->type); + v->CountLeadingZeros(i->src1.value); + i->Remove(); + } + break; + // TODO(benvanik): INSERT/EXTRACT + // TODO(benvanik): SPLAT/PERMUTE/SWIZZLE + case OPCODE_SPLAT: + if (i->src1.value->IsConstant()) { + // Quite a few of these, from building vec128s. + } + break; } i = i->next; } @@ -438,7 +440,7 @@ int ConstantPropagationPass::Run(HIRBuilder* builder) { return 0; } -void ConstantPropagationPass::PropagateCarry(hir::Value* v, bool did_carry) { +void ConstantPropagationPass::PropagateCarry(Value* v, bool did_carry) { auto next = v->use_head; while (next) { auto use = next; @@ -450,3 +452,7 @@ void ConstantPropagationPass::PropagateCarry(hir::Value* v, bool did_carry) { } } } + +} // namespace passes +} // namespace compiler +} // namespace alloy diff --git a/src/alloy/compiler/passes/constant_propagation_pass.h b/src/alloy/compiler/passes/constant_propagation_pass.h index 2220394ad..cdc7f1353 100644 --- a/src/alloy/compiler/passes/constant_propagation_pass.h +++ b/src/alloy/compiler/passes/constant_propagation_pass.h @@ -12,27 +12,23 @@ #include - namespace alloy { namespace compiler { namespace passes { - class ConstantPropagationPass : public CompilerPass { -public: + public: ConstantPropagationPass(); virtual ~ConstantPropagationPass(); virtual int Run(hir::HIRBuilder* builder); -private: + private: void PropagateCarry(hir::Value* v, bool did_carry); }; - } // namespace passes } // namespace compiler } // namespace alloy - #endif // ALLOY_COMPILER_PASSES_CONSTANT_PROPAGATION_PASS_H_ diff --git a/src/alloy/compiler/passes/context_promotion_pass.cc b/src/alloy/compiler/passes/context_promotion_pass.cc index dc225aea6..2f14acd77 100644 --- a/src/alloy/compiler/passes/context_promotion_pass.cc +++ b/src/alloy/compiler/passes/context_promotion_pass.cc @@ -14,22 +14,24 @@ #include #include -using namespace alloy; -using namespace alloy::compiler; -using namespace alloy::compiler::passes; -using namespace alloy::frontend; -using namespace alloy::hir; -using namespace alloy::runtime; - - DEFINE_bool(store_all_context_values, false, "Don't strip dead context stores to aid in debugging."); +namespace alloy { +namespace compiler { +namespace passes { -ContextPromotionPass::ContextPromotionPass() : - context_values_size_(0), context_values_(0), - CompilerPass() { -} +// TODO(benvanik): remove when enums redefined. +using namespace alloy::hir; + +using alloy::frontend::ContextInfo; +using alloy::hir::Block; +using alloy::hir::HIRBuilder; +using alloy::hir::Instr; +using alloy::hir::Value; + +ContextPromotionPass::ContextPromotionPass() + : context_values_size_(0), context_values_(0), CompilerPass() {} ContextPromotionPass::~ContextPromotionPass() { if (context_values_) { @@ -70,7 +72,7 @@ int ContextPromotionPass::Run(HIRBuilder* builder) { // Promote loads to values. // Process each block independently, for now. - Block* block = builder->first_block(); + auto block = builder->first_block(); while (block) { PromoteBlock(block); block = block->next; @@ -121,7 +123,7 @@ void ContextPromotionPass::PromoteBlock(Block* block) { void ContextPromotionPass::RemoveDeadStoresBlock(Block* block) { // TODO(benvanik): use a bitvector. // To avoid clearing the structure, we use a token. - Value* token = (Value*)block; + auto token = (Value*)block; // Walk backwards and mark offsets that are written to. // If the offset was written to earlier, ignore the store. @@ -141,3 +143,7 @@ void ContextPromotionPass::RemoveDeadStoresBlock(Block* block) { i = prev; } } + +} // namespace passes +} // namespace compiler +} // namespace alloy diff --git a/src/alloy/compiler/passes/context_promotion_pass.h b/src/alloy/compiler/passes/context_promotion_pass.h index 8c4d7b743..925f0bb32 100644 --- a/src/alloy/compiler/passes/context_promotion_pass.h +++ b/src/alloy/compiler/passes/context_promotion_pass.h @@ -12,14 +12,12 @@ #include - namespace alloy { namespace compiler { namespace passes { - class ContextPromotionPass : public CompilerPass { -public: + public: ContextPromotionPass(); virtual ~ContextPromotionPass(); @@ -27,19 +25,17 @@ public: virtual int Run(hir::HIRBuilder* builder); -private: + private: void PromoteBlock(hir::Block* block); void RemoveDeadStoresBlock(hir::Block* block); -private: + private: size_t context_values_size_; hir::Value** context_values_; }; - } // namespace passes } // namespace compiler } // namespace alloy - #endif // ALLOY_COMPILER_PASSES_CONTEXT_PROMOTION_PASS_H_ diff --git a/src/alloy/compiler/passes/control_flow_analysis_pass.cc b/src/alloy/compiler/passes/control_flow_analysis_pass.cc index 5cf6ea6a6..312fa3441 100644 --- a/src/alloy/compiler/passes/control_flow_analysis_pass.cc +++ b/src/alloy/compiler/passes/control_flow_analysis_pass.cc @@ -13,21 +13,19 @@ #include #include -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::compiler; -using namespace alloy::compiler::passes; -using namespace alloy::frontend; +namespace alloy { +namespace compiler { +namespace passes { + +// TODO(benvanik): remove when enums redefined. using namespace alloy::hir; -using namespace alloy::runtime; +using alloy::hir::Edge; +using alloy::hir::HIRBuilder; -ControlFlowAnalysisPass::ControlFlowAnalysisPass() : - CompilerPass() { -} +ControlFlowAnalysisPass::ControlFlowAnalysisPass() : CompilerPass() {} -ControlFlowAnalysisPass::~ControlFlowAnalysisPass() { -} +ControlFlowAnalysisPass::~ControlFlowAnalysisPass() {} int ControlFlowAnalysisPass::Run(HIRBuilder* builder) { SCOPE_profile_cpu_f("alloy"); @@ -46,7 +44,7 @@ int ControlFlowAnalysisPass::Run(HIRBuilder* builder) { auto label = instr->src1.label; builder->AddEdge(block, label->block, Edge::UNCONDITIONAL); } else if (instr->opcode == &OPCODE_BRANCH_TRUE_info || - instr->opcode == &OPCODE_BRANCH_FALSE_info) { + instr->opcode == &OPCODE_BRANCH_FALSE_info) { auto label = instr->src2.label; builder->AddEdge(block, label->block, 0); } @@ -67,3 +65,7 @@ int ControlFlowAnalysisPass::Run(HIRBuilder* builder) { return 0; } + +} // namespace passes +} // namespace compiler +} // namespace alloy diff --git a/src/alloy/compiler/passes/control_flow_analysis_pass.h b/src/alloy/compiler/passes/control_flow_analysis_pass.h index c639db5cb..35ce33fba 100644 --- a/src/alloy/compiler/passes/control_flow_analysis_pass.h +++ b/src/alloy/compiler/passes/control_flow_analysis_pass.h @@ -12,26 +12,22 @@ #include - namespace alloy { namespace compiler { namespace passes { - class ControlFlowAnalysisPass : public CompilerPass { -public: + public: ControlFlowAnalysisPass(); virtual ~ControlFlowAnalysisPass(); virtual int Run(hir::HIRBuilder* builder); -private: + private: }; - } // namespace passes } // namespace compiler } // namespace alloy - #endif // ALLOY_COMPILER_PASSES_CONTROL_FLOW_ANALYSIS_PASS_H_ diff --git a/src/alloy/compiler/passes/data_flow_analysis_pass.cc b/src/alloy/compiler/passes/data_flow_analysis_pass.cc index 209410016..5c7fbdc89 100644 --- a/src/alloy/compiler/passes/data_flow_analysis_pass.cc +++ b/src/alloy/compiler/passes/data_flow_analysis_pass.cc @@ -19,21 +19,20 @@ #include #pragma warning(pop) -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::compiler; -using namespace alloy::compiler::passes; -using namespace alloy::frontend; +namespace alloy { +namespace compiler { +namespace passes { + +// TODO(benvanik): remove when enums redefined. using namespace alloy::hir; -using namespace alloy::runtime; +using alloy::hir::HIRBuilder; +using alloy::hir::OpcodeSignatureType; +using alloy::hir::Value; -DataFlowAnalysisPass::DataFlowAnalysisPass() : - CompilerPass() { -} +DataFlowAnalysisPass::DataFlowAnalysisPass() : CompilerPass() {} -DataFlowAnalysisPass::~DataFlowAnalysisPass() { -} +DataFlowAnalysisPass::~DataFlowAnalysisPass() {} int DataFlowAnalysisPass::Run(HIRBuilder* builder) { SCOPE_profile_cpu_f("alloy"); @@ -66,15 +65,15 @@ void DataFlowAnalysisPass::AnalyzeFlow(HIRBuilder* builder, // Stash for value map. We may want to maintain this during building. auto arena = builder->arena(); - Value** value_map = (Value**)arena->Alloc( - sizeof(Value*) * max_value_estimate); + Value** value_map = + (Value**)arena->Alloc(sizeof(Value*) * max_value_estimate); // Allocate incoming bitvectors for use by blocks. We don't need outgoing // because they are only used during the block iteration. // Mapped by block ordinal. // TODO(benvanik): cache this list, grow as needed, etc. - auto incoming_bitvectors = (llvm::BitVector**)arena->Alloc( - sizeof(llvm::BitVector*) * block_count); + auto incoming_bitvectors = + (llvm::BitVector**)arena->Alloc(sizeof(llvm::BitVector*) * block_count); for (auto n = 0u; n < block_count; n++) { incoming_bitvectors[n] = new llvm::BitVector(max_value_estimate); } @@ -90,10 +89,10 @@ void DataFlowAnalysisPass::AnalyzeFlow(HIRBuilder* builder, auto instr = block->instr_head; while (instr) { uint32_t signature = instr->opcode->signature; -#define SET_INCOMING_VALUE(v) \ - if (v->def && v->def->block != block) { \ - incoming_values.set(v->ordinal); \ - } \ +#define SET_INCOMING_VALUE(v) \ + if (v->def && v->def->block != block) { \ + incoming_values.set(v->ordinal); \ + } \ XEASSERT(v->ordinal < max_value_estimate); \ value_map[v->ordinal] = v; if (GET_OPCODE_SIG_TYPE_SRC1(signature) == OPCODE_SIG_TYPE_V) { @@ -201,3 +200,7 @@ void DataFlowAnalysisPass::AnalyzeFlow(HIRBuilder* builder, delete incoming_bitvectors[n]; } } + +} // namespace passes +} // namespace compiler +} // namespace alloy diff --git a/src/alloy/compiler/passes/dead_code_elimination_pass.cc b/src/alloy/compiler/passes/dead_code_elimination_pass.cc index afb8d87b2..f18bfc26f 100644 --- a/src/alloy/compiler/passes/dead_code_elimination_pass.cc +++ b/src/alloy/compiler/passes/dead_code_elimination_pass.cc @@ -9,18 +9,20 @@ #include -using namespace alloy; -using namespace alloy::compiler; -using namespace alloy::compiler::passes; +namespace alloy { +namespace compiler { +namespace passes { + +// TODO(benvanik): remove when enums redefined. using namespace alloy::hir; +using alloy::hir::HIRBuilder; +using alloy::hir::Instr; +using alloy::hir::Value; -DeadCodeEliminationPass::DeadCodeEliminationPass() : - CompilerPass() { -} +DeadCodeEliminationPass::DeadCodeEliminationPass() : CompilerPass() {} -DeadCodeEliminationPass::~DeadCodeEliminationPass() { -} +DeadCodeEliminationPass::~DeadCodeEliminationPass() {} int DeadCodeEliminationPass::Run(HIRBuilder* builder) { SCOPE_profile_cpu_f("alloy"); @@ -63,7 +65,7 @@ int DeadCodeEliminationPass::Run(HIRBuilder* builder) { bool any_instr_removed = false; bool any_locals_removed = false; - Block* block = builder->first_block(); + auto block = builder->first_block(); while (block) { // Walk instructions in reverse. Instr* i = block->instr_tail; @@ -71,8 +73,8 @@ int DeadCodeEliminationPass::Run(HIRBuilder* builder) { auto prev = i->prev; auto opcode = i->opcode; - if (!(opcode->flags & OPCODE_FLAG_VOLATILE) && - i->dest && !i->dest->use_head) { + if (!(opcode->flags & OPCODE_FLAG_VOLATILE) && i->dest && + !i->dest->use_head) { // Has no uses and is not volatile. This instruction can die! MakeNopRecursive(i); any_instr_removed = true; @@ -110,7 +112,7 @@ int DeadCodeEliminationPass::Run(HIRBuilder* builder) { // Remove all nops. if (any_instr_removed) { - Block* block = builder->first_block(); + auto block = builder->first_block(); while (block) { Instr* i = block->instr_head; while (i) { @@ -148,19 +150,19 @@ void DeadCodeEliminationPass::MakeNopRecursive(Instr* i) { i->dest->def = NULL; i->dest = NULL; -#define MAKE_NOP_SRC(n) \ - if (i->src##n##_use) { \ - Value::Use* use = i->src##n##_use; \ - Value* value = i->src##n##.value; \ - i->src##n##_use = NULL; \ - i->src##n##.value = NULL; \ - value->RemoveUse(use); \ - if (!value->use_head) { \ +#define MAKE_NOP_SRC(n) \ + if (i->src##n##_use) { \ + Value::Use* use = i->src##n##_use; \ + Value* value = i->src##n##.value; \ + i->src##n##_use = NULL; \ + i->src##n##.value = NULL; \ + value->RemoveUse(use); \ + if (!value->use_head) { \ /* Value is now unused, so recursively kill it. */ \ - if (value->def && value->def != i) { \ - MakeNopRecursive(value->def); \ - } \ - } \ + if (value->def && value->def != i) { \ + MakeNopRecursive(value->def); \ + } \ + } \ } MAKE_NOP_SRC(1); MAKE_NOP_SRC(2); @@ -209,3 +211,7 @@ bool DeadCodeEliminationPass::CheckLocalUse(Instr* i) { return false; } + +} // namespace passes +} // namespace compiler +} // namespace alloy diff --git a/src/alloy/compiler/passes/finalization_pass.cc b/src/alloy/compiler/passes/finalization_pass.cc index e6358f242..5066b53ab 100644 --- a/src/alloy/compiler/passes/finalization_pass.cc +++ b/src/alloy/compiler/passes/finalization_pass.cc @@ -13,21 +13,18 @@ #include #include -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::compiler; -using namespace alloy::compiler::passes; -using namespace alloy::frontend; +namespace alloy { +namespace compiler { +namespace passes { + +// TODO(benvanik): remove when enums redefined. using namespace alloy::hir; -using namespace alloy::runtime; +using alloy::hir::HIRBuilder; -FinalizationPass::FinalizationPass() : - CompilerPass() { -} +FinalizationPass::FinalizationPass() : CompilerPass() {} -FinalizationPass::~FinalizationPass() { -} +FinalizationPass::~FinalizationPass() {} int FinalizationPass::Run(HIRBuilder* builder) { SCOPE_profile_cpu_f("alloy"); @@ -70,3 +67,7 @@ int FinalizationPass::Run(HIRBuilder* builder) { return 0; } + +} // namespace passes +} // namespace compiler +} // namespace alloy diff --git a/src/alloy/compiler/passes/finalization_pass.h b/src/alloy/compiler/passes/finalization_pass.h index a2260003a..30cec0d3c 100644 --- a/src/alloy/compiler/passes/finalization_pass.h +++ b/src/alloy/compiler/passes/finalization_pass.h @@ -12,26 +12,22 @@ #include - namespace alloy { namespace compiler { namespace passes { - class FinalizationPass : public CompilerPass { -public: + public: FinalizationPass(); virtual ~FinalizationPass(); virtual int Run(hir::HIRBuilder* builder); -private: + private: }; - } // namespace passes } // namespace compiler } // namespace alloy - #endif // ALLOY_COMPILER_PASSES_FINALIZATION_PASS_H_ diff --git a/src/alloy/compiler/passes/register_allocation_pass.cc b/src/alloy/compiler/passes/register_allocation_pass.cc index 7c3a0a7a9..aa6fcf13c 100644 --- a/src/alloy/compiler/passes/register_allocation_pass.cc +++ b/src/alloy/compiler/passes/register_allocation_pass.cc @@ -11,20 +11,25 @@ #include -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::compiler; -using namespace alloy::compiler::passes; +namespace alloy { +namespace compiler { +namespace passes { + +// TODO(benvanik): remove when enums redefined. using namespace alloy::hir; +using alloy::backend::MachineInfo; +using alloy::hir::HIRBuilder; +using alloy::hir::Instr; +using alloy::hir::OpcodeSignatureType; +using alloy::hir::RegAssignment; +using alloy::hir::TypeName; +using alloy::hir::Value; #define ASSERT_NO_CYCLES 0 - -RegisterAllocationPass::RegisterAllocationPass( - const MachineInfo* machine_info) : - machine_info_(machine_info), - CompilerPass() { +RegisterAllocationPass::RegisterAllocationPass(const MachineInfo* machine_info) + : machine_info_(machine_info), CompilerPass() { // Initialize register sets. // TODO(benvanik): rewrite in a way that makes sense - this is terrible. auto mi_sets = machine_info->register_sets; @@ -88,7 +93,7 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) { instr = block->instr_head; while (instr) { - const OpcodeInfo* info = instr->opcode; + const auto info = instr->opcode; uint32_t signature = info->signature; // Update the register use heaps. @@ -101,7 +106,7 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) { // reuse it. // NOTE: these checks require that the usage list be sorted! bool has_preferred_reg = false; - RegAssignment preferred_reg = { 0 }; + RegAssignment preferred_reg = {0}; if (GET_OPCODE_SIG_TYPE_SRC1(signature) == OPCODE_SIG_TYPE_V && !instr->src1.value->IsConstant()) { if (!instr->src1_use->next) { @@ -117,7 +122,8 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) { // Must not have been set already. XEASSERTNULL(instr->dest->reg.set); - // Sort the usage list. We depend on this in future uses of this variable. + // Sort the usage list. We depend on this in future uses of this + // variable. SortUsageList(instr->dest); // If we have a preferred register, use that. @@ -181,7 +187,6 @@ void RegisterAllocationPass::DumpUsage(const char* name) { #endif } - void RegisterAllocationPass::PrepareBlockState() { for (size_t i = 0; i < XECOUNT(usage_sets_.all_sets); ++i) { auto usage_set = usage_sets_.all_sets[i]; @@ -249,9 +254,8 @@ bool RegisterAllocationPass::IsRegInUse(const RegAssignment& reg) { return !usage_set->availability.test(reg.index); } -RegisterAllocationPass::RegisterSetUsage* -RegisterAllocationPass::MarkRegUsed(const RegAssignment& reg, - Value* value, Value::Use* use) { +RegisterAllocationPass::RegisterSetUsage* RegisterAllocationPass::MarkRegUsed( + const RegAssignment& reg, Value* value, Value::Use* use) { auto usage_set = RegisterSetForValue(value); usage_set->availability.set(reg.index, false); usage_set->upcoming_uses.emplace_back(value, use); @@ -298,7 +302,8 @@ bool RegisterAllocationPass::TryAllocateRegister(Value* value) { // Find the first free register, if any. // We have to ensure it's a valid one (in our count). unsigned long first_unused = 0; - bool all_used = _BitScanForward(&first_unused, usage_set->availability.to_ulong()) == 0; + bool all_used = + _BitScanForward(&first_unused, usage_set->availability.to_ulong()) == 0; if (!all_used && first_unused < usage_set->count) { // Available! Use it!. value->reg.set = usage_set->set; @@ -311,8 +316,8 @@ bool RegisterAllocationPass::TryAllocateRegister(Value* value) { return false; } -bool RegisterAllocationPass::SpillOneRegister( - HIRBuilder* builder, TypeName required_type) { +bool RegisterAllocationPass::SpillOneRegister(HIRBuilder* builder, + TypeName required_type) { // Get the set that we will be picking from. RegisterSetUsage* usage_set; if (required_type <= INT64_TYPE) { @@ -326,17 +331,17 @@ bool RegisterAllocationPass::SpillOneRegister( DumpUsage("SpillOneRegister (pre)"); // Pick the one with the furthest next use. XEASSERT(!usage_set->upcoming_uses.empty()); - auto furthest_usage = std::max_element( - usage_set->upcoming_uses.begin(), usage_set->upcoming_uses.end(), - RegisterUsage::Comparer()); - Value* spill_value = furthest_usage->value; + auto furthest_usage = std::max_element(usage_set->upcoming_uses.begin(), + usage_set->upcoming_uses.end(), + RegisterUsage::Comparer()); + auto spill_value = furthest_usage->value; Value::Use* prev_use = furthest_usage->use->prev; Value::Use* next_use = furthest_usage->use; XEASSERTNOTNULL(next_use); usage_set->upcoming_uses.erase(furthest_usage); DumpUsage("SpillOneRegister (post)"); const auto reg = spill_value->reg; - + // We know the spill_value use list is sorted, so we can cut it right now. // This makes it easier down below. auto new_head_use = next_use; @@ -367,7 +372,8 @@ bool RegisterAllocationPass::SpillOneRegister( spill_value->last_use = spill_store; } else if (prev_use) { // We insert the store immediately before the previous use. - // If we were smarter we could then re-run allocation and reuse the register + // If we were smarter we could then re-run allocation and reuse the + // register // once dropped. spill_store->MoveBefore(prev_use->instr); @@ -396,7 +402,7 @@ bool RegisterAllocationPass::SpillOneRegister( auto new_value = builder->LoadLocal(spill_value->local_slot); auto spill_load = builder->last_instr(); spill_load->MoveBefore(next_use->instr); - // Note: implicit first use added. +// Note: implicit first use added. #if ASSERT_NO_CYCLES builder->AssertNoCycles(); @@ -448,8 +454,7 @@ bool RegisterAllocationPass::SpillOneRegister( } RegisterAllocationPass::RegisterSetUsage* -RegisterAllocationPass::RegisterSetForValue( - const Value* value) { +RegisterAllocationPass::RegisterSetForValue(const Value* value) { if (value->type <= INT64_TYPE) { return usage_sets_.int_set; } else if (value->type <= FLOAT64_TYPE) { @@ -498,16 +503,24 @@ void RegisterAllocationPass::SortUsageList(Value* value) { Value::Use* e = nullptr; if (psize == 0) { // p is empty; e must come from q - e = q; q = q->next; qsize--; + e = q; + q = q->next; + qsize--; } else if (qsize == 0 || !q) { // q is empty; e must come from p - e = p; p = p->next; psize--; + e = p; + p = p->next; + psize--; } else if (CompareValueUse(p, q) <= 0) { // First element of p is lower (or same); e must come from p - e = p; p = p->next; psize--; + e = p; + p = p->next; + psize--; } else { // First element of q is lower; e must come from q - e = q; q = q->next; qsize--; + e = q; + q = q->next; + qsize--; } // add the next element to the merged list if (tail) { @@ -537,3 +550,7 @@ void RegisterAllocationPass::SortUsageList(Value* value) { value->use_head = head; value->last_use = tail->instr; } + +} // namespace passes +} // namespace compiler +} // namespace alloy diff --git a/src/alloy/compiler/passes/register_allocation_pass.h b/src/alloy/compiler/passes/register_allocation_pass.h index aa5943aea..47b88cae0 100644 --- a/src/alloy/compiler/passes/register_allocation_pass.h +++ b/src/alloy/compiler/passes/register_allocation_pass.h @@ -17,20 +17,18 @@ #include #include - namespace alloy { namespace compiler { namespace passes { - class RegisterAllocationPass : public CompilerPass { -public: + public: RegisterAllocationPass(const backend::MachineInfo* machine_info); virtual ~RegisterAllocationPass(); virtual int Run(hir::HIRBuilder* builder); -private: + private: // TODO(benvanik): rewrite all this set shit -- too much indirection, the // complexity is not needed. struct RegisterUsage { @@ -70,7 +68,7 @@ private: void SortUsageList(hir::Value* value); -private: + private: const backend::MachineInfo* machine_info_; struct { RegisterSetUsage* int_set = nullptr; @@ -80,10 +78,8 @@ private: } usage_sets_; }; - } // namespace passes } // namespace compiler } // namespace alloy - #endif // ALLOY_COMPILER_PASSES_REGISTER_ALLOCATION_PASS_H_ diff --git a/src/alloy/compiler/passes/simplification_pass.cc b/src/alloy/compiler/passes/simplification_pass.cc index 7fc53c940..22ec69820 100644 --- a/src/alloy/compiler/passes/simplification_pass.cc +++ b/src/alloy/compiler/passes/simplification_pass.cc @@ -9,18 +9,20 @@ #include -using namespace alloy; -using namespace alloy::compiler; -using namespace alloy::compiler::passes; +namespace alloy { +namespace compiler { +namespace passes { + +// TODO(benvanik): remove when enums redefined. using namespace alloy::hir; +using alloy::hir::HIRBuilder; +using alloy::hir::Instr; +using alloy::hir::Value; -SimplificationPass::SimplificationPass() : - CompilerPass() { -} +SimplificationPass::SimplificationPass() : CompilerPass() {} -SimplificationPass::~SimplificationPass() { -} +SimplificationPass::~SimplificationPass() {} int SimplificationPass::Run(HIRBuilder* builder) { SCOPE_profile_cpu_f("alloy"); @@ -65,7 +67,7 @@ void SimplificationPass::CheckTruncate(Instr* i) { // Walk backward up src's chain looking for an extend. We may have // assigns, so skip those. auto src = i->src1.value; - Instr* def = src->def; + auto def = src->def; while (def && def->opcode == &OPCODE_ASSIGN_info) { // Skip asignments. def = def->src1.value->def; @@ -93,7 +95,7 @@ void SimplificationPass::CheckByteSwap(Instr* i) { // Walk backward up src's chain looking for a byte swap. We may have // assigns, so skip those. auto src = i->src1.value; - Instr* def = src->def; + auto def = src->def; while (def && def->opcode == &OPCODE_ASSIGN_info) { // Skip asignments. def = def->src1.value->def; @@ -147,11 +149,11 @@ void SimplificationPass::SimplifyAssignments(HIRBuilder* builder) { } Value* SimplificationPass::CheckValue(Value* value) { - Instr* def = value->def; + auto def = value->def; if (def && def->opcode == &OPCODE_ASSIGN_info) { // Value comes from an assignment - recursively find if it comes from // another assignment. It probably doesn't, if we already replaced it. - Value* replacement = def->src1.value; + auto replacement = def->src1.value; while (true) { def = replacement->def; if (!def || def->opcode != &OPCODE_ASSIGN_info) { @@ -163,3 +165,7 @@ Value* SimplificationPass::CheckValue(Value* value) { } return value; } + +} // namespace passes +} // namespace compiler +} // namespace alloy diff --git a/src/alloy/compiler/passes/simplification_pass.h b/src/alloy/compiler/passes/simplification_pass.h index 19e1023fb..6806d48c7 100644 --- a/src/alloy/compiler/passes/simplification_pass.h +++ b/src/alloy/compiler/passes/simplification_pass.h @@ -12,20 +12,18 @@ #include - namespace alloy { namespace compiler { namespace passes { - class SimplificationPass : public CompilerPass { -public: + public: SimplificationPass(); virtual ~SimplificationPass(); virtual int Run(hir::HIRBuilder* builder); -private: + private: void EliminateConversions(hir::HIRBuilder* builder); void CheckTruncate(hir::Instr* i); void CheckByteSwap(hir::Instr* i); @@ -34,10 +32,8 @@ private: hir::Value* CheckValue(hir::Value* value); }; - } // namespace passes } // namespace compiler } // namespace alloy - #endif // ALLOY_COMPILER_PASSES_SIMPLIFICATION_PASS_H_ diff --git a/src/alloy/compiler/passes/validation_pass.cc b/src/alloy/compiler/passes/validation_pass.cc index 265c82fe9..4ddb06cf2 100644 --- a/src/alloy/compiler/passes/validation_pass.cc +++ b/src/alloy/compiler/passes/validation_pass.cc @@ -13,21 +13,22 @@ #include #include -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::compiler; -using namespace alloy::compiler::passes; -using namespace alloy::frontend; +namespace alloy { +namespace compiler { +namespace passes { + +// TODO(benvanik): remove when enums redefined. using namespace alloy::hir; -using namespace alloy::runtime; +using alloy::hir::Block; +using alloy::hir::HIRBuilder; +using alloy::hir::Instr; +using alloy::hir::OpcodeSignatureType; +using alloy::hir::Value; -ValidationPass::ValidationPass() : - CompilerPass() { -} +ValidationPass::ValidationPass() : CompilerPass() {} -ValidationPass::~ValidationPass() { -} +ValidationPass::~ValidationPass() {} int ValidationPass::Run(HIRBuilder* builder) { SCOPE_profile_cpu_f("alloy"); @@ -90,7 +91,7 @@ int ValidationPass::ValidateInstruction(Block* block, Instr* instr) { } int ValidationPass::ValidateValue(Block* block, Instr* instr, Value* value) { - //if (value->def) { + // if (value->def) { // auto def = value->def; // XEASSERT(def->block == block); // if (def->block != block) { @@ -99,3 +100,7 @@ int ValidationPass::ValidateValue(Block* block, Instr* instr, Value* value) { //} return 0; } + +} // namespace passes +} // namespace compiler +} // namespace alloy diff --git a/src/alloy/compiler/passes/validation_pass.h b/src/alloy/compiler/passes/validation_pass.h index a9f0c8f9a..47c474887 100644 --- a/src/alloy/compiler/passes/validation_pass.h +++ b/src/alloy/compiler/passes/validation_pass.h @@ -12,28 +12,24 @@ #include - namespace alloy { namespace compiler { namespace passes { - class ValidationPass : public CompilerPass { -public: + public: ValidationPass(); virtual ~ValidationPass(); virtual int Run(hir::HIRBuilder* builder); -private: + private: int ValidateInstruction(hir::Block* block, hir::Instr* instr); int ValidateValue(hir::Block* block, hir::Instr* instr, hir::Value* value); }; - } // namespace passes } // namespace compiler } // namespace alloy - #endif // ALLOY_COMPILER_PASSES_VALIDATION_PASS_H_ diff --git a/src/alloy/compiler/passes/value_reduction_pass.cc b/src/alloy/compiler/passes/value_reduction_pass.cc index 94453e294..94dbba0bb 100644 --- a/src/alloy/compiler/passes/value_reduction_pass.cc +++ b/src/alloy/compiler/passes/value_reduction_pass.cc @@ -19,21 +19,20 @@ #include #pragma warning(pop) -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::compiler; -using namespace alloy::compiler::passes; -using namespace alloy::frontend; +namespace alloy { +namespace compiler { +namespace passes { + +// TODO(benvanik): remove when enums redefined. using namespace alloy::hir; -using namespace alloy::runtime; +using alloy::hir::HIRBuilder; +using alloy::hir::OpcodeInfo; +using alloy::hir::Value; -ValueReductionPass::ValueReductionPass() : - CompilerPass() { -} +ValueReductionPass::ValueReductionPass() : CompilerPass() {} -ValueReductionPass::~ValueReductionPass() { -} +ValueReductionPass::~ValueReductionPass() {} void ValueReductionPass::ComputeLastUse(Value* value) { // TODO(benvanik): compute during construction? @@ -137,3 +136,7 @@ int ValueReductionPass::Run(HIRBuilder* builder) { return 0; } + +} // namespace passes +} // namespace compiler +} // namespace alloy diff --git a/src/alloy/compiler/passes/value_reduction_pass.h b/src/alloy/compiler/passes/value_reduction_pass.h index 3c6bc72af..95a9eaac0 100644 --- a/src/alloy/compiler/passes/value_reduction_pass.h +++ b/src/alloy/compiler/passes/value_reduction_pass.h @@ -12,27 +12,23 @@ #include - namespace alloy { namespace compiler { namespace passes { - class ValueReductionPass : public CompilerPass { -public: + public: ValueReductionPass(); virtual ~ValueReductionPass(); virtual int Run(hir::HIRBuilder* builder); -private: + private: void ComputeLastUse(hir::Value* value); }; - } // namespace passes } // namespace compiler } // namespace alloy - #endif // ALLOY_COMPILER_PASSES_VALUE_REDUCTION_PASS_H_ diff --git a/src/alloy/compiler/tracing.h b/src/alloy/compiler/tracing.h index 85d99992a..5763d6cb0 100644 --- a/src/alloy/compiler/tracing.h +++ b/src/alloy/compiler/tracing.h @@ -13,18 +13,16 @@ #include #include - namespace alloy { namespace compiler { const uint32_t ALLOY_COMPILER = alloy::tracing::EventType::ALLOY_COMPILER; - class EventType { -public: + public: enum { - ALLOY_COMPILER_INIT = ALLOY_COMPILER | (1), - ALLOY_COMPILER_DEINIT = ALLOY_COMPILER | (2), + ALLOY_COMPILER_INIT = ALLOY_COMPILER | (1), + ALLOY_COMPILER_DEINIT = ALLOY_COMPILER | (2), }; typedef struct Init_s { @@ -35,9 +33,7 @@ public: } Deinit; }; - } // namespace compiler } // namespace alloy - #endif // ALLOY_COMPILER_TRACING_H_ diff --git a/src/alloy/core.h b/src/alloy/core.h index cf8c95c44..df3724e7b 100644 --- a/src/alloy/core.h +++ b/src/alloy/core.h @@ -17,61 +17,76 @@ #include #include - namespace alloy { typedef struct XECACHEALIGN vec128_s { union { struct { - float x; - float y; - float z; - float w; + float x; + float y; + float z; + float w; }; struct { - uint32_t ix; - uint32_t iy; - uint32_t iz; - uint32_t iw; + uint32_t ix; + uint32_t iy; + uint32_t iz; + uint32_t iw; }; - float f4[4]; - uint32_t i4[4]; - uint16_t s8[8]; - uint8_t b16[16]; + float f4[4]; + uint32_t i4[4]; + uint16_t s8[8]; + uint8_t b16[16]; struct { - uint64_t low; - uint64_t high; + uint64_t low; + uint64_t high; }; }; - bool operator== (const vec128_s& b) const { + bool operator==(const vec128_s& b) const { return low == b.low && high == b.high; } } vec128_t; XEFORCEINLINE vec128_t vec128i(uint32_t x, uint32_t y, uint32_t z, uint32_t w) { vec128_t v; - v.i4[0] = x; v.i4[1] = y; v.i4[2] = z; v.i4[3] = w; + v.i4[0] = x; + v.i4[1] = y; + v.i4[2] = z; + v.i4[3] = w; return v; } XEFORCEINLINE vec128_t vec128f(float x, float y, float z, float w) { vec128_t v; - v.f4[0] = x; v.f4[1] = y; v.f4[2] = z; v.f4[3] = w; + v.f4[0] = x; + v.f4[1] = y; + v.f4[2] = z; + v.f4[3] = w; return v; } -XEFORCEINLINE vec128_t vec128b( - uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, - uint8_t y0, uint8_t y1, uint8_t y2, uint8_t y3, - uint8_t z0, uint8_t z1, uint8_t z2, uint8_t z3, - uint8_t w0, uint8_t w1, uint8_t w2, uint8_t w3) { +XEFORCEINLINE vec128_t vec128b(uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, + uint8_t y0, uint8_t y1, uint8_t y2, uint8_t y3, + uint8_t z0, uint8_t z1, uint8_t z2, uint8_t z3, + uint8_t w0, uint8_t w1, uint8_t w2, uint8_t w3) { vec128_t v; - v.b16[0] = x3; v.b16[1] = x2; v.b16[2] = x1; v.b16[3] = x0; - v.b16[4] = y3; v.b16[5] = y2; v.b16[6] = y1; v.b16[7] = y0; - v.b16[8] = z3; v.b16[9] = z2; v.b16[10] = z1; v.b16[11] = z0; - v.b16[12] = w3; v.b16[13] = w2; v.b16[14] = w1; v.b16[15] = w0; + v.b16[0] = x3; + v.b16[1] = x2; + v.b16[2] = x1; + v.b16[3] = x0; + v.b16[4] = y3; + v.b16[5] = y2; + v.b16[6] = y1; + v.b16[7] = y0; + v.b16[8] = z3; + v.b16[9] = z2; + v.b16[10] = z1; + v.b16[11] = z0; + v.b16[12] = w3; + v.b16[13] = w2; + v.b16[14] = w1; + v.b16[15] = w0; return v; } } // namespace alloy - #endif // ALLOY_CORE_H_ diff --git a/src/alloy/delegate.h b/src/alloy/delegate.h index 2cbfde0ac..1d0344f29 100644 --- a/src/alloy/delegate.h +++ b/src/alloy/delegate.h @@ -16,15 +16,13 @@ #include - namespace alloy { - // TODO(benvanik): go lockfree, and don't hold the lock while emitting. template class Delegate { -public: + public: typedef std::function listener_t; void AddListener(listener_t const& listener) { @@ -49,18 +47,16 @@ public: void operator()(T& e) { std::lock_guard guard(lock_); - for (auto &listener : listeners_) { + for (auto& listener : listeners_) { listener(e); } } -private: + private: std::mutex lock_; std::vector listeners_; }; - } // namespace alloy - #endif // ALLOY_DELEGATE_H_ diff --git a/src/alloy/frontend/context_info.cc b/src/alloy/frontend/context_info.cc index d93a2f2d6..126b77448 100644 --- a/src/alloy/frontend/context_info.cc +++ b/src/alloy/frontend/context_info.cc @@ -9,14 +9,13 @@ #include -using namespace alloy; -using namespace alloy::frontend; +namespace alloy { +namespace frontend { +ContextInfo::ContextInfo(size_t size, uintptr_t thread_state_offset) + : size_(size), thread_state_offset_(thread_state_offset) {} -ContextInfo::ContextInfo(size_t size, uintptr_t thread_state_offset) : - size_(size), - thread_state_offset_(thread_state_offset) { -} +ContextInfo::~ContextInfo() {} -ContextInfo::~ContextInfo() { -} +} // namespace frontend +} // namespace alloy diff --git a/src/alloy/frontend/context_info.h b/src/alloy/frontend/context_info.h index 542d6a40c..47cc8ae06 100644 --- a/src/alloy/frontend/context_info.h +++ b/src/alloy/frontend/context_info.h @@ -12,13 +12,11 @@ #include - namespace alloy { namespace frontend { - class ContextInfo { -public: + public: ContextInfo(size_t size, uintptr_t thread_state_offset); ~ContextInfo(); @@ -26,14 +24,12 @@ public: uintptr_t thread_state_offset() const { return thread_state_offset_; } -private: + private: size_t size_; uintptr_t thread_state_offset_; }; - } // namespace frontend } // namespace alloy - #endif // ALLOY_FRONTEND_CONTEXT_INFO_H_ diff --git a/src/alloy/frontend/frontend.cc b/src/alloy/frontend/frontend.cc index 68ad147ef..bd0651465 100644 --- a/src/alloy/frontend/frontend.cc +++ b/src/alloy/frontend/frontend.cc @@ -12,23 +12,17 @@ #include #include -using namespace alloy; -using namespace alloy::frontend; -using namespace alloy::runtime; +namespace alloy { +namespace frontend { +Frontend::Frontend(runtime::Runtime* runtime) + : runtime_(runtime), context_info_(0) {} -Frontend::Frontend(Runtime* runtime) : - runtime_(runtime), context_info_(0) { -} +Frontend::~Frontend() { delete context_info_; } -Frontend::~Frontend() { - delete context_info_; -} +Memory* Frontend::memory() const { return runtime_->memory(); } -Memory* Frontend::memory() const { - return runtime_->memory(); -} +int Frontend::Initialize() { return 0; } -int Frontend::Initialize() { - return 0; -} +} // namespace frontend +} // namespace alloy diff --git a/src/alloy/frontend/frontend.h b/src/alloy/frontend/frontend.h index c8a13b027..33662ea3e 100644 --- a/src/alloy/frontend/frontend.h +++ b/src/alloy/frontend/frontend.h @@ -16,17 +16,17 @@ #include #include - -namespace alloy { namespace runtime { - class Runtime; -} } +namespace alloy { +namespace runtime { +class Runtime; +} // namespace runtime +} // namespace alloy namespace alloy { namespace frontend { - class Frontend { -public: + public: Frontend(runtime::Runtime* runtime); virtual ~Frontend(); @@ -36,20 +36,17 @@ public: virtual int Initialize(); - virtual int DeclareFunction( - runtime::FunctionInfo* symbol_info) = 0; - virtual int DefineFunction( - runtime::FunctionInfo* symbol_info, uint32_t debug_info_flags, - runtime::Function** out_function) = 0; + virtual int DeclareFunction(runtime::FunctionInfo* symbol_info) = 0; + virtual int DefineFunction(runtime::FunctionInfo* symbol_info, + uint32_t debug_info_flags, + runtime::Function** out_function) = 0; -protected: + protected: runtime::Runtime* runtime_; ContextInfo* context_info_; }; - } // namespace frontend } // namespace alloy - #endif // ALLOY_FRONTEND_FRONTEND_H_ diff --git a/src/alloy/frontend/ppc/ppc_context.cc b/src/alloy/frontend/ppc/ppc_context.cc index 8b3344bf6..b6eeb336c 100644 --- a/src/alloy/frontend/ppc/ppc_context.cc +++ b/src/alloy/frontend/ppc/ppc_context.cc @@ -9,19 +9,11 @@ #include -using namespace alloy; -using namespace alloy::frontend; -using namespace alloy::frontend::ppc; - - -namespace { - -uint64_t ParseInt64(const char* value) { - return xestrtoulla(value, NULL, 0); -} - -} +namespace alloy { +namespace frontend { +namespace ppc { +uint64_t ParseInt64(const char* value) { return xestrtoulla(value, NULL, 0); } void PPCContext::SetRegFromString(const char* name, const char* value) { int n; @@ -32,9 +24,8 @@ void PPCContext::SetRegFromString(const char* name, const char* value) { } } -bool PPCContext::CompareRegWithString( - const char* name, const char* value, - char* out_value, size_t out_value_size) { +bool PPCContext::CompareRegWithString(const char* name, const char* value, + char* out_value, size_t out_value_size) { int n; if (sscanf(name, "r%d", &n) == 1) { uint64_t expected = ParseInt64(value); @@ -48,3 +39,7 @@ bool PPCContext::CompareRegWithString( return false; } } + +} // namespace ppc +} // namespace frontend +} // namespace alloy diff --git a/src/alloy/frontend/ppc/ppc_disasm.cc b/src/alloy/frontend/ppc/ppc_disasm.cc index aa823a972..98f7a7746 100644 --- a/src/alloy/frontend/ppc/ppc_disasm.cc +++ b/src/alloy/frontend/ppc/ppc_disasm.cc @@ -9,10 +9,6 @@ #include - -using namespace alloy::frontend::ppc; - - namespace alloy { namespace frontend { namespace ppc { @@ -26,221 +22,210 @@ void Disasm__(InstrData& i, StringBuffer* str) { } void Disasm_X_FRT_FRB(InstrData& i, StringBuffer* str) { - str->Append("%*s%s f%d, f%d", i.X.Rc ? -7 : -8, i.type->name, i.X.Rc ? "." : "", - i.X.RT, i.X.RB); + str->Append("%*s%s f%d, f%d", i.X.Rc ? -7 : -8, i.type->name, + i.X.Rc ? "." : "", i.X.RT, i.X.RB); } void Disasm_A_FRT_FRB(InstrData& i, StringBuffer* str) { - str->Append("%*s%s f%d, f%d", i.A.Rc ? -7 : -8, i.type->name, i.A.Rc ? "." : "", - i.A.FRT, i.A.FRB); + str->Append("%*s%s f%d, f%d", i.A.Rc ? -7 : -8, i.type->name, + i.A.Rc ? "." : "", i.A.FRT, i.A.FRB); } void Disasm_A_FRT_FRA_FRB(InstrData& i, StringBuffer* str) { - str->Append("%*s%s f%d, f%d, f%d", i.A.Rc ? -7 : -8, i.type->name, i.A.Rc ? "." : "", - i.A.FRT, i.A.FRA, i.A.FRB); + str->Append("%*s%s f%d, f%d, f%d", i.A.Rc ? -7 : -8, i.type->name, + i.A.Rc ? "." : "", i.A.FRT, i.A.FRA, i.A.FRB); } void Disasm_A_FRT_FRA_FRB_FRC(InstrData& i, StringBuffer* str) { - str->Append("%*s%s f%d, f%d, f%d, f%d", i.A.Rc ? -7 : -8, i.type->name, i.A.Rc ? "." : "", - i.A.FRT, i.A.FRA, i.A.FRB, i.A.FRC); + str->Append("%*s%s f%d, f%d, f%d, f%d", i.A.Rc ? -7 : -8, i.type->name, + i.A.Rc ? "." : "", i.A.FRT, i.A.FRA, i.A.FRB, i.A.FRC); } void Disasm_X_RT_RA_RB(InstrData& i, StringBuffer* str) { - str->Append("%-8s r%d, r%d, %d", i.type->name, - i.X.RT, i.X.RA, i.X.RB); + str->Append("%-8s r%d, r%d, %d", i.type->name, i.X.RT, i.X.RA, i.X.RB); } void Disasm_X_RT_RA0_RB(InstrData& i, StringBuffer* str) { if (i.X.RA) { - str->Append("%-8s r%d, r%d, %d", i.type->name, - i.X.RT, i.X.RA, i.X.RB); + str->Append("%-8s r%d, r%d, %d", i.type->name, i.X.RT, i.X.RA, i.X.RB); } else { - str->Append("%-8s r%d, 0, %d", i.type->name, - i.X.RT, i.X.RB); + str->Append("%-8s r%d, 0, %d", i.type->name, i.X.RT, i.X.RB); } } void Disasm_X_FRT_RA_RB(InstrData& i, StringBuffer* str) { - str->Append("%-8s f%d, r%d, %d", i.type->name, - i.X.RT, i.X.RA, i.X.RB); + str->Append("%-8s f%d, r%d, %d", i.type->name, i.X.RT, i.X.RA, i.X.RB); } void Disasm_X_FRT_RA0_RB(InstrData& i, StringBuffer* str) { if (i.X.RA) { - str->Append("%-8s f%d, r%d, %d", i.type->name, - i.X.RT, i.X.RA, i.X.RB); + str->Append("%-8s f%d, r%d, %d", i.type->name, i.X.RT, i.X.RA, i.X.RB); } else { - str->Append("%-8s f%d, 0, %d", i.type->name, - i.X.RT, i.X.RB); + str->Append("%-8s f%d, 0, %d", i.type->name, i.X.RT, i.X.RB); } } void Disasm_D_RT_RA_I(InstrData& i, StringBuffer* str) { - str->Append("%-8s r%d, r%d, %d", i.type->name, - i.D.RT, i.D.RA, (int32_t)(int16_t)XEEXTS16(i.D.DS)); + str->Append("%-8s r%d, r%d, %d", i.type->name, i.D.RT, i.D.RA, + (int32_t)(int16_t)XEEXTS16(i.D.DS)); } void Disasm_D_RT_RA0_I(InstrData& i, StringBuffer* str) { if (i.D.RA) { - str->Append("%-8s r%d, r%d, %d", i.type->name, - i.D.RT, i.D.RA, (int32_t)(int16_t)XEEXTS16(i.D.DS)); + str->Append("%-8s r%d, r%d, %d", i.type->name, i.D.RT, i.D.RA, + (int32_t)(int16_t)XEEXTS16(i.D.DS)); } else { - str->Append("%-8s r%d, 0, %d", i.type->name, - i.D.RT, (int32_t)(int16_t)XEEXTS16(i.D.DS)); + str->Append("%-8s r%d, 0, %d", i.type->name, i.D.RT, + (int32_t)(int16_t)XEEXTS16(i.D.DS)); } } void Disasm_D_FRT_RA_I(InstrData& i, StringBuffer* str) { - str->Append("%-8s f%d, r%d, %d", i.type->name, - i.D.RT, i.D.RA, (int32_t)(int16_t)XEEXTS16(i.D.DS)); + str->Append("%-8s f%d, r%d, %d", i.type->name, i.D.RT, i.D.RA, + (int32_t)(int16_t)XEEXTS16(i.D.DS)); } void Disasm_D_FRT_RA0_I(InstrData& i, StringBuffer* str) { if (i.D.RA) { - str->Append("%-8s f%d, r%d, %d", i.type->name, - i.D.RT, i.D.RA, (int32_t)(int16_t)XEEXTS16(i.D.DS)); + str->Append("%-8s f%d, r%d, %d", i.type->name, i.D.RT, i.D.RA, + (int32_t)(int16_t)XEEXTS16(i.D.DS)); } else { - str->Append("%-8s f%d, 0, %d", i.type->name, - i.D.RT, (int32_t)(int16_t)XEEXTS16(i.D.DS)); + str->Append("%-8s f%d, 0, %d", i.type->name, i.D.RT, + (int32_t)(int16_t)XEEXTS16(i.D.DS)); } } void Disasm_DS_RT_RA_I(InstrData& i, StringBuffer* str) { - str->Append("%-8s r%d, r%d, %d", i.type->name, - i.DS.RT, i.DS.RA, (int32_t)(int16_t)XEEXTS16(i.DS.DS << 2)); + str->Append("%-8s r%d, r%d, %d", i.type->name, i.DS.RT, i.DS.RA, + (int32_t)(int16_t)XEEXTS16(i.DS.DS << 2)); } void Disasm_DS_RT_RA0_I(InstrData& i, StringBuffer* str) { if (i.DS.RA) { - str->Append("%-8s r%d, r%d, %d", i.type->name, - i.DS.RT, i.DS.RA, (int32_t)(int16_t)XEEXTS16(i.DS.DS << 2)); + str->Append("%-8s r%d, r%d, %d", i.type->name, i.DS.RT, i.DS.RA, + (int32_t)(int16_t)XEEXTS16(i.DS.DS << 2)); } else { - str->Append("%-8s r%d, 0, %d", i.type->name, - i.DS.RT, (int32_t)(int16_t)XEEXTS16(i.DS.DS << 2)); + str->Append("%-8s r%d, 0, %d", i.type->name, i.DS.RT, + (int32_t)(int16_t)XEEXTS16(i.DS.DS << 2)); } } void Disasm_D_RA(InstrData& i, StringBuffer* str) { - str->Append("%-8s r%d", i.type->name, - i.D.RA); + str->Append("%-8s r%d", i.type->name, i.D.RA); } void Disasm_X_RA_RB(InstrData& i, StringBuffer* str) { - str->Append("%-8s r%d, r%d", i.type->name, - i.X.RA, i.X.RB); + str->Append("%-8s r%d, r%d", i.type->name, i.X.RA, i.X.RB); } void Disasm_XO_RT_RA_RB(InstrData& i, StringBuffer* str) { str->Append("%*s%s%s r%d, r%d, r%d", i.XO.Rc ? -7 : -8, i.type->name, - i.XO.OE ? "o" : "", i.XO.Rc ? "." : "", - i.XO.RT, i.XO.RA, i.XO.RB); + i.XO.OE ? "o" : "", i.XO.Rc ? "." : "", i.XO.RT, i.XO.RA, + i.XO.RB); } void Disasm_XO_RT_RA(InstrData& i, StringBuffer* str) { str->Append("%*s%s%s r%d, r%d", i.XO.Rc ? -7 : -8, i.type->name, - i.XO.OE ? "o" : "", i.XO.Rc ? "." : "", - i.XO.RT, i.XO.RA); + i.XO.OE ? "o" : "", i.XO.Rc ? "." : "", i.XO.RT, i.XO.RA); } void Disasm_X_RA_RT_RB(InstrData& i, StringBuffer* str) { - str->Append("%*s%s r%d, r%d, r%d", i.X.Rc ? -7 : -8, i.type->name, i.X.Rc ? "." : "", - i.X.RA, i.X.RT, i.X.RB); + str->Append("%*s%s r%d, r%d, r%d", i.X.Rc ? -7 : -8, i.type->name, + i.X.Rc ? "." : "", i.X.RA, i.X.RT, i.X.RB); } void Disasm_D_RA_RT_I(InstrData& i, StringBuffer* str) { - str->Append("%-7s. r%d, r%d, %.4Xh", i.type->name, - i.D.RA, i.D.RT, i.D.DS); + str->Append("%-7s. r%d, r%d, %.4Xh", i.type->name, i.D.RA, i.D.RT, i.D.DS); } void Disasm_X_RA_RT(InstrData& i, StringBuffer* str) { - str->Append("%*s%s r%d, r%d", i.X.Rc ? -7 : -8, i.type->name, i.X.Rc ? "." : "", - i.X.RA, i.X.RT); + str->Append("%*s%s r%d, r%d", i.X.Rc ? -7 : -8, i.type->name, + i.X.Rc ? "." : "", i.X.RA, i.X.RT); } -#define OP(x) ((((uint32_t)(x)) & 0x3f) << 26) -#define VX128(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x3d0)) -#define VX128_1(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x7f3)) -#define VX128_2(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x210)) -#define VX128_3(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x7f0)) -#define VX128_4(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x730)) -#define VX128_5(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x10)) -#define VX128_P(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x630)) +#define OP(x) ((((uint32_t)(x)) & 0x3f) << 26) +#define VX128(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x3d0)) +#define VX128_1(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x7f3)) +#define VX128_2(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x210)) +#define VX128_3(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x7f0)) +#define VX128_4(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x730)) +#define VX128_5(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x10)) +#define VX128_P(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x630)) #define VX128_VD128 (i.VX128.VD128l | (i.VX128.VD128h << 5)) -#define VX128_VA128 (i.VX128.VA128l | (i.VX128.VA128h << 5) | (i.VX128.VA128H << 6)) +#define VX128_VA128 \ + (i.VX128.VA128l | (i.VX128.VA128h << 5) | (i.VX128.VA128H << 6)) #define VX128_VB128 (i.VX128.VB128l | (i.VX128.VB128h << 5)) #define VX128_1_VD128 (i.VX128_1.VD128l | (i.VX128_1.VD128h << 5)) #define VX128_2_VD128 (i.VX128_2.VD128l | (i.VX128_2.VD128h << 5)) -#define VX128_2_VA128 (i.VX128_2.VA128l | (i.VX128_2.VA128h << 5) | (i.VX128_2.VA128H << 6)) +#define VX128_2_VA128 \ + (i.VX128_2.VA128l | (i.VX128_2.VA128h << 5) | (i.VX128_2.VA128H << 6)) #define VX128_2_VB128 (i.VX128_2.VB128l | (i.VX128_2.VD128h << 5)) -#define VX128_2_VC (i.VX128_2.VC) +#define VX128_2_VC (i.VX128_2.VC) #define VX128_3_VD128 (i.VX128_3.VD128l | (i.VX128_3.VD128h << 5)) #define VX128_3_VB128 (i.VX128_3.VB128l | (i.VX128_3.VB128h << 5)) -#define VX128_3_IMM (i.VX128_3.IMM) +#define VX128_3_IMM (i.VX128_3.IMM) #define VX128_4_VD128 (i.VX128_4.VD128l | (i.VX128_4.VD128h << 5)) #define VX128_4_VB128 (i.VX128_4.VB128l | (i.VX128_4.VB128h << 5)) #define VX128_5_VD128 (i.VX128_5.VD128l | (i.VX128_5.VD128h << 5)) -#define VX128_5_VA128 (i.VX128_5.VA128l | (i.VX128_5.VA128h << 5)) | (i.VX128_5.VA128H << 6) +#define VX128_5_VA128 \ + (i.VX128_5.VA128l | (i.VX128_5.VA128h << 5)) | (i.VX128_5.VA128H << 6) #define VX128_5_VB128 (i.VX128_5.VB128l | (i.VX128_5.VB128h << 5)) -#define VX128_5_SH (i.VX128_5.SH) +#define VX128_5_SH (i.VX128_5.SH) #define VX128_R_VD128 (i.VX128_R.VD128l | (i.VX128_R.VD128h << 5)) -#define VX128_R_VA128 (i.VX128_R.VA128l | (i.VX128_R.VA128h << 5) | (i.VX128_R.VA128H << 6)) +#define VX128_R_VA128 \ + (i.VX128_R.VA128l | (i.VX128_R.VA128h << 5) | (i.VX128_R.VA128H << 6)) #define VX128_R_VB128 (i.VX128_R.VB128l | (i.VX128_R.VB128h << 5)) - + void Disasm_X_VX_RA0_RB(InstrData& i, StringBuffer* str) { if (i.X.RA) { - str->Append("%-8s v%d, r%d, r%d", i.type->name, - i.X.RT, i.X.RA, i.X.RB); + str->Append("%-8s v%d, r%d, r%d", i.type->name, i.X.RT, i.X.RA, i.X.RB); } else { - str->Append("%-8s v%d, 0, r%d", i.type->name, - i.X.RT, i.X.RB); + str->Append("%-8s v%d, 0, r%d", i.type->name, i.X.RT, i.X.RB); } } void Disasm_VX1281_VD_RA0_RB(InstrData& i, StringBuffer* str) { const uint32_t vd = VX128_1_VD128; if (i.VX128_1.RA) { - str->Append("%-8s v%d, r%d, r%d", i.type->name, - vd, i.VX128_1.RA, i.VX128_1.RB); + str->Append("%-8s v%d, r%d, r%d", i.type->name, vd, i.VX128_1.RA, + i.VX128_1.RB); } else { - str->Append("%-8s v%d, 0, r%d", i.type->name, - vd, i.VX128_1.RB); + str->Append("%-8s v%d, 0, r%d", i.type->name, vd, i.VX128_1.RB); } } void Disasm_VX1283_VD_VB(InstrData& i, StringBuffer* str) { const uint32_t vd = VX128_3_VD128; const uint32_t vb = VX128_3_VB128; - str->Append("%-8s v%d, v%d", i.type->name, - vd, vb); + str->Append("%-8s v%d, v%d", i.type->name, vd, vb); } void Disasm_VX1283_VD_VB_I(InstrData& i, StringBuffer* str) { const uint32_t vd = VX128_VD128; const uint32_t va = VX128_VA128; const uint32_t uimm = i.VX128_3.IMM; - str->Append("%-8s v%d, v%d, %.2Xh", i.type->name, - vd, va, uimm); + str->Append("%-8s v%d, v%d, %.2Xh", i.type->name, vd, va, uimm); } void Disasm_VX_VD_VA_VB(InstrData& i, StringBuffer* str) { - str->Append("%-8s v%d, v%d, v%d", i.type->name, - i.VX.VD, i.VX.VA, i.VX.VB); + str->Append("%-8s v%d, v%d, v%d", i.type->name, i.VX.VD, i.VX.VA, i.VX.VB); } void Disasm_VX128_VD_VA_VB(InstrData& i, StringBuffer* str) { const uint32_t vd = VX128_VD128; const uint32_t va = VX128_VA128; const uint32_t vb = VX128_VB128; - str->Append("%-8s v%d, v%d, v%d", i.type->name, - vd, va, vb); + str->Append("%-8s v%d, v%d, v%d", i.type->name, vd, va, vb); } void Disasm_VX128_VD_VA_VD_VB(InstrData& i, StringBuffer* str) { const uint32_t vd = VX128_VD128; const uint32_t va = VX128_VA128; const uint32_t vb = VX128_VB128; - str->Append("%-8s v%d, v%d, v%d, v%d", i.type->name, - vd, va, vd, vb); + str->Append("%-8s v%d, v%d, v%d, v%d", i.type->name, vd, va, vd, vb); } void Disasm_VX1282_VD_VA_VB_VC(InstrData& i, StringBuffer* str) { const uint32_t vd = VX128_2_VD128; const uint32_t va = VX128_2_VA128; const uint32_t vb = VX128_2_VB128; const uint32_t vc = i.VX128_2.VC; - str->Append("%-8s v%d, v%d, v%d, v%d", i.type->name, - vd, va, vb, vc); + str->Append("%-8s v%d, v%d, v%d, v%d", i.type->name, vd, va, vb, vc); } void Disasm_VXA_VD_VA_VB_VC(InstrData& i, StringBuffer* str) { - str->Append("%-8s v%d, v%d, v%d, v%d", i.type->name, - i.VXA.VD, i.VXA.VA, i.VXA.VB, i.VXA.VC); + str->Append("%-8s v%d, v%d, v%d, v%d", i.type->name, i.VXA.VD, i.VXA.VA, + i.VXA.VB, i.VXA.VC); } void Disasm_sync(InstrData& i, StringBuffer* str) { const char* name; int L = i.X.RT & 3; switch (L) { - case 0: name = "hwsync"; break; - case 1: name = "lwsync"; break; - default: - case 2: - case 3: - name = "sync"; - break; + case 0: + name = "hwsync"; + break; + case 1: + name = "lwsync"; + break; + default: + case 2: + case 3: + name = "sync"; + break; } str->Append("%-8s %.2X", name, L); } @@ -248,10 +233,18 @@ void Disasm_sync(InstrData& i, StringBuffer* str) { void Disasm_dcbf(InstrData& i, StringBuffer* str) { const char* name; switch (i.X.RT & 3) { - case 0: name = "dcbf"; break; - case 1: name = "dcbfl"; break; - case 2: name = "dcbf.RESERVED"; break; - case 3: name = "dcbflp"; break; + case 0: + name = "dcbf"; + break; + case 1: + name = "dcbfl"; + break; + case 2: + name = "dcbf.RESERVED"; + break; + case 3: + name = "dcbflp"; + break; } str->Append("%-8s r%d, r%d", name, i.X.RA, i.X.RB); } @@ -266,13 +259,12 @@ void Disasm_dcbz(InstrData& i, StringBuffer* str) { } void Disasm_fcmp(InstrData& i, StringBuffer* str) { - str->Append("%-8s cr%d, f%d, f%d", i.type->name, - i.X.RT >> 2, i.X.RA, i.X.RB); + str->Append("%-8s cr%d, f%d, f%d", i.type->name, i.X.RT >> 2, i.X.RA, i.X.RB); } void Disasm_mffsx(InstrData& i, StringBuffer* str) { - str->Append("%*s%s f%d, FPSCR", i.X.Rc ? -7 : -8, i.type->name, i.X.Rc ? "." : "", - i.X.RT); + str->Append("%*s%s f%d, FPSCR", i.X.Rc ? -7 : -8, i.type->name, + i.X.Rc ? "." : "", i.X.RT); } void Disasm_bx(InstrData& i, StringBuffer* str) { @@ -283,8 +275,7 @@ void Disasm_bx(InstrData& i, StringBuffer* str) { } else { nia = (uint32_t)(i.address + XEEXTS26(i.I.LI << 2)); } - str->Append("%-8s %.8X", name, - nia); + str->Append("%-8s %.8X", name, nia); // TODO(benvanik): resolve target name? } void Disasm_bcx(InstrData& i, StringBuffer* str) { @@ -295,7 +286,9 @@ void Disasm_bcx(InstrData& i, StringBuffer* str) { } else { s1 = ""; } - char s2[8] = { 'c', 'r', 0, }; + char s2[8] = { + 'c', 'r', 0, + }; if (!XESELECTBITS(i.B.BO, 4, 4)) { char* s2a = _itoa(i.B.BI >> 2, s2 + 2, 10); s2a += xestrlena(s2a); @@ -310,14 +303,15 @@ void Disasm_bcx(InstrData& i, StringBuffer* str) { } else { nia = (uint32_t)(i.address + XEEXTS16(i.B.BD << 2)); } - str->Append("%-8s %s%s%s%.8X", i.type->name, - s0, s1, s2, nia); + str->Append("%-8s %s%s%s%.8X", i.type->name, s0, s1, s2, nia); // TODO(benvanik): resolve target name? } void Disasm_bcctrx(InstrData& i, StringBuffer* str) { // TODO(benvanik): mnemonics const char* s0 = i.XL.LK ? "lr, " : ""; - char s2[8] = { 'c', 'r', 0, }; + char s2[8] = { + 'c', 'r', 0, + }; if (!XESELECTBITS(i.XL.BO, 4, 4)) { char* s2a = _itoa(i.XL.BI >> 2, s2 + 2, 10); s2a += xestrlena(s2a); @@ -326,8 +320,7 @@ void Disasm_bcctrx(InstrData& i, StringBuffer* str) { } else { s2[0] = 0; } - str->Append("%-8s %s%sctr", i.type->name, - s0, s2); + str->Append("%-8s %s%sctr", i.type->name, s0, s2); // TODO(benvanik): resolve target name? } void Disasm_bclrx(InstrData& i, StringBuffer* str) { @@ -341,7 +334,9 @@ void Disasm_bclrx(InstrData& i, StringBuffer* str) { } else { s1 = ""; } - char s2[8] = { 'c', 'r', 0, }; + char s2[8] = { + 'c', 'r', 0, + }; if (!XESELECTBITS(i.XL.BO, 4, 4)) { char* s2a = _itoa(i.XL.BI >> 2, s2 + 2, 10); s2a += xestrlena(s2a); @@ -350,179 +345,166 @@ void Disasm_bclrx(InstrData& i, StringBuffer* str) { } else { s2[0] = 0; } - str->Append("%-8s %s%s", name, - s1, s2); + str->Append("%-8s %s%s", name, s1, s2); } void Disasm_mfcr(InstrData& i, StringBuffer* str) { - str->Append("%-8s r%d, cr", i.type->name, - i.X.RT); + str->Append("%-8s r%d, cr", i.type->name, i.X.RT); } const char* Disasm_spr_name(uint32_t n) { const char* reg = "???"; switch (n) { - case 1: - reg = "xer"; - break; - case 8: - reg = "lr"; - break; - case 9: - reg = "ctr"; - break; + case 1: + reg = "xer"; + break; + case 8: + reg = "lr"; + break; + case 9: + reg = "ctr"; + break; } return reg; } void Disasm_mfspr(InstrData& i, StringBuffer* str) { const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F); const char* reg = Disasm_spr_name(n); - str->Append("%-8s r%d, %s", i.type->name, - i.XFX.RT, reg); + str->Append("%-8s r%d, %s", i.type->name, i.XFX.RT, reg); } void Disasm_mtspr(InstrData& i, StringBuffer* str) { const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F); const char* reg = Disasm_spr_name(n); - str->Append("%-8s %s, r%d", i.type->name, - reg, i.XFX.RT); + str->Append("%-8s %s, r%d", i.type->name, reg, i.XFX.RT); } void Disasm_mftb(InstrData& i, StringBuffer* str) { - str->Append("%-8s r%d, tb", i.type->name, - i.XFX.RT); + str->Append("%-8s r%d, tb", i.type->name, i.XFX.RT); } void Disasm_mfmsr(InstrData& i, StringBuffer* str) { - str->Append("%-8s r%d", i.type->name, - i.X.RT); + str->Append("%-8s r%d", i.type->name, i.X.RT); } void Disasm_mtmsr(InstrData& i, StringBuffer* str) { - str->Append("%-8s r%d, %d", i.type->name, - i.X.RT, (i.X.RA & 16) ? 1 : 0); + str->Append("%-8s r%d, %d", i.type->name, i.X.RT, (i.X.RA & 16) ? 1 : 0); } void Disasm_cmp(InstrData& i, StringBuffer* str) { - str->Append("%-8s cr%d, %.2X, r%d, r%d", i.type->name, - i.X.RT >> 2, i.X.RT & 1, i.X.RA, i.X.RB); + str->Append("%-8s cr%d, %.2X, r%d, r%d", i.type->name, i.X.RT >> 2, + i.X.RT & 1, i.X.RA, i.X.RB); } void Disasm_cmpi(InstrData& i, StringBuffer* str) { - str->Append("%-8s cr%d, %.2X, r%d, %d", i.type->name, - i.D.RT >> 2, i.D.RT & 1, i.D.RA, XEEXTS16(i.D.DS)); + str->Append("%-8s cr%d, %.2X, r%d, %d", i.type->name, i.D.RT >> 2, i.D.RT & 1, + i.D.RA, XEEXTS16(i.D.DS)); } void Disasm_cmpli(InstrData& i, StringBuffer* str) { - str->Append("%-8s cr%d, %.2X, r%d, %.2X", i.type->name, - i.D.RT >> 2, i.D.RT & 1, i.D.RA, XEEXTS16(i.D.DS)); + str->Append("%-8s cr%d, %.2X, r%d, %.2X", i.type->name, i.D.RT >> 2, + i.D.RT & 1, i.D.RA, XEEXTS16(i.D.DS)); } void Disasm_rld(InstrData& i, StringBuffer* str) { if (i.MD.idx == 0) { // XEDISASMR(rldiclx, 0x78000000, MD ) - str->Append("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, "rldicl", i.MD.Rc ? "." : "", - i.MD.RA, i.MD.RT, (i.MD.SH5 << 5) | i.MD.SH, (i.MD.MB5 << 5) | i.MD.MB); + str->Append("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, "rldicl", + i.MD.Rc ? "." : "", i.MD.RA, i.MD.RT, (i.MD.SH5 << 5) | i.MD.SH, + (i.MD.MB5 << 5) | i.MD.MB); } else if (i.MD.idx == 1) { // XEDISASMR(rldicrx, 0x78000004, MD ) - str->Append("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, "rldicr", i.MD.Rc ? "." : "", - i.MD.RA, i.MD.RT, (i.MD.SH5 << 5) | i.MD.SH, (i.MD.MB5 << 5) | i.MD.MB); + str->Append("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, "rldicr", + i.MD.Rc ? "." : "", i.MD.RA, i.MD.RT, (i.MD.SH5 << 5) | i.MD.SH, + (i.MD.MB5 << 5) | i.MD.MB); } else if (i.MD.idx == 2) { // XEDISASMR(rldicx, 0x78000008, MD ) uint32_t sh = (i.MD.SH5 << 5) | i.MD.SH; uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB; const char* name = (mb == 0x3E) ? "sldi" : "rldic"; - str->Append("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, name, i.MD.Rc ? "." : "", - i.MD.RA, i.MD.RT, sh, mb); + str->Append("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, name, + i.MD.Rc ? "." : "", i.MD.RA, i.MD.RT, sh, mb); } else if (i.MDS.idx == 8) { // XEDISASMR(rldclx, 0x78000010, MDS) - str->Append("%*s%s r%d, r%d, %d, %d", i.MDS.Rc ? -7 : -8, "rldcl", i.MDS.Rc ? "." : "", - i.MDS.RA, i.MDS.RT, i.MDS.RB, (i.MDS.MB5 << 5) | i.MDS.MB); + str->Append("%*s%s r%d, r%d, %d, %d", i.MDS.Rc ? -7 : -8, "rldcl", + i.MDS.Rc ? "." : "", i.MDS.RA, i.MDS.RT, i.MDS.RB, + (i.MDS.MB5 << 5) | i.MDS.MB); } else if (i.MDS.idx == 9) { // XEDISASMR(rldcrx, 0x78000012, MDS) - str->Append("%*s%s r%d, r%d, %d, %d", i.MDS.Rc ? -7 : -8, "rldcr", i.MDS.Rc ? "." : "", - i.MDS.RA, i.MDS.RT, i.MDS.RB, (i.MDS.MB5 << 5) | i.MDS.MB); + str->Append("%*s%s r%d, r%d, %d, %d", i.MDS.Rc ? -7 : -8, "rldcr", + i.MDS.Rc ? "." : "", i.MDS.RA, i.MDS.RT, i.MDS.RB, + (i.MDS.MB5 << 5) | i.MDS.MB); } else if (i.MD.idx == 3) { // XEDISASMR(rldimix, 0x7800000C, MD ) - str->Append("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, "rldimi", i.MD.Rc ? "." : "", - i.MD.RA, i.MD.RT, (i.MD.SH5 << 5) | i.MD.SH, (i.MD.MB5 << 5) | i.MD.MB); + str->Append("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, "rldimi", + i.MD.Rc ? "." : "", i.MD.RA, i.MD.RT, (i.MD.SH5 << 5) | i.MD.SH, + (i.MD.MB5 << 5) | i.MD.MB); } else { XEASSERTALWAYS(); } } void Disasm_rlwim(InstrData& i, StringBuffer* str) { - str->Append("%*s%s r%d, r%d, %d, %d, %d", i.M.Rc ? -7 : -8, i.type->name, i.M.Rc ? "." : "", - i.M.RA, i.M.RT, i.M.SH, i.M.MB, i.M.ME); + str->Append("%*s%s r%d, r%d, %d, %d, %d", i.M.Rc ? -7 : -8, i.type->name, + i.M.Rc ? "." : "", i.M.RA, i.M.RT, i.M.SH, i.M.MB, i.M.ME); } void Disasm_rlwnmx(InstrData& i, StringBuffer* str) { - str->Append("%*s%s r%d, r%d, r%d, %d, %d", i.M.Rc ? -7 : -8, i.type->name, i.M.Rc ? "." : "", - i.M.RA, i.M.RT, i.M.SH, i.M.MB, i.M.ME); + str->Append("%*s%s r%d, r%d, r%d, %d, %d", i.M.Rc ? -7 : -8, i.type->name, + i.M.Rc ? "." : "", i.M.RA, i.M.RT, i.M.SH, i.M.MB, i.M.ME); } void Disasm_srawix(InstrData& i, StringBuffer* str) { - str->Append("%*s%s r%d, r%d, %d", i.X.Rc ? -7 : -8, i.type->name, i.X.Rc ? "." : "", - i.X.RA, i.X.RT, i.X.RB); + str->Append("%*s%s r%d, r%d, %d", i.X.Rc ? -7 : -8, i.type->name, + i.X.Rc ? "." : "", i.X.RA, i.X.RT, i.X.RB); } void Disasm_sradix(InstrData& i, StringBuffer* str) { - str->Append("%*s%s r%d, r%d, %d", i.XS.Rc ? -7 : -8, i.type->name, i.XS.Rc ? "." : "", - i.XS.RA, i.XS.RT, (i.XS.SH5 << 5) | i.XS.SH); + str->Append("%*s%s r%d, r%d, %d", i.XS.Rc ? -7 : -8, i.type->name, + i.XS.Rc ? "." : "", i.XS.RA, i.XS.RT, (i.XS.SH5 << 5) | i.XS.SH); } void Disasm_vpermwi128(InstrData& i, StringBuffer* str) { const uint32_t vd = i.VX128_P.VD128l | (i.VX128_P.VD128h << 5); const uint32_t vb = i.VX128_P.VB128l | (i.VX128_P.VB128h << 5); - str->Append("%-8s v%d, v%d, %.2X", i.type->name, - vd, vb, i.VX128_P.PERMl | (i.VX128_P.PERMh << 5)); + str->Append("%-8s v%d, v%d, %.2X", i.type->name, vd, vb, + i.VX128_P.PERMl | (i.VX128_P.PERMh << 5)); } void Disasm_vrfin128(InstrData& i, StringBuffer* str) { const uint32_t vd = VX128_3_VD128; const uint32_t vb = VX128_3_VB128; - str->Append("%-8s v%d, v%d", i.type->name, - vd, vb); + str->Append("%-8s v%d, v%d", i.type->name, vd, vb); } void Disasm_vrlimi128(InstrData& i, StringBuffer* str) { const uint32_t vd = VX128_4_VD128; const uint32_t vb = VX128_4_VB128; - str->Append("%-8s v%d, v%d, %.2X, %.2X", i.type->name, - vd, vb, i.VX128_4.IMM, i.VX128_4.z); + str->Append("%-8s v%d, v%d, %.2X, %.2X", i.type->name, vd, vb, i.VX128_4.IMM, + i.VX128_4.z); } void Disasm_vsldoi128(InstrData& i, StringBuffer* str) { const uint32_t vd = VX128_5_VD128; const uint32_t va = VX128_5_VA128; const uint32_t vb = VX128_5_VB128; const uint32_t sh = i.VX128_5.SH; - str->Append("%-8s v%d, v%d, v%d, %.2X", i.type->name, - vd, va, vb, sh); + str->Append("%-8s v%d, v%d, v%d, %.2X", i.type->name, vd, va, vb, sh); } void Disasm_vspltb(InstrData& i, StringBuffer* str) { - str->Append("%-8s v%d, v%d, %.2X", i.type->name, - i.VX.VD, i.VX.VB, i.VX.VA & 0xF); + str->Append("%-8s v%d, v%d, %.2X", i.type->name, i.VX.VD, i.VX.VB, + i.VX.VA & 0xF); } void Disasm_vsplth(InstrData& i, StringBuffer* str) { - str->Append("%-8s v%d, v%d, %.2X", i.type->name, - i.VX.VD, i.VX.VB, i.VX.VA & 0x7); + str->Append("%-8s v%d, v%d, %.2X", i.type->name, i.VX.VD, i.VX.VB, + i.VX.VA & 0x7); } void Disasm_vspltw(InstrData& i, StringBuffer* str) { - str->Append("%-8s v%d, v%d, %.2X", i.type->name, - i.VX.VD, i.VX.VB, i.VX.VA); + str->Append("%-8s v%d, v%d, %.2X", i.type->name, i.VX.VD, i.VX.VB, i.VX.VA); } void Disasm_vspltisb(InstrData& i, StringBuffer* str) { // 5bit -> 8bit sign extend int8_t simm = (i.VX.VA & 0x10) ? (i.VX.VA | 0xF0) : i.VX.VA; - str->Append("%-8s v%d, %.2X", i.type->name, - i.VX.VD, simm); + str->Append("%-8s v%d, %.2X", i.type->name, i.VX.VD, simm); } void Disasm_vspltish(InstrData& i, StringBuffer* str) { // 5bit -> 16bit sign extend int16_t simm = (i.VX.VA & 0x10) ? (i.VX.VA | 0xFFF0) : i.VX.VA; - str->Append("%-8s v%d, %.4X", i.type->name, - i.VX.VD, simm); + str->Append("%-8s v%d, %.4X", i.type->name, i.VX.VD, simm); } void Disasm_vspltisw(InstrData& i, StringBuffer* str) { // 5bit -> 32bit sign extend int32_t simm = (i.VX.VA & 0x10) ? (i.VX.VA | 0xFFFFFFF0) : i.VX.VA; - str->Append("%-8s v%d, %.8X", i.type->name, - i.VX.VD, simm); + str->Append("%-8s v%d, %.8X", i.type->name, i.VX.VD, simm); } -} // namespace ppc -} // namespace frontend -} // namespace alloy - - -int alloy::frontend::ppc::DisasmPPC(InstrData& i, StringBuffer* str) { +int DisasmPPC(InstrData& i, StringBuffer* str) { if (!i.type) { str->Append("???"); } else { @@ -531,3 +513,6 @@ int alloy::frontend::ppc::DisasmPPC(InstrData& i, StringBuffer* str) { return 0; } +} // namespace ppc +} // namespace frontend +} // namespace alloy diff --git a/src/alloy/frontend/ppc/ppc_disasm.h b/src/alloy/frontend/ppc/ppc_disasm.h index e5254661a..fe6c26be6 100644 --- a/src/alloy/frontend/ppc/ppc_disasm.h +++ b/src/alloy/frontend/ppc/ppc_disasm.h @@ -12,18 +12,14 @@ #include - namespace alloy { namespace frontend { namespace ppc { - int DisasmPPC(InstrData& i, StringBuffer* str); - } // namespace ppc } // namespace frontend } // namespace alloy - #endif // ALLOY_FRONTEND_PPC_PPC_DISASM_H_ diff --git a/src/alloy/frontend/ppc/ppc_emit-private.h b/src/alloy/frontend/ppc/ppc_emit-private.h index 2c147f45e..5d717e69b 100644 --- a/src/alloy/frontend/ppc/ppc_emit-private.h +++ b/src/alloy/frontend/ppc/ppc_emit-private.h @@ -13,25 +13,21 @@ #include #include - namespace alloy { namespace frontend { namespace ppc { - #define XEEMITTER(name, opcode, format) int InstrEmit_##name #define XEREGISTERINSTR(name, opcode) \ - RegisterInstrEmit(opcode, (InstrEmitFn)InstrEmit_##name); + RegisterInstrEmit(opcode, (InstrEmitFn)InstrEmit_##name); #define XEINSTRNOTIMPLEMENTED() //#define XEINSTRNOTIMPLEMENTED XEASSERTALWAYS //#define XEINSTRNOTIMPLEMENTED() __debugbreak() - } // namespace ppc } // namespace frontend } // namespace alloy - #endif // ALLOY_FRONTEND_PPC_PPC_EMIT_PRIVATE_H_ diff --git a/src/alloy/frontend/ppc/ppc_emit.h b/src/alloy/frontend/ppc/ppc_emit.h index 9afea2f19..4edc4e021 100644 --- a/src/alloy/frontend/ppc/ppc_emit.h +++ b/src/alloy/frontend/ppc/ppc_emit.h @@ -12,22 +12,18 @@ #include - namespace alloy { namespace frontend { namespace ppc { - void RegisterEmitCategoryAltivec(); void RegisterEmitCategoryALU(); void RegisterEmitCategoryControl(); void RegisterEmitCategoryFPU(); void RegisterEmitCategoryMemory(); - } // namespace ppc } // namespace frontend } // namespace alloy - #endif // ALLOY_FRONTEND_PPC_PPC_EMIT_H_ diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index 1a985d1ae..9b0a845c5 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -12,187 +12,147 @@ #include #include - -using namespace alloy::frontend::ppc; -using namespace alloy::hir; -using namespace alloy::runtime; - - namespace alloy { namespace frontend { namespace ppc { +// TODO(benvanik): remove when enums redefined. +using namespace alloy::hir; + +using alloy::hir::Value; Value* CalculateEA_0(PPCHIRBuilder& f, uint32_t ra, uint32_t rb); - #define SHUFPS_SWAP_DWORDS 0x1B - // Most of this file comes from: // http://biallas.net/doc/vmx128/vmx128.txt // https://github.com/kakaroto/ps3ida/blob/master/plugins/PPCAltivec/src/main.cpp - -#define OP(x) ((((uint32_t)(x)) & 0x3f) << 26) -#define VX128(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x3d0)) -#define VX128_1(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x7f3)) -#define VX128_2(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x210)) -#define VX128_3(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x7f0)) -#define VX128_4(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x730)) -#define VX128_5(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x10)) -#define VX128_P(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x630)) +#define OP(x) ((((uint32_t)(x)) & 0x3f) << 26) +#define VX128(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x3d0)) +#define VX128_1(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x7f3)) +#define VX128_2(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x210)) +#define VX128_3(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x7f0)) +#define VX128_4(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x730)) +#define VX128_5(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x10)) +#define VX128_P(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x630)) #define VX128_VD128 (i.VX128.VD128l | (i.VX128.VD128h << 5)) -#define VX128_VA128 (i.VX128.VA128l | (i.VX128.VA128h << 5) | (i.VX128.VA128H << 6)) +#define VX128_VA128 \ + (i.VX128.VA128l | (i.VX128.VA128h << 5) | (i.VX128.VA128H << 6)) #define VX128_VB128 (i.VX128.VB128l | (i.VX128.VB128h << 5)) #define VX128_1_VD128 (i.VX128_1.VD128l | (i.VX128_1.VD128h << 5)) #define VX128_2_VD128 (i.VX128_2.VD128l | (i.VX128_2.VD128h << 5)) -#define VX128_2_VA128 (i.VX128_2.VA128l | (i.VX128_2.VA128h << 5) | (i.VX128_2.VA128H << 6)) +#define VX128_2_VA128 \ + (i.VX128_2.VA128l | (i.VX128_2.VA128h << 5) | (i.VX128_2.VA128H << 6)) #define VX128_2_VB128 (i.VX128_2.VB128l | (i.VX128_2.VD128h << 5)) -#define VX128_2_VC (i.VX128_2.VC) +#define VX128_2_VC (i.VX128_2.VC) #define VX128_3_VD128 (i.VX128_3.VD128l | (i.VX128_3.VD128h << 5)) #define VX128_3_VB128 (i.VX128_3.VB128l | (i.VX128_3.VB128h << 5)) -#define VX128_3_IMM (i.VX128_3.IMM) +#define VX128_3_IMM (i.VX128_3.IMM) #define VX128_5_VD128 (i.VX128_5.VD128l | (i.VX128_5.VD128h << 5)) -#define VX128_5_VA128 (i.VX128_5.VA128l | (i.VX128_5.VA128h << 5)) | (i.VX128_5.VA128H << 6) +#define VX128_5_VA128 \ + (i.VX128_5.VA128l | (i.VX128_5.VA128h << 5)) | (i.VX128_5.VA128H << 6) #define VX128_5_VB128 (i.VX128_5.VB128l | (i.VX128_5.VB128h << 5)) -#define VX128_5_SH (i.VX128_5.SH) +#define VX128_5_SH (i.VX128_5.SH) #define VX128_R_VD128 (i.VX128_R.VD128l | (i.VX128_R.VD128h << 5)) -#define VX128_R_VA128 (i.VX128_R.VA128l | (i.VX128_R.VA128h << 5) | (i.VX128_R.VA128H << 6)) +#define VX128_R_VA128 \ + (i.VX128_R.VA128l | (i.VX128_R.VA128h << 5) | (i.VX128_R.VA128H << 6)) #define VX128_R_VB128 (i.VX128_R.VB128l | (i.VX128_R.VB128h << 5)) - -// namespace { - -// // Shuffle masks to shift the values over and insert zeros from the low bits. -// static __m128i __shift_table_left[16] = { -// _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0), // unused -// _mm_set_epi8(14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 15), -// _mm_set_epi8(13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 15, 15), -// _mm_set_epi8(12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 15, 15, 15), -// _mm_set_epi8(11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 15, 15, 15, 15), -// _mm_set_epi8(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 15, 15, 15, 15, 15), -// _mm_set_epi8( 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 15, 15, 15, 15, 15, 15), -// _mm_set_epi8( 8, 7, 6, 5, 4, 3, 2, 1, 0, 15, 15, 15, 15, 15, 15, 15), -// _mm_set_epi8( 7, 6, 5, 4, 3, 2, 1, 0, 15, 15, 15, 15, 15, 15, 15, 15), -// _mm_set_epi8( 6, 5, 4, 3, 2, 1, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15), -// _mm_set_epi8( 5, 4, 3, 2, 1, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15), -// _mm_set_epi8( 4, 3, 2, 1, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15), -// _mm_set_epi8( 3, 2, 1, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15), -// _mm_set_epi8( 2, 1, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15), -// _mm_set_epi8( 1, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15), -// _mm_set_epi8( 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15), -// }; -// static __m128i __shift_table_right[16] = { -// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), // unused -// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15), -// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 14), -// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 14, 13), -// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 14, 13, 12), -// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 14, 13, 12, 11), -// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 14, 13, 12, 11, 10), -// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 14, 13, 12, 11, 10, 9), -// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 15, 14, 13, 12, 11, 10, 9, 8), -// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7), -// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6), -// _mm_set_epi8( 0, 0, 0, 0, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5), -// _mm_set_epi8( 0, 0, 0, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4), -// _mm_set_epi8( 0, 0, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3), -// _mm_set_epi8( 0, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2), -// _mm_set_epi8( 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1), -// }; - -// } - unsigned int xerotl(unsigned int value, unsigned int shift) { XEASSERT(shift < 32); return shift == 0 ? value : ((value << shift) | (value >> (32 - shift))); } -XEEMITTER(dst, 0x7C0002AC, XDSS)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(dst, 0x7C0002AC, XDSS)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(dstst, 0x7C0002EC, XDSS)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(dstst, 0x7C0002EC, XDSS)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(dss, 0x7C00066C, XDSS)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(dss, 0x7C00066C, XDSS)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(lvebx, 0x7C00000E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lvebx, 0x7C00000E, X)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(lvehx, 0x7C00004E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lvehx, 0x7C00004E, X)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -int InstrEmit_lvewx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { +int InstrEmit_lvewx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, + uint32_t rb) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(lvewx, 0x7C00008E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lvewx, 0x7C00008E, X)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_lvewx_(f, i, i.X.RT, i.X.RA, i.X.RB); } -XEEMITTER(lvewx128, VX128_1(4, 131), VX128_1)(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_lvewx_(f, i, VX128_1_VD128, i.VX128_1.RA, i.VX128_1.RB); +XEEMITTER(lvewx128, VX128_1(4, 131), VX128_1)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_lvewx_(f, i, VX128_1_VD128, i.VX128_1.RA, i.VX128_1.RB); } -int InstrEmit_lvsl_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { +int InstrEmit_lvsl_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, + uint32_t rb) { Value* ea = CalculateEA_0(f, ra, rb); Value* sh = f.Truncate(f.And(ea, f.LoadConstant((int64_t)0xF)), INT8_TYPE); Value* v = f.LoadVectorShl(sh); f.StoreVR(vd, v); return 0; } -XEEMITTER(lvsl, 0x7C00000C, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lvsl, 0x7C00000C, X)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_lvsl_(f, i, i.X.RT, i.X.RA, i.X.RB); } -XEEMITTER(lvsl128, VX128_1(4, 3), VX128_1)(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_lvsl_(f, i, VX128_1_VD128, i.VX128_1.RA, i.VX128_1.RB); +XEEMITTER(lvsl128, VX128_1(4, 3), VX128_1)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_lvsl_(f, i, VX128_1_VD128, i.VX128_1.RA, i.VX128_1.RB); } -int InstrEmit_lvsr_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { +int InstrEmit_lvsr_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, + uint32_t rb) { Value* ea = CalculateEA_0(f, ra, rb); Value* sh = f.Truncate(f.And(ea, f.LoadConstant((int64_t)0xF)), INT8_TYPE); Value* v = f.LoadVectorShr(sh); f.StoreVR(vd, v); return 0; } -XEEMITTER(lvsr, 0x7C00004C, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lvsr, 0x7C00004C, X)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_lvsr_(f, i, i.X.RT, i.X.RA, i.X.RB); } -XEEMITTER(lvsr128, VX128_1(4, 67), VX128_1)(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_lvsr_(f, i, VX128_1_VD128, i.VX128_1.RA, i.VX128_1.RB); +XEEMITTER(lvsr128, VX128_1(4, 67), VX128_1)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_lvsr_(f, i, VX128_1_VD128, i.VX128_1.RA, i.VX128_1.RB); } -int InstrEmit_lvx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { +int InstrEmit_lvx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, + uint32_t rb) { Value* ea = f.And(CalculateEA_0(f, ra, rb), f.LoadConstant(~0xFull)); f.StoreVR(vd, f.ByteSwap(f.Load(ea, VEC128_TYPE))); return 0; } -XEEMITTER(lvx, 0x7C0000CE, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lvx, 0x7C0000CE, X)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_lvx_(f, i, i.X.RT, i.X.RA, i.X.RB); } -XEEMITTER(lvx128, VX128_1(4, 195), VX128_1)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lvx128, VX128_1(4, 195), VX128_1)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_lvx_(f, i, VX128_1_VD128, i.VX128_1.RA, i.VX128_1.RB); } -XEEMITTER(lvxl, 0x7C0002CE, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lvxl, 0x7C0002CE, X)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_lvx(f, i); } -XEEMITTER(lvxl128, VX128_1(4, 707), VX128_1)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lvxl128, VX128_1(4, 707), VX128_1)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_lvx128(f, i); } -XEEMITTER(stvebx, 0x7C00010E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stvebx, 0x7C00010E, X)(PPCHIRBuilder& f, InstrData& i) { Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB); Value* el = f.And(ea, f.LoadConstant(0xFull)); Value* v = f.Extract(f.LoadVR(i.X.RT), el, INT8_TYPE); @@ -200,7 +160,7 @@ XEEMITTER(stvebx, 0x7C00010E, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(stvehx, 0x7C00014E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stvehx, 0x7C00014E, X)(PPCHIRBuilder& f, InstrData& i) { Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB); ea = f.And(ea, f.LoadConstant(~0x1ull)); Value* el = f.Shr(f.And(ea, f.LoadConstant(0xFull)), 1); @@ -209,7 +169,8 @@ XEEMITTER(stvehx, 0x7C00014E, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -int InstrEmit_stvewx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { +int InstrEmit_stvewx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, + uint32_t rb) { Value* ea = CalculateEA_0(f, ra, rb); ea = f.And(ea, f.LoadConstant(~0x3ull)); Value* el = f.Shr(f.And(ea, f.LoadConstant(0xFull)), 2); @@ -217,88 +178,87 @@ int InstrEmit_stvewx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, f.Store(ea, f.ByteSwap(v)); return 0; } -XEEMITTER(stvewx, 0x7C00018E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stvewx, 0x7C00018E, X)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_stvewx_(f, i, i.X.RT, i.X.RA, i.X.RB); } -XEEMITTER(stvewx128, VX128_1(4, 387), VX128_1)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stvewx128, VX128_1(4, 387), VX128_1)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_stvewx_(f, i, VX128_1_VD128, i.VX128_1.RA, i.VX128_1.RB); } -int InstrEmit_stvx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { +int InstrEmit_stvx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, + uint32_t rb) { Value* ea = f.And(CalculateEA_0(f, ra, rb), f.LoadConstant(~0xFull)); f.Store(ea, f.ByteSwap(f.LoadVR(vd))); return 0; } -XEEMITTER(stvx, 0x7C0001CE, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stvx, 0x7C0001CE, X)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_stvx_(f, i, i.X.RT, i.X.RA, i.X.RB); } -XEEMITTER(stvx128, VX128_1(4, 451), VX128_1)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stvx128, VX128_1(4, 451), VX128_1)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_stvx_(f, i, VX128_1_VD128, i.VX128_1.RA, i.VX128_1.RB); } -XEEMITTER(stvxl, 0x7C0003CE, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stvxl, 0x7C0003CE, X)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_stvx(f, i); } -XEEMITTER(stvxl128, VX128_1(4, 963), VX128_1)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stvxl128, VX128_1(4, 963), VX128_1)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_stvx128(f, i); } // The lvlx/lvrx/etc instructions are in Cell docs only: // https://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/C40E4C6133B31EE8872570B500791108/$file/vector_simd_pem_v_2.07c_26Oct2006_cell.pdf -int InstrEmit_lvlx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { +int InstrEmit_lvlx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, + uint32_t rb) { Value* ea = CalculateEA_0(f, ra, rb); Value* eb = f.And(f.Truncate(ea, INT8_TYPE), f.LoadConstant((int8_t)0xF)); // ea &= ~0xF ea = f.And(ea, f.LoadConstant(~0xFull)); // v = (new << eb) - Value* v = f.Permute( - f.LoadVectorShl(eb), - f.ByteSwap(f.Load(ea, VEC128_TYPE)), - f.LoadZero(VEC128_TYPE), - INT8_TYPE); + Value* v = f.Permute(f.LoadVectorShl(eb), f.ByteSwap(f.Load(ea, VEC128_TYPE)), + f.LoadZero(VEC128_TYPE), INT8_TYPE); f.StoreVR(vd, v); return 0; } -XEEMITTER(lvlx, 0x7C00040E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lvlx, 0x7C00040E, X)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_lvlx_(f, i, i.X.RT, i.X.RA, i.X.RB); } -XEEMITTER(lvlx128, VX128_1(4, 1027), VX128_1)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lvlx128, VX128_1(4, 1027), VX128_1)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_lvlx_(f, i, VX128_1_VD128, i.VX128_1.RA, i.VX128_1.RB); } -XEEMITTER(lvlxl, 0x7C00060E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lvlxl, 0x7C00060E, X)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_lvlx(f, i); } -XEEMITTER(lvlxl128, VX128_1(4, 1539), VX128_1)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lvlxl128, VX128_1(4, 1539), VX128_1)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_lvlx128(f, i); } -int InstrEmit_lvrx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { +int InstrEmit_lvrx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, + uint32_t rb) { Value* ea = CalculateEA_0(f, ra, rb); Value* eb = f.And(f.Truncate(ea, INT8_TYPE), f.LoadConstant((int8_t)0xF)); // ea &= ~0xF ea = f.And(ea, f.LoadConstant(~0xFull)); // v = (new >> (16 - eb)) - Value* v = f.Permute( - f.LoadVectorShr(f.Sub(f.LoadConstant((int8_t)16), eb)), - f.LoadZero(VEC128_TYPE), - f.ByteSwap(f.Load(ea, VEC128_TYPE)), - INT8_TYPE); + Value* v = f.Permute(f.LoadVectorShr(f.Sub(f.LoadConstant((int8_t)16), eb)), + f.LoadZero(VEC128_TYPE), + f.ByteSwap(f.Load(ea, VEC128_TYPE)), INT8_TYPE); f.StoreVR(vd, v); return 0; } -XEEMITTER(lvrx, 0x7C00044E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lvrx, 0x7C00044E, X)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_lvrx_(f, i, i.X.RT, i.X.RA, i.X.RB); } -XEEMITTER(lvrx128, VX128_1(4, 1091), VX128_1)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lvrx128, VX128_1(4, 1091), VX128_1)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_lvrx_(f, i, VX128_1_VD128, i.VX128_1.RA, i.VX128_1.RB); } -XEEMITTER(lvrxl, 0x7C00064E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lvrxl, 0x7C00064E, X)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_lvrx(f, i); } -XEEMITTER(lvrxl128, VX128_1(4, 1603), VX128_1)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lvrxl128, VX128_1(4, 1603), VX128_1)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_lvrx128(f, i); } -int InstrEmit_stvlx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { +int InstrEmit_stvlx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, + uint32_t rb) { // NOTE: if eb == 0 (so 16b aligned) this equals new_value // we could optimize this to prevent the other load/mask, in that case. Value* ea = CalculateEA_0(f, ra, rb); @@ -308,38 +268,33 @@ int InstrEmit_stvlx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, u ea = f.And(ea, f.LoadConstant(~0xFull)); Value* old_value = f.ByteSwap(f.Load(ea, VEC128_TYPE)); // v = (new >> eb) | (old & (ONE << (16 - eb))) - Value* v = f.Permute( - f.LoadVectorShr(eb), - f.LoadZero(VEC128_TYPE), - new_value, - INT8_TYPE); + Value* v = f.Permute(f.LoadVectorShr(eb), f.LoadZero(VEC128_TYPE), new_value, + INT8_TYPE); v = f.Or( - v, - f.And( - old_value, - f.Permute( - f.LoadVectorShl(f.Sub(f.LoadConstant((int8_t)16), eb)), - f.Not(f.LoadZero(VEC128_TYPE)), - f.LoadZero(VEC128_TYPE), - INT8_TYPE))); + v, f.And(old_value, + f.Permute(f.LoadVectorShl(f.Sub(f.LoadConstant((int8_t)16), eb)), + f.Not(f.LoadZero(VEC128_TYPE)), + f.LoadZero(VEC128_TYPE), INT8_TYPE))); // ea &= ~0xF (handled above) f.Store(ea, f.ByteSwap(v)); return 0; } -XEEMITTER(stvlx, 0x7C00050E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stvlx, 0x7C00050E, X)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_stvlx_(f, i, i.X.RT, i.X.RA, i.X.RB); } -XEEMITTER(stvlx128, VX128_1(4, 1283), VX128_1)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stvlx128, VX128_1(4, 1283), VX128_1)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_stvlx_(f, i, VX128_1_VD128, i.VX128_1.RA, i.VX128_1.RB); } -XEEMITTER(stvlxl, 0x7C00070E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stvlxl, 0x7C00070E, X)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_stvlx(f, i); } -XEEMITTER(stvlxl128, VX128_1(4, 1795), VX128_1)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stvlxl128, VX128_1(4, 1795), VX128_1)(PPCHIRBuilder& f, + InstrData& i) { return InstrEmit_stvlx128(f, i); } -int InstrEmit_stvrx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { +int InstrEmit_stvrx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, + uint32_t rb) { // NOTE: if eb == 0 (so 16b aligned) this equals new_value // we could optimize this to prevent the other load/mask, in that case. Value* ea = CalculateEA_0(f, ra, rb); @@ -349,48 +304,40 @@ int InstrEmit_stvrx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, u ea = f.And(ea, f.LoadConstant(~0xFull)); Value* old_value = f.ByteSwap(f.Load(ea, VEC128_TYPE)); // v = (new << (16 - eb)) | (old & (ONE >> eb)) - Value* v = f.Permute( - f.LoadVectorShl(f.Sub(f.LoadConstant((int8_t)16), eb)), - new_value, - f.LoadZero(VEC128_TYPE), - INT8_TYPE); - v = f.Or( - v, - f.And( - old_value, - f.Permute( - f.LoadVectorShr(eb), - f.LoadZero(VEC128_TYPE), - f.Not(f.LoadZero(VEC128_TYPE)), - INT8_TYPE))); + Value* v = f.Permute(f.LoadVectorShl(f.Sub(f.LoadConstant((int8_t)16), eb)), + new_value, f.LoadZero(VEC128_TYPE), INT8_TYPE); + v = f.Or(v, f.And(old_value, + f.Permute(f.LoadVectorShr(eb), f.LoadZero(VEC128_TYPE), + f.Not(f.LoadZero(VEC128_TYPE)), INT8_TYPE))); // ea &= ~0xF (handled above) f.Store(ea, f.ByteSwap(v)); return 0; } -XEEMITTER(stvrx, 0x7C00054E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stvrx, 0x7C00054E, X)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_stvrx_(f, i, i.X.RT, i.X.RA, i.X.RB); } -XEEMITTER(stvrx128, VX128_1(4, 1347), VX128_1)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stvrx128, VX128_1(4, 1347), VX128_1)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_stvrx_(f, i, VX128_1_VD128, i.VX128_1.RA, i.VX128_1.RB); } -XEEMITTER(stvrxl, 0x7C00074E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stvrxl, 0x7C00074E, X)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_stvrx(f, i); } -XEEMITTER(stvrxl128, VX128_1(4, 1859), VX128_1)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stvrxl128, VX128_1(4, 1859), VX128_1)(PPCHIRBuilder& f, + InstrData& i) { return InstrEmit_stvrx128(f, i); } -XEEMITTER(mfvscr, 0x10000604, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mfvscr, 0x10000604, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(mtvscr, 0x10000644, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mtvscr, 0x10000644, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vaddcuw, 0x10000180, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vaddcuw, 0x10000180, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } @@ -401,80 +348,80 @@ int InstrEmit_vaddfp_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vaddfp, 0x1000000A, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vaddfp, 0x1000000A, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vaddfp_(f, i.VX.VD, i.VX.VA, i.VX.VB); } -XEEMITTER(vaddfp128, VX128(5, 16), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vaddfp128, VX128(5, 16), VX128)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vaddfp_(f, VX128_VD128, VX128_VA128, VX128_VB128); } -XEEMITTER(vaddsbs, 0x10000300, VX )(PPCHIRBuilder& f, InstrData& i) { - Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), - INT8_TYPE, ARITHMETIC_SATURATE); +XEEMITTER(vaddsbs, 0x10000300, VX)(PPCHIRBuilder& f, InstrData& i) { + Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT8_TYPE, + ARITHMETIC_SATURATE); f.StoreSAT(f.DidSaturate(v)); f.StoreVR(i.VX.VD, v); return 0; } -XEEMITTER(vaddshs, 0x10000340, VX )(PPCHIRBuilder& f, InstrData& i) { - Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), - INT16_TYPE, ARITHMETIC_SATURATE); +XEEMITTER(vaddshs, 0x10000340, VX)(PPCHIRBuilder& f, InstrData& i) { + Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT16_TYPE, + ARITHMETIC_SATURATE); f.StoreSAT(f.DidSaturate(v)); f.StoreVR(i.VX.VD, v); return 0; } -XEEMITTER(vaddsws, 0x10000380, VX )(PPCHIRBuilder& f, InstrData& i) { - Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), - INT32_TYPE, ARITHMETIC_SATURATE); +XEEMITTER(vaddsws, 0x10000380, VX)(PPCHIRBuilder& f, InstrData& i) { + Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT32_TYPE, + ARITHMETIC_SATURATE); f.StoreSAT(f.DidSaturate(v)); f.StoreVR(i.VX.VD, v); return 0; } -XEEMITTER(vaddubm, 0x10000000, VX )(PPCHIRBuilder& f, InstrData& i) { - Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), - INT8_TYPE, ARITHMETIC_UNSIGNED); +XEEMITTER(vaddubm, 0x10000000, VX)(PPCHIRBuilder& f, InstrData& i) { + Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT8_TYPE, + ARITHMETIC_UNSIGNED); f.StoreSAT(f.DidSaturate(v)); f.StoreVR(i.VX.VD, v); return 0; } -XEEMITTER(vaddubs, 0x10000200, VX )(PPCHIRBuilder& f, InstrData& i) { - Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), - INT8_TYPE, ARITHMETIC_UNSIGNED | ARITHMETIC_SATURATE); +XEEMITTER(vaddubs, 0x10000200, VX)(PPCHIRBuilder& f, InstrData& i) { + Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT8_TYPE, + ARITHMETIC_UNSIGNED | ARITHMETIC_SATURATE); f.StoreSAT(f.DidSaturate(v)); f.StoreVR(i.VX.VD, v); return 0; } -XEEMITTER(vadduhm, 0x10000040, VX )(PPCHIRBuilder& f, InstrData& i) { - Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), - INT16_TYPE, ARITHMETIC_UNSIGNED); +XEEMITTER(vadduhm, 0x10000040, VX)(PPCHIRBuilder& f, InstrData& i) { + Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT16_TYPE, + ARITHMETIC_UNSIGNED); f.StoreSAT(f.DidSaturate(v)); f.StoreVR(i.VX.VD, v); return 0; } -XEEMITTER(vadduhs, 0x10000240, VX )(PPCHIRBuilder& f, InstrData& i) { - Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), - INT16_TYPE, ARITHMETIC_UNSIGNED | ARITHMETIC_SATURATE); +XEEMITTER(vadduhs, 0x10000240, VX)(PPCHIRBuilder& f, InstrData& i) { + Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT16_TYPE, + ARITHMETIC_UNSIGNED | ARITHMETIC_SATURATE); f.StoreSAT(f.DidSaturate(v)); f.StoreVR(i.VX.VD, v); return 0; } -XEEMITTER(vadduwm, 0x10000080, VX )(PPCHIRBuilder& f, InstrData& i) { - Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), - INT32_TYPE, ARITHMETIC_UNSIGNED); +XEEMITTER(vadduwm, 0x10000080, VX)(PPCHIRBuilder& f, InstrData& i) { + Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT32_TYPE, + ARITHMETIC_UNSIGNED); f.StoreSAT(f.DidSaturate(v)); f.StoreVR(i.VX.VD, v); return 0; } -XEEMITTER(vadduws, 0x10000280, VX )(PPCHIRBuilder& f, InstrData& i) { - Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), - INT32_TYPE, ARITHMETIC_UNSIGNED | ARITHMETIC_SATURATE); +XEEMITTER(vadduws, 0x10000280, VX)(PPCHIRBuilder& f, InstrData& i) { + Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT32_TYPE, + ARITHMETIC_UNSIGNED | ARITHMETIC_SATURATE); f.StoreSAT(f.DidSaturate(v)); f.StoreVR(i.VX.VD, v); return 0; @@ -486,10 +433,10 @@ int InstrEmit_vand_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vand, 0x10000404, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vand, 0x10000404, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vand_(f, i.VX.VD, i.VX.VA, i.VX.VB); } -XEEMITTER(vand128, VX128(5, 528), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vand128, VX128(5, 528), VX128)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vand_(f, VX128_VD128, VX128_VA128, VX128_VB128); } @@ -499,118 +446,124 @@ int InstrEmit_vandc_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vandc, 0x10000444, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vandc, 0x10000444, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vandc_(f, i.VX.VD, i.VX.VA, i.VX.VB); } -XEEMITTER(vandc128, VX128(5, 592), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vandc128, VX128(5, 592), VX128)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vandc_(f, VX128_VD128, VX128_VA128, VX128_VB128); } -XEEMITTER(vavgsb, 0x10000502, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vavgsb, 0x10000502, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vavgsh, 0x10000542, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vavgsh, 0x10000542, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vavgsw, 0x10000582, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vavgsw, 0x10000582, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vavgub, 0x10000402, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vavgub, 0x10000402, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vavguh, 0x10000442, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vavguh, 0x10000442, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vavguw, 0x10000482, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vavguw, 0x10000482, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -int InstrEmit_vcfsx_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm) { +int InstrEmit_vcfsx_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, + uint32_t uimm) { // (VD) <- float(VB as signed) / 2^uimm uimm = uimm ? (2 << (uimm - 1)) : 1; - Value* v = f.Div( - f.VectorConvertI2F(f.LoadVR(vb)), - f.Splat(f.LoadConstant((float)uimm), VEC128_TYPE)); + Value* v = f.Div(f.VectorConvertI2F(f.LoadVR(vb)), + f.Splat(f.LoadConstant((float)uimm), VEC128_TYPE)); f.StoreVR(vd, v); return 0; } -XEEMITTER(vcfsx, 0x1000034A, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vcfsx, 0x1000034A, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vcfsx_(f, i.VX.VD, i.VX.VB, i.VX.VA); } -XEEMITTER(vcsxwfp128, VX128_3(6, 688), VX128_3)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vcsxwfp128, VX128_3(6, 688), VX128_3)(PPCHIRBuilder& f, + InstrData& i) { return InstrEmit_vcfsx_(f, VX128_3_VD128, VX128_3_VB128, VX128_3_IMM); } -int InstrEmit_vcfux_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm) { +int InstrEmit_vcfux_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, + uint32_t uimm) { // (VD) <- float(VB as unsigned) / 2^uimm uimm = uimm ? (2 << (uimm - 1)) : 1; - Value* v = f.Div( - f.VectorConvertI2F(f.LoadVR(vb), ARITHMETIC_UNSIGNED), - f.Splat(f.LoadConstant((float)uimm), VEC128_TYPE)); + Value* v = f.Div(f.VectorConvertI2F(f.LoadVR(vb), ARITHMETIC_UNSIGNED), + f.Splat(f.LoadConstant((float)uimm), VEC128_TYPE)); f.StoreVR(vd, v); return 0; } -XEEMITTER(vcfux, 0x1000030A, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vcfux, 0x1000030A, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vcfux_(f, i.VX.VD, i.VX.VB, i.VX.VA); } -XEEMITTER(vcuxwfp128, VX128_3(6, 752), VX128_3)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vcuxwfp128, VX128_3(6, 752), VX128_3)(PPCHIRBuilder& f, + InstrData& i) { return InstrEmit_vcfux_(f, VX128_3_VD128, VX128_3_VB128, VX128_3_IMM); } -int InstrEmit_vctsxs_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm) { +int InstrEmit_vctsxs_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, + uint32_t uimm) { // (VD) <- int_sat(VB as signed * 2^uimm) uimm = uimm ? (2 << (uimm - 1)) : 1; - Value* v = f.Mul( - f.LoadVR(vb), - f.Splat(f.LoadConstant((float)uimm), VEC128_TYPE)); + Value* v = + f.Mul(f.LoadVR(vb), f.Splat(f.LoadConstant((float)uimm), VEC128_TYPE)); v = f.VectorConvertF2I(v, ARITHMETIC_SATURATE); f.StoreVR(vd, v); return 0; } -XEEMITTER(vctsxs, 0x100003CA, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vctsxs, 0x100003CA, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vctsxs_(f, i.VX.VD, i.VX.VB, i.VX.VA); } -XEEMITTER(vcfpsxws128, VX128_3(6, 560), VX128_3)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vcfpsxws128, VX128_3(6, 560), VX128_3)(PPCHIRBuilder& f, + InstrData& i) { return InstrEmit_vctsxs_(f, VX128_3_VD128, VX128_3_VB128, VX128_3_IMM); } -int InstrEmit_vctuxs_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm) { +int InstrEmit_vctuxs_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, + uint32_t uimm) { // (VD) <- int_sat(VB as unsigned * 2^uimm) uimm = uimm ? (2 << (uimm - 1)) : 1; - Value* v = f.Mul( - f.LoadVR(vb), - f.Splat(f.LoadConstant((float)uimm), VEC128_TYPE)); + Value* v = + f.Mul(f.LoadVR(vb), f.Splat(f.LoadConstant((float)uimm), VEC128_TYPE)); v = f.VectorConvertF2I(v, ARITHMETIC_UNSIGNED | ARITHMETIC_SATURATE); f.StoreVR(vd, v); return 0; } -XEEMITTER(vctuxs, 0x1000038A, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vctuxs, 0x1000038A, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vctuxs_(f, i.VX.VD, i.VX.VB, i.VX.VA); } -XEEMITTER(vcfpuxws128, VX128_3(6, 624), VX128_3)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vcfpuxws128, VX128_3(6, 624), VX128_3)(PPCHIRBuilder& f, + InstrData& i) { return InstrEmit_vctuxs_(f, VX128_3_VD128, VX128_3_VB128, VX128_3_IMM); } -int InstrEmit_vcmpbfp_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t va, uint32_t vb, uint32_t rc) { +int InstrEmit_vcmpbfp_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t va, + uint32_t vb, uint32_t rc) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vcmpbfp, 0x100003C6, VXR )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vcmpbfp, 0x100003C6, VXR)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vcmpbfp_(f, i, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); } -XEEMITTER(vcmpbfp128, VX128(6, 384), VX128_R)(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_vcmpbfp_(f, i, VX128_R_VD128, VX128_R_VA128, VX128_R_VB128, i.VX128_R.Rc); +XEEMITTER(vcmpbfp128, VX128(6, 384), VX128_R)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vcmpbfp_(f, i, VX128_R_VD128, VX128_R_VA128, VX128_R_VB128, + i.VX128_R.Rc); } enum vcmpxxfp_op { @@ -618,24 +571,25 @@ enum vcmpxxfp_op { vcmpxxfp_gt, vcmpxxfp_ge, }; -int InstrEmit_vcmpxxfp_(PPCHIRBuilder& f, InstrData& i, vcmpxxfp_op cmpop, uint32_t vd, uint32_t va, uint32_t vb, uint32_t rc) { +int InstrEmit_vcmpxxfp_(PPCHIRBuilder& f, InstrData& i, vcmpxxfp_op cmpop, + uint32_t vd, uint32_t va, uint32_t vb, uint32_t rc) { // (VD.xyzw) = (VA.xyzw) OP (VB.xyzw) ? 0xFFFFFFFF : 0x00000000 // if (Rc) CR6 = all_equal | 0 | none_equal | 0 // If an element in either VA or VB is NaN the result will be 0x00000000 Value* v; switch (cmpop) { - case vcmpxxfp_eq: - v = f.VectorCompareEQ(f.LoadVR(va), f.LoadVR(vb), FLOAT32_TYPE); - break; - case vcmpxxfp_gt: - v = f.VectorCompareSGT(f.LoadVR(va), f.LoadVR(vb), FLOAT32_TYPE); - break; - case vcmpxxfp_ge: - v = f.VectorCompareSGE(f.LoadVR(va), f.LoadVR(vb), FLOAT32_TYPE); - break; - default: - XEASSERTALWAYS(); - return 1; + case vcmpxxfp_eq: + v = f.VectorCompareEQ(f.LoadVR(va), f.LoadVR(vb), FLOAT32_TYPE); + break; + case vcmpxxfp_gt: + v = f.VectorCompareSGT(f.LoadVR(va), f.LoadVR(vb), FLOAT32_TYPE); + break; + case vcmpxxfp_ge: + v = f.VectorCompareSGE(f.LoadVR(va), f.LoadVR(vb), FLOAT32_TYPE); + break; + default: + XEASSERTALWAYS(); + return 1; } if (rc) { f.UpdateCR6(v); @@ -644,23 +598,29 @@ int InstrEmit_vcmpxxfp_(PPCHIRBuilder& f, InstrData& i, vcmpxxfp_op cmpop, uint3 return 0; } -XEEMITTER(vcmpeqfp, 0x100000C6, VXR )(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_eq, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); +XEEMITTER(vcmpeqfp, 0x100000C6, VXR)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_eq, i.VXR.VD, i.VXR.VA, i.VXR.VB, + i.VXR.Rc); } -XEEMITTER(vcmpeqfp128, VX128(6, 0), VX128_R)(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_eq, VX128_R_VD128, VX128_R_VA128, VX128_R_VB128, i.VX128_R.Rc); +XEEMITTER(vcmpeqfp128, VX128(6, 0), VX128_R)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_eq, VX128_R_VD128, VX128_R_VA128, + VX128_R_VB128, i.VX128_R.Rc); } -XEEMITTER(vcmpgefp, 0x100001C6, VXR )(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_ge, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); +XEEMITTER(vcmpgefp, 0x100001C6, VXR)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_ge, i.VXR.VD, i.VXR.VA, i.VXR.VB, + i.VXR.Rc); } -XEEMITTER(vcmpgefp128, VX128(6, 128), VX128_R)(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_ge, VX128_R_VD128, VX128_R_VA128, VX128_R_VB128, i.VX128_R.Rc); +XEEMITTER(vcmpgefp128, VX128(6, 128), VX128_R)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_ge, VX128_R_VD128, VX128_R_VA128, + VX128_R_VB128, i.VX128_R.Rc); } -XEEMITTER(vcmpgtfp, 0x100002C6, VXR )(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_gt, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); +XEEMITTER(vcmpgtfp, 0x100002C6, VXR)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_gt, i.VXR.VD, i.VXR.VA, i.VXR.VB, + i.VXR.Rc); } -XEEMITTER(vcmpgtfp128, VX128(6, 256), VX128_R)(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_gt, VX128_R_VD128, VX128_R_VA128, VX128_R_VB128, i.VX128_R.Rc); +XEEMITTER(vcmpgtfp128, VX128(6, 256), VX128_R)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_gt, VX128_R_VD128, VX128_R_VA128, + VX128_R_VB128, i.VX128_R.Rc); } enum vcmpxxi_op { @@ -668,55 +628,65 @@ enum vcmpxxi_op { vcmpxxi_gt_signed, vcmpxxi_gt_unsigned, }; -int InstrEmit_vcmpxxi_(PPCHIRBuilder& f, InstrData& i, vcmpxxi_op cmpop, uint32_t width, uint32_t vd, uint32_t va, uint32_t vb, uint32_t rc) { +int InstrEmit_vcmpxxi_(PPCHIRBuilder& f, InstrData& i, vcmpxxi_op cmpop, + uint32_t width, uint32_t vd, uint32_t va, uint32_t vb, + uint32_t rc) { // (VD.xyzw) = (VA.xyzw) OP (VB.xyzw) ? 0xFFFFFFFF : 0x00000000 // if (Rc) CR6 = all_equal | 0 | none_equal | 0 // If an element in either VA or VB is NaN the result will be 0x00000000 Value* v; switch (cmpop) { - case vcmpxxi_eq: - switch (width) { - case 1: - v = f.VectorCompareEQ(f.LoadVR(va), f.LoadVR(vb), INT8_TYPE); + case vcmpxxi_eq: + switch (width) { + case 1: + v = f.VectorCompareEQ(f.LoadVR(va), f.LoadVR(vb), INT8_TYPE); + break; + case 2: + v = f.VectorCompareEQ(f.LoadVR(va), f.LoadVR(vb), INT16_TYPE); + break; + case 4: + v = f.VectorCompareEQ(f.LoadVR(va), f.LoadVR(vb), INT32_TYPE); + break; + default: + XEASSERTALWAYS(); + return 1; + } break; - case 2: - v = f.VectorCompareEQ(f.LoadVR(va), f.LoadVR(vb), INT16_TYPE); + case vcmpxxi_gt_signed: + switch (width) { + case 1: + v = f.VectorCompareSGT(f.LoadVR(va), f.LoadVR(vb), INT8_TYPE); + break; + case 2: + v = f.VectorCompareSGT(f.LoadVR(va), f.LoadVR(vb), INT16_TYPE); + break; + case 4: + v = f.VectorCompareSGT(f.LoadVR(va), f.LoadVR(vb), INT32_TYPE); + break; + default: + XEASSERTALWAYS(); + return 1; + } break; - case 4: - v = f.VectorCompareEQ(f.LoadVR(va), f.LoadVR(vb), INT32_TYPE); + case vcmpxxi_gt_unsigned: + switch (width) { + case 1: + v = f.VectorCompareUGT(f.LoadVR(va), f.LoadVR(vb), INT8_TYPE); + break; + case 2: + v = f.VectorCompareUGT(f.LoadVR(va), f.LoadVR(vb), INT16_TYPE); + break; + case 4: + v = f.VectorCompareUGT(f.LoadVR(va), f.LoadVR(vb), INT32_TYPE); + break; + default: + XEASSERTALWAYS(); + return 1; + } break; - default: XEASSERTALWAYS(); return 1; - } - break; - case vcmpxxi_gt_signed: - switch (width) { - case 1: - v = f.VectorCompareSGT(f.LoadVR(va), f.LoadVR(vb), INT8_TYPE); - break; - case 2: - v = f.VectorCompareSGT(f.LoadVR(va), f.LoadVR(vb), INT16_TYPE); - break; - case 4: - v = f.VectorCompareSGT(f.LoadVR(va), f.LoadVR(vb), INT32_TYPE); - break; - default: XEASSERTALWAYS(); return 1; - } - break; - case vcmpxxi_gt_unsigned: - switch (width) { - case 1: - v = f.VectorCompareUGT(f.LoadVR(va), f.LoadVR(vb), INT8_TYPE); - break; - case 2: - v = f.VectorCompareUGT(f.LoadVR(va), f.LoadVR(vb), INT16_TYPE); - break; - case 4: - v = f.VectorCompareUGT(f.LoadVR(va), f.LoadVR(vb), INT32_TYPE); - break; - default: XEASSERTALWAYS(); return 1; - } - break; - default: XEASSERTALWAYS(); return 1; + default: + XEASSERTALWAYS(); + return 1; } if (rc) { f.UpdateCR6(v); @@ -724,35 +694,45 @@ int InstrEmit_vcmpxxi_(PPCHIRBuilder& f, InstrData& i, vcmpxxi_op cmpop, uint32_ f.StoreVR(vd, v); return 0; } -XEEMITTER(vcmpequb, 0x10000006, VXR )(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_vcmpxxi_(f, i, vcmpxxi_eq, 1, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); +XEEMITTER(vcmpequb, 0x10000006, VXR)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vcmpxxi_(f, i, vcmpxxi_eq, 1, i.VXR.VD, i.VXR.VA, i.VXR.VB, + i.VXR.Rc); } -XEEMITTER(vcmpequh, 0x10000046, VXR )(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_vcmpxxi_(f, i, vcmpxxi_eq, 2, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); +XEEMITTER(vcmpequh, 0x10000046, VXR)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vcmpxxi_(f, i, vcmpxxi_eq, 2, i.VXR.VD, i.VXR.VA, i.VXR.VB, + i.VXR.Rc); } -XEEMITTER(vcmpequw, 0x10000086, VXR )(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_vcmpxxi_(f, i, vcmpxxi_eq, 4, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); +XEEMITTER(vcmpequw, 0x10000086, VXR)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vcmpxxi_(f, i, vcmpxxi_eq, 4, i.VXR.VD, i.VXR.VA, i.VXR.VB, + i.VXR.Rc); } -XEEMITTER(vcmpequw128, VX128(6, 512), VX128_R)(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_vcmpxxi_(f, i, vcmpxxi_eq, 4, VX128_R_VD128, VX128_R_VA128, VX128_R_VB128, i.VX128_R.Rc); +XEEMITTER(vcmpequw128, VX128(6, 512), VX128_R)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vcmpxxi_(f, i, vcmpxxi_eq, 4, VX128_R_VD128, VX128_R_VA128, + VX128_R_VB128, i.VX128_R.Rc); } -XEEMITTER(vcmpgtsb, 0x10000306, VXR )(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_signed, 1, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); +XEEMITTER(vcmpgtsb, 0x10000306, VXR)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_signed, 1, i.VXR.VD, i.VXR.VA, + i.VXR.VB, i.VXR.Rc); } -XEEMITTER(vcmpgtsh, 0x10000346, VXR )(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_signed, 2, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); +XEEMITTER(vcmpgtsh, 0x10000346, VXR)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_signed, 2, i.VXR.VD, i.VXR.VA, + i.VXR.VB, i.VXR.Rc); } -XEEMITTER(vcmpgtsw, 0x10000386, VXR )(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_signed, 4, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); +XEEMITTER(vcmpgtsw, 0x10000386, VXR)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_signed, 4, i.VXR.VD, i.VXR.VA, + i.VXR.VB, i.VXR.Rc); } -XEEMITTER(vcmpgtub, 0x10000206, VXR )(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_unsigned, 1, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); +XEEMITTER(vcmpgtub, 0x10000206, VXR)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_unsigned, 1, i.VXR.VD, i.VXR.VA, + i.VXR.VB, i.VXR.Rc); } -XEEMITTER(vcmpgtuh, 0x10000246, VXR )(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_unsigned, 2, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); +XEEMITTER(vcmpgtuh, 0x10000246, VXR)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_unsigned, 2, i.VXR.VD, i.VXR.VA, + i.VXR.VB, i.VXR.Rc); } -XEEMITTER(vcmpgtuw, 0x10000286, VXR )(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_unsigned, 4, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); +XEEMITTER(vcmpgtuw, 0x10000286, VXR)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_unsigned, 4, i.VXR.VD, i.VXR.VA, + i.VXR.VB, i.VXR.Rc); } int InstrEmit_vexptefp_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { @@ -761,10 +741,11 @@ int InstrEmit_vexptefp_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vexptefp, 0x1000018A, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vexptefp, 0x1000018A, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vexptefp_(f, i.VX.VD, i.VX.VB); } -XEEMITTER(vexptefp128, VX128_3(6, 1712), VX128_3)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vexptefp128, VX128_3(6, 1712), VX128_3)(PPCHIRBuilder& f, + InstrData& i) { return InstrEmit_vexptefp_(f, VX128_3_VD128, VX128_3_VB128); } @@ -774,34 +755,36 @@ int InstrEmit_vlogefp_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vlogefp, 0x100001CA, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vlogefp, 0x100001CA, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vlogefp_(f, i.VX.VD, i.VX.VB); } -XEEMITTER(vlogefp128, VX128_3(6, 1776), VX128_3)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vlogefp128, VX128_3(6, 1776), VX128_3)(PPCHIRBuilder& f, + InstrData& i) { return InstrEmit_vlogefp_(f, VX128_3_VD128, VX128_3_VB128); } -int InstrEmit_vmaddfp_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, uint32_t vc) { +int InstrEmit_vmaddfp_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, + uint32_t vc) { // (VD) <- ((VA) * (VC)) + (VB) - Value* v = f.MulAdd( - f.LoadVR(va), f.LoadVR(vc), f.LoadVR(vb)); + Value* v = f.MulAdd(f.LoadVR(va), f.LoadVR(vc), f.LoadVR(vb)); f.StoreVR(vd, v); return 0; } -XEEMITTER(vmaddfp, 0x1000002E, VXA )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmaddfp, 0x1000002E, VXA)(PPCHIRBuilder& f, InstrData& i) { // (VD) <- ((VA) * (VC)) + (VB) return InstrEmit_vmaddfp_(f, i.VXA.VD, i.VXA.VA, i.VXA.VB, i.VXA.VC); } -XEEMITTER(vmaddfp128, VX128(5, 208), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmaddfp128, VX128(5, 208), VX128)(PPCHIRBuilder& f, InstrData& i) { // (VD) <- ((VA) * (VB)) + (VD) // NOTE: this resuses VD and swaps the arg order! - return InstrEmit_vmaddfp_(f, VX128_VD128, VX128_VA128, VX128_VD128, VX128_VB128); + return InstrEmit_vmaddfp_(f, VX128_VD128, VX128_VA128, VX128_VD128, + VX128_VB128); } -XEEMITTER(vmaddcfp128, VX128(5, 272), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmaddcfp128, VX128(5, 272), VX128)(PPCHIRBuilder& f, InstrData& i) { // (VD) <- ((VA) * (VD)) + (VB) - Value* v = f.MulAdd( - f.LoadVR(VX128_VA128), f.LoadVR(VX128_VD128), f.LoadVR(VX128_VB128)); + Value* v = f.MulAdd(f.LoadVR(VX128_VA128), f.LoadVR(VX128_VD128), + f.LoadVR(VX128_VB128)); f.StoreVR(VX128_VD128, v); return 0; } @@ -812,49 +795,49 @@ int InstrEmit_vmaxfp_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vmaxfp, 0x1000040A, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmaxfp, 0x1000040A, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vmaxfp_(f, i.VX.VD, i.VX.VA, i.VX.VB); } -XEEMITTER(vmaxfp128, VX128(6, 640), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmaxfp128, VX128(6, 640), VX128)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vmaxfp_(f, VX128_VD128, VX128_VA128, VX128_VB128); } -XEEMITTER(vmaxsb, 0x10000102, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmaxsb, 0x10000102, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmaxsh, 0x10000142, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmaxsh, 0x10000142, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmaxsw, 0x10000182, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmaxsw, 0x10000182, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmaxub, 0x10000002, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmaxub, 0x10000002, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmaxuh, 0x10000042, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmaxuh, 0x10000042, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmaxuw, 0x10000082, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmaxuw, 0x10000082, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmhaddshs, 0x10000020, VXA )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmhaddshs, 0x10000020, VXA)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmhraddshs, 0x10000021, VXA )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmhraddshs, 0x10000021, VXA)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } @@ -865,54 +848,54 @@ int InstrEmit_vminfp_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vminfp, 0x1000044A, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vminfp, 0x1000044A, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vminfp_(f, i.VX.VD, i.VX.VA, i.VX.VB); } -XEEMITTER(vminfp128, VX128(6, 704), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vminfp128, VX128(6, 704), VX128)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vminfp_(f, VX128_VD128, VX128_VA128, VX128_VB128); } -XEEMITTER(vminsb, 0x10000302, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vminsb, 0x10000302, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vminsh, 0x10000342, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vminsh, 0x10000342, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vminsw, 0x10000382, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vminsw, 0x10000382, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vminub, 0x10000202, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vminub, 0x10000202, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vminuh, 0x10000242, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vminuh, 0x10000242, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vminuw, 0x10000282, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vminuw, 0x10000282, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmladduhm, 0x10000022, VXA )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmladduhm, 0x10000022, VXA)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmrghb, 0x1000000C, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmrghb, 0x1000000C, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmrghh, 0x1000004C, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmrghh, 0x1000004C, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } @@ -922,27 +905,24 @@ int InstrEmit_vmrghw_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { // (VD.y) = (VB.x) // (VD.z) = (VA.y) // (VD.w) = (VB.y) - Value* v = f.Permute( - f.LoadConstant(0x00040105), - f.LoadVR(va), - f.LoadVR(vb), - INT32_TYPE); + Value* v = f.Permute(f.LoadConstant(0x00040105), f.LoadVR(va), f.LoadVR(vb), + INT32_TYPE); f.StoreVR(vd, v); return 0; } -XEEMITTER(vmrghw, 0x1000008C, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmrghw, 0x1000008C, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vmrghw_(f, i.VX.VD, i.VX.VA, i.VX.VB); } -XEEMITTER(vmrghw128, VX128(6, 768), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmrghw128, VX128(6, 768), VX128)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vmrghw_(f, VX128_VD128, VX128_VA128, VX128_VB128); } -XEEMITTER(vmrglb, 0x1000010C, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmrglb, 0x1000010C, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmrglh, 0x1000014C, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmrglh, 0x1000014C, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } @@ -952,52 +932,49 @@ int InstrEmit_vmrglw_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { // (VD.y) = (VB.z) // (VD.z) = (VA.w) // (VD.w) = (VB.w) - Value* v = f.Permute( - f.LoadConstant(0x02060307), - f.LoadVR(va), - f.LoadVR(vb), - INT32_TYPE); + Value* v = f.Permute(f.LoadConstant(0x02060307), f.LoadVR(va), f.LoadVR(vb), + INT32_TYPE); f.StoreVR(vd, v); return 0; } -XEEMITTER(vmrglw, 0x1000018C, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmrglw, 0x1000018C, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vmrglw_(f, i.VX.VD, i.VX.VA, i.VX.VB); } -XEEMITTER(vmrglw128, VX128(6, 832), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmrglw128, VX128(6, 832), VX128)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vmrglw_(f, VX128_VD128, VX128_VA128, VX128_VB128); } -XEEMITTER(vmsummbm, 0x10000025, VXA )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmsummbm, 0x10000025, VXA)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmsumshm, 0x10000028, VXA )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmsumshm, 0x10000028, VXA)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmsumshs, 0x10000029, VXA )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmsumshs, 0x10000029, VXA)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmsumubm, 0x10000024, VXA )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmsumubm, 0x10000024, VXA)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmsumuhm, 0x10000026, VXA )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmsumuhm, 0x10000026, VXA)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmsumuhs, 0x10000027, VXA )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmsumuhs, 0x10000027, VXA)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmsum3fp128, VX128(5, 400), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmsum3fp128, VX128(5, 400), VX128)(PPCHIRBuilder& f, InstrData& i) { // Dot product XYZ. // (VD.xyzw) = (VA.x * VB.x) + (VA.y * VB.y) + (VA.z * VB.z) Value* v = f.DotProduct3(f.LoadVR(VX128_VA128), f.LoadVR(VX128_VB128)); @@ -1006,7 +983,7 @@ XEEMITTER(vmsum3fp128, VX128(5, 400), VX128 )(PPCHIRBuilder& f, InstrData return 0; } -XEEMITTER(vmsum4fp128, VX128(5, 464), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmsum4fp128, VX128(5, 464), VX128)(PPCHIRBuilder& f, InstrData& i) { // Dot product XYZW. // (VD.xyzw) = (VA.x * VB.x) + (VA.y * VB.y) + (VA.z * VB.z) + (VA.w * VB.w) Value* v = f.DotProduct4(f.LoadVR(VX128_VA128), f.LoadVR(VX128_VB128)); @@ -1015,54 +992,55 @@ XEEMITTER(vmsum4fp128, VX128(5, 464), VX128 )(PPCHIRBuilder& f, InstrData return 0; } -XEEMITTER(vmulesb, 0x10000308, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmulesb, 0x10000308, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmulesh, 0x10000348, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmulesh, 0x10000348, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmuleub, 0x10000208, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmuleub, 0x10000208, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmuleuh, 0x10000248, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmuleuh, 0x10000248, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmulosb, 0x10000108, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmulosb, 0x10000108, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmulosh, 0x10000148, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmulosh, 0x10000148, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmuloub, 0x10000008, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmuloub, 0x10000008, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmulouh, 0x10000048, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmulouh, 0x10000048, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vmulfp128, VX128(5, 144), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vmulfp128, VX128(5, 144), VX128)(PPCHIRBuilder& f, InstrData& i) { // (VD) <- (VA) * (VB) (4 x fp) Value* v = f.Mul(f.LoadVR(VX128_VA128), f.LoadVR(VX128_VB128)); f.StoreVR(VX128_VD128, v); return 0; } -int InstrEmit_vnmsubfp_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, uint32_t vc) { +int InstrEmit_vnmsubfp_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, + uint32_t vc) { // (VD) <- -(((VA) * (VC)) - (VB)) // NOTE: only one rounding should take place, but that's hard... // This really needs VFNMSUB132PS/VFNMSUB213PS/VFNMSUB231PS but that's AVX. @@ -1070,11 +1048,12 @@ int InstrEmit_vnmsubfp_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, f.StoreVR(vd, v); return 0; } -XEEMITTER(vnmsubfp, 0x1000002F, VXA )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vnmsubfp, 0x1000002F, VXA)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vnmsubfp_(f, i.VXA.VD, i.VXA.VA, i.VXA.VB, i.VXA.VC); } -XEEMITTER(vnmsubfp128, VX128(5, 336), VX128 )(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_vnmsubfp_(f, VX128_VD128, VX128_VA128, VX128_VB128, VX128_VD128); +XEEMITTER(vnmsubfp128, VX128(5, 336), VX128)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vnmsubfp_(f, VX128_VD128, VX128_VA128, VX128_VB128, + VX128_VD128); } int InstrEmit_vnor_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { @@ -1083,10 +1062,10 @@ int InstrEmit_vnor_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vnor, 0x10000504, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vnor, 0x10000504, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vnor_(f, i.VX.VD, i.VX.VA, i.VX.VB); } -XEEMITTER(vnor128, VX128(5, 656), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vnor128, VX128(5, 656), VX128)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vnor_(f, VX128_VD128, VX128_VA128, VX128_VB128); } @@ -1101,26 +1080,29 @@ int InstrEmit_vor_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { } return 0; } -XEEMITTER(vor, 0x10000484, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vor, 0x10000484, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vor_(f, i.VX.VD, i.VX.VA, i.VX.VB); } -XEEMITTER(vor128, VX128(5, 720), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vor128, VX128(5, 720), VX128)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vor_(f, VX128_VD128, VX128_VA128, VX128_VB128); } -int InstrEmit_vperm_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, uint32_t vc) { +int InstrEmit_vperm_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, + uint32_t vc) { Value* v = f.Permute(f.LoadVR(vc), f.LoadVR(va), f.LoadVR(vb), INT8_TYPE); f.StoreVR(vd, v); return 0; } -XEEMITTER(vperm, 0x1000002B, VXA )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vperm, 0x1000002B, VXA)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vperm_(f, i.VXA.VD, i.VXA.VA, i.VXA.VB, i.VXA.VC); } -XEEMITTER(vperm128, VX128_2(5, 0), VX128_2)(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_vperm_(f, VX128_2_VD128, VX128_2_VA128, VX128_2_VB128, VX128_2_VC); +XEEMITTER(vperm128, VX128_2(5, 0), VX128_2)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vperm_(f, VX128_2_VD128, VX128_2_VA128, VX128_2_VB128, + VX128_2_VC); } -XEEMITTER(vpermwi128, VX128_P(6, 528), VX128_P)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vpermwi128, VX128_P(6, 528), VX128_P)(PPCHIRBuilder& f, + InstrData& i) { // (VD.x) = (VB.uimm[6-7]) // (VD.y) = (VB.uimm[4-5]) // (VD.z) = (VB.uimm[2-3]) @@ -1135,15 +1117,15 @@ XEEMITTER(vpermwi128, VX128_P(6, 528), VX128_P)(PPCHIRBuilder& f, InstrData int InstrEmit_vrefp_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { // (VD) <- 1/(VB) - vec128_t one = { 1, 1, 1, 1 }; + vec128_t one = {1, 1, 1, 1}; Value* v = f.Div(f.LoadConstant(one), f.LoadVR(vb)); f.StoreVR(vd, v); return 0; } -XEEMITTER(vrefp, 0x1000010A, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vrefp, 0x1000010A, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vrefp_(f, i.VX.VD, i.VX.VB); } -XEEMITTER(vrefp128, VX128_3(6, 1584), VX128_3)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vrefp128, VX128_3(6, 1584), VX128_3)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vrefp_(f, VX128_3_VD128, VX128_3_VB128); } @@ -1153,10 +1135,10 @@ int InstrEmit_vrfim_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vrfim, 0x100002CA, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vrfim, 0x100002CA, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vrfim_(f, i.VX.VD, i.VX.VB); } -XEEMITTER(vrfim128, VX128_3(6, 816), VX128_3)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vrfim128, VX128_3(6, 816), VX128_3)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vrfim_(f, VX128_3_VD128, VX128_3_VB128); } @@ -1166,10 +1148,10 @@ int InstrEmit_vrfin_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vrfin, 0x1000020A, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vrfin, 0x1000020A, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vrfin_(f, i.VX.VD, i.VX.VB); } -XEEMITTER(vrfin128, VX128_3(6, 880), VX128_3)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vrfin128, VX128_3(6, 880), VX128_3)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vrfin_(f, VX128_3_VD128, VX128_3_VB128); } @@ -1179,10 +1161,10 @@ int InstrEmit_vrfip_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vrfip, 0x1000028A, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vrfip, 0x1000028A, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vrfip_(f, i.VX.VD, i.VX.VB); } -XEEMITTER(vrfip128, VX128_3(6, 944), VX128_3)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vrfip128, VX128_3(6, 944), VX128_3)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vrfip_(f, VX128_3_VD128, VX128_3_VB128); } @@ -1192,33 +1174,34 @@ int InstrEmit_vrfiz_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vrfiz, 0x1000024A, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vrfiz, 0x1000024A, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vrfiz_(f, i.VX.VD, i.VX.VB); } -XEEMITTER(vrfiz128, VX128_3(6, 1008), VX128_3)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vrfiz128, VX128_3(6, 1008), VX128_3)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vrfiz_(f, VX128_3_VD128, VX128_3_VB128); } -XEEMITTER(vrlb, 0x10000004, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vrlb, 0x10000004, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vrlh, 0x10000044, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vrlh, 0x10000044, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vrlw, 0x10000084, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vrlw, 0x10000084, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vrlw128, VX128(6, 80), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vrlw128, VX128(6, 80), VX128)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vrlimi128, VX128_4(6, 1808), VX128_4)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vrlimi128, VX128_4(6, 1808), VX128_4)(PPCHIRBuilder& f, + InstrData& i) { const uint32_t vd = i.VX128_4.VD128l | (i.VX128_4.VD128h << 5); const uint32_t vb = i.VX128_4.VB128l | (i.VX128_4.VB128h << 5); uint32_t blend_mask_src = i.VX128_4.IMM; @@ -1237,27 +1220,28 @@ XEEMITTER(vrlimi128, VX128_4(6, 1808), VX128_4)(PPCHIRBuilder& f, InstrData // TODO(benvanik): constants need conversion. uint32_t swizzle_mask; switch (rotate) { - case 1: - // X Y Z W -> Y Z W X - swizzle_mask = SWIZZLE_XYZW_TO_YZWX; - break; - case 2: - // X Y Z W -> Z W X Y - swizzle_mask = SWIZZLE_XYZW_TO_ZWXY; - break; - case 3: - // X Y Z W -> W X Y Z - swizzle_mask = SWIZZLE_XYZW_TO_WXYZ; - break; - default: XEASSERTALWAYS(); return 1; + case 1: + // X Y Z W -> Y Z W X + swizzle_mask = SWIZZLE_XYZW_TO_YZWX; + break; + case 2: + // X Y Z W -> Z W X Y + swizzle_mask = SWIZZLE_XYZW_TO_ZWXY; + break; + case 3: + // X Y Z W -> W X Y Z + swizzle_mask = SWIZZLE_XYZW_TO_WXYZ; + break; + default: + XEASSERTALWAYS(); + return 1; } v = f.Swizzle(f.LoadVR(vb), FLOAT32_TYPE, swizzle_mask); } else { v = f.LoadVR(vb); } if (blend_mask != 0x00010203) { - v = f.Permute( - f.LoadConstant(blend_mask), v, f.LoadVR(vd), INT32_TYPE); + v = f.Permute(f.LoadConstant(blend_mask), v, f.LoadVR(vd), INT32_TYPE); } f.StoreVR(vd, v); return 0; @@ -1272,38 +1256,40 @@ int InstrEmit_vrsqrtefp_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vrsqrtefp, 0x1000014A, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vrsqrtefp, 0x1000014A, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vrsqrtefp_(f, i.VX.VD, i.VX.VB); } -XEEMITTER(vrsqrtefp128, VX128_3(6, 1648), VX128_3)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vrsqrtefp128, VX128_3(6, 1648), VX128_3)(PPCHIRBuilder& f, + InstrData& i) { return InstrEmit_vrsqrtefp_(f, VX128_3_VD128, VX128_3_VB128); } -int InstrEmit_vsel_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, uint32_t vc) { +int InstrEmit_vsel_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, + uint32_t vc) { Value* a = f.LoadVR(va); Value* v = f.Xor(f.And(f.Xor(a, f.LoadVR(vb)), f.LoadVR(vc)), a); f.StoreVR(vd, v); return 0; } -XEEMITTER(vsel, 0x1000002A, VXA )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsel, 0x1000002A, VXA)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vsel_(f, i.VXA.VD, i.VXA.VA, i.VXA.VB, i.VXA.VC); } -XEEMITTER(vsel128, VX128(5, 848), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsel128, VX128(5, 848), VX128)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vsel_(f, VX128_VD128, VX128_VA128, VX128_VB128, VX128_VD128); } -XEEMITTER(vsl, 0x100001C4, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsl, 0x100001C4, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vslb, 0x10000104, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vslb, 0x10000104, VX)(PPCHIRBuilder& f, InstrData& i) { Value* v = f.VectorShl(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT8_TYPE); f.StoreVR(i.VX.VD, v); return 0; } -XEEMITTER(vslh, 0x10000144, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vslh, 0x10000144, VX)(PPCHIRBuilder& f, InstrData& i) { Value* v = f.VectorShl(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT16_TYPE); f.StoreVR(i.VX.VD, v); return 0; @@ -1317,32 +1303,33 @@ int InstrEmit_vslw_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vslw, 0x10000184, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vslw, 0x10000184, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vslw_(f, i.VX.VD, i.VX.VA, i.VX.VB); } -XEEMITTER(vslw128, VX128(6, 208), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vslw128, VX128(6, 208), VX128)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vslw_(f, VX128_VD128, VX128_VA128, VX128_VB128); } static uint8_t __vsldoi_table[16][16] = { - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, - { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, - { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, - { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}, - { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}, - { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, - { 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}, - { 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}, - { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}, - { 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}, - {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}, - {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}, - {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27}, - {13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28}, - {14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}, - {15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, + {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}, + {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}, + {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, + {6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}, + {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}, + {8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}, + {9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}, + {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}, + {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}, + {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27}, + {13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28}, + {14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}, + {15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}, }; -int InstrEmit_vsldoi_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, uint32_t sh) { +int InstrEmit_vsldoi_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, + uint32_t sh) { // (VD) <- ((VA) || (VB)) << (SH << 3) if (!sh) { f.StoreVR(vd, f.LoadVR(va)); @@ -1358,30 +1345,28 @@ int InstrEmit_vsldoi_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, u vec128_t shift = *((vec128_t*)(__vsldoi_table[sh])); for (int i = 0; i < 4; ++i) shift.i4[i] = XESWAP32BE(shift.i4[i]); Value* control = f.LoadConstant(shift); - Value* v = f.Permute( - control, - f.LoadVR(va), - f.LoadVR(vb), INT8_TYPE); + Value* v = f.Permute(control, f.LoadVR(va), f.LoadVR(vb), INT8_TYPE); f.StoreVR(vd, v); return 0; } -XEEMITTER(vsldoi, 0x1000002C, VXA )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsldoi, 0x1000002C, VXA)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vsldoi_(f, i.VXA.VD, i.VXA.VA, i.VXA.VB, i.VXA.VC & 0xF); } -XEEMITTER(vsldoi128, VX128_5(4, 16), VX128_5)(PPCHIRBuilder& f, InstrData& i) { - return InstrEmit_vsldoi_(f, VX128_5_VD128, VX128_5_VA128, VX128_5_VB128, VX128_5_SH); +XEEMITTER(vsldoi128, VX128_5(4, 16), VX128_5)(PPCHIRBuilder& f, InstrData& i) { + return InstrEmit_vsldoi_(f, VX128_5_VD128, VX128_5_VA128, VX128_5_VB128, + VX128_5_SH); } -XEEMITTER(vslo, 0x1000040C, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vslo, 0x1000040C, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vslo128, VX128(5, 912), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vslo128, VX128(5, 912), VX128)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vspltb, 0x1000020C, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vspltb, 0x1000020C, VX)(PPCHIRBuilder& f, InstrData& i) { // b <- UIMM*8 // do i = 0 to 127 by 8 // (VD)[i:i+7] <- (VB)[b:b+7] @@ -1391,7 +1376,7 @@ XEEMITTER(vspltb, 0x1000020C, VX )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(vsplth, 0x1000024C, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsplth, 0x1000024C, VX)(PPCHIRBuilder& f, InstrData& i) { // (VD.xyzw) <- (VB.uimm) Value* h = f.Extract(f.LoadVR(i.VX.VB), (i.VX.VA & 0x7), INT16_TYPE); Value* v = f.Splat(h, VEC128_TYPE); @@ -1399,21 +1384,23 @@ XEEMITTER(vsplth, 0x1000024C, VX )(PPCHIRBuilder& f, InstrData& i) { return 0; } -int InstrEmit_vspltw_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm) { +int InstrEmit_vspltw_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, + uint32_t uimm) { // (VD.xyzw) <- (VB.uimm) Value* w = f.Extract(f.LoadVR(vb), (uimm & 0x3), INT32_TYPE); Value* v = f.Splat(w, VEC128_TYPE); f.StoreVR(vd, v); return 0; } -XEEMITTER(vspltw, 0x1000028C, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vspltw, 0x1000028C, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vspltw_(f, i.VX.VD, i.VX.VB, i.VX.VA); } -XEEMITTER(vspltw128, VX128_3(6, 1840), VX128_3)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vspltw128, VX128_3(6, 1840), VX128_3)(PPCHIRBuilder& f, + InstrData& i) { return InstrEmit_vspltw_(f, VX128_3_VD128, VX128_3_VB128, VX128_3_IMM); } -XEEMITTER(vspltisb, 0x1000030C, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vspltisb, 0x1000030C, VX)(PPCHIRBuilder& f, InstrData& i) { // (VD.xyzw) <- sign_extend(uimm) Value* v; if (i.VX.VA) { @@ -1428,7 +1415,7 @@ XEEMITTER(vspltisb, 0x1000030C, VX )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(vspltish, 0x1000034C, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vspltish, 0x1000034C, VX)(PPCHIRBuilder& f, InstrData& i) { // (VD.xyzw) <- sign_extend(uimm) Value* v; if (i.VX.VA) { @@ -1457,26 +1444,27 @@ int InstrEmit_vspltisw_(PPCHIRBuilder& f, uint32_t vd, uint32_t uimm) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vspltisw, 0x1000038C, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vspltisw, 0x1000038C, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vspltisw_(f, i.VX.VD, i.VX.VA); } -XEEMITTER(vspltisw128, VX128_3(6, 1904), VX128_3)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vspltisw128, VX128_3(6, 1904), VX128_3)(PPCHIRBuilder& f, + InstrData& i) { return InstrEmit_vspltisw_(f, VX128_3_VD128, VX128_3_IMM); } -XEEMITTER(vsr, 0x100002C4, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsr, 0x100002C4, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vsrab, 0x10000304, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsrab, 0x10000304, VX)(PPCHIRBuilder& f, InstrData& i) { // (VD) <- (VA) >>a (VB) by bytes Value* v = f.VectorSha(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT8_TYPE); f.StoreVR(i.VX.VD, v); return 0; } -XEEMITTER(vsrah, 0x10000344, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsrah, 0x10000344, VX)(PPCHIRBuilder& f, InstrData& i) { // (VD) <- (VA) >>a (VB) by halfwords Value* v = f.VectorSha(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT16_TYPE); f.StoreVR(i.VX.VD, v); @@ -1489,21 +1477,21 @@ int InstrEmit_vsraw_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vsraw, 0x10000384, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsraw, 0x10000384, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vsraw_(f, i.VX.VD, i.VX.VA, i.VX.VB); } -XEEMITTER(vsraw128, VX128(6, 336), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsraw128, VX128(6, 336), VX128)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vsraw_(f, VX128_VD128, VX128_VA128, VX128_VB128); } -XEEMITTER(vsrb, 0x10000204, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsrb, 0x10000204, VX)(PPCHIRBuilder& f, InstrData& i) { // (VD) <- (VA) >> (VB) by bytes Value* v = f.VectorShr(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT8_TYPE); f.StoreVR(i.VX.VD, v); return 0; } -XEEMITTER(vsrh, 0x10000244, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsrh, 0x10000244, VX)(PPCHIRBuilder& f, InstrData& i) { // (VD) <- (VA) >> (VB) by halfwords Value* v = f.VectorShr(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT16_TYPE); f.StoreVR(i.VX.VD, v); @@ -1513,10 +1501,10 @@ XEEMITTER(vsrh, 0x10000244, VX )(PPCHIRBuilder& f, InstrData& i) { int InstrEmit_vsro_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { return 1; } -XEEMITTER(vsro, 0x1000044C, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsro, 0x1000044C, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vsro_(f, i.VX.VD, i.VX.VA, i.VX.VB); } -XEEMITTER(vsro128, VX128(5, 976), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsro128, VX128(5, 976), VX128)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vsro_(f, VX128_VD128, VX128_VA128, VX128_VB128); } @@ -1526,14 +1514,14 @@ int InstrEmit_vsrw_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vsrw, 0x10000284, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsrw, 0x10000284, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vsrw_(f, i.VX.VD, i.VX.VA, i.VX.VB); } -XEEMITTER(vsrw128, VX128(6, 464), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsrw128, VX128(6, 464), VX128)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vsrw_(f, VX128_VD128, VX128_VA128, VX128_VB128); } -XEEMITTER(vsubcuw, 0x10000580, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsubcuw, 0x10000580, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } @@ -1544,166 +1532,166 @@ int InstrEmit_vsubfp_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vsubfp, 0x1000004A, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsubfp, 0x1000004A, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vsubfp_(f, i.VX.VD, i.VX.VA, i.VX.VB); } -XEEMITTER(vsubfp128, VX128(5, 80), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsubfp128, VX128(5, 80), VX128)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vsubfp_(f, VX128_VD128, VX128_VA128, VX128_VB128); } -XEEMITTER(vsubsbs, 0x10000700, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsubsbs, 0x10000700, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vsubshs, 0x10000740, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsubshs, 0x10000740, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vsubsws, 0x10000780, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsubsws, 0x10000780, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vsububm, 0x10000400, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsububm, 0x10000400, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vsububs, 0x10000600, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsububs, 0x10000600, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vsubuhm, 0x10000440, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsubuhm, 0x10000440, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vsubuhs, 0x10000640, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsubuhs, 0x10000640, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vsubuwm, 0x10000480, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsubuwm, 0x10000480, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vsubuws, 0x10000680, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsubuws, 0x10000680, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vsumsws, 0x10000788, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsumsws, 0x10000788, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vsum2sws, 0x10000688, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsum2sws, 0x10000688, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vsum4sbs, 0x10000708, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsum4sbs, 0x10000708, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vsum4shs, 0x10000648, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsum4shs, 0x10000648, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vsum4ubs, 0x10000608, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vsum4ubs, 0x10000608, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vpkpx, 0x1000030E, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vpkpx, 0x1000030E, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vpkshss, 0x1000018E, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vpkshss, 0x1000018E, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vpkshss128, VX128(5, 512), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vpkshss128, VX128(5, 512), VX128)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vpkswss, 0x100001CE, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vpkswss, 0x100001CE, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vpkswss128, VX128(5, 640), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vpkswss128, VX128(5, 640), VX128)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vpkswus, 0x1000014E, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vpkswus, 0x1000014E, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vpkswus128, VX128(5, 704), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vpkswus128, VX128(5, 704), VX128)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vpkuhum, 0x1000000E, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vpkuhum, 0x1000000E, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vpkuhum128, VX128(5, 768), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vpkuhum128, VX128(5, 768), VX128)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vpkuhus, 0x1000008E, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vpkuhus, 0x1000008E, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vpkuhus128, VX128(5, 832), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vpkuhus128, VX128(5, 832), VX128)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vpkshus, 0x1000010E, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vpkshus, 0x1000010E, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vpkshus128, VX128(5, 576), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vpkshus128, VX128(5, 576), VX128)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vpkuwum, 0x1000004E, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vpkuwum, 0x1000004E, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vpkuwum128, VX128(5, 896), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vpkuwum128, VX128(5, 896), VX128)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vpkuwus, 0x100000CE, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vpkuwus, 0x100000CE, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vpkuwus128, VX128(5, 960), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vpkuwus128, VX128(5, 960), VX128)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vupkhpx, 0x1000034E, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vupkhpx, 0x1000034E, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vupklpx, 0x100003CE, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vupklpx, 0x100003CE, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } @@ -1714,10 +1702,10 @@ int InstrEmit_vupkhsh_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vupkhsh, 0x1000024E, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vupkhsh, 0x1000024E, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vupkhsh_(f, i.VX.VD, i.VX.VB); } -XEEMITTER(vupkhsh128, 0x100002CE, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vupkhsh128, 0x100002CE, VX)(PPCHIRBuilder& f, InstrData& i) { uint32_t va = VX128_VA128; XEASSERTZERO(va); return InstrEmit_vupkhsh_(f, VX128_VD128, VX128_VB128); @@ -1729,10 +1717,10 @@ int InstrEmit_vupklsh_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vupklsh, 0x100002CE, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vupklsh, 0x100002CE, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vupklsh_(f, i.VX.VD, i.VX.VB); } -XEEMITTER(vupklsh128, 0x100002CE, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vupklsh128, 0x100002CE, VX)(PPCHIRBuilder& f, InstrData& i) { uint32_t va = VX128_VA128; XEASSERTZERO(va); return InstrEmit_vupklsh_(f, VX128_VD128, VX128_VB128); @@ -1744,10 +1732,10 @@ int InstrEmit_vupkhsb_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vupkhsb, 0x1000020E, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vupkhsb, 0x1000020E, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vupkhsb_(f, i.VX.VD, i.VX.VB); } -XEEMITTER(vupkhsb128, VX128(6, 896), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vupkhsb128, VX128(6, 896), VX128)(PPCHIRBuilder& f, InstrData& i) { uint32_t va = VX128_VA128; if (va == 0x60) { // Hrm, my instruction tables suck. @@ -1762,10 +1750,10 @@ int InstrEmit_vupklsb_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vupklsb, 0x1000028E, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vupklsb, 0x1000028E, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vupklsb_(f, i.VX.VD, i.VX.VB); } -XEEMITTER(vupklsb128, VX128(6, 960), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vupklsb128, VX128(6, 960), VX128)(PPCHIRBuilder& f, InstrData& i) { uint32_t va = VX128_VA128; if (va == 0x60) { // Hrm, my instruction tables suck. @@ -1774,7 +1762,8 @@ XEEMITTER(vupklsb128, VX128(6, 960), VX128 )(PPCHIRBuilder& f, InstrData return InstrEmit_vupklsb_(f, VX128_VD128, VX128_VB128); } -XEEMITTER(vpkd3d128, VX128_4(6, 1552), VX128_4)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vpkd3d128, VX128_4(6, 1552), VX128_4)(PPCHIRBuilder& f, + InstrData& i) { const uint32_t vd = i.VX128_4.VD128l | (i.VX128_4.VD128h << 5); const uint32_t vb = i.VX128_4.VB128l | (i.VX128_4.VB128h << 5); uint32_t type = i.VX128_4.IMM >> 2; @@ -1782,63 +1771,64 @@ XEEMITTER(vpkd3d128, VX128_4(6, 1552), VX128_4)(PPCHIRBuilder& f, InstrData uint32_t pack = i.VX128_4.z; Value* v = f.LoadVR(vb); switch (type) { - case 0: // VPACK_D3DCOLOR - v = f.Pack(v, PACK_TYPE_D3DCOLOR); - break; - case 1: // VPACK_NORMSHORT2 - v = f.Pack(v, PACK_TYPE_SHORT_2); - break; - case 3: // VPACK_... 2 FLOAT16s DXGI_FORMAT_R16G16_FLOAT - v = f.Pack(v, PACK_TYPE_FLOAT16_2); - break; - case 5: // VPACK_... 4 FLOAT16s DXGI_FORMAT_R16G16B16A16_FLOAT - v = f.Pack(v, PACK_TYPE_FLOAT16_4); - break; - default: - XEASSERTALWAYS(); - return 1; + case 0: // VPACK_D3DCOLOR + v = f.Pack(v, PACK_TYPE_D3DCOLOR); + break; + case 1: // VPACK_NORMSHORT2 + v = f.Pack(v, PACK_TYPE_SHORT_2); + break; + case 3: // VPACK_... 2 FLOAT16s DXGI_FORMAT_R16G16_FLOAT + v = f.Pack(v, PACK_TYPE_FLOAT16_2); + break; + case 5: // VPACK_... 4 FLOAT16s DXGI_FORMAT_R16G16B16A16_FLOAT + v = f.Pack(v, PACK_TYPE_FLOAT16_4); + break; + default: + XEASSERTALWAYS(); + return 1; } // http://hlssmod.net/he_code/public/pixelwriter.h // control = prev:0123 | new:4567 - uint32_t control = 0x00010203; // original + uint32_t control = 0x00010203; // original uint32_t src = xerotl(0x04050607, shift * 8); uint32_t mask = 0; switch (pack) { - case 1: // VPACK_32 - // VPACK_32 & shift = 3 puts lower 32 bits in x (leftmost slot). - mask = 0x000000FF << (shift * 8); - control = (control & ~mask) | (src & mask); - break; - case 2: // 64bit - if (shift < 3) { - mask = 0x0000FFFF << (shift * 8); - } else { - // w - src = 0x00000007; - mask = 0x000000FF; - } - control = (control & ~mask) | (src & mask); - break; - case 3: // 64bit - if (shift < 3) { - mask = 0x0000FFFF << (shift * 8); - } else { - // z - src = 0x00000006; - mask = 0x000000FF; - } - control = (control & ~mask) | (src & mask); - break; - default: - XEASSERTALWAYS(); - return 1; + case 1: // VPACK_32 + // VPACK_32 & shift = 3 puts lower 32 bits in x (leftmost slot). + mask = 0x000000FF << (shift * 8); + control = (control & ~mask) | (src & mask); + break; + case 2: // 64bit + if (shift < 3) { + mask = 0x0000FFFF << (shift * 8); + } else { + // w + src = 0x00000007; + mask = 0x000000FF; + } + control = (control & ~mask) | (src & mask); + break; + case 3: // 64bit + if (shift < 3) { + mask = 0x0000FFFF << (shift * 8); + } else { + // z + src = 0x00000006; + mask = 0x000000FF; + } + control = (control & ~mask) | (src & mask); + break; + default: + XEASSERTALWAYS(); + return 1; } v = f.Permute(f.LoadConstant(control), f.LoadVR(vd), v, INT32_TYPE); f.StoreVR(vd, v); return 0; } -XEEMITTER(vupkd3d128, VX128_3(6, 2032), VX128_3)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vupkd3d128, VX128_3(6, 2032), VX128_3)(PPCHIRBuilder& f, + InstrData& i) { // Can't find many docs on this. Best reference is // http://worldcraft.googlecode.com/svn/trunk/src/qylib/math/xmmatrix.inl, // which shows how it's used in some cases. Since it's all intrinsics, @@ -1848,21 +1838,21 @@ XEEMITTER(vupkd3d128, VX128_3(6, 2032), VX128_3)(PPCHIRBuilder& f, InstrData const uint32_t type = i.VX128_3.IMM >> 2; Value* v = f.LoadVR(vb); switch (type) { - case 0: // VPACK_D3DCOLOR - v = f.Unpack(v, PACK_TYPE_D3DCOLOR); - break; - case 1: // VPACK_NORMSHORT2 - v = f.Unpack(v, PACK_TYPE_SHORT_2); - break; - case 3: // VPACK_... 2 FLOAT16s DXGI_FORMAT_R16G16_FLOAT - v = f.Unpack(v, PACK_TYPE_FLOAT16_2); - break; - case 5: // VPACK_... 4 FLOAT16s DXGI_FORMAT_R16G16B16A16_FLOAT - v = f.Unpack(v, PACK_TYPE_FLOAT16_4); - break; - default: - XEASSERTALWAYS(); - return 1; + case 0: // VPACK_D3DCOLOR + v = f.Unpack(v, PACK_TYPE_D3DCOLOR); + break; + case 1: // VPACK_NORMSHORT2 + v = f.Unpack(v, PACK_TYPE_SHORT_2); + break; + case 3: // VPACK_... 2 FLOAT16s DXGI_FORMAT_R16G16_FLOAT + v = f.Unpack(v, PACK_TYPE_FLOAT16_2); + break; + case 5: // VPACK_... 4 FLOAT16s DXGI_FORMAT_R16G16B16A16_FLOAT + v = f.Unpack(v, PACK_TYPE_FLOAT16_4); + break; + default: + XEASSERTALWAYS(); + return 1; } f.StoreVR(vd, v); return 0; @@ -1880,261 +1870,259 @@ int InstrEmit_vxor_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { f.StoreVR(vd, v); return 0; } -XEEMITTER(vxor, 0x100004C4, VX )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vxor, 0x100004C4, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vxor_(f, i.VX.VD, i.VX.VA, i.VX.VB); } -XEEMITTER(vxor128, VX128(5, 784), VX128 )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(vxor128, VX128(5, 784), VX128)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vxor_(f, VX128_VD128, VX128_VA128, VX128_VB128); } - void RegisterEmitCategoryAltivec() { - XEREGISTERINSTR(dst, 0x7C0002AC); - XEREGISTERINSTR(dstst, 0x7C0002EC); - XEREGISTERINSTR(dss, 0x7C00066C); - XEREGISTERINSTR(lvebx, 0x7C00000E); - XEREGISTERINSTR(lvehx, 0x7C00004E); - XEREGISTERINSTR(lvewx, 0x7C00008E); - XEREGISTERINSTR(lvewx128, VX128_1(4, 131)); - XEREGISTERINSTR(lvsl, 0x7C00000C); - XEREGISTERINSTR(lvsl128, VX128_1(4, 3)); - XEREGISTERINSTR(lvsr, 0x7C00004C); - XEREGISTERINSTR(lvsr128, VX128_1(4, 67)); - XEREGISTERINSTR(lvx, 0x7C0000CE); - XEREGISTERINSTR(lvx128, VX128_1(4, 195)); - XEREGISTERINSTR(lvxl, 0x7C0002CE); - XEREGISTERINSTR(lvxl128, VX128_1(4, 707)); - XEREGISTERINSTR(stvebx, 0x7C00010E); - XEREGISTERINSTR(stvehx, 0x7C00014E); - XEREGISTERINSTR(stvewx, 0x7C00018E); - XEREGISTERINSTR(stvewx128, VX128_1(4, 387)); - XEREGISTERINSTR(stvx, 0x7C0001CE); - XEREGISTERINSTR(stvx128, VX128_1(4, 451)); - XEREGISTERINSTR(stvxl, 0x7C0003CE); - XEREGISTERINSTR(stvxl128, VX128_1(4, 963)); - XEREGISTERINSTR(lvlx, 0x7C00040E); - XEREGISTERINSTR(lvlx128, VX128_1(4, 1027)); - XEREGISTERINSTR(lvlxl, 0x7C00060E); - XEREGISTERINSTR(lvlxl128, VX128_1(4, 1539)); - XEREGISTERINSTR(lvrx, 0x7C00044E); - XEREGISTERINSTR(lvrx128, VX128_1(4, 1091)); - XEREGISTERINSTR(lvrxl, 0x7C00064E); - XEREGISTERINSTR(lvrxl128, VX128_1(4, 1603)); - XEREGISTERINSTR(stvlx, 0x7C00050E); - XEREGISTERINSTR(stvlx128, VX128_1(4, 1283)); - XEREGISTERINSTR(stvlxl, 0x7C00070E); - XEREGISTERINSTR(stvlxl128, VX128_1(4, 1795)); - XEREGISTERINSTR(stvrx, 0x7C00054E); - XEREGISTERINSTR(stvrx128, VX128_1(4, 1347)); - XEREGISTERINSTR(stvrxl, 0x7C00074E); - XEREGISTERINSTR(stvrxl128, VX128_1(4, 1859)); + XEREGISTERINSTR(dst, 0x7C0002AC); + XEREGISTERINSTR(dstst, 0x7C0002EC); + XEREGISTERINSTR(dss, 0x7C00066C); + XEREGISTERINSTR(lvebx, 0x7C00000E); + XEREGISTERINSTR(lvehx, 0x7C00004E); + XEREGISTERINSTR(lvewx, 0x7C00008E); + XEREGISTERINSTR(lvewx128, VX128_1(4, 131)); + XEREGISTERINSTR(lvsl, 0x7C00000C); + XEREGISTERINSTR(lvsl128, VX128_1(4, 3)); + XEREGISTERINSTR(lvsr, 0x7C00004C); + XEREGISTERINSTR(lvsr128, VX128_1(4, 67)); + XEREGISTERINSTR(lvx, 0x7C0000CE); + XEREGISTERINSTR(lvx128, VX128_1(4, 195)); + XEREGISTERINSTR(lvxl, 0x7C0002CE); + XEREGISTERINSTR(lvxl128, VX128_1(4, 707)); + XEREGISTERINSTR(stvebx, 0x7C00010E); + XEREGISTERINSTR(stvehx, 0x7C00014E); + XEREGISTERINSTR(stvewx, 0x7C00018E); + XEREGISTERINSTR(stvewx128, VX128_1(4, 387)); + XEREGISTERINSTR(stvx, 0x7C0001CE); + XEREGISTERINSTR(stvx128, VX128_1(4, 451)); + XEREGISTERINSTR(stvxl, 0x7C0003CE); + XEREGISTERINSTR(stvxl128, VX128_1(4, 963)); + XEREGISTERINSTR(lvlx, 0x7C00040E); + XEREGISTERINSTR(lvlx128, VX128_1(4, 1027)); + XEREGISTERINSTR(lvlxl, 0x7C00060E); + XEREGISTERINSTR(lvlxl128, VX128_1(4, 1539)); + XEREGISTERINSTR(lvrx, 0x7C00044E); + XEREGISTERINSTR(lvrx128, VX128_1(4, 1091)); + XEREGISTERINSTR(lvrxl, 0x7C00064E); + XEREGISTERINSTR(lvrxl128, VX128_1(4, 1603)); + XEREGISTERINSTR(stvlx, 0x7C00050E); + XEREGISTERINSTR(stvlx128, VX128_1(4, 1283)); + XEREGISTERINSTR(stvlxl, 0x7C00070E); + XEREGISTERINSTR(stvlxl128, VX128_1(4, 1795)); + XEREGISTERINSTR(stvrx, 0x7C00054E); + XEREGISTERINSTR(stvrx128, VX128_1(4, 1347)); + XEREGISTERINSTR(stvrxl, 0x7C00074E); + XEREGISTERINSTR(stvrxl128, VX128_1(4, 1859)); - XEREGISTERINSTR(mfvscr, 0x10000604); - XEREGISTERINSTR(mtvscr, 0x10000644); - XEREGISTERINSTR(vaddcuw, 0x10000180); - XEREGISTERINSTR(vaddfp, 0x1000000A); - XEREGISTERINSTR(vaddfp128, VX128(5, 16)); - XEREGISTERINSTR(vaddsbs, 0x10000300); - XEREGISTERINSTR(vaddshs, 0x10000340); - XEREGISTERINSTR(vaddsws, 0x10000380); - XEREGISTERINSTR(vaddubm, 0x10000000); - XEREGISTERINSTR(vaddubs, 0x10000200); - XEREGISTERINSTR(vadduhm, 0x10000040); - XEREGISTERINSTR(vadduhs, 0x10000240); - XEREGISTERINSTR(vadduwm, 0x10000080); - XEREGISTERINSTR(vadduws, 0x10000280); - XEREGISTERINSTR(vand, 0x10000404); - XEREGISTERINSTR(vand128, VX128(5, 528)); - XEREGISTERINSTR(vandc, 0x10000444); - XEREGISTERINSTR(vandc128, VX128(5, 592)); - XEREGISTERINSTR(vavgsb, 0x10000502); - XEREGISTERINSTR(vavgsh, 0x10000542); - XEREGISTERINSTR(vavgsw, 0x10000582); - XEREGISTERINSTR(vavgub, 0x10000402); - XEREGISTERINSTR(vavguh, 0x10000442); - XEREGISTERINSTR(vavguw, 0x10000482); - XEREGISTERINSTR(vcfsx, 0x1000034A); - XEREGISTERINSTR(vcsxwfp128, VX128_3(6, 688)); - XEREGISTERINSTR(vcfpsxws128, VX128_3(6, 560)); - XEREGISTERINSTR(vcfux, 0x1000030A); - XEREGISTERINSTR(vcuxwfp128, VX128_3(6, 752)); - XEREGISTERINSTR(vcfpuxws128, VX128_3(6, 624)); - XEREGISTERINSTR(vcmpbfp, 0x100003C6); - XEREGISTERINSTR(vcmpbfp128, VX128(6, 384)); - XEREGISTERINSTR(vcmpeqfp, 0x100000C6); - XEREGISTERINSTR(vcmpeqfp128, VX128(6, 0)); - XEREGISTERINSTR(vcmpgefp, 0x100001C6); - XEREGISTERINSTR(vcmpgefp128, VX128(6, 128)); - XEREGISTERINSTR(vcmpgtfp, 0x100002C6); - XEREGISTERINSTR(vcmpgtfp128, VX128(6, 256)); - XEREGISTERINSTR(vcmpgtsb, 0x10000306); - XEREGISTERINSTR(vcmpgtsh, 0x10000346); - XEREGISTERINSTR(vcmpgtsw, 0x10000386); - XEREGISTERINSTR(vcmpequb, 0x10000006); - XEREGISTERINSTR(vcmpgtub, 0x10000206); - XEREGISTERINSTR(vcmpequh, 0x10000046); - XEREGISTERINSTR(vcmpgtuh, 0x10000246); - XEREGISTERINSTR(vcmpequw, 0x10000086); - XEREGISTERINSTR(vcmpequw128, VX128(6, 512)); - XEREGISTERINSTR(vcmpgtuw, 0x10000286); - XEREGISTERINSTR(vctsxs, 0x100003CA); - XEREGISTERINSTR(vctuxs, 0x1000038A); - XEREGISTERINSTR(vexptefp, 0x1000018A); - XEREGISTERINSTR(vexptefp128, VX128_3(6, 1712)); - XEREGISTERINSTR(vlogefp, 0x100001CA); - XEREGISTERINSTR(vlogefp128, VX128_3(6, 1776)); - XEREGISTERINSTR(vmaddfp, 0x1000002E); - XEREGISTERINSTR(vmaddfp128, VX128(5, 208)); - XEREGISTERINSTR(vmaddcfp128, VX128(5, 272)); - XEREGISTERINSTR(vmaxfp, 0x1000040A); - XEREGISTERINSTR(vmaxfp128, VX128(6, 640)); - XEREGISTERINSTR(vmaxsb, 0x10000102); - XEREGISTERINSTR(vmaxsh, 0x10000142); - XEREGISTERINSTR(vmaxsw, 0x10000182); - XEREGISTERINSTR(vmaxub, 0x10000002); - XEREGISTERINSTR(vmaxuh, 0x10000042); - XEREGISTERINSTR(vmaxuw, 0x10000082); - XEREGISTERINSTR(vmhaddshs, 0x10000020); - XEREGISTERINSTR(vmhraddshs, 0x10000021); - XEREGISTERINSTR(vminfp, 0x1000044A); - XEREGISTERINSTR(vminfp128, VX128(6, 704)); - XEREGISTERINSTR(vminsb, 0x10000302); - XEREGISTERINSTR(vminsh, 0x10000342); - XEREGISTERINSTR(vminsw, 0x10000382); - XEREGISTERINSTR(vminub, 0x10000202); - XEREGISTERINSTR(vminuh, 0x10000242); - XEREGISTERINSTR(vminuw, 0x10000282); - XEREGISTERINSTR(vmladduhm, 0x10000022); - XEREGISTERINSTR(vmrghb, 0x1000000C); - XEREGISTERINSTR(vmrghh, 0x1000004C); - XEREGISTERINSTR(vmrghw, 0x1000008C); - XEREGISTERINSTR(vmrghw128, VX128(6, 768)); - XEREGISTERINSTR(vmrglb, 0x1000010C); - XEREGISTERINSTR(vmrglh, 0x1000014C); - XEREGISTERINSTR(vmrglw, 0x1000018C); - XEREGISTERINSTR(vmrglw128, VX128(6, 832)); - XEREGISTERINSTR(vmsummbm, 0x10000025); - XEREGISTERINSTR(vmsumshm, 0x10000028); - XEREGISTERINSTR(vmsumshs, 0x10000029); - XEREGISTERINSTR(vmsumubm, 0x10000024); - XEREGISTERINSTR(vmsumuhm, 0x10000026); - XEREGISTERINSTR(vmsumuhs, 0x10000027); - XEREGISTERINSTR(vmsum3fp128, VX128(5, 400)); - XEREGISTERINSTR(vmsum4fp128, VX128(5, 464)); - XEREGISTERINSTR(vmulesb, 0x10000308); - XEREGISTERINSTR(vmulesh, 0x10000348); - XEREGISTERINSTR(vmuleub, 0x10000208); - XEREGISTERINSTR(vmuleuh, 0x10000248); - XEREGISTERINSTR(vmulosb, 0x10000108); - XEREGISTERINSTR(vmulosh, 0x10000148); - XEREGISTERINSTR(vmuloub, 0x10000008); - XEREGISTERINSTR(vmulouh, 0x10000048); - XEREGISTERINSTR(vmulfp128, VX128(5, 144)); - XEREGISTERINSTR(vnmsubfp, 0x1000002F); - XEREGISTERINSTR(vnmsubfp128, VX128(5, 336)); - XEREGISTERINSTR(vnor, 0x10000504); - XEREGISTERINSTR(vnor128, VX128(5, 656)); - XEREGISTERINSTR(vor, 0x10000484); - XEREGISTERINSTR(vor128, VX128(5, 720)); - XEREGISTERINSTR(vperm, 0x1000002B); - XEREGISTERINSTR(vperm128, VX128_2(5, 0)); - XEREGISTERINSTR(vpermwi128, VX128_P(6, 528)); - XEREGISTERINSTR(vpkpx, 0x1000030E); - XEREGISTERINSTR(vpkshss, 0x1000018E); - XEREGISTERINSTR(vpkshss128, VX128(5, 512)); - XEREGISTERINSTR(vpkshus, 0x1000010E); - XEREGISTERINSTR(vpkshus128, VX128(5, 576)); - XEREGISTERINSTR(vpkswss, 0x100001CE); - XEREGISTERINSTR(vpkswss128, VX128(5, 640)); - XEREGISTERINSTR(vpkswus, 0x1000014E); - XEREGISTERINSTR(vpkswus128, VX128(5, 704)); - XEREGISTERINSTR(vpkuhum, 0x1000000E); - XEREGISTERINSTR(vpkuhum128, VX128(5, 768)); - XEREGISTERINSTR(vpkuhus, 0x1000008E); - XEREGISTERINSTR(vpkuhus128, VX128(5, 832)); - XEREGISTERINSTR(vpkuwum, 0x1000004E); - XEREGISTERINSTR(vpkuwum128, VX128(5, 896)); - XEREGISTERINSTR(vpkuwus, 0x100000CE); - XEREGISTERINSTR(vpkuwus128, VX128(5, 960)); - XEREGISTERINSTR(vpkd3d128, VX128_4(6, 1552)); - XEREGISTERINSTR(vrefp, 0x1000010A); - XEREGISTERINSTR(vrefp128, VX128_3(6, 1584)); - XEREGISTERINSTR(vrfim, 0x100002CA); - XEREGISTERINSTR(vrfim128, VX128_3(6, 816)); - XEREGISTERINSTR(vrfin, 0x1000020A); - XEREGISTERINSTR(vrfin128, VX128_3(6, 880)); - XEREGISTERINSTR(vrfip, 0x1000028A); - XEREGISTERINSTR(vrfip128, VX128_3(6, 944)); - XEREGISTERINSTR(vrfiz, 0x1000024A); - XEREGISTERINSTR(vrfiz128, VX128_3(6, 1008)); - XEREGISTERINSTR(vrlb, 0x10000004); - XEREGISTERINSTR(vrlh, 0x10000044); - XEREGISTERINSTR(vrlw, 0x10000084); - XEREGISTERINSTR(vrlw128, VX128(6, 80)); - XEREGISTERINSTR(vrlimi128, VX128_4(6, 1808)); - XEREGISTERINSTR(vrsqrtefp, 0x1000014A); - XEREGISTERINSTR(vrsqrtefp128, VX128_3(6, 1648)); - XEREGISTERINSTR(vsel, 0x1000002A); - XEREGISTERINSTR(vsel128, VX128(5, 848)); - XEREGISTERINSTR(vsl, 0x100001C4); - XEREGISTERINSTR(vslb, 0x10000104); - XEREGISTERINSTR(vslh, 0x10000144); - XEREGISTERINSTR(vslo, 0x1000040C); - XEREGISTERINSTR(vslo128, VX128(5, 912)); - XEREGISTERINSTR(vslw, 0x10000184); - XEREGISTERINSTR(vslw128, VX128(6, 208)); - XEREGISTERINSTR(vsldoi, 0x1000002C); - XEREGISTERINSTR(vsldoi128, VX128_5(4, 16)); - XEREGISTERINSTR(vspltb, 0x1000020C); - XEREGISTERINSTR(vsplth, 0x1000024C); - XEREGISTERINSTR(vspltw, 0x1000028C); - XEREGISTERINSTR(vspltw128, VX128_3(6, 1840)); - XEREGISTERINSTR(vspltisb, 0x1000030C); - XEREGISTERINSTR(vspltish, 0x1000034C); - XEREGISTERINSTR(vspltisw, 0x1000038C); - XEREGISTERINSTR(vspltisw128, VX128_3(6, 1904)); - XEREGISTERINSTR(vsr, 0x100002C4); - XEREGISTERINSTR(vsrab, 0x10000304); - XEREGISTERINSTR(vsrah, 0x10000344); - XEREGISTERINSTR(vsraw, 0x10000384); - XEREGISTERINSTR(vsraw128, VX128(6, 336)); - XEREGISTERINSTR(vsrb, 0x10000204); - XEREGISTERINSTR(vsrh, 0x10000244); - XEREGISTERINSTR(vsro, 0x1000044C); - XEREGISTERINSTR(vsro128, VX128(5, 976)); - XEREGISTERINSTR(vsrw, 0x10000284); - XEREGISTERINSTR(vsrw128, VX128(6, 464)); - XEREGISTERINSTR(vsubcuw, 0x10000580); - XEREGISTERINSTR(vsubfp, 0x1000004A); - XEREGISTERINSTR(vsubfp128, VX128(5, 80)); - XEREGISTERINSTR(vsubsbs, 0x10000700); - XEREGISTERINSTR(vsubshs, 0x10000740); - XEREGISTERINSTR(vsubsws, 0x10000780); - XEREGISTERINSTR(vsububm, 0x10000400); - XEREGISTERINSTR(vsububs, 0x10000600); - XEREGISTERINSTR(vsubuhm, 0x10000440); - XEREGISTERINSTR(vsubuhs, 0x10000640); - XEREGISTERINSTR(vsubuwm, 0x10000480); - XEREGISTERINSTR(vsubuws, 0x10000680); - XEREGISTERINSTR(vsumsws, 0x10000788); - XEREGISTERINSTR(vsum2sws, 0x10000688); - XEREGISTERINSTR(vsum4sbs, 0x10000708); - XEREGISTERINSTR(vsum4shs, 0x10000648); - XEREGISTERINSTR(vsum4ubs, 0x10000608); - XEREGISTERINSTR(vupkhpx, 0x1000034E); - XEREGISTERINSTR(vupkhsb, 0x1000020E); - XEREGISTERINSTR(vupkhsb128, VX128(6, 896)); - XEREGISTERINSTR(vupkhsh, 0x1000024E); - XEREGISTERINSTR(vupklpx, 0x100003CE); - XEREGISTERINSTR(vupklsb, 0x1000028E); - XEREGISTERINSTR(vupklsb128, VX128(6, 960)); - XEREGISTERINSTR(vupklsh, 0x100002CE); - XEREGISTERINSTR(vupkd3d128, VX128_3(6, 2032)); - XEREGISTERINSTR(vxor, 0x100004C4); - XEREGISTERINSTR(vxor128, VX128(5, 784)); + XEREGISTERINSTR(mfvscr, 0x10000604); + XEREGISTERINSTR(mtvscr, 0x10000644); + XEREGISTERINSTR(vaddcuw, 0x10000180); + XEREGISTERINSTR(vaddfp, 0x1000000A); + XEREGISTERINSTR(vaddfp128, VX128(5, 16)); + XEREGISTERINSTR(vaddsbs, 0x10000300); + XEREGISTERINSTR(vaddshs, 0x10000340); + XEREGISTERINSTR(vaddsws, 0x10000380); + XEREGISTERINSTR(vaddubm, 0x10000000); + XEREGISTERINSTR(vaddubs, 0x10000200); + XEREGISTERINSTR(vadduhm, 0x10000040); + XEREGISTERINSTR(vadduhs, 0x10000240); + XEREGISTERINSTR(vadduwm, 0x10000080); + XEREGISTERINSTR(vadduws, 0x10000280); + XEREGISTERINSTR(vand, 0x10000404); + XEREGISTERINSTR(vand128, VX128(5, 528)); + XEREGISTERINSTR(vandc, 0x10000444); + XEREGISTERINSTR(vandc128, VX128(5, 592)); + XEREGISTERINSTR(vavgsb, 0x10000502); + XEREGISTERINSTR(vavgsh, 0x10000542); + XEREGISTERINSTR(vavgsw, 0x10000582); + XEREGISTERINSTR(vavgub, 0x10000402); + XEREGISTERINSTR(vavguh, 0x10000442); + XEREGISTERINSTR(vavguw, 0x10000482); + XEREGISTERINSTR(vcfsx, 0x1000034A); + XEREGISTERINSTR(vcsxwfp128, VX128_3(6, 688)); + XEREGISTERINSTR(vcfpsxws128, VX128_3(6, 560)); + XEREGISTERINSTR(vcfux, 0x1000030A); + XEREGISTERINSTR(vcuxwfp128, VX128_3(6, 752)); + XEREGISTERINSTR(vcfpuxws128, VX128_3(6, 624)); + XEREGISTERINSTR(vcmpbfp, 0x100003C6); + XEREGISTERINSTR(vcmpbfp128, VX128(6, 384)); + XEREGISTERINSTR(vcmpeqfp, 0x100000C6); + XEREGISTERINSTR(vcmpeqfp128, VX128(6, 0)); + XEREGISTERINSTR(vcmpgefp, 0x100001C6); + XEREGISTERINSTR(vcmpgefp128, VX128(6, 128)); + XEREGISTERINSTR(vcmpgtfp, 0x100002C6); + XEREGISTERINSTR(vcmpgtfp128, VX128(6, 256)); + XEREGISTERINSTR(vcmpgtsb, 0x10000306); + XEREGISTERINSTR(vcmpgtsh, 0x10000346); + XEREGISTERINSTR(vcmpgtsw, 0x10000386); + XEREGISTERINSTR(vcmpequb, 0x10000006); + XEREGISTERINSTR(vcmpgtub, 0x10000206); + XEREGISTERINSTR(vcmpequh, 0x10000046); + XEREGISTERINSTR(vcmpgtuh, 0x10000246); + XEREGISTERINSTR(vcmpequw, 0x10000086); + XEREGISTERINSTR(vcmpequw128, VX128(6, 512)); + XEREGISTERINSTR(vcmpgtuw, 0x10000286); + XEREGISTERINSTR(vctsxs, 0x100003CA); + XEREGISTERINSTR(vctuxs, 0x1000038A); + XEREGISTERINSTR(vexptefp, 0x1000018A); + XEREGISTERINSTR(vexptefp128, VX128_3(6, 1712)); + XEREGISTERINSTR(vlogefp, 0x100001CA); + XEREGISTERINSTR(vlogefp128, VX128_3(6, 1776)); + XEREGISTERINSTR(vmaddfp, 0x1000002E); + XEREGISTERINSTR(vmaddfp128, VX128(5, 208)); + XEREGISTERINSTR(vmaddcfp128, VX128(5, 272)); + XEREGISTERINSTR(vmaxfp, 0x1000040A); + XEREGISTERINSTR(vmaxfp128, VX128(6, 640)); + XEREGISTERINSTR(vmaxsb, 0x10000102); + XEREGISTERINSTR(vmaxsh, 0x10000142); + XEREGISTERINSTR(vmaxsw, 0x10000182); + XEREGISTERINSTR(vmaxub, 0x10000002); + XEREGISTERINSTR(vmaxuh, 0x10000042); + XEREGISTERINSTR(vmaxuw, 0x10000082); + XEREGISTERINSTR(vmhaddshs, 0x10000020); + XEREGISTERINSTR(vmhraddshs, 0x10000021); + XEREGISTERINSTR(vminfp, 0x1000044A); + XEREGISTERINSTR(vminfp128, VX128(6, 704)); + XEREGISTERINSTR(vminsb, 0x10000302); + XEREGISTERINSTR(vminsh, 0x10000342); + XEREGISTERINSTR(vminsw, 0x10000382); + XEREGISTERINSTR(vminub, 0x10000202); + XEREGISTERINSTR(vminuh, 0x10000242); + XEREGISTERINSTR(vminuw, 0x10000282); + XEREGISTERINSTR(vmladduhm, 0x10000022); + XEREGISTERINSTR(vmrghb, 0x1000000C); + XEREGISTERINSTR(vmrghh, 0x1000004C); + XEREGISTERINSTR(vmrghw, 0x1000008C); + XEREGISTERINSTR(vmrghw128, VX128(6, 768)); + XEREGISTERINSTR(vmrglb, 0x1000010C); + XEREGISTERINSTR(vmrglh, 0x1000014C); + XEREGISTERINSTR(vmrglw, 0x1000018C); + XEREGISTERINSTR(vmrglw128, VX128(6, 832)); + XEREGISTERINSTR(vmsummbm, 0x10000025); + XEREGISTERINSTR(vmsumshm, 0x10000028); + XEREGISTERINSTR(vmsumshs, 0x10000029); + XEREGISTERINSTR(vmsumubm, 0x10000024); + XEREGISTERINSTR(vmsumuhm, 0x10000026); + XEREGISTERINSTR(vmsumuhs, 0x10000027); + XEREGISTERINSTR(vmsum3fp128, VX128(5, 400)); + XEREGISTERINSTR(vmsum4fp128, VX128(5, 464)); + XEREGISTERINSTR(vmulesb, 0x10000308); + XEREGISTERINSTR(vmulesh, 0x10000348); + XEREGISTERINSTR(vmuleub, 0x10000208); + XEREGISTERINSTR(vmuleuh, 0x10000248); + XEREGISTERINSTR(vmulosb, 0x10000108); + XEREGISTERINSTR(vmulosh, 0x10000148); + XEREGISTERINSTR(vmuloub, 0x10000008); + XEREGISTERINSTR(vmulouh, 0x10000048); + XEREGISTERINSTR(vmulfp128, VX128(5, 144)); + XEREGISTERINSTR(vnmsubfp, 0x1000002F); + XEREGISTERINSTR(vnmsubfp128, VX128(5, 336)); + XEREGISTERINSTR(vnor, 0x10000504); + XEREGISTERINSTR(vnor128, VX128(5, 656)); + XEREGISTERINSTR(vor, 0x10000484); + XEREGISTERINSTR(vor128, VX128(5, 720)); + XEREGISTERINSTR(vperm, 0x1000002B); + XEREGISTERINSTR(vperm128, VX128_2(5, 0)); + XEREGISTERINSTR(vpermwi128, VX128_P(6, 528)); + XEREGISTERINSTR(vpkpx, 0x1000030E); + XEREGISTERINSTR(vpkshss, 0x1000018E); + XEREGISTERINSTR(vpkshss128, VX128(5, 512)); + XEREGISTERINSTR(vpkshus, 0x1000010E); + XEREGISTERINSTR(vpkshus128, VX128(5, 576)); + XEREGISTERINSTR(vpkswss, 0x100001CE); + XEREGISTERINSTR(vpkswss128, VX128(5, 640)); + XEREGISTERINSTR(vpkswus, 0x1000014E); + XEREGISTERINSTR(vpkswus128, VX128(5, 704)); + XEREGISTERINSTR(vpkuhum, 0x1000000E); + XEREGISTERINSTR(vpkuhum128, VX128(5, 768)); + XEREGISTERINSTR(vpkuhus, 0x1000008E); + XEREGISTERINSTR(vpkuhus128, VX128(5, 832)); + XEREGISTERINSTR(vpkuwum, 0x1000004E); + XEREGISTERINSTR(vpkuwum128, VX128(5, 896)); + XEREGISTERINSTR(vpkuwus, 0x100000CE); + XEREGISTERINSTR(vpkuwus128, VX128(5, 960)); + XEREGISTERINSTR(vpkd3d128, VX128_4(6, 1552)); + XEREGISTERINSTR(vrefp, 0x1000010A); + XEREGISTERINSTR(vrefp128, VX128_3(6, 1584)); + XEREGISTERINSTR(vrfim, 0x100002CA); + XEREGISTERINSTR(vrfim128, VX128_3(6, 816)); + XEREGISTERINSTR(vrfin, 0x1000020A); + XEREGISTERINSTR(vrfin128, VX128_3(6, 880)); + XEREGISTERINSTR(vrfip, 0x1000028A); + XEREGISTERINSTR(vrfip128, VX128_3(6, 944)); + XEREGISTERINSTR(vrfiz, 0x1000024A); + XEREGISTERINSTR(vrfiz128, VX128_3(6, 1008)); + XEREGISTERINSTR(vrlb, 0x10000004); + XEREGISTERINSTR(vrlh, 0x10000044); + XEREGISTERINSTR(vrlw, 0x10000084); + XEREGISTERINSTR(vrlw128, VX128(6, 80)); + XEREGISTERINSTR(vrlimi128, VX128_4(6, 1808)); + XEREGISTERINSTR(vrsqrtefp, 0x1000014A); + XEREGISTERINSTR(vrsqrtefp128, VX128_3(6, 1648)); + XEREGISTERINSTR(vsel, 0x1000002A); + XEREGISTERINSTR(vsel128, VX128(5, 848)); + XEREGISTERINSTR(vsl, 0x100001C4); + XEREGISTERINSTR(vslb, 0x10000104); + XEREGISTERINSTR(vslh, 0x10000144); + XEREGISTERINSTR(vslo, 0x1000040C); + XEREGISTERINSTR(vslo128, VX128(5, 912)); + XEREGISTERINSTR(vslw, 0x10000184); + XEREGISTERINSTR(vslw128, VX128(6, 208)); + XEREGISTERINSTR(vsldoi, 0x1000002C); + XEREGISTERINSTR(vsldoi128, VX128_5(4, 16)); + XEREGISTERINSTR(vspltb, 0x1000020C); + XEREGISTERINSTR(vsplth, 0x1000024C); + XEREGISTERINSTR(vspltw, 0x1000028C); + XEREGISTERINSTR(vspltw128, VX128_3(6, 1840)); + XEREGISTERINSTR(vspltisb, 0x1000030C); + XEREGISTERINSTR(vspltish, 0x1000034C); + XEREGISTERINSTR(vspltisw, 0x1000038C); + XEREGISTERINSTR(vspltisw128, VX128_3(6, 1904)); + XEREGISTERINSTR(vsr, 0x100002C4); + XEREGISTERINSTR(vsrab, 0x10000304); + XEREGISTERINSTR(vsrah, 0x10000344); + XEREGISTERINSTR(vsraw, 0x10000384); + XEREGISTERINSTR(vsraw128, VX128(6, 336)); + XEREGISTERINSTR(vsrb, 0x10000204); + XEREGISTERINSTR(vsrh, 0x10000244); + XEREGISTERINSTR(vsro, 0x1000044C); + XEREGISTERINSTR(vsro128, VX128(5, 976)); + XEREGISTERINSTR(vsrw, 0x10000284); + XEREGISTERINSTR(vsrw128, VX128(6, 464)); + XEREGISTERINSTR(vsubcuw, 0x10000580); + XEREGISTERINSTR(vsubfp, 0x1000004A); + XEREGISTERINSTR(vsubfp128, VX128(5, 80)); + XEREGISTERINSTR(vsubsbs, 0x10000700); + XEREGISTERINSTR(vsubshs, 0x10000740); + XEREGISTERINSTR(vsubsws, 0x10000780); + XEREGISTERINSTR(vsububm, 0x10000400); + XEREGISTERINSTR(vsububs, 0x10000600); + XEREGISTERINSTR(vsubuhm, 0x10000440); + XEREGISTERINSTR(vsubuhs, 0x10000640); + XEREGISTERINSTR(vsubuwm, 0x10000480); + XEREGISTERINSTR(vsubuws, 0x10000680); + XEREGISTERINSTR(vsumsws, 0x10000788); + XEREGISTERINSTR(vsum2sws, 0x10000688); + XEREGISTERINSTR(vsum4sbs, 0x10000708); + XEREGISTERINSTR(vsum4shs, 0x10000648); + XEREGISTERINSTR(vsum4ubs, 0x10000608); + XEREGISTERINSTR(vupkhpx, 0x1000034E); + XEREGISTERINSTR(vupkhsb, 0x1000020E); + XEREGISTERINSTR(vupkhsb128, VX128(6, 896)); + XEREGISTERINSTR(vupkhsh, 0x1000024E); + XEREGISTERINSTR(vupklpx, 0x100003CE); + XEREGISTERINSTR(vupklsb, 0x1000028E); + XEREGISTERINSTR(vupklsb128, VX128(6, 960)); + XEREGISTERINSTR(vupklsh, 0x100002CE); + XEREGISTERINSTR(vupkd3d128, VX128_3(6, 2032)); + XEREGISTERINSTR(vxor, 0x100004C4); + XEREGISTERINSTR(vxor128, VX128(5, 784)); } - } // namespace ppc } // namespace frontend } // namespace alloy diff --git a/src/alloy/frontend/ppc/ppc_emit_alu.cc b/src/alloy/frontend/ppc/ppc_emit_alu.cc index ce023eb85..cf8245064 100644 --- a/src/alloy/frontend/ppc/ppc_emit_alu.cc +++ b/src/alloy/frontend/ppc/ppc_emit_alu.cc @@ -12,28 +12,24 @@ #include #include - -using namespace alloy::frontend::ppc; -using namespace alloy::hir; -using namespace alloy::runtime; - - namespace alloy { namespace frontend { namespace ppc { +// TODO(benvanik): remove when enums redefined. +using namespace alloy::hir; + +using alloy::hir::Value; // Integer arithmetic (A-3) -XEEMITTER(addx, 0x7C000214, XO )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(addx, 0x7C000214, XO)(PPCHIRBuilder& f, InstrData& i) { // RD <- (RA) + (RB) - Value* v = f.Add( - f.LoadGPR(i.XO.RA), - f.LoadGPR(i.XO.RB)); + Value* v = f.Add(f.LoadGPR(i.XO.RA), f.LoadGPR(i.XO.RB)); f.StoreGPR(i.XO.RT, v); if (i.XO.OE) { XEASSERTALWAYS(); - //e.update_xer_with_overflow(EFLAGS OF?); + // e.update_xer_with_overflow(EFLAGS OF?); } if (i.XO.Rc) { f.UpdateCR(0, v); @@ -41,18 +37,16 @@ XEEMITTER(addx, 0x7C000214, XO )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(addcx, 0x7C000014, XO )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(addcx, 0x7C000014, XO)(PPCHIRBuilder& f, InstrData& i) { // RD <- (RA) + (RB) // CA <- carry bit - Value* v = f.Add( - f.LoadGPR(i.XO.RA), - f.LoadGPR(i.XO.RB), - ARITHMETIC_SET_CARRY); + Value* v = + f.Add(f.LoadGPR(i.XO.RA), f.LoadGPR(i.XO.RB), ARITHMETIC_SET_CARRY); f.StoreCA(f.DidCarry(v)); f.StoreGPR(i.XO.RT, v); if (i.XO.OE) { XEASSERTALWAYS(); - //e.update_xer_with_overflow(EFLAGS OF?); + // e.update_xer_with_overflow(EFLAGS OF?); } if (i.XO.Rc) { f.UpdateCR(0, v); @@ -60,18 +54,15 @@ XEEMITTER(addcx, 0x7C000014, XO )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(addex, 0x7C000114, XO )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(addex, 0x7C000114, XO)(PPCHIRBuilder& f, InstrData& i) { // RD <- (RA) + (RB) + XER[CA] - Value* v = f.AddWithCarry( - f.LoadGPR(i.XO.RA), - f.LoadGPR(i.XO.RB), - f.LoadCA(), - ARITHMETIC_SET_CARRY); + Value* v = f.AddWithCarry(f.LoadGPR(i.XO.RA), f.LoadGPR(i.XO.RB), f.LoadCA(), + ARITHMETIC_SET_CARRY); f.StoreCA(f.DidCarry(v)); f.StoreGPR(i.XO.RT, v); if (i.XO.OE) { XEASSERTALWAYS(); - //e.update_xer_with_overflow(EFLAGS OF?); + // e.update_xer_with_overflow(EFLAGS OF?); } if (i.XO.Rc) { f.UpdateCR(0, v); @@ -79,7 +70,7 @@ XEEMITTER(addex, 0x7C000114, XO )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(addi, 0x38000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(addi, 0x38000000, D)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // RT <- EXTS(SI) // else @@ -93,30 +84,26 @@ XEEMITTER(addi, 0x38000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(addic, 0x30000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(addic, 0x30000000, D)(PPCHIRBuilder& f, InstrData& i) { // RT <- (RA) + EXTS(SI) - Value* v = f.Add( - f.LoadGPR(i.D.RA), - f.LoadConstant(XEEXTS16(i.D.DS)), - ARITHMETIC_SET_CARRY); + Value* v = f.Add(f.LoadGPR(i.D.RA), f.LoadConstant(XEEXTS16(i.D.DS)), + ARITHMETIC_SET_CARRY); f.StoreCA(f.DidCarry(v)); f.StoreGPR(i.D.RT, v); return 0; } -XEEMITTER(addicx, 0x34000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(addicx, 0x34000000, D)(PPCHIRBuilder& f, InstrData& i) { // RT <- (RA) + EXTS(SI) - Value* v = f.Add( - f.LoadGPR(i.D.RA), - f.LoadConstant(XEEXTS16(i.D.DS)), - ARITHMETIC_SET_CARRY); + Value* v = f.Add(f.LoadGPR(i.D.RA), f.LoadConstant(XEEXTS16(i.D.DS)), + ARITHMETIC_SET_CARRY); f.StoreCA(f.DidCarry(v)); f.StoreGPR(i.D.RT, v); f.UpdateCR(0, v); return 0; } -XEEMITTER(addis, 0x3C000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(addis, 0x3C000000, D)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // RT <- EXTS(SI) || i16.0 // else @@ -130,16 +117,13 @@ XEEMITTER(addis, 0x3C000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(addmex, 0x7C0001D4, XO )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(addmex, 0x7C0001D4, XO)(PPCHIRBuilder& f, InstrData& i) { // RT <- (RA) + CA - 1 - Value* v = f.AddWithCarry( - f.LoadGPR(i.XO.RA), - f.LoadConstant((int64_t)-1), - f.LoadCA(), - ARITHMETIC_SET_CARRY); + Value* v = f.AddWithCarry(f.LoadGPR(i.XO.RA), f.LoadConstant((int64_t)-1), + f.LoadCA(), ARITHMETIC_SET_CARRY); if (i.XO.OE) { // With XER[SO] update too. - //e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1)); + // e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1)); XEASSERTALWAYS(); } else { // Just CA update. @@ -152,16 +136,13 @@ XEEMITTER(addmex, 0x7C0001D4, XO )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(addzex, 0x7C000194, XO )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(addzex, 0x7C000194, XO)(PPCHIRBuilder& f, InstrData& i) { // RT <- (RA) + CA - Value* v = f.AddWithCarry( - f.LoadGPR(i.XO.RA), - f.LoadZero(INT64_TYPE), - f.LoadCA(), - ARITHMETIC_SET_CARRY); + Value* v = f.AddWithCarry(f.LoadGPR(i.XO.RA), f.LoadZero(INT64_TYPE), + f.LoadCA(), ARITHMETIC_SET_CARRY); if (i.XO.OE) { // With XER[SO] update too. - //e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1)); + // e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1)); XEASSERTALWAYS(); } else { // Just CA update. @@ -174,7 +155,7 @@ XEEMITTER(addzex, 0x7C000194, XO )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(divdx, 0x7C0003D2, XO )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(divdx, 0x7C0003D2, XO)(PPCHIRBuilder& f, InstrData& i) { // dividend <- (RA) // divisor <- (RB) // if divisor = 0 then @@ -190,7 +171,7 @@ XEEMITTER(divdx, 0x7C0003D2, XO )(PPCHIRBuilder& f, InstrData& i) { f.StoreGPR(i.XO.RT, v); if (i.XO.OE) { // If we are OE=1 we need to clear the overflow bit. - //e.update_xer_with_overflow(e.get_uint64(0)); + // e.update_xer_with_overflow(e.get_uint64(0)); XEASSERTALWAYS(); return 1; } @@ -200,7 +181,7 @@ XEEMITTER(divdx, 0x7C0003D2, XO )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(divdux, 0x7C000392, XO )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(divdux, 0x7C000392, XO)(PPCHIRBuilder& f, InstrData& i) { // dividend <- (RA) // divisor <- (RB) // if divisor = 0 then @@ -216,7 +197,7 @@ XEEMITTER(divdux, 0x7C000392, XO )(PPCHIRBuilder& f, InstrData& i) { f.StoreGPR(i.XO.RT, v); if (i.XO.OE) { // If we are OE=1 we need to clear the overflow bit. - //e.update_xer_with_overflow(e.get_uint64(0)); + // e.update_xer_with_overflow(e.get_uint64(0)); XEASSERTALWAYS(); return 1; } @@ -226,7 +207,7 @@ XEEMITTER(divdux, 0x7C000392, XO )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(divwx, 0x7C0003D6, XO )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(divwx, 0x7C0003D6, XO)(PPCHIRBuilder& f, InstrData& i) { // dividend[0:31] <- (RA)[32:63] // divisor[0:31] <- (RB)[32:63] // if divisor = 0 then @@ -244,7 +225,7 @@ XEEMITTER(divwx, 0x7C0003D6, XO )(PPCHIRBuilder& f, InstrData& i) { f.StoreGPR(i.XO.RT, v); if (i.XO.OE) { // If we are OE=1 we need to clear the overflow bit. - //e.update_xer_with_overflow(e.get_uint64(0)); + // e.update_xer_with_overflow(e.get_uint64(0)); XEASSERTALWAYS(); return 1; } @@ -254,7 +235,7 @@ XEEMITTER(divwx, 0x7C0003D6, XO )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(divwux, 0x7C000396, XO )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(divwux, 0x7C000396, XO)(PPCHIRBuilder& f, InstrData& i) { // dividend[0:31] <- (RA)[32:63] // divisor[0:31] <- (RB)[32:63] // if divisor = 0 then @@ -273,7 +254,7 @@ XEEMITTER(divwux, 0x7C000396, XO )(PPCHIRBuilder& f, InstrData& i) { f.StoreGPR(i.XO.RT, v); if (i.XO.OE) { // If we are OE=1 we need to clear the overflow bit. - //e.update_xer_with_overflow(e.get_uint64(0)); + // e.update_xer_with_overflow(e.get_uint64(0)); XEASSERTALWAYS(); return 1; } @@ -283,7 +264,7 @@ XEEMITTER(divwux, 0x7C000396, XO )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(mulhdx, 0x7C000092, XO )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mulhdx, 0x7C000092, XO)(PPCHIRBuilder& f, InstrData& i) { // RT <- ((RA) × (RB) as 128)[0:63] if (i.XO.OE) { // With XER update. @@ -298,15 +279,15 @@ XEEMITTER(mulhdx, 0x7C000092, XO )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(mulhdux, 0x7C000012, XO )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mulhdux, 0x7C000012, XO)(PPCHIRBuilder& f, InstrData& i) { // RT <- ((RA) × (RB) as 128)[0:63] if (i.XO.OE) { // With XER update. XEINSTRNOTIMPLEMENTED(); return 1; } - Value* v = f.MulHi( - f.LoadGPR(i.XO.RA), f.LoadGPR(i.XO.RB), ARITHMETIC_UNSIGNED); + Value* v = + f.MulHi(f.LoadGPR(i.XO.RA), f.LoadGPR(i.XO.RB), ARITHMETIC_UNSIGNED); f.StoreGPR(i.XO.RT, v); if (i.XO.Rc) { f.UpdateCR(0, v); @@ -314,16 +295,16 @@ XEEMITTER(mulhdux, 0x7C000012, XO )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(mulhwx, 0x7C000096, XO )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mulhwx, 0x7C000096, XO)(PPCHIRBuilder& f, InstrData& i) { // RT[32:64] <- ((RA)[32:63] × (RB)[32:63])[0:31] if (i.XO.OE) { // With XER update. XEINSTRNOTIMPLEMENTED(); return 1; } - Value* v = f.SignExtend(f.MulHi( - f.Truncate(f.LoadGPR(i.XO.RA), INT32_TYPE), - f.Truncate(f.LoadGPR(i.XO.RB), INT32_TYPE)), INT64_TYPE); + Value* v = f.SignExtend(f.MulHi(f.Truncate(f.LoadGPR(i.XO.RA), INT32_TYPE), + f.Truncate(f.LoadGPR(i.XO.RB), INT32_TYPE)), + INT64_TYPE); f.StoreGPR(i.XO.RT, v); if (i.XO.Rc) { f.UpdateCR(0, v); @@ -331,17 +312,17 @@ XEEMITTER(mulhwx, 0x7C000096, XO )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(mulhwux, 0x7C000016, XO )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mulhwux, 0x7C000016, XO)(PPCHIRBuilder& f, InstrData& i) { // RT[32:64] <- ((RA)[32:63] × (RB)[32:63])[0:31] if (i.XO.OE) { // With XER update. XEINSTRNOTIMPLEMENTED(); return 1; } - Value* v = f.ZeroExtend(f.MulHi( - f.Truncate(f.LoadGPR(i.XO.RA), INT32_TYPE), - f.Truncate(f.LoadGPR(i.XO.RB), INT32_TYPE), - ARITHMETIC_UNSIGNED), INT64_TYPE); + Value* v = f.ZeroExtend( + f.MulHi(f.Truncate(f.LoadGPR(i.XO.RA), INT32_TYPE), + f.Truncate(f.LoadGPR(i.XO.RB), INT32_TYPE), ARITHMETIC_UNSIGNED), + INT64_TYPE); f.StoreGPR(i.XO.RT, v); if (i.XO.Rc) { f.UpdateCR(0, v, false); @@ -349,7 +330,7 @@ XEEMITTER(mulhwux, 0x7C000016, XO )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(mulldx, 0x7C0001D2, XO )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mulldx, 0x7C0001D2, XO)(PPCHIRBuilder& f, InstrData& i) { // RT <- ((RA) × (RB))[64:127] if (i.XO.OE) { // With XER update. @@ -364,7 +345,7 @@ XEEMITTER(mulldx, 0x7C0001D2, XO )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(mulli, 0x1C000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mulli, 0x1C000000, D)(PPCHIRBuilder& f, InstrData& i) { // prod[0:127] <- (RA) × EXTS(SI) // RT <- prod[64:127] Value* v = f.Mul(f.LoadGPR(i.D.RA), f.LoadConstant(XEEXTS16(i.D.DS))); @@ -372,7 +353,7 @@ XEEMITTER(mulli, 0x1C000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(mullwx, 0x7C0001D6, XO )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mullwx, 0x7C0001D6, XO)(PPCHIRBuilder& f, InstrData& i) { // RT <- (RA)[32:63] × (RB)[32:63] if (i.XO.OE) { // With XER update. @@ -389,7 +370,7 @@ XEEMITTER(mullwx, 0x7C0001D6, XO )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(negx, 0x7C0000D0, XO )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(negx, 0x7C0000D0, XO)(PPCHIRBuilder& f, InstrData& i) { // RT <- ¬(RA) + 1 if (i.XO.OE) { // With XER update. @@ -399,15 +380,15 @@ XEEMITTER(negx, 0x7C0000D0, XO )(PPCHIRBuilder& f, InstrData& i) { // This may just magically do that... XEASSERTALWAYS(); - //Function* ssub_with_overflow = Intrinsic::getDeclaration( + // Function* ssub_with_overflow = Intrinsic::getDeclaration( // e.gen_module(), Intrinsic::ssub_with_overflow, jit_type_nint); - //jit_value_t v = b.CreateCall2(ssub_with_overflow, + // jit_value_t v = b.CreateCall2(ssub_with_overflow, // e.get_int64(0), f.LoadGPR(i.XO.RA)); - //jit_value_t v0 = b.CreateExtractValue(v, 0); - //f.StoreGPR(i.XO.RT, v0); - //e.update_xer_with_overflow(b.CreateExtractValue(v, 1)); + // jit_value_t v0 = b.CreateExtractValue(v, 0); + // f.StoreGPR(i.XO.RT, v0); + // e.update_xer_with_overflow(b.CreateExtractValue(v, 1)); - //if (i.XO.Rc) { + // if (i.XO.Rc) { // // With cr0 update. // f.UpdateCR(0, v0, e.get_int64(0), true); //} @@ -422,13 +403,13 @@ XEEMITTER(negx, 0x7C0000D0, XO )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(subfx, 0x7C000050, XO )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(subfx, 0x7C000050, XO)(PPCHIRBuilder& f, InstrData& i) { // RT <- ¬(RA) + (RB) + 1 Value* v = f.Sub(f.LoadGPR(i.XO.RB), f.LoadGPR(i.XO.RA)); f.StoreGPR(i.XO.RT, v); if (i.XO.OE) { XEASSERTALWAYS(); - //e.update_xer_with_overflow(EFLAGS??); + // e.update_xer_with_overflow(EFLAGS??); } if (i.XO.Rc) { f.UpdateCR(0, v); @@ -436,17 +417,15 @@ XEEMITTER(subfx, 0x7C000050, XO )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(subfcx, 0x7C000010, XO )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(subfcx, 0x7C000010, XO)(PPCHIRBuilder& f, InstrData& i) { // RT <- ¬(RA) + (RB) + 1 - Value* v = f.Sub( - f.LoadGPR(i.XO.RB), - f.LoadGPR(i.XO.RA), - ARITHMETIC_SET_CARRY); + Value* v = + f.Sub(f.LoadGPR(i.XO.RB), f.LoadGPR(i.XO.RA), ARITHMETIC_SET_CARRY); f.StoreCA(f.DidCarry(v)); f.StoreGPR(i.XO.RT, v); if (i.XO.OE) { XEASSERTALWAYS(); - //e.update_xer_with_overflow(EFLAGS??); + // e.update_xer_with_overflow(EFLAGS??); } if (i.XO.Rc) { f.UpdateCR(0, v); @@ -454,29 +433,24 @@ XEEMITTER(subfcx, 0x7C000010, XO )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(subficx, 0x20000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(subficx, 0x20000000, D)(PPCHIRBuilder& f, InstrData& i) { // RT <- ¬(RA) + EXTS(SI) + 1 - Value* v = f.Sub( - f.LoadConstant(XEEXTS16(i.D.DS)), - f.LoadGPR(i.D.RA), - ARITHMETIC_SET_CARRY); + Value* v = f.Sub(f.LoadConstant(XEEXTS16(i.D.DS)), f.LoadGPR(i.D.RA), + ARITHMETIC_SET_CARRY); f.StoreCA(f.DidCarry(v)); f.StoreGPR(i.D.RT, v); return 0; } -XEEMITTER(subfex, 0x7C000110, XO )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(subfex, 0x7C000110, XO)(PPCHIRBuilder& f, InstrData& i) { // RT <- ¬(RA) + (RB) + CA - Value* v = f.AddWithCarry( - f.Not(f.LoadGPR(i.XO.RA)), - f.LoadGPR(i.XO.RB), - f.LoadCA(), - ARITHMETIC_SET_CARRY); + Value* v = f.AddWithCarry(f.Not(f.LoadGPR(i.XO.RA)), f.LoadGPR(i.XO.RB), + f.LoadCA(), ARITHMETIC_SET_CARRY); f.StoreCA(f.DidCarry(v)); f.StoreGPR(i.XO.RT, v); if (i.XO.OE) { XEASSERTALWAYS(); - //e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1)); + // e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1)); } if (i.XO.Rc) { f.UpdateCR(0, v); @@ -484,15 +458,13 @@ XEEMITTER(subfex, 0x7C000110, XO )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(subfmex, 0x7C0001D0, XO )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(subfmex, 0x7C0001D0, XO)(PPCHIRBuilder& f, InstrData& i) { // RT <- ¬(RA) + CA - 1 - Value* v = f.AddWithCarry( - f.Not(f.LoadGPR(i.XO.RA)), - f.LoadConstant((int64_t)-1), - f.LoadCA()); + Value* v = f.AddWithCarry(f.Not(f.LoadGPR(i.XO.RA)), + f.LoadConstant((int64_t)-1), f.LoadCA()); if (i.XO.OE) { XEASSERTALWAYS(); - //e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1)); + // e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1)); } else { f.StoreCA(f.DidCarry(v)); } @@ -503,15 +475,13 @@ XEEMITTER(subfmex, 0x7C0001D0, XO )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(subfzex, 0x7C000190, XO )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(subfzex, 0x7C000190, XO)(PPCHIRBuilder& f, InstrData& i) { // RT <- ¬(RA) + CA - Value* v = f.AddWithCarry( - f.Not(f.LoadGPR(i.XO.RA)), - f.LoadZero(INT64_TYPE), - f.LoadCA()); + Value* v = f.AddWithCarry(f.Not(f.LoadGPR(i.XO.RA)), f.LoadZero(INT64_TYPE), + f.LoadCA()); if (i.XO.OE) { XEASSERTALWAYS(); - //e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1)); + // e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1)); } else { f.StoreCA(f.DidCarry(v)); } @@ -522,10 +492,9 @@ XEEMITTER(subfzex, 0x7C000190, XO )(PPCHIRBuilder& f, InstrData& i) { return 0; } - // Integer compare (A-4) -XEEMITTER(cmp, 0x7C000000, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(cmp, 0x7C000000, X)(PPCHIRBuilder& f, InstrData& i) { // if L = 0 then // a <- EXTS((RA)[32:63]) // b <- EXTS((RB)[32:63]) @@ -554,7 +523,7 @@ XEEMITTER(cmp, 0x7C000000, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(cmpi, 0x2C000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(cmpi, 0x2C000000, D)(PPCHIRBuilder& f, InstrData& i) { // if L = 0 then // a <- EXTS((RA)[32:63]) // else @@ -581,7 +550,7 @@ XEEMITTER(cmpi, 0x2C000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(cmpl, 0x7C000040, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(cmpl, 0x7C000040, X)(PPCHIRBuilder& f, InstrData& i) { // if L = 0 then // a <- i32.0 || (RA)[32:63] // b <- i32.0 || (RB)[32:63] @@ -610,7 +579,7 @@ XEEMITTER(cmpl, 0x7C000040, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(cmpli, 0x28000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(cmpli, 0x28000000, D)(PPCHIRBuilder& f, InstrData& i) { // if L = 0 then // a <- i32.0 || (RA)[32:63] // else @@ -637,10 +606,9 @@ XEEMITTER(cmpli, 0x28000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } - // Integer logical (A-5) -XEEMITTER(andx, 0x7C000038, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(andx, 0x7C000038, X)(PPCHIRBuilder& f, InstrData& i) { // RA <- (RS) & (RB) Value* ra = f.And(f.LoadGPR(i.X.RT), f.LoadGPR(i.X.RB)); f.StoreGPR(i.X.RA, ra); @@ -650,7 +618,7 @@ XEEMITTER(andx, 0x7C000038, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(andcx, 0x7C000078, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(andcx, 0x7C000078, X)(PPCHIRBuilder& f, InstrData& i) { // RA <- (RS) & ¬(RB) Value* ra = f.And(f.LoadGPR(i.X.RT), f.Not(f.LoadGPR(i.X.RB))); f.StoreGPR(i.X.RA, ra); @@ -660,27 +628,24 @@ XEEMITTER(andcx, 0x7C000078, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(andix, 0x70000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(andix, 0x70000000, D)(PPCHIRBuilder& f, InstrData& i) { // RA <- (RS) & (i48.0 || UI) - Value* ra = f.And( - f.LoadGPR(i.D.RT), - f.LoadConstant((uint64_t)i.D.DS)); + Value* ra = f.And(f.LoadGPR(i.D.RT), f.LoadConstant((uint64_t)i.D.DS)); f.StoreGPR(i.D.RA, ra); f.UpdateCR(0, ra); return 0; } -XEEMITTER(andisx, 0x74000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(andisx, 0x74000000, D)(PPCHIRBuilder& f, InstrData& i) { // RA <- (RS) & (i32.0 || UI || i16.0) - Value* ra = f.And( - f.LoadGPR(i.D.RT), - f.LoadConstant((uint64_t(i.D.DS) << 16))); + Value* ra = + f.And(f.LoadGPR(i.D.RT), f.LoadConstant((uint64_t(i.D.DS) << 16))); f.StoreGPR(i.D.RA, ra); f.UpdateCR(0, ra); return 0; } -XEEMITTER(cntlzdx, 0x7C000074, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(cntlzdx, 0x7C000074, X)(PPCHIRBuilder& f, InstrData& i) { // n <- 0 // do while n < 64 // if (RS)[n] = 1 then leave n @@ -695,14 +660,13 @@ XEEMITTER(cntlzdx, 0x7C000074, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(cntlzwx, 0x7C000034, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(cntlzwx, 0x7C000034, X)(PPCHIRBuilder& f, InstrData& i) { // n <- 32 // do while n < 64 // if (RS)[n] = 1 then leave n // n <- n + 1 // RA <- n - 32 - Value* v = f.CountLeadingZeros( - f.Truncate(f.LoadGPR(i.X.RT), INT32_TYPE)); + Value* v = f.CountLeadingZeros(f.Truncate(f.LoadGPR(i.X.RT), INT32_TYPE)); v = f.ZeroExtend(v, INT64_TYPE); f.StoreGPR(i.X.RA, v); if (i.X.Rc) { @@ -711,7 +675,7 @@ XEEMITTER(cntlzwx, 0x7C000034, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(eqvx, 0x7C000238, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(eqvx, 0x7C000238, X)(PPCHIRBuilder& f, InstrData& i) { // RA <- (RS) == (RB) Value* ra = f.Xor(f.LoadGPR(i.X.RT), f.LoadGPR(i.X.RB)); ra = f.Not(ra); @@ -722,7 +686,7 @@ XEEMITTER(eqvx, 0x7C000238, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(extsbx, 0x7C000774, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(extsbx, 0x7C000774, X)(PPCHIRBuilder& f, InstrData& i) { // s <- (RS)[56] // RA[56:63] <- (RS)[56:63] // RA[0:55] <- i56.s @@ -735,7 +699,7 @@ XEEMITTER(extsbx, 0x7C000774, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(extshx, 0x7C000734, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(extshx, 0x7C000734, X)(PPCHIRBuilder& f, InstrData& i) { // s <- (RS)[48] // RA[48:63] <- (RS)[48:63] // RA[0:47] <- 48.s @@ -748,7 +712,7 @@ XEEMITTER(extshx, 0x7C000734, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(extswx, 0x7C0007B4, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(extswx, 0x7C0007B4, X)(PPCHIRBuilder& f, InstrData& i) { // s <- (RS)[32] // RA[32:63] <- (RS)[32:63] // RA[0:31] <- i32.s @@ -761,11 +725,9 @@ XEEMITTER(extswx, 0x7C0007B4, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(nandx, 0x7C0003B8, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(nandx, 0x7C0003B8, X)(PPCHIRBuilder& f, InstrData& i) { // RA <- ¬((RS) & (RB)) - Value* ra = f.And( - f.LoadGPR(i.X.RT), - f.LoadGPR(i.X.RB)); + Value* ra = f.And(f.LoadGPR(i.X.RT), f.LoadGPR(i.X.RB)); ra = f.Not(ra); f.StoreGPR(i.X.RA, ra); if (i.X.Rc) { @@ -774,11 +736,9 @@ XEEMITTER(nandx, 0x7C0003B8, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(norx, 0x7C0000F8, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(norx, 0x7C0000F8, X)(PPCHIRBuilder& f, InstrData& i) { // RA <- ¬((RS) | (RB)) - Value* ra = f.Or( - f.LoadGPR(i.X.RT), - f.LoadGPR(i.X.RB)); + Value* ra = f.Or(f.LoadGPR(i.X.RT), f.LoadGPR(i.X.RB)); ra = f.Not(ra); f.StoreGPR(i.X.RA, ra); if (i.X.Rc) { @@ -787,10 +747,9 @@ XEEMITTER(norx, 0x7C0000F8, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(orx, 0x7C000378, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(orx, 0x7C000378, X)(PPCHIRBuilder& f, InstrData& i) { // RA <- (RS) | (RB) - if (i.X.RT == i.X.RB && i.X.RT == i.X.RA && - !i.X.Rc) { + if (i.X.RT == i.X.RB && i.X.RT == i.X.RA && !i.X.Rc) { // Sometimes used as no-op. f.Nop(); return 0; @@ -799,9 +758,7 @@ XEEMITTER(orx, 0x7C000378, X )(PPCHIRBuilder& f, InstrData& i) { if (i.X.RT == i.X.RB) { ra = f.LoadGPR(i.X.RT); } else { - ra = f.Or( - f.LoadGPR(i.X.RT), - f.LoadGPR(i.X.RB)); + ra = f.Or(f.LoadGPR(i.X.RT), f.LoadGPR(i.X.RB)); } f.StoreGPR(i.X.RA, ra); if (i.X.Rc) { @@ -810,11 +767,9 @@ XEEMITTER(orx, 0x7C000378, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(orcx, 0x7C000338, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(orcx, 0x7C000338, X)(PPCHIRBuilder& f, InstrData& i) { // RA <- (RS) | ¬(RB) - Value* ra = f.Or( - f.LoadGPR(i.X.RT), - f.Not(f.LoadGPR(i.X.RB))); + Value* ra = f.Or(f.LoadGPR(i.X.RT), f.Not(f.LoadGPR(i.X.RB))); f.StoreGPR(i.X.RA, ra); if (i.X.Rc) { f.UpdateCR(0, ra); @@ -822,33 +777,27 @@ XEEMITTER(orcx, 0x7C000338, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(ori, 0x60000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(ori, 0x60000000, D)(PPCHIRBuilder& f, InstrData& i) { // RA <- (RS) | (i48.0 || UI) if (!i.D.RA && !i.D.RT && !i.D.DS) { f.Nop(); return 0; } - Value* ra = f.Or( - f.LoadGPR(i.D.RT), - f.LoadConstant((uint64_t)i.D.DS)); + Value* ra = f.Or(f.LoadGPR(i.D.RT), f.LoadConstant((uint64_t)i.D.DS)); f.StoreGPR(i.D.RA, ra); return 0; } -XEEMITTER(oris, 0x64000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(oris, 0x64000000, D)(PPCHIRBuilder& f, InstrData& i) { // RA <- (RS) | (i32.0 || UI || i16.0) - Value* ra = f.Or( - f.LoadGPR(i.D.RT), - f.LoadConstant((uint64_t(i.D.DS) << 16))); + Value* ra = f.Or(f.LoadGPR(i.D.RT), f.LoadConstant((uint64_t(i.D.DS) << 16))); f.StoreGPR(i.D.RA, ra); return 0; } -XEEMITTER(xorx, 0x7C000278, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(xorx, 0x7C000278, X)(PPCHIRBuilder& f, InstrData& i) { // RA <- (RS) XOR (RB) - Value* ra = f.Xor( - f.LoadGPR(i.X.RT), - f.LoadGPR(i.X.RB)); + Value* ra = f.Xor(f.LoadGPR(i.X.RT), f.LoadGPR(i.X.RB)); f.StoreGPR(i.X.RA, ra); if (i.X.Rc) { f.UpdateCR(0, ra); @@ -856,28 +805,24 @@ XEEMITTER(xorx, 0x7C000278, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(xori, 0x68000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(xori, 0x68000000, D)(PPCHIRBuilder& f, InstrData& i) { // RA <- (RS) XOR (i48.0 || UI) - Value* ra = f.Xor( - f.LoadGPR(i.D.RT), - f.LoadConstant((uint64_t)i.D.DS)); + Value* ra = f.Xor(f.LoadGPR(i.D.RT), f.LoadConstant((uint64_t)i.D.DS)); f.StoreGPR(i.D.RA, ra); return 0; } -XEEMITTER(xoris, 0x6C000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(xoris, 0x6C000000, D)(PPCHIRBuilder& f, InstrData& i) { // RA <- (RS) XOR (i32.0 || UI || i16.0) - Value* ra = f.Xor( - f.LoadGPR(i.D.RT), - f.LoadConstant((uint64_t(i.D.DS) << 16))); + Value* ra = + f.Xor(f.LoadGPR(i.D.RT), f.LoadConstant((uint64_t(i.D.DS) << 16))); f.StoreGPR(i.D.RA, ra); return 0; } - // Integer rotate (A-6) -XEEMITTER(rld, 0x78000000, MDS)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(rld, 0x78000000, MDS)(PPCHIRBuilder& f, InstrData& i) { if (i.MD.idx == 0) { // XEEMITTER(rldiclx, 0x78000000, MD ) // n <- sh[5] || sh[0:4] @@ -955,9 +900,7 @@ XEEMITTER(rld, 0x78000000, MDS)(PPCHIRBuilder& f, InstrData& i) { } if (m != 0xFFFFFFFFFFFFFFFF) { Value* ra = f.LoadGPR(i.MD.RA); - v = f.Or( - f.And(v, f.LoadConstant(m)), - f.And(ra, f.LoadConstant(~m))); + v = f.Or(f.And(v, f.LoadConstant(m)), f.And(ra, f.LoadConstant(~m))); } f.StoreGPR(i.MD.RA, v); if (i.MD.Rc) { @@ -970,7 +913,7 @@ XEEMITTER(rld, 0x78000000, MDS)(PPCHIRBuilder& f, InstrData& i) { } } -XEEMITTER(rlwimix, 0x50000000, M )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(rlwimix, 0x50000000, M)(PPCHIRBuilder& f, InstrData& i) { // n <- SH // r <- ROTL32((RS)[32:63], n) // m <- MASK(MB+32, ME+32) @@ -994,7 +937,7 @@ XEEMITTER(rlwimix, 0x50000000, M )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(rlwinmx, 0x54000000, M )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(rlwinmx, 0x54000000, M)(PPCHIRBuilder& f, InstrData& i) { // n <- SH // r <- ROTL32((RS)[32:63], n) // m <- MASK(MB+32, ME+32) @@ -1021,14 +964,14 @@ XEEMITTER(rlwinmx, 0x54000000, M )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(rlwnmx, 0x5C000000, M )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(rlwnmx, 0x5C000000, M)(PPCHIRBuilder& f, InstrData& i) { // n <- (RB)[59:63] // r <- ROTL32((RS)[32:63], n) // m <- MASK(MB+32, ME+32) // RA <- r & m Value* v = f.Truncate(f.LoadGPR(i.M.RT), INT32_TYPE); - Value* sh = f.And(f.Truncate(f.LoadGPR(i.M.SH), INT32_TYPE), - f.LoadConstant(0x1F)); + Value* sh = + f.And(f.Truncate(f.LoadGPR(i.M.SH), INT32_TYPE), f.LoadConstant(0x1F)); v = f.RotateLeft(v, sh); // Compiler sometimes masks with 0xFFFFFFFF (identity) - avoid the work here // as our truncation/zero-extend does it for us. @@ -1043,10 +986,9 @@ XEEMITTER(rlwnmx, 0x5C000000, M )(PPCHIRBuilder& f, InstrData& i) { return 0; } - // Integer shift (A-7) -XEEMITTER(sldx, 0x7C000036, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(sldx, 0x7C000036, X)(PPCHIRBuilder& f, InstrData& i) { // n <- (RB)[59:63] // r <- ROTL64((RS), n) // if (RB)[58] = 0 then @@ -1062,7 +1004,7 @@ XEEMITTER(sldx, 0x7C000036, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(slwx, 0x7C000030, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(slwx, 0x7C000030, X)(PPCHIRBuilder& f, InstrData& i) { // n <- (RB)[59:63] // r <- ROTL32((RS)[32:63], n) // if (RB)[58] = 0 then @@ -1070,8 +1012,8 @@ XEEMITTER(slwx, 0x7C000030, X )(PPCHIRBuilder& f, InstrData& i) { // else // m <- i64.0 // RA <- r & m - Value* v = f.Shl(f.Truncate(f.LoadGPR(i.X.RT), INT32_TYPE), - f.LoadGPR(i.X.RB)); + Value* v = + f.Shl(f.Truncate(f.LoadGPR(i.X.RT), INT32_TYPE), f.LoadGPR(i.X.RB)); v = f.ZeroExtend(v, INT64_TYPE); f.StoreGPR(i.X.RA, v); if (i.X.Rc) { @@ -1080,7 +1022,7 @@ XEEMITTER(slwx, 0x7C000030, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(srdx, 0x7C000436, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(srdx, 0x7C000436, X)(PPCHIRBuilder& f, InstrData& i) { // n <- (RB)[58:63] // r <- ROTL64((RS), 64-n) // if (RB)[57] = 0 then @@ -1097,7 +1039,7 @@ XEEMITTER(srdx, 0x7C000436, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(srwx, 0x7C000430, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(srwx, 0x7C000430, X)(PPCHIRBuilder& f, InstrData& i) { // n <- (RB)[59:63] // r <- ROTL32((RS)[32:63], 64-n) // if (RB)[58] = 0 then @@ -1106,8 +1048,8 @@ XEEMITTER(srwx, 0x7C000430, X )(PPCHIRBuilder& f, InstrData& i) { // m <- i64.0 // RA <- r & m // TODO(benvanik): if >1F, zero out the result. - Value* v = f.Shr(f.Truncate(f.LoadGPR(i.X.RT), INT32_TYPE), - f.LoadGPR(i.X.RB)); + Value* v = + f.Shr(f.Truncate(f.LoadGPR(i.X.RT), INT32_TYPE), f.LoadGPR(i.X.RB)); v = f.ZeroExtend(v, INT64_TYPE); f.StoreGPR(i.X.RA, v); if (i.X.Rc) { @@ -1116,7 +1058,7 @@ XEEMITTER(srwx, 0x7C000430, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(sradx, 0x7C000634, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(sradx, 0x7C000634, X)(PPCHIRBuilder& f, InstrData& i) { // n <- rB[58-63] // r <- ROTL[64](rS, 64 - n) // if rB[57] = 0 then m ← MASK(n, 63) @@ -1136,8 +1078,7 @@ XEEMITTER(sradx, 0x7C000634, X )(PPCHIRBuilder& f, InstrData& i) { // is negative. Start tracking that here. // TODO(benvanik): dynamically generate mask better than this. Value* ca_sh = f.Sub(f.LoadConstant((int8_t)63), sh); - Value* ca = - f.Shr(f.Shl(f.LoadConstant(0xFFFFFFFFFFFFFFFFull), ca_sh), ca_sh); + Value* ca = f.Shr(f.Shl(f.LoadConstant(0xFFFFFFFFFFFFFFFFull), ca_sh), ca_sh); ca = f.CompareNE(f.And(ca, v), f.LoadZero(INT64_TYPE)); // Shift right. @@ -1157,7 +1098,7 @@ XEEMITTER(sradx, 0x7C000634, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(sradix, 0x7C000674, XS )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(sradix, 0x7C000674, XS)(PPCHIRBuilder& f, InstrData& i) { // n <- sh[5] || sh[0-4] // r <- ROTL[64](rS, 64 - n) // m ← MASK(n, 63) @@ -1173,9 +1114,8 @@ XEEMITTER(sradix, 0x7C000674, XS )(PPCHIRBuilder& f, InstrData& i) { // is negative. XEASSERT(sh); uint64_t mask = XEMASK(64 - sh, 63); - Value* ca = f.And( - f.Truncate(f.Shr(v, 63), INT8_TYPE), - f.IsTrue(f.And(v, f.LoadConstant(mask)))); + Value* ca = f.And(f.Truncate(f.Shr(v, 63), INT8_TYPE), + f.IsTrue(f.And(v, f.LoadConstant(mask)))); f.StoreCA(ca); v = f.Sha(v, sh); @@ -1186,7 +1126,7 @@ XEEMITTER(sradix, 0x7C000674, XS )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(srawx, 0x7C000630, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(srawx, 0x7C000630, X)(PPCHIRBuilder& f, InstrData& i) { // n <- rB[59-63] // r <- ROTL32((RS)[32:63], 64-n) // m <- MASK(n+32, 63) @@ -1196,18 +1136,15 @@ XEEMITTER(srawx, 0x7C000630, X )(PPCHIRBuilder& f, InstrData& i) { // if n == 0: rA <- sign_extend(rS), XER[CA] = 0 // if n >= 32: rA <- 64 sign bits of rS, XER[CA] = sign bit of lo_32(rS) Value* v = f.Truncate(f.LoadGPR(i.X.RT), INT32_TYPE); - Value* sh = f.And( - f.Truncate(f.LoadGPR(i.X.RB), INT32_TYPE), - f.LoadConstant(0x7F)); + Value* sh = + f.And(f.Truncate(f.LoadGPR(i.X.RB), INT32_TYPE), f.LoadConstant(0x7F)); // CA is set if any bits are shifted out of the right and if the result // is negative. Value* mask = f.Not(f.Shl(f.LoadConstant(-1), sh)); - Value* ca = f.And( - f.Truncate(f.Shr(v, 31), INT8_TYPE), - f.IsTrue(f.And(v, mask))); + Value* ca = + f.And(f.Truncate(f.Shr(v, 31), INT8_TYPE), f.IsTrue(f.And(v, mask))); f.StoreCA(ca); - v = f.Sha(v, sh), - v = f.SignExtend(v, INT64_TYPE); + v = f.Sha(v, sh), v = f.SignExtend(v, INT64_TYPE); f.StoreGPR(i.X.RA, v); if (i.X.Rc) { f.UpdateCR(0, v); @@ -1215,7 +1152,7 @@ XEEMITTER(srawx, 0x7C000630, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(srawix, 0x7C000670, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(srawix, 0x7C000670, X)(PPCHIRBuilder& f, InstrData& i) { // n <- SH // r <- ROTL32((RS)[32:63], 64-n) // m <- MASK(n+32, 63) @@ -1234,12 +1171,10 @@ XEEMITTER(srawix, 0x7C000670, X )(PPCHIRBuilder& f, InstrData& i) { // CA is set if any bits are shifted out of the right and if the result // is negative. uint32_t mask = (uint32_t)XEMASK(64 - i.X.RB, 63); - ca = f.And( - f.Truncate(f.Shr(v, 31), INT8_TYPE), - f.IsTrue(f.And(v, f.LoadConstant(mask)))); + ca = f.And(f.Truncate(f.Shr(v, 31), INT8_TYPE), + f.IsTrue(f.And(v, f.LoadConstant(mask)))); - v = f.Sha(v, (int8_t)i.X.RB), - v = f.SignExtend(v, INT64_TYPE); + v = f.Sha(v, (int8_t)i.X.RB), v = f.SignExtend(v, INT64_TYPE); } f.StoreCA(ca); f.StoreGPR(i.X.RA, v); @@ -1249,79 +1184,77 @@ XEEMITTER(srawix, 0x7C000670, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } - void RegisterEmitCategoryALU() { - XEREGISTERINSTR(addx, 0x7C000214); - XEREGISTERINSTR(addcx, 0X7C000014); - XEREGISTERINSTR(addex, 0x7C000114); - XEREGISTERINSTR(addi, 0x38000000); - XEREGISTERINSTR(addic, 0x30000000); - XEREGISTERINSTR(addicx, 0x34000000); - XEREGISTERINSTR(addis, 0x3C000000); - XEREGISTERINSTR(addmex, 0x7C0001D4); - XEREGISTERINSTR(addzex, 0x7C000194); - XEREGISTERINSTR(divdx, 0x7C0003D2); - XEREGISTERINSTR(divdux, 0x7C000392); - XEREGISTERINSTR(divwx, 0x7C0003D6); - XEREGISTERINSTR(divwux, 0x7C000396); - XEREGISTERINSTR(mulhdx, 0x7C000092); - XEREGISTERINSTR(mulhdux, 0x7C000012); - XEREGISTERINSTR(mulhwx, 0x7C000096); - XEREGISTERINSTR(mulhwux, 0x7C000016); - XEREGISTERINSTR(mulldx, 0x7C0001D2); - XEREGISTERINSTR(mulli, 0x1C000000); - XEREGISTERINSTR(mullwx, 0x7C0001D6); - XEREGISTERINSTR(negx, 0x7C0000D0); - XEREGISTERINSTR(subfx, 0x7C000050); - XEREGISTERINSTR(subfcx, 0x7C000010); - XEREGISTERINSTR(subficx, 0x20000000); - XEREGISTERINSTR(subfex, 0x7C000110); - XEREGISTERINSTR(subfmex, 0x7C0001D0); - XEREGISTERINSTR(subfzex, 0x7C000190); - XEREGISTERINSTR(cmp, 0x7C000000); - XEREGISTERINSTR(cmpi, 0x2C000000); - XEREGISTERINSTR(cmpl, 0x7C000040); - XEREGISTERINSTR(cmpli, 0x28000000); - XEREGISTERINSTR(andx, 0x7C000038); - XEREGISTERINSTR(andcx, 0x7C000078); - XEREGISTERINSTR(andix, 0x70000000); - XEREGISTERINSTR(andisx, 0x74000000); - XEREGISTERINSTR(cntlzdx, 0x7C000074); - XEREGISTERINSTR(cntlzwx, 0x7C000034); - XEREGISTERINSTR(eqvx, 0x7C000238); - XEREGISTERINSTR(extsbx, 0x7C000774); - XEREGISTERINSTR(extshx, 0x7C000734); - XEREGISTERINSTR(extswx, 0x7C0007B4); - XEREGISTERINSTR(nandx, 0x7C0003B8); - XEREGISTERINSTR(norx, 0x7C0000F8); - XEREGISTERINSTR(orx, 0x7C000378); - XEREGISTERINSTR(orcx, 0x7C000338); - XEREGISTERINSTR(ori, 0x60000000); - XEREGISTERINSTR(oris, 0x64000000); - XEREGISTERINSTR(xorx, 0x7C000278); - XEREGISTERINSTR(xori, 0x68000000); - XEREGISTERINSTR(xoris, 0x6C000000); - XEREGISTERINSTR(rld, 0x78000000); + XEREGISTERINSTR(addx, 0x7C000214); + XEREGISTERINSTR(addcx, 0X7C000014); + XEREGISTERINSTR(addex, 0x7C000114); + XEREGISTERINSTR(addi, 0x38000000); + XEREGISTERINSTR(addic, 0x30000000); + XEREGISTERINSTR(addicx, 0x34000000); + XEREGISTERINSTR(addis, 0x3C000000); + XEREGISTERINSTR(addmex, 0x7C0001D4); + XEREGISTERINSTR(addzex, 0x7C000194); + XEREGISTERINSTR(divdx, 0x7C0003D2); + XEREGISTERINSTR(divdux, 0x7C000392); + XEREGISTERINSTR(divwx, 0x7C0003D6); + XEREGISTERINSTR(divwux, 0x7C000396); + XEREGISTERINSTR(mulhdx, 0x7C000092); + XEREGISTERINSTR(mulhdux, 0x7C000012); + XEREGISTERINSTR(mulhwx, 0x7C000096); + XEREGISTERINSTR(mulhwux, 0x7C000016); + XEREGISTERINSTR(mulldx, 0x7C0001D2); + XEREGISTERINSTR(mulli, 0x1C000000); + XEREGISTERINSTR(mullwx, 0x7C0001D6); + XEREGISTERINSTR(negx, 0x7C0000D0); + XEREGISTERINSTR(subfx, 0x7C000050); + XEREGISTERINSTR(subfcx, 0x7C000010); + XEREGISTERINSTR(subficx, 0x20000000); + XEREGISTERINSTR(subfex, 0x7C000110); + XEREGISTERINSTR(subfmex, 0x7C0001D0); + XEREGISTERINSTR(subfzex, 0x7C000190); + XEREGISTERINSTR(cmp, 0x7C000000); + XEREGISTERINSTR(cmpi, 0x2C000000); + XEREGISTERINSTR(cmpl, 0x7C000040); + XEREGISTERINSTR(cmpli, 0x28000000); + XEREGISTERINSTR(andx, 0x7C000038); + XEREGISTERINSTR(andcx, 0x7C000078); + XEREGISTERINSTR(andix, 0x70000000); + XEREGISTERINSTR(andisx, 0x74000000); + XEREGISTERINSTR(cntlzdx, 0x7C000074); + XEREGISTERINSTR(cntlzwx, 0x7C000034); + XEREGISTERINSTR(eqvx, 0x7C000238); + XEREGISTERINSTR(extsbx, 0x7C000774); + XEREGISTERINSTR(extshx, 0x7C000734); + XEREGISTERINSTR(extswx, 0x7C0007B4); + XEREGISTERINSTR(nandx, 0x7C0003B8); + XEREGISTERINSTR(norx, 0x7C0000F8); + XEREGISTERINSTR(orx, 0x7C000378); + XEREGISTERINSTR(orcx, 0x7C000338); + XEREGISTERINSTR(ori, 0x60000000); + XEREGISTERINSTR(oris, 0x64000000); + XEREGISTERINSTR(xorx, 0x7C000278); + XEREGISTERINSTR(xori, 0x68000000); + XEREGISTERINSTR(xoris, 0x6C000000); + XEREGISTERINSTR(rld, 0x78000000); // -- // XEREGISTERINSTR(rldclx, 0x78000010); // -- // XEREGISTERINSTR(rldcrx, 0x78000012); // -- // XEREGISTERINSTR(rldicx, 0x78000008); // -- // XEREGISTERINSTR(rldiclx, 0x78000000); // -- // XEREGISTERINSTR(rldicrx, 0x78000004); // -- // XEREGISTERINSTR(rldimix, 0x7800000C); - XEREGISTERINSTR(rlwimix, 0x50000000); - XEREGISTERINSTR(rlwinmx, 0x54000000); - XEREGISTERINSTR(rlwnmx, 0x5C000000); - XEREGISTERINSTR(sldx, 0x7C000036); - XEREGISTERINSTR(slwx, 0x7C000030); - XEREGISTERINSTR(srdx, 0x7C000436); - XEREGISTERINSTR(srwx, 0x7C000430); - XEREGISTERINSTR(sradx, 0x7C000634); - XEREGISTERINSTR(sradix, 0x7C000674); - XEREGISTERINSTR(srawx, 0x7C000630); - XEREGISTERINSTR(srawix, 0x7C000670); + XEREGISTERINSTR(rlwimix, 0x50000000); + XEREGISTERINSTR(rlwinmx, 0x54000000); + XEREGISTERINSTR(rlwnmx, 0x5C000000); + XEREGISTERINSTR(sldx, 0x7C000036); + XEREGISTERINSTR(slwx, 0x7C000030); + XEREGISTERINSTR(srdx, 0x7C000436); + XEREGISTERINSTR(srwx, 0x7C000430); + XEREGISTERINSTR(sradx, 0x7C000634); + XEREGISTERINSTR(sradix, 0x7C000674); + XEREGISTERINSTR(srawx, 0x7C000630); + XEREGISTERINSTR(srawix, 0x7C000670); } - } // namespace ppc } // namespace frontend } // namespace alloy diff --git a/src/alloy/frontend/ppc/ppc_emit_control.cc b/src/alloy/frontend/ppc/ppc_emit_control.cc index 111be91a3..439a1f02d 100644 --- a/src/alloy/frontend/ppc/ppc_emit_control.cc +++ b/src/alloy/frontend/ppc/ppc_emit_control.cc @@ -12,21 +12,19 @@ #include #include - -using namespace alloy::frontend::ppc; -using namespace alloy::hir; -using namespace alloy::runtime; - - namespace alloy { namespace frontend { namespace ppc { +// TODO(benvanik): remove when enums redefined. +using namespace alloy::hir; -int InstrEmit_branch( - PPCHIRBuilder& f, const char* src, uint64_t cia, - Value* nia, bool lk, Value* cond = NULL, bool expect_true = true, - bool nia_is_lr = false) { +using alloy::hir::Label; +using alloy::hir::Value; + +int InstrEmit_branch(PPCHIRBuilder& f, const char* src, uint64_t cia, + Value* nia, bool lk, Value* cond = NULL, + bool expect_true = true, bool nia_is_lr = false) { uint32_t call_flags = 0; // TODO(benvanik): this may be wrong and overwrite LRs when not desired! @@ -54,8 +52,7 @@ int InstrEmit_branch( // recursion. uint64_t nia_value = nia->AsUint64() & 0xFFFFFFFF; bool is_recursion = false; - if (nia_value == f.symbol_info()->address() && - lk) { + if (nia_value == f.symbol_info()->address() && lk) { is_recursion = true; } Label* label = is_recursion ? NULL : f.LookupLabel(nia_value); @@ -73,7 +70,7 @@ int InstrEmit_branch( } } else { // Call function. - FunctionInfo* symbol_info = f.LookupFunction(nia_value); + auto symbol_info = f.LookupFunction(nia_value); if (cond) { if (!expect_true) { cond = f.IsFalse(cond); @@ -84,27 +81,27 @@ int InstrEmit_branch( } } } else { - // Indirect branch to pointer. +// Indirect branch to pointer. - // TODO(benvanik): runtime recursion detection? +// TODO(benvanik): runtime recursion detection? - // TODO(benvanik): run a DFA pass to see if we can detect whether this is - // a normal function return that is pulling the LR from the stack that - // it set in the prolog. If so, we can omit the dynamic check! +// TODO(benvanik): run a DFA pass to see if we can detect whether this is +// a normal function return that is pulling the LR from the stack that +// it set in the prolog. If so, we can omit the dynamic check! - //// Dynamic test when branching to LR, which is usually used for the return. - //// We only do this if LK=0 as returns wouldn't set LR. - //// Ideally it's a return and we can just do a simple ret and be done. - //// If it's not, we fall through to the full indirection logic. - //if (!lk && reg == kXEPPCRegLR) { - // // The return block will spill registers for us. - // // TODO(benvanik): 'lr_mismatch' debug info. - // // Note: we need to test on *only* the 32-bit target, as the target ptr may - // // have garbage in the upper 32 bits. - // c.cmp(target.r32(), c.getGpArg(1).r32()); - // // TODO(benvanik): evaluate hint here. - // c.je(e.GetReturnLabel(), kCondHintLikely); - //} +//// Dynamic test when branching to LR, which is usually used for the return. +//// We only do this if LK=0 as returns wouldn't set LR. +//// Ideally it's a return and we can just do a simple ret and be done. +//// If it's not, we fall through to the full indirection logic. +// if (!lk && reg == kXEPPCRegLR) { +// // The return block will spill registers for us. +// // TODO(benvanik): 'lr_mismatch' debug info. +// // Note: we need to test on *only* the 32-bit target, as the target ptr may +// // have garbage in the upper 32 bits. +// c.cmp(target.r32(), c.getGpArg(1).r32()); +// // TODO(benvanik): evaluate hint here. +// c.je(e.GetReturnLabel(), kCondHintLikely); +//} #if 0 // This breaks longjump, as that uses blr with a non-return lr. // It'd be nice to move SET_RETURN_ADDRESS semantics up into context @@ -124,27 +121,26 @@ int InstrEmit_branch( #else { #endif - // Jump to pointer. - bool likely_return = !lk && nia_is_lr; - if (likely_return) { - call_flags |= CALL_POSSIBLE_RETURN; - } - if (cond) { - if (!expect_true) { - cond = f.IsFalse(cond); - } - f.CallIndirectTrue(cond, nia, call_flags); - } else { - f.CallIndirect(nia, call_flags); + // Jump to pointer. + bool likely_return = !lk && nia_is_lr; + if (likely_return) { + call_flags |= CALL_POSSIBLE_RETURN; + } + if (cond) { + if (!expect_true) { + cond = f.IsFalse(cond); } + f.CallIndirectTrue(cond, nia, call_flags); + } else { + f.CallIndirect(nia, call_flags); } } - - return 0; } +return 0; +} -XEEMITTER(bx, 0x48000000, I )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(bx, 0x48000000, I)(PPCHIRBuilder& f, InstrData& i) { // if AA then // NIA <- EXTS(LI || 0b00) // else @@ -159,11 +155,10 @@ XEEMITTER(bx, 0x48000000, I )(PPCHIRBuilder& f, InstrData& i) { nia = (uint32_t)(i.address + XEEXTS26(i.I.LI << 2)); } - return InstrEmit_branch( - f, "bx", i.address, f.LoadConstant(nia), i.I.LK); + return InstrEmit_branch(f, "bx", i.address, f.LoadConstant(nia), i.I.LK); } -XEEMITTER(bcx, 0x40000000, B )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(bcx, 0x40000000, B)(PPCHIRBuilder& f, InstrData& i) { // if ¬BO[2] then // CTR <- CTR - 1 // ctr_ok <- BO[2] | ((CTR[0:63] != 0) XOR BO[3]) @@ -236,11 +231,11 @@ XEEMITTER(bcx, 0x40000000, B )(PPCHIRBuilder& f, InstrData& i) { } else { nia = (uint32_t)(i.address + XEEXTS16(i.B.BD << 2)); } - return InstrEmit_branch( - f, "bcx", i.address, f.LoadConstant(nia), i.B.LK, ok, expect_true); + return InstrEmit_branch(f, "bcx", i.address, f.LoadConstant(nia), i.B.LK, ok, + expect_true); } -XEEMITTER(bcctrx, 0x4C000420, XL )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(bcctrx, 0x4C000420, XL)(PPCHIRBuilder& f, InstrData& i) { // cond_ok <- BO[0] | (CR[BI+32] ≡ BO[1]) // if cond_ok then // NIA <- CTR[0:61] || 0b00 @@ -268,11 +263,11 @@ XEEMITTER(bcctrx, 0x4C000420, XL )(PPCHIRBuilder& f, InstrData& i) { } bool expect_true = !not_cond_ok; - return InstrEmit_branch( - f, "bcctrx", i.address, f.LoadCTR(), i.XL.LK, cond_ok, expect_true); + return InstrEmit_branch(f, "bcctrx", i.address, f.LoadCTR(), i.XL.LK, cond_ok, + expect_true); } -XEEMITTER(bclrx, 0x4C000020, XL )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(bclrx, 0x4C000020, XL)(PPCHIRBuilder& f, InstrData& i) { // if ¬BO[2] then // CTR <- CTR - 1 // ctr_ok <- BO[2] | ((CTR[0:63] != 0) XOR BO[3] @@ -336,71 +331,68 @@ XEEMITTER(bclrx, 0x4C000020, XL )(PPCHIRBuilder& f, InstrData& i) { expect_true = !not_cond_ok; } - return InstrEmit_branch( - f, "bclrx", i.address, f.LoadLR(), i.XL.LK, ok, expect_true, true); + return InstrEmit_branch(f, "bclrx", i.address, f.LoadLR(), i.XL.LK, ok, + expect_true, true); } - // Condition register logical (A-23) -XEEMITTER(crand, 0x4C000202, XL )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(crand, 0x4C000202, XL)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(crandc, 0x4C000102, XL )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(crandc, 0x4C000102, XL)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(creqv, 0x4C000242, XL )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(creqv, 0x4C000242, XL)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(crnand, 0x4C0001C2, XL )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(crnand, 0x4C0001C2, XL)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(crnor, 0x4C000042, XL )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(crnor, 0x4C000042, XL)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(cror, 0x4C000382, XL )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(cror, 0x4C000382, XL)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(crorc, 0x4C000342, XL )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(crorc, 0x4C000342, XL)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(crxor, 0x4C000182, XL )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(crxor, 0x4C000182, XL)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(mcrf, 0x4C000000, XL )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mcrf, 0x4C000000, XL)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } - // System linkage (A-24) -XEEMITTER(sc, 0x44000002, SC )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(sc, 0x44000002, SC)(PPCHIRBuilder& f, InstrData& i) { f.CallExtern(f.symbol_info()); return 0; } - // Trap (A-25) -int InstrEmit_trap(PPCHIRBuilder& f, InstrData& i, - Value* va, Value* vb, uint32_t TO) { +int InstrEmit_trap(PPCHIRBuilder& f, InstrData& i, Value* va, Value* vb, + uint32_t TO) { // if (a < b) & TO[0] then TRAP // if (a > b) & TO[1] then TRAP // if (a = b) & TO[2] then TRAP @@ -435,7 +427,7 @@ int InstrEmit_trap(PPCHIRBuilder& f, InstrData& i, return 0; } -XEEMITTER(td, 0x7C000088, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(td, 0x7C000088, X)(PPCHIRBuilder& f, InstrData& i) { // a <- (RA) // b <- (RB) // if (a < b) & TO[0] then TRAP @@ -448,7 +440,7 @@ XEEMITTER(td, 0x7C000088, X )(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_trap(f, i, ra, rb, i.X.RT); } -XEEMITTER(tdi, 0x08000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(tdi, 0x08000000, D)(PPCHIRBuilder& f, InstrData& i) { // a <- (RA) // if (a < EXTS(SI)) & TO[0] then TRAP // if (a > EXTS(SI)) & TO[1] then TRAP @@ -460,7 +452,7 @@ XEEMITTER(tdi, 0x08000000, D )(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_trap(f, i, ra, rb, i.D.RT); } -XEEMITTER(tw, 0x7C000008, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(tw, 0x7C000008, X)(PPCHIRBuilder& f, InstrData& i) { // a <- EXTS((RA)[32:63]) // b <- EXTS((RB)[32:63]) // if (a < b) & TO[0] then TRAP @@ -468,14 +460,14 @@ XEEMITTER(tw, 0x7C000008, X )(PPCHIRBuilder& f, InstrData& i) { // if (a = b) & TO[2] then TRAP // if (a u b) & TO[4] then TRAP - Value* ra = f.SignExtend(f.Truncate( - f.LoadGPR(i.X.RA), INT32_TYPE), INT64_TYPE); - Value* rb = f.SignExtend(f.Truncate( - f.LoadGPR(i.X.RB), INT32_TYPE), INT64_TYPE); + Value* ra = + f.SignExtend(f.Truncate(f.LoadGPR(i.X.RA), INT32_TYPE), INT64_TYPE); + Value* rb = + f.SignExtend(f.Truncate(f.LoadGPR(i.X.RB), INT32_TYPE), INT64_TYPE); return InstrEmit_trap(f, i, ra, rb, i.X.RT); } -XEEMITTER(twi, 0x0C000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(twi, 0x0C000000, D)(PPCHIRBuilder& f, InstrData& i) { // a <- EXTS((RA)[32:63]) // if (a < EXTS(SI)) & TO[0] then TRAP // if (a > EXTS(SI)) & TO[1] then TRAP @@ -488,21 +480,20 @@ XEEMITTER(twi, 0x0C000000, D )(PPCHIRBuilder& f, InstrData& i) { f.Trap(type); return 0; } - Value* ra = f.SignExtend(f.Truncate( - f.LoadGPR(i.D.RA), INT32_TYPE), INT64_TYPE); + Value* ra = + f.SignExtend(f.Truncate(f.LoadGPR(i.D.RA), INT32_TYPE), INT64_TYPE); Value* rb = f.LoadConstant(XEEXTS16(i.D.DS)); return InstrEmit_trap(f, i, ra, rb, i.D.RT); } - // Processor control (A-26) -XEEMITTER(mfcr, 0x7C000026, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mfcr, 0x7C000026, X)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(mfspr, 0x7C0002A6, XFX)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mfspr, 0x7C0002A6, XFX)(PPCHIRBuilder& f, InstrData& i) { // n <- spr[5:9] || spr[0:4] // if length(SPR(n)) = 64 then // RT <- SPR(n) @@ -511,40 +502,40 @@ XEEMITTER(mfspr, 0x7C0002A6, XFX)(PPCHIRBuilder& f, InstrData& i) { Value* v; const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F); switch (n) { - case 1: - // XER - v = f.LoadXER(); - break; - case 8: - // LR - v = f.LoadLR(); - break; - case 9: - // CTR - v = f.LoadCTR(); - break; - // 268 + 269 = TB + TBU - default: - XEINSTRNOTIMPLEMENTED(); - return 1; + case 1: + // XER + v = f.LoadXER(); + break; + case 8: + // LR + v = f.LoadLR(); + break; + case 9: + // CTR + v = f.LoadCTR(); + break; + // 268 + 269 = TB + TBU + default: + XEINSTRNOTIMPLEMENTED(); + return 1; } f.StoreGPR(i.XFX.RT, v); return 0; } -XEEMITTER(mftb, 0x7C0002E6, XFX)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mftb, 0x7C0002E6, XFX)(PPCHIRBuilder& f, InstrData& i) { Value* time = f.LoadClock(); f.StoreGPR(i.XFX.RT, time); return 0; } -XEEMITTER(mtcrf, 0x7C000120, XFX)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mtcrf, 0x7C000120, XFX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(mtspr, 0x7C0003A6, XFX)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mtspr, 0x7C0003A6, XFX)(PPCHIRBuilder& f, InstrData& i) { // n <- spr[5:9] || spr[0:4] // if length(SPR(n)) = 64 then // SPR(n) <- (RS) @@ -555,21 +546,21 @@ XEEMITTER(mtspr, 0x7C0003A6, XFX)(PPCHIRBuilder& f, InstrData& i) { const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F); switch (n) { - case 1: - // XER - f.StoreXER(rt); - break; - case 8: - // LR - f.StoreLR(rt); - break; - case 9: - // CTR - f.StoreCTR(rt); - break; - default: - XEINSTRNOTIMPLEMENTED(); - return 1; + case 1: + // XER + f.StoreXER(rt); + break; + case 8: + // LR + f.StoreLR(rt); + break; + case 9: + // CTR + f.StoreCTR(rt); + break; + default: + XEINSTRNOTIMPLEMENTED(); + return 1; } return 0; @@ -578,52 +569,50 @@ XEEMITTER(mtspr, 0x7C0003A6, XFX)(PPCHIRBuilder& f, InstrData& i) { // TODO(benvanik): MSR is used for toggling interrupts, and it'd be nice to // obey that setting. It's usually guarding atomic stores. -XEEMITTER(mfmsr, 0x7C0000A6, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mfmsr, 0x7C0000A6, X)(PPCHIRBuilder& f, InstrData& i) { f.Nop(); return 0; } -XEEMITTER(mtmsr, 0x7C000124, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mtmsr, 0x7C000124, X)(PPCHIRBuilder& f, InstrData& i) { f.Nop(); return 0; } -XEEMITTER(mtmsrd, 0x7C000164, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mtmsrd, 0x7C000164, X)(PPCHIRBuilder& f, InstrData& i) { f.Nop(); return 0; } - void RegisterEmitCategoryControl() { - XEREGISTERINSTR(bx, 0x48000000); - XEREGISTERINSTR(bcx, 0x40000000); - XEREGISTERINSTR(bcctrx, 0x4C000420); - XEREGISTERINSTR(bclrx, 0x4C000020); - XEREGISTERINSTR(crand, 0x4C000202); - XEREGISTERINSTR(crandc, 0x4C000102); - XEREGISTERINSTR(creqv, 0x4C000242); - XEREGISTERINSTR(crnand, 0x4C0001C2); - XEREGISTERINSTR(crnor, 0x4C000042); - XEREGISTERINSTR(cror, 0x4C000382); - XEREGISTERINSTR(crorc, 0x4C000342); - XEREGISTERINSTR(crxor, 0x4C000182); - XEREGISTERINSTR(mcrf, 0x4C000000); - XEREGISTERINSTR(sc, 0x44000002); - XEREGISTERINSTR(td, 0x7C000088); - XEREGISTERINSTR(tdi, 0x08000000); - XEREGISTERINSTR(tw, 0x7C000008); - XEREGISTERINSTR(twi, 0x0C000000); - XEREGISTERINSTR(mfcr, 0x7C000026); - XEREGISTERINSTR(mfspr, 0x7C0002A6); - XEREGISTERINSTR(mftb, 0x7C0002E6); - XEREGISTERINSTR(mtcrf, 0x7C000120); - XEREGISTERINSTR(mtspr, 0x7C0003A6); - XEREGISTERINSTR(mfmsr, 0x7C0000A6); - XEREGISTERINSTR(mtmsr, 0x7C000124); - XEREGISTERINSTR(mtmsrd, 0x7C000164); + XEREGISTERINSTR(bx, 0x48000000); + XEREGISTERINSTR(bcx, 0x40000000); + XEREGISTERINSTR(bcctrx, 0x4C000420); + XEREGISTERINSTR(bclrx, 0x4C000020); + XEREGISTERINSTR(crand, 0x4C000202); + XEREGISTERINSTR(crandc, 0x4C000102); + XEREGISTERINSTR(creqv, 0x4C000242); + XEREGISTERINSTR(crnand, 0x4C0001C2); + XEREGISTERINSTR(crnor, 0x4C000042); + XEREGISTERINSTR(cror, 0x4C000382); + XEREGISTERINSTR(crorc, 0x4C000342); + XEREGISTERINSTR(crxor, 0x4C000182); + XEREGISTERINSTR(mcrf, 0x4C000000); + XEREGISTERINSTR(sc, 0x44000002); + XEREGISTERINSTR(td, 0x7C000088); + XEREGISTERINSTR(tdi, 0x08000000); + XEREGISTERINSTR(tw, 0x7C000008); + XEREGISTERINSTR(twi, 0x0C000000); + XEREGISTERINSTR(mfcr, 0x7C000026); + XEREGISTERINSTR(mfspr, 0x7C0002A6); + XEREGISTERINSTR(mftb, 0x7C0002E6); + XEREGISTERINSTR(mtcrf, 0x7C000120); + XEREGISTERINSTR(mtspr, 0x7C0003A6); + XEREGISTERINSTR(mfmsr, 0x7C0000A6); + XEREGISTERINSTR(mtmsr, 0x7C000124); + XEREGISTERINSTR(mtmsrd, 0x7C000164); } - } // namespace ppc } // namespace frontend } // namespace alloy diff --git a/src/alloy/frontend/ppc/ppc_emit_fpu.cc b/src/alloy/frontend/ppc/ppc_emit_fpu.cc index c09fea20f..c651c6d6e 100644 --- a/src/alloy/frontend/ppc/ppc_emit_fpu.cc +++ b/src/alloy/frontend/ppc/ppc_emit_fpu.cc @@ -12,148 +12,145 @@ #include #include - -using namespace alloy::frontend::ppc; -using namespace alloy::hir; -using namespace alloy::runtime; - - namespace alloy { namespace frontend { namespace ppc { +// TODO(benvanik): remove when enums redefined. +using namespace alloy::hir; + +using alloy::hir::RoundMode; +using alloy::hir::Value; // Good source of information: // http://mamedev.org/source/src/emu/cpu/powerpc/ppc_ops.c // The correctness of that code is not reflected here yet -_- - // Enable rounding numbers to single precision as required. // This adds a bunch of work per operation and I'm not sure it's required. #define ROUND_TO_SINGLE - // Floating-point arithmetic (A-8) -XEEMITTER(faddx, 0xFC00002A, A )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(faddx, 0xFC00002A, A)(PPCHIRBuilder& f, InstrData& i) { // frD <- (frA) + (frB) Value* v = f.Add(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB)); f.StoreFPR(i.A.FRT, v); // f.UpdateFPRF(v); if (i.A.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } -XEEMITTER(faddsx, 0xEC00002A, A )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(faddsx, 0xEC00002A, A)(PPCHIRBuilder& f, InstrData& i) { // frD <- (frA) + (frB) Value* v = f.Add(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB)); v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE); f.StoreFPR(i.A.FRT, v); // f.UpdateFPRF(v); if (i.A.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } -XEEMITTER(fdivx, 0xFC000024, A )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fdivx, 0xFC000024, A)(PPCHIRBuilder& f, InstrData& i) { // frD <- frA / frB Value* v = f.Div(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB)); f.StoreFPR(i.A.FRT, v); // f.UpdateFPRF(v); if (i.A.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } -XEEMITTER(fdivsx, 0xEC000024, A )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fdivsx, 0xEC000024, A)(PPCHIRBuilder& f, InstrData& i) { // frD <- frA / frB Value* v = f.Div(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB)); v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE); f.StoreFPR(i.A.FRT, v); // f.UpdateFPRF(v); if (i.A.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } -XEEMITTER(fmulx, 0xFC000032, A )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fmulx, 0xFC000032, A)(PPCHIRBuilder& f, InstrData& i) { // frD <- (frA) x (frC) Value* v = f.Mul(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC)); f.StoreFPR(i.A.FRT, v); // f.UpdateFPRF(v); if (i.A.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } -XEEMITTER(fmulsx, 0xEC000032, A )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fmulsx, 0xEC000032, A)(PPCHIRBuilder& f, InstrData& i) { // frD <- (frA) x (frC) Value* v = f.Mul(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC)); v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE); f.StoreFPR(i.A.FRT, v); // f.UpdateFPRF(v); if (i.A.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } -XEEMITTER(fresx, 0xEC000030, A )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fresx, 0xEC000030, A)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(frsqrtex, 0xFC000034, A )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(frsqrtex, 0xFC000034, A)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(fsubx, 0xFC000028, A )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fsubx, 0xFC000028, A)(PPCHIRBuilder& f, InstrData& i) { // frD <- (frA) - (frB) Value* v = f.Sub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB)); f.StoreFPR(i.A.FRT, v); // f.UpdateFPRF(v); if (i.A.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } -XEEMITTER(fsubsx, 0xEC000028, A )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fsubsx, 0xEC000028, A)(PPCHIRBuilder& f, InstrData& i) { // frD <- (frA) - (frB) Value* v = f.Sub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB)); v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE); f.StoreFPR(i.A.FRT, v); // f.UpdateFPRF(v); if (i.A.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } -XEEMITTER(fselx, 0xFC00002E, A )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fselx, 0xFC00002E, A)(PPCHIRBuilder& f, InstrData& i) { // if (frA) >= 0.0 // then frD <- (frC) // else frD <- (frB) @@ -161,28 +158,28 @@ XEEMITTER(fselx, 0xFC00002E, A )(PPCHIRBuilder& f, InstrData& i) { Value* v = f.Select(ge, f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB)); f.StoreFPR(i.A.FRT, v); if (i.A.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } -XEEMITTER(fsqrtx, 0xFC00002C, A )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fsqrtx, 0xFC00002C, A)(PPCHIRBuilder& f, InstrData& i) { // Double precision: // frD <- sqrt(frB) Value* v = f.Sqrt(f.LoadFPR(i.A.FRA)); f.StoreFPR(i.A.FRT, v); // f.UpdateFPRF(v); if (i.A.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } -XEEMITTER(fsqrtsx, 0xEC00002C, A )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fsqrtsx, 0xEC00002C, A)(PPCHIRBuilder& f, InstrData& i) { // Single precision: // frD <- sqrt(frB) Value* v = f.Sqrt(f.LoadFPR(i.A.FRA)); @@ -190,144 +187,128 @@ XEEMITTER(fsqrtsx, 0xEC00002C, A )(PPCHIRBuilder& f, InstrData& i) { f.StoreFPR(i.A.FRT, v); // f.UpdateFPRF(v); if (i.A.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } - // Floating-point multiply-add (A-9) -XEEMITTER(fmaddx, 0xFC00003A, A )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fmaddx, 0xFC00003A, A)(PPCHIRBuilder& f, InstrData& i) { // frD <- (frA x frC) + frB - Value* v = f.MulAdd( - f.LoadFPR(i.A.FRA), - f.LoadFPR(i.A.FRC), - f.LoadFPR(i.A.FRB)); + Value* v = + f.MulAdd(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB)); f.StoreFPR(i.A.FRT, v); // f.UpdateFPRF(v); if (i.A.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } -XEEMITTER(fmaddsx, 0xEC00003A, A )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fmaddsx, 0xEC00003A, A)(PPCHIRBuilder& f, InstrData& i) { // frD <- (frA x frC) + frB - Value* v = f.MulAdd( - f.LoadFPR(i.A.FRA), - f.LoadFPR(i.A.FRC), - f.LoadFPR(i.A.FRB)); + Value* v = + f.MulAdd(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB)); v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE); f.StoreFPR(i.A.FRT, v); // f.UpdateFPRF(v); if (i.A.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } -XEEMITTER(fmsubx, 0xFC000038, A )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fmsubx, 0xFC000038, A)(PPCHIRBuilder& f, InstrData& i) { // frD <- (frA x frC) - frB - Value* v = f.MulSub( - f.LoadFPR(i.A.FRA), - f.LoadFPR(i.A.FRC), - f.LoadFPR(i.A.FRB)); + Value* v = + f.MulSub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB)); f.StoreFPR(i.A.FRT, v); // f.UpdateFPRF(v); if (i.A.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } -XEEMITTER(fmsubsx, 0xEC000038, A )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fmsubsx, 0xEC000038, A)(PPCHIRBuilder& f, InstrData& i) { // frD <- (frA x frC) - frB - Value* v = f.MulSub( - f.LoadFPR(i.A.FRA), - f.LoadFPR(i.A.FRC), - f.LoadFPR(i.A.FRB)); + Value* v = + f.MulSub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB)); v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE); f.StoreFPR(i.A.FRT, v); // f.UpdateFPRF(v); if (i.A.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } -XEEMITTER(fnmaddx, 0xFC00003E, A )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fnmaddx, 0xFC00003E, A)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(fnmaddsx, 0xEC00003E, A )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fnmaddsx, 0xEC00003E, A)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(fnmsubx, 0xFC00003C, A )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fnmsubx, 0xFC00003C, A)(PPCHIRBuilder& f, InstrData& i) { // frD <- -([frA x frC] - frB) - Value* v = f.Neg(f.MulSub( - f.LoadFPR(i.A.FRA), - f.LoadFPR(i.A.FRC), - f.LoadFPR(i.A.FRB))); + Value* v = f.Neg( + f.MulSub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB))); f.StoreFPR(i.A.FRT, v); // f.UpdateFPRF(v); if (i.A.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } -XEEMITTER(fnmsubsx, 0xEC00003C, A )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fnmsubsx, 0xEC00003C, A)(PPCHIRBuilder& f, InstrData& i) { // frD <- -([frA x frC] - frB) - Value* v = f.Neg(f.MulSub( - f.LoadFPR(i.A.FRA), - f.LoadFPR(i.A.FRC), - f.LoadFPR(i.A.FRB))); + Value* v = f.Neg( + f.MulSub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB))); v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE); f.StoreFPR(i.A.FRT, v); // f.UpdateFPRF(v); if (i.A.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } - // Floating-point rounding and conversion (A-10) -XEEMITTER(fcfidx, 0xFC00069C, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fcfidx, 0xFC00069C, X)(PPCHIRBuilder& f, InstrData& i) { // frD <- signed_int64_to_double( frB ) - Value* v = f.Convert( - f.Cast(f.LoadFPR(i.A.FRB), INT64_TYPE), - FLOAT64_TYPE); + Value* v = f.Convert(f.Cast(f.LoadFPR(i.A.FRB), INT64_TYPE), FLOAT64_TYPE); f.StoreFPR(i.A.FRT, v); // f.UpdateFPRF(v); if (i.A.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } -XEEMITTER(fctidx, 0xFC00065C, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fctidx, 0xFC00065C, X)(PPCHIRBuilder& f, InstrData& i) { // frD <- double_to_signed_int64( frB ) // TODO(benvanik): pull from FPSCR[RN] RoundMode round_mode = ROUND_TO_ZERO; @@ -336,19 +317,19 @@ XEEMITTER(fctidx, 0xFC00065C, X )(PPCHIRBuilder& f, InstrData& i) { f.StoreFPR(i.X.RT, v); // f.UpdateFPRF(v); if (i.X.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } -XEEMITTER(fctidzx, 0xFC00065E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fctidzx, 0xFC00065E, X)(PPCHIRBuilder& f, InstrData& i) { // TODO(benvanik): assuming round to zero is always set, is that ok? return InstrEmit_fctidx(f, i); } -XEEMITTER(fctiwx, 0xFC00001C, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fctiwx, 0xFC00001C, X)(PPCHIRBuilder& f, InstrData& i) { // frD <- double_to_signed_int32( frB ) // TODO(benvanik): pull from FPSCR[RN] RoundMode round_mode = ROUND_TO_ZERO; @@ -357,19 +338,19 @@ XEEMITTER(fctiwx, 0xFC00001C, X )(PPCHIRBuilder& f, InstrData& i) { f.StoreFPR(i.X.RT, v); // f.UpdateFPRF(v); if (i.A.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } -XEEMITTER(fctiwzx, 0xFC00001E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fctiwzx, 0xFC00001E, X)(PPCHIRBuilder& f, InstrData& i) { // TODO(benvanik): assuming round to zero is always set, is that ok? return InstrEmit_fctiwx(f, i); } -XEEMITTER(frspx, 0xFC000018, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(frspx, 0xFC000018, X)(PPCHIRBuilder& f, InstrData& i) { // frD <- Round_single(frB) // TODO(benvanik): pull from FPSCR[RN] RoundMode round_mode = ROUND_TO_ZERO; @@ -378,14 +359,13 @@ XEEMITTER(frspx, 0xFC000018, X )(PPCHIRBuilder& f, InstrData& i) { f.StoreFPR(i.X.RT, v); // f.UpdateFPRF(v); if (i.X.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } - // Floating-point compare (A-11) int InstrEmit_fcmpx_(PPCHIRBuilder& f, InstrData& i, bool ordered) { @@ -410,22 +390,21 @@ int InstrEmit_fcmpx_(PPCHIRBuilder& f, InstrData& i, bool ordered) { f.UpdateCR(crf, f.LoadFPR(i.X.RA), f.LoadFPR(i.X.RB), false); return 0; } -XEEMITTER(fcmpo, 0xFC000040, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fcmpo, 0xFC000040, X)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_fcmpx_(f, i, true); } -XEEMITTER(fcmpu, 0xFC000000, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fcmpu, 0xFC000000, X)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_fcmpx_(f, i, false); } - // Floating-point status and control register (A -XEEMITTER(mcrfs, 0xFC000080, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mcrfs, 0xFC000080, X)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(mffsx, 0xFC00048E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mffsx, 0xFC00048E, X)(PPCHIRBuilder& f, InstrData& i) { if (i.X.Rc) { XEINSTRNOTIMPLEMENTED(); return 1; @@ -434,17 +413,17 @@ XEEMITTER(mffsx, 0xFC00048E, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(mtfsb0x, 0xFC00008C, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mtfsb0x, 0xFC00008C, X)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(mtfsb1x, 0xFC00004C, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mtfsb1x, 0xFC00004C, X)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(mtfsfx, 0xFC00058E, XFL)(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mtfsfx, 0xFC00058E, XFL)(PPCHIRBuilder& f, InstrData& i) { if (i.XFL.Rc) { XEINSTRNOTIMPLEMENTED(); return 1; @@ -460,99 +439,96 @@ XEEMITTER(mtfsfx, 0xFC00058E, XFL)(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(mtfsfix, 0xFC00010C, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(mtfsfix, 0xFC00010C, X)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } - // Floating-point move (A-21) -XEEMITTER(fabsx, 0xFC000210, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fabsx, 0xFC000210, X)(PPCHIRBuilder& f, InstrData& i) { // frD <- abs(frB) Value* v = f.Abs(f.LoadFPR(i.X.RB)); f.StoreFPR(i.X.RT, v); if (i.X.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } -XEEMITTER(fmrx, 0xFC000090, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fmrx, 0xFC000090, X)(PPCHIRBuilder& f, InstrData& i) { // frD <- (frB) Value* v = f.LoadFPR(i.X.RB); f.StoreFPR(i.X.RT, v); if (i.X.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } -XEEMITTER(fnabsx, 0xFC000110, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fnabsx, 0xFC000110, X)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(fnegx, 0xFC000050, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(fnegx, 0xFC000050, X)(PPCHIRBuilder& f, InstrData& i) { // frD <- ¬ frB[0] || frB[1-63] Value* v = f.Neg(f.LoadFPR(i.X.RB)); f.StoreFPR(i.X.RT, v); if (i.X.Rc) { - //e.update_cr_with_cond(1, v); + // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; } return 0; } - void RegisterEmitCategoryFPU() { - XEREGISTERINSTR(faddx, 0xFC00002A); - XEREGISTERINSTR(faddsx, 0xEC00002A); - XEREGISTERINSTR(fdivx, 0xFC000024); - XEREGISTERINSTR(fdivsx, 0xEC000024); - XEREGISTERINSTR(fmulx, 0xFC000032); - XEREGISTERINSTR(fmulsx, 0xEC000032); - XEREGISTERINSTR(fresx, 0xEC000030); - XEREGISTERINSTR(frsqrtex, 0xFC000034); - XEREGISTERINSTR(fsubx, 0xFC000028); - XEREGISTERINSTR(fsubsx, 0xEC000028); - XEREGISTERINSTR(fselx, 0xFC00002E); - XEREGISTERINSTR(fsqrtx, 0xFC00002C); - XEREGISTERINSTR(fsqrtsx, 0xEC00002C); - XEREGISTERINSTR(fmaddx, 0xFC00003A); - XEREGISTERINSTR(fmaddsx, 0xEC00003A); - XEREGISTERINSTR(fmsubx, 0xFC000038); - XEREGISTERINSTR(fmsubsx, 0xEC000038); - XEREGISTERINSTR(fnmaddx, 0xFC00003E); - XEREGISTERINSTR(fnmaddsx, 0xEC00003E); - XEREGISTERINSTR(fnmsubx, 0xFC00003C); - XEREGISTERINSTR(fnmsubsx, 0xEC00003C); - XEREGISTERINSTR(fcfidx, 0xFC00069C); - XEREGISTERINSTR(fctidx, 0xFC00065C); - XEREGISTERINSTR(fctidzx, 0xFC00065E); - XEREGISTERINSTR(fctiwx, 0xFC00001C); - XEREGISTERINSTR(fctiwzx, 0xFC00001E); - XEREGISTERINSTR(frspx, 0xFC000018); - XEREGISTERINSTR(fcmpo, 0xFC000040); - XEREGISTERINSTR(fcmpu, 0xFC000000); - XEREGISTERINSTR(mcrfs, 0xFC000080); - XEREGISTERINSTR(mffsx, 0xFC00048E); - XEREGISTERINSTR(mtfsb0x, 0xFC00008C); - XEREGISTERINSTR(mtfsb1x, 0xFC00004C); - XEREGISTERINSTR(mtfsfx, 0xFC00058E); - XEREGISTERINSTR(mtfsfix, 0xFC00010C); - XEREGISTERINSTR(fabsx, 0xFC000210); - XEREGISTERINSTR(fmrx, 0xFC000090); - XEREGISTERINSTR(fnabsx, 0xFC000110); - XEREGISTERINSTR(fnegx, 0xFC000050); + XEREGISTERINSTR(faddx, 0xFC00002A); + XEREGISTERINSTR(faddsx, 0xEC00002A); + XEREGISTERINSTR(fdivx, 0xFC000024); + XEREGISTERINSTR(fdivsx, 0xEC000024); + XEREGISTERINSTR(fmulx, 0xFC000032); + XEREGISTERINSTR(fmulsx, 0xEC000032); + XEREGISTERINSTR(fresx, 0xEC000030); + XEREGISTERINSTR(frsqrtex, 0xFC000034); + XEREGISTERINSTR(fsubx, 0xFC000028); + XEREGISTERINSTR(fsubsx, 0xEC000028); + XEREGISTERINSTR(fselx, 0xFC00002E); + XEREGISTERINSTR(fsqrtx, 0xFC00002C); + XEREGISTERINSTR(fsqrtsx, 0xEC00002C); + XEREGISTERINSTR(fmaddx, 0xFC00003A); + XEREGISTERINSTR(fmaddsx, 0xEC00003A); + XEREGISTERINSTR(fmsubx, 0xFC000038); + XEREGISTERINSTR(fmsubsx, 0xEC000038); + XEREGISTERINSTR(fnmaddx, 0xFC00003E); + XEREGISTERINSTR(fnmaddsx, 0xEC00003E); + XEREGISTERINSTR(fnmsubx, 0xFC00003C); + XEREGISTERINSTR(fnmsubsx, 0xEC00003C); + XEREGISTERINSTR(fcfidx, 0xFC00069C); + XEREGISTERINSTR(fctidx, 0xFC00065C); + XEREGISTERINSTR(fctidzx, 0xFC00065E); + XEREGISTERINSTR(fctiwx, 0xFC00001C); + XEREGISTERINSTR(fctiwzx, 0xFC00001E); + XEREGISTERINSTR(frspx, 0xFC000018); + XEREGISTERINSTR(fcmpo, 0xFC000040); + XEREGISTERINSTR(fcmpu, 0xFC000000); + XEREGISTERINSTR(mcrfs, 0xFC000080); + XEREGISTERINSTR(mffsx, 0xFC00048E); + XEREGISTERINSTR(mtfsb0x, 0xFC00008C); + XEREGISTERINSTR(mtfsb1x, 0xFC00004C); + XEREGISTERINSTR(mtfsfx, 0xFC00058E); + XEREGISTERINSTR(mtfsfix, 0xFC00010C); + XEREGISTERINSTR(fabsx, 0xFC000210); + XEREGISTERINSTR(fmrx, 0xFC000090); + XEREGISTERINSTR(fnabsx, 0xFC000110); + XEREGISTERINSTR(fnegx, 0xFC000050); } - } // namespace ppc } // namespace frontend } // namespace alloy diff --git a/src/alloy/frontend/ppc/ppc_emit_memory.cc b/src/alloy/frontend/ppc/ppc_emit_memory.cc index 738090abf..a7264f50c 100644 --- a/src/alloy/frontend/ppc/ppc_emit_memory.cc +++ b/src/alloy/frontend/ppc/ppc_emit_memory.cc @@ -12,23 +12,22 @@ #include #include - -using namespace alloy::frontend::ppc; -using namespace alloy::hir; -using namespace alloy::runtime; - - namespace alloy { namespace frontend { namespace ppc { +// TODO(benvanik): remove when enums redefined. +using namespace alloy::hir; + +using alloy::hir::Value; + #define TRUNCATE_ADDRESSES 0 Value* CalculateEA(PPCHIRBuilder& f, uint32_t ra, uint32_t rb) { #if TRUNCATE_ADDRESSES - return f.ZeroExtend(f.Add( - f.Truncate(f.LoadGPR(ra), INT32_TYPE), - f.Truncate(f.LoadGPR(rb), INT32_TYPE)), INT64_TYPE); + return f.ZeroExtend(f.Add(f.Truncate(f.LoadGPR(ra), INT32_TYPE), + f.Truncate(f.LoadGPR(rb), INT32_TYPE)), + INT64_TYPE); #else return f.Add(f.LoadGPR(ra), f.LoadGPR(rb)); #endif // TRUNCATE_ADDRESSES @@ -37,9 +36,9 @@ Value* CalculateEA(PPCHIRBuilder& f, uint32_t ra, uint32_t rb) { Value* CalculateEA_0(PPCHIRBuilder& f, uint32_t ra, uint32_t rb) { #if TRUNCATE_ADDRESSES if (ra) { - return f.ZeroExtend(f.Add( - f.Truncate(f.LoadGPR(ra), INT32_TYPE), - f.Truncate(f.LoadGPR(rb), INT32_TYPE)), INT64_TYPE); + return f.ZeroExtend(f.Add(f.Truncate(f.LoadGPR(ra), INT32_TYPE), + f.Truncate(f.LoadGPR(rb), INT32_TYPE)), + INT64_TYPE); } else { return f.ZeroExtend(f.Truncate(f.LoadGPR(rb), INT32_TYPE), INT64_TYPE); } @@ -54,9 +53,9 @@ Value* CalculateEA_0(PPCHIRBuilder& f, uint32_t ra, uint32_t rb) { Value* CalculateEA_i(PPCHIRBuilder& f, uint32_t ra, uint64_t imm) { #if TRUNCATE_ADDRESSES - return f.ZeroExtend(f.Add( - f.Truncate(f.LoadGPR(ra), INT32_TYPE), - f.LoadConstant((int32_t)imm)), INT64_TYPE); + return f.ZeroExtend(f.Add(f.Truncate(f.LoadGPR(ra), INT32_TYPE), + f.LoadConstant((int32_t)imm)), + INT64_TYPE); #else return f.Add(f.LoadGPR(ra), f.LoadConstant(imm)); #endif // TRUNCATE_ADDRESSES @@ -65,9 +64,9 @@ Value* CalculateEA_i(PPCHIRBuilder& f, uint32_t ra, uint64_t imm) { Value* CalculateEA_0_i(PPCHIRBuilder& f, uint32_t ra, uint64_t imm) { #if TRUNCATE_ADDRESSES if (ra) { - return f.ZeroExtend(f.Add( - f.Truncate(f.LoadGPR(ra), INT32_TYPE), - f.LoadConstant((int32_t)imm)), INT64_TYPE); + return f.ZeroExtend(f.Add(f.Truncate(f.LoadGPR(ra), INT32_TYPE), + f.LoadConstant((int32_t)imm)), + INT64_TYPE); } else { return f.ZeroExtend(f.LoadConstant((int32_t)imm), INT64_TYPE); } @@ -80,10 +79,9 @@ Value* CalculateEA_0_i(PPCHIRBuilder& f, uint32_t ra, uint64_t imm) { #endif // TRUNCATE_ADDRESSES } - // Integer load (A-13) -XEEMITTER(lbz, 0x88000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lbz, 0x88000000, D)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -96,7 +94,7 @@ XEEMITTER(lbz, 0x88000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lbzu, 0x8C000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lbzu, 0x8C000000, D)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + EXTS(D) // RT <- i56.0 || MEM(EA, 1) // RA <- EA @@ -107,7 +105,7 @@ XEEMITTER(lbzu, 0x8C000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lbzux, 0x7C0000EE, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lbzux, 0x7C0000EE, X)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + (RB) // RT <- i56.0 || MEM(EA, 1) // RA <- EA @@ -118,7 +116,7 @@ XEEMITTER(lbzux, 0x7C0000EE, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lbzx, 0x7C0000AE, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lbzx, 0x7C0000AE, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -131,7 +129,7 @@ XEEMITTER(lbzx, 0x7C0000AE, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lha, 0xA8000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lha, 0xA8000000, D)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -144,17 +142,17 @@ XEEMITTER(lha, 0xA8000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lhau, 0xAC000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lhau, 0xAC000000, D)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(lhaux, 0x7C0002EE, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lhaux, 0x7C0002EE, X)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(lhax, 0x7C0002AE, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lhax, 0x7C0002AE, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -167,7 +165,7 @@ XEEMITTER(lhax, 0x7C0002AE, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lhz, 0xA0000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lhz, 0xA0000000, D)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -180,7 +178,7 @@ XEEMITTER(lhz, 0xA0000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lhzu, 0xA4000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lhzu, 0xA4000000, D)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + EXTS(D) // RT <- i48.0 || MEM(EA, 2) // RA <- EA @@ -191,7 +189,7 @@ XEEMITTER(lhzu, 0xA4000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lhzux, 0x7C00026E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lhzux, 0x7C00026E, X)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + (RB) // RT <- i48.0 || MEM(EA, 2) // RA <- EA @@ -202,7 +200,7 @@ XEEMITTER(lhzux, 0x7C00026E, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lhzx, 0x7C00022E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lhzx, 0x7C00022E, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -215,7 +213,7 @@ XEEMITTER(lhzx, 0x7C00022E, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lwa, 0xE8000002, DS )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lwa, 0xE8000002, DS)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -228,7 +226,7 @@ XEEMITTER(lwa, 0xE8000002, DS )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lwaux, 0x7C0002EA, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lwaux, 0x7C0002EA, X)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + (RB) // RT <- EXTS(MEM(EA, 4)) // RA <- EA @@ -239,7 +237,7 @@ XEEMITTER(lwaux, 0x7C0002EA, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lwax, 0x7C0002AA, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lwax, 0x7C0002AA, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -252,7 +250,7 @@ XEEMITTER(lwax, 0x7C0002AA, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lwz, 0x80000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lwz, 0x80000000, D)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -265,7 +263,7 @@ XEEMITTER(lwz, 0x80000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lwzu, 0x84000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lwzu, 0x84000000, D)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + EXTS(D) // RT <- i32.0 || MEM(EA, 4) // RA <- EA @@ -276,7 +274,7 @@ XEEMITTER(lwzu, 0x84000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lwzux, 0x7C00006E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lwzux, 0x7C00006E, X)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + (RB) // RT <- i32.0 || MEM(EA, 4) // RA <- EA @@ -287,7 +285,7 @@ XEEMITTER(lwzux, 0x7C00006E, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lwzx, 0x7C00002E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lwzx, 0x7C00002E, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -300,8 +298,7 @@ XEEMITTER(lwzx, 0x7C00002E, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } - -XEEMITTER(ld, 0xE8000000, DS )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(ld, 0xE8000000, DS)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -314,7 +311,7 @@ XEEMITTER(ld, 0xE8000000, DS )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(ldu, 0xE8000001, DS )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(ldu, 0xE8000001, DS)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + EXTS(DS || 0b00) // RT <- MEM(EA, 8) // RA <- EA @@ -325,7 +322,7 @@ XEEMITTER(ldu, 0xE8000001, DS )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(ldux, 0x7C00006A, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(ldux, 0x7C00006A, X)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + (RB) // RT <- MEM(EA, 8) // RA <- EA @@ -336,7 +333,7 @@ XEEMITTER(ldux, 0x7C00006A, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(ldx, 0x7C00002A, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(ldx, 0x7C00002A, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -349,10 +346,9 @@ XEEMITTER(ldx, 0x7C00002A, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } - // Integer store (A-14) -XEEMITTER(stb, 0x98000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stb, 0x98000000, D)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -364,7 +360,7 @@ XEEMITTER(stb, 0x98000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(stbu, 0x9C000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stbu, 0x9C000000, D)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + EXTS(D) // MEM(EA, 1) <- (RS)[56:63] // RA <- EA @@ -374,7 +370,7 @@ XEEMITTER(stbu, 0x9C000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(stbux, 0x7C0001EE, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stbux, 0x7C0001EE, X)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + (RB) // MEM(EA, 1) <- (RS)[56:63] // RA <- EA @@ -384,7 +380,7 @@ XEEMITTER(stbux, 0x7C0001EE, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(stbx, 0x7C0001AE, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stbx, 0x7C0001AE, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -396,7 +392,7 @@ XEEMITTER(stbx, 0x7C0001AE, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(sth, 0xB0000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(sth, 0xB0000000, D)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -408,7 +404,7 @@ XEEMITTER(sth, 0xB0000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(sthu, 0xB4000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(sthu, 0xB4000000, D)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + EXTS(D) // MEM(EA, 2) <- (RS)[48:63] // RA <- EA @@ -418,7 +414,7 @@ XEEMITTER(sthu, 0xB4000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(sthux, 0x7C00036E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(sthux, 0x7C00036E, X)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + (RB) // MEM(EA, 2) <- (RS)[48:63] // RA <- EA @@ -428,7 +424,7 @@ XEEMITTER(sthux, 0x7C00036E, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(sthx, 0x7C00032E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(sthx, 0x7C00032E, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -440,7 +436,7 @@ XEEMITTER(sthx, 0x7C00032E, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(stw, 0x90000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stw, 0x90000000, D)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -452,7 +448,7 @@ XEEMITTER(stw, 0x90000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(stwu, 0x94000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stwu, 0x94000000, D)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + EXTS(D) // MEM(EA, 4) <- (RS)[32:63] // RA <- EA @@ -462,7 +458,7 @@ XEEMITTER(stwu, 0x94000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(stwux, 0x7C00016E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stwux, 0x7C00016E, X)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + (RB) // MEM(EA, 4) <- (RS)[32:63] // RA <- EA @@ -472,7 +468,7 @@ XEEMITTER(stwux, 0x7C00016E, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(stwx, 0x7C00012E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stwx, 0x7C00012E, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -484,7 +480,7 @@ XEEMITTER(stwx, 0x7C00012E, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(std, 0xF8000000, DS )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(std, 0xF8000000, DS)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -496,7 +492,7 @@ XEEMITTER(std, 0xF8000000, DS )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(stdu, 0xF8000001, DS )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stdu, 0xF8000001, DS)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + EXTS(DS || 0b00) // MEM(EA, 8) <- (RS) // RA <- EA @@ -506,7 +502,7 @@ XEEMITTER(stdu, 0xF8000001, DS )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(stdux, 0x7C00016A, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stdux, 0x7C00016A, X)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + (RB) // MEM(EA, 8) <- (RS) // RA <- EA @@ -528,10 +524,9 @@ XEEMITTER(stdx, 0x7C00012A, X)(PPCHIRBuilder& f, InstrData& i) { return 0; } - // Integer load and store with byte reverse (A-1 -XEEMITTER(lhbrx, 0x7C00062C, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lhbrx, 0x7C00062C, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -544,7 +539,7 @@ XEEMITTER(lhbrx, 0x7C00062C, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lwbrx, 0x7C00042C, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lwbrx, 0x7C00042C, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -557,7 +552,7 @@ XEEMITTER(lwbrx, 0x7C00042C, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(ldbrx, 0x7C000428, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(ldbrx, 0x7C000428, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -570,7 +565,7 @@ XEEMITTER(ldbrx, 0x7C000428, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(sthbrx, 0x7C00072C, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(sthbrx, 0x7C00072C, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -582,7 +577,7 @@ XEEMITTER(sthbrx, 0x7C00072C, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(stwbrx, 0x7C00052C, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stwbrx, 0x7C00052C, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -594,7 +589,7 @@ XEEMITTER(stwbrx, 0x7C00052C, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(stdbrx, 0x7C000528, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stdbrx, 0x7C000528, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -606,64 +601,61 @@ XEEMITTER(stdbrx, 0x7C000528, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } - // Integer load and store multiple (A-16) -XEEMITTER(lmw, 0xB8000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lmw, 0xB8000000, D)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(stmw, 0xBC000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stmw, 0xBC000000, D)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } - // Integer load and store string (A-17) -XEEMITTER(lswi, 0x7C0004AA, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lswi, 0x7C0004AA, X)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(lswx, 0x7C00042A, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lswx, 0x7C00042A, X)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(stswi, 0x7C0005AA, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stswi, 0x7C0005AA, X)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(stswx, 0x7C00052A, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stswx, 0x7C00052A, X)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } - // Memory synchronization (A-18) -XEEMITTER(eieio, 0x7C0006AC, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(eieio, 0x7C0006AC, X)(PPCHIRBuilder& f, InstrData& i) { // XEINSTRNOTIMPLEMENTED(); f.Nop(); return 0; } -XEEMITTER(sync, 0x7C0004AC, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(sync, 0x7C0004AC, X)(PPCHIRBuilder& f, InstrData& i) { // XEINSTRNOTIMPLEMENTED(); f.Nop(); return 0; } -XEEMITTER(isync, 0x4C00012C, XL )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(isync, 0x4C00012C, XL)(PPCHIRBuilder& f, InstrData& i) { // XEINSTRNOTIMPLEMENTED(); f.Nop(); return 0; } -XEEMITTER(ldarx, 0x7C0000A8, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(ldarx, 0x7C0000A8, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -679,7 +671,7 @@ XEEMITTER(ldarx, 0x7C0000A8, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lwarx, 0x7C000028, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lwarx, 0x7C000028, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -690,12 +682,13 @@ XEEMITTER(lwarx, 0x7C000028, X )(PPCHIRBuilder& f, InstrData& i) { // RESERVE_ADDR <- real_addr(EA) // RT <- i32.0 || MEM(EA, 4) Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB); - Value* rt = f.ZeroExtend(f.ByteSwap(f.LoadAcquire(ea, INT32_TYPE)), INT64_TYPE); + Value* rt = + f.ZeroExtend(f.ByteSwap(f.LoadAcquire(ea, INT32_TYPE)), INT64_TYPE); f.StoreGPR(i.X.RT, rt); return 0; } -XEEMITTER(stdcx, 0x7C0001AD, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stdcx, 0x7C0001AD, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -712,7 +705,7 @@ XEEMITTER(stdcx, 0x7C0001AD, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(stwcx, 0x7C00012D, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stwcx, 0x7C00012D, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -729,10 +722,9 @@ XEEMITTER(stwcx, 0x7C00012D, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } - // Floating-point load (A-19) -XEEMITTER(lfd, 0xC8000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lfd, 0xC8000000, D)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -745,7 +737,7 @@ XEEMITTER(lfd, 0xC8000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lfdu, 0xCC000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lfdu, 0xCC000000, D)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + EXTS(D) // FRT <- MEM(EA, 8) // RA <- EA @@ -756,7 +748,7 @@ XEEMITTER(lfdu, 0xCC000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lfdux, 0x7C0004EE, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lfdux, 0x7C0004EE, X)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + (RB) // FRT <- MEM(EA, 8) // RA <- EA @@ -767,7 +759,7 @@ XEEMITTER(lfdux, 0x7C0004EE, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lfdx, 0x7C0004AE, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lfdx, 0x7C0004AE, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -780,7 +772,7 @@ XEEMITTER(lfdx, 0x7C0004AE, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(lfs, 0xC0000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lfs, 0xC0000000, D)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -789,39 +781,36 @@ XEEMITTER(lfs, 0xC0000000, D )(PPCHIRBuilder& f, InstrData& i) { // FRT <- DOUBLE(MEM(EA, 4)) Value* ea = CalculateEA_0_i(f, i.D.RA, XEEXTS16(i.D.DS)); Value* rt = f.Convert( - f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE), - FLOAT64_TYPE); + f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE), FLOAT64_TYPE); f.StoreFPR(i.D.RT, rt); return 0; } -XEEMITTER(lfsu, 0xC4000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lfsu, 0xC4000000, D)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + EXTS(D) // FRT <- DOUBLE(MEM(EA, 4)) // RA <- EA Value* ea = CalculateEA_i(f, i.D.RA, XEEXTS16(i.D.DS)); Value* rt = f.Convert( - f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE), - FLOAT64_TYPE); + f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE), FLOAT64_TYPE); f.StoreFPR(i.D.RT, rt); f.StoreGPR(i.D.RA, ea); return 0; } -XEEMITTER(lfsux, 0x7C00046E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lfsux, 0x7C00046E, X)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + (RB) // FRT <- DOUBLE(MEM(EA, 4)) // RA <- EA Value* ea = CalculateEA(f, i.X.RA, i.X.RB); Value* rt = f.Convert( - f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE), - FLOAT64_TYPE); + f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE), FLOAT64_TYPE); f.StoreFPR(i.X.RT, rt); f.StoreGPR(i.X.RA, ea); return 0; } -XEEMITTER(lfsx, 0x7C00042E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(lfsx, 0x7C00042E, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -830,16 +819,14 @@ XEEMITTER(lfsx, 0x7C00042E, X )(PPCHIRBuilder& f, InstrData& i) { // FRT <- DOUBLE(MEM(EA, 4)) Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB); Value* rt = f.Convert( - f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE), - FLOAT64_TYPE); + f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE), FLOAT64_TYPE); f.StoreFPR(i.X.RT, rt); return 0; } - // Floating-point store (A-20) -XEEMITTER(stfd, 0xD8000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stfd, 0xD8000000, D)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -851,7 +838,7 @@ XEEMITTER(stfd, 0xD8000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(stfdu, 0xDC000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stfdu, 0xDC000000, D)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + EXTS(D) // MEM(EA, 8) <- (FRS) // RA <- EA @@ -861,7 +848,7 @@ XEEMITTER(stfdu, 0xDC000000, D )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(stfdux, 0x7C0005EE, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stfdux, 0x7C0005EE, X)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + (RB) // MEM(EA, 8) <- (FRS) // RA <- EA @@ -871,7 +858,7 @@ XEEMITTER(stfdux, 0x7C0005EE, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(stfdx, 0x7C0005AE, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stfdx, 0x7C0005AE, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -883,7 +870,7 @@ XEEMITTER(stfdx, 0x7C0005AE, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(stfiwx, 0x7C0007AE, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stfiwx, 0x7C0007AE, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -891,12 +878,12 @@ XEEMITTER(stfiwx, 0x7C0007AE, X )(PPCHIRBuilder& f, InstrData& i) { // EA <- b + (RB) // MEM(EA, 4) <- (FRS)[32:63] Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB); - f.Store(ea, f.ByteSwap( - f.Truncate(f.Cast(f.LoadFPR(i.X.RT), INT64_TYPE), INT32_TYPE))); + f.Store(ea, f.ByteSwap(f.Truncate(f.Cast(f.LoadFPR(i.X.RT), INT64_TYPE), + INT32_TYPE))); return 0; } -XEEMITTER(stfs, 0xD0000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stfs, 0xD0000000, D)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -904,34 +891,34 @@ XEEMITTER(stfs, 0xD0000000, D )(PPCHIRBuilder& f, InstrData& i) { // EA <- b + EXTS(D) // MEM(EA, 4) <- SINGLE(FRS) Value* ea = CalculateEA_0_i(f, i.D.RA, XEEXTS16(i.D.DS)); - f.Store(ea, f.ByteSwap(f.Cast( - f.Convert(f.LoadFPR(i.D.RT), FLOAT32_TYPE), INT32_TYPE))); + f.Store(ea, f.ByteSwap(f.Cast(f.Convert(f.LoadFPR(i.D.RT), FLOAT32_TYPE), + INT32_TYPE))); return 0; } -XEEMITTER(stfsu, 0xD4000000, D )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stfsu, 0xD4000000, D)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + EXTS(D) // MEM(EA, 4) <- SINGLE(FRS) // RA <- EA Value* ea = CalculateEA_i(f, i.D.RA, XEEXTS16(i.D.DS)); - f.Store(ea, f.ByteSwap(f.Cast( - f.Convert(f.LoadFPR(i.D.RT), FLOAT32_TYPE), INT32_TYPE))); + f.Store(ea, f.ByteSwap(f.Cast(f.Convert(f.LoadFPR(i.D.RT), FLOAT32_TYPE), + INT32_TYPE))); f.StoreGPR(i.D.RA, ea); return 0; } -XEEMITTER(stfsux, 0x7C00056E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stfsux, 0x7C00056E, X)(PPCHIRBuilder& f, InstrData& i) { // EA <- (RA) + (RB) // MEM(EA, 4) <- SINGLE(FRS) // RA <- EA Value* ea = CalculateEA(f, i.X.RA, i.X.RB); - f.Store(ea, f.ByteSwap(f.Cast( - f.Convert(f.LoadFPR(i.X.RT), FLOAT32_TYPE), INT32_TYPE))); + f.Store(ea, f.ByteSwap(f.Cast(f.Convert(f.LoadFPR(i.X.RT), FLOAT32_TYPE), + INT32_TYPE))); f.StoreGPR(i.X.RA, ea); return 0; } -XEEMITTER(stfsx, 0x7C00052E, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(stfsx, 0x7C00052E, X)(PPCHIRBuilder& f, InstrData& i) { // if RA = 0 then // b <- 0 // else @@ -939,15 +926,14 @@ XEEMITTER(stfsx, 0x7C00052E, X )(PPCHIRBuilder& f, InstrData& i) { // EA <- b + (RB) // MEM(EA, 4) <- SINGLE(FRS) Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB); - f.Store(ea, f.ByteSwap(f.Cast( - f.Convert(f.LoadFPR(i.X.RT), FLOAT32_TYPE), INT32_TYPE))); + f.Store(ea, f.ByteSwap(f.Cast(f.Convert(f.LoadFPR(i.X.RT), FLOAT32_TYPE), + INT32_TYPE))); return 0; } - // Cache management (A-27) -XEEMITTER(dcbf, 0x7C0000AC, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(dcbf, 0x7C0000AC, X)(PPCHIRBuilder& f, InstrData& i) { // No-op for now. // TODO(benvanik): use prefetch // XEINSTRNOTIMPLEMENTED(); @@ -955,7 +941,7 @@ XEEMITTER(dcbf, 0x7C0000AC, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(dcbst, 0x7C00006C, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(dcbst, 0x7C00006C, X)(PPCHIRBuilder& f, InstrData& i) { // No-op for now. // TODO(benvanik): use prefetch // XEINSTRNOTIMPLEMENTED(); @@ -963,7 +949,7 @@ XEEMITTER(dcbst, 0x7C00006C, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(dcbt, 0x7C00022C, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(dcbt, 0x7C00022C, X)(PPCHIRBuilder& f, InstrData& i) { // No-op for now. // TODO(benvanik): use prefetch // XEINSTRNOTIMPLEMENTED(); @@ -971,7 +957,7 @@ XEEMITTER(dcbt, 0x7C00022C, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(dcbtst, 0x7C0001EC, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(dcbtst, 0x7C0001EC, X)(PPCHIRBuilder& f, InstrData& i) { // No-op for now. // TODO(benvanik): use prefetch // XEINSTRNOTIMPLEMENTED(); @@ -979,7 +965,7 @@ XEEMITTER(dcbtst, 0x7C0001EC, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(dcbz, 0x7C0007EC, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(dcbz, 0x7C0007EC, X)(PPCHIRBuilder& f, InstrData& i) { // No-op for now. // TODO(benvanik): use prefetch // or dcbz128 0x7C2007EC @@ -988,98 +974,96 @@ XEEMITTER(dcbz, 0x7C0007EC, X )(PPCHIRBuilder& f, InstrData& i) { return 0; } -XEEMITTER(icbi, 0x7C0007AC, X )(PPCHIRBuilder& f, InstrData& i) { +XEEMITTER(icbi, 0x7C0007AC, X)(PPCHIRBuilder& f, InstrData& i) { // XEINSTRNOTIMPLEMENTED(); f.Nop(); return 0; } - void RegisterEmitCategoryMemory() { - XEREGISTERINSTR(lbz, 0x88000000); - XEREGISTERINSTR(lbzu, 0x8C000000); - XEREGISTERINSTR(lbzux, 0x7C0000EE); - XEREGISTERINSTR(lbzx, 0x7C0000AE); - XEREGISTERINSTR(lha, 0xA8000000); - XEREGISTERINSTR(lhau, 0xAC000000); - XEREGISTERINSTR(lhaux, 0x7C0002EE); - XEREGISTERINSTR(lhax, 0x7C0002AE); - XEREGISTERINSTR(lhz, 0xA0000000); - XEREGISTERINSTR(lhzu, 0xA4000000); - XEREGISTERINSTR(lhzux, 0x7C00026E); - XEREGISTERINSTR(lhzx, 0x7C00022E); - XEREGISTERINSTR(lwa, 0xE8000002); - XEREGISTERINSTR(lwaux, 0x7C0002EA); - XEREGISTERINSTR(lwax, 0x7C0002AA); - XEREGISTERINSTR(lwz, 0x80000000); - XEREGISTERINSTR(lwzu, 0x84000000); - XEREGISTERINSTR(lwzux, 0x7C00006E); - XEREGISTERINSTR(lwzx, 0x7C00002E); - XEREGISTERINSTR(ld, 0xE8000000); - XEREGISTERINSTR(ldu, 0xE8000001); - XEREGISTERINSTR(ldux, 0x7C00006A); - XEREGISTERINSTR(ldx, 0x7C00002A); - XEREGISTERINSTR(stb, 0x98000000); - XEREGISTERINSTR(stbu, 0x9C000000); - XEREGISTERINSTR(stbux, 0x7C0001EE); - XEREGISTERINSTR(stbx, 0x7C0001AE); - XEREGISTERINSTR(sth, 0xB0000000); - XEREGISTERINSTR(sthu, 0xB4000000); - XEREGISTERINSTR(sthux, 0x7C00036E); - XEREGISTERINSTR(sthx, 0x7C00032E); - XEREGISTERINSTR(stw, 0x90000000); - XEREGISTERINSTR(stwu, 0x94000000); - XEREGISTERINSTR(stwux, 0x7C00016E); - XEREGISTERINSTR(stwx, 0x7C00012E); - XEREGISTERINSTR(std, 0xF8000000); - XEREGISTERINSTR(stdu, 0xF8000001); - XEREGISTERINSTR(stdux, 0x7C00016A); - XEREGISTERINSTR(stdx, 0x7C00012A); - XEREGISTERINSTR(lhbrx, 0x7C00062C); - XEREGISTERINSTR(lwbrx, 0x7C00042C); - XEREGISTERINSTR(ldbrx, 0x7C000428); - XEREGISTERINSTR(sthbrx, 0x7C00072C); - XEREGISTERINSTR(stwbrx, 0x7C00052C); - XEREGISTERINSTR(stdbrx, 0x7C000528); - XEREGISTERINSTR(lmw, 0xB8000000); - XEREGISTERINSTR(stmw, 0xBC000000); - XEREGISTERINSTR(lswi, 0x7C0004AA); - XEREGISTERINSTR(lswx, 0x7C00042A); - XEREGISTERINSTR(stswi, 0x7C0005AA); - XEREGISTERINSTR(stswx, 0x7C00052A); - XEREGISTERINSTR(eieio, 0x7C0006AC); - XEREGISTERINSTR(sync, 0x7C0004AC); - XEREGISTERINSTR(isync, 0x4C00012C); - XEREGISTERINSTR(ldarx, 0x7C0000A8); - XEREGISTERINSTR(lwarx, 0x7C000028); - XEREGISTERINSTR(stdcx, 0x7C0001AD); - XEREGISTERINSTR(stwcx, 0x7C00012D); - XEREGISTERINSTR(lfd, 0xC8000000); - XEREGISTERINSTR(lfdu, 0xCC000000); - XEREGISTERINSTR(lfdux, 0x7C0004EE); - XEREGISTERINSTR(lfdx, 0x7C0004AE); - XEREGISTERINSTR(lfs, 0xC0000000); - XEREGISTERINSTR(lfsu, 0xC4000000); - XEREGISTERINSTR(lfsux, 0x7C00046E); - XEREGISTERINSTR(lfsx, 0x7C00042E); - XEREGISTERINSTR(stfd, 0xD8000000); - XEREGISTERINSTR(stfdu, 0xDC000000); - XEREGISTERINSTR(stfdux, 0x7C0005EE); - XEREGISTERINSTR(stfdx, 0x7C0005AE); - XEREGISTERINSTR(stfiwx, 0x7C0007AE); - XEREGISTERINSTR(stfs, 0xD0000000); - XEREGISTERINSTR(stfsu, 0xD4000000); - XEREGISTERINSTR(stfsux, 0x7C00056E); - XEREGISTERINSTR(stfsx, 0x7C00052E); - XEREGISTERINSTR(dcbf, 0x7C0000AC); - XEREGISTERINSTR(dcbst, 0x7C00006C); - XEREGISTERINSTR(dcbt, 0x7C00022C); - XEREGISTERINSTR(dcbtst, 0x7C0001EC); - XEREGISTERINSTR(dcbz, 0x7C0007EC); - XEREGISTERINSTR(icbi, 0x7C0007AC); + XEREGISTERINSTR(lbz, 0x88000000); + XEREGISTERINSTR(lbzu, 0x8C000000); + XEREGISTERINSTR(lbzux, 0x7C0000EE); + XEREGISTERINSTR(lbzx, 0x7C0000AE); + XEREGISTERINSTR(lha, 0xA8000000); + XEREGISTERINSTR(lhau, 0xAC000000); + XEREGISTERINSTR(lhaux, 0x7C0002EE); + XEREGISTERINSTR(lhax, 0x7C0002AE); + XEREGISTERINSTR(lhz, 0xA0000000); + XEREGISTERINSTR(lhzu, 0xA4000000); + XEREGISTERINSTR(lhzux, 0x7C00026E); + XEREGISTERINSTR(lhzx, 0x7C00022E); + XEREGISTERINSTR(lwa, 0xE8000002); + XEREGISTERINSTR(lwaux, 0x7C0002EA); + XEREGISTERINSTR(lwax, 0x7C0002AA); + XEREGISTERINSTR(lwz, 0x80000000); + XEREGISTERINSTR(lwzu, 0x84000000); + XEREGISTERINSTR(lwzux, 0x7C00006E); + XEREGISTERINSTR(lwzx, 0x7C00002E); + XEREGISTERINSTR(ld, 0xE8000000); + XEREGISTERINSTR(ldu, 0xE8000001); + XEREGISTERINSTR(ldux, 0x7C00006A); + XEREGISTERINSTR(ldx, 0x7C00002A); + XEREGISTERINSTR(stb, 0x98000000); + XEREGISTERINSTR(stbu, 0x9C000000); + XEREGISTERINSTR(stbux, 0x7C0001EE); + XEREGISTERINSTR(stbx, 0x7C0001AE); + XEREGISTERINSTR(sth, 0xB0000000); + XEREGISTERINSTR(sthu, 0xB4000000); + XEREGISTERINSTR(sthux, 0x7C00036E); + XEREGISTERINSTR(sthx, 0x7C00032E); + XEREGISTERINSTR(stw, 0x90000000); + XEREGISTERINSTR(stwu, 0x94000000); + XEREGISTERINSTR(stwux, 0x7C00016E); + XEREGISTERINSTR(stwx, 0x7C00012E); + XEREGISTERINSTR(std, 0xF8000000); + XEREGISTERINSTR(stdu, 0xF8000001); + XEREGISTERINSTR(stdux, 0x7C00016A); + XEREGISTERINSTR(stdx, 0x7C00012A); + XEREGISTERINSTR(lhbrx, 0x7C00062C); + XEREGISTERINSTR(lwbrx, 0x7C00042C); + XEREGISTERINSTR(ldbrx, 0x7C000428); + XEREGISTERINSTR(sthbrx, 0x7C00072C); + XEREGISTERINSTR(stwbrx, 0x7C00052C); + XEREGISTERINSTR(stdbrx, 0x7C000528); + XEREGISTERINSTR(lmw, 0xB8000000); + XEREGISTERINSTR(stmw, 0xBC000000); + XEREGISTERINSTR(lswi, 0x7C0004AA); + XEREGISTERINSTR(lswx, 0x7C00042A); + XEREGISTERINSTR(stswi, 0x7C0005AA); + XEREGISTERINSTR(stswx, 0x7C00052A); + XEREGISTERINSTR(eieio, 0x7C0006AC); + XEREGISTERINSTR(sync, 0x7C0004AC); + XEREGISTERINSTR(isync, 0x4C00012C); + XEREGISTERINSTR(ldarx, 0x7C0000A8); + XEREGISTERINSTR(lwarx, 0x7C000028); + XEREGISTERINSTR(stdcx, 0x7C0001AD); + XEREGISTERINSTR(stwcx, 0x7C00012D); + XEREGISTERINSTR(lfd, 0xC8000000); + XEREGISTERINSTR(lfdu, 0xCC000000); + XEREGISTERINSTR(lfdux, 0x7C0004EE); + XEREGISTERINSTR(lfdx, 0x7C0004AE); + XEREGISTERINSTR(lfs, 0xC0000000); + XEREGISTERINSTR(lfsu, 0xC4000000); + XEREGISTERINSTR(lfsux, 0x7C00046E); + XEREGISTERINSTR(lfsx, 0x7C00042E); + XEREGISTERINSTR(stfd, 0xD8000000); + XEREGISTERINSTR(stfdu, 0xDC000000); + XEREGISTERINSTR(stfdux, 0x7C0005EE); + XEREGISTERINSTR(stfdx, 0x7C0005AE); + XEREGISTERINSTR(stfiwx, 0x7C0007AE); + XEREGISTERINSTR(stfs, 0xD0000000); + XEREGISTERINSTR(stfsu, 0xD4000000); + XEREGISTERINSTR(stfsux, 0x7C00056E); + XEREGISTERINSTR(stfsx, 0x7C00052E); + XEREGISTERINSTR(dcbf, 0x7C0000AC); + XEREGISTERINSTR(dcbst, 0x7C00006C); + XEREGISTERINSTR(dcbt, 0x7C00022C); + XEREGISTERINSTR(dcbtst, 0x7C0001EC); + XEREGISTERINSTR(dcbz, 0x7C0007EC); + XEREGISTERINSTR(icbi, 0x7C0007AC); } - } // namespace ppc } // namespace frontend } // namespace alloy diff --git a/src/alloy/frontend/ppc/ppc_frontend.cc b/src/alloy/frontend/ppc/ppc_frontend.cc index 29f62ab42..f6970d5f5 100644 --- a/src/alloy/frontend/ppc/ppc_frontend.cc +++ b/src/alloy/frontend/ppc/ppc_frontend.cc @@ -15,44 +15,40 @@ #include #include -using namespace alloy; -using namespace alloy::frontend; -using namespace alloy::frontend::ppc; -using namespace alloy::runtime; +namespace alloy { +namespace frontend { +namespace ppc { +using alloy::runtime::Function; +using alloy::runtime::FunctionInfo; +using alloy::runtime::Runtime; -namespace { - void InitializeIfNeeded(); - void CleanupOnShutdown(); +void InitializeIfNeeded(); +void CleanupOnShutdown(); - void InitializeIfNeeded() { - static bool has_initialized = false; - if (has_initialized) { - return; - } - has_initialized = true; - - RegisterEmitCategoryAltivec(); - RegisterEmitCategoryALU(); - RegisterEmitCategoryControl(); - RegisterEmitCategoryFPU(); - RegisterEmitCategoryMemory(); - - atexit(CleanupOnShutdown); +void InitializeIfNeeded() { + static bool has_initialized = false; + if (has_initialized) { + return; } + has_initialized = true; - void CleanupOnShutdown() { - } + RegisterEmitCategoryAltivec(); + RegisterEmitCategoryALU(); + RegisterEmitCategoryControl(); + RegisterEmitCategoryFPU(); + RegisterEmitCategoryMemory(); + + atexit(CleanupOnShutdown); } +void CleanupOnShutdown() {} -PPCFrontend::PPCFrontend(Runtime* runtime) : - Frontend(runtime) { +PPCFrontend::PPCFrontend(Runtime* runtime) : Frontend(runtime) { InitializeIfNeeded(); - ContextInfo* info = new ContextInfo( - sizeof(PPCContext), - offsetof(PPCContext, thread_state)); + ContextInfo* info = + new ContextInfo(sizeof(PPCContext), offsetof(PPCContext, thread_state)); // Add fields/etc. context_info_ = info; } @@ -61,8 +57,7 @@ PPCFrontend::~PPCFrontend() { // Force cleanup now before we deinit. translator_pool_.Reset(); - alloy::tracing::WriteEvent(EventType::Deinit({ - })); + alloy::tracing::WriteEvent(EventType::Deinit({})); } int PPCFrontend::Initialize() { @@ -71,14 +66,12 @@ int PPCFrontend::Initialize() { return result; } - alloy::tracing::WriteEvent(EventType::Init({ - })); + alloy::tracing::WriteEvent(EventType::Init({})); return result; } -int PPCFrontend::DeclareFunction( - FunctionInfo* symbol_info) { +int PPCFrontend::DeclareFunction(FunctionInfo* symbol_info) { // Could scan or something here. // Could also check to see if it's a well-known function type and classify // for later. @@ -87,12 +80,16 @@ int PPCFrontend::DeclareFunction( return 0; } -int PPCFrontend::DefineFunction( - FunctionInfo* symbol_info, uint32_t debug_info_flags, - Function** out_function) { +int PPCFrontend::DefineFunction(FunctionInfo* symbol_info, + uint32_t debug_info_flags, + Function** out_function) { PPCTranslator* translator = translator_pool_.Allocate(this); - int result = translator->Translate( - symbol_info, debug_info_flags, out_function); + int result = + translator->Translate(symbol_info, debug_info_flags, out_function); translator_pool_.Release(translator); return result; } + +} // namespace ppc +} // namespace frontend +} // namespace alloy diff --git a/src/alloy/frontend/ppc/ppc_frontend.h b/src/alloy/frontend/ppc/ppc_frontend.h index 612b7c1b2..76e37f4a9 100644 --- a/src/alloy/frontend/ppc/ppc_frontend.h +++ b/src/alloy/frontend/ppc/ppc_frontend.h @@ -15,7 +15,6 @@ #include - namespace alloy { namespace frontend { namespace ppc { @@ -23,26 +22,23 @@ namespace ppc { class PPCTranslator; class PPCFrontend : public Frontend { -public: + public: PPCFrontend(runtime::Runtime* runtime); virtual ~PPCFrontend(); virtual int Initialize(); - virtual int DeclareFunction( - runtime::FunctionInfo* symbol_info); - virtual int DefineFunction( - runtime::FunctionInfo* symbol_info, uint32_t debug_info_flags, - runtime::Function** out_function); + virtual int DeclareFunction(runtime::FunctionInfo* symbol_info); + virtual int DefineFunction(runtime::FunctionInfo* symbol_info, + uint32_t debug_info_flags, + runtime::Function** out_function); -private: + private: TypePool translator_pool_; }; - } // namespace ppc } // namespace frontend } // namespace alloy - #endif // ALLOY_FRONTEND_PPC_PPC_FRONTEND_H_ diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index db2f304b4..4b81401dd 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -18,22 +18,25 @@ #include #include -using namespace alloy; -using namespace alloy::frontend; -using namespace alloy::frontend::ppc; +namespace alloy { +namespace frontend { +namespace ppc { + +// TODO(benvanik): remove when enums redefined. using namespace alloy::hir; -using namespace alloy::runtime; +using alloy::hir::Label; +using alloy::hir::TypeName; +using alloy::hir::Value; +using alloy::runtime::Runtime; +using alloy::runtime::FunctionInfo; -PPCHIRBuilder::PPCHIRBuilder(PPCFrontend* frontend) : - frontend_(frontend), - HIRBuilder() { +PPCHIRBuilder::PPCHIRBuilder(PPCFrontend* frontend) + : frontend_(frontend), HIRBuilder() { comment_buffer_ = new StringBuffer(4096); } -PPCHIRBuilder::~PPCHIRBuilder() { - delete comment_buffer_; -} +PPCHIRBuilder::~PPCHIRBuilder() { delete comment_buffer_; } void PPCHIRBuilder::Reset() { start_address_ = 0; @@ -51,13 +54,11 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, bool with_debug_info) { symbol_info_ = symbol_info; start_address_ = symbol_info->address(); - instr_count_ = - (symbol_info->end_address() - symbol_info->address()) / 4 + 1; + instr_count_ = (symbol_info->end_address() - symbol_info->address()) / 4 + 1; with_debug_info_ = with_debug_info; if (with_debug_info_) { - Comment("%s fn %.8X-%.8X %s", - symbol_info->module()->name(), + Comment("%s fn %.8X-%.8X %s", symbol_info->module()->name(), symbol_info->address(), symbol_info->end_address(), symbol_info->name()); } @@ -121,7 +122,7 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, bool with_debug_info) { if (!i.type) { XELOGCPU("Invalid instruction %.8X %.8X", i.address, i.code); Comment("INVALID!"); - //TraceInvalidInstruction(i); + // TraceInvalidInstruction(i); continue; } @@ -134,11 +135,11 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, bool with_debug_info) { } if (!i.type->emit || emit(*this, i)) { - XELOGCPU("Unimplemented instr %.8X %.8X %s", - i.address, i.code, i.type->name); + XELOGCPU("Unimplemented instr %.8X %.8X %s", i.address, i.code, + i.type->name); Comment("UNIMPLEMENTED!"); - //DebugBreak(); - //TraceInvalidInstruction(i); + // DebugBreak(); + // TraceInvalidInstruction(i); } } @@ -147,8 +148,7 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, bool with_debug_info) { void PPCHIRBuilder::AnnotateLabel(uint64_t address, Label* label) { char name_buffer[13]; - xesnprintfa(name_buffer, XECOUNT(name_buffer), - "loc_%.8X", (uint32_t)address); + xesnprintfa(name_buffer, XECOUNT(name_buffer), "loc_%.8X", (uint32_t)address); label->name = (char*)arena_->Alloc(sizeof(name_buffer)); xe_copy_struct(label->name, name_buffer, sizeof(name_buffer)); } @@ -197,10 +197,10 @@ Label* PPCHIRBuilder::LookupLabel(uint64_t address) { return label; } -//Value* PPCHIRBuilder::LoadXER() { +// Value* PPCHIRBuilder::LoadXER() { //} // -//void PPCHIRBuilder::StoreXER(Value* value) { +// void PPCHIRBuilder::StoreXER(Value* value) { //} Value* PPCHIRBuilder::LoadLR() { @@ -235,13 +235,12 @@ void PPCHIRBuilder::StoreCR(uint32_t n, Value* value) { XEASSERTALWAYS(); } -void PPCHIRBuilder::UpdateCR( - uint32_t n, Value* lhs, bool is_signed) { +void PPCHIRBuilder::UpdateCR(uint32_t n, Value* lhs, bool is_signed) { UpdateCR(n, lhs, LoadZero(lhs->type), is_signed); } -void PPCHIRBuilder::UpdateCR( - uint32_t n, Value* lhs, Value* rhs, bool is_signed) { +void PPCHIRBuilder::UpdateCR(uint32_t n, Value* lhs, Value* rhs, + bool is_signed) { if (is_signed) { Value* lt = CompareSLT(lhs, rhs); StoreContext(offsetof(PPCContext, cr0) + (4 * n) + 0, lt); @@ -264,7 +263,8 @@ void PPCHIRBuilder::UpdateCR6(Value* src_value) { // Testing for all 1's and all 0's. // if (Rc) CR6 = all_equal | 0 | none_equal | 0 // TODO(benvanik): efficient instruction? - StoreContext(offsetof(PPCContext, cr6.cr6_all_equal), IsFalse(Not(src_value))); + StoreContext(offsetof(PPCContext, cr6.cr6_all_equal), + IsFalse(Not(src_value))); StoreContext(offsetof(PPCContext, cr6.cr6_none_equal), IsFalse(src_value)); } @@ -282,9 +282,7 @@ Value* PPCHIRBuilder::LoadXER() { return NULL; } -void PPCHIRBuilder::StoreXER(Value* value) { - XEASSERTALWAYS(); -} +void PPCHIRBuilder::StoreXER(Value* value) { XEASSERTALWAYS(); } Value* PPCHIRBuilder::LoadCA() { return LoadContext(offsetof(PPCContext, xer_ca), INT8_TYPE); @@ -305,48 +303,41 @@ void PPCHIRBuilder::StoreSAT(Value* value) { } Value* PPCHIRBuilder::LoadGPR(uint32_t reg) { - return LoadContext( - offsetof(PPCContext, r) + reg * 8, INT64_TYPE); + return LoadContext(offsetof(PPCContext, r) + reg * 8, INT64_TYPE); } void PPCHIRBuilder::StoreGPR(uint32_t reg, Value* value) { XEASSERT(value->type == INT64_TYPE); - StoreContext( - offsetof(PPCContext, r) + reg * 8, value); + StoreContext(offsetof(PPCContext, r) + reg * 8, value); } Value* PPCHIRBuilder::LoadFPR(uint32_t reg) { - return LoadContext( - offsetof(PPCContext, f) + reg * 8, FLOAT64_TYPE); + return LoadContext(offsetof(PPCContext, f) + reg * 8, FLOAT64_TYPE); } void PPCHIRBuilder::StoreFPR(uint32_t reg, Value* value) { XEASSERT(value->type == FLOAT64_TYPE); - StoreContext( - offsetof(PPCContext, f) + reg * 8, value); + StoreContext(offsetof(PPCContext, f) + reg * 8, value); } Value* PPCHIRBuilder::LoadVR(uint32_t reg) { - return LoadContext( - offsetof(PPCContext, v) + reg * 16, VEC128_TYPE); + return LoadContext(offsetof(PPCContext, v) + reg * 16, VEC128_TYPE); } void PPCHIRBuilder::StoreVR(uint32_t reg, Value* value) { XEASSERT(value->type == VEC128_TYPE); - StoreContext( - offsetof(PPCContext, v) + reg * 16, value); + StoreContext(offsetof(PPCContext, v) + reg * 16, value); } -Value* PPCHIRBuilder::LoadAcquire( - Value* address, TypeName type, uint32_t load_flags) { - AtomicExchange( - LoadContext(offsetof(PPCContext, reserve_address), INT64_TYPE), - Truncate(address, INT32_TYPE)); +Value* PPCHIRBuilder::LoadAcquire(Value* address, TypeName type, + uint32_t load_flags) { + AtomicExchange(LoadContext(offsetof(PPCContext, reserve_address), INT64_TYPE), + Truncate(address, INT32_TYPE)); return Load(address, type, load_flags); } -Value* PPCHIRBuilder::StoreRelease( - Value* address, Value* value, uint32_t store_flags) { +Value* PPCHIRBuilder::StoreRelease(Value* address, Value* value, + uint32_t store_flags) { Value* old_address = AtomicExchange( LoadContext(offsetof(PPCContext, reserve_address), INT64_TYPE), LoadZero(INT32_TYPE)); @@ -357,3 +348,7 @@ Value* PPCHIRBuilder::StoreRelease( MarkLabel(skip_label); return eq; } + +} // namespace ppc +} // namespace frontend +} // namespace alloy diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.h b/src/alloy/frontend/ppc/ppc_hir_builder.h index 58560bf02..1a7f8e8d0 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.h +++ b/src/alloy/frontend/ppc/ppc_hir_builder.h @@ -15,19 +15,18 @@ #include #include - namespace alloy { namespace frontend { namespace ppc { class PPCFrontend; - class PPCHIRBuilder : public hir::HIRBuilder { using Instr = alloy::hir::Instr; using Label = alloy::hir::Label; using Value = alloy::hir::Value; -public: + + public: PPCHIRBuilder(PPCFrontend* frontend); virtual ~PPCHIRBuilder(); @@ -53,9 +52,9 @@ public: void StoreFPSCR(Value* value); Value* LoadXER(); void StoreXER(Value* value); - //void UpdateXERWithOverflow(); - //void UpdateXERWithOverflowAndCarry(); - //void StoreOV(Value* value); + // void UpdateXERWithOverflow(); + // void UpdateXERWithOverflowAndCarry(); + // void StoreOV(Value* value); Value* LoadCA(); void StoreCA(Value* value); Value* LoadSAT(); @@ -68,31 +67,30 @@ public: Value* LoadVR(uint32_t reg); void StoreVR(uint32_t reg, Value* value); - Value* LoadAcquire(Value* address, hir::TypeName type, uint32_t load_flags = 0); + Value* LoadAcquire(Value* address, hir::TypeName type, + uint32_t load_flags = 0); Value* StoreRelease(Value* address, Value* value, uint32_t store_flags = 0); -private: + private: void AnnotateLabel(uint64_t address, Label* label); -private: - PPCFrontend* frontend_; + private: + PPCFrontend* frontend_; // Reset whenever needed: StringBuffer* comment_buffer_; // Reset each Emit: - bool with_debug_info_; + bool with_debug_info_; runtime::FunctionInfo* symbol_info_; - uint64_t start_address_; - uint64_t instr_count_; - Instr** instr_offset_list_; - Label** label_list_; + uint64_t start_address_; + uint64_t instr_count_; + Instr** instr_offset_list_; + Label** label_list_; }; - } // namespace ppc } // namespace frontend } // namespace alloy - #endif // ALLOY_FRONTEND_PPC_PPC_HIR_BUILDER_H_ diff --git a/src/alloy/frontend/ppc/ppc_instr.cc b/src/alloy/frontend/ppc/ppc_instr.cc index b12ff37bf..83647dfe7 100644 --- a/src/alloy/frontend/ppc/ppc_instr.cc +++ b/src/alloy/frontend/ppc/ppc_instr.cc @@ -13,11 +13,9 @@ #include - -using namespace alloy; -using namespace alloy::frontend; -using namespace alloy::frontend::ppc; - +namespace alloy { +namespace frontend { +namespace ppc { void InstrOperand::Dump(std::string& out_str) { if (display) { @@ -92,21 +90,18 @@ void InstrOperand::Dump(std::string& out_str) { out_str += buffer; } - -void InstrAccessBits::Clear() { - spr = cr = gpr = fpr = 0; -} +void InstrAccessBits::Clear() { spr = cr = gpr = fpr = 0; } void InstrAccessBits::Extend(InstrAccessBits& other) { - spr |= other.spr; - cr |= other.cr; - gpr |= other.gpr; - fpr |= other.fpr; - vr31_0 |= other.vr31_0; - vr63_32 |= other.vr63_32; - vr95_64 |= other.vr95_64; - vr127_96 |= other.vr127_96; - } + spr |= other.spr; + cr |= other.cr; + gpr |= other.gpr; + fpr |= other.fpr; + vr31_0 |= other.vr31_0; + vr63_32 |= other.vr63_32; + vr95_64 |= other.vr95_64; + vr127_96 |= other.vr127_96; +} void InstrAccessBits::MarkAccess(InstrRegister& reg) { uint64_t bits = 0; @@ -128,7 +123,7 @@ void InstrAccessBits::MarkAccess(InstrRegister& reg) { spr |= bits << (2 * 2); break; case InstrRegister::kCR: - cr |= bits << (2 * reg.ordinal); + cr |= bits << (2 * reg.ordinal); break; case InstrRegister::kFPSCR: spr |= bits << (2 * 3); @@ -281,41 +276,31 @@ void InstrAccessBits::Dump(std::string& out_str) { out_str = str.str(); } - void InstrDisasm::Init(const char* name, const char* info, uint32_t flags) { this->name = name; this->info = info; this->flags = flags; } -void InstrDisasm::AddLR(InstrRegister::Access access) { -} +void InstrDisasm::AddLR(InstrRegister::Access access) {} -void InstrDisasm::AddCTR(InstrRegister::Access access) { -} +void InstrDisasm::AddCTR(InstrRegister::Access access) {} -void InstrDisasm::AddCR(uint32_t bf, InstrRegister::Access access) { -} +void InstrDisasm::AddCR(uint32_t bf, InstrRegister::Access access) {} -void InstrDisasm::AddFPSCR(InstrRegister::Access access) { -} +void InstrDisasm::AddFPSCR(InstrRegister::Access access) {} -void InstrDisasm::AddRegOperand( - InstrRegister::RegisterSet set, uint32_t ordinal, - InstrRegister::Access access, const char* display) { -} +void InstrDisasm::AddRegOperand(InstrRegister::RegisterSet set, + uint32_t ordinal, InstrRegister::Access access, + const char* display) {} void InstrDisasm::AddSImmOperand(uint64_t value, size_t width, - const char* display) { -} + const char* display) {} void InstrDisasm::AddUImmOperand(uint64_t value, size_t width, - const char* display) { -} + const char* display) {} -int InstrDisasm::Finish() { - return 0; -} +int InstrDisasm::Finish() { return 0; } void InstrDisasm::Dump(std::string& out_str, size_t pad) { out_str = name; @@ -330,47 +315,55 @@ void InstrDisasm::Dump(std::string& out_str, size_t pad) { } } - -InstrType* alloy::frontend::ppc::GetInstrType(uint32_t code) { +InstrType* GetInstrType(uint32_t code) { // Fast lookup via tables. InstrType* slot = NULL; switch (code >> 26) { - case 4: - // Opcode = 4, index = bits 10-0 (10) - slot = alloy::frontend::ppc::tables::instr_table_4[XESELECTBITS(code, 0, 10)]; - break; - case 19: - // Opcode = 19, index = bits 10-1 (10) - slot = alloy::frontend::ppc::tables::instr_table_19[XESELECTBITS(code, 1, 10)]; - break; - case 30: - // Opcode = 30, index = bits 4-1 (4) - // Special cased to an uber instruction. - slot = alloy::frontend::ppc::tables::instr_table_30[XESELECTBITS(code, 0, 0)]; - break; - case 31: - // Opcode = 31, index = bits 10-1 (10) - slot = alloy::frontend::ppc::tables::instr_table_31[XESELECTBITS(code, 1, 10)]; - break; - case 58: - // Opcode = 58, index = bits 1-0 (2) - slot = alloy::frontend::ppc::tables::instr_table_58[XESELECTBITS(code, 0, 1)]; - break; - case 59: - // Opcode = 59, index = bits 5-1 (5) - slot = alloy::frontend::ppc::tables::instr_table_59[XESELECTBITS(code, 1, 5)]; - break; - case 62: - // Opcode = 62, index = bits 1-0 (2) - slot = alloy::frontend::ppc::tables::instr_table_62[XESELECTBITS(code, 0, 1)]; - break; - case 63: - // Opcode = 63, index = bits 10-1 (10) - slot = alloy::frontend::ppc::tables::instr_table_63[XESELECTBITS(code, 1, 10)]; - break; - default: - slot = alloy::frontend::ppc::tables::instr_table[XESELECTBITS(code, 26, 31)]; - break; + case 4: + // Opcode = 4, index = bits 10-0 (10) + slot = alloy::frontend::ppc::tables::instr_table_4[XESELECTBITS(code, 0, + 10)]; + break; + case 19: + // Opcode = 19, index = bits 10-1 (10) + slot = alloy::frontend::ppc::tables::instr_table_19[XESELECTBITS(code, 1, + 10)]; + break; + case 30: + // Opcode = 30, index = bits 4-1 (4) + // Special cased to an uber instruction. + slot = alloy::frontend::ppc::tables::instr_table_30[XESELECTBITS(code, 0, + 0)]; + break; + case 31: + // Opcode = 31, index = bits 10-1 (10) + slot = alloy::frontend::ppc::tables::instr_table_31[XESELECTBITS(code, 1, + 10)]; + break; + case 58: + // Opcode = 58, index = bits 1-0 (2) + slot = alloy::frontend::ppc::tables::instr_table_58[XESELECTBITS(code, 0, + 1)]; + break; + case 59: + // Opcode = 59, index = bits 5-1 (5) + slot = alloy::frontend::ppc::tables::instr_table_59[XESELECTBITS(code, 1, + 5)]; + break; + case 62: + // Opcode = 62, index = bits 1-0 (2) + slot = alloy::frontend::ppc::tables::instr_table_62[XESELECTBITS(code, 0, + 1)]; + break; + case 63: + // Opcode = 63, index = bits 10-1 (10) + slot = alloy::frontend::ppc::tables::instr_table_63[XESELECTBITS(code, 1, + 10)]; + break; + default: + slot = + alloy::frontend::ppc::tables::instr_table[XESELECTBITS(code, 26, 31)]; + break; } if (slot && slot->opcode) { return slot; @@ -379,8 +372,7 @@ InstrType* alloy::frontend::ppc::GetInstrType(uint32_t code) { // Slow lookup via linear scan. // This is primarily due to laziness. It could be made fast like the others. for (size_t n = 0; - n < XECOUNT(alloy::frontend::ppc::tables::instr_table_scan); - n++) { + n < XECOUNT(alloy::frontend::ppc::tables::instr_table_scan); n++) { slot = &(alloy::frontend::ppc::tables::instr_table_scan[n]); if (slot->opcode == (code & slot->opcode_mask)) { return slot; @@ -390,7 +382,7 @@ InstrType* alloy::frontend::ppc::GetInstrType(uint32_t code) { return NULL; } -int alloy::frontend::ppc::RegisterInstrEmit(uint32_t code, InstrEmitFn emit) { +int RegisterInstrEmit(uint32_t code, InstrEmitFn emit) { InstrType* instr_type = GetInstrType(code); XEASSERTNOTNULL(instr_type); if (!instr_type) { @@ -400,3 +392,7 @@ int alloy::frontend::ppc::RegisterInstrEmit(uint32_t code, InstrEmitFn emit) { instr_type->emit = emit; return 0; } + +} // namespace ppc +} // namespace frontend +} // namespace alloy diff --git a/src/alloy/frontend/ppc/ppc_instr.h b/src/alloy/frontend/ppc/ppc_instr.h index 01026e7f6..80b8cc3d1 100644 --- a/src/alloy/frontend/ppc/ppc_instr.h +++ b/src/alloy/frontend/ppc/ppc_instr.h @@ -15,81 +15,73 @@ #include #include - namespace alloy { namespace frontend { namespace ppc { - // TODO(benvanik): rename these typedef enum { - kXEPPCInstrFormatI = 0, - kXEPPCInstrFormatB = 1, - kXEPPCInstrFormatSC = 2, - kXEPPCInstrFormatD = 3, - kXEPPCInstrFormatDS = 4, - kXEPPCInstrFormatX = 5, - kXEPPCInstrFormatXL = 6, - kXEPPCInstrFormatXFX = 7, - kXEPPCInstrFormatXFL = 8, - kXEPPCInstrFormatXS = 9, - kXEPPCInstrFormatXO = 10, - kXEPPCInstrFormatA = 11, - kXEPPCInstrFormatM = 12, - kXEPPCInstrFormatMD = 13, - kXEPPCInstrFormatMDS = 14, - kXEPPCInstrFormatVXA = 15, - kXEPPCInstrFormatVX = 16, - kXEPPCInstrFormatVXR = 17, - kXEPPCInstrFormatVX128 = 18, - kXEPPCInstrFormatVX128_1 = 19, - kXEPPCInstrFormatVX128_2 = 20, - kXEPPCInstrFormatVX128_3 = 21, - kXEPPCInstrFormatVX128_4 = 22, - kXEPPCInstrFormatVX128_5 = 23, - kXEPPCInstrFormatVX128_P = 24, - kXEPPCInstrFormatVX128_R = 25, - kXEPPCInstrFormatXDSS = 26, + kXEPPCInstrFormatI = 0, + kXEPPCInstrFormatB = 1, + kXEPPCInstrFormatSC = 2, + kXEPPCInstrFormatD = 3, + kXEPPCInstrFormatDS = 4, + kXEPPCInstrFormatX = 5, + kXEPPCInstrFormatXL = 6, + kXEPPCInstrFormatXFX = 7, + kXEPPCInstrFormatXFL = 8, + kXEPPCInstrFormatXS = 9, + kXEPPCInstrFormatXO = 10, + kXEPPCInstrFormatA = 11, + kXEPPCInstrFormatM = 12, + kXEPPCInstrFormatMD = 13, + kXEPPCInstrFormatMDS = 14, + kXEPPCInstrFormatVXA = 15, + kXEPPCInstrFormatVX = 16, + kXEPPCInstrFormatVXR = 17, + kXEPPCInstrFormatVX128 = 18, + kXEPPCInstrFormatVX128_1 = 19, + kXEPPCInstrFormatVX128_2 = 20, + kXEPPCInstrFormatVX128_3 = 21, + kXEPPCInstrFormatVX128_4 = 22, + kXEPPCInstrFormatVX128_5 = 23, + kXEPPCInstrFormatVX128_P = 24, + kXEPPCInstrFormatVX128_R = 25, + kXEPPCInstrFormatXDSS = 26, } xe_ppc_instr_format_e; typedef enum { - kXEPPCInstrMaskVXR = 0xFC0003FF, - kXEPPCInstrMaskVXA = 0xFC00003F, - kXEPPCInstrMaskVX128 = 0xFC0003D0, - kXEPPCInstrMaskVX128_1 = 0xFC0007F3, - kXEPPCInstrMaskVX128_2 = 0xFC000210, - kXEPPCInstrMaskVX128_3 = 0xFC0007F0, - kXEPPCInstrMaskVX128_4 = 0xFC000730, - kXEPPCInstrMaskVX128_5 = 0xFC000010, - kXEPPCInstrMaskVX128_P = 0xFC000630, - kXEPPCInstrMaskVX128_R = 0xFC000390, + kXEPPCInstrMaskVXR = 0xFC0003FF, + kXEPPCInstrMaskVXA = 0xFC00003F, + kXEPPCInstrMaskVX128 = 0xFC0003D0, + kXEPPCInstrMaskVX128_1 = 0xFC0007F3, + kXEPPCInstrMaskVX128_2 = 0xFC000210, + kXEPPCInstrMaskVX128_3 = 0xFC0007F0, + kXEPPCInstrMaskVX128_4 = 0xFC000730, + kXEPPCInstrMaskVX128_5 = 0xFC000010, + kXEPPCInstrMaskVX128_P = 0xFC000630, + kXEPPCInstrMaskVX128_R = 0xFC000390, } xe_ppc_instr_mask_e; typedef enum { - kXEPPCInstrTypeGeneral = (1 << 0), - kXEPPCInstrTypeBranch = (1 << 1), - kXEPPCInstrTypeBranchCond = kXEPPCInstrTypeBranch | (1 << 2), + kXEPPCInstrTypeGeneral = (1 << 0), + kXEPPCInstrTypeBranch = (1 << 1), + kXEPPCInstrTypeBranchCond = kXEPPCInstrTypeBranch | (1 << 2), kXEPPCInstrTypeBranchAlways = kXEPPCInstrTypeBranch | (1 << 3), - kXEPPCInstrTypeSyscall = (1 << 4), + kXEPPCInstrTypeSyscall = (1 << 4), } xe_ppc_instr_type_e; typedef enum { - kXEPPCInstrFlagReserved = 0, + kXEPPCInstrFlagReserved = 0, } xe_ppc_instr_flag_e; - class InstrType; - -static inline int64_t XEEXTS16(uint32_t v) { - return (int64_t)((int16_t)v); -} +static inline int64_t XEEXTS16(uint32_t v) { return (int64_t)((int16_t)v); } static inline int64_t XEEXTS26(uint32_t v) { return (int64_t)(v & 0x02000000 ? (int32_t)v | 0xFC000000 : (int32_t)(v)); } -static inline uint64_t XEEXTZ16(uint32_t v) { - return (uint64_t)((uint16_t)v); -} +static inline uint64_t XEEXTZ16(uint32_t v) { return (uint64_t)((uint16_t)v); } static inline uint64_t XEMASK(uint32_t mstart, uint32_t mstop) { // if mstart ≤ mstop then // mask[mstart:mstop] = ones @@ -105,289 +97,338 @@ static inline uint64_t XEMASK(uint32_t mstart, uint32_t mstop) { return mstart <= mstop ? value : ~value; } - typedef struct { - InstrType* type; - uint64_t address; + InstrType* type; + uint64_t address; union { - uint32_t code; + uint32_t code; // kXEPPCInstrFormatI struct { - uint32_t LK : 1; - uint32_t AA : 1; - uint32_t LI : 24; - uint32_t : 6; + uint32_t LK : 1; + uint32_t AA : 1; + uint32_t LI : 24; + uint32_t: + 6; } I; // kXEPPCInstrFormatB struct { - uint32_t LK : 1; - uint32_t AA : 1; - uint32_t BD : 14; - uint32_t BI : 5; - uint32_t BO : 5; - uint32_t : 6; + uint32_t LK : 1; + uint32_t AA : 1; + uint32_t BD : 14; + uint32_t BI : 5; + uint32_t BO : 5; + uint32_t: + 6; } B; // kXEPPCInstrFormatSC // kXEPPCInstrFormatD struct { - uint32_t DS : 16; - uint32_t RA : 5; - uint32_t RT : 5; - uint32_t : 6; + uint32_t DS : 16; + uint32_t RA : 5; + uint32_t RT : 5; + uint32_t: + 6; } D; // kXEPPCInstrFormatDS struct { - uint32_t : 2; - uint32_t DS : 14; - uint32_t RA : 5; - uint32_t RT : 5; - uint32_t : 6; + uint32_t: + 2; + uint32_t DS : 14; + uint32_t RA : 5; + uint32_t RT : 5; + uint32_t: + 6; } DS; // kXEPPCInstrFormatX struct { - uint32_t Rc : 1; - uint32_t : 10; - uint32_t RB : 5; - uint32_t RA : 5; - uint32_t RT : 5; - uint32_t : 6; + uint32_t Rc : 1; + uint32_t: + 10; + uint32_t RB : 5; + uint32_t RA : 5; + uint32_t RT : 5; + uint32_t: + 6; } X; // kXEPPCInstrFormatXL struct { - uint32_t LK : 1; - uint32_t : 10; - uint32_t BB : 5; - uint32_t BI : 5; - uint32_t BO : 5; - uint32_t : 6; + uint32_t LK : 1; + uint32_t: + 10; + uint32_t BB : 5; + uint32_t BI : 5; + uint32_t BO : 5; + uint32_t: + 6; } XL; // kXEPPCInstrFormatXFX struct { - uint32_t : 1; - uint32_t : 10; - uint32_t spr : 10; - uint32_t RT : 5; - uint32_t : 6; + uint32_t: + 1; + uint32_t: + 10; + uint32_t spr : 10; + uint32_t RT : 5; + uint32_t: + 6; } XFX; // kXEPPCInstrFormatXFL struct { - uint32_t Rc : 1; - uint32_t : 10; - uint32_t RB : 5; - uint32_t W : 1; - uint32_t FM : 8; - uint32_t L : 1; - uint32_t : 6; + uint32_t Rc : 1; + uint32_t: + 10; + uint32_t RB : 5; + uint32_t W : 1; + uint32_t FM : 8; + uint32_t L : 1; + uint32_t: + 6; } XFL; // kXEPPCInstrFormatXS struct { - uint32_t Rc : 1; - uint32_t SH5 : 1; - uint32_t : 9; - uint32_t SH : 5; - uint32_t RA : 5; - uint32_t RT : 5; - uint32_t : 6; + uint32_t Rc : 1; + uint32_t SH5 : 1; + uint32_t: + 9; + uint32_t SH : 5; + uint32_t RA : 5; + uint32_t RT : 5; + uint32_t: + 6; } XS; // kXEPPCInstrFormatXO struct { - uint32_t Rc : 1; - uint32_t : 9; - uint32_t OE : 1; - uint32_t RB : 5; - uint32_t RA : 5; - uint32_t RT : 5; - uint32_t : 6; + uint32_t Rc : 1; + uint32_t: + 9; + uint32_t OE : 1; + uint32_t RB : 5; + uint32_t RA : 5; + uint32_t RT : 5; + uint32_t: + 6; } XO; // kXEPPCInstrFormatA struct { - uint32_t Rc : 1; - uint32_t XO : 5; - uint32_t FRC : 5; - uint32_t FRB : 5; - uint32_t FRA : 5; - uint32_t FRT : 5; - uint32_t : 6; + uint32_t Rc : 1; + uint32_t XO : 5; + uint32_t FRC : 5; + uint32_t FRB : 5; + uint32_t FRA : 5; + uint32_t FRT : 5; + uint32_t: + 6; } A; // kXEPPCInstrFormatM struct { - uint32_t Rc : 1; - uint32_t ME : 5; - uint32_t MB : 5; - uint32_t SH : 5; - uint32_t RA : 5; - uint32_t RT : 5; - uint32_t : 6; + uint32_t Rc : 1; + uint32_t ME : 5; + uint32_t MB : 5; + uint32_t SH : 5; + uint32_t RA : 5; + uint32_t RT : 5; + uint32_t: + 6; } M; // kXEPPCInstrFormatMD struct { - uint32_t Rc : 1; - uint32_t SH5 : 1; - uint32_t idx : 3; - uint32_t MB5 : 1; - uint32_t MB : 5; - uint32_t SH : 5; - uint32_t RA : 5; - uint32_t RT : 5; - uint32_t : 6; + uint32_t Rc : 1; + uint32_t SH5 : 1; + uint32_t idx : 3; + uint32_t MB5 : 1; + uint32_t MB : 5; + uint32_t SH : 5; + uint32_t RA : 5; + uint32_t RT : 5; + uint32_t: + 6; } MD; // kXEPPCInstrFormatMDS struct { - uint32_t Rc : 1; - uint32_t idx : 4; - uint32_t MB5 : 1; - uint32_t MB : 5; - uint32_t RB : 5; - uint32_t RA : 5; - uint32_t RT : 5; - uint32_t : 6; + uint32_t Rc : 1; + uint32_t idx : 4; + uint32_t MB5 : 1; + uint32_t MB : 5; + uint32_t RB : 5; + uint32_t RA : 5; + uint32_t RT : 5; + uint32_t: + 6; } MDS; // kXEPPCInstrFormatVXA struct { - uint32_t : 6; - uint32_t VC : 5; - uint32_t VB : 5; - uint32_t VA : 5; - uint32_t VD : 5; - uint32_t : 6; + uint32_t: + 6; + uint32_t VC : 5; + uint32_t VB : 5; + uint32_t VA : 5; + uint32_t VD : 5; + uint32_t: + 6; } VXA; // kXEPPCInstrFormatVX struct { - uint32_t : 11; - uint32_t VB : 5; - uint32_t VA : 5; - uint32_t VD : 5; - uint32_t : 6; + uint32_t: + 11; + uint32_t VB : 5; + uint32_t VA : 5; + uint32_t VD : 5; + uint32_t: + 6; } VX; // kXEPPCInstrFormatVXR struct { - uint32_t : 10; - uint32_t Rc : 1; - uint32_t VB : 5; - uint32_t VA : 5; - uint32_t VD : 5; - uint32_t : 6; + uint32_t: + 10; + uint32_t Rc : 1; + uint32_t VB : 5; + uint32_t VA : 5; + uint32_t VD : 5; + uint32_t: + 6; } VXR; // kXEPPCInstrFormatVX128 struct { // VD128 = VD128l | (VD128h << 5) // VA128 = VA128l | (VA128h << 5) | (VA128H << 6) // VB128 = VB128l | (VB128h << 5) - uint32_t VB128h : 2; - uint32_t VD128h : 2; - uint32_t : 1; - uint32_t VA128h : 1; - uint32_t : 4; - uint32_t VA128H : 1; - uint32_t VB128l : 5; - uint32_t VA128l : 5; - uint32_t VD128l : 5; - uint32_t : 6; + uint32_t VB128h : 2; + uint32_t VD128h : 2; + uint32_t: + 1; + uint32_t VA128h : 1; + uint32_t: + 4; + uint32_t VA128H : 1; + uint32_t VB128l : 5; + uint32_t VA128l : 5; + uint32_t VD128l : 5; + uint32_t: + 6; } VX128; // kXEPPCInstrFormatVX128_1 struct { - // VD128 = VD128l | (VD128h << 5) - uint32_t : 2; - uint32_t VD128h : 2; - uint32_t : 7; - uint32_t RB : 5; - uint32_t RA : 5; - uint32_t VD128l : 5; - uint32_t : 6; + // VD128 = VD128l | (VD128h << 5) + uint32_t: + 2; + uint32_t VD128h : 2; + uint32_t: + 7; + uint32_t RB : 5; + uint32_t RA : 5; + uint32_t VD128l : 5; + uint32_t: + 6; } VX128_1; // kXEPPCInstrFormatVX128_2 struct { // VD128 = VD128l | (VD128h << 5) // VA128 = VA128l | (VA128h << 5) | (VA128H << 6) // VB128 = VB128l | (VB128h << 5) - uint32_t VB128h : 2; - uint32_t VD128h : 2; - uint32_t : 1; - uint32_t VA128h : 1; - uint32_t VC : 3; - uint32_t : 1; - uint32_t VA128H : 1; - uint32_t VB128l : 5; - uint32_t VA128l : 5; - uint32_t VD128l : 5; - uint32_t : 6; + uint32_t VB128h : 2; + uint32_t VD128h : 2; + uint32_t: + 1; + uint32_t VA128h : 1; + uint32_t VC : 3; + uint32_t: + 1; + uint32_t VA128H : 1; + uint32_t VB128l : 5; + uint32_t VA128l : 5; + uint32_t VD128l : 5; + uint32_t: + 6; } VX128_2; // kXEPPCInstrFormatVX128_3 struct { // VD128 = VD128l | (VD128h << 5) // VB128 = VB128l | (VB128h << 5) - uint32_t VB128h : 2; - uint32_t VD128h : 2; - uint32_t : 7; - uint32_t VB128l : 5; - uint32_t IMM : 5; - uint32_t VD128l : 5; - uint32_t : 6; + uint32_t VB128h : 2; + uint32_t VD128h : 2; + uint32_t: + 7; + uint32_t VB128l : 5; + uint32_t IMM : 5; + uint32_t VD128l : 5; + uint32_t: + 6; } VX128_3; // kXEPPCInstrFormatVX128_4 struct { // VD128 = VD128l | (VD128h << 5) // VB128 = VB128l | (VB128h << 5) - uint32_t VB128h : 2; - uint32_t VD128h : 2; - uint32_t : 2; - uint32_t z : 2; - uint32_t : 3; - uint32_t VB128l : 5; - uint32_t IMM : 5; - uint32_t VD128l : 5; - uint32_t : 6; + uint32_t VB128h : 2; + uint32_t VD128h : 2; + uint32_t: + 2; + uint32_t z : 2; + uint32_t: + 3; + uint32_t VB128l : 5; + uint32_t IMM : 5; + uint32_t VD128l : 5; + uint32_t: + 6; } VX128_4; // kXEPPCInstrFormatVX128_5 struct { // VD128 = VD128l | (VD128h << 5) // VA128 = VA128l | (VA128h << 5) | (VA128H << 6) // VB128 = VB128l | (VB128h << 5) - uint32_t VB128h : 2; - uint32_t VD128h : 2; - uint32_t : 1; - uint32_t VA128h : 1; - uint32_t SH : 4; - uint32_t VA128H : 1; - uint32_t VB128l : 5; - uint32_t VA128l : 5; - uint32_t VD128l : 5; - uint32_t : 6; + uint32_t VB128h : 2; + uint32_t VD128h : 2; + uint32_t: + 1; + uint32_t VA128h : 1; + uint32_t SH : 4; + uint32_t VA128H : 1; + uint32_t VB128l : 5; + uint32_t VA128l : 5; + uint32_t VD128l : 5; + uint32_t: + 6; } VX128_5; // kXEPPCInstrFormatVX128_P struct { // VD128 = VD128l | (VD128h << 5) // VB128 = VB128l | (VB128h << 5) // PERM = PERMl | (PERMh << 5) - uint32_t VB128h : 2; - uint32_t VD128h : 2; - uint32_t : 2; - uint32_t PERMh : 3; - uint32_t : 2; - uint32_t VB128l : 5; - uint32_t PERMl : 5; - uint32_t VD128l : 5; - uint32_t : 6; + uint32_t VB128h : 2; + uint32_t VD128h : 2; + uint32_t: + 2; + uint32_t PERMh : 3; + uint32_t: + 2; + uint32_t VB128l : 5; + uint32_t PERMl : 5; + uint32_t VD128l : 5; + uint32_t: + 6; } VX128_P; // kXEPPCInstrFormatVX128_R struct { // VD128 = VD128l | (VD128h << 5) // VA128 = VA128l | (VA128h << 5) | (VA128H << 6) // VB128 = VB128l | (VB128h << 5) - uint32_t VB128h : 2; - uint32_t VD128h : 2; - uint32_t : 1; - uint32_t VA128h : 1; - uint32_t Rc : 1; - uint32_t : 3; - uint32_t VA128H : 1; - uint32_t VB128l : 5; - uint32_t VA128l : 5; - uint32_t VD128l : 5; - uint32_t : 6; + uint32_t VB128h : 2; + uint32_t VD128h : 2; + uint32_t: + 1; + uint32_t VA128h : 1; + uint32_t Rc : 1; + uint32_t: + 3; + uint32_t VA128H : 1; + uint32_t VB128l : 5; + uint32_t VA128l : 5; + uint32_t VD128l : 5; + uint32_t: + 6; } VX128_R; // kXEPPCInstrFormatXDSS struct { @@ -395,31 +436,29 @@ typedef struct { }; } InstrData; - typedef struct { enum RegisterSet { kXER, kLR, kCTR, - kCR, // 0-7 + kCR, // 0-7 kFPSCR, - kGPR, // 0-31 - kFPR, // 0-31 - kVMX, // 0-127 + kGPR, // 0-31 + kFPR, // 0-31 + kVMX, // 0-127 }; enum Access { - kRead = 1 << 0, - kWrite = 1 << 1, - kReadWrite = kRead | kWrite, + kRead = 1 << 0, + kWrite = 1 << 1, + kReadWrite = kRead | kWrite, }; RegisterSet set; - uint32_t ordinal; - Access access; + uint32_t ordinal; + Access access; } InstrRegister; - typedef struct { enum OperandType { kRegister, @@ -431,30 +470,34 @@ typedef struct { union { InstrRegister reg; struct { - bool is_signed; - uint64_t value; - size_t width; + bool is_signed; + uint64_t value; + size_t width; } imm; }; void Dump(std::string& out_str); } InstrOperand; - class InstrAccessBits { -public: - InstrAccessBits() : - spr(0), cr(0), gpr(0), fpr(0), - vr31_0(0), vr63_32(0), vr95_64(0), vr127_96(0) { - } + public: + InstrAccessBits() + : spr(0), + cr(0), + gpr(0), + fpr(0), + vr31_0(0), + vr63_32(0), + vr95_64(0), + vr127_96(0) {} // Bitmasks derived from the accesses to registers. // Format is 2 bits for each register, even bits indicating reads and odds // indicating writes. - uint64_t spr; // fpcsr/ctr/lr/xer - uint64_t cr; // cr7/6/5/4/3/2/1/0 - uint64_t gpr; // r31-0 - uint64_t fpr; // f31-0 + uint64_t spr; // fpcsr/ctr/lr/xer + uint64_t cr; // cr7/6/5/4/3/2/1/0 + uint64_t gpr; // r31-0 + uint64_t fpr; // f31-0 uint64_t vr31_0; uint64_t vr63_32; uint64_t vr95_64; @@ -466,21 +509,20 @@ public: void Dump(std::string& out_str); }; - class InstrDisasm { -public: + public: enum Flags { - kOE = 1 << 0, - kRc = 1 << 1, - kCA = 1 << 2, - kLR = 1 << 4, - kFP = 1 << 5, - kVMX = 1 << 6, + kOE = 1 << 0, + kRc = 1 << 1, + kCA = 1 << 2, + kLR = 1 << 4, + kFP = 1 << 5, + kVMX = 1 << 6, }; - const char* name; - const char* info; - uint32_t flags; + const char* name; + const char* info; + uint32_t flags; void Init(const char* name, const char* info, uint32_t flags); void AddLR(InstrRegister::Access access); @@ -496,32 +538,27 @@ public: void Dump(std::string& out_str, size_t pad = 13); }; - typedef void (*InstrDisasmFn)(InstrData& i, StringBuffer* str); typedef void* InstrEmitFn; - class InstrType { -public: - uint32_t opcode; - uint32_t opcode_mask; // Only used for certain opcodes (altivec, etc). - uint32_t format; // xe_ppc_instr_format_e - uint32_t type; // xe_ppc_instr_type_e - uint32_t flags; // xe_ppc_instr_flag_e + public: + uint32_t opcode; + uint32_t opcode_mask; // Only used for certain opcodes (altivec, etc). + uint32_t format; // xe_ppc_instr_format_e + uint32_t type; // xe_ppc_instr_type_e + uint32_t flags; // xe_ppc_instr_flag_e InstrDisasmFn disasm; - char name[16]; + char name[16]; - InstrEmitFn emit; + InstrEmitFn emit; }; InstrType* GetInstrType(uint32_t code); int RegisterInstrEmit(uint32_t code, InstrEmitFn emit); - } // namespace ppc } // namespace frontend } // namespace alloy - #endif // ALLOY_FRONTEND_PPC_PPC_INSTR_H_ - diff --git a/src/alloy/frontend/ppc/ppc_instr_tables.h b/src/alloy/frontend/ppc/ppc_instr_tables.h index e0ce4640e..998b31039 100644 --- a/src/alloy/frontend/ppc/ppc_instr_tables.h +++ b/src/alloy/frontend/ppc/ppc_instr_tables.h @@ -12,7 +12,6 @@ #include - namespace alloy { namespace frontend { namespace ppc { @@ -90,9 +89,8 @@ void Disasm_vspltisw(InstrData& i, StringBuffer* str); namespace tables { - -static InstrType** instr_table_prep( - InstrType* unprep, int unprep_count, int a, int b) { +static InstrType** instr_table_prep(InstrType* unprep, int unprep_count, int a, + int b) { int prep_count = (int)pow(2.0, b - a + 1); InstrType** prep = (InstrType**)xe_calloc(prep_count * sizeof(void*)); for (int n = 0; n < unprep_count; n++) { @@ -102,8 +100,8 @@ static InstrType** instr_table_prep( return prep; } -static InstrType** instr_table_prep_63( - InstrType* unprep, int unprep_count, int a, int b) { +static InstrType** instr_table_prep_63(InstrType* unprep, int unprep_count, + int a, int b) { // Special handling for A format instructions. int prep_count = (int)pow(2.0, b - a + 1); InstrType** prep = (InstrType**)xe_calloc(prep_count * sizeof(void*)); @@ -121,19 +119,14 @@ static InstrType** instr_table_prep_63( return prep; } - -#define EMPTY(slot) {0} -#define INSTRUCTION(name, opcode, format, type, disasm_fn, descr) { \ - opcode, \ - 0, \ - kXEPPCInstrFormat##format, \ - kXEPPCInstrType##type, \ - 0, \ - Disasm_##disasm_fn, \ - #name, \ -} -#define FLAG(t) kXEPPCInstrFlag##t - +#define EMPTY(slot) \ + { 0 } +#define INSTRUCTION(name, opcode, format, type, disasm_fn, descr) \ + { \ + opcode, 0, kXEPPCInstrFormat##format, kXEPPCInstrType##type, 0, \ + Disasm_##disasm_fn, #name, \ + } +#define FLAG(t) kXEPPCInstrFlag##t // This table set is constructed from: // pem_64bit_v3.0.2005jul15.pdf, A.2 @@ -141,340 +134,559 @@ static InstrType** instr_table_prep_63( // Opcode = 4, index = bits 11-0 (6) static InstrType instr_table_4_unprep[] = { - // TODO: all of the vector ops - INSTRUCTION(mfvscr, 0x10000604, VX , General , 0 , "Move from Vector Status and Control Register"), - INSTRUCTION(mtvscr, 0x10000644, VX , General , 0 , "Move to Vector Status and Control Register"), - INSTRUCTION(vaddcuw, 0x10000180, VX , General , 0 , "Vector Add Carryout Unsigned Word"), - INSTRUCTION(vaddfp, 0x1000000A, VX , General , VX_VD_VA_VB , "Vector Add Floating Point"), - INSTRUCTION(vaddsbs, 0x10000300, VX , General , 0 , "Vector Add Signed Byte Saturate"), - INSTRUCTION(vaddshs, 0x10000340, VX , General , 0 , "Vector Add Signed Half Word Saturate"), - INSTRUCTION(vaddsws, 0x10000380, VX , General , 0 , "Vector Add Signed Word Saturate"), - INSTRUCTION(vaddubm, 0x10000000, VX , General , 0 , "Vector Add Unsigned Byte Modulo"), - INSTRUCTION(vaddubs, 0x10000200, VX , General , 0 , "Vector Add Unsigned Byte Saturate"), - INSTRUCTION(vadduhm, 0x10000040, VX , General , 0 , "Vector Add Unsigned Half Word Modulo"), - INSTRUCTION(vadduhs, 0x10000240, VX , General , 0 , "Vector Add Unsigned Half Word Saturate"), - INSTRUCTION(vadduwm, 0x10000080, VX , General , 0 , "Vector Add Unsigned Word Modulo"), - INSTRUCTION(vadduws, 0x10000280, VX , General , 0 , "Vector Add Unsigned Word Saturate"), - INSTRUCTION(vand, 0x10000404, VX , General , VX_VD_VA_VB , "Vector Logical AND"), - INSTRUCTION(vandc, 0x10000444, VX , General , VX_VD_VA_VB , "Vector Logical AND with Complement"), - INSTRUCTION(vavgsb, 0x10000502, VX , General , 0 , "Vector Average Signed Byte"), - INSTRUCTION(vavgsh, 0x10000542, VX , General , 0 , "Vector Average Signed Half Word"), - INSTRUCTION(vavgsw, 0x10000582, VX , General , 0 , "Vector Average Signed Word"), - INSTRUCTION(vavgub, 0x10000402, VX , General , 0 , "Vector Average Unsigned Byte"), - INSTRUCTION(vavguh, 0x10000442, VX , General , 0 , "Vector Average Unsigned Half Word"), - INSTRUCTION(vavguw, 0x10000482, VX , General , 0 , "Vector Average Unsigned Word"), - INSTRUCTION(vcfsx, 0x1000034A, VX , General , 0 , "Vector Convert from Signed Fixed-Point Word"), - INSTRUCTION(vcfux, 0x1000030A, VX , General , 0 , "Vector Convert from Unsigned Fixed-Point Word"), - INSTRUCTION(vctsxs, 0x100003CA, VX , General , 0 , "Vector Convert to Signed Fixed-Point Word Saturate"), - INSTRUCTION(vctuxs, 0x1000038A, VX , General , 0 , "Vector Convert to Unsigned Fixed-Point Word Saturate"), - INSTRUCTION(vexptefp, 0x1000018A, VX , General , 0 , "Vector 2 Raised to the Exponent Estimate Floating Point"), - INSTRUCTION(vlogefp, 0x100001CA, VX , General , 0 , "Vector Log2 Estimate Floating Point"), - INSTRUCTION(vmaxfp, 0x1000040A, VX , General , 0 , "Vector Maximum Floating Point"), - INSTRUCTION(vmaxsb, 0x10000102, VX , General , 0 , "Vector Maximum Signed Byte"), - INSTRUCTION(vmaxsh, 0x10000142, VX , General , 0 , "Vector Maximum Signed Half Word"), - INSTRUCTION(vmaxsw, 0x10000182, VX , General , 0 , "Vector Maximum Signed Word"), - INSTRUCTION(vmaxub, 0x10000002, VX , General , 0 , "Vector Maximum Unsigned Byte"), - INSTRUCTION(vmaxuh, 0x10000042, VX , General , 0 , "Vector Maximum Unsigned Half Word"), - INSTRUCTION(vmaxuw, 0x10000082, VX , General , 0 , "Vector Maximum Unsigned Word"), - INSTRUCTION(vminfp, 0x1000044A, VX , General , 0 , "Vector Minimum Floating Point"), - INSTRUCTION(vminsb, 0x10000302, VX , General , 0 , "Vector Minimum Signed Byte"), - INSTRUCTION(vminsh, 0x10000342, VX , General , 0 , "Vector Minimum Signed Half Word"), - INSTRUCTION(vminsw, 0x10000382, VX , General , 0 , "Vector Minimum Signed Word"), - INSTRUCTION(vminub, 0x10000202, VX , General , 0 , "Vector Minimum Unsigned Byte"), - INSTRUCTION(vminuh, 0x10000242, VX , General , 0 , "Vector Minimum Unsigned Half Word"), - INSTRUCTION(vminuw, 0x10000282, VX , General , 0 , "Vector Minimum Unsigned Word"), - INSTRUCTION(vmrghb, 0x1000000C, VX , General , 0 , "Vector Merge High Byte"), - INSTRUCTION(vmrghh, 0x1000004C, VX , General , 0 , "Vector Merge High Half Word"), - INSTRUCTION(vmrghw, 0x1000008C, VX , General , 0 , "Vector Merge High Word"), - INSTRUCTION(vmrglb, 0x1000010C, VX , General , 0 , "Vector Merge Low Byte"), - INSTRUCTION(vmrglh, 0x1000014C, VX , General , 0 , "Vector Merge Low Half Word"), - INSTRUCTION(vmrglw, 0x1000018C, VX , General , 0 , "Vector Merge Low Word"), - INSTRUCTION(vmulesb, 0x10000308, VX , General , 0 , "Vector Multiply Even Signed Byte"), - INSTRUCTION(vmulesh, 0x10000348, VX , General , 0 , "Vector Multiply Even Signed Half Word"), - INSTRUCTION(vmuleub, 0x10000208, VX , General , 0 , "Vector Multiply Even Unsigned Byte"), - INSTRUCTION(vmuleuh, 0x10000248, VX , General , 0 , "Vector Multiply Even Unsigned Half Word"), - INSTRUCTION(vmulosb, 0x10000108, VX , General , 0 , "Vector Multiply Odd Signed Byte"), - INSTRUCTION(vmulosh, 0x10000148, VX , General , 0 , "Vector Multiply Odd Signed Half Word"), - INSTRUCTION(vmuloub, 0x10000008, VX , General , 0 , "Vector Multiply Odd Unsigned Byte"), - INSTRUCTION(vmulouh, 0x10000048, VX , General , 0 , "Vector Multiply Odd Unsigned Half Word"), - INSTRUCTION(vnor, 0x10000504, VX , General , VX_VD_VA_VB , "Vector Logical NOR"), - INSTRUCTION(vor, 0x10000484, VX , General , VX_VD_VA_VB , "Vector Logical OR"), - INSTRUCTION(vpkpx, 0x1000030E, VX , General , 0 , "Vector Pack Pixel"), - INSTRUCTION(vpkshss, 0x1000018E, VX , General , 0 , "Vector Pack Signed Half Word Signed Saturate"), - INSTRUCTION(vpkshus, 0x1000010E, VX , General , 0 , "Vector Pack Signed Half Word Unsigned Saturate"), - INSTRUCTION(vpkswss, 0x100001CE, VX , General , 0 , "Vector Pack Signed Word Signed Saturate"), - INSTRUCTION(vpkswus, 0x1000014E, VX , General , 0 , "Vector Pack Signed Word Unsigned Saturate"), - INSTRUCTION(vpkuhum, 0x1000000E, VX , General , 0 , "Vector Pack Unsigned Half Word Unsigned Modulo"), - INSTRUCTION(vpkuhus, 0x1000008E, VX , General , 0 , "Vector Pack Unsigned Half Word Unsigned Saturate"), - INSTRUCTION(vpkuwum, 0x1000004E, VX , General , 0 , "Vector Pack Unsigned Word Unsigned Modulo"), - INSTRUCTION(vpkuwus, 0x100000CE, VX , General , 0 , "Vector Pack Unsigned Word Unsigned Saturate"), - INSTRUCTION(vrefp, 0x1000010A, VX , General , 0 , "Vector Reciprocal Estimate Floating Point"), - INSTRUCTION(vrfim, 0x100002CA, VX , General , 0 , "Vector Round to Floating-Point Integer toward -Infinity"), - INSTRUCTION(vrfin, 0x1000020A, VX , General , 0 , "Vector Round to Floating-Point Integer Nearest"), - INSTRUCTION(vrfip, 0x1000028A, VX , General , 0 , "Vector Round to Floating-Point Integer toward +Infinity"), - INSTRUCTION(vrfiz, 0x1000024A, VX , General , 0 , "Vector Round to Floating-Point Integer toward Zero"), - INSTRUCTION(vrlb, 0x10000004, VX , General , 0 , "Vector Rotate Left Integer Byte"), - INSTRUCTION(vrlh, 0x10000044, VX , General , 0 , "Vector Rotate Left Integer Half Word"), - INSTRUCTION(vrlw, 0x10000084, VX , General , 0 , "Vector Rotate Left Integer Word"), - INSTRUCTION(vrsqrtefp, 0x1000014A, VX , General , 0 , "Vector Reciprocal Square Root Estimate Floating Point"), - INSTRUCTION(vsl, 0x100001C4, VX , General , 0 , "Vector Shift Left"), - INSTRUCTION(vslb, 0x10000104, VX , General , VX_VD_VA_VB , "Vector Shift Left Integer Byte"), - INSTRUCTION(vslh, 0x10000144, VX , General , 0 , "Vector Shift Left Integer Half Word"), - INSTRUCTION(vslo, 0x1000040C, VX , General , 0 , "Vector Shift Left by Octet"), - INSTRUCTION(vslw, 0x10000184, VX , General , 0 , "Vector Shift Left Integer Word"), - INSTRUCTION(vspltb, 0x1000020C, VX , General , vspltb , "Vector Splat Byte"), - INSTRUCTION(vsplth, 0x1000024C, VX , General , vsplth , "Vector Splat Half Word"), - INSTRUCTION(vspltisb, 0x1000030C, VX , General , vspltisb , "Vector Splat Immediate Signed Byte"), - INSTRUCTION(vspltish, 0x1000034C, VX , General , vspltish , "Vector Splat Immediate Signed Half Word"), - INSTRUCTION(vspltisw, 0x1000038C, VX , General , vspltisw , "Vector Splat Immediate Signed Word"), - INSTRUCTION(vspltw, 0x1000028C, VX , General , vspltw , "Vector Splat Word"), - INSTRUCTION(vsr, 0x100002C4, VX , General , VX_VD_VA_VB , "Vector Shift Right"), - INSTRUCTION(vsrab, 0x10000304, VX , General , VX_VD_VA_VB , "Vector Shift Right Algebraic Byte"), - INSTRUCTION(vsrah, 0x10000344, VX , General , VX_VD_VA_VB , "Vector Shift Right Algebraic Half Word"), - INSTRUCTION(vsraw, 0x10000384, VX , General , VX_VD_VA_VB , "Vector Shift Right Algebraic Word"), - INSTRUCTION(vsrb, 0x10000204, VX , General , VX_VD_VA_VB , "Vector Shift Right Byte"), - INSTRUCTION(vsrh, 0x10000244, VX , General , VX_VD_VA_VB , "Vector Shift Right Half Word"), - INSTRUCTION(vsro, 0x1000044C, VX , General , VX_VD_VA_VB , "Vector Shift Right Octet"), - INSTRUCTION(vsrw, 0x10000284, VX , General , VX_VD_VA_VB , "Vector Shift Right Word"), - INSTRUCTION(vsubcuw, 0x10000580, VX , General , 0 , "Vector Subtract Carryout Unsigned Word"), - INSTRUCTION(vsubfp, 0x1000004A, VX , General , 0 , "Vector Subtract Floating Point"), - INSTRUCTION(vsubsbs, 0x10000700, VX , General , 0 , "Vector Subtract Signed Byte Saturate"), - INSTRUCTION(vsubshs, 0x10000740, VX , General , 0 , "Vector Subtract Signed Half Word Saturate"), - INSTRUCTION(vsubsws, 0x10000780, VX , General , 0 , "Vector Subtract Signed Word Saturate"), - INSTRUCTION(vsububm, 0x10000400, VX , General , 0 , "Vector Subtract Unsigned Byte Modulo"), - INSTRUCTION(vsububs, 0x10000600, VX , General , 0 , "Vector Subtract Unsigned Byte Saturate"), - INSTRUCTION(vsubuhm, 0x10000440, VX , General , 0 , "Vector Subtract Unsigned Half Word Modulo"), - INSTRUCTION(vsubuhs, 0x10000640, VX , General , 0 , "Vector Subtract Unsigned Half Word Saturate"), - INSTRUCTION(vsubuwm, 0x10000480, VX , General , 0 , "Vector Subtract Unsigned Word Modulo"), - INSTRUCTION(vsubuws, 0x10000680, VX , General , 0 , "Vector Subtract Unsigned Word Saturate"), - INSTRUCTION(vsumsws, 0x10000788, VX , General , 0 , "Vector Sum Across Signed Word Saturate"), - INSTRUCTION(vsum2sws, 0x10000688, VX , General , 0 , "Vector Sum Across Partial (1/2) Signed Word Saturate"), - INSTRUCTION(vsum4sbs, 0x10000708, VX , General , 0 , "Vector Sum Across Partial (1/4) Signed Byte Saturate"), - INSTRUCTION(vsum4shs, 0x10000648, VX , General , 0 , "Vector Sum Across Partial (1/4) Signed Half Word Saturate"), - INSTRUCTION(vsum4ubs, 0x10000608, VX , General , 0 , "Vector Sum Across Partial (1/4) Unsigned Byte Saturate"), - INSTRUCTION(vupkhpx, 0x1000034E, VX , General , 0 , "Vector Unpack High Pixel"), - INSTRUCTION(vupkhsb, 0x1000020E, VX , General , 0 , "Vector Unpack High Signed Byte"), - INSTRUCTION(vupkhsh, 0x1000024E, VX , General , 0 , "Vector Unpack High Signed Half Word"), - INSTRUCTION(vupklpx, 0x100003CE, VX , General , 0 , "Vector Unpack Low Pixel"), - INSTRUCTION(vupklsb, 0x1000028E, VX , General , 0 , "Vector Unpack Low Signed Byte"), - INSTRUCTION(vupklsh, 0x100002CE, VX , General , 0 , "Vector Unpack Low Signed Half Word"), - INSTRUCTION(vxor, 0x100004C4, VX , General , VX_VD_VA_VB , "Vector Logical XOR"), + // TODO: all of the vector ops + INSTRUCTION(mfvscr, 0x10000604, VX, General, 0, + "Move from Vector Status and Control Register"), + INSTRUCTION(mtvscr, 0x10000644, VX, General, 0, + "Move to Vector Status and Control Register"), + INSTRUCTION(vaddcuw, 0x10000180, VX, General, 0, + "Vector Add Carryout Unsigned Word"), + INSTRUCTION(vaddfp, 0x1000000A, VX, General, VX_VD_VA_VB, + "Vector Add Floating Point"), + INSTRUCTION(vaddsbs, 0x10000300, VX, General, 0, + "Vector Add Signed Byte Saturate"), + INSTRUCTION(vaddshs, 0x10000340, VX, General, 0, + "Vector Add Signed Half Word Saturate"), + INSTRUCTION(vaddsws, 0x10000380, VX, General, 0, + "Vector Add Signed Word Saturate"), + INSTRUCTION(vaddubm, 0x10000000, VX, General, 0, + "Vector Add Unsigned Byte Modulo"), + INSTRUCTION(vaddubs, 0x10000200, VX, General, 0, + "Vector Add Unsigned Byte Saturate"), + INSTRUCTION(vadduhm, 0x10000040, VX, General, 0, + "Vector Add Unsigned Half Word Modulo"), + INSTRUCTION(vadduhs, 0x10000240, VX, General, 0, + "Vector Add Unsigned Half Word Saturate"), + INSTRUCTION(vadduwm, 0x10000080, VX, General, 0, + "Vector Add Unsigned Word Modulo"), + INSTRUCTION(vadduws, 0x10000280, VX, General, 0, + "Vector Add Unsigned Word Saturate"), + INSTRUCTION(vand, 0x10000404, VX, General, VX_VD_VA_VB, + "Vector Logical AND"), + INSTRUCTION(vandc, 0x10000444, VX, General, VX_VD_VA_VB, + "Vector Logical AND with Complement"), + INSTRUCTION(vavgsb, 0x10000502, VX, General, 0, + "Vector Average Signed Byte"), + INSTRUCTION(vavgsh, 0x10000542, VX, General, 0, + "Vector Average Signed Half Word"), + INSTRUCTION(vavgsw, 0x10000582, VX, General, 0, + "Vector Average Signed Word"), + INSTRUCTION(vavgub, 0x10000402, VX, General, 0, + "Vector Average Unsigned Byte"), + INSTRUCTION(vavguh, 0x10000442, VX, General, 0, + "Vector Average Unsigned Half Word"), + INSTRUCTION(vavguw, 0x10000482, VX, General, 0, + "Vector Average Unsigned Word"), + INSTRUCTION(vcfsx, 0x1000034A, VX, General, 0, + "Vector Convert from Signed Fixed-Point Word"), + INSTRUCTION(vcfux, 0x1000030A, VX, General, 0, + "Vector Convert from Unsigned Fixed-Point Word"), + INSTRUCTION(vctsxs, 0x100003CA, VX, General, 0, + "Vector Convert to Signed Fixed-Point Word Saturate"), + INSTRUCTION(vctuxs, 0x1000038A, VX, General, 0, + "Vector Convert to Unsigned Fixed-Point Word Saturate"), + INSTRUCTION(vexptefp, 0x1000018A, VX, General, 0, + "Vector 2 Raised to the Exponent Estimate Floating Point"), + INSTRUCTION(vlogefp, 0x100001CA, VX, General, 0, + "Vector Log2 Estimate Floating Point"), + INSTRUCTION(vmaxfp, 0x1000040A, VX, General, 0, + "Vector Maximum Floating Point"), + INSTRUCTION(vmaxsb, 0x10000102, VX, General, 0, + "Vector Maximum Signed Byte"), + INSTRUCTION(vmaxsh, 0x10000142, VX, General, 0, + "Vector Maximum Signed Half Word"), + INSTRUCTION(vmaxsw, 0x10000182, VX, General, 0, + "Vector Maximum Signed Word"), + INSTRUCTION(vmaxub, 0x10000002, VX, General, 0, + "Vector Maximum Unsigned Byte"), + INSTRUCTION(vmaxuh, 0x10000042, VX, General, 0, + "Vector Maximum Unsigned Half Word"), + INSTRUCTION(vmaxuw, 0x10000082, VX, General, 0, + "Vector Maximum Unsigned Word"), + INSTRUCTION(vminfp, 0x1000044A, VX, General, 0, + "Vector Minimum Floating Point"), + INSTRUCTION(vminsb, 0x10000302, VX, General, 0, + "Vector Minimum Signed Byte"), + INSTRUCTION(vminsh, 0x10000342, VX, General, 0, + "Vector Minimum Signed Half Word"), + INSTRUCTION(vminsw, 0x10000382, VX, General, 0, + "Vector Minimum Signed Word"), + INSTRUCTION(vminub, 0x10000202, VX, General, 0, + "Vector Minimum Unsigned Byte"), + INSTRUCTION(vminuh, 0x10000242, VX, General, 0, + "Vector Minimum Unsigned Half Word"), + INSTRUCTION(vminuw, 0x10000282, VX, General, 0, + "Vector Minimum Unsigned Word"), + INSTRUCTION(vmrghb, 0x1000000C, VX, General, 0, "Vector Merge High Byte"), + INSTRUCTION(vmrghh, 0x1000004C, VX, General, 0, + "Vector Merge High Half Word"), + INSTRUCTION(vmrghw, 0x1000008C, VX, General, 0, "Vector Merge High Word"), + INSTRUCTION(vmrglb, 0x1000010C, VX, General, 0, "Vector Merge Low Byte"), + INSTRUCTION(vmrglh, 0x1000014C, VX, General, 0, + "Vector Merge Low Half Word"), + INSTRUCTION(vmrglw, 0x1000018C, VX, General, 0, "Vector Merge Low Word"), + INSTRUCTION(vmulesb, 0x10000308, VX, General, 0, + "Vector Multiply Even Signed Byte"), + INSTRUCTION(vmulesh, 0x10000348, VX, General, 0, + "Vector Multiply Even Signed Half Word"), + INSTRUCTION(vmuleub, 0x10000208, VX, General, 0, + "Vector Multiply Even Unsigned Byte"), + INSTRUCTION(vmuleuh, 0x10000248, VX, General, 0, + "Vector Multiply Even Unsigned Half Word"), + INSTRUCTION(vmulosb, 0x10000108, VX, General, 0, + "Vector Multiply Odd Signed Byte"), + INSTRUCTION(vmulosh, 0x10000148, VX, General, 0, + "Vector Multiply Odd Signed Half Word"), + INSTRUCTION(vmuloub, 0x10000008, VX, General, 0, + "Vector Multiply Odd Unsigned Byte"), + INSTRUCTION(vmulouh, 0x10000048, VX, General, 0, + "Vector Multiply Odd Unsigned Half Word"), + INSTRUCTION(vnor, 0x10000504, VX, General, VX_VD_VA_VB, + "Vector Logical NOR"), + INSTRUCTION(vor, 0x10000484, VX, General, VX_VD_VA_VB, "Vector Logical OR"), + INSTRUCTION(vpkpx, 0x1000030E, VX, General, 0, "Vector Pack Pixel"), + INSTRUCTION(vpkshss, 0x1000018E, VX, General, 0, + "Vector Pack Signed Half Word Signed Saturate"), + INSTRUCTION(vpkshus, 0x1000010E, VX, General, 0, + "Vector Pack Signed Half Word Unsigned Saturate"), + INSTRUCTION(vpkswss, 0x100001CE, VX, General, 0, + "Vector Pack Signed Word Signed Saturate"), + INSTRUCTION(vpkswus, 0x1000014E, VX, General, 0, + "Vector Pack Signed Word Unsigned Saturate"), + INSTRUCTION(vpkuhum, 0x1000000E, VX, General, 0, + "Vector Pack Unsigned Half Word Unsigned Modulo"), + INSTRUCTION(vpkuhus, 0x1000008E, VX, General, 0, + "Vector Pack Unsigned Half Word Unsigned Saturate"), + INSTRUCTION(vpkuwum, 0x1000004E, VX, General, 0, + "Vector Pack Unsigned Word Unsigned Modulo"), + INSTRUCTION(vpkuwus, 0x100000CE, VX, General, 0, + "Vector Pack Unsigned Word Unsigned Saturate"), + INSTRUCTION(vrefp, 0x1000010A, VX, General, 0, + "Vector Reciprocal Estimate Floating Point"), + INSTRUCTION(vrfim, 0x100002CA, VX, General, 0, + "Vector Round to Floating-Point Integer toward -Infinity"), + INSTRUCTION(vrfin, 0x1000020A, VX, General, 0, + "Vector Round to Floating-Point Integer Nearest"), + INSTRUCTION(vrfip, 0x1000028A, VX, General, 0, + "Vector Round to Floating-Point Integer toward +Infinity"), + INSTRUCTION(vrfiz, 0x1000024A, VX, General, 0, + "Vector Round to Floating-Point Integer toward Zero"), + INSTRUCTION(vrlb, 0x10000004, VX, General, 0, + "Vector Rotate Left Integer Byte"), + INSTRUCTION(vrlh, 0x10000044, VX, General, 0, + "Vector Rotate Left Integer Half Word"), + INSTRUCTION(vrlw, 0x10000084, VX, General, 0, + "Vector Rotate Left Integer Word"), + INSTRUCTION(vrsqrtefp, 0x1000014A, VX, General, 0, + "Vector Reciprocal Square Root Estimate Floating Point"), + INSTRUCTION(vsl, 0x100001C4, VX, General, 0, "Vector Shift Left"), + INSTRUCTION(vslb, 0x10000104, VX, General, VX_VD_VA_VB, + "Vector Shift Left Integer Byte"), + INSTRUCTION(vslh, 0x10000144, VX, General, 0, + "Vector Shift Left Integer Half Word"), + INSTRUCTION(vslo, 0x1000040C, VX, General, 0, "Vector Shift Left by Octet"), + INSTRUCTION(vslw, 0x10000184, VX, General, 0, + "Vector Shift Left Integer Word"), + INSTRUCTION(vspltb, 0x1000020C, VX, General, vspltb, "Vector Splat Byte"), + INSTRUCTION(vsplth, 0x1000024C, VX, General, vsplth, + "Vector Splat Half Word"), + INSTRUCTION(vspltisb, 0x1000030C, VX, General, vspltisb, + "Vector Splat Immediate Signed Byte"), + INSTRUCTION(vspltish, 0x1000034C, VX, General, vspltish, + "Vector Splat Immediate Signed Half Word"), + INSTRUCTION(vspltisw, 0x1000038C, VX, General, vspltisw, + "Vector Splat Immediate Signed Word"), + INSTRUCTION(vspltw, 0x1000028C, VX, General, vspltw, "Vector Splat Word"), + INSTRUCTION(vsr, 0x100002C4, VX, General, VX_VD_VA_VB, + "Vector Shift Right"), + INSTRUCTION(vsrab, 0x10000304, VX, General, VX_VD_VA_VB, + "Vector Shift Right Algebraic Byte"), + INSTRUCTION(vsrah, 0x10000344, VX, General, VX_VD_VA_VB, + "Vector Shift Right Algebraic Half Word"), + INSTRUCTION(vsraw, 0x10000384, VX, General, VX_VD_VA_VB, + "Vector Shift Right Algebraic Word"), + INSTRUCTION(vsrb, 0x10000204, VX, General, VX_VD_VA_VB, + "Vector Shift Right Byte"), + INSTRUCTION(vsrh, 0x10000244, VX, General, VX_VD_VA_VB, + "Vector Shift Right Half Word"), + INSTRUCTION(vsro, 0x1000044C, VX, General, VX_VD_VA_VB, + "Vector Shift Right Octet"), + INSTRUCTION(vsrw, 0x10000284, VX, General, VX_VD_VA_VB, + "Vector Shift Right Word"), + INSTRUCTION(vsubcuw, 0x10000580, VX, General, 0, + "Vector Subtract Carryout Unsigned Word"), + INSTRUCTION(vsubfp, 0x1000004A, VX, General, 0, + "Vector Subtract Floating Point"), + INSTRUCTION(vsubsbs, 0x10000700, VX, General, 0, + "Vector Subtract Signed Byte Saturate"), + INSTRUCTION(vsubshs, 0x10000740, VX, General, 0, + "Vector Subtract Signed Half Word Saturate"), + INSTRUCTION(vsubsws, 0x10000780, VX, General, 0, + "Vector Subtract Signed Word Saturate"), + INSTRUCTION(vsububm, 0x10000400, VX, General, 0, + "Vector Subtract Unsigned Byte Modulo"), + INSTRUCTION(vsububs, 0x10000600, VX, General, 0, + "Vector Subtract Unsigned Byte Saturate"), + INSTRUCTION(vsubuhm, 0x10000440, VX, General, 0, + "Vector Subtract Unsigned Half Word Modulo"), + INSTRUCTION(vsubuhs, 0x10000640, VX, General, 0, + "Vector Subtract Unsigned Half Word Saturate"), + INSTRUCTION(vsubuwm, 0x10000480, VX, General, 0, + "Vector Subtract Unsigned Word Modulo"), + INSTRUCTION(vsubuws, 0x10000680, VX, General, 0, + "Vector Subtract Unsigned Word Saturate"), + INSTRUCTION(vsumsws, 0x10000788, VX, General, 0, + "Vector Sum Across Signed Word Saturate"), + INSTRUCTION(vsum2sws, 0x10000688, VX, General, 0, + "Vector Sum Across Partial (1/2) Signed Word Saturate"), + INSTRUCTION(vsum4sbs, 0x10000708, VX, General, 0, + "Vector Sum Across Partial (1/4) Signed Byte Saturate"), + INSTRUCTION(vsum4shs, 0x10000648, VX, General, 0, + "Vector Sum Across Partial (1/4) Signed Half Word Saturate"), + INSTRUCTION(vsum4ubs, 0x10000608, VX, General, 0, + "Vector Sum Across Partial (1/4) Unsigned Byte Saturate"), + INSTRUCTION(vupkhpx, 0x1000034E, VX, General, 0, + "Vector Unpack High Pixel"), + INSTRUCTION(vupkhsb, 0x1000020E, VX, General, 0, + "Vector Unpack High Signed Byte"), + INSTRUCTION(vupkhsh, 0x1000024E, VX, General, 0, + "Vector Unpack High Signed Half Word"), + INSTRUCTION(vupklpx, 0x100003CE, VX, General, 0, "Vector Unpack Low Pixel"), + INSTRUCTION(vupklsb, 0x1000028E, VX, General, 0, + "Vector Unpack Low Signed Byte"), + INSTRUCTION(vupklsh, 0x100002CE, VX, General, 0, + "Vector Unpack Low Signed Half Word"), + INSTRUCTION(vxor, 0x100004C4, VX, General, VX_VD_VA_VB, + "Vector Logical XOR"), }; static InstrType** instr_table_4 = instr_table_prep( instr_table_4_unprep, XECOUNT(instr_table_4_unprep), 0, 11); // Opcode = 19, index = bits 10-1 (10) static InstrType instr_table_19_unprep[] = { - INSTRUCTION(mcrf, 0x4C000000, XL , General , 0 , NULL), - INSTRUCTION(bclrx, 0x4C000020, XL , BranchCond , bclrx , "Branch Conditional to Link Register"), - INSTRUCTION(crnor, 0x4C000042, XL , General , 0 , NULL), - INSTRUCTION(crandc, 0x4C000102, XL , General , 0 , NULL), - INSTRUCTION(isync, 0x4C00012C, XL , General , 0 , NULL), - INSTRUCTION(crxor, 0x4C000182, XL , General , 0 , NULL), - INSTRUCTION(crnand, 0x4C0001C2, XL , General , 0 , NULL), - INSTRUCTION(crand, 0x4C000202, XL , General , 0 , NULL), - INSTRUCTION(creqv, 0x4C000242, XL , General , 0 , NULL), - INSTRUCTION(crorc, 0x4C000342, XL , General , 0 , NULL), - INSTRUCTION(cror, 0x4C000382, XL , General , 0 , NULL), - INSTRUCTION(bcctrx, 0x4C000420, XL , BranchCond , bcctrx , "Branch Conditional to Count Register"), + INSTRUCTION(mcrf, 0x4C000000, XL, General, 0, NULL), + INSTRUCTION(bclrx, 0x4C000020, XL, BranchCond, bclrx, + "Branch Conditional to Link Register"), + INSTRUCTION(crnor, 0x4C000042, XL, General, 0, NULL), + INSTRUCTION(crandc, 0x4C000102, XL, General, 0, NULL), + INSTRUCTION(isync, 0x4C00012C, XL, General, 0, NULL), + INSTRUCTION(crxor, 0x4C000182, XL, General, 0, NULL), + INSTRUCTION(crnand, 0x4C0001C2, XL, General, 0, NULL), + INSTRUCTION(crand, 0x4C000202, XL, General, 0, NULL), + INSTRUCTION(creqv, 0x4C000242, XL, General, 0, NULL), + INSTRUCTION(crorc, 0x4C000342, XL, General, 0, NULL), + INSTRUCTION(cror, 0x4C000382, XL, General, 0, NULL), + INSTRUCTION(bcctrx, 0x4C000420, XL, BranchCond, bcctrx, + "Branch Conditional to Count Register"), }; static InstrType** instr_table_19 = instr_table_prep( instr_table_19_unprep, XECOUNT(instr_table_19_unprep), 1, 10); // Opcode = 30, index = bits 4-1 (4) static InstrType instr_table_30_unprep[] = { - // Decoding these instrunctions in this table is difficult because the - // index bits are kind of random. This is special cased by an uber - // instruction handler. - INSTRUCTION(rld, 0x78000000, MD , General , rld , NULL), - // INSTRUCTION(rldiclx, 0x78000000, MD , General , 0), - // INSTRUCTION(rldicrx, 0x78000004, MD , General , 0), - // INSTRUCTION(rldicx, 0x78000008, MD , General , 0), - // INSTRUCTION(rldimix, 0x7800000C, MD , General , 0), - // INSTRUCTION(rldclx, 0x78000010, MDS, General , 0), - // INSTRUCTION(rldcrx, 0x78000012, MDS, General , 0), + // Decoding these instrunctions in this table is difficult because the + // index bits are kind of random. This is special cased by an uber + // instruction handler. + INSTRUCTION(rld, 0x78000000, MD, General, rld, NULL), + // INSTRUCTION(rldiclx, 0x78000000, MD , General , 0), + // INSTRUCTION(rldicrx, 0x78000004, MD , General , 0), + // INSTRUCTION(rldicx, 0x78000008, MD , General , 0), + // INSTRUCTION(rldimix, 0x7800000C, MD , General , 0), + // INSTRUCTION(rldclx, 0x78000010, MDS, General , 0), + // INSTRUCTION(rldcrx, 0x78000012, MDS, General , 0), }; static InstrType** instr_table_30 = instr_table_prep( instr_table_30_unprep, XECOUNT(instr_table_30_unprep), 0, 0); // Opcode = 31, index = bits 10-1 (10) static InstrType instr_table_31_unprep[] = { - INSTRUCTION(cmp, 0x7C000000, X , General , cmp , "Compare"), - INSTRUCTION(tw, 0x7C000008, X , General , X_RA_RB , "Trap Word"), - INSTRUCTION(lvsl, 0x7C00000C, X , General , X_VX_RA0_RB , "Load Vector for Shift Left"), - INSTRUCTION(lvebx, 0x7C00000E, X , General , 0 , "Load Vector Element Byte Indexed"), - INSTRUCTION(subfcx, 0x7C000010, XO , General , XO_RT_RA_RB , "Subtract From Carrying"), - INSTRUCTION(mulhdux, 0x7C000012, XO , General , XO_RT_RA_RB , "Multiply High Doubleword Unsigned"), - INSTRUCTION(addcx, 0x7C000014, XO , General , XO_RT_RA_RB , "Add Carrying"), - INSTRUCTION(mulhwux, 0x7C000016, XO , General , XO_RT_RA_RB , "Multiply High Word Unsigned"), - INSTRUCTION(mfcr, 0x7C000026, X , General , mfcr , "Move From Condition Register"), - INSTRUCTION(lwarx, 0x7C000028, X , General , X_RT_RA0_RB , "Load Word And Reserve Indexed"), - INSTRUCTION(ldx, 0x7C00002A, X , General , X_RT_RA0_RB , "Load Doubleword Indexed"), - INSTRUCTION(lwzx, 0x7C00002E, X , General , X_RT_RA0_RB , "Load Word and Zero Indexed"), - INSTRUCTION(slwx, 0x7C000030, X , General , X_RA_RT_RB , "Shift Left Word"), - INSTRUCTION(cntlzwx, 0x7C000034, X , General , X_RA_RT , "Count Leading Zeros Word"), - INSTRUCTION(sldx, 0x7C000036, X , General , X_RA_RT_RB , "Shift Left Doubleword"), - INSTRUCTION(andx, 0x7C000038, X , General , X_RA_RT_RB , "AND"), - INSTRUCTION(cmpl, 0x7C000040, X , General , cmp , "Compare Logical"), - INSTRUCTION(lvsr, 0x7C00004C, X , General , X_VX_RA0_RB , "Load Vector for Shift Right"), - INSTRUCTION(lvehx, 0x7C00004E, X , General , 0 , "Load Vector Element Half Word Indexed"), - INSTRUCTION(subfx, 0x7C000050, XO , General , XO_RT_RA_RB , "Subtract From"), - INSTRUCTION(ldux, 0x7C00006A, X , General , X_RT_RA_RB , "Load Doubleword with Update Indexed"), - INSTRUCTION(dcbst, 0x7C00006C, X , General , 0 , NULL), - INSTRUCTION(lwzux, 0x7C00006E, X , General , X_RT_RA_RB , "Load Word and Zero with Update Indexed"), - INSTRUCTION(cntlzdx, 0x7C000074, X , General , X_RA_RT , "Count Leading Zeros Doubleword"), - INSTRUCTION(andcx, 0x7C000078, X , General , X_RA_RT_RB , "AND with Complement"), - INSTRUCTION(td, 0x7C000088, X , General , X_RA_RB , "Trap Doubleword"), - INSTRUCTION(lvewx, 0x7C00008E, X , General , 0 , "Load Vector Element Word Indexed"), - INSTRUCTION(mulhdx, 0x7C000092, XO , General , XO_RT_RA_RB , "Multiply High Doubleword"), - INSTRUCTION(mulhwx, 0x7C000096, XO , General , XO_RT_RA_RB , "Multiply High Word"), - INSTRUCTION(mfmsr, 0x7C0000A6, X , General , mfmsr , "Move From Machine State Register"), - INSTRUCTION(ldarx, 0x7C0000A8, X , General , X_RT_RA0_RB , "Load Doubleword And Reserve Indexed"), - INSTRUCTION(dcbf, 0x7C0000AC, X , General , dcbf , "Data Cache Block Flush"), - INSTRUCTION(lbzx, 0x7C0000AE, X , General , X_RT_RA0_RB , "Load Byte and Zero Indexed"), - INSTRUCTION(lvx, 0x7C0000CE, X , General , X_VX_RA0_RB , "Load Vector Indexed"), - INSTRUCTION(negx, 0x7C0000D0, XO , General , XO_RT_RA , "Negate"), - INSTRUCTION(lbzux, 0x7C0000EE, X , General , X_RT_RA_RB , "Load Byte and Zero with Update Indexed"), - INSTRUCTION(norx, 0x7C0000F8, X , General , X_RA_RT_RB , "NOR"), - INSTRUCTION(stvebx, 0x7C00010E, X , General , 0 , "Store Vector Element Byte Indexed"), - INSTRUCTION(subfex, 0x7C000110, XO , General , XO_RT_RA_RB , "Subtract From Extended"), - INSTRUCTION(addex, 0x7C000114, XO , General , XO_RT_RA_RB , "Add Extended"), - INSTRUCTION(mtcrf, 0x7C000120, XFX, General , 0 , NULL), - INSTRUCTION(mtmsr, 0x7C000124, X , General , mtmsr , "Move To Machine State Register"), - INSTRUCTION(stdx, 0x7C00012A, X , General , X_RT_RA0_RB , "Store Doubleword Indexed"), - INSTRUCTION(stwcx, 0x7C00012D, X , General , X_RT_RA0_RB , "Store Word Conditional Indexed"), - INSTRUCTION(stwx, 0x7C00012E, X , General , X_RT_RA0_RB , "Store Word Indexed"), - INSTRUCTION(stvehx, 0x7C00014E, X , General , 0 , "Store Vector Element Half Word Indexed"), - INSTRUCTION(mtmsrd, 0x7C000164, X , General , mtmsr , "Move To Machine State Register Doubleword"), - INSTRUCTION(stdux, 0x7C00016A, X , General , X_RT_RA_RB , "Store Doubleword with Update Indexed"), - INSTRUCTION(stwux, 0x7C00016E, X , General , X_RT_RA_RB , "Store Word with Update Indexed"), - INSTRUCTION(stvewx, 0x7C00018E, X , General , 0 , "Store Vector Element Word Indexed"), - INSTRUCTION(subfzex, 0x7C000190, XO , General , XO_RT_RA , "Subtract From Zero Extended"), - INSTRUCTION(addzex, 0x7C000194, XO , General , XO_RT_RA , "Add to Zero Extended"), - INSTRUCTION(stdcx, 0x7C0001AD, X , General , X_RT_RA0_RB , "Store Doubleword Conditional Indexed"), - INSTRUCTION(stbx, 0x7C0001AE, X , General , X_RT_RA0_RB , "Store Byte Indexed"), - INSTRUCTION(stvx, 0x7C0001CE, X , General , 0 , "Store Vector Indexed"), - INSTRUCTION(subfmex, 0x7C0001D0, XO , General , XO_RT_RA , "Subtract From Minus One Extended"), - INSTRUCTION(mulldx, 0x7C0001D2, XO , General , XO_RT_RA_RB , "Multiply Low Doubleword"), - INSTRUCTION(addmex, 0x7C0001D4, XO , General , XO_RT_RA , "Add to Minus One Extended"), - INSTRUCTION(mullwx, 0x7C0001D6, XO , General , XO_RT_RA_RB , "Multiply Low Word"), - INSTRUCTION(dcbtst, 0x7C0001EC, X , General , 0 , "Data Cache Block Touch for Store"), - INSTRUCTION(stbux, 0x7C0001EE, X , General , X_RT_RA_RB , "Store Byte with Update Indexed"), - INSTRUCTION(addx, 0x7C000214, XO , General , XO_RT_RA_RB , "Add"), - INSTRUCTION(dcbt, 0x7C00022C, X , General , 0 , "Data Cache Block Touch"), - INSTRUCTION(lhzx, 0x7C00022E, X , General , X_RT_RA0_RB , "Load Halfword and Zero Indexed"), - INSTRUCTION(eqvx, 0x7C000238, X , General , X_RA_RT_RB , "Equivalent"), - INSTRUCTION(eciwx, 0x7C00026C, X , General , 0 , NULL), - INSTRUCTION(lhzux, 0x7C00026E, X , General , X_RT_RA_RB , "Load Halfword and Zero with Update Indexed"), - INSTRUCTION(xorx, 0x7C000278, X , General , X_RA_RT_RB , "XOR"), - INSTRUCTION(mfspr, 0x7C0002A6, XFX, General , mfspr , "Move From Special Purpose Register"), - INSTRUCTION(lwax, 0x7C0002AA, X , General , X_RT_RA0_RB , "Load Word Algebraic Indexed"), - INSTRUCTION(lhax, 0x7C0002AE, X , General , X_RT_RA0_RB , "Load Halfword Algebraic Indexed"), - INSTRUCTION(lvxl, 0x7C0002CE, X , General , X_VX_RA0_RB , "Load Vector Indexed LRU"), - INSTRUCTION(mftb, 0x7C0002E6, XFX, General , mftb , "Move From Time Base"), - INSTRUCTION(lwaux, 0x7C0002EA, X , General , X_RT_RA_RB , "Load Word Algebraic with Update Indexed"), - INSTRUCTION(lhaux, 0x7C0002EE, X , General , 0 , NULL), - INSTRUCTION(sthx, 0x7C00032E, X , General , X_RT_RA0_RB , "Store Halfword Indexed"), - INSTRUCTION(orcx, 0x7C000338, X , General , X_RA_RT_RB , "OR with Complement"), - INSTRUCTION(ecowx, 0x7C00036C, X , General , 0 , NULL), - INSTRUCTION(sthux, 0x7C00036E, X , General , X_RT_RA_RB , "Store Halfword with Update Indexed"), - INSTRUCTION(orx, 0x7C000378, X , General , X_RA_RT_RB , "OR"), - INSTRUCTION(divdux, 0x7C000392, XO , General , XO_RT_RA_RB , "Divide Doubleword Unsigned"), - INSTRUCTION(divwux, 0x7C000396, XO , General , XO_RT_RA_RB , "Divide Word Unsigned"), - INSTRUCTION(mtspr, 0x7C0003A6, XFX, General , mtspr , "Move To Special Purpose Register"), - INSTRUCTION(nandx, 0x7C0003B8, X , General , X_RA_RT_RB , "NAND"), - INSTRUCTION(stvxl, 0x7C0003CE, X , General , 0 , "Store Vector Indexed LRU"), - INSTRUCTION(divdx, 0x7C0003D2, XO , General , XO_RT_RA_RB , "Divide Doubleword"), - INSTRUCTION(divwx, 0x7C0003D6, XO , General , XO_RT_RA_RB , "Divide Word"), - INSTRUCTION(lvlx, 0x7C00040E, X , General , 0 , "Load Vector Indexed"), - INSTRUCTION(ldbrx, 0x7C000428, X , General , X_RT_RA0_RB , "Load Doubleword Byte-Reverse Indexed"), - INSTRUCTION(lswx, 0x7C00042A, X , General , 0 , NULL), - INSTRUCTION(lwbrx, 0x7C00042C, X , General , X_RT_RA0_RB , "Load Word Byte-Reverse Indexed"), - INSTRUCTION(lfsx, 0x7C00042E, X , General , X_FRT_RA0_RB , "Load Floating-Point Single Indexed"), - INSTRUCTION(srwx, 0x7C000430, X , General , X_RA_RT_RB , "Shift Right Word"), - INSTRUCTION(srdx, 0x7C000436, X , General , X_RA_RT_RB , "Shift Right Doubleword"), - INSTRUCTION(lfsux, 0x7C00046E, X , General , X_FRT_RA_RB , "Load Floating-Point Single with Update Indexed"), - INSTRUCTION(lswi, 0x7C0004AA, X , General , 0 , NULL), - INSTRUCTION(sync, 0x7C0004AC, X , General , sync , "Synchronize"), - INSTRUCTION(lfdx, 0x7C0004AE, X , General , X_FRT_RA0_RB , "Load Floating-Point Double Indexed"), - INSTRUCTION(lfdux, 0x7C0004EE, X , General , X_FRT_RA_RB , "Load Floating-Point Double with Update Indexed"), - INSTRUCTION(stdbrx, 0x7C000528, X , General , X_RT_RA0_RB , "Store Doubleword Byte-Reverse Indexed"), - INSTRUCTION(stswx, 0x7C00052A, X , General , 0 , NULL), - INSTRUCTION(stwbrx, 0x7C00052C, X , General , X_RT_RA0_RB , "Store Word Byte-Reverse Indexed"), - INSTRUCTION(stfsx, 0x7C00052E, X , General , X_FRT_RA0_RB , "Store Floating-Point Single Indexed"), - INSTRUCTION(stfsux, 0x7C00056E, X , General , X_FRT_RA_RB , "Store Floating-Point Single with Update Indexed"), - INSTRUCTION(stswi, 0x7C0005AA, X , General , 0 , NULL), - INSTRUCTION(stfdx, 0x7C0005AE, X , General , X_FRT_RA0_RB , "Store Floating-Point Double Indexed"), - INSTRUCTION(stfdux, 0x7C0005EE, X , General , X_FRT_RA_RB , "Store Floating-Point Double with Update Indexed"), - INSTRUCTION(lhbrx, 0x7C00062C, X , General , X_RT_RA0_RB , "Load Halfword Byte-Reverse Indexed"), - INSTRUCTION(srawx, 0x7C000630, X , General , X_RA_RT_RB , "Shift Right Algebraic Word"), - INSTRUCTION(sradx, 0x7C000634, X , General , X_RA_RT_RB , "Shift Right Algebraic Doubleword"), - INSTRUCTION(srawix, 0x7C000670, X , General , srawix , "Shift Right Algebraic Word Immediate"), - INSTRUCTION(sradix, 0x7C000674, XS , General , sradix , "Shift Right Algebraic Doubleword Immediate"), // TODO - INSTRUCTION(eieio, 0x7C0006AC, X , General , _ , "Enforce In-Order Execution of I/O Instruction"), - INSTRUCTION(sthbrx, 0x7C00072C, X , General , X_RT_RA0_RB , "Store Halfword Byte-Reverse Indexed"), - INSTRUCTION(extshx, 0x7C000734, X , General , X_RA_RT , "Extend Sign Halfword"), - INSTRUCTION(extsbx, 0x7C000774, X , General , X_RA_RT , "Extend Sign Byte"), - INSTRUCTION(icbi, 0x7C0007AC, X , General , 0 , NULL), - INSTRUCTION(stfiwx, 0x7C0007AE, X , General , X_FRT_RA0_RB , "Store Floating-Point as Integer Word Indexed"), - INSTRUCTION(extswx, 0x7C0007B4, X , General , X_RA_RT , "Extend Sign Word"), - INSTRUCTION(dcbz, 0x7C0007EC, X , General , dcbz , "Data Cache Block set to Zero"), // 0x7C2007EC = DCBZ128 - INSTRUCTION(dst, 0x7C0002AC, XDSS, General , 0 , NULL), - INSTRUCTION(dstst, 0x7C0002EC, XDSS, General , 0 , NULL), - INSTRUCTION(dss, 0x7C00066C, XDSS, General , 0 , NULL), - INSTRUCTION(lvebx, 0x7C00000E, X , General , 0 , "Load Vector Element Byte Indexed"), - INSTRUCTION(lvehx, 0x7C00004E, X , General , 0 , "Load Vector Element Half Word Indexed"), - INSTRUCTION(lvewx, 0x7C00008E, X , General , 0 , "Load Vector Element Word Indexed"), - INSTRUCTION(lvsl, 0x7C00000C, X , General , 0 , "Load Vector for Shift Left"), - INSTRUCTION(lvsr, 0x7C00004C, X , General , 0 , "Load Vector for Shift Right"), - INSTRUCTION(lvx, 0x7C0000CE, X , General , 0 , "Load Vector Indexed"), - INSTRUCTION(lvxl, 0x7C0002CE, X , General , 0 , "Load Vector Indexed LRU"), - INSTRUCTION(stvebx, 0x7C00010E, X , General , 0 , "Store Vector Element Byte Indexed"), - INSTRUCTION(stvehx, 0x7C00014E, X , General , 0 , "Store Vector Element Half Word Indexed"), - INSTRUCTION(stvewx, 0x7C00018E, X , General , 0 , "Store Vector Element Word Indexed"), - INSTRUCTION(stvx, 0x7C0001CE, X , General , X_VX_RA0_RB , "Store Vector Indexed"), - INSTRUCTION(stvxl, 0x7C0003CE, X , General , X_VX_RA0_RB , "Store Vector Indexed LRU"), - INSTRUCTION(lvlx, 0x7C00040E, X , General , X_VX_RA0_RB , "Load Vector Left Indexed"), - INSTRUCTION(lvlxl, 0x7C00060E, X , General , X_VX_RA0_RB , "Load Vector Left Indexed LRU"), - INSTRUCTION(lvrx, 0x7C00044E, X , General , X_VX_RA0_RB , "Load Vector Right Indexed"), - INSTRUCTION(lvrxl, 0x7C00064E, X , General , X_VX_RA0_RB , "Load Vector Right Indexed LRU"), - INSTRUCTION(stvlx, 0x7C00050E, X , General , X_VX_RA0_RB , "Store Vector Left Indexed"), - INSTRUCTION(stvlxl, 0x7C00070E, X , General , X_VX_RA0_RB , "Store Vector Left Indexed LRU"), - INSTRUCTION(stvrx, 0x7C00054E, X , General , X_VX_RA0_RB , "Store Vector Right Indexed"), - INSTRUCTION(stvrxl, 0x7C00074E, X , General , X_VX_RA0_RB , "Store Vector Right Indexed LRU"), + INSTRUCTION(cmp, 0x7C000000, X, General, cmp, "Compare"), + INSTRUCTION(tw, 0x7C000008, X, General, X_RA_RB, "Trap Word"), + INSTRUCTION(lvsl, 0x7C00000C, X, General, X_VX_RA0_RB, + "Load Vector for Shift Left"), + INSTRUCTION(lvebx, 0x7C00000E, X, General, 0, + "Load Vector Element Byte Indexed"), + INSTRUCTION(subfcx, 0x7C000010, XO, General, XO_RT_RA_RB, + "Subtract From Carrying"), + INSTRUCTION(mulhdux, 0x7C000012, XO, General, XO_RT_RA_RB, + "Multiply High Doubleword Unsigned"), + INSTRUCTION(addcx, 0x7C000014, XO, General, XO_RT_RA_RB, "Add Carrying"), + INSTRUCTION(mulhwux, 0x7C000016, XO, General, XO_RT_RA_RB, + "Multiply High Word Unsigned"), + INSTRUCTION(mfcr, 0x7C000026, X, General, mfcr, + "Move From Condition Register"), + INSTRUCTION(lwarx, 0x7C000028, X, General, X_RT_RA0_RB, + "Load Word And Reserve Indexed"), + INSTRUCTION(ldx, 0x7C00002A, X, General, X_RT_RA0_RB, + "Load Doubleword Indexed"), + INSTRUCTION(lwzx, 0x7C00002E, X, General, X_RT_RA0_RB, + "Load Word and Zero Indexed"), + INSTRUCTION(slwx, 0x7C000030, X, General, X_RA_RT_RB, "Shift Left Word"), + INSTRUCTION(cntlzwx, 0x7C000034, X, General, X_RA_RT, + "Count Leading Zeros Word"), + INSTRUCTION(sldx, 0x7C000036, X, General, X_RA_RT_RB, + "Shift Left Doubleword"), + INSTRUCTION(andx, 0x7C000038, X, General, X_RA_RT_RB, "AND"), + INSTRUCTION(cmpl, 0x7C000040, X, General, cmp, "Compare Logical"), + INSTRUCTION(lvsr, 0x7C00004C, X, General, X_VX_RA0_RB, + "Load Vector for Shift Right"), + INSTRUCTION(lvehx, 0x7C00004E, X, General, 0, + "Load Vector Element Half Word Indexed"), + INSTRUCTION(subfx, 0x7C000050, XO, General, XO_RT_RA_RB, "Subtract From"), + INSTRUCTION(ldux, 0x7C00006A, X, General, X_RT_RA_RB, + "Load Doubleword with Update Indexed"), + INSTRUCTION(dcbst, 0x7C00006C, X, General, 0, NULL), + INSTRUCTION(lwzux, 0x7C00006E, X, General, X_RT_RA_RB, + "Load Word and Zero with Update Indexed"), + INSTRUCTION(cntlzdx, 0x7C000074, X, General, X_RA_RT, + "Count Leading Zeros Doubleword"), + INSTRUCTION(andcx, 0x7C000078, X, General, X_RA_RT_RB, + "AND with Complement"), + INSTRUCTION(td, 0x7C000088, X, General, X_RA_RB, "Trap Doubleword"), + INSTRUCTION(lvewx, 0x7C00008E, X, General, 0, + "Load Vector Element Word Indexed"), + INSTRUCTION(mulhdx, 0x7C000092, XO, General, XO_RT_RA_RB, + "Multiply High Doubleword"), + INSTRUCTION(mulhwx, 0x7C000096, XO, General, XO_RT_RA_RB, + "Multiply High Word"), + INSTRUCTION(mfmsr, 0x7C0000A6, X, General, mfmsr, + "Move From Machine State Register"), + INSTRUCTION(ldarx, 0x7C0000A8, X, General, X_RT_RA0_RB, + "Load Doubleword And Reserve Indexed"), + INSTRUCTION(dcbf, 0x7C0000AC, X, General, dcbf, "Data Cache Block Flush"), + INSTRUCTION(lbzx, 0x7C0000AE, X, General, X_RT_RA0_RB, + "Load Byte and Zero Indexed"), + INSTRUCTION(lvx, 0x7C0000CE, X, General, X_VX_RA0_RB, + "Load Vector Indexed"), + INSTRUCTION(negx, 0x7C0000D0, XO, General, XO_RT_RA, "Negate"), + INSTRUCTION(lbzux, 0x7C0000EE, X, General, X_RT_RA_RB, + "Load Byte and Zero with Update Indexed"), + INSTRUCTION(norx, 0x7C0000F8, X, General, X_RA_RT_RB, "NOR"), + INSTRUCTION(stvebx, 0x7C00010E, X, General, 0, + "Store Vector Element Byte Indexed"), + INSTRUCTION(subfex, 0x7C000110, XO, General, XO_RT_RA_RB, + "Subtract From Extended"), + INSTRUCTION(addex, 0x7C000114, XO, General, XO_RT_RA_RB, "Add Extended"), + INSTRUCTION(mtcrf, 0x7C000120, XFX, General, 0, NULL), + INSTRUCTION(mtmsr, 0x7C000124, X, General, mtmsr, + "Move To Machine State Register"), + INSTRUCTION(stdx, 0x7C00012A, X, General, X_RT_RA0_RB, + "Store Doubleword Indexed"), + INSTRUCTION(stwcx, 0x7C00012D, X, General, X_RT_RA0_RB, + "Store Word Conditional Indexed"), + INSTRUCTION(stwx, 0x7C00012E, X, General, X_RT_RA0_RB, + "Store Word Indexed"), + INSTRUCTION(stvehx, 0x7C00014E, X, General, 0, + "Store Vector Element Half Word Indexed"), + INSTRUCTION(mtmsrd, 0x7C000164, X, General, mtmsr, + "Move To Machine State Register Doubleword"), + INSTRUCTION(stdux, 0x7C00016A, X, General, X_RT_RA_RB, + "Store Doubleword with Update Indexed"), + INSTRUCTION(stwux, 0x7C00016E, X, General, X_RT_RA_RB, + "Store Word with Update Indexed"), + INSTRUCTION(stvewx, 0x7C00018E, X, General, 0, + "Store Vector Element Word Indexed"), + INSTRUCTION(subfzex, 0x7C000190, XO, General, XO_RT_RA, + "Subtract From Zero Extended"), + INSTRUCTION(addzex, 0x7C000194, XO, General, XO_RT_RA, + "Add to Zero Extended"), + INSTRUCTION(stdcx, 0x7C0001AD, X, General, X_RT_RA0_RB, + "Store Doubleword Conditional Indexed"), + INSTRUCTION(stbx, 0x7C0001AE, X, General, X_RT_RA0_RB, + "Store Byte Indexed"), + INSTRUCTION(stvx, 0x7C0001CE, X, General, 0, "Store Vector Indexed"), + INSTRUCTION(subfmex, 0x7C0001D0, XO, General, XO_RT_RA, + "Subtract From Minus One Extended"), + INSTRUCTION(mulldx, 0x7C0001D2, XO, General, XO_RT_RA_RB, + "Multiply Low Doubleword"), + INSTRUCTION(addmex, 0x7C0001D4, XO, General, XO_RT_RA, + "Add to Minus One Extended"), + INSTRUCTION(mullwx, 0x7C0001D6, XO, General, XO_RT_RA_RB, + "Multiply Low Word"), + INSTRUCTION(dcbtst, 0x7C0001EC, X, General, 0, + "Data Cache Block Touch for Store"), + INSTRUCTION(stbux, 0x7C0001EE, X, General, X_RT_RA_RB, + "Store Byte with Update Indexed"), + INSTRUCTION(addx, 0x7C000214, XO, General, XO_RT_RA_RB, "Add"), + INSTRUCTION(dcbt, 0x7C00022C, X, General, 0, "Data Cache Block Touch"), + INSTRUCTION(lhzx, 0x7C00022E, X, General, X_RT_RA0_RB, + "Load Halfword and Zero Indexed"), + INSTRUCTION(eqvx, 0x7C000238, X, General, X_RA_RT_RB, "Equivalent"), + INSTRUCTION(eciwx, 0x7C00026C, X, General, 0, NULL), + INSTRUCTION(lhzux, 0x7C00026E, X, General, X_RT_RA_RB, + "Load Halfword and Zero with Update Indexed"), + INSTRUCTION(xorx, 0x7C000278, X, General, X_RA_RT_RB, "XOR"), + INSTRUCTION(mfspr, 0x7C0002A6, XFX, General, mfspr, + "Move From Special Purpose Register"), + INSTRUCTION(lwax, 0x7C0002AA, X, General, X_RT_RA0_RB, + "Load Word Algebraic Indexed"), + INSTRUCTION(lhax, 0x7C0002AE, X, General, X_RT_RA0_RB, + "Load Halfword Algebraic Indexed"), + INSTRUCTION(lvxl, 0x7C0002CE, X, General, X_VX_RA0_RB, + "Load Vector Indexed LRU"), + INSTRUCTION(mftb, 0x7C0002E6, XFX, General, mftb, "Move From Time Base"), + INSTRUCTION(lwaux, 0x7C0002EA, X, General, X_RT_RA_RB, + "Load Word Algebraic with Update Indexed"), + INSTRUCTION(lhaux, 0x7C0002EE, X, General, 0, NULL), + INSTRUCTION(sthx, 0x7C00032E, X, General, X_RT_RA0_RB, + "Store Halfword Indexed"), + INSTRUCTION(orcx, 0x7C000338, X, General, X_RA_RT_RB, "OR with Complement"), + INSTRUCTION(ecowx, 0x7C00036C, X, General, 0, NULL), + INSTRUCTION(sthux, 0x7C00036E, X, General, X_RT_RA_RB, + "Store Halfword with Update Indexed"), + INSTRUCTION(orx, 0x7C000378, X, General, X_RA_RT_RB, "OR"), + INSTRUCTION(divdux, 0x7C000392, XO, General, XO_RT_RA_RB, + "Divide Doubleword Unsigned"), + INSTRUCTION(divwux, 0x7C000396, XO, General, XO_RT_RA_RB, + "Divide Word Unsigned"), + INSTRUCTION(mtspr, 0x7C0003A6, XFX, General, mtspr, + "Move To Special Purpose Register"), + INSTRUCTION(nandx, 0x7C0003B8, X, General, X_RA_RT_RB, "NAND"), + INSTRUCTION(stvxl, 0x7C0003CE, X, General, 0, "Store Vector Indexed LRU"), + INSTRUCTION(divdx, 0x7C0003D2, XO, General, XO_RT_RA_RB, + "Divide Doubleword"), + INSTRUCTION(divwx, 0x7C0003D6, XO, General, XO_RT_RA_RB, "Divide Word"), + INSTRUCTION(lvlx, 0x7C00040E, X, General, 0, "Load Vector Indexed"), + INSTRUCTION(ldbrx, 0x7C000428, X, General, X_RT_RA0_RB, + "Load Doubleword Byte-Reverse Indexed"), + INSTRUCTION(lswx, 0x7C00042A, X, General, 0, NULL), + INSTRUCTION(lwbrx, 0x7C00042C, X, General, X_RT_RA0_RB, + "Load Word Byte-Reverse Indexed"), + INSTRUCTION(lfsx, 0x7C00042E, X, General, X_FRT_RA0_RB, + "Load Floating-Point Single Indexed"), + INSTRUCTION(srwx, 0x7C000430, X, General, X_RA_RT_RB, "Shift Right Word"), + INSTRUCTION(srdx, 0x7C000436, X, General, X_RA_RT_RB, + "Shift Right Doubleword"), + INSTRUCTION(lfsux, 0x7C00046E, X, General, X_FRT_RA_RB, + "Load Floating-Point Single with Update Indexed"), + INSTRUCTION(lswi, 0x7C0004AA, X, General, 0, NULL), + INSTRUCTION(sync, 0x7C0004AC, X, General, sync, "Synchronize"), + INSTRUCTION(lfdx, 0x7C0004AE, X, General, X_FRT_RA0_RB, + "Load Floating-Point Double Indexed"), + INSTRUCTION(lfdux, 0x7C0004EE, X, General, X_FRT_RA_RB, + "Load Floating-Point Double with Update Indexed"), + INSTRUCTION(stdbrx, 0x7C000528, X, General, X_RT_RA0_RB, + "Store Doubleword Byte-Reverse Indexed"), + INSTRUCTION(stswx, 0x7C00052A, X, General, 0, NULL), + INSTRUCTION(stwbrx, 0x7C00052C, X, General, X_RT_RA0_RB, + "Store Word Byte-Reverse Indexed"), + INSTRUCTION(stfsx, 0x7C00052E, X, General, X_FRT_RA0_RB, + "Store Floating-Point Single Indexed"), + INSTRUCTION(stfsux, 0x7C00056E, X, General, X_FRT_RA_RB, + "Store Floating-Point Single with Update Indexed"), + INSTRUCTION(stswi, 0x7C0005AA, X, General, 0, NULL), + INSTRUCTION(stfdx, 0x7C0005AE, X, General, X_FRT_RA0_RB, + "Store Floating-Point Double Indexed"), + INSTRUCTION(stfdux, 0x7C0005EE, X, General, X_FRT_RA_RB, + "Store Floating-Point Double with Update Indexed"), + INSTRUCTION(lhbrx, 0x7C00062C, X, General, X_RT_RA0_RB, + "Load Halfword Byte-Reverse Indexed"), + INSTRUCTION(srawx, 0x7C000630, X, General, X_RA_RT_RB, + "Shift Right Algebraic Word"), + INSTRUCTION(sradx, 0x7C000634, X, General, X_RA_RT_RB, + "Shift Right Algebraic Doubleword"), + INSTRUCTION(srawix, 0x7C000670, X, General, srawix, + "Shift Right Algebraic Word Immediate"), + INSTRUCTION(sradix, 0x7C000674, XS, General, sradix, + "Shift Right Algebraic Doubleword Immediate"), // TODO + INSTRUCTION(eieio, 0x7C0006AC, X, General, _, + "Enforce In-Order Execution of I/O Instruction"), + INSTRUCTION(sthbrx, 0x7C00072C, X, General, X_RT_RA0_RB, + "Store Halfword Byte-Reverse Indexed"), + INSTRUCTION(extshx, 0x7C000734, X, General, X_RA_RT, + "Extend Sign Halfword"), + INSTRUCTION(extsbx, 0x7C000774, X, General, X_RA_RT, "Extend Sign Byte"), + INSTRUCTION(icbi, 0x7C0007AC, X, General, 0, NULL), + INSTRUCTION(stfiwx, 0x7C0007AE, X, General, X_FRT_RA0_RB, + "Store Floating-Point as Integer Word Indexed"), + INSTRUCTION(extswx, 0x7C0007B4, X, General, X_RA_RT, "Extend Sign Word"), + INSTRUCTION(dcbz, 0x7C0007EC, X, General, dcbz, + "Data Cache Block set to Zero"), // 0x7C2007EC = DCBZ128 + INSTRUCTION(dst, 0x7C0002AC, XDSS, General, 0, NULL), + INSTRUCTION(dstst, 0x7C0002EC, XDSS, General, 0, NULL), + INSTRUCTION(dss, 0x7C00066C, XDSS, General, 0, NULL), + INSTRUCTION(lvebx, 0x7C00000E, X, General, 0, + "Load Vector Element Byte Indexed"), + INSTRUCTION(lvehx, 0x7C00004E, X, General, 0, + "Load Vector Element Half Word Indexed"), + INSTRUCTION(lvewx, 0x7C00008E, X, General, 0, + "Load Vector Element Word Indexed"), + INSTRUCTION(lvsl, 0x7C00000C, X, General, 0, "Load Vector for Shift Left"), + INSTRUCTION(lvsr, 0x7C00004C, X, General, 0, "Load Vector for Shift Right"), + INSTRUCTION(lvx, 0x7C0000CE, X, General, 0, "Load Vector Indexed"), + INSTRUCTION(lvxl, 0x7C0002CE, X, General, 0, "Load Vector Indexed LRU"), + INSTRUCTION(stvebx, 0x7C00010E, X, General, 0, + "Store Vector Element Byte Indexed"), + INSTRUCTION(stvehx, 0x7C00014E, X, General, 0, + "Store Vector Element Half Word Indexed"), + INSTRUCTION(stvewx, 0x7C00018E, X, General, 0, + "Store Vector Element Word Indexed"), + INSTRUCTION(stvx, 0x7C0001CE, X, General, X_VX_RA0_RB, + "Store Vector Indexed"), + INSTRUCTION(stvxl, 0x7C0003CE, X, General, X_VX_RA0_RB, + "Store Vector Indexed LRU"), + INSTRUCTION(lvlx, 0x7C00040E, X, General, X_VX_RA0_RB, + "Load Vector Left Indexed"), + INSTRUCTION(lvlxl, 0x7C00060E, X, General, X_VX_RA0_RB, + "Load Vector Left Indexed LRU"), + INSTRUCTION(lvrx, 0x7C00044E, X, General, X_VX_RA0_RB, + "Load Vector Right Indexed"), + INSTRUCTION(lvrxl, 0x7C00064E, X, General, X_VX_RA0_RB, + "Load Vector Right Indexed LRU"), + INSTRUCTION(stvlx, 0x7C00050E, X, General, X_VX_RA0_RB, + "Store Vector Left Indexed"), + INSTRUCTION(stvlxl, 0x7C00070E, X, General, X_VX_RA0_RB, + "Store Vector Left Indexed LRU"), + INSTRUCTION(stvrx, 0x7C00054E, X, General, X_VX_RA0_RB, + "Store Vector Right Indexed"), + INSTRUCTION(stvrxl, 0x7C00074E, X, General, X_VX_RA0_RB, + "Store Vector Right Indexed LRU"), }; static InstrType** instr_table_31 = instr_table_prep( instr_table_31_unprep, XECOUNT(instr_table_31_unprep), 1, 10); // Opcode = 58, index = bits 1-0 (2) static InstrType instr_table_58_unprep[] = { - INSTRUCTION(ld, 0xE8000000, DS , General , DS_RT_RA0_I , "Load Doubleword"), - INSTRUCTION(ldu, 0xE8000001, DS , General , DS_RT_RA_I , "Load Doubleword with Update"), - INSTRUCTION(lwa, 0xE8000002, DS , General , DS_RT_RA0_I , "Load Word Algebraic"), + INSTRUCTION(ld, 0xE8000000, DS, General, DS_RT_RA0_I, "Load Doubleword"), + INSTRUCTION(ldu, 0xE8000001, DS, General, DS_RT_RA_I, + "Load Doubleword with Update"), + INSTRUCTION(lwa, 0xE8000002, DS, General, DS_RT_RA0_I, + "Load Word Algebraic"), }; static InstrType** instr_table_58 = instr_table_prep( instr_table_58_unprep, XECOUNT(instr_table_58_unprep), 0, 1); // Opcode = 59, index = bits 5-1 (5) static InstrType instr_table_59_unprep[] = { - INSTRUCTION(fdivsx, 0xEC000024, A , General , A_FRT_FRA_FRB , "Floating Divide [Single]"), - INSTRUCTION(fsubsx, 0xEC000028, A , General , A_FRT_FRA_FRB , "Floating Subtract [Single]"), - INSTRUCTION(faddsx, 0xEC00002A, A , General , A_FRT_FRA_FRB , "Floating Add [Single]"), - INSTRUCTION(fsqrtsx, 0xEC00002C, A , General , A_FRT_FRB , "Floating Square Root [Single]"), - INSTRUCTION(fresx, 0xEC000030, A , General , A_FRT_FRB , "Floating Reciprocal Estimate [Single]"), - INSTRUCTION(fmulsx, 0xEC000032, A , General , A_FRT_FRA_FRB , "Floating Multiply [Single]"), - INSTRUCTION(fmsubsx, 0xEC000038, A , General , A_FRT_FRA_FRB_FRC , "Floating Multiply-Subtract [Single]"), - INSTRUCTION(fmaddsx, 0xEC00003A, A , General , A_FRT_FRA_FRB_FRC , "Floating Multiply-Add [Single]"), - INSTRUCTION(fnmsubsx, 0xEC00003C, A , General , A_FRT_FRA_FRB_FRC , "Floating Negative Multiply-Subtract [Single]"), - INSTRUCTION(fnmaddsx, 0xEC00003E, A , General , A_FRT_FRA_FRB_FRC , "Floating Negative Multiply-Add [Single]"), + INSTRUCTION(fdivsx, 0xEC000024, A, General, A_FRT_FRA_FRB, + "Floating Divide [Single]"), + INSTRUCTION(fsubsx, 0xEC000028, A, General, A_FRT_FRA_FRB, + "Floating Subtract [Single]"), + INSTRUCTION(faddsx, 0xEC00002A, A, General, A_FRT_FRA_FRB, + "Floating Add [Single]"), + INSTRUCTION(fsqrtsx, 0xEC00002C, A, General, A_FRT_FRB, + "Floating Square Root [Single]"), + INSTRUCTION(fresx, 0xEC000030, A, General, A_FRT_FRB, + "Floating Reciprocal Estimate [Single]"), + INSTRUCTION(fmulsx, 0xEC000032, A, General, A_FRT_FRA_FRB, + "Floating Multiply [Single]"), + INSTRUCTION(fmsubsx, 0xEC000038, A, General, A_FRT_FRA_FRB_FRC, + "Floating Multiply-Subtract [Single]"), + INSTRUCTION(fmaddsx, 0xEC00003A, A, General, A_FRT_FRA_FRB_FRC, + "Floating Multiply-Add [Single]"), + INSTRUCTION(fnmsubsx, 0xEC00003C, A, General, A_FRT_FRA_FRB_FRC, + "Floating Negative Multiply-Subtract [Single]"), + INSTRUCTION(fnmaddsx, 0xEC00003E, A, General, A_FRT_FRA_FRB_FRC, + "Floating Negative Multiply-Add [Single]"), }; static InstrType** instr_table_59 = instr_table_prep( instr_table_59_unprep, XECOUNT(instr_table_59_unprep), 1, 5); // Opcode = 62, index = bits 1-0 (2) static InstrType instr_table_62_unprep[] = { - INSTRUCTION(std, 0xF8000000, DS , General , DS_RT_RA0_I , "Store Doubleword"), - INSTRUCTION(stdu, 0xF8000001, DS , General , DS_RT_RA_I , "Store Doubleword with Update"), + INSTRUCTION(std, 0xF8000000, DS, General, DS_RT_RA0_I, "Store Doubleword"), + INSTRUCTION(stdu, 0xF8000001, DS, General, DS_RT_RA_I, + "Store Doubleword with Update"), }; static InstrType** instr_table_62 = instr_table_prep( instr_table_62_unprep, XECOUNT(instr_table_62_unprep), 0, 1); @@ -483,215 +695,381 @@ static InstrType** instr_table_62 = instr_table_prep( // NOTE: the A format instructions need some special handling because // they only use 6bits to identify their index. static InstrType instr_table_63_unprep[] = { - INSTRUCTION(fcmpu, 0xFC000000, X , General , fcmp , "Floating Compare Unordered"), - INSTRUCTION(frspx, 0xFC000018, X , General , X_FRT_FRB , "Floating Round to Single-Precision"), - INSTRUCTION(fctiwx, 0xFC00001C, X , General , X_FRT_FRB , "Floating Convert To Integer Word"), - INSTRUCTION(fctiwzx, 0xFC00001E, X , General , X_FRT_FRB , "Floating Convert To Integer Word with round toward Zero"), - INSTRUCTION(fdivx, 0xFC000024, A , General , A_FRT_FRA_FRB , "Floating Divide [Single]"), - INSTRUCTION(fsubx, 0xFC000028, A , General , A_FRT_FRA_FRB , "Floating Subtract [Single]"), - INSTRUCTION(faddx, 0xFC00002A, A , General , A_FRT_FRA_FRB , "Floating Add [Single]"), - INSTRUCTION(fsqrtx, 0xFC00002C, A , General , A_FRT_FRB , "Floating Square Root [Single]"), - INSTRUCTION(fselx, 0xFC00002E, A , General , A_FRT_FRA_FRB_FRC , "Floating Select"), - INSTRUCTION(fmulx, 0xFC000032, A , General , A_FRT_FRA_FRB , "Floating Multiply [Single]"), - INSTRUCTION(frsqrtex, 0xFC000034, A , General , A_FRT_FRB , "Floating Reciprocal Square Root Estimate [Single]"), - INSTRUCTION(fmsubx, 0xFC000038, A , General , 0 , "Floating Multiply-Subtract [Single]"), - INSTRUCTION(fmaddx, 0xFC00003A, A , General , A_FRT_FRA_FRB_FRC , "Floating Multiply-Add [Single]"), - INSTRUCTION(fnmsubx, 0xFC00003C, A , General , A_FRT_FRA_FRB_FRC , "Floating Negative Multiply-Subtract [Single]"), - INSTRUCTION(fnmaddx, 0xFC00003E, A , General , A_FRT_FRA_FRB_FRC , "Floating Negative Multiply-Add [Single]"), - INSTRUCTION(fcmpo, 0xFC000040, X , General , fcmp , "Floating Compare Ordered"), - INSTRUCTION(mtfsb1x, 0xFC00004C, X , General , 0 , NULL), - INSTRUCTION(fnegx, 0xFC000050, X , General , X_FRT_FRB , "Floating Negate"), - INSTRUCTION(mcrfs, 0xFC000080, X , General , 0 , NULL), - INSTRUCTION(mtfsb0x, 0xFC00008C, X , General , 0 , NULL), - INSTRUCTION(fmrx, 0xFC000090, X , General , X_FRT_FRB , "Floating Move Register"), - INSTRUCTION(mtfsfix, 0xFC00010C, X , General , 0 , NULL), - INSTRUCTION(fnabsx, 0xFC000110, X , General , X_FRT_FRB , "Floating Negative Absolute Value"), - INSTRUCTION(fabsx, 0xFC000210, X , General , X_FRT_FRB , "Floating Absolute Value"), - INSTRUCTION(mffsx, 0xFC00048E, X , General , 0 , "Move from FPSCR"), - INSTRUCTION(mtfsfx, 0xFC00058E, XFL, General , 0 , "Move to FPSCR Fields"), - INSTRUCTION(fctidx, 0xFC00065C, X , General , X_FRT_FRB , "Floating Convert To Integer Doubleword"), - INSTRUCTION(fctidzx, 0xFC00065E, X , General , X_FRT_FRB , "Floating Convert To Integer Doubleword with round toward Zero"), - INSTRUCTION(fcfidx, 0xFC00069C, X , General , X_FRT_FRB , "Floating Convert From Integer Doubleword"), + INSTRUCTION(fcmpu, 0xFC000000, X, General, fcmp, + "Floating Compare Unordered"), + INSTRUCTION(frspx, 0xFC000018, X, General, X_FRT_FRB, + "Floating Round to Single-Precision"), + INSTRUCTION(fctiwx, 0xFC00001C, X, General, X_FRT_FRB, + "Floating Convert To Integer Word"), + INSTRUCTION(fctiwzx, 0xFC00001E, X, General, X_FRT_FRB, + "Floating Convert To Integer Word with round toward Zero"), + INSTRUCTION(fdivx, 0xFC000024, A, General, A_FRT_FRA_FRB, + "Floating Divide [Single]"), + INSTRUCTION(fsubx, 0xFC000028, A, General, A_FRT_FRA_FRB, + "Floating Subtract [Single]"), + INSTRUCTION(faddx, 0xFC00002A, A, General, A_FRT_FRA_FRB, + "Floating Add [Single]"), + INSTRUCTION(fsqrtx, 0xFC00002C, A, General, A_FRT_FRB, + "Floating Square Root [Single]"), + INSTRUCTION(fselx, 0xFC00002E, A, General, A_FRT_FRA_FRB_FRC, + "Floating Select"), + INSTRUCTION(fmulx, 0xFC000032, A, General, A_FRT_FRA_FRB, + "Floating Multiply [Single]"), + INSTRUCTION(frsqrtex, 0xFC000034, A, General, A_FRT_FRB, + "Floating Reciprocal Square Root Estimate [Single]"), + INSTRUCTION(fmsubx, 0xFC000038, A, General, 0, + "Floating Multiply-Subtract [Single]"), + INSTRUCTION(fmaddx, 0xFC00003A, A, General, A_FRT_FRA_FRB_FRC, + "Floating Multiply-Add [Single]"), + INSTRUCTION(fnmsubx, 0xFC00003C, A, General, A_FRT_FRA_FRB_FRC, + "Floating Negative Multiply-Subtract [Single]"), + INSTRUCTION(fnmaddx, 0xFC00003E, A, General, A_FRT_FRA_FRB_FRC, + "Floating Negative Multiply-Add [Single]"), + INSTRUCTION(fcmpo, 0xFC000040, X, General, fcmp, + "Floating Compare Ordered"), + INSTRUCTION(mtfsb1x, 0xFC00004C, X, General, 0, NULL), + INSTRUCTION(fnegx, 0xFC000050, X, General, X_FRT_FRB, "Floating Negate"), + INSTRUCTION(mcrfs, 0xFC000080, X, General, 0, NULL), + INSTRUCTION(mtfsb0x, 0xFC00008C, X, General, 0, NULL), + INSTRUCTION(fmrx, 0xFC000090, X, General, X_FRT_FRB, + "Floating Move Register"), + INSTRUCTION(mtfsfix, 0xFC00010C, X, General, 0, NULL), + INSTRUCTION(fnabsx, 0xFC000110, X, General, X_FRT_FRB, + "Floating Negative Absolute Value"), + INSTRUCTION(fabsx, 0xFC000210, X, General, X_FRT_FRB, + "Floating Absolute Value"), + INSTRUCTION(mffsx, 0xFC00048E, X, General, 0, "Move from FPSCR"), + INSTRUCTION(mtfsfx, 0xFC00058E, XFL, General, 0, "Move to FPSCR Fields"), + INSTRUCTION(fctidx, 0xFC00065C, X, General, X_FRT_FRB, + "Floating Convert To Integer Doubleword"), + INSTRUCTION( + fctidzx, 0xFC00065E, X, General, X_FRT_FRB, + "Floating Convert To Integer Doubleword with round toward Zero"), + INSTRUCTION(fcfidx, 0xFC00069C, X, General, X_FRT_FRB, + "Floating Convert From Integer Doubleword"), }; static InstrType** instr_table_63 = instr_table_prep_63( instr_table_63_unprep, XECOUNT(instr_table_63_unprep), 1, 10); // Main table, index = bits 31-26 (6) : (code >> 26) static InstrType instr_table_unprep[64] = { - INSTRUCTION(tdi, 0x08000000, D , General , D_RA , "Trap Doubleword Immediate"), - INSTRUCTION(twi, 0x0C000000, D , General , D_RA , "Trap Word Immediate"), - INSTRUCTION(mulli, 0x1C000000, D , General , D_RT_RA_I , "Multiply Low Immediate"), - INSTRUCTION(subficx, 0x20000000, D , General , D_RT_RA_I , "Subtract From Immediate Carrying"), - INSTRUCTION(cmpli, 0x28000000, D , General , cmpli , "Compare Logical Immediate"), - INSTRUCTION(cmpi, 0x2C000000, D , General , cmpi , "Compare Immediate"), - INSTRUCTION(addic, 0x30000000, D , General , D_RT_RA_I , "Add Immediate Carrying"), - INSTRUCTION(addicx, 0x34000000, D , General , D_RT_RA_I , "Add Immediate Carrying and Record"), - INSTRUCTION(addi, 0x38000000, D , General , D_RT_RA0_I , "Add Immediate"), - INSTRUCTION(addis, 0x3C000000, D , General , D_RT_RA0_I , "Add Immediate Shifted"), - INSTRUCTION(bcx, 0x40000000, B , BranchCond , bcx , "Branch Conditional"), - INSTRUCTION(sc, 0x44000002, SC , Syscall , 0 , NULL), - INSTRUCTION(bx, 0x48000000, I , BranchAlways , bx , "Branch"), - INSTRUCTION(rlwimix, 0x50000000, M , General , rlwim , "Rotate Left Word Immediate then Mask Insert"), - INSTRUCTION(rlwinmx, 0x54000000, M , General , rlwim , "Rotate Left Word Immediate then AND with Mask"), - INSTRUCTION(rlwnmx, 0x5C000000, M , General , rlwnmx , "Rotate Left Word then AND with Mask"), - INSTRUCTION(ori, 0x60000000, D , General , D_RA_RT_I , "OR Immediate"), - INSTRUCTION(oris, 0x64000000, D , General , D_RA_RT_I , "OR Immediate Shifted"), - INSTRUCTION(xori, 0x68000000, D , General , D_RA_RT_I , "XOR Immediate"), - INSTRUCTION(xoris, 0x6C000000, D , General , D_RA_RT_I , "XOR Immediate Shifted"), - INSTRUCTION(andix, 0x70000000, D , General , D_RA_RT_I , "AND Immediate"), - INSTRUCTION(andisx, 0x74000000, D , General , D_RA_RT_I , "AND Immediate Shifted"), - INSTRUCTION(lwz, 0x80000000, D , General , D_RT_RA0_I , "Load Word and Zero"), - INSTRUCTION(lwzu, 0x84000000, D , General , D_RT_RA_I , "Load Word and Zero with Udpate"), - INSTRUCTION(lbz, 0x88000000, D , General , D_RT_RA0_I , "Load Byte and Zero"), - INSTRUCTION(lbzu, 0x8C000000, D , General , D_RT_RA_I , "Load Byte and Zero with Update"), - INSTRUCTION(stw, 0x90000000, D , General , D_RT_RA0_I , "Store Word"), - INSTRUCTION(stwu, 0x94000000, D , General , D_RT_RA_I , "Store Word with Update"), - INSTRUCTION(stb, 0x98000000, D , General , D_RT_RA0_I , "Store Byte"), - INSTRUCTION(stbu, 0x9C000000, D , General , D_RT_RA_I , "Store Byte with Update"), - INSTRUCTION(lhz, 0xA0000000, D , General , D_RT_RA0_I , "Load Halfword and Zero"), - INSTRUCTION(lhzu, 0xA4000000, D , General , D_RT_RA_I , "Load Halfword and Zero with Update"), - INSTRUCTION(lha, 0xA8000000, D , General , D_RT_RA0_I , "Load Halfword Algebraic"), - INSTRUCTION(lhau, 0xAC000000, D , General , D_RT_RA_I , NULL), - INSTRUCTION(sth, 0xB0000000, D , General , D_RT_RA0_I , "Store Halfword"), - INSTRUCTION(sthu, 0xB4000000, D , General , D_RT_RA_I , "Store Halfword with Update"), - INSTRUCTION(lmw, 0xB8000000, D , General , 0 , NULL), - INSTRUCTION(stmw, 0xBC000000, D , General , 0 , NULL), - INSTRUCTION(lfs, 0xC0000000, D , General , D_FRT_RA0_I , "Load Floating-Point Single"), - INSTRUCTION(lfsu, 0xC4000000, D , General , D_FRT_RA_I , "Load Floating-Point Single with Update"), - INSTRUCTION(lfd, 0xC8000000, D , General , D_FRT_RA0_I , "Load Floating-Point Double"), - INSTRUCTION(lfdu, 0xCC000000, D , General , D_FRT_RA_I , "Load Floating-Point Double with Update"), - INSTRUCTION(stfs, 0xD0000000, D , General , D_FRT_RA0_I , "Store Floating-Point Single"), - INSTRUCTION(stfsu, 0xD4000000, D , General , D_FRT_RA_I , "Store Floating-Point Single with Update"), - INSTRUCTION(stfd, 0xD8000000, D , General , D_FRT_RA0_I , "Store Floating-Point Double"), - INSTRUCTION(stfdu, 0xDC000000, D , General , D_FRT_RA_I , "Store Floating-Point Double with Update"), + INSTRUCTION(tdi, 0x08000000, D, General, D_RA, "Trap Doubleword Immediate"), + INSTRUCTION(twi, 0x0C000000, D, General, D_RA, "Trap Word Immediate"), + INSTRUCTION(mulli, 0x1C000000, D, General, D_RT_RA_I, + "Multiply Low Immediate"), + INSTRUCTION(subficx, 0x20000000, D, General, D_RT_RA_I, + "Subtract From Immediate Carrying"), + INSTRUCTION(cmpli, 0x28000000, D, General, cmpli, + "Compare Logical Immediate"), + INSTRUCTION(cmpi, 0x2C000000, D, General, cmpi, "Compare Immediate"), + INSTRUCTION(addic, 0x30000000, D, General, D_RT_RA_I, + "Add Immediate Carrying"), + INSTRUCTION(addicx, 0x34000000, D, General, D_RT_RA_I, + "Add Immediate Carrying and Record"), + INSTRUCTION(addi, 0x38000000, D, General, D_RT_RA0_I, "Add Immediate"), + INSTRUCTION(addis, 0x3C000000, D, General, D_RT_RA0_I, + "Add Immediate Shifted"), + INSTRUCTION(bcx, 0x40000000, B, BranchCond, bcx, "Branch Conditional"), + INSTRUCTION(sc, 0x44000002, SC, Syscall, 0, NULL), + INSTRUCTION(bx, 0x48000000, I, BranchAlways, bx, "Branch"), + INSTRUCTION(rlwimix, 0x50000000, M, General, rlwim, + "Rotate Left Word Immediate then Mask Insert"), + INSTRUCTION(rlwinmx, 0x54000000, M, General, rlwim, + "Rotate Left Word Immediate then AND with Mask"), + INSTRUCTION(rlwnmx, 0x5C000000, M, General, rlwnmx, + "Rotate Left Word then AND with Mask"), + INSTRUCTION(ori, 0x60000000, D, General, D_RA_RT_I, "OR Immediate"), + INSTRUCTION(oris, 0x64000000, D, General, D_RA_RT_I, + "OR Immediate Shifted"), + INSTRUCTION(xori, 0x68000000, D, General, D_RA_RT_I, "XOR Immediate"), + INSTRUCTION(xoris, 0x6C000000, D, General, D_RA_RT_I, + "XOR Immediate Shifted"), + INSTRUCTION(andix, 0x70000000, D, General, D_RA_RT_I, "AND Immediate"), + INSTRUCTION(andisx, 0x74000000, D, General, D_RA_RT_I, + "AND Immediate Shifted"), + INSTRUCTION(lwz, 0x80000000, D, General, D_RT_RA0_I, "Load Word and Zero"), + INSTRUCTION(lwzu, 0x84000000, D, General, D_RT_RA_I, + "Load Word and Zero with Udpate"), + INSTRUCTION(lbz, 0x88000000, D, General, D_RT_RA0_I, "Load Byte and Zero"), + INSTRUCTION(lbzu, 0x8C000000, D, General, D_RT_RA_I, + "Load Byte and Zero with Update"), + INSTRUCTION(stw, 0x90000000, D, General, D_RT_RA0_I, "Store Word"), + INSTRUCTION(stwu, 0x94000000, D, General, D_RT_RA_I, + "Store Word with Update"), + INSTRUCTION(stb, 0x98000000, D, General, D_RT_RA0_I, "Store Byte"), + INSTRUCTION(stbu, 0x9C000000, D, General, D_RT_RA_I, + "Store Byte with Update"), + INSTRUCTION(lhz, 0xA0000000, D, General, D_RT_RA0_I, + "Load Halfword and Zero"), + INSTRUCTION(lhzu, 0xA4000000, D, General, D_RT_RA_I, + "Load Halfword and Zero with Update"), + INSTRUCTION(lha, 0xA8000000, D, General, D_RT_RA0_I, + "Load Halfword Algebraic"), + INSTRUCTION(lhau, 0xAC000000, D, General, D_RT_RA_I, NULL), + INSTRUCTION(sth, 0xB0000000, D, General, D_RT_RA0_I, "Store Halfword"), + INSTRUCTION(sthu, 0xB4000000, D, General, D_RT_RA_I, + "Store Halfword with Update"), + INSTRUCTION(lmw, 0xB8000000, D, General, 0, NULL), + INSTRUCTION(stmw, 0xBC000000, D, General, 0, NULL), + INSTRUCTION(lfs, 0xC0000000, D, General, D_FRT_RA0_I, + "Load Floating-Point Single"), + INSTRUCTION(lfsu, 0xC4000000, D, General, D_FRT_RA_I, + "Load Floating-Point Single with Update"), + INSTRUCTION(lfd, 0xC8000000, D, General, D_FRT_RA0_I, + "Load Floating-Point Double"), + INSTRUCTION(lfdu, 0xCC000000, D, General, D_FRT_RA_I, + "Load Floating-Point Double with Update"), + INSTRUCTION(stfs, 0xD0000000, D, General, D_FRT_RA0_I, + "Store Floating-Point Single"), + INSTRUCTION(stfsu, 0xD4000000, D, General, D_FRT_RA_I, + "Store Floating-Point Single with Update"), + INSTRUCTION(stfd, 0xD8000000, D, General, D_FRT_RA0_I, + "Store Floating-Point Double"), + INSTRUCTION(stfdu, 0xDC000000, D, General, D_FRT_RA_I, + "Store Floating-Point Double with Update"), }; -static InstrType** instr_table = instr_table_prep( - instr_table_unprep, XECOUNT(instr_table_unprep), 26, 31); +static InstrType** instr_table = + instr_table_prep(instr_table_unprep, XECOUNT(instr_table_unprep), 26, 31); // Altivec instructions. // TODO(benvanik): build a table like the other instructions. // This table is looked up via linear scan of opcodes. -#define SCAN_INSTRUCTION(name, opcode, format, type, disasm_fn, descr) { \ - opcode, \ - kXEPPCInstrMask##format, \ - kXEPPCInstrFormat##format, \ - kXEPPCInstrType##type, \ - 0, \ - Disasm_##disasm_fn, \ - #name, \ -} -#define OP(x) ((((uint32_t)(x)) & 0x3f) << 26) -#define VX128(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x3d0)) -#define VX128_1(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x7f3)) -#define VX128_2(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x210)) -#define VX128_3(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x7f0)) -#define VX128_4(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x730)) -#define VX128_5(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x10)) -#define VX128_P(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x630)) -#define VX128_R(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x390)) +#define SCAN_INSTRUCTION(name, opcode, format, type, disasm_fn, descr) \ + { \ + opcode, kXEPPCInstrMask##format, kXEPPCInstrFormat##format, \ + kXEPPCInstrType##type, 0, Disasm_##disasm_fn, #name, \ + } +#define OP(x) ((((uint32_t)(x)) & 0x3f) << 26) +#define VX128(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x3d0)) +#define VX128_1(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x7f3)) +#define VX128_2(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x210)) +#define VX128_3(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x7f0)) +#define VX128_4(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x730)) +#define VX128_5(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x10)) +#define VX128_P(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x630)) +#define VX128_R(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x390)) static InstrType instr_table_scan[] = { - SCAN_INSTRUCTION(vcmpbfp, 0x100003C6, VXR , General , 0 , "Vector Compare Bounds Floating Point"), - SCAN_INSTRUCTION(vcmpeqfp, 0x100000C6, VXR , General , 0 , "Vector Compare Equal-to Floating Point"), - SCAN_INSTRUCTION(vcmpequb, 0x10000006, VXR , General , 0 , "Vector Compare Equal-to Unsigned Byte"), - SCAN_INSTRUCTION(vcmpequh, 0x10000046, VXR , General , 0 , "Vector Compare Equal-to Unsigned Half Word"), - SCAN_INSTRUCTION(vcmpequw, 0x10000086, VXR , General , 0 , "Vector Compare Equal-to Unsigned Word"), - SCAN_INSTRUCTION(vcmpgefp, 0x100001C6, VXR , General , 0 , "Vector Compare Greater-Than-or-Equal-to Floating Point"), - SCAN_INSTRUCTION(vcmpgtfp, 0x100002C6, VXR , General , 0 , "Vector Compare Greater-Than Floating Point"), - SCAN_INSTRUCTION(vcmpgtsb, 0x10000306, VXR , General , 0 , "Vector Compare Greater-Than Signed Byte"), - SCAN_INSTRUCTION(vcmpgtsh, 0x10000346, VXR , General , 0 , "Vector Compare Greater-Than Signed Half Word"), - SCAN_INSTRUCTION(vcmpgtsw, 0x10000386, VXR , General , 0 , "Vector Compare Greater-Than Signed Word"), - SCAN_INSTRUCTION(vcmpgtub, 0x10000206, VXR , General , 0 , "Vector Compare Greater-Than Unsigned Byte"), - SCAN_INSTRUCTION(vcmpgtuh, 0x10000246, VXR , General , 0 , "Vector Compare Greater-Than Unsigned Half Word"), - SCAN_INSTRUCTION(vcmpgtuw, 0x10000286, VXR , General , 0 , "Vector Compare Greater-Than Unsigned Word"), - SCAN_INSTRUCTION(vmaddfp, 0x1000002E, VXA , General , VXA_VD_VA_VB_VC , "Vector Multiply-Add Floating Point"), - SCAN_INSTRUCTION(vmhaddshs, 0x10000020, VXA , General , VXA_VD_VA_VB_VC , "Vector Multiply-High and Add Signed Signed Half Word Saturate"), - SCAN_INSTRUCTION(vmhraddshs, 0x10000021, VXA , General , VXA_VD_VA_VB_VC , "Vector Multiply-High Round and Add Signed Signed Half Word Saturate"), - SCAN_INSTRUCTION(vmladduhm, 0x10000022, VXA , General , VXA_VD_VA_VB_VC , "Vector Multiply-Low and Add Unsigned Half Word Modulo"), - SCAN_INSTRUCTION(vmsummbm, 0x10000025, VXA , General , VXA_VD_VA_VB_VC , "Vector Multiply-Sum Mixed-Sign Byte Modulo"), - SCAN_INSTRUCTION(vmsumshm, 0x10000028, VXA , General , VXA_VD_VA_VB_VC , "Vector Multiply-Sum Signed Half Word Modulo"), - SCAN_INSTRUCTION(vmsumshs, 0x10000029, VXA , General , VXA_VD_VA_VB_VC , "Vector Multiply-Sum Signed Half Word Saturate"), - SCAN_INSTRUCTION(vmsumubm, 0x10000024, VXA , General , VXA_VD_VA_VB_VC , "Vector Multiply-Sum Unsigned Byte Modulo"), - SCAN_INSTRUCTION(vmsumuhm, 0x10000026, VXA , General , VXA_VD_VA_VB_VC , "Vector Multiply-Sum Unsigned Half Word Modulo"), - SCAN_INSTRUCTION(vmsumuhs, 0x10000027, VXA , General , VXA_VD_VA_VB_VC , "Vector Multiply-Sum Unsigned Half Word Saturate"), - SCAN_INSTRUCTION(vnmsubfp, 0x1000002F, VXA , General , VXA_VD_VA_VB_VC , "Vector Negative Multiply-Subtract Floating Point"), - SCAN_INSTRUCTION(vperm, 0x1000002B, VXA , General , VXA_VD_VA_VB_VC , "Vector Permute"), - SCAN_INSTRUCTION(vsel, 0x1000002A, VXA , General , VXA_VD_VA_VB_VC , "Vector Conditional Select"), - SCAN_INSTRUCTION(vsldoi, 0x1000002C, VXA , General , VXA_VD_VA_VB_VC , "Vector Shift Left Double by Octet Immediate"), - SCAN_INSTRUCTION(lvsl128, VX128_1(4, 3), VX128_1 , General , VX1281_VD_RA0_RB, "Load Vector128 for Shift Left"), - SCAN_INSTRUCTION(lvsr128, VX128_1(4, 67), VX128_1 , General , VX1281_VD_RA0_RB, "Load Vector128 for Shift Right"), - SCAN_INSTRUCTION(lvewx128, VX128_1(4, 131), VX128_1 , General , VX1281_VD_RA0_RB, "Load Vector128 Element Word Indexed"), - SCAN_INSTRUCTION(lvx128, VX128_1(4, 195), VX128_1 , General , VX1281_VD_RA0_RB, "Load Vector128 Indexed"), - SCAN_INSTRUCTION(stvewx128, VX128_1(4, 387), VX128_1 , General , VX1281_VD_RA0_RB, "Store Vector128 Element Word Indexed"), - SCAN_INSTRUCTION(stvx128, VX128_1(4, 451), VX128_1 , General , VX1281_VD_RA0_RB, "Store Vector128 Indexed"), - SCAN_INSTRUCTION(lvxl128, VX128_1(4, 707), VX128_1 , General , VX1281_VD_RA0_RB, "Load Vector128 Left Indexed"), - SCAN_INSTRUCTION(stvxl128, VX128_1(4, 963), VX128_1 , General , VX1281_VD_RA0_RB, "Store Vector128 Indexed LRU"), - SCAN_INSTRUCTION(lvlx128, VX128_1(4, 1027), VX128_1 , General , VX1281_VD_RA0_RB, "Load Vector128 Left Indexed LRU"), - SCAN_INSTRUCTION(lvrx128, VX128_1(4, 1091), VX128_1 , General , VX1281_VD_RA0_RB, "Load Vector128 Right Indexed"), - SCAN_INSTRUCTION(stvlx128, VX128_1(4, 1283), VX128_1 , General , VX1281_VD_RA0_RB, "Store Vector128 Left Indexed"), - SCAN_INSTRUCTION(stvrx128, VX128_1(4, 1347), VX128_1 , General , VX1281_VD_RA0_RB, "Store Vector128 Right Indexed"), - SCAN_INSTRUCTION(lvlxl128, VX128_1(4, 1539), VX128_1 , General , VX1281_VD_RA0_RB, "Load Vector128 Indexed LRU"), - SCAN_INSTRUCTION(lvrxl128, VX128_1(4, 1603), VX128_1 , General , VX1281_VD_RA0_RB, "Load Vector128 Right Indexed LRU"), - SCAN_INSTRUCTION(stvlxl128, VX128_1(4, 1795), VX128_1 , General , VX1281_VD_RA0_RB, "Store Vector128 Left Indexed LRU"), - SCAN_INSTRUCTION(stvrxl128, VX128_1(4, 1859), VX128_1 , General , VX1281_VD_RA0_RB, "Store Vector128 Right Indexed LRU"), - SCAN_INSTRUCTION(vsldoi128, VX128_5(4, 16), VX128_5 , General , vsldoi128 , "Vector128 Shift Left Double by Octet Immediate"), - SCAN_INSTRUCTION(vperm128, VX128_2(5, 0), VX128_2 , General , VX1282_VD_VA_VB_VC, "Vector128 Permute"), - SCAN_INSTRUCTION(vaddfp128, VX128(5, 16), VX128 , General , VX128_VD_VA_VB , "Vector128 Add Floating Point"), - SCAN_INSTRUCTION(vsubfp128, VX128(5, 80), VX128 , General , VX128_VD_VA_VB , "Vector128 Subtract Floating Point"), - SCAN_INSTRUCTION(vmulfp128, VX128(5, 144), VX128 , General , VX128_VD_VA_VB , "Vector128 Multiply Floating-Point"), - SCAN_INSTRUCTION(vmaddfp128, VX128(5, 208), VX128 , General , VX128_VD_VA_VD_VB, "Vector128 Multiply Add Floating Point"), - SCAN_INSTRUCTION(vmaddcfp128, VX128(5, 272), VX128 , General , VX128_VD_VA_VD_VB, "Vector128 Multiply Add Floating Point"), - SCAN_INSTRUCTION(vnmsubfp128, VX128(5, 336), VX128 , General , VX128_VD_VA_VB , "Vector128 Negative Multiply-Subtract Floating Point"), - SCAN_INSTRUCTION(vmsum3fp128, VX128(5, 400), VX128 , General , VX128_VD_VA_VB , "Vector128 Multiply Sum 3-way Floating Point"), - SCAN_INSTRUCTION(vmsum4fp128, VX128(5, 464), VX128 , General , VX128_VD_VA_VB , "Vector128 Multiply Sum 4-way Floating-Point"), - SCAN_INSTRUCTION(vpkshss128, VX128(5, 512), VX128 , General , 0 , "Vector128 Pack Signed Half Word Signed Saturate"), - SCAN_INSTRUCTION(vand128, VX128(5, 528), VX128 , General , VX128_VD_VA_VB , "Vector128 Logical AND"), - SCAN_INSTRUCTION(vpkshus128, VX128(5, 576), VX128 , General , 0 , "Vector128 Pack Signed Half Word Unsigned Saturate"), - SCAN_INSTRUCTION(vandc128, VX128(5, 592), VX128 , General , VX128_VD_VA_VB , "Vector128 Logical AND with Complement"), - SCAN_INSTRUCTION(vpkswss128, VX128(5, 640), VX128 , General , 0 , "Vector128 Pack Signed Word Signed Saturate"), - SCAN_INSTRUCTION(vnor128, VX128(5, 656), VX128 , General , VX128_VD_VA_VB , "Vector128 Logical NOR"), - SCAN_INSTRUCTION(vpkswus128, VX128(5, 704), VX128 , General , 0 , "Vector128 Pack Signed Word Unsigned Saturate"), - SCAN_INSTRUCTION(vor128, VX128(5, 720), VX128 , General , VX128_VD_VA_VB , "Vector128 Logical OR"), - SCAN_INSTRUCTION(vpkuhum128, VX128(5, 768), VX128 , General , 0 , "Vector128 Pack Unsigned Half Word Unsigned Modulo"), - SCAN_INSTRUCTION(vxor128, VX128(5, 784), VX128 , General , VX128_VD_VA_VB , "Vector128 Logical XOR"), - SCAN_INSTRUCTION(vpkuhus128, VX128(5, 832), VX128 , General , 0 , "Vector128 Pack Unsigned Half Word Unsigned Saturate"), - SCAN_INSTRUCTION(vsel128, VX128(5, 848), VX128 , General , 0 , "Vector128 Conditional Select"), - SCAN_INSTRUCTION(vpkuwum128, VX128(5, 896), VX128 , General , 0 , "Vector128 Pack Unsigned Word Unsigned Modulo"), - SCAN_INSTRUCTION(vslo128, VX128(5, 912), VX128 , General , 0 , "Vector128 Shift Left Octet"), - SCAN_INSTRUCTION(vpkuwus128, VX128(5, 960), VX128 , General , 0 , "Vector128 Pack Unsigned Word Unsigned Saturate"), - SCAN_INSTRUCTION(vsro128, VX128(5, 976), VX128 , General , VX128_VD_VA_VB , "Vector128 Shift Right Octet"), - SCAN_INSTRUCTION(vpermwi128, VX128_P(6, 528), VX128_P , General , vpermwi128 , "Vector128 Permutate Word Immediate"), - SCAN_INSTRUCTION(vcfpsxws128, VX128_3(6, 560), VX128_3 , General , VX1283_VD_VB_I , "Vector128 Convert From Floating-Point to Signed Fixed-Point Word Saturate"), - SCAN_INSTRUCTION(vcfpuxws128, VX128_3(6, 624), VX128_3 , General , 0 , "Vector128 Convert From Floating-Point to Unsigned Fixed-Point Word Saturate"), - SCAN_INSTRUCTION(vcsxwfp128, VX128_3(6, 688), VX128_3 , General , VX1283_VD_VB_I , "Vector128 Convert From Signed Fixed-Point Word to Floating-Point"), - SCAN_INSTRUCTION(vcuxwfp128, VX128_3(6, 752), VX128_3 , General , 0 , "Vector128 Convert From Unsigned Fixed-Point Word to Floating-Point"), - SCAN_INSTRUCTION(vrfim128, VX128_3(6, 816), VX128_3 , General , 0 , "Vector128 Round to Floating-Point Integer toward -Infinity"), - SCAN_INSTRUCTION(vrfin128, VX128_3(6, 880), VX128_3 , General , vrfin128 , "Vector128 Round to Floating-Point Integer Nearest"), - SCAN_INSTRUCTION(vrfip128, VX128_3(6, 944), VX128_3 , General , 0 , "Vector128 Round to Floating-Point Integer toward +Infinity"), - SCAN_INSTRUCTION(vrfiz128, VX128_3(6, 1008), VX128_3 , General , 0 , "Vector128 Round to Floating-Point Integer toward Zero"), - SCAN_INSTRUCTION(vpkd3d128, VX128_4(6, 1552), VX128_4 , General , 0 , "Vector128 Pack D3Dtype, Rotate Left Immediate and Mask Insert"), - SCAN_INSTRUCTION(vrefp128, VX128_3(6, 1584), VX128_3 , General , 0 , "Vector128 Reciprocal Estimate Floating Point"), - SCAN_INSTRUCTION(vrsqrtefp128, VX128_3(6, 1648), VX128_3 , General , VX1283_VD_VB , "Vector128 Reciprocal Square Root Estimate Floating Point"), - SCAN_INSTRUCTION(vexptefp128, VX128_3(6, 1712), VX128_3 , General , 0 , "Vector128 Log2 Estimate Floating Point"), - SCAN_INSTRUCTION(vlogefp128, VX128_3(6, 1776), VX128_3 , General , 0 , "Vector128 Log2 Estimate Floating Point"), - SCAN_INSTRUCTION(vrlimi128, VX128_4(6, 1808), VX128_4 , General , vrlimi128 , "Vector128 Rotate Left Immediate and Mask Insert"), - SCAN_INSTRUCTION(vspltw128, VX128_3(6, 1840), VX128_3 , General , VX1283_VD_VB_I , "Vector128 Splat Word"), - SCAN_INSTRUCTION(vspltisw128, VX128_3(6, 1904), VX128_3 , General , VX1283_VD_VB_I , "Vector128 Splat Immediate Signed Word"), - SCAN_INSTRUCTION(vupkd3d128, VX128_3(6, 2032), VX128_3 , General , VX1283_VD_VB_I , "Vector128 Unpack D3Dtype"), - SCAN_INSTRUCTION(vcmpeqfp128, VX128_R(6, 0), VX128_R , General , VX128_VD_VA_VB , "Vector128 Compare Equal-to Floating Point"), - SCAN_INSTRUCTION(vrlw128, VX128(6, 80), VX128 , General , 0 , "Vector128 Rotate Left Word"), - SCAN_INSTRUCTION(vcmpgefp128, VX128_R(6, 128), VX128_R , General , 0 , "Vector128 Compare Greater-Than-or-Equal-to Floating Point"), - SCAN_INSTRUCTION(vslw128, VX128(6, 208), VX128 , General , VX128_VD_VA_VB , "Vector128 Shift Left Integer Word"), - SCAN_INSTRUCTION(vcmpgtfp128, VX128_R(6, 256), VX128_R , General , 0 , "Vector128 Compare Greater-Than Floating-Point"), - SCAN_INSTRUCTION(vsraw128, VX128(6, 336), VX128 , General , VX128_VD_VA_VB , "Vector128 Shift Right Arithmetic Word"), - SCAN_INSTRUCTION(vcmpbfp128, VX128_R(6, 384), VX128_R , General , 0 , "Vector128 Compare Bounds Floating Point"), - SCAN_INSTRUCTION(vsrw128, VX128(6, 464), VX128 , General , VX128_VD_VA_VB , "Vector128 Shift Right Word"), - SCAN_INSTRUCTION(vcmpequw128, VX128_R(6, 512), VX128_R , General , VX128_VD_VA_VB , "Vector128 Compare Equal-to Unsigned Word"), - SCAN_INSTRUCTION(vmaxfp128, VX128(6, 640), VX128 , General , 0 , "Vector128 Maximum Floating Point"), - SCAN_INSTRUCTION(vminfp128, VX128(6, 704), VX128 , General , 0 , "Vector128 Minimum Floating Point"), - SCAN_INSTRUCTION(vmrghw128, VX128(6, 768), VX128 , General , VX128_VD_VA_VB , "Vector128 Merge High Word"), - SCAN_INSTRUCTION(vmrglw128, VX128(6, 832), VX128 , General , VX128_VD_VA_VB , "Vector128 Merge Low Word"), - SCAN_INSTRUCTION(vupkhsb128, VX128(6, 896), VX128 , General , 0 , "Vector128 Unpack High Signed Byte"), - SCAN_INSTRUCTION(vupklsb128, VX128(6, 960), VX128 , General , 0 , "Vector128 Unpack Low Signed Byte"), + SCAN_INSTRUCTION(vcmpbfp, 0x100003C6, VXR, General, 0, + "Vector Compare Bounds Floating Point"), + SCAN_INSTRUCTION(vcmpeqfp, 0x100000C6, VXR, General, 0, + "Vector Compare Equal-to Floating Point"), + SCAN_INSTRUCTION(vcmpequb, 0x10000006, VXR, General, 0, + "Vector Compare Equal-to Unsigned Byte"), + SCAN_INSTRUCTION(vcmpequh, 0x10000046, VXR, General, 0, + "Vector Compare Equal-to Unsigned Half Word"), + SCAN_INSTRUCTION(vcmpequw, 0x10000086, VXR, General, 0, + "Vector Compare Equal-to Unsigned Word"), + SCAN_INSTRUCTION(vcmpgefp, 0x100001C6, VXR, General, 0, + "Vector Compare Greater-Than-or-Equal-to Floating Point"), + SCAN_INSTRUCTION(vcmpgtfp, 0x100002C6, VXR, General, 0, + "Vector Compare Greater-Than Floating Point"), + SCAN_INSTRUCTION(vcmpgtsb, 0x10000306, VXR, General, 0, + "Vector Compare Greater-Than Signed Byte"), + SCAN_INSTRUCTION(vcmpgtsh, 0x10000346, VXR, General, 0, + "Vector Compare Greater-Than Signed Half Word"), + SCAN_INSTRUCTION(vcmpgtsw, 0x10000386, VXR, General, 0, + "Vector Compare Greater-Than Signed Word"), + SCAN_INSTRUCTION(vcmpgtub, 0x10000206, VXR, General, 0, + "Vector Compare Greater-Than Unsigned Byte"), + SCAN_INSTRUCTION(vcmpgtuh, 0x10000246, VXR, General, 0, + "Vector Compare Greater-Than Unsigned Half Word"), + SCAN_INSTRUCTION(vcmpgtuw, 0x10000286, VXR, General, 0, + "Vector Compare Greater-Than Unsigned Word"), + SCAN_INSTRUCTION(vmaddfp, 0x1000002E, VXA, General, VXA_VD_VA_VB_VC, + "Vector Multiply-Add Floating Point"), + SCAN_INSTRUCTION( + vmhaddshs, 0x10000020, VXA, General, VXA_VD_VA_VB_VC, + "Vector Multiply-High and Add Signed Signed Half Word Saturate"), + SCAN_INSTRUCTION( + vmhraddshs, 0x10000021, VXA, General, VXA_VD_VA_VB_VC, + "Vector Multiply-High Round and Add Signed Signed Half Word Saturate"), + SCAN_INSTRUCTION(vmladduhm, 0x10000022, VXA, General, VXA_VD_VA_VB_VC, + "Vector Multiply-Low and Add Unsigned Half Word Modulo"), + SCAN_INSTRUCTION(vmsummbm, 0x10000025, VXA, General, VXA_VD_VA_VB_VC, + "Vector Multiply-Sum Mixed-Sign Byte Modulo"), + SCAN_INSTRUCTION(vmsumshm, 0x10000028, VXA, General, VXA_VD_VA_VB_VC, + "Vector Multiply-Sum Signed Half Word Modulo"), + SCAN_INSTRUCTION(vmsumshs, 0x10000029, VXA, General, VXA_VD_VA_VB_VC, + "Vector Multiply-Sum Signed Half Word Saturate"), + SCAN_INSTRUCTION(vmsumubm, 0x10000024, VXA, General, VXA_VD_VA_VB_VC, + "Vector Multiply-Sum Unsigned Byte Modulo"), + SCAN_INSTRUCTION(vmsumuhm, 0x10000026, VXA, General, VXA_VD_VA_VB_VC, + "Vector Multiply-Sum Unsigned Half Word Modulo"), + SCAN_INSTRUCTION(vmsumuhs, 0x10000027, VXA, General, VXA_VD_VA_VB_VC, + "Vector Multiply-Sum Unsigned Half Word Saturate"), + SCAN_INSTRUCTION(vnmsubfp, 0x1000002F, VXA, General, VXA_VD_VA_VB_VC, + "Vector Negative Multiply-Subtract Floating Point"), + SCAN_INSTRUCTION(vperm, 0x1000002B, VXA, General, VXA_VD_VA_VB_VC, + "Vector Permute"), + SCAN_INSTRUCTION(vsel, 0x1000002A, VXA, General, VXA_VD_VA_VB_VC, + "Vector Conditional Select"), + SCAN_INSTRUCTION(vsldoi, 0x1000002C, VXA, General, VXA_VD_VA_VB_VC, + "Vector Shift Left Double by Octet Immediate"), + SCAN_INSTRUCTION(lvsl128, VX128_1(4, 3), VX128_1, General, VX1281_VD_RA0_RB, + "Load Vector128 for Shift Left"), + SCAN_INSTRUCTION(lvsr128, VX128_1(4, 67), VX128_1, General, + VX1281_VD_RA0_RB, "Load Vector128 for Shift Right"), + SCAN_INSTRUCTION(lvewx128, VX128_1(4, 131), VX128_1, General, + VX1281_VD_RA0_RB, "Load Vector128 Element Word Indexed"), + SCAN_INSTRUCTION(lvx128, VX128_1(4, 195), VX128_1, General, + VX1281_VD_RA0_RB, "Load Vector128 Indexed"), + SCAN_INSTRUCTION(stvewx128, VX128_1(4, 387), VX128_1, General, + VX1281_VD_RA0_RB, "Store Vector128 Element Word Indexed"), + SCAN_INSTRUCTION(stvx128, VX128_1(4, 451), VX128_1, General, + VX1281_VD_RA0_RB, "Store Vector128 Indexed"), + SCAN_INSTRUCTION(lvxl128, VX128_1(4, 707), VX128_1, General, + VX1281_VD_RA0_RB, "Load Vector128 Left Indexed"), + SCAN_INSTRUCTION(stvxl128, VX128_1(4, 963), VX128_1, General, + VX1281_VD_RA0_RB, "Store Vector128 Indexed LRU"), + SCAN_INSTRUCTION(lvlx128, VX128_1(4, 1027), VX128_1, General, + VX1281_VD_RA0_RB, "Load Vector128 Left Indexed LRU"), + SCAN_INSTRUCTION(lvrx128, VX128_1(4, 1091), VX128_1, General, + VX1281_VD_RA0_RB, "Load Vector128 Right Indexed"), + SCAN_INSTRUCTION(stvlx128, VX128_1(4, 1283), VX128_1, General, + VX1281_VD_RA0_RB, "Store Vector128 Left Indexed"), + SCAN_INSTRUCTION(stvrx128, VX128_1(4, 1347), VX128_1, General, + VX1281_VD_RA0_RB, "Store Vector128 Right Indexed"), + SCAN_INSTRUCTION(lvlxl128, VX128_1(4, 1539), VX128_1, General, + VX1281_VD_RA0_RB, "Load Vector128 Indexed LRU"), + SCAN_INSTRUCTION(lvrxl128, VX128_1(4, 1603), VX128_1, General, + VX1281_VD_RA0_RB, "Load Vector128 Right Indexed LRU"), + SCAN_INSTRUCTION(stvlxl128, VX128_1(4, 1795), VX128_1, General, + VX1281_VD_RA0_RB, "Store Vector128 Left Indexed LRU"), + SCAN_INSTRUCTION(stvrxl128, VX128_1(4, 1859), VX128_1, General, + VX1281_VD_RA0_RB, "Store Vector128 Right Indexed LRU"), + SCAN_INSTRUCTION(vsldoi128, VX128_5(4, 16), VX128_5, General, vsldoi128, + "Vector128 Shift Left Double by Octet Immediate"), + SCAN_INSTRUCTION(vperm128, VX128_2(5, 0), VX128_2, General, + VX1282_VD_VA_VB_VC, "Vector128 Permute"), + SCAN_INSTRUCTION(vaddfp128, VX128(5, 16), VX128, General, VX128_VD_VA_VB, + "Vector128 Add Floating Point"), + SCAN_INSTRUCTION(vsubfp128, VX128(5, 80), VX128, General, VX128_VD_VA_VB, + "Vector128 Subtract Floating Point"), + SCAN_INSTRUCTION(vmulfp128, VX128(5, 144), VX128, General, VX128_VD_VA_VB, + "Vector128 Multiply Floating-Point"), + SCAN_INSTRUCTION(vmaddfp128, VX128(5, 208), VX128, General, + VX128_VD_VA_VD_VB, + "Vector128 Multiply Add Floating Point"), + SCAN_INSTRUCTION(vmaddcfp128, VX128(5, 272), VX128, General, + VX128_VD_VA_VD_VB, + "Vector128 Multiply Add Floating Point"), + SCAN_INSTRUCTION(vnmsubfp128, VX128(5, 336), VX128, General, VX128_VD_VA_VB, + "Vector128 Negative Multiply-Subtract Floating Point"), + SCAN_INSTRUCTION(vmsum3fp128, VX128(5, 400), VX128, General, VX128_VD_VA_VB, + "Vector128 Multiply Sum 3-way Floating Point"), + SCAN_INSTRUCTION(vmsum4fp128, VX128(5, 464), VX128, General, VX128_VD_VA_VB, + "Vector128 Multiply Sum 4-way Floating-Point"), + SCAN_INSTRUCTION(vpkshss128, VX128(5, 512), VX128, General, 0, + "Vector128 Pack Signed Half Word Signed Saturate"), + SCAN_INSTRUCTION(vand128, VX128(5, 528), VX128, General, VX128_VD_VA_VB, + "Vector128 Logical AND"), + SCAN_INSTRUCTION(vpkshus128, VX128(5, 576), VX128, General, 0, + "Vector128 Pack Signed Half Word Unsigned Saturate"), + SCAN_INSTRUCTION(vandc128, VX128(5, 592), VX128, General, VX128_VD_VA_VB, + "Vector128 Logical AND with Complement"), + SCAN_INSTRUCTION(vpkswss128, VX128(5, 640), VX128, General, 0, + "Vector128 Pack Signed Word Signed Saturate"), + SCAN_INSTRUCTION(vnor128, VX128(5, 656), VX128, General, VX128_VD_VA_VB, + "Vector128 Logical NOR"), + SCAN_INSTRUCTION(vpkswus128, VX128(5, 704), VX128, General, 0, + "Vector128 Pack Signed Word Unsigned Saturate"), + SCAN_INSTRUCTION(vor128, VX128(5, 720), VX128, General, VX128_VD_VA_VB, + "Vector128 Logical OR"), + SCAN_INSTRUCTION(vpkuhum128, VX128(5, 768), VX128, General, 0, + "Vector128 Pack Unsigned Half Word Unsigned Modulo"), + SCAN_INSTRUCTION(vxor128, VX128(5, 784), VX128, General, VX128_VD_VA_VB, + "Vector128 Logical XOR"), + SCAN_INSTRUCTION(vpkuhus128, VX128(5, 832), VX128, General, 0, + "Vector128 Pack Unsigned Half Word Unsigned Saturate"), + SCAN_INSTRUCTION(vsel128, VX128(5, 848), VX128, General, 0, + "Vector128 Conditional Select"), + SCAN_INSTRUCTION(vpkuwum128, VX128(5, 896), VX128, General, 0, + "Vector128 Pack Unsigned Word Unsigned Modulo"), + SCAN_INSTRUCTION(vslo128, VX128(5, 912), VX128, General, 0, + "Vector128 Shift Left Octet"), + SCAN_INSTRUCTION(vpkuwus128, VX128(5, 960), VX128, General, 0, + "Vector128 Pack Unsigned Word Unsigned Saturate"), + SCAN_INSTRUCTION(vsro128, VX128(5, 976), VX128, General, VX128_VD_VA_VB, + "Vector128 Shift Right Octet"), + SCAN_INSTRUCTION(vpermwi128, VX128_P(6, 528), VX128_P, General, vpermwi128, + "Vector128 Permutate Word Immediate"), + SCAN_INSTRUCTION(vcfpsxws128, VX128_3(6, 560), VX128_3, General, + VX1283_VD_VB_I, + "Vector128 Convert From Floating-Point to Signed " + "Fixed-Point Word Saturate"), + SCAN_INSTRUCTION(vcfpuxws128, VX128_3(6, 624), VX128_3, General, 0, + "Vector128 Convert From Floating-Point to Unsigned " + "Fixed-Point Word Saturate"), + SCAN_INSTRUCTION( + vcsxwfp128, VX128_3(6, 688), VX128_3, General, VX1283_VD_VB_I, + "Vector128 Convert From Signed Fixed-Point Word to Floating-Point"), + SCAN_INSTRUCTION( + vcuxwfp128, VX128_3(6, 752), VX128_3, General, 0, + "Vector128 Convert From Unsigned Fixed-Point Word to Floating-Point"), + SCAN_INSTRUCTION( + vrfim128, VX128_3(6, 816), VX128_3, General, 0, + "Vector128 Round to Floating-Point Integer toward -Infinity"), + SCAN_INSTRUCTION(vrfin128, VX128_3(6, 880), VX128_3, General, vrfin128, + "Vector128 Round to Floating-Point Integer Nearest"), + SCAN_INSTRUCTION( + vrfip128, VX128_3(6, 944), VX128_3, General, 0, + "Vector128 Round to Floating-Point Integer toward +Infinity"), + SCAN_INSTRUCTION(vrfiz128, VX128_3(6, 1008), VX128_3, General, 0, + "Vector128 Round to Floating-Point Integer toward Zero"), + SCAN_INSTRUCTION( + vpkd3d128, VX128_4(6, 1552), VX128_4, General, 0, + "Vector128 Pack D3Dtype, Rotate Left Immediate and Mask Insert"), + SCAN_INSTRUCTION(vrefp128, VX128_3(6, 1584), VX128_3, General, 0, + "Vector128 Reciprocal Estimate Floating Point"), + SCAN_INSTRUCTION( + vrsqrtefp128, VX128_3(6, 1648), VX128_3, General, VX1283_VD_VB, + "Vector128 Reciprocal Square Root Estimate Floating Point"), + SCAN_INSTRUCTION(vexptefp128, VX128_3(6, 1712), VX128_3, General, 0, + "Vector128 Log2 Estimate Floating Point"), + SCAN_INSTRUCTION(vlogefp128, VX128_3(6, 1776), VX128_3, General, 0, + "Vector128 Log2 Estimate Floating Point"), + SCAN_INSTRUCTION(vrlimi128, VX128_4(6, 1808), VX128_4, General, vrlimi128, + "Vector128 Rotate Left Immediate and Mask Insert"), + SCAN_INSTRUCTION(vspltw128, VX128_3(6, 1840), VX128_3, General, + VX1283_VD_VB_I, "Vector128 Splat Word"), + SCAN_INSTRUCTION(vspltisw128, VX128_3(6, 1904), VX128_3, General, + VX1283_VD_VB_I, "Vector128 Splat Immediate Signed Word"), + SCAN_INSTRUCTION(vupkd3d128, VX128_3(6, 2032), VX128_3, General, + VX1283_VD_VB_I, "Vector128 Unpack D3Dtype"), + SCAN_INSTRUCTION(vcmpeqfp128, VX128_R(6, 0), VX128_R, General, + VX128_VD_VA_VB, + "Vector128 Compare Equal-to Floating Point"), + SCAN_INSTRUCTION(vrlw128, VX128(6, 80), VX128, General, 0, + "Vector128 Rotate Left Word"), + SCAN_INSTRUCTION( + vcmpgefp128, + VX128_R(6, 128), VX128_R, General, 0, + "Vector128 Compare Greater-Than-or-Equal-to Floating Point"), + SCAN_INSTRUCTION(vslw128, VX128(6, 208), VX128, General, VX128_VD_VA_VB, + "Vector128 Shift Left Integer Word"), + SCAN_INSTRUCTION(vcmpgtfp128, VX128_R(6, 256), VX128_R, General, 0, + "Vector128 Compare Greater-Than Floating-Point"), + SCAN_INSTRUCTION(vsraw128, VX128(6, 336), VX128, General, VX128_VD_VA_VB, + "Vector128 Shift Right Arithmetic Word"), + SCAN_INSTRUCTION(vcmpbfp128, VX128_R(6, 384), VX128_R, General, 0, + "Vector128 Compare Bounds Floating Point"), + SCAN_INSTRUCTION(vsrw128, VX128(6, 464), VX128, General, VX128_VD_VA_VB, + "Vector128 Shift Right Word"), + SCAN_INSTRUCTION(vcmpequw128, VX128_R(6, 512), VX128_R, General, + VX128_VD_VA_VB, + "Vector128 Compare Equal-to Unsigned Word"), + SCAN_INSTRUCTION(vmaxfp128, VX128(6, 640), VX128, General, 0, + "Vector128 Maximum Floating Point"), + SCAN_INSTRUCTION(vminfp128, VX128(6, 704), VX128, General, 0, + "Vector128 Minimum Floating Point"), + SCAN_INSTRUCTION(vmrghw128, VX128(6, 768), VX128, General, VX128_VD_VA_VB, + "Vector128 Merge High Word"), + SCAN_INSTRUCTION(vmrglw128, VX128(6, 832), VX128, General, VX128_VD_VA_VB, + "Vector128 Merge Low Word"), + SCAN_INSTRUCTION(vupkhsb128, VX128(6, 896), VX128, General, 0, + "Vector128 Unpack High Signed Byte"), + SCAN_INSTRUCTION(vupklsb128, VX128(6, 960), VX128, General, 0, + "Vector128 Unpack Low Signed Byte"), }; #undef OP #undef VX128 @@ -702,16 +1080,13 @@ static InstrType instr_table_scan[] = { #undef VX128_5 #undef VX128_P - #undef FLAG #undef INSTRUCTION #undef EMPTY - } // namespace tables } // namespace ppc } // namespace frontend } // namespace alloy - #endif // ALLOY_FRONTEND_PPC_PPC_INSTR_TABLES_H_ diff --git a/src/alloy/frontend/ppc/ppc_scanner.cc b/src/alloy/frontend/ppc/ppc_scanner.cc index 9658bd595..ef180dfcf 100644 --- a/src/alloy/frontend/ppc/ppc_scanner.cc +++ b/src/alloy/frontend/ppc/ppc_scanner.cc @@ -16,18 +16,15 @@ #include #include -using namespace alloy; -using namespace alloy::frontend; -using namespace alloy::frontend::ppc; -using namespace alloy::runtime; +namespace alloy { +namespace frontend { +namespace ppc { +using alloy::runtime::FunctionInfo; -PPCScanner::PPCScanner(PPCFrontend* frontend) : - frontend_(frontend) { -} +PPCScanner::PPCScanner(PPCFrontend* frontend) : frontend_(frontend) {} -PPCScanner::~PPCScanner() { -} +PPCScanner::~PPCScanner() {} bool PPCScanner::IsRestGprLr(uint64_t address) { FunctionInfo* symbol_info; @@ -80,9 +77,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { // Check if the function starts with a mfspr lr, as that's a good indication // of whether or not this is a normal function with a prolog/epilog. // Some valid leaf functions won't have this, but most will. - if (address == start_address && - i.type && - i.type->opcode == 0x7C0002A6 && + if (address == start_address && i.type && i.type->opcode == 0x7C0002A6 && (((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F)) == 8) { starts_with_mfspr_lr = true; } @@ -104,8 +99,8 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { // This is generally a return. if (furthest_target > address) { // Remaining targets within function, not end. - XELOGSDB("ignoring blr %.8X (branch to %.8X)", - address, furthest_target); + XELOGSDB("ignoring blr %.8X (branch to %.8X)", address, + furthest_target); } else { // Function end point. XELOGSDB("function end %.8X", address); @@ -131,7 +126,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { // b/ba/bl/bla uint32_t target = (uint32_t)XEEXTS26(i.I.LI << 2) + (i.I.AA ? 0 : (int32_t)address); - + if (i.I.LK) { XELOGSDB("bl %.8X -> %.8X", address, target); // Queue call target if needed. @@ -142,16 +137,15 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { // If the target is back into the function and there's no further target // we are at the end of a function. // (Indirect branches may still go beyond, but no way of knowing). - if (target >= start_address && - target < address && furthest_target <= address) { + if (target >= start_address && target < address && + furthest_target <= address) { XELOGSDB("function end %.8X (back b)", address); ends_fn = true; } // If the target is not a branch and it goes to before the current // address it's definitely a tail call. - if (!ends_fn && - target < start_address && furthest_target <= address) { + if (!ends_fn && target < start_address && furthest_target <= address) { XELOGSDB("function end %.8X (back b before addr)", address); ends_fn = true; } @@ -160,9 +154,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { // Note that sometimes functions stick this in a basic block *inside* // of the function somewhere, so ensure we don't have any branches over // it. - if (!ends_fn && - furthest_target <= address && - IsRestGprLr(target)) { + if (!ends_fn && furthest_target <= address && IsRestGprLr(target)) { XELOGSDB("function end %.8X (__restgprlr_*)", address); ends_fn = true; } @@ -174,9 +166,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { // b KeBugCheck // This check may hit on functions that jump over data code, so only // trigger this check in leaf functions (no mfspr lr/prolog). - if (!ends_fn && - !starts_with_mfspr_lr && - blocks_found == 1) { + if (!ends_fn && !starts_with_mfspr_lr && blocks_found == 1) { XELOGSDB("HEURISTIC: ending at simple leaf thunk %.8X", address); ends_fn = true; } @@ -206,7 +196,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { // TODO(benvanik): perhaps queue up for a speculative check? I think // we are running over tail-call functions here that branch to // somewhere else. - //GetOrInsertFunction(target); + // GetOrInsertFunction(target); } } ends_block = true; @@ -220,7 +210,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { // Queue call target if needed. // TODO(benvanik): see if this is correct - not sure anyone makes // function calls with bcl. - //GetOrInsertFunction(target); + // GetOrInsertFunction(target); } else { XELOGSDB("bc %.8X -> %.8X", address, target); @@ -259,8 +249,8 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { address += 4; if (end_address && address > end_address) { // Hmm.... - XELOGSDB("Ran over function bounds! %.8X-%.8X", - start_address, end_address); + XELOGSDB("Ran over function bounds! %.8X-%.8X", start_address, + end_address); break; } } @@ -270,8 +260,8 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { // from someplace valid (like method hints) this may indicate an error. // It's also possible that we guessed in hole-filling and there's another // function below this one. - XELOGSDB("Function ran under: %.8X-%.8X ended at %.8X", - start_address, end_address, address + 4); + XELOGSDB("Function ran under: %.8X-%.8X ended at %.8X", start_address, + end_address, address + 4); } symbol_info->set_end_address(address); @@ -300,8 +290,7 @@ std::vector PPCScanner::FindBlocks(FunctionInfo* symbol_info) { bool in_block = false; uint64_t block_start = 0; InstrData i; - for (uint64_t address = start_address; - address <= end_address; address += 4) { + for (uint64_t address = start_address; address <= end_address; address += 4) { i.address = address; i.code = XEGETUINT32BE(p + address); if (!i.code) { @@ -330,12 +319,12 @@ std::vector PPCScanner::FindBlocks(FunctionInfo* symbol_info) { ends_block = true; } else if (i.type->opcode == 0x48000000) { // b/ba/bl/bla - //uint32_t target = + // uint32_t target = // (uint32_t)XEEXTS26(i.I.LI << 2) + (i.I.AA ? 0 : (int32_t)address); ends_block = true; } else if (i.type->opcode == 0x40000000) { // bc/bca/bcl/bcla - //uint32_t target = + // uint32_t target = // (uint32_t)XEEXTS16(i.B.BD << 2) + (i.B.AA ? 0 : (int32_t)address); ends_block = true; } else if (i.type->opcode == 0x4C000020) { @@ -349,16 +338,14 @@ std::vector PPCScanner::FindBlocks(FunctionInfo* symbol_info) { if (ends_block) { in_block = false; block_map[block_start] = { - block_start, - address, + block_start, address, }; } } if (in_block) { block_map[block_start] = { - block_start, - end_address, + block_start, end_address, }; } @@ -368,3 +355,7 @@ std::vector PPCScanner::FindBlocks(FunctionInfo* symbol_info) { } return blocks; } + +} // namespace ppc +} // namespace frontend +} // namespace alloy diff --git a/src/alloy/frontend/ppc/ppc_scanner.h b/src/alloy/frontend/ppc/ppc_scanner.h index 1498cab16..deb51dcdf 100644 --- a/src/alloy/frontend/ppc/ppc_scanner.h +++ b/src/alloy/frontend/ppc/ppc_scanner.h @@ -13,7 +13,6 @@ #include #include - namespace alloy { namespace frontend { namespace ppc { @@ -25,9 +24,8 @@ typedef struct BlockInfo_t { uint64_t end_address; } BlockInfo; - class PPCScanner { -public: + public: PPCScanner(PPCFrontend* frontend); ~PPCScanner(); @@ -35,17 +33,15 @@ public: std::vector FindBlocks(runtime::FunctionInfo* symbol_info); -private: + private: bool IsRestGprLr(uint64_t address); -private: + private: PPCFrontend* frontend_; }; - } // namespace ppc } // namespace frontend } // namespace alloy - #endif // ALLOY_FRONTEND_PPC_PPC_SCANNER_H_ diff --git a/src/alloy/frontend/ppc/ppc_translator.cc b/src/alloy/frontend/ppc/ppc_translator.cc index 4f879336c..cf6e22dde 100644 --- a/src/alloy/frontend/ppc/ppc_translator.cc +++ b/src/alloy/frontend/ppc/ppc_translator.cc @@ -19,17 +19,20 @@ #include #include -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::compiler; -using namespace alloy::frontend; -using namespace alloy::frontend::ppc; -using namespace alloy::hir; +namespace alloy { +namespace frontend { +namespace ppc { + +// TODO(benvanik): remove when enums redefined. using namespace alloy::runtime; +using alloy::backend::Backend; +using alloy::compiler::Compiler; +using alloy::runtime::Function; +using alloy::runtime::FunctionInfo; +namespace passes = alloy::compiler::passes; -PPCTranslator::PPCTranslator(PPCFrontend* frontend) : - frontend_(frontend) { +PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) { Backend* backend = frontend->runtime()->backend(); scanner_ = new PPCScanner(frontend); @@ -54,21 +57,21 @@ PPCTranslator::PPCTranslator(PPCFrontend* frontend) : if (validate) compiler_->AddPass(new passes::ValidationPass()); compiler_->AddPass(new passes::SimplificationPass()); if (validate) compiler_->AddPass(new passes::ValidationPass()); - //compiler_->AddPass(new passes::DeadStoreEliminationPass()); - //if (validate) compiler_->AddPass(new passes::ValidationPass()); + // compiler_->AddPass(new passes::DeadStoreEliminationPass()); + // if (validate) compiler_->AddPass(new passes::ValidationPass()); compiler_->AddPass(new passes::DeadCodeEliminationPass()); if (validate) compiler_->AddPass(new passes::ValidationPass()); //// Removes all unneeded variables. Try not to add new ones after this. - //compiler_->AddPass(new passes::ValueReductionPass()); - //if (validate) compiler_->AddPass(new passes::ValidationPass()); + // compiler_->AddPass(new passes::ValueReductionPass()); + // if (validate) compiler_->AddPass(new passes::ValidationPass()); // Register allocation for the target backend. // Will modify the HIR to add loads/stores. // This should be the last pass before finalization, as after this all // registers are assigned and ready to be emitted. - compiler_->AddPass(new passes::RegisterAllocationPass( - backend->machine_info())); + compiler_->AddPass( + new passes::RegisterAllocationPass(backend->machine_info())); if (validate) compiler_->AddPass(new passes::ValidationPass()); // Must come last. The HIR is not really HIR after this. @@ -82,10 +85,9 @@ PPCTranslator::~PPCTranslator() { delete scanner_; } -int PPCTranslator::Translate( - FunctionInfo* symbol_info, - uint32_t debug_info_flags, - Function** out_function) { +int PPCTranslator::Translate(FunctionInfo* symbol_info, + uint32_t debug_info_flags, + Function** out_function) { SCOPE_profile_cpu_f("alloy"); // Scan the function to find its extents. We only need to do this if we @@ -139,10 +141,8 @@ int PPCTranslator::Translate( } // Assemble to backend machine code. - result = assembler_->Assemble( - symbol_info, builder_, - debug_info_flags, debug_info, - out_function); + result = assembler_->Assemble(symbol_info, builder_, debug_info_flags, + debug_info, out_function); XEEXPECTZERO(result); result = 0; @@ -158,15 +158,14 @@ XECLEANUP: return result; }; -void PPCTranslator::DumpSource( - runtime::FunctionInfo* symbol_info, StringBuffer* string_buffer) { +void PPCTranslator::DumpSource(runtime::FunctionInfo* symbol_info, + StringBuffer* string_buffer) { Memory* memory = frontend_->memory(); const uint8_t* p = memory->membase(); - string_buffer->Append("%s fn %.8X-%.8X %s\n", - symbol_info->module()->name(), - symbol_info->address(), symbol_info->end_address(), - symbol_info->name()); + string_buffer->Append("%s fn %.8X-%.8X %s\n", symbol_info->module()->name(), + symbol_info->address(), symbol_info->end_address(), + symbol_info->name()); auto blocks = scanner_->FindBlocks(symbol_info); @@ -182,10 +181,8 @@ void PPCTranslator::DumpSource( i.type = GetInstrType(i.code); // Check labels. - if (block_it != blocks.end() && - block_it->start_address == address) { - string_buffer->Append( - "%.8X loc_%.8X:\n", address, address); + if (block_it != blocks.end() && block_it->start_address == address) { + string_buffer->Append("%.8X loc_%.8X:\n", address, address); ++block_it; } @@ -194,3 +191,7 @@ void PPCTranslator::DumpSource( string_buffer->Append("\n"); } } + +} // namespace ppc +} // namespace frontend +} // namespace alloy diff --git a/src/alloy/frontend/ppc/ppc_translator.h b/src/alloy/frontend/ppc/ppc_translator.h index 9977a56e5..868ad5aeb 100644 --- a/src/alloy/frontend/ppc/ppc_translator.h +++ b/src/alloy/frontend/ppc/ppc_translator.h @@ -15,7 +15,6 @@ #include #include - namespace alloy { namespace frontend { namespace ppc { @@ -24,34 +23,30 @@ class PPCFrontend; class PPCHIRBuilder; class PPCScanner; - class PPCTranslator { -public: + public: PPCTranslator(PPCFrontend* frontend); ~PPCTranslator(); - int Translate(runtime::FunctionInfo* symbol_info, - uint32_t debug_info_flags, + int Translate(runtime::FunctionInfo* symbol_info, uint32_t debug_info_flags, runtime::Function** out_function); -private: + private: void DumpSource(runtime::FunctionInfo* symbol_info, StringBuffer* string_buffer); -private: - PPCFrontend* frontend_; - PPCScanner* scanner_; - PPCHIRBuilder* builder_; - compiler::Compiler* compiler_; - backend::Assembler* assembler_; + private: + PPCFrontend* frontend_; + PPCScanner* scanner_; + PPCHIRBuilder* builder_; + compiler::Compiler* compiler_; + backend::Assembler* assembler_; - StringBuffer string_buffer_; + StringBuffer string_buffer_; }; - } // namespace ppc } // namespace frontend } // namespace alloy - #endif // ALLOY_FRONTEND_PPC_PPC_TRANSLATOR_H_ diff --git a/src/alloy/frontend/tracing.h b/src/alloy/frontend/tracing.h index ad9e8dae7..66a445a4b 100644 --- a/src/alloy/frontend/tracing.h +++ b/src/alloy/frontend/tracing.h @@ -13,18 +13,16 @@ #include #include - namespace alloy { namespace frontend { const uint32_t ALLOY_FRONTEND = alloy::tracing::EventType::ALLOY_FRONTEND; - class EventType { -public: + public: enum { - ALLOY_FRONTEND_INIT = ALLOY_FRONTEND | (1), - ALLOY_FRONTEND_DEINIT = ALLOY_FRONTEND | (2), + ALLOY_FRONTEND_INIT = ALLOY_FRONTEND | (1), + ALLOY_FRONTEND_DEINIT = ALLOY_FRONTEND | (2), }; typedef struct Init_s { @@ -35,9 +33,7 @@ public: } Deinit; }; - } // namespace frontend } // namespace alloy - #endif // ALLOY_FRONTEND_TRACING_H_ diff --git a/src/alloy/hir/block.cc b/src/alloy/hir/block.cc index ebace67fa..60e9f988d 100644 --- a/src/alloy/hir/block.cc +++ b/src/alloy/hir/block.cc @@ -11,9 +11,8 @@ #include -using namespace alloy; -using namespace alloy::hir; - +namespace alloy { +namespace hir { void Block::AssertNoCycles() { Instr* hare = instr_head; @@ -37,3 +36,6 @@ void Block::AssertNoCycles() { } } } + +} // namespace hir +} // namespace alloy diff --git a/src/alloy/hir/block.h b/src/alloy/hir/block.h index f60dd83c5..4d2df2e9a 100644 --- a/src/alloy/hir/block.h +++ b/src/alloy/hir/block.h @@ -14,7 +14,6 @@ XEDECLARECLASS1(llvm, BitVector); - namespace alloy { namespace hir { @@ -23,14 +22,14 @@ class HIRBuilder; class Instr; class Label; - class Edge { -public: + public: enum EdgeFlags { UNCONDITIONAL = (1 << 0), DOMINATES = (1 << 1), }; -public: + + public: Edge* outgoing_next; Edge* outgoing_prev; Edge* incoming_next; @@ -42,9 +41,8 @@ public: uint32_t flags; }; - class Block { -public: + public: Arena* arena; Block* next; @@ -65,9 +63,7 @@ public: void AssertNoCycles(); }; - } // namespace hir } // namespace alloy - #endif // ALLOY_HIR_BLOCK_H_ diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index de0ce4a34..3cd66c157 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -14,10 +14,10 @@ #include #include -using namespace alloy; -using namespace alloy::hir; -using namespace alloy::runtime; +namespace alloy { +namespace hir { +using alloy::runtime::FunctionInfo; #define ASSERT_ADDRESS_TYPE(value) #define ASSERT_INTEGER_TYPE(value) @@ -26,7 +26,6 @@ using namespace alloy::runtime; #define ASSERT_VECTOR_TYPE(value) #define ASSERT_TYPES_EQUAL(value1, value2) - HIRBuilder::HIRBuilder() { arena_ = new Arena(); Reset(); @@ -74,7 +73,7 @@ int HIRBuilder::Finalize() { // No following block. // Sometimes VC++ generates functions with bl at the end even if they // will never return. Just add a return to satisfy things. - //XELOGW("Fall-through out of the function."); + // XELOGW("Fall-through out of the function."); Trap(); Return(); current_block_ = NULL; @@ -91,22 +90,36 @@ int HIRBuilder::Finalize() { void HIRBuilder::DumpValue(StringBuffer* str, Value* value) { if (value->IsConstant()) { switch (value->type) { - case INT8_TYPE: str->Append("%X", value->constant.i8); break; - case INT16_TYPE: str->Append("%X", value->constant.i16); break; - case INT32_TYPE: str->Append("%X", value->constant.i32); break; - case INT64_TYPE: str->Append("%llX", value->constant.i64); break; - case FLOAT32_TYPE: str->Append("%F", value->constant.f32); break; - case FLOAT64_TYPE: str->Append("%F", value->constant.f64); break; - case VEC128_TYPE: str->Append("(%F,%F,%F,%F)", - value->constant.v128.x, - value->constant.v128.y, - value->constant.v128.z, - value->constant.v128.w); break; - default: XEASSERTALWAYS(); break; + case INT8_TYPE: + str->Append("%X", value->constant.i8); + break; + case INT16_TYPE: + str->Append("%X", value->constant.i16); + break; + case INT32_TYPE: + str->Append("%X", value->constant.i32); + break; + case INT64_TYPE: + str->Append("%llX", value->constant.i64); + break; + case FLOAT32_TYPE: + str->Append("%F", value->constant.f32); + break; + case FLOAT64_TYPE: + str->Append("%F", value->constant.f64); + break; + case VEC128_TYPE: + str->Append("(%F,%F,%F,%F)", value->constant.v128.x, + value->constant.v128.y, value->constant.v128.z, + value->constant.v128.w); + break; + default: + XEASSERTALWAYS(); + break; } } else { static const char* type_names[] = { - "i8", "i16", "i32", "i64", "f32", "f64", "v128", + "i8", "i16", "i32", "i64", "f32", "f64", "v128", }; str->Append("v%d.%s", value->ordinal, type_names[value->type]); } @@ -115,30 +128,30 @@ void HIRBuilder::DumpValue(StringBuffer* str, Value* value) { } } -void HIRBuilder::DumpOp( - StringBuffer* str, OpcodeSignatureType sig_type, Instr::Op* op) { +void HIRBuilder::DumpOp(StringBuffer* str, OpcodeSignatureType sig_type, + Instr::Op* op) { switch (sig_type) { - case OPCODE_SIG_TYPE_X: - break; - case OPCODE_SIG_TYPE_L: - if (op->label->name) { - str->Append(op->label->name); - } else { - str->Append("label%d", op->label->id); - } - break; - case OPCODE_SIG_TYPE_O: - str->Append("+%lld", op->offset); - break; - case OPCODE_SIG_TYPE_S: - if (true) { - auto target = op->symbol_info; - str->Append(target->name() ? target->name() : ""); - } - break; - case OPCODE_SIG_TYPE_V: - DumpValue(str, op->value); - break; + case OPCODE_SIG_TYPE_X: + break; + case OPCODE_SIG_TYPE_L: + if (op->label->name) { + str->Append(op->label->name); + } else { + str->Append("label%d", op->label->id); + } + break; + case OPCODE_SIG_TYPE_O: + str->Append("+%lld", op->offset); + break; + case OPCODE_SIG_TYPE_S: + if (true) { + auto target = op->symbol_info; + str->Append(target->name() ? target->name() : ""); + } + break; + case OPCODE_SIG_TYPE_V: + DumpValue(str, op->value); + break; } } @@ -184,8 +197,7 @@ void HIRBuilder::Dump(StringBuffer* str) { } else if (src_label) { str->Append(" ; in: label%d", src_label->id); } else { - str->Append(" ; in: ", - incoming_edge->src->ordinal); + str->Append(" ; in: ", incoming_edge->src->ordinal); } str->Append(", dom:%d, uncond:%d\n", (incoming_edge->flags & Edge::DOMINATES) ? 1 : 0, @@ -200,8 +212,7 @@ void HIRBuilder::Dump(StringBuffer* str) { } else if (dest_label) { str->Append(" ; out: label%d", dest_label->id); } else { - str->Append(" ; out: ", - outgoing_edge->dest->ordinal); + str->Append(" ; out: ", outgoing_edge->dest->ordinal); } str->Append(", dom:%d, uncond:%d\n", (outgoing_edge->flags & Edge::DOMINATES) ? 1 : 0, @@ -279,9 +290,7 @@ void HIRBuilder::AssertNoCycles() { } } -Block* HIRBuilder::current_block() const { - return current_block_; -} +Block* HIRBuilder::current_block() const { return current_block_; } Instr* HIRBuilder::last_instr() const { if (current_block_ && current_block_->instr_tail) { @@ -466,8 +475,8 @@ bool HIRBuilder::IsUnconditionalJump(Instr* instr) { return false; } -Instr* HIRBuilder::AppendInstr( - const OpcodeInfo& opcode_info, uint16_t flags, Value* dest) { +Instr* HIRBuilder::AppendInstr(const OpcodeInfo& opcode_info, uint16_t flags, + Value* dest) { if (!current_block_) { AppendBlock(); } @@ -597,16 +606,15 @@ void HIRBuilder::TrapTrue(Value* cond, uint16_t trap_code) { EndBlock(); } -void HIRBuilder::Call( - FunctionInfo* symbol_info, uint32_t call_flags) { +void HIRBuilder::Call(FunctionInfo* symbol_info, uint32_t call_flags) { Instr* i = AppendInstr(OPCODE_CALL_info, call_flags); i->src1.symbol_info = symbol_info; i->src2.value = i->src3.value = NULL; EndBlock(); } -void HIRBuilder::CallTrue( - Value* cond, FunctionInfo* symbol_info, uint32_t call_flags) { +void HIRBuilder::CallTrue(Value* cond, FunctionInfo* symbol_info, + uint32_t call_flags) { if (cond->IsConstant()) { if (cond->IsConstantTrue()) { Call(symbol_info, call_flags); @@ -621,8 +629,7 @@ void HIRBuilder::CallTrue( EndBlock(); } -void HIRBuilder::CallIndirect( - Value* value, uint32_t call_flags) { +void HIRBuilder::CallIndirect(Value* value, uint32_t call_flags) { ASSERT_ADDRESS_TYPE(value); Instr* i = AppendInstr(OPCODE_CALL_INDIRECT_info, call_flags); i->set_src1(value); @@ -630,8 +637,8 @@ void HIRBuilder::CallIndirect( EndBlock(); } -void HIRBuilder::CallIndirectTrue( - Value* cond, Value* value, uint32_t call_flags) { +void HIRBuilder::CallIndirectTrue(Value* cond, Value* value, + uint32_t call_flags) { if (cond->IsConstant()) { if (cond->IsConstantTrue()) { CallIndirect(value, call_flags); @@ -697,8 +704,7 @@ void HIRBuilder::Branch(Block* block, uint32_t branch_flags) { Branch(block->label_head, branch_flags); } -void HIRBuilder::BranchTrue( - Value* cond, Label* label, uint32_t branch_flags) { +void HIRBuilder::BranchTrue(Value* cond, Label* label, uint32_t branch_flags) { if (cond->IsConstant()) { if (cond->IsConstantTrue()) { Branch(label, branch_flags); @@ -713,8 +719,7 @@ void HIRBuilder::BranchTrue( EndBlock(); } -void HIRBuilder::BranchFalse( - Value* cond, Label* label, uint32_t branch_flags) { +void HIRBuilder::BranchFalse(Value* cond, Label* label, uint32_t branch_flags) { if (cond->IsConstant()) { if (cond->IsConstantFalse()) { Branch(label, branch_flags); @@ -736,9 +741,7 @@ Value* HIRBuilder::Assign(Value* value) { return value; } - Instr* i = AppendInstr( - OPCODE_ASSIGN_info, 0, - AllocValue(value->type)); + Instr* i = AppendInstr(OPCODE_ASSIGN_info, 0, AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; @@ -753,9 +756,7 @@ Value* HIRBuilder::Cast(Value* value, TypeName target_type) { return dest; } - Instr* i = AppendInstr( - OPCODE_CAST_info, 0, - AllocValue(target_type)); + Instr* i = AppendInstr(OPCODE_CAST_info, 0, AllocValue(target_type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; @@ -770,9 +771,7 @@ Value* HIRBuilder::ZeroExtend(Value* value, TypeName target_type) { return dest; } - Instr* i = AppendInstr( - OPCODE_ZERO_EXTEND_info, 0, - AllocValue(target_type)); + Instr* i = AppendInstr(OPCODE_ZERO_EXTEND_info, 0, AllocValue(target_type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; @@ -787,9 +786,7 @@ Value* HIRBuilder::SignExtend(Value* value, TypeName target_type) { return dest; } - Instr* i = AppendInstr( - OPCODE_SIGN_EXTEND_info, 0, - AllocValue(target_type)); + Instr* i = AppendInstr(OPCODE_SIGN_EXTEND_info, 0, AllocValue(target_type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; @@ -807,16 +804,14 @@ Value* HIRBuilder::Truncate(Value* value, TypeName target_type) { return dest; } - Instr* i = AppendInstr( - OPCODE_TRUNCATE_info, 0, - AllocValue(target_type)); + Instr* i = AppendInstr(OPCODE_TRUNCATE_info, 0, AllocValue(target_type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; } Value* HIRBuilder::Convert(Value* value, TypeName target_type, - RoundMode round_mode) { + RoundMode round_mode) { if (value->type == target_type) { return value; } else if (value->IsConstant()) { @@ -825,9 +820,8 @@ Value* HIRBuilder::Convert(Value* value, TypeName target_type, return dest; } - Instr* i = AppendInstr( - OPCODE_CONVERT_info, round_mode, - AllocValue(target_type)); + Instr* i = + AppendInstr(OPCODE_CONVERT_info, round_mode, AllocValue(target_type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; @@ -842,9 +836,8 @@ Value* HIRBuilder::Round(Value* value, RoundMode round_mode) { return dest; } - Instr* i = AppendInstr( - OPCODE_ROUND_info, round_mode, - AllocValue(value->type)); + Instr* i = + AppendInstr(OPCODE_ROUND_info, round_mode, AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; @@ -853,9 +846,8 @@ Value* HIRBuilder::Round(Value* value, RoundMode round_mode) { Value* HIRBuilder::VectorConvertI2F(Value* value, uint32_t arithmetic_flags) { ASSERT_VECTOR_TYPE(value); - Instr* i = AppendInstr( - OPCODE_VECTOR_CONVERT_I2F_info, arithmetic_flags, - AllocValue(value->type)); + Instr* i = AppendInstr(OPCODE_VECTOR_CONVERT_I2F_info, arithmetic_flags, + AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; @@ -864,9 +856,8 @@ Value* HIRBuilder::VectorConvertI2F(Value* value, uint32_t arithmetic_flags) { Value* HIRBuilder::VectorConvertF2I(Value* value, uint32_t arithmetic_flags) { ASSERT_VECTOR_TYPE(value); - Instr* i = AppendInstr( - OPCODE_VECTOR_CONVERT_F2I_info, arithmetic_flags, - AllocValue(value->type)); + Instr* i = AppendInstr(OPCODE_VECTOR_CONVERT_F2I_info, arithmetic_flags, + AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; @@ -947,9 +938,8 @@ Value* HIRBuilder::LoadConstant(const vec128_t& value) { Value* HIRBuilder::LoadVectorShl(Value* sh) { XEASSERT(sh->type == INT8_TYPE); - Instr* i = AppendInstr( - OPCODE_LOAD_VECTOR_SHL_info, 0, - AllocValue(VEC128_TYPE)); + Instr* i = + AppendInstr(OPCODE_LOAD_VECTOR_SHL_info, 0, AllocValue(VEC128_TYPE)); i->set_src1(sh); i->src2.value = i->src3.value = NULL; return i->dest; @@ -957,18 +947,15 @@ Value* HIRBuilder::LoadVectorShl(Value* sh) { Value* HIRBuilder::LoadVectorShr(Value* sh) { XEASSERT(sh->type == INT8_TYPE); - Instr* i = AppendInstr( - OPCODE_LOAD_VECTOR_SHR_info, 0, - AllocValue(VEC128_TYPE)); + Instr* i = + AppendInstr(OPCODE_LOAD_VECTOR_SHR_info, 0, AllocValue(VEC128_TYPE)); i->set_src1(sh); i->src2.value = i->src3.value = NULL; return i->dest; } Value* HIRBuilder::LoadClock() { - Instr* i = AppendInstr( - OPCODE_LOAD_CLOCK_info, 0, - AllocValue(INT64_TYPE)); + Instr* i = AppendInstr(OPCODE_LOAD_CLOCK_info, 0, AllocValue(INT64_TYPE)); i->src1.value = i->src2.value = i->src3.value = NULL; return i->dest; } @@ -980,9 +967,7 @@ Value* HIRBuilder::AllocLocal(TypeName type) { } Value* HIRBuilder::LoadLocal(Value* slot) { - Instr* i = AppendInstr( - OPCODE_LOAD_LOCAL_info, 0, - AllocValue(slot->type)); + Instr* i = AppendInstr(OPCODE_LOAD_LOCAL_info, 0, AllocValue(slot->type)); i->set_src1(slot); i->src2.value = i->src3.value = NULL; return i->dest; @@ -996,9 +981,7 @@ void HIRBuilder::StoreLocal(Value* slot, Value* value) { } Value* HIRBuilder::LoadContext(size_t offset, TypeName type) { - Instr* i = AppendInstr( - OPCODE_LOAD_CONTEXT_info, 0, - AllocValue(type)); + Instr* i = AppendInstr(OPCODE_LOAD_CONTEXT_info, 0, AllocValue(type)); i->src1.offset = offset; i->src2.value = i->src3.value = NULL; return i->dest; @@ -1011,19 +994,15 @@ void HIRBuilder::StoreContext(size_t offset, Value* value) { i->src3.value = NULL; } -Value* HIRBuilder::Load( - Value* address, TypeName type, uint32_t load_flags) { +Value* HIRBuilder::Load(Value* address, TypeName type, uint32_t load_flags) { ASSERT_ADDRESS_TYPE(address); - Instr* i = AppendInstr( - OPCODE_LOAD_info, load_flags, - AllocValue(type)); + Instr* i = AppendInstr(OPCODE_LOAD_info, load_flags, AllocValue(type)); i->set_src1(address); i->src2.value = i->src3.value = NULL; return i->dest; } -void HIRBuilder::Store( - Value* address, Value* value, uint32_t store_flags) { +void HIRBuilder::Store(Value* address, Value* value, uint32_t store_flags) { ASSERT_ADDRESS_TYPE(address); Instr* i = AppendInstr(OPCODE_STORE_info, store_flags); i->set_src1(address); @@ -1031,8 +1010,8 @@ void HIRBuilder::Store( i->src3.value = NULL; } -void HIRBuilder::Prefetch( - Value* address, size_t length, uint32_t prefetch_flags) { +void HIRBuilder::Prefetch(Value* address, size_t length, + uint32_t prefetch_flags) { ASSERT_ADDRESS_TYPE(address); Instr* i = AppendInstr(OPCODE_PREFETCH_info, prefetch_flags); i->set_src1(address); @@ -1043,14 +1022,12 @@ void HIRBuilder::Prefetch( Value* HIRBuilder::Max(Value* value1, Value* value2) { ASSERT_TYPES_EQUAL(value1, value2); - if (value1->type != VEC128_TYPE && - value1->IsConstant() && value2->IsConstant()) { + if (value1->type != VEC128_TYPE && value1->IsConstant() && + value2->IsConstant()) { return value1->Compare(OPCODE_COMPARE_SLT, value2) ? value2 : value1; } - Instr* i = AppendInstr( - OPCODE_MAX_info, 0, - AllocValue(value1->type)); + Instr* i = AppendInstr(OPCODE_MAX_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; @@ -1060,14 +1037,12 @@ Value* HIRBuilder::Max(Value* value1, Value* value2) { Value* HIRBuilder::Min(Value* value1, Value* value2) { ASSERT_TYPES_EQUAL(value1, value2); - if (value1->type != VEC128_TYPE && - value1->IsConstant() && value2->IsConstant()) { + if (value1->type != VEC128_TYPE && value1->IsConstant() && + value2->IsConstant()) { return value1->Compare(OPCODE_COMPARE_SLT, value2) ? value1 : value2; } - Instr* i = AppendInstr( - OPCODE_MIN_info, 0, - AllocValue(value1->type)); + Instr* i = AppendInstr(OPCODE_MIN_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; @@ -1075,16 +1050,14 @@ Value* HIRBuilder::Min(Value* value1, Value* value2) { } Value* HIRBuilder::Select(Value* cond, Value* value1, Value* value2) { - XEASSERT(cond->type == INT8_TYPE); // for now + XEASSERT(cond->type == INT8_TYPE); // for now ASSERT_TYPES_EQUAL(value1, value2); if (cond->IsConstant()) { return cond->IsConstantTrue() ? value1 : value2; } - Instr* i = AppendInstr( - OPCODE_SELECT_info, 0, - AllocValue(value1->type)); + Instr* i = AppendInstr(OPCODE_SELECT_info, 0, AllocValue(value1->type)); i->set_src1(cond); i->set_src2(value1); i->set_src3(value2); @@ -1096,9 +1069,7 @@ Value* HIRBuilder::IsTrue(Value* value) { return LoadConstant(value->IsConstantTrue() ? 1 : 0); } - Instr* i = AppendInstr( - OPCODE_IS_TRUE_info, 0, - AllocValue(INT8_TYPE)); + Instr* i = AppendInstr(OPCODE_IS_TRUE_info, 0, AllocValue(INT8_TYPE)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; @@ -1109,24 +1080,20 @@ Value* HIRBuilder::IsFalse(Value* value) { return LoadConstant(value->IsConstantFalse() ? 1 : 0); } - Instr* i = AppendInstr( - OPCODE_IS_FALSE_info, 0, - AllocValue(INT8_TYPE)); + Instr* i = AppendInstr(OPCODE_IS_FALSE_info, 0, AllocValue(INT8_TYPE)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; } -Value* HIRBuilder::CompareXX( - const OpcodeInfo& opcode, Value* value1, Value* value2) { +Value* HIRBuilder::CompareXX(const OpcodeInfo& opcode, Value* value1, + Value* value2) { ASSERT_TYPES_EQUAL(value1, value2); if (value1->IsConstant() && value2->IsConstant()) { return LoadConstant(value1->Compare(opcode.num, value2) ? 1 : 0); } - Instr* i = AppendInstr( - opcode, 0, - AllocValue(INT8_TYPE)); + Instr* i = AppendInstr(opcode, 0, AllocValue(INT8_TYPE)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; @@ -1174,81 +1141,72 @@ Value* HIRBuilder::CompareUGE(Value* value1, Value* value2) { } Value* HIRBuilder::DidCarry(Value* value) { - Instr* i = AppendInstr( - OPCODE_DID_CARRY_info, 0, - AllocValue(INT8_TYPE)); + Instr* i = AppendInstr(OPCODE_DID_CARRY_info, 0, AllocValue(INT8_TYPE)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; } Value* HIRBuilder::DidOverflow(Value* value) { - Instr* i = AppendInstr( - OPCODE_DID_OVERFLOW_info, 0, - AllocValue(INT8_TYPE)); + Instr* i = AppendInstr(OPCODE_DID_OVERFLOW_info, 0, AllocValue(INT8_TYPE)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; } Value* HIRBuilder::DidSaturate(Value* value) { - Instr* i = AppendInstr( - OPCODE_DID_SATURATE_info, 0, - AllocValue(INT8_TYPE)); + Instr* i = AppendInstr(OPCODE_DID_SATURATE_info, 0, AllocValue(INT8_TYPE)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; } -Value* HIRBuilder::VectorCompareXX( - const OpcodeInfo& opcode, Value* value1, Value* value2, - TypeName part_type) { +Value* HIRBuilder::VectorCompareXX(const OpcodeInfo& opcode, Value* value1, + Value* value2, TypeName part_type) { ASSERT_TYPES_EQUAL(value1, value2); // TODO(benvanik): check how this is used - sometimes I think it's used to // load bitmasks and may be worth checking constants on. - Instr* i = AppendInstr( - opcode, part_type, - AllocValue(value1->type)); + Instr* i = AppendInstr(opcode, part_type, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; return i->dest; } -Value* HIRBuilder::VectorCompareEQ( - Value* value1, Value* value2, TypeName part_type) { - return VectorCompareXX( - OPCODE_VECTOR_COMPARE_EQ_info, value1, value2, part_type); +Value* HIRBuilder::VectorCompareEQ(Value* value1, Value* value2, + TypeName part_type) { + return VectorCompareXX(OPCODE_VECTOR_COMPARE_EQ_info, value1, value2, + part_type); } -Value* HIRBuilder::VectorCompareSGT( - Value* value1, Value* value2, TypeName part_type) { - return VectorCompareXX( - OPCODE_VECTOR_COMPARE_SGT_info, value1, value2, part_type); +Value* HIRBuilder::VectorCompareSGT(Value* value1, Value* value2, + TypeName part_type) { + return VectorCompareXX(OPCODE_VECTOR_COMPARE_SGT_info, value1, value2, + part_type); } -Value* HIRBuilder::VectorCompareSGE( - Value* value1, Value* value2, TypeName part_type) { - return VectorCompareXX( - OPCODE_VECTOR_COMPARE_SGE_info, value1, value2, part_type); +Value* HIRBuilder::VectorCompareSGE(Value* value1, Value* value2, + TypeName part_type) { + return VectorCompareXX(OPCODE_VECTOR_COMPARE_SGE_info, value1, value2, + part_type); } -Value* HIRBuilder::VectorCompareUGT( - Value* value1, Value* value2, TypeName part_type) { - return VectorCompareXX( - OPCODE_VECTOR_COMPARE_UGT_info, value1, value2, part_type); +Value* HIRBuilder::VectorCompareUGT(Value* value1, Value* value2, + TypeName part_type) { + return VectorCompareXX(OPCODE_VECTOR_COMPARE_UGT_info, value1, value2, + part_type); } -Value* HIRBuilder::VectorCompareUGE( - Value* value1, Value* value2, TypeName part_type) { - return VectorCompareXX( - OPCODE_VECTOR_COMPARE_UGE_info, value1, value2, part_type); +Value* HIRBuilder::VectorCompareUGE(Value* value1, Value* value2, + TypeName part_type) { + return VectorCompareXX(OPCODE_VECTOR_COMPARE_UGE_info, value1, value2, + part_type); } -Value* HIRBuilder::Add( - Value* value1, Value* value2, uint32_t arithmetic_flags) { +Value* HIRBuilder::Add(Value* value1, Value* value2, + uint32_t arithmetic_flags) { ASSERT_TYPES_EQUAL(value1, value2); // TODO(benvanik): optimize when flags set. @@ -1264,24 +1222,21 @@ Value* HIRBuilder::Add( } } - Instr* i = AppendInstr( - OPCODE_ADD_info, arithmetic_flags, - AllocValue(value1->type)); + Instr* i = + AppendInstr(OPCODE_ADD_info, arithmetic_flags, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; return i->dest; } -Value* HIRBuilder::AddWithCarry( - Value* value1, Value* value2, Value* value3, - uint32_t arithmetic_flags) { +Value* HIRBuilder::AddWithCarry(Value* value1, Value* value2, Value* value3, + uint32_t arithmetic_flags) { ASSERT_TYPES_EQUAL(value1, value2); XEASSERT(value3->type == INT8_TYPE); - Instr* i = AppendInstr( - OPCODE_ADD_CARRY_info, arithmetic_flags, - AllocValue(value1->type)); + Instr* i = AppendInstr(OPCODE_ADD_CARRY_info, arithmetic_flags, + AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->set_src3(value3); @@ -1297,61 +1252,56 @@ Value* HIRBuilder::VectorAdd(Value* value1, Value* value2, TypeName part_type, uint32_t flags = part_type | (arithmetic_flags << 8); XEASSERTZERO(flags >> 16); - Instr* i = AppendInstr( - OPCODE_VECTOR_ADD_info, (uint16_t)flags, - AllocValue(value1->type)); + Instr* i = AppendInstr(OPCODE_VECTOR_ADD_info, (uint16_t)flags, + AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; return i->dest; } -Value* HIRBuilder::Sub( - Value* value1, Value* value2, uint32_t arithmetic_flags) { +Value* HIRBuilder::Sub(Value* value1, Value* value2, + uint32_t arithmetic_flags) { ASSERT_TYPES_EQUAL(value1, value2); - Instr* i = AppendInstr( - OPCODE_SUB_info, arithmetic_flags, - AllocValue(value1->type)); + Instr* i = + AppendInstr(OPCODE_SUB_info, arithmetic_flags, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; return i->dest; } -Value* HIRBuilder::Mul( - Value* value1, Value* value2, uint32_t arithmetic_flags) { +Value* HIRBuilder::Mul(Value* value1, Value* value2, + uint32_t arithmetic_flags) { ASSERT_TYPES_EQUAL(value1, value2); - Instr* i = AppendInstr( - OPCODE_MUL_info, arithmetic_flags, - AllocValue(value1->type)); + Instr* i = + AppendInstr(OPCODE_MUL_info, arithmetic_flags, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; return i->dest; } -Value* HIRBuilder::MulHi( - Value* value1, Value* value2, uint32_t arithmetic_flags) { +Value* HIRBuilder::MulHi(Value* value1, Value* value2, + uint32_t arithmetic_flags) { ASSERT_TYPES_EQUAL(value1, value2); - Instr* i = AppendInstr( - OPCODE_MUL_HI_info, arithmetic_flags, - AllocValue(value1->type)); + Instr* i = AppendInstr(OPCODE_MUL_HI_info, arithmetic_flags, + AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; return i->dest; } -Value* HIRBuilder::Div( - Value* value1, Value* value2, uint32_t arithmetic_flags) { +Value* HIRBuilder::Div(Value* value1, Value* value2, + uint32_t arithmetic_flags) { ASSERT_TYPES_EQUAL(value1, value2); - Instr* i = AppendInstr( - OPCODE_DIV_info, arithmetic_flags, - AllocValue(value1->type)); + Instr* i = + AppendInstr(OPCODE_DIV_info, arithmetic_flags, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; @@ -1370,9 +1320,7 @@ Value* HIRBuilder::MulAdd(Value* value1, Value* value2, Value* value3) { return Add(dest, value3); } - Instr* i = AppendInstr( - OPCODE_MUL_ADD_info, 0, - AllocValue(value1->type)); + Instr* i = AppendInstr(OPCODE_MUL_ADD_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->set_src3(value3); @@ -1391,9 +1339,7 @@ Value* HIRBuilder::MulSub(Value* value1, Value* value2, Value* value3) { return Sub(dest, value3); } - Instr* i = AppendInstr( - OPCODE_MUL_SUB_info, 0, - AllocValue(value1->type)); + Instr* i = AppendInstr(OPCODE_MUL_SUB_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->set_src3(value3); @@ -1403,9 +1349,7 @@ Value* HIRBuilder::MulSub(Value* value1, Value* value2, Value* value3) { Value* HIRBuilder::Neg(Value* value) { ASSERT_NON_VECTOR_TYPE(value); - Instr* i = AppendInstr( - OPCODE_NEG_info, 0, - AllocValue(value->type)); + Instr* i = AppendInstr(OPCODE_NEG_info, 0, AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; @@ -1414,9 +1358,7 @@ Value* HIRBuilder::Neg(Value* value) { Value* HIRBuilder::Abs(Value* value) { ASSERT_NON_VECTOR_TYPE(value); - Instr* i = AppendInstr( - OPCODE_ABS_info, 0, - AllocValue(value->type)); + Instr* i = AppendInstr(OPCODE_ABS_info, 0, AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; @@ -1425,9 +1367,7 @@ Value* HIRBuilder::Abs(Value* value) { Value* HIRBuilder::Sqrt(Value* value) { ASSERT_FLOAT_TYPE(value); - Instr* i = AppendInstr( - OPCODE_SQRT_info, 0, - AllocValue(value->type)); + Instr* i = AppendInstr(OPCODE_SQRT_info, 0, AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; @@ -1436,9 +1376,7 @@ Value* HIRBuilder::Sqrt(Value* value) { Value* HIRBuilder::RSqrt(Value* value) { ASSERT_FLOAT_TYPE(value); - Instr* i = AppendInstr( - OPCODE_RSQRT_info, 0, - AllocValue(value->type)); + Instr* i = AppendInstr(OPCODE_RSQRT_info, 0, AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; @@ -1447,9 +1385,7 @@ Value* HIRBuilder::RSqrt(Value* value) { Value* HIRBuilder::Pow2(Value* value) { ASSERT_FLOAT_TYPE(value); - Instr* i = AppendInstr( - OPCODE_POW2_info, 0, - AllocValue(value->type)); + Instr* i = AppendInstr(OPCODE_POW2_info, 0, AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; @@ -1458,9 +1394,7 @@ Value* HIRBuilder::Pow2(Value* value) { Value* HIRBuilder::Log2(Value* value) { ASSERT_FLOAT_TYPE(value); - Instr* i = AppendInstr( - OPCODE_LOG2_info, 0, - AllocValue(value->type)); + Instr* i = AppendInstr(OPCODE_LOG2_info, 0, AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; @@ -1471,9 +1405,8 @@ Value* HIRBuilder::DotProduct3(Value* value1, Value* value2) { ASSERT_VECTOR_TYPE(value2); ASSERT_TYPES_EQUAL(value1, value2); - Instr* i = AppendInstr( - OPCODE_DOT_PRODUCT_3_info, 0, - AllocValue(FLOAT32_TYPE)); + Instr* i = + AppendInstr(OPCODE_DOT_PRODUCT_3_info, 0, AllocValue(FLOAT32_TYPE)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; @@ -1485,9 +1418,8 @@ Value* HIRBuilder::DotProduct4(Value* value1, Value* value2) { ASSERT_VECTOR_TYPE(value2); ASSERT_TYPES_EQUAL(value1, value2); - Instr* i = AppendInstr( - OPCODE_DOT_PRODUCT_4_info, 0, - AllocValue(FLOAT32_TYPE)); + Instr* i = + AppendInstr(OPCODE_DOT_PRODUCT_4_info, 0, AllocValue(FLOAT32_TYPE)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; @@ -1507,9 +1439,7 @@ Value* HIRBuilder::And(Value* value1, Value* value2) { return value2; } - Instr* i = AppendInstr( - OPCODE_AND_info, 0, - AllocValue(value1->type)); + Instr* i = AppendInstr(OPCODE_AND_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; @@ -1529,9 +1459,7 @@ Value* HIRBuilder::Or(Value* value1, Value* value2) { return value1; } - Instr* i = AppendInstr( - OPCODE_OR_info, 0, - AllocValue(value1->type)); + Instr* i = AppendInstr(OPCODE_OR_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; @@ -1547,9 +1475,7 @@ Value* HIRBuilder::Xor(Value* value1, Value* value2) { return LoadZero(value1->type); } - Instr* i = AppendInstr( - OPCODE_XOR_info, 0, - AllocValue(value1->type)); + Instr* i = AppendInstr(OPCODE_XOR_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; @@ -1565,9 +1491,7 @@ Value* HIRBuilder::Not(Value* value) { return dest; } - Instr* i = AppendInstr( - OPCODE_NOT_info, 0, - AllocValue(value->type)); + Instr* i = AppendInstr(OPCODE_NOT_info, 0, AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; @@ -1586,9 +1510,7 @@ Value* HIRBuilder::Shl(Value* value1, Value* value2) { value2 = Truncate(value2, INT8_TYPE); } - Instr* i = AppendInstr( - OPCODE_SHL_info, 0, - AllocValue(value1->type)); + Instr* i = AppendInstr(OPCODE_SHL_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; @@ -1598,14 +1520,12 @@ Value* HIRBuilder::Shl(Value* value1, int8_t value2) { return Shl(value1, LoadConstant(value2)); } -Value* HIRBuilder::VectorShl(Value* value1, Value* value2, - TypeName part_type) { +Value* HIRBuilder::VectorShl(Value* value1, Value* value2, TypeName part_type) { ASSERT_VECTOR_TYPE(value1); ASSERT_VECTOR_TYPE(value2); - Instr* i = AppendInstr( - OPCODE_VECTOR_SHL_info, part_type, - AllocValue(value1->type)); + Instr* i = + AppendInstr(OPCODE_VECTOR_SHL_info, part_type, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; @@ -1623,9 +1543,7 @@ Value* HIRBuilder::Shr(Value* value1, Value* value2) { value2 = Truncate(value2, INT8_TYPE); } - Instr* i = AppendInstr( - OPCODE_SHR_info, 0, - AllocValue(value1->type)); + Instr* i = AppendInstr(OPCODE_SHR_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; @@ -1635,14 +1553,12 @@ Value* HIRBuilder::Shr(Value* value1, int8_t value2) { return Shr(value1, LoadConstant(value2)); } -Value* HIRBuilder::VectorShr(Value* value1, Value* value2, - TypeName part_type) { +Value* HIRBuilder::VectorShr(Value* value1, Value* value2, TypeName part_type) { ASSERT_VECTOR_TYPE(value1); ASSERT_VECTOR_TYPE(value2); - Instr* i = AppendInstr( - OPCODE_VECTOR_SHR_info, part_type, - AllocValue(value1->type)); + Instr* i = + AppendInstr(OPCODE_VECTOR_SHR_info, part_type, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; @@ -1660,9 +1576,7 @@ Value* HIRBuilder::Sha(Value* value1, Value* value2) { value2 = Truncate(value2, INT8_TYPE); } - Instr* i = AppendInstr( - OPCODE_SHA_info, 0, - AllocValue(value1->type)); + Instr* i = AppendInstr(OPCODE_SHA_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; @@ -1672,14 +1586,12 @@ Value* HIRBuilder::Sha(Value* value1, int8_t value2) { return Sha(value1, LoadConstant(value2)); } -Value* HIRBuilder::VectorSha(Value* value1, Value* value2, - TypeName part_type) { +Value* HIRBuilder::VectorSha(Value* value1, Value* value2, TypeName part_type) { ASSERT_VECTOR_TYPE(value1); ASSERT_VECTOR_TYPE(value2); - Instr* i = AppendInstr( - OPCODE_VECTOR_SHA_info, part_type, - AllocValue(value1->type)); + Instr* i = + AppendInstr(OPCODE_VECTOR_SHA_info, part_type, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; @@ -1698,9 +1610,7 @@ Value* HIRBuilder::RotateLeft(Value* value1, Value* value2) { value2 = Truncate(value2, INT8_TYPE); } - Instr* i = AppendInstr( - OPCODE_ROTATE_LEFT_info, 0, - AllocValue(value1->type)); + Instr* i = AppendInstr(OPCODE_ROTATE_LEFT_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; @@ -1712,9 +1622,7 @@ Value* HIRBuilder::ByteSwap(Value* value) { return value; } - Instr* i = AppendInstr( - OPCODE_BYTE_SWAP_info, 0, - AllocValue(value->type)); + Instr* i = AppendInstr(OPCODE_BYTE_SWAP_info, 0, AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; @@ -1724,13 +1632,13 @@ Value* HIRBuilder::CountLeadingZeros(Value* value) { ASSERT_INTEGER_TYPE(value); if (value->IsConstantZero()) { - const static uint8_t zeros[] = { 8, 16, 32, 64, }; + const static uint8_t zeros[] = { + 8, 16, 32, 64, + }; return LoadConstant(zeros[value->type]); } - Instr* i = AppendInstr( - OPCODE_CNTLZ_info, 0, - AllocValue(INT8_TYPE)); + Instr* i = AppendInstr(OPCODE_CNTLZ_info, 0, AllocValue(INT8_TYPE)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; @@ -1739,9 +1647,7 @@ Value* HIRBuilder::CountLeadingZeros(Value* value) { Value* HIRBuilder::Insert(Value* value, Value* index, Value* part) { // TODO(benvanik): could do some of this as constants. - Instr* i = AppendInstr( - OPCODE_INSERT_info, 0, - AllocValue(value->type)); + Instr* i = AppendInstr(OPCODE_INSERT_info, 0, AllocValue(value->type)); i->set_src1(value); i->set_src2(ZeroExtend(index, INT64_TYPE)); i->set_src3(part); @@ -1752,55 +1658,48 @@ Value* HIRBuilder::Insert(Value* value, uint64_t index, Value* part) { return Insert(value, LoadConstant(index), part); } -Value* HIRBuilder::Extract(Value* value, Value* index, - TypeName target_type) { +Value* HIRBuilder::Extract(Value* value, Value* index, TypeName target_type) { // TODO(benvanik): could do some of this as constants. - Value* trunc_index = index->type != INT8_TYPE ? - Truncate(index, INT8_TYPE) : index; + Value* trunc_index = + index->type != INT8_TYPE ? Truncate(index, INT8_TYPE) : index; - Instr* i = AppendInstr( - OPCODE_EXTRACT_info, 0, - AllocValue(target_type)); + Instr* i = AppendInstr(OPCODE_EXTRACT_info, 0, AllocValue(target_type)); i->set_src1(value); i->set_src2(trunc_index); i->src3.value = NULL; return i->dest; } -Value* HIRBuilder::Extract(Value* value, uint8_t index, - TypeName target_type) { +Value* HIRBuilder::Extract(Value* value, uint8_t index, TypeName target_type) { return Extract(value, LoadConstant(index), target_type); } Value* HIRBuilder::Splat(Value* value, TypeName target_type) { // TODO(benvanik): could do some of this as constants. - Instr* i = AppendInstr( - OPCODE_SPLAT_info, 0, - AllocValue(target_type)); + Instr* i = AppendInstr(OPCODE_SPLAT_info, 0, AllocValue(target_type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; } -Value* HIRBuilder::Permute( - Value* control, Value* value1, Value* value2, TypeName part_type) { +Value* HIRBuilder::Permute(Value* control, Value* value1, Value* value2, + TypeName part_type) { ASSERT_TYPES_EQUAL(value1, value2); // TODO(benvanik): could do some of this as constants. - Instr* i = AppendInstr( - OPCODE_PERMUTE_info, part_type, - AllocValue(value1->type)); + Instr* i = + AppendInstr(OPCODE_PERMUTE_info, part_type, AllocValue(value1->type)); i->set_src1(control); i->set_src2(value1); i->set_src3(value2); return i->dest; } -Value* HIRBuilder::Swizzle( - Value* value, TypeName part_type, uint32_t swizzle_mask) { +Value* HIRBuilder::Swizzle(Value* value, TypeName part_type, + uint32_t swizzle_mask) { // For now. XEASSERT(part_type == INT32_TYPE || part_type == FLOAT32_TYPE); @@ -1810,9 +1709,8 @@ Value* HIRBuilder::Swizzle( // TODO(benvanik): could do some of this as constants. - Instr* i = AppendInstr( - OPCODE_SWIZZLE_info, part_type, - AllocValue(value->type)); + Instr* i = + AppendInstr(OPCODE_SWIZZLE_info, part_type, AllocValue(value->type)); i->set_src1(value); i->src2.offset = swizzle_mask; i->src3.value = NULL; @@ -1821,9 +1719,7 @@ Value* HIRBuilder::Swizzle( Value* HIRBuilder::Pack(Value* value, uint32_t pack_flags) { ASSERT_VECTOR_TYPE(value); - Instr* i = AppendInstr( - OPCODE_PACK_info, pack_flags, - AllocValue(VEC128_TYPE)); + Instr* i = AppendInstr(OPCODE_PACK_info, pack_flags, AllocValue(VEC128_TYPE)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; @@ -1833,23 +1729,21 @@ Value* HIRBuilder::Unpack(Value* value, uint32_t pack_flags) { ASSERT_VECTOR_TYPE(value); // TODO(benvanik): check if this is a constant - sometimes this is just used // to initialize registers. - Instr* i = AppendInstr( - OPCODE_UNPACK_info, pack_flags, - AllocValue(VEC128_TYPE)); + Instr* i = + AppendInstr(OPCODE_UNPACK_info, pack_flags, AllocValue(VEC128_TYPE)); i->set_src1(value); i->src2.value = i->src3.value = NULL; return i->dest; } -Value* HIRBuilder::CompareExchange( - Value* address, Value* compare_value, Value* exchange_value) { +Value* HIRBuilder::CompareExchange(Value* address, Value* compare_value, + Value* exchange_value) { ASSERT_ADDRESS_TYPE(address); ASSERT_INTEGER_TYPE(compare_value); ASSERT_INTEGER_TYPE(exchange_value); ASSERT_TYPES_EQUAL(compare_value, exchange_value); - Instr* i = AppendInstr( - OPCODE_COMPARE_EXCHANGE_info, 0, - AllocValue(exchange_value->type)); + Instr* i = AppendInstr(OPCODE_COMPARE_EXCHANGE_info, 0, + AllocValue(exchange_value->type)); i->set_src1(address); i->set_src2(compare_value); i->set_src3(exchange_value); @@ -1859,9 +1753,8 @@ Value* HIRBuilder::CompareExchange( Value* HIRBuilder::AtomicExchange(Value* address, Value* new_value) { ASSERT_ADDRESS_TYPE(address); ASSERT_INTEGER_TYPE(new_value); - Instr* i = AppendInstr( - OPCODE_ATOMIC_EXCHANGE_info, 0, - AllocValue(new_value->type)); + Instr* i = + AppendInstr(OPCODE_ATOMIC_EXCHANGE_info, 0, AllocValue(new_value->type)); i->set_src1(address); i->set_src2(new_value); i->src3.value = NULL; @@ -1871,9 +1764,7 @@ Value* HIRBuilder::AtomicExchange(Value* address, Value* new_value) { Value* HIRBuilder::AtomicAdd(Value* address, Value* value) { ASSERT_ADDRESS_TYPE(address); ASSERT_INTEGER_TYPE(value); - Instr* i = AppendInstr( - OPCODE_ATOMIC_ADD_info, 0, - AllocValue(value->type)); + Instr* i = AppendInstr(OPCODE_ATOMIC_ADD_info, 0, AllocValue(value->type)); i->set_src1(address); i->set_src2(value); i->src3.value = NULL; @@ -1883,11 +1774,12 @@ Value* HIRBuilder::AtomicAdd(Value* address, Value* value) { Value* HIRBuilder::AtomicSub(Value* address, Value* value) { ASSERT_ADDRESS_TYPE(address); ASSERT_INTEGER_TYPE(value); - Instr* i = AppendInstr( - OPCODE_ATOMIC_SUB_info, 0, - AllocValue(value->type)); + Instr* i = AppendInstr(OPCODE_ATOMIC_SUB_info, 0, AllocValue(value->type)); i->set_src1(address); i->set_src2(value); i->src3.value = NULL; return i->dest; } + +} // namespace hir +} // namespace alloy diff --git a/src/alloy/hir/hir_builder.h b/src/alloy/hir/hir_builder.h index 7703dc8f1..9d01a69b6 100644 --- a/src/alloy/hir/hir_builder.h +++ b/src/alloy/hir/hir_builder.h @@ -17,17 +17,15 @@ #include #include - namespace alloy { namespace hir { enum FunctionAttributes { - FUNCTION_ATTRIB_INLINE = (1 << 1), + FUNCTION_ATTRIB_INLINE = (1 << 1), }; - class HIRBuilder { -public: + public: HIRBuilder(); virtual ~HIRBuilder(); @@ -86,10 +84,8 @@ public: void Branch(Label* label, uint32_t branch_flags = 0); void Branch(Block* block, uint32_t branch_flags = 0); - void BranchTrue(Value* cond, Label* label, - uint32_t branch_flags = 0); - void BranchFalse(Value* cond, Label* label, - uint32_t branch_flags = 0); + void BranchTrue(Value* cond, Label* label, uint32_t branch_flags = 0); + void BranchFalse(Value* cond, Label* label, uint32_t branch_flags = 0); // phi type_name, Block* b1, Value* v1, Block* b2, Value* v2, etc @@ -162,13 +158,12 @@ public: uint32_t arithmetic_flags = 0); Value* VectorAdd(Value* value1, Value* value2, TypeName part_type, uint32_t arithmetic_flags = 0); - Value* Sub(Value* value1, Value* value2, - uint32_t arithmetic_flags = 0); + Value* Sub(Value* value1, Value* value2, uint32_t arithmetic_flags = 0); Value* Mul(Value* value1, Value* value2, uint32_t arithmetic_flags = 0); Value* MulHi(Value* value1, Value* value2, uint32_t arithmetic_flags = 0); Value* Div(Value* value1, Value* value2, uint32_t arithmetic_flags = 0); - Value* MulAdd(Value* value1, Value* value2, Value* value3); // (1 * 2) + 3 - Value* MulSub(Value* value1, Value* value2, Value* value3); // (1 * 2) - 3 + Value* MulAdd(Value* value1, Value* value2, Value* value3); // (1 * 2) + 3 + Value* MulSub(Value* value1, Value* value2, Value* value3); // (1 * 2) - 3 Value* Neg(Value* value); Value* Abs(Value* value); Value* Sqrt(Value* value); @@ -208,48 +203,44 @@ public: Value* Pack(Value* value, uint32_t pack_flags = 0); Value* Unpack(Value* value, uint32_t pack_flags = 0); - Value* CompareExchange(Value* address, - Value* compare_value, Value* exchange_value); + Value* CompareExchange(Value* address, Value* compare_value, + Value* exchange_value); Value* AtomicExchange(Value* address, Value* new_value); Value* AtomicAdd(Value* address, Value* value); Value* AtomicSub(Value* address, Value* value); -protected: + protected: void DumpValue(StringBuffer* str, Value* value); - void DumpOp( - StringBuffer* str, OpcodeSignatureType sig_type, Instr::Op* op); + void DumpOp(StringBuffer* str, OpcodeSignatureType sig_type, Instr::Op* op); Value* AllocValue(TypeName type = INT64_TYPE); Value* CloneValue(Value* source); -private: + private: Block* AppendBlock(); void EndBlock(); bool IsUnconditionalJump(Instr* instr); - Instr* AppendInstr(const OpcodeInfo& opcode, uint16_t flags, - Value* dest = 0); + Instr* AppendInstr(const OpcodeInfo& opcode, uint16_t flags, Value* dest = 0); Value* CompareXX(const OpcodeInfo& opcode, Value* value1, Value* value2); - Value* VectorCompareXX( - const OpcodeInfo& opcode, Value* value1, Value* value2, TypeName part_type); + Value* VectorCompareXX(const OpcodeInfo& opcode, Value* value1, Value* value2, + TypeName part_type); -protected: - Arena* arena_; + protected: + Arena* arena_; - uint32_t attributes_; + uint32_t attributes_; - uint32_t next_label_id_; - uint32_t next_value_ordinal_; + uint32_t next_label_id_; + uint32_t next_value_ordinal_; std::vector locals_; - Block* block_head_; - Block* block_tail_; - Block* current_block_; + Block* block_head_; + Block* block_tail_; + Block* current_block_; }; - } // namespace hir } // namespace alloy - #endif // ALLOY_HIR_HIR_BUILDER_H_ diff --git a/src/alloy/hir/instr.cc b/src/alloy/hir/instr.cc index dc489ef4b..20271c016 100644 --- a/src/alloy/hir/instr.cc +++ b/src/alloy/hir/instr.cc @@ -11,9 +11,8 @@ #include -using namespace alloy; -using namespace alloy::hir; - +namespace alloy { +namespace hir { void Instr::set_src1(Value* value) { if (src1.value == value) { @@ -114,3 +113,6 @@ void Instr::Remove() { block->instr_tail = prev; } } + +} // namespace hir +} // namespace alloy diff --git a/src/alloy/hir/instr.h b/src/alloy/hir/instr.h index b128c534a..c72c7d9e2 100644 --- a/src/alloy/hir/instr.h +++ b/src/alloy/hir/instr.h @@ -14,9 +14,11 @@ #include #include - -namespace alloy { namespace runtime { class FunctionInfo; } } - +namespace alloy { +namespace runtime { +class FunctionInfo; +} // namespace runtime +} // namespace alloy namespace alloy { namespace hir { @@ -25,26 +27,26 @@ class Block; class Label; class Instr { -public: - Block* block; - Instr* next; - Instr* prev; + public: + Block* block; + Instr* next; + Instr* prev; const OpcodeInfo* opcode; - uint16_t flags; - uint32_t ordinal; + uint16_t flags; + uint32_t ordinal; typedef union { runtime::FunctionInfo* symbol_info; - Label* label; - Value* value; - uint64_t offset; + Label* label; + Value* value; + uint64_t offset; } Op; - Value* dest; - Op src1; - Op src2; - Op src3; + Value* dest; + Op src1; + Op src2; + Op src3; Value::Use* src1_use; Value::Use* src2_use; @@ -59,9 +61,7 @@ public: void Remove(); }; - } // namespace hir } // namespace alloy - #endif // ALLOY_HIR_INSTR_H_ diff --git a/src/alloy/hir/label.h b/src/alloy/hir/label.h index 35ff5cc09..74beaa92d 100644 --- a/src/alloy/hir/label.h +++ b/src/alloy/hir/label.h @@ -12,28 +12,24 @@ #include - namespace alloy { namespace hir { class Block; - class Label { -public: + public: Block* block; Label* next; Label* prev; - uint32_t id; - char* name; + uint32_t id; + char* name; - void* tag; + void* tag; }; - } // namespace hir } // namespace alloy - #endif // ALLOY_HIR_LABEL_H_ diff --git a/src/alloy/hir/opcodes.cc b/src/alloy/hir/opcodes.cc index 24880d5be..5c66c8b1d 100644 --- a/src/alloy/hir/opcodes.cc +++ b/src/alloy/hir/opcodes.cc @@ -9,15 +9,13 @@ #include -using namespace alloy; -using namespace alloy::hir; - - namespace alloy { namespace hir { #define DEFINE_OPCODE(num, name, sig, flags) \ - static const OpcodeInfo num##_info = { flags, sig, name, num, }; + static const OpcodeInfo num##_info = { \ + flags, sig, name, num, \ + }; #include #undef DEFINE_OPCODE diff --git a/src/alloy/hir/opcodes.h b/src/alloy/hir/opcodes.h index b52e7b55d..841d1f134 100644 --- a/src/alloy/hir/opcodes.h +++ b/src/alloy/hir/opcodes.h @@ -12,17 +12,15 @@ #include - namespace alloy { namespace hir { - enum CallFlags { - CALL_TAIL = (1 << 1), - CALL_POSSIBLE_RETURN = (1 << 2), + CALL_TAIL = (1 << 1), + CALL_POSSIBLE_RETURN = (1 << 2), }; enum BranchFlags { - BRANCH_LIKELY = (1 << 1), + BRANCH_LIKELY = (1 << 1), BRANCH_UNLIKELY = (1 << 2), }; enum RoundMode { @@ -33,20 +31,20 @@ enum RoundMode { ROUND_TO_POSITIVE_INFINITY, }; enum LoadFlags { - LOAD_NO_ALIAS = (1 << 1), - LOAD_ALIGNED = (1 << 2), - LOAD_UNALIGNED = (1 << 3), - LOAD_VOLATILE = (1 << 4), + LOAD_NO_ALIAS = (1 << 1), + LOAD_ALIGNED = (1 << 2), + LOAD_UNALIGNED = (1 << 3), + LOAD_VOLATILE = (1 << 4), }; enum StoreFlags { - STORE_NO_ALIAS = (1 << 1), - STORE_ALIGNED = (1 << 2), + STORE_NO_ALIAS = (1 << 1), + STORE_ALIGNED = (1 << 2), STORE_UNALIGNED = (1 << 3), - STORE_VOLATILE = (1 << 4), + STORE_VOLATILE = (1 << 4), }; enum PrefetchFlags { - PREFETCH_LOAD = (1 << 1), - PREFETCH_STORE = (1 << 2), + PREFETCH_LOAD = (1 << 1), + PREFETCH_STORE = (1 << 2), }; enum ArithmeticFlags { ARITHMETIC_SET_CARRY = (1 << 1), @@ -56,11 +54,8 @@ enum ArithmeticFlags { enum Permutes { PERMUTE_XY_ZW = 0x00010405, }; -#define SWIZZLE_MASK(x, y, z, w) ( \ - (((x) & 0x3) << 6) | \ - (((y) & 0x3) << 4) | \ - (((z) & 0x3) << 2) | \ - (((w) & 0x3))) +#define SWIZZLE_MASK(x, y, z, w) \ + ((((x)&0x3) << 6) | (((y)&0x3) << 4) | (((z)&0x3) << 2) | (((w)&0x3))) enum Swizzles { SWIZZLE_XYZW_TO_XYZW = SWIZZLE_MASK(0, 1, 2, 3), SWIZZLE_XYZW_TO_YZWX = SWIZZLE_MASK(1, 2, 3, 0), @@ -78,19 +73,14 @@ enum PackType { PACK_TYPE_S16_IN_32_HI = 7, }; - enum Opcode { OPCODE_COMMENT, OPCODE_NOP, - OPCODE_SOURCE_OFFSET, - OPCODE_DEBUG_BREAK, OPCODE_DEBUG_BREAK_TRUE, - OPCODE_TRAP, OPCODE_TRAP_TRUE, - OPCODE_CALL, OPCODE_CALL_TRUE, OPCODE_CALL_INDIRECT, @@ -99,11 +89,9 @@ enum Opcode { OPCODE_RETURN, OPCODE_RETURN_TRUE, OPCODE_SET_RETURN_ADDRESS, - OPCODE_BRANCH, OPCODE_BRANCH_TRUE, OPCODE_BRANCH_FALSE, - OPCODE_ASSIGN, OPCODE_CAST, OPCODE_ZERO_EXTEND, @@ -113,22 +101,16 @@ enum Opcode { OPCODE_ROUND, OPCODE_VECTOR_CONVERT_I2F, OPCODE_VECTOR_CONVERT_F2I, - OPCODE_LOAD_VECTOR_SHL, OPCODE_LOAD_VECTOR_SHR, - OPCODE_LOAD_CLOCK, - OPCODE_LOAD_LOCAL, OPCODE_STORE_LOCAL, - OPCODE_LOAD_CONTEXT, OPCODE_STORE_CONTEXT, - OPCODE_LOAD, OPCODE_STORE, OPCODE_PREFETCH, - OPCODE_MAX, OPCODE_MIN, OPCODE_SELECT, @@ -152,13 +134,12 @@ enum Opcode { OPCODE_VECTOR_COMPARE_SGE, OPCODE_VECTOR_COMPARE_UGT, OPCODE_VECTOR_COMPARE_UGE, - OPCODE_ADD, OPCODE_ADD_CARRY, OPCODE_VECTOR_ADD, OPCODE_SUB, OPCODE_MUL, - OPCODE_MUL_HI, // TODO(benvanik): remove this and add INT128 type. + OPCODE_MUL_HI, // TODO(benvanik): remove this and add INT128 type. OPCODE_DIV, OPCODE_MUL_ADD, OPCODE_MUL_SUB, @@ -170,7 +151,6 @@ enum Opcode { OPCODE_LOG2, OPCODE_DOT_PRODUCT_3, OPCODE_DOT_PRODUCT_4, - OPCODE_AND, OPCODE_OR, OPCODE_XOR, @@ -191,22 +171,20 @@ enum Opcode { OPCODE_SWIZZLE, OPCODE_PACK, OPCODE_UNPACK, - OPCODE_COMPARE_EXCHANGE, OPCODE_ATOMIC_EXCHANGE, OPCODE_ATOMIC_ADD, OPCODE_ATOMIC_SUB, - - __OPCODE_MAX_VALUE, // Keep at end. + __OPCODE_MAX_VALUE, // Keep at end. }; enum OpcodeFlags { - OPCODE_FLAG_BRANCH = (1 << 1), - OPCODE_FLAG_MEMORY = (1 << 2), + OPCODE_FLAG_BRANCH = (1 << 1), + OPCODE_FLAG_MEMORY = (1 << 2), OPCODE_FLAG_COMMUNATIVE = (1 << 3), - OPCODE_FLAG_VOLATILE = (1 << 4), - OPCODE_FLAG_IGNORE = (1 << 5), - OPCODE_FLAG_HIDE = (1 << 6), + OPCODE_FLAG_VOLATILE = (1 << 4), + OPCODE_FLAG_IGNORE = (1 << 5), + OPCODE_FLAG_HIDE = (1 << 6), OPCODE_FLAG_PAIRED_PREV = (1 << 7), }; @@ -220,26 +198,38 @@ enum OpcodeSignatureType { }; enum OpcodeSignature { - OPCODE_SIG_X = (OPCODE_SIG_TYPE_X), - OPCODE_SIG_X_L = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_L << 3), - OPCODE_SIG_X_O = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_O << 3), - OPCODE_SIG_X_O_V = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_O << 3) | (OPCODE_SIG_TYPE_V << 6), - OPCODE_SIG_X_S = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_S << 3), - OPCODE_SIG_X_V = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3), - OPCODE_SIG_X_V_L = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_L << 6), - OPCODE_SIG_X_V_L_L = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_L << 6) | (OPCODE_SIG_TYPE_L << 9), - OPCODE_SIG_X_V_O = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_O << 6), - OPCODE_SIG_X_V_S = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_S << 6), - OPCODE_SIG_X_V_V = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_V << 6), - OPCODE_SIG_X_V_V_V = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_V << 6) | (OPCODE_SIG_TYPE_V << 9), - OPCODE_SIG_V = (OPCODE_SIG_TYPE_V), - OPCODE_SIG_V_O = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_O << 3), - OPCODE_SIG_V_V = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3), - OPCODE_SIG_V_V_O = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_O << 6), - OPCODE_SIG_V_V_O_V = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_O << 6) | (OPCODE_SIG_TYPE_V << 9), - OPCODE_SIG_V_V_V = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_V << 6), - OPCODE_SIG_V_V_V_O = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_V << 6) | (OPCODE_SIG_TYPE_O << 9), - OPCODE_SIG_V_V_V_V = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_V << 6) | (OPCODE_SIG_TYPE_V << 9), + OPCODE_SIG_X = (OPCODE_SIG_TYPE_X), + OPCODE_SIG_X_L = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_L << 3), + OPCODE_SIG_X_O = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_O << 3), + OPCODE_SIG_X_O_V = + (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_O << 3) | (OPCODE_SIG_TYPE_V << 6), + OPCODE_SIG_X_S = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_S << 3), + OPCODE_SIG_X_V = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3), + OPCODE_SIG_X_V_L = + (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_L << 6), + OPCODE_SIG_X_V_L_L = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | + (OPCODE_SIG_TYPE_L << 6) | (OPCODE_SIG_TYPE_L << 9), + OPCODE_SIG_X_V_O = + (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_O << 6), + OPCODE_SIG_X_V_S = + (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_S << 6), + OPCODE_SIG_X_V_V = + (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_V << 6), + OPCODE_SIG_X_V_V_V = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | + (OPCODE_SIG_TYPE_V << 6) | (OPCODE_SIG_TYPE_V << 9), + OPCODE_SIG_V = (OPCODE_SIG_TYPE_V), + OPCODE_SIG_V_O = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_O << 3), + OPCODE_SIG_V_V = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3), + OPCODE_SIG_V_V_O = + (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_O << 6), + OPCODE_SIG_V_V_O_V = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3) | + (OPCODE_SIG_TYPE_O << 6) | (OPCODE_SIG_TYPE_V << 9), + OPCODE_SIG_V_V_V = + (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_V << 6), + OPCODE_SIG_V_V_V_O = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3) | + (OPCODE_SIG_TYPE_V << 6) | (OPCODE_SIG_TYPE_O << 9), + OPCODE_SIG_V_V_V_V = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3) | + (OPCODE_SIG_TYPE_V << 6) | (OPCODE_SIG_TYPE_V << 9), }; #define GET_OPCODE_SIG_TYPE_DEST(sig) (OpcodeSignatureType)(sig & 0x7) @@ -248,21 +238,17 @@ enum OpcodeSignature { #define GET_OPCODE_SIG_TYPE_SRC3(sig) (OpcodeSignatureType)((sig >> 9) & 0x7) typedef struct { - uint32_t flags; - uint32_t signature; + uint32_t flags; + uint32_t signature; const char* name; - Opcode num; + Opcode num; } OpcodeInfo; - -#define DEFINE_OPCODE(num, name, sig, flags) \ - extern const OpcodeInfo num##_info; +#define DEFINE_OPCODE(num, name, sig, flags) extern const OpcodeInfo num##_info; #include #undef DEFINE_OPCODE - } // namespace hir } // namespace alloy - #endif // ALLOY_HIR_OPCODES_H_ diff --git a/src/alloy/hir/tracing.h b/src/alloy/hir/tracing.h index fbc2325f7..a0ad6bd89 100644 --- a/src/alloy/hir/tracing.h +++ b/src/alloy/hir/tracing.h @@ -13,23 +13,19 @@ #include #include - namespace alloy { namespace hir { const uint32_t ALLOY_HIR = alloy::tracing::EventType::ALLOY_HIR; - class EventType { -public: + public: enum { - ALLOY_HIR_FOO = ALLOY_HIR | (0), + ALLOY_HIR_FOO = ALLOY_HIR | (0), }; }; - } // namespace hir } // namespace alloy - #endif // ALLOY_HIR_TRACING_H_ diff --git a/src/alloy/hir/value.cc b/src/alloy/hir/value.cc index 0f723e943..3d78c407b 100644 --- a/src/alloy/hir/value.cc +++ b/src/alloy/hir/value.cc @@ -9,9 +9,8 @@ #include -using namespace alloy; -using namespace alloy::hir; - +namespace alloy { +namespace hir { Value::Use* Value::AddUse(Arena* arena, Instr* instr) { Use* use = arena->Alloc(); @@ -39,34 +38,34 @@ void Value::RemoveUse(Use* use) { uint32_t Value::AsUint32() { XEASSERT(IsConstant()); switch (type) { - case INT8_TYPE: - return constant.i8; - case INT16_TYPE: - return constant.i16; - case INT32_TYPE: - return constant.i32; - case INT64_TYPE: - return (uint32_t)constant.i64; - default: - XEASSERTALWAYS(); - return 0; + case INT8_TYPE: + return constant.i8; + case INT16_TYPE: + return constant.i16; + case INT32_TYPE: + return constant.i32; + case INT64_TYPE: + return (uint32_t)constant.i64; + default: + XEASSERTALWAYS(); + return 0; } } uint64_t Value::AsUint64() { XEASSERT(IsConstant()); switch (type) { - case INT8_TYPE: - return constant.i8; - case INT16_TYPE: - return constant.i16; - case INT32_TYPE: - return constant.i32; - case INT64_TYPE: - return constant.i64; - default: - XEASSERTALWAYS(); - return 0; + case INT8_TYPE: + return constant.i8; + case INT16_TYPE: + return constant.i16; + case INT32_TYPE: + return constant.i32; + case INT64_TYPE: + return constant.i64; + default: + XEASSERTALWAYS(); + return 0; } } @@ -77,87 +76,6 @@ void Value::Cast(TypeName target_type) { void Value::ZeroExtend(TypeName target_type) { switch (type) { - case INT8_TYPE: - type = target_type; - constant.i64 = constant.i64 & 0xFF; - return; - case INT16_TYPE: - type = target_type; - constant.i64 = constant.i64 & 0xFFFF; - return; - case INT32_TYPE: - type = target_type; - constant.i64 = constant.i64 & 0xFFFFFFFF; - return; - } - // Unsupported types. - XEASSERTALWAYS(); -} - -void Value::SignExtend(TypeName target_type) { - switch (type) { - case INT8_TYPE: - type = target_type; - switch (target_type) { - case INT16_TYPE: - constant.i16 = constant.i8; - break; - case INT32_TYPE: - constant.i32 = constant.i8; - break; - case INT64_TYPE: - constant.i64 = constant.i8; - break; - } - return; - case INT16_TYPE: - type = target_type; - switch (target_type) { - case INT32_TYPE: - constant.i32 = constant.i16; - break; - case INT64_TYPE: - constant.i64 = constant.i16; - break; - } - return; - case INT32_TYPE: - type = target_type; - switch (target_type) { - case INT64_TYPE: - constant.i64 = constant.i32; - break; - } - return; - } - // Unsupported types. - XEASSERTALWAYS(); -} - -void Value::Truncate(TypeName target_type) { - switch (type) { - case INT16_TYPE: - switch (target_type) { - case INT8_TYPE: - type = target_type; - constant.i64 = constant.i64 & 0xFF; - return; - } - break; - case INT32_TYPE: - switch (target_type) { - case INT8_TYPE: - type = target_type; - constant.i64 = constant.i64 & 0xFF; - return; - case INT16_TYPE: - type = target_type; - constant.i64 = constant.i64 & 0xFFFF; - return; - } - break; - case INT64_TYPE: - switch (target_type) { case INT8_TYPE: type = target_type; constant.i64 = constant.i64 & 0xFF; @@ -170,8 +88,89 @@ void Value::Truncate(TypeName target_type) { type = target_type; constant.i64 = constant.i64 & 0xFFFFFFFF; return; - } - break; + } + // Unsupported types. + XEASSERTALWAYS(); +} + +void Value::SignExtend(TypeName target_type) { + switch (type) { + case INT8_TYPE: + type = target_type; + switch (target_type) { + case INT16_TYPE: + constant.i16 = constant.i8; + break; + case INT32_TYPE: + constant.i32 = constant.i8; + break; + case INT64_TYPE: + constant.i64 = constant.i8; + break; + } + return; + case INT16_TYPE: + type = target_type; + switch (target_type) { + case INT32_TYPE: + constant.i32 = constant.i16; + break; + case INT64_TYPE: + constant.i64 = constant.i16; + break; + } + return; + case INT32_TYPE: + type = target_type; + switch (target_type) { + case INT64_TYPE: + constant.i64 = constant.i32; + break; + } + return; + } + // Unsupported types. + XEASSERTALWAYS(); +} + +void Value::Truncate(TypeName target_type) { + switch (type) { + case INT16_TYPE: + switch (target_type) { + case INT8_TYPE: + type = target_type; + constant.i64 = constant.i64 & 0xFF; + return; + } + break; + case INT32_TYPE: + switch (target_type) { + case INT8_TYPE: + type = target_type; + constant.i64 = constant.i64 & 0xFF; + return; + case INT16_TYPE: + type = target_type; + constant.i64 = constant.i64 & 0xFFFF; + return; + } + break; + case INT64_TYPE: + switch (target_type) { + case INT8_TYPE: + type = target_type; + constant.i64 = constant.i64 & 0xFF; + return; + case INT16_TYPE: + type = target_type; + constant.i64 = constant.i64 & 0xFFFF; + return; + case INT32_TYPE: + type = target_type; + constant.i64 = constant.i64 & 0xFFFFFFFF; + return; + } + break; } // Unsupported types. XEASSERTALWAYS(); @@ -188,70 +187,70 @@ void Value::Round(RoundMode round_mode) { } bool Value::Add(Value* other) { - #define CHECK_DID_CARRY(v1, v2) (((uint64_t)v2) > ~((uint64_t)v1)) - #define ADD_DID_CARRY(a, b) CHECK_DID_CARRY(a, b) +#define CHECK_DID_CARRY(v1, v2) (((uint64_t)v2) > ~((uint64_t)v1)) +#define ADD_DID_CARRY(a, b) CHECK_DID_CARRY(a, b) XEASSERT(type == other->type); bool did_carry = false; switch (type) { - case INT8_TYPE: - did_carry = ADD_DID_CARRY(constant.i8, other->constant.i8); - constant.i8 += other->constant.i8; - break; - case INT16_TYPE: - did_carry = ADD_DID_CARRY(constant.i16, other->constant.i16); - constant.i16 += other->constant.i16; - break; - case INT32_TYPE: - did_carry = ADD_DID_CARRY(constant.i32, other->constant.i32); - constant.i32 += other->constant.i32; - break; - case INT64_TYPE: - did_carry = ADD_DID_CARRY(constant.i64, other->constant.i64); - constant.i64 += other->constant.i64; - break; - case FLOAT32_TYPE: - constant.f32 += other->constant.f32; - break; - case FLOAT64_TYPE: - constant.f64 += other->constant.f64; - break; - default: - XEASSERTALWAYS(); - break; + case INT8_TYPE: + did_carry = ADD_DID_CARRY(constant.i8, other->constant.i8); + constant.i8 += other->constant.i8; + break; + case INT16_TYPE: + did_carry = ADD_DID_CARRY(constant.i16, other->constant.i16); + constant.i16 += other->constant.i16; + break; + case INT32_TYPE: + did_carry = ADD_DID_CARRY(constant.i32, other->constant.i32); + constant.i32 += other->constant.i32; + break; + case INT64_TYPE: + did_carry = ADD_DID_CARRY(constant.i64, other->constant.i64); + constant.i64 += other->constant.i64; + break; + case FLOAT32_TYPE: + constant.f32 += other->constant.f32; + break; + case FLOAT64_TYPE: + constant.f64 += other->constant.f64; + break; + default: + XEASSERTALWAYS(); + break; } return did_carry; } bool Value::Sub(Value* other) { - #define SUB_DID_CARRY(a, b) (b > a) +#define SUB_DID_CARRY(a, b) (b > a) XEASSERT(type == other->type); bool did_carry = false; switch (type) { - case INT8_TYPE: - did_carry = SUB_DID_CARRY(constant.i8, other->constant.i8); - constant.i8 -= other->constant.i8; - break; - case INT16_TYPE: - did_carry = SUB_DID_CARRY(constant.i16, other->constant.i16); - constant.i16 -= other->constant.i16; - break; - case INT32_TYPE: - did_carry = SUB_DID_CARRY(constant.i32, other->constant.i32); - constant.i32 -= other->constant.i32; - break; - case INT64_TYPE: - did_carry = SUB_DID_CARRY(constant.i64, other->constant.i64); - constant.i64 -= other->constant.i64; - break; - case FLOAT32_TYPE: - constant.f32 -= other->constant.f32; - break; - case FLOAT64_TYPE: - constant.f64 -= other->constant.f64; - break; - default: - XEASSERTALWAYS(); - break; + case INT8_TYPE: + did_carry = SUB_DID_CARRY(constant.i8, other->constant.i8); + constant.i8 -= other->constant.i8; + break; + case INT16_TYPE: + did_carry = SUB_DID_CARRY(constant.i16, other->constant.i16); + constant.i16 -= other->constant.i16; + break; + case INT32_TYPE: + did_carry = SUB_DID_CARRY(constant.i32, other->constant.i32); + constant.i32 -= other->constant.i32; + break; + case INT64_TYPE: + did_carry = SUB_DID_CARRY(constant.i64, other->constant.i64); + constant.i64 -= other->constant.i64; + break; + case FLOAT32_TYPE: + constant.f32 -= other->constant.f32; + break; + case FLOAT64_TYPE: + constant.f64 -= other->constant.f64; + break; + default: + XEASSERTALWAYS(); + break; } return did_carry; } @@ -259,54 +258,54 @@ bool Value::Sub(Value* other) { void Value::Mul(Value* other) { XEASSERT(type == other->type); switch (type) { - case INT8_TYPE: - constant.i8 *= other->constant.i8; - break; - case INT16_TYPE: - constant.i16 *= other->constant.i16; - break; - case INT32_TYPE: - constant.i32 *= other->constant.i32; - break; - case INT64_TYPE: - constant.i64 *= other->constant.i64; - break; - case FLOAT32_TYPE: - constant.f32 *= other->constant.f32; - break; - case FLOAT64_TYPE: - constant.f64 *= other->constant.f64; - break; - default: - XEASSERTALWAYS(); - break; + case INT8_TYPE: + constant.i8 *= other->constant.i8; + break; + case INT16_TYPE: + constant.i16 *= other->constant.i16; + break; + case INT32_TYPE: + constant.i32 *= other->constant.i32; + break; + case INT64_TYPE: + constant.i64 *= other->constant.i64; + break; + case FLOAT32_TYPE: + constant.f32 *= other->constant.f32; + break; + case FLOAT64_TYPE: + constant.f64 *= other->constant.f64; + break; + default: + XEASSERTALWAYS(); + break; } } void Value::Div(Value* other) { XEASSERT(type == other->type); switch (type) { - case INT8_TYPE: - constant.i8 /= other->constant.i8; - break; - case INT16_TYPE: - constant.i16 /= other->constant.i16; - break; - case INT32_TYPE: - constant.i32 /= other->constant.i32; - break; - case INT64_TYPE: - constant.i64 /= other->constant.i64; - break; - case FLOAT32_TYPE: - constant.f32 /= other->constant.f32; - break; - case FLOAT64_TYPE: - constant.f64 /= other->constant.f64; - break; - default: - XEASSERTALWAYS(); - break; + case INT8_TYPE: + constant.i8 /= other->constant.i8; + break; + case INT16_TYPE: + constant.i16 /= other->constant.i16; + break; + case INT32_TYPE: + constant.i32 /= other->constant.i32; + break; + case INT64_TYPE: + constant.i64 /= other->constant.i64; + break; + case FLOAT32_TYPE: + constant.f32 /= other->constant.f32; + break; + case FLOAT64_TYPE: + constant.f64 /= other->constant.f64; + break; + default: + XEASSERTALWAYS(); + break; } } @@ -322,276 +321,276 @@ void Value::MulSub(Value* dest, Value* value1, Value* value2, Value* value3) { void Value::Neg() { switch (type) { - case INT8_TYPE: - constant.i8 = -constant.i8; - break; - case INT16_TYPE: - constant.i16 = -constant.i16; - break; - case INT32_TYPE: - constant.i32 = -constant.i32; - break; - case INT64_TYPE: - constant.i64 = -constant.i64; - break; - case FLOAT32_TYPE: - constant.f32 = -constant.f32; - break; - case FLOAT64_TYPE: - constant.f64 = -constant.f64; - break; - default: - XEASSERTALWAYS(); - break; + case INT8_TYPE: + constant.i8 = -constant.i8; + break; + case INT16_TYPE: + constant.i16 = -constant.i16; + break; + case INT32_TYPE: + constant.i32 = -constant.i32; + break; + case INT64_TYPE: + constant.i64 = -constant.i64; + break; + case FLOAT32_TYPE: + constant.f32 = -constant.f32; + break; + case FLOAT64_TYPE: + constant.f64 = -constant.f64; + break; + default: + XEASSERTALWAYS(); + break; } } void Value::Abs() { switch (type) { - case INT8_TYPE: - constant.i8 = abs(constant.i8); - break; - case INT16_TYPE: - constant.i16 = abs(constant.i16); - break; - case INT32_TYPE: - constant.i32 = abs(constant.i32); - break; - case INT64_TYPE: - constant.i64 = abs(constant.i64); - break; - case FLOAT32_TYPE: - constant.f32 = abs(constant.f32); - break; - case FLOAT64_TYPE: - constant.f64 = abs(constant.f64); - break; - default: - XEASSERTALWAYS(); - break; + case INT8_TYPE: + constant.i8 = abs(constant.i8); + break; + case INT16_TYPE: + constant.i16 = abs(constant.i16); + break; + case INT32_TYPE: + constant.i32 = abs(constant.i32); + break; + case INT64_TYPE: + constant.i64 = abs(constant.i64); + break; + case FLOAT32_TYPE: + constant.f32 = abs(constant.f32); + break; + case FLOAT64_TYPE: + constant.f64 = abs(constant.f64); + break; + default: + XEASSERTALWAYS(); + break; } } void Value::Sqrt() { switch (type) { - case FLOAT32_TYPE: - constant.f32 = 1.0f / sqrtf(constant.f32); - break; - case FLOAT64_TYPE: - constant.f64 = 1.0 / sqrt(constant.f64); - break; - default: - XEASSERTALWAYS(); - break; + case FLOAT32_TYPE: + constant.f32 = 1.0f / sqrtf(constant.f32); + break; + case FLOAT64_TYPE: + constant.f64 = 1.0 / sqrt(constant.f64); + break; + default: + XEASSERTALWAYS(); + break; } } void Value::RSqrt() { switch (type) { - case FLOAT32_TYPE: - constant.f32 = sqrt(constant.f32); - break; - case FLOAT64_TYPE: - constant.f64 = sqrt(constant.f64); - break; - default: - XEASSERTALWAYS(); - break; + case FLOAT32_TYPE: + constant.f32 = sqrt(constant.f32); + break; + case FLOAT64_TYPE: + constant.f64 = sqrt(constant.f64); + break; + default: + XEASSERTALWAYS(); + break; } } void Value::And(Value* other) { XEASSERT(type == other->type); switch (type) { - case INT8_TYPE: - constant.i8 &= other->constant.i8; - break; - case INT16_TYPE: - constant.i16 &= other->constant.i16; - break; - case INT32_TYPE: - constant.i32 &= other->constant.i32; - break; - case INT64_TYPE: - constant.i64 &= other->constant.i64; - break; - default: - XEASSERTALWAYS(); - break; + case INT8_TYPE: + constant.i8 &= other->constant.i8; + break; + case INT16_TYPE: + constant.i16 &= other->constant.i16; + break; + case INT32_TYPE: + constant.i32 &= other->constant.i32; + break; + case INT64_TYPE: + constant.i64 &= other->constant.i64; + break; + default: + XEASSERTALWAYS(); + break; } } void Value::Or(Value* other) { XEASSERT(type == other->type); switch (type) { - case INT8_TYPE: - constant.i8 |= other->constant.i8; - break; - case INT16_TYPE: - constant.i16 |= other->constant.i16; - break; - case INT32_TYPE: - constant.i32 |= other->constant.i32; - break; - case INT64_TYPE: - constant.i64 |= other->constant.i64; - break; - default: - XEASSERTALWAYS(); - break; + case INT8_TYPE: + constant.i8 |= other->constant.i8; + break; + case INT16_TYPE: + constant.i16 |= other->constant.i16; + break; + case INT32_TYPE: + constant.i32 |= other->constant.i32; + break; + case INT64_TYPE: + constant.i64 |= other->constant.i64; + break; + default: + XEASSERTALWAYS(); + break; } } void Value::Xor(Value* other) { XEASSERT(type == other->type); switch (type) { - case INT8_TYPE: - constant.i8 ^= other->constant.i8; - break; - case INT16_TYPE: - constant.i16 ^= other->constant.i16; - break; - case INT32_TYPE: - constant.i32 ^= other->constant.i32; - break; - case INT64_TYPE: - constant.i64 ^= other->constant.i64; - break; - default: - XEASSERTALWAYS(); - break; + case INT8_TYPE: + constant.i8 ^= other->constant.i8; + break; + case INT16_TYPE: + constant.i16 ^= other->constant.i16; + break; + case INT32_TYPE: + constant.i32 ^= other->constant.i32; + break; + case INT64_TYPE: + constant.i64 ^= other->constant.i64; + break; + default: + XEASSERTALWAYS(); + break; } } void Value::Not() { switch (type) { - case INT8_TYPE: - constant.i8 = ~constant.i8; - break; - case INT16_TYPE: - constant.i16 = ~constant.i16; - break; - case INT32_TYPE: - constant.i32 = ~constant.i32; - break; - case INT64_TYPE: - constant.i64 = ~constant.i64; - break; - case VEC128_TYPE: - constant.v128.low = ~constant.v128.low; - constant.v128.high = ~constant.v128.high; - break; - default: - XEASSERTALWAYS(); - break; + case INT8_TYPE: + constant.i8 = ~constant.i8; + break; + case INT16_TYPE: + constant.i16 = ~constant.i16; + break; + case INT32_TYPE: + constant.i32 = ~constant.i32; + break; + case INT64_TYPE: + constant.i64 = ~constant.i64; + break; + case VEC128_TYPE: + constant.v128.low = ~constant.v128.low; + constant.v128.high = ~constant.v128.high; + break; + default: + XEASSERTALWAYS(); + break; } } void Value::Shl(Value* other) { XEASSERT(other->type == INT8_TYPE); switch (type) { - case INT8_TYPE: - constant.i8 <<= other->constant.i8; - break; - case INT16_TYPE: - constant.i16 <<= other->constant.i8; - break; - case INT32_TYPE: - constant.i32 <<= other->constant.i8; - break; - case INT64_TYPE: - constant.i64 <<= other->constant.i8; - break; - default: - XEASSERTALWAYS(); - break; + case INT8_TYPE: + constant.i8 <<= other->constant.i8; + break; + case INT16_TYPE: + constant.i16 <<= other->constant.i8; + break; + case INT32_TYPE: + constant.i32 <<= other->constant.i8; + break; + case INT64_TYPE: + constant.i64 <<= other->constant.i8; + break; + default: + XEASSERTALWAYS(); + break; } } void Value::Shr(Value* other) { XEASSERT(other->type == INT8_TYPE); switch (type) { - case INT8_TYPE: - constant.i8 = (uint8_t)constant.i8 >> other->constant.i8; - break; - case INT16_TYPE: - constant.i16 = (uint16_t)constant.i16 >> other->constant.i8; - break; - case INT32_TYPE: - constant.i32 = (uint32_t)constant.i32 >> other->constant.i8; - break; - case INT64_TYPE: - constant.i64 = (uint16_t)constant.i64 >> other->constant.i8; - break; - default: - XEASSERTALWAYS(); - break; + case INT8_TYPE: + constant.i8 = (uint8_t)constant.i8 >> other->constant.i8; + break; + case INT16_TYPE: + constant.i16 = (uint16_t)constant.i16 >> other->constant.i8; + break; + case INT32_TYPE: + constant.i32 = (uint32_t)constant.i32 >> other->constant.i8; + break; + case INT64_TYPE: + constant.i64 = (uint16_t)constant.i64 >> other->constant.i8; + break; + default: + XEASSERTALWAYS(); + break; } } void Value::Sha(Value* other) { XEASSERT(other->type == INT8_TYPE); switch (type) { - case INT8_TYPE: - constant.i8 = constant.i8 >> other->constant.i8; - break; - case INT16_TYPE: - constant.i16 = constant.i16 >> other->constant.i8; - break; - case INT32_TYPE: - constant.i32 = constant.i32 >> other->constant.i8; - break; - case INT64_TYPE: - constant.i64 = constant.i64 >> other->constant.i8; - break; - default: - XEASSERTALWAYS(); - break; + case INT8_TYPE: + constant.i8 = constant.i8 >> other->constant.i8; + break; + case INT16_TYPE: + constant.i16 = constant.i16 >> other->constant.i8; + break; + case INT32_TYPE: + constant.i32 = constant.i32 >> other->constant.i8; + break; + case INT64_TYPE: + constant.i64 = constant.i64 >> other->constant.i8; + break; + default: + XEASSERTALWAYS(); + break; } } void Value::ByteSwap() { switch (type) { - case INT8_TYPE: - constant.i8 = constant.i8; - break; - case INT16_TYPE: - constant.i16 = XESWAP16(constant.i16); - break; - case INT32_TYPE: - constant.i32 = XESWAP32(constant.i32); - break; - case INT64_TYPE: - constant.i64 = XESWAP64(constant.i64); - break; - case VEC128_TYPE: - for (int n = 0; n < 4; n++) { - constant.v128.i4[n] = XESWAP32(constant.v128.i4[n]); - } - break; - default: - XEASSERTALWAYS(); - break; + case INT8_TYPE: + constant.i8 = constant.i8; + break; + case INT16_TYPE: + constant.i16 = XESWAP16(constant.i16); + break; + case INT32_TYPE: + constant.i32 = XESWAP32(constant.i32); + break; + case INT64_TYPE: + constant.i64 = XESWAP64(constant.i64); + break; + case VEC128_TYPE: + for (int n = 0; n < 4; n++) { + constant.v128.i4[n] = XESWAP32(constant.v128.i4[n]); + } + break; + default: + XEASSERTALWAYS(); + break; } } void Value::CountLeadingZeros(const Value* other) { switch (other->type) { - case INT8_TYPE: - constant.i8 = static_cast(__lzcnt16(other->constant.i8) - 8); - break; - case INT16_TYPE: - constant.i8 = static_cast(__lzcnt16(other->constant.i16)); - break; - case INT32_TYPE: - constant.i8 = static_cast(__lzcnt(other->constant.i32)); - break; - case INT64_TYPE: - constant.i8 = static_cast(__lzcnt64(other->constant.i64)); - break; - default: - XEASSERTALWAYS(); - break; + case INT8_TYPE: + constant.i8 = static_cast(__lzcnt16(other->constant.i8) - 8); + break; + case INT16_TYPE: + constant.i8 = static_cast(__lzcnt16(other->constant.i16)); + break; + case INT32_TYPE: + constant.i8 = static_cast(__lzcnt(other->constant.i32)); + break; + case INT64_TYPE: + constant.i8 = static_cast(__lzcnt64(other->constant.i64)); + break; + default: + XEASSERTALWAYS(); + break; } } @@ -600,3 +599,6 @@ bool Value::Compare(Opcode opcode, Value* other) { XEASSERTALWAYS(); return false; } + +} // namespace hir +} // namespace alloy diff --git a/src/alloy/hir/value.h b/src/alloy/hir/value.h index 3c4e82619..edde60c67 100644 --- a/src/alloy/hir/value.h +++ b/src/alloy/hir/value.h @@ -14,58 +14,51 @@ #include #include - namespace alloy { namespace hir { class Instr; - enum TypeName { // Many tables rely on this ordering. - INT8_TYPE = 0, - INT16_TYPE = 1, - INT32_TYPE = 2, - INT64_TYPE = 3, - FLOAT32_TYPE = 4, - FLOAT64_TYPE = 5, - VEC128_TYPE = 6, - + INT8_TYPE = 0, + INT16_TYPE = 1, + INT32_TYPE = 2, + INT64_TYPE = 3, + FLOAT32_TYPE = 4, + FLOAT64_TYPE = 5, + VEC128_TYPE = 6, MAX_TYPENAME, }; -static bool IsIntType(TypeName type_name) { - return type_name <= INT64_TYPE; -} +static bool IsIntType(TypeName type_name) { return type_name <= INT64_TYPE; } static bool IsFloatType(TypeName type_name) { return type_name == FLOAT32_TYPE || type_name == FLOAT64_TYPE; } -static bool IsVecType(TypeName type_name) { - return type_name == VEC128_TYPE; -} +static bool IsVecType(TypeName type_name) { return type_name == VEC128_TYPE; } static size_t GetTypeSize(TypeName type_name) { switch (type_name) { - case INT8_TYPE: - return 1; - case INT16_TYPE: - return 2; - case INT32_TYPE: - return 4; - case INT64_TYPE: - return 8; - case FLOAT32_TYPE: - return 4; - case FLOAT64_TYPE: - return 8; - default: - case VEC128_TYPE: - return 16; + case INT8_TYPE: + return 1; + case INT16_TYPE: + return 2; + case INT32_TYPE: + return 4; + case INT64_TYPE: + return 8; + case FLOAT32_TYPE: + return 4; + case FLOAT64_TYPE: + return 8; + default: + case VEC128_TYPE: + return 16; } } enum ValueFlags { - VALUE_IS_CONSTANT = (1 << 1), - VALUE_IS_ALLOCATED = (1 << 2), // Used by backends. Do not set. + VALUE_IS_CONSTANT = (1 << 1), + VALUE_IS_ALLOCATED = (1 << 2), // Used by backends. Do not set. }; struct RegAssignment { @@ -74,23 +67,23 @@ struct RegAssignment { }; class Value { -public: + public: typedef struct Use_s { - Instr* instr; - Use_s* prev; - Use_s* next; + Instr* instr; + Use_s* prev; + Use_s* next; } Use; typedef union { - int8_t i8; - int16_t i16; - int32_t i32; - int64_t i64; - float f32; - double f64; - vec128_t v128; + int8_t i8; + int16_t i16; + int32_t i32; + int64_t i64; + float f32; + double f64; + vec128_t v128; } ConstantValue; -public: + public: uint32_t ordinal; TypeName type; @@ -98,14 +91,14 @@ public: RegAssignment reg; ConstantValue constant; - Instr* def; - Use* use_head; + Instr* def; + Use* use_head; // NOTE: for performance reasons this is not maintained during construction. - Instr* last_use; - Value* local_slot; + Instr* last_use; + Value* local_slot; // TODO(benvanik): remove to shrink size. - void* tag; + void* tag; Use* AddUse(Arena* arena, Instr* instr); void RemoveUse(Use* use); @@ -184,9 +177,7 @@ public: constant.v128 = other->constant.v128; } - inline bool IsConstant() const { - return !!(flags & VALUE_IS_CONSTANT); - } + inline bool IsConstant() const { return !!(flags & VALUE_IS_CONSTANT); } bool IsConstantTrue() const { if (type == VEC128_TYPE) { XEASSERTALWAYS(); @@ -201,8 +192,8 @@ public: } bool IsConstantZero() const { if (type == VEC128_TYPE) { - return (flags & VALUE_IS_CONSTANT) && - !constant.v128.low && !constant.v128.high; + return (flags & VALUE_IS_CONSTANT) && !constant.v128.low && + !constant.v128.high; } return (flags & VALUE_IS_CONSTANT) && !constant.i64; } @@ -210,160 +201,174 @@ public: if (type == VEC128_TYPE) { XEASSERTALWAYS(); } - return (flags & VALUE_IS_CONSTANT) && - (other->flags & VALUE_IS_CONSTANT) && + return (flags & VALUE_IS_CONSTANT) && (other->flags & VALUE_IS_CONSTANT) && constant.i64 == other->constant.i64; } bool IsConstantNE(Value* other) const { if (type == VEC128_TYPE) { XEASSERTALWAYS(); } - return (flags & VALUE_IS_CONSTANT) && - (other->flags & VALUE_IS_CONSTANT) && + return (flags & VALUE_IS_CONSTANT) && (other->flags & VALUE_IS_CONSTANT) && constant.i64 != other->constant.i64; } bool IsConstantSLT(Value* other) const { XEASSERT(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); switch (type) { - case INT8_TYPE: - return constant.i8 < other->constant.i8; - case INT16_TYPE: - return constant.i16 < other->constant.i16; - case INT32_TYPE: - return constant.i32 < other->constant.i32; - case INT64_TYPE: - return constant.i64 < other->constant.i64; - case FLOAT32_TYPE: - return constant.f32 < other->constant.f32; - case FLOAT64_TYPE: - return constant.f64 < other->constant.f64; - default: XEASSERTALWAYS(); return false; + case INT8_TYPE: + return constant.i8 < other->constant.i8; + case INT16_TYPE: + return constant.i16 < other->constant.i16; + case INT32_TYPE: + return constant.i32 < other->constant.i32; + case INT64_TYPE: + return constant.i64 < other->constant.i64; + case FLOAT32_TYPE: + return constant.f32 < other->constant.f32; + case FLOAT64_TYPE: + return constant.f64 < other->constant.f64; + default: + XEASSERTALWAYS(); + return false; } } bool IsConstantSLE(Value* other) const { XEASSERT(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); switch (type) { - case INT8_TYPE: - return constant.i8 <= other->constant.i8; - case INT16_TYPE: - return constant.i16 <= other->constant.i16; - case INT32_TYPE: - return constant.i32 <= other->constant.i32; - case INT64_TYPE: - return constant.i64 <= other->constant.i64; - case FLOAT32_TYPE: - return constant.f32 <= other->constant.f32; - case FLOAT64_TYPE: - return constant.f64 <= other->constant.f64; - default: XEASSERTALWAYS(); return false; + case INT8_TYPE: + return constant.i8 <= other->constant.i8; + case INT16_TYPE: + return constant.i16 <= other->constant.i16; + case INT32_TYPE: + return constant.i32 <= other->constant.i32; + case INT64_TYPE: + return constant.i64 <= other->constant.i64; + case FLOAT32_TYPE: + return constant.f32 <= other->constant.f32; + case FLOAT64_TYPE: + return constant.f64 <= other->constant.f64; + default: + XEASSERTALWAYS(); + return false; } } bool IsConstantSGT(Value* other) const { XEASSERT(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); switch (type) { - case INT8_TYPE: - return constant.i8 > other->constant.i8; - case INT16_TYPE: - return constant.i16 > other->constant.i16; - case INT32_TYPE: - return constant.i32 > other->constant.i32; - case INT64_TYPE: - return constant.i64 > other->constant.i64; - case FLOAT32_TYPE: - return constant.f32 > other->constant.f32; - case FLOAT64_TYPE: - return constant.f64 > other->constant.f64; - default: XEASSERTALWAYS(); return false; + case INT8_TYPE: + return constant.i8 > other->constant.i8; + case INT16_TYPE: + return constant.i16 > other->constant.i16; + case INT32_TYPE: + return constant.i32 > other->constant.i32; + case INT64_TYPE: + return constant.i64 > other->constant.i64; + case FLOAT32_TYPE: + return constant.f32 > other->constant.f32; + case FLOAT64_TYPE: + return constant.f64 > other->constant.f64; + default: + XEASSERTALWAYS(); + return false; } } bool IsConstantSGE(Value* other) const { XEASSERT(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); switch (type) { - case INT8_TYPE: - return constant.i8 >= other->constant.i8; - case INT16_TYPE: - return constant.i16 >= other->constant.i16; - case INT32_TYPE: - return constant.i32 >= other->constant.i32; - case INT64_TYPE: - return constant.i64 >= other->constant.i64; - case FLOAT32_TYPE: - return constant.f32 >= other->constant.f32; - case FLOAT64_TYPE: - return constant.f64 >= other->constant.f64; - default: XEASSERTALWAYS(); return false; + case INT8_TYPE: + return constant.i8 >= other->constant.i8; + case INT16_TYPE: + return constant.i16 >= other->constant.i16; + case INT32_TYPE: + return constant.i32 >= other->constant.i32; + case INT64_TYPE: + return constant.i64 >= other->constant.i64; + case FLOAT32_TYPE: + return constant.f32 >= other->constant.f32; + case FLOAT64_TYPE: + return constant.f64 >= other->constant.f64; + default: + XEASSERTALWAYS(); + return false; } } bool IsConstantULT(Value* other) const { XEASSERT(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); switch (type) { - case INT8_TYPE: - return (uint8_t)constant.i8 < (uint8_t)other->constant.i8; - case INT16_TYPE: - return (uint16_t)constant.i16 < (uint16_t)other->constant.i16; - case INT32_TYPE: - return (uint32_t)constant.i32 < (uint32_t)other->constant.i32; - case INT64_TYPE: - return (uint64_t)constant.i64 < (uint64_t)other->constant.i64; - case FLOAT32_TYPE: - return constant.f32 < other->constant.f32; - case FLOAT64_TYPE: - return constant.f64 < other->constant.f64; - default: XEASSERTALWAYS(); return false; + case INT8_TYPE: + return (uint8_t)constant.i8 < (uint8_t)other->constant.i8; + case INT16_TYPE: + return (uint16_t)constant.i16 < (uint16_t)other->constant.i16; + case INT32_TYPE: + return (uint32_t)constant.i32 < (uint32_t)other->constant.i32; + case INT64_TYPE: + return (uint64_t)constant.i64 < (uint64_t)other->constant.i64; + case FLOAT32_TYPE: + return constant.f32 < other->constant.f32; + case FLOAT64_TYPE: + return constant.f64 < other->constant.f64; + default: + XEASSERTALWAYS(); + return false; } } bool IsConstantULE(Value* other) const { XEASSERT(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); switch (type) { - case INT8_TYPE: - return (uint8_t)constant.i8 <= (uint8_t)other->constant.i8; - case INT16_TYPE: - return (uint16_t)constant.i16 <= (uint16_t)other->constant.i16; - case INT32_TYPE: - return (uint32_t)constant.i32 <= (uint32_t)other->constant.i32; - case INT64_TYPE: - return (uint64_t)constant.i64 <= (uint64_t)other->constant.i64; - case FLOAT32_TYPE: - return constant.f32 <= other->constant.f32; - case FLOAT64_TYPE: - return constant.f64 <= other->constant.f64; - default: XEASSERTALWAYS(); return false; + case INT8_TYPE: + return (uint8_t)constant.i8 <= (uint8_t)other->constant.i8; + case INT16_TYPE: + return (uint16_t)constant.i16 <= (uint16_t)other->constant.i16; + case INT32_TYPE: + return (uint32_t)constant.i32 <= (uint32_t)other->constant.i32; + case INT64_TYPE: + return (uint64_t)constant.i64 <= (uint64_t)other->constant.i64; + case FLOAT32_TYPE: + return constant.f32 <= other->constant.f32; + case FLOAT64_TYPE: + return constant.f64 <= other->constant.f64; + default: + XEASSERTALWAYS(); + return false; } } bool IsConstantUGT(Value* other) const { XEASSERT(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); switch (type) { - case INT8_TYPE: - return (uint8_t)constant.i8 > (uint8_t)other->constant.i8; - case INT16_TYPE: - return (uint16_t)constant.i16 > (uint16_t)other->constant.i16; - case INT32_TYPE: - return (uint32_t)constant.i32 > (uint32_t)other->constant.i32; - case INT64_TYPE: - return (uint64_t)constant.i64 > (uint64_t)other->constant.i64; - case FLOAT32_TYPE: - return constant.f32 > other->constant.f32; - case FLOAT64_TYPE: - return constant.f64 > other->constant.f64; - default: XEASSERTALWAYS(); return false; + case INT8_TYPE: + return (uint8_t)constant.i8 > (uint8_t)other->constant.i8; + case INT16_TYPE: + return (uint16_t)constant.i16 > (uint16_t)other->constant.i16; + case INT32_TYPE: + return (uint32_t)constant.i32 > (uint32_t)other->constant.i32; + case INT64_TYPE: + return (uint64_t)constant.i64 > (uint64_t)other->constant.i64; + case FLOAT32_TYPE: + return constant.f32 > other->constant.f32; + case FLOAT64_TYPE: + return constant.f64 > other->constant.f64; + default: + XEASSERTALWAYS(); + return false; } } bool IsConstantUGE(Value* other) const { XEASSERT(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); switch (type) { - case INT8_TYPE: - return (uint8_t)constant.i8 >= (uint8_t)other->constant.i8; - case INT16_TYPE: - return (uint16_t)constant.i16 >= (uint16_t)other->constant.i16; - case INT32_TYPE: - return (uint32_t)constant.i32 >= (uint32_t)other->constant.i32; - case INT64_TYPE: - return (uint64_t)constant.i64 >= (uint64_t)other->constant.i64; - case FLOAT32_TYPE: - return constant.f32 >= other->constant.f32; - case FLOAT64_TYPE: - return constant.f64 >= other->constant.f64; - default: XEASSERTALWAYS(); return false; + case INT8_TYPE: + return (uint8_t)constant.i8 >= (uint8_t)other->constant.i8; + case INT16_TYPE: + return (uint16_t)constant.i16 >= (uint16_t)other->constant.i16; + case INT32_TYPE: + return (uint32_t)constant.i32 >= (uint32_t)other->constant.i32; + case INT64_TYPE: + return (uint64_t)constant.i64 >= (uint64_t)other->constant.i64; + case FLOAT32_TYPE: + return constant.f32 >= other->constant.f32; + case FLOAT64_TYPE: + return constant.f64 >= other->constant.f64; + default: + XEASSERTALWAYS(); + return false; } } uint32_t AsUint32(); @@ -397,9 +402,7 @@ public: bool Compare(Opcode opcode, Value* other); }; - } // namespace hir } // namespace alloy - #endif // ALLOY_HIR_VALUE_H_ diff --git a/src/alloy/memory.cc b/src/alloy/memory.cc index 2933392dd..9fabfb9ba 100644 --- a/src/alloy/memory.cc +++ b/src/alloy/memory.cc @@ -13,11 +13,10 @@ #include #endif -using namespace alloy; +namespace alloy { - -Memory::Memory() : - membase_(0), reserve_address_(0) { +Memory::Memory() : membase_(0), reserve_address_(0) { +// TODO(benvanik): move to poly. #if XE_LIKE_WIN32 SYSTEM_INFO si; GetSystemInfo(&si); @@ -27,12 +26,9 @@ Memory::Memory() : #endif } -Memory::~Memory() { -} +Memory::~Memory() {} -int Memory::Initialize() { - return 0; -} +int Memory::Initialize() { return 0; } void Memory::Zero(uint64_t address, size_t size) { uint8_t* p = membase_ + address; @@ -50,15 +46,14 @@ void Memory::Copy(uint64_t dest, uint64_t src, size_t size) { XEIGNORE(xe_copy_memory(pdest, size, psrc, size)); } -uint64_t Memory::SearchAligned( - uint64_t start, uint64_t end, - const uint32_t* values, size_t value_count) { +uint64_t Memory::SearchAligned(uint64_t start, uint64_t end, + const uint32_t* values, size_t value_count) { XEASSERT(start <= end); - const uint32_t *p = (const uint32_t*)(membase_ + start); - const uint32_t *pe = (const uint32_t*)(membase_ + end); + const uint32_t* p = (const uint32_t*)(membase_ + start); + const uint32_t* pe = (const uint32_t*)(membase_ + end); while (p != pe) { if (*p == values[0]) { - const uint32_t *pc = p + 1; + const uint32_t* pc = p + 1; size_t matched = 1; for (size_t n = 1; n < value_count; n++, pc++) { if (*pc != values[n]) { @@ -74,3 +69,5 @@ uint64_t Memory::SearchAligned( } return 0; } + +} // namespace alloy diff --git a/src/alloy/memory.h b/src/alloy/memory.h index 72719cc4a..a29d12170 100644 --- a/src/alloy/memory.h +++ b/src/alloy/memory.h @@ -12,19 +12,16 @@ #include - namespace alloy { - enum { - MEMORY_FLAG_64KB_PAGES = (1 << 1), - MEMORY_FLAG_ZERO = (1 << 2), - MEMORY_FLAG_PHYSICAL = (1 << 3), + MEMORY_FLAG_64KB_PAGES = (1 << 1), + MEMORY_FLAG_ZERO = (1 << 2), + MEMORY_FLAG_PHYSICAL = (1 << 3), }; - class Memory { -public: + public: Memory(); virtual ~Memory(); @@ -42,8 +39,8 @@ public: void Fill(uint64_t address, size_t size, uint8_t value); void Copy(uint64_t dest, uint64_t src, size_t size); - uint64_t SearchAligned(uint64_t start, uint64_t end, - const uint32_t* values, size_t value_count); + uint64_t SearchAligned(uint64_t start, uint64_t end, const uint32_t* values, + size_t value_count); virtual uint8_t LoadI8(uint64_t address) = 0; virtual uint16_t LoadI16(uint64_t address) = 0; @@ -54,9 +51,8 @@ public: virtual void StoreI32(uint64_t address, uint32_t value) = 0; virtual void StoreI64(uint64_t address, uint64_t value) = 0; - virtual uint64_t HeapAlloc( - uint64_t base_address, size_t size, uint32_t flags, - uint32_t alignment = 0x20) = 0; + virtual uint64_t HeapAlloc(uint64_t base_address, size_t size, uint32_t flags, + uint32_t alignment = 0x20) = 0; virtual int HeapFree(uint64_t address, size_t size) = 0; virtual size_t QuerySize(uint64_t base_address) = 0; @@ -64,14 +60,12 @@ public: virtual int Protect(uint64_t address, size_t size, uint32_t access) = 0; virtual uint32_t QueryProtect(uint64_t address) = 0; -protected: - size_t system_page_size_; - uint8_t* membase_; - uint32_t reserve_address_; + protected: + size_t system_page_size_; + uint8_t* membase_; + uint32_t reserve_address_; }; - } // namespace alloy - #endif // ALLOY_MEMORY_H_ diff --git a/src/alloy/runtime/debug_info.cc b/src/alloy/runtime/debug_info.cc index ad6056eec..266e57946 100644 --- a/src/alloy/runtime/debug_info.cc +++ b/src/alloy/runtime/debug_info.cc @@ -9,18 +9,16 @@ #include -using namespace alloy; -using namespace alloy::runtime; +namespace alloy { +namespace runtime { - -DebugInfo::DebugInfo() : - source_disasm_(0), - raw_hir_disasm_(0), - hir_disasm_(0), - machine_code_disasm_(0), - source_map_count_(0), - source_map_(NULL) { -} +DebugInfo::DebugInfo() + : source_disasm_(0), + raw_hir_disasm_(0), + hir_disasm_(0), + machine_code_disasm_(0), + source_map_count_(0), + source_map_(NULL) {} DebugInfo::~DebugInfo() { xe_free(source_map_); @@ -70,3 +68,6 @@ SourceMapEntry* DebugInfo::LookupCodeOffset(uint64_t offset) { } return NULL; } + +} // namespace runtime +} // namespace alloy diff --git a/src/alloy/runtime/debug_info.h b/src/alloy/runtime/debug_info.h index 47d2aa277..8ed6b0b34 100644 --- a/src/alloy/runtime/debug_info.h +++ b/src/alloy/runtime/debug_info.h @@ -12,35 +12,28 @@ #include - namespace alloy { namespace runtime { - enum DebugInfoFlags { - DEBUG_INFO_NONE = 0, - - DEBUG_INFO_SOURCE_DISASM = (1 << 1), - DEBUG_INFO_RAW_HIR_DISASM = (1 << 2), - DEBUG_INFO_HIR_DISASM = (1 << 3), - DEBUG_INFO_MACHINE_CODE_DISASM = (1 << 4), - - DEBUG_INFO_SOURCE_MAP = (1 << 5), - - DEBUG_INFO_DEFAULT = DEBUG_INFO_SOURCE_MAP, - DEBUG_INFO_ALL_DISASM = 0xFFFF, + DEBUG_INFO_NONE = 0, + DEBUG_INFO_SOURCE_DISASM = (1 << 1), + DEBUG_INFO_RAW_HIR_DISASM = (1 << 2), + DEBUG_INFO_HIR_DISASM = (1 << 3), + DEBUG_INFO_MACHINE_CODE_DISASM = (1 << 4), + DEBUG_INFO_SOURCE_MAP = (1 << 5), + DEBUG_INFO_DEFAULT = DEBUG_INFO_SOURCE_MAP, + DEBUG_INFO_ALL_DISASM = 0xFFFF, }; - typedef struct SourceMapEntry_s { - uint64_t source_offset; // Original source address/offset. - uint64_t hir_offset; // Block ordinal (16b) | Instr ordinal (16b) - uint64_t code_offset; // Offset from emitted code start. + uint64_t source_offset; // Original source address/offset. + uint64_t hir_offset; // Block ordinal (16b) | Instr ordinal (16b) + uint64_t code_offset; // Offset from emitted code start. } SourceMapEntry; - class DebugInfo { -public: + public: DebugInfo(); ~DebugInfo(); @@ -53,13 +46,12 @@ public: const char* machine_code_disasm() const { return machine_code_disasm_; } void set_machine_code_disasm(char* value) { machine_code_disasm_ = value; } - void InitializeSourceMap(size_t source_map_count, - SourceMapEntry* source_map); + void InitializeSourceMap(size_t source_map_count, SourceMapEntry* source_map); SourceMapEntry* LookupSourceOffset(uint64_t offset); SourceMapEntry* LookupHIROffset(uint64_t offset); SourceMapEntry* LookupCodeOffset(uint64_t offset); -private: + private: char* source_disasm_; char* raw_hir_disasm_; char* hir_disasm_; @@ -69,9 +61,7 @@ private: SourceMapEntry* source_map_; }; - } // namespace runtime } // namespace alloy - #endif // ALLOY_RUNTIME_DEBUG_INFO_H_ diff --git a/src/alloy/runtime/debugger.cc b/src/alloy/runtime/debugger.cc index 565a6d6cb..fee71e67e 100644 --- a/src/alloy/runtime/debugger.cc +++ b/src/alloy/runtime/debugger.cc @@ -13,19 +13,15 @@ #include -using namespace alloy; -using namespace alloy::runtime; +namespace alloy { +namespace runtime { +Breakpoint::Breakpoint(Type type, uint64_t address) + : type_(type), address_(address) {} -Breakpoint::Breakpoint(Type type, uint64_t address) : - type_(type), address_(address) { -} +Breakpoint::~Breakpoint() {} -Breakpoint::~Breakpoint() { -} - -Debugger::Debugger(Runtime* runtime) : - runtime_(runtime) {} +Debugger::Debugger(Runtime* runtime) : runtime_(runtime) {} Debugger::~Debugger() {} @@ -134,8 +130,8 @@ int Debugger::RemoveBreakpoint(Breakpoint* breakpoint) { return 0; } -void Debugger::FindBreakpoints( - uint64_t address, std::vector& out_breakpoints) { +void Debugger::FindBreakpoints(uint64_t address, + std::vector& out_breakpoints) { std::lock_guard guard(breakpoints_lock_); out_breakpoints.clear(); @@ -191,8 +187,8 @@ void Debugger::OnFunctionDefined(FunctionInfo* symbol_info, } } -void Debugger::OnBreakpointHit( - ThreadState* thread_state, Breakpoint* breakpoint) { +void Debugger::OnBreakpointHit(ThreadState* thread_state, + Breakpoint* breakpoint) { // Suspend all threads immediately. SuspendAllThreads(); @@ -202,3 +198,6 @@ void Debugger::OnBreakpointHit( // Note that we stay suspended. } + +} // namespace runtime +} // namespace alloy diff --git a/src/alloy/runtime/debugger.h b/src/alloy/runtime/debugger.h index 344cb80ab..5eb399a0f 100644 --- a/src/alloy/runtime/debugger.h +++ b/src/alloy/runtime/debugger.h @@ -15,7 +15,6 @@ #include - namespace alloy { namespace runtime { @@ -25,14 +24,14 @@ class FunctionInfo; class Runtime; class ThreadState; - class Breakpoint { -public: + public: enum Type { TEMP_TYPE, CODE_TYPE, }; -public: + + public: Breakpoint(Type type, uint64_t address); ~Breakpoint(); @@ -42,42 +41,41 @@ public: const char* id() const { return id_.c_str(); } void set_id(const char* id) { id_ = id; } -private: + private: Type type_; uint64_t address_; std::string id_; }; - class DebugEvent { -public: - DebugEvent(Debugger* debugger) : - debugger_(debugger) {} + public: + DebugEvent(Debugger* debugger) : debugger_(debugger) {} virtual ~DebugEvent() {} Debugger* debugger() const { return debugger_; } -protected: + + protected: Debugger* debugger_; }; - class BreakpointHitEvent : public DebugEvent { -public: - BreakpointHitEvent( - Debugger* debugger, ThreadState* thread_state, Breakpoint* breakpoint) : - thread_state_(thread_state), breakpoint_(breakpoint), - DebugEvent(debugger) {} + public: + BreakpointHitEvent(Debugger* debugger, ThreadState* thread_state, + Breakpoint* breakpoint) + : thread_state_(thread_state), + breakpoint_(breakpoint), + DebugEvent(debugger) {} virtual ~BreakpointHitEvent() {} ThreadState* thread_state() const { return thread_state_; } Breakpoint* breakpoint() const { return breakpoint_; } -protected: + + protected: ThreadState* thread_state_; Breakpoint* breakpoint_; }; - class Debugger { -public: + public: Debugger(Runtime* runtime); ~Debugger(); @@ -87,12 +85,12 @@ public: int ResumeThread(uint32_t thread_id); int ResumeAllThreads(bool force = false); - void ForEachThread(std::function callback); + void ForEachThread(std::function callback); int AddBreakpoint(Breakpoint* breakpoint); int RemoveBreakpoint(Breakpoint* breakpoint); - void FindBreakpoints( - uint64_t address, std::vector& out_breakpoints); + void FindBreakpoints(uint64_t address, + std::vector& out_breakpoints); void OnThreadCreated(ThreadState* thread_state); void OnThreadDestroyed(ThreadState* thread_state); @@ -100,10 +98,10 @@ public: void OnBreakpointHit(ThreadState* thread_state, Breakpoint* breakpoint); -public: + public: Delegate breakpoint_hit; -private: + private: Runtime* runtime_; std::mutex threads_lock_; @@ -115,9 +113,7 @@ private: BreakpointMultimap breakpoints_; }; - } // namespace runtime } // namespace alloy - #endif // ALLOY_RUNTIME_DEBUGGER_H_ diff --git a/src/alloy/runtime/entry_table.cc b/src/alloy/runtime/entry_table.cc index 5238ec6ae..4d2bef52a 100644 --- a/src/alloy/runtime/entry_table.cc +++ b/src/alloy/runtime/entry_table.cc @@ -9,9 +9,8 @@ #include -using namespace alloy; -using namespace alloy::runtime; - +namespace alloy { +namespace runtime { EntryTable::EntryTable() = default; @@ -75,8 +74,7 @@ std::vector EntryTable::FindWithAddress(uint64_t address) { std::vector fns; for (auto it = map_.begin(); it != map_.end(); ++it) { Entry* entry = it->second; - if (address >= entry->address && - address <= entry->end_address) { + if (address >= entry->address && address <= entry->end_address) { if (entry->status == Entry::STATUS_READY) { fns.push_back(entry->function); } @@ -84,3 +82,6 @@ std::vector EntryTable::FindWithAddress(uint64_t address) { } return fns; } + +} // namespace runtime +} // namespace alloy diff --git a/src/alloy/runtime/entry_table.h b/src/alloy/runtime/entry_table.h index 9ff7729b1..206d36c15 100644 --- a/src/alloy/runtime/entry_table.h +++ b/src/alloy/runtime/entry_table.h @@ -14,30 +14,27 @@ #include - namespace alloy { namespace runtime { class Function; - typedef struct Entry_t { typedef enum { - STATUS_NEW = 0, + STATUS_NEW = 0, STATUS_COMPILING, STATUS_READY, STATUS_FAILED, } Status; - uint64_t address; - uint64_t end_address; - Status status; + uint64_t address; + uint64_t end_address; + Status status; Function* function; } Entry; - class EntryTable { -public: + public: EntryTable(); ~EntryTable(); @@ -46,16 +43,14 @@ public: std::vector FindWithAddress(uint64_t address); -private: + private: // TODO(benvanik): replace with a better data structure. std::mutex lock_; typedef std::unordered_map EntryMap; EntryMap map_; }; - } // namespace runtime } // namespace alloy - #endif // ALLOY_RUNTIME_ENTRY_TABLE_H_ diff --git a/src/alloy/runtime/function.cc b/src/alloy/runtime/function.cc index a5993be99..6b1125681 100644 --- a/src/alloy/runtime/function.cc +++ b/src/alloy/runtime/function.cc @@ -13,14 +13,13 @@ #include #include -using namespace alloy; -using namespace alloy::runtime; +namespace alloy { +namespace runtime { - -Function::Function(FunctionInfo* symbol_info) : - address_(symbol_info->address()), - symbol_info_(symbol_info), debug_info_(0) { -} +Function::Function(FunctionInfo* symbol_info) + : address_(symbol_info->address()), + symbol_info_(symbol_info), + debug_info_(0) {} Function::~Function() = default; @@ -75,16 +74,14 @@ int Function::Call(ThreadState* thread_state, uint64_t return_address) { } int result = 0; - + if (symbol_info_->behavior() == FunctionInfo::BEHAVIOR_EXTERN) { auto handler = symbol_info_->extern_handler(); if (handler) { - handler(thread_state->raw_context(), - symbol_info_->extern_arg0(), + handler(thread_state->raw_context(), symbol_info_->extern_arg0(), symbol_info_->extern_arg1()); } else { - XELOGW("undefined extern call to %.8X %s", - symbol_info_->address(), + XELOGW("undefined extern call to %.8X %s", symbol_info_->address(), symbol_info_->name()); result = 1; } @@ -97,3 +94,6 @@ int Function::Call(ThreadState* thread_state, uint64_t return_address) { } return result; } + +} // namespace runtime +} // namespace alloy diff --git a/src/alloy/runtime/function.h b/src/alloy/runtime/function.h index e34ff5119..3ea3c4c9e 100644 --- a/src/alloy/runtime/function.h +++ b/src/alloy/runtime/function.h @@ -16,7 +16,6 @@ #include #include - namespace alloy { namespace runtime { @@ -24,9 +23,8 @@ class Breakpoint; class FunctionInfo; class ThreadState; - class Function { -public: + public: Function(FunctionInfo* symbol_info); virtual ~Function(); @@ -41,14 +39,13 @@ public: int Call(ThreadState* thread_state, uint64_t return_address); -protected: + protected: Breakpoint* FindBreakpoint(uint64_t address); virtual int AddBreakpointImpl(Breakpoint* breakpoint) { return 0; } virtual int RemoveBreakpointImpl(Breakpoint* breakpoint) { return 0; } - virtual int CallImpl(ThreadState* thread_state, - uint64_t return_address) = 0; + virtual int CallImpl(ThreadState* thread_state, uint64_t return_address) = 0; -protected: + protected: uint64_t address_; FunctionInfo* symbol_info_; DebugInfo* debug_info_; @@ -58,9 +55,7 @@ protected: std::vector breakpoints_; }; - } // namespace runtime } // namespace alloy - #endif // ALLOY_RUNTIME_FUNCTION_H_ diff --git a/src/alloy/runtime/instrument.cc b/src/alloy/runtime/instrument.cc index 5bae5fc98..87bdcec78 100644 --- a/src/alloy/runtime/instrument.cc +++ b/src/alloy/runtime/instrument.cc @@ -13,16 +13,11 @@ #include #include -using namespace alloy; -using namespace alloy::runtime; +namespace alloy { +namespace runtime { - - -Instrument::Instrument(Runtime* runtime) : - runtime_(runtime), - memory_(runtime->memory()), - is_attached_(false) { -} +Instrument::Instrument(Runtime* runtime) + : runtime_(runtime), memory_(runtime->memory()), is_attached_(false) {} Instrument::~Instrument() { if (is_attached_) { @@ -34,7 +29,7 @@ bool Instrument::Attach() { if (is_attached_) { return false; } - //runtime->AttachInstrument(this); + // runtime->AttachInstrument(this); is_attached_ = true; return true; } @@ -44,16 +39,12 @@ bool Instrument::Detach() { return false; } is_attached_ = false; - //runtime->DetachInstrument(this); + // runtime->DetachInstrument(this); return true; } - -FunctionInstrument::FunctionInstrument( - Runtime* runtime, Function* function) : - target_(function), - Instrument(runtime) { -} +FunctionInstrument::FunctionInstrument(Runtime* runtime, Function* function) + : target_(function), Instrument(runtime) {} bool FunctionInstrument::Attach() { if (!Instrument::Attach()) { @@ -88,12 +79,9 @@ void FunctionInstrument::Exit(ThreadState* thread_state) { // } - -MemoryInstrument::MemoryInstrument( - Runtime* runtime, uint64_t address, uint64_t end_address) : - address_(address), end_address_(end_address), - Instrument(runtime) { -} +MemoryInstrument::MemoryInstrument(Runtime* runtime, uint64_t address, + uint64_t end_address) + : address_(address), end_address_(end_address), Instrument(runtime) {} bool MemoryInstrument::Attach() { if (!Instrument::Attach()) { @@ -116,7 +104,10 @@ bool MemoryInstrument::Detach() { return true; } -void MemoryInstrument::Access( - ThreadState* thread_state, uint64_t address, AccessType type) { +void MemoryInstrument::Access(ThreadState* thread_state, uint64_t address, + AccessType type) { // TODO(benvanik): get thread local instance } + +} // namespace runtime +} // namespace alloy diff --git a/src/alloy/runtime/instrument.h b/src/alloy/runtime/instrument.h index 2c45fc31c..c75d0ad09 100644 --- a/src/alloy/runtime/instrument.h +++ b/src/alloy/runtime/instrument.h @@ -14,7 +14,6 @@ XEDECLARECLASS1(alloy, Memory); - namespace alloy { namespace runtime { @@ -22,9 +21,8 @@ class Function; class Runtime; class ThreadState; - class Instrument { -public: + public: Instrument(Runtime* runtime); virtual ~Instrument(); @@ -35,15 +33,14 @@ public: virtual bool Attach(); virtual bool Detach(); -private: - Runtime* runtime_; - Memory* memory_; - bool is_attached_; + private: + Runtime* runtime_; + Memory* memory_; + bool is_attached_; }; - class FunctionInstrument : public Instrument { -public: + public: FunctionInstrument(Runtime* runtime, Function* function); virtual ~FunctionInstrument() {} @@ -52,13 +49,13 @@ public: virtual bool Attach(); virtual bool Detach(); -public: + public: void Enter(ThreadState* thread_state); void Exit(ThreadState* thread_state); -protected: + protected: class Instance { - public: + public: Instance(FunctionInstrument* instrument) : instrument_(instrument) {} virtual ~Instance() {} @@ -75,17 +72,16 @@ protected: // Call(target_fn/address) // Return(opt_value) - private: + private: FunctionInstrument* instrument_; }; -private: + private: Function* target_; }; - class MemoryInstrument : public Instrument { -public: + public: MemoryInstrument(Runtime* runtime, uint64_t address, uint64_t end_address); virtual ~MemoryInstrument() {} @@ -95,34 +91,33 @@ public: virtual bool Attach(); virtual bool Detach(); -public: + public: enum AccessType { ACCESS_READ = (1 << 1), ACCESS_WRITE = (1 << 2), }; void Access(ThreadState* thread_state, uint64_t address, AccessType type); -protected: + protected: class Instance { - public: + public: Instance(MemoryInstrument* instrument) : instrument_(instrument) {} virtual ~Instance() {} MemoryInstrument* instrument() const { return instrument_; } - virtual void OnAccess( - ThreadState* thread_state, uint64_t address, AccessType type) = 0; + virtual void OnAccess(ThreadState* thread_state, uint64_t address, + AccessType type) = 0; - private: + private: MemoryInstrument* instrument_; }; -private: + private: uint64_t address_; uint64_t end_address_; }; - // ThreadInstrument // (v Detach()) // ThreadInstrumentInstance: @@ -141,9 +136,7 @@ private: // v OnUnload(context) // // get proc address? - } // namespace runtime } // namespace alloy - #endif // ALLOY_RUNTIME_INSTRUMENT_H_ diff --git a/src/alloy/runtime/module.cc b/src/alloy/runtime/module.cc index 4cd4550c9..f144de2e3 100644 --- a/src/alloy/runtime/module.cc +++ b/src/alloy/runtime/module.cc @@ -14,12 +14,11 @@ #include -using namespace alloy; -using namespace alloy::runtime; +namespace alloy { +namespace runtime { - -Module::Module(Runtime* runtime) : - runtime_(runtime), memory_(runtime->memory()) {} +Module::Module(Runtime* runtime) + : runtime_(runtime), memory_(runtime->memory()) {} Module::~Module() { std::lock_guard guard(lock_); @@ -30,9 +29,7 @@ Module::~Module() { } } -bool Module::ContainsAddress(uint64_t address) { - return true; -} +bool Module::ContainsAddress(uint64_t address) { return true; } SymbolInfo* Module::LookupSymbol(uint64_t address, bool wait) { lock_.lock(); @@ -58,8 +55,9 @@ SymbolInfo* Module::LookupSymbol(uint64_t address, bool wait) { return symbol_info; } -SymbolInfo::Status Module::DeclareSymbol( - SymbolInfo::Type type, uint64_t address, SymbolInfo** out_symbol_info) { +SymbolInfo::Status Module::DeclareSymbol(SymbolInfo::Type type, + uint64_t address, + SymbolInfo** out_symbol_info) { *out_symbol_info = NULL; lock_.lock(); SymbolMap::const_iterator it = map_.find(address); @@ -85,12 +83,12 @@ SymbolInfo::Status Module::DeclareSymbol( } else { // Create and return for initialization. switch (type) { - case SymbolInfo::TYPE_FUNCTION: - symbol_info = new FunctionInfo(this, address); - break; - case SymbolInfo::TYPE_VARIABLE: - symbol_info = new VariableInfo(this, address); - break; + case SymbolInfo::TYPE_FUNCTION: + symbol_info = new FunctionInfo(this, address); + break; + case SymbolInfo::TYPE_VARIABLE: + symbol_info = new VariableInfo(this, address); + break; } map_[address] = symbol_info; list_.push_back(symbol_info); @@ -107,20 +105,20 @@ SymbolInfo::Status Module::DeclareSymbol( return status; } -SymbolInfo::Status Module::DeclareFunction( - uint64_t address, FunctionInfo** out_symbol_info) { +SymbolInfo::Status Module::DeclareFunction(uint64_t address, + FunctionInfo** out_symbol_info) { SymbolInfo* symbol_info; - SymbolInfo::Status status = DeclareSymbol( - SymbolInfo::TYPE_FUNCTION, address, &symbol_info); + SymbolInfo::Status status = + DeclareSymbol(SymbolInfo::TYPE_FUNCTION, address, &symbol_info); *out_symbol_info = (FunctionInfo*)symbol_info; return status; } -SymbolInfo::Status Module::DeclareVariable( - uint64_t address, VariableInfo** out_symbol_info) { +SymbolInfo::Status Module::DeclareVariable(uint64_t address, + VariableInfo** out_symbol_info) { SymbolInfo* symbol_info; - SymbolInfo::Status status = DeclareSymbol( - SymbolInfo::TYPE_VARIABLE, address, &symbol_info); + SymbolInfo::Status status = + DeclareSymbol(SymbolInfo::TYPE_VARIABLE, address, &symbol_info); *out_symbol_info = (VariableInfo*)symbol_info; return status; } @@ -156,7 +154,7 @@ SymbolInfo::Status Module::DefineVariable(VariableInfo* symbol_info) { return DefineSymbol((SymbolInfo*)symbol_info); } -void Module::ForEachFunction(std::function callback) { +void Module::ForEachFunction(std::function callback) { SCOPE_profile_cpu_f("alloy"); std::lock_guard guard(lock_); for (auto it = list_.begin(); it != list_.end(); ++it) { @@ -169,7 +167,7 @@ void Module::ForEachFunction(std::function callback) { } void Module::ForEachFunction(size_t since, size_t& version, - std::function callback) { + std::function callback) { SCOPE_profile_cpu_f("alloy"); std::lock_guard guard(lock_); size_t count = list_.size(); @@ -204,8 +202,7 @@ int Module::ReadMap(const char* file_name) { while (std::getline(infile, line)) { // Remove newline. while (line.size() && - (line[line.size() - 1] == '\r' || - line[line.size() - 1] == '\n')) { + (line[line.size() - 1] == '\r' || line[line.size() - 1] == '\n')) { line.erase(line.end() - 1); } @@ -254,3 +251,6 @@ int Module::ReadMap(const char* file_name) { return 0; } + +} // namespace runtime +} // namespace alloy diff --git a/src/alloy/runtime/module.h b/src/alloy/runtime/module.h index 63ca706fe..e55b18375 100644 --- a/src/alloy/runtime/module.h +++ b/src/alloy/runtime/module.h @@ -19,16 +19,14 @@ #include #include - namespace alloy { namespace runtime { class Function; class Runtime; - class Module { -public: + public: Module(Runtime* runtime); virtual ~Module(); @@ -39,30 +37,30 @@ public: virtual bool ContainsAddress(uint64_t address); SymbolInfo* LookupSymbol(uint64_t address, bool wait = true); - SymbolInfo::Status DeclareFunction( - uint64_t address, FunctionInfo** out_symbol_info); - SymbolInfo::Status DeclareVariable( - uint64_t address, VariableInfo** out_symbol_info); + SymbolInfo::Status DeclareFunction(uint64_t address, + FunctionInfo** out_symbol_info); + SymbolInfo::Status DeclareVariable(uint64_t address, + VariableInfo** out_symbol_info); SymbolInfo::Status DefineFunction(FunctionInfo* symbol_info); SymbolInfo::Status DefineVariable(VariableInfo* symbol_info); - void ForEachFunction(std::function callback); + void ForEachFunction(std::function callback); void ForEachFunction(size_t since, size_t& version, - std::function callback); + std::function callback); int ReadMap(const char* file_name); -private: - SymbolInfo::Status DeclareSymbol( - SymbolInfo::Type type, uint64_t address, SymbolInfo** out_symbol_info); + private: + SymbolInfo::Status DeclareSymbol(SymbolInfo::Type type, uint64_t address, + SymbolInfo** out_symbol_info); SymbolInfo::Status DefineSymbol(SymbolInfo* symbol_info); -protected: + protected: Runtime* runtime_; Memory* memory_; -private: + private: // TODO(benvanik): replace with a better data structure. std::mutex lock_; typedef std::unordered_map SymbolMap; @@ -71,9 +69,7 @@ private: SymbolList list_; }; - } // namespace runtime } // namespace alloy - #endif // ALLOY_RUNTIME_MODULE_H_ diff --git a/src/alloy/runtime/raw_module.cc b/src/alloy/runtime/raw_module.cc index c152dcf1c..32346bc1a 100644 --- a/src/alloy/runtime/raw_module.cc +++ b/src/alloy/runtime/raw_module.cc @@ -9,15 +9,15 @@ #include -using namespace alloy; -using namespace alloy::runtime; +namespace alloy { +namespace runtime { - -RawModule::RawModule(Runtime* runtime) : - name_(0), - base_address_(0), low_address_(0), high_address_(0), - Module(runtime) { -} +RawModule::RawModule(Runtime* runtime) + : name_(0), + base_address_(0), + low_address_(0), + high_address_(0), + Module(runtime) {} RawModule::~RawModule() { if (base_address_) { @@ -33,8 +33,8 @@ int RawModule::LoadFile(uint64_t base_address, const char* path) { fseek(file, 0, SEEK_SET); // Allocate memory. - base_address_ = memory_->HeapAlloc( - base_address, file_length, MEMORY_FLAG_ZERO); + base_address_ = + memory_->HeapAlloc(base_address, file_length, MEMORY_FLAG_ZERO); if (!base_address_) { fclose(file); return 1; @@ -59,3 +59,6 @@ int RawModule::LoadFile(uint64_t base_address, const char* path) { bool RawModule::ContainsAddress(uint64_t address) { return address >= low_address_ && address < high_address_; } + +} // namespace runtime +} // namespace alloy diff --git a/src/alloy/runtime/raw_module.h b/src/alloy/runtime/raw_module.h index 230e44f7e..dfedfb60c 100644 --- a/src/alloy/runtime/raw_module.h +++ b/src/alloy/runtime/raw_module.h @@ -12,13 +12,11 @@ #include - namespace alloy { namespace runtime { - class RawModule : public Module { -public: + public: RawModule(Runtime* runtime); virtual ~RawModule(); @@ -28,16 +26,14 @@ public: virtual bool ContainsAddress(uint64_t address); -private: - char* name_; - uint64_t base_address_; - uint64_t low_address_; - uint64_t high_address_; + private: + char* name_; + uint64_t base_address_; + uint64_t low_address_; + uint64_t high_address_; }; - } // namespace runtime } // namespace alloy - #endif // ALLOY_RUNTIME_RAW_MODULE_H_ diff --git a/src/alloy/runtime/runtime.cc b/src/alloy/runtime/runtime.cc index cf9cce22c..233dc0c07 100644 --- a/src/alloy/runtime/runtime.cc +++ b/src/alloy/runtime/runtime.cc @@ -14,26 +14,28 @@ #include #include -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::frontend; -using namespace alloy::runtime; +// TODO(benvanik): based on compiler support +#include +#include +DEFINE_string(runtime_backend, "any", "Runtime backend [any, ivm, x64]."); -DEFINE_string(runtime_backend, "any", - "Runtime backend [any, ivm, x64]."); +namespace alloy { +namespace runtime { +using alloy::backend::Backend; +using alloy::frontend::Frontend; -Runtime::Runtime(Memory* memory) : - memory_(memory), debugger_(0), backend_(0), frontend_(0) { +Runtime::Runtime(Memory* memory) + : memory_(memory), debugger_(0), backend_(0), frontend_(0) { tracing::Initialize(); } Runtime::~Runtime() { { std::lock_guard guard(modules_lock_); - for (ModuleList::iterator it = modules_.begin(); - it != modules_.end(); ++it) { + for (ModuleList::iterator it = modules_.begin(); it != modules_.end(); + ++it) { Module* module = *it; delete module; } @@ -46,10 +48,6 @@ Runtime::~Runtime() { tracing::Flush(); } -// TODO(benvanik): based on compiler support -#include -#include - int Runtime::Initialize(Frontend* frontend, Backend* backend) { // Must be initialized by subclass before calling into this. XEASSERTNOTNULL(memory_); @@ -64,27 +62,23 @@ int Runtime::Initialize(Frontend* frontend, Backend* backend) { if (!backend) { #if defined(ALLOY_HAS_X64_BACKEND) && ALLOY_HAS_X64_BACKEND if (FLAGS_runtime_backend == "x64") { - backend = new alloy::backend::x64::X64Backend( - this); + backend = new alloy::backend::x64::X64Backend(this); } #endif // ALLOY_HAS_X64_BACKEND #if defined(ALLOY_HAS_IVM_BACKEND) && ALLOY_HAS_IVM_BACKEND if (FLAGS_runtime_backend == "ivm") { - backend = new alloy::backend::ivm::IVMBackend( - this); + backend = new alloy::backend::ivm::IVMBackend(this); } #endif // ALLOY_HAS_IVM_BACKEND if (FLAGS_runtime_backend == "any") { #if defined(ALLOY_HAS_X64_BACKEND) && ALLOY_HAS_X64_BACKEND if (!backend) { - backend = new alloy::backend::x64::X64Backend( - this); + backend = new alloy::backend::x64::X64Backend(this); } #endif // ALLOY_HAS_X64_BACKEND #if defined(ALLOY_HAS_IVM_BACKEND) && ALLOY_HAS_IVM_BACKEND if (!backend) { - backend = new alloy::backend::ivm::IVMBackend( - this); + backend = new alloy::backend::ivm::IVMBackend(this); } #endif // ALLOY_HAS_IVM_BACKEND } @@ -118,8 +112,7 @@ int Runtime::AddModule(Module* module) { Module* Runtime::GetModule(const char* name) { std::lock_guard guard(modules_lock_); Module* result = NULL; - for (ModuleList::iterator it = modules_.begin(); - it != modules_.end(); ++it) { + for (ModuleList::iterator it = modules_.begin(); it != modules_.end(); ++it) { Module* module = *it; if (xestrcmpa(module->name(), name) == 0) { result = module; @@ -147,7 +140,7 @@ int Runtime::ResolveFunction(uint64_t address, Function** out_function) { Entry::Status status = entry_table_.GetOrCreate(address, &entry); if (status == Entry::STATUS_NEW) { // Needs to be generated. We have the 'lock' on it and must do so now. - + // Grab symbol declaration. FunctionInfo* symbol_info; int result = LookupFunctionInfo(address, &symbol_info); @@ -173,8 +166,8 @@ int Runtime::ResolveFunction(uint64_t address, Function** out_function) { } } -int Runtime::LookupFunctionInfo( - uint64_t address, FunctionInfo** out_symbol_info) { +int Runtime::LookupFunctionInfo(uint64_t address, + FunctionInfo** out_symbol_info) { SCOPE_profile_cpu_f("alloy"); *out_symbol_info = NULL; @@ -187,8 +180,8 @@ int Runtime::LookupFunctionInfo( std::lock_guard guard(modules_lock_); // TODO(benvanik): sort by code address (if contiguous) so can bsearch. // TODO(benvanik): cache last module low/high, as likely to be in there. - for (ModuleList::const_iterator it = modules_.begin(); - it != modules_.end(); ++it) { + for (ModuleList::const_iterator it = modules_.begin(); it != modules_.end(); + ++it) { Module* module = *it; if (module->ContainsAddress(address)) { code_module = module; @@ -227,8 +220,8 @@ int Runtime::LookupFunctionInfo(Module* module, uint64_t address, return 0; } -int Runtime::DemandFunction( - FunctionInfo* symbol_info, Function** out_function) { +int Runtime::DemandFunction(FunctionInfo* symbol_info, + Function** out_function) { SCOPE_profile_cpu_f("alloy"); *out_function = NULL; @@ -240,7 +233,8 @@ int Runtime::DemandFunction( if (symbol_status == SymbolInfo::STATUS_NEW) { // Symbol is undefined, so define now. Function* function = NULL; - int result = frontend_->DefineFunction(symbol_info, DEBUG_INFO_DEFAULT, &function); + int result = + frontend_->DefineFunction(symbol_info, DEBUG_INFO_DEFAULT, &function); if (result) { symbol_info->set_status(SymbolInfo::STATUS_FAILED); return result; @@ -263,3 +257,6 @@ int Runtime::DemandFunction( return 0; } + +} // namespace runtime +} // namespace alloy diff --git a/src/alloy/runtime/runtime.h b/src/alloy/runtime/runtime.h index 68d4f488d..5ede95140 100644 --- a/src/alloy/runtime/runtime.h +++ b/src/alloy/runtime/runtime.h @@ -23,16 +23,14 @@ #include #include - namespace alloy { namespace runtime { - class Runtime { -public: + public: typedef std::vector ModuleList; -public: + public: Runtime(Memory* memory); virtual ~Runtime(); @@ -54,27 +52,25 @@ public: FunctionInfo** out_symbol_info); int ResolveFunction(uint64_t address, Function** out_function); - //uint32_t CreateCallback(void (*callback)(void* data), void* data); + // uint32_t CreateCallback(void (*callback)(void* data), void* data); -private: + private: int DemandFunction(FunctionInfo* symbol_info, Function** out_function); -protected: - Memory* memory_; + protected: + Memory* memory_; - Debugger* debugger_; + Debugger* debugger_; frontend::Frontend* frontend_; - backend::Backend* backend_; + backend::Backend* backend_; - EntryTable entry_table_; - std::mutex modules_lock_; - ModuleList modules_; + EntryTable entry_table_; + std::mutex modules_lock_; + ModuleList modules_; }; - } // namespace runtime } // namespace alloy - #endif // ALLOY_RUNTIME_RUNTIME_H_ diff --git a/src/alloy/runtime/symbol_info.cc b/src/alloy/runtime/symbol_info.cc index e87727b3a..7e060ff7f 100644 --- a/src/alloy/runtime/symbol_info.cc +++ b/src/alloy/runtime/symbol_info.cc @@ -9,14 +9,15 @@ #include -using namespace alloy; -using namespace alloy::runtime; +namespace alloy { +namespace runtime { - -SymbolInfo::SymbolInfo(Type type, Module* module, uint64_t address) : - type_(type), status_(STATUS_DEFINING), - module_(module), address_(address), name_(0) { -} +SymbolInfo::SymbolInfo(Type type, Module* module, uint64_t address) + : type_(type), + status_(STATUS_DEFINING), + module_(module), + address_(address), + name_(0) {} SymbolInfo::~SymbolInfo() { if (name_) { @@ -31,14 +32,15 @@ void SymbolInfo::set_name(const char* name) { name_ = xestrdupa(name); } -FunctionInfo::FunctionInfo(Module* module, uint64_t address) : - end_address_(0), behavior_(BEHAVIOR_DEFAULT), function_(0), - SymbolInfo(SymbolInfo::TYPE_FUNCTION, module, address) { +FunctionInfo::FunctionInfo(Module* module, uint64_t address) + : end_address_(0), + behavior_(BEHAVIOR_DEFAULT), + function_(0), + SymbolInfo(SymbolInfo::TYPE_FUNCTION, module, address) { xe_zero_struct(&extern_info_, sizeof(extern_info_)); } -FunctionInfo::~FunctionInfo() { -} +FunctionInfo::~FunctionInfo() {} void FunctionInfo::SetupExtern(ExternHandler handler, void* arg0, void* arg1) { behavior_ = BEHAVIOR_EXTERN; @@ -47,9 +49,10 @@ void FunctionInfo::SetupExtern(ExternHandler handler, void* arg0, void* arg1) { extern_info_.arg1 = arg1; } -VariableInfo::VariableInfo(Module* module, uint64_t address) : - SymbolInfo(SymbolInfo::TYPE_VARIABLE, module, address) { -} +VariableInfo::VariableInfo(Module* module, uint64_t address) + : SymbolInfo(SymbolInfo::TYPE_VARIABLE, module, address) {} -VariableInfo::~VariableInfo() { -} +VariableInfo::~VariableInfo() {} + +} // namespace runtime +} // namespace alloy diff --git a/src/alloy/runtime/symbol_info.h b/src/alloy/runtime/symbol_info.h index 8d2a964e7..e9a3b06f2 100644 --- a/src/alloy/runtime/symbol_info.h +++ b/src/alloy/runtime/symbol_info.h @@ -12,16 +12,14 @@ #include - namespace alloy { namespace runtime { class Function; class Module; - class SymbolInfo { -public: + public: enum Type { TYPE_FUNCTION, TYPE_VARIABLE, @@ -34,7 +32,8 @@ public: STATUS_DEFINED, STATUS_FAILED, }; -public: + + public: SymbolInfo(Type type, Module* module, uint64_t address); virtual ~SymbolInfo(); @@ -47,26 +46,26 @@ public: const char* name() const { return name_; } void set_name(const char* name); -protected: - Type type_; - Module* module_; - Status status_; - uint64_t address_; + protected: + Type type_; + Module* module_; + Status status_; + uint64_t address_; - char* name_; + char* name_; }; class FunctionInfo : public SymbolInfo { -public: + public: enum Behavior { - BEHAVIOR_DEFAULT = 0, + BEHAVIOR_DEFAULT = 0, BEHAVIOR_PROLOG, BEHAVIOR_EPILOG, BEHAVIOR_EPILOG_RETURN, BEHAVIOR_EXTERN, }; -public: + public: FunctionInfo(Module* module, uint64_t address); virtual ~FunctionInfo(); @@ -80,15 +79,15 @@ public: Function* function() const { return function_; } void set_function(Function* value) { function_ = value; } - typedef void(*ExternHandler)(void* context, void* arg0, void* arg1); + typedef void (*ExternHandler)(void* context, void* arg0, void* arg1); void SetupExtern(ExternHandler handler, void* arg0, void* arg1); ExternHandler extern_handler() const { return extern_info_.handler; } void* extern_arg0() const { return extern_info_.arg0; } void* extern_arg1() const { return extern_info_.arg1; } -private: - uint64_t end_address_; - Behavior behavior_; + private: + uint64_t end_address_; + Behavior behavior_; Function* function_; struct { ExternHandler handler; @@ -98,16 +97,14 @@ private: }; class VariableInfo : public SymbolInfo { -public: + public: VariableInfo(Module* module, uint64_t address); virtual ~VariableInfo(); -private: + private: }; - } // namespace runtime } // namespace alloy - #endif // ALLOY_RUNTIME_SYMBOL_INFO_H_ diff --git a/src/alloy/runtime/thread_state.cc b/src/alloy/runtime/thread_state.cc index 84add8bce..828863fc5 100644 --- a/src/alloy/runtime/thread_state.cc +++ b/src/alloy/runtime/thread_state.cc @@ -11,19 +11,18 @@ #include -using namespace alloy; -using namespace alloy::runtime; +namespace alloy { +namespace runtime { - -namespace { __declspec(thread) ThreadState* thread_state_ = NULL; -} - -ThreadState::ThreadState(Runtime* runtime, uint32_t thread_id) : - runtime_(runtime), memory_(runtime->memory()), - thread_id_(thread_id), name_(0), - backend_data_(0), raw_context_(0) { +ThreadState::ThreadState(Runtime* runtime, uint32_t thread_id) + : runtime_(runtime), + memory_(runtime->memory()), + thread_id_(thread_id), + name_(0), + backend_data_(0), + raw_context_(0) { if (thread_id_ == UINT_MAX) { // System thread. Assign the system thread ID with a high bit // set so people know what's up. @@ -59,10 +58,9 @@ void ThreadState::Bind(ThreadState* thread_state) { thread_state_ = thread_state; } -ThreadState* ThreadState::Get() { - return thread_state_; -} +ThreadState* ThreadState::Get() { return thread_state_; } -uint32_t ThreadState::GetThreadID() { - return thread_state_->thread_id_; -} +uint32_t ThreadState::GetThreadID() { return thread_state_->thread_id_; } + +} // namespace runtime +} // namespace alloy diff --git a/src/alloy/runtime/thread_state.h b/src/alloy/runtime/thread_state.h index 26cd4566b..a10e67438 100644 --- a/src/alloy/runtime/thread_state.h +++ b/src/alloy/runtime/thread_state.h @@ -14,15 +14,13 @@ #include - namespace alloy { namespace runtime { class Runtime; - class ThreadState { -public: + public: ThreadState(Runtime* runtime, uint32_t thread_id); virtual ~ThreadState(); @@ -43,18 +41,16 @@ public: static ThreadState* Get(); static uint32_t GetThreadID(); -protected: - Runtime* runtime_; - Memory* memory_; - uint32_t thread_id_; - char* name_; - void* backend_data_; - void* raw_context_; + protected: + Runtime* runtime_; + Memory* memory_; + uint32_t thread_id_; + char* name_; + void* backend_data_; + void* raw_context_; }; - } // namespace runtime } // namespace alloy - #endif // ALLOY_RUNTIME_THREAD_STATE_H_ diff --git a/src/alloy/runtime/tracing.h b/src/alloy/runtime/tracing.h index 262662b90..1356208cb 100644 --- a/src/alloy/runtime/tracing.h +++ b/src/alloy/runtime/tracing.h @@ -13,31 +13,27 @@ #include #include - namespace alloy { namespace runtime { const uint32_t ALLOY_RUNTIME = alloy::tracing::EventType::ALLOY_RUNTIME; - class EventType { -public: + public: enum { - ALLOY_RUNTIME_INIT = ALLOY_RUNTIME | (1), - ALLOY_RUNTIME_DEINIT = ALLOY_RUNTIME | (2), - - ALLOY_RUNTIME_THREAD = ALLOY_RUNTIME | (1 << 25), - ALLOY_RUNTIME_THREAD_INIT = ALLOY_RUNTIME_THREAD | (1), - ALLOY_RUNTIME_THREAD_DEINIT = ALLOY_RUNTIME_THREAD | (2), - - ALLOY_RUNTIME_MEMORY = ALLOY_RUNTIME | (2 << 25), - ALLOY_RUNTIME_MEMORY_INIT = ALLOY_RUNTIME_MEMORY | (1), - ALLOY_RUNTIME_MEMORY_DEINIT = ALLOY_RUNTIME_MEMORY | (2), - ALLOY_RUNTIME_MEMORY_HEAP = ALLOY_RUNTIME_MEMORY | (1000), - ALLOY_RUNTIME_MEMORY_HEAP_INIT = ALLOY_RUNTIME_MEMORY_HEAP | (1), - ALLOY_RUNTIME_MEMORY_HEAP_DEINIT = ALLOY_RUNTIME_MEMORY | (2), - ALLOY_RUNTIME_MEMORY_HEAP_ALLOC = ALLOY_RUNTIME_MEMORY | (3), - ALLOY_RUNTIME_MEMORY_HEAP_FREE = ALLOY_RUNTIME_MEMORY | (4), + ALLOY_RUNTIME_INIT = ALLOY_RUNTIME | (1), + ALLOY_RUNTIME_DEINIT = ALLOY_RUNTIME | (2), + ALLOY_RUNTIME_THREAD = ALLOY_RUNTIME | (1 << 25), + ALLOY_RUNTIME_THREAD_INIT = ALLOY_RUNTIME_THREAD | (1), + ALLOY_RUNTIME_THREAD_DEINIT = ALLOY_RUNTIME_THREAD | (2), + ALLOY_RUNTIME_MEMORY = ALLOY_RUNTIME | (2 << 25), + ALLOY_RUNTIME_MEMORY_INIT = ALLOY_RUNTIME_MEMORY | (1), + ALLOY_RUNTIME_MEMORY_DEINIT = ALLOY_RUNTIME_MEMORY | (2), + ALLOY_RUNTIME_MEMORY_HEAP = ALLOY_RUNTIME_MEMORY | (1000), + ALLOY_RUNTIME_MEMORY_HEAP_INIT = ALLOY_RUNTIME_MEMORY_HEAP | (1), + ALLOY_RUNTIME_MEMORY_HEAP_DEINIT = ALLOY_RUNTIME_MEMORY | (2), + ALLOY_RUNTIME_MEMORY_HEAP_ALLOC = ALLOY_RUNTIME_MEMORY | (3), + ALLOY_RUNTIME_MEMORY_HEAP_FREE = ALLOY_RUNTIME_MEMORY | (4), }; typedef struct Init_s { @@ -63,32 +59,30 @@ public: } MemoryDeinit; typedef struct MemoryHeapInit_s { static const uint32_t event_type = ALLOY_RUNTIME_MEMORY_HEAP_INIT; - uint32_t heap_id; - uint64_t low_address; - uint64_t high_address; - uint32_t is_physical; + uint32_t heap_id; + uint64_t low_address; + uint64_t high_address; + uint32_t is_physical; } MemoryHeapInit; typedef struct MemoryHeapDeinit_s { static const uint32_t event_type = ALLOY_RUNTIME_MEMORY_HEAP_DEINIT; - uint32_t heap_id; + uint32_t heap_id; } MemoryHeapDeinit; typedef struct MemoryHeapAlloc_s { static const uint32_t event_type = ALLOY_RUNTIME_MEMORY_HEAP_ALLOC; - uint32_t heap_id; - uint32_t flags; - uint64_t address; - size_t size; + uint32_t heap_id; + uint32_t flags; + uint64_t address; + size_t size; } MemoryHeapAlloc; typedef struct MemoryHeapFree_s { static const uint32_t event_type = ALLOY_RUNTIME_MEMORY_HEAP_FREE; - uint32_t heap_id; - uint64_t address; + uint32_t heap_id; + uint64_t address; } MemoryHeapFree; }; - } // namespace runtime } // namespace alloy - #endif // ALLOY_RUNTIME_TRACING_H_ diff --git a/src/alloy/string_buffer.cc b/src/alloy/string_buffer.cc index 89124e737..887dbbf5f 100644 --- a/src/alloy/string_buffer.cc +++ b/src/alloy/string_buffer.cc @@ -9,19 +9,16 @@ #include -using namespace alloy; +namespace alloy { - -StringBuffer::StringBuffer(size_t initial_capacity) : - buffer_(0), capacity_(0), offset_(0) { +StringBuffer::StringBuffer(size_t initial_capacity) + : buffer_(0), capacity_(0), offset_(0) { capacity_ = MAX(initial_capacity, 1024); buffer_ = (char*)xe_calloc(capacity_); buffer_[0] = 0; } -StringBuffer::~StringBuffer() { - xe_free(buffer_); -} +StringBuffer::~StringBuffer() { xe_free(buffer_); } void StringBuffer::Reset() { offset_ = 0; @@ -37,8 +34,8 @@ void StringBuffer::Append(const char* format, ...) { void StringBuffer::AppendVarargs(const char* format, va_list args) { while (true) { - int len = xevsnprintfa( - buffer_ + offset_, capacity_ - offset_ - 1, format, args); + int len = + xevsnprintfa(buffer_ + offset_, capacity_ - offset_ - 1, format, args); if (len == -1) { size_t old_capacity = capacity_; capacity_ = capacity_ * 2; @@ -58,17 +55,13 @@ void StringBuffer::AppendBytes(const uint8_t* buffer, size_t length) { capacity_ = MAX(capacity_ * 2, capacity_ + length); buffer_ = (char*)xe_realloc(buffer_, old_capacity, capacity_); } - xe_copy_memory( - buffer_ + offset_, capacity_ - offset_, - buffer, length); + xe_copy_memory(buffer_ + offset_, capacity_ - offset_, buffer, length); offset_ += length; buffer_[offset_] = 0; } -const char* StringBuffer::GetString() const { - return buffer_; -} +const char* StringBuffer::GetString() const { return buffer_; } -char* StringBuffer::ToString() { - return xestrdupa(buffer_); -} +char* StringBuffer::ToString() { return xestrdupa(buffer_); } + +} // namespace alloy diff --git a/src/alloy/string_buffer.h b/src/alloy/string_buffer.h index 8b2b05d95..b14055d1d 100644 --- a/src/alloy/string_buffer.h +++ b/src/alloy/string_buffer.h @@ -12,12 +12,10 @@ #include - namespace alloy { - class StringBuffer { -public: + public: StringBuffer(size_t initial_capacity = 0); ~StringBuffer(); @@ -33,14 +31,12 @@ public: char* ToString(); char* EncodeBase64(); -private: - char* buffer_; - size_t capacity_; - size_t offset_; + private: + char* buffer_; + size_t capacity_; + size_t offset_; }; - } // namespace alloy - #endif // ALLOY_STRING_BUFFER_H_ diff --git a/src/alloy/tracing/channel.cc b/src/alloy/tracing/channel.cc index ef59e3aec..ea2616e52 100644 --- a/src/alloy/tracing/channel.cc +++ b/src/alloy/tracing/channel.cc @@ -9,12 +9,12 @@ #include -using namespace alloy; -using namespace alloy::tracing; +namespace alloy { +namespace tracing { +Channel::Channel() {} -Channel::Channel() { -} +Channel::~Channel() {} -Channel::~Channel() { -} +} // namespace tracing +} // namespace alloy diff --git a/src/alloy/tracing/channel.h b/src/alloy/tracing/channel.h index 24d6f0031..6d36ac00a 100644 --- a/src/alloy/tracing/channel.h +++ b/src/alloy/tracing/channel.h @@ -12,25 +12,20 @@ #include - namespace alloy { namespace tracing { - class Channel { -public: + public: Channel(); virtual ~Channel(); - virtual void Write( - size_t buffer_count, - size_t buffer_lengths[], const uint8_t* buffers[]) = 0; + virtual void Write(size_t buffer_count, size_t buffer_lengths[], + const uint8_t* buffers[]) = 0; virtual void Flush() = 0; }; - } // namespace tracing } // namespace alloy - #endif // ALLOY_TRACING_CHANNEL_H_ diff --git a/src/alloy/tracing/channels/file_channel.cc b/src/alloy/tracing/channels/file_channel.cc index 7b2db652b..89767d428 100644 --- a/src/alloy/tracing/channels/file_channel.cc +++ b/src/alloy/tracing/channels/file_channel.cc @@ -9,10 +9,9 @@ #include -using namespace alloy; -using namespace alloy::tracing; -using namespace alloy::tracing::channels; - +namespace alloy { +namespace tracing { +namespace channels { FileChannel::FileChannel(const char* path) { path_ = xestrdupa(path); @@ -27,9 +26,8 @@ FileChannel::~FileChannel() { path_ = 0; } -void FileChannel::Write( - size_t buffer_count, - size_t buffer_lengths[], const uint8_t* buffers[]) { +void FileChannel::Write(size_t buffer_count, size_t buffer_lengths[], + const uint8_t* buffers[]) { std::lock_guard guard(lock_); if (file_) { for (size_t n = 0; n < buffer_count; n++) { @@ -44,3 +42,7 @@ void FileChannel::Flush() { fflush(file_); } } + +} // namespace channels +} // namespace tracing +} // namespace alloy diff --git a/src/alloy/tracing/channels/file_channel.h b/src/alloy/tracing/channels/file_channel.h index 55e8e71fb..ba290dc1a 100644 --- a/src/alloy/tracing/channels/file_channel.h +++ b/src/alloy/tracing/channels/file_channel.h @@ -16,33 +16,28 @@ #include - namespace alloy { namespace tracing { namespace channels { - class FileChannel : public Channel { -public: + public: FileChannel(const char* path); virtual ~FileChannel(); - virtual void Write( - size_t buffer_count, - size_t buffer_lengths[], const uint8_t* buffers[]); + virtual void Write(size_t buffer_count, size_t buffer_lengths[], + const uint8_t* buffers[]); virtual void Flush(); -private: + private: char* path_; FILE* file_; std::mutex lock_; }; - } // namespace channels } // namespace tracing } // namespace alloy - #endif // ALLOY_TRACING_CHANNELS_FILE_CHANNEL_H_ diff --git a/src/alloy/tracing/event_type.h b/src/alloy/tracing/event_type.h index 33e2614fb..3ad6a0d9c 100644 --- a/src/alloy/tracing/event_type.h +++ b/src/alloy/tracing/event_type.h @@ -12,25 +12,21 @@ #include - namespace alloy { namespace tracing { - class EventType { -public: + public: enum { - ALLOY = (0 << 31), - ALLOY_TRACE_INIT = ALLOY | (1), - ALLOY_TRACE_EOF = ALLOY | (2), - - ALLOY_BACKEND = ALLOY | (1 << 26), - ALLOY_COMPILER = ALLOY | (2 << 26), - ALLOY_HIR = ALLOY | (3 << 26), - ALLOY_FRONTEND = ALLOY | (4 << 26), - ALLOY_RUNTIME = ALLOY | (5 << 26), - - USER = (1 << 31), + ALLOY = (0 << 31), + ALLOY_TRACE_INIT = ALLOY | (1), + ALLOY_TRACE_EOF = ALLOY | (2), + ALLOY_BACKEND = ALLOY | (1 << 26), + ALLOY_COMPILER = ALLOY | (2 << 26), + ALLOY_HIR = ALLOY | (3 << 26), + ALLOY_FRONTEND = ALLOY | (4 << 26), + ALLOY_RUNTIME = ALLOY | (5 << 26), + USER = (1 << 31), }; typedef struct TraceInit_s { @@ -41,9 +37,7 @@ public: } TraceEOF; }; - } // namespace tracing } // namespace alloy - #endif // ALLOY_TRACING_EVENT_TYPES_H_ diff --git a/src/alloy/tracing/tracer.cc b/src/alloy/tracing/tracer.cc index c97a16f14..fbb4c43bb 100644 --- a/src/alloy/tracing/tracer.cc +++ b/src/alloy/tracing/tracer.cc @@ -11,41 +11,32 @@ #include -using namespace alloy; -using namespace alloy::tracing; - - -namespace { +namespace alloy { +namespace tracing { volatile int next_thread_id_ = 0x10000000; -}; - - -Tracer::Tracer(Channel* channel) : - channel_(channel) { +Tracer::Tracer(Channel* channel) : channel_(channel) { thread_id_ = xe_atomic_inc_32(&next_thread_id_); } -Tracer::~Tracer() { -} +Tracer::~Tracer() {} -void Tracer::WriteEvent( - uint32_t event_type, size_t size, const uint8_t* data) { +void Tracer::WriteEvent(uint32_t event_type, size_t size, const uint8_t* data) { uint32_t header[] = { - event_type, - (uint32_t)thread_id_, - 0, // time in us - (uint32_t)size, + event_type, (uint32_t)thread_id_, + 0, // time in us + (uint32_t)size, }; size_t buffer_count = size ? 2 : 1; size_t buffer_lengths[] = { - sizeof(header), - size, + sizeof(header), size, }; const uint8_t* buffers[] = { - (const uint8_t*)header, - data, + (const uint8_t*)header, data, }; channel_->Write(buffer_count, buffer_lengths, buffers); } + +} // namespace tracing +} // namespace alloy diff --git a/src/alloy/tracing/tracer.h b/src/alloy/tracing/tracer.h index 3915326e9..3d322f495 100644 --- a/src/alloy/tracing/tracer.h +++ b/src/alloy/tracing/tracer.h @@ -12,32 +12,28 @@ #include - namespace alloy { namespace tracing { class Channel; - class Tracer { -public: + public: Tracer(Channel* channel); ~Tracer(); int thread_id() const { return thread_id_; } void set_thread_id(int value) { thread_id_ = value; } - void WriteEvent( - uint32_t event_type, size_t size = 0, const uint8_t* data = 0); + void WriteEvent(uint32_t event_type, size_t size = 0, + const uint8_t* data = 0); -private: + private: Channel* channel_; int thread_id_; }; - } // namespace tracing } // namespace alloy - #endif // ALLOY_TRACING_TRACER_H_ diff --git a/src/alloy/tracing/tracing.cc b/src/alloy/tracing/tracing.cc index 7a6fc9342..16c7eaf75 100644 --- a/src/alloy/tracing/tracing.cc +++ b/src/alloy/tracing/tracing.cc @@ -17,33 +17,24 @@ #include #include -using namespace alloy; -using namespace alloy::tracing; - - -DEFINE_string(trace_file, "", - "Traces to the given file path."); +DEFINE_string(trace_file, "", "Traces to the given file path."); // trace shared memory // trace socket +namespace alloy { +namespace tracing { -namespace { - -static Channel* shared_channel = NULL; +Channel* shared_channel = NULL; __declspec(thread) Tracer* thread_tracer = NULL; void CleanupTracing() { if (shared_channel) { - alloy::tracing::WriteEvent(EventType::TraceEOF({ - })); + alloy::tracing::WriteEvent(EventType::TraceEOF({})); shared_channel->Flush(); } } -}; - - -bool alloy::tracing::Initialize(Channel* channel) { +bool Initialize(Channel* channel) { if (shared_channel) { return false; } @@ -58,24 +49,23 @@ bool alloy::tracing::Initialize(Channel* channel) { } } shared_channel = channel; - alloy::tracing::WriteEvent(EventType::TraceInit({ - })); + alloy::tracing::WriteEvent(EventType::TraceInit({})); channel->Flush(); atexit(CleanupTracing); return true; } -void alloy::tracing::Shutdown() { +void Shutdown() { // ? } -void alloy::tracing::Flush() { +void Flush() { if (shared_channel) { shared_channel->Flush(); } } -Tracer* alloy::tracing::GetThreadTracer() { +Tracer* GetThreadTracer() { if (!shared_channel) { return NULL; } @@ -85,10 +75,12 @@ Tracer* alloy::tracing::GetThreadTracer() { return thread_tracer; } -void alloy::tracing::WriteEvent( - uint32_t event_type, size_t size, const void* data) { +void WriteEvent(uint32_t event_type, size_t size, const void* data) { Tracer* t = GetThreadTracer(); if (t) { t->WriteEvent(event_type, size, (const uint8_t*)data); } } + +} // namespace tracing +} // namespace alloy diff --git a/src/alloy/tracing/tracing.h b/src/alloy/tracing/tracing.h index ced2081de..4ca602bc0 100644 --- a/src/alloy/tracing/tracing.h +++ b/src/alloy/tracing/tracing.h @@ -14,14 +14,12 @@ #include - namespace alloy { namespace tracing { class Channel; class Tracer; - bool Initialize(Channel* channel = 0); void Shutdown(); void Flush(); @@ -30,7 +28,8 @@ Tracer* GetThreadTracer(); void WriteEvent(uint32_t event_type, size_t size = 0, const void* data = 0); -template void WriteEvent(const T& ev) { +template +void WriteEvent(const T& ev) { if (sizeof(T) > 1) { alloy::tracing::WriteEvent(T::event_type, sizeof(T), &ev); } else { @@ -38,9 +37,7 @@ template void WriteEvent(const T& ev) { } } - } // namespace tracing } // namespace alloy - #endif // ALLOY_TRACING_TRACING_H_ diff --git a/src/alloy/type_pool.h b/src/alloy/type_pool.h index beb9dbd43..ce124eab4 100644 --- a/src/alloy/type_pool.h +++ b/src/alloy/type_pool.h @@ -14,20 +14,16 @@ #include - namespace alloy { - -template +template class TypePool { -public: - ~TypePool() { - Reset(); - } + public: + ~TypePool() { Reset(); } void Reset() { std::lock_guard guard(lock_); - for (TList::iterator it = list_.begin(); it != list_.end(); ++it) { + for (auto it = list_.begin(); it != list_.end(); ++it) { T* value = *it; delete value; } @@ -54,14 +50,12 @@ public: list_.push_back(value); } -private: - std::mutex lock_; + private: + std::mutex lock_; typedef std::vector TList; - TList list_; + TList list_; }; - } // namespace alloy - #endif // ALLOY_TYPE_POOL_H_ diff --git a/src/poly/poly-private.h b/src/poly/poly-private.h index d4095d575..500cddd52 100644 --- a/src/poly/poly-private.h +++ b/src/poly/poly-private.h @@ -12,8 +12,4 @@ #include -namespace poly { - -} // namespace poly - #endif // POLY_POLY_PRIVATE_H_ diff --git a/src/poly/poly.cc b/src/poly/poly.cc index 51b85164e..2e306025b 100644 --- a/src/poly/poly.cc +++ b/src/poly/poly.cc @@ -10,6 +10,4 @@ #include #include -namespace poly { - -} // namespace poly +namespace poly {} // namespace poly diff --git a/src/poly/poly.h b/src/poly/poly.h index 061fd09c1..f6e6eb97b 100644 --- a/src/poly/poly.h +++ b/src/poly/poly.h @@ -10,8 +10,6 @@ #ifndef POLY_POLY_H_ #define POLY_POLY_H_ -namespace poly { - -} // namespace poly +namespace poly {} // namespace poly #endif // POLY_POLY_H_ From 9031d5f4a463249a70a845e3f02f5de2dbcae2fe Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 10 Jul 2014 22:51:27 -0700 Subject: [PATCH 017/388] Fix clang warnings / move some plat code into poly. --- src/alloy/backend/ivm/ivm_assembler.cc | 4 +- src/alloy/backend/ivm/ivm_function.cc | 6 +- src/alloy/backend/x64/x64_assembler.cc | 2 +- src/alloy/backend/x64/x64_backend.cc | 2 +- src/alloy/backend/x64/x64_code_cache.cc | 2 - src/alloy/backend/x64/x64_emitter.cc | 19 ++- src/alloy/backend/x64/x64_function.cc | 2 +- src/alloy/backend/x64/x64_sequences.cc | 6 +- src/alloy/backend/x64/x64_tracers.cc | 130 +++++++++--------- src/alloy/backend/x64/x64_tracers.h | 14 -- .../passes/constant_propagation_pass.cc | 4 + .../compiler/passes/context_promotion_pass.cc | 2 +- .../passes/data_flow_analysis_pass.cc | 4 + .../passes/dead_code_elimination_pass.cc | 5 +- .../passes/register_allocation_pass.cc | 12 +- .../passes/register_allocation_pass.h | 1 - src/alloy/compiler/passes/validation_pass.cc | 2 + .../compiler/passes/value_reduction_pass.cc | 4 + src/alloy/core.h | 2 + src/alloy/frontend/ppc/ppc_disasm.cc | 33 +---- src/alloy/frontend/ppc/ppc_emit_altivec.cc | 18 +-- src/alloy/frontend/ppc/ppc_hir_builder.cc | 8 +- src/alloy/frontend/ppc/ppc_instr.cc | 2 +- src/alloy/hir/block.cc | 2 +- src/alloy/hir/hir_builder.cc | 2 +- src/alloy/hir/value.cc | 95 +++++++------ src/alloy/hir/value.h | 9 +- src/alloy/runtime/debugger.h | 6 +- src/alloy/runtime/function.cc | 2 +- src/alloy/runtime/instrument.cc | 4 +- src/alloy/runtime/raw_module.cc | 6 +- src/alloy/runtime/runtime.cc | 2 +- src/alloy/runtime/symbol_info.cc | 8 +- src/alloy/runtime/thread_state.cc | 2 +- src/alloy/tracing/tracing.cc | 2 +- src/poly/cxx_compat.h | 25 ++++ src/poly/math.h | 104 ++++++++++++++ src/poly/poly.h | 3 + src/poly/sources.gypi | 2 + src/xenia/assert.h | 1 + src/xenia/kernel/xboxkrnl_modules.cc | 6 +- 41 files changed, 347 insertions(+), 218 deletions(-) create mode 100644 src/poly/cxx_compat.h create mode 100644 src/poly/math.h diff --git a/src/alloy/backend/ivm/ivm_assembler.cc b/src/alloy/backend/ivm/ivm_assembler.cc index 67d8c63b2..c26657d37 100644 --- a/src/alloy/backend/ivm/ivm_assembler.cc +++ b/src/alloy/backend/ivm/ivm_assembler.cc @@ -26,7 +26,7 @@ using alloy::runtime::Function; using alloy::runtime::FunctionInfo; IVMAssembler::IVMAssembler(Backend* backend) - : source_map_arena_(128 * 1024), Assembler(backend) {} + : Assembler(backend), source_map_arena_(128 * 1024) {} IVMAssembler::~IVMAssembler() { alloy::tracing::WriteEvent(EventType::AssemblerDeinit({})); @@ -94,7 +94,7 @@ int IVMAssembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder, auto i = block->instr_head; while (i) { - int result = TranslateIntCodes(ctx, i); + TranslateIntCodes(ctx, i); i = i->next; } block = block->next; diff --git a/src/alloy/backend/ivm/ivm_function.cc b/src/alloy/backend/ivm/ivm_function.cc index 4ed6a13b9..b44f1f07a 100644 --- a/src/alloy/backend/ivm/ivm_function.cc +++ b/src/alloy/backend/ivm/ivm_function.cc @@ -23,12 +23,12 @@ using alloy::runtime::FunctionInfo; using alloy::runtime::ThreadState; IVMFunction::IVMFunction(FunctionInfo* symbol_info) - : register_count_(0), + : Function(symbol_info), + register_count_(0), intcode_count_(0), intcodes_(0), source_map_count_(0), - source_map_(0), - Function(symbol_info) {} + source_map_(0) {} IVMFunction::~IVMFunction() { xe_free(intcodes_); diff --git a/src/alloy/backend/x64/x64_assembler.cc b/src/alloy/backend/x64/x64_assembler.cc index b274a7eca..3f3e6e4fb 100644 --- a/src/alloy/backend/x64/x64_assembler.cc +++ b/src/alloy/backend/x64/x64_assembler.cc @@ -34,7 +34,7 @@ using alloy::runtime::Function; using alloy::runtime::FunctionInfo; X64Assembler::X64Assembler(X64Backend* backend) - : x64_backend_(backend), emitter_(0), allocator_(0), Assembler(backend) {} + : Assembler(backend), x64_backend_(backend), emitter_(0), allocator_(0) {} X64Assembler::~X64Assembler() { alloy::tracing::WriteEvent(EventType::AssemblerDeinit({})); diff --git a/src/alloy/backend/x64/x64_backend.cc b/src/alloy/backend/x64/x64_backend.cc index 3ec784599..e1bf31cbe 100644 --- a/src/alloy/backend/x64/x64_backend.cc +++ b/src/alloy/backend/x64/x64_backend.cc @@ -21,7 +21,7 @@ namespace x64 { using alloy::runtime::Runtime; -X64Backend::X64Backend(Runtime* runtime) : code_cache_(0), Backend(runtime) {} +X64Backend::X64Backend(Runtime* runtime) : Backend(runtime), code_cache_(0) {} X64Backend::~X64Backend() { alloy::tracing::WriteEvent(EventType::Deinit({})); diff --git a/src/alloy/backend/x64/x64_code_cache.cc b/src/alloy/backend/x64/x64_code_cache.cc index b3ea120c8..71a0b2d30 100644 --- a/src/alloy/backend/x64/x64_code_cache.cc +++ b/src/alloy/backend/x64/x64_code_cache.cc @@ -214,8 +214,6 @@ void X64CodeChunk::AddTableEntry(uint8_t* code, size_t code_size, offset += UNWIND_INFO_SIZE; if (!stack_size) { - uint8_t prolog_size = 0; - // http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx UNWIND_INFO* unwind_info = (UNWIND_INFO*)(buffer + unwind_info_offset); unwind_info->Version = 1; diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index ee552c71a..797a03dd3 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -54,12 +54,12 @@ const uint32_t X64Emitter::xmm_reg_map_[X64Emitter::XMM_COUNT] = { }; X64Emitter::X64Emitter(X64Backend* backend, XbyakAllocator* allocator) - : runtime_(backend->runtime()), + : CodeGenerator(MAX_CODE_SIZE, AutoGrow, allocator), + runtime_(backend->runtime()), backend_(backend), code_cache_(backend->code_cache()), allocator_(allocator), - current_instr_(0), - CodeGenerator(MAX_CODE_SIZE, AutoGrow, allocator) {} + current_instr_(0) {} X64Emitter::~X64Emitter() {} @@ -263,9 +263,14 @@ uint64_t ResolveFunctionSymbol(void* raw_context, uint64_t symbol_info_ptr) { auto x64_fn = static_cast(fn); uint64_t addr = reinterpret_cast(x64_fn->machine_code()); - // Overwrite the call site. - // The return address points to ReloadRCX work after the call. +// Overwrite the call site. +// The return address points to ReloadRCX work after the call. +#if XE_WIN32_LIKE uint64_t return_address = reinterpret_cast(_ReturnAddress()); +#else + uint64_t return_address = + reinterpret_cast(__builtin_return_address(0)); +#endif // XE_WIN32_LIKE #pragma pack(push, 1) struct Asm { uint16_t mov_rax; @@ -364,7 +369,7 @@ void X64Emitter::CallIndirect(const hir::Instr* instr, const Reg64& reg) { uint64_t UndefinedCallExtern(void* raw_context, uint64_t symbol_info_ptr) { auto symbol_info = reinterpret_cast(symbol_info_ptr); - XELOGW("undefined extern call to %.8X %s", symbol_info->address(), + XELOGW("undefined extern call to %.8llX %s", symbol_info->address(), symbol_info->name()); return 0; } @@ -584,7 +589,7 @@ void X64Emitter::LoadConstantXmm(Xbyak::Xmm dest, float v) { if (!v) { // 0 vpxor(dest, dest); - } else if (x.i == ~0UL) { + } else if (x.i == ~0U) { // 1111... vpcmpeqb(dest, dest); } else { diff --git a/src/alloy/backend/x64/x64_function.cc b/src/alloy/backend/x64/x64_function.cc index 5e20887ba..28b16ee1e 100644 --- a/src/alloy/backend/x64/x64_function.cc +++ b/src/alloy/backend/x64/x64_function.cc @@ -24,7 +24,7 @@ using alloy::runtime::FunctionInfo; using alloy::runtime::ThreadState; X64Function::X64Function(FunctionInfo* symbol_info) - : machine_code_(NULL), code_size_(0), Function(symbol_info) {} + : Function(symbol_info), machine_code_(NULL), code_size_(0) {} X64Function::~X64Function() { // machine_code_ is freed by code cache. diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index 6d513aae0..e969fe402 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -2665,7 +2665,7 @@ EMITTER(VECTOR_ADD, MATCH(I, V128<>, V128<>>)) { case FLOAT32_TYPE: e.vaddps(dest, src1, src2); break; - default: XEASSERTALWAYS(); break; + default: XEASSERTUNHANDLEDCASE(part_type); break; } }); } @@ -4704,7 +4704,7 @@ EMITTER(PACK, MATCH(I, V128<>>)) { case PACK_TYPE_S16_IN_32_HI: EmitS16_IN_32_HI(e, i); break; - default: XEASSERTALWAYS(); break; + default: XEASSERTUNHANDLEDCASE(i.instr->flags); break; } } static void EmitD3DCOLOR(X64Emitter& e, const EmitArgType& i) { @@ -4806,7 +4806,7 @@ EMITTER(UNPACK, MATCH(I, V128<>>)) { case PACK_TYPE_S16_IN_32_HI: EmitS16_IN_32_HI(e, i); break; - default: XEASSERTALWAYS(); break; + default: XEASSERTUNHANDLEDCASE(i.instr->flags); break; } } static void EmitD3DCOLOR(X64Emitter& e, const EmitArgType& i) { diff --git a/src/alloy/backend/x64/x64_tracers.cc b/src/alloy/backend/x64/x64_tracers.cc index 29227db0d..4c4fdaabf 100644 --- a/src/alloy/backend/x64/x64_tracers.cc +++ b/src/alloy/backend/x64/x64_tracers.cc @@ -34,6 +34,20 @@ namespace x64 { DFLUSH(); \ if (thread_state->thread_id() == TARGET_THREAD) printf +// TODO(benvanik): properly pull out values. +typedef union __declspec(align(16)) { + __m128 m128; + float m128_f32[4]; + uint64_t m128_u64[2]; + int8_t m128_i8[16]; + int16_t m128_i16[8]; + int32_t m128_i32[4]; + int64_t m128_i64[2]; + uint8_t m128_u8[16]; + uint16_t m128_u16[8]; + uint32_t m128_u32[4]; +} __m128_x; + uint32_t GetTracingMode() { uint32_t mode = 0; #if ITRACE @@ -53,154 +67,142 @@ void TraceString(void* raw_context, const char* str) { void TraceContextLoadI8(void* raw_context, uint64_t offset, uint8_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("%d (%X) = ctx i8 +%d\n", (int8_t)value, value, offset); + DPRINT("%d (%X) = ctx i8 +%llu\n", (int8_t)value, value, offset); } void TraceContextLoadI16(void* raw_context, uint64_t offset, uint16_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("%d (%X) = ctx i16 +%d\n", (int16_t)value, value, offset); + DPRINT("%d (%X) = ctx i16 +%llu\n", (int16_t)value, value, offset); } void TraceContextLoadI32(void* raw_context, uint64_t offset, uint32_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("%d (%X) = ctx i32 +%d\n", (int32_t)value, value, offset); + DPRINT("%d (%X) = ctx i32 +%llu\n", (int32_t)value, value, offset); } void TraceContextLoadI64(void* raw_context, uint64_t offset, uint64_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("%lld (%llX) = ctx i64 +%d\n", (int64_t)value, value, offset); + DPRINT("%lld (%llX) = ctx i64 +%llu\n", (int64_t)value, value, offset); } void TraceContextLoadF32(void* raw_context, uint64_t offset, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("%e (%X) = ctx f32 +%d\n", value.m128_f32[0], value.m128_i32[0], - offset); + DPRINT("%e (%X) = ctx f32 +%llu\n", poly::m128_f32<0>(value), + poly::m128_i32<0>(value), offset); } void TraceContextLoadF64(void* raw_context, uint64_t offset, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - union { - double d; - uint64_t x; - } f; - f.x = value.m128_i64[0]; - DPRINT("%lle (%llX) = ctx f64 +%d\n", f.d, value.m128_i64[0], offset); + DPRINT("%le (%llX) = ctx f64 +%llu\n", poly::m128_f64<0>(value), + poly::m128_i64<0>(value), offset); } void TraceContextLoadV128(void* raw_context, uint64_t offset, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = ctx v128 +%d\n", - value.m128_f32[0], value.m128_f32[1], value.m128_f32[2], - value.m128_f32[3], value.m128_i32[0], value.m128_i32[1], - value.m128_i32[2], value.m128_i32[3], offset); + DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = ctx v128 +%llu\n", + poly::m128_f32<0>(value), poly::m128_f32<1>(value), + poly::m128_f32<2>(value), poly::m128_f32<3>(value), + poly::m128_i32<0>(value), poly::m128_i32<1>(value), + poly::m128_i32<2>(value), poly::m128_i32<3>(value), offset); } void TraceContextStoreI8(void* raw_context, uint64_t offset, uint8_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("ctx i8 +%d = %d (%X)\n", offset, (int8_t)value, value); + DPRINT("ctx i8 +%llu = %d (%X)\n", offset, (int8_t)value, value); } void TraceContextStoreI16(void* raw_context, uint64_t offset, uint16_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("ctx i16 +%d = %d (%X)\n", offset, (int16_t)value, value); + DPRINT("ctx i16 +%llu = %d (%X)\n", offset, (int16_t)value, value); } void TraceContextStoreI32(void* raw_context, uint64_t offset, uint32_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("ctx i32 +%d = %d (%X)\n", offset, (int32_t)value, value); + DPRINT("ctx i32 +%llu = %d (%X)\n", offset, (int32_t)value, value); } void TraceContextStoreI64(void* raw_context, uint64_t offset, uint64_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("ctx i64 +%d = %lld (%llX)\n", offset, (int64_t)value, value); + DPRINT("ctx i64 +%llu = %lld (%llX)\n", offset, (int64_t)value, value); } void TraceContextStoreF32(void* raw_context, uint64_t offset, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("ctx f32 +%d = %e (%X)\n", offset, value.m128_i32[0], - value.m128_f32[0]); + DPRINT("ctx f32 +%llu = %e (%X)\n", offset, poly::m128_f32<0>(value), + poly::m128_i32<0>(value)); } void TraceContextStoreF64(void* raw_context, uint64_t offset, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - union { - double d; - uint64_t x; - } f; - f.x = value.m128_i64[0]; - DPRINT("ctx f64 +%d = %lle (%llX)\n", offset, value.m128_i64[0], f.d); + DPRINT("ctx f64 +%llu = %le (%llX)\n", offset, poly::m128_f64<0>(value), + poly::m128_i64<0>(value)); } void TraceContextStoreV128(void* raw_context, uint64_t offset, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("ctx v128 +%d = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", offset, - value.m128_f32[0], value.m128_f32[1], value.m128_f32[2], - value.m128_f32[3], value.m128_i32[0], value.m128_i32[1], - value.m128_i32[2], value.m128_i32[3]); + DPRINT("ctx v128 +%llu = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", offset, + poly::m128_f32<0>(value), poly::m128_f32<1>(value), + poly::m128_f32<2>(value), poly::m128_f32<3>(value), + poly::m128_i32<0>(value), poly::m128_i32<1>(value), + poly::m128_i32<2>(value), poly::m128_i32<3>(value)); } void TraceMemoryLoadI8(void* raw_context, uint64_t address, uint8_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("%d (%X) = load.i8 %.8X\n", (int8_t)value, value, address); + DPRINT("%d (%X) = load.i8 %.8llX\n", (int8_t)value, value, address); } void TraceMemoryLoadI16(void* raw_context, uint64_t address, uint16_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("%d (%X) = load.i16 %.8X\n", (int16_t)value, value, address); + DPRINT("%d (%X) = load.i16 %.8llX\n", (int16_t)value, value, address); } void TraceMemoryLoadI32(void* raw_context, uint64_t address, uint32_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("%d (%X) = load.i32 %.8X\n", (int32_t)value, value, address); + DPRINT("%d (%X) = load.i32 %.8llX\n", (int32_t)value, value, address); } void TraceMemoryLoadI64(void* raw_context, uint64_t address, uint64_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("%lld (%llX) = load.i64 %.8X\n", (int64_t)value, value, address); + DPRINT("%lld (%llX) = load.i64 %.8llX\n", (int64_t)value, value, address); } void TraceMemoryLoadF32(void* raw_context, uint64_t address, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("%e (%X) = load.f32 %.8X\n", value.m128_f32[0], value.m128_i32[0], - address); + DPRINT("%e (%X) = load.f32 %.8llX\n", poly::m128_f32<0>(value), + poly::m128_i32<0>(value), address); } void TraceMemoryLoadF64(void* raw_context, uint64_t address, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - union { - double d; - uint64_t x; - } f; - f.x = value.m128_i64[0]; - DPRINT("%lle (%llX) = load.f64 %.8X\n", f.d, value.m128_i64[0], address); + DPRINT("%le (%llX) = load.f64 %.8llX\n", poly::m128_f64<0>(value), + poly::m128_i64<0>(value), address); } void TraceMemoryLoadV128(void* raw_context, uint64_t address, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = load.v128 %.8X\n", - value.m128_f32[0], value.m128_f32[1], value.m128_f32[2], - value.m128_f32[3], value.m128_i32[0], value.m128_i32[1], - value.m128_i32[2], value.m128_i32[3], address); + DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = load.v128 %.8llX\n", + poly::m128_f32<0>(value), poly::m128_f32<1>(value), + poly::m128_f32<2>(value), poly::m128_f32<3>(value), + poly::m128_i32<0>(value), poly::m128_i32<1>(value), + poly::m128_i32<2>(value), poly::m128_i32<3>(value), address); } void TraceMemoryStoreI8(void* raw_context, uint64_t address, uint8_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("store.i8 %.8X = %d (%X)\n", address, (int8_t)value, value); + DPRINT("store.i8 %.8llX = %d (%X)\n", address, (int8_t)value, value); } void TraceMemoryStoreI16(void* raw_context, uint64_t address, uint16_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("store.i16 %.8X = %d (%X)\n", address, (int16_t)value, value); + DPRINT("store.i16 %.8llX = %d (%X)\n", address, (int16_t)value, value); } void TraceMemoryStoreI32(void* raw_context, uint64_t address, uint32_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("store.i32 %.8X = %d (%X)\n", address, (int32_t)value, value); + DPRINT("store.i32 %.8llX = %d (%X)\n", address, (int32_t)value, value); } void TraceMemoryStoreI64(void* raw_context, uint64_t address, uint64_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("store.i64 %.8X = %lld (%llX)\n", address, (int64_t)value, value); + DPRINT("store.i64 %.8llX = %lld (%llX)\n", address, (int64_t)value, value); } void TraceMemoryStoreF32(void* raw_context, uint64_t address, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("store.f32 %.8X = %e (%X)\n", address, value.m128_f32[0], - value.m128_i32[0]); + DPRINT("store.f32 %.8llX = %e (%X)\n", address, poly::m128_f32<0>(value), + poly::m128_i32<0>(value)); } void TraceMemoryStoreF64(void* raw_context, uint64_t address, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - union { - double d; - uint64_t x; - } f; - f.x = value.m128_i64[0]; - DPRINT("store.f64 %.8X = %lle (%llX)\n", address, f.d, value.m128_i64[0]); + DPRINT("store.f64 %.8llX = %le (%llX)\n", address, poly::m128_f64<0>(value), + poly::m128_i64<0>(value)); } void TraceMemoryStoreV128(void* raw_context, uint64_t address, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("store.v128 %.8X = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", - address, value.m128_f32[0], value.m128_f32[1], value.m128_f32[2], - value.m128_f32[3], value.m128_i32[0], value.m128_i32[1], - value.m128_i32[2], value.m128_i32[3]); + DPRINT("store.v128 %.8llX = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", + address, poly::m128_f32<0>(value), poly::m128_f32<1>(value), + poly::m128_f32<2>(value), poly::m128_f32<3>(value), + poly::m128_i32<0>(value), poly::m128_i32<1>(value), + poly::m128_i32<2>(value), poly::m128_i32<3>(value)); } } // namespace x64 diff --git a/src/alloy/backend/x64/x64_tracers.h b/src/alloy/backend/x64/x64_tracers.h index 8151b4305..6ef29927b 100644 --- a/src/alloy/backend/x64/x64_tracers.h +++ b/src/alloy/backend/x64/x64_tracers.h @@ -12,21 +12,7 @@ #include -#if XE_LIKE_WIN32 #include -#else -typedef union __declspec(align(16)) __m128 { - float m128_f32[4]; - uint64_t m128_u64[2]; - int8_t m128_i8[16]; - int16_t m128_i16[8]; - int32_t m128_i32[4]; - int64_t m128_i64[2]; - uint8_t m128_u8[16]; - uint16_t m128_u16[8]; - uint32_t m128_u32[4]; -} __m128; -#endif namespace alloy { namespace backend { diff --git a/src/alloy/compiler/passes/constant_propagation_pass.cc b/src/alloy/compiler/passes/constant_propagation_pass.cc index 9dcb8d3ec..d9f2b8620 100644 --- a/src/alloy/compiler/passes/constant_propagation_pass.cc +++ b/src/alloy/compiler/passes/constant_propagation_pass.cc @@ -430,6 +430,10 @@ int ConstantPropagationPass::Run(HIRBuilder* builder) { // Quite a few of these, from building vec128s. } break; + + default: + // Ignored. + break; } i = i->next; } diff --git a/src/alloy/compiler/passes/context_promotion_pass.cc b/src/alloy/compiler/passes/context_promotion_pass.cc index 2f14acd77..1b028464c 100644 --- a/src/alloy/compiler/passes/context_promotion_pass.cc +++ b/src/alloy/compiler/passes/context_promotion_pass.cc @@ -31,7 +31,7 @@ using alloy::hir::Instr; using alloy::hir::Value; ContextPromotionPass::ContextPromotionPass() - : context_values_size_(0), context_values_(0), CompilerPass() {} + : CompilerPass(), context_values_size_(0), context_values_(0) {} ContextPromotionPass::~ContextPromotionPass() { if (context_values_) { diff --git a/src/alloy/compiler/passes/data_flow_analysis_pass.cc b/src/alloy/compiler/passes/data_flow_analysis_pass.cc index 5c7fbdc89..4c82d527c 100644 --- a/src/alloy/compiler/passes/data_flow_analysis_pass.cc +++ b/src/alloy/compiler/passes/data_flow_analysis_pass.cc @@ -13,11 +13,15 @@ #include #include +#if XE_COMPILER_MSVC #pragma warning(push) #pragma warning(disable : 4244) #pragma warning(disable : 4267) #include #pragma warning(pop) +#else +#include +#endif // XE_COMPILER_MSVC namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/passes/dead_code_elimination_pass.cc b/src/alloy/compiler/passes/dead_code_elimination_pass.cc index f18bfc26f..40f83bb3d 100644 --- a/src/alloy/compiler/passes/dead_code_elimination_pass.cc +++ b/src/alloy/compiler/passes/dead_code_elimination_pass.cc @@ -153,9 +153,9 @@ void DeadCodeEliminationPass::MakeNopRecursive(Instr* i) { #define MAKE_NOP_SRC(n) \ if (i->src##n##_use) { \ Value::Use* use = i->src##n##_use; \ - Value* value = i->src##n##.value; \ + Value* value = i->src##n.value; \ i->src##n##_use = NULL; \ - i->src##n##.value = NULL; \ + i->src##n.value = NULL; \ value->RemoveUse(use); \ if (!value->use_head) { \ /* Value is now unused, so recursively kill it. */ \ @@ -192,7 +192,6 @@ void DeadCodeEliminationPass::ReplaceAssignment(Instr* i) { } bool DeadCodeEliminationPass::CheckLocalUse(Instr* i) { - auto slot = i->src1.value; auto src = i->src2.value; auto use = src->use_head; diff --git a/src/alloy/compiler/passes/register_allocation_pass.cc b/src/alloy/compiler/passes/register_allocation_pass.cc index aa6fcf13c..26840a20f 100644 --- a/src/alloy/compiler/passes/register_allocation_pass.cc +++ b/src/alloy/compiler/passes/register_allocation_pass.cc @@ -29,7 +29,7 @@ using alloy::hir::Value; #define ASSERT_NO_CYCLES 0 RegisterAllocationPass::RegisterAllocationPass(const MachineInfo* machine_info) - : machine_info_(machine_info), CompilerPass() { + : CompilerPass() { // Initialize register sets. // TODO(benvanik): rewrite in a way that makes sense - this is terrible. auto mi_sets = machine_info->register_sets; @@ -301,11 +301,11 @@ bool RegisterAllocationPass::TryAllocateRegister(Value* value) { // Find the first free register, if any. // We have to ensure it's a valid one (in our count). - unsigned long first_unused = 0; - bool all_used = - _BitScanForward(&first_unused, usage_set->availability.to_ulong()) == 0; - if (!all_used && first_unused < usage_set->count) { - // Available! Use it!. + uint32_t first_unused = 0; + bool none_used = poly::bit_scan_forward( + static_cast(usage_set->availability.to_ulong()), &first_unused); + if (none_used && first_unused < usage_set->count) { + // Available! Use it! value->reg.set = usage_set->set; value->reg.index = first_unused; MarkRegUsed(value->reg, value, value->use_head); diff --git a/src/alloy/compiler/passes/register_allocation_pass.h b/src/alloy/compiler/passes/register_allocation_pass.h index 47b88cae0..70f212c08 100644 --- a/src/alloy/compiler/passes/register_allocation_pass.h +++ b/src/alloy/compiler/passes/register_allocation_pass.h @@ -69,7 +69,6 @@ class RegisterAllocationPass : public CompilerPass { void SortUsageList(hir::Value* value); private: - const backend::MachineInfo* machine_info_; struct { RegisterSetUsage* int_set = nullptr; RegisterSetUsage* float_set = nullptr; diff --git a/src/alloy/compiler/passes/validation_pass.cc b/src/alloy/compiler/passes/validation_pass.cc index 4ddb06cf2..a199e9416 100644 --- a/src/alloy/compiler/passes/validation_pass.cc +++ b/src/alloy/compiler/passes/validation_pass.cc @@ -33,11 +33,13 @@ ValidationPass::~ValidationPass() {} int ValidationPass::Run(HIRBuilder* builder) { SCOPE_profile_cpu_f("alloy"); +#if 0 StringBuffer str; builder->Dump(&str); printf(str.GetString()); fflush(stdout); str.Reset(); +#endif // 0 auto block = builder->first_block(); while (block) { diff --git a/src/alloy/compiler/passes/value_reduction_pass.cc b/src/alloy/compiler/passes/value_reduction_pass.cc index 94dbba0bb..4c5cf2e28 100644 --- a/src/alloy/compiler/passes/value_reduction_pass.cc +++ b/src/alloy/compiler/passes/value_reduction_pass.cc @@ -13,11 +13,15 @@ #include #include +#if XE_COMPILER_MSVC #pragma warning(push) #pragma warning(disable : 4244) #pragma warning(disable : 4267) #include #pragma warning(pop) +#else +#include +#endif // XE_COMPILER_MSVC namespace alloy { namespace compiler { diff --git a/src/alloy/core.h b/src/alloy/core.h index df3724e7b..b7f5dae91 100644 --- a/src/alloy/core.h +++ b/src/alloy/core.h @@ -13,6 +13,8 @@ // TODO(benvanik): move the common stuff into here? #include +#include + #include #include #include diff --git a/src/alloy/frontend/ppc/ppc_disasm.cc b/src/alloy/frontend/ppc/ppc_disasm.cc index 98f7a7746..c362cae2c 100644 --- a/src/alloy/frontend/ppc/ppc_disasm.cc +++ b/src/alloy/frontend/ppc/ppc_disasm.cc @@ -286,16 +286,9 @@ void Disasm_bcx(InstrData& i, StringBuffer* str) { } else { s1 = ""; } - char s2[8] = { - 'c', 'r', 0, - }; + char s2[8] = {0}; if (!XESELECTBITS(i.B.BO, 4, 4)) { - char* s2a = _itoa(i.B.BI >> 2, s2 + 2, 10); - s2a += xestrlena(s2a); - s2a[0] = ','; - s2a[1] = ' '; - } else { - s2[0] = 0; + xesnprintfa(s2, XECOUNT(s2), "cr%d, ", i.B.BI >> 2); } uint32_t nia; if (i.B.AA) { @@ -309,16 +302,9 @@ void Disasm_bcx(InstrData& i, StringBuffer* str) { void Disasm_bcctrx(InstrData& i, StringBuffer* str) { // TODO(benvanik): mnemonics const char* s0 = i.XL.LK ? "lr, " : ""; - char s2[8] = { - 'c', 'r', 0, - }; + char s2[8] = {0}; if (!XESELECTBITS(i.XL.BO, 4, 4)) { - char* s2a = _itoa(i.XL.BI >> 2, s2 + 2, 10); - s2a += xestrlena(s2a); - s2a[0] = ','; - s2a[1] = ' '; - } else { - s2[0] = 0; + xesnprintfa(s2, XECOUNT(s2), "cr%d, ", i.XL.BI >> 2); } str->Append("%-8s %s%sctr", i.type->name, s0, s2); // TODO(benvanik): resolve target name? @@ -334,16 +320,9 @@ void Disasm_bclrx(InstrData& i, StringBuffer* str) { } else { s1 = ""; } - char s2[8] = { - 'c', 'r', 0, - }; + char s2[8] = {0}; if (!XESELECTBITS(i.XL.BO, 4, 4)) { - char* s2a = _itoa(i.XL.BI >> 2, s2 + 2, 10); - s2a += xestrlena(s2a); - s2a[0] = ','; - s2a[1] = ' '; - } else { - s2[0] = 0; + xesnprintfa(s2, XECOUNT(s2), "cr%d, ", i.XL.BI >> 2); } str->Append("%-8s %s%s", name, s1, s2); } diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index 9b0a845c5..583e1c00b 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -588,7 +588,7 @@ int InstrEmit_vcmpxxfp_(PPCHIRBuilder& f, InstrData& i, vcmpxxfp_op cmpop, v = f.VectorCompareSGE(f.LoadVR(va), f.LoadVR(vb), FLOAT32_TYPE); break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(cmpop); return 1; } if (rc) { @@ -648,7 +648,7 @@ int InstrEmit_vcmpxxi_(PPCHIRBuilder& f, InstrData& i, vcmpxxi_op cmpop, v = f.VectorCompareEQ(f.LoadVR(va), f.LoadVR(vb), INT32_TYPE); break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(width); return 1; } break; @@ -664,7 +664,7 @@ int InstrEmit_vcmpxxi_(PPCHIRBuilder& f, InstrData& i, vcmpxxi_op cmpop, v = f.VectorCompareSGT(f.LoadVR(va), f.LoadVR(vb), INT32_TYPE); break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(width); return 1; } break; @@ -680,12 +680,12 @@ int InstrEmit_vcmpxxi_(PPCHIRBuilder& f, InstrData& i, vcmpxxi_op cmpop, v = f.VectorCompareUGT(f.LoadVR(va), f.LoadVR(vb), INT32_TYPE); break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(width); return 1; } break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(cmpop); return 1; } if (rc) { @@ -1117,7 +1117,7 @@ XEEMITTER(vpermwi128, VX128_P(6, 528), VX128_P)(PPCHIRBuilder& f, int InstrEmit_vrefp_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { // (VD) <- 1/(VB) - vec128_t one = {1, 1, 1, 1}; + vec128_t one = {{{1, 1, 1, 1}}}; Value* v = f.Div(f.LoadConstant(one), f.LoadVR(vb)); f.StoreVR(vd, v); return 0; @@ -1784,7 +1784,7 @@ XEEMITTER(vpkd3d128, VX128_4(6, 1552), VX128_4)(PPCHIRBuilder& f, v = f.Pack(v, PACK_TYPE_FLOAT16_4); break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(type); return 1; } // http://hlssmod.net/he_code/public/pixelwriter.h @@ -1819,7 +1819,7 @@ XEEMITTER(vpkd3d128, VX128_4(6, 1552), VX128_4)(PPCHIRBuilder& f, control = (control & ~mask) | (src & mask); break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(pack); return 1; } v = f.Permute(f.LoadConstant(control), f.LoadVR(vd), v, INT32_TYPE); @@ -1851,7 +1851,7 @@ XEEMITTER(vupkd3d128, VX128_3(6, 2032), VX128_3)(PPCHIRBuilder& f, v = f.Unpack(v, PACK_TYPE_FLOAT16_4); break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(type); return 1; } f.StoreVR(vd, v); diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index 4b81401dd..1d737917f 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -32,7 +32,7 @@ using alloy::runtime::Runtime; using alloy::runtime::FunctionInfo; PPCHIRBuilder::PPCHIRBuilder(PPCFrontend* frontend) - : frontend_(frontend), HIRBuilder() { + : HIRBuilder(), frontend_(frontend) { comment_buffer_ = new StringBuffer(4096); } @@ -88,8 +88,6 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, bool with_debug_info) { // TODO(benvanik): find a way to avoid using the opcode tables. i.type = GetInstrType(i.code); - Instr* prev_instr = last_instr(); - // Mark label, if we were assigned one earlier on in the walk. // We may still get a label, but it'll be inserted by LookupLabel // as needed. @@ -120,7 +118,7 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, bool with_debug_info) { instr_offset_list_[offset] = first_instr; if (!i.type) { - XELOGCPU("Invalid instruction %.8X %.8X", i.address, i.code); + XELOGCPU("Invalid instruction %.8llX %.8X", i.address, i.code); Comment("INVALID!"); // TraceInvalidInstruction(i); continue; @@ -135,7 +133,7 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, bool with_debug_info) { } if (!i.type->emit || emit(*this, i)) { - XELOGCPU("Unimplemented instr %.8X %.8X %s", i.address, i.code, + XELOGCPU("Unimplemented instr %.8llX %.8X %s", i.address, i.code, i.type->name); Comment("UNIMPLEMENTED!"); // DebugBreak(); diff --git a/src/alloy/frontend/ppc/ppc_instr.cc b/src/alloy/frontend/ppc/ppc_instr.cc index 83647dfe7..c7029158a 100644 --- a/src/alloy/frontend/ppc/ppc_instr.cc +++ b/src/alloy/frontend/ppc/ppc_instr.cc @@ -146,7 +146,7 @@ void InstrAccessBits::MarkAccess(InstrRegister& reg) { } break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(reg.set); break; } } diff --git a/src/alloy/hir/block.cc b/src/alloy/hir/block.cc index 60e9f988d..66160338f 100644 --- a/src/alloy/hir/block.cc +++ b/src/alloy/hir/block.cc @@ -20,7 +20,7 @@ void Block::AssertNoCycles() { if (!hare) { return; } - while (hare = hare->next) { + while ((hare = hare->next)) { if (hare == tortoise) { // Cycle! XEASSERTALWAYS(); diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index 3cd66c157..d25aaac23 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -273,7 +273,7 @@ void HIRBuilder::AssertNoCycles() { if (!hare) { return; } - while (hare = hare->next) { + while ((hare = hare->next)) { if (hare == tortoise) { // Cycle! XEASSERTALWAYS(); diff --git a/src/alloy/hir/value.cc b/src/alloy/hir/value.cc index 3d78c407b..41c162080 100644 --- a/src/alloy/hir/value.cc +++ b/src/alloy/hir/value.cc @@ -47,7 +47,7 @@ uint32_t Value::AsUint32() { case INT64_TYPE: return (uint32_t)constant.i64; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(type); return 0; } } @@ -64,7 +64,7 @@ uint64_t Value::AsUint64() { case INT64_TYPE: return constant.i64; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(type); return 0; } } @@ -88,9 +88,10 @@ void Value::ZeroExtend(TypeName target_type) { type = target_type; constant.i64 = constant.i64 & 0xFFFFFFFF; return; + default: + XEASSERTUNHANDLEDCASE(type); + break; } - // Unsupported types. - XEASSERTALWAYS(); } void Value::SignExtend(TypeName target_type) { @@ -100,37 +101,44 @@ void Value::SignExtend(TypeName target_type) { switch (target_type) { case INT16_TYPE: constant.i16 = constant.i8; - break; + return; case INT32_TYPE: constant.i32 = constant.i8; - break; + return; case INT64_TYPE: constant.i64 = constant.i8; - break; + return; + default: + XEASSERTUNHANDLEDCASE(target_type); + return; } - return; case INT16_TYPE: type = target_type; switch (target_type) { case INT32_TYPE: constant.i32 = constant.i16; - break; + return; case INT64_TYPE: constant.i64 = constant.i16; - break; + return; + default: + XEASSERTUNHANDLEDCASE(target_type); + return; } - return; case INT32_TYPE: type = target_type; switch (target_type) { case INT64_TYPE: constant.i64 = constant.i32; - break; + return; + default: + XEASSERTUNHANDLEDCASE(target_type); + return; } + default: + XEASSERTUNHANDLEDCASE(); return; } - // Unsupported types. - XEASSERTALWAYS(); } void Value::Truncate(TypeName target_type) { @@ -141,8 +149,10 @@ void Value::Truncate(TypeName target_type) { type = target_type; constant.i64 = constant.i64 & 0xFF; return; + default: + XEASSERTUNHANDLEDCASE(target_type); + return; } - break; case INT32_TYPE: switch (target_type) { case INT8_TYPE: @@ -153,8 +163,10 @@ void Value::Truncate(TypeName target_type) { type = target_type; constant.i64 = constant.i64 & 0xFFFF; return; + default: + XEASSERTUNHANDLEDCASE(target_type); + return; } - break; case INT64_TYPE: switch (target_type) { case INT8_TYPE: @@ -169,11 +181,14 @@ void Value::Truncate(TypeName target_type) { type = target_type; constant.i64 = constant.i64 & 0xFFFFFFFF; return; + default: + XEASSERTUNHANDLEDCASE(target_type); + return; } - break; + default: + XEASSERTUNHANDLEDCASE(type); + return; } - // Unsupported types. - XEASSERTALWAYS(); } void Value::Convert(TypeName target_type, RoundMode round_mode) { @@ -215,7 +230,7 @@ bool Value::Add(Value* other) { constant.f64 += other->constant.f64; break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(type); break; } return did_carry; @@ -249,7 +264,7 @@ bool Value::Sub(Value* other) { constant.f64 -= other->constant.f64; break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(type); break; } return did_carry; @@ -277,7 +292,7 @@ void Value::Mul(Value* other) { constant.f64 *= other->constant.f64; break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(type); break; } } @@ -304,7 +319,7 @@ void Value::Div(Value* other) { constant.f64 /= other->constant.f64; break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(type); break; } } @@ -340,7 +355,7 @@ void Value::Neg() { constant.f64 = -constant.f64; break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(type); break; } } @@ -366,7 +381,7 @@ void Value::Abs() { constant.f64 = abs(constant.f64); break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(type); break; } } @@ -380,7 +395,7 @@ void Value::Sqrt() { constant.f64 = 1.0 / sqrt(constant.f64); break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(type); break; } } @@ -394,7 +409,7 @@ void Value::RSqrt() { constant.f64 = sqrt(constant.f64); break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(type); break; } } @@ -415,7 +430,7 @@ void Value::And(Value* other) { constant.i64 &= other->constant.i64; break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(type); break; } } @@ -436,7 +451,7 @@ void Value::Or(Value* other) { constant.i64 |= other->constant.i64; break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(type); break; } } @@ -457,7 +472,7 @@ void Value::Xor(Value* other) { constant.i64 ^= other->constant.i64; break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(type); break; } } @@ -481,7 +496,7 @@ void Value::Not() { constant.v128.high = ~constant.v128.high; break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(type); break; } } @@ -502,7 +517,7 @@ void Value::Shl(Value* other) { constant.i64 <<= other->constant.i8; break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(type); break; } } @@ -523,7 +538,7 @@ void Value::Shr(Value* other) { constant.i64 = (uint16_t)constant.i64 >> other->constant.i8; break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(type); break; } } @@ -544,7 +559,7 @@ void Value::Sha(Value* other) { constant.i64 = constant.i64 >> other->constant.i8; break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(type); break; } } @@ -569,7 +584,7 @@ void Value::ByteSwap() { } break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(type); break; } } @@ -577,19 +592,19 @@ void Value::ByteSwap() { void Value::CountLeadingZeros(const Value* other) { switch (other->type) { case INT8_TYPE: - constant.i8 = static_cast(__lzcnt16(other->constant.i8) - 8); + constant.i8 = poly::lzcnt(constant.i8); break; case INT16_TYPE: - constant.i8 = static_cast(__lzcnt16(other->constant.i16)); + constant.i8 = poly::lzcnt(constant.i16); break; case INT32_TYPE: - constant.i8 = static_cast(__lzcnt(other->constant.i32)); + constant.i8 = poly::lzcnt(constant.i32); break; case INT64_TYPE: - constant.i8 = static_cast(__lzcnt64(other->constant.i64)); + constant.i8 = poly::lzcnt(constant.i64); break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(type); break; } } diff --git a/src/alloy/hir/value.h b/src/alloy/hir/value.h index edde60c67..eb87a983f 100644 --- a/src/alloy/hir/value.h +++ b/src/alloy/hir/value.h @@ -31,11 +31,6 @@ enum TypeName { MAX_TYPENAME, }; -static bool IsIntType(TypeName type_name) { return type_name <= INT64_TYPE; } -static bool IsFloatType(TypeName type_name) { - return type_name == FLOAT32_TYPE || type_name == FLOAT64_TYPE; -} -static bool IsVecType(TypeName type_name) { return type_name == VEC128_TYPE; } static size_t GetTypeSize(TypeName type_name) { switch (type_name) { case INT8_TYPE: @@ -50,9 +45,11 @@ static size_t GetTypeSize(TypeName type_name) { return 4; case FLOAT64_TYPE: return 8; - default: case VEC128_TYPE: return 16; + default: + XEASSERTUNHANDLEDCASE(type_name); + break; } } diff --git a/src/alloy/runtime/debugger.h b/src/alloy/runtime/debugger.h index 5eb399a0f..40eb93d04 100644 --- a/src/alloy/runtime/debugger.h +++ b/src/alloy/runtime/debugger.h @@ -62,9 +62,9 @@ class BreakpointHitEvent : public DebugEvent { public: BreakpointHitEvent(Debugger* debugger, ThreadState* thread_state, Breakpoint* breakpoint) - : thread_state_(thread_state), - breakpoint_(breakpoint), - DebugEvent(debugger) {} + : DebugEvent(debugger), + thread_state_(thread_state), + breakpoint_(breakpoint) {} virtual ~BreakpointHitEvent() {} ThreadState* thread_state() const { return thread_state_; } Breakpoint* breakpoint() const { return breakpoint_; } diff --git a/src/alloy/runtime/function.cc b/src/alloy/runtime/function.cc index 6b1125681..974b50eaa 100644 --- a/src/alloy/runtime/function.cc +++ b/src/alloy/runtime/function.cc @@ -81,7 +81,7 @@ int Function::Call(ThreadState* thread_state, uint64_t return_address) { handler(thread_state->raw_context(), symbol_info_->extern_arg0(), symbol_info_->extern_arg1()); } else { - XELOGW("undefined extern call to %.8X %s", symbol_info_->address(), + XELOGW("undefined extern call to %.8llX %s", symbol_info_->address(), symbol_info_->name()); result = 1; } diff --git a/src/alloy/runtime/instrument.cc b/src/alloy/runtime/instrument.cc index 87bdcec78..3466d7cd5 100644 --- a/src/alloy/runtime/instrument.cc +++ b/src/alloy/runtime/instrument.cc @@ -44,7 +44,7 @@ bool Instrument::Detach() { } FunctionInstrument::FunctionInstrument(Runtime* runtime, Function* function) - : target_(function), Instrument(runtime) {} + : Instrument(runtime), target_(function) {} bool FunctionInstrument::Attach() { if (!Instrument::Attach()) { @@ -81,7 +81,7 @@ void FunctionInstrument::Exit(ThreadState* thread_state) { MemoryInstrument::MemoryInstrument(Runtime* runtime, uint64_t address, uint64_t end_address) - : address_(address), end_address_(end_address), Instrument(runtime) {} + : Instrument(runtime), address_(address), end_address_(end_address) {} bool MemoryInstrument::Attach() { if (!Instrument::Attach()) { diff --git a/src/alloy/runtime/raw_module.cc b/src/alloy/runtime/raw_module.cc index 32346bc1a..43df9f67a 100644 --- a/src/alloy/runtime/raw_module.cc +++ b/src/alloy/runtime/raw_module.cc @@ -13,11 +13,11 @@ namespace alloy { namespace runtime { RawModule::RawModule(Runtime* runtime) - : name_(0), + : Module(runtime), + name_(0), base_address_(0), low_address_(0), - high_address_(0), - Module(runtime) {} + high_address_(0) {} RawModule::~RawModule() { if (base_address_) { diff --git a/src/alloy/runtime/runtime.cc b/src/alloy/runtime/runtime.cc index 233dc0c07..5d8f4bc23 100644 --- a/src/alloy/runtime/runtime.cc +++ b/src/alloy/runtime/runtime.cc @@ -27,7 +27,7 @@ using alloy::backend::Backend; using alloy::frontend::Frontend; Runtime::Runtime(Memory* memory) - : memory_(memory), debugger_(0), backend_(0), frontend_(0) { + : memory_(memory), debugger_(0), frontend_(0), backend_(0) { tracing::Initialize(); } diff --git a/src/alloy/runtime/symbol_info.cc b/src/alloy/runtime/symbol_info.cc index 7e060ff7f..2392cc452 100644 --- a/src/alloy/runtime/symbol_info.cc +++ b/src/alloy/runtime/symbol_info.cc @@ -14,8 +14,8 @@ namespace runtime { SymbolInfo::SymbolInfo(Type type, Module* module, uint64_t address) : type_(type), - status_(STATUS_DEFINING), module_(module), + status_(STATUS_DEFINING), address_(address), name_(0) {} @@ -33,10 +33,10 @@ void SymbolInfo::set_name(const char* name) { } FunctionInfo::FunctionInfo(Module* module, uint64_t address) - : end_address_(0), + : SymbolInfo(SymbolInfo::TYPE_FUNCTION, module, address), + end_address_(0), behavior_(BEHAVIOR_DEFAULT), - function_(0), - SymbolInfo(SymbolInfo::TYPE_FUNCTION, module, address) { + function_(0) { xe_zero_struct(&extern_info_, sizeof(extern_info_)); } diff --git a/src/alloy/runtime/thread_state.cc b/src/alloy/runtime/thread_state.cc index 828863fc5..cfe153bd6 100644 --- a/src/alloy/runtime/thread_state.cc +++ b/src/alloy/runtime/thread_state.cc @@ -14,7 +14,7 @@ namespace alloy { namespace runtime { -__declspec(thread) ThreadState* thread_state_ = NULL; +thread_local ThreadState* thread_state_ = NULL; ThreadState::ThreadState(Runtime* runtime, uint32_t thread_id) : runtime_(runtime), diff --git a/src/alloy/tracing/tracing.cc b/src/alloy/tracing/tracing.cc index 16c7eaf75..ace0d54a9 100644 --- a/src/alloy/tracing/tracing.cc +++ b/src/alloy/tracing/tracing.cc @@ -25,7 +25,7 @@ namespace alloy { namespace tracing { Channel* shared_channel = NULL; -__declspec(thread) Tracer* thread_tracer = NULL; +thread_local Tracer* thread_tracer = NULL; void CleanupTracing() { if (shared_channel) { diff --git a/src/poly/cxx_compat.h b/src/poly/cxx_compat.h new file mode 100644 index 000000000..88d647aa5 --- /dev/null +++ b/src/poly/cxx_compat.h @@ -0,0 +1,25 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef POLY_POLY_CXX_COMPAT_H_ +#define POLY_POLY_CXX_COMPAT_H_ + +// C++11 thread local storage. +// http://en.cppreference.com/w/cpp/language/storage_duration +#if XE_COMPILER_MSVC +// VC++2014 may have this. +#define thread_local __declspec(thread) +#elif XE_LIKE_OSX +// Clang supports it on OSX but the runtime doesn't. +#define thread_local __thread +#endif // XE_COMPILER_MSVC + +namespace poly {} // namespace poly + +#endif // POLY_POLY_CXX_COMPAT_H_ diff --git a/src/poly/math.h b/src/poly/math.h new file mode 100644 index 000000000..d332191b5 --- /dev/null +++ b/src/poly/math.h @@ -0,0 +1,104 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef POLY_MATH_H_ +#define POLY_MATH_H_ + +#include + +#include +#include + +namespace poly { + +// lzcnt instruction, typed for integers of all sizes. +// The number of leading zero bits in the value parameter. If value is zero, the +// return value is the size of the input operand (8, 16, 32, or 64). If the most +// significant bit of value is one, the return value is zero. +#if XE_COMPILER_MSVC +uint8_t lzcnt(uint8_t v) { return static_cast(__lzcnt16(v) - 8); } +uint8_t lzcnt(uint16_t v) { return static_cast(__lzcnt16(v)); } +uint8_t lzcnt(uint32_t v) { return static_cast(__lzcnt(v)); } +uint8_t lzcnt(uint64_t v) { return static_cast(__lzcnt64(v)); } +#else +uint8_t lzcnt(uint8_t v) { return static_cast(__builtin_clzs(v) - 8); } +uint8_t lzcnt(uint16_t v) { return static_cast(__builtin_clzs(v)); } +uint8_t lzcnt(uint32_t v) { return static_cast(__builtin_clz(v)); } +uint8_t lzcnt(uint64_t v) { return static_cast(__builtin_clzll(v)); } +#endif // XE_COMPILER_MSVC +uint8_t lzcnt(int8_t v) { return lzcnt(static_cast(v)); } +uint8_t lzcnt(int16_t v) { return lzcnt(static_cast(v)); } +uint8_t lzcnt(int32_t v) { return lzcnt(static_cast(v)); } +uint8_t lzcnt(int64_t v) { return lzcnt(static_cast(v)); } + +// BitScanForward (bsf). +// Search the value from least significant bit (LSB) to the most significant bit +// (MSB) for a set bit (1). +// Returns false if no bits are set and the output index is invalid. +#if XE_COMPILER_MSVC +bool bit_scan_forward(uint32_t v, uint32_t* out_first_set_index) { + return _BitScanForward(out_first_set_index, v) != 0; +} +bool bit_scan_forward(uint64_t v, uint32_t* out_first_set_index) { + return _BitScanForward64(out_first_set_index, v) != 0; +} +#else +bool bit_scan_forward(uint32_t v, uint32_t* out_first_set_index) { + int i = ffs(v); + *out_first_set_index = i; + return i != 0; +} +bool bit_scan_forward(uint64_t v, uint32_t* out_first_set_index) { + int i = ffsll(v); + *out_first_set_index = i; + return i != 0; +} +#endif // XE_COMPILER_MSVC +bool bit_scan_forward(int32_t v, uint32_t* out_first_set_index) { + return bit_scan_forward(static_cast(v), out_first_set_index); +} +bool bit_scan_forward(int64_t v, uint32_t* out_first_set_index) { + return bit_scan_forward(static_cast(v), out_first_set_index); +} + +// Utilities for SSE values. +template +float m128_f32(const __m128& v) { + float ret; + _mm_store_ss(&ret, _mm_shuffle_ps(v, v, _MM_SHUFFLE(N, N, N, N))); + return ret; +} +template +int32_t m128_i32(const __m128& v) { + union { + float f; + int32_t i; + } ret; + _mm_store_ss(&ret.f, _mm_shuffle_ps(v, v, _MM_SHUFFLE(N, N, N, N))); + return ret.i; +} +template +double m128_f64(const __m128& v) { + double ret; + _mm_store_sd(&ret, _mm_shuffle_ps(v, v, _MM_SHUFFLE(N, N, N, N))); + return ret; +} +template +int64_t m128_i64(const __m128& v) { + union { + double f; + int64_t i; + } ret; + _mm_store_sd(&ret.f, _mm_shuffle_ps(v, v, _MM_SHUFFLE(N, N, N, N))); + return ret.i; +} + +} // namespace poly + +#endif // POLY_MATH_H_ diff --git a/src/poly/poly.h b/src/poly/poly.h index f6e6eb97b..e9b10a17b 100644 --- a/src/poly/poly.h +++ b/src/poly/poly.h @@ -10,6 +10,9 @@ #ifndef POLY_POLY_H_ #define POLY_POLY_H_ +#include +#include + namespace poly {} // namespace poly #endif // POLY_POLY_H_ diff --git a/src/poly/sources.gypi b/src/poly/sources.gypi index 91b1b6c4f..d19d26fdd 100644 --- a/src/poly/sources.gypi +++ b/src/poly/sources.gypi @@ -1,6 +1,8 @@ # Copyright 2014 Ben Vanik. All Rights Reserved. { 'sources': [ + 'cxx_compat.h', + 'math.h', 'poly-private.h', 'poly.cc', 'poly.h', diff --git a/src/xenia/assert.h b/src/xenia/assert.h index 8215bd549..05803a62a 100644 --- a/src/xenia/assert.h +++ b/src/xenia/assert.h @@ -52,6 +52,7 @@ #define XEASSERTNOTZERO(expr) XEASSERTCORE( (expr) != 0 ) #define XEASSERTNULL(expr) XEASSERTCORE( (expr) == NULL ) #define XEASSERTNOTNULL(expr) XEASSERTCORE( (expr) != NULL ) +#define XEASSERTUNHANDLEDCASE(var) XEASSERTALWAYS() #if XE_COMPILER_MSVC diff --git a/src/xenia/kernel/xboxkrnl_modules.cc b/src/xenia/kernel/xboxkrnl_modules.cc index 222517882..319cc0ec2 100644 --- a/src/xenia/kernel/xboxkrnl_modules.cc +++ b/src/xenia/kernel/xboxkrnl_modules.cc @@ -43,7 +43,7 @@ X_STATUS xeExGetXConfigSetting( value = 0x00001000; // USA/Canada break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(setting); return X_STATUS_INVALID_PARAMETER_2; } break; @@ -80,12 +80,12 @@ X_STATUS xeExGetXConfigSetting( value = 0; break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(setting); return X_STATUS_INVALID_PARAMETER_2; } break; default: - XEASSERTALWAYS(); + XEASSERTUNHANDLEDCASE(category); return X_STATUS_INVALID_PARAMETER_1; } From f24b45a07c20796de30cc02d523d4584b32f1dfd Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 10 Jul 2014 23:51:28 -0700 Subject: [PATCH 018/388] Moving threading utils to poly. --- src/alloy/backend/x64/x64_sequences.cc | 21 ++++++++------- src/alloy/runtime/entry_table.cc | 2 +- src/alloy/runtime/module.cc | 6 ++--- src/alloy/runtime/thread_state.cc | 2 +- src/poly/poly.h | 1 + src/poly/sources.gypi | 3 +++ src/poly/threading.h | 36 ++++++++++++++++++++++++++ src/poly/threading_mac.cc | 32 +++++++++++++++++++++++ src/poly/threading_win.cc | 30 +++++++++++++++++++++ 9 files changed, 119 insertions(+), 14 deletions(-) create mode 100644 src/poly/threading.h create mode 100644 src/poly/threading_mac.cc create mode 100644 src/poly/threading_win.cc diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index e969fe402..496ffac17 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -29,21 +29,20 @@ #include #include -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::backend::x64; -using namespace alloy::hir; -using namespace alloy::runtime; +namespace alloy { +namespace backend { +namespace x64 { using namespace Xbyak; +// TODO(benvanik): direct usings. +using namespace alloy::hir; +using namespace alloy::runtime; + // Utilities/types used only in this file: #include -namespace { -static std::unordered_multimap sequence_table; -} // namespace - +std::unordered_multimap sequence_table; // Selects the right byte/word/etc from a vector. We need to flip logical // indices (0,1,2,3,4,5,6,7,...) = (3,2,1,0,7,6,5,4,...) @@ -5121,3 +5120,7 @@ bool alloy::backend::x64::SelectSequence(X64Emitter& e, const Instr* i, const In XELOGE("No sequence match for variant %s", i->opcode->name); return false; } + +} // namespace x64 +} // namespace backend +} // namespace alloy diff --git a/src/alloy/runtime/entry_table.cc b/src/alloy/runtime/entry_table.cc index 4d2bef52a..0277be312 100644 --- a/src/alloy/runtime/entry_table.cc +++ b/src/alloy/runtime/entry_table.cc @@ -48,7 +48,7 @@ Entry::Status EntryTable::GetOrCreate(uint64_t address, Entry** out_entry) { do { lock_.unlock(); // TODO(benvanik): sleep for less time? - Sleep(0); + poly::threading::Sleep(std::chrono::microseconds(100)); lock_.lock(); } while (entry->status == Entry::STATUS_COMPILING); } diff --git a/src/alloy/runtime/module.cc b/src/alloy/runtime/module.cc index f144de2e3..24e27f00c 100644 --- a/src/alloy/runtime/module.cc +++ b/src/alloy/runtime/module.cc @@ -42,7 +42,7 @@ SymbolInfo* Module::LookupSymbol(uint64_t address, bool wait) { do { lock_.unlock(); // TODO(benvanik): sleep for less time? - Sleep(0); + poly::threading::Sleep(std::chrono::microseconds(100)); lock_.lock(); } while (symbol_info->status() == SymbolInfo::STATUS_DECLARING); } else { @@ -75,7 +75,7 @@ SymbolInfo::Status Module::DeclareSymbol(SymbolInfo::Type type, do { lock_.unlock(); // TODO(benvanik): sleep for less time? - Sleep(0); + poly::threading::Sleep(std::chrono::microseconds(100)); lock_.lock(); } while (symbol_info->status() == SymbolInfo::STATUS_DECLARING); } @@ -135,7 +135,7 @@ SymbolInfo::Status Module::DefineSymbol(SymbolInfo* symbol_info) { do { lock_.unlock(); // TODO(benvanik): sleep for less time? - Sleep(0); + poly::threading::Sleep(std::chrono::microseconds(100)); lock_.lock(); } while (symbol_info->status() == SymbolInfo::STATUS_DEFINING); status = symbol_info->status(); diff --git a/src/alloy/runtime/thread_state.cc b/src/alloy/runtime/thread_state.cc index cfe153bd6..549d7d2d3 100644 --- a/src/alloy/runtime/thread_state.cc +++ b/src/alloy/runtime/thread_state.cc @@ -26,7 +26,7 @@ ThreadState::ThreadState(Runtime* runtime, uint32_t thread_id) if (thread_id_ == UINT_MAX) { // System thread. Assign the system thread ID with a high bit // set so people know what's up. - uint32_t system_thread_handle = GetCurrentThreadId(); + uint32_t system_thread_handle = poly::threading::current_thread_id(); thread_id_ = 0x80000000 | system_thread_handle; } backend_data_ = runtime->backend()->AllocThreadData(); diff --git a/src/poly/poly.h b/src/poly/poly.h index e9b10a17b..aab80b5e1 100644 --- a/src/poly/poly.h +++ b/src/poly/poly.h @@ -12,6 +12,7 @@ #include #include +#include namespace poly {} // namespace poly diff --git a/src/poly/sources.gypi b/src/poly/sources.gypi index d19d26fdd..2a6f55017 100644 --- a/src/poly/sources.gypi +++ b/src/poly/sources.gypi @@ -6,6 +6,7 @@ 'poly-private.h', 'poly.cc', 'poly.h', + 'threading.h', ], 'conditions': [ @@ -19,10 +20,12 @@ }], ['OS == "mac"', { 'sources': [ + 'threading_mac.cc', ], }], ['OS == "win"', { 'sources': [ + 'threading_win.cc', ], }], ], diff --git a/src/poly/threading.h b/src/poly/threading.h new file mode 100644 index 000000000..06e21c9c8 --- /dev/null +++ b/src/poly/threading.h @@ -0,0 +1,36 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef POLY_THREADING_H_ +#define POLY_THREADING_H_ + +#include +#include + +namespace poly { +namespace threading { + +// Gets a stable thread-specific ID, but may not be. Use for informative +// purposes only. +uint32_t current_thread_id(); + +// Yields the current thread to the scheduler. Maybe. +void Yield(); + +// Sleeps the current thread for at least as long as the given duration. +void Sleep(std::chrono::microseconds duration); +template +void Sleep(std::chrono::duration duration) { + Sleep(std::chrono::duration_cast(duration)); +} + +} // namespace threading +} // namespace poly + +#endif // POLY_THREADING_H_ diff --git a/src/poly/threading_mac.cc b/src/poly/threading_mac.cc new file mode 100644 index 000000000..55b508f35 --- /dev/null +++ b/src/poly/threading_mac.cc @@ -0,0 +1,32 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include +#include + +namespace poly { +namespace threading { + +uint32_t current_thread_id() { + mach_port_t tid = pthread_mach_thread_np(pthread_self()); + return static_cast(tid); +} + +void Yield() { pthread_yield_np(); } + +void Sleep(std::chrono::microseconds duration) { + timespec rqtp = {duration.count() / 1000000, duration.count() % 1000}; + nanosleep(&rqtp, nullptr); + // TODO(benvanik): spin while rmtp >0? +} + +} // namespace threading +} // namespace poly diff --git a/src/poly/threading_win.cc b/src/poly/threading_win.cc new file mode 100644 index 000000000..7b2b8be3d --- /dev/null +++ b/src/poly/threading_win.cc @@ -0,0 +1,30 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +namespace poly { +namespace threading { + +uint32_t current_thread_id() { + return static_cast(GetCurrentThreadId()); +} + +void Yield() { SwitchToThread(); } + +void Sleep(std::chrono::microseconds duration) { + if (duration.count() < 100) { + SwitchToThread(); + } else { + Sleep(duration.count() / 1000); + } +} + +} // namespace threading +} // namespace poly From 1d543429309c986c8a06f284d20a95e0cfb637df Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 11 Jul 2014 18:03:35 -0700 Subject: [PATCH 019/388] Starting to cleanup includes a bit. Still a mess. --- src/alloy/backend/x64/x64_emitter.cc | 2 +- src/alloy/backend/x64/x64_tracers.cc | 14 --- src/alloy/hir/value.cc | 2 +- src/alloy/hir/value.h | 2 +- src/alloy/runtime/debugger.h | 1 + src/alloy/runtime/entry_table.h | 1 + src/poly/config.h | 17 +++ src/poly/cxx_compat.h | 2 + src/poly/math.h | 59 ++++++---- src/poly/platform.h | 163 +++++++++++++++++++++++++++ src/poly/poly.h | 2 + src/poly/sources.gypi | 1 + src/poly/threading.h | 2 + src/poly/threading_win.cc | 4 +- src/xenia/assert.h | 1 - src/xenia/atomic.h | 3 +- src/xenia/byte_order.h | 2 + src/xenia/common.h | 1 - src/xenia/core/socket_win.cc | 3 +- src/xenia/gpu/resource_cache.h | 1 + src/xenia/kernel/fs/filesystem.h | 5 +- src/xenia/logging.h | 3 +- src/xenia/platform.h | 124 +------------------- src/xenia/platform_includes.h | 63 ----------- src/xenia/profiling.h | 1 - src/xenia/sources.gypi | 1 - src/xenia/string.h | 1 - src/xenia/types.h | 9 +- 28 files changed, 245 insertions(+), 245 deletions(-) create mode 100644 src/poly/config.h create mode 100644 src/poly/platform.h delete mode 100644 src/xenia/platform_includes.h diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index 797a03dd3..4b5383295 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -265,7 +265,7 @@ uint64_t ResolveFunctionSymbol(void* raw_context, uint64_t symbol_info_ptr) { // Overwrite the call site. // The return address points to ReloadRCX work after the call. -#if XE_WIN32_LIKE +#if XE_LIKE_WIN32 uint64_t return_address = reinterpret_cast(_ReturnAddress()); #else uint64_t return_address = diff --git a/src/alloy/backend/x64/x64_tracers.cc b/src/alloy/backend/x64/x64_tracers.cc index 4c4fdaabf..e47d1eda8 100644 --- a/src/alloy/backend/x64/x64_tracers.cc +++ b/src/alloy/backend/x64/x64_tracers.cc @@ -34,20 +34,6 @@ namespace x64 { DFLUSH(); \ if (thread_state->thread_id() == TARGET_THREAD) printf -// TODO(benvanik): properly pull out values. -typedef union __declspec(align(16)) { - __m128 m128; - float m128_f32[4]; - uint64_t m128_u64[2]; - int8_t m128_i8[16]; - int16_t m128_i16[8]; - int32_t m128_i32[4]; - int64_t m128_i64[2]; - uint8_t m128_u8[16]; - uint16_t m128_u16[8]; - uint32_t m128_u32[4]; -} __m128_x; - uint32_t GetTracingMode() { uint32_t mode = 0; #if ITRACE diff --git a/src/alloy/hir/value.cc b/src/alloy/hir/value.cc index 41c162080..a7b7bddef 100644 --- a/src/alloy/hir/value.cc +++ b/src/alloy/hir/value.cc @@ -136,7 +136,7 @@ void Value::SignExtend(TypeName target_type) { return; } default: - XEASSERTUNHANDLEDCASE(); + XEASSERTUNHANDLEDCASE(type); return; } } diff --git a/src/alloy/hir/value.h b/src/alloy/hir/value.h index eb87a983f..bd4e37acf 100644 --- a/src/alloy/hir/value.h +++ b/src/alloy/hir/value.h @@ -49,7 +49,7 @@ static size_t GetTypeSize(TypeName type_name) { return 16; default: XEASSERTUNHANDLEDCASE(type_name); - break; + return 0; } } diff --git a/src/alloy/runtime/debugger.h b/src/alloy/runtime/debugger.h index 40eb93d04..d9b97a8a9 100644 --- a/src/alloy/runtime/debugger.h +++ b/src/alloy/runtime/debugger.h @@ -12,6 +12,7 @@ #include #include +#include #include diff --git a/src/alloy/runtime/entry_table.h b/src/alloy/runtime/entry_table.h index 206d36c15..0470c7b27 100644 --- a/src/alloy/runtime/entry_table.h +++ b/src/alloy/runtime/entry_table.h @@ -11,6 +11,7 @@ #define ALLOY_RUNTIME_ENTRY_TABLE_H_ #include +#include #include diff --git a/src/poly/config.h b/src/poly/config.h new file mode 100644 index 000000000..dead1d518 --- /dev/null +++ b/src/poly/config.h @@ -0,0 +1,17 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef POLY_CONFIG_H_ +#define POLY_CONFIG_H_ + +#if defined(DEBUG) || defined(_DEBUG) +#define XE_DEBUG 1 +#endif // DEBUG + +#endif // POLY_CONFIG_H_ diff --git a/src/poly/cxx_compat.h b/src/poly/cxx_compat.h index 88d647aa5..f0ac6d8fb 100644 --- a/src/poly/cxx_compat.h +++ b/src/poly/cxx_compat.h @@ -10,6 +10,8 @@ #ifndef POLY_POLY_CXX_COMPAT_H_ #define POLY_POLY_CXX_COMPAT_H_ +#include + // C++11 thread local storage. // http://en.cppreference.com/w/cpp/language/storage_duration #if XE_COMPILER_MSVC diff --git a/src/poly/math.h b/src/poly/math.h index d332191b5..5fcce51fd 100644 --- a/src/poly/math.h +++ b/src/poly/math.h @@ -15,6 +15,9 @@ #include #include +#include +#include + namespace poly { // lzcnt instruction, typed for integers of all sizes. @@ -22,48 +25,48 @@ namespace poly { // return value is the size of the input operand (8, 16, 32, or 64). If the most // significant bit of value is one, the return value is zero. #if XE_COMPILER_MSVC -uint8_t lzcnt(uint8_t v) { return static_cast(__lzcnt16(v) - 8); } -uint8_t lzcnt(uint16_t v) { return static_cast(__lzcnt16(v)); } -uint8_t lzcnt(uint32_t v) { return static_cast(__lzcnt(v)); } -uint8_t lzcnt(uint64_t v) { return static_cast(__lzcnt64(v)); } +inline uint8_t lzcnt(uint8_t v) { return static_cast(__lzcnt16(v) - 8); } +inline uint8_t lzcnt(uint16_t v) { return static_cast(__lzcnt16(v)); } +inline uint8_t lzcnt(uint32_t v) { return static_cast(__lzcnt(v)); } +inline uint8_t lzcnt(uint64_t v) { return static_cast(__lzcnt64(v)); } #else -uint8_t lzcnt(uint8_t v) { return static_cast(__builtin_clzs(v) - 8); } -uint8_t lzcnt(uint16_t v) { return static_cast(__builtin_clzs(v)); } -uint8_t lzcnt(uint32_t v) { return static_cast(__builtin_clz(v)); } -uint8_t lzcnt(uint64_t v) { return static_cast(__builtin_clzll(v)); } +inline uint8_t lzcnt(uint8_t v) { return static_cast(__builtin_clzs(v) - 8); } +inline uint8_t lzcnt(uint16_t v) { return static_cast(__builtin_clzs(v)); } +inline uint8_t lzcnt(uint32_t v) { return static_cast(__builtin_clz(v)); } +inline uint8_t lzcnt(uint64_t v) { return static_cast(__builtin_clzll(v)); } #endif // XE_COMPILER_MSVC -uint8_t lzcnt(int8_t v) { return lzcnt(static_cast(v)); } -uint8_t lzcnt(int16_t v) { return lzcnt(static_cast(v)); } -uint8_t lzcnt(int32_t v) { return lzcnt(static_cast(v)); } -uint8_t lzcnt(int64_t v) { return lzcnt(static_cast(v)); } +inline uint8_t lzcnt(int8_t v) { return lzcnt(static_cast(v)); } +inline uint8_t lzcnt(int16_t v) { return lzcnt(static_cast(v)); } +inline uint8_t lzcnt(int32_t v) { return lzcnt(static_cast(v)); } +inline uint8_t lzcnt(int64_t v) { return lzcnt(static_cast(v)); } // BitScanForward (bsf). // Search the value from least significant bit (LSB) to the most significant bit // (MSB) for a set bit (1). // Returns false if no bits are set and the output index is invalid. #if XE_COMPILER_MSVC -bool bit_scan_forward(uint32_t v, uint32_t* out_first_set_index) { - return _BitScanForward(out_first_set_index, v) != 0; +inline bool bit_scan_forward(uint32_t v, uint32_t* out_first_set_index) { + return _BitScanForward(reinterpret_cast(out_first_set_index), v) != 0; } -bool bit_scan_forward(uint64_t v, uint32_t* out_first_set_index) { - return _BitScanForward64(out_first_set_index, v) != 0; +inline bool bit_scan_forward(uint64_t v, uint32_t* out_first_set_index) { + return _BitScanForward64(reinterpret_cast(out_first_set_index), v) != 0; } #else -bool bit_scan_forward(uint32_t v, uint32_t* out_first_set_index) { +inline bool bit_scan_forward(uint32_t v, uint32_t* out_first_set_index) { int i = ffs(v); *out_first_set_index = i; return i != 0; } -bool bit_scan_forward(uint64_t v, uint32_t* out_first_set_index) { +inline bool bit_scan_forward(uint64_t v, uint32_t* out_first_set_index) { int i = ffsll(v); *out_first_set_index = i; return i != 0; } #endif // XE_COMPILER_MSVC -bool bit_scan_forward(int32_t v, uint32_t* out_first_set_index) { +inline bool bit_scan_forward(int32_t v, uint32_t* out_first_set_index) { return bit_scan_forward(static_cast(v), out_first_set_index); } -bool bit_scan_forward(int64_t v, uint32_t* out_first_set_index) { +inline bool bit_scan_forward(int64_t v, uint32_t* out_first_set_index) { return bit_scan_forward(static_cast(v), out_first_set_index); } @@ -84,20 +87,28 @@ int32_t m128_i32(const __m128& v) { return ret.i; } template -double m128_f64(const __m128& v) { +double m128_f64(const __m128d& v) { double ret; - _mm_store_sd(&ret, _mm_shuffle_ps(v, v, _MM_SHUFFLE(N, N, N, N))); + _mm_store_sd(&ret, _mm_shuffle_pd(v, v, _MM_SHUFFLE2(N, N))); return ret; } template -int64_t m128_i64(const __m128& v) { +double m128_f64(const __m128& v) { + return m128_f64(_mm_castps_pd(v)); +} +template +int64_t m128_i64(const __m128d& v) { union { double f; int64_t i; } ret; - _mm_store_sd(&ret.f, _mm_shuffle_ps(v, v, _MM_SHUFFLE(N, N, N, N))); + _mm_store_sd(&ret.f, _mm_shuffle_pd(v, v, _MM_SHUFFLE2(N, N))); return ret.i; } +template +int64_t m128_i64(const __m128& v) { + return m128_i64(_mm_castps_pd(v)); +} } // namespace poly diff --git a/src/poly/platform.h b/src/poly/platform.h new file mode 100644 index 000000000..f5705e11b --- /dev/null +++ b/src/poly/platform.h @@ -0,0 +1,163 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef POLY_PLATFORM_H_ +#define POLY_PLATFORM_H_ + +// NOTE: ordering matters here as sometimes multiple flags are defined on +// certain platforms. + +// Great resource on predefined macros: http://predef.sourceforge.net/preos.html + +/* +XE_PLATFORM: IOS | OSX | XBOX360 | WINCE | WIN32 | ANDROID | NACL | UNIX +XE_LIKE: OSX | WIN32 | POSIX +XE_PROFILE: EMBEDDED | DESKTOP (+ _SIMULATOR) +XE_COMPILER: GNUC | MSVC | CLANG | INTEL | UNKNOWN +XE_CPU: 32BIT | 64BIT | BIGENDIAN | LITTLEENDIAN +*/ + +#if defined(__APPLE__) +#include +#endif + +#if (defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED ) || \ + (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE ) || \ + (defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR) + +#define XE_PLATFORM_IOS 1 +#define XE_LIKE_OSX 1 +#define XE_PROFILE_EMBEDDED 1 + +#if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR +// EMBEDDED *and* SIMULATOR +#define XE_PROFILE_SIMULATOR 1 +#endif + +#elif defined(TARGET_OS_MAC) && TARGET_OS_MAC + +#define XE_PLATFORM_OSX 1 +#define XE_LIKE_OSX 1 +#define XE_PROFILE_DESKTOP 1 + +#elif defined(_XBOX) + +#define XE_PLATFORM_XBOX360 1 +#define XE_LIKE_WIN32 1 +#define XE_PROFILE_EMBEDDED 1 + +#elif defined(_WIN32_WCE) + +#define XE_PLATFORM_WINCE 1 +#define XE_LIKE_WIN32 1 +#define XE_PROFILE_EMBEDDED 1 + +#elif defined(__CYGWIN__) + +#define XE_PLATFORM_CYGWIN 1 +#define XE_LIKE_POSIX 1 +#define XE_PROFILE_DESKTOP 1 + +#elif defined(WIN32) || defined(_WIN32) + +#define XE_PLATFORM_WIN32 1 +#define XE_LIKE_WIN32 1 +#define XE_PROFILE_DESKTOP 1 + +#elif defined(ANDROID) + +#define XE_PLATFORM_ANDROID 1 +#define XE_LIKE_POSIX 1 +#define XE_PROFILE_EMBEDDED 1 + +#elif defined(__native_client__) + +#define XE_PLATFORM_NACL 1 +#define XE_LIKE_POSIX 1 +#define XE_PROFILE_DESKTOP 1 + +#else + +#define XE_PLATFORM_UNIX 1 +#define XE_LIKE_POSIX 1 +#define XE_PROFILE_DESKTOP 1 + +#endif + +#if defined(__clang__) +#define XE_COMPILER_CLANG 1 +#elif defined(__GNUC__) +#define XE_COMPILER_GNUC 1 +#elif defined(_MSC_VER) +#define XE_COMPILER_MSVC 1 +#elif defined(__MINGW32) +#define XE_COMPILER_MINGW32 1 +#elif defined(__INTEL_COMPILER) +#define XE_COMPILER_INTEL 1 +#else +#define XE_COMPILER_UNKNOWN 1 +#endif + +#if defined(__ia64__) || defined(_M_IA64) || \ + defined(__ppc64__) || defined(__PPC64__) || \ + defined(__arch64__) || \ + defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) || \ + defined(__LP64__) || defined(__LLP64) || \ + defined(_WIN64) || \ + (__WORDSIZE == 64) +#define XE_CPU_64BIT 1 +#else +#define XE_CPU_32BIT 1 +#endif // [64bit flags] + +#if defined(__ppc__) || defined(__PPC__) || defined(__powerpc__) || defined(__powerpc) || defined(__POWERPC__) || defined(_M_PPC) || defined(__PPC) || \ + defined(__ppc64__) || defined(__PPC64__) || \ + defined(__ARMEB__) || defined(__THUMBEB__) || \ + defined(__AARCH64EB__) || \ + defined(__BIG_ENDIAN) || defined(__BIG_ENDIAN__) +#define XE_CPU_BIGENDIAN 1 +#else +#define XE_CPU_LITTLEENDIAN 1 +#endif // [big endian flags] + +#if XE_CPU_32BIT +#define XE_ALIGNMENT 8 +#else +#define XE_ALIGNMENT 16 +#endif // 32BIT + +#if XE_PLATFORM_WINCE || XE_PLATFORM_WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#include +#include +#undef min +#undef max +#undef Yield +#endif // WINCE || WIN32 + +#if XE_PLATFORM_XBOX360 +#include +#include +#endif // XBOX360 + +#if XE_COMPILER_MSVC +// Disable warning C4068: unknown pragma +#pragma warning(disable : 4068) +#endif // MSVC + +#if XE_COMPILER_MSVC +#include +#else +#include +#endif // MSVC + +#endif // POLY_PLATFORM_H_ diff --git a/src/poly/poly.h b/src/poly/poly.h index aab80b5e1..6c70dedd7 100644 --- a/src/poly/poly.h +++ b/src/poly/poly.h @@ -10,8 +10,10 @@ #ifndef POLY_POLY_H_ #define POLY_POLY_H_ +#include #include #include +#include #include namespace poly {} // namespace poly diff --git a/src/poly/sources.gypi b/src/poly/sources.gypi index 2a6f55017..dcf5478f5 100644 --- a/src/poly/sources.gypi +++ b/src/poly/sources.gypi @@ -1,6 +1,7 @@ # Copyright 2014 Ben Vanik. All Rights Reserved. { 'sources': [ + 'config.h', 'cxx_compat.h', 'math.h', 'poly-private.h', diff --git a/src/poly/threading.h b/src/poly/threading.h index 06e21c9c8..6fb792b2d 100644 --- a/src/poly/threading.h +++ b/src/poly/threading.h @@ -13,6 +13,8 @@ #include #include +#include + namespace poly { namespace threading { diff --git a/src/poly/threading_win.cc b/src/poly/threading_win.cc index 7b2b8be3d..b95a6c455 100644 --- a/src/poly/threading_win.cc +++ b/src/poly/threading_win.cc @@ -9,6 +9,8 @@ #include +#include + namespace poly { namespace threading { @@ -22,7 +24,7 @@ void Sleep(std::chrono::microseconds duration) { if (duration.count() < 100) { SwitchToThread(); } else { - Sleep(duration.count() / 1000); + ::Sleep(static_cast(duration.count() / 1000)); } } diff --git a/src/xenia/assert.h b/src/xenia/assert.h index 05803a62a..4f765bbd8 100644 --- a/src/xenia/assert.h +++ b/src/xenia/assert.h @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/src/xenia/atomic.h b/src/xenia/atomic.h index ae483495c..10403280d 100644 --- a/src/xenia/atomic.h +++ b/src/xenia/atomic.h @@ -10,8 +10,9 @@ #ifndef XENIA_ATOMIC_H_ #define XENIA_ATOMIC_H_ +#include + #include -#include // These functions are modeled off of the Apple OSAtomic routines diff --git a/src/xenia/byte_order.h b/src/xenia/byte_order.h index 310ea9466..0bdedd717 100644 --- a/src/xenia/byte_order.h +++ b/src/xenia/byte_order.h @@ -10,6 +10,8 @@ #ifndef XENIA_BYTE_ORDER_H_ #define XENIA_BYTE_ORDER_H_ +#include + #include #include diff --git a/src/xenia/common.h b/src/xenia/common.h index 68d9d2eb7..0e8cac0a2 100644 --- a/src/xenia/common.h +++ b/src/xenia/common.h @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/src/xenia/core/socket_win.cc b/src/xenia/core/socket_win.cc index 3d999c710..1f2eba015 100644 --- a/src/xenia/core/socket_win.cc +++ b/src/xenia/core/socket_win.cc @@ -9,9 +9,10 @@ #include +#include +#include #include #include -#include // TODO(benvanik): win32 calls diff --git a/src/xenia/gpu/resource_cache.h b/src/xenia/gpu/resource_cache.h index be95f0861..968fdc40b 100644 --- a/src/xenia/gpu/resource_cache.h +++ b/src/xenia/gpu/resource_cache.h @@ -11,6 +11,7 @@ #define XENIA_GPU_RESOURCE_CACHE_H_ #include +#include #include #include diff --git a/src/xenia/kernel/fs/filesystem.h b/src/xenia/kernel/fs/filesystem.h index 94b9d787f..b252d5e61 100644 --- a/src/xenia/kernel/fs/filesystem.h +++ b/src/xenia/kernel/fs/filesystem.h @@ -10,11 +10,12 @@ #ifndef XENIA_KERNEL_FS_FILESYSTEM_H_ #define XENIA_KERNEL_FS_FILESYSTEM_H_ +#include +#include + #include #include -#include - #include diff --git a/src/xenia/logging.h b/src/xenia/logging.h index e6496c158..9c5579f9a 100644 --- a/src/xenia/logging.h +++ b/src/xenia/logging.h @@ -10,8 +10,9 @@ #ifndef XENIA_LOGGING_H_ #define XENIA_LOGGING_H_ +#include + #include -#include #include #include diff --git a/src/xenia/platform.h b/src/xenia/platform.h index 976216172..060b992e5 100644 --- a/src/xenia/platform.h +++ b/src/xenia/platform.h @@ -10,129 +10,7 @@ #ifndef XENIA_PLATFORM_H_ #define XENIA_PLATFORM_H_ -// NOTE: ordering matters here as sometimes multiple flags are defined on -// certain platforms. - -// Great resource on predefined macros: http://predef.sourceforge.net/preos.html - -/* -XE_PLATFORM: IOS | OSX | XBOX360 | WINCE | WIN32 | ANDROID | NACL | UNIX -XE_LIKE: OSX | WIN32 | POSIX -XE_PROFILE: EMBEDDED | DESKTOP (+ _SIMULATOR) -XE_COMPILER: GNUC | MSVC | INTEL | UNKNOWN -XE_CPU: 32BIT | 64BIT | BIGENDIAN | LITTLEENDIAN -*/ - - -#if defined(__APPLE__) -#include -#endif - -#if (defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED ) || \ - (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE ) || \ - (defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR) - -#define XE_PLATFORM_IOS 1 -#define XE_LIKE_OSX 1 -#define XE_PROFILE_EMBEDDED 1 - -#if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR -// EMBEDDED *and* SIMULATOR -#define XE_PROFILE_SIMULATOR 1 -#endif - -#elif defined(TARGET_OS_MAC) && TARGET_OS_MAC - -#define XE_PLATFORM_OSX 1 -#define XE_LIKE_OSX 1 -#define XE_PROFILE_DESKTOP 1 - -#elif defined(_XBOX) - -#define XE_PLATFORM_XBOX360 1 -#define XE_LIKE_WIN32 1 -#define XE_PROFILE_EMBEDDED 1 - -#elif defined(_WIN32_WCE) - -#define XE_PLATFORM_WINCE 1 -#define XE_LIKE_WIN32 1 -#define XE_PROFILE_EMBEDDED 1 - -#elif defined(__CYGWIN__) - -#define XE_PLATFORM_CYGWIN 1 -#define XE_LIKE_POSIX 1 -#define XE_PROFILE_DESKTOP 1 - -#elif defined(WIN32) || defined(_WIN32) - -#define XE_PLATFORM_WIN32 1 -#define XE_LIKE_WIN32 1 -#define XE_PROFILE_DESKTOP 1 - -#elif defined(ANDROID) - -#define XE_PLATFORM_ANDROID 1 -#define XE_LIKE_POSIX 1 -#define XE_PROFILE_EMBEDDED 1 - -#elif defined(__native_client__) - -#define XE_PLATFORM_NACL 1 -#define XE_LIKE_POSIX 1 -#define XE_PROFILE_DESKTOP 1 - -#else - -#define XE_PLATFORM_UNIX 1 -#define XE_LIKE_POSIX 1 -#define XE_PROFILE_DESKTOP 1 - -#endif - -#if defined(__GNUC__) -#define XE_COMPILER_GNUC 1 -#elif defined(_MSC_VER) -#define XE_COMPILER_MSVC 1 -#elif defined(__MINGW32) -#define XE_COMPILER_MINGW32 1 -#elif defined(__INTEL_COMPILER) -#define XE_COMPILER_INTEL 1 -#else -#define XE_COMPILER_UNKNOWN 1 -#endif - -#if defined(__ia64__) || defined(_M_IA64) || \ - defined(__ppc64__) || defined(__PPC64__) || \ - defined(__arch64__) || \ - defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) || \ - defined(__LP64__) || defined(__LLP64) || \ - defined(_WIN64) || \ - (__WORDSIZE == 64) -#define XE_CPU_64BIT 1 -#else -#define XE_CPU_32BIT 1 -#endif // [64bit flags] - -#if defined(__ppc__) || defined(__PPC__) || defined(__powerpc__) || defined(__powerpc) || defined(__POWERPC__) || defined(_M_PPC) || defined(__PPC) || \ - defined(__ppc64__) || defined(__PPC64__) || \ - defined(__ARMEB__) || \ - defined(__BIG_ENDIAN) || defined(__BIG_ENDIAN__) -#define XE_CPU_BIGENDIAN 1 -#else -#define XE_CPU_LITTLEENDIAN 1 -#endif // [big endian flags] - -#if defined(DEBUG) || defined(_DEBUG) -#define XE_DEBUG 1 -#endif // DEBUG - -#if XE_CPU_32BIT -#define XE_ALIGNMENT 8 -#else -#define XE_ALIGNMENT 16 -#endif // 32BIT +#include bool xe_has_console(); #if XE_LIKE_WIN32 && defined(UNICODE) && UNICODE diff --git a/src/xenia/platform_includes.h b/src/xenia/platform_includes.h deleted file mode 100644 index 6aaf86811..000000000 --- a/src/xenia/platform_includes.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_PLATFORM_INCLUDES_H_ -#define XENIA_PLATFORM_INCLUDES_H_ - -#include - - -#if XE_PLATFORM_WINCE || XE_PLATFORM_WIN32 -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#include -#include -#undef min -#undef max -#endif // WINCE || WIN32 - -#if XE_PLATFORM_XBOX360 -#include -#include -#endif // XBOX360 - -#if XE_COMPILER_MSVC -// Disable warning C4068: unknown pragma -#pragma warning(disable : 4068) -#endif // MSVC - -#if XE_LIKE_POSIX -#include -#include -#endif // POSIX - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - - -#endif // XENIA_PLATFORM_INCLUDES_H_ diff --git a/src/xenia/profiling.h b/src/xenia/profiling.h index 30ab996ac..4577dbb8f 100644 --- a/src/xenia/profiling.h +++ b/src/xenia/profiling.h @@ -14,7 +14,6 @@ #include #include -#include #include #include diff --git a/src/xenia/sources.gypi b/src/xenia/sources.gypi index 9de67ac78..4fdccb166 100644 --- a/src/xenia/sources.gypi +++ b/src/xenia/sources.gypi @@ -17,7 +17,6 @@ 'malloc.h', 'platform.cc', 'platform.h', - 'platform_includes.h', 'profiling.cc', 'profiling.h', 'string.cc', diff --git a/src/xenia/string.h b/src/xenia/string.h index e833118ef..6008d3073 100644 --- a/src/xenia/string.h +++ b/src/xenia/string.h @@ -11,7 +11,6 @@ #define XENIA_STRING_H_ #include -#include // NOTE: these differing implementations should behave pretty much the same. diff --git a/src/xenia/types.h b/src/xenia/types.h index 4cd3f5daf..78a60de8c 100644 --- a/src/xenia/types.h +++ b/src/xenia/types.h @@ -10,14 +10,9 @@ #ifndef XENIA_TYPES_H_ #define XENIA_TYPES_H_ -#include -#include +#include -namespace xe { -// TODO(benvanik): support other compilers/etc -using std::auto_ptr; -using std::shared_ptr; -} // namespace xe +#include #define XE_EMPTY_MACRO do { } while(0) From 4b6f1882e775a1c5568d5142ca311413770f345b Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 11 Jul 2014 18:40:51 -0700 Subject: [PATCH 020/388] Adding cpplint. --- third_party/google-styleguide/cpplint/README | 45 + .../google-styleguide/cpplint/cpplint.py | 5620 +++++++++++++++++ 2 files changed, 5665 insertions(+) create mode 100644 third_party/google-styleguide/cpplint/README create mode 100644 third_party/google-styleguide/cpplint/cpplint.py diff --git a/third_party/google-styleguide/cpplint/README b/third_party/google-styleguide/cpplint/README new file mode 100644 index 000000000..4ffb1ebd1 --- /dev/null +++ b/third_party/google-styleguide/cpplint/README @@ -0,0 +1,45 @@ +This is automated checker to make sure a C++ file follows Google's C++ style +guide (http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml). As it +heavily relies on regular expressions, cpplint.py won't catch all violations of +the style guide and will very occasionally report a false positive. There is a +list of things we currently don't handle very well at the top of cpplint.py, +and we welcome patches to improve it. + +The linting tool takes a list of files as input. For full usage instructions, +please see the output of: + + ./cpplint.py --help + +Unit tests are provided in cpplint_unittest.py. This file can safely be ignored +by end users who have downloaded this package and only want to run the lint +tool. + +--- + +cpplint.py and its corresponding unit tests are Copyright (C) 2009 Google Inc. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/third_party/google-styleguide/cpplint/cpplint.py b/third_party/google-styleguide/cpplint/cpplint.py new file mode 100644 index 000000000..ebe576df4 --- /dev/null +++ b/third_party/google-styleguide/cpplint/cpplint.py @@ -0,0 +1,5620 @@ +#!/usr/bin/python +# +# Copyright (c) 2009 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Does google-lint on c++ files. + +The goal of this script is to identify places in the code that *may* +be in non-compliance with google style. It does not attempt to fix +up these problems -- the point is to educate. It does also not +attempt to find all problems, or to ensure that everything it does +find is legitimately a problem. + +In particular, we can get very confused by /* and // inside strings! +We do a small hack, which is to ignore //'s with "'s after them on the +same line, but it is far from perfect (in either direction). +""" + +import codecs +import copy +import getopt +import math # for log +import os +import re +import sre_compile +import string +import sys +import unicodedata + + +_USAGE = """ +Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...] + [--counting=total|toplevel|detailed] [--root=subdir] + [--linelength=digits] + [file] ... + + The style guidelines this tries to follow are those in + http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml + + Every problem is given a confidence score from 1-5, with 5 meaning we are + certain of the problem, and 1 meaning it could be a legitimate construct. + This will miss some errors, and is not a substitute for a code review. + + To suppress false-positive errors of a certain category, add a + 'NOLINT(category)' comment to the line. NOLINT or NOLINT(*) + suppresses errors of all categories on that line. + + The files passed in will be linted; at least one file must be provided. + Default linted extensions are .cc, .cpp, .cu, .cuh and .h. Change the + extensions with the --extensions flag. + + Flags: + + output=vs7 + By default, the output is formatted to ease emacs parsing. Visual Studio + compatible output (vs7) may also be used. Other formats are unsupported. + + verbose=# + Specify a number 0-5 to restrict errors to certain verbosity levels. + + filter=-x,+y,... + Specify a comma-separated list of category-filters to apply: only + error messages whose category names pass the filters will be printed. + (Category names are printed with the message and look like + "[whitespace/indent]".) Filters are evaluated left to right. + "-FOO" and "FOO" means "do not print categories that start with FOO". + "+FOO" means "do print categories that start with FOO". + + Examples: --filter=-whitespace,+whitespace/braces + --filter=whitespace,runtime/printf,+runtime/printf_format + --filter=-,+build/include_what_you_use + + To see a list of all the categories used in cpplint, pass no arg: + --filter= + + counting=total|toplevel|detailed + The total number of errors found is always printed. If + 'toplevel' is provided, then the count of errors in each of + the top-level categories like 'build' and 'whitespace' will + also be printed. If 'detailed' is provided, then a count + is provided for each category like 'build/class'. + + root=subdir + The root directory used for deriving header guard CPP variable. + By default, the header guard CPP variable is calculated as the relative + path to the directory that contains .git, .hg, or .svn. When this flag + is specified, the relative path is calculated from the specified + directory. If the specified directory does not exist, this flag is + ignored. + + Examples: + Assuming that src/.git exists, the header guard CPP variables for + src/chrome/browser/ui/browser.h are: + + No flag => CHROME_BROWSER_UI_BROWSER_H_ + --root=chrome => BROWSER_UI_BROWSER_H_ + --root=chrome/browser => UI_BROWSER_H_ + + linelength=digits + This is the allowed line length for the project. The default value is + 80 characters. + + Examples: + --linelength=120 + + extensions=extension,extension,... + The allowed file extensions that cpplint will check + + Examples: + --extensions=hpp,cpp +""" + +# We categorize each error message we print. Here are the categories. +# We want an explicit list so we can list them all in cpplint --filter=. +# If you add a new error message with a new category, add it to the list +# here! cpplint_unittest.py should tell you if you forget to do this. +_ERROR_CATEGORIES = [ + 'build/class', + 'build/c++11', + 'build/deprecated', + 'build/endif_comment', + 'build/explicit_make_pair', + 'build/forward_decl', + 'build/header_guard', + 'build/include', + 'build/include_alpha', + 'build/include_order', + 'build/include_what_you_use', + 'build/namespaces', + 'build/printf_format', + 'build/storage_class', + 'legal/copyright', + 'readability/alt_tokens', + 'readability/braces', + 'readability/casting', + 'readability/check', + 'readability/constructors', + 'readability/fn_size', + 'readability/function', + 'readability/multiline_comment', + 'readability/multiline_string', + 'readability/namespace', + 'readability/nolint', + 'readability/nul', + 'readability/streams', + 'readability/todo', + 'readability/utf8', + 'runtime/arrays', + 'runtime/casting', + 'runtime/explicit', + 'runtime/int', + 'runtime/init', + 'runtime/invalid_increment', + 'runtime/member_string_references', + 'runtime/memset', + 'runtime/operator', + 'runtime/printf', + 'runtime/printf_format', + 'runtime/references', + 'runtime/string', + 'runtime/threadsafe_fn', + 'runtime/vlog', + 'whitespace/blank_line', + 'whitespace/braces', + 'whitespace/comma', + 'whitespace/comments', + 'whitespace/empty_conditional_body', + 'whitespace/empty_loop_body', + 'whitespace/end_of_line', + 'whitespace/ending_newline', + 'whitespace/forcolon', + 'whitespace/indent', + 'whitespace/line_length', + 'whitespace/newline', + 'whitespace/operators', + 'whitespace/parens', + 'whitespace/semicolon', + 'whitespace/tab', + 'whitespace/todo' + ] + +# The default state of the category filter. This is overridden by the --filter= +# flag. By default all errors are on, so only add here categories that should be +# off by default (i.e., categories that must be enabled by the --filter= flags). +# All entries here should start with a '-' or '+', as in the --filter= flag. +_DEFAULT_FILTERS = ['-build/include_alpha'] + +# We used to check for high-bit characters, but after much discussion we +# decided those were OK, as long as they were in UTF-8 and didn't represent +# hard-coded international strings, which belong in a separate i18n file. + +# C++ headers +_CPP_HEADERS = frozenset([ + # Legacy + 'algobase.h', + 'algo.h', + 'alloc.h', + 'builtinbuf.h', + 'bvector.h', + 'complex.h', + 'defalloc.h', + 'deque.h', + 'editbuf.h', + 'fstream.h', + 'function.h', + 'hash_map', + 'hash_map.h', + 'hash_set', + 'hash_set.h', + 'hashtable.h', + 'heap.h', + 'indstream.h', + 'iomanip.h', + 'iostream.h', + 'istream.h', + 'iterator.h', + 'list.h', + 'map.h', + 'multimap.h', + 'multiset.h', + 'ostream.h', + 'pair.h', + 'parsestream.h', + 'pfstream.h', + 'procbuf.h', + 'pthread_alloc', + 'pthread_alloc.h', + 'rope', + 'rope.h', + 'ropeimpl.h', + 'set.h', + 'slist', + 'slist.h', + 'stack.h', + 'stdiostream.h', + 'stl_alloc.h', + 'stl_relops.h', + 'streambuf.h', + 'stream.h', + 'strfile.h', + 'strstream.h', + 'tempbuf.h', + 'tree.h', + 'type_traits.h', + 'vector.h', + # 17.6.1.2 C++ library headers + 'algorithm', + 'array', + 'atomic', + 'bitset', + 'chrono', + 'codecvt', + 'complex', + 'condition_variable', + 'deque', + 'exception', + 'forward_list', + 'fstream', + 'functional', + 'future', + 'initializer_list', + 'iomanip', + 'ios', + 'iosfwd', + 'iostream', + 'istream', + 'iterator', + 'limits', + 'list', + 'locale', + 'map', + 'memory', + 'mutex', + 'new', + 'numeric', + 'ostream', + 'queue', + 'random', + 'ratio', + 'regex', + 'set', + 'sstream', + 'stack', + 'stdexcept', + 'streambuf', + 'string', + 'strstream', + 'system_error', + 'thread', + 'tuple', + 'typeindex', + 'typeinfo', + 'type_traits', + 'unordered_map', + 'unordered_set', + 'utility', + 'valarray', + 'vector', + # 17.6.1.2 C++ headers for C library facilities + 'cassert', + 'ccomplex', + 'cctype', + 'cerrno', + 'cfenv', + 'cfloat', + 'cinttypes', + 'ciso646', + 'climits', + 'clocale', + 'cmath', + 'csetjmp', + 'csignal', + 'cstdalign', + 'cstdarg', + 'cstdbool', + 'cstddef', + 'cstdint', + 'cstdio', + 'cstdlib', + 'cstring', + 'ctgmath', + 'ctime', + 'cuchar', + 'cwchar', + 'cwctype', + ]) + + +# Assertion macros. These are defined in base/logging.h and +# testing/base/gunit.h. Note that the _M versions need to come first +# for substring matching to work. +_CHECK_MACROS = [ + 'DCHECK', 'CHECK', + 'EXPECT_TRUE_M', 'EXPECT_TRUE', + 'ASSERT_TRUE_M', 'ASSERT_TRUE', + 'EXPECT_FALSE_M', 'EXPECT_FALSE', + 'ASSERT_FALSE_M', 'ASSERT_FALSE', + ] + +# Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE +_CHECK_REPLACEMENT = dict([(m, {}) for m in _CHECK_MACROS]) + +for op, replacement in [('==', 'EQ'), ('!=', 'NE'), + ('>=', 'GE'), ('>', 'GT'), + ('<=', 'LE'), ('<', 'LT')]: + _CHECK_REPLACEMENT['DCHECK'][op] = 'DCHECK_%s' % replacement + _CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement + _CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement + _CHECK_REPLACEMENT['ASSERT_TRUE'][op] = 'ASSERT_%s' % replacement + _CHECK_REPLACEMENT['EXPECT_TRUE_M'][op] = 'EXPECT_%s_M' % replacement + _CHECK_REPLACEMENT['ASSERT_TRUE_M'][op] = 'ASSERT_%s_M' % replacement + +for op, inv_replacement in [('==', 'NE'), ('!=', 'EQ'), + ('>=', 'LT'), ('>', 'LE'), + ('<=', 'GT'), ('<', 'GE')]: + _CHECK_REPLACEMENT['EXPECT_FALSE'][op] = 'EXPECT_%s' % inv_replacement + _CHECK_REPLACEMENT['ASSERT_FALSE'][op] = 'ASSERT_%s' % inv_replacement + _CHECK_REPLACEMENT['EXPECT_FALSE_M'][op] = 'EXPECT_%s_M' % inv_replacement + _CHECK_REPLACEMENT['ASSERT_FALSE_M'][op] = 'ASSERT_%s_M' % inv_replacement + +# Alternative tokens and their replacements. For full list, see section 2.5 +# Alternative tokens [lex.digraph] in the C++ standard. +# +# Digraphs (such as '%:') are not included here since it's a mess to +# match those on a word boundary. +_ALT_TOKEN_REPLACEMENT = { + 'and': '&&', + 'bitor': '|', + 'or': '||', + 'xor': '^', + 'compl': '~', + 'bitand': '&', + 'and_eq': '&=', + 'or_eq': '|=', + 'xor_eq': '^=', + 'not': '!', + 'not_eq': '!=' + } + +# Compile regular expression that matches all the above keywords. The "[ =()]" +# bit is meant to avoid matching these keywords outside of boolean expressions. +# +# False positives include C-style multi-line comments and multi-line strings +# but those have always been troublesome for cpplint. +_ALT_TOKEN_REPLACEMENT_PATTERN = re.compile( + r'[ =()](' + ('|'.join(_ALT_TOKEN_REPLACEMENT.keys())) + r')(?=[ (]|$)') + + +# These constants define types of headers for use with +# _IncludeState.CheckNextIncludeOrder(). +_C_SYS_HEADER = 1 +_CPP_SYS_HEADER = 2 +_LIKELY_MY_HEADER = 3 +_POSSIBLE_MY_HEADER = 4 +_OTHER_HEADER = 5 + +# These constants define the current inline assembly state +_NO_ASM = 0 # Outside of inline assembly block +_INSIDE_ASM = 1 # Inside inline assembly block +_END_ASM = 2 # Last line of inline assembly block +_BLOCK_ASM = 3 # The whole block is an inline assembly block + +# Match start of assembly blocks +_MATCH_ASM = re.compile(r'^\s*(?:asm|_asm|__asm|__asm__)' + r'(?:\s+(volatile|__volatile__))?' + r'\s*[{(]') + + +_regexp_compile_cache = {} + +# Finds occurrences of NOLINT or NOLINT(...). +_RE_SUPPRESSION = re.compile(r'\bNOLINT\b(\([^)]*\))?') + +# {str, set(int)}: a map from error categories to sets of linenumbers +# on which those errors are expected and should be suppressed. +_error_suppressions = {} + +# The root directory used for deriving header guard CPP variable. +# This is set by --root flag. +_root = None + +# The allowed line length of files. +# This is set by --linelength flag. +_line_length = 80 + +# The allowed extensions for file names +# This is set by --extensions flag. +_valid_extensions = set(['cc', 'h', 'cpp', 'cu', 'cuh']) + +def ParseNolintSuppressions(filename, raw_line, linenum, error): + """Updates the global list of error-suppressions. + + Parses any NOLINT comments on the current line, updating the global + error_suppressions store. Reports an error if the NOLINT comment + was malformed. + + Args: + filename: str, the name of the input file. + raw_line: str, the line of input text, with comments. + linenum: int, the number of the current line. + error: function, an error handler. + """ + # FIXME(adonovan): "NOLINT(" is misparsed as NOLINT(*). + matched = _RE_SUPPRESSION.search(raw_line) + if matched: + category = matched.group(1) + if category in (None, '(*)'): # => "suppress all" + _error_suppressions.setdefault(None, set()).add(linenum) + else: + if category.startswith('(') and category.endswith(')'): + category = category[1:-1] + if category in _ERROR_CATEGORIES: + _error_suppressions.setdefault(category, set()).add(linenum) + else: + error(filename, linenum, 'readability/nolint', 5, + 'Unknown NOLINT error category: %s' % category) + + +def ResetNolintSuppressions(): + "Resets the set of NOLINT suppressions to empty." + _error_suppressions.clear() + + +def IsErrorSuppressedByNolint(category, linenum): + """Returns true if the specified error category is suppressed on this line. + + Consults the global error_suppressions map populated by + ParseNolintSuppressions/ResetNolintSuppressions. + + Args: + category: str, the category of the error. + linenum: int, the current line number. + Returns: + bool, True iff the error should be suppressed due to a NOLINT comment. + """ + return (linenum in _error_suppressions.get(category, set()) or + linenum in _error_suppressions.get(None, set())) + + +def Match(pattern, s): + """Matches the string with the pattern, caching the compiled regexp.""" + # The regexp compilation caching is inlined in both Match and Search for + # performance reasons; factoring it out into a separate function turns out + # to be noticeably expensive. + if pattern not in _regexp_compile_cache: + _regexp_compile_cache[pattern] = sre_compile.compile(pattern) + return _regexp_compile_cache[pattern].match(s) + + +def ReplaceAll(pattern, rep, s): + """Replaces instances of pattern in a string with a replacement. + + The compiled regex is kept in a cache shared by Match and Search. + + Args: + pattern: regex pattern + rep: replacement text + s: search string + + Returns: + string with replacements made (or original string if no replacements) + """ + if pattern not in _regexp_compile_cache: + _regexp_compile_cache[pattern] = sre_compile.compile(pattern) + return _regexp_compile_cache[pattern].sub(rep, s) + + +def Search(pattern, s): + """Searches the string for the pattern, caching the compiled regexp.""" + if pattern not in _regexp_compile_cache: + _regexp_compile_cache[pattern] = sre_compile.compile(pattern) + return _regexp_compile_cache[pattern].search(s) + + +class _IncludeState(dict): + """Tracks line numbers for includes, and the order in which includes appear. + + As a dict, an _IncludeState object serves as a mapping between include + filename and line number on which that file was included. + + Call CheckNextIncludeOrder() once for each header in the file, passing + in the type constants defined above. Calls in an illegal order will + raise an _IncludeError with an appropriate error message. + + """ + # self._section will move monotonically through this set. If it ever + # needs to move backwards, CheckNextIncludeOrder will raise an error. + _INITIAL_SECTION = 0 + _MY_H_SECTION = 1 + _C_SECTION = 2 + _CPP_SECTION = 3 + _OTHER_H_SECTION = 4 + + _TYPE_NAMES = { + _C_SYS_HEADER: 'C system header', + _CPP_SYS_HEADER: 'C++ system header', + _LIKELY_MY_HEADER: 'header this file implements', + _POSSIBLE_MY_HEADER: 'header this file may implement', + _OTHER_HEADER: 'other header', + } + _SECTION_NAMES = { + _INITIAL_SECTION: "... nothing. (This can't be an error.)", + _MY_H_SECTION: 'a header this file implements', + _C_SECTION: 'C system header', + _CPP_SECTION: 'C++ system header', + _OTHER_H_SECTION: 'other header', + } + + def __init__(self): + dict.__init__(self) + self.ResetSection() + + def ResetSection(self): + # The name of the current section. + self._section = self._INITIAL_SECTION + # The path of last found header. + self._last_header = '' + + def SetLastHeader(self, header_path): + self._last_header = header_path + + def CanonicalizeAlphabeticalOrder(self, header_path): + """Returns a path canonicalized for alphabetical comparison. + + - replaces "-" with "_" so they both cmp the same. + - removes '-inl' since we don't require them to be after the main header. + - lowercase everything, just in case. + + Args: + header_path: Path to be canonicalized. + + Returns: + Canonicalized path. + """ + return header_path.replace('-inl.h', '.h').replace('-', '_').lower() + + def IsInAlphabeticalOrder(self, clean_lines, linenum, header_path): + """Check if a header is in alphabetical order with the previous header. + + Args: + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + header_path: Canonicalized header to be checked. + + Returns: + Returns true if the header is in alphabetical order. + """ + # If previous section is different from current section, _last_header will + # be reset to empty string, so it's always less than current header. + # + # If previous line was a blank line, assume that the headers are + # intentionally sorted the way they are. + if (self._last_header > header_path and + not Match(r'^\s*$', clean_lines.elided[linenum - 1])): + return False + return True + + def CheckNextIncludeOrder(self, header_type): + """Returns a non-empty error message if the next header is out of order. + + This function also updates the internal state to be ready to check + the next include. + + Args: + header_type: One of the _XXX_HEADER constants defined above. + + Returns: + The empty string if the header is in the right order, or an + error message describing what's wrong. + + """ + error_message = ('Found %s after %s' % + (self._TYPE_NAMES[header_type], + self._SECTION_NAMES[self._section])) + + last_section = self._section + + if header_type == _C_SYS_HEADER: + if self._section <= self._C_SECTION: + self._section = self._C_SECTION + else: + self._last_header = '' + return error_message + elif header_type == _CPP_SYS_HEADER: + if self._section <= self._CPP_SECTION: + self._section = self._CPP_SECTION + else: + self._last_header = '' + return error_message + elif header_type == _LIKELY_MY_HEADER: + if self._section <= self._MY_H_SECTION: + self._section = self._MY_H_SECTION + else: + self._section = self._OTHER_H_SECTION + elif header_type == _POSSIBLE_MY_HEADER: + if self._section <= self._MY_H_SECTION: + self._section = self._MY_H_SECTION + else: + # This will always be the fallback because we're not sure + # enough that the header is associated with this file. + self._section = self._OTHER_H_SECTION + else: + assert header_type == _OTHER_HEADER + self._section = self._OTHER_H_SECTION + + if last_section != self._section: + self._last_header = '' + + return '' + + +class _CppLintState(object): + """Maintains module-wide state..""" + + def __init__(self): + self.verbose_level = 1 # global setting. + self.error_count = 0 # global count of reported errors + # filters to apply when emitting error messages + self.filters = _DEFAULT_FILTERS[:] + self.counting = 'total' # In what way are we counting errors? + self.errors_by_category = {} # string to int dict storing error counts + + # output format: + # "emacs" - format that emacs can parse (default) + # "vs7" - format that Microsoft Visual Studio 7 can parse + self.output_format = 'emacs' + + def SetOutputFormat(self, output_format): + """Sets the output format for errors.""" + self.output_format = output_format + + def SetVerboseLevel(self, level): + """Sets the module's verbosity, and returns the previous setting.""" + last_verbose_level = self.verbose_level + self.verbose_level = level + return last_verbose_level + + def SetCountingStyle(self, counting_style): + """Sets the module's counting options.""" + self.counting = counting_style + + def SetFilters(self, filters): + """Sets the error-message filters. + + These filters are applied when deciding whether to emit a given + error message. + + Args: + filters: A string of comma-separated filters (eg "+whitespace/indent"). + Each filter should start with + or -; else we die. + + Raises: + ValueError: The comma-separated filters did not all start with '+' or '-'. + E.g. "-,+whitespace,-whitespace/indent,whitespace/badfilter" + """ + # Default filters always have less priority than the flag ones. + self.filters = _DEFAULT_FILTERS[:] + for filt in filters.split(','): + clean_filt = filt.strip() + if clean_filt: + self.filters.append(clean_filt) + for filt in self.filters: + if not (filt.startswith('+') or filt.startswith('-')): + raise ValueError('Every filter in --filters must start with + or -' + ' (%s does not)' % filt) + + def ResetErrorCounts(self): + """Sets the module's error statistic back to zero.""" + self.error_count = 0 + self.errors_by_category = {} + + def IncrementErrorCount(self, category): + """Bumps the module's error statistic.""" + self.error_count += 1 + if self.counting in ('toplevel', 'detailed'): + if self.counting != 'detailed': + category = category.split('/')[0] + if category not in self.errors_by_category: + self.errors_by_category[category] = 0 + self.errors_by_category[category] += 1 + + def PrintErrorCounts(self): + """Print a summary of errors by category, and the total.""" + for category, count in self.errors_by_category.iteritems(): + sys.stderr.write('Category \'%s\' errors found: %d\n' % + (category, count)) + sys.stderr.write('Total errors found: %d\n' % self.error_count) + +_cpplint_state = _CppLintState() + + +def _OutputFormat(): + """Gets the module's output format.""" + return _cpplint_state.output_format + + +def _SetOutputFormat(output_format): + """Sets the module's output format.""" + _cpplint_state.SetOutputFormat(output_format) + + +def _VerboseLevel(): + """Returns the module's verbosity setting.""" + return _cpplint_state.verbose_level + + +def _SetVerboseLevel(level): + """Sets the module's verbosity, and returns the previous setting.""" + return _cpplint_state.SetVerboseLevel(level) + + +def _SetCountingStyle(level): + """Sets the module's counting options.""" + _cpplint_state.SetCountingStyle(level) + + +def _Filters(): + """Returns the module's list of output filters, as a list.""" + return _cpplint_state.filters + + +def _SetFilters(filters): + """Sets the module's error-message filters. + + These filters are applied when deciding whether to emit a given + error message. + + Args: + filters: A string of comma-separated filters (eg "whitespace/indent"). + Each filter should start with + or -; else we die. + """ + _cpplint_state.SetFilters(filters) + + +class _FunctionState(object): + """Tracks current function name and the number of lines in its body.""" + + _NORMAL_TRIGGER = 250 # for --v=0, 500 for --v=1, etc. + _TEST_TRIGGER = 400 # about 50% more than _NORMAL_TRIGGER. + + def __init__(self): + self.in_a_function = False + self.lines_in_function = 0 + self.current_function = '' + + def Begin(self, function_name): + """Start analyzing function body. + + Args: + function_name: The name of the function being tracked. + """ + self.in_a_function = True + self.lines_in_function = 0 + self.current_function = function_name + + def Count(self): + """Count line in current function body.""" + if self.in_a_function: + self.lines_in_function += 1 + + def Check(self, error, filename, linenum): + """Report if too many lines in function body. + + Args: + error: The function to call with any errors found. + filename: The name of the current file. + linenum: The number of the line to check. + """ + if Match(r'T(EST|est)', self.current_function): + base_trigger = self._TEST_TRIGGER + else: + base_trigger = self._NORMAL_TRIGGER + trigger = base_trigger * 2**_VerboseLevel() + + if self.lines_in_function > trigger: + error_level = int(math.log(self.lines_in_function / base_trigger, 2)) + # 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ... + if error_level > 5: + error_level = 5 + error(filename, linenum, 'readability/fn_size', error_level, + 'Small and focused functions are preferred:' + ' %s has %d non-comment lines' + ' (error triggered by exceeding %d lines).' % ( + self.current_function, self.lines_in_function, trigger)) + + def End(self): + """Stop analyzing function body.""" + self.in_a_function = False + + +class _IncludeError(Exception): + """Indicates a problem with the include order in a file.""" + pass + + +class FileInfo: + """Provides utility functions for filenames. + + FileInfo provides easy access to the components of a file's path + relative to the project root. + """ + + def __init__(self, filename): + self._filename = filename + + def FullName(self): + """Make Windows paths like Unix.""" + return os.path.abspath(self._filename).replace('\\', '/') + + def RepositoryName(self): + """FullName after removing the local path to the repository. + + If we have a real absolute path name here we can try to do something smart: + detecting the root of the checkout and truncating /path/to/checkout from + the name so that we get header guards that don't include things like + "C:\Documents and Settings\..." or "/home/username/..." in them and thus + people on different computers who have checked the source out to different + locations won't see bogus errors. + """ + fullname = self.FullName() + + if os.path.exists(fullname): + project_dir = os.path.dirname(fullname) + + if os.path.exists(os.path.join(project_dir, ".svn")): + # If there's a .svn file in the current directory, we recursively look + # up the directory tree for the top of the SVN checkout + root_dir = project_dir + one_up_dir = os.path.dirname(root_dir) + while os.path.exists(os.path.join(one_up_dir, ".svn")): + root_dir = os.path.dirname(root_dir) + one_up_dir = os.path.dirname(one_up_dir) + + prefix = os.path.commonprefix([root_dir, project_dir]) + return fullname[len(prefix) + 1:] + + # Not SVN <= 1.6? Try to find a git, hg, or svn top level directory by + # searching up from the current path. + root_dir = os.path.dirname(fullname) + while (root_dir != os.path.dirname(root_dir) and + not os.path.exists(os.path.join(root_dir, ".git")) and + not os.path.exists(os.path.join(root_dir, ".hg")) and + not os.path.exists(os.path.join(root_dir, ".svn"))): + root_dir = os.path.dirname(root_dir) + + if (os.path.exists(os.path.join(root_dir, ".git")) or + os.path.exists(os.path.join(root_dir, ".hg")) or + os.path.exists(os.path.join(root_dir, ".svn"))): + prefix = os.path.commonprefix([root_dir, project_dir]) + return fullname[len(prefix) + 1:] + + # Don't know what to do; header guard warnings may be wrong... + return fullname + + def Split(self): + """Splits the file into the directory, basename, and extension. + + For 'chrome/browser/browser.cc', Split() would + return ('chrome/browser', 'browser', '.cc') + + Returns: + A tuple of (directory, basename, extension). + """ + + googlename = self.RepositoryName() + project, rest = os.path.split(googlename) + return (project,) + os.path.splitext(rest) + + def BaseName(self): + """File base name - text after the final slash, before the final period.""" + return self.Split()[1] + + def Extension(self): + """File extension - text following the final period.""" + return self.Split()[2] + + def NoExtension(self): + """File has no source file extension.""" + return '/'.join(self.Split()[0:2]) + + def IsSource(self): + """File has a source file extension.""" + return self.Extension()[1:] in ('c', 'cc', 'cpp', 'cxx') + + +def _ShouldPrintError(category, confidence, linenum): + """If confidence >= verbose, category passes filter and is not suppressed.""" + + # There are three ways we might decide not to print an error message: + # a "NOLINT(category)" comment appears in the source, + # the verbosity level isn't high enough, or the filters filter it out. + if IsErrorSuppressedByNolint(category, linenum): + return False + + if confidence < _cpplint_state.verbose_level: + return False + + is_filtered = False + for one_filter in _Filters(): + if one_filter.startswith('-'): + if category.startswith(one_filter[1:]): + is_filtered = True + elif one_filter.startswith('+'): + if category.startswith(one_filter[1:]): + is_filtered = False + else: + assert False # should have been checked for in SetFilter. + if is_filtered: + return False + + return True + + +def Error(filename, linenum, category, confidence, message): + """Logs the fact we've found a lint error. + + We log where the error was found, and also our confidence in the error, + that is, how certain we are this is a legitimate style regression, and + not a misidentification or a use that's sometimes justified. + + False positives can be suppressed by the use of + "cpplint(category)" comments on the offending line. These are + parsed into _error_suppressions. + + Args: + filename: The name of the file containing the error. + linenum: The number of the line containing the error. + category: A string used to describe the "category" this bug + falls under: "whitespace", say, or "runtime". Categories + may have a hierarchy separated by slashes: "whitespace/indent". + confidence: A number from 1-5 representing a confidence score for + the error, with 5 meaning that we are certain of the problem, + and 1 meaning that it could be a legitimate construct. + message: The error message. + """ + if _ShouldPrintError(category, confidence, linenum): + _cpplint_state.IncrementErrorCount(category) + if _cpplint_state.output_format == 'vs7': + sys.stderr.write('%s(%s): %s [%s] [%d]\n' % ( + filename, linenum, message, category, confidence)) + elif _cpplint_state.output_format == 'eclipse': + sys.stderr.write('%s:%s: warning: %s [%s] [%d]\n' % ( + filename, linenum, message, category, confidence)) + else: + sys.stderr.write('%s:%s: %s [%s] [%d]\n' % ( + filename, linenum, message, category, confidence)) + + +# Matches standard C++ escape sequences per 2.13.2.3 of the C++ standard. +_RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile( + r'\\([abfnrtv?"\\\']|\d+|x[0-9a-fA-F]+)') +# Match a single C style comment on the same line. +_RE_PATTERN_C_COMMENTS = r'/\*(?:[^*]|\*(?!/))*\*/' +# Matches multi-line C style comments. +# This RE is a little bit more complicated than one might expect, because we +# have to take care of space removals tools so we can handle comments inside +# statements better. +# The current rule is: We only clear spaces from both sides when we're at the +# end of the line. Otherwise, we try to remove spaces from the right side, +# if this doesn't work we try on left side but only if there's a non-character +# on the right. +_RE_PATTERN_CLEANSE_LINE_C_COMMENTS = re.compile( + r'(\s*' + _RE_PATTERN_C_COMMENTS + r'\s*$|' + + _RE_PATTERN_C_COMMENTS + r'\s+|' + + r'\s+' + _RE_PATTERN_C_COMMENTS + r'(?=\W)|' + + _RE_PATTERN_C_COMMENTS + r')') + + +def IsCppString(line): + """Does line terminate so, that the next symbol is in string constant. + + This function does not consider single-line nor multi-line comments. + + Args: + line: is a partial line of code starting from the 0..n. + + Returns: + True, if next character appended to 'line' is inside a + string constant. + """ + + line = line.replace(r'\\', 'XX') # after this, \\" does not match to \" + return ((line.count('"') - line.count(r'\"') - line.count("'\"'")) & 1) == 1 + + +def CleanseRawStrings(raw_lines): + """Removes C++11 raw strings from lines. + + Before: + static const char kData[] = R"( + multi-line string + )"; + + After: + static const char kData[] = "" + (replaced by blank line) + ""; + + Args: + raw_lines: list of raw lines. + + Returns: + list of lines with C++11 raw strings replaced by empty strings. + """ + + delimiter = None + lines_without_raw_strings = [] + for line in raw_lines: + if delimiter: + # Inside a raw string, look for the end + end = line.find(delimiter) + if end >= 0: + # Found the end of the string, match leading space for this + # line and resume copying the original lines, and also insert + # a "" on the last line. + leading_space = Match(r'^(\s*)\S', line) + line = leading_space.group(1) + '""' + line[end + len(delimiter):] + delimiter = None + else: + # Haven't found the end yet, append a blank line. + line = '""' + + # Look for beginning of a raw string, and replace them with + # empty strings. This is done in a loop to handle multiple raw + # strings on the same line. + while delimiter is None: + # Look for beginning of a raw string. + # See 2.14.15 [lex.string] for syntax. + matched = Match(r'^(.*)\b(?:R|u8R|uR|UR|LR)"([^\s\\()]*)\((.*)$', line) + if matched: + delimiter = ')' + matched.group(2) + '"' + + end = matched.group(3).find(delimiter) + if end >= 0: + # Raw string ended on same line + line = (matched.group(1) + '""' + + matched.group(3)[end + len(delimiter):]) + delimiter = None + else: + # Start of a multi-line raw string + line = matched.group(1) + '""' + else: + break + + lines_without_raw_strings.append(line) + + # TODO(unknown): if delimiter is not None here, we might want to + # emit a warning for unterminated string. + return lines_without_raw_strings + + +def FindNextMultiLineCommentStart(lines, lineix): + """Find the beginning marker for a multiline comment.""" + while lineix < len(lines): + if lines[lineix].strip().startswith('/*'): + # Only return this marker if the comment goes beyond this line + if lines[lineix].strip().find('*/', 2) < 0: + return lineix + lineix += 1 + return len(lines) + + +def FindNextMultiLineCommentEnd(lines, lineix): + """We are inside a comment, find the end marker.""" + while lineix < len(lines): + if lines[lineix].strip().endswith('*/'): + return lineix + lineix += 1 + return len(lines) + + +def RemoveMultiLineCommentsFromRange(lines, begin, end): + """Clears a range of lines for multi-line comments.""" + # Having // dummy comments makes the lines non-empty, so we will not get + # unnecessary blank line warnings later in the code. + for i in range(begin, end): + lines[i] = '// dummy' + + +def RemoveMultiLineComments(filename, lines, error): + """Removes multiline (c-style) comments from lines.""" + lineix = 0 + while lineix < len(lines): + lineix_begin = FindNextMultiLineCommentStart(lines, lineix) + if lineix_begin >= len(lines): + return + lineix_end = FindNextMultiLineCommentEnd(lines, lineix_begin) + if lineix_end >= len(lines): + error(filename, lineix_begin + 1, 'readability/multiline_comment', 5, + 'Could not find end of multi-line comment') + return + RemoveMultiLineCommentsFromRange(lines, lineix_begin, lineix_end + 1) + lineix = lineix_end + 1 + + +def CleanseComments(line): + """Removes //-comments and single-line C-style /* */ comments. + + Args: + line: A line of C++ source. + + Returns: + The line with single-line comments removed. + """ + commentpos = line.find('//') + if commentpos != -1 and not IsCppString(line[:commentpos]): + line = line[:commentpos].rstrip() + # get rid of /* ... */ + return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line) + + +class CleansedLines(object): + """Holds 3 copies of all lines with different preprocessing applied to them. + + 1) elided member contains lines without strings and comments, + 2) lines member contains lines without comments, and + 3) raw_lines member contains all the lines without processing. + All these three members are of , and of the same length. + """ + + def __init__(self, lines): + self.elided = [] + self.lines = [] + self.raw_lines = lines + self.num_lines = len(lines) + self.lines_without_raw_strings = CleanseRawStrings(lines) + for linenum in range(len(self.lines_without_raw_strings)): + self.lines.append(CleanseComments( + self.lines_without_raw_strings[linenum])) + elided = self._CollapseStrings(self.lines_without_raw_strings[linenum]) + self.elided.append(CleanseComments(elided)) + + def NumLines(self): + """Returns the number of lines represented.""" + return self.num_lines + + @staticmethod + def _CollapseStrings(elided): + """Collapses strings and chars on a line to simple "" or '' blocks. + + We nix strings first so we're not fooled by text like '"http://"' + + Args: + elided: The line being processed. + + Returns: + The line with collapsed strings. + """ + if _RE_PATTERN_INCLUDE.match(elided): + return elided + + # Remove escaped characters first to make quote/single quote collapsing + # basic. Things that look like escaped characters shouldn't occur + # outside of strings and chars. + elided = _RE_PATTERN_CLEANSE_LINE_ESCAPES.sub('', elided) + + # Replace quoted strings and digit separators. Both single quotes + # and double quotes are processed in the same loop, otherwise + # nested quotes wouldn't work. + collapsed = '' + while True: + # Find the first quote character + match = Match(r'^([^\'"]*)([\'"])(.*)$', elided) + if not match: + collapsed += elided + break + head, quote, tail = match.groups() + + if quote == '"': + # Collapse double quoted strings + second_quote = tail.find('"') + if second_quote >= 0: + collapsed += head + '""' + elided = tail[second_quote + 1:] + else: + # Unmatched double quote, don't bother processing the rest + # of the line since this is probably a multiline string. + collapsed += elided + break + else: + # Found single quote, check nearby text to eliminate digit separators. + # + # There is no special handling for floating point here, because + # the integer/fractional/exponent parts would all be parsed + # correctly as long as there are digits on both sides of the + # separator. So we are fine as long as we don't see something + # like "0.'3" (gcc 4.9.0 will not allow this literal). + if Search(r'\b(?:0[bBxX]?|[1-9])[0-9a-fA-F]*$', head): + match_literal = Match(r'^((?:\'?[0-9a-zA-Z_])*)(.*)$', "'" + tail) + collapsed += head + match_literal.group(1).replace("'", '') + elided = match_literal.group(2) + else: + second_quote = tail.find('\'') + if second_quote >= 0: + collapsed += head + "''" + elided = tail[second_quote + 1:] + else: + # Unmatched single quote + collapsed += elided + break + + return collapsed + + +def FindEndOfExpressionInLine(line, startpos, stack): + """Find the position just after the end of current parenthesized expression. + + Args: + line: a CleansedLines line. + startpos: start searching at this position. + stack: nesting stack at startpos. + + Returns: + On finding matching end: (index just after matching end, None) + On finding an unclosed expression: (-1, None) + Otherwise: (-1, new stack at end of this line) + """ + for i in xrange(startpos, len(line)): + char = line[i] + if char in '([{': + # Found start of parenthesized expression, push to expression stack + stack.append(char) + elif char == '<': + # Found potential start of template argument list + if i > 0 and line[i - 1] == '<': + # Left shift operator + if stack and stack[-1] == '<': + stack.pop() + if not stack: + return (-1, None) + elif i > 0 and Search(r'\boperator\s*$', line[0:i]): + # operator<, don't add to stack + continue + else: + # Tentative start of template argument list + stack.append('<') + elif char in ')]}': + # Found end of parenthesized expression. + # + # If we are currently expecting a matching '>', the pending '<' + # must have been an operator. Remove them from expression stack. + while stack and stack[-1] == '<': + stack.pop() + if not stack: + return (-1, None) + if ((stack[-1] == '(' and char == ')') or + (stack[-1] == '[' and char == ']') or + (stack[-1] == '{' and char == '}')): + stack.pop() + if not stack: + return (i + 1, None) + else: + # Mismatched parentheses + return (-1, None) + elif char == '>': + # Found potential end of template argument list. + + # Ignore "->" and operator functions + if (i > 0 and + (line[i - 1] == '-' or Search(r'\boperator\s*$', line[0:i - 1]))): + continue + + # Pop the stack if there is a matching '<'. Otherwise, ignore + # this '>' since it must be an operator. + if stack: + if stack[-1] == '<': + stack.pop() + if not stack: + return (i + 1, None) + elif char == ';': + # Found something that look like end of statements. If we are currently + # expecting a '>', the matching '<' must have been an operator, since + # template argument list should not contain statements. + while stack and stack[-1] == '<': + stack.pop() + if not stack: + return (-1, None) + + # Did not find end of expression or unbalanced parentheses on this line + return (-1, stack) + + +def CloseExpression(clean_lines, linenum, pos): + """If input points to ( or { or [ or <, finds the position that closes it. + + If lines[linenum][pos] points to a '(' or '{' or '[' or '<', finds the + linenum/pos that correspond to the closing of the expression. + + TODO(unknown): cpplint spends a fair bit of time matching parentheses. + Ideally we would want to index all opening and closing parentheses once + and have CloseExpression be just a simple lookup, but due to preprocessor + tricks, this is not so easy. + + Args: + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + pos: A position on the line. + + Returns: + A tuple (line, linenum, pos) pointer *past* the closing brace, or + (line, len(lines), -1) if we never find a close. Note we ignore + strings and comments when matching; and the line we return is the + 'cleansed' line at linenum. + """ + + line = clean_lines.elided[linenum] + if (line[pos] not in '({[<') or Match(r'<[<=]', line[pos:]): + return (line, clean_lines.NumLines(), -1) + + # Check first line + (end_pos, stack) = FindEndOfExpressionInLine(line, pos, []) + if end_pos > -1: + return (line, linenum, end_pos) + + # Continue scanning forward + while stack and linenum < clean_lines.NumLines() - 1: + linenum += 1 + line = clean_lines.elided[linenum] + (end_pos, stack) = FindEndOfExpressionInLine(line, 0, stack) + if end_pos > -1: + return (line, linenum, end_pos) + + # Did not find end of expression before end of file, give up + return (line, clean_lines.NumLines(), -1) + + +def FindStartOfExpressionInLine(line, endpos, stack): + """Find position at the matching start of current expression. + + This is almost the reverse of FindEndOfExpressionInLine, but note + that the input position and returned position differs by 1. + + Args: + line: a CleansedLines line. + endpos: start searching at this position. + stack: nesting stack at endpos. + + Returns: + On finding matching start: (index at matching start, None) + On finding an unclosed expression: (-1, None) + Otherwise: (-1, new stack at beginning of this line) + """ + i = endpos + while i >= 0: + char = line[i] + if char in ')]}': + # Found end of expression, push to expression stack + stack.append(char) + elif char == '>': + # Found potential end of template argument list. + # + # Ignore it if it's a "->" or ">=" or "operator>" + if (i > 0 and + (line[i - 1] == '-' or + Match(r'\s>=\s', line[i - 1:]) or + Search(r'\boperator\s*$', line[0:i]))): + i -= 1 + else: + stack.append('>') + elif char == '<': + # Found potential start of template argument list + if i > 0 and line[i - 1] == '<': + # Left shift operator + i -= 1 + else: + # If there is a matching '>', we can pop the expression stack. + # Otherwise, ignore this '<' since it must be an operator. + if stack and stack[-1] == '>': + stack.pop() + if not stack: + return (i, None) + elif char in '([{': + # Found start of expression. + # + # If there are any unmatched '>' on the stack, they must be + # operators. Remove those. + while stack and stack[-1] == '>': + stack.pop() + if not stack: + return (-1, None) + if ((char == '(' and stack[-1] == ')') or + (char == '[' and stack[-1] == ']') or + (char == '{' and stack[-1] == '}')): + stack.pop() + if not stack: + return (i, None) + else: + # Mismatched parentheses + return (-1, None) + elif char == ';': + # Found something that look like end of statements. If we are currently + # expecting a '<', the matching '>' must have been an operator, since + # template argument list should not contain statements. + while stack and stack[-1] == '>': + stack.pop() + if not stack: + return (-1, None) + + i -= 1 + + return (-1, stack) + + +def ReverseCloseExpression(clean_lines, linenum, pos): + """If input points to ) or } or ] or >, finds the position that opens it. + + If lines[linenum][pos] points to a ')' or '}' or ']' or '>', finds the + linenum/pos that correspond to the opening of the expression. + + Args: + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + pos: A position on the line. + + Returns: + A tuple (line, linenum, pos) pointer *at* the opening brace, or + (line, 0, -1) if we never find the matching opening brace. Note + we ignore strings and comments when matching; and the line we + return is the 'cleansed' line at linenum. + """ + line = clean_lines.elided[linenum] + if line[pos] not in ')}]>': + return (line, 0, -1) + + # Check last line + (start_pos, stack) = FindStartOfExpressionInLine(line, pos, []) + if start_pos > -1: + return (line, linenum, start_pos) + + # Continue scanning backward + while stack and linenum > 0: + linenum -= 1 + line = clean_lines.elided[linenum] + (start_pos, stack) = FindStartOfExpressionInLine(line, len(line) - 1, stack) + if start_pos > -1: + return (line, linenum, start_pos) + + # Did not find start of expression before beginning of file, give up + return (line, 0, -1) + + +def CheckForCopyright(filename, lines, error): + """Logs an error if no Copyright message appears at the top of the file.""" + + # We'll say it should occur by line 10. Don't forget there's a + # dummy line at the front. + for line in xrange(1, min(len(lines), 11)): + if re.search(r'Copyright', lines[line], re.I): break + else: # means no copyright line was found + error(filename, 0, 'legal/copyright', 5, + 'No copyright message found. ' + 'You should have a line: "Copyright [year] "') + + +def GetIndentLevel(line): + """Return the number of leading spaces in line. + + Args: + line: A string to check. + + Returns: + An integer count of leading spaces, possibly zero. + """ + indent = Match(r'^( *)\S', line) + if indent: + return len(indent.group(1)) + else: + return 0 + + +def GetHeaderGuardCPPVariable(filename): + """Returns the CPP variable that should be used as a header guard. + + Args: + filename: The name of a C++ header file. + + Returns: + The CPP variable that should be used as a header guard in the + named file. + + """ + + # Restores original filename in case that cpplint is invoked from Emacs's + # flymake. + filename = re.sub(r'_flymake\.h$', '.h', filename) + filename = re.sub(r'/\.flymake/([^/]*)$', r'/\1', filename) + + fileinfo = FileInfo(filename) + file_path_from_root = fileinfo.RepositoryName() + if _root: + file_path_from_root = re.sub('^' + _root + os.sep, '', file_path_from_root) + return re.sub(r'[-./\s]', '_', file_path_from_root).upper() + '_' + + +def CheckForHeaderGuard(filename, lines, error): + """Checks that the file contains a header guard. + + Logs an error if no #ifndef header guard is present. For other + headers, checks that the full pathname is used. + + Args: + filename: The name of the C++ header file. + lines: An array of strings, each representing a line of the file. + error: The function to call with any errors found. + """ + + cppvar = GetHeaderGuardCPPVariable(filename) + + ifndef = None + ifndef_linenum = 0 + define = None + endif = None + endif_linenum = 0 + for linenum, line in enumerate(lines): + linesplit = line.split() + if len(linesplit) >= 2: + # find the first occurrence of #ifndef and #define, save arg + if not ifndef and linesplit[0] == '#ifndef': + # set ifndef to the header guard presented on the #ifndef line. + ifndef = linesplit[1] + ifndef_linenum = linenum + if not define and linesplit[0] == '#define': + define = linesplit[1] + # find the last occurrence of #endif, save entire line + if line.startswith('#endif'): + endif = line + endif_linenum = linenum + + if not ifndef: + error(filename, 0, 'build/header_guard', 5, + 'No #ifndef header guard found, suggested CPP variable is: %s' % + cppvar) + return + + if not define: + error(filename, 0, 'build/header_guard', 5, + 'No #define header guard found, suggested CPP variable is: %s' % + cppvar) + return + + # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__ + # for backward compatibility. + if ifndef != cppvar: + error_level = 0 + if ifndef != cppvar + '_': + error_level = 5 + + ParseNolintSuppressions(filename, lines[ifndef_linenum], ifndef_linenum, + error) + error(filename, ifndef_linenum, 'build/header_guard', error_level, + '#ifndef header guard has wrong style, please use: %s' % cppvar) + + if define != ifndef: + error(filename, 0, 'build/header_guard', 5, + '#ifndef and #define don\'t match, suggested CPP variable is: %s' % + cppvar) + return + + if endif != ('#endif // %s' % cppvar): + error_level = 0 + if endif != ('#endif // %s' % (cppvar + '_')): + error_level = 5 + + ParseNolintSuppressions(filename, lines[endif_linenum], endif_linenum, + error) + error(filename, endif_linenum, 'build/header_guard', error_level, + '#endif line should be "#endif // %s"' % cppvar) + + +def CheckForBadCharacters(filename, lines, error): + """Logs an error for each line containing bad characters. + + Two kinds of bad characters: + + 1. Unicode replacement characters: These indicate that either the file + contained invalid UTF-8 (likely) or Unicode replacement characters (which + it shouldn't). Note that it's possible for this to throw off line + numbering if the invalid UTF-8 occurred adjacent to a newline. + + 2. NUL bytes. These are problematic for some tools. + + Args: + filename: The name of the current file. + lines: An array of strings, each representing a line of the file. + error: The function to call with any errors found. + """ + for linenum, line in enumerate(lines): + if u'\ufffd' in line: + error(filename, linenum, 'readability/utf8', 5, + 'Line contains invalid UTF-8 (or Unicode replacement character).') + if '\0' in line: + error(filename, linenum, 'readability/nul', 5, 'Line contains NUL byte.') + + +def CheckForNewlineAtEOF(filename, lines, error): + """Logs an error if there is no newline char at the end of the file. + + Args: + filename: The name of the current file. + lines: An array of strings, each representing a line of the file. + error: The function to call with any errors found. + """ + + # The array lines() was created by adding two newlines to the + # original file (go figure), then splitting on \n. + # To verify that the file ends in \n, we just have to make sure the + # last-but-two element of lines() exists and is empty. + if len(lines) < 3 or lines[-2]: + error(filename, len(lines) - 2, 'whitespace/ending_newline', 5, + 'Could not find a newline character at the end of the file.') + + +def CheckForMultilineCommentsAndStrings(filename, clean_lines, linenum, error): + """Logs an error if we see /* ... */ or "..." that extend past one line. + + /* ... */ comments are legit inside macros, for one line. + Otherwise, we prefer // comments, so it's ok to warn about the + other. Likewise, it's ok for strings to extend across multiple + lines, as long as a line continuation character (backslash) + terminates each line. Although not currently prohibited by the C++ + style guide, it's ugly and unnecessary. We don't do well with either + in this lint program, so we warn about both. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + line = clean_lines.elided[linenum] + + # Remove all \\ (escaped backslashes) from the line. They are OK, and the + # second (escaped) slash may trigger later \" detection erroneously. + line = line.replace('\\\\', '') + + if line.count('/*') > line.count('*/'): + error(filename, linenum, 'readability/multiline_comment', 5, + 'Complex multi-line /*...*/-style comment found. ' + 'Lint may give bogus warnings. ' + 'Consider replacing these with //-style comments, ' + 'with #if 0...#endif, ' + 'or with more clearly structured multi-line comments.') + + if (line.count('"') - line.count('\\"')) % 2: + error(filename, linenum, 'readability/multiline_string', 5, + 'Multi-line string ("...") found. This lint script doesn\'t ' + 'do well with such strings, and may give bogus warnings. ' + 'Use C++11 raw strings or concatenation instead.') + + +# (non-threadsafe name, thread-safe alternative, validation pattern) +# +# The validation pattern is used to eliminate false positives such as: +# _rand(); // false positive due to substring match. +# ->rand(); // some member function rand(). +# ACMRandom rand(seed); // some variable named rand. +# ISAACRandom rand(); // another variable named rand. +# +# Basically we require the return value of these functions to be used +# in some expression context on the same line by matching on some +# operator before the function name. This eliminates constructors and +# member function calls. +_UNSAFE_FUNC_PREFIX = r'(?:[-+*/=%^&|(<]\s*|>\s+)' +_THREADING_LIST = ( + ('asctime(', 'asctime_r(', _UNSAFE_FUNC_PREFIX + r'asctime\([^)]+\)'), + ('ctime(', 'ctime_r(', _UNSAFE_FUNC_PREFIX + r'ctime\([^)]+\)'), + ('getgrgid(', 'getgrgid_r(', _UNSAFE_FUNC_PREFIX + r'getgrgid\([^)]+\)'), + ('getgrnam(', 'getgrnam_r(', _UNSAFE_FUNC_PREFIX + r'getgrnam\([^)]+\)'), + ('getlogin(', 'getlogin_r(', _UNSAFE_FUNC_PREFIX + r'getlogin\(\)'), + ('getpwnam(', 'getpwnam_r(', _UNSAFE_FUNC_PREFIX + r'getpwnam\([^)]+\)'), + ('getpwuid(', 'getpwuid_r(', _UNSAFE_FUNC_PREFIX + r'getpwuid\([^)]+\)'), + ('gmtime(', 'gmtime_r(', _UNSAFE_FUNC_PREFIX + r'gmtime\([^)]+\)'), + ('localtime(', 'localtime_r(', _UNSAFE_FUNC_PREFIX + r'localtime\([^)]+\)'), + ('rand(', 'rand_r(', _UNSAFE_FUNC_PREFIX + r'rand\(\)'), + ('strtok(', 'strtok_r(', + _UNSAFE_FUNC_PREFIX + r'strtok\([^)]+\)'), + ('ttyname(', 'ttyname_r(', _UNSAFE_FUNC_PREFIX + r'ttyname\([^)]+\)'), + ) + + +def CheckPosixThreading(filename, clean_lines, linenum, error): + """Checks for calls to thread-unsafe functions. + + Much code has been originally written without consideration of + multi-threading. Also, engineers are relying on their old experience; + they have learned posix before threading extensions were added. These + tests guide the engineers to use thread-safe functions (when using + posix directly). + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + line = clean_lines.elided[linenum] + for single_thread_func, multithread_safe_func, pattern in _THREADING_LIST: + # Additional pattern matching check to confirm that this is the + # function we are looking for + if Search(pattern, line): + error(filename, linenum, 'runtime/threadsafe_fn', 2, + 'Consider using ' + multithread_safe_func + + '...) instead of ' + single_thread_func + + '...) for improved thread safety.') + + +def CheckVlogArguments(filename, clean_lines, linenum, error): + """Checks that VLOG() is only used for defining a logging level. + + For example, VLOG(2) is correct. VLOG(INFO), VLOG(WARNING), VLOG(ERROR), and + VLOG(FATAL) are not. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + line = clean_lines.elided[linenum] + if Search(r'\bVLOG\((INFO|ERROR|WARNING|DFATAL|FATAL)\)', line): + error(filename, linenum, 'runtime/vlog', 5, + 'VLOG() should be used with numeric verbosity level. ' + 'Use LOG() if you want symbolic severity levels.') + +# Matches invalid increment: *count++, which moves pointer instead of +# incrementing a value. +_RE_PATTERN_INVALID_INCREMENT = re.compile( + r'^\s*\*\w+(\+\+|--);') + + +def CheckInvalidIncrement(filename, clean_lines, linenum, error): + """Checks for invalid increment *count++. + + For example following function: + void increment_counter(int* count) { + *count++; + } + is invalid, because it effectively does count++, moving pointer, and should + be replaced with ++*count, (*count)++ or *count += 1. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + line = clean_lines.elided[linenum] + if _RE_PATTERN_INVALID_INCREMENT.match(line): + error(filename, linenum, 'runtime/invalid_increment', 5, + 'Changing pointer instead of value (or unused value of operator*).') + + +class _BlockInfo(object): + """Stores information about a generic block of code.""" + + def __init__(self, seen_open_brace): + self.seen_open_brace = seen_open_brace + self.open_parentheses = 0 + self.inline_asm = _NO_ASM + + def CheckBegin(self, filename, clean_lines, linenum, error): + """Run checks that applies to text up to the opening brace. + + This is mostly for checking the text after the class identifier + and the "{", usually where the base class is specified. For other + blocks, there isn't much to check, so we always pass. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + pass + + def CheckEnd(self, filename, clean_lines, linenum, error): + """Run checks that applies to text after the closing brace. + + This is mostly used for checking end of namespace comments. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + pass + + def IsBlockInfo(self): + """Returns true if this block is a _BlockInfo. + + This is convenient for verifying that an object is an instance of + a _BlockInfo, but not an instance of any of the derived classes. + + Returns: + True for this class, False for derived classes. + """ + return self.__class__ == _BlockInfo + + +class _ExternCInfo(_BlockInfo): + """Stores information about an 'extern "C"' block.""" + + def __init__(self): + _BlockInfo.__init__(self, True) + + +class _ClassInfo(_BlockInfo): + """Stores information about a class.""" + + def __init__(self, name, class_or_struct, clean_lines, linenum): + _BlockInfo.__init__(self, False) + self.name = name + self.starting_linenum = linenum + self.is_derived = False + if class_or_struct == 'struct': + self.access = 'public' + self.is_struct = True + else: + self.access = 'private' + self.is_struct = False + + # Remember initial indentation level for this class. Using raw_lines here + # instead of elided to account for leading comments. + self.class_indent = GetIndentLevel(clean_lines.raw_lines[linenum]) + + # Try to find the end of the class. This will be confused by things like: + # class A { + # } *x = { ... + # + # But it's still good enough for CheckSectionSpacing. + self.last_line = 0 + depth = 0 + for i in range(linenum, clean_lines.NumLines()): + line = clean_lines.elided[i] + depth += line.count('{') - line.count('}') + if not depth: + self.last_line = i + break + + def CheckBegin(self, filename, clean_lines, linenum, error): + # Look for a bare ':' + if Search('(^|[^:]):($|[^:])', clean_lines.elided[linenum]): + self.is_derived = True + + def CheckEnd(self, filename, clean_lines, linenum, error): + # Check that closing brace is aligned with beginning of the class. + # Only do this if the closing brace is indented by only whitespaces. + # This means we will not check single-line class definitions. + indent = Match(r'^( *)\}', clean_lines.elided[linenum]) + if indent and len(indent.group(1)) != self.class_indent: + if self.is_struct: + parent = 'struct ' + self.name + else: + parent = 'class ' + self.name + error(filename, linenum, 'whitespace/indent', 3, + 'Closing brace should be aligned with beginning of %s' % parent) + + +class _NamespaceInfo(_BlockInfo): + """Stores information about a namespace.""" + + def __init__(self, name, linenum): + _BlockInfo.__init__(self, False) + self.name = name or '' + self.starting_linenum = linenum + + def CheckEnd(self, filename, clean_lines, linenum, error): + """Check end of namespace comments.""" + line = clean_lines.raw_lines[linenum] + + # Check how many lines is enclosed in this namespace. Don't issue + # warning for missing namespace comments if there aren't enough + # lines. However, do apply checks if there is already an end of + # namespace comment and it's incorrect. + # + # TODO(unknown): We always want to check end of namespace comments + # if a namespace is large, but sometimes we also want to apply the + # check if a short namespace contained nontrivial things (something + # other than forward declarations). There is currently no logic on + # deciding what these nontrivial things are, so this check is + # triggered by namespace size only, which works most of the time. + if (linenum - self.starting_linenum < 10 + and not Match(r'};*\s*(//|/\*).*\bnamespace\b', line)): + return + + # Look for matching comment at end of namespace. + # + # Note that we accept C style "/* */" comments for terminating + # namespaces, so that code that terminate namespaces inside + # preprocessor macros can be cpplint clean. + # + # We also accept stuff like "// end of namespace ." with the + # period at the end. + # + # Besides these, we don't accept anything else, otherwise we might + # get false negatives when existing comment is a substring of the + # expected namespace. + if self.name: + # Named namespace + if not Match((r'};*\s*(//|/\*).*\bnamespace\s+' + re.escape(self.name) + + r'[\*/\.\\\s]*$'), + line): + error(filename, linenum, 'readability/namespace', 5, + 'Namespace should be terminated with "// namespace %s"' % + self.name) + else: + # Anonymous namespace + if not Match(r'};*\s*(//|/\*).*\bnamespace[\*/\.\\\s]*$', line): + # If "// namespace anonymous" or "// anonymous namespace (more text)", + # mention "// anonymous namespace" as an acceptable form + if Match(r'}.*\b(namespace anonymous|anonymous namespace)\b', line): + error(filename, linenum, 'readability/namespace', 5, + 'Anonymous namespace should be terminated with "// namespace"' + ' or "// anonymous namespace"') + else: + error(filename, linenum, 'readability/namespace', 5, + 'Anonymous namespace should be terminated with "// namespace"') + + +class _PreprocessorInfo(object): + """Stores checkpoints of nesting stacks when #if/#else is seen.""" + + def __init__(self, stack_before_if): + # The entire nesting stack before #if + self.stack_before_if = stack_before_if + + # The entire nesting stack up to #else + self.stack_before_else = [] + + # Whether we have already seen #else or #elif + self.seen_else = False + + +class NestingState(object): + """Holds states related to parsing braces.""" + + def __init__(self): + # Stack for tracking all braces. An object is pushed whenever we + # see a "{", and popped when we see a "}". Only 3 types of + # objects are possible: + # - _ClassInfo: a class or struct. + # - _NamespaceInfo: a namespace. + # - _BlockInfo: some other type of block. + self.stack = [] + + # Top of the previous stack before each Update(). + # + # Because the nesting_stack is updated at the end of each line, we + # had to do some convoluted checks to find out what is the current + # scope at the beginning of the line. This check is simplified by + # saving the previous top of nesting stack. + # + # We could save the full stack, but we only need the top. Copying + # the full nesting stack would slow down cpplint by ~10%. + self.previous_stack_top = [] + + # Stack of _PreprocessorInfo objects. + self.pp_stack = [] + + def SeenOpenBrace(self): + """Check if we have seen the opening brace for the innermost block. + + Returns: + True if we have seen the opening brace, False if the innermost + block is still expecting an opening brace. + """ + return (not self.stack) or self.stack[-1].seen_open_brace + + def InNamespaceBody(self): + """Check if we are currently one level inside a namespace body. + + Returns: + True if top of the stack is a namespace block, False otherwise. + """ + return self.stack and isinstance(self.stack[-1], _NamespaceInfo) + + def InExternC(self): + """Check if we are currently one level inside an 'extern "C"' block. + + Returns: + True if top of the stack is an extern block, False otherwise. + """ + return self.stack and isinstance(self.stack[-1], _ExternCInfo) + + def InClassDeclaration(self): + """Check if we are currently one level inside a class or struct declaration. + + Returns: + True if top of the stack is a class/struct, False otherwise. + """ + return self.stack and isinstance(self.stack[-1], _ClassInfo) + + def InAsmBlock(self): + """Check if we are currently one level inside an inline ASM block. + + Returns: + True if the top of the stack is a block containing inline ASM. + """ + return self.stack and self.stack[-1].inline_asm != _NO_ASM + + def InTemplateArgumentList(self, clean_lines, linenum, pos): + """Check if current position is inside template argument list. + + Args: + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + pos: position just after the suspected template argument. + Returns: + True if (linenum, pos) is inside template arguments. + """ + while linenum < clean_lines.NumLines(): + # Find the earliest character that might indicate a template argument + line = clean_lines.elided[linenum] + match = Match(r'^[^{};=\[\]\.<>]*(.)', line[pos:]) + if not match: + linenum += 1 + pos = 0 + continue + token = match.group(1) + pos += len(match.group(0)) + + # These things do not look like template argument list: + # class Suspect { + # class Suspect x; } + if token in ('{', '}', ';'): return False + + # These things look like template argument list: + # template + # template + # template + # template + if token in ('>', '=', '[', ']', '.'): return True + + # Check if token is an unmatched '<'. + # If not, move on to the next character. + if token != '<': + pos += 1 + if pos >= len(line): + linenum += 1 + pos = 0 + continue + + # We can't be sure if we just find a single '<', and need to + # find the matching '>'. + (_, end_line, end_pos) = CloseExpression(clean_lines, linenum, pos - 1) + if end_pos < 0: + # Not sure if template argument list or syntax error in file + return False + linenum = end_line + pos = end_pos + return False + + def UpdatePreprocessor(self, line): + """Update preprocessor stack. + + We need to handle preprocessors due to classes like this: + #ifdef SWIG + struct ResultDetailsPageElementExtensionPoint { + #else + struct ResultDetailsPageElementExtensionPoint : public Extension { + #endif + + We make the following assumptions (good enough for most files): + - Preprocessor condition evaluates to true from #if up to first + #else/#elif/#endif. + + - Preprocessor condition evaluates to false from #else/#elif up + to #endif. We still perform lint checks on these lines, but + these do not affect nesting stack. + + Args: + line: current line to check. + """ + if Match(r'^\s*#\s*(if|ifdef|ifndef)\b', line): + # Beginning of #if block, save the nesting stack here. The saved + # stack will allow us to restore the parsing state in the #else case. + self.pp_stack.append(_PreprocessorInfo(copy.deepcopy(self.stack))) + elif Match(r'^\s*#\s*(else|elif)\b', line): + # Beginning of #else block + if self.pp_stack: + if not self.pp_stack[-1].seen_else: + # This is the first #else or #elif block. Remember the + # whole nesting stack up to this point. This is what we + # keep after the #endif. + self.pp_stack[-1].seen_else = True + self.pp_stack[-1].stack_before_else = copy.deepcopy(self.stack) + + # Restore the stack to how it was before the #if + self.stack = copy.deepcopy(self.pp_stack[-1].stack_before_if) + else: + # TODO(unknown): unexpected #else, issue warning? + pass + elif Match(r'^\s*#\s*endif\b', line): + # End of #if or #else blocks. + if self.pp_stack: + # If we saw an #else, we will need to restore the nesting + # stack to its former state before the #else, otherwise we + # will just continue from where we left off. + if self.pp_stack[-1].seen_else: + # Here we can just use a shallow copy since we are the last + # reference to it. + self.stack = self.pp_stack[-1].stack_before_else + # Drop the corresponding #if + self.pp_stack.pop() + else: + # TODO(unknown): unexpected #endif, issue warning? + pass + + # TODO(unknown): Update() is too long, but we will refactor later. + def Update(self, filename, clean_lines, linenum, error): + """Update nesting state with current line. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + line = clean_lines.elided[linenum] + + # Remember top of the previous nesting stack. + # + # The stack is always pushed/popped and not modified in place, so + # we can just do a shallow copy instead of copy.deepcopy. Using + # deepcopy would slow down cpplint by ~28%. + if self.stack: + self.previous_stack_top = self.stack[-1] + else: + self.previous_stack_top = None + + # Update pp_stack + self.UpdatePreprocessor(line) + + # Count parentheses. This is to avoid adding struct arguments to + # the nesting stack. + if self.stack: + inner_block = self.stack[-1] + depth_change = line.count('(') - line.count(')') + inner_block.open_parentheses += depth_change + + # Also check if we are starting or ending an inline assembly block. + if inner_block.inline_asm in (_NO_ASM, _END_ASM): + if (depth_change != 0 and + inner_block.open_parentheses == 1 and + _MATCH_ASM.match(line)): + # Enter assembly block + inner_block.inline_asm = _INSIDE_ASM + else: + # Not entering assembly block. If previous line was _END_ASM, + # we will now shift to _NO_ASM state. + inner_block.inline_asm = _NO_ASM + elif (inner_block.inline_asm == _INSIDE_ASM and + inner_block.open_parentheses == 0): + # Exit assembly block + inner_block.inline_asm = _END_ASM + + # Consume namespace declaration at the beginning of the line. Do + # this in a loop so that we catch same line declarations like this: + # namespace proto2 { namespace bridge { class MessageSet; } } + while True: + # Match start of namespace. The "\b\s*" below catches namespace + # declarations even if it weren't followed by a whitespace, this + # is so that we don't confuse our namespace checker. The + # missing spaces will be flagged by CheckSpacing. + namespace_decl_match = Match(r'^\s*namespace\b\s*([:\w]+)?(.*)$', line) + if not namespace_decl_match: + break + + new_namespace = _NamespaceInfo(namespace_decl_match.group(1), linenum) + self.stack.append(new_namespace) + + line = namespace_decl_match.group(2) + if line.find('{') != -1: + new_namespace.seen_open_brace = True + line = line[line.find('{') + 1:] + + # Look for a class declaration in whatever is left of the line + # after parsing namespaces. The regexp accounts for decorated classes + # such as in: + # class LOCKABLE API Object { + # }; + class_decl_match = Match( + r'^(\s*(?:template\s*<[\w\s<>,:]*>\s*)?' + r'(class|struct)\s+(?:[A-Z_]+\s+)*(\w+(?:::\w+)*))' + r'(.*)$', line) + if (class_decl_match and + (not self.stack or self.stack[-1].open_parentheses == 0)): + # We do not want to accept classes that are actually template arguments: + # template , + # template class Ignore3> + # void Function() {}; + # + # To avoid template argument cases, we scan forward and look for + # an unmatched '>'. If we see one, assume we are inside a + # template argument list. + end_declaration = len(class_decl_match.group(1)) + if not self.InTemplateArgumentList(clean_lines, linenum, end_declaration): + self.stack.append(_ClassInfo( + class_decl_match.group(3), class_decl_match.group(2), + clean_lines, linenum)) + line = class_decl_match.group(4) + + # If we have not yet seen the opening brace for the innermost block, + # run checks here. + if not self.SeenOpenBrace(): + self.stack[-1].CheckBegin(filename, clean_lines, linenum, error) + + # Update access control if we are inside a class/struct + if self.stack and isinstance(self.stack[-1], _ClassInfo): + classinfo = self.stack[-1] + access_match = Match( + r'^(.*)\b(public|private|protected|signals)(\s+(?:slots\s*)?)?' + r':(?:[^:]|$)', + line) + if access_match: + classinfo.access = access_match.group(2) + + # Check that access keywords are indented +1 space. Skip this + # check if the keywords are not preceded by whitespaces. + indent = access_match.group(1) + if (len(indent) != classinfo.class_indent + 1 and + Match(r'^\s*$', indent)): + if classinfo.is_struct: + parent = 'struct ' + classinfo.name + else: + parent = 'class ' + classinfo.name + slots = '' + if access_match.group(3): + slots = access_match.group(3) + error(filename, linenum, 'whitespace/indent', 3, + '%s%s: should be indented +1 space inside %s' % ( + access_match.group(2), slots, parent)) + + # Consume braces or semicolons from what's left of the line + while True: + # Match first brace, semicolon, or closed parenthesis. + matched = Match(r'^[^{;)}]*([{;)}])(.*)$', line) + if not matched: + break + + token = matched.group(1) + if token == '{': + # If namespace or class hasn't seen a opening brace yet, mark + # namespace/class head as complete. Push a new block onto the + # stack otherwise. + if not self.SeenOpenBrace(): + self.stack[-1].seen_open_brace = True + elif Match(r'^extern\s*"[^"]*"\s*\{', line): + self.stack.append(_ExternCInfo()) + else: + self.stack.append(_BlockInfo(True)) + if _MATCH_ASM.match(line): + self.stack[-1].inline_asm = _BLOCK_ASM + + elif token == ';' or token == ')': + # If we haven't seen an opening brace yet, but we already saw + # a semicolon, this is probably a forward declaration. Pop + # the stack for these. + # + # Similarly, if we haven't seen an opening brace yet, but we + # already saw a closing parenthesis, then these are probably + # function arguments with extra "class" or "struct" keywords. + # Also pop these stack for these. + if not self.SeenOpenBrace(): + self.stack.pop() + else: # token == '}' + # Perform end of block checks and pop the stack. + if self.stack: + self.stack[-1].CheckEnd(filename, clean_lines, linenum, error) + self.stack.pop() + line = matched.group(2) + + def InnermostClass(self): + """Get class info on the top of the stack. + + Returns: + A _ClassInfo object if we are inside a class, or None otherwise. + """ + for i in range(len(self.stack), 0, -1): + classinfo = self.stack[i - 1] + if isinstance(classinfo, _ClassInfo): + return classinfo + return None + + def CheckCompletedBlocks(self, filename, error): + """Checks that all classes and namespaces have been completely parsed. + + Call this when all lines in a file have been processed. + Args: + filename: The name of the current file. + error: The function to call with any errors found. + """ + # Note: This test can result in false positives if #ifdef constructs + # get in the way of brace matching. See the testBuildClass test in + # cpplint_unittest.py for an example of this. + for obj in self.stack: + if isinstance(obj, _ClassInfo): + error(filename, obj.starting_linenum, 'build/class', 5, + 'Failed to find complete declaration of class %s' % + obj.name) + elif isinstance(obj, _NamespaceInfo): + error(filename, obj.starting_linenum, 'build/namespaces', 5, + 'Failed to find complete declaration of namespace %s' % + obj.name) + + +def CheckForNonStandardConstructs(filename, clean_lines, linenum, + nesting_state, error): + r"""Logs an error if we see certain non-ANSI constructs ignored by gcc-2. + + Complain about several constructs which gcc-2 accepts, but which are + not standard C++. Warning about these in lint is one way to ease the + transition to new compilers. + - put storage class first (e.g. "static const" instead of "const static"). + - "%lld" instead of %qd" in printf-type functions. + - "%1$d" is non-standard in printf-type functions. + - "\%" is an undefined character escape sequence. + - text after #endif is not allowed. + - invalid inner-style forward declaration. + - >? and ?= and )\?=?\s*(\w+|[+-]?\d+)(\.\d*)?', + line): + error(filename, linenum, 'build/deprecated', 3, + '>? and ))?' + # r'\s*const\s*' + type_name + '\s*&\s*\w+\s*;' + error(filename, linenum, 'runtime/member_string_references', 2, + 'const string& members are dangerous. It is much better to use ' + 'alternatives, such as pointers or simple constants.') + + # Everything else in this function operates on class declarations. + # Return early if the top of the nesting stack is not a class, or if + # the class head is not completed yet. + classinfo = nesting_state.InnermostClass() + if not classinfo or not classinfo.seen_open_brace: + return + + # The class may have been declared with namespace or classname qualifiers. + # The constructor and destructor will not have those qualifiers. + base_classname = classinfo.name.split('::')[-1] + + # Look for single-argument constructors that aren't marked explicit. + # Technically a valid construct, but against style. + args = Match(r'\s+(?:inline\s+)?%s\s*\(([^,()]+)\)' + % re.escape(base_classname), + line) + if (args and + args.group(1) != 'void' and + not Search(r'\bstd::initializer_list\b', args.group(1)) and + not Match(r'(const\s+)?%s(\s+const)?\s*(?:<\w+>\s*)?&' + % re.escape(base_classname), args.group(1).strip())): + error(filename, linenum, 'runtime/explicit', 5, + 'Single-argument constructors should be marked explicit.') + + +def CheckSpacingForFunctionCall(filename, clean_lines, linenum, error): + """Checks for the correctness of various spacing around function calls. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + line = clean_lines.elided[linenum] + + # Since function calls often occur inside if/for/while/switch + # expressions - which have their own, more liberal conventions - we + # first see if we should be looking inside such an expression for a + # function call, to which we can apply more strict standards. + fncall = line # if there's no control flow construct, look at whole line + for pattern in (r'\bif\s*\((.*)\)\s*{', + r'\bfor\s*\((.*)\)\s*{', + r'\bwhile\s*\((.*)\)\s*[{;]', + r'\bswitch\s*\((.*)\)\s*{'): + match = Search(pattern, line) + if match: + fncall = match.group(1) # look inside the parens for function calls + break + + # Except in if/for/while/switch, there should never be space + # immediately inside parens (eg "f( 3, 4 )"). We make an exception + # for nested parens ( (a+b) + c ). Likewise, there should never be + # a space before a ( when it's a function argument. I assume it's a + # function argument when the char before the whitespace is legal in + # a function name (alnum + _) and we're not starting a macro. Also ignore + # pointers and references to arrays and functions coz they're too tricky: + # we use a very simple way to recognize these: + # " (something)(maybe-something)" or + # " (something)(maybe-something," or + # " (something)[something]" + # Note that we assume the contents of [] to be short enough that + # they'll never need to wrap. + if ( # Ignore control structures. + not Search(r'\b(if|for|while|switch|return|new|delete|catch|sizeof)\b', + fncall) and + # Ignore pointers/references to functions. + not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and + # Ignore pointers/references to arrays. + not Search(r' \([^)]+\)\[[^\]]+\]', fncall)): + if Search(r'\w\s*\(\s(?!\s*\\$)', fncall): # a ( used for a fn call + error(filename, linenum, 'whitespace/parens', 4, + 'Extra space after ( in function call') + elif Search(r'\(\s+(?!(\s*\\)|\()', fncall): + error(filename, linenum, 'whitespace/parens', 2, + 'Extra space after (') + if (Search(r'\w\s+\(', fncall) and + not Search(r'#\s*define|typedef|using\s+\w+\s*=', fncall) and + not Search(r'\w\s+\((\w+::)*\*\w+\)\(', fncall)): + # TODO(unknown): Space after an operator function seem to be a common + # error, silence those for now by restricting them to highest verbosity. + if Search(r'\boperator_*\b', line): + error(filename, linenum, 'whitespace/parens', 0, + 'Extra space before ( in function call') + else: + error(filename, linenum, 'whitespace/parens', 4, + 'Extra space before ( in function call') + # If the ) is followed only by a newline or a { + newline, assume it's + # part of a control statement (if/while/etc), and don't complain + if Search(r'[^)]\s+\)\s*[^{\s]', fncall): + # If the closing parenthesis is preceded by only whitespaces, + # try to give a more descriptive error message. + if Search(r'^\s+\)', fncall): + error(filename, linenum, 'whitespace/parens', 2, + 'Closing ) should be moved to the previous line') + else: + error(filename, linenum, 'whitespace/parens', 2, + 'Extra space before )') + + +def IsBlankLine(line): + """Returns true if the given line is blank. + + We consider a line to be blank if the line is empty or consists of + only white spaces. + + Args: + line: A line of a string. + + Returns: + True, if the given line is blank. + """ + return not line or line.isspace() + + +def CheckForFunctionLengths(filename, clean_lines, linenum, + function_state, error): + """Reports for long function bodies. + + For an overview why this is done, see: + http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Write_Short_Functions + + Uses a simplistic algorithm assuming other style guidelines + (especially spacing) are followed. + Only checks unindented functions, so class members are unchecked. + Trivial bodies are unchecked, so constructors with huge initializer lists + may be missed. + Blank/comment lines are not counted so as to avoid encouraging the removal + of vertical space and comments just to get through a lint check. + NOLINT *on the last line of a function* disables this check. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + function_state: Current function name and lines in body so far. + error: The function to call with any errors found. + """ + lines = clean_lines.lines + line = lines[linenum] + joined_line = '' + + starting_func = False + regexp = r'(\w(\w|::|\*|\&|\s)*)\(' # decls * & space::name( ... + match_result = Match(regexp, line) + if match_result: + # If the name is all caps and underscores, figure it's a macro and + # ignore it, unless it's TEST or TEST_F. + function_name = match_result.group(1).split()[-1] + if function_name == 'TEST' or function_name == 'TEST_F' or ( + not Match(r'[A-Z_]+$', function_name)): + starting_func = True + + if starting_func: + body_found = False + for start_linenum in xrange(linenum, clean_lines.NumLines()): + start_line = lines[start_linenum] + joined_line += ' ' + start_line.lstrip() + if Search(r'(;|})', start_line): # Declarations and trivial functions + body_found = True + break # ... ignore + elif Search(r'{', start_line): + body_found = True + function = Search(r'((\w|:)*)\(', line).group(1) + if Match(r'TEST', function): # Handle TEST... macros + parameter_regexp = Search(r'(\(.*\))', joined_line) + if parameter_regexp: # Ignore bad syntax + function += parameter_regexp.group(1) + else: + function += '()' + function_state.Begin(function) + break + if not body_found: + # No body for the function (or evidence of a non-function) was found. + error(filename, linenum, 'readability/fn_size', 5, + 'Lint failed to find start of function body.') + elif Match(r'^\}\s*$', line): # function end + function_state.Check(error, filename, linenum) + function_state.End() + elif not Match(r'^\s*$', line): + function_state.Count() # Count non-blank/non-comment lines. + + +_RE_PATTERN_TODO = re.compile(r'^//(\s*)TODO(\(.+?\))?:?(\s|$)?') + + +def CheckComment(line, filename, linenum, next_line_start, error): + """Checks for common mistakes in comments. + + Args: + line: The line in question. + filename: The name of the current file. + linenum: The number of the line to check. + next_line_start: The first non-whitespace column of the next line. + error: The function to call with any errors found. + """ + commentpos = line.find('//') + if commentpos != -1: + # Check if the // may be in quotes. If so, ignore it + # Comparisons made explicit for clarity -- pylint: disable=g-explicit-bool-comparison + if (line.count('"', 0, commentpos) - + line.count('\\"', 0, commentpos)) % 2 == 0: # not in quotes + # Allow one space for new scopes, two spaces otherwise: + if (not (Match(r'^.*{ *//', line) and next_line_start == commentpos) and + ((commentpos >= 1 and + line[commentpos-1] not in string.whitespace) or + (commentpos >= 2 and + line[commentpos-2] not in string.whitespace))): + error(filename, linenum, 'whitespace/comments', 2, + 'At least two spaces is best between code and comments') + + # Checks for common mistakes in TODO comments. + comment = line[commentpos:] + match = _RE_PATTERN_TODO.match(comment) + if match: + # One whitespace is correct; zero whitespace is handled elsewhere. + leading_whitespace = match.group(1) + if len(leading_whitespace) > 1: + error(filename, linenum, 'whitespace/todo', 2, + 'Too many spaces before TODO') + + username = match.group(2) + if not username: + error(filename, linenum, 'readability/todo', 2, + 'Missing username in TODO; it should look like ' + '"// TODO(my_username): Stuff."') + + middle_whitespace = match.group(3) + # Comparisons made explicit for correctness -- pylint: disable=g-explicit-bool-comparison + if middle_whitespace != ' ' and middle_whitespace != '': + error(filename, linenum, 'whitespace/todo', 2, + 'TODO(my_username) should be followed by a space') + + # If the comment contains an alphanumeric character, there + # should be a space somewhere between it and the //. + if Match(r'//[^ ]*\w', comment): + error(filename, linenum, 'whitespace/comments', 4, + 'Should have a space between // and comment') + +def CheckAccess(filename, clean_lines, linenum, nesting_state, error): + """Checks for improper use of DISALLOW* macros. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + nesting_state: A NestingState instance which maintains information about + the current stack of nested blocks being parsed. + error: The function to call with any errors found. + """ + line = clean_lines.elided[linenum] # get rid of comments and strings + + matched = Match((r'\s*(DISALLOW_COPY_AND_ASSIGN|' + r'DISALLOW_EVIL_CONSTRUCTORS|' + r'DISALLOW_IMPLICIT_CONSTRUCTORS)'), line) + if not matched: + return + if nesting_state.stack and isinstance(nesting_state.stack[-1], _ClassInfo): + if nesting_state.stack[-1].access != 'private': + error(filename, linenum, 'readability/constructors', 3, + '%s must be in the private: section' % matched.group(1)) + + else: + # Found DISALLOW* macro outside a class declaration, or perhaps it + # was used inside a function when it should have been part of the + # class declaration. We could issue a warning here, but it + # probably resulted in a compiler error already. + pass + + +def CheckSpacing(filename, clean_lines, linenum, nesting_state, error): + """Checks for the correctness of various spacing issues in the code. + + Things we check for: spaces around operators, spaces after + if/for/while/switch, no spaces around parens in function calls, two + spaces between code and comment, don't start a block with a blank + line, don't end a function with a blank line, don't add a blank line + after public/protected/private, don't have too many blank lines in a row. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + nesting_state: A NestingState instance which maintains information about + the current stack of nested blocks being parsed. + error: The function to call with any errors found. + """ + + # Don't use "elided" lines here, otherwise we can't check commented lines. + # Don't want to use "raw" either, because we don't want to check inside C++11 + # raw strings, + raw = clean_lines.lines_without_raw_strings + line = raw[linenum] + + # Before nixing comments, check if the line is blank for no good + # reason. This includes the first line after a block is opened, and + # blank lines at the end of a function (ie, right before a line like '}' + # + # Skip all the blank line checks if we are immediately inside a + # namespace body. In other words, don't issue blank line warnings + # for this block: + # namespace { + # + # } + # + # A warning about missing end of namespace comments will be issued instead. + # + # Also skip blank line checks for 'extern "C"' blocks, which are formatted + # like namespaces. + if (IsBlankLine(line) and + not nesting_state.InNamespaceBody() and + not nesting_state.InExternC()): + elided = clean_lines.elided + prev_line = elided[linenum - 1] + prevbrace = prev_line.rfind('{') + # TODO(unknown): Don't complain if line before blank line, and line after, + # both start with alnums and are indented the same amount. + # This ignores whitespace at the start of a namespace block + # because those are not usually indented. + if prevbrace != -1 and prev_line[prevbrace:].find('}') == -1: + # OK, we have a blank line at the start of a code block. Before we + # complain, we check if it is an exception to the rule: The previous + # non-empty line has the parameters of a function header that are indented + # 4 spaces (because they did not fit in a 80 column line when placed on + # the same line as the function name). We also check for the case where + # the previous line is indented 6 spaces, which may happen when the + # initializers of a constructor do not fit into a 80 column line. + exception = False + if Match(r' {6}\w', prev_line): # Initializer list? + # We are looking for the opening column of initializer list, which + # should be indented 4 spaces to cause 6 space indentation afterwards. + search_position = linenum-2 + while (search_position >= 0 + and Match(r' {6}\w', elided[search_position])): + search_position -= 1 + exception = (search_position >= 0 + and elided[search_position][:5] == ' :') + else: + # Search for the function arguments or an initializer list. We use a + # simple heuristic here: If the line is indented 4 spaces; and we have a + # closing paren, without the opening paren, followed by an opening brace + # or colon (for initializer lists) we assume that it is the last line of + # a function header. If we have a colon indented 4 spaces, it is an + # initializer list. + exception = (Match(r' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)', + prev_line) + or Match(r' {4}:', prev_line)) + + if not exception: + error(filename, linenum, 'whitespace/blank_line', 2, + 'Redundant blank line at the start of a code block ' + 'should be deleted.') + # Ignore blank lines at the end of a block in a long if-else + # chain, like this: + # if (condition1) { + # // Something followed by a blank line + # + # } else if (condition2) { + # // Something else + # } + if linenum + 1 < clean_lines.NumLines(): + next_line = raw[linenum + 1] + if (next_line + and Match(r'\s*}', next_line) + and next_line.find('} else ') == -1): + error(filename, linenum, 'whitespace/blank_line', 3, + 'Redundant blank line at the end of a code block ' + 'should be deleted.') + + matched = Match(r'\s*(public|protected|private):', prev_line) + if matched: + error(filename, linenum, 'whitespace/blank_line', 3, + 'Do not leave a blank line after "%s:"' % matched.group(1)) + + # Next, check comments + next_line_start = 0 + if linenum + 1 < clean_lines.NumLines(): + next_line = raw[linenum + 1] + next_line_start = len(next_line) - len(next_line.lstrip()) + CheckComment(line, filename, linenum, next_line_start, error) + + # get rid of comments and strings + line = clean_lines.elided[linenum] + + # You shouldn't have spaces before your brackets, except maybe after + # 'delete []' or 'return []() {};' + if Search(r'\w\s+\[', line) and not Search(r'(?:delete|return)\s+\[', line): + error(filename, linenum, 'whitespace/braces', 5, + 'Extra space before [') + + # In range-based for, we wanted spaces before and after the colon, but + # not around "::" tokens that might appear. + if (Search(r'for *\(.*[^:]:[^: ]', line) or + Search(r'for *\(.*[^: ]:[^:]', line)): + error(filename, linenum, 'whitespace/forcolon', 2, + 'Missing space around colon in range-based for loop') + + +def CheckOperatorSpacing(filename, clean_lines, linenum, error): + """Checks for horizontal spacing around operators. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + line = clean_lines.elided[linenum] + + # Don't try to do spacing checks for operator methods. Do this by + # replacing the troublesome characters with something else, + # preserving column position for all other characters. + # + # The replacement is done repeatedly to avoid false positives from + # operators that call operators. + while True: + match = Match(r'^(.*\boperator\b)(\S+)(\s*\(.*)$', line) + if match: + line = match.group(1) + ('_' * len(match.group(2))) + match.group(3) + else: + break + + # We allow no-spaces around = within an if: "if ( (a=Foo()) == 0 )". + # Otherwise not. Note we only check for non-spaces on *both* sides; + # sometimes people put non-spaces on one side when aligning ='s among + # many lines (not that this is behavior that I approve of...) + if Search(r'[\w.]=[\w.]', line) and not Search(r'\b(if|while) ', line): + error(filename, linenum, 'whitespace/operators', 4, + 'Missing spaces around =') + + # It's ok not to have spaces around binary operators like + - * /, but if + # there's too little whitespace, we get concerned. It's hard to tell, + # though, so we punt on this one for now. TODO. + + # You should always have whitespace around binary operators. + # + # Check <= and >= first to avoid false positives with < and >, then + # check non-include lines for spacing around < and >. + # + # If the operator is followed by a comma, assume it's be used in a + # macro context and don't do any checks. This avoids false + # positives. + # + # Note that && is not included here. Those are checked separately + # in CheckRValueReference + match = Search(r'[^<>=!\s](==|!=|<=|>=|\|\|)[^<>=!\s,;\)]', line) + if match: + error(filename, linenum, 'whitespace/operators', 3, + 'Missing spaces around %s' % match.group(1)) + elif not Match(r'#.*include', line): + # Look for < that is not surrounded by spaces. This is only + # triggered if both sides are missing spaces, even though + # technically should should flag if at least one side is missing a + # space. This is done to avoid some false positives with shifts. + match = Match(r'^(.*[^\s<])<[^\s=<,]', line) + if match: + (_, _, end_pos) = CloseExpression( + clean_lines, linenum, len(match.group(1))) + if end_pos <= -1: + error(filename, linenum, 'whitespace/operators', 3, + 'Missing spaces around <') + + # Look for > that is not surrounded by spaces. Similar to the + # above, we only trigger if both sides are missing spaces to avoid + # false positives with shifts. + match = Match(r'^(.*[^-\s>])>[^\s=>,]', line) + if match: + (_, _, start_pos) = ReverseCloseExpression( + clean_lines, linenum, len(match.group(1))) + if start_pos <= -1: + error(filename, linenum, 'whitespace/operators', 3, + 'Missing spaces around >') + + # We allow no-spaces around << when used like this: 10<<20, but + # not otherwise (particularly, not when used as streams) + # We also allow operators following an opening parenthesis, since + # those tend to be macros that deal with operators. + match = Search(r'(operator|\S)(?:L|UL|ULL|l|ul|ull)?<<([^\s,=])', line) + if (match and match.group(1) != '(' and + not (match.group(1).isdigit() and match.group(2).isdigit()) and + not (match.group(1) == 'operator' and match.group(2) == ';')): + error(filename, linenum, 'whitespace/operators', 3, + 'Missing spaces around <<') + + # We allow no-spaces around >> for almost anything. This is because + # C++11 allows ">>" to close nested templates, which accounts for + # most cases when ">>" is not followed by a space. + # + # We still warn on ">>" followed by alpha character, because that is + # likely due to ">>" being used for right shifts, e.g.: + # value >> alpha + # + # When ">>" is used to close templates, the alphanumeric letter that + # follows would be part of an identifier, and there should still be + # a space separating the template type and the identifier. + # type> alpha + match = Search(r'>>[a-zA-Z_]', line) + if match: + error(filename, linenum, 'whitespace/operators', 3, + 'Missing spaces around >>') + + # There shouldn't be space around unary operators + match = Search(r'(!\s|~\s|[\s]--[\s;]|[\s]\+\+[\s;])', line) + if match: + error(filename, linenum, 'whitespace/operators', 4, + 'Extra space for operator %s' % match.group(1)) + + +def CheckParenthesisSpacing(filename, clean_lines, linenum, error): + """Checks for horizontal spacing around parentheses. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + line = clean_lines.elided[linenum] + + # No spaces after an if, while, switch, or for + match = Search(r' (if\(|for\(|while\(|switch\()', line) + if match: + error(filename, linenum, 'whitespace/parens', 5, + 'Missing space before ( in %s' % match.group(1)) + + # For if/for/while/switch, the left and right parens should be + # consistent about how many spaces are inside the parens, and + # there should either be zero or one spaces inside the parens. + # We don't want: "if ( foo)" or "if ( foo )". + # Exception: "for ( ; foo; bar)" and "for (foo; bar; )" are allowed. + match = Search(r'\b(if|for|while|switch)\s*' + r'\(([ ]*)(.).*[^ ]+([ ]*)\)\s*{\s*$', + line) + if match: + if len(match.group(2)) != len(match.group(4)): + if not (match.group(3) == ';' and + len(match.group(2)) == 1 + len(match.group(4)) or + not match.group(2) and Search(r'\bfor\s*\(.*; \)', line)): + error(filename, linenum, 'whitespace/parens', 5, + 'Mismatching spaces inside () in %s' % match.group(1)) + if len(match.group(2)) not in [0, 1]: + error(filename, linenum, 'whitespace/parens', 5, + 'Should have zero or one spaces inside ( and ) in %s' % + match.group(1)) + + +def CheckCommaSpacing(filename, clean_lines, linenum, error): + """Checks for horizontal spacing near commas and semicolons. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + raw = clean_lines.lines_without_raw_strings + line = clean_lines.elided[linenum] + + # You should always have a space after a comma (either as fn arg or operator) + # + # This does not apply when the non-space character following the + # comma is another comma, since the only time when that happens is + # for empty macro arguments. + # + # We run this check in two passes: first pass on elided lines to + # verify that lines contain missing whitespaces, second pass on raw + # lines to confirm that those missing whitespaces are not due to + # elided comments. + if Search(r',[^,\s]', line) and Search(r',[^,\s]', raw[linenum]): + error(filename, linenum, 'whitespace/comma', 3, + 'Missing space after ,') + + # You should always have a space after a semicolon + # except for few corner cases + # TODO(unknown): clarify if 'if (1) { return 1;}' is requires one more + # space after ; + if Search(r';[^\s};\\)/]', line): + error(filename, linenum, 'whitespace/semicolon', 3, + 'Missing space after ;') + + +def CheckBracesSpacing(filename, clean_lines, linenum, error): + """Checks for horizontal spacing near commas. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + line = clean_lines.elided[linenum] + + # Except after an opening paren, or after another opening brace (in case of + # an initializer list, for instance), you should have spaces before your + # braces. And since you should never have braces at the beginning of a line, + # this is an easy test. + match = Match(r'^(.*[^ ({]){', line) + if match: + # Try a bit harder to check for brace initialization. This + # happens in one of the following forms: + # Constructor() : initializer_list_{} { ... } + # Constructor{}.MemberFunction() + # Type variable{}; + # FunctionCall(type{}, ...); + # LastArgument(..., type{}); + # LOG(INFO) << type{} << " ..."; + # map_of_type[{...}] = ...; + # ternary = expr ? new type{} : nullptr; + # OuterTemplate{}> + # + # We check for the character following the closing brace, and + # silence the warning if it's one of those listed above, i.e. + # "{.;,)<>]:". + # + # To account for nested initializer list, we allow any number of + # closing braces up to "{;,)<". We can't simply silence the + # warning on first sight of closing brace, because that would + # cause false negatives for things that are not initializer lists. + # Silence this: But not this: + # Outer{ if (...) { + # Inner{...} if (...){ // Missing space before { + # }; } + # + # There is a false negative with this approach if people inserted + # spurious semicolons, e.g. "if (cond){};", but we will catch the + # spurious semicolon with a separate check. + (endline, endlinenum, endpos) = CloseExpression( + clean_lines, linenum, len(match.group(1))) + trailing_text = '' + if endpos > -1: + trailing_text = endline[endpos:] + for offset in xrange(endlinenum + 1, + min(endlinenum + 3, clean_lines.NumLines() - 1)): + trailing_text += clean_lines.elided[offset] + if not Match(r'^[\s}]*[{.;,)<>\]:]', trailing_text): + error(filename, linenum, 'whitespace/braces', 5, + 'Missing space before {') + + # Make sure '} else {' has spaces. + if Search(r'}else', line): + error(filename, linenum, 'whitespace/braces', 5, + 'Missing space before else') + + # You shouldn't have a space before a semicolon at the end of the line. + # There's a special case for "for" since the style guide allows space before + # the semicolon there. + if Search(r':\s*;\s*$', line): + error(filename, linenum, 'whitespace/semicolon', 5, + 'Semicolon defining empty statement. Use {} instead.') + elif Search(r'^\s*;\s*$', line): + error(filename, linenum, 'whitespace/semicolon', 5, + 'Line contains only semicolon. If this should be an empty statement, ' + 'use {} instead.') + elif (Search(r'\s+;\s*$', line) and + not Search(r'\bfor\b', line)): + error(filename, linenum, 'whitespace/semicolon', 5, + 'Extra space before last semicolon. If this should be an empty ' + 'statement, use {} instead.') + + +def IsDecltype(clean_lines, linenum, column): + """Check if the token ending on (linenum, column) is decltype(). + + Args: + clean_lines: A CleansedLines instance containing the file. + linenum: the number of the line to check. + column: end column of the token to check. + Returns: + True if this token is decltype() expression, False otherwise. + """ + (text, _, start_col) = ReverseCloseExpression(clean_lines, linenum, column) + if start_col < 0: + return False + if Search(r'\bdecltype\s*$', text[0:start_col]): + return True + return False + + +def IsTemplateParameterList(clean_lines, linenum, column): + """Check if the token ending on (linenum, column) is the end of template<>. + + Args: + clean_lines: A CleansedLines instance containing the file. + linenum: the number of the line to check. + column: end column of the token to check. + Returns: + True if this token is end of a template parameter list, False otherwise. + """ + (_, startline, startpos) = ReverseCloseExpression( + clean_lines, linenum, column) + if (startpos > -1 and + Search(r'\btemplate\s*$', clean_lines.elided[startline][0:startpos])): + return True + return False + + +def IsRValueType(clean_lines, nesting_state, linenum, column): + """Check if the token ending on (linenum, column) is a type. + + Assumes that text to the right of the column is "&&" or a function + name. + + Args: + clean_lines: A CleansedLines instance containing the file. + nesting_state: A NestingState instance which maintains information about + the current stack of nested blocks being parsed. + linenum: the number of the line to check. + column: end column of the token to check. + Returns: + True if this token is a type, False if we are not sure. + """ + prefix = clean_lines.elided[linenum][0:column] + + # Get one word to the left. If we failed to do so, this is most + # likely not a type, since it's unlikely that the type name and "&&" + # would be split across multiple lines. + match = Match(r'^(.*)(\b\w+|[>*)&])\s*$', prefix) + if not match: + return False + + # Check text following the token. If it's "&&>" or "&&," or "&&...", it's + # most likely a rvalue reference used inside a template. + suffix = clean_lines.elided[linenum][column:] + if Match(r'&&\s*(?:[>,]|\.\.\.)', suffix): + return True + + # Check for simple type and end of templates: + # int&& variable + # vector&& variable + # + # Because this function is called recursively, we also need to + # recognize pointer and reference types: + # int* Function() + # int& Function() + if match.group(2) in ['char', 'char16_t', 'char32_t', 'wchar_t', 'bool', + 'short', 'int', 'long', 'signed', 'unsigned', + 'float', 'double', 'void', 'auto', '>', '*', '&']: + return True + + # If we see a close parenthesis, look for decltype on the other side. + # decltype would unambiguously identify a type, anything else is + # probably a parenthesized expression and not a type. + if match.group(2) == ')': + return IsDecltype( + clean_lines, linenum, len(match.group(1)) + len(match.group(2)) - 1) + + # Check for casts and cv-qualifiers. + # match.group(1) remainder + # -------------- --------- + # const_cast< type&& + # const type&& + # type const&& + if Search(r'\b(?:const_cast\s*<|static_cast\s*<|dynamic_cast\s*<|' + r'reinterpret_cast\s*<|\w+\s)\s*$', + match.group(1)): + return True + + # Look for a preceding symbol that might help differentiate the context. + # These are the cases that would be ambiguous: + # match.group(1) remainder + # -------------- --------- + # Call ( expression && + # Declaration ( type&& + # sizeof ( type&& + # if ( expression && + # while ( expression && + # for ( type&& + # for( ; expression && + # statement ; type&& + # block { type&& + # constructor { expression && + start = linenum + line = match.group(1) + match_symbol = None + while start >= 0: + # We want to skip over identifiers and commas to get to a symbol. + # Commas are skipped so that we can find the opening parenthesis + # for function parameter lists. + match_symbol = Match(r'^(.*)([^\w\s,])[\w\s,]*$', line) + if match_symbol: + break + start -= 1 + line = clean_lines.elided[start] + + if not match_symbol: + # Probably the first statement in the file is an rvalue reference + return True + + if match_symbol.group(2) == '}': + # Found closing brace, probably an indicate of this: + # block{} type&& + return True + + if match_symbol.group(2) == ';': + # Found semicolon, probably one of these: + # for(; expression && + # statement; type&& + + # Look for the previous 'for(' in the previous lines. + before_text = match_symbol.group(1) + for i in xrange(start - 1, max(start - 6, 0), -1): + before_text = clean_lines.elided[i] + before_text + if Search(r'for\s*\([^{};]*$', before_text): + # This is the condition inside a for-loop + return False + + # Did not find a for-init-statement before this semicolon, so this + # is probably a new statement and not a condition. + return True + + if match_symbol.group(2) == '{': + # Found opening brace, probably one of these: + # block{ type&& = ... ; } + # constructor{ expression && expression } + + # Look for a closing brace or a semicolon. If we see a semicolon + # first, this is probably a rvalue reference. + line = clean_lines.elided[start][0:len(match_symbol.group(1)) + 1] + end = start + depth = 1 + while True: + for ch in line: + if ch == ';': + return True + elif ch == '{': + depth += 1 + elif ch == '}': + depth -= 1 + if depth == 0: + return False + end += 1 + if end >= clean_lines.NumLines(): + break + line = clean_lines.elided[end] + # Incomplete program? + return False + + if match_symbol.group(2) == '(': + # Opening parenthesis. Need to check what's to the left of the + # parenthesis. Look back one extra line for additional context. + before_text = match_symbol.group(1) + if linenum > 1: + before_text = clean_lines.elided[linenum - 1] + before_text + before_text = match_symbol.group(1) + + # Patterns that are likely to be types: + # [](type&& + # for (type&& + # sizeof(type&& + # operator=(type&& + # + if Search(r'(?:\]|\bfor|\bsizeof|\boperator\s*\S+\s*)\s*$', before_text): + return True + + # Patterns that are likely to be expressions: + # if (expression && + # while (expression && + # : initializer(expression && + # , initializer(expression && + # ( FunctionCall(expression && + # + FunctionCall(expression && + # + (expression && + # + # The last '+' represents operators such as '+' and '-'. + if Search(r'(?:\bif|\bwhile|[-+=%^(]*>)?\s*$', + match_symbol.group(1)) + if match_func: + # Check for constructors, which don't have return types. + if Search(r'\bexplicit$', match_func.group(1)): + return True + implicit_constructor = Match(r'\s*(\w+)\((?:const\s+)?(\w+)', prefix) + if (implicit_constructor and + implicit_constructor.group(1) == implicit_constructor.group(2)): + return True + return IsRValueType(clean_lines, nesting_state, linenum, + len(match_func.group(1))) + + # Nothing before the function name. If this is inside a block scope, + # this is probably a function call. + return not (nesting_state.previous_stack_top and + nesting_state.previous_stack_top.IsBlockInfo()) + + if match_symbol.group(2) == '>': + # Possibly a closing bracket, check that what's on the other side + # looks like the start of a template. + return IsTemplateParameterList( + clean_lines, start, len(match_symbol.group(1))) + + # Some other symbol, usually something like "a=b&&c". This is most + # likely not a type. + return False + + +def IsRValueAllowed(clean_lines, linenum): + """Check if RValue reference is allowed within some range of lines. + + Args: + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + Returns: + True if line is within the region where RValue references are allowed. + """ + for i in xrange(linenum, 0, -1): + line = clean_lines.elided[i] + if Match(r'GOOGLE_ALLOW_RVALUE_REFERENCES_(?:PUSH|POP)', line): + if not line.endswith('PUSH'): + return False + for j in xrange(linenum, clean_lines.NumLines(), 1): + line = clean_lines.elided[j] + if Match(r'GOOGLE_ALLOW_RVALUE_REFERENCES_(?:PUSH|POP)', line): + return line.endswith('POP') + return False + + +def CheckRValueReference(filename, clean_lines, linenum, nesting_state, error): + """Check for rvalue references. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + nesting_state: A NestingState instance which maintains information about + the current stack of nested blocks being parsed. + error: The function to call with any errors found. + """ + # Find lines missing spaces around &&. + # TODO(unknown): currently we don't check for rvalue references + # with spaces surrounding the && to avoid false positives with + # boolean expressions. + line = clean_lines.elided[linenum] + match = Match(r'^(.*\S)&&', line) + if not match: + match = Match(r'(.*)&&\S', line) + if (not match) or '(&&)' in line or Search(r'\boperator\s*$', match.group(1)): + return + + # Either poorly formed && or an rvalue reference, check the context + # to get a more accurate error message. Mostly we want to determine + # if what's to the left of "&&" is a type or not. + and_pos = len(match.group(1)) + if IsRValueType(clean_lines, nesting_state, linenum, and_pos): + if not IsRValueAllowed(clean_lines, linenum): + error(filename, linenum, 'build/c++11', 3, + 'RValue references are an unapproved C++ feature.') + else: + error(filename, linenum, 'whitespace/operators', 3, + 'Missing spaces around &&') + + +def CheckSectionSpacing(filename, clean_lines, class_info, linenum, error): + """Checks for additional blank line issues related to sections. + + Currently the only thing checked here is blank line before protected/private. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + class_info: A _ClassInfo objects. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + # Skip checks if the class is small, where small means 25 lines or less. + # 25 lines seems like a good cutoff since that's the usual height of + # terminals, and any class that can't fit in one screen can't really + # be considered "small". + # + # Also skip checks if we are on the first line. This accounts for + # classes that look like + # class Foo { public: ... }; + # + # If we didn't find the end of the class, last_line would be zero, + # and the check will be skipped by the first condition. + if (class_info.last_line - class_info.starting_linenum <= 24 or + linenum <= class_info.starting_linenum): + return + + matched = Match(r'\s*(public|protected|private):', clean_lines.lines[linenum]) + if matched: + # Issue warning if the line before public/protected/private was + # not a blank line, but don't do this if the previous line contains + # "class" or "struct". This can happen two ways: + # - We are at the beginning of the class. + # - We are forward-declaring an inner class that is semantically + # private, but needed to be public for implementation reasons. + # Also ignores cases where the previous line ends with a backslash as can be + # common when defining classes in C macros. + prev_line = clean_lines.lines[linenum - 1] + if (not IsBlankLine(prev_line) and + not Search(r'\b(class|struct)\b', prev_line) and + not Search(r'\\$', prev_line)): + # Try a bit harder to find the beginning of the class. This is to + # account for multi-line base-specifier lists, e.g.: + # class Derived + # : public Base { + end_class_head = class_info.starting_linenum + for i in range(class_info.starting_linenum, linenum): + if Search(r'\{\s*$', clean_lines.lines[i]): + end_class_head = i + break + if end_class_head < linenum - 1: + error(filename, linenum, 'whitespace/blank_line', 3, + '"%s:" should be preceded by a blank line' % matched.group(1)) + + +def GetPreviousNonBlankLine(clean_lines, linenum): + """Return the most recent non-blank line and its line number. + + Args: + clean_lines: A CleansedLines instance containing the file contents. + linenum: The number of the line to check. + + Returns: + A tuple with two elements. The first element is the contents of the last + non-blank line before the current line, or the empty string if this is the + first non-blank line. The second is the line number of that line, or -1 + if this is the first non-blank line. + """ + + prevlinenum = linenum - 1 + while prevlinenum >= 0: + prevline = clean_lines.elided[prevlinenum] + if not IsBlankLine(prevline): # if not a blank line... + return (prevline, prevlinenum) + prevlinenum -= 1 + return ('', -1) + + +def CheckBraces(filename, clean_lines, linenum, error): + """Looks for misplaced braces (e.g. at the end of line). + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + + line = clean_lines.elided[linenum] # get rid of comments and strings + + if Match(r'\s*{\s*$', line): + # We allow an open brace to start a line in the case where someone is using + # braces in a block to explicitly create a new scope, which is commonly used + # to control the lifetime of stack-allocated variables. Braces are also + # used for brace initializers inside function calls. We don't detect this + # perfectly: we just don't complain if the last non-whitespace character on + # the previous non-blank line is ',', ';', ':', '(', '{', or '}', or if the + # previous line starts a preprocessor block. + prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] + if (not Search(r'[,;:}{(]\s*$', prevline) and + not Match(r'\s*#', prevline)): + error(filename, linenum, 'whitespace/braces', 4, + '{ should almost always be at the end of the previous line') + + # An else clause should be on the same line as the preceding closing brace. + if Match(r'\s*else\b\s*(?:if\b|\{|$)', line): + prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] + if Match(r'\s*}\s*$', prevline): + error(filename, linenum, 'whitespace/newline', 4, + 'An else should appear on the same line as the preceding }') + + # If braces come on one side of an else, they should be on both. + # However, we have to worry about "else if" that spans multiple lines! + if Search(r'else if\s*\(', line): # could be multi-line if + brace_on_left = bool(Search(r'}\s*else if\s*\(', line)) + # find the ( after the if + pos = line.find('else if') + pos = line.find('(', pos) + if pos > 0: + (endline, _, endpos) = CloseExpression(clean_lines, linenum, pos) + brace_on_right = endline[endpos:].find('{') != -1 + if brace_on_left != brace_on_right: # must be brace after if + error(filename, linenum, 'readability/braces', 5, + 'If an else has a brace on one side, it should have it on both') + elif Search(r'}\s*else[^{]*$', line) or Match(r'[^}]*else\s*{', line): + error(filename, linenum, 'readability/braces', 5, + 'If an else has a brace on one side, it should have it on both') + + # Likewise, an else should never have the else clause on the same line + if Search(r'\belse [^\s{]', line) and not Search(r'\belse if\b', line): + error(filename, linenum, 'whitespace/newline', 4, + 'Else clause should never be on same line as else (use 2 lines)') + + # In the same way, a do/while should never be on one line + if Match(r'\s*do [^\s{]', line): + error(filename, linenum, 'whitespace/newline', 4, + 'do/while clauses should not be on a single line') + + # Check single-line if/else bodies. The style guide says 'curly braces are not + # required for single-line statements'. We additionally allow multi-line, + # single statements, but we reject anything with more than one semicolon in + # it. This means that the first semicolon after the if should be at the end of + # its line, and the line after that should have an indent level equal to or + # lower than the if. We also check for ambiguous if/else nesting without + # braces. + if_else_match = Search(r'\b(if\s*\(|else\b)', line) + if if_else_match and not Match(r'\s*#', line): + if_indent = GetIndentLevel(line) + endline, endlinenum, endpos = line, linenum, if_else_match.end() + if_match = Search(r'\bif\s*\(', line) + if if_match: + # This could be a multiline if condition, so find the end first. + pos = if_match.end() - 1 + (endline, endlinenum, endpos) = CloseExpression(clean_lines, linenum, pos) + # Check for an opening brace, either directly after the if or on the next + # line. If found, this isn't a single-statement conditional. + if (not Match(r'\s*{', endline[endpos:]) + and not (Match(r'\s*$', endline[endpos:]) + and endlinenum < (len(clean_lines.elided) - 1) + and Match(r'\s*{', clean_lines.elided[endlinenum + 1]))): + while (endlinenum < len(clean_lines.elided) + and ';' not in clean_lines.elided[endlinenum][endpos:]): + endlinenum += 1 + endpos = 0 + if endlinenum < len(clean_lines.elided): + endline = clean_lines.elided[endlinenum] + # We allow a mix of whitespace and closing braces (e.g. for one-liner + # methods) and a single \ after the semicolon (for macros) + endpos = endline.find(';') + if not Match(r';[\s}]*(\\?)$', endline[endpos:]): + # Semicolon isn't the last character, there's something trailing + error(filename, linenum, 'readability/braces', 4, + 'If/else bodies with multiple statements require braces') + elif endlinenum < len(clean_lines.elided) - 1: + # Make sure the next line is dedented + next_line = clean_lines.elided[endlinenum + 1] + next_indent = GetIndentLevel(next_line) + # With ambiguous nested if statements, this will error out on the + # if that *doesn't* match the else, regardless of whether it's the + # inner one or outer one. + if (if_match and Match(r'\s*else\b', next_line) + and next_indent != if_indent): + error(filename, linenum, 'readability/braces', 4, + 'Else clause should be indented at the same level as if. ' + 'Ambiguous nested if/else chains require braces.') + elif next_indent > if_indent: + error(filename, linenum, 'readability/braces', 4, + 'If/else bodies with multiple statements require braces') + + +def CheckTrailingSemicolon(filename, clean_lines, linenum, error): + """Looks for redundant trailing semicolon. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + + line = clean_lines.elided[linenum] + + # Block bodies should not be followed by a semicolon. Due to C++11 + # brace initialization, there are more places where semicolons are + # required than not, so we use a whitelist approach to check these + # rather than a blacklist. These are the places where "};" should + # be replaced by just "}": + # 1. Some flavor of block following closing parenthesis: + # for (;;) {}; + # while (...) {}; + # switch (...) {}; + # Function(...) {}; + # if (...) {}; + # if (...) else if (...) {}; + # + # 2. else block: + # if (...) else {}; + # + # 3. const member function: + # Function(...) const {}; + # + # 4. Block following some statement: + # x = 42; + # {}; + # + # 5. Block at the beginning of a function: + # Function(...) { + # {}; + # } + # + # Note that naively checking for the preceding "{" will also match + # braces inside multi-dimensional arrays, but this is fine since + # that expression will not contain semicolons. + # + # 6. Block following another block: + # while (true) {} + # {}; + # + # 7. End of namespaces: + # namespace {}; + # + # These semicolons seems far more common than other kinds of + # redundant semicolons, possibly due to people converting classes + # to namespaces. For now we do not warn for this case. + # + # Try matching case 1 first. + match = Match(r'^(.*\)\s*)\{', line) + if match: + # Matched closing parenthesis (case 1). Check the token before the + # matching opening parenthesis, and don't warn if it looks like a + # macro. This avoids these false positives: + # - macro that defines a base class + # - multi-line macro that defines a base class + # - macro that defines the whole class-head + # + # But we still issue warnings for macros that we know are safe to + # warn, specifically: + # - TEST, TEST_F, TEST_P, MATCHER, MATCHER_P + # - TYPED_TEST + # - INTERFACE_DEF + # - EXCLUSIVE_LOCKS_REQUIRED, SHARED_LOCKS_REQUIRED, LOCKS_EXCLUDED: + # + # We implement a whitelist of safe macros instead of a blacklist of + # unsafe macros, even though the latter appears less frequently in + # google code and would have been easier to implement. This is because + # the downside for getting the whitelist wrong means some extra + # semicolons, while the downside for getting the blacklist wrong + # would result in compile errors. + # + # In addition to macros, we also don't want to warn on compound + # literals and lambdas. + closing_brace_pos = match.group(1).rfind(')') + opening_parenthesis = ReverseCloseExpression( + clean_lines, linenum, closing_brace_pos) + if opening_parenthesis[2] > -1: + line_prefix = opening_parenthesis[0][0:opening_parenthesis[2]] + macro = Search(r'\b([A-Z_]+)\s*$', line_prefix) + func = Match(r'^(.*\])\s*$', line_prefix) + if ((macro and + macro.group(1) not in ( + 'TEST', 'TEST_F', 'MATCHER', 'MATCHER_P', 'TYPED_TEST', + 'EXCLUSIVE_LOCKS_REQUIRED', 'SHARED_LOCKS_REQUIRED', + 'LOCKS_EXCLUDED', 'INTERFACE_DEF')) or + (func and not Search(r'\boperator\s*\[\s*\]', func.group(1))) or + Search(r'\s+=\s*$', line_prefix)): + match = None + if (match and + opening_parenthesis[1] > 1 and + Search(r'\]\s*$', clean_lines.elided[opening_parenthesis[1] - 1])): + # Multi-line lambda-expression + match = None + + else: + # Try matching cases 2-3. + match = Match(r'^(.*(?:else|\)\s*const)\s*)\{', line) + if not match: + # Try matching cases 4-6. These are always matched on separate lines. + # + # Note that we can't simply concatenate the previous line to the + # current line and do a single match, otherwise we may output + # duplicate warnings for the blank line case: + # if (cond) { + # // blank line + # } + prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] + if prevline and Search(r'[;{}]\s*$', prevline): + match = Match(r'^(\s*)\{', line) + + # Check matching closing brace + if match: + (endline, endlinenum, endpos) = CloseExpression( + clean_lines, linenum, len(match.group(1))) + if endpos > -1 and Match(r'^\s*;', endline[endpos:]): + # Current {} pair is eligible for semicolon check, and we have found + # the redundant semicolon, output warning here. + # + # Note: because we are scanning forward for opening braces, and + # outputting warnings for the matching closing brace, if there are + # nested blocks with trailing semicolons, we will get the error + # messages in reversed order. + error(filename, endlinenum, 'readability/braces', 4, + "You don't need a ; after a }") + + +def CheckEmptyBlockBody(filename, clean_lines, linenum, error): + """Look for empty loop/conditional body with only a single semicolon. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + + # Search for loop keywords at the beginning of the line. Because only + # whitespaces are allowed before the keywords, this will also ignore most + # do-while-loops, since those lines should start with closing brace. + # + # We also check "if" blocks here, since an empty conditional block + # is likely an error. + line = clean_lines.elided[linenum] + matched = Match(r'\s*(for|while|if)\s*\(', line) + if matched: + # Find the end of the conditional expression + (end_line, end_linenum, end_pos) = CloseExpression( + clean_lines, linenum, line.find('(')) + + # Output warning if what follows the condition expression is a semicolon. + # No warning for all other cases, including whitespace or newline, since we + # have a separate check for semicolons preceded by whitespace. + if end_pos >= 0 and Match(r';', end_line[end_pos:]): + if matched.group(1) == 'if': + error(filename, end_linenum, 'whitespace/empty_conditional_body', 5, + 'Empty conditional bodies should use {}') + else: + error(filename, end_linenum, 'whitespace/empty_loop_body', 5, + 'Empty loop bodies should use {} or continue') + + +def FindCheckMacro(line): + """Find a replaceable CHECK-like macro. + + Args: + line: line to search on. + Returns: + (macro name, start position), or (None, -1) if no replaceable + macro is found. + """ + for macro in _CHECK_MACROS: + i = line.find(macro) + if i >= 0: + # Find opening parenthesis. Do a regular expression match here + # to make sure that we are matching the expected CHECK macro, as + # opposed to some other macro that happens to contain the CHECK + # substring. + matched = Match(r'^(.*\b' + macro + r'\s*)\(', line) + if not matched: + continue + return (macro, len(matched.group(1))) + return (None, -1) + + +def CheckCheck(filename, clean_lines, linenum, error): + """Checks the use of CHECK and EXPECT macros. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + + # Decide the set of replacement macros that should be suggested + lines = clean_lines.elided + (check_macro, start_pos) = FindCheckMacro(lines[linenum]) + if not check_macro: + return + + # Find end of the boolean expression by matching parentheses + (last_line, end_line, end_pos) = CloseExpression( + clean_lines, linenum, start_pos) + if end_pos < 0: + return + if linenum == end_line: + expression = lines[linenum][start_pos + 1:end_pos - 1] + else: + expression = lines[linenum][start_pos + 1:] + for i in xrange(linenum + 1, end_line): + expression += lines[i] + expression += last_line[0:end_pos - 1] + + # Parse expression so that we can take parentheses into account. + # This avoids false positives for inputs like "CHECK((a < 4) == b)", + # which is not replaceable by CHECK_LE. + lhs = '' + rhs = '' + operator = None + while expression: + matched = Match(r'^\s*(<<|<<=|>>|>>=|->\*|->|&&|\|\||' + r'==|!=|>=|>|<=|<|\()(.*)$', expression) + if matched: + token = matched.group(1) + if token == '(': + # Parenthesized operand + expression = matched.group(2) + (end, _) = FindEndOfExpressionInLine(expression, 0, ['(']) + if end < 0: + return # Unmatched parenthesis + lhs += '(' + expression[0:end] + expression = expression[end:] + elif token in ('&&', '||'): + # Logical and/or operators. This means the expression + # contains more than one term, for example: + # CHECK(42 < a && a < b); + # + # These are not replaceable with CHECK_LE, so bail out early. + return + elif token in ('<<', '<<=', '>>', '>>=', '->*', '->'): + # Non-relational operator + lhs += token + expression = matched.group(2) + else: + # Relational operator + operator = token + rhs = matched.group(2) + break + else: + # Unparenthesized operand. Instead of appending to lhs one character + # at a time, we do another regular expression match to consume several + # characters at once if possible. Trivial benchmark shows that this + # is more efficient when the operands are longer than a single + # character, which is generally the case. + matched = Match(r'^([^-=!<>()&|]+)(.*)$', expression) + if not matched: + matched = Match(r'^(\s*\S)(.*)$', expression) + if not matched: + break + lhs += matched.group(1) + expression = matched.group(2) + + # Only apply checks if we got all parts of the boolean expression + if not (lhs and operator and rhs): + return + + # Check that rhs do not contain logical operators. We already know + # that lhs is fine since the loop above parses out && and ||. + if rhs.find('&&') > -1 or rhs.find('||') > -1: + return + + # At least one of the operands must be a constant literal. This is + # to avoid suggesting replacements for unprintable things like + # CHECK(variable != iterator) + # + # The following pattern matches decimal, hex integers, strings, and + # characters (in that order). + lhs = lhs.strip() + rhs = rhs.strip() + match_constant = r'^([-+]?(\d+|0[xX][0-9a-fA-F]+)[lLuU]{0,3}|".*"|\'.*\')$' + if Match(match_constant, lhs) or Match(match_constant, rhs): + # Note: since we know both lhs and rhs, we can provide a more + # descriptive error message like: + # Consider using CHECK_EQ(x, 42) instead of CHECK(x == 42) + # Instead of: + # Consider using CHECK_EQ instead of CHECK(a == b) + # + # We are still keeping the less descriptive message because if lhs + # or rhs gets long, the error message might become unreadable. + error(filename, linenum, 'readability/check', 2, + 'Consider using %s instead of %s(a %s b)' % ( + _CHECK_REPLACEMENT[check_macro][operator], + check_macro, operator)) + + +def CheckAltTokens(filename, clean_lines, linenum, error): + """Check alternative keywords being used in boolean expressions. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + line = clean_lines.elided[linenum] + + # Avoid preprocessor lines + if Match(r'^\s*#', line): + return + + # Last ditch effort to avoid multi-line comments. This will not help + # if the comment started before the current line or ended after the + # current line, but it catches most of the false positives. At least, + # it provides a way to workaround this warning for people who use + # multi-line comments in preprocessor macros. + # + # TODO(unknown): remove this once cpplint has better support for + # multi-line comments. + if line.find('/*') >= 0 or line.find('*/') >= 0: + return + + for match in _ALT_TOKEN_REPLACEMENT_PATTERN.finditer(line): + error(filename, linenum, 'readability/alt_tokens', 2, + 'Use operator %s instead of %s' % ( + _ALT_TOKEN_REPLACEMENT[match.group(1)], match.group(1))) + + +def GetLineWidth(line): + """Determines the width of the line in column positions. + + Args: + line: A string, which may be a Unicode string. + + Returns: + The width of the line in column positions, accounting for Unicode + combining characters and wide characters. + """ + if isinstance(line, unicode): + width = 0 + for uc in unicodedata.normalize('NFC', line): + if unicodedata.east_asian_width(uc) in ('W', 'F'): + width += 2 + elif not unicodedata.combining(uc): + width += 1 + return width + else: + return len(line) + + +def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state, + error): + """Checks rules from the 'C++ style rules' section of cppguide.html. + + Most of these rules are hard to test (naming, comment style), but we + do what we can. In particular we check for 2-space indents, line lengths, + tab usage, spaces inside code, etc. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + file_extension: The extension (without the dot) of the filename. + nesting_state: A NestingState instance which maintains information about + the current stack of nested blocks being parsed. + error: The function to call with any errors found. + """ + + # Don't use "elided" lines here, otherwise we can't check commented lines. + # Don't want to use "raw" either, because we don't want to check inside C++11 + # raw strings, + raw_lines = clean_lines.lines_without_raw_strings + line = raw_lines[linenum] + + if line.find('\t') != -1: + error(filename, linenum, 'whitespace/tab', 1, + 'Tab found; better to use spaces') + + # One or three blank spaces at the beginning of the line is weird; it's + # hard to reconcile that with 2-space indents. + # NOTE: here are the conditions rob pike used for his tests. Mine aren't + # as sophisticated, but it may be worth becoming so: RLENGTH==initial_spaces + # if(RLENGTH > 20) complain = 0; + # if(match($0, " +(error|private|public|protected):")) complain = 0; + # if(match(prev, "&& *$")) complain = 0; + # if(match(prev, "\\|\\| *$")) complain = 0; + # if(match(prev, "[\",=><] *$")) complain = 0; + # if(match($0, " <<")) complain = 0; + # if(match(prev, " +for \\(")) complain = 0; + # if(prevodd && match(prevprev, " +for \\(")) complain = 0; + scope_or_label_pattern = r'\s*\w+\s*:\s*\\?$' + classinfo = nesting_state.InnermostClass() + initial_spaces = 0 + cleansed_line = clean_lines.elided[linenum] + while initial_spaces < len(line) and line[initial_spaces] == ' ': + initial_spaces += 1 + if line and line[-1].isspace(): + error(filename, linenum, 'whitespace/end_of_line', 4, + 'Line ends in whitespace. Consider deleting these extra spaces.') + # There are certain situations we allow one space, notably for + # section labels, and also lines containing multi-line raw strings. + elif ((initial_spaces == 1 or initial_spaces == 3) and + not Match(scope_or_label_pattern, cleansed_line) and + not (clean_lines.raw_lines[linenum] != line and + Match(r'^\s*""', line))): + error(filename, linenum, 'whitespace/indent', 3, + 'Weird number of spaces at line-start. ' + 'Are you using a 2-space indent?') + + # Check if the line is a header guard. + is_header_guard = False + if file_extension == 'h': + cppvar = GetHeaderGuardCPPVariable(filename) + if (line.startswith('#ifndef %s' % cppvar) or + line.startswith('#define %s' % cppvar) or + line.startswith('#endif // %s' % cppvar)): + is_header_guard = True + # #include lines and header guards can be long, since there's no clean way to + # split them. + # + # URLs can be long too. It's possible to split these, but it makes them + # harder to cut&paste. + # + # The "$Id:...$" comment may also get very long without it being the + # developers fault. + if (not line.startswith('#include') and not is_header_guard and + not Match(r'^\s*//.*http(s?)://\S*$', line) and + not Match(r'^// \$Id:.*#[0-9]+ \$$', line)): + line_width = GetLineWidth(line) + extended_length = int((_line_length * 1.25)) + if line_width > extended_length: + error(filename, linenum, 'whitespace/line_length', 4, + 'Lines should very rarely be longer than %i characters' % + extended_length) + elif line_width > _line_length: + error(filename, linenum, 'whitespace/line_length', 2, + 'Lines should be <= %i characters long' % _line_length) + + if (cleansed_line.count(';') > 1 and + # for loops are allowed two ;'s (and may run over two lines). + cleansed_line.find('for') == -1 and + (GetPreviousNonBlankLine(clean_lines, linenum)[0].find('for') == -1 or + GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and + # It's ok to have many commands in a switch case that fits in 1 line + not ((cleansed_line.find('case ') != -1 or + cleansed_line.find('default:') != -1) and + cleansed_line.find('break;') != -1)): + error(filename, linenum, 'whitespace/newline', 0, + 'More than one command on the same line') + + # Some more style checks + CheckBraces(filename, clean_lines, linenum, error) + CheckTrailingSemicolon(filename, clean_lines, linenum, error) + CheckEmptyBlockBody(filename, clean_lines, linenum, error) + CheckAccess(filename, clean_lines, linenum, nesting_state, error) + CheckSpacing(filename, clean_lines, linenum, nesting_state, error) + CheckOperatorSpacing(filename, clean_lines, linenum, error) + CheckParenthesisSpacing(filename, clean_lines, linenum, error) + CheckCommaSpacing(filename, clean_lines, linenum, error) + CheckBracesSpacing(filename, clean_lines, linenum, error) + CheckSpacingForFunctionCall(filename, clean_lines, linenum, error) + CheckRValueReference(filename, clean_lines, linenum, nesting_state, error) + CheckCheck(filename, clean_lines, linenum, error) + CheckAltTokens(filename, clean_lines, linenum, error) + classinfo = nesting_state.InnermostClass() + if classinfo: + CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error) + + +_RE_PATTERN_INCLUDE_NEW_STYLE = re.compile(r'#include +"[^/]+\.h"') +_RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$') +# Matches the first component of a filename delimited by -s and _s. That is: +# _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo' +# _RE_FIRST_COMPONENT.match('foo.cc').group(0) == 'foo' +# _RE_FIRST_COMPONENT.match('foo-bar_baz.cc').group(0) == 'foo' +# _RE_FIRST_COMPONENT.match('foo_bar-baz.cc').group(0) == 'foo' +_RE_FIRST_COMPONENT = re.compile(r'^[^-_.]+') + + +def _DropCommonSuffixes(filename): + """Drops common suffixes like _test.cc or -inl.h from filename. + + For example: + >>> _DropCommonSuffixes('foo/foo-inl.h') + 'foo/foo' + >>> _DropCommonSuffixes('foo/bar/foo.cc') + 'foo/bar/foo' + >>> _DropCommonSuffixes('foo/foo_internal.h') + 'foo/foo' + >>> _DropCommonSuffixes('foo/foo_unusualinternal.h') + 'foo/foo_unusualinternal' + + Args: + filename: The input filename. + + Returns: + The filename with the common suffix removed. + """ + for suffix in ('test.cc', 'regtest.cc', 'unittest.cc', + 'inl.h', 'impl.h', 'internal.h'): + if (filename.endswith(suffix) and len(filename) > len(suffix) and + filename[-len(suffix) - 1] in ('-', '_')): + return filename[:-len(suffix) - 1] + return os.path.splitext(filename)[0] + + +def _IsTestFilename(filename): + """Determines if the given filename has a suffix that identifies it as a test. + + Args: + filename: The input filename. + + Returns: + True if 'filename' looks like a test, False otherwise. + """ + if (filename.endswith('_test.cc') or + filename.endswith('_unittest.cc') or + filename.endswith('_regtest.cc')): + return True + else: + return False + + +def _ClassifyInclude(fileinfo, include, is_system): + """Figures out what kind of header 'include' is. + + Args: + fileinfo: The current file cpplint is running over. A FileInfo instance. + include: The path to a #included file. + is_system: True if the #include used <> rather than "". + + Returns: + One of the _XXX_HEADER constants. + + For example: + >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'stdio.h', True) + _C_SYS_HEADER + >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'string', True) + _CPP_SYS_HEADER + >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/foo.h', False) + _LIKELY_MY_HEADER + >>> _ClassifyInclude(FileInfo('foo/foo_unknown_extension.cc'), + ... 'bar/foo_other_ext.h', False) + _POSSIBLE_MY_HEADER + >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/bar.h', False) + _OTHER_HEADER + """ + # This is a list of all standard c++ header files, except + # those already checked for above. + is_cpp_h = include in _CPP_HEADERS + + if is_system: + if is_cpp_h: + return _CPP_SYS_HEADER + else: + return _C_SYS_HEADER + + # If the target file and the include we're checking share a + # basename when we drop common extensions, and the include + # lives in . , then it's likely to be owned by the target file. + target_dir, target_base = ( + os.path.split(_DropCommonSuffixes(fileinfo.RepositoryName()))) + include_dir, include_base = os.path.split(_DropCommonSuffixes(include)) + if target_base == include_base and ( + include_dir == target_dir or + include_dir == os.path.normpath(target_dir + '/../public')): + return _LIKELY_MY_HEADER + + # If the target and include share some initial basename + # component, it's possible the target is implementing the + # include, so it's allowed to be first, but we'll never + # complain if it's not there. + target_first_component = _RE_FIRST_COMPONENT.match(target_base) + include_first_component = _RE_FIRST_COMPONENT.match(include_base) + if (target_first_component and include_first_component and + target_first_component.group(0) == + include_first_component.group(0)): + return _POSSIBLE_MY_HEADER + + return _OTHER_HEADER + + + +def CheckIncludeLine(filename, clean_lines, linenum, include_state, error): + """Check rules that are applicable to #include lines. + + Strings on #include lines are NOT removed from elided line, to make + certain tasks easier. However, to prevent false positives, checks + applicable to #include lines in CheckLanguage must be put here. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + include_state: An _IncludeState instance in which the headers are inserted. + error: The function to call with any errors found. + """ + fileinfo = FileInfo(filename) + line = clean_lines.lines[linenum] + + # "include" should use the new style "foo/bar.h" instead of just "bar.h" + if _RE_PATTERN_INCLUDE_NEW_STYLE.search(line): + error(filename, linenum, 'build/include', 4, + 'Include the directory when naming .h files') + + # we shouldn't include a file more than once. actually, there are a + # handful of instances where doing so is okay, but in general it's + # not. + match = _RE_PATTERN_INCLUDE.search(line) + if match: + include = match.group(2) + is_system = (match.group(1) == '<') + if include in include_state: + error(filename, linenum, 'build/include', 4, + '"%s" already included at %s:%s' % + (include, filename, include_state[include])) + else: + include_state[include] = linenum + + # We want to ensure that headers appear in the right order: + # 1) for foo.cc, foo.h (preferred location) + # 2) c system files + # 3) cpp system files + # 4) for foo.cc, foo.h (deprecated location) + # 5) other google headers + # + # We classify each include statement as one of those 5 types + # using a number of techniques. The include_state object keeps + # track of the highest type seen, and complains if we see a + # lower type after that. + error_message = include_state.CheckNextIncludeOrder( + _ClassifyInclude(fileinfo, include, is_system)) + if error_message: + error(filename, linenum, 'build/include_order', 4, + '%s. Should be: %s.h, c system, c++ system, other.' % + (error_message, fileinfo.BaseName())) + canonical_include = include_state.CanonicalizeAlphabeticalOrder(include) + if not include_state.IsInAlphabeticalOrder( + clean_lines, linenum, canonical_include): + error(filename, linenum, 'build/include_alpha', 4, + 'Include "%s" not in alphabetical order' % include) + include_state.SetLastHeader(canonical_include) + + # Look for any of the stream classes that are part of standard C++. + match = _RE_PATTERN_INCLUDE.match(line) + if match: + include = match.group(2) + if Match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include): + # Many unit tests use cout, so we exempt them. + if not _IsTestFilename(filename): + # Suggest a different header for ostream + if include == 'ostream': + error(filename, linenum, 'readability/streams', 3, + 'For logging, include "base/logging.h" instead of .') + else: + error(filename, linenum, 'readability/streams', 3, + 'Streams are highly discouraged.') + + +def _GetTextInside(text, start_pattern): + r"""Retrieves all the text between matching open and close parentheses. + + Given a string of lines and a regular expression string, retrieve all the text + following the expression and between opening punctuation symbols like + (, [, or {, and the matching close-punctuation symbol. This properly nested + occurrences of the punctuations, so for the text like + printf(a(), b(c())); + a call to _GetTextInside(text, r'printf\(') will return 'a(), b(c())'. + start_pattern must match string having an open punctuation symbol at the end. + + Args: + text: The lines to extract text. Its comments and strings must be elided. + It can be single line and can span multiple lines. + start_pattern: The regexp string indicating where to start extracting + the text. + Returns: + The extracted text. + None if either the opening string or ending punctuation could not be found. + """ + # TODO(unknown): Audit cpplint.py to see what places could be profitably + # rewritten to use _GetTextInside (and use inferior regexp matching today). + + # Give opening punctuations to get the matching close-punctuations. + matching_punctuation = {'(': ')', '{': '}', '[': ']'} + closing_punctuation = set(matching_punctuation.itervalues()) + + # Find the position to start extracting text. + match = re.search(start_pattern, text, re.M) + if not match: # start_pattern not found in text. + return None + start_position = match.end(0) + + assert start_position > 0, ( + 'start_pattern must ends with an opening punctuation.') + assert text[start_position - 1] in matching_punctuation, ( + 'start_pattern must ends with an opening punctuation.') + # Stack of closing punctuations we expect to have in text after position. + punctuation_stack = [matching_punctuation[text[start_position - 1]]] + position = start_position + while punctuation_stack and position < len(text): + if text[position] == punctuation_stack[-1]: + punctuation_stack.pop() + elif text[position] in closing_punctuation: + # A closing punctuation without matching opening punctuations. + return None + elif text[position] in matching_punctuation: + punctuation_stack.append(matching_punctuation[text[position]]) + position += 1 + if punctuation_stack: + # Opening punctuations left without matching close-punctuations. + return None + # punctuations match. + return text[start_position:position - 1] + + +# Patterns for matching call-by-reference parameters. +# +# Supports nested templates up to 2 levels deep using this messy pattern: +# < (?: < (?: < [^<>]* +# > +# | [^<>] )* +# > +# | [^<>] )* +# > +_RE_PATTERN_IDENT = r'[_a-zA-Z]\w*' # =~ [[:alpha:]][[:alnum:]]* +_RE_PATTERN_TYPE = ( + r'(?:const\s+)?(?:typename\s+|class\s+|struct\s+|union\s+|enum\s+)?' + r'(?:\w|' + r'\s*<(?:<(?:<[^<>]*>|[^<>])*>|[^<>])*>|' + r'::)+') +# A call-by-reference parameter ends with '& identifier'. +_RE_PATTERN_REF_PARAM = re.compile( + r'(' + _RE_PATTERN_TYPE + r'(?:\s*(?:\bconst\b|[*]))*\s*' + r'&\s*' + _RE_PATTERN_IDENT + r')\s*(?:=[^,()]+)?[,)]') +# A call-by-const-reference parameter either ends with 'const& identifier' +# or looks like 'const type& identifier' when 'type' is atomic. +_RE_PATTERN_CONST_REF_PARAM = ( + r'(?:.*\s*\bconst\s*&\s*' + _RE_PATTERN_IDENT + + r'|const\s+' + _RE_PATTERN_TYPE + r'\s*&\s*' + _RE_PATTERN_IDENT + r')') + + +def CheckLanguage(filename, clean_lines, linenum, file_extension, + include_state, nesting_state, error): + """Checks rules from the 'C++ language rules' section of cppguide.html. + + Some of these rules are hard to test (function overloading, using + uint32 inappropriately), but we do the best we can. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + file_extension: The extension (without the dot) of the filename. + include_state: An _IncludeState instance in which the headers are inserted. + nesting_state: A NestingState instance which maintains information about + the current stack of nested blocks being parsed. + error: The function to call with any errors found. + """ + # If the line is empty or consists of entirely a comment, no need to + # check it. + line = clean_lines.elided[linenum] + if not line: + return + + match = _RE_PATTERN_INCLUDE.search(line) + if match: + CheckIncludeLine(filename, clean_lines, linenum, include_state, error) + return + + # Reset include state across preprocessor directives. This is meant + # to silence warnings for conditional includes. + if Match(r'^\s*#\s*(?:ifdef|elif|else|endif)\b', line): + include_state.ResetSection() + + # Make Windows paths like Unix. + fullname = os.path.abspath(filename).replace('\\', '/') + + # Perform other checks now that we are sure that this is not an include line + CheckCasts(filename, clean_lines, linenum, error) + CheckGlobalStatic(filename, clean_lines, linenum, error) + CheckPrintf(filename, clean_lines, linenum, error) + + if file_extension == 'h': + # TODO(unknown): check that 1-arg constructors are explicit. + # How to tell it's a constructor? + # (handled in CheckForNonStandardConstructs for now) + # TODO(unknown): check that classes have DISALLOW_EVIL_CONSTRUCTORS + # (level 1 error) + pass + + # Check if people are using the verboten C basic types. The only exception + # we regularly allow is "unsigned short port" for port. + if Search(r'\bshort port\b', line): + if not Search(r'\bunsigned short port\b', line): + error(filename, linenum, 'runtime/int', 4, + 'Use "unsigned short" for ports, not "short"') + else: + match = Search(r'\b(short|long(?! +double)|long long)\b', line) + if match: + error(filename, linenum, 'runtime/int', 4, + 'Use int16/int64/etc, rather than the C type %s' % match.group(1)) + + # Check if some verboten operator overloading is going on + # TODO(unknown): catch out-of-line unary operator&: + # class X {}; + # int operator&(const X& x) { return 42; } // unary operator& + # The trick is it's hard to tell apart from binary operator&: + # class Y { int operator&(const Y& x) { return 23; } }; // binary operator& + if Search(r'\boperator\s*&\s*\(\s*\)', line): + error(filename, linenum, 'runtime/operator', 4, + 'Unary operator& is dangerous. Do not use it.') + + # Check for suspicious usage of "if" like + # } if (a == b) { + if Search(r'\}\s*if\s*\(', line): + error(filename, linenum, 'readability/braces', 4, + 'Did you mean "else if"? If not, start a new line for "if".') + + # Check for potential format string bugs like printf(foo). + # We constrain the pattern not to pick things like DocidForPrintf(foo). + # Not perfect but it can catch printf(foo.c_str()) and printf(foo->c_str()) + # TODO(unknown): Catch the following case. Need to change the calling + # convention of the whole function to process multiple line to handle it. + # printf( + # boy_this_is_a_really_long_variable_that_cannot_fit_on_the_prev_line); + printf_args = _GetTextInside(line, r'(?i)\b(string)?printf\s*\(') + if printf_args: + match = Match(r'([\w.\->()]+)$', printf_args) + if match and match.group(1) != '__VA_ARGS__': + function_name = re.search(r'\b((?:string)?printf)\s*\(', + line, re.I).group(1) + error(filename, linenum, 'runtime/printf', 4, + 'Potential format string bug. Do %s("%%s", %s) instead.' + % (function_name, match.group(1))) + + # Check for potential memset bugs like memset(buf, sizeof(buf), 0). + match = Search(r'memset\s*\(([^,]*),\s*([^,]*),\s*0\s*\)', line) + if match and not Match(r"^''|-?[0-9]+|0x[0-9A-Fa-f]$", match.group(2)): + error(filename, linenum, 'runtime/memset', 4, + 'Did you mean "memset(%s, 0, %s)"?' + % (match.group(1), match.group(2))) + + if Search(r'\busing namespace\b', line): + error(filename, linenum, 'build/namespaces', 5, + 'Do not use namespace using-directives. ' + 'Use using-declarations instead.') + + # Detect variable-length arrays. + match = Match(r'\s*(.+::)?(\w+) [a-z]\w*\[(.+)];', line) + if (match and match.group(2) != 'return' and match.group(2) != 'delete' and + match.group(3).find(']') == -1): + # Split the size using space and arithmetic operators as delimiters. + # If any of the resulting tokens are not compile time constants then + # report the error. + tokens = re.split(r'\s|\+|\-|\*|\/|<<|>>]', match.group(3)) + is_const = True + skip_next = False + for tok in tokens: + if skip_next: + skip_next = False + continue + + if Search(r'sizeof\(.+\)', tok): continue + if Search(r'arraysize\(\w+\)', tok): continue + + tok = tok.lstrip('(') + tok = tok.rstrip(')') + if not tok: continue + if Match(r'\d+', tok): continue + if Match(r'0[xX][0-9a-fA-F]+', tok): continue + if Match(r'k[A-Z0-9]\w*', tok): continue + if Match(r'(.+::)?k[A-Z0-9]\w*', tok): continue + if Match(r'(.+::)?[A-Z][A-Z0-9_]*', tok): continue + # A catch all for tricky sizeof cases, including 'sizeof expression', + # 'sizeof(*type)', 'sizeof(const type)', 'sizeof(struct StructName)' + # requires skipping the next token because we split on ' ' and '*'. + if tok.startswith('sizeof'): + skip_next = True + continue + is_const = False + break + if not is_const: + error(filename, linenum, 'runtime/arrays', 1, + 'Do not use variable-length arrays. Use an appropriately named ' + "('k' followed by CamelCase) compile-time constant for the size.") + + # If DISALLOW_EVIL_CONSTRUCTORS, DISALLOW_COPY_AND_ASSIGN, or + # DISALLOW_IMPLICIT_CONSTRUCTORS is present, then it should be the last thing + # in the class declaration. + match = Match( + (r'\s*' + r'(DISALLOW_(EVIL_CONSTRUCTORS|COPY_AND_ASSIGN|IMPLICIT_CONSTRUCTORS))' + r'\(.*\);$'), + line) + if match and linenum + 1 < clean_lines.NumLines(): + next_line = clean_lines.elided[linenum + 1] + # We allow some, but not all, declarations of variables to be present + # in the statement that defines the class. The [\w\*,\s]* fragment of + # the regular expression below allows users to declare instances of + # the class or pointers to instances, but not less common types such + # as function pointers or arrays. It's a tradeoff between allowing + # reasonable code and avoiding trying to parse more C++ using regexps. + if not Search(r'^\s*}[\w\*,\s]*;', next_line): + error(filename, linenum, 'readability/constructors', 3, + match.group(1) + ' should be the last thing in the class') + + # Check for use of unnamed namespaces in header files. Registration + # macros are typically OK, so we allow use of "namespace {" on lines + # that end with backslashes. + if (file_extension == 'h' + and Search(r'\bnamespace\s*{', line) + and line[-1] != '\\'): + error(filename, linenum, 'build/namespaces', 4, + 'Do not use unnamed namespaces in header files. See ' + 'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces' + ' for more information.') + + +def CheckGlobalStatic(filename, clean_lines, linenum, error): + """Check for unsafe global or static objects. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + line = clean_lines.elided[linenum] + + # Check for people declaring static/global STL strings at the top level. + # This is dangerous because the C++ language does not guarantee that + # globals with constructors are initialized before the first access. + match = Match( + r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)', + line) + # Remove false positives: + # - String pointers (as opposed to values). + # string *pointer + # const string *pointer + # string const *pointer + # string *const pointer + # + # - Functions and template specializations. + # string Function(... + # string Class::Method(... + # + # - Operators. These are matched separately because operator names + # cross non-word boundaries, and trying to match both operators + # and functions at the same time would decrease accuracy of + # matching identifiers. + # string Class::operator*() + if (match and + not Search(r'\bstring\b(\s+const)?\s*\*\s*(const\s+)?\w', line) and + not Search(r'\boperator\W', line) and + not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)?\s*\(([^"]|$)', match.group(3))): + error(filename, linenum, 'runtime/string', 4, + 'For a static/global string constant, use a C style string instead: ' + '"%schar %s[]".' % + (match.group(1), match.group(2))) + + if Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line): + error(filename, linenum, 'runtime/init', 4, + 'You seem to be initializing a member variable with itself.') + + +def CheckPrintf(filename, clean_lines, linenum, error): + """Check for printf related issues. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + line = clean_lines.elided[linenum] + + # When snprintf is used, the second argument shouldn't be a literal. + match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line) + if match and match.group(2) != '0': + # If 2nd arg is zero, snprintf is used to calculate size. + error(filename, linenum, 'runtime/printf', 3, + 'If you can, use sizeof(%s) instead of %s as the 2nd arg ' + 'to snprintf.' % (match.group(1), match.group(2))) + + # Check if some verboten C functions are being used. + if Search(r'\bsprintf\b', line): + error(filename, linenum, 'runtime/printf', 5, + 'Never use sprintf. Use snprintf instead.') + match = Search(r'\b(strcpy|strcat)\b', line) + if match: + error(filename, linenum, 'runtime/printf', 4, + 'Almost always, snprintf is better than %s' % match.group(1)) + + +def IsDerivedFunction(clean_lines, linenum): + """Check if current line contains an inherited function. + + Args: + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + Returns: + True if current line contains a function with "override" + virt-specifier. + """ + # Look for leftmost opening parenthesis on current line + opening_paren = clean_lines.elided[linenum].find('(') + if opening_paren < 0: return False + + # Look for "override" after the matching closing parenthesis + line, _, closing_paren = CloseExpression(clean_lines, linenum, opening_paren) + return closing_paren >= 0 and Search(r'\boverride\b', line[closing_paren:]) + + +def IsInitializerList(clean_lines, linenum): + """Check if current line is inside constructor initializer list. + + Args: + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + Returns: + True if current line appears to be inside constructor initializer + list, False otherwise. + """ + for i in xrange(linenum, 1, -1): + line = clean_lines.elided[i] + if i == linenum: + remove_function_body = Match(r'^(.*)\{\s*$', line) + if remove_function_body: + line = remove_function_body.group(1) + + if Search(r'\s:\s*\w+[({]', line): + # A lone colon tend to indicate the start of a constructor + # initializer list. It could also be a ternary operator, which + # also tend to appear in constructor initializer lists as + # opposed to parameter lists. + return True + if Search(r'\}\s*,\s*$', line): + # A closing brace followed by a comma is probably the end of a + # brace-initialized member in constructor initializer list. + return True + if Search(r'[{};]\s*$', line): + # Found one of the following: + # - A closing brace or semicolon, probably the end of the previous + # function. + # - An opening brace, probably the start of current class or namespace. + # + # Current line is probably not inside an initializer list since + # we saw one of those things without seeing the starting colon. + return False + + # Got to the beginning of the file without seeing the start of + # constructor initializer list. + return False + + +def CheckForNonConstReference(filename, clean_lines, linenum, + nesting_state, error): + """Check for non-const references. + + Separate from CheckLanguage since it scans backwards from current + line, instead of scanning forward. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + nesting_state: A NestingState instance which maintains information about + the current stack of nested blocks being parsed. + error: The function to call with any errors found. + """ + # Do nothing if there is no '&' on current line. + line = clean_lines.elided[linenum] + if '&' not in line: + return + + # If a function is inherited, current function doesn't have much of + # a choice, so any non-const references should not be blamed on + # derived function. + if IsDerivedFunction(clean_lines, linenum): + return + + # Long type names may be broken across multiple lines, usually in one + # of these forms: + # LongType + # ::LongTypeContinued &identifier + # LongType:: + # LongTypeContinued &identifier + # LongType< + # ...>::LongTypeContinued &identifier + # + # If we detected a type split across two lines, join the previous + # line to current line so that we can match const references + # accordingly. + # + # Note that this only scans back one line, since scanning back + # arbitrary number of lines would be expensive. If you have a type + # that spans more than 2 lines, please use a typedef. + if linenum > 1: + previous = None + if Match(r'\s*::(?:[\w<>]|::)+\s*&\s*\S', line): + # previous_line\n + ::current_line + previous = Search(r'\b((?:const\s*)?(?:[\w<>]|::)+[\w<>])\s*$', + clean_lines.elided[linenum - 1]) + elif Match(r'\s*[a-zA-Z_]([\w<>]|::)+\s*&\s*\S', line): + # previous_line::\n + current_line + previous = Search(r'\b((?:const\s*)?(?:[\w<>]|::)+::)\s*$', + clean_lines.elided[linenum - 1]) + if previous: + line = previous.group(1) + line.lstrip() + else: + # Check for templated parameter that is split across multiple lines + endpos = line.rfind('>') + if endpos > -1: + (_, startline, startpos) = ReverseCloseExpression( + clean_lines, linenum, endpos) + if startpos > -1 and startline < linenum: + # Found the matching < on an earlier line, collect all + # pieces up to current line. + line = '' + for i in xrange(startline, linenum + 1): + line += clean_lines.elided[i].strip() + + # Check for non-const references in function parameters. A single '&' may + # found in the following places: + # inside expression: binary & for bitwise AND + # inside expression: unary & for taking the address of something + # inside declarators: reference parameter + # We will exclude the first two cases by checking that we are not inside a + # function body, including one that was just introduced by a trailing '{'. + # TODO(unknown): Doesn't account for 'catch(Exception& e)' [rare]. + if (nesting_state.previous_stack_top and + not (isinstance(nesting_state.previous_stack_top, _ClassInfo) or + isinstance(nesting_state.previous_stack_top, _NamespaceInfo))): + # Not at toplevel, not within a class, and not within a namespace + return + + # Avoid preprocessors + if Search(r'\\\s*$', line): + return + + # Avoid constructor initializer lists + if IsInitializerList(clean_lines, linenum): + return + + # We allow non-const references in a few standard places, like functions + # called "swap()" or iostream operators like "<<" or ">>". Do not check + # those function parameters. + # + # We also accept & in static_assert, which looks like a function but + # it's actually a declaration expression. + whitelisted_functions = (r'(?:[sS]wap(?:<\w:+>)?|' + r'operator\s*[<>][<>]|' + r'static_assert|COMPILE_ASSERT' + r')\s*\(') + if Search(whitelisted_functions, line): + return + elif not Search(r'\S+\([^)]*$', line): + # Don't see a whitelisted function on this line. Actually we + # didn't see any function name on this line, so this is likely a + # multi-line parameter list. Try a bit harder to catch this case. + for i in xrange(2): + if (linenum > i and + Search(whitelisted_functions, clean_lines.elided[linenum - i - 1])): + return + + decls = ReplaceAll(r'{[^}]*}', ' ', line) # exclude function body + for parameter in re.findall(_RE_PATTERN_REF_PARAM, decls): + if not Match(_RE_PATTERN_CONST_REF_PARAM, parameter): + error(filename, linenum, 'runtime/references', 2, + 'Is this a non-const reference? ' + 'If so, make const or use a pointer: ' + + ReplaceAll(' *<', '<', parameter)) + + +def CheckCasts(filename, clean_lines, linenum, error): + """Various cast related checks. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + line = clean_lines.elided[linenum] + + # Check to see if they're using an conversion function cast. + # I just try to capture the most common basic types, though there are more. + # Parameterless conversion functions, such as bool(), are allowed as they are + # probably a member operator declaration or default constructor. + match = Search( + r'(\bnew\s+|\S<\s*(?:const\s+)?)?\b' + r'(int|float|double|bool|char|int32|uint32|int64|uint64)' + r'(\([^)].*)', line) + expecting_function = ExpectingFunctionArgs(clean_lines, linenum) + if match and not expecting_function: + matched_type = match.group(2) + + # matched_new_or_template is used to silence two false positives: + # - New operators + # - Template arguments with function types + # + # For template arguments, we match on types immediately following + # an opening bracket without any spaces. This is a fast way to + # silence the common case where the function type is the first + # template argument. False negative with less-than comparison is + # avoided because those operators are usually followed by a space. + # + # function // bracket + no space = false positive + # value < double(42) // bracket + space = true positive + matched_new_or_template = match.group(1) + + # Other things to ignore: + # - Function pointers + # - Casts to pointer types + # - Placement new + # - Alias declarations + matched_funcptr = match.group(3) + if (matched_new_or_template is None and + not (matched_funcptr and + (Match(r'\((?:[^() ]+::\s*\*\s*)?[^() ]+\)\s*\(', + matched_funcptr) or + matched_funcptr.startswith('(*)'))) and + not Match(r'\s*using\s+\S+\s*=\s*' + matched_type, line) and + not Search(r'new\(\S+\)\s*' + matched_type, line)): + error(filename, linenum, 'readability/casting', 4, + 'Using deprecated casting style. ' + 'Use static_cast<%s>(...) instead' % + matched_type) + + if not expecting_function: + CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum], + 'static_cast', + r'\((int|float|double|bool|char|u?int(16|32|64))\)', error) + + # This doesn't catch all cases. Consider (const char * const)"hello". + # + # (char *) "foo" should always be a const_cast (reinterpret_cast won't + # compile). + if CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum], + 'const_cast', r'\((char\s?\*+\s?)\)\s*"', error): + pass + else: + # Check pointer casts for other than string constants + CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum], + 'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error) + + # In addition, we look for people taking the address of a cast. This + # is dangerous -- casts can assign to temporaries, so the pointer doesn't + # point where you think. + match = Search( + r'(?:&\(([^)]+)\)[\w(])|' + r'(?:&(static|dynamic|down|reinterpret)_cast\b)', line) + if match and match.group(1) != '*': + # Try a better error message when the & is bound to something + # dereferenced by the casted pointer, as opposed to the casted + # pointer itself. + parenthesis_error = False + match = Match(r'^(.*&(?:static|dynamic|down|reinterpret)_cast\b)<', line) + if match: + _, y1, x1 = CloseExpression(clean_lines, linenum, len(match.group(1))) + if x1 >= 0 and clean_lines.elided[y1][x1] == '(': + _, y2, x2 = CloseExpression(clean_lines, y1, x1) + if x2 >= 0: + extended_line = clean_lines.elided[y2][x2:] + if y2 < clean_lines.NumLines() - 1: + extended_line += clean_lines.elided[y2 + 1] + if Match(r'\s*(?:->|\[)', extended_line): + parenthesis_error = True + + if parenthesis_error: + error(filename, linenum, 'readability/casting', 4, + ('Are you taking an address of something dereferenced ' + 'from a cast? Wrapping the dereferenced expression in ' + 'parentheses will make the binding more obvious')) + else: + error(filename, linenum, 'runtime/casting', 4, + ('Are you taking an address of a cast? ' + 'This is dangerous: could be a temp var. ' + 'Take the address before doing the cast, rather than after')) + + +def CheckCStyleCast(filename, linenum, line, raw_line, cast_type, pattern, + error): + """Checks for a C-style cast by looking for the pattern. + + Args: + filename: The name of the current file. + linenum: The number of the line to check. + line: The line of code to check. + raw_line: The raw line of code to check, with comments. + cast_type: The string for the C++ cast to recommend. This is either + reinterpret_cast, static_cast, or const_cast, depending. + pattern: The regular expression used to find C-style casts. + error: The function to call with any errors found. + + Returns: + True if an error was emitted. + False otherwise. + """ + match = Search(pattern, line) + if not match: + return False + + # Exclude lines with keywords that tend to look like casts, and also + # macros which are generally troublesome. + if Match(r'.*\b(?:sizeof|alignof|alignas|[A-Z_]+)\s*$', + line[0:match.start(1) - 1]): + return False + + # operator++(int) and operator--(int) + if (line[0:match.start(1) - 1].endswith(' operator++') or + line[0:match.start(1) - 1].endswith(' operator--')): + return False + + # A single unnamed argument for a function tends to look like old + # style cast. If we see those, don't issue warnings for deprecated + # casts, instead issue warnings for unnamed arguments where + # appropriate. + # + # These are things that we want warnings for, since the style guide + # explicitly require all parameters to be named: + # Function(int); + # Function(int) { + # ConstMember(int) const; + # ConstMember(int) const { + # ExceptionMember(int) throw (...); + # ExceptionMember(int) throw (...) { + # PureVirtual(int) = 0; + # + # These are functions of some sort, where the compiler would be fine + # if they had named parameters, but people often omit those + # identifiers to reduce clutter: + # (FunctionPointer)(int); + # (FunctionPointer)(int) = value; + # Function((function_pointer_arg)(int)) + # ; + # <(FunctionPointerTemplateArgument)(int)>; + remainder = line[match.end(0):] + if Match(r'^\s*(?:;|const\b|throw\b|final\b|override\b|=|>|\{|\))', + remainder): + # Looks like an unnamed parameter. + + # Don't warn on any kind of template arguments. + if Match(r'^\s*>', remainder): + return False + + # Don't warn on assignments to function pointers, but keep warnings for + # unnamed parameters to pure virtual functions. Note that this pattern + # will also pass on assignments of "0" to function pointers, but the + # preferred values for those would be "nullptr" or "NULL". + matched_zero = Match(r'^\s=\s*(\S+)\s*;', remainder) + if matched_zero and matched_zero.group(1) != '0': + return False + + # Don't warn on function pointer declarations. For this we need + # to check what came before the "(type)" string. + if Match(r'.*\)\s*$', line[0:match.start(0)]): + return False + + # Don't warn if the parameter is named with block comments, e.g.: + # Function(int /*unused_param*/); + if '/*' in raw_line: + return False + + # Passed all filters, issue warning here. + error(filename, linenum, 'readability/function', 3, + 'All parameters should be named in a function') + return True + + # At this point, all that should be left is actual casts. + error(filename, linenum, 'readability/casting', 4, + 'Using C-style cast. Use %s<%s>(...) instead' % + (cast_type, match.group(1))) + + return True + + +def ExpectingFunctionArgs(clean_lines, linenum): + """Checks whether where function type arguments are expected. + + Args: + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + + Returns: + True if the line at 'linenum' is inside something that expects arguments + of function types. + """ + line = clean_lines.elided[linenum] + return (Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line) or + (linenum >= 2 and + (Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\((?:\S+,)?\s*$', + clean_lines.elided[linenum - 1]) or + Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\(\s*$', + clean_lines.elided[linenum - 2]) or + Search(r'\bstd::m?function\s*\<\s*$', + clean_lines.elided[linenum - 1])))) + + +_HEADERS_CONTAINING_TEMPLATES = ( + ('', ('deque',)), + ('', ('unary_function', 'binary_function', + 'plus', 'minus', 'multiplies', 'divides', 'modulus', + 'negate', + 'equal_to', 'not_equal_to', 'greater', 'less', + 'greater_equal', 'less_equal', + 'logical_and', 'logical_or', 'logical_not', + 'unary_negate', 'not1', 'binary_negate', 'not2', + 'bind1st', 'bind2nd', + 'pointer_to_unary_function', + 'pointer_to_binary_function', + 'ptr_fun', + 'mem_fun_t', 'mem_fun', 'mem_fun1_t', 'mem_fun1_ref_t', + 'mem_fun_ref_t', + 'const_mem_fun_t', 'const_mem_fun1_t', + 'const_mem_fun_ref_t', 'const_mem_fun1_ref_t', + 'mem_fun_ref', + )), + ('', ('numeric_limits',)), + ('', ('list',)), + ('', ('map', 'multimap',)), + ('', ('allocator',)), + ('', ('queue', 'priority_queue',)), + ('', ('set', 'multiset',)), + ('', ('stack',)), + ('', ('char_traits', 'basic_string',)), + ('', ('pair',)), + ('', ('vector',)), + + # gcc extensions. + # Note: std::hash is their hash, ::hash is our hash + ('', ('hash_map', 'hash_multimap',)), + ('', ('hash_set', 'hash_multiset',)), + ('', ('slist',)), + ) + +_RE_PATTERN_STRING = re.compile(r'\bstring\b') + +_re_pattern_algorithm_header = [] +for _template in ('copy', 'max', 'min', 'min_element', 'sort', 'swap', + 'transform'): + # Match max(..., ...), max(..., ...), but not foo->max, foo.max or + # type::max(). + _re_pattern_algorithm_header.append( + (re.compile(r'[^>.]\b' + _template + r'(<.*?>)?\([^\)]'), + _template, + '')) + +_re_pattern_templates = [] +for _header, _templates in _HEADERS_CONTAINING_TEMPLATES: + for _template in _templates: + _re_pattern_templates.append( + (re.compile(r'(\<|\b)' + _template + r'\s*\<'), + _template + '<>', + _header)) + + +def FilesBelongToSameModule(filename_cc, filename_h): + """Check if these two filenames belong to the same module. + + The concept of a 'module' here is a as follows: + foo.h, foo-inl.h, foo.cc, foo_test.cc and foo_unittest.cc belong to the + same 'module' if they are in the same directory. + some/path/public/xyzzy and some/path/internal/xyzzy are also considered + to belong to the same module here. + + If the filename_cc contains a longer path than the filename_h, for example, + '/absolute/path/to/base/sysinfo.cc', and this file would include + 'base/sysinfo.h', this function also produces the prefix needed to open the + header. This is used by the caller of this function to more robustly open the + header file. We don't have access to the real include paths in this context, + so we need this guesswork here. + + Known bugs: tools/base/bar.cc and base/bar.h belong to the same module + according to this implementation. Because of this, this function gives + some false positives. This should be sufficiently rare in practice. + + Args: + filename_cc: is the path for the .cc file + filename_h: is the path for the header path + + Returns: + Tuple with a bool and a string: + bool: True if filename_cc and filename_h belong to the same module. + string: the additional prefix needed to open the header file. + """ + + if not filename_cc.endswith('.cc'): + return (False, '') + filename_cc = filename_cc[:-len('.cc')] + if filename_cc.endswith('_unittest'): + filename_cc = filename_cc[:-len('_unittest')] + elif filename_cc.endswith('_test'): + filename_cc = filename_cc[:-len('_test')] + filename_cc = filename_cc.replace('/public/', '/') + filename_cc = filename_cc.replace('/internal/', '/') + + if not filename_h.endswith('.h'): + return (False, '') + filename_h = filename_h[:-len('.h')] + if filename_h.endswith('-inl'): + filename_h = filename_h[:-len('-inl')] + filename_h = filename_h.replace('/public/', '/') + filename_h = filename_h.replace('/internal/', '/') + + files_belong_to_same_module = filename_cc.endswith(filename_h) + common_path = '' + if files_belong_to_same_module: + common_path = filename_cc[:-len(filename_h)] + return files_belong_to_same_module, common_path + + +def UpdateIncludeState(filename, include_state, io=codecs): + """Fill up the include_state with new includes found from the file. + + Args: + filename: the name of the header to read. + include_state: an _IncludeState instance in which the headers are inserted. + io: The io factory to use to read the file. Provided for testability. + + Returns: + True if a header was succesfully added. False otherwise. + """ + headerfile = None + try: + headerfile = io.open(filename, 'r', 'utf8', 'replace') + except IOError: + return False + linenum = 0 + for line in headerfile: + linenum += 1 + clean_line = CleanseComments(line) + match = _RE_PATTERN_INCLUDE.search(clean_line) + if match: + include = match.group(2) + # The value formatting is cute, but not really used right now. + # What matters here is that the key is in include_state. + include_state.setdefault(include, '%s:%d' % (filename, linenum)) + return True + + +def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error, + io=codecs): + """Reports for missing stl includes. + + This function will output warnings to make sure you are including the headers + necessary for the stl containers and functions that you use. We only give one + reason to include a header. For example, if you use both equal_to<> and + less<> in a .h file, only one (the latter in the file) of these will be + reported as a reason to include the . + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + include_state: An _IncludeState instance. + error: The function to call with any errors found. + io: The IO factory to use to read the header file. Provided for unittest + injection. + """ + required = {} # A map of header name to linenumber and the template entity. + # Example of required: { '': (1219, 'less<>') } + + for linenum in xrange(clean_lines.NumLines()): + line = clean_lines.elided[linenum] + if not line or line[0] == '#': + continue + + # String is special -- it is a non-templatized type in STL. + matched = _RE_PATTERN_STRING.search(line) + if matched: + # Don't warn about strings in non-STL namespaces: + # (We check only the first match per line; good enough.) + prefix = line[:matched.start()] + if prefix.endswith('std::') or not prefix.endswith('::'): + required[''] = (linenum, 'string') + + for pattern, template, header in _re_pattern_algorithm_header: + if pattern.search(line): + required[header] = (linenum, template) + + # The following function is just a speed up, no semantics are changed. + if not '<' in line: # Reduces the cpu time usage by skipping lines. + continue + + for pattern, template, header in _re_pattern_templates: + if pattern.search(line): + required[header] = (linenum, template) + + # The policy is that if you #include something in foo.h you don't need to + # include it again in foo.cc. Here, we will look at possible includes. + # Let's copy the include_state so it is only messed up within this function. + include_state = include_state.copy() + + # Did we find the header for this file (if any) and succesfully load it? + header_found = False + + # Use the absolute path so that matching works properly. + abs_filename = FileInfo(filename).FullName() + + # For Emacs's flymake. + # If cpplint is invoked from Emacs's flymake, a temporary file is generated + # by flymake and that file name might end with '_flymake.cc'. In that case, + # restore original file name here so that the corresponding header file can be + # found. + # e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.h' + # instead of 'foo_flymake.h' + abs_filename = re.sub(r'_flymake\.cc$', '.cc', abs_filename) + + # include_state is modified during iteration, so we iterate over a copy of + # the keys. + header_keys = include_state.keys() + for header in header_keys: + (same_module, common_path) = FilesBelongToSameModule(abs_filename, header) + fullpath = common_path + header + if same_module and UpdateIncludeState(fullpath, include_state, io): + header_found = True + + # If we can't find the header file for a .cc, assume it's because we don't + # know where to look. In that case we'll give up as we're not sure they + # didn't include it in the .h file. + # TODO(unknown): Do a better job of finding .h files so we are confident that + # not having the .h file means there isn't one. + if filename.endswith('.cc') and not header_found: + return + + # All the lines have been processed, report the errors found. + for required_header_unstripped in required: + template = required[required_header_unstripped][1] + if required_header_unstripped.strip('<>"') not in include_state: + error(filename, required[required_header_unstripped][0], + 'build/include_what_you_use', 4, + 'Add #include ' + required_header_unstripped + ' for ' + template) + + +_RE_PATTERN_EXPLICIT_MAKEPAIR = re.compile(r'\bmake_pair\s*<') + + +def CheckMakePairUsesDeduction(filename, clean_lines, linenum, error): + """Check that make_pair's template arguments are deduced. + + G++ 4.6 in C++11 mode fails badly if make_pair's template arguments are + specified explicitly, and such use isn't intended in any case. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + line = clean_lines.elided[linenum] + match = _RE_PATTERN_EXPLICIT_MAKEPAIR.search(line) + if match: + error(filename, linenum, 'build/explicit_make_pair', + 4, # 4 = high confidence + 'For C++11-compatibility, omit template arguments from make_pair' + ' OR use pair directly OR if appropriate, construct a pair directly') +def CheckDefaultLambdaCaptures(filename, clean_lines, linenum, error): + """Check that default lambda captures are not used. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + line = clean_lines.elided[linenum] + + # A lambda introducer specifies a default capture if it starts with "[=" + # or if it starts with "[&" _not_ followed by an identifier. + match = Match(r'^(.*)\[\s*(?:=|&[^\w])', line) + if match: + # Found a potential error, check what comes after the lambda-introducer. + # If it's not open parenthesis (for lambda-declarator) or open brace + # (for compound-statement), it's not a lambda. + line, _, pos = CloseExpression(clean_lines, linenum, len(match.group(1))) + if pos >= 0 and Match(r'^\s*[{(]', line[pos:]): + error(filename, linenum, 'build/c++11', + 4, # 4 = high confidence + 'Default lambda captures are an unapproved C++ feature.') + + + + +def ProcessLine(filename, file_extension, clean_lines, line, + include_state, function_state, nesting_state, error, + extra_check_functions=[]): + """Processes a single line in the file. + + Args: + filename: Filename of the file that is being processed. + file_extension: The extension (dot not included) of the file. + clean_lines: An array of strings, each representing a line of the file, + with comments stripped. + line: Number of line being processed. + include_state: An _IncludeState instance in which the headers are inserted. + function_state: A _FunctionState instance which counts function lines, etc. + nesting_state: A NestingState instance which maintains information about + the current stack of nested blocks being parsed. + error: A callable to which errors are reported, which takes 4 arguments: + filename, line number, error level, and message + extra_check_functions: An array of additional check functions that will be + run on each source line. Each function takes 4 + arguments: filename, clean_lines, line, error + """ + raw_lines = clean_lines.raw_lines + ParseNolintSuppressions(filename, raw_lines[line], line, error) + nesting_state.Update(filename, clean_lines, line, error) + if nesting_state.InAsmBlock(): return + CheckForFunctionLengths(filename, clean_lines, line, function_state, error) + CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error) + CheckStyle(filename, clean_lines, line, file_extension, nesting_state, error) + CheckLanguage(filename, clean_lines, line, file_extension, include_state, + nesting_state, error) + CheckForNonConstReference(filename, clean_lines, line, nesting_state, error) + CheckForNonStandardConstructs(filename, clean_lines, line, + nesting_state, error) + CheckVlogArguments(filename, clean_lines, line, error) + CheckPosixThreading(filename, clean_lines, line, error) + CheckInvalidIncrement(filename, clean_lines, line, error) + CheckMakePairUsesDeduction(filename, clean_lines, line, error) + CheckDefaultLambdaCaptures(filename, clean_lines, line, error) + for check_fn in extra_check_functions: + check_fn(filename, clean_lines, line, error) + +def FlagCxx11Features(filename, clean_lines, linenum, error): + """Flag those c++11 features that we only allow in certain places. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + line = clean_lines.elided[linenum] + + # Flag unapproved C++11 headers. + include = Match(r'\s*#\s*include\s+[<"]([^<"]+)[">]', line) + if include and include.group(1) in ('cfenv', + 'condition_variable', + 'fenv.h', + 'future', + 'mutex', + 'thread', + 'chrono', + 'ratio', + 'regex', + 'system_error', + ): + error(filename, linenum, 'build/c++11', 5, + ('<%s> is an unapproved C++11 header.') % include.group(1)) + + # The only place where we need to worry about C++11 keywords and library + # features in preprocessor directives is in macro definitions. + if Match(r'\s*#', line) and not Match(r'\s*#\s*define\b', line): return + + # These are classes and free functions. The classes are always + # mentioned as std::*, but we only catch the free functions if + # they're not found by ADL. They're alphabetical by header. + for top_name in ( + # type_traits + 'alignment_of', + 'aligned_union', + + # utility + 'forward', + ): + if Search(r'\bstd::%s\b' % top_name, line): + error(filename, linenum, 'build/c++11', 5, + ('std::%s is an unapproved C++11 class or function. Send c-style ' + 'an example of where it would make your code more readable, and ' + 'they may let you use it.') % top_name) + + +def ProcessFileData(filename, file_extension, lines, error, + extra_check_functions=[]): + """Performs lint checks and reports any errors to the given error function. + + Args: + filename: Filename of the file that is being processed. + file_extension: The extension (dot not included) of the file. + lines: An array of strings, each representing a line of the file, with the + last element being empty if the file is terminated with a newline. + error: A callable to which errors are reported, which takes 4 arguments: + filename, line number, error level, and message + extra_check_functions: An array of additional check functions that will be + run on each source line. Each function takes 4 + arguments: filename, clean_lines, line, error + """ + lines = (['// marker so line numbers and indices both start at 1'] + lines + + ['// marker so line numbers end in a known way']) + + include_state = _IncludeState() + function_state = _FunctionState() + nesting_state = NestingState() + + ResetNolintSuppressions() + + CheckForCopyright(filename, lines, error) + + if file_extension == 'h': + CheckForHeaderGuard(filename, lines, error) + + RemoveMultiLineComments(filename, lines, error) + clean_lines = CleansedLines(lines) + for line in xrange(clean_lines.NumLines()): + ProcessLine(filename, file_extension, clean_lines, line, + include_state, function_state, nesting_state, error, + extra_check_functions) + FlagCxx11Features(filename, clean_lines, line, error) + nesting_state.CheckCompletedBlocks(filename, error) + + CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error) + + # We check here rather than inside ProcessLine so that we see raw + # lines rather than "cleaned" lines. + CheckForBadCharacters(filename, lines, error) + + CheckForNewlineAtEOF(filename, lines, error) + + +def ProcessFile(filename, vlevel, extra_check_functions=[]): + """Does google-lint on a single file. + + Args: + filename: The name of the file to parse. + + vlevel: The level of errors to report. Every error of confidence + >= verbose_level will be reported. 0 is a good default. + + extra_check_functions: An array of additional check functions that will be + run on each source line. Each function takes 4 + arguments: filename, clean_lines, line, error + """ + + _SetVerboseLevel(vlevel) + + lf_lines = [] + crlf_lines = [] + try: + # Support the UNIX convention of using "-" for stdin. Note that + # we are not opening the file with universal newline support + # (which codecs doesn't support anyway), so the resulting lines do + # contain trailing '\r' characters if we are reading a file that + # has CRLF endings. + # If after the split a trailing '\r' is present, it is removed + # below. + if filename == '-': + lines = codecs.StreamReaderWriter(sys.stdin, + codecs.getreader('utf8'), + codecs.getwriter('utf8'), + 'replace').read().split('\n') + else: + lines = codecs.open(filename, 'r', 'utf8', 'replace').read().split('\n') + + # Remove trailing '\r'. + # The -1 accounts for the extra trailing blank line we get from split() + for linenum in range(len(lines) - 1): + if lines[linenum].endswith('\r'): + lines[linenum] = lines[linenum].rstrip('\r') + crlf_lines.append(linenum + 1) + else: + lf_lines.append(linenum + 1) + + except IOError: + sys.stderr.write( + "Skipping input '%s': Can't open for reading\n" % filename) + return + + # Note, if no dot is found, this will give the entire filename as the ext. + file_extension = filename[filename.rfind('.') + 1:] + + # When reading from stdin, the extension is unknown, so no cpplint tests + # should rely on the extension. + if filename != '-' and file_extension not in _valid_extensions: + sys.stderr.write('Ignoring %s; not a valid file name ' + '(%s)\n' % (filename, ', '.join(_valid_extensions))) + else: + ProcessFileData(filename, file_extension, lines, Error, + extra_check_functions) + + # If end-of-line sequences are a mix of LF and CR-LF, issue + # warnings on the lines with CR. + # + # Don't issue any warnings if all lines are uniformly LF or CR-LF, + # since critique can handle these just fine, and the style guide + # doesn't dictate a particular end of line sequence. + # + # We can't depend on os.linesep to determine what the desired + # end-of-line sequence should be, since that will return the + # server-side end-of-line sequence. + if lf_lines and crlf_lines: + # Warn on every line with CR. An alternative approach might be to + # check whether the file is mostly CRLF or just LF, and warn on the + # minority, we bias toward LF here since most tools prefer LF. + for linenum in crlf_lines: + Error(filename, linenum, 'whitespace/newline', 1, + 'Unexpected \\r (^M) found; better to use only \\n') + + sys.stderr.write('Done processing %s\n' % filename) + + +def PrintUsage(message): + """Prints a brief usage string and exits, optionally with an error message. + + Args: + message: The optional error message. + """ + sys.stderr.write(_USAGE) + if message: + sys.exit('\nFATAL ERROR: ' + message) + else: + sys.exit(1) + + +def PrintCategories(): + """Prints a list of all the error-categories used by error messages. + + These are the categories used to filter messages via --filter. + """ + sys.stderr.write(''.join(' %s\n' % cat for cat in _ERROR_CATEGORIES)) + sys.exit(0) + + +def ParseArguments(args): + """Parses the command line arguments. + + This may set the output format and verbosity level as side-effects. + + Args: + args: The command line arguments: + + Returns: + The list of filenames to lint. + """ + try: + (opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=', + 'counting=', + 'filter=', + 'root=', + 'linelength=', + 'extensions=']) + except getopt.GetoptError: + PrintUsage('Invalid arguments.') + + verbosity = _VerboseLevel() + output_format = _OutputFormat() + filters = '' + counting_style = '' + + for (opt, val) in opts: + if opt == '--help': + PrintUsage(None) + elif opt == '--output': + if val not in ('emacs', 'vs7', 'eclipse'): + PrintUsage('The only allowed output formats are emacs, vs7 and eclipse.') + output_format = val + elif opt == '--verbose': + verbosity = int(val) + elif opt == '--filter': + filters = val + if not filters: + PrintCategories() + elif opt == '--counting': + if val not in ('total', 'toplevel', 'detailed'): + PrintUsage('Valid counting options are total, toplevel, and detailed') + counting_style = val + elif opt == '--root': + global _root + _root = val + elif opt == '--linelength': + global _line_length + try: + _line_length = int(val) + except ValueError: + PrintUsage('Line length must be digits.') + elif opt == '--extensions': + global _valid_extensions + try: + _valid_extensions = set(val.split(',')) + except ValueError: + PrintUsage('Extensions must be comma seperated list.') + + if not filenames: + PrintUsage('No files were specified.') + + _SetOutputFormat(output_format) + _SetVerboseLevel(verbosity) + _SetFilters(filters) + _SetCountingStyle(counting_style) + + return filenames + + +def main(): + filenames = ParseArguments(sys.argv[1:]) + + # Change stderr to write with replacement characters so we don't die + # if we try to print something containing non-ASCII characters. + sys.stderr = codecs.StreamReaderWriter(sys.stderr, + codecs.getreader('utf8'), + codecs.getwriter('utf8'), + 'replace') + + _cpplint_state.ResetErrorCounts() + for filename in filenames: + ProcessFile(filename, _cpplint_state.verbose_level) + _cpplint_state.PrintErrorCounts() + + sys.exit(_cpplint_state.error_count > 0) + + +if __name__ == '__main__': + main() From 8a6807bd92ffd00c2fbd82c3cc7cbe519e9f13ff Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 11 Jul 2014 18:43:35 -0700 Subject: [PATCH 021/388] Fixing linter to work on Windows (ironically, by breaking it). --- src/poly/cxx_compat.h | 6 +++--- third_party/google-styleguide/cpplint/cpplint.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/poly/cxx_compat.h b/src/poly/cxx_compat.h index f0ac6d8fb..080152245 100644 --- a/src/poly/cxx_compat.h +++ b/src/poly/cxx_compat.h @@ -7,8 +7,8 @@ ****************************************************************************** */ -#ifndef POLY_POLY_CXX_COMPAT_H_ -#define POLY_POLY_CXX_COMPAT_H_ +#ifndef POLY_CXX_COMPAT_H_ +#define POLY_CXX_COMPAT_H_ #include @@ -24,4 +24,4 @@ namespace poly {} // namespace poly -#endif // POLY_POLY_CXX_COMPAT_H_ +#endif // POLY_CXX_COMPAT_H_ diff --git a/third_party/google-styleguide/cpplint/cpplint.py b/third_party/google-styleguide/cpplint/cpplint.py index ebe576df4..d3159c627 100644 --- a/third_party/google-styleguide/cpplint/cpplint.py +++ b/third_party/google-styleguide/cpplint/cpplint.py @@ -1553,7 +1553,7 @@ def GetHeaderGuardCPPVariable(filename): fileinfo = FileInfo(filename) file_path_from_root = fileinfo.RepositoryName() if _root: - file_path_from_root = re.sub('^' + _root + os.sep, '', file_path_from_root) + file_path_from_root = re.sub('^' + _root + '\/', '', file_path_from_root) return re.sub(r'[-./\s]', '_', file_path_from_root).upper() + '_' From 840357413c04c99e4af483741fdb42f246374dfc Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 11 Jul 2014 18:49:49 -0700 Subject: [PATCH 022/388] Style guide notes. --- README.md | 11 +++-------- docs/building.md | 2 +- docs/style_guide.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 9 deletions(-) create mode 100644 docs/style_guide.md diff --git a/README.md b/README.md index e0460e25c..5896228b7 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ that. ## Status -* Some code runs. [Insert any game name here] doesn't. +* Some code runs. [Insert any game name here] doesn't. Except Frogger 2. Yep. * Asserts! Crashes! Hangs! Blank screens! ## Disclaimer @@ -47,7 +47,8 @@ update gyp files/etc. ## Building See [building](docs/building.md) for setup and information about the -`xenia-build` script. +`xenia-build` script. When writing code, check the [style guide](docs/style_guide.md) +and be sure to clang-format! ## Contributors Wanted! @@ -55,16 +56,10 @@ Have some spare time, know advanced C++, and want to write an emulator? Contribute! There's a ton of work that needs to be done, a lot of which is wide open greenfield fun. -That said, the project is currently undergoing a lot of major foundational -development and core pieces are changing rapidly and poorly documented. -It'll be difficult to casually hack things in unless you know what you're -doing. - Fixes and optimizations are always welcome (please!), but in addition to that there are some major work areas still untouched: * Help work through missing functionality/bugs in game [compat](https://github.com/benvanik/xenia/issues?labels=compat) -* Write an [OpenGL driver](https://github.com/benvanik/xenia/issues/59) * Add input drivers for [OSX](https://github.com/benvanik/xenia/issues/61) and [PS4 controllers](https://github.com/benvanik/xenia/issues/60) (or anything else) * Start [hacking on audio](https://github.com/benvanik/xenia/issues/62) * Build a [virtual LIVE service](https://github.com/benvanik/xenia/issues/64) diff --git a/docs/building.md b/docs/building.md index 84fa7acf3..6e797a74e 100644 --- a/docs/building.md +++ b/docs/building.md @@ -44,7 +44,7 @@ keypresses: #### setup -Run this on initial checkout to pull down all dependencies and setup LLVM. +Run this on initial checkout to pull down all dependencies and submodules. xb setup diff --git a/docs/style_guide.md b/docs/style_guide.md new file mode 100644 index 000000000..4101f8946 --- /dev/null +++ b/docs/style_guide.md @@ -0,0 +1,45 @@ +# Style Guide + +The style guide can be summed up as 'clang-format with the Google style set'. +In addition, the [Google Style Guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml) +is followed and cpplint is the source of truth. + +Base rules: + +* 80 column line length max +* LF (Unix-style) line endings +* 2-space soft tabs, no TABs! +* [Google Style Guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml) for naming/casing/etc + +Code that really breaks from the formatting rules will not be accepted, as then +no one else can use clang-format on the code without also touching all your +lines. + +## Tools + +### clang-format + +clang-format with the Google style is used to format all files. I recommend +installing/wiring it up to your editor of choice so that you don't even have to +think about tabs and wrapping and such. + +#### Visual Studio + +Grab the official [experimental Visual Studio plugin](http://llvm.org/builds/). +To switch to the Google style go Tools -> Options -> LLVM/Clang -> ClangFormat +and set Style to Google. Then use ctrl-r/ctrl-f to trigger the formatting. +Unfortunately it only does the cursor by default, so you'll have to select the +whole doc and invoke it to get it all done. + +If you have a better option, let me know! + +#### Xcode + +Install [Alcatraz](http://alcatraz.io/) to get the [ClangFormat](https://github.com/travisjeffery/ClangFormat-Xcode) +package. Set it to use the Google style and format on save. Never think about +tabs or linefeeds or whatever again. + +### cpplint + +TODO(benvanik): write a cool script to do this/editor plugins. +In the future, the linter will run as a git commit hook and on travis. From bf882714d005472785a6cd845f614f07fb774327 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 12 Jul 2014 16:51:52 -0700 Subject: [PATCH 023/388] Cleaning up asserts and file/line macros. --- src/alloy/arena.cc | 2 +- src/alloy/backend/ivm/ivm_intcode.cc | 30 ++--- src/alloy/backend/ivm/ivm_stack.cc | 2 +- src/alloy/backend/x64/x64_code_cache.cc | 4 +- src/alloy/backend/x64/x64_emitter.cc | 14 +-- src/alloy/backend/x64/x64_sequence.inl | 28 ++--- src/alloy/backend/x64/x64_sequences.cc | 114 +++++++++--------- .../passes/constant_propagation_pass.cc | 6 +- .../passes/data_flow_analysis_pass.cc | 10 +- .../passes/register_allocation_pass.cc | 16 +-- src/alloy/compiler/passes/validation_pass.cc | 6 +- src/alloy/core.h | 10 +- src/alloy/frontend/ppc/ppc_disasm.cc | 2 +- src/alloy/frontend/ppc/ppc_emit-private.h | 2 +- src/alloy/frontend/ppc/ppc_emit_altivec.cc | 24 ++-- src/alloy/frontend/ppc/ppc_emit_alu.cc | 32 ++--- src/alloy/frontend/ppc/ppc_hir_builder.cc | 22 ++-- src/alloy/frontend/ppc/ppc_instr.cc | 6 +- src/alloy/hir/block.cc | 4 +- src/alloy/hir/hir_builder.cc | 18 +-- src/alloy/hir/value.cc | 92 +++++++------- src/alloy/hir/value.h | 42 +++---- src/alloy/memory.cc | 2 +- src/alloy/runtime/runtime.cc | 2 +- src/poly/assert.h | 77 ++++++++++++ src/poly/config.h | 2 +- src/poly/cxx_compat.h | 1 + src/poly/math.h | 23 +++- src/poly/poly.h | 1 + src/poly/sources.gypi | 2 + src/xenia/apu/audio_system.cc | 14 +-- src/xenia/apu/nop/nop_audio_system.cc | 2 +- src/xenia/apu/xaudio2/xaudio2_audio_driver.cc | 10 +- src/xenia/apu/xaudio2/xaudio2_audio_system.cc | 6 +- src/xenia/assert.h | 74 ------------ src/xenia/atomic.h | 1 + src/xenia/common.h | 3 +- src/xenia/core/path_posix.cc | 2 +- src/xenia/core/path_win.cc | 4 +- src/xenia/cpu/processor.cc | 4 +- src/xenia/cpu/xenon_memory.cc | 20 +-- src/xenia/cpu/xenon_thread_state.cc | 2 +- src/xenia/emulator.cc | 2 +- src/xenia/export_resolver.cc | 6 +- src/xenia/gpu/command_processor.cc | 26 ++-- src/xenia/gpu/d3d11/d3d11_buffer_resource.cc | 2 +- src/xenia/gpu/d3d11/d3d11_graphics_system.cc | 10 +- src/xenia/gpu/d3d11/d3d11_profiler_display.cc | 12 +- src/xenia/gpu/d3d11/d3d11_shader_resource.cc | 4 +- .../gpu/d3d11/d3d11_shader_translator.cc | 12 +- src/xenia/gpu/d3d11/d3d11_texture_resource.cc | 4 +- src/xenia/gpu/graphics_driver.cc | 12 +- src/xenia/gpu/graphics_system.cc | 8 +- src/xenia/gpu/nop/nop_graphics_system.cc | 6 +- src/xenia/gpu/shader_resource.cc | 18 +-- .../kernel/fs/devices/disc_image_device.cc | 4 +- .../kernel/fs/devices/disc_image_entry.cc | 4 +- .../kernel/fs/devices/host_path_device.cc | 4 +- .../kernel/fs/devices/host_path_entry.cc | 4 +- .../fs/devices/stfs_container_device.cc | 4 +- .../kernel/fs/devices/stfs_container_entry.cc | 4 +- src/xenia/kernel/fs/entry.cc | 2 +- src/xenia/kernel/kernel_state.cc | 6 +- src/xenia/kernel/object_table.cc | 8 +- src/xenia/kernel/objects/xevent.cc | 6 +- src/xenia/kernel/objects/xfile.h | 6 +- src/xenia/kernel/objects/xmutant.cc | 8 +- src/xenia/kernel/objects/xnotify_listener.cc | 2 +- src/xenia/kernel/objects/xsemaphore.cc | 4 +- src/xenia/kernel/objects/xthread.cc | 4 +- src/xenia/kernel/objects/xtimer.cc | 6 +- src/xenia/kernel/util/xex2.cc | 38 +++--- src/xenia/kernel/xam_content.cc | 2 +- src/xenia/kernel/xam_msg.cc | 8 +- src/xenia/kernel/xam_user.cc | 2 +- src/xenia/kernel/xboxkrnl_audio.cc | 8 +- src/xenia/kernel/xboxkrnl_debug.cc | 18 +-- src/xenia/kernel/xboxkrnl_hal.cc | 4 +- src/xenia/kernel/xboxkrnl_io.cc | 32 ++--- src/xenia/kernel/xboxkrnl_memory.cc | 22 ++-- src/xenia/kernel/xboxkrnl_misc.cc | 2 +- src/xenia/kernel/xboxkrnl_modules.cc | 10 +- src/xenia/kernel/xboxkrnl_rtl.cc | 32 ++--- src/xenia/kernel/xboxkrnl_strings.cc | 52 ++++---- src/xenia/kernel/xboxkrnl_threading.cc | 46 +++---- src/xenia/kernel/xboxkrnl_video.cc | 10 +- src/xenia/kernel/xboxkrnl_video.h | 2 +- src/xenia/kernel/xobject.cc | 14 +-- src/xenia/logging.h | 4 +- src/xenia/profiling.h | 4 +- src/xenia/sources.gypi | 1 - src/xenia/ui/window.cc | 2 +- 92 files changed, 636 insertions(+), 613 deletions(-) create mode 100644 src/poly/assert.h delete mode 100644 src/xenia/assert.h diff --git a/src/alloy/arena.cc b/src/alloy/arena.cc index 638adeabf..65f953e33 100644 --- a/src/alloy/arena.cc +++ b/src/alloy/arena.cc @@ -45,7 +45,7 @@ void* Arena::Alloc(size_t size) { if (active_chunk_->capacity - active_chunk_->offset < size + 4096) { Chunk* next = active_chunk_->next; if (!next) { - XEASSERT(size < chunk_size_); // need to support larger chunks + assert_true(size < chunk_size_, "need to support larger chunks"); next = new Chunk(chunk_size_); active_chunk_->next = next; } diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index 27ea32345..38fc97b06 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -159,8 +159,8 @@ uint32_t AllocOpRegister(TranslationContext& ctx, OpcodeSignatureType sig_type, uint32_t IntCode_INVALID(IntCodeState& ics, const IntCode* i); uint32_t IntCode_INVALID_TYPE(IntCodeState& ics, const IntCode* i); int DispatchToC(TranslationContext& ctx, Instr* i, IntCodeFn fn) { - XEASSERT(fn != IntCode_INVALID); - XEASSERT(fn != IntCode_INVALID_TYPE); + assert_true(fn != IntCode_INVALID); + assert_true(fn != IntCode_INVALID_TYPE); const OpcodeInfo* op = i->opcode; uint32_t sig = op->signature; @@ -194,11 +194,11 @@ int DispatchToC(TranslationContext& ctx, Instr* i, IntCodeFn fn) { } uint32_t IntCode_INVALID(IntCodeState& ics, const IntCode* i) { - XEASSERTALWAYS(); + assert_always(); return IA_NEXT; } uint32_t IntCode_INVALID_TYPE(IntCodeState& ics, const IntCode* i) { - XEASSERTALWAYS(); + assert_always(); return IA_NEXT; } int TranslateInvalid(TranslationContext& ctx, Instr* i) { @@ -368,7 +368,7 @@ uint32_t IntCode_CALL_XX(IntCodeState& ics, const IntCode* i, uint32_t reg) { if (!fn) { ics.thread_state->runtime()->ResolveFunction(symbol_info->address(), &fn); } - XEASSERTNOTNULL(fn); + assert_not_null(fn); // TODO(benvanik): proper tail call support, somehow. uint64_t return_address = (i->flags & CALL_TAIL) ? ics.return_address : ics.call_return_address; @@ -444,7 +444,7 @@ uint32_t IntCode_CALL_INDIRECT_XX(IntCodeState& ics, const IntCode* i, // Real call. Function* fn = NULL; ics.thread_state->runtime()->ResolveFunction(target, &fn); - XEASSERTNOTNULL(fn); + assert_not_null(fn); // TODO(benvanik): proper tail call support, somehow. uint64_t return_address = (i->flags & CALL_TAIL) ? ics.return_address : ics.call_return_address; @@ -2309,17 +2309,17 @@ uint32_t IntCode_ADD_I64_I64(IntCodeState& ics, const IntCode* i) { return IA_NEXT; } uint32_t IntCode_ADD_F32_F32(IntCodeState& ics, const IntCode* i) { - XEASSERT(!i->flags); + assert_true(!i->flags); ics.rf[i->dest_reg].f32 = ics.rf[i->src1_reg].f32 + ics.rf[i->src2_reg].f32; return IA_NEXT; } uint32_t IntCode_ADD_F64_F64(IntCodeState& ics, const IntCode* i) { - XEASSERT(!i->flags); + assert_true(!i->flags); ics.rf[i->dest_reg].f64 = ics.rf[i->src1_reg].f64 + ics.rf[i->src2_reg].f64; return IA_NEXT; } uint32_t IntCode_ADD_V128_V128(IntCodeState& ics, const IntCode* i) { - XEASSERT(!i->flags); + assert_true(!i->flags); const vec128_t& src1 = ics.rf[i->src1_reg].v128; const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; @@ -2380,13 +2380,13 @@ uint32_t IntCode_ADD_CARRY_I64_I64(IntCodeState& ics, const IntCode* i) { return IA_NEXT; } uint32_t IntCode_ADD_CARRY_F32_F32(IntCodeState& ics, const IntCode* i) { - XEASSERT(!i->flags); + assert_true(!i->flags); ics.rf[i->dest_reg].f32 = ics.rf[i->src1_reg].f32 + ics.rf[i->src2_reg].f32 + ics.rf[i->src3_reg].i8; return IA_NEXT; } uint32_t IntCode_ADD_CARRY_F64_F64(IntCodeState& ics, const IntCode* i) { - XEASSERT(!i->flags); + assert_true(!i->flags); ics.rf[i->dest_reg].f64 = ics.rf[i->src1_reg].f64 + ics.rf[i->src2_reg].f64 + ics.rf[i->src3_reg].i8; return IA_NEXT; @@ -2570,12 +2570,12 @@ uint32_t IntCode_SUB_I64_I64(IntCodeState& ics, const IntCode* i) { return IA_NEXT; } uint32_t IntCode_SUB_F32_F32(IntCodeState& ics, const IntCode* i) { - XEASSERT(!i->flags); + assert_true(!i->flags); ics.rf[i->dest_reg].f32 = ics.rf[i->src1_reg].f32 - ics.rf[i->src2_reg].f32; return IA_NEXT; } uint32_t IntCode_SUB_F64_F64(IntCodeState& ics, const IntCode* i) { - XEASSERT(!i->flags); + assert_true(!i->flags); ics.rf[i->dest_reg].f64 = ics.rf[i->src1_reg].f64 - ics.rf[i->src2_reg].f64; return IA_NEXT; } @@ -3564,7 +3564,7 @@ int Translate_BYTE_SWAP(TranslationContext& ctx, Instr* i) { uint32_t IntCode_CNTLZ_I8(IntCodeState& ics, const IntCode* i) { // CHECK - XEASSERTALWAYS(); + assert_always(); DWORD index; DWORD mask = ics.rf[i->src1_reg].i8; BOOLEAN is_nonzero = _BitScanReverse(&index, mask); @@ -3573,7 +3573,7 @@ uint32_t IntCode_CNTLZ_I8(IntCodeState& ics, const IntCode* i) { } uint32_t IntCode_CNTLZ_I16(IntCodeState& ics, const IntCode* i) { // CHECK - XEASSERTALWAYS(); + assert_always(); DWORD index; DWORD mask = ics.rf[i->src1_reg].i16; BOOLEAN is_nonzero = _BitScanReverse(&index, mask); diff --git a/src/alloy/backend/ivm/ivm_stack.cc b/src/alloy/backend/ivm/ivm_stack.cc index 62eb85e20..5177ed351 100644 --- a/src/alloy/backend/ivm/ivm_stack.cc +++ b/src/alloy/backend/ivm/ivm_stack.cc @@ -32,7 +32,7 @@ Register* IVMStack::Alloc(size_t register_count) { if (active_chunk_->capacity - active_chunk_->offset < size) { Chunk* next = active_chunk_->next; if (!next) { - XEASSERT(size < chunk_size_); // need to support larger chunks + assert_true(size < chunk_size_, "need to support larger chunks"); next = new Chunk(chunk_size_); next->prev = active_chunk_; active_chunk_->next = next; diff --git a/src/alloy/backend/x64/x64_code_cache.cc b/src/alloy/backend/x64/x64_code_cache.cc index 71a0b2d30..f204c2200 100644 --- a/src/alloy/backend/x64/x64_code_cache.cc +++ b/src/alloy/backend/x64/x64_code_cache.cc @@ -73,7 +73,7 @@ void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size, if (active_chunk_->capacity - active_chunk_->offset < code_size) { auto next = active_chunk_->next; if (!next) { - XEASSERT(code_size < chunk_size_); // need to support larger chunks + assert_true(code_size < chunk_size_, "need to support larger chunks"); next = new X64CodeChunk(chunk_size_); active_chunk_->next = next; } @@ -197,7 +197,7 @@ void X64CodeChunk::AddTableEntry(uint8_t* code, size_t code_size, size_t new_size = old_size * 2; auto new_table = (RUNTIME_FUNCTION*)xe_realloc(fn_table, old_size, new_size); - XEASSERTNOTNULL(new_table); + assert_not_null(new_table); if (!new_table) { return; } diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index 4b5383295..bb409622c 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -140,7 +140,7 @@ int X64Emitter::Emit(HIRBuilder* builder, size_t& out_stack_size) { // Adding or changing anything here must be matched! const bool emit_prolog = true; const size_t stack_size = StackLayout::GUEST_STACK_SIZE + stack_offset; - XEASSERT((stack_size + 8) % 16 == 0); + assert_true((stack_size + 8) % 16 == 0); out_stack_size = stack_size; stack_size_ = stack_size; if (emit_prolog) { @@ -167,7 +167,7 @@ int X64Emitter::Emit(HIRBuilder* builder, size_t& out_stack_size) { const Instr* new_tail = instr; if (!SelectSequence(*this, instr, &new_tail)) { // No sequence found! - XEASSERTALWAYS(); + assert_always(); XELOGE("Unable to process HIR opcode %s", instr->opcode->name); break; } @@ -231,7 +231,7 @@ void X64Emitter::Trap(uint16_t trap_type) { void X64Emitter::UnimplementedInstr(const hir::Instr* i) { // TODO(benvanik): notify debugger. db(0xCC); - XEASSERTALWAYS(); + assert_always(); } // Total size of ResolveFunctionSymbol call site in bytes. @@ -259,7 +259,7 @@ uint64_t ResolveFunctionSymbol(void* raw_context, uint64_t symbol_info_ptr) { // Resolve function. This will demand compile as required. Function* fn = NULL; thread_state->runtime()->ResolveFunction(symbol_info->address(), &fn); - XEASSERTNOTNULL(fn); + assert_not_null(fn); auto x64_fn = static_cast(fn); uint64_t addr = reinterpret_cast(x64_fn->machine_code()); @@ -307,7 +307,7 @@ void X64Emitter::Call(const hir::Instr* instr, // 5b ReloadECX(); size_t total_size = getSize() - start; - XEASSERT(total_size == TOTAL_RESOLVE_SIZE); + assert_true(total_size == TOTAL_RESOLVE_SIZE); // EDX overwritten, don't bother reloading. } @@ -334,7 +334,7 @@ uint64_t ResolveFunctionAddress(void* raw_context, uint64_t target_address) { Function* fn = NULL; thread_state->runtime()->ResolveFunction(target_address, &fn); - XEASSERTNOTNULL(fn); + assert_not_null(fn); auto x64_fn = static_cast(fn); return reinterpret_cast(x64_fn->machine_code()); } @@ -375,7 +375,7 @@ uint64_t UndefinedCallExtern(void* raw_context, uint64_t symbol_info_ptr) { } void X64Emitter::CallExtern(const hir::Instr* instr, const FunctionInfo* symbol_info) { - XEASSERT(symbol_info->behavior() == FunctionInfo::BEHAVIOR_EXTERN); + assert_true(symbol_info->behavior() == FunctionInfo::BEHAVIOR_EXTERN); if (!symbol_info->extern_handler()) { CallNative(UndefinedCallExtern, reinterpret_cast(symbol_info)); } else { diff --git a/src/alloy/backend/x64/x64_sequence.inl b/src/alloy/backend/x64/x64_sequence.inl index eae1096eb..50466b3af 100644 --- a/src/alloy/backend/x64/x64_sequence.inl +++ b/src/alloy/backend/x64/x64_sequence.inl @@ -133,7 +133,7 @@ struct ValueOp : Op, KEY_TYPE> { bool is_constant; virtual bool ConstantFitsIn32Reg() const { return true; } const REG_TYPE& reg() const { - XEASSERT(!is_constant); + assert_true(!is_constant); return reg_; } operator const REG_TYPE&() const { @@ -184,28 +184,28 @@ protected: template struct I8 : ValueOp, KEY_TYPE_V_I8, Reg8, int8_t, TAG> { const int8_t constant() const { - XEASSERT(is_constant); + assert_true(is_constant); return value->constant.i8; } }; template struct I16 : ValueOp, KEY_TYPE_V_I16, Reg16, int16_t, TAG> { const int16_t constant() const { - XEASSERT(is_constant); + assert_true(is_constant); return value->constant.i16; } }; template struct I32 : ValueOp, KEY_TYPE_V_I32, Reg32, int32_t, TAG> { const int32_t constant() const { - XEASSERT(is_constant); + assert_true(is_constant); return value->constant.i32; } }; template struct I64 : ValueOp, KEY_TYPE_V_I64, Reg64, int64_t, TAG> { const int64_t constant() const { - XEASSERT(is_constant); + assert_true(is_constant); return value->constant.i64; } bool ConstantFitsIn32Reg() const override { @@ -223,21 +223,21 @@ struct I64 : ValueOp, KEY_TYPE_V_I64, Reg64, int64_t, TAG> { template struct F32 : ValueOp, KEY_TYPE_V_F32, Xmm, float, TAG> { const float constant() const { - XEASSERT(is_constant); + assert_true(is_constant); return value->constant.f32; } }; template struct F64 : ValueOp, KEY_TYPE_V_F64, Xmm, double, TAG> { const double constant() const { - XEASSERT(is_constant); + assert_true(is_constant); return value->constant.f64; } }; template struct V128 : ValueOp, KEY_TYPE_V_V128, Xmm, vec128_t, TAG> { const vec128_t& constant() const { - XEASSERT(is_constant); + assert_true(is_constant); return value->constant.v128; } }; @@ -542,7 +542,7 @@ struct SingleSequence : public Sequence, T> { X64Emitter& e, const EmitArgType& i, const REG_REG_FN& reg_reg_fn, const REG_CONST_FN& reg_const_fn) { if (i.src1.is_constant) { - XEASSERT(!i.src2.is_constant); + assert_true(!i.src2.is_constant); if (i.dest == i.src2) { if (i.src1.ConstantFitsIn32Reg()) { reg_const_fn(e, i.dest, static_cast(i.src1.constant())); @@ -584,7 +584,7 @@ struct SingleSequence : public Sequence, T> { X64Emitter& e, const EmitArgType& i, const REG_REG_FN& reg_reg_fn, const REG_CONST_FN& reg_const_fn) { if (i.src1.is_constant) { - XEASSERT(!i.src2.is_constant); + assert_true(!i.src2.is_constant); if (i.dest == i.src2) { auto temp = GetTempReg(e); e.mov(temp, i.src2); @@ -632,7 +632,7 @@ struct SingleSequence : public Sequence, T> { static void EmitCommutativeBinaryXmmOp( X64Emitter& e, const EmitArgType& i, const FN& fn) { if (i.src1.is_constant) { - XEASSERT(!i.src2.is_constant); + assert_true(!i.src2.is_constant); e.LoadConstantXmm(e.xmm0, i.src1.constant()); fn(e, i.dest, e.xmm0, i.src2); } else if (i.src2.is_constant) { @@ -647,7 +647,7 @@ struct SingleSequence : public Sequence, T> { static void EmitAssociativeBinaryXmmOp( X64Emitter& e, const EmitArgType& i, const FN& fn) { if (i.src1.is_constant) { - XEASSERT(!i.src2.is_constant); + assert_true(!i.src2.is_constant); e.LoadConstantXmm(e.xmm0, i.src1.constant()); fn(e, i.dest, e.xmm0, i.src2); } else if (i.src2.is_constant) { @@ -663,7 +663,7 @@ struct SingleSequence : public Sequence, T> { X64Emitter& e, const EmitArgType& i, const REG_REG_FN& reg_reg_fn, const REG_CONST_FN& reg_const_fn) { if (i.src1.is_constant) { - XEASSERT(!i.src2.is_constant); + assert_true(!i.src2.is_constant); if (i.src1.ConstantFitsIn32Reg()) { reg_const_fn(e, i.src2, static_cast(i.src1.constant())); } else { @@ -688,7 +688,7 @@ struct SingleSequence : public Sequence, T> { X64Emitter& e, const EmitArgType& i, const REG_REG_FN& reg_reg_fn, const REG_CONST_FN& reg_const_fn) { if (i.src1.is_constant) { - XEASSERT(!i.src2.is_constant); + assert_true(!i.src2.is_constant); if (i.src1.ConstantFitsIn32Reg()) { reg_const_fn(e, i.dest, i.src2, static_cast(i.src1.constant()), true); } else { diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index 496ffac17..f59f465db 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -1016,7 +1016,7 @@ EMITTER(LOAD_VECTOR_SHL_I8, MATCH(I, I8<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { if (i.src1.is_constant) { auto sh = i.src1.constant(); - XEASSERT(sh < XECOUNT(lvsl_table)); + assert_true(sh < XECOUNT(lvsl_table)); e.mov(e.rax, (uintptr_t)&lvsl_table[sh]); e.vmovaps(i.dest, e.ptr[e.rax]); } else { @@ -1068,7 +1068,7 @@ EMITTER(LOAD_VECTOR_SHR_I8, MATCH(I, I8<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { if (i.src1.is_constant) { auto sh = i.src1.constant(); - XEASSERT(sh < XECOUNT(lvsr_table)); + assert_true(sh < XECOUNT(lvsr_table)); e.mov(e.rax, (uintptr_t)&lvsr_table[sh]); e.vmovaps(i.dest, e.ptr[e.rax]); } else { @@ -2176,28 +2176,28 @@ EMITTER_ASSOCIATIVE_COMPARE_FLT_XX(UGE, setae); // https://code.google.com/p/corkami/wiki/x86oddities EMITTER(DID_CARRY_I8, MATCH(I, I8<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { - XEASSERT(!i.src1.is_constant); + assert_true(!i.src1.is_constant); e.LoadEflags(); e.setc(i.dest); } }; EMITTER(DID_CARRY_I16, MATCH(I, I16<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { - XEASSERT(!i.src1.is_constant); + assert_true(!i.src1.is_constant); e.LoadEflags(); e.setc(i.dest); } }; EMITTER(DID_CARRY_I32, MATCH(I, I32<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { - XEASSERT(!i.src1.is_constant); + assert_true(!i.src1.is_constant); e.LoadEflags(); e.setc(i.dest); } }; EMITTER(DID_CARRY_I64, MATCH(I, I64<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { - XEASSERT(!i.src1.is_constant); + assert_true(!i.src1.is_constant); e.LoadEflags(); e.setc(i.dest); } @@ -2629,8 +2629,8 @@ EMITTER(VECTOR_ADD, MATCH(I, V128<>, V128<>>)) { if (saturate) { if (is_unsigned) { // We reuse all these temps... - XEASSERT(src1 != e.xmm0 && src1 != e.xmm1 && src1 != e.xmm2); - XEASSERT(src2 != e.xmm0 && src2 != e.xmm1 && src2 != e.xmm2); + assert_true(src1 != e.xmm0 && src1 != e.xmm1 && src1 != e.xmm2); + assert_true(src2 != e.xmm0 && src2 != e.xmm1 && src2 != e.xmm2); // Clamp to 0xFFFFFFFF. // Wish there was a vpaddusd... // | A | B | C | D | @@ -2655,7 +2655,7 @@ EMITTER(VECTOR_ADD, MATCH(I, V128<>, V128<>>)) { // dest.f[n] = xmm1.f[n] ? xmm1.f[n] : dest.f[n]; e.vblendvps(dest, dest, e.xmm1, e.xmm1); } else { - XEASSERTALWAYS(); + assert_always(); } } else { e.vpaddd(dest, src1, src2); @@ -2664,7 +2664,7 @@ EMITTER(VECTOR_ADD, MATCH(I, V128<>, V128<>>)) { case FLOAT32_TYPE: e.vaddps(dest, src1, src2); break; - default: XEASSERTUNHANDLEDCASE(part_type); break; + default: assert_unhandled_case(part_type); break; } }); } @@ -2728,7 +2728,7 @@ EMITTER(SUB_I64, MATCH(I, I64<>, I64<>>)) { }; EMITTER(SUB_F32, MATCH(I, F32<>, F32<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { - XEASSERT(!i.instr->flags); + assert_true(!i.instr->flags); EmitAssociativeBinaryXmmOp(e, i, [](X64Emitter& e, Xmm dest, Xmm src1, Xmm src2) { e.vsubss(dest, src1, src2); @@ -2737,7 +2737,7 @@ EMITTER(SUB_F32, MATCH(I, F32<>, F32<>>)) { }; EMITTER(SUB_F64, MATCH(I, F64<>, F64<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { - XEASSERT(!i.instr->flags); + assert_true(!i.instr->flags); EmitAssociativeBinaryXmmOp(e, i, [](X64Emitter& e, Xmm dest, Xmm src1, Xmm src2) { e.vsubsd(dest, src1, src2); @@ -2746,7 +2746,7 @@ EMITTER(SUB_F64, MATCH(I, F64<>, F64<>>)) { }; EMITTER(SUB_V128, MATCH(I, V128<>, V128<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { - XEASSERT(!i.instr->flags); + assert_true(!i.instr->flags); EmitAssociativeBinaryXmmOp(e, i, [](X64Emitter& e, Xmm dest, Xmm src1, Xmm src2) { e.vsubps(dest, src1, src2); @@ -2774,7 +2774,7 @@ EMITTER(MUL_I8, MATCH(I, I8<>, I8<>>)) { // dest hi, dest low = src * edx // TODO(benvanik): place src2 in edx? if (i.src1.is_constant) { - XEASSERT(!i.src2.is_constant); + assert_true(!i.src2.is_constant); e.movzx(e.edx, i.src2); e.mov(e.eax, static_cast(i.src1.constant())); e.mulx(e.edx, i.dest.reg().cvt32(), e.eax); @@ -2793,7 +2793,7 @@ EMITTER(MUL_I16, MATCH(I, I16<>, I16<>>)) { // dest hi, dest low = src * edx // TODO(benvanik): place src2 in edx? if (i.src1.is_constant) { - XEASSERT(!i.src2.is_constant); + assert_true(!i.src2.is_constant); e.movzx(e.edx, i.src2); e.mov(e.ax, static_cast(i.src1.constant())); e.mulx(e.edx, i.dest.reg().cvt32(), e.eax); @@ -2813,7 +2813,7 @@ EMITTER(MUL_I32, MATCH(I, I32<>, I32<>>)) { // dest hi, dest low = src * edx // TODO(benvanik): place src2 in edx? if (i.src1.is_constant) { - XEASSERT(!i.src2.is_constant); + assert_true(!i.src2.is_constant); e.mov(e.edx, i.src2); e.mov(e.eax, i.src1.constant()); e.mulx(e.edx, i.dest, e.eax); @@ -2833,7 +2833,7 @@ EMITTER(MUL_I64, MATCH(I, I64<>, I64<>>)) { // dest hi, dest low = src * rdx // TODO(benvanik): place src2 in edx? if (i.src1.is_constant) { - XEASSERT(!i.src2.is_constant); + assert_true(!i.src2.is_constant); e.mov(e.rdx, i.src2); e.mov(e.rax, i.src1.constant()); e.mulx(e.rdx, i.dest, e.rax); @@ -2850,7 +2850,7 @@ EMITTER(MUL_I64, MATCH(I, I64<>, I64<>>)) { }; EMITTER(MUL_F32, MATCH(I, F32<>, F32<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { - XEASSERT(!i.instr->flags); + assert_true(!i.instr->flags); EmitCommutativeBinaryXmmOp(e, i, [](X64Emitter& e, Xmm dest, Xmm src1, Xmm src2) { e.vmulss(dest, src1, src2); @@ -2859,7 +2859,7 @@ EMITTER(MUL_F32, MATCH(I, F32<>, F32<>>)) { }; EMITTER(MUL_F64, MATCH(I, F64<>, F64<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { - XEASSERT(!i.instr->flags); + assert_true(!i.instr->flags); EmitCommutativeBinaryXmmOp(e, i, [](X64Emitter& e, Xmm dest, Xmm src1, Xmm src2) { e.vmulsd(dest, src1, src2); @@ -2868,7 +2868,7 @@ EMITTER(MUL_F64, MATCH(I, F64<>, F64<>>)) { }; EMITTER(MUL_V128, MATCH(I, V128<>, V128<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { - XEASSERT(!i.instr->flags); + assert_true(!i.instr->flags); EmitCommutativeBinaryXmmOp(e, i, [](X64Emitter& e, Xmm dest, Xmm src1, Xmm src2) { e.vmulps(dest, src1, src2); @@ -2993,7 +2993,7 @@ EMITTER(DIV_I8, MATCH(I, I8<>, I8<>>)) { // NOTE: RDX clobbered. bool clobbered_rcx = false; if (i.src2.is_constant) { - XEASSERT(!i.src1.is_constant); + assert_true(!i.src1.is_constant); clobbered_rcx = true; e.mov(e.cl, i.src2.constant()); if (i.instr->flags & ARITHMETIC_UNSIGNED) { @@ -3032,7 +3032,7 @@ EMITTER(DIV_I16, MATCH(I, I16<>, I16<>>)) { // NOTE: RDX clobbered. bool clobbered_rcx = false; if (i.src2.is_constant) { - XEASSERT(!i.src1.is_constant); + assert_true(!i.src1.is_constant); clobbered_rcx = true; e.mov(e.cx, i.src2.constant()); if (i.instr->flags & ARITHMETIC_UNSIGNED) { @@ -3081,7 +3081,7 @@ EMITTER(DIV_I32, MATCH(I, I32<>, I32<>>)) { // NOTE: RDX clobbered. bool clobbered_rcx = false; if (i.src2.is_constant) { - XEASSERT(!i.src1.is_constant); + assert_true(!i.src1.is_constant); clobbered_rcx = true; e.mov(e.ecx, i.src2.constant()); if (i.instr->flags & ARITHMETIC_UNSIGNED) { @@ -3130,7 +3130,7 @@ EMITTER(DIV_I64, MATCH(I, I64<>, I64<>>)) { // NOTE: RDX clobbered. bool clobbered_rcx = false; if (i.src2.is_constant) { - XEASSERT(!i.src1.is_constant); + assert_true(!i.src1.is_constant); clobbered_rcx = true; e.mov(e.rcx, i.src2.constant()); if (i.instr->flags & ARITHMETIC_UNSIGNED) { @@ -3176,7 +3176,7 @@ EMITTER(DIV_I64, MATCH(I, I64<>, I64<>>)) { }; EMITTER(DIV_F32, MATCH(I, F32<>, F32<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { - XEASSERT(!i.instr->flags); + assert_true(!i.instr->flags); EmitAssociativeBinaryXmmOp(e, i, [](X64Emitter& e, Xmm dest, Xmm src1, Xmm src2) { e.vdivss(dest, src1, src2); @@ -3185,7 +3185,7 @@ EMITTER(DIV_F32, MATCH(I, F32<>, F32<>>)) { }; EMITTER(DIV_F64, MATCH(I, F64<>, F64<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { - XEASSERT(!i.instr->flags); + assert_true(!i.instr->flags); EmitAssociativeBinaryXmmOp(e, i, [](X64Emitter& e, Xmm dest, Xmm src1, Xmm src2) { e.vdivsd(dest, src1, src2); @@ -3194,7 +3194,7 @@ EMITTER(DIV_F64, MATCH(I, F64<>, F64<>>)) { }; EMITTER(DIV_V128, MATCH(I, V128<>, V128<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { - XEASSERT(!i.instr->flags); + assert_true(!i.instr->flags); EmitAssociativeBinaryXmmOp(e, i, [](X64Emitter& e, Xmm dest, Xmm src1, Xmm src2) { e.vdivps(dest, src1, src2); @@ -3380,7 +3380,7 @@ EMITTER(NEG_F64, MATCH(I, F64<>>)) { }; EMITTER(NEG_V128, MATCH(I, V128<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { - XEASSERT(!i.instr->flags); + assert_true(!i.instr->flags); e.vxorps(i.dest, i.src1, e.GetXmmConstPtr(XMMSignMaskPS)); } }; @@ -3483,7 +3483,7 @@ EMITTER(POW2_F32, MATCH(I, F32<>>)) { return _mm_load_ss(&result); } static void Emit(X64Emitter& e, const EmitArgType& i) { - XEASSERTALWAYS(); + assert_always(); e.lea(e.r8, e.StashXmm(i.src1)); e.CallNativeSafe(EmulatePow2); e.vmovaps(i.dest, e.xmm0); @@ -3495,7 +3495,7 @@ EMITTER(POW2_F64, MATCH(I, F64<>>)) { return _mm_load_sd(&result); } static void Emit(X64Emitter& e, const EmitArgType& i) { - XEASSERTALWAYS(); + assert_always(); e.lea(e.r8, e.StashXmm(i.src1)); e.CallNativeSafe(EmulatePow2); e.vmovaps(i.dest, e.xmm0); @@ -3534,7 +3534,7 @@ EMITTER(LOG2_F32, MATCH(I, F32<>>)) { return _mm_load_ss(&result); } static void Emit(X64Emitter& e, const EmitArgType& i) { - XEASSERTALWAYS(); + assert_always(); e.lea(e.r8, e.StashXmm(i.src1)); e.CallNativeSafe(EmulateLog2); e.vmovaps(i.dest, e.xmm0); @@ -3546,7 +3546,7 @@ EMITTER(LOG2_F64, MATCH(I, F64<>>)) { return _mm_load_sd(&result); } static void Emit(X64Emitter& e, const EmitArgType& i) { - XEASSERTALWAYS(); + assert_always(); e.lea(e.r8, e.StashXmm(i.src1)); e.CallNativeSafe(EmulateLog2); e.vmovaps(i.dest, e.xmm0); @@ -3958,7 +3958,7 @@ EMITTER(VECTOR_SHL_V128, MATCH(I, V128<>, V128<>>)) { EmitInt32(e, i); break; default: - XEASSERTALWAYS(); + assert_always(); break; } } @@ -3990,7 +3990,7 @@ EMITTER(VECTOR_SHL_V128, MATCH(I, V128<>, V128<>>)) { } } else { // Counts differ, so pre-mask and load constant. - XEASSERTALWAYS(); + assert_always(); } } else { // Fully variable shift. @@ -4046,11 +4046,11 @@ EMITTER(VECTOR_SHL_V128, MATCH(I, V128<>, V128<>>)) { e.vpsllw(i.dest, i.src1, shamt.s8[0] & 0xF); } else { // Counts differ, so pre-mask and load constant. - XEASSERTALWAYS(); + assert_always(); } } else { // Fully variable shift. - XEASSERTALWAYS(); + assert_always(); } } static void EmitInt32(X64Emitter& e, const EmitArgType& i) { @@ -4105,7 +4105,7 @@ EMITTER(VECTOR_SHR_V128, MATCH(I, V128<>, V128<>>)) { EmitInt32(e, i); break; default: - XEASSERTALWAYS(); + assert_always(); break; } } @@ -4137,11 +4137,11 @@ EMITTER(VECTOR_SHR_V128, MATCH(I, V128<>, V128<>>)) { } } else { // Counts differ, so pre-mask and load constant. - XEASSERTALWAYS(); + assert_always(); } } else { // Fully variable shift. - XEASSERTALWAYS(); + assert_always(); } } static void EmitInt16(X64Emitter& e, const EmitArgType& i) { @@ -4159,11 +4159,11 @@ EMITTER(VECTOR_SHR_V128, MATCH(I, V128<>, V128<>>)) { e.vpsrlw(i.dest, i.src1, shamt.s8[0] & 0xF); } else { // Counts differ, so pre-mask and load constant. - XEASSERTALWAYS(); + assert_always(); } } else { // Fully variable shift. - XEASSERTALWAYS(); + assert_always(); } } static void EmitInt32(X64Emitter& e, const EmitArgType& i) { @@ -4215,7 +4215,7 @@ EMITTER(VECTOR_SHA_V128, MATCH(I, V128<>, V128<>>)) { e.vpsravd(i.dest, i.src1, e.xmm0); break; default: - XEASSERTALWAYS(); + assert_always(); break; } } @@ -4375,14 +4375,14 @@ EMITTER(EXTRACT_I8, MATCH(I, V128<>, I8<>>)) { if (i.src2.is_constant) { e.vpextrb(i.dest.reg().cvt32(), i.src1, VEC128_B(i.src2.constant())); } else { - XEASSERTALWAYS(); + assert_always(); // TODO(benvanik): try out hlide's version: // e.mov(e.eax, 0x80808003); // e.xor(e.al, i.src2); // e.and(e.al, 15); // e.vmovd(e.xmm0, e.eax); // e.vpshufb(e.xmm0, i.src1, e.xmm0); - // e.vmovd(i.dest.reg().cvt32(), e.xmm0); + // e.vmovd(i.dest.reg().cvt32(), e.xmm0); } } }; @@ -4443,7 +4443,7 @@ EMITTER(EXTRACT_F32, MATCH(I, V128<>, I8<>>)) { if (i.src2.is_constant) { e.vextractps(i.dest, i.src1, VEC128_F(i.src2.constant())); } else { - XEASSERTALWAYS(); + assert_always(); // TODO(benvanik): try out hlide's version: // e.mov(e.eax, 3); // e.and(e.al, i.src2); // eax = [(i&3), 0, 0, 0] @@ -4573,7 +4573,7 @@ EMITTER(PERMUTE_I32, MATCH(I, I32<>, V128<>, V128<>>)) { } } else { // Permute by non-constant. - XEASSERTALWAYS(); + assert_always(); } } }; @@ -4650,9 +4650,9 @@ EMITTER(SWIZZLE, MATCH(I, V128<>, OffsetOp>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { auto element_type = i.instr->flags; if (element_type == INT8_TYPE) { - XEASSERTALWAYS(); + assert_always(); } else if (element_type == INT16_TYPE) { - XEASSERTALWAYS(); + assert_always(); } else if (element_type == INT32_TYPE || element_type == FLOAT32_TYPE) { uint8_t swizzle_mask = static_cast(i.src2.value); swizzle_mask = @@ -4662,9 +4662,9 @@ EMITTER(SWIZZLE, MATCH(I, V128<>, OffsetOp>)) { (((swizzle_mask >> 0) & 0x3) << 6); e.vpshufd(i.dest, i.src1, swizzle_mask); } else if (element_type == INT64_TYPE || element_type == FLOAT64_TYPE) { - XEASSERTALWAYS(); + assert_always(); } else { - XEASSERTALWAYS(); + assert_always(); } } }; @@ -4703,7 +4703,7 @@ EMITTER(PACK, MATCH(I, V128<>>)) { case PACK_TYPE_S16_IN_32_HI: EmitS16_IN_32_HI(e, i); break; - default: XEASSERTUNHANDLEDCASE(i.instr->flags); break; + default: assert_unhandled_case(i.instr->flags); break; } } static void EmitD3DCOLOR(X64Emitter& e, const EmitArgType& i) { @@ -4755,19 +4755,19 @@ EMITTER(PACK, MATCH(I, V128<>>)) { e.vpblendw(i.dest, e.xmm0, B11110000); } static void EmitSHORT_2(X64Emitter& e, const EmitArgType& i) { - XEASSERTALWAYS(); + assert_always(); } static void EmitS8_IN_16_LO(X64Emitter& e, const EmitArgType& i) { - XEASSERTALWAYS(); + assert_always(); } static void EmitS8_IN_16_HI(X64Emitter& e, const EmitArgType& i) { - XEASSERTALWAYS(); + assert_always(); } static void EmitS16_IN_32_LO(X64Emitter& e, const EmitArgType& i) { - XEASSERTALWAYS(); + assert_always(); } static void EmitS16_IN_32_HI(X64Emitter& e, const EmitArgType& i) { - XEASSERTALWAYS(); + assert_always(); } }; EMITTER_OPCODE_TABLE( @@ -4805,7 +4805,7 @@ EMITTER(UNPACK, MATCH(I, V128<>>)) { case PACK_TYPE_S16_IN_32_HI: EmitS16_IN_32_HI(e, i); break; - default: XEASSERTUNHANDLEDCASE(i.instr->flags); break; + default: assert_unhandled_case(i.instr->flags); break; } } static void EmitD3DCOLOR(X64Emitter& e, const EmitArgType& i) { diff --git a/src/alloy/compiler/passes/constant_propagation_pass.cc b/src/alloy/compiler/passes/constant_propagation_pass.cc index d9f2b8620..330e93fac 100644 --- a/src/alloy/compiler/passes/constant_propagation_pass.cc +++ b/src/alloy/compiler/passes/constant_propagation_pass.cc @@ -277,13 +277,13 @@ int ConstantPropagationPass::Run(HIRBuilder* builder) { break; case OPCODE_DID_CARRY: - XEASSERT(!i->src1.value->IsConstant()); + assert_true(!i->src1.value->IsConstant()); break; case OPCODE_DID_OVERFLOW: - XEASSERT(!i->src1.value->IsConstant()); + assert_true(!i->src1.value->IsConstant()); break; case OPCODE_DID_SATURATE: - XEASSERT(!i->src1.value->IsConstant()); + assert_true(!i->src1.value->IsConstant()); break; case OPCODE_ADD: diff --git a/src/alloy/compiler/passes/data_flow_analysis_pass.cc b/src/alloy/compiler/passes/data_flow_analysis_pass.cc index 4c82d527c..28b0a6d5a 100644 --- a/src/alloy/compiler/passes/data_flow_analysis_pass.cc +++ b/src/alloy/compiler/passes/data_flow_analysis_pass.cc @@ -97,7 +97,7 @@ void DataFlowAnalysisPass::AnalyzeFlow(HIRBuilder* builder, if (v->def && v->def->block != block) { \ incoming_values.set(v->ordinal); \ } \ - XEASSERT(v->ordinal < max_value_estimate); \ + assert_true(v->ordinal < max_value_estimate); \ value_map[v->ordinal] = v; if (GET_OPCODE_SIG_TYPE_SRC1(signature) == OPCODE_SIG_TYPE_V) { SET_INCOMING_VALUE(instr->src1.value); @@ -128,7 +128,7 @@ void DataFlowAnalysisPass::AnalyzeFlow(HIRBuilder* builder, auto outgoing_ordinal = outgoing_values.find_first(); while (outgoing_ordinal != -1) { Value* src_value = value_map[outgoing_ordinal]; - XEASSERTNOTNULL(src_value); + assert_not_null(src_value); if (!src_value->local_slot) { src_value->local_slot = builder->AllocLocal(src_value->type); } @@ -142,7 +142,7 @@ void DataFlowAnalysisPass::AnalyzeFlow(HIRBuilder* builder, while (def_next && def_next->opcode->flags & OPCODE_FLAG_PAIRED_PREV) { def_next = def_next->next; } - XEASSERTNOTNULL(def_next); + assert_not_null(def_next); builder->last_instr()->MoveBefore(def_next); // We don't need it in the incoming list. @@ -153,7 +153,7 @@ void DataFlowAnalysisPass::AnalyzeFlow(HIRBuilder* builder, while (tail && tail->opcode->flags & OPCODE_FLAG_BRANCH) { tail = tail->prev; } - XEASSERTNOTZERO(tail); + assert_not_zero(tail); builder->last_instr()->MoveBefore(tail->next); } @@ -164,7 +164,7 @@ void DataFlowAnalysisPass::AnalyzeFlow(HIRBuilder* builder, auto incoming_ordinal = incoming_values.find_first(); while (incoming_ordinal != -1) { Value* src_value = value_map[incoming_ordinal]; - XEASSERTNOTNULL(src_value); + assert_not_null(src_value); if (!src_value->local_slot) { src_value->local_slot = builder->AllocLocal(src_value->type); } diff --git a/src/alloy/compiler/passes/register_allocation_pass.cc b/src/alloy/compiler/passes/register_allocation_pass.cc index 26840a20f..6f5189ba7 100644 --- a/src/alloy/compiler/passes/register_allocation_pass.cc +++ b/src/alloy/compiler/passes/register_allocation_pass.cc @@ -114,13 +114,13 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) { // dest. has_preferred_reg = true; preferred_reg = instr->src1.value->reg; - XEASSERTNOTNULL(preferred_reg.set); + assert_not_null(preferred_reg.set); } } if (GET_OPCODE_SIG_TYPE_DEST(signature) == OPCODE_SIG_TYPE_V) { // Must not have been set already. - XEASSERTNULL(instr->dest->reg.set); + assert_null(instr->dest->reg.set); // Sort the usage list. We depend on this in future uses of this // variable. @@ -144,7 +144,7 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) { if (!SpillOneRegister(builder, instr->dest->type)) { // Unable to spill anything - this shouldn't happen. XELOGE("Unable to spill any registers"); - XEASSERTALWAYS(); + assert_always(); return 1; } @@ -152,7 +152,7 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) { if (!TryAllocateRegister(instr->dest)) { // Boned. XELOGE("Register allocation failed"); - XEASSERTALWAYS(); + assert_always(); return 1; } } @@ -330,14 +330,14 @@ bool RegisterAllocationPass::SpillOneRegister(HIRBuilder* builder, DumpUsage("SpillOneRegister (pre)"); // Pick the one with the furthest next use. - XEASSERT(!usage_set->upcoming_uses.empty()); + assert_true(!usage_set->upcoming_uses.empty()); auto furthest_usage = std::max_element(usage_set->upcoming_uses.begin(), usage_set->upcoming_uses.end(), RegisterUsage::Comparer()); auto spill_value = furthest_usage->value; Value::Use* prev_use = furthest_usage->use->prev; Value::Use* next_use = furthest_usage->use; - XEASSERTNOTNULL(next_use); + assert_not_null(next_use); usage_set->upcoming_uses.erase(furthest_usage); DumpUsage("SpillOneRegister (post)"); const auto reg = spill_value->reg; @@ -361,11 +361,11 @@ bool RegisterAllocationPass::SpillOneRegister(HIRBuilder* builder, builder->StoreLocal(spill_value->local_slot, spill_value); auto spill_store = builder->last_instr(); auto spill_store_use = spill_store->src2_use; - XEASSERTNULL(spill_store_use->prev); + assert_null(spill_store_use->prev); if (prev_use && prev_use->instr->opcode->flags & OPCODE_FLAG_PAIRED_PREV) { // Instruction is paired. This is bad. We will insert the spill after the // paired instruction. - XEASSERTNOTNULL(prev_use->instr->next); + assert_not_null(prev_use->instr->next); spill_store->MoveBefore(prev_use->instr->next); // Update last use. diff --git a/src/alloy/compiler/passes/validation_pass.cc b/src/alloy/compiler/passes/validation_pass.cc index a199e9416..27e85f7b6 100644 --- a/src/alloy/compiler/passes/validation_pass.cc +++ b/src/alloy/compiler/passes/validation_pass.cc @@ -45,7 +45,7 @@ int ValidationPass::Run(HIRBuilder* builder) { while (block) { auto label = block->label_head; while (label) { - XEASSERT(label->block == block); + assert_true(label->block == block); if (label->block != block) { return 1; } @@ -67,7 +67,7 @@ int ValidationPass::Run(HIRBuilder* builder) { } int ValidationPass::ValidateInstruction(Block* block, Instr* instr) { - XEASSERT(instr->block == block); + assert_true(instr->block == block); if (instr->block != block) { return 1; } @@ -95,7 +95,7 @@ int ValidationPass::ValidateInstruction(Block* block, Instr* instr) { int ValidationPass::ValidateValue(Block* block, Instr* instr, Value* value) { // if (value->def) { // auto def = value->def; - // XEASSERT(def->block == block); + // assert_true(def->block == block); // if (def->block != block) { // return 1; // } diff --git a/src/alloy/core.h b/src/alloy/core.h index b7f5dae91..9e25f171d 100644 --- a/src/alloy/core.h +++ b/src/alloy/core.h @@ -11,7 +11,15 @@ #define ALLOY_CORE_H_ // TODO(benvanik): move the common stuff into here? -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include diff --git a/src/alloy/frontend/ppc/ppc_disasm.cc b/src/alloy/frontend/ppc/ppc_disasm.cc index c362cae2c..41f8c928a 100644 --- a/src/alloy/frontend/ppc/ppc_disasm.cc +++ b/src/alloy/frontend/ppc/ppc_disasm.cc @@ -412,7 +412,7 @@ void Disasm_rld(InstrData& i, StringBuffer* str) { i.MD.Rc ? "." : "", i.MD.RA, i.MD.RT, (i.MD.SH5 << 5) | i.MD.SH, (i.MD.MB5 << 5) | i.MD.MB); } else { - XEASSERTALWAYS(); + assert_always(); } } void Disasm_rlwim(InstrData& i, StringBuffer* str) { diff --git a/src/alloy/frontend/ppc/ppc_emit-private.h b/src/alloy/frontend/ppc/ppc_emit-private.h index 5d717e69b..3acb10ffe 100644 --- a/src/alloy/frontend/ppc/ppc_emit-private.h +++ b/src/alloy/frontend/ppc/ppc_emit-private.h @@ -23,7 +23,7 @@ namespace ppc { RegisterInstrEmit(opcode, (InstrEmitFn)InstrEmit_##name); #define XEINSTRNOTIMPLEMENTED() -//#define XEINSTRNOTIMPLEMENTED XEASSERTALWAYS +//#define XEINSTRNOTIMPLEMENTED assert_trueALWAYS //#define XEINSTRNOTIMPLEMENTED() __debugbreak() } // namespace ppc diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index 583e1c00b..c3a4b5db8 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -62,7 +62,7 @@ Value* CalculateEA_0(PPCHIRBuilder& f, uint32_t ra, uint32_t rb); #define VX128_R_VB128 (i.VX128_R.VB128l | (i.VX128_R.VB128h << 5)) unsigned int xerotl(unsigned int value, unsigned int shift) { - XEASSERT(shift < 32); + assert_true(shift < 32); return shift == 0 ? value : ((value << shift) | (value >> (32 - shift))); } @@ -588,7 +588,7 @@ int InstrEmit_vcmpxxfp_(PPCHIRBuilder& f, InstrData& i, vcmpxxfp_op cmpop, v = f.VectorCompareSGE(f.LoadVR(va), f.LoadVR(vb), FLOAT32_TYPE); break; default: - XEASSERTUNHANDLEDCASE(cmpop); + assert_unhandled_case(cmpop); return 1; } if (rc) { @@ -648,7 +648,7 @@ int InstrEmit_vcmpxxi_(PPCHIRBuilder& f, InstrData& i, vcmpxxi_op cmpop, v = f.VectorCompareEQ(f.LoadVR(va), f.LoadVR(vb), INT32_TYPE); break; default: - XEASSERTUNHANDLEDCASE(width); + assert_unhandled_case(width); return 1; } break; @@ -664,7 +664,7 @@ int InstrEmit_vcmpxxi_(PPCHIRBuilder& f, InstrData& i, vcmpxxi_op cmpop, v = f.VectorCompareSGT(f.LoadVR(va), f.LoadVR(vb), INT32_TYPE); break; default: - XEASSERTUNHANDLEDCASE(width); + assert_unhandled_case(width); return 1; } break; @@ -680,12 +680,12 @@ int InstrEmit_vcmpxxi_(PPCHIRBuilder& f, InstrData& i, vcmpxxi_op cmpop, v = f.VectorCompareUGT(f.LoadVR(va), f.LoadVR(vb), INT32_TYPE); break; default: - XEASSERTUNHANDLEDCASE(width); + assert_unhandled_case(width); return 1; } break; default: - XEASSERTUNHANDLEDCASE(cmpop); + assert_unhandled_case(cmpop); return 1; } if (rc) { @@ -1233,7 +1233,7 @@ XEEMITTER(vrlimi128, VX128_4(6, 1808), VX128_4)(PPCHIRBuilder& f, swizzle_mask = SWIZZLE_XYZW_TO_WXYZ; break; default: - XEASSERTALWAYS(); + assert_always(); return 1; } v = f.Swizzle(f.LoadVR(vb), FLOAT32_TYPE, swizzle_mask); @@ -1707,7 +1707,7 @@ XEEMITTER(vupkhsh, 0x1000024E, VX)(PPCHIRBuilder& f, InstrData& i) { } XEEMITTER(vupkhsh128, 0x100002CE, VX)(PPCHIRBuilder& f, InstrData& i) { uint32_t va = VX128_VA128; - XEASSERTZERO(va); + assert_zero(va); return InstrEmit_vupkhsh_(f, VX128_VD128, VX128_VB128); } @@ -1722,7 +1722,7 @@ XEEMITTER(vupklsh, 0x100002CE, VX)(PPCHIRBuilder& f, InstrData& i) { } XEEMITTER(vupklsh128, 0x100002CE, VX)(PPCHIRBuilder& f, InstrData& i) { uint32_t va = VX128_VA128; - XEASSERTZERO(va); + assert_zero(va); return InstrEmit_vupklsh_(f, VX128_VD128, VX128_VB128); } @@ -1784,7 +1784,7 @@ XEEMITTER(vpkd3d128, VX128_4(6, 1552), VX128_4)(PPCHIRBuilder& f, v = f.Pack(v, PACK_TYPE_FLOAT16_4); break; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); return 1; } // http://hlssmod.net/he_code/public/pixelwriter.h @@ -1819,7 +1819,7 @@ XEEMITTER(vpkd3d128, VX128_4(6, 1552), VX128_4)(PPCHIRBuilder& f, control = (control & ~mask) | (src & mask); break; default: - XEASSERTUNHANDLEDCASE(pack); + assert_unhandled_case(pack); return 1; } v = f.Permute(f.LoadConstant(control), f.LoadVR(vd), v, INT32_TYPE); @@ -1851,7 +1851,7 @@ XEEMITTER(vupkd3d128, VX128_3(6, 2032), VX128_3)(PPCHIRBuilder& f, v = f.Unpack(v, PACK_TYPE_FLOAT16_4); break; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); return 1; } f.StoreVR(vd, v); diff --git a/src/alloy/frontend/ppc/ppc_emit_alu.cc b/src/alloy/frontend/ppc/ppc_emit_alu.cc index cf8245064..da8bf65a6 100644 --- a/src/alloy/frontend/ppc/ppc_emit_alu.cc +++ b/src/alloy/frontend/ppc/ppc_emit_alu.cc @@ -28,7 +28,7 @@ XEEMITTER(addx, 0x7C000214, XO)(PPCHIRBuilder& f, InstrData& i) { Value* v = f.Add(f.LoadGPR(i.XO.RA), f.LoadGPR(i.XO.RB)); f.StoreGPR(i.XO.RT, v); if (i.XO.OE) { - XEASSERTALWAYS(); + assert_always(); // e.update_xer_with_overflow(EFLAGS OF?); } if (i.XO.Rc) { @@ -45,7 +45,7 @@ XEEMITTER(addcx, 0x7C000014, XO)(PPCHIRBuilder& f, InstrData& i) { f.StoreCA(f.DidCarry(v)); f.StoreGPR(i.XO.RT, v); if (i.XO.OE) { - XEASSERTALWAYS(); + assert_always(); // e.update_xer_with_overflow(EFLAGS OF?); } if (i.XO.Rc) { @@ -61,7 +61,7 @@ XEEMITTER(addex, 0x7C000114, XO)(PPCHIRBuilder& f, InstrData& i) { f.StoreCA(f.DidCarry(v)); f.StoreGPR(i.XO.RT, v); if (i.XO.OE) { - XEASSERTALWAYS(); + assert_always(); // e.update_xer_with_overflow(EFLAGS OF?); } if (i.XO.Rc) { @@ -124,7 +124,7 @@ XEEMITTER(addmex, 0x7C0001D4, XO)(PPCHIRBuilder& f, InstrData& i) { if (i.XO.OE) { // With XER[SO] update too. // e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1)); - XEASSERTALWAYS(); + assert_always(); } else { // Just CA update. f.StoreCA(f.DidCarry(v)); @@ -143,7 +143,7 @@ XEEMITTER(addzex, 0x7C000194, XO)(PPCHIRBuilder& f, InstrData& i) { if (i.XO.OE) { // With XER[SO] update too. // e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1)); - XEASSERTALWAYS(); + assert_always(); } else { // Just CA update. f.StoreCA(f.DidCarry(v)); @@ -172,7 +172,7 @@ XEEMITTER(divdx, 0x7C0003D2, XO)(PPCHIRBuilder& f, InstrData& i) { if (i.XO.OE) { // If we are OE=1 we need to clear the overflow bit. // e.update_xer_with_overflow(e.get_uint64(0)); - XEASSERTALWAYS(); + assert_always(); return 1; } if (i.XO.Rc) { @@ -198,7 +198,7 @@ XEEMITTER(divdux, 0x7C000392, XO)(PPCHIRBuilder& f, InstrData& i) { if (i.XO.OE) { // If we are OE=1 we need to clear the overflow bit. // e.update_xer_with_overflow(e.get_uint64(0)); - XEASSERTALWAYS(); + assert_always(); return 1; } if (i.XO.Rc) { @@ -226,7 +226,7 @@ XEEMITTER(divwx, 0x7C0003D6, XO)(PPCHIRBuilder& f, InstrData& i) { if (i.XO.OE) { // If we are OE=1 we need to clear the overflow bit. // e.update_xer_with_overflow(e.get_uint64(0)); - XEASSERTALWAYS(); + assert_always(); return 1; } if (i.XO.Rc) { @@ -255,7 +255,7 @@ XEEMITTER(divwux, 0x7C000396, XO)(PPCHIRBuilder& f, InstrData& i) { if (i.XO.OE) { // If we are OE=1 we need to clear the overflow bit. // e.update_xer_with_overflow(e.get_uint64(0)); - XEASSERTALWAYS(); + assert_always(); return 1; } if (i.XO.Rc) { @@ -379,7 +379,7 @@ XEEMITTER(negx, 0x7C0000D0, XO)(PPCHIRBuilder& f, InstrData& i) { // if RA == 0x8000000000000000 then no-op and set OV=1 // This may just magically do that... - XEASSERTALWAYS(); + assert_always(); // Function* ssub_with_overflow = Intrinsic::getDeclaration( // e.gen_module(), Intrinsic::ssub_with_overflow, jit_type_nint); // jit_value_t v = b.CreateCall2(ssub_with_overflow, @@ -408,7 +408,7 @@ XEEMITTER(subfx, 0x7C000050, XO)(PPCHIRBuilder& f, InstrData& i) { Value* v = f.Sub(f.LoadGPR(i.XO.RB), f.LoadGPR(i.XO.RA)); f.StoreGPR(i.XO.RT, v); if (i.XO.OE) { - XEASSERTALWAYS(); + assert_always(); // e.update_xer_with_overflow(EFLAGS??); } if (i.XO.Rc) { @@ -424,7 +424,7 @@ XEEMITTER(subfcx, 0x7C000010, XO)(PPCHIRBuilder& f, InstrData& i) { f.StoreCA(f.DidCarry(v)); f.StoreGPR(i.XO.RT, v); if (i.XO.OE) { - XEASSERTALWAYS(); + assert_always(); // e.update_xer_with_overflow(EFLAGS??); } if (i.XO.Rc) { @@ -449,7 +449,7 @@ XEEMITTER(subfex, 0x7C000110, XO)(PPCHIRBuilder& f, InstrData& i) { f.StoreCA(f.DidCarry(v)); f.StoreGPR(i.XO.RT, v); if (i.XO.OE) { - XEASSERTALWAYS(); + assert_always(); // e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1)); } if (i.XO.Rc) { @@ -463,7 +463,7 @@ XEEMITTER(subfmex, 0x7C0001D0, XO)(PPCHIRBuilder& f, InstrData& i) { Value* v = f.AddWithCarry(f.Not(f.LoadGPR(i.XO.RA)), f.LoadConstant((int64_t)-1), f.LoadCA()); if (i.XO.OE) { - XEASSERTALWAYS(); + assert_always(); // e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1)); } else { f.StoreCA(f.DidCarry(v)); @@ -480,7 +480,7 @@ XEEMITTER(subfzex, 0x7C000190, XO)(PPCHIRBuilder& f, InstrData& i) { Value* v = f.AddWithCarry(f.Not(f.LoadGPR(i.XO.RA)), f.LoadZero(INT64_TYPE), f.LoadCA()); if (i.XO.OE) { - XEASSERTALWAYS(); + assert_always(); // e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1)); } else { f.StoreCA(f.DidCarry(v)); @@ -1112,7 +1112,7 @@ XEEMITTER(sradix, 0x7C000674, XS)(PPCHIRBuilder& f, InstrData& i) { // CA is set if any bits are shifted out of the right and if the result // is negative. - XEASSERT(sh); + assert_true(sh); uint64_t mask = XEMASK(64 - sh, 63); Value* ca = f.And(f.Truncate(f.Shr(v, 63), INT8_TYPE), f.IsTrue(f.And(v, f.LoadConstant(mask)))); diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index 1d737917f..c0fc5c54c 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -206,7 +206,7 @@ Value* PPCHIRBuilder::LoadLR() { } void PPCHIRBuilder::StoreLR(Value* value) { - XEASSERT(value->type == INT64_TYPE); + assert_true(value->type == INT64_TYPE); StoreContext(offsetof(PPCContext, lr), value); } @@ -215,12 +215,12 @@ Value* PPCHIRBuilder::LoadCTR() { } void PPCHIRBuilder::StoreCTR(Value* value) { - XEASSERT(value->type == INT64_TYPE); + assert_true(value->type == INT64_TYPE); StoreContext(offsetof(PPCContext, ctr), value); } Value* PPCHIRBuilder::LoadCR(uint32_t n) { - XEASSERTALWAYS(); + assert_always(); return 0; } @@ -230,7 +230,7 @@ Value* PPCHIRBuilder::LoadCRField(uint32_t n, uint32_t bit) { void PPCHIRBuilder::StoreCR(uint32_t n, Value* value) { // TODO(benvanik): split bits out and store in values. - XEASSERTALWAYS(); + assert_always(); } void PPCHIRBuilder::UpdateCR(uint32_t n, Value* lhs, bool is_signed) { @@ -271,23 +271,23 @@ Value* PPCHIRBuilder::LoadFPSCR() { } void PPCHIRBuilder::StoreFPSCR(Value* value) { - XEASSERT(value->type == INT64_TYPE); + assert_true(value->type == INT64_TYPE); StoreContext(offsetof(PPCContext, fpscr), value); } Value* PPCHIRBuilder::LoadXER() { - XEASSERTALWAYS(); + assert_always(); return NULL; } -void PPCHIRBuilder::StoreXER(Value* value) { XEASSERTALWAYS(); } +void PPCHIRBuilder::StoreXER(Value* value) { assert_always(); } Value* PPCHIRBuilder::LoadCA() { return LoadContext(offsetof(PPCContext, xer_ca), INT8_TYPE); } void PPCHIRBuilder::StoreCA(Value* value) { - XEASSERT(value->type == INT8_TYPE); + assert_true(value->type == INT8_TYPE); StoreContext(offsetof(PPCContext, xer_ca), value); } @@ -305,7 +305,7 @@ Value* PPCHIRBuilder::LoadGPR(uint32_t reg) { } void PPCHIRBuilder::StoreGPR(uint32_t reg, Value* value) { - XEASSERT(value->type == INT64_TYPE); + assert_true(value->type == INT64_TYPE); StoreContext(offsetof(PPCContext, r) + reg * 8, value); } @@ -314,7 +314,7 @@ Value* PPCHIRBuilder::LoadFPR(uint32_t reg) { } void PPCHIRBuilder::StoreFPR(uint32_t reg, Value* value) { - XEASSERT(value->type == FLOAT64_TYPE); + assert_true(value->type == FLOAT64_TYPE); StoreContext(offsetof(PPCContext, f) + reg * 8, value); } @@ -323,7 +323,7 @@ Value* PPCHIRBuilder::LoadVR(uint32_t reg) { } void PPCHIRBuilder::StoreVR(uint32_t reg, Value* value) { - XEASSERT(value->type == VEC128_TYPE); + assert_true(value->type == VEC128_TYPE); StoreContext(offsetof(PPCContext, v) + reg * 16, value); } diff --git a/src/alloy/frontend/ppc/ppc_instr.cc b/src/alloy/frontend/ppc/ppc_instr.cc index c7029158a..251d07afe 100644 --- a/src/alloy/frontend/ppc/ppc_instr.cc +++ b/src/alloy/frontend/ppc/ppc_instr.cc @@ -146,7 +146,7 @@ void InstrAccessBits::MarkAccess(InstrRegister& reg) { } break; default: - XEASSERTUNHANDLEDCASE(reg.set); + assert_unhandled_case(reg.set); break; } } @@ -384,11 +384,11 @@ InstrType* GetInstrType(uint32_t code) { int RegisterInstrEmit(uint32_t code, InstrEmitFn emit) { InstrType* instr_type = GetInstrType(code); - XEASSERTNOTNULL(instr_type); + assert_not_null(instr_type); if (!instr_type) { return 1; } - XEASSERTNULL(instr_type->emit); + assert_null(instr_type->emit); instr_type->emit = emit; return 0; } diff --git a/src/alloy/hir/block.cc b/src/alloy/hir/block.cc index 66160338f..0327c3163 100644 --- a/src/alloy/hir/block.cc +++ b/src/alloy/hir/block.cc @@ -23,12 +23,12 @@ void Block::AssertNoCycles() { while ((hare = hare->next)) { if (hare == tortoise) { // Cycle! - XEASSERTALWAYS(); + assert_always(); } hare = hare->next; if (hare == tortoise) { // Cycle! - XEASSERTALWAYS(); + assert_always(); } tortoise = tortoise->next; if (!hare || !tortoise) { diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index d25aaac23..2a2b011e1 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -114,7 +114,7 @@ void HIRBuilder::DumpValue(StringBuffer* str, Value* value) { value->constant.v128.w); break; default: - XEASSERTALWAYS(); + assert_always(); break; } } else { @@ -276,12 +276,12 @@ void HIRBuilder::AssertNoCycles() { while ((hare = hare->next)) { if (hare == tortoise) { // Cycle! - XEASSERTALWAYS(); + assert_always(); } hare = hare->next; if (hare == tortoise) { // Cycle! - XEASSERTALWAYS(); + assert_always(); } tortoise = tortoise->next; if (!hare || !tortoise) { @@ -937,7 +937,7 @@ Value* HIRBuilder::LoadConstant(const vec128_t& value) { } Value* HIRBuilder::LoadVectorShl(Value* sh) { - XEASSERT(sh->type == INT8_TYPE); + assert_true(sh->type == INT8_TYPE); Instr* i = AppendInstr(OPCODE_LOAD_VECTOR_SHL_info, 0, AllocValue(VEC128_TYPE)); i->set_src1(sh); @@ -946,7 +946,7 @@ Value* HIRBuilder::LoadVectorShl(Value* sh) { } Value* HIRBuilder::LoadVectorShr(Value* sh) { - XEASSERT(sh->type == INT8_TYPE); + assert_true(sh->type == INT8_TYPE); Instr* i = AppendInstr(OPCODE_LOAD_VECTOR_SHR_info, 0, AllocValue(VEC128_TYPE)); i->set_src1(sh); @@ -1050,7 +1050,7 @@ Value* HIRBuilder::Min(Value* value1, Value* value2) { } Value* HIRBuilder::Select(Value* cond, Value* value1, Value* value2) { - XEASSERT(cond->type == INT8_TYPE); // for now + assert_true(cond->type == INT8_TYPE); // for now ASSERT_TYPES_EQUAL(value1, value2); if (cond->IsConstant()) { @@ -1233,7 +1233,7 @@ Value* HIRBuilder::Add(Value* value1, Value* value2, Value* HIRBuilder::AddWithCarry(Value* value1, Value* value2, Value* value3, uint32_t arithmetic_flags) { ASSERT_TYPES_EQUAL(value1, value2); - XEASSERT(value3->type == INT8_TYPE); + assert_true(value3->type == INT8_TYPE); Instr* i = AppendInstr(OPCODE_ADD_CARRY_info, arithmetic_flags, AllocValue(value1->type)); @@ -1250,7 +1250,7 @@ Value* HIRBuilder::VectorAdd(Value* value1, Value* value2, TypeName part_type, // This is shady. uint32_t flags = part_type | (arithmetic_flags << 8); - XEASSERTZERO(flags >> 16); + assert_zero(flags >> 16); Instr* i = AppendInstr(OPCODE_VECTOR_ADD_info, (uint16_t)flags, AllocValue(value1->type)); @@ -1701,7 +1701,7 @@ Value* HIRBuilder::Permute(Value* control, Value* value1, Value* value2, Value* HIRBuilder::Swizzle(Value* value, TypeName part_type, uint32_t swizzle_mask) { // For now. - XEASSERT(part_type == INT32_TYPE || part_type == FLOAT32_TYPE); + assert_true(part_type == INT32_TYPE || part_type == FLOAT32_TYPE); if (swizzle_mask == SWIZZLE_XYZW_TO_XYZW) { return Assign(value); diff --git a/src/alloy/hir/value.cc b/src/alloy/hir/value.cc index a7b7bddef..d25b6bea0 100644 --- a/src/alloy/hir/value.cc +++ b/src/alloy/hir/value.cc @@ -36,7 +36,7 @@ void Value::RemoveUse(Use* use) { } uint32_t Value::AsUint32() { - XEASSERT(IsConstant()); + assert_true(IsConstant()); switch (type) { case INT8_TYPE: return constant.i8; @@ -47,13 +47,13 @@ uint32_t Value::AsUint32() { case INT64_TYPE: return (uint32_t)constant.i64; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); return 0; } } uint64_t Value::AsUint64() { - XEASSERT(IsConstant()); + assert_true(IsConstant()); switch (type) { case INT8_TYPE: return constant.i8; @@ -64,14 +64,14 @@ uint64_t Value::AsUint64() { case INT64_TYPE: return constant.i64; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); return 0; } } void Value::Cast(TypeName target_type) { // TODO(benvanik): big matrix. - XEASSERTALWAYS(); + assert_always(); } void Value::ZeroExtend(TypeName target_type) { @@ -89,7 +89,7 @@ void Value::ZeroExtend(TypeName target_type) { constant.i64 = constant.i64 & 0xFFFFFFFF; return; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); break; } } @@ -109,7 +109,7 @@ void Value::SignExtend(TypeName target_type) { constant.i64 = constant.i8; return; default: - XEASSERTUNHANDLEDCASE(target_type); + assert_unhandled_case(target_type); return; } case INT16_TYPE: @@ -122,7 +122,7 @@ void Value::SignExtend(TypeName target_type) { constant.i64 = constant.i16; return; default: - XEASSERTUNHANDLEDCASE(target_type); + assert_unhandled_case(target_type); return; } case INT32_TYPE: @@ -132,11 +132,11 @@ void Value::SignExtend(TypeName target_type) { constant.i64 = constant.i32; return; default: - XEASSERTUNHANDLEDCASE(target_type); + assert_unhandled_case(target_type); return; } default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); return; } } @@ -150,7 +150,7 @@ void Value::Truncate(TypeName target_type) { constant.i64 = constant.i64 & 0xFF; return; default: - XEASSERTUNHANDLEDCASE(target_type); + assert_unhandled_case(target_type); return; } case INT32_TYPE: @@ -164,7 +164,7 @@ void Value::Truncate(TypeName target_type) { constant.i64 = constant.i64 & 0xFFFF; return; default: - XEASSERTUNHANDLEDCASE(target_type); + assert_unhandled_case(target_type); return; } case INT64_TYPE: @@ -182,29 +182,29 @@ void Value::Truncate(TypeName target_type) { constant.i64 = constant.i64 & 0xFFFFFFFF; return; default: - XEASSERTUNHANDLEDCASE(target_type); + assert_unhandled_case(target_type); return; } default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); return; } } void Value::Convert(TypeName target_type, RoundMode round_mode) { // TODO(benvanik): big matrix. - XEASSERTALWAYS(); + assert_always(); } void Value::Round(RoundMode round_mode) { // TODO(benvanik): big matrix. - XEASSERTALWAYS(); + assert_always(); } bool Value::Add(Value* other) { #define CHECK_DID_CARRY(v1, v2) (((uint64_t)v2) > ~((uint64_t)v1)) #define ADD_DID_CARRY(a, b) CHECK_DID_CARRY(a, b) - XEASSERT(type == other->type); + assert_true(type == other->type); bool did_carry = false; switch (type) { case INT8_TYPE: @@ -230,7 +230,7 @@ bool Value::Add(Value* other) { constant.f64 += other->constant.f64; break; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); break; } return did_carry; @@ -238,7 +238,7 @@ bool Value::Add(Value* other) { bool Value::Sub(Value* other) { #define SUB_DID_CARRY(a, b) (b > a) - XEASSERT(type == other->type); + assert_true(type == other->type); bool did_carry = false; switch (type) { case INT8_TYPE: @@ -264,14 +264,14 @@ bool Value::Sub(Value* other) { constant.f64 -= other->constant.f64; break; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); break; } return did_carry; } void Value::Mul(Value* other) { - XEASSERT(type == other->type); + assert_true(type == other->type); switch (type) { case INT8_TYPE: constant.i8 *= other->constant.i8; @@ -292,13 +292,13 @@ void Value::Mul(Value* other) { constant.f64 *= other->constant.f64; break; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); break; } } void Value::Div(Value* other) { - XEASSERT(type == other->type); + assert_true(type == other->type); switch (type) { case INT8_TYPE: constant.i8 /= other->constant.i8; @@ -319,19 +319,19 @@ void Value::Div(Value* other) { constant.f64 /= other->constant.f64; break; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); break; } } void Value::MulAdd(Value* dest, Value* value1, Value* value2, Value* value3) { // TODO(benvanik): big matrix. - XEASSERTALWAYS(); + assert_always(); } void Value::MulSub(Value* dest, Value* value1, Value* value2, Value* value3) { // TODO(benvanik): big matrix. - XEASSERTALWAYS(); + assert_always(); } void Value::Neg() { @@ -355,7 +355,7 @@ void Value::Neg() { constant.f64 = -constant.f64; break; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); break; } } @@ -381,7 +381,7 @@ void Value::Abs() { constant.f64 = abs(constant.f64); break; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); break; } } @@ -395,7 +395,7 @@ void Value::Sqrt() { constant.f64 = 1.0 / sqrt(constant.f64); break; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); break; } } @@ -409,13 +409,13 @@ void Value::RSqrt() { constant.f64 = sqrt(constant.f64); break; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); break; } } void Value::And(Value* other) { - XEASSERT(type == other->type); + assert_true(type == other->type); switch (type) { case INT8_TYPE: constant.i8 &= other->constant.i8; @@ -430,13 +430,13 @@ void Value::And(Value* other) { constant.i64 &= other->constant.i64; break; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); break; } } void Value::Or(Value* other) { - XEASSERT(type == other->type); + assert_true(type == other->type); switch (type) { case INT8_TYPE: constant.i8 |= other->constant.i8; @@ -451,13 +451,13 @@ void Value::Or(Value* other) { constant.i64 |= other->constant.i64; break; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); break; } } void Value::Xor(Value* other) { - XEASSERT(type == other->type); + assert_true(type == other->type); switch (type) { case INT8_TYPE: constant.i8 ^= other->constant.i8; @@ -472,7 +472,7 @@ void Value::Xor(Value* other) { constant.i64 ^= other->constant.i64; break; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); break; } } @@ -496,13 +496,13 @@ void Value::Not() { constant.v128.high = ~constant.v128.high; break; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); break; } } void Value::Shl(Value* other) { - XEASSERT(other->type == INT8_TYPE); + assert_true(other->type == INT8_TYPE); switch (type) { case INT8_TYPE: constant.i8 <<= other->constant.i8; @@ -517,13 +517,13 @@ void Value::Shl(Value* other) { constant.i64 <<= other->constant.i8; break; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); break; } } void Value::Shr(Value* other) { - XEASSERT(other->type == INT8_TYPE); + assert_true(other->type == INT8_TYPE); switch (type) { case INT8_TYPE: constant.i8 = (uint8_t)constant.i8 >> other->constant.i8; @@ -538,13 +538,13 @@ void Value::Shr(Value* other) { constant.i64 = (uint16_t)constant.i64 >> other->constant.i8; break; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); break; } } void Value::Sha(Value* other) { - XEASSERT(other->type == INT8_TYPE); + assert_true(other->type == INT8_TYPE); switch (type) { case INT8_TYPE: constant.i8 = constant.i8 >> other->constant.i8; @@ -559,7 +559,7 @@ void Value::Sha(Value* other) { constant.i64 = constant.i64 >> other->constant.i8; break; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); break; } } @@ -584,7 +584,7 @@ void Value::ByteSwap() { } break; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); break; } } @@ -604,14 +604,14 @@ void Value::CountLeadingZeros(const Value* other) { constant.i8 = poly::lzcnt(constant.i64); break; default: - XEASSERTUNHANDLEDCASE(type); + assert_unhandled_case(type); break; } } bool Value::Compare(Opcode opcode, Value* other) { // TODO(benvanik): big matrix. - XEASSERTALWAYS(); + assert_always(); return false; } diff --git a/src/alloy/hir/value.h b/src/alloy/hir/value.h index bd4e37acf..38e4947e9 100644 --- a/src/alloy/hir/value.h +++ b/src/alloy/hir/value.h @@ -48,7 +48,7 @@ static size_t GetTypeSize(TypeName type_name) { case VEC128_TYPE: return 16; default: - XEASSERTUNHANDLEDCASE(type_name); + assert_unhandled_case(type_name); return 0; } } @@ -177,13 +177,13 @@ class Value { inline bool IsConstant() const { return !!(flags & VALUE_IS_CONSTANT); } bool IsConstantTrue() const { if (type == VEC128_TYPE) { - XEASSERTALWAYS(); + assert_always(); } return (flags & VALUE_IS_CONSTANT) && !!constant.i64; } bool IsConstantFalse() const { if (type == VEC128_TYPE) { - XEASSERTALWAYS(); + assert_always(); } return (flags & VALUE_IS_CONSTANT) && !constant.i64; } @@ -196,20 +196,20 @@ class Value { } bool IsConstantEQ(Value* other) const { if (type == VEC128_TYPE) { - XEASSERTALWAYS(); + assert_always(); } return (flags & VALUE_IS_CONSTANT) && (other->flags & VALUE_IS_CONSTANT) && constant.i64 == other->constant.i64; } bool IsConstantNE(Value* other) const { if (type == VEC128_TYPE) { - XEASSERTALWAYS(); + assert_always(); } return (flags & VALUE_IS_CONSTANT) && (other->flags & VALUE_IS_CONSTANT) && constant.i64 != other->constant.i64; } bool IsConstantSLT(Value* other) const { - XEASSERT(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); + assert_true(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); switch (type) { case INT8_TYPE: return constant.i8 < other->constant.i8; @@ -224,12 +224,12 @@ class Value { case FLOAT64_TYPE: return constant.f64 < other->constant.f64; default: - XEASSERTALWAYS(); + assert_always(); return false; } } bool IsConstantSLE(Value* other) const { - XEASSERT(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); + assert_true(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); switch (type) { case INT8_TYPE: return constant.i8 <= other->constant.i8; @@ -244,12 +244,12 @@ class Value { case FLOAT64_TYPE: return constant.f64 <= other->constant.f64; default: - XEASSERTALWAYS(); + assert_always(); return false; } } bool IsConstantSGT(Value* other) const { - XEASSERT(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); + assert_true(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); switch (type) { case INT8_TYPE: return constant.i8 > other->constant.i8; @@ -264,12 +264,12 @@ class Value { case FLOAT64_TYPE: return constant.f64 > other->constant.f64; default: - XEASSERTALWAYS(); + assert_always(); return false; } } bool IsConstantSGE(Value* other) const { - XEASSERT(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); + assert_true(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); switch (type) { case INT8_TYPE: return constant.i8 >= other->constant.i8; @@ -284,12 +284,12 @@ class Value { case FLOAT64_TYPE: return constant.f64 >= other->constant.f64; default: - XEASSERTALWAYS(); + assert_always(); return false; } } bool IsConstantULT(Value* other) const { - XEASSERT(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); + assert_true(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); switch (type) { case INT8_TYPE: return (uint8_t)constant.i8 < (uint8_t)other->constant.i8; @@ -304,12 +304,12 @@ class Value { case FLOAT64_TYPE: return constant.f64 < other->constant.f64; default: - XEASSERTALWAYS(); + assert_always(); return false; } } bool IsConstantULE(Value* other) const { - XEASSERT(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); + assert_true(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); switch (type) { case INT8_TYPE: return (uint8_t)constant.i8 <= (uint8_t)other->constant.i8; @@ -324,12 +324,12 @@ class Value { case FLOAT64_TYPE: return constant.f64 <= other->constant.f64; default: - XEASSERTALWAYS(); + assert_always(); return false; } } bool IsConstantUGT(Value* other) const { - XEASSERT(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); + assert_true(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); switch (type) { case INT8_TYPE: return (uint8_t)constant.i8 > (uint8_t)other->constant.i8; @@ -344,12 +344,12 @@ class Value { case FLOAT64_TYPE: return constant.f64 > other->constant.f64; default: - XEASSERTALWAYS(); + assert_always(); return false; } } bool IsConstantUGE(Value* other) const { - XEASSERT(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); + assert_true(flags & VALUE_IS_CONSTANT && other->flags & VALUE_IS_CONSTANT); switch (type) { case INT8_TYPE: return (uint8_t)constant.i8 >= (uint8_t)other->constant.i8; @@ -364,7 +364,7 @@ class Value { case FLOAT64_TYPE: return constant.f64 >= other->constant.f64; default: - XEASSERTALWAYS(); + assert_always(); return false; } } diff --git a/src/alloy/memory.cc b/src/alloy/memory.cc index 9fabfb9ba..59568ee49 100644 --- a/src/alloy/memory.cc +++ b/src/alloy/memory.cc @@ -48,7 +48,7 @@ void Memory::Copy(uint64_t dest, uint64_t src, size_t size) { uint64_t Memory::SearchAligned(uint64_t start, uint64_t end, const uint32_t* values, size_t value_count) { - XEASSERT(start <= end); + assert_true(start <= end); const uint32_t* p = (const uint32_t*)(membase_ + start); const uint32_t* pe = (const uint32_t*)(membase_ + end); while (p != pe) { diff --git a/src/alloy/runtime/runtime.cc b/src/alloy/runtime/runtime.cc index 5d8f4bc23..66e514ae8 100644 --- a/src/alloy/runtime/runtime.cc +++ b/src/alloy/runtime/runtime.cc @@ -50,7 +50,7 @@ Runtime::~Runtime() { int Runtime::Initialize(Frontend* frontend, Backend* backend) { // Must be initialized by subclass before calling into this. - XEASSERTNOTNULL(memory_); + assert_not_null(memory_); // Create debugger first. Other types hook up to it. debugger_ = new Debugger(this); diff --git a/src/poly/assert.h b/src/poly/assert.h new file mode 100644 index 000000000..50e083d16 --- /dev/null +++ b/src/poly/assert.h @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef POLY_ASSERT_H_ +#define POLY_ASSERT_H_ + +#include + +#include +#include + +namespace poly { + +#define static_assert_size(type, size) \ + static_assert(sizeof(type) == size, \ + "bad definition for "## #type##": must be "## #size##" bytes") + +// We rely on assert being compiled out in NDEBUG. +#define poly_assert assert + +#define __POLY_EXPAND(x) x +#define __POLY_ARGC(...) \ + __POLY_EXPAND(__POLY_ARGC_IMPL(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, 7, \ + 6, 5, 4, 3, 2, 1, 0)) +#define __POLY_ARGC_IMPL(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, \ + x13, x14, x15, N, ...) \ + N +#define __POLY_MACRO_DISPATCH(func, ...) \ + __POLY_MACRO_DISPATCH_(func, __POLY_ARGC(__VA_ARGS__)) +#define __POLY_MACRO_DISPATCH_(func, nargs) __POLY_MACRO_DISPATCH__(func, nargs) +#define __POLY_MACRO_DISPATCH__(func, nargs) func##nargs + +#define assert_always(...) poly_assert(false) + +#define assert_true(...) \ + __POLY_MACRO_DISPATCH(assert_true, __VA_ARGS__)(__VA_ARGS__) +#define assert_true1(expr) poly_assert(expr) +#define assert_true2(expr, message) poly_assert((expr) || !message) + +#define assert_false(...) \ + __POLY_MACRO_DISPATCH(assert_false, __VA_ARGS__)(__VA_ARGS__) +#define assert_false1(expr) poly_assert(!(expr)) +#define assert_false2(expr, message) poly_assert(!(expr) || !message) + +#define assert_zero(...) \ + __POLY_MACRO_DISPATCH(assert_zero, __VA_ARGS__)(__VA_ARGS__) +#define assert_zero1(expr) poly_assert((expr) == 0) +#define assert_zero2(expr, message) poly_assert((expr) == 0 || !message) + +#define assert_not_zero(...) \ + __POLY_MACRO_DISPATCH(assert_not_zero, __VA_ARGS__)(__VA_ARGS__) +#define assert_not_zero1(expr) poly_assert((expr) != 0) +#define assert_not_zero2(expr, message) poly_assert((expr) != 0 || !message) + +#define assert_null(...) \ + __POLY_MACRO_DISPATCH(assert_null, __VA_ARGS__)(__VA_ARGS__) +#define assert_null1(expr) poly_assert((expr) == nullptr) +#define assert_null2(expr, message) poly_assert((expr) == nullptr || !message) + +#define assert_not_null(...) \ + __POLY_MACRO_DISPATCH(assert_not_null, __VA_ARGS__)(__VA_ARGS__) +#define assert_not_null1(expr) poly_assert((expr) != nullptr) +#define assert_not_null2(expr, message) \ + poly_assert((expr) != nullptr || !message) + +#define assert_unhandled_case(variable) \ + assert_always("unhandled switch("## #variable##") case") + +} // namespace poly + +#endif // POLY_ASSERT_H_ diff --git a/src/poly/config.h b/src/poly/config.h index dead1d518..bdba0f17b 100644 --- a/src/poly/config.h +++ b/src/poly/config.h @@ -11,7 +11,7 @@ #define POLY_CONFIG_H_ #if defined(DEBUG) || defined(_DEBUG) -#define XE_DEBUG 1 +#define XE_DEBUG 1 #endif // DEBUG #endif // POLY_CONFIG_H_ diff --git a/src/poly/cxx_compat.h b/src/poly/cxx_compat.h index 080152245..d2d03897f 100644 --- a/src/poly/cxx_compat.h +++ b/src/poly/cxx_compat.h @@ -16,6 +16,7 @@ // http://en.cppreference.com/w/cpp/language/storage_duration #if XE_COMPILER_MSVC // VC++2014 may have this. +#define _ALLOW_KEYWORD_MACROS 1 #define thread_local __declspec(thread) #elif XE_LIKE_OSX // Clang supports it on OSX but the runtime doesn't. diff --git a/src/poly/math.h b/src/poly/math.h index 5fcce51fd..7a20fade4 100644 --- a/src/poly/math.h +++ b/src/poly/math.h @@ -25,15 +25,25 @@ namespace poly { // return value is the size of the input operand (8, 16, 32, or 64). If the most // significant bit of value is one, the return value is zero. #if XE_COMPILER_MSVC -inline uint8_t lzcnt(uint8_t v) { return static_cast(__lzcnt16(v) - 8); } +inline uint8_t lzcnt(uint8_t v) { + return static_cast(__lzcnt16(v) - 8); +} inline uint8_t lzcnt(uint16_t v) { return static_cast(__lzcnt16(v)); } inline uint8_t lzcnt(uint32_t v) { return static_cast(__lzcnt(v)); } inline uint8_t lzcnt(uint64_t v) { return static_cast(__lzcnt64(v)); } #else -inline uint8_t lzcnt(uint8_t v) { return static_cast(__builtin_clzs(v) - 8); } -inline uint8_t lzcnt(uint16_t v) { return static_cast(__builtin_clzs(v)); } -inline uint8_t lzcnt(uint32_t v) { return static_cast(__builtin_clz(v)); } -inline uint8_t lzcnt(uint64_t v) { return static_cast(__builtin_clzll(v)); } +inline uint8_t lzcnt(uint8_t v) { + return static_cast(__builtin_clzs(v) - 8); +} +inline uint8_t lzcnt(uint16_t v) { + return static_cast(__builtin_clzs(v)); +} +inline uint8_t lzcnt(uint32_t v) { + return static_cast(__builtin_clz(v)); +} +inline uint8_t lzcnt(uint64_t v) { + return static_cast(__builtin_clzll(v)); +} #endif // XE_COMPILER_MSVC inline uint8_t lzcnt(int8_t v) { return lzcnt(static_cast(v)); } inline uint8_t lzcnt(int16_t v) { return lzcnt(static_cast(v)); } @@ -49,7 +59,8 @@ inline bool bit_scan_forward(uint32_t v, uint32_t* out_first_set_index) { return _BitScanForward(reinterpret_cast(out_first_set_index), v) != 0; } inline bool bit_scan_forward(uint64_t v, uint32_t* out_first_set_index) { - return _BitScanForward64(reinterpret_cast(out_first_set_index), v) != 0; + return _BitScanForward64(reinterpret_cast(out_first_set_index), v) != + 0; } #else inline bool bit_scan_forward(uint32_t v, uint32_t* out_first_set_index) { diff --git a/src/poly/poly.h b/src/poly/poly.h index 6c70dedd7..52cc74b79 100644 --- a/src/poly/poly.h +++ b/src/poly/poly.h @@ -10,6 +10,7 @@ #ifndef POLY_POLY_H_ #define POLY_POLY_H_ +#include #include #include #include diff --git a/src/poly/sources.gypi b/src/poly/sources.gypi index dcf5478f5..7a29bd85b 100644 --- a/src/poly/sources.gypi +++ b/src/poly/sources.gypi @@ -1,9 +1,11 @@ # Copyright 2014 Ben Vanik. All Rights Reserved. { 'sources': [ + 'assert.h', 'config.h', 'cxx_compat.h', 'math.h', + 'platform.h', 'poly-private.h', 'poly.cc', 'poly.h', diff --git a/src/xenia/apu/audio_system.cc b/src/xenia/apu/audio_system.cc index 68b9ccbee..214620494 100644 --- a/src/xenia/apu/audio_system.cc +++ b/src/xenia/apu/audio_system.cc @@ -82,7 +82,7 @@ void AudioSystem::ThreadStart() { auto result = WaitForMultipleObjectsEx(maximum_client_count_, client_wait_handles_, FALSE, INFINITE, FALSE); if (result == WAIT_FAILED) { DWORD err = GetLastError(); - XEASSERTALWAYS(); + assert_always(); break; } @@ -131,7 +131,7 @@ void AudioSystem::Shutdown() { X_STATUS AudioSystem::RegisterClient( uint32_t callback, uint32_t callback_arg, size_t* out_index) { - XEASSERTTRUE(unused_clients_.size()); + assert_true(unused_clients_.size()); xe_mutex_lock(lock_); auto index = unused_clients_.front(); @@ -143,7 +143,7 @@ X_STATUS AudioSystem::RegisterClient( if (XFAILED(result)) { return result; } - XEASSERTNOTNULL(driver != NULL); + assert_not_null(driver); unused_clients_.pop(); @@ -165,8 +165,8 @@ void AudioSystem::SubmitFrame(size_t index, uint32_t samples_ptr) { SCOPE_profile_cpu_f("apu"); xe_mutex_lock(lock_); - XEASSERTTRUE(index < maximum_client_count_); - XEASSERTTRUE(clients_[index].driver != NULL); + assert_true(index < maximum_client_count_); + assert_true(clients_[index].driver != NULL); (clients_[index].driver)->SubmitFrame(samples_ptr); ResetEvent(client_wait_handles_[index]); xe_mutex_unlock(lock_); @@ -176,7 +176,7 @@ void AudioSystem::UnregisterClient(size_t index) { SCOPE_profile_cpu_f("apu"); xe_mutex_lock(lock_); - XEASSERTTRUE(index < maximum_client_count_); + assert_true(index < maximum_client_count_); DestroyDriver(clients_[index].driver); clients_[index] = { 0 }; unused_clients_.push(index); @@ -199,4 +199,4 @@ void AudioSystem::WriteRegister(uint64_t addr, uint64_t value) { uint32_t r = addr & 0xFFFF; XELOGAPU("WriteRegister(%.4X, %.8X)", r, value); // 1804h is written to with 0x02000000 and 0x03000000 around a lock operation -} \ No newline at end of file +} diff --git a/src/xenia/apu/nop/nop_audio_system.cc b/src/xenia/apu/nop/nop_audio_system.cc index fae7b153f..d384c3de3 100644 --- a/src/xenia/apu/nop/nop_audio_system.cc +++ b/src/xenia/apu/nop/nop_audio_system.cc @@ -29,5 +29,5 @@ X_STATUS NopAudioSystem::CreateDriver(size_t index, HANDLE wait_handle, AudioDri } void NopAudioSystem::DestroyDriver(AudioDriver* driver) { - XEASSERTALWAYS(); + assert_always(); } diff --git a/src/xenia/apu/xaudio2/xaudio2_audio_driver.cc b/src/xenia/apu/xaudio2/xaudio2_audio_driver.cc index 0155753c4..7be6c9d55 100644 --- a/src/xenia/apu/xaudio2/xaudio2_audio_driver.cc +++ b/src/xenia/apu/xaudio2/xaudio2_audio_driver.cc @@ -67,7 +67,7 @@ void XAudio2AudioDriver::Initialize() { hr = XAudio2Create(&audio_, 0, XAUDIO2_DEFAULT_PROCESSOR); if (FAILED(hr)) { XELOGE("XAudio2Create failed with %.8X", hr); - XEASSERTALWAYS(); + assert_always(); return; } @@ -83,7 +83,7 @@ void XAudio2AudioDriver::Initialize() { hr = audio_->CreateMasteringVoice(&mastering_voice_); if (FAILED(hr)) { XELOGE("CreateMasteringVoice failed with %.8X", hr); - XEASSERTALWAYS(); + assert_always(); return; } @@ -106,14 +106,14 @@ void XAudio2AudioDriver::Initialize() { voice_callback_); if (FAILED(hr)) { XELOGE("CreateSourceVoice failed with %.8X", hr); - XEASSERTALWAYS(); + assert_always(); return; } hr = pcm_voice_->Start(); if (FAILED(hr)) { XELOGE("Start failed with %.8X", hr); - XEASSERTALWAYS(); + assert_always(); return; } @@ -148,7 +148,7 @@ void XAudio2AudioDriver::SubmitFrame(uint32_t frame_ptr) { hr = pcm_voice_->SubmitSourceBuffer(&buffer); if (FAILED(hr)) { XELOGE("SubmitSourceBuffer failed with %.8X", hr); - XEASSERTALWAYS(); + assert_always(); return; } } diff --git a/src/xenia/apu/xaudio2/xaudio2_audio_system.cc b/src/xenia/apu/xaudio2/xaudio2_audio_system.cc index 465c51b5e..f87197cb4 100644 --- a/src/xenia/apu/xaudio2/xaudio2_audio_system.cc +++ b/src/xenia/apu/xaudio2/xaudio2_audio_system.cc @@ -31,7 +31,7 @@ void XAudio2AudioSystem::Initialize() { } X_STATUS XAudio2AudioSystem::CreateDriver(size_t index, HANDLE wait, AudioDriver** out_driver) { - XEASSERTNOTNULL(out_driver); + assert_not_null(out_driver); auto driver = new XAudio2AudioDriver(emulator_, wait); driver->Initialize(); *out_driver = driver; @@ -39,9 +39,9 @@ X_STATUS XAudio2AudioSystem::CreateDriver(size_t index, HANDLE wait, AudioDriver } void XAudio2AudioSystem::DestroyDriver(AudioDriver* driver) { - XEASSERTNOTNULL(driver); + assert_not_null(driver); auto xdriver = static_cast(driver); xdriver->Shutdown(); - XEASSERTNOTNULL(xdriver); + assert_not_null(xdriver); delete xdriver; } diff --git a/src/xenia/assert.h b/src/xenia/assert.h deleted file mode 100644 index 4f765bbd8..000000000 --- a/src/xenia/assert.h +++ /dev/null @@ -1,74 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_ASSERT_H_ -#define XENIA_ASSERT_H_ - -#include - -#include -#include -#include -#include -#include - - -#if 0 && XE_COMPILER_MSVC && defined(UNICODE) && UNICODE -// http://msdn.microsoft.com/en-us/library/b0084kay.aspx -#if !defined(__WFILE__) -#define WIDEN2(x) L##x -#define WIDEN(x) WIDEN2(x) -#define __WFILE__ WIDEN(__FILE__) -#define __WFUNCTION__ WIDEN(__FUNCTION__) -#endif -#define XE_CURRENT_FILE __WFILE__ -#define XE_CURRENT_FUNCTION __WFUNCTION__ -#else -#define XE_CURRENT_FILE __FILE__ -#define XE_CURRENT_FUNCTION __FUNCTION__ -#endif // MSVC -#define XE_CURRENT_LINE __LINE__ - - -#define __XE_ASSERT(expr) assert(expr) -#if XE_OPTION_ENABLE_ASSERTS -#define XEASSERTCORE(expr) __XE_ASSERT(expr) -#else -#define XEASSERTCORE(expr) XE_EMPTY_MACRO -#endif // ENABLE_ASSERTS - -#define XEASSERTALWAYS() XEASSERTCORE( 0 ) -#define XEASSERT(expr) XEASSERTCORE( (expr) ) -#define XEASSERTTRUE(expr) XEASSERTCORE( (expr) ) -#define XEASSERTFALSE(expr) XEASSERTCORE(!(expr) ) -#define XEASSERTZERO(expr) XEASSERTCORE( (expr) == 0 ) -#define XEASSERTNOTZERO(expr) XEASSERTCORE( (expr) != 0 ) -#define XEASSERTNULL(expr) XEASSERTCORE( (expr) == NULL ) -#define XEASSERTNOTNULL(expr) XEASSERTCORE( (expr) != NULL ) -#define XEASSERTUNHANDLEDCASE(var) XEASSERTALWAYS() - - -#if XE_COMPILER_MSVC -// http://msdn.microsoft.com/en-us/library/bb918086.aspx -// TODO(benvanik): if 2010+, use static_assert? -// http://msdn.microsoft.com/en-us/library/dd293588.aspx -#define XESTATICASSERT(expr, message) _STATIC_ASSERT(expr) -//#elif XE_COMPILER_GNUC -// http://stackoverflow.com/questions/3385515/static-assert-in-c -//#define XESTATICASSERT(expr, message) ({ extern int __attribute__((error("assertion failure: '" #expr "' not true - " #message))) compile_time_check(); ((expr)?0:compile_time_check()),0; }) -#else -// http://stackoverflow.com/questions/3385515/static-assert-in-c -#define XESTATICASSERT3(expr, L) typedef char static_assertion_##L[(expr)?1:-1] -#define XESTATICASSERT2(expr, L) XESTATICASSERT3(expr, L) -#define XESTATICASSERT(expr, message) XESTATICASSERT2(expr, __LINE__) -#endif // MSVC - -#define XEASSERTSTRUCTSIZE(target, size) XESTATICASSERT(sizeof(target) == size, "bad definition for " ## target ## ": must be " ## size ## " bytes") - -#endif // XENIA_ASSERT_H_ diff --git a/src/xenia/atomic.h b/src/xenia/atomic.h index 10403280d..bd1ebc14d 100644 --- a/src/xenia/atomic.h +++ b/src/xenia/atomic.h @@ -13,6 +13,7 @@ #include #include +#include // These functions are modeled off of the Apple OSAtomic routines diff --git a/src/xenia/common.h b/src/xenia/common.h index 0e8cac0a2..c76f9eae1 100644 --- a/src/xenia/common.h +++ b/src/xenia/common.h @@ -10,7 +10,8 @@ #ifndef XENIA_COMMON_H_ #define XENIA_COMMON_H_ -#include +#include + #include #include #include diff --git a/src/xenia/core/path_posix.cc b/src/xenia/core/path_posix.cc index b8bedda56..0dc9aadec 100644 --- a/src/xenia/core/path_posix.cc +++ b/src/xenia/core/path_posix.cc @@ -12,5 +12,5 @@ const xechar_t* xe_path_get_tmp(const xechar_t* prefix) { // - XEASSERTALWAYS(); + assert_always(); } diff --git a/src/xenia/core/path_win.cc b/src/xenia/core/path_win.cc index e1361d945..ded9bf388 100644 --- a/src/xenia/core/path_win.cc +++ b/src/xenia/core/path_win.cc @@ -11,7 +11,7 @@ const xechar_t* xe_path_get_tmp(const xechar_t* prefix) { - // - XEASSERTALWAYS(); + // + assert_always(); return NULL; } diff --git a/src/xenia/cpu/processor.cc b/src/xenia/cpu/processor.cc index 7aa67ccdf..b263e1aad 100644 --- a/src/xenia/cpu/processor.cc +++ b/src/xenia/cpu/processor.cc @@ -68,7 +68,7 @@ Processor::~Processor() { } int Processor::Setup() { - XEASSERTNULL(runtime_); + assert_null(runtime_); runtime_ = new XenonRuntime(memory_, export_resolver_); if (!runtime_) { @@ -127,7 +127,7 @@ uint64_t Processor::Execute( SCOPE_profile_cpu_f("cpu"); PPCContext* context = thread_state->context(); - XEASSERT(arg_count <= 5); + assert_true(arg_count <= 5); for (size_t i = 0; i < arg_count; ++i) { context->r[3 + i] = args[i]; } diff --git a/src/xenia/cpu/xenon_memory.cc b/src/xenia/cpu/xenon_memory.cc index c20130fae..2993f4850 100644 --- a/src/xenia/cpu/xenon_memory.cc +++ b/src/xenia/cpu/xenon_memory.cc @@ -174,7 +174,7 @@ LONG CALLBACK CheckMMIOHandler(PEXCEPTION_POINTERS ex_info) { auto action = ex_info->ExceptionRecord->ExceptionInformation[0]; if (action == 0) { uint64_t value = range.read(range.context, address & 0xFFFFFFFF); - XEASSERT((disasm.Argument1.ArgType & BE::REGISTER_TYPE) == + assert_true((disasm.Argument1.ArgType & BE::REGISTER_TYPE) == BE::REGISTER_TYPE); uint64_t* reg_ptr = GetContextRegPtr(disasm.Argument1.ArgType, ex_info->ContextRecord); @@ -203,7 +203,7 @@ LONG CALLBACK CheckMMIOHandler(PEXCEPTION_POINTERS ex_info) { } else if ((disasm.Argument2.ArgType & BE::CONSTANT_TYPE) == BE::CONSTANT_TYPE) { value = disasm.Instruction.Immediat; } else { - XEASSERTALWAYS(); + assert_always(); } switch (disasm.Argument2.ArgSize) { case 8: @@ -290,7 +290,7 @@ int XenonMemory::Initialize() { NULL); if (!mapping_) { XELOGE("Unable to reserve the 4gb guest address space."); - XEASSERTNOTNULL(mapping_); + assert_not_null(mapping_); XEFAIL(); } @@ -306,7 +306,7 @@ int XenonMemory::Initialize() { } if (!mapping_base_) { XELOGE("Unable to find a continuous block in the 64bit address space."); - XEASSERTALWAYS(); + assert_always(); XEFAIL(); } membase_ = mapping_base_; @@ -362,7 +362,7 @@ int XenonMemory::MapViews(uint8_t* mapping_base) { 0xC0000000, 0xDFFFFFFF, 0x00000000, // - physical 16mb pages 0xE0000000, 0xFFFFFFFF, 0x00000000, // - physical 4k pages }; - XEASSERT(XECOUNT(map_info) == XECOUNT(views_.all_views)); + assert_true(XECOUNT(map_info) == XECOUNT(views_.all_views)); for (size_t n = 0; n < XECOUNT(map_info); n++) { views_.all_views[n] = (uint8_t*)MapViewOfFileEx( mapping_, @@ -398,14 +398,14 @@ bool XenonMemory::AddMappedRange(uint64_t address, uint64_t mask, protect = PAGE_READONLY; } else { // Write-only memory is not supported. - XEASSERTALWAYS(); + assert_always(); } if (!VirtualAlloc(Translate(address), size, MEM_COMMIT, protect)) { return false; } - XEASSERT(g_mapped_range_count_ + 1 < XECOUNT(g_mapped_ranges_)); + assert_true(g_mapped_range_count_ + 1 < XECOUNT(g_mapped_ranges_)); g_mapped_ranges_[g_mapped_range_count_++] = { reinterpret_cast(mapping_base_) | address, 0xFFFFFFFF00000000 | mask, @@ -518,13 +518,13 @@ uint64_t XenonMemory::HeapAlloc( if (base_address >= XENON_MEMORY_VIRTUAL_HEAP_LOW && base_address < XENON_MEMORY_VIRTUAL_HEAP_HIGH) { // Overlapping managed heap. - XEASSERTALWAYS(); + assert_always(); return 0; } if (base_address >= XENON_MEMORY_PHYSICAL_HEAP_LOW && base_address < XENON_MEMORY_PHYSICAL_HEAP_HIGH) { // Overlapping managed heap. - XEASSERTALWAYS(); + assert_always(); return 0; } @@ -534,7 +534,7 @@ uint64_t XenonMemory::HeapAlloc( void* pv = VirtualAlloc(p, size, MEM_COMMIT, PAGE_READWRITE); if (!pv) { // Failed. - XEASSERTALWAYS(); + assert_always(); return 0; } diff --git a/src/xenia/cpu/xenon_thread_state.cc b/src/xenia/cpu/xenon_thread_state.cc index c4dd94069..e5ed16da5 100644 --- a/src/xenia/cpu/xenon_thread_state.cc +++ b/src/xenia/cpu/xenon_thread_state.cc @@ -32,7 +32,7 @@ XenonThreadState::XenonThreadState( // Allocate with 64b alignment. context_ = (PPCContext*)xe_malloc_aligned(sizeof(PPCContext)); - XEASSERT(((uint64_t)context_ & 0xF) == 0); + assert_true(((uint64_t)context_ & 0xF) == 0); xe_zero_struct(context_, sizeof(PPCContext)); // Stash pointers to common structures that callbacks may need. diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index deb33c9c3..64c9ac00b 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -127,7 +127,7 @@ XECLEANUP: } void Emulator::set_main_window(Window* window) { - XEASSERTNULL(main_window_); + assert_null(main_window_); main_window_ = window; window->closed.AddListener([](UIEvent& e) { diff --git a/src/xenia/export_resolver.cc b/src/xenia/export_resolver.cc index 9d09b63ec..8d37240e3 100644 --- a/src/xenia/export_resolver.cc +++ b/src/xenia/export_resolver.cc @@ -78,7 +78,7 @@ KernelExport* ExportResolver::GetExportByOrdinal(const char* library_name, KernelExport* ExportResolver::GetExportByName(const char* library_name, const char* name) { // TODO(benvanik): lookup by name. - XEASSERTALWAYS(); + assert_always(); return NULL; } @@ -86,7 +86,7 @@ void ExportResolver::SetVariableMapping(const char* library_name, const uint32_t ordinal, uint32_t value) { KernelExport* kernel_export = GetExportByOrdinal(library_name, ordinal); - XEASSERTNOTNULL(kernel_export); + assert_not_null(kernel_export); kernel_export->is_implemented = true; kernel_export->variable_ptr = value; } @@ -96,7 +96,7 @@ void ExportResolver::SetFunctionMapping( void* shim_data, xe_kernel_export_shim_fn shim, xe_kernel_export_impl_fn impl) { KernelExport* kernel_export = GetExportByOrdinal(library_name, ordinal); - XEASSERTNOTNULL(kernel_export); + assert_not_null(kernel_export); kernel_export->is_implemented = true; kernel_export->function_data.shim_data = shim_data; kernel_export->function_data.shim = shim; diff --git a/src/xenia/gpu/command_processor.cc b/src/xenia/gpu/command_processor.cc index 23c27c5a9..d84c7e236 100644 --- a/src/xenia/gpu/command_processor.cc +++ b/src/xenia/gpu/command_processor.cc @@ -144,10 +144,10 @@ void CommandProcessor::ExecutePrimaryBuffer( uint32_t n = 0; while (args.ptr != end_ptr) { n += ExecutePacket(args); - XEASSERT(args.ptr < args.max_address); + assert_true(args.ptr < args.max_address); } if (end_index > start_index) { - XEASSERT(n == (end_index - start_index)); + assert_true(n == (end_index - start_index)); } XETRACECP(" ExecutePrimaryBuffer End"); @@ -164,7 +164,7 @@ void CommandProcessor::ExecuteIndirectBuffer(uint32_t ptr, uint32_t length) { args.ptr_mask = 0; for (uint32_t n = 0; n < length;) { n += ExecutePacket(args); - XEASSERT(n <= length); + assert_true(n <= length); } XETRACECP(" ExecuteIndirectBuffer End"); @@ -343,7 +343,7 @@ uint32_t CommandProcessor::ExecutePacket(PacketArgs& args) { value = GpuSwap(value, endianness); } else { // Register. - XEASSERT(poll_reg_addr < RegisterFile::kRegisterCount); + assert_true(poll_reg_addr < RegisterFile::kRegisterCount); value = regs->values[poll_reg_addr].u32; if (poll_reg_addr == XE_GPU_REG_COHER_STATUS_HOST) { MakeCoherent(); @@ -438,7 +438,7 @@ uint32_t CommandProcessor::ExecutePacket(PacketArgs& args) { value = GpuSwap(value, endianness); } else { // Register. - XEASSERT(poll_reg_addr < RegisterFile::kRegisterCount); + assert_true(poll_reg_addr < RegisterFile::kRegisterCount); value = regs->values[poll_reg_addr].u32; } bool matched = false; @@ -496,7 +496,7 @@ uint32_t CommandProcessor::ExecutePacket(PacketArgs& args) { // Just an event flag? Where does this write? } else { // Write to an address. - XEASSERTALWAYS(); + assert_always(); ADVANCE_PTR(count - 1); } } @@ -564,7 +564,7 @@ uint32_t CommandProcessor::ExecutePacket(PacketArgs& args) { draw_command_.index_buffer = nullptr; } else { // Unknown source select. - XEASSERTALWAYS(); + assert_always(); } driver_->Draw(draw_command_); } else { @@ -584,7 +584,7 @@ uint32_t CommandProcessor::ExecutePacket(PacketArgs& args) { uint32_t index_count = d0 >> 16; uint32_t prim_type = d0 & 0x3F; uint32_t src_sel = (d0 >> 6) & 0x3; - XEASSERT(src_sel == 0x2); // 'SrcSel=AutoIndex' + assert_true(src_sel == 0x2); // 'SrcSel=AutoIndex' if (!driver_->PrepareDraw(draw_command_)) { draw_command_.prim_type = (XE_GPU_PRIMITIVE_TYPE)prim_type; draw_command_.start_index = 0; @@ -619,7 +619,7 @@ uint32_t CommandProcessor::ExecutePacket(PacketArgs& args) { } break; default: - XEASSERTALWAYS(); + assert_always(); break; } } @@ -660,7 +660,7 @@ uint32_t CommandProcessor::ExecutePacket(PacketArgs& args) { uint32_t start_size = READ_PTR(); uint32_t start = start_size >> 16; uint32_t size = start_size & 0xFFFF; // dwords - XEASSERT(start == 0); + assert_true(start == 0); driver_->LoadShader((XE_GPU_SHADER_TYPE)type, GpuToCpu(packet_ptr, addr), size * 4, start); } @@ -675,9 +675,9 @@ uint32_t CommandProcessor::ExecutePacket(PacketArgs& args) { uint32_t start_size = READ_PTR(); uint32_t start = start_size >> 16; uint32_t size = start_size & 0xFFFF; // dwords - XEASSERT(start == 0); + assert_true(start == 0); // TODO(benvanik): figure out if this could wrap. - XEASSERT(args.ptr + size * 4 < args.max_address); + assert_true(args.ptr + size * 4 < args.max_address); driver_->LoadShader((XE_GPU_SHADER_TYPE)type, args.ptr, size * 4, start); ADVANCE_PTR(size); @@ -751,7 +751,7 @@ uint32_t CommandProcessor::ExecutePacket(PacketArgs& args) { void CommandProcessor::WriteRegister( uint32_t packet_ptr, uint32_t index, uint32_t value) { RegisterFile* regs = driver_->register_file(); - XEASSERT(index < RegisterFile::kRegisterCount); + assert_true(index < RegisterFile::kRegisterCount); regs->values[index].u32 = value; // If this is a COHER register, set the dirty flag. diff --git a/src/xenia/gpu/d3d11/d3d11_buffer_resource.cc b/src/xenia/gpu/d3d11/d3d11_buffer_resource.cc index 8f03cfe58..1b1654c59 100644 --- a/src/xenia/gpu/d3d11/d3d11_buffer_resource.cc +++ b/src/xenia/gpu/d3d11/d3d11_buffer_resource.cc @@ -53,7 +53,7 @@ int D3D11IndexBufferResource::InvalidateRegion( SCOPE_profile_cpu_f("gpu"); // All that's done so far: - XEASSERT(info_.endianness == 0x2); + assert_true(info_.endianness == 0x2); D3D11_MAPPED_SUBRESOURCE res; HRESULT hr = resource_cache_->context()->Map( diff --git a/src/xenia/gpu/d3d11/d3d11_graphics_system.cc b/src/xenia/gpu/d3d11/d3d11_graphics_system.cc index 8e6fc5a7e..11d113ca4 100644 --- a/src/xenia/gpu/d3d11/d3d11_graphics_system.cc +++ b/src/xenia/gpu/d3d11/d3d11_graphics_system.cc @@ -33,8 +33,8 @@ D3D11GraphicsSystem::~D3D11GraphicsSystem() { void D3D11GraphicsSystem::Initialize() { GraphicsSystem::Initialize(); - XEASSERTNULL(timer_queue_); - XEASSERTNULL(vsync_timer_); + assert_null(timer_queue_); + assert_null(vsync_timer_); timer_queue_ = CreateTimerQueue(); CreateTimerQueueTimer( @@ -111,7 +111,7 @@ void D3D11GraphicsSystem::Initialize() { // Create the window. // This will pump through the run-loop and and be where our swapping // will take place. - XEASSERTNULL(window_); + assert_null(window_); window_ = new D3D11Window(run_loop_, dxgi_factory_, device_); if (window_->Initialize("Xenia D3D11", 1280, 720)) { XELOGE("Failed to create D3D11Window"); @@ -126,7 +126,7 @@ void D3D11GraphicsSystem::Initialize() { // Create the driver. // This runs in the worker thread and builds command lines to present // in the window. - XEASSERTNULL(driver_); + assert_null(driver_); driver_ = new D3D11GraphicsDriver( memory_, window_->swap_chain(), device_); if (driver_->Initialize()) { @@ -180,7 +180,7 @@ void __stdcall D3D11GraphicsSystem::VsyncCallback(D3D11GraphicsSystem* gs, void D3D11GraphicsSystem::Shutdown() { GraphicsSystem::Shutdown(); - + if (vsync_timer_) { DeleteTimerQueueTimer(timer_queue_, vsync_timer_, NULL); } diff --git a/src/xenia/gpu/d3d11/d3d11_profiler_display.cc b/src/xenia/gpu/d3d11/d3d11_profiler_display.cc index 276b73c40..8bcefd0e7 100644 --- a/src/xenia/gpu/d3d11/d3d11_profiler_display.cc +++ b/src/xenia/gpu/d3d11/d3d11_profiler_display.cc @@ -140,7 +140,7 @@ D3D11ProfilerDisplay::D3D11ProfilerDisplay(D3D11Window* window) : window_(window !SetupShaders() || !SetupFont()) { // Hrm. - XEASSERTALWAYS(); + assert_always(); } // Pass through mouse events. @@ -183,7 +183,7 @@ bool D3D11ProfilerDisplay::SetupState() { blend_desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blend_desc.RenderTarget[0].RenderTargetWriteMask = 0x0F; hr = device->CreateBlendState(&blend_desc, &blend_state_); - XEASSERT(SUCCEEDED(hr)); + assert_true(SUCCEEDED(hr)); D3D11_DEPTH_STENCIL_DESC depth_stencil_desc; xe_zero_struct(&depth_stencil_desc, sizeof(depth_stencil_desc)); @@ -191,7 +191,7 @@ bool D3D11ProfilerDisplay::SetupState() { depth_stencil_desc.StencilEnable = false; depth_stencil_desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; hr = device->CreateDepthStencilState(&depth_stencil_desc, &depth_stencil_state_); - XEASSERT(SUCCEEDED(hr)); + assert_true(SUCCEEDED(hr)); return true; } @@ -484,7 +484,7 @@ D3D11ProfilerDisplay::Vertex* D3D11ProfilerDisplay::AllocateVertices( if (draw_state_.vertex_index + count > XECOUNT(draw_state_.vertex_buffer)) { Flush(); } - XEASSERT(draw_state_.vertex_index + count <= XECOUNT(draw_state_.vertex_buffer)); + assert_true(draw_state_.vertex_index + count <= XECOUNT(draw_state_.vertex_buffer)); size_t head = draw_state_.vertex_index; draw_state_.vertex_index += count; @@ -493,7 +493,7 @@ D3D11ProfilerDisplay::Vertex* D3D11ProfilerDisplay::AllocateVertices( draw_state_.commands[draw_state_.command_index - 1].primitive == primitive) { draw_state_.commands[draw_state_.command_index - 1].vertex_count += count; } else { - XEASSERT(draw_state_.command_index < XECOUNT(draw_state_.commands)); + assert_true(draw_state_.command_index < XECOUNT(draw_state_.commands)); draw_state_.commands[draw_state_.command_index].primitive = primitive; draw_state_.commands[draw_state_.command_index].vertex_count = count; ++draw_state_.command_index; @@ -511,7 +511,7 @@ void D3D11ProfilerDisplay::Flush() { context->Map(vertex_buffer_, 0, D3D11_MAP_WRITE_DISCARD, 0, &res); memcpy(res.pData, draw_state_.vertex_buffer, sizeof(Vertex) * draw_state_.vertex_index); context->Unmap(vertex_buffer_, 0); - + uint32_t stride = 20; uint32_t offset = 0; context->IASetVertexBuffers(0, 1, &vertex_buffer_, &stride, &offset); diff --git a/src/xenia/gpu/d3d11/d3d11_shader_resource.cc b/src/xenia/gpu/d3d11/d3d11_shader_resource.cc index e4be7e2cf..b5c28c9f2 100644 --- a/src/xenia/gpu/d3d11/d3d11_shader_resource.cc +++ b/src/xenia/gpu/d3d11/d3d11_shader_resource.cc @@ -252,7 +252,7 @@ int D3D11VertexShaderResource::CreateInputLayout(const void* byte_code, vtx_format = DXGI_FORMAT_R32G32B32A32_FLOAT; break; default: - XEASSERTALWAYS(); + assert_always(); break; } element_descs[el_index].SemanticName = "XE_VF"; @@ -299,7 +299,7 @@ int D3D11VertexShaderResource::DemandGeometryShader( shader = new D3D11QuadListGeometryShader(device); break; default: - XEASSERTALWAYS(); + assert_always(); return 1; } if (!shader) { diff --git a/src/xenia/gpu/d3d11/d3d11_shader_translator.cc b/src/xenia/gpu/d3d11/d3d11_shader_translator.cc index b23c0d5a5..1d7c74940 100644 --- a/src/xenia/gpu/d3d11/d3d11_shader_translator.cc +++ b/src/xenia/gpu/d3d11/d3d11_shader_translator.cc @@ -58,7 +58,7 @@ const char* GetFormatTypeName(const VertexBufferResource::DeclElement& el) { return "float4"; default: XELOGE("Unknown vertex format: %d", el.format); - XEASSERTALWAYS(); + assert_always(); return "float4"; } } @@ -141,7 +141,7 @@ int D3D11ShaderTranslator::TranslateVertexShader( append( "struct VS_OUTPUT {\n"); if (alloc_counts.positions) { - XEASSERT(alloc_counts.positions == 1); + assert_true(alloc_counts.positions == 1); append( " float4 oPos : SV_POSITION;\n"); } @@ -244,7 +244,7 @@ int D3D11ShaderTranslator::TranslatePixelShader( append( "struct VS_OUTPUT {\n"); if (alloc_counts.positions) { - XEASSERT(alloc_counts.positions == 1); + assert_true(alloc_counts.positions == 1); append( " float4 oPos : SV_POSITION;\n"); } @@ -417,7 +417,7 @@ void D3D11ShaderTranslator::AppendDestRegName(uint32_t num, uint32_t dst_exp) { default: // TODO(benvanik): other render targets? // TODO(benvanik): depth? - XEASSERTALWAYS(); + assert_always(); break; } break; @@ -1272,7 +1272,7 @@ int D3D11ShaderTranslator::GetFormatComponentCount(uint32_t format) { return 4; default: XELOGE("Unknown vertex format: %d", format); - XEASSERTALWAYS(); + assert_always(); return 4; } } @@ -1348,7 +1348,7 @@ int D3D11ShaderTranslator::TranslateExec(const instr_cf_exec_t& cf) { case TEX_SET_GRADIENTS_H: case TEX_SET_GRADIENTS_V: default: - XEASSERTALWAYS(); + assert_always(); break; } } else { diff --git a/src/xenia/gpu/d3d11/d3d11_texture_resource.cc b/src/xenia/gpu/d3d11/d3d11_texture_resource.cc index a90c60b0d..301638ffd 100644 --- a/src/xenia/gpu/d3d11/d3d11_texture_resource.cc +++ b/src/xenia/gpu/d3d11/d3d11_texture_resource.cc @@ -136,13 +136,13 @@ int D3D11TextureResource::CreateHandle2D() { int D3D11TextureResource::CreateHandle3D() { XELOGE("D3D11: CreateTexture3D not yet implemented"); - XEASSERTALWAYS(); + assert_always(); return 1; } int D3D11TextureResource::CreateHandleCube() { XELOGE("D3D11: CreateTextureCube not yet implemented"); - XEASSERTALWAYS(); + assert_always(); return 1; } diff --git a/src/xenia/gpu/graphics_driver.cc b/src/xenia/gpu/graphics_driver.cc index e398839b8..46642a0d3 100644 --- a/src/xenia/gpu/graphics_driver.cc +++ b/src/xenia/gpu/graphics_driver.cc @@ -157,7 +157,7 @@ int GraphicsDriver::PopulateShaders(DrawCommand& command) { XELOGE("No pixel shader bound; ignoring"); return 1; } - + xe_gpu_program_cntl_t program_cntl; program_cntl.dword_0 = register_file_[XE_GPU_REG_SQ_PROGRAM_CNTL].u32; if (!vertex_shader_->is_prepared()) { @@ -181,7 +181,7 @@ int GraphicsDriver::PopulateShaders(DrawCommand& command) { int GraphicsDriver::PopulateInputAssembly(DrawCommand& command) { SCOPE_profile_cpu_f("gpu"); - + const auto& buffer_inputs = command.vertex_shader->buffer_inputs(); command.vertex_buffer_count = buffer_inputs.count; for (size_t n = 0; n < buffer_inputs.count; n++) { @@ -201,10 +201,10 @@ int GraphicsDriver::PopulateInputAssembly(DrawCommand& command) { fetch = &group->vertex_fetch_2; break; } - XEASSERTNOTNULL(fetch); + assert_not_null(fetch); // If this assert doesn't hold, maybe we just abort? - XEASSERT(fetch->type == 0x3); - XEASSERTNOTZERO(fetch->size); + assert_true(fetch->type == 0x3); + assert_not_zero(fetch->size); const auto& info = desc.info; @@ -278,7 +278,7 @@ int GraphicsDriver::PopulateSamplerSet( XELOGW("D3D11: unknown texture format %d", info.format); return 0; // invalid texture used } - + // TODO(benvanik): quick validate without refetching intraframe. // Fetch texture from the cache. MemoryRange memory_range; diff --git a/src/xenia/gpu/graphics_system.cc b/src/xenia/gpu/graphics_system.cc index 86905cc48..abd03e2d6 100644 --- a/src/xenia/gpu/graphics_system.cc +++ b/src/xenia/gpu/graphics_system.cc @@ -72,7 +72,7 @@ void GraphicsSystem::ThreadStart() { // Initialize driver and ringbuffer. Initialize(); - XEASSERTNOTNULL(driver_); + assert_not_null(driver_); SetEvent(thread_wait_); // Main run loop. @@ -128,7 +128,7 @@ void GraphicsSystem::InitializeRingBuffer(uint32_t ptr, uint32_t page_count) { while (!driver_) { Sleep(0); } - XEASSERTNOTNULL(driver_); + assert_not_null(driver_); command_processor_->Initialize(driver_, ptr, page_count); } @@ -154,7 +154,7 @@ uint64_t GraphicsSystem::ReadRegister(uint64_t addr) { return 1; } - XEASSERT(r >= 0 && r < RegisterFile::kRegisterCount); + assert_true(r >= 0 && r < RegisterFile::kRegisterCount); return regs->values[r].u32; } @@ -175,7 +175,7 @@ void GraphicsSystem::WriteRegister(uint64_t addr, uint64_t value) { break; } - XEASSERT(r >= 0 && r < RegisterFile::kRegisterCount); + assert_true(r >= 0 && r < RegisterFile::kRegisterCount); regs->values[r].u32 = (uint32_t)value; } diff --git a/src/xenia/gpu/nop/nop_graphics_system.cc b/src/xenia/gpu/nop/nop_graphics_system.cc index 9ae31bb3a..8e470375d 100644 --- a/src/xenia/gpu/nop/nop_graphics_system.cc +++ b/src/xenia/gpu/nop/nop_graphics_system.cc @@ -40,11 +40,11 @@ NopGraphicsSystem::~NopGraphicsSystem() { void NopGraphicsSystem::Initialize() { GraphicsSystem::Initialize(); - XEASSERTNULL(driver_); + assert_null(driver_); driver_ = new NopGraphicsDriver(memory_); - XEASSERTNULL(timer_queue_); - XEASSERTNULL(vsync_timer_); + assert_null(timer_queue_); + assert_null(vsync_timer_); timer_queue_ = CreateTimerQueue(); CreateTimerQueueTimer( diff --git a/src/xenia/gpu/shader_resource.cc b/src/xenia/gpu/shader_resource.cc index 07b64efbe..dfbac3648 100644 --- a/src/xenia/gpu/shader_resource.cc +++ b/src/xenia/gpu/shader_resource.cc @@ -29,7 +29,7 @@ ShaderResource::ShaderResource(const MemoryRange& memory_range, // Verify. dword_count_ = memory_range.length / 4; - XEASSERT(dword_count_ <= 512); + assert_true(dword_count_ <= 512); // Copy bytes and swap. size_t byte_size = dword_count_ * sizeof(uint32_t); @@ -122,7 +122,7 @@ void ShaderResource::GatherExec(const instr_cf_exec_t* cf) { case TEX_SET_GRADIENTS_H: case TEX_SET_GRADIENTS_V: default: - XEASSERTALWAYS(); + assert_always(); break; } } else { @@ -145,7 +145,7 @@ void ShaderResource::GatherExec(const instr_cf_exec_t* cf) { } void ShaderResource::GatherVertexFetch(const instr_fetch_vtx_t* vtx) { - XEASSERT(type_ == XE_GPU_SHADER_TYPE_VERTEX); + assert_true(type_ == XE_GPU_SHADER_TYPE_VERTEX); // dst_reg/dst_swiz // src_reg/src_swiz @@ -188,16 +188,16 @@ void ShaderResource::GatherVertexFetch(const instr_fetch_vtx_t* vtx) { auto& desc = inputs.descs[n]; auto& info = desc.info; if (desc.fetch_slot == fetch_slot) { - XEASSERT(info.element_count <= XECOUNT(info.elements)); + assert_true(info.element_count <= XECOUNT(info.elements)); // It may not hold that all strides are equal, but I hope it does. - XEASSERT(!vtx->stride || info.stride_words == vtx->stride); + assert_true(!vtx->stride || info.stride_words == vtx->stride); el = &info.elements[info.element_count++]; break; } } if (!el) { - XEASSERTNOTZERO(vtx->stride); - XEASSERT(inputs.count + 1 < XECOUNT(inputs.descs)); + assert_not_zero(vtx->stride); + assert_true(inputs.count + 1 < XECOUNT(inputs.descs)); auto& desc = inputs.descs[inputs.count++]; desc.input_index = inputs.count - 1; desc.fetch_slot = fetch_slot; @@ -243,7 +243,7 @@ void ShaderResource::GatherVertexFetch(const instr_fetch_vtx_t* vtx) { break; default: XELOGE("Unknown vertex format: %d", el->format); - XEASSERTALWAYS(); + assert_always(); break; } } @@ -251,7 +251,7 @@ void ShaderResource::GatherVertexFetch(const instr_fetch_vtx_t* vtx) { void ShaderResource::GatherTextureFetch(const xenos::instr_fetch_tex_t* tex) { // TODO(benvanik): check dest_swiz to see if we are writing anything. - XEASSERT(sampler_inputs_.count + 1 < XECOUNT(sampler_inputs_.descs)); + assert_true(sampler_inputs_.count + 1 < XECOUNT(sampler_inputs_.descs)); auto& input = sampler_inputs_.descs[sampler_inputs_.count++]; input.input_index = sampler_inputs_.count - 1; input.fetch_slot = tex->const_idx & 0xF; // ? diff --git a/src/xenia/kernel/fs/devices/disc_image_device.cc b/src/xenia/kernel/fs/devices/disc_image_device.cc index f46e3e1d7..e3e2a8c4b 100644 --- a/src/xenia/kernel/fs/devices/disc_image_device.cc +++ b/src/xenia/kernel/fs/devices/disc_image_device.cc @@ -98,11 +98,11 @@ Entry* DiscImageDevice::ResolvePath(const char* path) { } X_STATUS DiscImageDevice::QueryVolume(XVolumeInfo* out_info, size_t length) { - XEASSERTALWAYS(); + assert_always(); return X_STATUS_NOT_IMPLEMENTED; } X_STATUS DiscImageDevice::QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length) { - XEASSERTALWAYS(); + assert_always(); return X_STATUS_NOT_IMPLEMENTED; } diff --git a/src/xenia/kernel/fs/devices/disc_image_entry.cc b/src/xenia/kernel/fs/devices/disc_image_entry.cc index 2b4b51834..a11f98088 100644 --- a/src/xenia/kernel/fs/devices/disc_image_entry.cc +++ b/src/xenia/kernel/fs/devices/disc_image_entry.cc @@ -53,7 +53,7 @@ DiscImageEntry::~DiscImageEntry() { } X_STATUS DiscImageEntry::QueryInfo(XFileInfo* out_info) { - XEASSERTNOTNULL(out_info); + assert_not_null(out_info); out_info->creation_time = 0; out_info->last_access_time = 0; out_info->last_write_time = 0; @@ -66,7 +66,7 @@ X_STATUS DiscImageEntry::QueryInfo(XFileInfo* out_info) { X_STATUS DiscImageEntry::QueryDirectory( XDirectoryInfo* out_info, size_t length, const char* file_name, bool restart) { - XEASSERTNOTNULL(out_info); + assert_not_null(out_info); if (restart == true && gdfx_entry_iterator_ != gdfx_entry_->children.end()) { gdfx_entry_iterator_ = gdfx_entry_->children.end(); diff --git a/src/xenia/kernel/fs/devices/host_path_device.cc b/src/xenia/kernel/fs/devices/host_path_device.cc index 675563416..b4cbf5046 100644 --- a/src/xenia/kernel/fs/devices/host_path_device.cc +++ b/src/xenia/kernel/fs/devices/host_path_device.cc @@ -67,7 +67,7 @@ Entry* HostPathDevice::ResolvePath(const char* path) { // TODO(gibbed): call into HostPathDevice? X_STATUS HostPathDevice::QueryVolume(XVolumeInfo* out_info, size_t length) { - XEASSERTNOTNULL(out_info); + assert_not_null(out_info); const char* name = "test"; // TODO(gibbed): actual value auto end = (uint8_t*)out_info + length; @@ -86,7 +86,7 @@ X_STATUS HostPathDevice::QueryVolume(XVolumeInfo* out_info, size_t length) { // TODO(gibbed): call into HostPathDevice? X_STATUS HostPathDevice::QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length) { - XEASSERTNOTNULL(out_info); + assert_not_null(out_info); const char* name = "test"; // TODO(gibbed): actual value auto end = (uint8_t*)out_info + length; diff --git a/src/xenia/kernel/fs/devices/host_path_entry.cc b/src/xenia/kernel/fs/devices/host_path_entry.cc index 037563625..a7f908bd3 100644 --- a/src/xenia/kernel/fs/devices/host_path_entry.cc +++ b/src/xenia/kernel/fs/devices/host_path_entry.cc @@ -54,7 +54,7 @@ HostPathEntry::~HostPathEntry() { #define COMBINE_TIME(t) (((uint64_t)t.dwHighDateTime << 32) | t.dwLowDateTime) X_STATUS HostPathEntry::QueryInfo(XFileInfo* out_info) { - XEASSERTNOTNULL(out_info); + assert_not_null(out_info); WIN32_FILE_ATTRIBUTE_DATA data; if (!GetFileAttributesEx( @@ -75,7 +75,7 @@ X_STATUS HostPathEntry::QueryInfo(XFileInfo* out_info) { X_STATUS HostPathEntry::QueryDirectory( XDirectoryInfo* out_info, size_t length, const char* file_name, bool restart) { - XEASSERTNOTNULL(out_info); + assert_not_null(out_info); WIN32_FIND_DATA ffd; diff --git a/src/xenia/kernel/fs/devices/stfs_container_device.cc b/src/xenia/kernel/fs/devices/stfs_container_device.cc index d557c2a1d..b055e8820 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_device.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_device.cc @@ -100,11 +100,11 @@ Entry* STFSContainerDevice::ResolvePath(const char* path) { X_STATUS STFSContainerDevice::QueryVolume(XVolumeInfo* out_info, size_t length) { - XEASSERTALWAYS(); + assert_always(); return X_STATUS_NOT_IMPLEMENTED; } X_STATUS STFSContainerDevice::QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length) { - XEASSERTALWAYS(); + assert_always(); return X_STATUS_NOT_IMPLEMENTED; } diff --git a/src/xenia/kernel/fs/devices/stfs_container_entry.cc b/src/xenia/kernel/fs/devices/stfs_container_entry.cc index a91d1234b..318b11bf7 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_entry.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_entry.cc @@ -32,7 +32,7 @@ STFSContainerEntry::~STFSContainerEntry() { } X_STATUS STFSContainerEntry::QueryInfo(XFileInfo* out_info) { - XEASSERTNOTNULL(out_info); + assert_not_null(out_info); out_info->creation_time = stfs_entry_->update_timestamp; out_info->last_access_time = stfs_entry_->access_timestamp; out_info->last_write_time = stfs_entry_->update_timestamp; @@ -45,7 +45,7 @@ X_STATUS STFSContainerEntry::QueryInfo(XFileInfo* out_info) { X_STATUS STFSContainerEntry::QueryDirectory( XDirectoryInfo* out_info, size_t length, const char* file_name, bool restart) { - XEASSERTNOTNULL(out_info); + assert_not_null(out_info); if (restart && stfs_entry_iterator_ != stfs_entry_->children.end()) { stfs_entry_iterator_ = stfs_entry_->children.end(); diff --git a/src/xenia/kernel/fs/entry.cc b/src/xenia/kernel/fs/entry.cc index c7c28819b..0658d0f7b 100644 --- a/src/xenia/kernel/fs/entry.cc +++ b/src/xenia/kernel/fs/entry.cc @@ -26,7 +26,7 @@ MemoryMapping::~MemoryMapping() { Entry::Entry(Type type, Device* device, const char* path) : type_(type), device_(device) { - XEASSERTNOTNULL(device); + assert_not_null(device); path_ = xestrdupa(path); // TODO(benvanik): *shudder* absolute_path_ = xestrdupa((std::string(device->path()) + std::string(path)).c_str()); diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index bc10751d7..025fcc990 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -42,7 +42,7 @@ KernelState::KernelState(Emulator* emulator) : object_table_ = new ObjectTable(); object_mutex_ = xe_mutex_alloc(10000); - XEASSERTNULL(shared_kernel_state_); + assert_null(shared_kernel_state_); shared_kernel_state_ = this; } @@ -55,7 +55,7 @@ KernelState::~KernelState() { delete dispatcher_; - XEASSERT(shared_kernel_state_ == this); + assert_true(shared_kernel_state_ == this); shared_kernel_state_ = NULL; } @@ -81,7 +81,7 @@ XModule* KernelState::GetModule(const char* name) { return NULL; } else { // TODO(benvanik): support user modules/loading/etc. - XEASSERTALWAYS(); + assert_always(); return NULL; } } diff --git a/src/xenia/kernel/object_table.cc b/src/xenia/kernel/object_table.cc index 47940a6fb..746821bf0 100644 --- a/src/xenia/kernel/object_table.cc +++ b/src/xenia/kernel/object_table.cc @@ -22,7 +22,7 @@ ObjectTable::ObjectTable() : table_(NULL), last_free_entry_(0) { table_mutex_ = xe_mutex_alloc(0); - XEASSERTNOTNULL(table_mutex_); + assert_not_null(table_mutex_); } ObjectTable::~ObjectTable() { @@ -88,7 +88,7 @@ X_STATUS ObjectTable::FindFreeSlot(uint32_t* out_slot) { } X_STATUS ObjectTable::AddHandle(XObject* object, X_HANDLE* out_handle) { - XEASSERTNOTNULL(out_handle); + assert_not_null(out_handle); X_STATUS result = X_STATUS_SUCCESS; @@ -156,7 +156,7 @@ X_STATUS ObjectTable::RemoveHandle(X_HANDLE handle) { } X_STATUS ObjectTable::GetObject(X_HANDLE handle, XObject** out_object) { - XEASSERTNOTNULL(out_object); + assert_not_null(out_object); X_STATUS result = X_STATUS_SUCCESS; @@ -197,7 +197,7 @@ X_STATUS ObjectTable::GetObject(X_HANDLE handle, XObject** out_object) { X_HANDLE ObjectTable::TranslateHandle(X_HANDLE handle) { if (handle == 0xFFFFFFFF) { // CurrentProcess - //XEASSERTALWAYS(); + //assert_always(); return 0; } else if (handle == 0xFFFFFFFE) { // CurrentThread diff --git a/src/xenia/kernel/objects/xevent.cc b/src/xenia/kernel/objects/xevent.cc index ff0b73cc1..e1034d787 100644 --- a/src/xenia/kernel/objects/xevent.cc +++ b/src/xenia/kernel/objects/xevent.cc @@ -26,13 +26,13 @@ XEvent::~XEvent() { } void XEvent::Initialize(bool manual_reset, bool initial_state) { - XEASSERTNULL(handle_); + assert_null(handle_); handle_ = CreateEvent(NULL, manual_reset, initial_state, NULL); } void XEvent::InitializeNative(void* native_ptr, DISPATCH_HEADER& header) { - XEASSERTNULL(handle_); + assert_null(handle_); bool manual_reset; switch (header.type_flags >> 24) { @@ -43,7 +43,7 @@ void XEvent::InitializeNative(void* native_ptr, DISPATCH_HEADER& header) { manual_reset = false; break; default: - XEASSERTALWAYS(); + assert_always(); return; } diff --git a/src/xenia/kernel/objects/xfile.h b/src/xenia/kernel/objects/xfile.h index 9eafe88fe..61852af41 100644 --- a/src/xenia/kernel/objects/xfile.h +++ b/src/xenia/kernel/objects/xfile.h @@ -81,7 +81,7 @@ public: } while (info->next_entry_offset != 0); } }; -XEASSERTSTRUCTSIZE(XDirectoryInfo, 72); +static_assert_size(XDirectoryInfo, 72); // http://msdn.microsoft.com/en-us/library/windows/hardware/ff540287(v=vs.85).aspx class XVolumeInfo { @@ -102,7 +102,7 @@ public: xe_copy_memory(dst + 20, this->label_length, this->label, this->label_length); } }; -XEASSERTSTRUCTSIZE(XVolumeInfo, 24); +static_assert_size(XVolumeInfo, 24); // http://msdn.microsoft.com/en-us/library/windows/hardware/ff540251(v=vs.85).aspx class XFileSystemAttributeInfo { @@ -121,7 +121,7 @@ public: xe_copy_memory(dst + 12, this->fs_name_length, this->fs_name, this->fs_name_length); } }; -XEASSERTSTRUCTSIZE(XFileSystemAttributeInfo, 16); +static_assert_size(XFileSystemAttributeInfo, 16); class XFile : public XObject { public: diff --git a/src/xenia/kernel/objects/xmutant.cc b/src/xenia/kernel/objects/xmutant.cc index 02ff6f27b..99eecc04a 100644 --- a/src/xenia/kernel/objects/xmutant.cc +++ b/src/xenia/kernel/objects/xmutant.cc @@ -26,22 +26,22 @@ XMutant::~XMutant() { } void XMutant::Initialize(bool initial_owner) { - XEASSERTNULL(handle_); + assert_null(handle_); handle_ = CreateMutex(NULL, initial_owner ? TRUE : FALSE, NULL); } void XMutant::InitializeNative(void* native_ptr, DISPATCH_HEADER& header) { - XEASSERTNULL(handle_); + assert_null(handle_); // Haven't seen this yet, but it's possible. - XEASSERTALWAYS(); + assert_always(); } X_STATUS XMutant::ReleaseMutant( uint32_t priority_increment, bool abandon, bool wait) { // TODO(benvanik): abandoning. - XEASSERTFALSE(abandon); + assert_false(abandon); BOOL result = ReleaseMutex(handle_); if (result) { return X_STATUS_SUCCESS; diff --git a/src/xenia/kernel/objects/xnotify_listener.cc b/src/xenia/kernel/objects/xnotify_listener.cc index 7e9ffb704..2f874c988 100644 --- a/src/xenia/kernel/objects/xnotify_listener.cc +++ b/src/xenia/kernel/objects/xnotify_listener.cc @@ -28,7 +28,7 @@ XNotifyListener::~XNotifyListener() { } void XNotifyListener::Initialize(uint64_t mask) { - XEASSERTNULL(wait_handle_); + assert_null(wait_handle_); lock_ = xe_mutex_alloc(); wait_handle_ = CreateEvent(NULL, TRUE, FALSE, NULL); diff --git a/src/xenia/kernel/objects/xsemaphore.cc b/src/xenia/kernel/objects/xsemaphore.cc index 642a88181..c0594e8a2 100644 --- a/src/xenia/kernel/objects/xsemaphore.cc +++ b/src/xenia/kernel/objects/xsemaphore.cc @@ -26,13 +26,13 @@ XSemaphore::~XSemaphore() { } void XSemaphore::Initialize(int32_t initial_count, int32_t maximum_count) { - XEASSERTNULL(handle_); + assert_null(handle_); handle_ = CreateSemaphore(NULL, initial_count, maximum_count, NULL); } void XSemaphore::InitializeNative(void* native_ptr, DISPATCH_HEADER& header) { - XEASSERTNULL(handle_); + assert_null(handle_); // NOT IMPLEMENTED // We expect Initialize to be called shortly. diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index d8e4bac85..47566c20d 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -334,7 +334,7 @@ X_STATUS XThread::PlatformCreate() { this); #else // TODO(benvanik): pthread_create_suspended_np on linux - XEASSERTALWAYS(); + assert_always(); #endif // OSX } else { result_code = pthread_create( @@ -552,7 +552,7 @@ X_STATUS XThread::Delay( if (timeout_ticks > 0) { // Absolute time, based on January 1, 1601. // TODO(benvanik): convert time to relative time. - XEASSERTALWAYS(); + assert_always(); timeout_ms = 0; } else if (timeout_ticks < 0) { // Relative time. diff --git a/src/xenia/kernel/objects/xtimer.cc b/src/xenia/kernel/objects/xtimer.cc index f38aae6c0..70c8bdd90 100644 --- a/src/xenia/kernel/objects/xtimer.cc +++ b/src/xenia/kernel/objects/xtimer.cc @@ -28,7 +28,7 @@ XTimer::~XTimer() { } void XTimer::Initialize(uint32_t timer_type) { - XEASSERTNULL(handle_); + assert_null(handle_); bool manual_reset = false; switch (timer_type) { @@ -39,7 +39,7 @@ void XTimer::Initialize(uint32_t timer_type) { manual_reset = false; break; default: - XEASSERTALWAYS(); + assert_always(); break; } @@ -71,7 +71,7 @@ X_STATUS XTimer::SetTimer( void XTimer::CompletionRoutine( XTimer* timer, DWORD timer_low, DWORD timer_high) { - XEASSERT(timer->current_routine_); + assert_true(timer->current_routine_); // Queue APC to call back routine with (arg, low, high). // TODO(benvanik): APC dispatch. diff --git a/src/xenia/kernel/util/xex2.cc b/src/xenia/kernel/util/xex2.cc index 1aca590e3..50cf442cf 100644 --- a/src/xenia/kernel/util/xex2.cc +++ b/src/xenia/kernel/util/xex2.cc @@ -238,7 +238,7 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, { const size_t max_count = XECOUNT(header->import_libraries); size_t count = XEGETUINT32BE(pp + 0x08); - XEASSERT(count <= max_count); + assert_true(count <= max_count); if (count > max_count) { XELOGW("ignoring %zu extra entries in XEX_HEADER_IMPORT_LIBRARIES", (max_count - count)); @@ -260,7 +260,7 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, const uint16_t name_index = XEGETUINT16BE(pp + 0x24) & 0xFF; for (size_t i = 0, j = 0; i < string_table_size;) { - XEASSERT(j <= 0xFF); + assert_true(j <= 0xFF); if (j == name_index) { XEIGNORE(xestrcpya(library->name, XECOUNT(library->name), string_table + i)); @@ -293,7 +293,7 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, { const size_t max_count = XECOUNT(header->static_libraries); size_t count = (opt_header->length - 4) / 16; - XEASSERT(count <= max_count); + assert_true(count <= max_count); if (count > max_count) { XELOGW("ignoring %zu extra entries in XEX_HEADER_STATIC_LIBRARIES", (max_count - count)); @@ -326,7 +326,7 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, switch (fmt->compression_type) { case XEX_COMPRESSION_NONE: // TODO: XEX_COMPRESSION_NONE - XEASSERTALWAYS(); + assert_always(); break; case XEX_COMPRESSION_BASIC: { @@ -368,7 +368,7 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, break; case XEX_COMPRESSION_DELTA: // TODO: XEX_COMPRESSION_DELTA - XEASSERTALWAYS(); + assert_always(); break; } } @@ -460,7 +460,7 @@ typedef struct mspack_memory_file_t { } mspack_memory_file; mspack_memory_file *mspack_memory_open(struct mspack_system *sys, void* buffer, const size_t buffer_size) { - XEASSERT(buffer_size < INT_MAX); + assert_true(buffer_size < INT_MAX); if (buffer_size >= INT_MAX) { return NULL; } @@ -575,7 +575,7 @@ int xe_xex2_read_image_uncompressed(const xe_xex2_header_t *header, uncompressed_size); return 0; default: - XEASSERTALWAYS(); + assert_always(); return 1; } @@ -642,7 +642,7 @@ int xe_xex2_read_image_basic_compressed(const xe_xex2_header_t *header, } break; default: - XEASSERTALWAYS(); + assert_always(); return 1; } @@ -701,7 +701,7 @@ int xe_xex2_read_image_compressed(const xe_xex2_header_t *header, (uint8_t*)input_buffer, input_size); break; default: - XEASSERTALWAYS(); + assert_always(); return false; } @@ -809,7 +809,7 @@ int xe_xex2_read_image(xe_xex2_ref xex, const uint8_t *xex_addr, return xe_xex2_read_image_compressed( header, xex_addr, xex_length, memory); default: - XEASSERTALWAYS(); + assert_always(); return 1; } } @@ -922,7 +922,7 @@ int xe_xex2_find_import_infos(xe_xex2_ref xex, break; } } - XEASSERT(library_index != (size_t)-1); + assert_true(library_index != (size_t)-1); // Records: // The number of records does not correspond to the number of imports! @@ -947,9 +947,9 @@ int xe_xex2_find_import_infos(xe_xex2_ref xex, // Allocate storage. xe_xex2_import_info_t *infos = (xe_xex2_import_info_t*)xe_calloc( info_count * sizeof(xe_xex2_import_info_t)); - XEEXPECTNOTNULL(infos); + assert_not_null(infos); - XEASSERTNOTZERO(info_count); + assert_not_zero(info_count); // Construct infos. for (size_t n = 0, i = 0; n < library->record_count; n++) { @@ -958,7 +958,7 @@ int xe_xex2_find_import_infos(xe_xex2_ref xex, const uint32_t type = (value & 0xFF000000) >> 24; // Verify library index matches given library. - //XEASSERT(library_index == ((value >> 16) & 0xFF)); + //assert_true(library_index == ((value >> 16) & 0xFF)); switch (type) { case 0x00: @@ -971,14 +971,14 @@ int xe_xex2_find_import_infos(xe_xex2_ref xex, case 0x01: { // Thunk for previous record. - XEASSERT(i > 0); + assert_true(i > 0); xe_xex2_import_info_t* info = &infos[i - 1]; - XEASSERT(info->ordinal == (value & 0xFFFF)); + assert_true(info->ordinal == (value & 0xFFFF)); info->thunk_address = record; } break; default: - //XEASSERTALWAYS(); + //assert_always(); break; } } @@ -986,10 +986,6 @@ int xe_xex2_find_import_infos(xe_xex2_ref xex, xex->library_imports[library_index].count = info_count; xex->library_imports[library_index].infos = infos; return 0; - -XECLEANUP: - xe_free(infos); - return 1; } int xe_xex2_get_import_infos(xe_xex2_ref xex, diff --git a/src/xenia/kernel/xam_content.cc b/src/xenia/kernel/xam_content.cc index 5f53bc4ea..4b045c1dd 100644 --- a/src/xenia/kernel/xam_content.cc +++ b/src/xenia/kernel/xam_content.cc @@ -33,7 +33,7 @@ SHIM_CALL XamContentGetLicenseMask_shim( mask_ptr, overlapped_ptr); - XEASSERTZERO(overlapped_ptr); + assert_zero(overlapped_ptr); // Arcade games seem to call this and check the result mask for random bits. // If we fail, the games seem to use a hardcoded mask, which is likely trial. diff --git a/src/xenia/kernel/xam_msg.cc b/src/xenia/kernel/xam_msg.cc index 7215e94d1..ded24cee1 100644 --- a/src/xenia/kernel/xam_msg.cc +++ b/src/xenia/kernel/xam_msg.cc @@ -44,8 +44,8 @@ SHIM_CALL XMsgInProcessCall_shim( uint32_t a = SHIM_MEM_32(arg1 + 0); // 0x00000002 uint32_t b = SHIM_MEM_32(arg1 + 4); // out ptr to 4b - expect 0 XELOGD("XMPGetStatusEx(%.8X, %.8X)", a, b); - XEASSERTZERO(arg2); - XEASSERT(a == 2); + assert_zero(arg2); + assert_true(a == 2); SHIM_SET_MEM_32(b, 0); handled = true; } else if (message == 0x0007001A) { @@ -59,8 +59,8 @@ SHIM_CALL XMsgInProcessCall_shim( uint32_t a = SHIM_MEM_32(arg1 + 0); // 0x00000002 uint32_t b = SHIM_MEM_32(arg1 + 4); // out ptr to 4b - expect 0 XELOGD("XMPGetStatus(%.8X, %.8X)", a, b); - XEASSERTZERO(arg2); - XEASSERT(a == 2); + assert_zero(arg2); + assert_true(a == 2); SHIM_SET_MEM_32(b, 0); handled = true; } diff --git a/src/xenia/kernel/xam_user.cc b/src/xenia/kernel/xam_user.cc index 005475812..85ebc4835 100644 --- a/src/xenia/kernel/xam_user.cc +++ b/src/xenia/kernel/xam_user.cc @@ -136,7 +136,7 @@ SHIM_CALL XamUserReadProfileSettings_shim( // 0xfffe07d1 = profile? // TODO(benvanik): implement overlapped support - XEASSERTZERO(overlapped_ptr); + assert_zero(overlapped_ptr); // First call asks for size (fill buffer_size_ptr). // Second call asks for buffer contents with that size. diff --git a/src/xenia/kernel/xboxkrnl_audio.cc b/src/xenia/kernel/xboxkrnl_audio.cc index e048dad1a..76495c0bb 100644 --- a/src/xenia/kernel/xboxkrnl_audio.cc +++ b/src/xenia/kernel/xboxkrnl_audio.cc @@ -75,7 +75,7 @@ SHIM_CALL XAudioGetVoiceCategoryVolumeChangeMask_shim( "XAudioGetVoiceCategoryVolumeChangeMask(%.8X, %.8X)", driver_ptr, out_ptr); - XEASSERT((driver_ptr & 0xFFFF0000) == 0x41550000); + assert_true((driver_ptr & 0xFFFF0000) == 0x41550000); auto audio_system = state->emulator()->audio_system(); @@ -124,7 +124,7 @@ SHIM_CALL XAudioRegisterRenderDriverClient_shim( return; } - XEASSERTTRUE(!(index & ~0x0000FFFF)); + assert_true(!(index & ~0x0000FFFF)); SHIM_SET_MEM_32(driver_ptr, 0x41550000 | (index & 0x0000FFFF)); SHIM_SET_RETURN_32(X_ERROR_SUCCESS); } @@ -138,7 +138,7 @@ SHIM_CALL XAudioUnregisterRenderDriverClient_shim( "XAudioUnregisterRenderDriverClient(%.8X)", driver_ptr); - XEASSERT((driver_ptr & 0xFFFF0000) == 0x41550000); + assert_true((driver_ptr & 0xFFFF0000) == 0x41550000); auto audio_system = state->emulator()->audio_system(); audio_system->UnregisterClient(driver_ptr & 0x0000FFFF); @@ -155,7 +155,7 @@ SHIM_CALL XAudioSubmitRenderDriverFrame_shim( "XAudioSubmitRenderDriverFrame(%.8X, %.8X)", driver_ptr, samples_ptr); - XEASSERT((driver_ptr & 0xFFFF0000) == 0x41550000); + assert_true((driver_ptr & 0xFFFF0000) == 0x41550000); auto audio_system = state->emulator()->audio_system(); audio_system->SubmitFrame(driver_ptr & 0x0000FFFF, samples_ptr); diff --git a/src/xenia/kernel/xboxkrnl_debug.cc b/src/xenia/kernel/xboxkrnl_debug.cc index c0a9e7771..9db006604 100644 --- a/src/xenia/kernel/xboxkrnl_debug.cc +++ b/src/xenia/kernel/xboxkrnl_debug.cc @@ -168,7 +168,7 @@ SHIM_CALL DbgPrint_shim( local[0] = '\0'; strncat(local, start, end + 1 - start); - XEASSERT(arg_size == 8 || arg_size == 4); + assert_true(arg_size == 8 || arg_size == 4); if (arg_size == 8) { if (arg_extras == 0) { uint64_t value = arg_index < 7 @@ -179,7 +179,7 @@ SHIM_CALL DbgPrint_shim( arg_index++; } else { - XEASSERT(false); + assert_true(false); } } else if (arg_size == 4) { @@ -192,13 +192,13 @@ SHIM_CALL DbgPrint_shim( arg_index++; } else { - XEASSERT(false); + assert_true(false); } } } else if (*end == 'n') { - XEASSERT(arg_size == 4); + assert_true(arg_size == 4); if (arg_extras == 0) { uint32_t value = arg_index < 7 ? SHIM_GET_ARG_32(1 + arg_index) @@ -207,7 +207,7 @@ SHIM_CALL DbgPrint_shim( arg_index++; } else { - XEASSERT(false); + assert_true(false); } } else if (*end == 's' || @@ -216,7 +216,7 @@ SHIM_CALL DbgPrint_shim( local[0] = '\0'; strncat(local, start, end + 1 - start); - XEASSERT(arg_size == 4); + assert_true(arg_size == 4); if (arg_extras == 0) { uint32_t value = arg_index < 7 ? SHIM_GET_ARG_32(1 + arg_index) @@ -227,11 +227,11 @@ SHIM_CALL DbgPrint_shim( arg_index++; } else { - XEASSERT(false); + assert_true(false); } } else { - XEASSERT(false); + assert_true(false); break; } @@ -271,7 +271,7 @@ SHIM_CALL RtlRaiseException_shim( // SetThreadName. FFS. uint32_t thread_info_ptr = record_ptr + 20; uint32_t type = SHIM_MEM_32(thread_info_ptr + 0); - XEASSERT(type == 0x1000); + assert_true(type == 0x1000); uint32_t name_ptr = SHIM_MEM_32(thread_info_ptr + 4); uint32_t thread_id = SHIM_MEM_32(thread_info_ptr + 8); diff --git a/src/xenia/kernel/xboxkrnl_hal.cc b/src/xenia/kernel/xboxkrnl_hal.cc index 9234cbe81..e083ceca5 100644 --- a/src/xenia/kernel/xboxkrnl_hal.cc +++ b/src/xenia/kernel/xboxkrnl_hal.cc @@ -25,13 +25,13 @@ namespace kernel { void xeHalReturnToFirmware(uint32_t routine) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // void // IN FIRMWARE_REENTRY Routine // Routine must be 1 'HalRebootRoutine' - XEASSERT(routine == 1); + assert_true(routine == 1); // TODO(benvank): diediedie much more gracefully // Not sure how to blast back up the stack in LLVM without exceptions, though. diff --git a/src/xenia/kernel/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl_io.cc index cb3f4f2ca..2a07b4dbc 100644 --- a/src/xenia/kernel/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl_io.cc @@ -70,8 +70,8 @@ SHIM_CALL NtCreateFile_shim( attrs.root_directory != 0) { result = state->object_table()->GetObject( attrs.root_directory, (XObject**)&root_file); - XEASSERT(XSUCCEEDED(result)); - XEASSERT(root_file->type() == XObject::Type::kTypeFile); + assert_true(XSUCCEEDED(result)); + assert_true(root_file->type() == XObject::Type::kTypeFile); auto root_path = root_file->absolute_path(); auto target_path = xestrdupa((std::string(root_path) + std::string(object_name)).c_str()); @@ -147,9 +147,9 @@ SHIM_CALL NtOpenFile_shim( if (attrs.root_directory != 0xFFFFFFFD) { // ObDosDevices result = state->object_table()->GetObject( attrs.root_directory, (XObject**)&root_file); - XEASSERT(XSUCCEEDED(result)); - XEASSERT(root_file->type() == XObject::Type::kTypeFile); - XEASSERTALWAYS(); + assert_true(XSUCCEEDED(result)); + assert_true(root_file->type() == XObject::Type::kTypeFile); + assert_always(); } // Resolve the file using the virtual file system. @@ -226,7 +226,7 @@ SHIM_CALL NtReadFile_shim( byte_offset); // Async not supported yet. - XEASSERTNULL(apc_routine_ptr); + assert_zero(apc_routine_ptr); X_STATUS result = X_STATUS_SUCCESS; uint32_t info = 0; @@ -338,13 +338,13 @@ SHIM_CALL NtSetInformationFile_shim( // struct FILE_POSITION_INFORMATION { // LARGE_INTEGER CurrentByteOffset; // }; - XEASSERT(length == 8); + assert_true(length == 8); info = 8; file->set_position(SHIM_MEM_64(file_info_ptr)); break; default: // Unsupported, for now. - XEASSERTALWAYS(); + assert_always(); info = 0; break; } @@ -394,7 +394,7 @@ SHIM_CALL NtQueryInformationFile_shim( switch (file_info_class) { case XFileInternalInformation: // Internal unique file pointer. Not sure why anyone would want this. - XEASSERT(length == 8); + assert_true(length == 8); info = 8; // TODO(benvanik): use pointer to fs:: entry? SHIM_SET_MEM_64(file_info_ptr, hash_combine(0, file->absolute_path())); @@ -403,7 +403,7 @@ SHIM_CALL NtQueryInformationFile_shim( // struct FILE_POSITION_INFORMATION { // LARGE_INTEGER CurrentByteOffset; // }; - XEASSERT(length == 8); + assert_true(length == 8); info = 8; SHIM_SET_MEM_64(file_info_ptr, file->position()); break; @@ -418,7 +418,7 @@ SHIM_CALL NtQueryInformationFile_shim( // ULONG FileAttributes; // ULONG Unknown; // }; - XEASSERT(length == 56); + assert_true(length == 56); XFileInfo file_info; result = file->QueryInfo(&file_info); if (XSUCCEEDED(result)) { @@ -447,7 +447,7 @@ SHIM_CALL NtQueryInformationFile_shim( break; default: // Unsupported, for now. - XEASSERTALWAYS(); + assert_always(); info = 0; break; } @@ -489,9 +489,9 @@ SHIM_CALL NtQueryFullAttributesFile_shim( if (attrs.root_directory != 0xFFFFFFFD) { // ObDosDevices result = state->object_table()->GetObject( attrs.root_directory, (XObject**)&root_file); - XEASSERT(XSUCCEEDED(result)); - XEASSERT(root_file->type() == XObject::Type::kTypeFile); - XEASSERTALWAYS(); + assert_true(XSUCCEEDED(result)); + assert_true(root_file->type() == XObject::Type::kTypeFile); + assert_always(); } // Resolve the file using the virtual file system. @@ -560,7 +560,7 @@ SHIM_CALL NtQueryVolumeInformationFile_shim( } default: // Unsupported, for now. - XEASSERTALWAYS(); + assert_always(); info = 0; break; } diff --git a/src/xenia/kernel/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl_memory.cc index 5b1c8c579..ab153a625 100644 --- a/src/xenia/kernel/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl_memory.cc @@ -29,7 +29,7 @@ X_STATUS xeNtAllocateVirtualMemory( uint32_t allocation_type, uint32_t protect_bits, uint32_t unknown) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // NTSTATUS // _Inout_ PVOID *BaseAddress, @@ -39,7 +39,7 @@ X_STATUS xeNtAllocateVirtualMemory( // ? handle? // I've only seen zero. - XEASSERT(unknown == 0); + assert_true(unknown == 0); // This allocates memory from the kernel heap, which is initialized on startup // and shared by both the kernel implementation and user code. @@ -73,7 +73,7 @@ X_STATUS xeNtAllocateVirtualMemory( // already happened. if (*base_addr_ptr) { // Having a pointer already means that this is likely a follow-on COMMIT. - XEASSERT(!(allocation_type & X_MEM_RESERVE) && + assert_true(!(allocation_type & X_MEM_RESERVE) && (allocation_type & X_MEM_COMMIT)); return X_STATUS_SUCCESS; } @@ -127,7 +127,7 @@ X_STATUS xeNtFreeVirtualMemory( uint32_t* base_addr_ptr, uint32_t* region_size_ptr, uint32_t free_type, uint32_t unknown) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // NTSTATUS // _Inout_ PVOID *BaseAddress, @@ -136,7 +136,7 @@ X_STATUS xeNtFreeVirtualMemory( // ? handle? // I've only seen zero. - XEASSERT(unknown == 0); + assert_true(unknown == 0); if (!*base_addr_ptr) { return X_STATUS_MEMORY_NOT_ALLOCATED; @@ -193,7 +193,7 @@ uint32_t xeMmAllocatePhysicalMemoryEx( uint32_t type, uint32_t region_size, uint32_t protect_bits, uint32_t min_addr_range, uint32_t max_addr_range, uint32_t alignment) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // Type will usually be 0 (user request?), where 1 and 2 are sometimes made // by D3D/etc. @@ -230,8 +230,8 @@ uint32_t xeMmAllocatePhysicalMemoryEx( // and the memory must be allocated there. I haven't seen a game do this, // and instead they all do min=0 / max=-1 to indicate the system should pick. // If we have to suport arbitrary placement things will get nasty. - XEASSERT(min_addr_range == 0); - XEASSERT(max_addr_range == 0xFFFFFFFF); + assert_true(min_addr_range == 0); + assert_true(max_addr_range == 0xFFFFFFFF); // Allocate. uint32_t flags = MEMORY_FLAG_PHYSICAL; @@ -280,7 +280,7 @@ SHIM_CALL MmAllocatePhysicalMemoryEx_shim( void xeMmFreePhysicalMemory(uint32_t type, uint32_t base_address) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // base_address = result of MmAllocatePhysicalMemory. @@ -310,7 +310,7 @@ SHIM_CALL MmFreePhysicalMemory_shim( uint32_t xeMmQueryAddressProtect(uint32_t base_address) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); uint32_t access = state->memory()->QueryProtect(base_address); @@ -334,7 +334,7 @@ SHIM_CALL MmQueryAddressProtect_shim( uint32_t xeMmQueryAllocationSize(uint32_t base_address) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); size_t size = state->memory()->QuerySize(base_address); diff --git a/src/xenia/kernel/xboxkrnl_misc.cc b/src/xenia/kernel/xboxkrnl_misc.cc index 946aa30e9..1354d4806 100644 --- a/src/xenia/kernel/xboxkrnl_misc.cc +++ b/src/xenia/kernel/xboxkrnl_misc.cc @@ -28,7 +28,7 @@ void xeKeBugCheckEx(uint32_t code, uint32_t param1, uint32_t param2, uint32_t pa XELOGD("*** STOP: 0x%.8X (0x%.8X, 0x%.8X, 0x%.8X, 0x%.8X)", code, param1, param2, param3, param4); fflush(stdout); DebugBreak(); - XEASSERTALWAYS(); + assert_always(); } SHIM_CALL KeBugCheck_shim( diff --git a/src/xenia/kernel/xboxkrnl_modules.cc b/src/xenia/kernel/xboxkrnl_modules.cc index 319cc0ec2..b45724f4a 100644 --- a/src/xenia/kernel/xboxkrnl_modules.cc +++ b/src/xenia/kernel/xboxkrnl_modules.cc @@ -43,7 +43,7 @@ X_STATUS xeExGetXConfigSetting( value = 0x00001000; // USA/Canada break; default: - XEASSERTUNHANDLEDCASE(setting); + assert_unhandled_case(setting); return X_STATUS_INVALID_PARAMETER_2; } break; @@ -80,12 +80,12 @@ X_STATUS xeExGetXConfigSetting( value = 0; break; default: - XEASSERTUNHANDLEDCASE(setting); + assert_unhandled_case(setting); return X_STATUS_INVALID_PARAMETER_2; } break; default: - XEASSERTUNHANDLEDCASE(category); + assert_unhandled_case(category); return X_STATUS_INVALID_PARAMETER_1; } @@ -134,7 +134,7 @@ SHIM_CALL ExGetXConfigSetting_shim( int xeXexCheckExecutablePriviledge(uint32_t privilege) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // BOOL // DWORD Privilege @@ -176,7 +176,7 @@ SHIM_CALL XexCheckExecutablePrivilege_shim( int xeXexGetModuleHandle(const char* module_name, X_HANDLE* module_handle_ptr) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // BOOL // LPCSZ ModuleName diff --git a/src/xenia/kernel/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl_rtl.cc index f5d00f19a..5b632a6b3 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl_rtl.cc @@ -30,7 +30,7 @@ namespace kernel { uint32_t xeRtlCompareMemory(uint32_t source1_ptr, uint32_t source2_ptr, uint32_t length) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // SIZE_T // _In_ const VOID *Source1, @@ -74,7 +74,7 @@ SHIM_CALL RtlCompareMemory_shim( uint32_t xeRtlCompareMemoryUlong(uint32_t source_ptr, uint32_t length, uint32_t pattern) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // SIZE_T // _In_ PVOID Source, @@ -124,7 +124,7 @@ SHIM_CALL RtlCompareMemoryUlong_shim( void xeRtlFillMemoryUlong(uint32_t destination_ptr, uint32_t length, uint32_t pattern) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // VOID // _Out_ PVOID Destination, @@ -172,7 +172,7 @@ SHIM_CALL RtlFillMemoryUlong_shim( // http://msdn.microsoft.com/en-us/library/ff561918 void xeRtlInitAnsiString(uint32_t destination_ptr, uint32_t source_ptr) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // VOID // _Out_ PANSI_STRING DestinationString, @@ -207,7 +207,7 @@ SHIM_CALL RtlInitAnsiString_shim( // http://msdn.microsoft.com/en-us/library/ff561899 void xeRtlFreeAnsiString(uint32_t string_ptr) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // VOID // _Inout_ PANSI_STRING AnsiString @@ -242,7 +242,7 @@ SHIM_CALL RtlFreeAnsiString_shim( // http://msdn.microsoft.com/en-us/library/ff561934 void xeRtlInitUnicodeString(uint32_t destination_ptr, uint32_t source_ptr) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // VOID // _Out_ PUNICODE_STRING DestinationString, @@ -281,7 +281,7 @@ SHIM_CALL RtlInitUnicodeString_shim( // http://msdn.microsoft.com/en-us/library/ff561903 void xeRtlFreeUnicodeString(uint32_t string_ptr) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // VOID // _Inout_ PUNICODE_STRING UnicodeString @@ -310,7 +310,7 @@ SHIM_CALL RtlFreeUnicodeString_shim( X_STATUS xeRtlUnicodeStringToAnsiString( uint32_t destination_ptr, uint32_t source_ptr, uint32_t alloc_dest) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // NTSTATUS // _Inout_ PANSI_STRING DestinationString, @@ -318,7 +318,7 @@ X_STATUS xeRtlUnicodeStringToAnsiString( // _In_ BOOLEAN AllocateDestinationString XELOGE("RtlUnicodeStringToAnsiString not yet implemented"); - XEASSERTALWAYS(); + assert_always(); if (alloc_dest) { // Allocate a new buffer to place the string into. @@ -438,7 +438,7 @@ SHIM_CALL RtlNtStatusToDosError_shim( uint32_t xeRtlImageXexHeaderField(uint32_t xex_header_base_ptr, uint32_t image_field) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // PVOID // PVOID XexHeaderBase @@ -525,11 +525,11 @@ typedef struct { #pragma pack(pop) } -XEASSERTSTRUCTSIZE(X_RTL_CRITICAL_SECTION, 28); +static_assert_size(X_RTL_CRITICAL_SECTION, 28); void xeRtlInitializeCriticalSection(uint32_t cs_ptr) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // VOID // _Out_ LPCRITICAL_SECTION lpCriticalSection @@ -556,7 +556,7 @@ SHIM_CALL RtlInitializeCriticalSection_shim( X_STATUS xeRtlInitializeCriticalSectionAndSpinCount( uint32_t cs_ptr, uint32_t spin_count) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // NTSTATUS // _Out_ LPCRITICAL_SECTION lpCriticalSection, @@ -597,7 +597,7 @@ SHIM_CALL RtlInitializeCriticalSectionAndSpinCount_shim( // TODO(benvanik): remove the need for passing in thread_id. void xeRtlEnterCriticalSection(uint32_t cs_ptr, uint32_t thread_id) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // VOID // _Inout_ LPCRITICAL_SECTION lpCriticalSection @@ -651,7 +651,7 @@ SHIM_CALL RtlEnterCriticalSection_shim( // TODO(benvanik): remove the need for passing in thread_id. uint32_t xeRtlTryEnterCriticalSection(uint32_t cs_ptr, uint32_t thread_id) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // DWORD // _Inout_ LPCRITICAL_SECTION lpCriticalSection @@ -689,7 +689,7 @@ SHIM_CALL RtlTryEnterCriticalSection_shim( void xeRtlLeaveCriticalSection(uint32_t cs_ptr) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // VOID // _Inout_ LPCRITICAL_SECTION lpCriticalSection diff --git a/src/xenia/kernel/xboxkrnl_strings.cc b/src/xenia/kernel/xboxkrnl_strings.cc index caccdaf9c..f6815c01e 100644 --- a/src/xenia/kernel/xboxkrnl_strings.cc +++ b/src/xenia/kernel/xboxkrnl_strings.cc @@ -173,7 +173,7 @@ SHIM_CALL vsprintf_shim( local[0] = '\0'; strncat(local, start, end + 1 - start); - XEASSERT(arg_size == 8 || arg_size == 4); + assert_true(arg_size == 8 || arg_size == 4); if (arg_size == 8) { if (arg_extras == 0) { uint64_t value = SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... @@ -182,7 +182,7 @@ SHIM_CALL vsprintf_shim( arg_index++; } else { - XEASSERT(false); + assert_true(false); } } else if (arg_size == 4) { @@ -193,20 +193,20 @@ SHIM_CALL vsprintf_shim( arg_index++; } else { - XEASSERT(false); + assert_true(false); } } } else if (*end == 'n') { - XEASSERT(arg_size == 4); + assert_true(arg_size == 4); if (arg_extras == 0) { uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... SHIM_SET_MEM_32(value, (uint32_t)((b - buffer) / sizeof(char))); arg_index++; } else { - XEASSERT(false); + assert_true(false); } } else if (*end == 's' || @@ -215,7 +215,7 @@ SHIM_CALL vsprintf_shim( local[0] = '\0'; strncat(local, start, end + 1 - start); - XEASSERT(arg_size == 4); + assert_true(arg_size == 4); if (arg_extras == 0) { uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... const void* pointer = (const void*)SHIM_MEM_ADDR(value); @@ -224,11 +224,11 @@ SHIM_CALL vsprintf_shim( arg_index++; } else { - XEASSERT(false); + assert_true(false); } } else { - XEASSERT(false); + assert_true(false); break; } format = end; @@ -386,7 +386,7 @@ SHIM_CALL _vsnprintf_shim( local[0] = '\0'; strncat(local, start, end + 1 - start); - XEASSERT(arg_size == 8 || arg_size == 4); + assert_true(arg_size == 8 || arg_size == 4); if (arg_size == 8) { if (arg_extras == 0) { uint64_t value = SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... @@ -395,7 +395,7 @@ SHIM_CALL _vsnprintf_shim( arg_index++; } else { - XEASSERT(false); + assert_true(false); } } else if (arg_size == 4) { @@ -406,20 +406,20 @@ SHIM_CALL _vsnprintf_shim( arg_index++; } else { - XEASSERT(false); + assert_true(false); } } } else if (*end == 'n') { - XEASSERT(arg_size == 4); + assert_true(arg_size == 4); if (arg_extras == 0) { uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... SHIM_SET_MEM_32(value, (uint32_t)((b - buffer) / sizeof(char))); arg_index++; } else { - XEASSERT(false); + assert_true(false); } } else if (*end == 's' || @@ -428,7 +428,7 @@ SHIM_CALL _vsnprintf_shim( local[0] = '\0'; strncat(local, start, end + 1 - start); - XEASSERT(arg_size == 4); + assert_true(arg_size == 4); if (arg_extras == 0) { uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... const void* pointer = (const void*)SHIM_MEM_ADDR(value); @@ -437,11 +437,11 @@ SHIM_CALL _vsnprintf_shim( arg_index++; } else { - XEASSERT(false); + assert_true(false); } } else { - XEASSERT(false); + assert_true(false); break; } format = end; @@ -612,7 +612,7 @@ SHIM_CALL _vswprintf_shim( local[0] = '\0'; wcsncat(local, start, end + 1 - start); - XEASSERT(arg_size == 8 || arg_size == 4); + assert_true(arg_size == 8 || arg_size == 4); if (arg_size == 8) { if (arg_extras == 0) { uint64_t value = SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... @@ -621,7 +621,7 @@ SHIM_CALL _vswprintf_shim( arg_index++; } else { - XEASSERT(false); + assert_true(false); } } else if (arg_size == 4) { @@ -632,20 +632,20 @@ SHIM_CALL _vswprintf_shim( arg_index++; } else { - XEASSERT(false); + assert_true(false); } } } else if (*end == 'n') { - XEASSERT(arg_size == 4); + assert_true(arg_size == 4); if (arg_extras == 0) { uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... SHIM_SET_MEM_32(value, (uint32_t)((b - buffer) / sizeof(wchar_t))); arg_index++; } else { - XEASSERT(false); + assert_true(false); } } else if (*end == 'p') { @@ -653,7 +653,7 @@ SHIM_CALL _vswprintf_shim( local[0] = '\0'; wcsncat(local, start, end + 1 - start); - XEASSERT(arg_size == 4); + assert_true(arg_size == 4); if (arg_extras == 0) { uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... const void* pointer = (void*)SHIM_MEM_ADDR(value); @@ -662,7 +662,7 @@ SHIM_CALL _vswprintf_shim( arg_index++; } else { - XEASSERT(false); + assert_true(false); } } else if (*end == 's') { @@ -670,7 +670,7 @@ SHIM_CALL _vswprintf_shim( local[0] = '\0'; wcsncat(local, start, end + 1 - start); - XEASSERT(arg_size == 4); + assert_true(arg_size == 4); if (arg_extras == 0) { uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... const wchar_t* data = (const wchar_t*)SHIM_MEM_ADDR(value); @@ -687,11 +687,11 @@ SHIM_CALL _vswprintf_shim( arg_index++; } else { - XEASSERT(false); + assert_true(false); } } else { - XEASSERT(false); + assert_true(false); break; } format = end; diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index 064f34d7b..8e10a84ce 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -69,7 +69,7 @@ X_STATUS xeExCreateThread( uint32_t xapi_thread_startup, uint32_t start_address, uint32_t start_context, uint32_t creation_flags) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // DWORD // LPHANDLE Handle, @@ -158,7 +158,7 @@ SHIM_CALL ExTerminateThread_shim( X_STATUS xeNtResumeThread(uint32_t handle, uint32_t* out_suspend_count) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); X_STATUS result = X_STATUS_SUCCESS; @@ -198,7 +198,7 @@ SHIM_CALL NtResumeThread_shim( X_STATUS xeKeResumeThread(void* thread_ptr, uint32_t* out_suspend_count) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); X_STATUS result = X_STATUS_SUCCESS; @@ -236,7 +236,7 @@ SHIM_CALL KeResumeThread_shim( X_STATUS xeNtSuspendThread(uint32_t handle, uint32_t* out_suspend_count) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); X_STATUS result = X_STATUS_SUCCESS; @@ -276,7 +276,7 @@ SHIM_CALL NtSuspendThread_shim( uint32_t xeKeSetAffinityThread(void* thread_ptr, uint32_t affinity) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); XThread* thread = (XThread*)XObject::GetObject(state, thread_ptr); if (thread) { @@ -326,7 +326,7 @@ SHIM_CALL KeQueryBasePriorityThread_shim( uint32_t xeKeSetBasePriorityThread(void* thread_ptr, int32_t increment) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); int32_t prev_priority = 0; @@ -358,7 +358,7 @@ SHIM_CALL KeSetBasePriorityThread_shim( uint32_t xeKeGetCurrentProcessType() { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); // DWORD @@ -595,7 +595,7 @@ SHIM_CALL KeTlsSetValue_shim( X_STATUS xeNtCreateEvent(uint32_t* handle_ptr, void* obj_attributes, uint32_t event_type, uint32_t initial_state) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); XEvent* ev = new XEvent(state); ev->Initialize(!event_type, !!initial_state); @@ -638,10 +638,10 @@ SHIM_CALL NtCreateEvent_shim( int32_t xeKeSetEvent(void* event_ptr, uint32_t increment, uint32_t wait) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); XEvent* ev = (XEvent*)XObject::GetObject(state, event_ptr); - XEASSERTNOTNULL(ev); + assert_not_null(ev); if (!ev) { return 0; } @@ -708,7 +708,7 @@ SHIM_CALL KePulseEvent_shim( void* event_ptr = SHIM_MEM_ADDR(event_ref); XEvent* ev = (XEvent*)XObject::GetObject(state, event_ptr); - XEASSERTNOTNULL(ev); + assert_not_null(ev); if (ev) { result = ev->Pulse(increment, !!wait); } @@ -746,10 +746,10 @@ SHIM_CALL NtPulseEvent_shim( int32_t xeKeResetEvent(void* event_ptr) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); XEvent* ev = (XEvent*)XEvent::GetObject(state, event_ptr); - XEASSERTNOTNULL(ev); + assert_not_null(ev); if (!ev) { return 0; } @@ -825,11 +825,11 @@ SHIM_CALL NtCreateSemaphore_shim( void xeKeInitializeSemaphore( void* semaphore_ptr, int32_t count, int32_t limit) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); XSemaphore* sem = (XSemaphore*)XSemaphore::GetObject( state, semaphore_ptr, 5 /* SemaphoreObject */); - XEASSERTNOTNULL(sem); + assert_not_null(sem); if (!sem) { return; } @@ -856,10 +856,10 @@ SHIM_CALL KeInitializeSemaphore_shim( int32_t xeKeReleaseSemaphore( void* semaphore_ptr, int32_t increment, int32_t adjustment, bool wait) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); XSemaphore* sem = (XSemaphore*)XSemaphore::GetObject(state, semaphore_ptr); - XEASSERTNOTNULL(sem); + assert_not_null(sem); if (!sem) { return 0; } @@ -954,7 +954,7 @@ SHIM_CALL NtReleaseMutant_shim( // Whatever arg 1 is all games seem to set it to 0, so whether it's // abandon or wait we just say false. Which is good, cause they are // both ignored. - XEASSERTZERO(unknown); + assert_zero(unknown); uint32_t priority_increment = 0; bool abandon = false; bool wait = false; @@ -1016,8 +1016,8 @@ SHIM_CALL NtSetTimerEx_shim( uint32_t period_ms = SHIM_GET_ARG_32(6); uint32_t unk_zero = SHIM_GET_ARG_32(7); - XEASSERT(unk_one == 1); - XEASSERT(unk_zero == 0); + assert_true(unk_one == 1); + assert_true(unk_zero == 0); uint64_t due_time = SHIM_MEM_64(due_time_ptr); @@ -1075,7 +1075,7 @@ X_STATUS xeKeWaitForSingleObject( void* object_ptr, uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable, uint64_t* opt_timeout) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); XObject* object = XObject::GetObject(state, object_ptr); if (!object) { @@ -1153,7 +1153,7 @@ SHIM_CALL KeWaitForMultipleObjects_shim( count, objects_ptr, wait_type, wait_reason, processor_mode, alertable, timeout_ptr, wait_block_array_ptr); - XEASSERT(wait_type >= 0 && wait_type <= 1); + assert_true(wait_type >= 0 && wait_type <= 1); X_STATUS result = X_STATUS_SUCCESS; @@ -1192,7 +1192,7 @@ SHIM_CALL NtWaitForMultipleObjectsEx_shim( count, handles_ptr, wait_type, wait_mode, alertable, timeout_ptr); - XEASSERT(wait_type >= 0 && wait_type <= 1); + assert_true(wait_type >= 0 && wait_type <= 1); X_STATUS result = X_STATUS_SUCCESS; diff --git a/src/xenia/kernel/xboxkrnl_video.cc b/src/xenia/kernel/xboxkrnl_video.cc index 6519a067c..fa7d319c1 100644 --- a/src/xenia/kernel/xboxkrnl_video.cc +++ b/src/xenia/kernel/xboxkrnl_video.cc @@ -146,7 +146,7 @@ SHIM_CALL VdQueryVideoMode_shim( void xeVdInitializeEngines(uint32_t unk0, uint32_t callback, uint32_t unk1, uint32_t unk2_ptr, uint32_t unk3_ptr) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); GraphicsSystem* gs = state->emulator()->graphics_system(); if (!gs) { return; @@ -188,7 +188,7 @@ SHIM_CALL VdShutdownEngines_shim( void xeVdSetGraphicsInterruptCallback(uint32_t callback, uint32_t user_data) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); GraphicsSystem* gs = state->emulator()->graphics_system(); if (!gs) { return; @@ -217,7 +217,7 @@ SHIM_CALL VdSetGraphicsInterruptCallback_shim( void xeVdInitializeRingBuffer(uint32_t ptr, uint32_t page_count) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); GraphicsSystem* gs = state->emulator()->graphics_system(); if (!gs) { return; @@ -249,7 +249,7 @@ SHIM_CALL VdInitializeRingBuffer_shim( void xeVdEnableRingBufferRPtrWriteBack(uint32_t ptr, uint32_t block_size) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); GraphicsSystem* gs = state->emulator()->graphics_system(); if (!gs) { return; @@ -317,7 +317,7 @@ SHIM_CALL VdGetSystemCommandBuffer_shim( void xeVdSetSystemCommandBufferGpuIdentifierAddress(uint32_t unk) { KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); + assert_not_null(state); GraphicsSystem* gs = state->emulator()->graphics_system(); if (!gs) { return; diff --git a/src/xenia/kernel/xboxkrnl_video.h b/src/xenia/kernel/xboxkrnl_video.h index 1a30d0849..6c62811af 100644 --- a/src/xenia/kernel/xboxkrnl_video.h +++ b/src/xenia/kernel/xboxkrnl_video.h @@ -36,7 +36,7 @@ typedef struct { } X_VIDEO_MODE; #pragma pack(pop) -XEASSERTSTRUCTSIZE(X_VIDEO_MODE, 48); +static_assert_size(X_VIDEO_MODE, 48); void xeVdGetCurrentDisplayGamma(uint32_t* arg0, float* arg1); uint32_t xeVdQueryVideoFlags(); diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index 82564c3c2..df99a1d2e 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -29,8 +29,8 @@ XObject::XObject(KernelState* kernel_state, Type type) : } XObject::~XObject() { - XEASSERTZERO(handle_ref_count_); - XEASSERTZERO(pointer_ref_count_); + assert_zero(handle_ref_count_); + assert_zero(pointer_ref_count_); } Memory* XObject::memory() const { @@ -62,7 +62,7 @@ void XObject::Retain() { void XObject::Release() { if (!xe_atomic_dec_32(&pointer_ref_count_)) { - XEASSERT(pointer_ref_count_ >= handle_ref_count_); + assert_true(pointer_ref_count_ >= handle_ref_count_); delete this; } } @@ -75,7 +75,7 @@ uint32_t XObject::TimeoutTicksToMs(int64_t timeout_ticks) { if (timeout_ticks > 0) { // Absolute time, based on January 1, 1601. // TODO(benvanik): convert time to relative time. - XEASSERTALWAYS(); + assert_always(); return 0; } else if (timeout_ticks < 0) { // Relative time. @@ -135,7 +135,7 @@ X_STATUS XObject::WaitMultiple( void** wait_handles = (void**)alloca(sizeof(void*) * count); for (uint32_t n = 0; n < count; n++) { wait_handles[n] = objects[n]->GetWaitHandle(); - XEASSERTNOTNULL(wait_handles[n]); + assert_not_null(wait_handles[n]); } DWORD timeout_ms = opt_timeout ? @@ -167,7 +167,7 @@ void XObject::SetNativePointer(uint32_t native_ptr) { header.wait_list_flink = XESWAP32(header_be->wait_list_flink); header.wait_list_blink = XESWAP32(header_be->wait_list_blink); - XEASSERT(!(header.wait_list_blink & 0x1)); + assert_true(!(header.wait_list_blink & 0x1)); // Stash pointer in struct. uint64_t object_ptr = reinterpret_cast(this); @@ -252,7 +252,7 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr, case 23: // ProfileObject case 24: // ThreadedDpcObject default: - XEASSERTALWAYS(); + assert_always(); XObject::UnlockType(); return NULL; } diff --git a/src/xenia/logging.h b/src/xenia/logging.h index 9c5579f9a..c030f4465 100644 --- a/src/xenia/logging.h +++ b/src/xenia/logging.h @@ -32,14 +32,14 @@ void xe_handle_fatal( #if XE_OPTION_ENABLE_LOGGING #define XELOGCORE(level, fmt, ...) xe_log_line( \ - XE_CURRENT_FILE, XE_CURRENT_LINE, XE_CURRENT_FUNCTION, level, \ + __FILE__, __LINE__, __FUNCTION__, level, \ fmt, ##__VA_ARGS__) #else #define XELOGCORE(level, fmt, ...) XE_EMPTY_MACRO #endif // ENABLE_LOGGING #define XEFATAL(fmt, ...) do { \ - xe_handle_fatal(XE_CURRENT_FILE, XE_CURRENT_LINE, XE_CURRENT_FUNCTION, \ + xe_handle_fatal(__FILE__, __LINE__, __FUNCTION__, \ fmt, ##__VA_ARGS__); \ } while (false); diff --git a/src/xenia/profiling.h b/src/xenia/profiling.h index 4577dbb8f..3747bbd9b 100644 --- a/src/xenia/profiling.h +++ b/src/xenia/profiling.h @@ -55,7 +55,7 @@ namespace xe { // Enters a CPU profiling scope by function name, active for the duration of // the containing block. No previous definition required. #define SCOPE_profile_cpu_f(group_name) \ - MICROPROFILE_SCOPEI(group_name, XE_CURRENT_FUNCTION, xe::Profiler::GetColor(XE_CURRENT_FUNCTION)) + MICROPROFILE_SCOPEI(group_name, __FUNCTION__, xe::Profiler::GetColor(__FUNCTION__)) // Enters a previously defined GPU profiling scope, active for the duration // of the containing block. @@ -70,7 +70,7 @@ namespace xe { // Enters a GPU profiling scope by function name, active for the duration of // the containing block. No previous definition required. #define SCOPE_profile_gpu_f(group_name) \ - MICROPROFILE_SCOPEGPUI(group_name, XE_CURRENT_FUNCTION, xe::Profiler::GetColor(XE_CURRENT_FUNCTION)) + MICROPROFILE_SCOPEGPUI(group_name, __FUNCTION__, xe::Profiler::GetColor(__FUNCTION__)) // Tracks a CPU value counter. #define COUNT_profile_cpu(name, count) MICROPROFILE_META_CPU(name, count) diff --git a/src/xenia/sources.gypi b/src/xenia/sources.gypi index 4fdccb166..a60ec1749 100644 --- a/src/xenia/sources.gypi +++ b/src/xenia/sources.gypi @@ -1,7 +1,6 @@ # Copyright 2013 Ben Vanik. All Rights Reserved. { 'sources': [ - 'assert.h', 'atomic.h', 'byte_order.h', 'common.h', diff --git a/src/xenia/ui/window.cc b/src/xenia/ui/window.cc index 651423b74..0a37b1f1c 100644 --- a/src/xenia/ui/window.cc +++ b/src/xenia/ui/window.cc @@ -100,7 +100,7 @@ bool Window::OnResize(uint32_t width, uint32_t height) { } void Window::EndResizing() { - XEASSERT(resizing_); + assert_true(resizing_); resizing_ = false; auto e = UIEvent(this); resized(e); From 9b78dd977bb5f13b0fbe87c257d37eaf34b6aeb7 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 12 Jul 2014 17:48:54 -0700 Subject: [PATCH 024/388] Migrating atomic ops to std::atomic where possible and poly. --- src/alloy/backend/ivm/ivm_intcode.cc | 8 +- src/alloy/core.h | 1 - src/alloy/tracing/tracer.cc | 6 +- src/poly/atomic.h | 127 +++++++++++++++++++++++++ src/poly/poly.h | 1 + src/poly/sources.gypi | 1 + src/xenia/atomic.h | 100 ------------------- src/xenia/common.h | 2 +- src/xenia/core/ref.cc | 4 +- src/xenia/cpu/xenon_thread_state.cc | 4 +- src/xenia/kernel/objects/xthread.cc | 2 +- src/xenia/kernel/objects/xthread.h | 4 +- src/xenia/kernel/xboxkrnl_rtl.cc | 12 +-- src/xenia/kernel/xboxkrnl_threading.cc | 22 +++-- src/xenia/kernel/xboxkrnl_threading.h | 4 +- src/xenia/kernel/xobject.cc | 8 +- src/xenia/kernel/xobject.h | 6 +- src/xenia/sources.gypi | 1 - 18 files changed, 174 insertions(+), 139 deletions(-) create mode 100644 src/poly/atomic.h delete mode 100644 src/xenia/atomic.h diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index 38fc97b06..cdc25f136 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -4020,16 +4020,16 @@ int Translate_UNPACK(TranslationContext& ctx, Instr* i) { } uint32_t IntCode_ATOMIC_EXCHANGE_I32(IntCodeState& ics, const IntCode* i) { - auto address = (uint8_t*)ics.rf[i->src1_reg].u64; + auto address = (uint32_t*)ics.rf[i->src1_reg].u64; auto new_value = ics.rf[i->src2_reg].u32; - auto old_value = xe_atomic_exchange_32(new_value, address); + auto old_value = poly::atomic_exchange(new_value, address); ics.rf[i->dest_reg].u32 = old_value; return IA_NEXT; } uint32_t IntCode_ATOMIC_EXCHANGE_I64(IntCodeState& ics, const IntCode* i) { - auto address = (uint8_t*)ics.rf[i->src1_reg].u64; + auto address = (uint64_t*)ics.rf[i->src1_reg].u64; auto new_value = ics.rf[i->src2_reg].u64; - auto old_value = xe_atomic_exchange_64(new_value, address); + auto old_value = poly::atomic_exchange(new_value, address); ics.rf[i->dest_reg].u64 = old_value; return IA_NEXT; } diff --git a/src/alloy/core.h b/src/alloy/core.h index 9e25f171d..3d60666da 100644 --- a/src/alloy/core.h +++ b/src/alloy/core.h @@ -11,7 +11,6 @@ #define ALLOY_CORE_H_ // TODO(benvanik): move the common stuff into here? -#include #include #include #include diff --git a/src/alloy/tracing/tracer.cc b/src/alloy/tracing/tracer.cc index fbb4c43bb..01ee501d3 100644 --- a/src/alloy/tracing/tracer.cc +++ b/src/alloy/tracing/tracer.cc @@ -9,15 +9,17 @@ #include +#include + #include namespace alloy { namespace tracing { -volatile int next_thread_id_ = 0x10000000; +std::atomic next_thread_id_(0x10000000); Tracer::Tracer(Channel* channel) : channel_(channel) { - thread_id_ = xe_atomic_inc_32(&next_thread_id_); + thread_id_ = ++next_thread_id_; } Tracer::~Tracer() {} diff --git a/src/poly/atomic.h b/src/poly/atomic.h new file mode 100644 index 000000000..dab7e39bc --- /dev/null +++ b/src/poly/atomic.h @@ -0,0 +1,127 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef POLY_ATOMIC_H_ +#define POLY_ATOMIC_H_ + +#include + +#include +#include + +namespace poly { + +// These functions are modeled off of the Apple OSAtomic routines +// http://developer.apple.com/library/mac/#documentation/DriversKernelHardware/Reference/libkern_ref/OSAtomic_h/ + +#if XE_LIKE_OSX +#include + +inline int32_t atomic_inc(volatile int32_t* value) { + return OSAtomicIncrement32Barrier(reinterpret_cast(value)); +} +inline int32_t atomic_dec(volatile int32_t* value) { + return OSAtomicDecrement32Barrier(reinterpret_cast(value)); +} + +inline int32_t atomic_exchange(int32_t new_value, volatile int32_t* value) { + // +} +inline int64_t atomic_exchange(int64_t new_value, volatile int64_t* value) { + // +} + +inline int32_t atomic_cas(int32_t old_value, int32_t new_value, + volatile int32_t* value) { + return OSAtomicCompareAndSwap32Barrier( + old_value, new_value, reinterpret_cast(value)); +} + +#elif XE_LIKE_WIN32 + +inline int32_t atomic_inc(volatile int32_t* value) { + return InterlockedIncrement(reinterpret_cast(value)); +} +inline int32_t atomic_dec(volatile int32_t* value) { + return InterlockedDecrement(reinterpret_cast(value)); +} + +inline int32_t atomic_exchange(int32_t new_value, volatile int32_t* value) { + return InterlockedExchange(reinterpret_cast(value), + new_value); +} +inline int64_t atomic_exchange(int64_t new_value, volatile int64_t* value) { + return InterlockedExchange64(reinterpret_cast(value), + new_value); +} + +inline int32_t atomic_cas(int32_t old_value, int32_t new_value, + volatile int32_t* value) { + return InterlockedCompareExchange(reinterpret_cast(value), + new_value, old_value) == old_value; +} + +#elif XE_LIKE_POSIX + +inline int32_t atomic_inc(volatile int32_t* value) { + return __sync_add_and_fetch(value, 1); +} +inline int32_t atomic_dec(volatile int32_t* value) { + return __sync_sub_and_fetch(value, 1); +} + +inline int32_t atomic_exchange(int32_t new_value, volatile int32_t* value) { + // +} +inline int64_t atomic_exchange(int64_t new_value, volatile int64_t* value) { + // +} + +inline int32_t atomic_cas(int32_t old_value, int32_t new_value, + volatile int32_t* value) { + return __sync_bool_compare_and_swap(reinterpret_cast(value), + old_value, new_value); +} + +#else + +#error No atomic primitives defined for this platform/cpu combination. + +#endif // OSX + +inline uint32_t atomic_inc(volatile uint32_t* value) { + return static_cast( + atomic_inc(reinterpret_cast(value))); +} +inline uint32_t atomic_dec(volatile uint32_t* value) { + return static_cast( + atomic_dec(reinterpret_cast(value))); +} + +inline uint32_t atomic_exchange(uint32_t new_value, volatile uint32_t* value) { + return static_cast( + atomic_exchange(static_cast(new_value), + reinterpret_cast(value))); +} +inline uint64_t atomic_exchange(uint64_t new_value, volatile uint64_t* value) { + return static_cast( + atomic_exchange(static_cast(new_value), + reinterpret_cast(value))); +} + +inline uint32_t atomic_cas(uint32_t old_value, uint32_t new_value, + volatile uint32_t* value) { + return static_cast(atomic_cas( + static_cast(old_value), static_cast(new_value), + reinterpret_cast(value))); +} + +} // namespace poly + +#endif // POLY_ATOMIC_H_ diff --git a/src/poly/poly.h b/src/poly/poly.h index 52cc74b79..b7af898ff 100644 --- a/src/poly/poly.h +++ b/src/poly/poly.h @@ -11,6 +11,7 @@ #define POLY_POLY_H_ #include +#include #include #include #include diff --git a/src/poly/sources.gypi b/src/poly/sources.gypi index 7a29bd85b..c93d66a5d 100644 --- a/src/poly/sources.gypi +++ b/src/poly/sources.gypi @@ -2,6 +2,7 @@ { 'sources': [ 'assert.h', + 'atomic.h', 'config.h', 'cxx_compat.h', 'math.h', diff --git a/src/xenia/atomic.h b/src/xenia/atomic.h deleted file mode 100644 index bd1ebc14d..000000000 --- a/src/xenia/atomic.h +++ /dev/null @@ -1,100 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_ATOMIC_H_ -#define XENIA_ATOMIC_H_ - -#include - -#include -#include - - -// These functions are modeled off of the Apple OSAtomic routines -// http://developer.apple.com/library/mac/#documentation/DriversKernelHardware/Reference/libkern_ref/OSAtomic_h/ - -#if XE_LIKE_OSX -#include - -#define xe_atomic_inc_32(value) \ - OSAtomicIncrement32Barrier(value) -#define xe_atomic_dec_32(value) \ - OSAtomicDecrement32Barrier(value) -#define xe_atomic_add_32(amount, value) \ - ((void)OSAtomicAdd32Barrier(amount, value)) -#define xe_atomic_sub_32(amount, value) \ - ((void)OSAtomicAdd32Barrier(-amount, value)) -#define xe_atomic_exchange_32(newValue, value) \ - TODOTODO -#define xe_atomic_cas_32(oldValue, newValue, value) \ - OSAtomicCompareAndSwap32Barrier(oldValue, newValue, value) - -typedef OSQueueHead xe_atomic_stack_t; -#define xe_atomic_stack_init(stack) \ - *(stack) = (OSQueueHead)OS_ATOMIC_QUEUE_INIT -#define xe_atomic_stack_enqueue(stack, item, offset) \ - OSAtomicEnqueue((OSQueueHead*)stack, item, offset) -#define xe_atomic_stack_dequeue(stack, offset) \ - OSAtomicDequeue((OSQueueHead*)stack, offset) - -#elif XE_LIKE_WIN32 - -#define xe_atomic_inc_32(value) \ - InterlockedIncrement((volatile LONG*)value) -#define xe_atomic_dec_32(value) \ - InterlockedDecrement((volatile LONG*)value) -#define xe_atomic_add_32(amount, value) \ - ((void)InterlockedExchangeAdd((volatile LONG*)value, amount)) -#define xe_atomic_sub_32(amount, value) \ - ((void)InterlockedExchangeSubtract((volatile unsigned*)value, amount)) -#define xe_atomic_exchange_32(newValue, value) \ - InterlockedExchange((volatile LONG*)value, newValue) -#define xe_atomic_exchange_64(newValue, value) \ - InterlockedExchange64((volatile LONGLONG*)value, newValue) -#define xe_atomic_cas_32(oldValue, newValue, value) \ - (InterlockedCompareExchange((volatile LONG*)value, newValue, oldValue) == oldValue) - -typedef SLIST_HEADER xe_atomic_stack_t; -#define xe_atomic_stack_init(stack) \ - InitializeSListHead((PSLIST_HEADER)stack) -#define xe_atomic_stack_enqueue(stack, item, offset) \ - XEIGNORE(InterlockedPushEntrySList((PSLIST_HEADER)stack, (PSLIST_ENTRY)((byte*)item + offset))) -XEFORCEINLINE void* xe_atomic_stack_dequeue(xe_atomic_stack_t* stack, - const size_t offset) { - void* ptr = (void*)InterlockedPopEntrySList((PSLIST_HEADER)stack); - if (ptr) { - return (void*)(((uint8_t*)ptr) - offset); - } else { - return NULL; - } -} - -#elif XE_LIKE_POSIX - -#define xe_atomic_inc_32(value) \ - __sync_add_and_fetch(value, 1) -#define xe_atomic_dec_32(value) \ - __sync_sub_and_fetch(value, 1) -#define xe_atomic_add_32(amount, value) \ - __sync_fetch_and_add(value, amount) -#define xe_atomic_sub_32(amount, value) \ - __sync_fetch_and_sub(value, amount) -#define xe_atomic_exchange_32(newValue, value) \ - TODOTODO -#define xe_atomic_cas_32(oldValue, newValue, value) \ - __sync_bool_compare_and_swap(value, oldValue, newValue) - -#else - -#error No atomic primitives defined for this platform/cpu combination. - -#endif // OSX - - -#endif // XENIA_ATOMIC_H_ diff --git a/src/xenia/common.h b/src/xenia/common.h index c76f9eae1..3e9010f26 100644 --- a/src/xenia/common.h +++ b/src/xenia/common.h @@ -11,8 +11,8 @@ #define XENIA_COMMON_H_ #include +#include -#include #include #include #include diff --git a/src/xenia/core/ref.cc b/src/xenia/core/ref.cc index 68a847d6b..c09c613eb 100644 --- a/src/xenia/core/ref.cc +++ b/src/xenia/core/ref.cc @@ -15,14 +15,14 @@ void xe_ref_init(xe_ref_t* ref) { } void xe_ref_retain(xe_ref_t* ref) { - xe_atomic_inc_32(&ref->count); + poly::atomic_inc(&ref->count); } void xe_ref_release(xe_ref_t* ref, xe_ref_dealloc_t dealloc) { if (!ref) { return; } - if (!xe_atomic_dec_32(&ref->count)) { + if (!poly::atomic_dec(&ref->count)) { if (dealloc) { dealloc(ref); } diff --git a/src/xenia/cpu/xenon_thread_state.cc b/src/xenia/cpu/xenon_thread_state.cc index e5ed16da5..57959e15f 100644 --- a/src/xenia/cpu/xenon_thread_state.cc +++ b/src/xenia/cpu/xenon_thread_state.cc @@ -76,7 +76,7 @@ volatile int* XenonThreadState::suspend_flag_address() const { int XenonThreadState::Suspend(uint32_t timeout_ms) { // Set suspend flag. // One of the checks should call in to OnSuspend() at some point. - xe_atomic_inc_32(&context_->suspend_flag); + poly::atomic_inc(&context_->suspend_flag); return 0; } @@ -86,7 +86,7 @@ int XenonThreadState::Resume(bool force) { context_->suspend_flag = 0; SetEvent(debug_break_); } else { - if (!xe_atomic_dec_32(&context_->suspend_flag)) { + if (!poly::atomic_dec(&context_->suspend_flag)) { SetEvent(debug_break_); } } diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index 47566c20d..ad58f0ff7 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -406,7 +406,7 @@ void XThread::LeaveCriticalRegion() { } uint32_t XThread::RaiseIrql(uint32_t new_irql) { - return xe_atomic_exchange_32(new_irql, &irql_); + return irql_.exchange(new_irql); } void XThread::LowerIrql(uint32_t new_irql) { diff --git a/src/xenia/kernel/objects/xthread.h b/src/xenia/kernel/objects/xthread.h index 8b403429b..cec3c4dce 100644 --- a/src/xenia/kernel/objects/xthread.h +++ b/src/xenia/kernel/objects/xthread.h @@ -10,6 +10,8 @@ #ifndef XENIA_KERNEL_XBOXKRNL_XTHREAD_H_ #define XENIA_KERNEL_XBOXKRNL_XTHREAD_H_ +#include + #include #include @@ -94,7 +96,7 @@ private: char* name_; - uint32_t irql_; + std::atomic irql_; xe_mutex_t* apc_lock_; NativeList* apc_list_; diff --git a/src/xenia/kernel/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl_rtl.cc index 5b632a6b3..ebf874eb3 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl_rtl.cc @@ -606,13 +606,13 @@ void xeRtlEnterCriticalSection(uint32_t cs_ptr, uint32_t thread_id) { uint32_t spin_wait_remaining = cs->spin_count_div_256 * 256; spin: - if (xe_atomic_inc_32(&cs->lock_count) != 0) { + if (poly::atomic_inc(&cs->lock_count) != 0) { // If this thread already owns the CS increment the recursion count. if (cs->owning_thread_id == thread_id) { cs->recursion_count++; return; } - xe_atomic_dec_32(&cs->lock_count); + poly::atomic_dec(&cs->lock_count); // Thread was locked - spin wait. if (spin_wait_remaining) { @@ -658,13 +658,13 @@ uint32_t xeRtlTryEnterCriticalSection(uint32_t cs_ptr, uint32_t thread_id) { X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)IMPL_MEM_ADDR(cs_ptr); - if (xe_atomic_cas_32(-1, 0, &cs->lock_count)) { + if (poly::atomic_cas(-1, 0, &cs->lock_count)) { // Able to steal the lock right away. cs->owning_thread_id = thread_id; cs->recursion_count = 1; return 1; } else if (cs->owning_thread_id == thread_id) { - xe_atomic_inc_32(&cs->lock_count); + poly::atomic_inc(&cs->lock_count); ++cs->recursion_count; return 1; } @@ -699,13 +699,13 @@ void xeRtlLeaveCriticalSection(uint32_t cs_ptr) { // Drop recursion count - if we are still not zero'ed return. uint32_t recursion_count = --cs->recursion_count; if (recursion_count) { - xe_atomic_dec_32(&cs->lock_count); + poly::atomic_dec(&cs->lock_count); return; } // Unlock! cs->owning_thread_id = 0; - if (xe_atomic_dec_32(&cs->lock_count) != -1) { + if (poly::atomic_dec(&cs->lock_count) != -1) { // There were waiters - wake one of them. // TODO(benvanik): wake a waiter. XELOGE("RtlLeaveCriticalSection would have woken a waiter"); diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index 8e10a84ce..6aaa8b78c 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -1258,9 +1258,9 @@ SHIM_CALL NtSignalAndWaitForSingleObjectEx_shim( } -uint32_t xeKfAcquireSpinLock(void* lock_ptr) { +uint32_t xeKfAcquireSpinLock(uint32_t* lock_ptr) { // Lock. - while (!xe_atomic_cas_32(0, 1, lock_ptr)) { + while (!poly::atomic_cas(0, 1, lock_ptr)) { // Spin! // TODO(benvanik): error on deadlock? } @@ -1279,19 +1279,20 @@ SHIM_CALL KfAcquireSpinLock_shim( "KfAcquireSpinLock(%.8X)", lock_ptr); - uint32_t old_irql = xeKfAcquireSpinLock(SHIM_MEM_ADDR(lock_ptr)); + auto lock = reinterpret_cast(SHIM_MEM_ADDR(lock_ptr)); + uint32_t old_irql = xeKfAcquireSpinLock(lock); SHIM_SET_RETURN_64(old_irql); } -void xeKfReleaseSpinLock(void* lock_ptr, uint32_t old_irql) { +void xeKfReleaseSpinLock(uint32_t* lock_ptr, uint32_t old_irql) { // Restore IRQL. XThread* thread = XThread::GetCurrentThread(); thread->LowerIrql(old_irql); // Unlock. - xe_atomic_dec_32(lock_ptr); + poly::atomic_dec(lock_ptr); } @@ -1305,7 +1306,8 @@ SHIM_CALL KfReleaseSpinLock_shim( lock_ptr, old_irql); - xeKfReleaseSpinLock(SHIM_MEM_ADDR(lock_ptr), old_irql); + xeKfReleaseSpinLock(reinterpret_cast(SHIM_MEM_ADDR(lock_ptr)), + old_irql); } @@ -1318,8 +1320,8 @@ SHIM_CALL KeAcquireSpinLockAtRaisedIrql_shim( lock_ptr); // Lock. - void* lock = SHIM_MEM_ADDR(lock_ptr); - while (!xe_atomic_cas_32(0, 1, lock)) { + auto lock = reinterpret_cast(SHIM_MEM_ADDR(lock_ptr)); + while (!poly::atomic_cas(0, 1, lock)) { // Spin! // TODO(benvanik): error on deadlock? } @@ -1335,8 +1337,8 @@ SHIM_CALL KeReleaseSpinLockFromRaisedIrql_shim( lock_ptr); // Unlock. - void* lock = SHIM_MEM_ADDR(lock_ptr); - xe_atomic_dec_32(lock); + auto lock = reinterpret_cast(SHIM_MEM_ADDR(lock_ptr)); + poly::atomic_dec(lock); } diff --git a/src/xenia/kernel/xboxkrnl_threading.h b/src/xenia/kernel/xboxkrnl_threading.h index 9b33964f9..62f807065 100644 --- a/src/xenia/kernel/xboxkrnl_threading.h +++ b/src/xenia/kernel/xboxkrnl_threading.h @@ -52,8 +52,8 @@ X_STATUS xeKeWaitForSingleObject( void* object_ptr, uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable, uint64_t* opt_timeout); -uint32_t xeKfAcquireSpinLock(void* lock_ptr); -void xeKfReleaseSpinLock(void* lock_ptr, uint32_t old_irql); +uint32_t xeKfAcquireSpinLock(uint32_t* lock_ptr); +void xeKfReleaseSpinLock(uint32_t* lock_ptr, uint32_t old_irql); void xeKeEnterCriticalRegion(); void xeKeLeaveCriticalRegion(); diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index df99a1d2e..f3a48d8f7 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -46,22 +46,22 @@ X_HANDLE XObject::handle() const { } void XObject::RetainHandle() { - xe_atomic_inc_32(&handle_ref_count_); + ++handle_ref_count_; } bool XObject::ReleaseHandle() { - if (!xe_atomic_dec_32(&handle_ref_count_)) { + if (--handle_ref_count_ == 0) { return true; } return false; } void XObject::Retain() { - xe_atomic_inc_32(&pointer_ref_count_); + ++pointer_ref_count_; } void XObject::Release() { - if (!xe_atomic_dec_32(&pointer_ref_count_)) { + if (--pointer_ref_count_ == 0) { assert_true(pointer_ref_count_ >= handle_ref_count_); delete this; } diff --git a/src/xenia/kernel/xobject.h b/src/xenia/kernel/xobject.h index 1a3b8fae7..7733db4ab 100644 --- a/src/xenia/kernel/xobject.h +++ b/src/xenia/kernel/xobject.h @@ -10,6 +10,8 @@ #ifndef XENIA_KERNEL_XBOXKRNL_XOBJECT_H_ #define XENIA_KERNEL_XBOXKRNL_XOBJECT_H_ +#include + #include #include @@ -87,8 +89,8 @@ protected: KernelState* kernel_state_; private: - volatile int32_t handle_ref_count_; - volatile int32_t pointer_ref_count_; + std::atomic handle_ref_count_; + std::atomic pointer_ref_count_; Type type_; X_HANDLE handle_; diff --git a/src/xenia/sources.gypi b/src/xenia/sources.gypi index a60ec1749..48bb82f59 100644 --- a/src/xenia/sources.gypi +++ b/src/xenia/sources.gypi @@ -1,7 +1,6 @@ # Copyright 2013 Ben Vanik. All Rights Reserved. { 'sources': [ - 'atomic.h', 'byte_order.h', 'common.h', 'config.h', From 7ee79318e8151ceeeff91d2194cfcf2a93abc897 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 12 Jul 2014 21:52:33 -0700 Subject: [PATCH 025/388] Fixing a bunch of alloy clang issues. --- src/alloy/backend/ivm/ivm_intcode.cc | 70 ++++++++--------------- src/alloy/frontend/ppc/ppc_instr_tables.h | 2 + src/alloy/hir/value.cc | 2 + src/alloy/runtime/debugger.h | 1 + src/poly/assert.h | 2 +- src/poly/atomic.h | 19 +++--- src/poly/math.cc | 69 ++++++++++++++++++++++ src/poly/math.h | 30 ++++++++++ src/poly/sources.gypi | 1 + src/poly/threading.h | 3 + src/poly/threading_mac.cc | 4 ++ src/poly/threading_win.cc | 9 +++ src/xenia/types.h | 1 + 13 files changed, 157 insertions(+), 56 deletions(-) create mode 100644 src/poly/math.cc diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index cdc25f136..839a729e4 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -14,9 +14,6 @@ #include #include -// TODO(benvanik): reimplement packing functions -#include - // TODO(benvanik): make a compile time flag? //#define DYNAMIC_REGISTER_ACCESS_CHECK(address) false #define DYNAMIC_REGISTER_ACCESS_CHECK(address) \ @@ -38,10 +35,10 @@ using alloy::hir::Value; using alloy::runtime::Function; using alloy::runtime::FunctionInfo; -#define IPRINT -#define IFLUSH() -#define DPRINT -#define DFLUSH() +#define IPRINT(...) (void()) +#define IFLUSH() (void()) +#define DPRINT(...) (void()) +#define DFLUSH() (void()) //#define IPRINT if (ics.thread_state->thread_id() == 1) printf //#define IFLUSH() fflush(stdout) @@ -101,7 +98,7 @@ uint32_t AllocConstant(TranslationContext& ctx, Value* value) { uint32_t AllocLabel(TranslationContext& ctx, Label* label) { // If it's a back-branch to an already tagged label avoid setting up // a reference. - uint32_t value = (uint32_t)label->tag; + uint32_t value = *reinterpret_cast(label->tag); if (value & 0x80000000) { // Already set. return AllocConstant(ctx, value & ~0x80000000); @@ -124,11 +121,11 @@ uint32_t AllocLabel(TranslationContext& ctx, Label* label) { uint32_t AllocDynamicRegister(TranslationContext& ctx, Value* value) { if (value->flags & VALUE_IS_ALLOCATED) { - return (uint32_t)value->tag; + return *reinterpret_cast(value->tag); } else { value->flags |= VALUE_IS_ALLOCATED; auto reg = ctx.register_count++; - value->tag = (void*)reg; + value->tag = reinterpret_cast(reg); return (uint32_t)reg; } } @@ -207,6 +204,7 @@ int TranslateInvalid(TranslationContext& ctx, Instr* i) { uint32_t IntCode_COMMENT(IntCodeState& ics, const IntCode* i) { char* value = (char*)(i->src1_reg | ((uint64_t)i->src2_reg << 32)); + (void)(value); IPRINT("XE[t] :%d: %s\n", ics.thread_state->thread_id(), value); IFLUSH(); return IA_NEXT; @@ -1186,12 +1184,7 @@ int Translate_LOAD_VECTOR_SHR(TranslationContext& ctx, Instr* i) { } uint32_t IntCode_LOAD_CLOCK(IntCodeState& ics, const IntCode* i) { - LARGE_INTEGER counter; - uint64_t time = 0; - if (QueryPerformanceCounter(&counter)) { - time = counter.QuadPart; - } - ics.rf[i->dest_reg].i64 = time; + ics.rf[i->dest_reg].i64 = poly::threading::ticks(); return IA_NEXT; } int Translate_LOAD_CLOCK(TranslationContext& ctx, Instr* i) { @@ -2664,7 +2657,7 @@ int Translate_MUL(TranslationContext& ctx, Instr* i) { } } -namespace { +#if !XE_COMPILER_MSVC uint64_t Mul128(uint64_t xi_low, uint64_t xi_high, uint64_t yi_low, uint64_t yi_high) { // 128bit multiply, simplified for two input 64bit integers. @@ -2680,7 +2673,6 @@ uint64_t Mul128(uint64_t xi_low, uint64_t xi_high, uint64_t yi_low, uint64_t f = yi_high & LO_WORD; uint64_t e = (yi_high & HI_WORD) >> 32LL; uint64_t acc = d * h; - uint64_t o1 = acc & LO_WORD; acc >>= 32LL; uint64_t carry = 0; @@ -2692,7 +2684,6 @@ uint64_t Mul128(uint64_t xi_low, uint64_t xi_high, uint64_t yi_low, if (acc < ac2) { carry++; } - uint64_t rv2_lo = o1 | (acc << 32LL); ac2 = (acc >> 32LL) | (carry << 32LL); carry = 0; @@ -2719,7 +2710,7 @@ uint64_t Mul128(uint64_t xi_low, uint64_t xi_high, uint64_t yi_low, return rv2_hi; } -} +#endif // !XE_COMPILER_MSVC uint32_t IntCode_MUL_HI_I8_I8(IntCodeState& ics, const IntCode* i) { int16_t v = (int16_t)ics.rf[i->src1_reg].i8 * (int16_t)ics.rf[i->src2_reg].i8; @@ -3565,33 +3556,21 @@ int Translate_BYTE_SWAP(TranslationContext& ctx, Instr* i) { uint32_t IntCode_CNTLZ_I8(IntCodeState& ics, const IntCode* i) { // CHECK assert_always(); - DWORD index; - DWORD mask = ics.rf[i->src1_reg].i8; - BOOLEAN is_nonzero = _BitScanReverse(&index, mask); - ics.rf[i->dest_reg].i8 = is_nonzero ? (int8_t)(index - 24) ^ 0x7 : 8; + ics.rf[i->dest_reg].i8 = poly::lzcnt(ics.rf[i->src1_reg].i8); return IA_NEXT; } uint32_t IntCode_CNTLZ_I16(IntCodeState& ics, const IntCode* i) { // CHECK assert_always(); - DWORD index; - DWORD mask = ics.rf[i->src1_reg].i16; - BOOLEAN is_nonzero = _BitScanReverse(&index, mask); - ics.rf[i->dest_reg].i8 = is_nonzero ? (int8_t)(index - 16) ^ 0xF : 16; + ics.rf[i->dest_reg].i8 = poly::lzcnt(ics.rf[i->src1_reg].i16); return IA_NEXT; } uint32_t IntCode_CNTLZ_I32(IntCodeState& ics, const IntCode* i) { - DWORD index; - DWORD mask = ics.rf[i->src1_reg].i32; - BOOLEAN is_nonzero = _BitScanReverse(&index, mask); - ics.rf[i->dest_reg].i8 = is_nonzero ? (int8_t)index ^ 0x1F : 32; + ics.rf[i->dest_reg].i8 = poly::lzcnt(ics.rf[i->src1_reg].i32); return IA_NEXT; } uint32_t IntCode_CNTLZ_I64(IntCodeState& ics, const IntCode* i) { - DWORD index; - DWORD64 mask = ics.rf[i->src1_reg].i64; - BOOLEAN is_nonzero = _BitScanReverse64(&index, mask); - ics.rf[i->dest_reg].i8 = is_nonzero ? (int8_t)index ^ 0x3F : 64; + ics.rf[i->dest_reg].i8 = poly::lzcnt(ics.rf[i->src1_reg].i64); return IA_NEXT; } int Translate_CNTLZ(TranslationContext& ctx, Instr* i) { @@ -3872,21 +3851,18 @@ uint32_t IntCode_PACK_FLOAT16_2(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; dest.ix = dest.iy = dest.iz = 0; - dest.iw = - ((uint32_t)DirectX::PackedVector::XMConvertFloatToHalf(src1.x) << 16) | - DirectX::PackedVector::XMConvertFloatToHalf(src1.y); + dest.iw = (uint32_t(poly::float_to_half(src1.x)) << 16) | + poly::float_to_half(src1.y); return IA_NEXT; } uint32_t IntCode_PACK_FLOAT16_4(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; dest.ix = dest.iy = 0; - dest.iz = - ((uint32_t)DirectX::PackedVector::XMConvertFloatToHalf(src1.x) << 16) | - DirectX::PackedVector::XMConvertFloatToHalf(src1.y); - dest.iw = - ((uint32_t)DirectX::PackedVector::XMConvertFloatToHalf(src1.z) << 16) | - DirectX::PackedVector::XMConvertFloatToHalf(src1.w); + dest.iz = (uint32_t(poly::float_to_half(src1.x)) << 16) | + poly::float_to_half(src1.y); + dest.iw = (uint32_t(poly::float_to_half(src1.z)) << 16) | + poly::float_to_half(src1.w); return IA_NEXT; } uint32_t IntCode_PACK_SHORT_2(IntCodeState& ics, const IntCode* i) { @@ -3932,7 +3908,7 @@ uint32_t IntCode_UNPACK_FLOAT16_2(IntCodeState& ics, const IntCode* i) { vec128_t& dest = ics.rf[i->dest_reg].v128; uint32_t src = src1.iw; for (int n = 0; n < 2; n++) { - dest.f4[n] = DirectX::PackedVector::XMConvertHalfToFloat((uint16_t)src); + dest.f4[n] = poly::half_to_float(uint16_t(src)); src >>= 16; } dest.f4[2] = 0.0f; @@ -3944,7 +3920,7 @@ uint32_t IntCode_UNPACK_FLOAT16_4(IntCodeState& ics, const IntCode* i) { vec128_t& dest = ics.rf[i->dest_reg].v128; uint64_t src = src1.iz | ((uint64_t)src1.iw << 32); for (int n = 0; n < 4; n++) { - dest.f4[n] = DirectX::PackedVector::XMConvertHalfToFloat((uint16_t)src); + dest.f4[n] = poly::half_to_float(uint16_t(src)); src >>= 16; } return IA_NEXT; diff --git a/src/alloy/frontend/ppc/ppc_instr_tables.h b/src/alloy/frontend/ppc/ppc_instr_tables.h index 998b31039..336d28c7d 100644 --- a/src/alloy/frontend/ppc/ppc_instr_tables.h +++ b/src/alloy/frontend/ppc/ppc_instr_tables.h @@ -10,6 +10,8 @@ #ifndef ALLOY_FRONTEND_PPC_PPC_INSTR_TABLES_H_ #define ALLOY_FRONTEND_PPC_PPC_INSTR_TABLES_H_ +#include + #include namespace alloy { diff --git a/src/alloy/hir/value.cc b/src/alloy/hir/value.cc index d25b6bea0..770bdfe53 100644 --- a/src/alloy/hir/value.cc +++ b/src/alloy/hir/value.cc @@ -9,6 +9,8 @@ #include +#include + namespace alloy { namespace hir { diff --git a/src/alloy/runtime/debugger.h b/src/alloy/runtime/debugger.h index d9b97a8a9..bacb58f3f 100644 --- a/src/alloy/runtime/debugger.h +++ b/src/alloy/runtime/debugger.h @@ -12,6 +12,7 @@ #include #include +#include #include #include diff --git a/src/poly/assert.h b/src/poly/assert.h index 50e083d16..80d1898c4 100644 --- a/src/poly/assert.h +++ b/src/poly/assert.h @@ -70,7 +70,7 @@ namespace poly { poly_assert((expr) != nullptr || !message) #define assert_unhandled_case(variable) \ - assert_always("unhandled switch("## #variable##") case") + assert_always("unhandled switch(" #variable ") case") } // namespace poly diff --git a/src/poly/atomic.h b/src/poly/atomic.h index dab7e39bc..634b2d101 100644 --- a/src/poly/atomic.h +++ b/src/poly/atomic.h @@ -15,32 +15,35 @@ #include #include +#if XE_LIKE_OSX +#include +#endif // XE_LIKE_OSX + namespace poly { // These functions are modeled off of the Apple OSAtomic routines // http://developer.apple.com/library/mac/#documentation/DriversKernelHardware/Reference/libkern_ref/OSAtomic_h/ #if XE_LIKE_OSX -#include inline int32_t atomic_inc(volatile int32_t* value) { - return OSAtomicIncrement32Barrier(reinterpret_cast(value)); + return OSAtomicIncrement32Barrier(reinterpret_cast(value)); } inline int32_t atomic_dec(volatile int32_t* value) { - return OSAtomicDecrement32Barrier(reinterpret_cast(value)); + return OSAtomicDecrement32Barrier(reinterpret_cast(value)); } inline int32_t atomic_exchange(int32_t new_value, volatile int32_t* value) { - // + return OSAtomicCompareAndSwap32Barrier(*value, new_value, value); } inline int64_t atomic_exchange(int64_t new_value, volatile int64_t* value) { - // + return OSAtomicCompareAndSwap64Barrier(*value, new_value, value); } inline int32_t atomic_cas(int32_t old_value, int32_t new_value, volatile int32_t* value) { return OSAtomicCompareAndSwap32Barrier( - old_value, new_value, reinterpret_cast(value)); + old_value, new_value, reinterpret_cast(value)); } #elif XE_LIKE_WIN32 @@ -77,10 +80,10 @@ inline int32_t atomic_dec(volatile int32_t* value) { } inline int32_t atomic_exchange(int32_t new_value, volatile int32_t* value) { - // + return __sync_val_compare_and_swap(*value, value, new_value); } inline int64_t atomic_exchange(int64_t new_value, volatile int64_t* value) { - // + return __sync_val_compare_and_swap(*value, value, new_value); } inline int32_t atomic_cas(int32_t old_value, int32_t new_value, diff --git a/src/poly/math.cc b/src/poly/math.cc new file mode 100644 index 000000000..af7c661f7 --- /dev/null +++ b/src/poly/math.cc @@ -0,0 +1,69 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +namespace poly { + +// TODO(benvanik): replace with alternate implementation. +// XMConvertFloatToHalf +// Copyright (c) Microsoft Corporation. All rights reserved. +uint16_t float_to_half(float value) { + uint32_t Result; + uint32_t IValue = ((uint32_t *)(&value))[0]; + uint32_t Sign = (IValue & 0x80000000U) >> 16U; + IValue = IValue & 0x7FFFFFFFU; // Hack off the sign + if (IValue > 0x47FFEFFFU) { + // The number is too large to be represented as a half. Saturate to + // infinity. + Result = 0x7FFFU; + } else { + if (IValue < 0x38800000U) { + // The number is too small to be represented as a normalized half. + // Convert it to a denormalized value. + uint32_t Shift = 113U - (IValue >> 23U); + IValue = (0x800000U | (IValue & 0x7FFFFFU)) >> Shift; + } else { + // Rebias the exponent to represent the value as a normalized half. + IValue += 0xC8000000U; + } + Result = ((IValue + 0x0FFFU + ((IValue >> 13U) & 1U)) >> 13U) & 0x7FFFU; + } + return (uint16_t)(Result | Sign); +} + +// TODO(benvanik): replace with alternate implementation. +// XMConvertHalfToFloat +// Copyright (c) Microsoft Corporation. All rights reserved. +float half_to_float(uint16_t value) { + uint32_t Mantissa = (uint32_t)(value & 0x03FF); + uint32_t Exponent; + if ((value & 0x7C00) != 0) { + // The value is normalized + Exponent = (uint32_t)((value >> 10) & 0x1F); + } else if (Mantissa != 0) { + // The value is denormalized + // Normalize the value in the resulting float + Exponent = 1; + do { + Exponent--; + Mantissa <<= 1; + } while ((Mantissa & 0x0400) == 0); + Mantissa &= 0x03FF; + } else { + // The value is zero + Exponent = (uint32_t)-112; + } + uint32_t Result = ((value & 0x8000) << 16) | // Sign + ((Exponent + 112) << 23) | // Exponent + (Mantissa << 13); // Mantissa + return *(float *)&Result; +} + +} // namespace poly diff --git a/src/poly/math.h b/src/poly/math.h index 7a20fade4..57b0190d1 100644 --- a/src/poly/math.h +++ b/src/poly/math.h @@ -25,6 +25,7 @@ namespace poly { // return value is the size of the input operand (8, 16, 32, or 64). If the most // significant bit of value is one, the return value is zero. #if XE_COMPILER_MSVC +#if 1 inline uint8_t lzcnt(uint8_t v) { return static_cast(__lzcnt16(v) - 8); } @@ -32,6 +33,32 @@ inline uint8_t lzcnt(uint16_t v) { return static_cast(__lzcnt16(v)); } inline uint8_t lzcnt(uint32_t v) { return static_cast(__lzcnt(v)); } inline uint8_t lzcnt(uint64_t v) { return static_cast(__lzcnt64(v)); } #else +inline uint8_t lzcnt(uint8_t v) { + DWORD index; + DWORD mask = v; + BOOLEAN is_nonzero = _BitScanReverse(&index, mask); + return static_cast(is_nonzero ? int8_t(index - 24) ^ 0x7 : 8); +} +inline uint8_t lzcnt(uint16_t v) { + DWORD index; + DWORD mask = v; + BOOLEAN is_nonzero = _BitScanReverse(&index, mask); + return static_cast(is_nonzero ? int8_t(index - 16) ^ 0xF : 16); +} +inline uint8_t lzcnt(uint32_t v) { + DWORD index; + DWORD mask = v; + BOOLEAN is_nonzero = _BitScanReverse(&index, mask); + return static_cast(is_nonzero ? int8_t(index) ^ 0x1F : 32); +} +inline uint8_t lzcnt(uint64_t v) { + DWORD index; + DWORD64 mask = v; + BOOLEAN is_nonzero = _BitScanReverse64(&index, mask); + return static_cast(is_nonzero ? int8_t(index) ^ 0x3F : 64); +} +#endif // LZCNT supported +#else inline uint8_t lzcnt(uint8_t v) { return static_cast(__builtin_clzs(v) - 8); } @@ -121,6 +148,9 @@ int64_t m128_i64(const __m128& v) { return m128_i64(_mm_castps_pd(v)); } +uint16_t float_to_half(float value); +float half_to_float(uint16_t value); + } // namespace poly #endif // POLY_MATH_H_ diff --git a/src/poly/sources.gypi b/src/poly/sources.gypi index c93d66a5d..f9a0fe960 100644 --- a/src/poly/sources.gypi +++ b/src/poly/sources.gypi @@ -5,6 +5,7 @@ 'atomic.h', 'config.h', 'cxx_compat.h', + 'math.cc', 'math.h', 'platform.h', 'poly-private.h', diff --git a/src/poly/threading.h b/src/poly/threading.h index 6fb792b2d..5059aaf3a 100644 --- a/src/poly/threading.h +++ b/src/poly/threading.h @@ -18,6 +18,9 @@ namespace poly { namespace threading { +// Gets the current high-perforance tick count. +uint64_t ticks(); + // Gets a stable thread-specific ID, but may not be. Use for informative // purposes only. uint32_t current_thread_id(); diff --git a/src/poly/threading_mac.cc b/src/poly/threading_mac.cc index 55b508f35..5ee15b677 100644 --- a/src/poly/threading_mac.cc +++ b/src/poly/threading_mac.cc @@ -9,12 +9,16 @@ #include +#include +#include #include #include namespace poly { namespace threading { +uint64_t ticks() { return mach_absolute_time(); } + uint32_t current_thread_id() { mach_port_t tid = pthread_mach_thread_np(pthread_self()); return static_cast(tid); diff --git a/src/poly/threading_win.cc b/src/poly/threading_win.cc index b95a6c455..27689ab28 100644 --- a/src/poly/threading_win.cc +++ b/src/poly/threading_win.cc @@ -14,6 +14,15 @@ namespace poly { namespace threading { +uint64_t ticks() { + LARGE_INTEGER counter; + uint64_t time = 0; + if (QueryPerformanceCounter(&counter)) { + time = counter.QuadPart; + } + return time; +} + uint32_t current_thread_id() { return static_cast(GetCurrentThreadId()); } diff --git a/src/xenia/types.h b/src/xenia/types.h index 78a60de8c..59a07c8da 100644 --- a/src/xenia/types.h +++ b/src/xenia/types.h @@ -11,6 +11,7 @@ #define XENIA_TYPES_H_ #include +#include #include From 4a0531abc519f1b7ee396763b779efd7b91c4723 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 12 Jul 2014 22:25:12 -0700 Subject: [PATCH 026/388] Posix code cache. --- src/alloy/backend/x64/sources.gypi | 14 ++- src/alloy/backend/x64/x64_code_cache_posix.cc | 97 +++++++++++++++++++ ...64_code_cache.cc => x64_code_cache_win.cc} | 0 src/alloy/hir/opcodes.cc | 2 +- 4 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 src/alloy/backend/x64/x64_code_cache_posix.cc rename src/alloy/backend/x64/{x64_code_cache.cc => x64_code_cache_win.cc} (100%) diff --git a/src/alloy/backend/x64/sources.gypi b/src/alloy/backend/x64/sources.gypi index 38167e3f1..02d8163b1 100644 --- a/src/alloy/backend/x64/sources.gypi +++ b/src/alloy/backend/x64/sources.gypi @@ -6,7 +6,6 @@ 'x64_assembler.h', 'x64_backend.cc', 'x64_backend.h', - 'x64_code_cache.cc', 'x64_code_cache.h', 'x64_emitter.cc', 'x64_emitter.h', @@ -20,4 +19,17 @@ 'x64_tracers.cc', 'x64_tracers.h', ], + + 'conditions': [ + ['OS == "mac" or OS == "linux"', { + 'sources': [ + 'x64_code_cache_posix.cc', + ], + }], + ['OS == "win"', { + 'sources': [ + 'x64_code_cache_win.cc', + ], + }], + ], } diff --git a/src/alloy/backend/x64/x64_code_cache_posix.cc b/src/alloy/backend/x64/x64_code_cache_posix.cc new file mode 100644 index 000000000..09dbeccb5 --- /dev/null +++ b/src/alloy/backend/x64/x64_code_cache_posix.cc @@ -0,0 +1,97 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include + +#include + +namespace alloy { +namespace backend { +namespace x64 { + +class X64CodeChunk { + public: + X64CodeChunk(size_t chunk_size); + ~X64CodeChunk(); + + public: + X64CodeChunk* next; + size_t capacity; + uint8_t* buffer; + size_t offset; +}; + +X64CodeCache::X64CodeCache(size_t chunk_size) + : chunk_size_(chunk_size), head_chunk_(NULL), active_chunk_(NULL) {} + +X64CodeCache::~X64CodeCache() { + std::lock_guard guard(lock_); + auto chunk = head_chunk_; + while (chunk) { + auto next = chunk->next; + delete chunk; + chunk = next; + } + head_chunk_ = NULL; +} + +int X64CodeCache::Initialize() { return 0; } + +void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size, + size_t stack_size) { + SCOPE_profile_cpu_f("alloy"); + + // Always move the code to land on 16b alignment. We do this by rounding up + // to 16b so that all offsets are aligned. + code_size = XEROUNDUP(code_size, 16); + + lock_.lock(); + + if (active_chunk_) { + if (active_chunk_->capacity - active_chunk_->offset < code_size) { + auto next = active_chunk_->next; + if (!next) { + assert_true(code_size < chunk_size_, "need to support larger chunks"); + next = new X64CodeChunk(chunk_size_); + active_chunk_->next = next; + } + active_chunk_ = next; + } + } else { + head_chunk_ = active_chunk_ = new X64CodeChunk(chunk_size_); + } + + uint8_t* final_address = active_chunk_->buffer + active_chunk_->offset; + active_chunk_->offset += code_size; + + lock_.unlock(); + + // Copy code. + xe_copy_struct(final_address, machine_code, code_size); + + return final_address; +} + +X64CodeChunk::X64CodeChunk(size_t chunk_size) + : next(NULL), capacity(chunk_size), buffer(0), offset(0) { + buffer = (uint8_t*)mmap(nullptr, chunk_size, PROT_WRITE | PROT_EXEC, + MAP_ANON | MAP_PRIVATE, -1, 0); +} + +X64CodeChunk::~X64CodeChunk() { + if (buffer) { + munmap(buffer, capacity); + } +} + +} // namespace x64 +} // namespace backend +} // namespace alloy diff --git a/src/alloy/backend/x64/x64_code_cache.cc b/src/alloy/backend/x64/x64_code_cache_win.cc similarity index 100% rename from src/alloy/backend/x64/x64_code_cache.cc rename to src/alloy/backend/x64/x64_code_cache_win.cc diff --git a/src/alloy/hir/opcodes.cc b/src/alloy/hir/opcodes.cc index 5c66c8b1d..df922c493 100644 --- a/src/alloy/hir/opcodes.cc +++ b/src/alloy/hir/opcodes.cc @@ -13,7 +13,7 @@ namespace alloy { namespace hir { #define DEFINE_OPCODE(num, name, sig, flags) \ - static const OpcodeInfo num##_info = { \ + const OpcodeInfo num##_info = { \ flags, sig, name, num, \ }; #include From 48425da8ff441d7eb52ca039a6419d18cd4fb5b9 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 12 Jul 2014 22:59:16 -0700 Subject: [PATCH 027/388] Sandbox getting close to running. --- src/alloy/backend/ivm/ivm_function.cc | 8 ------ src/alloy/frontend/ppc/ppc_context.h | 1 - src/alloy/runtime/runtime.h | 2 +- src/alloy/runtime/thread_state.h | 6 ++--- src/xenia/cpu/xenon_thread_state.cc | 38 +++------------------------ src/xenia/cpu/xenon_thread_state.h | 7 ----- tools/alloy-sandbox/alloy-sandbox.cc | 10 +++---- 7 files changed, 11 insertions(+), 61 deletions(-) diff --git a/src/alloy/backend/ivm/ivm_function.cc b/src/alloy/backend/ivm/ivm_function.cc index b44f1f07a..f0baf3b36 100644 --- a/src/alloy/backend/ivm/ivm_function.cc +++ b/src/alloy/backend/ivm/ivm_function.cc @@ -128,8 +128,6 @@ int IVMFunction::CallImpl(ThreadState* thread_state, uint64_t return_address) { ics.return_address = return_address; ics.call_return_address = 0; - volatile int* suspend_flag_address = thread_state->suspend_flag_address(); - // TODO(benvanik): DID_CARRY -- need HIR to set a OPCODE_FLAG_SET_CARRY // or something so the fns can set an ics flag. @@ -139,12 +137,6 @@ int IVMFunction::CallImpl(ThreadState* thread_state, uint64_t return_address) { uint32_t ia = 0; while (true) { - // Check suspend. We could do this only on certain instructions, if we - // wanted to speed things up. - if (*suspend_flag_address) { - thread_state->EnterSuspend(); - } - #ifdef TRACE_SOURCE_OFFSET uint64_t source_offset = -1; if (source_index < this->source_map_count_ && diff --git a/src/alloy/frontend/ppc/ppc_context.h b/src/alloy/frontend/ppc/ppc_context.h index 5e40b19f2..d1d28860a 100644 --- a/src/alloy/frontend/ppc/ppc_context.h +++ b/src/alloy/frontend/ppc/ppc_context.h @@ -199,7 +199,6 @@ typedef struct XECACHEALIGN64 PPCContext_s { // Runtime-specific data pointer. Used on callbacks to get access to the // current runtime and its data. runtime::Runtime* runtime; - volatile int suspend_flag; void SetRegFromString(const char* name, const char* value); bool CompareRegWithString(const char* name, const char* value, diff --git a/src/alloy/runtime/runtime.h b/src/alloy/runtime/runtime.h index 5ede95140..fc5b90347 100644 --- a/src/alloy/runtime/runtime.h +++ b/src/alloy/runtime/runtime.h @@ -31,7 +31,7 @@ class Runtime { typedef std::vector ModuleList; public: - Runtime(Memory* memory); + explicit Runtime(Memory* memory); virtual ~Runtime(); Memory* memory() const { return memory_; } diff --git a/src/alloy/runtime/thread_state.h b/src/alloy/runtime/thread_state.h index a10e67438..2d1e36b3f 100644 --- a/src/alloy/runtime/thread_state.h +++ b/src/alloy/runtime/thread_state.h @@ -32,10 +32,8 @@ class ThreadState { void* backend_data() const { return backend_data_; } void* raw_context() const { return raw_context_; } - virtual volatile int* suspend_flag_address() const = 0; - virtual int Suspend(uint32_t timeout_ms = UINT_MAX) = 0; - virtual int Resume(bool force = false) = 0; - virtual void EnterSuspend() = 0; + virtual int Suspend(uint32_t timeout_ms = UINT_MAX) { return 1; } + virtual int Resume(bool force = false) { return 1; } static void Bind(ThreadState* thread_state); static ThreadState* Get(); diff --git a/src/xenia/cpu/xenon_thread_state.cc b/src/xenia/cpu/xenon_thread_state.cc index 57959e15f..b00a75355 100644 --- a/src/xenia/cpu/xenon_thread_state.cc +++ b/src/xenia/cpu/xenon_thread_state.cc @@ -23,13 +23,12 @@ using namespace xe::cpu; XenonThreadState::XenonThreadState( XenonRuntime* runtime, uint32_t thread_id, size_t stack_size, uint64_t thread_state_address) : - stack_size_(stack_size), thread_state_address_(thread_state_address), - ThreadState(runtime, thread_id) { + ThreadState(runtime, thread_id), + stack_size_(stack_size), + thread_state_address_(thread_state_address) { stack_address_ = memory_->HeapAlloc( 0, stack_size, MEMORY_FLAG_ZERO); - debug_break_ = CreateEvent(NULL, FALSE, FALSE, NULL); - // Allocate with 64b alignment. context_ = (PPCContext*)xe_malloc_aligned(sizeof(PPCContext)); assert_true(((uint64_t)context_ & 0xF) == 0); @@ -60,40 +59,9 @@ XenonThreadState::XenonThreadState( XenonThreadState::~XenonThreadState() { runtime_->debugger()->OnThreadDestroyed(this); - CloseHandle(debug_break_); - alloy::tracing::WriteEvent(EventType::ThreadDeinit({ })); xe_free_aligned(context_); memory_->HeapFree(stack_address_, stack_size_); } - -volatile int* XenonThreadState::suspend_flag_address() const { - return &context_->suspend_flag; -} - -int XenonThreadState::Suspend(uint32_t timeout_ms) { - // Set suspend flag. - // One of the checks should call in to OnSuspend() at some point. - poly::atomic_inc(&context_->suspend_flag); - return 0; -} - -int XenonThreadState::Resume(bool force) { - if (context_->suspend_flag) { - if (force) { - context_->suspend_flag = 0; - SetEvent(debug_break_); - } else { - if (!poly::atomic_dec(&context_->suspend_flag)) { - SetEvent(debug_break_); - } - } - } - return 0; -} - -void XenonThreadState::EnterSuspend() { - WaitForSingleObject(debug_break_, INFINITE); -} diff --git a/src/xenia/cpu/xenon_thread_state.h b/src/xenia/cpu/xenon_thread_state.h index ca3035590..0bda965fa 100644 --- a/src/xenia/cpu/xenon_thread_state.h +++ b/src/xenia/cpu/xenon_thread_state.h @@ -34,11 +34,6 @@ public: uint64_t thread_state_address() const { return thread_state_address_; } PPCContext* context() const { return context_; } - virtual volatile int* suspend_flag_address() const; - virtual int Suspend(uint32_t timeout_ms = UINT_MAX); - virtual int Resume(bool force = false); - virtual void EnterSuspend(); - private: uint64_t stack_address_; size_t stack_size_; @@ -46,8 +41,6 @@ private: // NOTE: must be 64b aligned for SSE ops. PPCContext* context_; - - HANDLE debug_break_; }; diff --git a/tools/alloy-sandbox/alloy-sandbox.cc b/tools/alloy-sandbox/alloy-sandbox.cc index 038580c69..324e8ea19 100644 --- a/tools/alloy-sandbox/alloy-sandbox.cc +++ b/tools/alloy-sandbox/alloy-sandbox.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include #include - #include +#include #include #include +#include #include @@ -22,7 +22,6 @@ using namespace alloy::runtime; using namespace xe; using namespace xe::cpu; - int alloy_sandbox(int argc, xechar_t** argv) { Profiler::Initialize(); xe::Profiler::ThreadEnter("main"); @@ -43,8 +42,8 @@ int alloy_sandbox(int argc, xechar_t** argv) { module->LoadFile(0x82000000, "test\\codegen\\instr_add.bin"); runtime->AddModule(module); - XenonThreadState* thread_state = new XenonThreadState( - runtime, 100, 64 * 1024, 0); + XenonThreadState* thread_state = + new XenonThreadState(runtime, 100, 64 * 1024, 0); Function* fn; runtime->ResolveFunction(0x82000000, &fn); @@ -54,6 +53,7 @@ int alloy_sandbox(int argc, xechar_t** argv) { ctx->r[25] = 25; fn->Call(thread_state, ctx->lr); auto result = ctx->r[11]; + printf("%llu", result); delete thread_state; From 9437d0b5642cdc6cabb3162da8458426cf22a249 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 13 Jul 2014 21:15:37 -0700 Subject: [PATCH 028/388] Sprucing up some of alloy. --- src/alloy/arena.cc | 6 +-- src/alloy/arena.h | 2 +- src/alloy/backend/ivm/ivm_intcode.cc | 2 +- src/alloy/delegate.h | 8 ++-- src/alloy/hir/hir_builder.cc | 2 +- src/alloy/memory.cc | 29 +++++--------- src/alloy/runtime/debug_info.cc | 16 ++++---- src/alloy/runtime/debugger.cc | 29 ++++++-------- src/alloy/runtime/debugger.h | 6 +-- src/alloy/runtime/entry_table.cc | 10 ++--- src/alloy/runtime/function.cc | 10 ++--- src/alloy/runtime/module.cc | 12 +++--- src/alloy/runtime/module.h | 2 +- src/alloy/runtime/raw_module.cc | 10 +---- src/alloy/runtime/raw_module.h | 10 +++-- src/alloy/runtime/runtime.cc | 45 +++++++++++----------- src/alloy/runtime/runtime.h | 16 ++++---- src/alloy/runtime/symbol_info.cc | 21 +++------- src/alloy/runtime/symbol_info.h | 8 ++-- src/alloy/runtime/thread_state.cc | 19 ++------- src/alloy/runtime/thread_state.h | 6 +-- src/alloy/string_buffer.cc | 33 ++++++++-------- src/alloy/string_buffer.h | 6 ++- src/alloy/tracing/channel.cc | 4 +- src/alloy/tracing/channels/file_channel.cc | 13 +++---- src/alloy/tracing/channels/file_channel.h | 12 +++--- src/alloy/tracing/tracer.cc | 2 +- src/alloy/tracing/tracer.h | 2 +- src/alloy/tracing/tracing.cc | 7 ++-- src/alloy/tracing/tracing.h | 5 ++- src/poly/memory.cc | 32 +++++++++++++++ src/poly/memory.h | 22 +++++++++++ src/poly/platform.h | 1 + src/poly/sources.gypi | 2 + src/xenia/cpu/processor.cc | 10 ++--- src/xenia/cpu/xenon_runtime.cc | 10 ++--- src/xenia/cpu/xenon_runtime.h | 2 +- src/xenia/cpu/xex_module.cc | 10 ++--- src/xenia/cpu/xex_module.h | 20 +++++----- tools/alloy-sandbox/alloy-sandbox.cc | 12 +++--- 40 files changed, 246 insertions(+), 228 deletions(-) create mode 100644 src/poly/memory.cc create mode 100644 src/poly/memory.h diff --git a/src/alloy/arena.cc b/src/alloy/arena.cc index 65f953e33..d3a8992d8 100644 --- a/src/alloy/arena.cc +++ b/src/alloy/arena.cc @@ -12,7 +12,7 @@ namespace alloy { Arena::Arena(size_t chunk_size) - : chunk_size_(chunk_size), head_chunk_(NULL), active_chunk_(NULL) {} + : chunk_size_(chunk_size), head_chunk_(nullptr), active_chunk_(nullptr) {} Arena::~Arena() { Reset(); @@ -22,7 +22,7 @@ Arena::~Arena() { delete chunk; chunk = next; } - head_chunk_ = NULL; + head_chunk_ = nullptr; } void Arena::Reset() { @@ -86,7 +86,7 @@ void* Arena::CloneContents() { } Arena::Chunk::Chunk(size_t chunk_size) - : next(NULL), capacity(chunk_size), buffer(0), offset(0) { + : next(nullptr), capacity(chunk_size), buffer(0), offset(0) { buffer = (uint8_t*)xe_malloc(capacity); } diff --git a/src/alloy/arena.h b/src/alloy/arena.h index 862622deb..3dae80b8d 100644 --- a/src/alloy/arena.h +++ b/src/alloy/arena.h @@ -25,7 +25,7 @@ class Arena { void* Alloc(size_t size); template T* Alloc() { - return (T*)Alloc(sizeof(T)); + return reinterpret_cast(Alloc(sizeof(T))); } void* CloneContents(); diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index 839a729e4..cc9e81d73 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -2657,7 +2657,7 @@ int Translate_MUL(TranslationContext& ctx, Instr* i) { } } -#if !XE_COMPILER_MSVC +#if XE_COMPILER_MSVC uint64_t Mul128(uint64_t xi_low, uint64_t xi_high, uint64_t yi_low, uint64_t yi_high) { // 128bit multiply, simplified for two input 64bit integers. diff --git a/src/alloy/delegate.h b/src/alloy/delegate.h index 1d0344f29..53d4eae72 100644 --- a/src/alloy/delegate.h +++ b/src/alloy/delegate.h @@ -23,14 +23,14 @@ namespace alloy { template class Delegate { public: - typedef std::function listener_t; + typedef std::function Listener; - void AddListener(listener_t const& listener) { + void AddListener(Listener const& listener) { std::lock_guard guard(lock_); listeners_.push_back(listener); } - void RemoveListener(listener_t const& listener) { + void RemoveListener(Listener const& listener) { std::lock_guard guard(lock_); for (auto it = listeners_.begin(); it != listeners_.end(); ++it) { if (it == listener) { @@ -54,7 +54,7 @@ class Delegate { private: std::mutex lock_; - std::vector listeners_; + std::vector listeners_; }; } // namespace alloy diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index 2a2b011e1..439a09e51 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -146,7 +146,7 @@ void HIRBuilder::DumpOp(StringBuffer* str, OpcodeSignatureType sig_type, case OPCODE_SIG_TYPE_S: if (true) { auto target = op->symbol_info; - str->Append(target->name() ? target->name() : ""); + str->Append(!target->name().empty() ? target->name() : ""); } break; case OPCODE_SIG_TYPE_V: diff --git a/src/alloy/memory.cc b/src/alloy/memory.cc index 59568ee49..c334c31a4 100644 --- a/src/alloy/memory.cc +++ b/src/alloy/memory.cc @@ -9,30 +9,21 @@ #include -#if !XE_LIKE_WIN32 -#include -#endif +#include namespace alloy { -Memory::Memory() : membase_(0), reserve_address_(0) { -// TODO(benvanik): move to poly. -#if XE_LIKE_WIN32 - SYSTEM_INFO si; - GetSystemInfo(&si); - system_page_size_ = si.dwPageSize; -#else - system_page_size_ = getpagesize(); -#endif +Memory::Memory() : membase_(nullptr), reserve_address_(0) { + system_page_size_ = poly::page_size(); } -Memory::~Memory() {} +Memory::~Memory() = default; int Memory::Initialize() { return 0; } void Memory::Zero(uint64_t address, size_t size) { uint8_t* p = membase_ + address; - XEIGNORE(xe_zero_memory(p, size, 0, size)); + memset(p, 0, size); } void Memory::Fill(uint64_t address, size_t size, uint8_t value) { @@ -42,15 +33,15 @@ void Memory::Fill(uint64_t address, size_t size, uint8_t value) { void Memory::Copy(uint64_t dest, uint64_t src, size_t size) { uint8_t* pdest = membase_ + dest; - uint8_t* psrc = membase_ + src; - XEIGNORE(xe_copy_memory(pdest, size, psrc, size)); + const uint8_t* psrc = membase_ + src; + memcpy(pdest, psrc, size); } uint64_t Memory::SearchAligned(uint64_t start, uint64_t end, const uint32_t* values, size_t value_count) { assert_true(start <= end); - const uint32_t* p = (const uint32_t*)(membase_ + start); - const uint32_t* pe = (const uint32_t*)(membase_ + end); + const uint32_t* p = reinterpret_cast(membase_ + start); + const uint32_t* pe = reinterpret_cast(membase_ + end); while (p != pe) { if (*p == values[0]) { const uint32_t* pc = p + 1; @@ -62,7 +53,7 @@ uint64_t Memory::SearchAligned(uint64_t start, uint64_t end, matched++; } if (matched == value_count) { - return (uint64_t)((uint8_t*)p - membase_); + return uint64_t(reinterpret_cast(p) - membase_); } } p++; diff --git a/src/alloy/runtime/debug_info.cc b/src/alloy/runtime/debug_info.cc index 266e57946..64022868c 100644 --- a/src/alloy/runtime/debug_info.cc +++ b/src/alloy/runtime/debug_info.cc @@ -13,12 +13,12 @@ namespace alloy { namespace runtime { DebugInfo::DebugInfo() - : source_disasm_(0), - raw_hir_disasm_(0), - hir_disasm_(0), - machine_code_disasm_(0), + : source_disasm_(nullptr), + raw_hir_disasm_(nullptr), + hir_disasm_(nullptr), + machine_code_disasm_(nullptr), source_map_count_(0), - source_map_(NULL) {} + source_map_(nullptr) {} DebugInfo::~DebugInfo() { xe_free(source_map_); @@ -44,7 +44,7 @@ SourceMapEntry* DebugInfo::LookupSourceOffset(uint64_t offset) { return entry; } } - return NULL; + return nullptr; } SourceMapEntry* DebugInfo::LookupHIROffset(uint64_t offset) { @@ -55,7 +55,7 @@ SourceMapEntry* DebugInfo::LookupHIROffset(uint64_t offset) { return entry; } } - return NULL; + return nullptr; } SourceMapEntry* DebugInfo::LookupCodeOffset(uint64_t offset) { @@ -66,7 +66,7 @@ SourceMapEntry* DebugInfo::LookupCodeOffset(uint64_t offset) { return entry; } } - return NULL; + return nullptr; } } // namespace runtime diff --git a/src/alloy/runtime/debugger.cc b/src/alloy/runtime/debugger.cc index fee71e67e..a5c129fc8 100644 --- a/src/alloy/runtime/debugger.cc +++ b/src/alloy/runtime/debugger.cc @@ -19,19 +19,18 @@ namespace runtime { Breakpoint::Breakpoint(Type type, uint64_t address) : type_(type), address_(address) {} -Breakpoint::~Breakpoint() {} +Breakpoint::~Breakpoint() = default; Debugger::Debugger(Runtime* runtime) : runtime_(runtime) {} -Debugger::~Debugger() {} +Debugger::~Debugger() = default; int Debugger::SuspendAllThreads(uint32_t timeout_ms) { std::lock_guard guard(threads_lock_); int result = 0; - for (auto it = threads_.begin(); it != threads_.end(); ++it) { - ThreadState* thread_state = it->second; - if (thread_state->Suspend(timeout_ms)) { + for (auto thread_state : threads_) { + if (thread_state.second->Suspend(timeout_ms)) { result = 1; } } @@ -57,9 +56,8 @@ int Debugger::ResumeAllThreads(bool force) { std::lock_guard guard(threads_lock_); int result = 0; - for (auto it = threads_.begin(); it != threads_.end(); ++it) { - ThreadState* thread_state = it->second; - if (thread_state->Resume(force)) { + for (auto thread_state : threads_) { + if (thread_state.second->Resume(force)) { result = 1; } } @@ -69,9 +67,8 @@ int Debugger::ResumeAllThreads(bool force) { void Debugger::ForEachThread(std::function callback) { std::lock_guard guard(threads_lock_); - for (auto it = threads_.begin(); it != threads_.end(); ++it) { - ThreadState* thread_state = it->second; - callback(thread_state); + for (auto thread_state : threads_) { + callback(thread_state.second); } } @@ -87,8 +84,7 @@ int Debugger::AddBreakpoint(Breakpoint* breakpoint) { auto fns = runtime_->FindFunctionsWithAddress(breakpoint->address()); // Add. - for (auto it = fns.begin(); it != fns.end(); ++it) { - Function* fn = *it; + for (auto fn : fns) { if (fn->AddBreakpoint(breakpoint)) { return 1; } @@ -122,8 +118,7 @@ int Debugger::RemoveBreakpoint(Breakpoint* breakpoint) { auto fns = runtime_->FindFunctionsWithAddress(breakpoint->address()); // Remove. - for (auto it = fns.begin(); it != fns.end(); ++it) { - Function* fn = *it; + for (auto fn : fns) { fn->RemoveBreakpoint(breakpoint); } @@ -181,8 +176,8 @@ void Debugger::OnFunctionDefined(FunctionInfo* symbol_info, if (breakpoints.size()) { // Breakpoints to add! - for (auto it = breakpoints.begin(); it != breakpoints.end(); ++it) { - function->AddBreakpoint(*it); + for (auto breakpoint : breakpoints) { + function->AddBreakpoint(breakpoint); } } } diff --git a/src/alloy/runtime/debugger.h b/src/alloy/runtime/debugger.h index bacb58f3f..fcac741d8 100644 --- a/src/alloy/runtime/debugger.h +++ b/src/alloy/runtime/debugger.h @@ -41,7 +41,7 @@ class Breakpoint { uint64_t address() const { return address_; } const char* id() const { return id_.c_str(); } - void set_id(const char* id) { id_ = id; } + void set_id(const char* id) { id_ = std::string(id); } private: Type type_; @@ -53,7 +53,7 @@ class Breakpoint { class DebugEvent { public: DebugEvent(Debugger* debugger) : debugger_(debugger) {} - virtual ~DebugEvent() {} + virtual ~DebugEvent() = default; Debugger* debugger() const { return debugger_; } protected: @@ -67,7 +67,7 @@ class BreakpointHitEvent : public DebugEvent { : DebugEvent(debugger), thread_state_(thread_state), breakpoint_(breakpoint) {} - virtual ~BreakpointHitEvent() {} + ~BreakpointHitEvent() override = default; ThreadState* thread_state() const { return thread_state_; } Breakpoint* breakpoint() const { return breakpoint_; } diff --git a/src/alloy/runtime/entry_table.cc b/src/alloy/runtime/entry_table.cc index 0277be312..df1a6f89b 100644 --- a/src/alloy/runtime/entry_table.cc +++ b/src/alloy/runtime/entry_table.cc @@ -26,11 +26,11 @@ EntryTable::~EntryTable() { Entry* EntryTable::Get(uint64_t address) { std::lock_guard guard(lock_); EntryMap::const_iterator it = map_.find(address); - Entry* entry = it != map_.end() ? it->second : NULL; + Entry* entry = it != map_.end() ? it->second : nullptr; if (entry) { // TODO(benvanik): wait if needed? if (entry->status != Entry::STATUS_READY) { - entry = NULL; + entry = nullptr; } } return entry; @@ -39,7 +39,7 @@ Entry* EntryTable::Get(uint64_t address) { Entry::Status EntryTable::GetOrCreate(uint64_t address, Entry** out_entry) { lock_.lock(); EntryMap::const_iterator it = map_.find(address); - Entry* entry = it != map_.end() ? it->second : NULL; + Entry* entry = it != map_.end() ? it->second : nullptr; Entry::Status status; if (entry) { // If we aren't ready yet spin and wait. @@ -72,8 +72,8 @@ std::vector EntryTable::FindWithAddress(uint64_t address) { SCOPE_profile_cpu_f("alloy"); std::lock_guard guard(lock_); std::vector fns; - for (auto it = map_.begin(); it != map_.end(); ++it) { - Entry* entry = it->second; + for (auto& it : map_) { + Entry* entry = it.second; if (address >= entry->address && address <= entry->end_address) { if (entry->status == Entry::STATUS_READY) { fns.push_back(entry->function); diff --git a/src/alloy/runtime/function.cc b/src/alloy/runtime/function.cc index 974b50eaa..7002cc86b 100644 --- a/src/alloy/runtime/function.cc +++ b/src/alloy/runtime/function.cc @@ -26,9 +26,10 @@ Function::~Function() = default; int Function::AddBreakpoint(Breakpoint* breakpoint) { std::lock_guard guard(lock_); bool found = false; - for (auto it = breakpoints_.begin(); it != breakpoints_.end(); ++it) { - if (*it == breakpoint) { + for (auto other : breakpoints_) { + if (other == breakpoint) { found = true; + break; } } if (!found) { @@ -54,9 +55,8 @@ int Function::RemoveBreakpoint(Breakpoint* breakpoint) { Breakpoint* Function::FindBreakpoint(uint64_t address) { std::lock_guard guard(lock_); - Breakpoint* result = NULL; - for (auto it = breakpoints_.begin(); it != breakpoints_.end(); ++it) { - Breakpoint* breakpoint = *it; + Breakpoint* result = nullptr; + for (auto breakpoint : breakpoints_) { if (breakpoint->address() == address) { result = breakpoint; break; diff --git a/src/alloy/runtime/module.cc b/src/alloy/runtime/module.cc index 24e27f00c..ff640088b 100644 --- a/src/alloy/runtime/module.cc +++ b/src/alloy/runtime/module.cc @@ -34,7 +34,7 @@ bool Module::ContainsAddress(uint64_t address) { return true; } SymbolInfo* Module::LookupSymbol(uint64_t address, bool wait) { lock_.lock(); SymbolMap::const_iterator it = map_.find(address); - SymbolInfo* symbol_info = it != map_.end() ? it->second : NULL; + SymbolInfo* symbol_info = it != map_.end() ? it->second : nullptr; if (symbol_info) { if (symbol_info->status() == SymbolInfo::STATUS_DECLARING) { // Some other thread is declaring the symbol - wait. @@ -47,7 +47,7 @@ SymbolInfo* Module::LookupSymbol(uint64_t address, bool wait) { } while (symbol_info->status() == SymbolInfo::STATUS_DECLARING); } else { // Immediate request, just return. - symbol_info = NULL; + symbol_info = nullptr; } } } @@ -58,10 +58,10 @@ SymbolInfo* Module::LookupSymbol(uint64_t address, bool wait) { SymbolInfo::Status Module::DeclareSymbol(SymbolInfo::Type type, uint64_t address, SymbolInfo** out_symbol_info) { - *out_symbol_info = NULL; + *out_symbol_info = nullptr; lock_.lock(); SymbolMap::const_iterator it = map_.find(address); - SymbolInfo* symbol_info = it != map_.end() ? it->second : NULL; + SymbolInfo* symbol_info = it != map_.end() ? it->second : nullptr; SymbolInfo::Status status; if (symbol_info) { // If we exist but are the wrong type, die. @@ -235,8 +235,8 @@ int Module::ReadMap(const char* file_name) { continue; } // Don't overwrite names we've set elsewhere. - if (!fn_info->name()) { - // If it's an mangled C++ name (?name@...) just use the name. + if (fn_info->name().empty()) { + // If it's a mangled C++ name (?name@...) just use the name. // TODO(benvanik): better demangling, or leave it to clients. /*if (name[0] == '?') { size_t at = name.find('@'); diff --git a/src/alloy/runtime/module.h b/src/alloy/runtime/module.h index e55b18375..e74899a63 100644 --- a/src/alloy/runtime/module.h +++ b/src/alloy/runtime/module.h @@ -32,7 +32,7 @@ class Module { Memory* memory() const { return memory_; } - virtual const char* name() const = 0; + virtual const std::string& name() const = 0; virtual bool ContainsAddress(uint64_t address); diff --git a/src/alloy/runtime/raw_module.cc b/src/alloy/runtime/raw_module.cc index 43df9f67a..0d0a4c6d7 100644 --- a/src/alloy/runtime/raw_module.cc +++ b/src/alloy/runtime/raw_module.cc @@ -13,17 +13,12 @@ namespace alloy { namespace runtime { RawModule::RawModule(Runtime* runtime) - : Module(runtime), - name_(0), - base_address_(0), - low_address_(0), - high_address_(0) {} + : Module(runtime), base_address_(0), low_address_(0), high_address_(0) {} RawModule::~RawModule() { if (base_address_) { memory_->HeapFree(base_address_, high_address_ - low_address_); } - xe_free(name_); } int RawModule::LoadFile(uint64_t base_address, const char* path) { @@ -47,8 +42,7 @@ int RawModule::LoadFile(uint64_t base_address, const char* path) { fclose(file); // Setup debug info. - const char* name = xestrrchra(path, XE_PATH_SEPARATOR) + 1; - name_ = xestrdupa(name); + name_ = std::string(xestrrchra(path, XE_PATH_SEPARATOR) + 1); // TODO(benvanik): debug info low_address_ = base_address; diff --git a/src/alloy/runtime/raw_module.h b/src/alloy/runtime/raw_module.h index dfedfb60c..8eb2c645d 100644 --- a/src/alloy/runtime/raw_module.h +++ b/src/alloy/runtime/raw_module.h @@ -10,6 +10,8 @@ #ifndef ALLOY_RUNTIME_RAW_MODULE_H_ #define ALLOY_RUNTIME_RAW_MODULE_H_ +#include + #include namespace alloy { @@ -18,16 +20,16 @@ namespace runtime { class RawModule : public Module { public: RawModule(Runtime* runtime); - virtual ~RawModule(); + ~RawModule() override; int LoadFile(uint64_t base_address, const char* path); - virtual const char* name() const { return name_; } + const std::string& name() const override { return name_; } - virtual bool ContainsAddress(uint64_t address); + bool ContainsAddress(uint64_t address) override; private: - char* name_; + std::string name_; uint64_t base_address_; uint64_t low_address_; uint64_t high_address_; diff --git a/src/alloy/runtime/runtime.cc b/src/alloy/runtime/runtime.cc index 66e514ae8..86fbbc319 100644 --- a/src/alloy/runtime/runtime.cc +++ b/src/alloy/runtime/runtime.cc @@ -26,8 +26,7 @@ namespace runtime { using alloy::backend::Backend; using alloy::frontend::Frontend; -Runtime::Runtime(Memory* memory) - : memory_(memory), debugger_(0), frontend_(0), backend_(0) { +Runtime::Runtime(Memory* memory) : memory_(memory) { tracing::Initialize(); } @@ -41,19 +40,20 @@ Runtime::~Runtime() { } } - delete frontend_; - delete backend_; - delete debugger_; + debugger_.reset(); + frontend_.reset(); + backend_.reset(); tracing::Flush(); } -int Runtime::Initialize(Frontend* frontend, Backend* backend) { +int Runtime::Initialize(std::unique_ptr frontend, + std::unique_ptr backend) { // Must be initialized by subclass before calling into this. assert_not_null(memory_); // Create debugger first. Other types hook up to it. - debugger_ = new Debugger(this); + debugger_.reset(new Debugger(this)); if (frontend_ || backend_) { return 1; @@ -62,23 +62,23 @@ int Runtime::Initialize(Frontend* frontend, Backend* backend) { if (!backend) { #if defined(ALLOY_HAS_X64_BACKEND) && ALLOY_HAS_X64_BACKEND if (FLAGS_runtime_backend == "x64") { - backend = new alloy::backend::x64::X64Backend(this); + backend.reset(new alloy::backend::x64::X64Backend(this)); } #endif // ALLOY_HAS_X64_BACKEND #if defined(ALLOY_HAS_IVM_BACKEND) && ALLOY_HAS_IVM_BACKEND if (FLAGS_runtime_backend == "ivm") { - backend = new alloy::backend::ivm::IVMBackend(this); + backend.reset(new alloy::backend::ivm::IVMBackend(this)); } #endif // ALLOY_HAS_IVM_BACKEND if (FLAGS_runtime_backend == "any") { #if defined(ALLOY_HAS_X64_BACKEND) && ALLOY_HAS_X64_BACKEND if (!backend) { - backend = new alloy::backend::x64::X64Backend(this); + backend.reset(new alloy::backend::x64::X64Backend(this)); } #endif // ALLOY_HAS_X64_BACKEND #if defined(ALLOY_HAS_IVM_BACKEND) && ALLOY_HAS_IVM_BACKEND if (!backend) { - backend = new alloy::backend::ivm::IVMBackend(this); + backend.reset(new alloy::backend::ivm::IVMBackend(this)); } #endif // ALLOY_HAS_IVM_BACKEND } @@ -87,19 +87,20 @@ int Runtime::Initialize(Frontend* frontend, Backend* backend) { if (!backend) { return 1; } - backend_ = backend; - frontend_ = frontend; - int result = backend_->Initialize(); + int result = backend->Initialize(); if (result) { return result; } - result = frontend_->Initialize(); + result = frontend->Initialize(); if (result) { return result; } + backend_ = std::move(backend); + frontend_ = std::move(frontend); + return 0; } @@ -114,7 +115,7 @@ Module* Runtime::GetModule(const char* name) { Module* result = NULL; for (ModuleList::iterator it = modules_.begin(); it != modules_.end(); ++it) { Module* module = *it; - if (xestrcmpa(module->name(), name) == 0) { + if (module->name() == name) { result = module; break; } @@ -135,7 +136,7 @@ std::vector Runtime::FindFunctionsWithAddress(uint64_t address) { int Runtime::ResolveFunction(uint64_t address, Function** out_function) { SCOPE_profile_cpu_f("alloy"); - *out_function = NULL; + *out_function = nullptr; Entry* entry; Entry::Status status = entry_table_.GetOrCreate(address, &entry); if (status == Entry::STATUS_NEW) { @@ -170,12 +171,12 @@ int Runtime::LookupFunctionInfo(uint64_t address, FunctionInfo** out_symbol_info) { SCOPE_profile_cpu_f("alloy"); - *out_symbol_info = NULL; + *out_symbol_info = nullptr; // TODO(benvanik): fast reject invalid addresses/log errors. // Find the module that contains the address. - Module* code_module = NULL; + Module* code_module = nullptr; { std::lock_guard guard(modules_lock_); // TODO(benvanik): sort by code address (if contiguous) so can bsearch. @@ -203,7 +204,7 @@ int Runtime::LookupFunctionInfo(Module* module, uint64_t address, // Atomic create/lookup symbol in module. // If we get back the NEW flag we must declare it now. - FunctionInfo* symbol_info = NULL; + FunctionInfo* symbol_info = nullptr; SymbolInfo::Status symbol_status = module->DeclareFunction(address, &symbol_info); if (symbol_status == SymbolInfo::STATUS_NEW) { @@ -224,7 +225,7 @@ int Runtime::DemandFunction(FunctionInfo* symbol_info, Function** out_function) { SCOPE_profile_cpu_f("alloy"); - *out_function = NULL; + *out_function = nullptr; // Lock function for generation. If it's already being generated // by another thread this will block and return DECLARED. @@ -232,7 +233,7 @@ int Runtime::DemandFunction(FunctionInfo* symbol_info, SymbolInfo::Status symbol_status = module->DefineFunction(symbol_info); if (symbol_status == SymbolInfo::STATUS_NEW) { // Symbol is undefined, so define now. - Function* function = NULL; + Function* function = nullptr; int result = frontend_->DefineFunction(symbol_info, DEBUG_INFO_DEFAULT, &function); if (result) { diff --git a/src/alloy/runtime/runtime.h b/src/alloy/runtime/runtime.h index fc5b90347..97968a9b8 100644 --- a/src/alloy/runtime/runtime.h +++ b/src/alloy/runtime/runtime.h @@ -10,6 +10,7 @@ #ifndef ALLOY_RUNTIME_RUNTIME_H_ #define ALLOY_RUNTIME_RUNTIME_H_ +#include #include #include @@ -35,11 +36,12 @@ class Runtime { virtual ~Runtime(); Memory* memory() const { return memory_; } - Debugger* debugger() const { return debugger_; } - frontend::Frontend* frontend() const { return frontend_; } - backend::Backend* backend() const { return backend_; } + Debugger* debugger() const { return debugger_.get(); } + frontend::Frontend* frontend() const { return frontend_.get(); } + backend::Backend* backend() const { return backend_.get(); } - int Initialize(frontend::Frontend* frontend, backend::Backend* backend = 0); + int Initialize(std::unique_ptr frontend, + std::unique_ptr backend = 0); int AddModule(Module* module); Module* GetModule(const char* name); @@ -60,10 +62,10 @@ class Runtime { protected: Memory* memory_; - Debugger* debugger_; + std::unique_ptr debugger_; - frontend::Frontend* frontend_; - backend::Backend* backend_; + std::unique_ptr frontend_; + std::unique_ptr backend_; EntryTable entry_table_; std::mutex modules_lock_; diff --git a/src/alloy/runtime/symbol_info.cc b/src/alloy/runtime/symbol_info.cc index 2392cc452..b525bf841 100644 --- a/src/alloy/runtime/symbol_info.cc +++ b/src/alloy/runtime/symbol_info.cc @@ -17,30 +17,19 @@ SymbolInfo::SymbolInfo(Type type, Module* module, uint64_t address) module_(module), status_(STATUS_DEFINING), address_(address), - name_(0) {} + name_("") {} -SymbolInfo::~SymbolInfo() { - if (name_) { - xe_free(name_); - } -} - -void SymbolInfo::set_name(const char* name) { - if (name_) { - xe_free(name_); - } - name_ = xestrdupa(name); -} +SymbolInfo::~SymbolInfo() = default; FunctionInfo::FunctionInfo(Module* module, uint64_t address) : SymbolInfo(SymbolInfo::TYPE_FUNCTION, module, address), end_address_(0), behavior_(BEHAVIOR_DEFAULT), function_(0) { - xe_zero_struct(&extern_info_, sizeof(extern_info_)); + memset(&extern_info_, 0, sizeof(extern_info_)); } -FunctionInfo::~FunctionInfo() {} +FunctionInfo::~FunctionInfo() = default; void FunctionInfo::SetupExtern(ExternHandler handler, void* arg0, void* arg1) { behavior_ = BEHAVIOR_EXTERN; @@ -52,7 +41,7 @@ void FunctionInfo::SetupExtern(ExternHandler handler, void* arg0, void* arg1) { VariableInfo::VariableInfo(Module* module, uint64_t address) : SymbolInfo(SymbolInfo::TYPE_VARIABLE, module, address) {} -VariableInfo::~VariableInfo() {} +VariableInfo::~VariableInfo() = default; } // namespace runtime } // namespace alloy diff --git a/src/alloy/runtime/symbol_info.h b/src/alloy/runtime/symbol_info.h index e9a3b06f2..c8157105e 100644 --- a/src/alloy/runtime/symbol_info.h +++ b/src/alloy/runtime/symbol_info.h @@ -10,6 +10,8 @@ #ifndef ALLOY_RUNTIME_SYMBOL_INFO_H_ #define ALLOY_RUNTIME_SYMBOL_INFO_H_ +#include + #include namespace alloy { @@ -43,8 +45,8 @@ class SymbolInfo { void set_status(Status value) { status_ = value; } uint64_t address() const { return address_; } - const char* name() const { return name_; } - void set_name(const char* name); + const std::string& name() const { return name_; } + void set_name(const std::string& value) { name_ = value; } protected: Type type_; @@ -52,7 +54,7 @@ class SymbolInfo { Status status_; uint64_t address_; - char* name_; + std::string name_; }; class FunctionInfo : public SymbolInfo { diff --git a/src/alloy/runtime/thread_state.cc b/src/alloy/runtime/thread_state.cc index 549d7d2d3..c2469b3c5 100644 --- a/src/alloy/runtime/thread_state.cc +++ b/src/alloy/runtime/thread_state.cc @@ -14,13 +14,13 @@ namespace alloy { namespace runtime { -thread_local ThreadState* thread_state_ = NULL; +thread_local ThreadState* thread_state_ = nullptr; ThreadState::ThreadState(Runtime* runtime, uint32_t thread_id) : runtime_(runtime), memory_(runtime->memory()), thread_id_(thread_id), - name_(0), + name_(""), backend_data_(0), raw_context_(0) { if (thread_id_ == UINT_MAX) { @@ -37,21 +37,8 @@ ThreadState::~ThreadState() { runtime_->backend()->FreeThreadData(backend_data_); } if (thread_state_ == this) { - thread_state_ = NULL; + thread_state_ = nullptr; } - if (name_) { - xe_free(name_); - } -} - -void ThreadState::set_name(const char* value) { - if (value == name_) { - return; - } - if (name_) { - xe_free(name_); - } - name_ = xestrdupa(value); } void ThreadState::Bind(ThreadState* thread_state) { diff --git a/src/alloy/runtime/thread_state.h b/src/alloy/runtime/thread_state.h index 2d1e36b3f..be6655438 100644 --- a/src/alloy/runtime/thread_state.h +++ b/src/alloy/runtime/thread_state.h @@ -27,8 +27,8 @@ class ThreadState { Runtime* runtime() const { return runtime_; } Memory* memory() const { return memory_; } uint32_t thread_id() const { return thread_id_; } - const char* name() const { return name_; } - void set_name(const char* value); + const std::string& name() const { return name_; } + void set_name(const std::string& value) { name_ = value; } void* backend_data() const { return backend_data_; } void* raw_context() const { return raw_context_; } @@ -43,7 +43,7 @@ class ThreadState { Runtime* runtime_; Memory* memory_; uint32_t thread_id_; - char* name_; + std::string name_; void* backend_data_; void* raw_context_; }; diff --git a/src/alloy/string_buffer.cc b/src/alloy/string_buffer.cc index 887dbbf5f..ca667f997 100644 --- a/src/alloy/string_buffer.cc +++ b/src/alloy/string_buffer.cc @@ -11,20 +11,21 @@ namespace alloy { -StringBuffer::StringBuffer(size_t initial_capacity) - : buffer_(0), capacity_(0), offset_(0) { - capacity_ = MAX(initial_capacity, 1024); - buffer_ = (char*)xe_calloc(capacity_); - buffer_[0] = 0; +StringBuffer::StringBuffer(size_t initial_capacity) : offset_(0) { + buffer_.resize(MAX(initial_capacity, 1024)); } -StringBuffer::~StringBuffer() { xe_free(buffer_); } +StringBuffer::~StringBuffer() = default; void StringBuffer::Reset() { offset_ = 0; buffer_[0] = 0; } +void StringBuffer::Append(const std::string& value) { + Append(value.c_str()); +} + void StringBuffer::Append(const char* format, ...) { va_list args; va_start(args, format); @@ -34,12 +35,10 @@ void StringBuffer::Append(const char* format, ...) { void StringBuffer::AppendVarargs(const char* format, va_list args) { while (true) { - int len = - xevsnprintfa(buffer_ + offset_, capacity_ - offset_ - 1, format, args); + int len = vsnprintf(buffer_.data() + offset_, buffer_.size() - offset_ - 1, + format, args); if (len == -1) { - size_t old_capacity = capacity_; - capacity_ = capacity_ * 2; - buffer_ = (char*)xe_realloc(buffer_, old_capacity, capacity_); + buffer_.resize(buffer_.size() * 2); continue; } else { offset_ += len; @@ -50,18 +49,16 @@ void StringBuffer::AppendVarargs(const char* format, va_list args) { } void StringBuffer::AppendBytes(const uint8_t* buffer, size_t length) { - if (offset_ + length > capacity_) { - size_t old_capacity = capacity_; - capacity_ = MAX(capacity_ * 2, capacity_ + length); - buffer_ = (char*)xe_realloc(buffer_, old_capacity, capacity_); + if (offset_ + length > buffer_.size()) { + buffer_.resize(MAX(buffer_.size() * 2, buffer_.size() + length)); } - xe_copy_memory(buffer_ + offset_, capacity_ - offset_, buffer, length); + memcpy(buffer_.data() + offset_, buffer, length); offset_ += length; buffer_[offset_] = 0; } -const char* StringBuffer::GetString() const { return buffer_; } +const char* StringBuffer::GetString() const { return buffer_.data(); } -char* StringBuffer::ToString() { return xestrdupa(buffer_); } +char* StringBuffer::ToString() { return strdup(buffer_.data()); } } // namespace alloy diff --git a/src/alloy/string_buffer.h b/src/alloy/string_buffer.h index b14055d1d..ca553d343 100644 --- a/src/alloy/string_buffer.h +++ b/src/alloy/string_buffer.h @@ -10,6 +10,8 @@ #ifndef ALLOY_STRING_BUFFER_H_ #define ALLOY_STRING_BUFFER_H_ +#include + #include namespace alloy { @@ -23,6 +25,7 @@ class StringBuffer { void Reset(); + void Append(const std::string& value); void Append(const char* format, ...); void AppendVarargs(const char* format, va_list args); void AppendBytes(const uint8_t* buffer, size_t length); @@ -32,8 +35,7 @@ class StringBuffer { char* EncodeBase64(); private: - char* buffer_; - size_t capacity_; + std::vector buffer_; size_t offset_; }; diff --git a/src/alloy/tracing/channel.cc b/src/alloy/tracing/channel.cc index ea2616e52..46fca1f61 100644 --- a/src/alloy/tracing/channel.cc +++ b/src/alloy/tracing/channel.cc @@ -12,9 +12,9 @@ namespace alloy { namespace tracing { -Channel::Channel() {} +Channel::Channel() = default; -Channel::~Channel() {} +Channel::~Channel() = default; } // namespace tracing } // namespace alloy diff --git a/src/alloy/tracing/channels/file_channel.cc b/src/alloy/tracing/channels/file_channel.cc index 89767d428..99bc8ba5e 100644 --- a/src/alloy/tracing/channels/file_channel.cc +++ b/src/alloy/tracing/channels/file_channel.cc @@ -13,17 +13,16 @@ namespace alloy { namespace tracing { namespace channels { -FileChannel::FileChannel(const char* path) { - path_ = xestrdupa(path); - file_ = fopen(path, "wb"); +FileChannel::FileChannel(const std::string& path) : path_(path) { + file_ = fopen(path_.c_str(), "wb"); } FileChannel::~FileChannel() { std::lock_guard guard(lock_); - fclose(file_); - file_ = 0; - free(path_); - path_ = 0; + if (file_) { + fclose(file_); + file_ = nullptr; + } } void FileChannel::Write(size_t buffer_count, size_t buffer_lengths[], diff --git a/src/alloy/tracing/channels/file_channel.h b/src/alloy/tracing/channels/file_channel.h index ba290dc1a..0b7df668c 100644 --- a/src/alloy/tracing/channels/file_channel.h +++ b/src/alloy/tracing/channels/file_channel.h @@ -22,16 +22,16 @@ namespace channels { class FileChannel : public Channel { public: - FileChannel(const char* path); - virtual ~FileChannel(); + FileChannel(const std::string& path); + ~FileChannel() override; - virtual void Write(size_t buffer_count, size_t buffer_lengths[], - const uint8_t* buffers[]); + void Write(size_t buffer_count, size_t buffer_lengths[], + const uint8_t* buffers[]) override; - virtual void Flush(); + void Flush() override; private: - char* path_; + std::string path_; FILE* file_; std::mutex lock_; }; diff --git a/src/alloy/tracing/tracer.cc b/src/alloy/tracing/tracer.cc index 01ee501d3..3c4f3a157 100644 --- a/src/alloy/tracing/tracer.cc +++ b/src/alloy/tracing/tracer.cc @@ -22,7 +22,7 @@ Tracer::Tracer(Channel* channel) : channel_(channel) { thread_id_ = ++next_thread_id_; } -Tracer::~Tracer() {} +Tracer::~Tracer() = default; void Tracer::WriteEvent(uint32_t event_type, size_t size, const uint8_t* data) { uint32_t header[] = { diff --git a/src/alloy/tracing/tracer.h b/src/alloy/tracing/tracer.h index 3d322f495..ba7faeab2 100644 --- a/src/alloy/tracing/tracer.h +++ b/src/alloy/tracing/tracer.h @@ -26,7 +26,7 @@ class Tracer { void set_thread_id(int value) { thread_id_ = value; } void WriteEvent(uint32_t event_type, size_t size = 0, - const uint8_t* data = 0); + const uint8_t* data = nullptr); private: Channel* channel_; diff --git a/src/alloy/tracing/tracing.cc b/src/alloy/tracing/tracing.cc index ace0d54a9..7c7ffa2bd 100644 --- a/src/alloy/tracing/tracing.cc +++ b/src/alloy/tracing/tracing.cc @@ -24,13 +24,14 @@ DEFINE_string(trace_file, "", "Traces to the given file path."); namespace alloy { namespace tracing { -Channel* shared_channel = NULL; -thread_local Tracer* thread_tracer = NULL; +Channel* shared_channel = nullptr; +thread_local Tracer* thread_tracer = nullptr; void CleanupTracing() { if (shared_channel) { alloy::tracing::WriteEvent(EventType::TraceEOF({})); shared_channel->Flush(); + shared_channel = nullptr; } } @@ -67,7 +68,7 @@ void Flush() { Tracer* GetThreadTracer() { if (!shared_channel) { - return NULL; + return nullptr; } if (!thread_tracer) { thread_tracer = new Tracer(shared_channel); diff --git a/src/alloy/tracing/tracing.h b/src/alloy/tracing/tracing.h index 4ca602bc0..bcfe68a9d 100644 --- a/src/alloy/tracing/tracing.h +++ b/src/alloy/tracing/tracing.h @@ -20,13 +20,14 @@ namespace tracing { class Channel; class Tracer; -bool Initialize(Channel* channel = 0); +bool Initialize(Channel* channel = nullptr); void Shutdown(); void Flush(); Tracer* GetThreadTracer(); -void WriteEvent(uint32_t event_type, size_t size = 0, const void* data = 0); +void WriteEvent(uint32_t event_type, size_t size = 0, + const void* data = nullptr); template void WriteEvent(const T& ev) { diff --git a/src/poly/memory.cc b/src/poly/memory.cc new file mode 100644 index 000000000..448899769 --- /dev/null +++ b/src/poly/memory.cc @@ -0,0 +1,32 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#if !XE_LIKE_WIN32 +#include +#endif // !XE_LIKE_WIN32 + +namespace poly { + +size_t page_size() { + static size_t value = 0; + if (!value) { +#if XE_LIKE_WIN32 + SYSTEM_INFO si; + GetSystemInfo(&si); + value = si.dwPageSize; +#else + value = getpagesize(); +#endif // XE_LIKE_WIN32 + } + return value; +} + +} // namespace poly diff --git a/src/poly/memory.h b/src/poly/memory.h new file mode 100644 index 000000000..01dbc608e --- /dev/null +++ b/src/poly/memory.h @@ -0,0 +1,22 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef POLY_MEMORY_H_ +#define POLY_MEMORY_H_ + +#include +#include + +namespace poly { + +size_t page_size(); + +} // namespace poly + +#endif // POLY_MEMORY_H_ diff --git a/src/poly/platform.h b/src/poly/platform.h index f5705e11b..019d69060 100644 --- a/src/poly/platform.h +++ b/src/poly/platform.h @@ -142,6 +142,7 @@ XE_CPU: 32BIT | 64BIT | BIGENDIAN | LITTLEENDIAN #undef min #undef max #undef Yield +#define strdup _strdup #endif // WINCE || WIN32 #if XE_PLATFORM_XBOX360 diff --git a/src/poly/sources.gypi b/src/poly/sources.gypi index f9a0fe960..a58841268 100644 --- a/src/poly/sources.gypi +++ b/src/poly/sources.gypi @@ -7,6 +7,8 @@ 'cxx_compat.h', 'math.cc', 'math.h', + 'memory.cc', + 'memory.h', 'platform.h', 'poly-private.h', 'poly.cc', diff --git a/src/xenia/cpu/processor.cc b/src/xenia/cpu/processor.cc index b263e1aad..0432fa294 100644 --- a/src/xenia/cpu/processor.cc +++ b/src/xenia/cpu/processor.cc @@ -75,12 +75,10 @@ int Processor::Setup() { return 1; } - Backend* backend = 0; - // Backend* backend = new alloy::backend::ivm::IVMBackend( - // runtime); - // Backend* backend = new alloy::backend::x64::X64Backend( - // runtime); - int result = runtime_->Initialize(backend); + std::unique_ptr backend; + // backend.reset(new alloy::backend::ivm::IVMBackend(runtime)); + // backend.reset(new alloy::backend::x64::X64Backend(runtime)); + int result = runtime_->Initialize(std::move(backend)); if (result) { return result; } diff --git a/src/xenia/cpu/xenon_runtime.cc b/src/xenia/cpu/xenon_runtime.cc index 0477bd926..9caa0841e 100644 --- a/src/xenia/cpu/xenon_runtime.cc +++ b/src/xenia/cpu/xenon_runtime.cc @@ -23,8 +23,8 @@ using namespace xe::cpu; XenonRuntime::XenonRuntime( alloy::Memory* memory, ExportResolver* export_resolver) : - export_resolver_(export_resolver), - Runtime(memory) { + Runtime(memory), + export_resolver_(export_resolver) { } XenonRuntime::~XenonRuntime() { @@ -32,11 +32,11 @@ XenonRuntime::~XenonRuntime() { })); } -int XenonRuntime::Initialize(backend::Backend* backend) { - PPCFrontend* frontend = new PPCFrontend(this); +int XenonRuntime::Initialize(std::unique_ptr backend) { + std::unique_ptr frontend(new PPCFrontend(this)); // TODO(benvanik): set options/etc. - int result = Runtime::Initialize(frontend, backend); + int result = Runtime::Initialize(std::move(frontend), std::move(backend)); if (result) { return result; } diff --git a/src/xenia/cpu/xenon_runtime.h b/src/xenia/cpu/xenon_runtime.h index 067677720..3b6c219b7 100644 --- a/src/xenia/cpu/xenon_runtime.h +++ b/src/xenia/cpu/xenon_runtime.h @@ -31,7 +31,7 @@ public: ExportResolver* export_resolver() const { return export_resolver_; } - virtual int Initialize(alloy::backend::Backend* backend = 0); + virtual int Initialize(std::unique_ptr backend = 0); private: ExportResolver* export_resolver_; diff --git a/src/xenia/cpu/xex_module.cc b/src/xenia/cpu/xex_module.cc index 2ff90c16a..9c63f6292 100644 --- a/src/xenia/cpu/xex_module.cc +++ b/src/xenia/cpu/xex_module.cc @@ -29,18 +29,16 @@ void UndefinedImport(PPCContext* ppc_state, void* arg0, void* arg1) { XexModule::XexModule( XenonRuntime* runtime) : runtime_(runtime), - name_(0), path_(0), xex_(0), + xex_(0), base_address_(0), low_address_(0), high_address_(0), Module(runtime) { } XexModule::~XexModule() { xe_xex2_release(xex_); - xe_free(name_); - xe_free(path_); } -int XexModule::Load(const char* name, const char* path, xe_xex2_ref xex) { +int XexModule::Load(const std::string& name, const std::string& path, xe_xex2_ref xex) { int result; xex_ = xe_xex2_retain(xex); @@ -79,8 +77,8 @@ int XexModule::Load(const char* name, const char* path, xe_xex2_ref xex) { } // Setup debug info. - name_ = xestrdupa(name); - path_ = xestrdupa(path); + name_ = std::string(name); + path_ = std::string(path); // TODO(benvanik): debug info // Load a specified module map and diff. diff --git a/src/xenia/cpu/xex_module.h b/src/xenia/cpu/xex_module.h index 68b0b5676..6e973246b 100644 --- a/src/xenia/cpu/xex_module.h +++ b/src/xenia/cpu/xex_module.h @@ -10,6 +10,8 @@ #ifndef XENIA_CPU_XEX_MODULE_H_ #define XENIA_CPU_XEX_MODULE_H_ +#include + #include #include #include @@ -28,11 +30,11 @@ public: xe_xex2_ref xex() const { return xex_; } - int Load(const char* name, const char* path, xe_xex2_ref xex); + int Load(const std::string& name, const std::string& path, xe_xex2_ref xex); - virtual const char* name() const { return name_; } + const std::string& name() const override { return name_; } - virtual bool ContainsAddress(uint64_t address); + bool ContainsAddress(uint64_t address) override; private: int SetupImports(xe_xex2_ref xex); @@ -41,13 +43,13 @@ private: private: XenonRuntime* runtime_; - char* name_; - char* path_; - xe_xex2_ref xex_; + std::string name_; + std::string path_; + xe_xex2_ref xex_; - uint64_t base_address_; - uint64_t low_address_; - uint64_t high_address_; + uint64_t base_address_; + uint64_t low_address_; + uint64_t high_address_; }; diff --git a/tools/alloy-sandbox/alloy-sandbox.cc b/tools/alloy-sandbox/alloy-sandbox.cc index 324e8ea19..75ec323dc 100644 --- a/tools/alloy-sandbox/alloy-sandbox.cc +++ b/tools/alloy-sandbox/alloy-sandbox.cc @@ -8,6 +8,8 @@ */ #include +#include +#include #include #include #include @@ -31,12 +33,10 @@ int alloy_sandbox(int argc, xechar_t** argv) { ExportResolver* export_resolver = new ExportResolver(); XenonRuntime* runtime = new XenonRuntime(memory, export_resolver); - Backend* backend = 0; - // Backend* backend = new alloy::backend::interpreter::InterpreterBackend( - // runtime); - // Backend* backend = new alloy::backend::x64::X64Backend( - // runtime); - runtime->Initialize(backend); + std::unique_ptr backend; + // backend.reset(new alloy::backend::ivm::IVMBackend(runtime)); + // backend.reset(new alloy::backend::x64::X64Backend(runtime)); + runtime->Initialize(std::move(backend)); RawModule* module = new RawModule(runtime); module->LoadFile(0x82000000, "test\\codegen\\instr_add.bin"); From 29e4c35c387fbdc59f33e725306b5bcbeb10b9b7 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 13 Jul 2014 21:25:58 -0700 Subject: [PATCH 029/388] Removing alloy::tracing, as it's unused. --- src/alloy/alloy.h | 1 - src/alloy/backend/assembler.cc | 2 - src/alloy/backend/backend.cc | 2 - src/alloy/backend/ivm/ivm_assembler.cc | 7 +- src/alloy/backend/ivm/ivm_backend.cc | 5 +- src/alloy/backend/ivm/ivm_function.cc | 1 - src/alloy/backend/ivm/sources.gypi | 1 - src/alloy/backend/ivm/tracing.h | 50 ------------ src/alloy/backend/sources.gypi | 1 - src/alloy/backend/tracing.h | 32 -------- src/alloy/backend/x64/sources.gypi | 1 - src/alloy/backend/x64/tracing.h | 50 ------------ src/alloy/backend/x64/x64_assembler.cc | 5 -- src/alloy/backend/x64/x64_backend.cc | 8 +- src/alloy/backend/x64/x64_code_cache_win.cc | 2 - src/alloy/backend/x64/x64_function.cc | 3 +- src/alloy/compiler/compiler.cc | 5 -- src/alloy/compiler/sources.gypi | 1 - src/alloy/compiler/tracing.h | 39 --------- src/alloy/frontend/frontend.cc | 1 - src/alloy/frontend/ppc/ppc_frontend.cc | 5 -- src/alloy/frontend/ppc/ppc_hir_builder.cc | 1 - src/alloy/frontend/ppc/ppc_scanner.cc | 1 - src/alloy/frontend/ppc/ppc_translator.cc | 1 - src/alloy/frontend/sources.gypi | 1 - src/alloy/frontend/tracing.h | 39 --------- src/alloy/hir/sources.gypi | 1 - src/alloy/hir/tracing.h | 31 -------- src/alloy/runtime/runtime.cc | 7 +- src/alloy/runtime/sources.gypi | 1 - src/alloy/runtime/tracing.h | 88 --------------------- src/alloy/sources.gypi | 1 - src/alloy/tracing/channel.cc | 20 ----- src/alloy/tracing/channel.h | 31 -------- src/alloy/tracing/channels/file_channel.cc | 47 ----------- src/alloy/tracing/channels/file_channel.h | 43 ---------- src/alloy/tracing/channels/sources.gypi | 7 -- src/alloy/tracing/event_type.h | 43 ---------- src/alloy/tracing/sources.gypi | 16 ---- src/alloy/tracing/tracer.cc | 44 ----------- src/alloy/tracing/tracer.h | 39 --------- src/alloy/tracing/tracing.cc | 87 -------------------- src/alloy/tracing/tracing.h | 44 ----------- src/xenia/cpu/xenon_memory.cc | 32 -------- src/xenia/cpu/xenon_runtime.cc | 9 +-- src/xenia/cpu/xenon_thread_state.cc | 32 +++----- src/xenia/cpu/xex_module.cc | 1 - 47 files changed, 17 insertions(+), 872 deletions(-) delete mode 100644 src/alloy/backend/ivm/tracing.h delete mode 100644 src/alloy/backend/tracing.h delete mode 100644 src/alloy/backend/x64/tracing.h delete mode 100644 src/alloy/compiler/tracing.h delete mode 100644 src/alloy/frontend/tracing.h delete mode 100644 src/alloy/hir/tracing.h delete mode 100644 src/alloy/runtime/tracing.h delete mode 100644 src/alloy/tracing/channel.cc delete mode 100644 src/alloy/tracing/channel.h delete mode 100644 src/alloy/tracing/channels/file_channel.cc delete mode 100644 src/alloy/tracing/channels/file_channel.h delete mode 100644 src/alloy/tracing/channels/sources.gypi delete mode 100644 src/alloy/tracing/event_type.h delete mode 100644 src/alloy/tracing/sources.gypi delete mode 100644 src/alloy/tracing/tracer.cc delete mode 100644 src/alloy/tracing/tracer.h delete mode 100644 src/alloy/tracing/tracing.cc delete mode 100644 src/alloy/tracing/tracing.h diff --git a/src/alloy/alloy.h b/src/alloy/alloy.h index f35589381..2a72b6125 100644 --- a/src/alloy/alloy.h +++ b/src/alloy/alloy.h @@ -16,6 +16,5 @@ #include #include #include -#include #endif // ALLOY_ALLOY_H_ diff --git a/src/alloy/backend/assembler.cc b/src/alloy/backend/assembler.cc index 935118fc3..6d5737692 100644 --- a/src/alloy/backend/assembler.cc +++ b/src/alloy/backend/assembler.cc @@ -9,8 +9,6 @@ #include -#include - namespace alloy { namespace backend { diff --git a/src/alloy/backend/backend.cc b/src/alloy/backend/backend.cc index e28100522..3982caa1f 100644 --- a/src/alloy/backend/backend.cc +++ b/src/alloy/backend/backend.cc @@ -9,8 +9,6 @@ #include -#include - namespace alloy { namespace backend { diff --git a/src/alloy/backend/ivm/ivm_assembler.cc b/src/alloy/backend/ivm/ivm_assembler.cc index c26657d37..220d9063d 100644 --- a/src/alloy/backend/ivm/ivm_assembler.cc +++ b/src/alloy/backend/ivm/ivm_assembler.cc @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -28,9 +27,7 @@ using alloy::runtime::FunctionInfo; IVMAssembler::IVMAssembler(Backend* backend) : Assembler(backend), source_map_arena_(128 * 1024) {} -IVMAssembler::~IVMAssembler() { - alloy::tracing::WriteEvent(EventType::AssemblerDeinit({})); -} +IVMAssembler::~IVMAssembler() = default; int IVMAssembler::Initialize() { int result = Assembler::Initialize(); @@ -38,8 +35,6 @@ int IVMAssembler::Initialize() { return result; } - alloy::tracing::WriteEvent(EventType::AssemblerInit({})); - return result; } diff --git a/src/alloy/backend/ivm/ivm_backend.cc b/src/alloy/backend/ivm/ivm_backend.cc index 7f738142a..286d3b5a3 100644 --- a/src/alloy/backend/ivm/ivm_backend.cc +++ b/src/alloy/backend/ivm/ivm_backend.cc @@ -11,7 +11,6 @@ #include #include -#include namespace alloy { namespace backend { @@ -21,7 +20,7 @@ using alloy::runtime::Runtime; IVMBackend::IVMBackend(Runtime* runtime) : Backend(runtime) {} -IVMBackend::~IVMBackend() { alloy::tracing::WriteEvent(EventType::Deinit({})); } +IVMBackend::~IVMBackend() = default; int IVMBackend::Initialize() { int result = Backend::Initialize(); @@ -38,8 +37,6 @@ int IVMBackend::Initialize() { 16, }; - alloy::tracing::WriteEvent(EventType::Init({})); - return result; } diff --git a/src/alloy/backend/ivm/ivm_function.cc b/src/alloy/backend/ivm/ivm_function.cc index f0baf3b36..2dba04264 100644 --- a/src/alloy/backend/ivm/ivm_function.cc +++ b/src/alloy/backend/ivm/ivm_function.cc @@ -10,7 +10,6 @@ #include #include -#include #include #include diff --git a/src/alloy/backend/ivm/sources.gypi b/src/alloy/backend/ivm/sources.gypi index 3216510e2..c13431404 100644 --- a/src/alloy/backend/ivm/sources.gypi +++ b/src/alloy/backend/ivm/sources.gypi @@ -10,6 +10,5 @@ 'ivm_function.cc', 'ivm_stack.cc', 'ivm_stack.h', - 'tracing.h', ], } diff --git a/src/alloy/backend/ivm/tracing.h b/src/alloy/backend/ivm/tracing.h deleted file mode 100644 index bf48319ae..000000000 --- a/src/alloy/backend/ivm/tracing.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_BACKEND_IVM_TRACING_H_ -#define ALLOY_BACKEND_IVM_TRACING_H_ - -#include - -namespace alloy { -namespace backend { -namespace ivm { - -const uint32_t ALLOY_BACKEND_IVM = alloy::backend::EventType::ALLOY_BACKEND_IVM; - -class EventType { - public: - enum { - ALLOY_BACKEND_IVM_INIT = ALLOY_BACKEND_IVM | (1), - ALLOY_BACKEND_IVM_DEINIT = ALLOY_BACKEND_IVM | (2), - ALLOY_BACKEND_IVM_ASSEMBLER = ALLOY_BACKEND_IVM | (1 << 20), - ALLOY_BACKEND_IVM_ASSEMBLER_INIT = ALLOY_BACKEND_IVM_ASSEMBLER | (1), - ALLOY_BACKEND_IVM_ASSEMBLER_DEINIT = ALLOY_BACKEND_IVM_ASSEMBLER | (2), - }; - - typedef struct Init_s { - static const uint32_t event_type = ALLOY_BACKEND_IVM_INIT; - } Init; - typedef struct Deinit_s { - static const uint32_t event_type = ALLOY_BACKEND_IVM_DEINIT; - } Deinit; - - typedef struct AssemblerInit_s { - static const uint32_t event_type = ALLOY_BACKEND_IVM_ASSEMBLER_INIT; - } AssemblerInit; - typedef struct AssemblerDeinit_s { - static const uint32_t event_type = ALLOY_BACKEND_IVM_ASSEMBLER_DEINIT; - } AssemblerDeinit; -}; - -} // namespace ivm -} // namespace backend -} // namespace alloy - -#endif // ALLOY_BACKEND_IVM_TRACING_H_ diff --git a/src/alloy/backend/sources.gypi b/src/alloy/backend/sources.gypi index 41419ac7a..ec3be77a4 100644 --- a/src/alloy/backend/sources.gypi +++ b/src/alloy/backend/sources.gypi @@ -6,7 +6,6 @@ 'backend.cc', 'backend.h', 'machine_info.h', - 'tracing.h', ], 'includes': [ diff --git a/src/alloy/backend/tracing.h b/src/alloy/backend/tracing.h deleted file mode 100644 index a7a8c934c..000000000 --- a/src/alloy/backend/tracing.h +++ /dev/null @@ -1,32 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_BACKEND_TRACING_H_ -#define ALLOY_BACKEND_TRACING_H_ - -#include -#include - -namespace alloy { -namespace backend { - -const uint32_t ALLOY_BACKEND = alloy::tracing::EventType::ALLOY_BACKEND; - -class EventType { - public: - enum { - ALLOY_BACKEND_IVM = ALLOY_BACKEND | (1 << 24), - ALLOY_BACKEND_X64 = ALLOY_BACKEND | (2 << 24), - }; -}; - -} // namespace backend -} // namespace alloy - -#endif // ALLOY_BACKEND_TRACING_H_ diff --git a/src/alloy/backend/x64/sources.gypi b/src/alloy/backend/x64/sources.gypi index 02d8163b1..a3ade7eeb 100644 --- a/src/alloy/backend/x64/sources.gypi +++ b/src/alloy/backend/x64/sources.gypi @@ -1,7 +1,6 @@ # Copyright 2013 Ben Vanik. All Rights Reserved. { 'sources': [ - 'tracing.h', 'x64_assembler.cc', 'x64_assembler.h', 'x64_backend.cc', diff --git a/src/alloy/backend/x64/tracing.h b/src/alloy/backend/x64/tracing.h deleted file mode 100644 index 5045f93f5..000000000 --- a/src/alloy/backend/x64/tracing.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_BACKEND_X64_TRACING_H_ -#define ALLOY_BACKEND_X64_TRACING_H_ - -#include - -namespace alloy { -namespace backend { -namespace x64 { - -const uint32_t ALLOY_BACKEND_X64 = alloy::backend::EventType::ALLOY_BACKEND_X64; - -class EventType { - public: - enum { - ALLOY_BACKEND_X64_INIT = ALLOY_BACKEND_X64 | (1), - ALLOY_BACKEND_X64_DEINIT = ALLOY_BACKEND_X64 | (2), - ALLOY_BACKEND_X64_ASSEMBLER = ALLOY_BACKEND_X64 | (1 << 20), - ALLOY_BACKEND_X64_ASSEMBLER_INIT = ALLOY_BACKEND_X64_ASSEMBLER | (1), - ALLOY_BACKEND_X64_ASSEMBLER_DEINIT = ALLOY_BACKEND_X64_ASSEMBLER | (2), - }; - - typedef struct Init_s { - static const uint32_t event_type = ALLOY_BACKEND_X64_INIT; - } Init; - typedef struct Deinit_s { - static const uint32_t event_type = ALLOY_BACKEND_X64_DEINIT; - } Deinit; - - typedef struct AssemblerInit_s { - static const uint32_t event_type = ALLOY_BACKEND_X64_ASSEMBLER_INIT; - } AssemblerInit; - typedef struct AssemblerDeinit_s { - static const uint32_t event_type = ALLOY_BACKEND_X64_ASSEMBLER_DEINIT; - } AssemblerDeinit; -}; - -} // namespace x64 -} // namespace backend -} // namespace alloy - -#endif // ALLOY_BACKEND_X64_TRACING_H_ diff --git a/src/alloy/backend/x64/x64_assembler.cc b/src/alloy/backend/x64/x64_assembler.cc index 3f3e6e4fb..01b179774 100644 --- a/src/alloy/backend/x64/x64_assembler.cc +++ b/src/alloy/backend/x64/x64_assembler.cc @@ -9,7 +9,6 @@ #include -#include #include #include #include @@ -37,8 +36,6 @@ X64Assembler::X64Assembler(X64Backend* backend) : Assembler(backend), x64_backend_(backend), emitter_(0), allocator_(0) {} X64Assembler::~X64Assembler() { - alloy::tracing::WriteEvent(EventType::AssemblerDeinit({})); - delete emitter_; delete allocator_; } @@ -52,8 +49,6 @@ int X64Assembler::Initialize() { allocator_ = new XbyakAllocator(); emitter_ = new X64Emitter(x64_backend_, allocator_); - alloy::tracing::WriteEvent(EventType::AssemblerInit({})); - return result; } diff --git a/src/alloy/backend/x64/x64_backend.cc b/src/alloy/backend/x64/x64_backend.cc index e1bf31cbe..cca85ca59 100644 --- a/src/alloy/backend/x64/x64_backend.cc +++ b/src/alloy/backend/x64/x64_backend.cc @@ -9,7 +9,6 @@ #include -#include #include #include #include @@ -23,10 +22,7 @@ using alloy::runtime::Runtime; X64Backend::X64Backend(Runtime* runtime) : Backend(runtime), code_cache_(0) {} -X64Backend::~X64Backend() { - alloy::tracing::WriteEvent(EventType::Deinit({})); - delete code_cache_; -} +X64Backend::~X64Backend() { delete code_cache_; } int X64Backend::Initialize() { int result = Backend::Initialize(); @@ -58,8 +54,6 @@ int X64Backend::Initialize() { delete thunk_emitter; delete allocator; - alloy::tracing::WriteEvent(EventType::Init({})); - return result; } diff --git a/src/alloy/backend/x64/x64_code_cache_win.cc b/src/alloy/backend/x64/x64_code_cache_win.cc index f204c2200..b5355cc46 100644 --- a/src/alloy/backend/x64/x64_code_cache_win.cc +++ b/src/alloy/backend/x64/x64_code_cache_win.cc @@ -9,8 +9,6 @@ #include -#include - namespace alloy { namespace backend { namespace x64 { diff --git a/src/alloy/backend/x64/x64_function.cc b/src/alloy/backend/x64/x64_function.cc index 28b16ee1e..1b3cc9117 100644 --- a/src/alloy/backend/x64/x64_function.cc +++ b/src/alloy/backend/x64/x64_function.cc @@ -9,7 +9,6 @@ #include -#include #include #include #include @@ -24,7 +23,7 @@ using alloy::runtime::FunctionInfo; using alloy::runtime::ThreadState; X64Function::X64Function(FunctionInfo* symbol_info) - : Function(symbol_info), machine_code_(NULL), code_size_(0) {} + : Function(symbol_info), machine_code_(nullptr), code_size_(0) {} X64Function::~X64Function() { // machine_code_ is freed by code cache. diff --git a/src/alloy/compiler/compiler.cc b/src/alloy/compiler/compiler.cc index 2aff744db..ac86f3212 100644 --- a/src/alloy/compiler/compiler.cc +++ b/src/alloy/compiler/compiler.cc @@ -10,7 +10,6 @@ #include #include -#include namespace alloy { namespace compiler { @@ -20,8 +19,6 @@ using alloy::runtime::Runtime; Compiler::Compiler(Runtime* runtime) : runtime_(runtime) { scratch_arena_ = new Arena(); - - alloy::tracing::WriteEvent(EventType::Init({})); } Compiler::~Compiler() { @@ -33,8 +30,6 @@ Compiler::~Compiler() { } delete scratch_arena_; - - alloy::tracing::WriteEvent(EventType::Deinit({})); } void Compiler::AddPass(CompilerPass* pass) { diff --git a/src/alloy/compiler/sources.gypi b/src/alloy/compiler/sources.gypi index d32e7dac4..d9a7df71a 100644 --- a/src/alloy/compiler/sources.gypi +++ b/src/alloy/compiler/sources.gypi @@ -6,7 +6,6 @@ 'compiler_pass.cc', 'compiler_pass.h', 'compiler_passes.h', - 'tracing.h', ], 'includes': [ diff --git a/src/alloy/compiler/tracing.h b/src/alloy/compiler/tracing.h deleted file mode 100644 index 5763d6cb0..000000000 --- a/src/alloy/compiler/tracing.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_COMPILER_TRACING_H_ -#define ALLOY_COMPILER_TRACING_H_ - -#include -#include - -namespace alloy { -namespace compiler { - -const uint32_t ALLOY_COMPILER = alloy::tracing::EventType::ALLOY_COMPILER; - -class EventType { - public: - enum { - ALLOY_COMPILER_INIT = ALLOY_COMPILER | (1), - ALLOY_COMPILER_DEINIT = ALLOY_COMPILER | (2), - }; - - typedef struct Init_s { - static const uint32_t event_type = ALLOY_COMPILER_INIT; - } Init; - typedef struct Deinit_s { - static const uint32_t event_type = ALLOY_COMPILER_DEINIT; - } Deinit; -}; - -} // namespace compiler -} // namespace alloy - -#endif // ALLOY_COMPILER_TRACING_H_ diff --git a/src/alloy/frontend/frontend.cc b/src/alloy/frontend/frontend.cc index bd0651465..d97236d72 100644 --- a/src/alloy/frontend/frontend.cc +++ b/src/alloy/frontend/frontend.cc @@ -9,7 +9,6 @@ #include -#include #include namespace alloy { diff --git a/src/alloy/frontend/ppc/ppc_frontend.cc b/src/alloy/frontend/ppc/ppc_frontend.cc index f6970d5f5..a537efda9 100644 --- a/src/alloy/frontend/ppc/ppc_frontend.cc +++ b/src/alloy/frontend/ppc/ppc_frontend.cc @@ -9,7 +9,6 @@ #include -#include #include #include #include @@ -56,8 +55,6 @@ PPCFrontend::PPCFrontend(Runtime* runtime) : Frontend(runtime) { PPCFrontend::~PPCFrontend() { // Force cleanup now before we deinit. translator_pool_.Reset(); - - alloy::tracing::WriteEvent(EventType::Deinit({})); } int PPCFrontend::Initialize() { @@ -66,8 +63,6 @@ int PPCFrontend::Initialize() { return result; } - alloy::tracing::WriteEvent(EventType::Init({})); - return result; } diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index c0fc5c54c..38f72daab 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -10,7 +10,6 @@ #include #include -#include #include #include #include diff --git a/src/alloy/frontend/ppc/ppc_scanner.cc b/src/alloy/frontend/ppc/ppc_scanner.cc index ef180dfcf..4244ab65c 100644 --- a/src/alloy/frontend/ppc/ppc_scanner.cc +++ b/src/alloy/frontend/ppc/ppc_scanner.cc @@ -11,7 +11,6 @@ #include -#include #include #include #include diff --git a/src/alloy/frontend/ppc/ppc_translator.cc b/src/alloy/frontend/ppc/ppc_translator.cc index cf6e22dde..4a701c729 100644 --- a/src/alloy/frontend/ppc/ppc_translator.cc +++ b/src/alloy/frontend/ppc/ppc_translator.cc @@ -11,7 +11,6 @@ #include #include -#include #include #include #include diff --git a/src/alloy/frontend/sources.gypi b/src/alloy/frontend/sources.gypi index d0d63ab49..7635a2678 100644 --- a/src/alloy/frontend/sources.gypi +++ b/src/alloy/frontend/sources.gypi @@ -5,7 +5,6 @@ 'context_info.h', 'frontend.cc', 'frontend.h', - 'tracing.h', ], 'includes': [ diff --git a/src/alloy/frontend/tracing.h b/src/alloy/frontend/tracing.h deleted file mode 100644 index 66a445a4b..000000000 --- a/src/alloy/frontend/tracing.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_FRONTEND_TRACING_H_ -#define ALLOY_FRONTEND_TRACING_H_ - -#include -#include - -namespace alloy { -namespace frontend { - -const uint32_t ALLOY_FRONTEND = alloy::tracing::EventType::ALLOY_FRONTEND; - -class EventType { - public: - enum { - ALLOY_FRONTEND_INIT = ALLOY_FRONTEND | (1), - ALLOY_FRONTEND_DEINIT = ALLOY_FRONTEND | (2), - }; - - typedef struct Init_s { - static const uint32_t event_type = ALLOY_FRONTEND_INIT; - } Init; - typedef struct Deinit_s { - static const uint32_t event_type = ALLOY_FRONTEND_DEINIT; - } Deinit; -}; - -} // namespace frontend -} // namespace alloy - -#endif // ALLOY_FRONTEND_TRACING_H_ diff --git a/src/alloy/hir/sources.gypi b/src/alloy/hir/sources.gypi index 1ea2d7783..a0317ce2a 100644 --- a/src/alloy/hir/sources.gypi +++ b/src/alloy/hir/sources.gypi @@ -11,7 +11,6 @@ 'opcodes.cc', 'opcodes.h', 'opcodes.inl', - 'tracing.h', 'value.cc', 'value.h', ], diff --git a/src/alloy/hir/tracing.h b/src/alloy/hir/tracing.h deleted file mode 100644 index a0ad6bd89..000000000 --- a/src/alloy/hir/tracing.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_HIR_TRACING_H_ -#define ALLOY_HIR_TRACING_H_ - -#include -#include - -namespace alloy { -namespace hir { - -const uint32_t ALLOY_HIR = alloy::tracing::EventType::ALLOY_HIR; - -class EventType { - public: - enum { - ALLOY_HIR_FOO = ALLOY_HIR | (0), - }; -}; - -} // namespace hir -} // namespace alloy - -#endif // ALLOY_HIR_TRACING_H_ diff --git a/src/alloy/runtime/runtime.cc b/src/alloy/runtime/runtime.cc index 86fbbc319..955cf0d85 100644 --- a/src/alloy/runtime/runtime.cc +++ b/src/alloy/runtime/runtime.cc @@ -12,7 +12,6 @@ #include #include -#include // TODO(benvanik): based on compiler support #include @@ -26,9 +25,7 @@ namespace runtime { using alloy::backend::Backend; using alloy::frontend::Frontend; -Runtime::Runtime(Memory* memory) : memory_(memory) { - tracing::Initialize(); -} +Runtime::Runtime(Memory* memory) : memory_(memory) {} Runtime::~Runtime() { { @@ -43,8 +40,6 @@ Runtime::~Runtime() { debugger_.reset(); frontend_.reset(); backend_.reset(); - - tracing::Flush(); } int Runtime::Initialize(std::unique_ptr frontend, diff --git a/src/alloy/runtime/sources.gypi b/src/alloy/runtime/sources.gypi index 399580ec0..d1d7648b5 100644 --- a/src/alloy/runtime/sources.gypi +++ b/src/alloy/runtime/sources.gypi @@ -21,7 +21,6 @@ 'symbol_info.h', 'thread_state.cc', 'thread_state.h', - 'tracing.h', ], 'includes': [ diff --git a/src/alloy/runtime/tracing.h b/src/alloy/runtime/tracing.h deleted file mode 100644 index 1356208cb..000000000 --- a/src/alloy/runtime/tracing.h +++ /dev/null @@ -1,88 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_RUNTIME_TRACING_H_ -#define ALLOY_RUNTIME_TRACING_H_ - -#include -#include - -namespace alloy { -namespace runtime { - -const uint32_t ALLOY_RUNTIME = alloy::tracing::EventType::ALLOY_RUNTIME; - -class EventType { - public: - enum { - ALLOY_RUNTIME_INIT = ALLOY_RUNTIME | (1), - ALLOY_RUNTIME_DEINIT = ALLOY_RUNTIME | (2), - ALLOY_RUNTIME_THREAD = ALLOY_RUNTIME | (1 << 25), - ALLOY_RUNTIME_THREAD_INIT = ALLOY_RUNTIME_THREAD | (1), - ALLOY_RUNTIME_THREAD_DEINIT = ALLOY_RUNTIME_THREAD | (2), - ALLOY_RUNTIME_MEMORY = ALLOY_RUNTIME | (2 << 25), - ALLOY_RUNTIME_MEMORY_INIT = ALLOY_RUNTIME_MEMORY | (1), - ALLOY_RUNTIME_MEMORY_DEINIT = ALLOY_RUNTIME_MEMORY | (2), - ALLOY_RUNTIME_MEMORY_HEAP = ALLOY_RUNTIME_MEMORY | (1000), - ALLOY_RUNTIME_MEMORY_HEAP_INIT = ALLOY_RUNTIME_MEMORY_HEAP | (1), - ALLOY_RUNTIME_MEMORY_HEAP_DEINIT = ALLOY_RUNTIME_MEMORY | (2), - ALLOY_RUNTIME_MEMORY_HEAP_ALLOC = ALLOY_RUNTIME_MEMORY | (3), - ALLOY_RUNTIME_MEMORY_HEAP_FREE = ALLOY_RUNTIME_MEMORY | (4), - }; - - typedef struct Init_s { - static const uint32_t event_type = ALLOY_RUNTIME_INIT; - } Init; - typedef struct Deinit_s { - static const uint32_t event_type = ALLOY_RUNTIME_DEINIT; - } Deinit; - - typedef struct ThreadInit_s { - static const uint32_t event_type = ALLOY_RUNTIME_THREAD_INIT; - } ThreadInit; - typedef struct ThreadDeinit_s { - static const uint32_t event_type = ALLOY_RUNTIME_THREAD_DEINIT; - } ThreadDeinit; - - typedef struct MemoryInit_s { - static const uint32_t event_type = ALLOY_RUNTIME_MEMORY_INIT; - // map of memory, etc? - } MemoryInit; - typedef struct MemoryDeinit_s { - static const uint32_t event_type = ALLOY_RUNTIME_MEMORY_DEINIT; - } MemoryDeinit; - typedef struct MemoryHeapInit_s { - static const uint32_t event_type = ALLOY_RUNTIME_MEMORY_HEAP_INIT; - uint32_t heap_id; - uint64_t low_address; - uint64_t high_address; - uint32_t is_physical; - } MemoryHeapInit; - typedef struct MemoryHeapDeinit_s { - static const uint32_t event_type = ALLOY_RUNTIME_MEMORY_HEAP_DEINIT; - uint32_t heap_id; - } MemoryHeapDeinit; - typedef struct MemoryHeapAlloc_s { - static const uint32_t event_type = ALLOY_RUNTIME_MEMORY_HEAP_ALLOC; - uint32_t heap_id; - uint32_t flags; - uint64_t address; - size_t size; - } MemoryHeapAlloc; - typedef struct MemoryHeapFree_s { - static const uint32_t event_type = ALLOY_RUNTIME_MEMORY_HEAP_FREE; - uint32_t heap_id; - uint64_t address; - } MemoryHeapFree; -}; - -} // namespace runtime -} // namespace alloy - -#endif // ALLOY_RUNTIME_TRACING_H_ diff --git a/src/alloy/sources.gypi b/src/alloy/sources.gypi index 89bca0b1d..6e3d80e12 100644 --- a/src/alloy/sources.gypi +++ b/src/alloy/sources.gypi @@ -40,6 +40,5 @@ 'frontend/sources.gypi', 'hir/sources.gypi', 'runtime/sources.gypi', - 'tracing/sources.gypi', ], } diff --git a/src/alloy/tracing/channel.cc b/src/alloy/tracing/channel.cc deleted file mode 100644 index 46fca1f61..000000000 --- a/src/alloy/tracing/channel.cc +++ /dev/null @@ -1,20 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -namespace alloy { -namespace tracing { - -Channel::Channel() = default; - -Channel::~Channel() = default; - -} // namespace tracing -} // namespace alloy diff --git a/src/alloy/tracing/channel.h b/src/alloy/tracing/channel.h deleted file mode 100644 index 6d36ac00a..000000000 --- a/src/alloy/tracing/channel.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_TRACING_CHANNEL_H_ -#define ALLOY_TRACING_CHANNEL_H_ - -#include - -namespace alloy { -namespace tracing { - -class Channel { - public: - Channel(); - virtual ~Channel(); - - virtual void Write(size_t buffer_count, size_t buffer_lengths[], - const uint8_t* buffers[]) = 0; - virtual void Flush() = 0; -}; - -} // namespace tracing -} // namespace alloy - -#endif // ALLOY_TRACING_CHANNEL_H_ diff --git a/src/alloy/tracing/channels/file_channel.cc b/src/alloy/tracing/channels/file_channel.cc deleted file mode 100644 index 99bc8ba5e..000000000 --- a/src/alloy/tracing/channels/file_channel.cc +++ /dev/null @@ -1,47 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -namespace alloy { -namespace tracing { -namespace channels { - -FileChannel::FileChannel(const std::string& path) : path_(path) { - file_ = fopen(path_.c_str(), "wb"); -} - -FileChannel::~FileChannel() { - std::lock_guard guard(lock_); - if (file_) { - fclose(file_); - file_ = nullptr; - } -} - -void FileChannel::Write(size_t buffer_count, size_t buffer_lengths[], - const uint8_t* buffers[]) { - std::lock_guard guard(lock_); - if (file_) { - for (size_t n = 0; n < buffer_count; n++) { - fwrite(buffers[n], buffer_lengths[n], 1, file_); - } - } -} - -void FileChannel::Flush() { - std::lock_guard guard(lock_); - if (file_) { - fflush(file_); - } -} - -} // namespace channels -} // namespace tracing -} // namespace alloy diff --git a/src/alloy/tracing/channels/file_channel.h b/src/alloy/tracing/channels/file_channel.h deleted file mode 100644 index 0b7df668c..000000000 --- a/src/alloy/tracing/channels/file_channel.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_TRACING_CHANNELS_FILE_CHANNEL_H_ -#define ALLOY_TRACING_CHANNELS_FILE_CHANNEL_H_ - -#include - -#include - -#include - -namespace alloy { -namespace tracing { -namespace channels { - -class FileChannel : public Channel { - public: - FileChannel(const std::string& path); - ~FileChannel() override; - - void Write(size_t buffer_count, size_t buffer_lengths[], - const uint8_t* buffers[]) override; - - void Flush() override; - - private: - std::string path_; - FILE* file_; - std::mutex lock_; -}; - -} // namespace channels -} // namespace tracing -} // namespace alloy - -#endif // ALLOY_TRACING_CHANNELS_FILE_CHANNEL_H_ diff --git a/src/alloy/tracing/channels/sources.gypi b/src/alloy/tracing/channels/sources.gypi deleted file mode 100644 index cfba21262..000000000 --- a/src/alloy/tracing/channels/sources.gypi +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright 2013 Ben Vanik. All Rights Reserved. -{ - 'sources': [ - 'file_channel.cc', - 'file_channel.h', - ], -} diff --git a/src/alloy/tracing/event_type.h b/src/alloy/tracing/event_type.h deleted file mode 100644 index 3ad6a0d9c..000000000 --- a/src/alloy/tracing/event_type.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_TRACING_EVENT_TYPES_H_ -#define ALLOY_TRACING_EVENT_TYPES_H_ - -#include - -namespace alloy { -namespace tracing { - -class EventType { - public: - enum { - ALLOY = (0 << 31), - ALLOY_TRACE_INIT = ALLOY | (1), - ALLOY_TRACE_EOF = ALLOY | (2), - ALLOY_BACKEND = ALLOY | (1 << 26), - ALLOY_COMPILER = ALLOY | (2 << 26), - ALLOY_HIR = ALLOY | (3 << 26), - ALLOY_FRONTEND = ALLOY | (4 << 26), - ALLOY_RUNTIME = ALLOY | (5 << 26), - USER = (1 << 31), - }; - - typedef struct TraceInit_s { - static const uint32_t event_type = ALLOY_TRACE_INIT; - } TraceInit; - typedef struct TraceEOF_s { - static const uint32_t event_type = ALLOY_TRACE_EOF; - } TraceEOF; -}; - -} // namespace tracing -} // namespace alloy - -#endif // ALLOY_TRACING_EVENT_TYPES_H_ diff --git a/src/alloy/tracing/sources.gypi b/src/alloy/tracing/sources.gypi deleted file mode 100644 index 5b6cb1623..000000000 --- a/src/alloy/tracing/sources.gypi +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright 2013 Ben Vanik. All Rights Reserved. -{ - 'sources': [ - 'channel.cc', - 'channel.h', - 'event_type.h', - 'tracer.cc', - 'tracer.h', - 'tracing.cc', - 'tracing.h', - ], - - 'includes': [ - 'channels/sources.gypi', - ], -} diff --git a/src/alloy/tracing/tracer.cc b/src/alloy/tracing/tracer.cc deleted file mode 100644 index 3c4f3a157..000000000 --- a/src/alloy/tracing/tracer.cc +++ /dev/null @@ -1,44 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include - -#include - -namespace alloy { -namespace tracing { - -std::atomic next_thread_id_(0x10000000); - -Tracer::Tracer(Channel* channel) : channel_(channel) { - thread_id_ = ++next_thread_id_; -} - -Tracer::~Tracer() = default; - -void Tracer::WriteEvent(uint32_t event_type, size_t size, const uint8_t* data) { - uint32_t header[] = { - event_type, (uint32_t)thread_id_, - 0, // time in us - (uint32_t)size, - }; - size_t buffer_count = size ? 2 : 1; - size_t buffer_lengths[] = { - sizeof(header), size, - }; - const uint8_t* buffers[] = { - (const uint8_t*)header, data, - }; - channel_->Write(buffer_count, buffer_lengths, buffers); -} - -} // namespace tracing -} // namespace alloy diff --git a/src/alloy/tracing/tracer.h b/src/alloy/tracing/tracer.h deleted file mode 100644 index ba7faeab2..000000000 --- a/src/alloy/tracing/tracer.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_TRACING_TRACER_H_ -#define ALLOY_TRACING_TRACER_H_ - -#include - -namespace alloy { -namespace tracing { - -class Channel; - -class Tracer { - public: - Tracer(Channel* channel); - ~Tracer(); - - int thread_id() const { return thread_id_; } - void set_thread_id(int value) { thread_id_ = value; } - - void WriteEvent(uint32_t event_type, size_t size = 0, - const uint8_t* data = nullptr); - - private: - Channel* channel_; - int thread_id_; -}; - -} // namespace tracing -} // namespace alloy - -#endif // ALLOY_TRACING_TRACER_H_ diff --git a/src/alloy/tracing/tracing.cc b/src/alloy/tracing/tracing.cc deleted file mode 100644 index 7c7ffa2bd..000000000 --- a/src/alloy/tracing/tracing.cc +++ /dev/null @@ -1,87 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include -#include - -#include -#include -#include -#include - -DEFINE_string(trace_file, "", "Traces to the given file path."); -// trace shared memory -// trace socket - -namespace alloy { -namespace tracing { - -Channel* shared_channel = nullptr; -thread_local Tracer* thread_tracer = nullptr; - -void CleanupTracing() { - if (shared_channel) { - alloy::tracing::WriteEvent(EventType::TraceEOF({})); - shared_channel->Flush(); - shared_channel = nullptr; - } -} - -bool Initialize(Channel* channel) { - if (shared_channel) { - return false; - } - if (!channel) { - // Create from flags. - if (FLAGS_trace_file.size()) { - channel = new channels::FileChannel(FLAGS_trace_file.c_str()); - } - if (!channel) { - // Tracing disabled. - return true; - } - } - shared_channel = channel; - alloy::tracing::WriteEvent(EventType::TraceInit({})); - channel->Flush(); - atexit(CleanupTracing); - return true; -} - -void Shutdown() { - // ? -} - -void Flush() { - if (shared_channel) { - shared_channel->Flush(); - } -} - -Tracer* GetThreadTracer() { - if (!shared_channel) { - return nullptr; - } - if (!thread_tracer) { - thread_tracer = new Tracer(shared_channel); - } - return thread_tracer; -} - -void WriteEvent(uint32_t event_type, size_t size, const void* data) { - Tracer* t = GetThreadTracer(); - if (t) { - t->WriteEvent(event_type, size, (const uint8_t*)data); - } -} - -} // namespace tracing -} // namespace alloy diff --git a/src/alloy/tracing/tracing.h b/src/alloy/tracing/tracing.h deleted file mode 100644 index bcfe68a9d..000000000 --- a/src/alloy/tracing/tracing.h +++ /dev/null @@ -1,44 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_TRACING_TRACING_H_ -#define ALLOY_TRACING_TRACING_H_ - -#include - -#include - -namespace alloy { -namespace tracing { - -class Channel; -class Tracer; - -bool Initialize(Channel* channel = nullptr); -void Shutdown(); -void Flush(); - -Tracer* GetThreadTracer(); - -void WriteEvent(uint32_t event_type, size_t size = 0, - const void* data = nullptr); - -template -void WriteEvent(const T& ev) { - if (sizeof(T) > 1) { - alloy::tracing::WriteEvent(T::event_type, sizeof(T), &ev); - } else { - alloy::tracing::WriteEvent(T::event_type); - } -} - -} // namespace tracing -} // namespace alloy - -#endif // ALLOY_TRACING_TRACING_H_ diff --git a/src/xenia/cpu/xenon_memory.cc b/src/xenia/cpu/xenon_memory.cc index 2993f4850..d7ad0d751 100644 --- a/src/xenia/cpu/xenon_memory.cc +++ b/src/xenia/cpu/xenon_memory.cc @@ -11,12 +11,9 @@ #include -#include - #include using namespace alloy; -using namespace alloy::runtime; using namespace xe::cpu; // TODO(benvanik): move xbox.h out @@ -267,9 +264,6 @@ XenonMemory::~XenonMemory() { CloseHandle(mapping_); mapping_base_ = 0; mapping_ = 0; - - alloy::tracing::WriteEvent(EventType::MemoryDeinit({ - })); } } @@ -311,9 +305,6 @@ int XenonMemory::Initialize() { } membase_ = mapping_base_; - alloy::tracing::WriteEvent(EventType::MemoryInit({ - })); - // Prepare heaps. virtual_heap_->Initialize( XENON_MEMORY_VIRTUAL_HEAP_LOW, XENON_MEMORY_VIRTUAL_HEAP_HIGH); @@ -542,10 +533,6 @@ uint64_t XenonMemory::HeapAlloc( xe_zero_struct(pv, size); } - alloy::tracing::WriteEvent(EventType::MemoryHeapAlloc({ - 0, flags, base_address, size, - })); - return base_address; } } @@ -559,9 +546,6 @@ int XenonMemory::HeapFree(uint64_t address, size_t size) { return physical_heap_->Free(address, size) ? 0 : 1; } else { // A placed address. Decommit. - alloy::tracing::WriteEvent(EventType::MemoryHeapFree({ - 0, address, - })); uint8_t* p = Translate(address); return VirtualFree(p, size, MEM_DECOMMIT) ? 0 : 1; } @@ -628,10 +612,6 @@ XenonMemoryHeap::~XenonMemoryHeap() { if (ptr_) { XEIGNORE(VirtualFree(ptr_, 0, MEM_RELEASE)); - - alloy::tracing::WriteEvent(EventType::MemoryHeapDeinit({ - heap_id_, - })); } } @@ -648,10 +628,6 @@ int XenonMemoryHeap::Initialize(uint64_t low, uint64_t high) { } space_ = create_mspace_with_base(ptr_, size_, 0); - alloy::tracing::WriteEvent(EventType::MemoryHeapInit({ - heap_id_, low, high, is_physical_, - })); - return 0; } @@ -719,10 +695,6 @@ uint64_t XenonMemoryHeap::Alloc( uint64_t address = (uint64_t)((uintptr_t)p - (uintptr_t)memory_->mapping_base_); - alloy::tracing::WriteEvent(EventType::MemoryHeapAlloc({ - heap_id_, flags, address, size, - })); - return address; } @@ -775,10 +747,6 @@ uint64_t XenonMemoryHeap::Free(uint64_t address, size_t size) { MEM_DECOMMIT); } - alloy::tracing::WriteEvent(EventType::MemoryHeapFree({ - heap_id_, address, - })); - return (uint64_t)real_size; } diff --git a/src/xenia/cpu/xenon_runtime.cc b/src/xenia/cpu/xenon_runtime.cc index 9caa0841e..46fe20d5f 100644 --- a/src/xenia/cpu/xenon_runtime.cc +++ b/src/xenia/cpu/xenon_runtime.cc @@ -10,7 +10,6 @@ #include #include -#include #include @@ -27,10 +26,7 @@ XenonRuntime::XenonRuntime( export_resolver_(export_resolver) { } -XenonRuntime::~XenonRuntime() { - alloy::tracing::WriteEvent(EventType::Deinit({ - })); -} +XenonRuntime::~XenonRuntime() = default; int XenonRuntime::Initialize(std::unique_ptr backend) { std::unique_ptr frontend(new PPCFrontend(this)); @@ -41,8 +37,5 @@ int XenonRuntime::Initialize(std::unique_ptr backend) { return result; } - alloy::tracing::WriteEvent(EventType::Init({ - })); - return result; } diff --git a/src/xenia/cpu/xenon_thread_state.cc b/src/xenia/cpu/xenon_thread_state.cc index b00a75355..9b09c5608 100644 --- a/src/xenia/cpu/xenon_thread_state.cc +++ b/src/xenia/cpu/xenon_thread_state.cc @@ -9,8 +9,6 @@ #include -#include - #include using namespace alloy; @@ -19,15 +17,13 @@ using namespace alloy::frontend::ppc; using namespace alloy::runtime; using namespace xe::cpu; - -XenonThreadState::XenonThreadState( - XenonRuntime* runtime, uint32_t thread_id, - size_t stack_size, uint64_t thread_state_address) : - ThreadState(runtime, thread_id), - stack_size_(stack_size), - thread_state_address_(thread_state_address) { - stack_address_ = memory_->HeapAlloc( - 0, stack_size, MEMORY_FLAG_ZERO); +XenonThreadState::XenonThreadState(XenonRuntime* runtime, uint32_t thread_id, + size_t stack_size, + uint64_t thread_state_address) + : ThreadState(runtime, thread_id), + stack_size_(stack_size), + thread_state_address_(thread_state_address) { + stack_address_ = memory_->HeapAlloc(0, stack_size, MEMORY_FLAG_ZERO); // Allocate with 64b alignment. context_ = (PPCContext*)xe_malloc_aligned(sizeof(PPCContext)); @@ -36,12 +32,12 @@ XenonThreadState::XenonThreadState( // Stash pointers to common structures that callbacks may need. context_->reserve_address = memory_->reserve_address(); - context_->membase = memory_->membase(); - context_->runtime = runtime; - context_->thread_state = this; + context_->membase = memory_->membase(); + context_->runtime = runtime; + context_->thread_state = this; // Set initial registers. - context_->r[1] = stack_address_ + stack_size; + context_->r[1] = stack_address_ + stack_size; context_->r[13] = thread_state_address_; // Pad out stack a bit, as some games seem to overwrite the caller by about @@ -50,18 +46,12 @@ XenonThreadState::XenonThreadState( raw_context_ = context_; - alloy::tracing::WriteEvent(EventType::ThreadInit({ - })); - runtime_->debugger()->OnThreadCreated(this); } XenonThreadState::~XenonThreadState() { runtime_->debugger()->OnThreadDestroyed(this); - alloy::tracing::WriteEvent(EventType::ThreadDeinit({ - })); - xe_free_aligned(context_); memory_->HeapFree(stack_address_, stack_size_); } diff --git a/src/xenia/cpu/xex_module.cc b/src/xenia/cpu/xex_module.cc index 9c63f6292..df019e5ae 100644 --- a/src/xenia/cpu/xex_module.cc +++ b/src/xenia/cpu/xex_module.cc @@ -9,7 +9,6 @@ #include -#include #include #include #include From 0a250d5e916025b3235d9ce968b106858b4432f1 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 13 Jul 2014 21:53:31 -0700 Subject: [PATCH 030/388] C++11ing some things. --- src/alloy/backend/backend.cc | 6 +-- src/alloy/compiler/compiler.cc | 24 +++--------- src/alloy/compiler/compiler.h | 12 +++--- src/alloy/compiler/compiler_pass.cc | 2 +- .../passes/constant_propagation_pass.h | 4 +- .../compiler/passes/context_promotion_pass.h | 6 +-- .../passes/control_flow_analysis_pass.h | 4 +- .../compiler/passes/data_flow_analysis_pass.h | 4 +- .../passes/dead_code_elimination_pass.h | 4 +- src/alloy/compiler/passes/finalization_pass.h | 4 +- .../passes/register_allocation_pass.h | 4 +- .../compiler/passes/simplification_pass.h | 4 +- src/alloy/compiler/passes/validation_pass.h | 4 +- .../compiler/passes/value_reduction_pass.h | 4 +- src/alloy/frontend/frontend.cc | 5 +-- src/alloy/frontend/frontend.h | 6 ++- src/alloy/frontend/ppc/ppc_frontend.cc | 6 +-- src/alloy/frontend/ppc/ppc_translator.cc | 37 ++++++++++--------- src/alloy/runtime/debugger.h | 6 +-- src/alloy/runtime/entry_table.cc | 6 +-- src/alloy/runtime/entry_table.h | 3 +- src/alloy/runtime/module.cc | 24 ++++-------- src/alloy/runtime/module.h | 6 +-- src/alloy/runtime/runtime.cc | 32 +++++++--------- src/alloy/runtime/runtime.h | 10 ++--- src/alloy/runtime/symbol_info.h | 6 +-- src/xenia/kernel/objects/xuser_module.cc | 19 +++++----- tools/alloy-sandbox/alloy-sandbox.cc | 4 +- 28 files changed, 113 insertions(+), 143 deletions(-) diff --git a/src/alloy/backend/backend.cc b/src/alloy/backend/backend.cc index 3982caa1f..d66283c82 100644 --- a/src/alloy/backend/backend.cc +++ b/src/alloy/backend/backend.cc @@ -15,14 +15,14 @@ namespace backend { using alloy::runtime::Runtime; Backend::Backend(Runtime* runtime) : runtime_(runtime) { - xe_zero_struct(&machine_info_, sizeof(machine_info_)); + memset(&machine_info_, 0, sizeof(machine_info_)); } -Backend::~Backend() {} +Backend::~Backend() = default; int Backend::Initialize() { return 0; } -void* Backend::AllocThreadData() { return NULL; } +void* Backend::AllocThreadData() { return nullptr; } void Backend::FreeThreadData(void* thread_data) {} diff --git a/src/alloy/compiler/compiler.cc b/src/alloy/compiler/compiler.cc index ac86f3212..2ad7ca527 100644 --- a/src/alloy/compiler/compiler.cc +++ b/src/alloy/compiler/compiler.cc @@ -17,24 +17,13 @@ namespace compiler { using alloy::hir::HIRBuilder; using alloy::runtime::Runtime; -Compiler::Compiler(Runtime* runtime) : runtime_(runtime) { - scratch_arena_ = new Arena(); -} +Compiler::Compiler(Runtime* runtime) : runtime_(runtime) {} -Compiler::~Compiler() { - Reset(); +Compiler::~Compiler() { Reset(); } - for (auto it = passes_.begin(); it != passes_.end(); ++it) { - CompilerPass* pass = *it; - delete pass; - } - - delete scratch_arena_; -} - -void Compiler::AddPass(CompilerPass* pass) { +void Compiler::AddPass(std::unique_ptr pass) { pass->Initialize(this); - passes_.push_back(pass); + passes_.push_back(std::move(pass)); } void Compiler::Reset() {} @@ -44,9 +33,8 @@ int Compiler::Compile(HIRBuilder* builder) { // TODO(benvanik): sophisticated stuff. Run passes in parallel, run until they // stop changing things, etc. - for (auto it = passes_.begin(); it != passes_.end(); ++it) { - CompilerPass* pass = *it; - scratch_arena_->Reset(); + for (auto& pass : passes_) { + scratch_arena_.Reset(); if (pass->Run(builder)) { return 1; } diff --git a/src/alloy/compiler/compiler.h b/src/alloy/compiler/compiler.h index 82c13890b..ed592bdb8 100644 --- a/src/alloy/compiler/compiler.h +++ b/src/alloy/compiler/compiler.h @@ -10,6 +10,9 @@ #ifndef ALLOY_COMPILER_COMPILER_H_ #define ALLOY_COMPILER_COMPILER_H_ +#include +#include + #include #include @@ -30,9 +33,9 @@ class Compiler { ~Compiler(); runtime::Runtime* runtime() const { return runtime_; } - Arena* scratch_arena() const { return scratch_arena_; } + Arena* scratch_arena() { return &scratch_arena_; } - void AddPass(CompilerPass* pass); + void AddPass(std::unique_ptr pass); void Reset(); @@ -40,10 +43,9 @@ class Compiler { private: runtime::Runtime* runtime_; - Arena* scratch_arena_; + Arena scratch_arena_; - typedef std::vector PassList; - PassList passes_; + std::vector> passes_; }; } // namespace compiler diff --git a/src/alloy/compiler/compiler_pass.cc b/src/alloy/compiler/compiler_pass.cc index 2c3e84afc..67ac1700f 100644 --- a/src/alloy/compiler/compiler_pass.cc +++ b/src/alloy/compiler/compiler_pass.cc @@ -16,7 +16,7 @@ namespace compiler { CompilerPass::CompilerPass() : runtime_(0), compiler_(0) {} -CompilerPass::~CompilerPass() {} +CompilerPass::~CompilerPass() = default; int CompilerPass::Initialize(Compiler* compiler) { runtime_ = compiler->runtime(); diff --git a/src/alloy/compiler/passes/constant_propagation_pass.h b/src/alloy/compiler/passes/constant_propagation_pass.h index cdc7f1353..ff7241e3e 100644 --- a/src/alloy/compiler/passes/constant_propagation_pass.h +++ b/src/alloy/compiler/passes/constant_propagation_pass.h @@ -19,9 +19,9 @@ namespace passes { class ConstantPropagationPass : public CompilerPass { public: ConstantPropagationPass(); - virtual ~ConstantPropagationPass(); + ~ConstantPropagationPass() override; - virtual int Run(hir::HIRBuilder* builder); + int Run(hir::HIRBuilder* builder) override; private: void PropagateCarry(hir::Value* v, bool did_carry); diff --git a/src/alloy/compiler/passes/context_promotion_pass.h b/src/alloy/compiler/passes/context_promotion_pass.h index 925f0bb32..a9b8bc95b 100644 --- a/src/alloy/compiler/passes/context_promotion_pass.h +++ b/src/alloy/compiler/passes/context_promotion_pass.h @@ -19,11 +19,11 @@ namespace passes { class ContextPromotionPass : public CompilerPass { public: ContextPromotionPass(); - virtual ~ContextPromotionPass(); + virtual ~ContextPromotionPass() override; - virtual int Initialize(Compiler* compiler); + int Initialize(Compiler* compiler) override; - virtual int Run(hir::HIRBuilder* builder); + int Run(hir::HIRBuilder* builder) override; private: void PromoteBlock(hir::Block* block); diff --git a/src/alloy/compiler/passes/control_flow_analysis_pass.h b/src/alloy/compiler/passes/control_flow_analysis_pass.h index 35ce33fba..bcde6cd5a 100644 --- a/src/alloy/compiler/passes/control_flow_analysis_pass.h +++ b/src/alloy/compiler/passes/control_flow_analysis_pass.h @@ -19,9 +19,9 @@ namespace passes { class ControlFlowAnalysisPass : public CompilerPass { public: ControlFlowAnalysisPass(); - virtual ~ControlFlowAnalysisPass(); + ~ControlFlowAnalysisPass() override; - virtual int Run(hir::HIRBuilder* builder); + int Run(hir::HIRBuilder* builder) override; private: }; diff --git a/src/alloy/compiler/passes/data_flow_analysis_pass.h b/src/alloy/compiler/passes/data_flow_analysis_pass.h index d19dc6e1c..f3990b2ec 100644 --- a/src/alloy/compiler/passes/data_flow_analysis_pass.h +++ b/src/alloy/compiler/passes/data_flow_analysis_pass.h @@ -21,9 +21,9 @@ namespace passes { class DataFlowAnalysisPass : public CompilerPass { public: DataFlowAnalysisPass(); - virtual ~DataFlowAnalysisPass(); + ~DataFlowAnalysisPass() override; - virtual int Run(hir::HIRBuilder* builder); + int Run(hir::HIRBuilder* builder) override; private: uint32_t LinearizeBlocks(hir::HIRBuilder* builder); diff --git a/src/alloy/compiler/passes/dead_code_elimination_pass.h b/src/alloy/compiler/passes/dead_code_elimination_pass.h index 9c3100f8c..14d8667df 100644 --- a/src/alloy/compiler/passes/dead_code_elimination_pass.h +++ b/src/alloy/compiler/passes/dead_code_elimination_pass.h @@ -21,9 +21,9 @@ namespace passes { class DeadCodeEliminationPass : public CompilerPass { public: DeadCodeEliminationPass(); - virtual ~DeadCodeEliminationPass(); + ~DeadCodeEliminationPass() override; - virtual int Run(hir::HIRBuilder* builder); + int Run(hir::HIRBuilder* builder) override; private: void MakeNopRecursive(hir::Instr* i); diff --git a/src/alloy/compiler/passes/finalization_pass.h b/src/alloy/compiler/passes/finalization_pass.h index 30cec0d3c..cf951f706 100644 --- a/src/alloy/compiler/passes/finalization_pass.h +++ b/src/alloy/compiler/passes/finalization_pass.h @@ -19,9 +19,9 @@ namespace passes { class FinalizationPass : public CompilerPass { public: FinalizationPass(); - virtual ~FinalizationPass(); + ~FinalizationPass() override; - virtual int Run(hir::HIRBuilder* builder); + int Run(hir::HIRBuilder* builder) override; private: }; diff --git a/src/alloy/compiler/passes/register_allocation_pass.h b/src/alloy/compiler/passes/register_allocation_pass.h index 70f212c08..aa8b03fb2 100644 --- a/src/alloy/compiler/passes/register_allocation_pass.h +++ b/src/alloy/compiler/passes/register_allocation_pass.h @@ -24,9 +24,9 @@ namespace passes { class RegisterAllocationPass : public CompilerPass { public: RegisterAllocationPass(const backend::MachineInfo* machine_info); - virtual ~RegisterAllocationPass(); + ~RegisterAllocationPass() override; - virtual int Run(hir::HIRBuilder* builder); + int Run(hir::HIRBuilder* builder) override; private: // TODO(benvanik): rewrite all this set shit -- too much indirection, the diff --git a/src/alloy/compiler/passes/simplification_pass.h b/src/alloy/compiler/passes/simplification_pass.h index 6806d48c7..328e200a9 100644 --- a/src/alloy/compiler/passes/simplification_pass.h +++ b/src/alloy/compiler/passes/simplification_pass.h @@ -19,9 +19,9 @@ namespace passes { class SimplificationPass : public CompilerPass { public: SimplificationPass(); - virtual ~SimplificationPass(); + ~SimplificationPass() override; - virtual int Run(hir::HIRBuilder* builder); + int Run(hir::HIRBuilder* builder) override; private: void EliminateConversions(hir::HIRBuilder* builder); diff --git a/src/alloy/compiler/passes/validation_pass.h b/src/alloy/compiler/passes/validation_pass.h index 47c474887..133187d6f 100644 --- a/src/alloy/compiler/passes/validation_pass.h +++ b/src/alloy/compiler/passes/validation_pass.h @@ -19,9 +19,9 @@ namespace passes { class ValidationPass : public CompilerPass { public: ValidationPass(); - virtual ~ValidationPass(); + ~ValidationPass() override; - virtual int Run(hir::HIRBuilder* builder); + int Run(hir::HIRBuilder* builder) override; private: int ValidateInstruction(hir::Block* block, hir::Instr* instr); diff --git a/src/alloy/compiler/passes/value_reduction_pass.h b/src/alloy/compiler/passes/value_reduction_pass.h index 95a9eaac0..b2ea00bb7 100644 --- a/src/alloy/compiler/passes/value_reduction_pass.h +++ b/src/alloy/compiler/passes/value_reduction_pass.h @@ -19,9 +19,9 @@ namespace passes { class ValueReductionPass : public CompilerPass { public: ValueReductionPass(); - virtual ~ValueReductionPass(); + ~ValueReductionPass() override; - virtual int Run(hir::HIRBuilder* builder); + int Run(hir::HIRBuilder* builder) override; private: void ComputeLastUse(hir::Value* value); diff --git a/src/alloy/frontend/frontend.cc b/src/alloy/frontend/frontend.cc index d97236d72..a9da0bfd7 100644 --- a/src/alloy/frontend/frontend.cc +++ b/src/alloy/frontend/frontend.cc @@ -14,10 +14,9 @@ namespace alloy { namespace frontend { -Frontend::Frontend(runtime::Runtime* runtime) - : runtime_(runtime), context_info_(0) {} +Frontend::Frontend(runtime::Runtime* runtime) : runtime_(runtime) {} -Frontend::~Frontend() { delete context_info_; } +Frontend::~Frontend() = default; Memory* Frontend::memory() const { return runtime_->memory(); } diff --git a/src/alloy/frontend/frontend.h b/src/alloy/frontend/frontend.h index 33662ea3e..ec43bee3d 100644 --- a/src/alloy/frontend/frontend.h +++ b/src/alloy/frontend/frontend.h @@ -10,6 +10,8 @@ #ifndef ALLOY_FRONTEND_FRONTEND_H_ #define ALLOY_FRONTEND_FRONTEND_H_ +#include + #include #include #include @@ -32,7 +34,7 @@ class Frontend { runtime::Runtime* runtime() const { return runtime_; } Memory* memory() const; - ContextInfo* context_info() const { return context_info_; } + ContextInfo* context_info() const { return context_info_.get(); } virtual int Initialize(); @@ -43,7 +45,7 @@ class Frontend { protected: runtime::Runtime* runtime_; - ContextInfo* context_info_; + std::unique_ptr context_info_; }; } // namespace frontend diff --git a/src/alloy/frontend/ppc/ppc_frontend.cc b/src/alloy/frontend/ppc/ppc_frontend.cc index a537efda9..33451e21f 100644 --- a/src/alloy/frontend/ppc/ppc_frontend.cc +++ b/src/alloy/frontend/ppc/ppc_frontend.cc @@ -46,10 +46,10 @@ void CleanupOnShutdown() {} PPCFrontend::PPCFrontend(Runtime* runtime) : Frontend(runtime) { InitializeIfNeeded(); - ContextInfo* info = - new ContextInfo(sizeof(PPCContext), offsetof(PPCContext, thread_state)); + std::unique_ptr context_info( + new ContextInfo(sizeof(PPCContext), offsetof(PPCContext, thread_state))); // Add fields/etc. - context_info_ = info; + context_info_ = std::move(context_info); } PPCFrontend::~PPCFrontend() { diff --git a/src/alloy/frontend/ppc/ppc_translator.cc b/src/alloy/frontend/ppc/ppc_translator.cc index 4a701c729..d93b9bd16 100644 --- a/src/alloy/frontend/ppc/ppc_translator.cc +++ b/src/alloy/frontend/ppc/ppc_translator.cc @@ -43,23 +43,24 @@ PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) { bool validate = FLAGS_validate_hir; // Build the CFG first. - compiler_->AddPass(new passes::ControlFlowAnalysisPass()); + compiler_->AddPass(std::make_unique()); // Passes are executed in the order they are added. Multiple of the same // pass type may be used. - if (validate) compiler_->AddPass(new passes::ValidationPass()); - compiler_->AddPass(new passes::ContextPromotionPass()); - if (validate) compiler_->AddPass(new passes::ValidationPass()); - compiler_->AddPass(new passes::SimplificationPass()); - if (validate) compiler_->AddPass(new passes::ValidationPass()); - compiler_->AddPass(new passes::ConstantPropagationPass()); - if (validate) compiler_->AddPass(new passes::ValidationPass()); - compiler_->AddPass(new passes::SimplificationPass()); - if (validate) compiler_->AddPass(new passes::ValidationPass()); - // compiler_->AddPass(new passes::DeadStoreEliminationPass()); - // if (validate) compiler_->AddPass(new passes::ValidationPass()); - compiler_->AddPass(new passes::DeadCodeEliminationPass()); - if (validate) compiler_->AddPass(new passes::ValidationPass()); + if (validate) compiler_->AddPass(std::make_unique()); + compiler_->AddPass(std::make_unique()); + if (validate) compiler_->AddPass(std::make_unique()); + compiler_->AddPass(std::make_unique()); + if (validate) compiler_->AddPass(std::make_unique()); + compiler_->AddPass(std::make_unique()); + if (validate) compiler_->AddPass(std::make_unique()); + compiler_->AddPass(std::make_unique()); + if (validate) compiler_->AddPass(std::make_unique()); + // compiler_->AddPass(std::make_unique()); + // if (validate) + // compiler_->AddPass(std::make_unique()); + compiler_->AddPass(std::make_unique()); + if (validate) compiler_->AddPass(std::make_unique()); //// Removes all unneeded variables. Try not to add new ones after this. // compiler_->AddPass(new passes::ValueReductionPass()); @@ -69,12 +70,12 @@ PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) { // Will modify the HIR to add loads/stores. // This should be the last pass before finalization, as after this all // registers are assigned and ready to be emitted. - compiler_->AddPass( - new passes::RegisterAllocationPass(backend->machine_info())); - if (validate) compiler_->AddPass(new passes::ValidationPass()); + compiler_->AddPass(std::make_unique( + backend->machine_info())); + if (validate) compiler_->AddPass(std::make_unique()); // Must come last. The HIR is not really HIR after this. - compiler_->AddPass(new passes::FinalizationPass()); + compiler_->AddPass(std::make_unique()); } PPCTranslator::~PPCTranslator() { diff --git a/src/alloy/runtime/debugger.h b/src/alloy/runtime/debugger.h index fcac741d8..1b09f3ab3 100644 --- a/src/alloy/runtime/debugger.h +++ b/src/alloy/runtime/debugger.h @@ -107,12 +107,10 @@ class Debugger { Runtime* runtime_; std::mutex threads_lock_; - typedef std::unordered_map ThreadMap; - ThreadMap threads_; + std::unordered_map threads_; std::mutex breakpoints_lock_; - typedef std::multimap BreakpointMultimap; - BreakpointMultimap breakpoints_; + std::multimap breakpoints_; }; } // namespace runtime diff --git a/src/alloy/runtime/entry_table.cc b/src/alloy/runtime/entry_table.cc index df1a6f89b..aa0a41cbb 100644 --- a/src/alloy/runtime/entry_table.cc +++ b/src/alloy/runtime/entry_table.cc @@ -16,7 +16,7 @@ EntryTable::EntryTable() = default; EntryTable::~EntryTable() { std::lock_guard guard(lock_); - EntryMap::iterator it = map_.begin(); + auto& it = map_.begin(); for (; it != map_.end(); ++it) { Entry* entry = it->second; delete entry; @@ -25,7 +25,7 @@ EntryTable::~EntryTable() { Entry* EntryTable::Get(uint64_t address) { std::lock_guard guard(lock_); - EntryMap::const_iterator it = map_.find(address); + const auto& it = map_.find(address); Entry* entry = it != map_.end() ? it->second : nullptr; if (entry) { // TODO(benvanik): wait if needed? @@ -38,7 +38,7 @@ Entry* EntryTable::Get(uint64_t address) { Entry::Status EntryTable::GetOrCreate(uint64_t address, Entry** out_entry) { lock_.lock(); - EntryMap::const_iterator it = map_.find(address); + const auto& it = map_.find(address); Entry* entry = it != map_.end() ? it->second : nullptr; Entry::Status status; if (entry) { diff --git a/src/alloy/runtime/entry_table.h b/src/alloy/runtime/entry_table.h index 0470c7b27..d2a0fa225 100644 --- a/src/alloy/runtime/entry_table.h +++ b/src/alloy/runtime/entry_table.h @@ -47,8 +47,7 @@ class EntryTable { private: // TODO(benvanik): replace with a better data structure. std::mutex lock_; - typedef std::unordered_map EntryMap; - EntryMap map_; + std::unordered_map map_; }; } // namespace runtime diff --git a/src/alloy/runtime/module.cc b/src/alloy/runtime/module.cc index ff640088b..bf953bf1e 100644 --- a/src/alloy/runtime/module.cc +++ b/src/alloy/runtime/module.cc @@ -20,20 +20,13 @@ namespace runtime { Module::Module(Runtime* runtime) : runtime_(runtime), memory_(runtime->memory()) {} -Module::~Module() { - std::lock_guard guard(lock_); - SymbolMap::iterator it = map_.begin(); - for (; it != map_.end(); ++it) { - SymbolInfo* symbol_info = it->second; - delete symbol_info; - } -} +Module::~Module() = default; bool Module::ContainsAddress(uint64_t address) { return true; } SymbolInfo* Module::LookupSymbol(uint64_t address, bool wait) { lock_.lock(); - SymbolMap::const_iterator it = map_.find(address); + const auto it = map_.find(address); SymbolInfo* symbol_info = it != map_.end() ? it->second : nullptr; if (symbol_info) { if (symbol_info->status() == SymbolInfo::STATUS_DECLARING) { @@ -60,7 +53,7 @@ SymbolInfo::Status Module::DeclareSymbol(SymbolInfo::Type type, SymbolInfo** out_symbol_info) { *out_symbol_info = nullptr; lock_.lock(); - SymbolMap::const_iterator it = map_.find(address); + auto it = map_.find(address); SymbolInfo* symbol_info = it != map_.end() ? it->second : nullptr; SymbolInfo::Status status; if (symbol_info) { @@ -91,7 +84,7 @@ SymbolInfo::Status Module::DeclareSymbol(SymbolInfo::Type type, break; } map_[address] = symbol_info; - list_.push_back(symbol_info); + list_.emplace_back(symbol_info); status = SymbolInfo::STATUS_NEW; } lock_.unlock(); @@ -157,10 +150,9 @@ SymbolInfo::Status Module::DefineVariable(VariableInfo* symbol_info) { void Module::ForEachFunction(std::function callback) { SCOPE_profile_cpu_f("alloy"); std::lock_guard guard(lock_); - for (auto it = list_.begin(); it != list_.end(); ++it) { - SymbolInfo* symbol_info = *it; + for (auto& symbol_info : list_) { if (symbol_info->type() == SymbolInfo::TYPE_FUNCTION) { - FunctionInfo* info = (FunctionInfo*)symbol_info; + FunctionInfo* info = static_cast(symbol_info.get()); callback(info); } } @@ -173,9 +165,9 @@ void Module::ForEachFunction(size_t since, size_t& version, size_t count = list_.size(); version = count; for (size_t n = since; n < count; n++) { - SymbolInfo* symbol_info = list_[n]; + auto& symbol_info = list_[n]; if (symbol_info->type() == SymbolInfo::TYPE_FUNCTION) { - FunctionInfo* info = (FunctionInfo*)symbol_info; + FunctionInfo* info = static_cast(symbol_info.get()); callback(info); } } diff --git a/src/alloy/runtime/module.h b/src/alloy/runtime/module.h index e74899a63..0c46c0418 100644 --- a/src/alloy/runtime/module.h +++ b/src/alloy/runtime/module.h @@ -63,10 +63,8 @@ class Module { private: // TODO(benvanik): replace with a better data structure. std::mutex lock_; - typedef std::unordered_map SymbolMap; - SymbolMap map_; - typedef std::vector SymbolList; - SymbolList list_; + std::unordered_map map_; + std::vector> list_; }; } // namespace runtime diff --git a/src/alloy/runtime/runtime.cc b/src/alloy/runtime/runtime.cc index 955cf0d85..bca91c686 100644 --- a/src/alloy/runtime/runtime.cc +++ b/src/alloy/runtime/runtime.cc @@ -30,11 +30,7 @@ Runtime::Runtime(Memory* memory) : memory_(memory) {} Runtime::~Runtime() { { std::lock_guard guard(modules_lock_); - for (ModuleList::iterator it = modules_.begin(); it != modules_.end(); - ++it) { - Module* module = *it; - delete module; - } + modules_.clear(); } debugger_.reset(); @@ -99,28 +95,28 @@ int Runtime::Initialize(std::unique_ptr frontend, return 0; } -int Runtime::AddModule(Module* module) { +int Runtime::AddModule(std::unique_ptr module) { std::lock_guard guard(modules_lock_); - modules_.push_back(module); + modules_.push_back(std::move(module)); return 0; } Module* Runtime::GetModule(const char* name) { std::lock_guard guard(modules_lock_); - Module* result = NULL; - for (ModuleList::iterator it = modules_.begin(); it != modules_.end(); ++it) { - Module* module = *it; + for (const auto& module : modules_) { if (module->name() == name) { - result = module; - break; + return module.get(); } } - return result; + return nullptr; } -Runtime::ModuleList Runtime::GetModules() { +std::vector Runtime::GetModules() { std::lock_guard guard(modules_lock_); - ModuleList clone = modules_; + std::vector clone(modules_.size()); + for (const auto& module : modules_) { + clone.push_back(module.get()); + } return clone; } @@ -176,11 +172,9 @@ int Runtime::LookupFunctionInfo(uint64_t address, std::lock_guard guard(modules_lock_); // TODO(benvanik): sort by code address (if contiguous) so can bsearch. // TODO(benvanik): cache last module low/high, as likely to be in there. - for (ModuleList::const_iterator it = modules_.begin(); it != modules_.end(); - ++it) { - Module* module = *it; + for (const auto& module : modules_) { if (module->ContainsAddress(address)) { - code_module = module; + code_module = module.get(); break; } } diff --git a/src/alloy/runtime/runtime.h b/src/alloy/runtime/runtime.h index 97968a9b8..2fd5d1498 100644 --- a/src/alloy/runtime/runtime.h +++ b/src/alloy/runtime/runtime.h @@ -28,9 +28,6 @@ namespace alloy { namespace runtime { class Runtime { - public: - typedef std::vector ModuleList; - public: explicit Runtime(Memory* memory); virtual ~Runtime(); @@ -43,9 +40,10 @@ class Runtime { int Initialize(std::unique_ptr frontend, std::unique_ptr backend = 0); - int AddModule(Module* module); + int AddModule(std::unique_ptr module); Module* GetModule(const char* name); - ModuleList GetModules(); + Module* GetModule(const std::string& name) { return GetModule(name.c_str()); } + std::vector GetModules(); std::vector FindFunctionsWithAddress(uint64_t address); @@ -69,7 +67,7 @@ class Runtime { EntryTable entry_table_; std::mutex modules_lock_; - ModuleList modules_; + std::vector> modules_; }; } // namespace runtime diff --git a/src/alloy/runtime/symbol_info.h b/src/alloy/runtime/symbol_info.h index c8157105e..50f97e322 100644 --- a/src/alloy/runtime/symbol_info.h +++ b/src/alloy/runtime/symbol_info.h @@ -69,7 +69,7 @@ class FunctionInfo : public SymbolInfo { public: FunctionInfo(Module* module, uint64_t address); - virtual ~FunctionInfo(); + ~FunctionInfo() override; bool has_end_address() const { return end_address_ > 0; } uint64_t end_address() const { return end_address_; } @@ -101,9 +101,7 @@ class FunctionInfo : public SymbolInfo { class VariableInfo : public SymbolInfo { public: VariableInfo(Module* module, uint64_t address); - virtual ~VariableInfo(); - - private: + ~VariableInfo() override; }; } // namespace runtime diff --git a/src/xenia/kernel/objects/xuser_module.cc b/src/xenia/kernel/objects/xuser_module.cc index 3a07b209a..2008aa94a 100644 --- a/src/xenia/kernel/objects/xuser_module.cc +++ b/src/xenia/kernel/objects/xuser_module.cc @@ -103,25 +103,26 @@ XECLEANUP: X_STATUS XUserModule::LoadFromMemory(const void* addr, const size_t length) { Processor* processor = kernel_state()->processor(); XenonRuntime* runtime = processor->runtime(); - XexModule* xex_module = NULL; // Load the XEX into memory and decrypt. xe_xex2_options_t xex_options; xe_zero_struct(&xex_options, sizeof(xex_options)); xex_ = xe_xex2_load(kernel_state()->memory(), addr, length, xex_options); - XEEXPECTNOTNULL(xex_); + if (!xex_) { + return X_STATUS_UNSUCCESSFUL; + } // Prepare the module for execution. // Runtime takes ownership. - xex_module = new XexModule(runtime); - XEEXPECTZERO(xex_module->Load(name_, path_, xex_)); - XEEXPECTZERO(runtime->AddModule(xex_module)); + auto xex_module = std::make_unique(runtime); + if (xex_module->Load(name_, path_, xex_)) { + return X_STATUS_UNSUCCESSFUL; + } + if (runtime->AddModule(std::move(xex_module))) { + return X_STATUS_UNSUCCESSFUL; + } return X_STATUS_SUCCESS; - -XECLEANUP: - delete xex_module; - return X_STATUS_UNSUCCESSFUL; } void* XUserModule::GetProcAddressByOrdinal(uint16_t ordinal) { diff --git a/tools/alloy-sandbox/alloy-sandbox.cc b/tools/alloy-sandbox/alloy-sandbox.cc index 75ec323dc..437204d2d 100644 --- a/tools/alloy-sandbox/alloy-sandbox.cc +++ b/tools/alloy-sandbox/alloy-sandbox.cc @@ -38,9 +38,9 @@ int alloy_sandbox(int argc, xechar_t** argv) { // backend.reset(new alloy::backend::x64::X64Backend(runtime)); runtime->Initialize(std::move(backend)); - RawModule* module = new RawModule(runtime); + auto module = std::make_unique(runtime); module->LoadFile(0x82000000, "test\\codegen\\instr_add.bin"); - runtime->AddModule(module); + runtime->AddModule(std::move(module)); XenonThreadState* thread_state = new XenonThreadState(runtime, 100, 64 * 1024, 0); From e9284dfaed2983836109d139e480ebbf2fbbbace Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 13 Jul 2014 22:28:00 -0700 Subject: [PATCH 031/388] More C++11ification. --- src/alloy/backend/assembler.h | 4 +- src/alloy/backend/backend.h | 4 +- src/alloy/backend/ivm/ivm_assembler.cc | 11 +++- src/alloy/backend/ivm/ivm_assembler.h | 14 ++--- src/alloy/backend/ivm/ivm_backend.cc | 4 +- src/alloy/backend/ivm/ivm_backend.h | 10 ++-- src/alloy/backend/ivm/ivm_intcode.cc | 2 +- src/alloy/backend/x64/x64_assembler.cc | 36 ++++++------ src/alloy/backend/x64/x64_assembler.h | 20 ++++--- src/alloy/backend/x64/x64_backend.cc | 11 ++-- src/alloy/backend/x64/x64_backend.h | 6 +- src/alloy/backend/x64/x64_sequences.cc | 2 +- src/alloy/frontend/ppc/ppc_translator.cc | 56 +++++++++---------- src/alloy/frontend/ppc/ppc_translator.h | 10 ++-- src/alloy/hir/hir_builder.cc | 2 +- src/alloy/reset_scope.h | 45 +++++++++++++++ src/alloy/runtime/function.cc | 3 +- src/alloy/runtime/function.h | 9 ++- src/alloy/runtime/raw_module.cc | 11 +++- src/alloy/runtime/raw_module.h | 2 +- src/alloy/sources.gypi | 1 + src/alloy/type_pool.h | 3 +- src/poly/platform.h | 12 ++++ src/xenia/core/file.cc | 6 +- src/xenia/core/pal_win.cc | 2 +- src/xenia/core/path.cc | 8 +-- src/xenia/emulator.cc | 6 +- src/xenia/emulator.h | 2 +- src/xenia/gpu/d3d11/d3d11_geometry_shader.cc | 2 +- src/xenia/gpu/d3d11/d3d11_shader_resource.cc | 2 +- .../kernel/fs/devices/disc_image_device.cc | 2 +- .../kernel/fs/devices/host_path_device.cc | 8 +-- .../kernel/fs/devices/host_path_entry.cc | 6 +- .../fs/devices/stfs_container_device.cc | 2 +- src/xenia/kernel/fs/filesystem.cc | 4 +- src/xenia/kernel/objects/xmodule.h | 2 +- src/xenia/logging.cc | 2 +- src/xenia/platform.cc | 2 +- src/xenia/string.h | 19 ------- tools/xenia-run/xenia-run.cc | 10 ++-- 40 files changed, 211 insertions(+), 152 deletions(-) create mode 100644 src/alloy/reset_scope.h diff --git a/src/alloy/backend/assembler.h b/src/alloy/backend/assembler.h index b9f6ed788..161142389 100644 --- a/src/alloy/backend/assembler.h +++ b/src/alloy/backend/assembler.h @@ -10,6 +10,8 @@ #ifndef ALLOY_BACKEND_ASSEMBLER_H_ #define ALLOY_BACKEND_ASSEMBLER_H_ +#include + #include namespace alloy { @@ -40,7 +42,7 @@ class Assembler { virtual int Assemble(runtime::FunctionInfo* symbol_info, hir::HIRBuilder* builder, uint32_t debug_info_flags, - runtime::DebugInfo* debug_info, + std::unique_ptr debug_info, runtime::Function** out_function) = 0; protected: diff --git a/src/alloy/backend/backend.h b/src/alloy/backend/backend.h index 7f3124646..e4dea7832 100644 --- a/src/alloy/backend/backend.h +++ b/src/alloy/backend/backend.h @@ -10,6 +10,8 @@ #ifndef ALLOY_BACKEND_BACKEND_H_ #define ALLOY_BACKEND_BACKEND_H_ +#include + #include #include @@ -37,7 +39,7 @@ class Backend { virtual void* AllocThreadData(); virtual void FreeThreadData(void* thread_data); - virtual Assembler* CreateAssembler() = 0; + virtual std::unique_ptr CreateAssembler() = 0; protected: runtime::Runtime* runtime_; diff --git a/src/alloy/backend/ivm/ivm_assembler.cc b/src/alloy/backend/ivm/ivm_assembler.cc index 220d9063d..53d78e336 100644 --- a/src/alloy/backend/ivm/ivm_assembler.cc +++ b/src/alloy/backend/ivm/ivm_assembler.cc @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -21,6 +22,7 @@ namespace backend { namespace ivm { using alloy::hir::HIRBuilder; +using alloy::runtime::DebugInfo; using alloy::runtime::Function; using alloy::runtime::FunctionInfo; @@ -47,10 +49,15 @@ void IVMAssembler::Reset() { int IVMAssembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder, uint32_t debug_info_flags, - runtime::DebugInfo* debug_info, + std::unique_ptr debug_info, Function** out_function) { + SCOPE_profile_cpu_f("alloy"); + + // Reset when we leave. + make_reset_scope(this); + IVMFunction* fn = new IVMFunction(symbol_info); - fn->set_debug_info(debug_info); + fn->set_debug_info(std::move(debug_info)); TranslationContext ctx; ctx.register_count = 0; diff --git a/src/alloy/backend/ivm/ivm_assembler.h b/src/alloy/backend/ivm/ivm_assembler.h index 04f4c142d..446361647 100644 --- a/src/alloy/backend/ivm/ivm_assembler.h +++ b/src/alloy/backend/ivm/ivm_assembler.h @@ -21,16 +21,16 @@ namespace ivm { class IVMAssembler : public Assembler { public: IVMAssembler(Backend* backend); - virtual ~IVMAssembler(); + ~IVMAssembler() override; - virtual int Initialize(); + int Initialize() override; - virtual void Reset(); + void Reset() override; - virtual int Assemble(runtime::FunctionInfo* symbol_info, - hir::HIRBuilder* builder, uint32_t debug_info_flags, - runtime::DebugInfo* debug_info, - runtime::Function** out_function); + int Assemble(runtime::FunctionInfo* symbol_info, hir::HIRBuilder* builder, + uint32_t debug_info_flags, + std::unique_ptr debug_info, + runtime::Function** out_function) override; private: Arena intcode_arena_; diff --git a/src/alloy/backend/ivm/ivm_backend.cc b/src/alloy/backend/ivm/ivm_backend.cc index 286d3b5a3..171765a36 100644 --- a/src/alloy/backend/ivm/ivm_backend.cc +++ b/src/alloy/backend/ivm/ivm_backend.cc @@ -47,7 +47,9 @@ void IVMBackend::FreeThreadData(void* thread_data) { delete stack; } -Assembler* IVMBackend::CreateAssembler() { return new IVMAssembler(this); } +std::unique_ptr IVMBackend::CreateAssembler() { + return std::make_unique(this); +} } // namespace ivm } // namespace backend diff --git a/src/alloy/backend/ivm/ivm_backend.h b/src/alloy/backend/ivm/ivm_backend.h index 5311e56f2..b01536b6b 100644 --- a/src/alloy/backend/ivm/ivm_backend.h +++ b/src/alloy/backend/ivm/ivm_backend.h @@ -23,14 +23,14 @@ namespace ivm { class IVMBackend : public Backend { public: IVMBackend(runtime::Runtime* runtime); - virtual ~IVMBackend(); + ~IVMBackend() override; - virtual int Initialize(); + int Initialize() override; - virtual void* AllocThreadData(); - virtual void FreeThreadData(void* thread_data); + void* AllocThreadData() override; + void FreeThreadData(void* thread_data) override; - virtual Assembler* CreateAssembler(); + std::unique_ptr CreateAssembler() override; }; } // namespace ivm diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index cc9e81d73..91181a9e7 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -216,7 +216,7 @@ int Translate_COMMENT(TranslationContext& ctx, Instr* i) { ic->flags = i->flags; ic->debug_flags = 0; // HACK HACK HACK - char* src = xestrdupa((char*)i->src1.offset); + char* src = strdup(reinterpret_cast(i->src1.offset)); uint64_t src_p = (uint64_t)src; ic->src1_reg = (uint32_t)src_p; ic->src2_reg = (uint32_t)(src_p >> 32); diff --git a/src/alloy/backend/x64/x64_assembler.cc b/src/alloy/backend/x64/x64_assembler.cc index 01b179774..be3777b1c 100644 --- a/src/alloy/backend/x64/x64_assembler.cc +++ b/src/alloy/backend/x64/x64_assembler.cc @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -33,12 +34,9 @@ using alloy::runtime::Function; using alloy::runtime::FunctionInfo; X64Assembler::X64Assembler(X64Backend* backend) - : Assembler(backend), x64_backend_(backend), emitter_(0), allocator_(0) {} + : Assembler(backend), x64_backend_(backend) {} -X64Assembler::~X64Assembler() { - delete emitter_; - delete allocator_; -} +X64Assembler::~X64Assembler() = default; int X64Assembler::Initialize() { int result = Assembler::Initialize(); @@ -46,8 +44,8 @@ int X64Assembler::Initialize() { return result; } - allocator_ = new XbyakAllocator(); - emitter_ = new X64Emitter(x64_backend_, allocator_); + allocator_.reset(new XbyakAllocator()); + emitter_.reset(new X64Emitter(x64_backend_, allocator_.get())); return result; } @@ -58,39 +56,39 @@ void X64Assembler::Reset() { } int X64Assembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder, - uint32_t debug_info_flags, DebugInfo* debug_info, + uint32_t debug_info_flags, + std::unique_ptr debug_info, Function** out_function) { SCOPE_profile_cpu_f("alloy"); - int result = 0; + // Reset when we leave. + make_reset_scope(this); // Lower HIR -> x64. void* machine_code = 0; size_t code_size = 0; - result = emitter_->Emit(builder, debug_info_flags, debug_info, machine_code, - code_size); - XEEXPECTZERO(result); + int result = emitter_->Emit(builder, debug_info_flags, debug_info.get(), + machine_code, code_size); + if (result) { + return result; + } // Stash generated machine code. if (debug_info_flags & DebugInfoFlags::DEBUG_INFO_MACHINE_CODE_DISASM) { - DumpMachineCode(debug_info, machine_code, code_size, &string_buffer_); + DumpMachineCode(debug_info.get(), machine_code, code_size, &string_buffer_); debug_info->set_machine_code_disasm(string_buffer_.ToString()); string_buffer_.Reset(); } { X64Function* fn = new X64Function(symbol_info); - fn->set_debug_info(debug_info); + fn->set_debug_info(std::move(debug_info)); fn->Setup(machine_code, code_size); *out_function = fn; - - result = 0; } -XECLEANUP: - Reset(); - return result; + return 0; } void X64Assembler::DumpMachineCode(DebugInfo* debug_info, void* machine_code, diff --git a/src/alloy/backend/x64/x64_assembler.h b/src/alloy/backend/x64/x64_assembler.h index 6cbf0c02c..769bee9db 100644 --- a/src/alloy/backend/x64/x64_assembler.h +++ b/src/alloy/backend/x64/x64_assembler.h @@ -10,6 +10,8 @@ #ifndef ALLOY_BACKEND_X64_X64_ASSEMBLER_H_ #define ALLOY_BACKEND_X64_X64_ASSEMBLER_H_ +#include + #include #include @@ -25,16 +27,16 @@ class XbyakAllocator; class X64Assembler : public Assembler { public: X64Assembler(X64Backend* backend); - virtual ~X64Assembler(); + ~X64Assembler() override; - virtual int Initialize(); + int Initialize() override; - virtual void Reset(); + void Reset() override; - virtual int Assemble(runtime::FunctionInfo* symbol_info, - hir::HIRBuilder* builder, uint32_t debug_info_flags, - runtime::DebugInfo* debug_info, - runtime::Function** out_function); + int Assemble(runtime::FunctionInfo* symbol_info, hir::HIRBuilder* builder, + uint32_t debug_info_flags, + std::unique_ptr debug_info, + runtime::Function** out_function) override; private: void DumpMachineCode(runtime::DebugInfo* debug_info, void* machine_code, @@ -42,8 +44,8 @@ class X64Assembler : public Assembler { private: X64Backend* x64_backend_; - X64Emitter* emitter_; - XbyakAllocator* allocator_; + std::unique_ptr emitter_; + std::unique_ptr allocator_; StringBuffer string_buffer_; }; diff --git a/src/alloy/backend/x64/x64_backend.cc b/src/alloy/backend/x64/x64_backend.cc index cca85ca59..32aed4d78 100644 --- a/src/alloy/backend/x64/x64_backend.cc +++ b/src/alloy/backend/x64/x64_backend.cc @@ -47,17 +47,18 @@ int X64Backend::Initialize() { return result; } - auto allocator = new XbyakAllocator(); - auto thunk_emitter = new X64ThunkEmitter(this, allocator); + // Generate thunks used to transition between jitted code and host code. + auto allocator = std::make_unique(); + auto thunk_emitter = std::make_unique(this, allocator.get()); host_to_guest_thunk_ = thunk_emitter->EmitHostToGuestThunk(); guest_to_host_thunk_ = thunk_emitter->EmitGuestToHostThunk(); - delete thunk_emitter; - delete allocator; return result; } -Assembler* X64Backend::CreateAssembler() { return new X64Assembler(this); } +std::unique_ptr X64Backend::CreateAssembler() { + return std::make_unique(this); +} } // namespace x64 } // namespace backend diff --git a/src/alloy/backend/x64/x64_backend.h b/src/alloy/backend/x64/x64_backend.h index f0ebfdd2a..e8322ee1a 100644 --- a/src/alloy/backend/x64/x64_backend.h +++ b/src/alloy/backend/x64/x64_backend.h @@ -28,15 +28,15 @@ typedef void* (*GuestToHostThunk)(void* target, void* arg0, void* arg1); class X64Backend : public Backend { public: X64Backend(runtime::Runtime* runtime); - virtual ~X64Backend(); + ~X64Backend() override; X64CodeCache* code_cache() const { return code_cache_; } HostToGuestThunk host_to_guest_thunk() const { return host_to_guest_thunk_; } GuestToHostThunk guest_to_host_thunk() const { return guest_to_host_thunk_; } - virtual int Initialize(); + int Initialize() override; - virtual Assembler* CreateAssembler(); + std::unique_ptr CreateAssembler() override; private: X64CodeCache* code_cache_; diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index f59f465db..b89916585 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -61,7 +61,7 @@ EMITTER(COMMENT, MATCH(I)) { auto str = reinterpret_cast(i.src1.value); // TODO(benvanik): pass through. // TODO(benvanik): don't just leak this memory. - auto str_copy = xestrdupa(str); + auto str_copy = strdup(str); e.mov(e.rdx, reinterpret_cast(str_copy)); e.CallNative(TraceString); } diff --git a/src/alloy/frontend/ppc/ppc_translator.cc b/src/alloy/frontend/ppc/ppc_translator.cc index d93b9bd16..92897ea0b 100644 --- a/src/alloy/frontend/ppc/ppc_translator.cc +++ b/src/alloy/frontend/ppc/ppc_translator.cc @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -34,10 +35,10 @@ namespace passes = alloy::compiler::passes; PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) { Backend* backend = frontend->runtime()->backend(); - scanner_ = new PPCScanner(frontend); - builder_ = new PPCHIRBuilder(frontend); - compiler_ = new Compiler(frontend->runtime()); - assembler_ = backend->CreateAssembler(); + scanner_.reset(new PPCScanner(frontend)); + builder_.reset(new PPCHIRBuilder(frontend)); + compiler_.reset(new Compiler(frontend->runtime())); + assembler_ = std::move(backend->CreateAssembler()); assembler_->Initialize(); bool validate = FLAGS_validate_hir; @@ -78,18 +79,19 @@ PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) { compiler_->AddPass(std::make_unique()); } -PPCTranslator::~PPCTranslator() { - delete assembler_; - delete compiler_; - delete builder_; - delete scanner_; -} +PPCTranslator::~PPCTranslator() = default; int PPCTranslator::Translate(FunctionInfo* symbol_info, uint32_t debug_info_flags, Function** out_function) { SCOPE_profile_cpu_f("alloy"); + // Reset() all caching when we leave. + make_reset_scope(builder_); + make_reset_scope(compiler_); + make_reset_scope(assembler_); + make_reset_scope(&string_buffer_); + // Scan the function to find its extents. We only need to do this if we // haven't already been provided with them from some other source. if (!symbol_info->has_end_address()) { @@ -106,9 +108,9 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info, if (FLAGS_always_disasm) { debug_info_flags |= DEBUG_INFO_ALL_DISASM; } - DebugInfo* debug_info = NULL; + std::unique_ptr debug_info; if (debug_info_flags) { - debug_info = new DebugInfo(); + debug_info.reset(new DebugInfo()); } // Stash source. @@ -119,8 +121,10 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info, } // Emit function. - int result = builder_->Emit(symbol_info, debug_info != NULL); - XEEXPECTZERO(result); + int result = builder_->Emit(symbol_info, debug_info != nullptr); + if (result) { + return result; + } // Stash raw HIR. if (debug_info_flags & DEBUG_INFO_RAW_HIR_DISASM) { @@ -130,8 +134,10 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info, } // Compile/optimize/etc. - result = compiler_->Compile(builder_); - XEEXPECTZERO(result); + result = compiler_->Compile(builder_.get()); + if (result) { + return result; + } // Stash optimized HIR. if (debug_info_flags & DEBUG_INFO_HIR_DISASM) { @@ -141,21 +147,13 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info, } // Assemble to backend machine code. - result = assembler_->Assemble(symbol_info, builder_, debug_info_flags, - debug_info, out_function); - XEEXPECTZERO(result); - - result = 0; - -XECLEANUP: + result = assembler_->Assemble(symbol_info, builder_.get(), debug_info_flags, + std::move(debug_info), out_function); if (result) { - delete debug_info; + return result; } - builder_->Reset(); - compiler_->Reset(); - assembler_->Reset(); - string_buffer_.Reset(); - return result; + + return 0; }; void PPCTranslator::DumpSource(runtime::FunctionInfo* symbol_info, diff --git a/src/alloy/frontend/ppc/ppc_translator.h b/src/alloy/frontend/ppc/ppc_translator.h index 868ad5aeb..22011d449 100644 --- a/src/alloy/frontend/ppc/ppc_translator.h +++ b/src/alloy/frontend/ppc/ppc_translator.h @@ -10,6 +10,8 @@ #ifndef ALLOY_FRONTEND_PPC_PPC_TRANSLATOR_H_ #define ALLOY_FRONTEND_PPC_PPC_TRANSLATOR_H_ +#include + #include #include #include @@ -37,10 +39,10 @@ class PPCTranslator { private: PPCFrontend* frontend_; - PPCScanner* scanner_; - PPCHIRBuilder* builder_; - compiler::Compiler* compiler_; - backend::Assembler* assembler_; + std::unique_ptr scanner_; + std::unique_ptr builder_; + std::unique_ptr compiler_; + std::unique_ptr assembler_; StringBuffer string_buffer_; }; diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index 439a09e51..1ba6ce55d 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -544,7 +544,7 @@ void HIRBuilder::Comment(const char* format, ...) { va_start(args, format); xevsnprintfa(buffer, 1024, format, args); va_end(args); - size_t len = xestrlena(buffer); + size_t len = strlen(buffer); if (!len) { return; } diff --git a/src/alloy/reset_scope.h b/src/alloy/reset_scope.h new file mode 100644 index 000000000..d10c2561d --- /dev/null +++ b/src/alloy/reset_scope.h @@ -0,0 +1,45 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef ALLOY_RESET_SCOPE_H_ +#define ALLOY_RESET_SCOPE_H_ + +#include + +#include + +namespace alloy { + +template +class ResetScope { + public: + ResetScope(T* value) : value_(value) {} + ~ResetScope() { + if (value_) { + value_->Reset(); + } + } + + private: + T* value_; +}; + +template +inline ResetScope make_reset_scope(T* value) { + return ResetScope(value); +} + +template +inline ResetScope make_reset_scope(const std::unique_ptr& value) { + return ResetScope(value.get()); +} + +} // namespace alloy + +#endif // ALLOY_RESET_SCOPE_H_ diff --git a/src/alloy/runtime/function.cc b/src/alloy/runtime/function.cc index 7002cc86b..4be19f45e 100644 --- a/src/alloy/runtime/function.cc +++ b/src/alloy/runtime/function.cc @@ -18,8 +18,7 @@ namespace runtime { Function::Function(FunctionInfo* symbol_info) : address_(symbol_info->address()), - symbol_info_(symbol_info), - debug_info_(0) {} + symbol_info_(symbol_info) {} Function::~Function() = default; diff --git a/src/alloy/runtime/function.h b/src/alloy/runtime/function.h index 3ea3c4c9e..68366ba8f 100644 --- a/src/alloy/runtime/function.h +++ b/src/alloy/runtime/function.h @@ -10,6 +10,7 @@ #ifndef ALLOY_RUNTIME_FUNCTION_H_ #define ALLOY_RUNTIME_FUNCTION_H_ +#include #include #include @@ -31,8 +32,10 @@ class Function { uint64_t address() const { return address_; } FunctionInfo* symbol_info() const { return symbol_info_; } - DebugInfo* debug_info() const { return debug_info_; } - void set_debug_info(DebugInfo* debug_info) { debug_info_ = debug_info; } + DebugInfo* debug_info() const { return debug_info_.get(); } + void set_debug_info(std::unique_ptr debug_info) { + debug_info_ = std::move(debug_info); + } int AddBreakpoint(Breakpoint* breakpoint); int RemoveBreakpoint(Breakpoint* breakpoint); @@ -48,7 +51,7 @@ class Function { protected: uint64_t address_; FunctionInfo* symbol_info_; - DebugInfo* debug_info_; + std::unique_ptr debug_info_; // TODO(benvanik): move elsewhere? DebugData? std::mutex lock_; diff --git a/src/alloy/runtime/raw_module.cc b/src/alloy/runtime/raw_module.cc index 0d0a4c6d7..365d620ac 100644 --- a/src/alloy/runtime/raw_module.cc +++ b/src/alloy/runtime/raw_module.cc @@ -21,8 +21,8 @@ RawModule::~RawModule() { } } -int RawModule::LoadFile(uint64_t base_address, const char* path) { - FILE* file = fopen(path, "rb"); +int RawModule::LoadFile(uint64_t base_address, const std::string& path) { + FILE* file = fopen(path.c_str(), "rb"); fseek(file, 0, SEEK_END); size_t file_length = ftell(file); fseek(file, 0, SEEK_SET); @@ -42,7 +42,12 @@ int RawModule::LoadFile(uint64_t base_address, const char* path) { fclose(file); // Setup debug info. - name_ = std::string(xestrrchra(path, XE_PATH_SEPARATOR) + 1); + auto last_slash = path.find_last_of(poly::path_separator); + if (last_slash != std::string::npos) { + name_ = path.substr(last_slash + 1); + } else { + name_ = path; + } // TODO(benvanik): debug info low_address_ = base_address; diff --git a/src/alloy/runtime/raw_module.h b/src/alloy/runtime/raw_module.h index 8eb2c645d..37723119b 100644 --- a/src/alloy/runtime/raw_module.h +++ b/src/alloy/runtime/raw_module.h @@ -22,7 +22,7 @@ class RawModule : public Module { RawModule(Runtime* runtime); ~RawModule() override; - int LoadFile(uint64_t base_address, const char* path); + int LoadFile(uint64_t base_address, const std::string& path); const std::string& name() const override { return name_; } diff --git a/src/alloy/sources.gypi b/src/alloy/sources.gypi index 6e3d80e12..c912345b5 100644 --- a/src/alloy/sources.gypi +++ b/src/alloy/sources.gypi @@ -10,6 +10,7 @@ 'delegate.h', 'memory.cc', 'memory.h', + 'reset_scope.h', 'string_buffer.cc', 'string_buffer.h', 'type_pool.h', diff --git a/src/alloy/type_pool.h b/src/alloy/type_pool.h index ce124eab4..57be0b36e 100644 --- a/src/alloy/type_pool.h +++ b/src/alloy/type_pool.h @@ -52,8 +52,7 @@ class TypePool { private: std::mutex lock_; - typedef std::vector TList; - TList list_; + std::vector list_; }; } // namespace alloy diff --git a/src/poly/platform.h b/src/poly/platform.h index 019d69060..10efb54c3 100644 --- a/src/poly/platform.h +++ b/src/poly/platform.h @@ -161,4 +161,16 @@ XE_CPU: 32BIT | 64BIT | BIGENDIAN | LITTLEENDIAN #include #endif // MSVC +namespace poly { + +#if XE_LIKE_WIN32 +const char path_separator = '\\'; +const size_t max_path = _MAX_PATH; +#else +const char path_separator = '/'; +const size_t max_path = PATH_MAX; +#endif // WIN32 + +} // namespace poly + #endif // POLY_PLATFORM_H_ diff --git a/src/xenia/core/file.cc b/src/xenia/core/file.cc index bf240d7f6..2c8bfd616 100644 --- a/src/xenia/core/file.cc +++ b/src/xenia/core/file.cc @@ -30,12 +30,12 @@ xe_file_ref xe_file_open(const xe_file_mode mode, const xechar_t *path) { xechar_t mode_string[10]; mode_string[0] = 0; if (mode & kXEFileModeRead) { - XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), XT("r"))); + XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), L"r")); } if (mode & kXEFileModeWrite) { - XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), XT("w"))); + XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), L"w")); } - XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), XT("b"))); + XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), L"b")); #if XE_LIKE_WIN32 && XE_WCHAR XEEXPECTZERO(_wfopen_s((FILE**)&file->handle, path, mode_string)); diff --git a/src/xenia/core/pal_win.cc b/src/xenia/core/pal_win.cc index 3ef63b141..5f6498e5b 100644 --- a/src/xenia/core/pal_win.cc +++ b/src/xenia/core/pal_win.cc @@ -75,7 +75,7 @@ int xe_pal_get_system_info(xe_system_info* out_info) { LPFN_GLPI glpi = NULL; PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL; - kernel32 = GetModuleHandle(TEXT("kernel32")); + kernel32 = GetModuleHandle(L"kernel32"); XEEXPECTNOTNULL(kernel32); glpi = (LPFN_GLPI)GetProcAddress(kernel32, "GetLogicalProcessorInformation"); XEEXPECTNOTNULL(glpi); diff --git a/src/xenia/core/path.cc b/src/xenia/core/path.cc index 6356178f6..c24d22966 100644 --- a/src/xenia/core/path.cc +++ b/src/xenia/core/path.cc @@ -13,11 +13,11 @@ void xe_path_join(const xechar_t* left, const xechar_t* right, xechar_t* out_path, size_t out_path_size) { #if XE_WCHAR - xesnprintf(out_path, out_path_size, XT("%ls%c%ls"), - left, XE_PATH_SEPARATOR, right); + xesnprintf(out_path, out_path_size, L"%ls%c%ls", + left, poly::path_separator, right); #else - xesnprintf(out_path, out_path_size, XT("%s%c%s"), - left, XE_PATH_SEPARATOR, right); + xesnprintf(out_path, out_path_size, L"%s%c%s", + left, poly::path_separator, right); #endif // XE_WCHAR } diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index 64c9ac00b..1b3dbbcac 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -147,7 +147,7 @@ X_STATUS Emulator::LaunchXexFile(const xechar_t* path) { int result_code = 0; // Get just the filename (foo.xex). - const xechar_t* file_name = xestrrchr(path, XE_PATH_SEPARATOR); + const xechar_t* file_name = xestrrchr(path, poly::path_separator); if (file_name) { // Skip slash. file_name++; @@ -157,7 +157,7 @@ X_STATUS Emulator::LaunchXexFile(const xechar_t* path) { } // Get the parent path of the file. - xechar_t parent_path[XE_MAX_PATH]; + xechar_t parent_path[poly::max_path]; XEIGNORE(xestrcpy(parent_path, XECOUNT(parent_path), path)); parent_path[file_name - path] = 0; @@ -176,7 +176,7 @@ X_STATUS Emulator::LaunchXexFile(const xechar_t* path) { "d:", "\\Device\\Harddisk1\\Partition0"); // Get the file name of the module to load from the filesystem. - char fs_path[XE_MAX_PATH]; + char fs_path[poly::max_path]; XEIGNORE(xestrcpya(fs_path, XECOUNT(fs_path), "game:\\")); char* fs_path_ptr = fs_path + xestrlena(fs_path); *fs_path_ptr = 0; diff --git a/src/xenia/emulator.h b/src/xenia/emulator.h index 82ede0ec6..3548e5d2c 100644 --- a/src/xenia/emulator.h +++ b/src/xenia/emulator.h @@ -65,7 +65,7 @@ public: X_STATUS LaunchSTFSTitle(const xechar_t* path); private: - xechar_t command_line_[XE_MAX_PATH]; + xechar_t command_line_[poly::max_path]; ui::Window* main_window_; diff --git a/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc b/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc index d8660cbfe..071395b7e 100644 --- a/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc +++ b/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc @@ -96,7 +96,7 @@ ID3D10Blob* D3D11GeometryShader::Compile(const char* shader_source) { base_path = FLAGS_dump_shaders.c_str(); } uint64_t hash = xe_hash64(shader_source, xestrlena(shader_source)); // ? - char file_name[XE_MAX_PATH]; + char file_name[poly::max_path]; xesnprintfa(file_name, XECOUNT(file_name), "%s/gen_%.16llX.gs", base_path, diff --git a/src/xenia/gpu/d3d11/d3d11_shader_resource.cc b/src/xenia/gpu/d3d11/d3d11_shader_resource.cc index b5c28c9f2..c9c3e033f 100644 --- a/src/xenia/gpu/d3d11/d3d11_shader_resource.cc +++ b/src/xenia/gpu/d3d11/d3d11_shader_resource.cc @@ -47,7 +47,7 @@ ID3D10Blob* D3D11ShaderCompile(XE_GPU_SHADER_TYPE type, base_path = FLAGS_dump_shaders.c_str(); } size_t hash = xe_hash64(disasm_source, xestrlena(disasm_source)); // ? - char file_name[XE_MAX_PATH]; + char file_name[poly::max_path]; xesnprintfa(file_name, XECOUNT(file_name), "%s/gen_%.16llX.%s", base_path, diff --git a/src/xenia/kernel/fs/devices/disc_image_device.cc b/src/xenia/kernel/fs/devices/disc_image_device.cc index e3e2a8c4b..b64172919 100644 --- a/src/xenia/kernel/fs/devices/disc_image_device.cc +++ b/src/xenia/kernel/fs/devices/disc_image_device.cc @@ -62,7 +62,7 @@ Entry* DiscImageDevice::ResolvePath(const char* path) { // Walk the path, one separator at a time. // We copy it into the buffer and shift it left over and over. - char remaining[XE_MAX_PATH]; + char remaining[poly::max_path]; XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), path)); while (remaining[0]) { char* next_slash = xestrchra(remaining, '\\'); diff --git a/src/xenia/kernel/fs/devices/host_path_device.cc b/src/xenia/kernel/fs/devices/host_path_device.cc index b4cbf5046..9eed206f0 100644 --- a/src/xenia/kernel/fs/devices/host_path_device.cc +++ b/src/xenia/kernel/fs/devices/host_path_device.cc @@ -35,23 +35,23 @@ Entry* HostPathDevice::ResolvePath(const char* path) { XELOGFS("HostPathDevice::ResolvePath(%s)", path); #if XE_WCHAR - xechar_t rel_path[XE_MAX_PATH]; + xechar_t rel_path[poly::max_path]; XEIGNORE(xestrwiden(rel_path, XECOUNT(rel_path), path)); #else const xechar_t* rel_path = path; #endif - xechar_t full_path[XE_MAX_PATH]; + xechar_t full_path[poly::max_path]; xe_path_join(local_path_, rel_path, full_path, XECOUNT(full_path)); // Swap around path separators. - if (XE_PATH_SEPARATOR != '\\') { + if (poly::path_separator != '\\') { for (size_t n = 0; n < XECOUNT(full_path); n++) { if (full_path[n] == 0) { break; } if (full_path[n] == '\\') { - full_path[n] = XE_PATH_SEPARATOR; + full_path[n] = poly::path_separator; } } } diff --git a/src/xenia/kernel/fs/devices/host_path_entry.cc b/src/xenia/kernel/fs/devices/host_path_entry.cc index a7f908bd3..f37f30008 100644 --- a/src/xenia/kernel/fs/devices/host_path_entry.cc +++ b/src/xenia/kernel/fs/devices/host_path_entry.cc @@ -87,10 +87,10 @@ X_STATUS HostPathEntry::QueryDirectory( } if (handle == INVALID_HANDLE_VALUE) { - xechar_t target_path[XE_MAX_PATH]; - xestrcpy(target_path, XE_MAX_PATH, local_path_); + xechar_t target_path[poly::max_path]; + xestrcpy(target_path, poly::max_path, local_path_); if (file_name == NULL) { - xestrcat(target_path, XE_MAX_PATH, XETEXT("*")); + xestrcat(target_path, poly::max_path, L"*"); } else { auto target_length = xestrlen(local_path_); diff --git a/src/xenia/kernel/fs/devices/stfs_container_device.cc b/src/xenia/kernel/fs/devices/stfs_container_device.cc index b055e8820..4d0d97127 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_device.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_device.cc @@ -63,7 +63,7 @@ Entry* STFSContainerDevice::ResolvePath(const char* path) { // Walk the path, one separator at a time. // We copy it into the buffer and shift it left over and over. - char remaining[XE_MAX_PATH]; + char remaining[poly::max_path]; XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), path)); while (remaining[0]) { char* next_slash = xestrchra(remaining, '\\'); diff --git a/src/xenia/kernel/fs/filesystem.cc b/src/xenia/kernel/fs/filesystem.cc index e83d409c8..2b53acd0e 100644 --- a/src/xenia/kernel/fs/filesystem.cc +++ b/src/xenia/kernel/fs/filesystem.cc @@ -91,7 +91,7 @@ Entry* FileSystem::ResolvePath(const char* path) { // Resolve symlinks. // TODO(benvanik): more robust symlink handling - right now we assume simple // drive path -> device mappings with nothing nested. - char full_path[XE_MAX_PATH]; + char full_path[poly::max_path]; XEIGNORE(xestrcpya(full_path, XECOUNT(full_path), path)); for (std::unordered_map::iterator it = symlinks_.begin(); it != symlinks_.end(); ++it) { @@ -111,7 +111,7 @@ Entry* FileSystem::ResolvePath(const char* path) { if (xestrcasestra(full_path, device->path()) == full_path) { // Found! // Trim the device prefix off and pass down. - char device_path[XE_MAX_PATH]; + char device_path[poly::max_path]; XEIGNORE(xestrcpya(device_path, XECOUNT(device_path), full_path + xestrlena(device->path()))); return device->ResolvePath(device_path); diff --git a/src/xenia/kernel/objects/xmodule.h b/src/xenia/kernel/objects/xmodule.h index 97c49b907..c19a4961f 100644 --- a/src/xenia/kernel/objects/xmodule.h +++ b/src/xenia/kernel/objects/xmodule.h @@ -34,7 +34,7 @@ public: protected: char name_[256]; - char path_[XE_MAX_PATH]; + char path_[poly::max_path]; }; diff --git a/src/xenia/logging.cc b/src/xenia/logging.cc index 77106bc54..1f387ad57 100644 --- a/src/xenia/logging.cc +++ b/src/xenia/logging.cc @@ -31,7 +31,7 @@ void xe_format_log_line( const char* function_name, const char level_char, const char* fmt, va_list args) { // Strip out just the filename from the path. - const char* filename = xestrrchra(file_path, XE_PATH_SEPARATOR); + const char* filename = xestrrchra(file_path, poly::path_separator); if (filename) { // Slash - skip over it. filename++; diff --git a/src/xenia/platform.cc b/src/xenia/platform.cc index d5d0a14eb..c9d4d063b 100644 --- a/src/xenia/platform.cc +++ b/src/xenia/platform.cc @@ -94,7 +94,7 @@ int xe_main_window_thunk( xe_attach_console(); wchar_t buffer[2048]; xestrcpy(buffer, XECOUNT(buffer), name); - xestrcat(buffer, XECOUNT(buffer), XETEXT(" ")); + xestrcat(buffer, XECOUNT(buffer), L" "); xestrcat(buffer, XECOUNT(buffer), command_line); int argc; wchar_t** argv = CommandLineToArgvW(buffer, &argc); diff --git a/src/xenia/string.h b/src/xenia/string.h index 6008d3073..4f4c44642 100644 --- a/src/xenia/string.h +++ b/src/xenia/string.h @@ -40,7 +40,6 @@ char* xestrcasestra(const char* str, const char* substr); #define xestrdupw _wcsdup #define xestrchrw wcschr #define xestrrchrw wcsrchr -#define xestrstrw wcsstr #define xestrcasestrw ?? #define xestrcpyw(dest, destLength, source) (wcscpy_s(dest, destLength, source) == 0) #define xestrncpyw(dest, destLength, source, count) (wcsncpy_s(dest, destLength, source, count) == 0) @@ -54,7 +53,6 @@ char* xestrcasestra(const char* str, const char* substr); #define xestrcasecmpa strcasecmp #define xestrchra strchr #define xestrrchra strrchr -#define xestrstra strstr #define xestrcpya(dest, destLength, source) (strcpy_s(dest, destLength, source) == 0) #define xestrncpya(dest, destLength, source, count) (strncpy_s(dest, destLength, source, count) == 0) #define xestrcata(dest, destLength, source) (strcat_s(dest, destLength, source) == 0) @@ -65,8 +63,6 @@ char* xestrcasestra(const char* str, const char* substr); typedef wchar_t xechar_t; #define XE_WCHAR 1 -#define XETEXT(s) L ## s -#define XESTRFORMAT L"%ls" #define xestrlen xestrlenw #define xestrcmp xestrcmpw @@ -74,7 +70,6 @@ typedef wchar_t xechar_t; #define xestrdup xestrdupw #define xestrchr xestrchrw #define xestrrchr xestrrchrw -#define xestrstr xestrstrw #define xestrcasestr xestrcasestrw #define xestrtoull xestrtoullw #define xestrcpy xestrcpyw @@ -89,8 +84,6 @@ typedef wchar_t xechar_t; typedef char xechar_t; #define XE_CHAR 1 -#define XETEXT(s) s -#define XESTRFORMAT "%s" #define xestrlen xestrlena #define xestrcmp xestrcmpa @@ -98,7 +91,6 @@ typedef char xechar_t; #define xestrdup xestrdupa #define xestrchr xestrchra #define xestrrchr xestrrchra -#define xestrstr xestrstra #define xestrcasestr xestrcasestra #define xestrtoull xestrtoulla #define xestrcpy xestrcpya @@ -111,15 +103,4 @@ typedef char xechar_t; #endif // WIN32 -#define XT XETEXT -#define XTS XESTRFORMAT - -#if XE_LIKE_WIN32 -#define XE_PATH_SEPARATOR ((xechar_t)'\\') -#define XE_MAX_PATH _MAX_PATH -#else -#define XE_PATH_SEPARATOR ((xechar_t)'/') -#define XE_MAX_PATH PATH_MAX -#endif // WIN32 - #endif // XENIA_STRING_H_ diff --git a/tools/xenia-run/xenia-run.cc b/tools/xenia-run/xenia-run.cc index 9f2151d8c..f684d14eb 100644 --- a/tools/xenia-run/xenia-run.cc +++ b/tools/xenia-run/xenia-run.cc @@ -37,7 +37,7 @@ int xenia_run(int argc, xechar_t** argv) { if (FLAGS_target.size()) { // Passed as a named argument. // TODO(benvanik): find something better than gflags that supports unicode. - xechar_t buffer[XE_MAX_PATH]; + xechar_t buffer[poly::max_path]; XEIGNORE(xestrwiden(buffer, sizeof(buffer), FLAGS_target.c_str())); path = buffer; } else { @@ -52,7 +52,7 @@ int xenia_run(int argc, xechar_t** argv) { // Normalize the path and make absolute. // TODO(benvanik): move this someplace common. - xechar_t abs_path[XE_MAX_PATH]; + xechar_t abs_path[poly::max_path]; xe_path_get_absolute(path, abs_path, XECOUNT(abs_path)); // Grab file extension. @@ -60,7 +60,7 @@ int xenia_run(int argc, xechar_t** argv) { const xechar_t* dot = xestrrchr(abs_path, '.'); // Create the emulator. - emulator = new Emulator(XT("")); + emulator = new Emulator(L""); XEEXPECTNOTNULL(emulator); X_STATUS result = emulator->Setup(); if (XFAILED(result)) { @@ -74,7 +74,7 @@ int xenia_run(int argc, xechar_t** argv) { if (!dot) { // Likely an STFS container. result = emulator->LaunchSTFSTitle(abs_path); - } else if (xestrcmp(dot, XT(".xex")) == 0) { + } else if (xestrcmp(dot, L".xex") == 0) { // Treat as a naked xex file. result = emulator->LaunchXexFile(abs_path); } else { @@ -96,4 +96,4 @@ XECLEANUP: Profiler::Shutdown(); return result_code; } -XE_MAIN_WINDOW_THUNK(xenia_run, XETEXT("xenia-run"), "xenia-run some.xex"); +XE_MAIN_WINDOW_THUNK(xenia_run, L"xenia-run", "xenia-run some.xex"); From ce70978ef678e8c17c35a92bef5bf98bdf0d61d1 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 14 Jul 2014 19:18:42 -0700 Subject: [PATCH 032/388] Starting to split up alloy/core.h. --- src/alloy/arena.cc | 2 + src/alloy/backend/ivm/ivm_assembler.h | 1 + src/alloy/backend/ivm/ivm_intcode.cc | 1 + src/alloy/backend/x64/x64_assembler.h | 1 + src/alloy/backend/x64/x64_code_cache_win.cc | 2 + src/alloy/core.h | 78 ----------------- src/alloy/frontend/ppc/ppc_context.h | 1 + src/alloy/frontend/ppc/ppc_disasm.cc | 3 + src/alloy/frontend/ppc/ppc_hir_builder.cc | 12 ++- src/alloy/frontend/ppc/ppc_hir_builder.h | 3 +- src/alloy/frontend/ppc/ppc_instr.cc | 1 + src/alloy/frontend/ppc/ppc_instr.h | 8 +- src/alloy/frontend/ppc/ppc_scanner.h | 2 + src/alloy/frontend/ppc/ppc_translator.h | 1 + src/alloy/hir/block.h | 1 + src/alloy/hir/hir_builder.cc | 1 + src/alloy/hir/hir_builder.h | 6 ++ src/alloy/hir/value.h | 3 + src/alloy/memory.cc | 2 +- src/alloy/runtime/debugger.h | 1 + src/alloy/runtime/entry_table.cc | 2 + src/alloy/runtime/module.cc | 1 + src/alloy/runtime/runtime.cc | 1 + src/alloy/runtime/thread_state.cc | 1 + src/alloy/sources.gypi | 1 + src/alloy/type_pool.h | 1 + src/alloy/vec128.h | 87 +++++++++++++++++++ src/poly/poly.h | 1 + src/xenia/gpu/shader_resource.h | 2 + src/xenia/hid/input_system.h | 2 + src/xenia/kernel/async_request.h | 2 + .../kernel/fs/devices/disc_image_entry.h | 2 + .../kernel/fs/devices/stfs_container_entry.h | 2 + 33 files changed, 146 insertions(+), 89 deletions(-) create mode 100644 src/alloy/vec128.h diff --git a/src/alloy/arena.cc b/src/alloy/arena.cc index d3a8992d8..66632e57d 100644 --- a/src/alloy/arena.cc +++ b/src/alloy/arena.cc @@ -9,6 +9,8 @@ #include +#include + namespace alloy { Arena::Arena(size_t chunk_size) diff --git a/src/alloy/backend/ivm/ivm_assembler.h b/src/alloy/backend/ivm/ivm_assembler.h index 446361647..eda2e864c 100644 --- a/src/alloy/backend/ivm/ivm_assembler.h +++ b/src/alloy/backend/ivm/ivm_assembler.h @@ -12,6 +12,7 @@ #include +#include #include namespace alloy { diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index 91181a9e7..a0d566a90 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -9,6 +9,7 @@ #include +#include #include #include #include diff --git a/src/alloy/backend/x64/x64_assembler.h b/src/alloy/backend/x64/x64_assembler.h index 769bee9db..9959a1135 100644 --- a/src/alloy/backend/x64/x64_assembler.h +++ b/src/alloy/backend/x64/x64_assembler.h @@ -14,6 +14,7 @@ #include +#include #include namespace alloy { diff --git a/src/alloy/backend/x64/x64_code_cache_win.cc b/src/alloy/backend/x64/x64_code_cache_win.cc index b5355cc46..f3e96455b 100644 --- a/src/alloy/backend/x64/x64_code_cache_win.cc +++ b/src/alloy/backend/x64/x64_code_cache_win.cc @@ -9,6 +9,8 @@ #include +#include + namespace alloy { namespace backend { namespace x64 { diff --git a/src/alloy/core.h b/src/alloy/core.h index 3d60666da..47633f886 100644 --- a/src/alloy/core.h +++ b/src/alloy/core.h @@ -20,82 +20,4 @@ #include #include -#include - -#include -#include -#include - -namespace alloy { - -typedef struct XECACHEALIGN vec128_s { - union { - struct { - float x; - float y; - float z; - float w; - }; - struct { - uint32_t ix; - uint32_t iy; - uint32_t iz; - uint32_t iw; - }; - float f4[4]; - uint32_t i4[4]; - uint16_t s8[8]; - uint8_t b16[16]; - struct { - uint64_t low; - uint64_t high; - }; - }; - - bool operator==(const vec128_s& b) const { - return low == b.low && high == b.high; - } -} vec128_t; -XEFORCEINLINE vec128_t vec128i(uint32_t x, uint32_t y, uint32_t z, uint32_t w) { - vec128_t v; - v.i4[0] = x; - v.i4[1] = y; - v.i4[2] = z; - v.i4[3] = w; - return v; -} -XEFORCEINLINE vec128_t vec128f(float x, float y, float z, float w) { - vec128_t v; - v.f4[0] = x; - v.f4[1] = y; - v.f4[2] = z; - v.f4[3] = w; - return v; -} -XEFORCEINLINE vec128_t vec128b(uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, - uint8_t y0, uint8_t y1, uint8_t y2, uint8_t y3, - uint8_t z0, uint8_t z1, uint8_t z2, uint8_t z3, - uint8_t w0, uint8_t w1, uint8_t w2, uint8_t w3) { - vec128_t v; - v.b16[0] = x3; - v.b16[1] = x2; - v.b16[2] = x1; - v.b16[3] = x0; - v.b16[4] = y3; - v.b16[5] = y2; - v.b16[6] = y1; - v.b16[7] = y0; - v.b16[8] = z3; - v.b16[9] = z2; - v.b16[10] = z1; - v.b16[11] = z0; - v.b16[12] = w3; - v.b16[13] = w2; - v.b16[14] = w1; - v.b16[15] = w0; - return v; -} - -} // namespace alloy - #endif // ALLOY_CORE_H_ diff --git a/src/alloy/frontend/ppc/ppc_context.h b/src/alloy/frontend/ppc/ppc_context.h index d1d28860a..6833f46cd 100644 --- a/src/alloy/frontend/ppc/ppc_context.h +++ b/src/alloy/frontend/ppc/ppc_context.h @@ -11,6 +11,7 @@ #define ALLOY_FRONTEND_PPC_PPC_CONTEXT_H_ #include +#include namespace alloy { namespace runtime { diff --git a/src/alloy/frontend/ppc/ppc_disasm.cc b/src/alloy/frontend/ppc/ppc_disasm.cc index 41f8c928a..8c832ce2f 100644 --- a/src/alloy/frontend/ppc/ppc_disasm.cc +++ b/src/alloy/frontend/ppc/ppc_disasm.cc @@ -9,6 +9,9 @@ #include +#include +#include + namespace alloy { namespace frontend { namespace ppc { diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index 38f72daab..0c466bd9e 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -31,11 +31,9 @@ using alloy::runtime::Runtime; using alloy::runtime::FunctionInfo; PPCHIRBuilder::PPCHIRBuilder(PPCFrontend* frontend) - : HIRBuilder(), frontend_(frontend) { - comment_buffer_ = new StringBuffer(4096); -} + : HIRBuilder(), frontend_(frontend), comment_buffer_(4096) {} -PPCHIRBuilder::~PPCHIRBuilder() { delete comment_buffer_; } +PPCHIRBuilder::~PPCHIRBuilder() = default; void PPCHIRBuilder::Reset() { start_address_ = 0; @@ -100,9 +98,9 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, bool with_debug_info) { if (label) { AnnotateLabel(address, label); } - comment_buffer_->Reset(); - DisasmPPC(i, comment_buffer_); - Comment("%.8X %.8X %s", address, i.code, comment_buffer_->GetString()); + comment_buffer_.Reset(); + DisasmPPC(i, &comment_buffer_); + Comment("%.8X %.8X %s", address, i.code, comment_buffer_.GetString()); first_instr = last_instr(); } diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.h b/src/alloy/frontend/ppc/ppc_hir_builder.h index 1a7f8e8d0..120bc4d3c 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.h +++ b/src/alloy/frontend/ppc/ppc_hir_builder.h @@ -11,6 +11,7 @@ #define ALLOY_FRONTEND_PPC_PPC_HIR_BUILDER_H_ #include +#include #include #include #include @@ -78,7 +79,7 @@ class PPCHIRBuilder : public hir::HIRBuilder { PPCFrontend* frontend_; // Reset whenever needed: - StringBuffer* comment_buffer_; + StringBuffer comment_buffer_; // Reset each Emit: bool with_debug_info_; diff --git a/src/alloy/frontend/ppc/ppc_instr.cc b/src/alloy/frontend/ppc/ppc_instr.cc index 251d07afe..df3a59206 100644 --- a/src/alloy/frontend/ppc/ppc_instr.cc +++ b/src/alloy/frontend/ppc/ppc_instr.cc @@ -12,6 +12,7 @@ #include #include +#include namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_instr.h b/src/alloy/frontend/ppc/ppc_instr.h index 80b8cc3d1..6baf95464 100644 --- a/src/alloy/frontend/ppc/ppc_instr.h +++ b/src/alloy/frontend/ppc/ppc_instr.h @@ -10,11 +10,15 @@ #ifndef ALLOY_FRONTEND_PPC_PPC_INSTR_H_ #define ALLOY_FRONTEND_PPC_PPC_INSTR_H_ -#include - #include #include +#include + +namespace alloy { +class StringBuffer; +} // namespace alloy + namespace alloy { namespace frontend { namespace ppc { diff --git a/src/alloy/frontend/ppc/ppc_scanner.h b/src/alloy/frontend/ppc/ppc_scanner.h index deb51dcdf..769b879d6 100644 --- a/src/alloy/frontend/ppc/ppc_scanner.h +++ b/src/alloy/frontend/ppc/ppc_scanner.h @@ -10,6 +10,8 @@ #ifndef ALLOY_FRONTEND_PPC_PPC_SCANNER_H_ #define ALLOY_FRONTEND_PPC_PPC_SCANNER_H_ +#include + #include #include diff --git a/src/alloy/frontend/ppc/ppc_translator.h b/src/alloy/frontend/ppc/ppc_translator.h index 22011d449..5b359f836 100644 --- a/src/alloy/frontend/ppc/ppc_translator.h +++ b/src/alloy/frontend/ppc/ppc_translator.h @@ -13,6 +13,7 @@ #include #include +#include #include #include #include diff --git a/src/alloy/hir/block.h b/src/alloy/hir/block.h index 4d2df2e9a..f79147697 100644 --- a/src/alloy/hir/block.h +++ b/src/alloy/hir/block.h @@ -10,6 +10,7 @@ #ifndef ALLOY_HIR_BLOCK_H_ #define ALLOY_HIR_BLOCK_H_ +#include #include XEDECLARECLASS1(llvm, BitVector); diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index 1ba6ce55d..11d9b836a 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -9,6 +9,7 @@ #include +#include #include #include #include diff --git a/src/alloy/hir/hir_builder.h b/src/alloy/hir/hir_builder.h index 9d01a69b6..4d6d53e7c 100644 --- a/src/alloy/hir/hir_builder.h +++ b/src/alloy/hir/hir_builder.h @@ -10,6 +10,8 @@ #ifndef ALLOY_HIR_HIR_BUILDER_H_ #define ALLOY_HIR_HIR_BUILDER_H_ +#include + #include #include #include @@ -17,6 +19,10 @@ #include #include +namespace alloy { +class StringBuffer; +} // namespace alloy + namespace alloy { namespace hir { diff --git a/src/alloy/hir/value.h b/src/alloy/hir/value.h index 38e4947e9..f88f5d6cd 100644 --- a/src/alloy/hir/value.h +++ b/src/alloy/hir/value.h @@ -11,8 +11,11 @@ #define ALLOY_HIR_VALUE_H_ #include +#include +#include #include #include +#include namespace alloy { namespace hir { diff --git a/src/alloy/memory.cc b/src/alloy/memory.cc index c334c31a4..b744a24b9 100644 --- a/src/alloy/memory.cc +++ b/src/alloy/memory.cc @@ -9,7 +9,7 @@ #include -#include +#include namespace alloy { diff --git a/src/alloy/runtime/debugger.h b/src/alloy/runtime/debugger.h index 1b09f3ab3..971443605 100644 --- a/src/alloy/runtime/debugger.h +++ b/src/alloy/runtime/debugger.h @@ -16,6 +16,7 @@ #include #include +#include namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/entry_table.cc b/src/alloy/runtime/entry_table.cc index aa0a41cbb..043623f4d 100644 --- a/src/alloy/runtime/entry_table.cc +++ b/src/alloy/runtime/entry_table.cc @@ -9,6 +9,8 @@ #include +#include + namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/module.cc b/src/alloy/runtime/module.cc index bf953bf1e..8184e2d53 100644 --- a/src/alloy/runtime/module.cc +++ b/src/alloy/runtime/module.cc @@ -13,6 +13,7 @@ #include #include +#include namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/runtime.cc b/src/alloy/runtime/runtime.cc index bca91c686..8f9ebd832 100644 --- a/src/alloy/runtime/runtime.cc +++ b/src/alloy/runtime/runtime.cc @@ -12,6 +12,7 @@ #include #include +#include // TODO(benvanik): based on compiler support #include diff --git a/src/alloy/runtime/thread_state.cc b/src/alloy/runtime/thread_state.cc index c2469b3c5..80b5ad71a 100644 --- a/src/alloy/runtime/thread_state.cc +++ b/src/alloy/runtime/thread_state.cc @@ -10,6 +10,7 @@ #include #include +#include namespace alloy { namespace runtime { diff --git a/src/alloy/sources.gypi b/src/alloy/sources.gypi index c912345b5..0854a8bc1 100644 --- a/src/alloy/sources.gypi +++ b/src/alloy/sources.gypi @@ -14,6 +14,7 @@ 'string_buffer.cc', 'string_buffer.h', 'type_pool.h', + 'vec128.h', ], 'conditions': [ diff --git a/src/alloy/type_pool.h b/src/alloy/type_pool.h index 57be0b36e..6483c9514 100644 --- a/src/alloy/type_pool.h +++ b/src/alloy/type_pool.h @@ -11,6 +11,7 @@ #define ALLOY_TYPE_POOL_H_ #include +#include #include diff --git a/src/alloy/vec128.h b/src/alloy/vec128.h new file mode 100644 index 000000000..7d251b0ff --- /dev/null +++ b/src/alloy/vec128.h @@ -0,0 +1,87 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef ALLOY_VEC128_H_ +#define ALLOY_VEC128_H_ + +#include + +namespace alloy { + +typedef struct XECACHEALIGN vec128_s { + union { + struct { + float x; + float y; + float z; + float w; + }; + struct { + uint32_t ix; + uint32_t iy; + uint32_t iz; + uint32_t iw; + }; + float f4[4]; + uint32_t i4[4]; + uint16_t s8[8]; + uint8_t b16[16]; + struct { + uint64_t low; + uint64_t high; + }; + }; + + bool operator==(const vec128_s& b) const { + return low == b.low && high == b.high; + } +} vec128_t; +XEFORCEINLINE vec128_t vec128i(uint32_t x, uint32_t y, uint32_t z, uint32_t w) { + vec128_t v; + v.i4[0] = x; + v.i4[1] = y; + v.i4[2] = z; + v.i4[3] = w; + return v; +} +XEFORCEINLINE vec128_t vec128f(float x, float y, float z, float w) { + vec128_t v; + v.f4[0] = x; + v.f4[1] = y; + v.f4[2] = z; + v.f4[3] = w; + return v; +} +XEFORCEINLINE vec128_t vec128b(uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, + uint8_t y0, uint8_t y1, uint8_t y2, uint8_t y3, + uint8_t z0, uint8_t z1, uint8_t z2, uint8_t z3, + uint8_t w0, uint8_t w1, uint8_t w2, uint8_t w3) { + vec128_t v; + v.b16[0] = x3; + v.b16[1] = x2; + v.b16[2] = x1; + v.b16[3] = x0; + v.b16[4] = y3; + v.b16[5] = y2; + v.b16[6] = y1; + v.b16[7] = y0; + v.b16[8] = z3; + v.b16[9] = z2; + v.b16[10] = z1; + v.b16[11] = z0; + v.b16[12] = w3; + v.b16[13] = w2; + v.b16[14] = w1; + v.b16[15] = w0; + return v; +} + +} // namespace alloy + +#endif // ALLOY_VEC128_H_ diff --git a/src/poly/poly.h b/src/poly/poly.h index b7af898ff..5b5c4b92e 100644 --- a/src/poly/poly.h +++ b/src/poly/poly.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/src/xenia/gpu/shader_resource.h b/src/xenia/gpu/shader_resource.h index b591bfaf2..85414daf8 100644 --- a/src/xenia/gpu/shader_resource.h +++ b/src/xenia/gpu/shader_resource.h @@ -10,6 +10,8 @@ #ifndef XENIA_GPU_SHADER_RESOURCE_H_ #define XENIA_GPU_SHADER_RESOURCE_H_ +#include + #include #include #include diff --git a/src/xenia/hid/input_system.h b/src/xenia/hid/input_system.h index a86fc8525..cb8d33019 100644 --- a/src/xenia/hid/input_system.h +++ b/src/xenia/hid/input_system.h @@ -10,6 +10,8 @@ #ifndef XENIA_HID_INPUT_SYSTEM_H_ #define XENIA_HID_INPUT_SYSTEM_H_ +#include + #include #include diff --git a/src/xenia/kernel/async_request.h b/src/xenia/kernel/async_request.h index 40317ea4a..0af0ac6f2 100644 --- a/src/xenia/kernel/async_request.h +++ b/src/xenia/kernel/async_request.h @@ -10,6 +10,8 @@ #ifndef XENIA_KERNEL_XBOXKRNL_ASYNC_REQUEST_H_ #define XENIA_KERNEL_XBOXKRNL_ASYNC_REQUEST_H_ +#include + #include #include diff --git a/src/xenia/kernel/fs/devices/disc_image_entry.h b/src/xenia/kernel/fs/devices/disc_image_entry.h index 4ed31b5ef..bbe788a3b 100644 --- a/src/xenia/kernel/fs/devices/disc_image_entry.h +++ b/src/xenia/kernel/fs/devices/disc_image_entry.h @@ -10,6 +10,8 @@ #ifndef XENIA_KERNEL_FS_DEVICES_DISC_IMAGE_ENTRY_H_ #define XENIA_KERNEL_FS_DEVICES_DISC_IMAGE_ENTRY_H_ +#include + #include #include diff --git a/src/xenia/kernel/fs/devices/stfs_container_entry.h b/src/xenia/kernel/fs/devices/stfs_container_entry.h index 2f9129595..8858a3441 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_entry.h +++ b/src/xenia/kernel/fs/devices/stfs_container_entry.h @@ -10,6 +10,8 @@ #ifndef XENIA_KERNEL_FS_DEVICES_STFS_CONTAINER_ENTRY_H_ #define XENIA_KERNEL_FS_DEVICES_STFS_CONTAINER_ENTRY_H_ +#include + #include #include From ec4f41fec41b1a43fd700b7c643e19cce718716c Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 17 Jul 2014 19:20:17 -0700 Subject: [PATCH 033/388] Moving byte order/memory access to poly. --- src/alloy/backend/ivm/ivm_intcode.cc | 50 ++--- src/alloy/core.h | 1 - src/alloy/frontend/ppc/ppc_emit_altivec.cc | 4 +- src/alloy/frontend/ppc/ppc_hir_builder.cc | 2 +- src/alloy/frontend/ppc/ppc_scanner.cc | 5 +- src/alloy/frontend/ppc/ppc_translator.cc | 2 +- src/alloy/hir/value.cc | 8 +- src/poly/byte_order.h | 61 ++++++ src/poly/memory.h | 175 +++++++++++++++++- src/poly/poly.h | 1 + src/poly/sources.gypi | 1 + src/xenia/apu/audio_system.cc | 2 +- src/xenia/apu/xaudio2/xaudio2_audio_driver.cc | 2 +- src/xenia/byte_order.h | 120 ------------ src/xenia/common.h | 3 +- src/xenia/core/crc32.cc | 2 +- src/xenia/core/hash.cc | 14 +- src/xenia/cpu/processor.cc | 2 +- src/xenia/cpu/xenon_memory.cc | 12 +- src/xenia/cpu/xex_module.cc | 16 +- src/xenia/gpu/command_processor.cc | 22 +-- src/xenia/gpu/d3d11/d3d11_buffer_resource.cc | 6 +- src/xenia/gpu/shader_resource.cc | 2 +- src/xenia/gpu/texture_resource.cc | 4 +- src/xenia/gpu/xenos/xenos.h | 2 +- src/xenia/kernel/fs/gdfx.cc | 16 +- src/xenia/kernel/fs/stfs.cc | 78 ++++---- src/xenia/kernel/native_list.cc | 24 +-- src/xenia/kernel/objects/xfile.h | 50 ++--- src/xenia/kernel/objects/xthread.cc | 52 +++--- src/xenia/kernel/util/shim_utils.h | 24 +-- src/xenia/kernel/util/xex2.cc | 140 +++++++------- src/xenia/kernel/xboxkrnl_audio.cc | 2 +- src/xenia/kernel/xboxkrnl_io.cc | 2 +- src/xenia/kernel/xboxkrnl_module.cc | 26 +-- src/xenia/kernel/xboxkrnl_modules.cc | 2 +- src/xenia/kernel/xboxkrnl_rtl.cc | 8 +- src/xenia/kernel/xboxkrnl_strings.cc | 12 +- src/xenia/kernel/xboxkrnl_video.cc | 30 +-- src/xenia/kernel/xobject.cc | 24 +-- src/xenia/sources.gypi | 1 - src/xenia/xbox.h | 84 ++++----- 42 files changed, 608 insertions(+), 486 deletions(-) create mode 100644 src/poly/byte_order.h delete mode 100644 src/xenia/byte_order.h diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index a0d566a90..fdc4ed8d7 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -1405,7 +1405,7 @@ uint32_t IntCode_LOAD_I16(IntCodeState& ics, const IntCode* i) { uint32_t address = ics.rf[i->src1_reg].u32; if (DYNAMIC_REGISTER_ACCESS_CHECK(address)) { ics.rf[i->dest_reg].i16 = - XESWAP16(ics.thread_state->memory()->LoadI16(address)); + poly::byte_swap(ics.thread_state->memory()->LoadI16(address)); return IA_NEXT; } DPRINT("%d (%X) = load.i16 %.8X\n", *((int16_t*)(ics.membase + address)), @@ -1418,7 +1418,7 @@ uint32_t IntCode_LOAD_I32(IntCodeState& ics, const IntCode* i) { uint32_t address = ics.rf[i->src1_reg].u32; if (DYNAMIC_REGISTER_ACCESS_CHECK(address)) { ics.rf[i->dest_reg].i32 = - XESWAP32(ics.thread_state->memory()->LoadI32(address)); + poly::byte_swap(ics.thread_state->memory()->LoadI32(address)); return IA_NEXT; } DFLUSH(); @@ -1432,7 +1432,7 @@ uint32_t IntCode_LOAD_I64(IntCodeState& ics, const IntCode* i) { uint32_t address = ics.rf[i->src1_reg].u32; if (DYNAMIC_REGISTER_ACCESS_CHECK(address)) { ics.rf[i->dest_reg].i64 = - XESWAP64(ics.thread_state->memory()->LoadI64(address)); + poly::byte_swap(ics.thread_state->memory()->LoadI64(address)); return IA_NEXT; } DPRINT("%lld (%llX) = load.i64 %.8X\n", *((int64_t*)(ics.membase + address)), @@ -1498,8 +1498,8 @@ uint32_t IntCode_STORE_I8(IntCodeState& ics, const IntCode* i) { uint32_t IntCode_STORE_I16(IntCodeState& ics, const IntCode* i) { uint32_t address = ics.rf[i->src1_reg].u32; if (DYNAMIC_REGISTER_ACCESS_CHECK(address)) { - ics.thread_state->memory()->StoreI16(address, - XESWAP16(ics.rf[i->src2_reg].i16)); + ics.thread_state->memory()->StoreI16( + address, poly::byte_swap(ics.rf[i->src2_reg].i16)); return IA_NEXT; } DPRINT("store.i16 %.8X = %d (%X)\n", address, ics.rf[i->src2_reg].i16, @@ -1512,8 +1512,8 @@ uint32_t IntCode_STORE_I16(IntCodeState& ics, const IntCode* i) { uint32_t IntCode_STORE_I32(IntCodeState& ics, const IntCode* i) { uint32_t address = ics.rf[i->src1_reg].u32; if (DYNAMIC_REGISTER_ACCESS_CHECK(address)) { - ics.thread_state->memory()->StoreI32(address, - XESWAP32(ics.rf[i->src2_reg].i32)); + ics.thread_state->memory()->StoreI32( + address, poly::byte_swap(ics.rf[i->src2_reg].i32)); return IA_NEXT; } DPRINT("store.i32 %.8X = %d (%X)\n", address, ics.rf[i->src2_reg].i32, @@ -1526,8 +1526,8 @@ uint32_t IntCode_STORE_I32(IntCodeState& ics, const IntCode* i) { uint32_t IntCode_STORE_I64(IntCodeState& ics, const IntCode* i) { uint32_t address = ics.rf[i->src1_reg].u32; if (DYNAMIC_REGISTER_ACCESS_CHECK(address)) { - ics.thread_state->memory()->StoreI64(address, - XESWAP64(ics.rf[i->src2_reg].i64)); + ics.thread_state->memory()->StoreI64( + address, poly::byte_swap(ics.rf[i->src2_reg].i64)); return IA_NEXT; } DPRINT("store.i64 %.8X = %lld (%llX)\n", address, ics.rf[i->src2_reg].i64, @@ -2210,13 +2210,13 @@ int Translate_VECTOR_COMPARE_SGT(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, fns[i->flags]); } -uint32_t IntCode_VECTOR_COMPARE_SGE_I8(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_VECTOR_COMPARE_SGE_I8(IntCodeState& ics, const IntCode* i){ VECTOR_COMPARER(int8_t, b16, b16, 16, >= )}; -uint32_t IntCode_VECTOR_COMPARE_SGE_I16(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_VECTOR_COMPARE_SGE_I16(IntCodeState& ics, const IntCode* i){ VECTOR_COMPARER(int16_t, s8, s8, 8, >= )}; -uint32_t IntCode_VECTOR_COMPARE_SGE_I32(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_VECTOR_COMPARE_SGE_I32(IntCodeState& ics, const IntCode* i){ VECTOR_COMPARER(int32_t, i4, i4, 4, >= )}; -uint32_t IntCode_VECTOR_COMPARE_SGE_F32(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_VECTOR_COMPARE_SGE_F32(IntCodeState& ics, const IntCode* i){ VECTOR_COMPARER(float, f4, i4, 4, >= )}; int Translate_VECTOR_COMPARE_SGE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { @@ -2228,13 +2228,13 @@ int Translate_VECTOR_COMPARE_SGE(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, fns[i->flags]); } -uint32_t IntCode_VECTOR_COMPARE_UGT_I8(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_VECTOR_COMPARE_UGT_I8(IntCodeState& ics, const IntCode* i){ VECTOR_COMPARER(uint8_t, b16, b16, 16, > )}; -uint32_t IntCode_VECTOR_COMPARE_UGT_I16(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_VECTOR_COMPARE_UGT_I16(IntCodeState& ics, const IntCode* i){ VECTOR_COMPARER(uint16_t, s8, s8, 8, > )}; -uint32_t IntCode_VECTOR_COMPARE_UGT_I32(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_VECTOR_COMPARE_UGT_I32(IntCodeState& ics, const IntCode* i){ VECTOR_COMPARER(uint32_t, i4, i4, 4, > )}; -uint32_t IntCode_VECTOR_COMPARE_UGT_F32(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_VECTOR_COMPARE_UGT_F32(IntCodeState& ics, const IntCode* i){ VECTOR_COMPARER(float, f4, i4, 4, > )}; int Translate_VECTOR_COMPARE_UGT(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { @@ -2246,13 +2246,13 @@ int Translate_VECTOR_COMPARE_UGT(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, fns[i->flags]); } -uint32_t IntCode_VECTOR_COMPARE_UGE_I8(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_VECTOR_COMPARE_UGE_I8(IntCodeState& ics, const IntCode* i){ VECTOR_COMPARER(uint8_t, b16, b16, 16, >= )}; -uint32_t IntCode_VECTOR_COMPARE_UGE_I16(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_VECTOR_COMPARE_UGE_I16(IntCodeState& ics, const IntCode* i){ VECTOR_COMPARER(uint16_t, s8, s8, 8, >= )}; -uint32_t IntCode_VECTOR_COMPARE_UGE_I32(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_VECTOR_COMPARE_UGE_I32(IntCodeState& ics, const IntCode* i){ VECTOR_COMPARER(uint32_t, i4, i4, 4, >= )}; -uint32_t IntCode_VECTOR_COMPARE_UGE_F32(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_VECTOR_COMPARE_UGE_F32(IntCodeState& ics, const IntCode* i){ VECTOR_COMPARER(float, f4, i4, 4, >= )}; int Translate_VECTOR_COMPARE_UGE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { @@ -3526,22 +3526,22 @@ int Translate_ROTATE_LEFT(TranslationContext& ctx, Instr* i) { } uint32_t IntCode_BYTE_SWAP_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = XESWAP16(ics.rf[i->src1_reg].i16); + ics.rf[i->dest_reg].i16 = poly::byte_swap(ics.rf[i->src1_reg].i16); return IA_NEXT; } uint32_t IntCode_BYTE_SWAP_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = XESWAP32(ics.rf[i->src1_reg].i32); + ics.rf[i->dest_reg].i32 = poly::byte_swap(ics.rf[i->src1_reg].i32); return IA_NEXT; } uint32_t IntCode_BYTE_SWAP_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = XESWAP64(ics.rf[i->src1_reg].i64); + ics.rf[i->dest_reg].i64 = poly::byte_swap(ics.rf[i->src1_reg].i64); return IA_NEXT; } uint32_t IntCode_BYTE_SWAP_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - VECI4(dest, n) = XESWAP32(VECI4(src1, n)); + VECI4(dest, n) = poly::byte_swap(VECI4(src1, n)); } return IA_NEXT; } diff --git a/src/alloy/core.h b/src/alloy/core.h index 47633f886..f5fd3040c 100644 --- a/src/alloy/core.h +++ b/src/alloy/core.h @@ -11,7 +11,6 @@ #define ALLOY_CORE_H_ // TODO(benvanik): move the common stuff into here? -#include #include #include #include diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index c3a4b5db8..b52102555 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -1343,7 +1343,9 @@ int InstrEmit_vsldoi_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, // (ABCD ABCD) << 4b = (BCDA) // (VA << SH) OR (VB >> (16 - SH)) vec128_t shift = *((vec128_t*)(__vsldoi_table[sh])); - for (int i = 0; i < 4; ++i) shift.i4[i] = XESWAP32BE(shift.i4[i]); + for (int i = 0; i < 4; ++i) { + shift.i4[i] = poly::byte_swap(shift.i4[i]); + } Value* control = f.LoadConstant(shift); Value* v = f.Permute(control, f.LoadVR(va), f.LoadVR(vb), INT8_TYPE); f.StoreVR(vd, v); diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index 0c466bd9e..8f0977992 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -81,7 +81,7 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, bool with_debug_info) { for (uint64_t address = start_address, offset = 0; address <= end_address; address += 4, offset++) { i.address = address; - i.code = XEGETUINT32BE(p + address); + i.code = poly::load_and_swap(p + address); // TODO(benvanik): find a way to avoid using the opcode tables. i.type = GetInstrType(i.code); diff --git a/src/alloy/frontend/ppc/ppc_scanner.cc b/src/alloy/frontend/ppc/ppc_scanner.cc index 4244ab65c..f23d10623 100644 --- a/src/alloy/frontend/ppc/ppc_scanner.cc +++ b/src/alloy/frontend/ppc/ppc_scanner.cc @@ -14,6 +14,7 @@ #include #include #include +#include namespace alloy { namespace frontend { @@ -58,7 +59,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { InstrData i; while (true) { i.address = address; - i.code = XEGETUINT32BE(p + address); + i.code = poly::load_and_swap(p + address); // If we fetched 0 assume that we somehow hit one of the awesome // 'no really we meant to end after that bl' functions. @@ -291,7 +292,7 @@ std::vector PPCScanner::FindBlocks(FunctionInfo* symbol_info) { InstrData i; for (uint64_t address = start_address; address <= end_address; address += 4) { i.address = address; - i.code = XEGETUINT32BE(p + address); + i.code = poly::load_and_swap(p + address); if (!i.code) { continue; } diff --git a/src/alloy/frontend/ppc/ppc_translator.cc b/src/alloy/frontend/ppc/ppc_translator.cc index 92897ea0b..ab7404b61 100644 --- a/src/alloy/frontend/ppc/ppc_translator.cc +++ b/src/alloy/frontend/ppc/ppc_translator.cc @@ -174,7 +174,7 @@ void PPCTranslator::DumpSource(runtime::FunctionInfo* symbol_info, for (uint64_t address = start_address, offset = 0; address <= end_address; address += 4, offset++) { i.address = address; - i.code = XEGETUINT32BE(p + address); + i.code = poly::load_and_swap(p + address); // TODO(benvanik): find a way to avoid using the opcode tables. i.type = GetInstrType(i.code); diff --git a/src/alloy/hir/value.cc b/src/alloy/hir/value.cc index 770bdfe53..211481c93 100644 --- a/src/alloy/hir/value.cc +++ b/src/alloy/hir/value.cc @@ -572,17 +572,17 @@ void Value::ByteSwap() { constant.i8 = constant.i8; break; case INT16_TYPE: - constant.i16 = XESWAP16(constant.i16); + constant.i16 = poly::byte_swap(constant.i16); break; case INT32_TYPE: - constant.i32 = XESWAP32(constant.i32); + constant.i32 = poly::byte_swap(constant.i32); break; case INT64_TYPE: - constant.i64 = XESWAP64(constant.i64); + constant.i64 = poly::byte_swap(constant.i64); break; case VEC128_TYPE: for (int n = 0; n < 4; n++) { - constant.v128.i4[n] = XESWAP32(constant.v128.i4[n]); + constant.v128.i4[n] = poly::byte_swap(constant.v128.i4[n]); } break; default: diff --git a/src/poly/byte_order.h b/src/poly/byte_order.h new file mode 100644 index 000000000..ab6e4d0e4 --- /dev/null +++ b/src/poly/byte_order.h @@ -0,0 +1,61 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef POLY_BYTE_ORDER_H_ +#define POLY_BYTE_ORDER_H_ + +#include + +#include +#include + +#if XE_LIKE_OSX +#include +#endif // XE_LIKE_OSX + +namespace poly { + +#if XE_COMPILER_MSVC +#define POLY_BYTE_SWAP_16 _byteswap_ushort +#define POLY_BYTE_SWAP_32 _byteswap_ulong +#define POLY_BYTE_SWAP_64 _byteswap_uint64 +#elif XE_LIKE_OSX +#define POLY_BYTE_SWAP_16 OSSwapInt16 +#define POLY_BYTE_SWAP_32 OSSwapInt32 +#define POLY_BYTE_SWAP_64 OSSwapInt64 +#else +#define POLY_BYTE_SWAP_16 __bswap_16 +#define POLY_BYTE_SWAP_32 __bswap_32 +#define POLY_BYTE_SWAP_64 __bswap_64 +#endif // XE_COMPILER_MSVC + +inline int16_t byte_swap(int16_t value) { + return static_cast(POLY_BYTE_SWAP_16(static_cast(value))); +} +inline uint16_t byte_swap(uint16_t value) { return POLY_BYTE_SWAP_16(value); } +inline int32_t byte_swap(int32_t value) { + return static_cast(POLY_BYTE_SWAP_32(static_cast(value))); +} +inline uint32_t byte_swap(uint32_t value) { return POLY_BYTE_SWAP_32(value); } +inline int64_t byte_swap(int64_t value) { + return static_cast(POLY_BYTE_SWAP_64(static_cast(value))); +} +inline uint64_t byte_swap(uint64_t value) { return POLY_BYTE_SWAP_64(value); } +inline float byte_swap(float value) { + uint32_t temp = byte_swap(*reinterpret_cast(&value)); + return *reinterpret_cast(&temp); +} +inline double byte_swap(double value) { + uint64_t temp = byte_swap(*reinterpret_cast(&value)); + return *reinterpret_cast(&temp); +} + +} // namespace poly + +#endif // POLY_BYTE_ORDER_H_ diff --git a/src/poly/memory.h b/src/poly/memory.h index 01dbc608e..a8a26c95f 100644 --- a/src/poly/memory.h +++ b/src/poly/memory.h @@ -10,13 +10,184 @@ #ifndef POLY_MEMORY_H_ #define POLY_MEMORY_H_ -#include -#include +#include namespace poly { size_t page_size(); +template +T load(const void* mem); +template <> +inline int8_t load(const void* mem) { + return *reinterpret_cast(mem); +} +template <> +inline uint8_t load(const void* mem) { + return *reinterpret_cast(mem); +} +template <> +inline int16_t load(const void* mem) { + return *reinterpret_cast(mem); +} +template <> +inline uint16_t load(const void* mem) { + return *reinterpret_cast(mem); +} +template <> +inline int32_t load(const void* mem) { + return *reinterpret_cast(mem); +} +template <> +inline uint32_t load(const void* mem) { + return *reinterpret_cast(mem); +} +template <> +inline int64_t load(const void* mem) { + return *reinterpret_cast(mem); +} +template <> +inline uint64_t load(const void* mem) { + return *reinterpret_cast(mem); +} +template <> +inline float load(const void* mem) { + return *reinterpret_cast(mem); +} +template <> +inline double load(const void* mem) { + return *reinterpret_cast(mem); +} + +template +T load_and_swap(const void* mem); +template <> +inline int8_t load_and_swap(const void* mem) { + return *reinterpret_cast(mem); +} +template <> +inline uint8_t load_and_swap(const void* mem) { + return *reinterpret_cast(mem); +} +template <> +inline int16_t load_and_swap(const void* mem) { + return byte_swap(*reinterpret_cast(mem)); +} +template <> +inline uint16_t load_and_swap(const void* mem) { + return byte_swap(*reinterpret_cast(mem)); +} +template <> +inline int32_t load_and_swap(const void* mem) { + return byte_swap(*reinterpret_cast(mem)); +} +template <> +inline uint32_t load_and_swap(const void* mem) { + return byte_swap(*reinterpret_cast(mem)); +} +template <> +inline int64_t load_and_swap(const void* mem) { + return byte_swap(*reinterpret_cast(mem)); +} +template <> +inline uint64_t load_and_swap(const void* mem) { + return byte_swap(*reinterpret_cast(mem)); +} +template <> +inline float load_and_swap(const void* mem) { + return byte_swap(*reinterpret_cast(mem)); +} +template <> +inline double load_and_swap(const void* mem) { + return byte_swap(*reinterpret_cast(mem)); +} + +template +void store(void* mem, T value); +template <> +inline void store(void* mem, int8_t value) { + *reinterpret_cast(mem) = value; +} +template <> +inline void store(void* mem, uint8_t value) { + *reinterpret_cast(mem) = value; +} +template <> +inline void store(void* mem, int16_t value) { + *reinterpret_cast(mem) = value; +} +template <> +inline void store(void* mem, uint16_t value) { + *reinterpret_cast(mem) = value; +} +template <> +inline void store(void* mem, int32_t value) { + *reinterpret_cast(mem) = value; +} +template <> +inline void store(void* mem, uint32_t value) { + *reinterpret_cast(mem) = value; +} +template <> +inline void store(void* mem, int64_t value) { + *reinterpret_cast(mem) = value; +} +template <> +inline void store(void* mem, uint64_t value) { + *reinterpret_cast(mem) = value; +} +template <> +inline void store(void* mem, float value) { + *reinterpret_cast(mem) = value; +} +template <> +inline void store(void* mem, double value) { + *reinterpret_cast(mem) = value; +} + +template +void store_and_swap(void* mem, T value); +template <> +inline void store_and_swap(void* mem, int8_t value) { + *reinterpret_cast(mem) = value; +} +template <> +inline void store_and_swap(void* mem, uint8_t value) { + *reinterpret_cast(mem) = value; +} +template <> +inline void store_and_swap(void* mem, int16_t value) { + *reinterpret_cast(mem) = byte_swap(value); +} +template <> +inline void store_and_swap(void* mem, uint16_t value) { + *reinterpret_cast(mem) = byte_swap(value); +} +template <> +inline void store_and_swap(void* mem, int32_t value) { + *reinterpret_cast(mem) = byte_swap(value); +} +template <> +inline void store_and_swap(void* mem, uint32_t value) { + *reinterpret_cast(mem) = byte_swap(value); +} +template <> +inline void store_and_swap(void* mem, int64_t value) { + *reinterpret_cast(mem) = byte_swap(value); +} +template <> +inline void store_and_swap(void* mem, uint64_t value) { + *reinterpret_cast(mem) = byte_swap(value); +} +template <> +inline void store_and_swap(void* mem, float value) { + *reinterpret_cast(mem) = byte_swap(value); +} +template <> +inline void store_and_swap(void* mem, double value) { + *reinterpret_cast(mem) = byte_swap(value); +} + } // namespace poly #endif // POLY_MEMORY_H_ diff --git a/src/poly/poly.h b/src/poly/poly.h index 5b5c4b92e..80700dac8 100644 --- a/src/poly/poly.h +++ b/src/poly/poly.h @@ -12,6 +12,7 @@ #include #include +#include #include #include #include diff --git a/src/poly/sources.gypi b/src/poly/sources.gypi index a58841268..49154f817 100644 --- a/src/poly/sources.gypi +++ b/src/poly/sources.gypi @@ -3,6 +3,7 @@ 'sources': [ 'assert.h', 'atomic.h', + 'byte_order.h', 'config.h', 'cxx_compat.h', 'math.cc', diff --git a/src/xenia/apu/audio_system.cc b/src/xenia/apu/audio_system.cc index 214620494..464211411 100644 --- a/src/xenia/apu/audio_system.cc +++ b/src/xenia/apu/audio_system.cc @@ -149,7 +149,7 @@ X_STATUS AudioSystem::RegisterClient( uint32_t ptr = (uint32_t)memory()->HeapAlloc(0, 0x4, 0); auto mem = memory()->membase(); - XESETUINT32BE(mem + ptr, callback_arg); + poly::store_and_swap(mem + ptr, callback_arg); clients_[index] = { driver, callback, callback_arg, ptr }; diff --git a/src/xenia/apu/xaudio2/xaudio2_audio_driver.cc b/src/xenia/apu/xaudio2/xaudio2_audio_driver.cc index 7be6c9d55..4360ad5f5 100644 --- a/src/xenia/apu/xaudio2/xaudio2_audio_driver.cc +++ b/src/xenia/apu/xaudio2/xaudio2_audio_driver.cc @@ -131,7 +131,7 @@ void XAudio2AudioDriver::SubmitFrame(uint32_t frame_ptr) { // interleave the data for (int index = 0, o = 0; index < channel_samples_; ++index) { for (int channel = 0, table = 0; channel < interleave_channels; ++channel, table += channel_samples_) { - output_frame[o++] = XESWAPF32BE(input_frame[table + index]); + output_frame[o++] = poly::byte_swap(input_frame[table + index]); } } diff --git a/src/xenia/byte_order.h b/src/xenia/byte_order.h deleted file mode 100644 index 0bdedd717..000000000 --- a/src/xenia/byte_order.h +++ /dev/null @@ -1,120 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_BYTE_ORDER_H_ -#define XENIA_BYTE_ORDER_H_ - -#include - -#include -#include - - -#if XE_COMPILER_MSVC -#define XESWAP16 _byteswap_ushort -#define XESWAP32 _byteswap_ulong -#define XESWAP64 _byteswap_uint64 -#elif XE_LIKE_OSX -#include -#define XESWAP16 OSSwapInt16 -#define XESWAP32 OSSwapInt32 -#define XESWAP64 OSSwapInt64 -#else -#define XESWAP16 __bswap_16 -#define XESWAP32 __bswap_32 -#define XESWAP64 __bswap_64 -#endif - - -#if XE_CPU_BIGENDIAN -#define XESWAP16BE(p) (p) -#define XESWAP32BE(p) (p) -#define XESWAP64BE(p) (p) -#define XESWAP16LE(p) XESWAP16(p) -#define XESWAP32LE(p) XESWAP32(p) -#define XESWAP64LE(p) XESWAP64(p) -#else -#define XESWAP16BE(p) XESWAP16(p) -#define XESWAP32BE(p) XESWAP32(p) -#define XESWAP64BE(p) XESWAP64(p) -#define XESWAP16LE(p) (p) -#define XESWAP32LE(p) (p) -#define XESWAP64LE(p) (p) -#endif - - -#if XE_CPU_BIGENDIAN -#define XESWAPF32BE(p) (p) -#define XESWAPF64BE(p) (p) -XEFORCEINLINE float XESWAPF32LE(float value) { - uint32_t dummy = XESWAP32LE(*reinterpret_cast(&value)); - return *reinterpret_cast(&dummy); -} -XEFORCEINLINE double XESWAPF64LE(double value) { - uint64_t dummy = XESWAP64LE(*reinterpret_cast(&value)); - return *reinterpret_cast(&dummy); -} -#else -XEFORCEINLINE float XESWAPF32BE(float value) { - uint32_t dummy = XESWAP32BE(*reinterpret_cast(&value)); - return *reinterpret_cast(&dummy); -} -XEFORCEINLINE double XESWAPF64BE(double value) { - uint64_t dummy = XESWAP64BE(*reinterpret_cast(&value)); - return *reinterpret_cast(&dummy); -} -#define XESWAPF32LE(p) (p) -#define XESWAPF64LE(p) (p) -#endif - - -#define XEGETINT8BE(p) ( (int8_t)(*(p))) -#define XEGETUINT8BE(p) ( (uint8_t)(*(p))) -#define XEGETINT16BE(p) ( (int16_t)XESWAP16BE(*(uint16_t*)(p))) -#define XEGETUINT16BE(p) ((uint16_t)XESWAP16BE(*(uint16_t*)(p))) -#define XEGETUINT24BE(p) \ - (((uint32_t)XEGETUINT8BE((p) + 0) << 16) | \ - ((uint32_t)XEGETUINT8BE((p) + 1) << 8) | \ - (uint32_t)XEGETUINT8BE((p) + 2)) -#define XEGETINT32BE(p) ( (int32_t)XESWAP32BE(*(uint32_t*)(p))) -#define XEGETUINT32BE(p) ((uint32_t)XESWAP32BE(*(uint32_t*)(p))) -#define XEGETINT64BE(p) ( (int64_t)XESWAP64BE(*(uint64_t*)(p))) -#define XEGETUINT64BE(p) ((uint64_t)XESWAP64BE(*(uint64_t*)(p))) -#define XEGETINT8LE(p) ( (int8_t)(*(p))) -#define XEGETUINT8LE(p) ( (uint8_t)(*(p))) -#define XEGETINT16LE(p) ( (int16_t)XESWAP16LE(*(uint16_t*)(p))) -#define XEGETUINT16LE(p) ((uint16_t)XESWAP16LE(*(uint16_t*)(p))) -#define XEGETUINT24LE(p) \ - (((uint32_t)XEGETUINT8LE((p) + 2) << 16) | \ - ((uint32_t)XEGETUINT8LE((p) + 1) << 8) | \ - (uint32_t)XEGETUINT8LE((p) + 0)) -#define XEGETINT32LE(p) ( (int32_t)XESWAP32LE(*(uint32_t*)(p))) -#define XEGETUINT32LE(p) ((uint32_t)XESWAP32LE(*(uint32_t*)(p))) -#define XEGETINT64LE(p) ( (int64_t)XESWAP64LE(*(uint64_t*)(p))) -#define XEGETUINT64LE(p) ((uint64_t)XESWAP64LE(*(uint64_t*)(p))) - -#define XESETINT8BE(p, v) (*( (int8_t*)(p)) = (int8_t)v) -#define XESETUINT8BE(p, v) (*( (uint8_t*)(p)) = (uint8_t)v) -#define XESETINT16BE(p, v) (*( (int16_t*)(p)) = XESWAP16BE( (int16_t)v)) -#define XESETUINT16BE(p, v) (*((uint16_t*)(p)) = XESWAP16BE((uint16_t)v)) -#define XESETINT32BE(p, v) (*( (int32_t*)(p)) = XESWAP32BE( (int32_t)v)) -#define XESETUINT32BE(p, v) (*((uint32_t*)(p)) = XESWAP32BE((uint32_t)v)) -#define XESETINT64BE(p, v) (*( (int64_t*)(p)) = XESWAP64BE( (int64_t)v)) -#define XESETUINT64BE(p, v) (*((uint64_t*)(p)) = XESWAP64BE((uint64_t)v)) -#define XESETINT8LE(p, v) (*( (int8_t*)(p)) = (int8_t)v) -#define XESETUINT8LE(p, v) (*( (uint8_t*)(p)) = (uint8_t)v) -#define XESETINT16LE(p, v) (*( (int16_t*)(p)) = (int16_t)v) -#define XESETUINT16LE(p, v) (*((uint16_t*)(p)) = (uint16_t)v) -#define XESETINT32LE(p, v) (*( (int32_t*)(p)) = (int32_t)v) -#define XESETUINT32LE(p, v) (*((uint32_t*)(p)) = (uint32_t)v) -#define XESETINT64LE(p, v) (*( (int64_t*)(p)) = (int64_t)v) -#define XESETUINT64LE(p, v) (*((uint64_t*)(p)) = (uint64_t)v) - - -#endif // XENIA_BYTE_ORDER_H_ diff --git a/src/xenia/common.h b/src/xenia/common.h index 3e9010f26..048829080 100644 --- a/src/xenia/common.h +++ b/src/xenia/common.h @@ -12,8 +12,9 @@ #include #include +#include +#include -#include #include #include #include diff --git a/src/xenia/core/crc32.cc b/src/xenia/core/crc32.cc index ada1ac88d..c28b768ac 100644 --- a/src/xenia/core/crc32.cc +++ b/src/xenia/core/crc32.cc @@ -300,7 +300,7 @@ uint32_t xe_crc32(const void* data, size_t length, uint32_t previous_crc) { const uint32_t* current = (const uint32_t*)data; while (length >= 8) { #if XE_CPU_BIGENDIAN - uint32_t one = *current++ ^ XESWAP32(crc); + uint32_t one = *current++ ^ poly::byte_swap(crc); uint32_t two = *current++; crc = xe_crc32_lookup_[0][ two & 0xFF] ^ xe_crc32_lookup_[1][(two>> 8) & 0xFF] ^ diff --git a/src/xenia/core/hash.cc b/src/xenia/core/hash.cc index 5a9e85256..a57afaa01 100644 --- a/src/xenia/core/hash.cc +++ b/src/xenia/core/hash.cc @@ -86,8 +86,8 @@ XEFORCEINLINE uint32_t UNALIGNED_LOAD32(const char *p) { #endif #if XE_CPU_BIGENDIAN -#define uint32_t_in_expected_order(x) (XESWAP32(x)) -#define uint64_in_expected_order(x) (XESWAP64(x)) +#define uint32_t_in_expected_order(x) (poly::byte_swap(x)) +#define uint64_in_expected_order(x) (poly::byte_swap(x)) #else #define uint32_t_in_expected_order(x) (x) #define uint64_in_expected_order(x) (x) @@ -227,9 +227,9 @@ uint32_t CityHash32(const char *s, size_t len) { h = Rotate32(h, 19); h = h * 5 + 0xe6546b64; g ^= a4; - g = XESWAP32(g) * 5; + g = poly::byte_swap(g) * 5; h += a4 * 5; - h = XESWAP32(h); + h = poly::byte_swap(h); f += a0; PERMUTE3(f, h, g); s += 20; @@ -346,11 +346,11 @@ static uint64_t HashLen33to64(const char *s, size_t len) { uint64_t h = Fetch64(s + len - 16) * mul; uint64_t u = Rotate(a + g, 43) + (Rotate(b, 30) + c) * 9; uint64_t v = ((a + g) ^ d) + f + 1; - uint64_t w = XESWAP64((u + v) * mul) + h; + uint64_t w = poly::byte_swap((u + v) * mul) + h; uint64_t x = Rotate(e + f, 42) + c; - uint64_t y = (XESWAP64((v + w) * mul) + g) * mul; + uint64_t y = (poly::byte_swap((v + w) * mul) + g) * mul; uint64_t z = e + f + c; - a = XESWAP64((x + z) * mul + y) + b; + a = poly::byte_swap((x + z) * mul + y) + b; b = ShiftMix((z + a) * mul + d + h) * mul; return b + x; } diff --git a/src/xenia/cpu/processor.cc b/src/xenia/cpu/processor.cc index 0432fa294..c5cea7411 100644 --- a/src/xenia/cpu/processor.cc +++ b/src/xenia/cpu/processor.cc @@ -144,7 +144,7 @@ uint64_t Processor::ExecuteInterrupt( // Set 0x10C(r13) to the current CPU ID. uint8_t* p = memory_->membase(); - XESETUINT8BE(p + interrupt_thread_block_ + 0x10C, cpu); + poly::store_and_swap(p + interrupt_thread_block_ + 0x10C, cpu); // Execute interrupt. uint64_t result = Execute(interrupt_thread_state_, address, args, arg_count); diff --git a/src/xenia/cpu/xenon_memory.cc b/src/xenia/cpu/xenon_memory.cc index d7ad0d751..c32d1400d 100644 --- a/src/xenia/cpu/xenon_memory.cc +++ b/src/xenia/cpu/xenon_memory.cc @@ -180,13 +180,13 @@ LONG CALLBACK CheckMMIOHandler(PEXCEPTION_POINTERS ex_info) { *reg_ptr = static_cast(value); break; case 16: - *reg_ptr = XESWAP16(static_cast(value)); + *reg_ptr = poly::byte_swap(static_cast(value)); break; case 32: - *reg_ptr = XESWAP32(static_cast(value)); + *reg_ptr = poly::byte_swap(static_cast(value)); break; case 64: - *reg_ptr = XESWAP64(static_cast(value)); + *reg_ptr = poly::byte_swap(static_cast(value)); break; } ex_info->ContextRecord->Rip += len; @@ -207,13 +207,13 @@ LONG CALLBACK CheckMMIOHandler(PEXCEPTION_POINTERS ex_info) { value = static_cast(value); break; case 16: - value = XESWAP16(static_cast(value)); + value = poly::byte_swap(static_cast(value)); break; case 32: - value = XESWAP32(static_cast(value)); + value = poly::byte_swap(static_cast(value)); break; case 64: - value = XESWAP64(static_cast(value)); + value = poly::byte_swap(static_cast(value)); break; } range.write(range.context, address & 0xFFFFFFFF, value); diff --git a/src/xenia/cpu/xex_module.cc b/src/xenia/cpu/xex_module.cc index df019e5ae..61796c952 100644 --- a/src/xenia/cpu/xex_module.cc +++ b/src/xenia/cpu/xex_module.cc @@ -132,20 +132,20 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) { if (kernel_export->type == KernelExport::Function) { // Not exactly sure what this should be... if (info->thunk_address) { - *slot = XESWAP32BE(info->thunk_address); + *slot = poly::byte_swap(info->thunk_address); } else { // TODO(benvanik): find out what import variables are. XELOGW("kernel import variable not defined %.8X %s", info->value_address, kernel_export->name); - *slot = XESWAP32BE(0xF00DF00D); + *slot = poly::byte_swap(0xF00DF00D); } } else { if (kernel_export->is_implemented) { // Implemented - replace with pointer. - XESETUINT32BE(slot, kernel_export->variable_ptr); + poly::store_and_swap(slot, kernel_export->variable_ptr); } else { // Not implemented - write with a dummy value. - XESETUINT32BE(slot, 0xD000BEEF | (kernel_export->ordinal & 0xFFF) << 16); + poly::store_and_swap(slot, 0xD000BEEF | (kernel_export->ordinal & 0xFFF) << 16); XELOGCPU("WARNING: imported a variable with no value: %s", kernel_export->name); } @@ -175,10 +175,10 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) { // nop // nop uint8_t* p = memory()->Translate(info->thunk_address); - XESETUINT32BE(p + 0x0, 0x44000002); - XESETUINT32BE(p + 0x4, 0x4E800020); - XESETUINT32BE(p + 0x8, 0x60000000); - XESETUINT32BE(p + 0xC, 0x60000000); + poly::store_and_swap(p + 0x0, 0x44000002); + poly::store_and_swap(p + 0x4, 0x4E800020); + poly::store_and_swap(p + 0x8, 0x60000000); + poly::store_and_swap(p + 0xC, 0x60000000); FunctionInfo::ExternHandler handler = 0; void* handler_data = 0; diff --git a/src/xenia/gpu/command_processor.cc b/src/xenia/gpu/command_processor.cc index d84c7e236..081b315a7 100644 --- a/src/xenia/gpu/command_processor.cc +++ b/src/xenia/gpu/command_processor.cc @@ -118,7 +118,7 @@ void CommandProcessor::Pump() { // TODO(benvanik): use read_ptr_update_freq_ and only issue after moving // that many indices. if (read_ptr_writeback_ptr_) { - XESETUINT32BE(p + read_ptr_writeback_ptr_, read_ptr_index_); + poly::store_and_swap(p + read_ptr_writeback_ptr_, read_ptr_index_); } } @@ -174,7 +174,7 @@ void CommandProcessor::ExecuteIndirectBuffer(uint32_t ptr, uint32_t length) { for (uint32_t __m = 0; __m < count; __m++) { \ XETRACECP("[%.8X] %.8X", \ packet_ptr + (1 + __m) * 4, \ - XEGETUINT32BE(packet_base + 1 * 4 + __m * 4)); \ + poly::load_and_swap(packet_base + 1 * 4 + __m * 4)); \ } void CommandProcessor::AdvancePtr(PacketArgs& args, uint32_t n) { @@ -186,9 +186,9 @@ void CommandProcessor::AdvancePtr(PacketArgs& args, uint32_t n) { } #define ADVANCE_PTR(n) AdvancePtr(args, n) #define PEEK_PTR() \ - XEGETUINT32BE(p + args.ptr) + poly::load_and_swap(p + args.ptr) #define READ_PTR() \ - XEGETUINT32BE(p + args.ptr); ADVANCE_PTR(1); + poly::load_and_swap(p + args.ptr); ADVANCE_PTR(1); uint32_t CommandProcessor::ExecutePacket(PacketArgs& args) { uint8_t* p = memory_->membase(); @@ -339,7 +339,7 @@ uint32_t CommandProcessor::ExecutePacket(PacketArgs& args) { // Memory. XE_GPU_ENDIAN endianness = (XE_GPU_ENDIAN)(poll_reg_addr & 0x3); poll_reg_addr &= ~0x3; - value = XEGETUINT32LE(p + GpuToCpu(packet_ptr, poll_reg_addr)); + value = poly::load(p + GpuToCpu(packet_ptr, poll_reg_addr)); value = GpuSwap(value, endianness); } else { // Register. @@ -434,7 +434,7 @@ uint32_t CommandProcessor::ExecutePacket(PacketArgs& args) { // Memory. XE_GPU_ENDIAN endianness = (XE_GPU_ENDIAN)(poll_reg_addr & 0x3); poll_reg_addr &= ~0x3; - value = XEGETUINT32LE(p + GpuToCpu(packet_ptr, poll_reg_addr)); + value = poly::load(p + GpuToCpu(packet_ptr, poll_reg_addr)); value = GpuSwap(value, endianness); } else { // Register. @@ -475,8 +475,8 @@ uint32_t CommandProcessor::ExecutePacket(PacketArgs& args) { XE_GPU_ENDIAN endianness = (XE_GPU_ENDIAN)(write_reg_addr & 0x3); write_reg_addr &= ~0x3; write_data = GpuSwap(write_data, endianness); - XESETUINT32LE(p + GpuToCpu(packet_ptr, write_reg_addr), - write_data); + poly::store(p + GpuToCpu(packet_ptr, write_reg_addr), + write_data); } else { // Register. WriteRegister(packet_ptr, write_reg_addr, write_data); @@ -524,7 +524,7 @@ uint32_t CommandProcessor::ExecutePacket(PacketArgs& args) { XE_GPU_ENDIAN endianness = (XE_GPU_ENDIAN)(address & 0x3); address &= ~0x3; data_value = GpuSwap(data_value, endianness); - XESETUINT32LE(p + GpuToCpu(address), data_value); + poly::store(p + GpuToCpu(address), data_value); } break; @@ -637,7 +637,7 @@ uint32_t CommandProcessor::ExecutePacket(PacketArgs& args) { size &= 0xFFF; index += 0x4000; // alu constants for (uint32_t n = 0; n < size; n++, index++) { - uint32_t data = XEGETUINT32BE( + uint32_t data = poly::load_and_swap( p + GpuToCpu(packet_ptr, address + n * 4)); const char* reg_name = regs->GetRegisterName(index); XETRACECP("[%.8X] %.8X -> %.4X %s", @@ -769,7 +769,7 @@ void CommandProcessor::WriteRegister( uint8_t* p = memory_->membase(); uint32_t scratch_addr = regs->values[XE_GPU_REG_SCRATCH_ADDR].u32; uint32_t mem_addr = scratch_addr + (scratch_reg * 4); - XESETUINT32BE(p + GpuToCpu(primary_buffer_ptr_, mem_addr), value); + poly::store_and_swap(p + GpuToCpu(primary_buffer_ptr_, mem_addr), value); } } } diff --git a/src/xenia/gpu/d3d11/d3d11_buffer_resource.cc b/src/xenia/gpu/d3d11/d3d11_buffer_resource.cc index 1b1654c59..1bb28f81f 100644 --- a/src/xenia/gpu/d3d11/d3d11_buffer_resource.cc +++ b/src/xenia/gpu/d3d11/d3d11_buffer_resource.cc @@ -69,7 +69,7 @@ int D3D11IndexBufferResource::InvalidateRegion( memory_range_.host_base); uint32_t* dest = reinterpret_cast(res.pData); for (uint32_t n = 0; n < index_count; n++) { - dest[n] = XESWAP32(src[n]); + dest[n] = poly::byte_swap(src[n]); } } else { uint32_t index_count = memory_range_.length / 2; @@ -77,7 +77,7 @@ int D3D11IndexBufferResource::InvalidateRegion( memory_range_.host_base); uint16_t* dest = reinterpret_cast(res.pData); for (uint32_t n = 0; n < index_count; n++) { - dest[n] = XESWAP16(src[n]); + dest[n] = poly::byte_swap(src[n]); } } resource_cache_->context()->Unmap(handle_, 0); @@ -138,7 +138,7 @@ int D3D11VertexBufferResource::InvalidateRegion( uint32_t o = 0; for (uint32_t i = 0; i < count; i++) { for (uint32_t j = 0; j < el.size_words; j++) { - dest_ptr[o + j] = XESWAP32(src_ptr[o + j]); + dest_ptr[o + j] = poly::byte_swap(src_ptr[o + j]); } o += stride; } diff --git a/src/xenia/gpu/shader_resource.cc b/src/xenia/gpu/shader_resource.cc index dfbac3648..8f6458e41 100644 --- a/src/xenia/gpu/shader_resource.cc +++ b/src/xenia/gpu/shader_resource.cc @@ -35,7 +35,7 @@ ShaderResource::ShaderResource(const MemoryRange& memory_range, size_t byte_size = dword_count_ * sizeof(uint32_t); dwords_ = (uint32_t*)xe_malloc(byte_size); for (uint32_t n = 0; n < dword_count_; n++) { - dwords_[n] = XEGETUINT32BE(memory_range.host_base + n * 4); + dwords_[n] = poly::load_and_swap(memory_range.host_base + n * 4); } // Disassemble, for debugging. diff --git a/src/xenia/gpu/texture_resource.cc b/src/xenia/gpu/texture_resource.cc index 531796c11..81857df6f 100644 --- a/src/xenia/gpu/texture_resource.cc +++ b/src/xenia/gpu/texture_resource.cc @@ -307,12 +307,12 @@ void TextureResource::TextureSwap(uint8_t* dest, const uint8_t* src, switch (info_.endianness) { case XE_GPU_ENDIAN_8IN16: for (uint32_t i = 0; i < pitch; i += 2, src += 2, dest += 2) { - *(uint16_t*)dest = XESWAP16(*(uint16_t*)src); + *(uint16_t*)dest = poly::byte_swap(*(uint16_t*)src); } break; case XE_GPU_ENDIAN_8IN32: // Swap bytes. for (uint32_t i = 0; i < pitch; i += 4, src += 4, dest += 4) { - *(uint32_t*)dest = XESWAP32(*(uint32_t*)src); + *(uint32_t*)dest = poly::byte_swap(*(uint32_t*)src); } break; case XE_GPU_ENDIAN_16IN32: // Swap half words. diff --git a/src/xenia/gpu/xenos/xenos.h b/src/xenia/gpu/xenos/xenos.h index 147fed4b5..ccd9a174d 100644 --- a/src/xenia/gpu/xenos/xenos.h +++ b/src/xenia/gpu/xenos/xenos.h @@ -83,7 +83,7 @@ XEFORCEINLINE uint32_t GpuSwap(uint32_t value, XE_GPU_ENDIAN endianness) { ((value >> 8) & 0x00FF00FF); case XE_GPU_ENDIAN_8IN32: // Swap bytes. // NOTE: we are likely doing two swaps here. Wasteful. Oh well. - return XESWAP32(value); + return poly::byte_swap(value); case XE_GPU_ENDIAN_16IN32: // Swap half words. return ((value >> 16) & 0xFFFF) | (value << 16); } diff --git a/src/xenia/kernel/fs/gdfx.cc b/src/xenia/kernel/fs/gdfx.cc index a373397a8..4e2f52abd 100644 --- a/src/xenia/kernel/fs/gdfx.cc +++ b/src/xenia/kernel/fs/gdfx.cc @@ -122,8 +122,8 @@ GDFX::Error GDFX::Verify(ParseState& state) { return kErrorReadError; } uint8_t* fs_ptr = state.ptr + state.game_offset + (32 * kXESectorSize); - state.root_sector = XEGETUINT32LE(fs_ptr + 20); - state.root_size = XEGETUINT32LE(fs_ptr + 24); + state.root_sector = poly::load(fs_ptr + 20); + state.root_size = poly::load(fs_ptr + 24); state.root_offset = state.game_offset + (state.root_sector * kXESectorSize); if (state.root_size < 13 || state.root_size > 32 * 1024 * 1024) { @@ -157,12 +157,12 @@ bool GDFX::ReadEntry(ParseState& state, const uint8_t* buffer, uint16_t entry_ordinal, GDFXEntry* parent) { const uint8_t* p = buffer + (entry_ordinal * 4); - uint16_t node_l = XEGETUINT16LE(p + 0); - uint16_t node_r = XEGETUINT16LE(p + 2); - size_t sector = XEGETUINT32LE(p + 4); - size_t length = XEGETUINT32LE(p + 8); - uint8_t attributes = XEGETUINT8LE(p + 12); - uint8_t name_length = XEGETUINT8LE(p + 13); + uint16_t node_l = poly::load(p + 0); + uint16_t node_r = poly::load(p + 2); + size_t sector = poly::load(p + 4); + size_t length = poly::load(p + 8); + uint8_t attributes = poly::load(p + 12); + uint8_t name_length = poly::load(p + 13); char* name = (char*)(p + 14); if (node_l && !ReadEntry(state, buffer, node_l, parent)) { diff --git a/src/xenia/kernel/fs/stfs.cc b/src/xenia/kernel/fs/stfs.cc index 10099afb9..b7662f35e 100644 --- a/src/xenia/kernel/fs/stfs.cc +++ b/src/xenia/kernel/fs/stfs.cc @@ -16,21 +16,29 @@ using namespace xe; using namespace xe::kernel; using namespace xe::kernel::fs; +#define XEGETUINT24BE(p) \ + (((uint32_t)poly::load_and_swap((p) + 0) << 16) | \ + ((uint32_t)poly::load_and_swap((p) + 1) << 8) | \ + (uint32_t)poly::load_and_swap((p) + 2)) +#define XEGETUINT24LE(p) \ + (((uint32_t)poly::load((p) + 2) << 16) | \ + ((uint32_t)poly::load((p) + 1) << 8) | \ + (uint32_t)poly::load((p) + 0)) bool STFSVolumeDescriptor::Read(const uint8_t* p) { - descriptor_size = XEGETUINT8BE(p + 0x00); + descriptor_size = poly::load_and_swap(p + 0x00); if (descriptor_size != 0x24) { XELOGE("STFS volume descriptor size mismatch, expected 0x24 but got 0x%X", descriptor_size); return false; } - reserved = XEGETUINT8BE(p + 0x01); - block_separation = XEGETUINT8BE(p + 0x02); - file_table_block_count = XEGETUINT16BE(p + 0x03); + reserved = poly::load_and_swap(p + 0x01); + block_separation = poly::load_and_swap(p + 0x02); + file_table_block_count = poly::load_and_swap(p + 0x03); file_table_block_number = XEGETUINT24BE(p + 0x05); xe_copy_struct(top_hash_table_hash, p + 0x08, 0x14); - total_allocated_block_count = XEGETUINT32BE(p + 0x1C); - total_unallocated_block_count = XEGETUINT32BE(p + 0x20); + total_allocated_block_count = poly::load_and_swap(p + 0x1C); + total_unallocated_block_count = poly::load_and_swap(p + 0x20); return true; }; @@ -38,29 +46,29 @@ bool STFSVolumeDescriptor::Read(const uint8_t* p) { bool STFSHeader::Read(const uint8_t* p) { xe_copy_struct(license_entries, p + 0x22C, 0x100); xe_copy_struct(header_hash, p + 0x32C, 0x14); - header_size = XEGETUINT32BE(p + 0x340); - content_type = (STFSContentType)XEGETUINT32BE(p + 0x344); - metadata_version = XEGETUINT32BE(p + 0x348); + header_size = poly::load_and_swap(p + 0x340); + content_type = (STFSContentType)poly::load_and_swap(p + 0x344); + metadata_version = poly::load_and_swap(p + 0x348); if (metadata_version > 1) { // This is a variant of thumbnail data/etc. // Can just ignore it for now (until we parse thumbnails). XELOGW("STFSContainer doesn't support version %d yet", metadata_version); } - content_size = XEGETUINT32BE(p + 0x34C); - media_id = XEGETUINT32BE(p + 0x354); - version = XEGETUINT32BE(p + 0x358); - base_version = XEGETUINT32BE(p + 0x35C); - title_id = XEGETUINT32BE(p + 0x360); - platform = (STFSPlatform)XEGETUINT8BE(p + 0x364); - executable_type = XEGETUINT8BE(p + 0x365); - disc_number = XEGETUINT8BE(p + 0x366); - disc_in_set = XEGETUINT8BE(p + 0x367); - save_game_id = XEGETUINT32BE(p + 0x368); + content_size = poly::load_and_swap(p + 0x34C); + media_id = poly::load_and_swap(p + 0x354); + version = poly::load_and_swap(p + 0x358); + base_version = poly::load_and_swap(p + 0x35C); + title_id = poly::load_and_swap(p + 0x360); + platform = (STFSPlatform)poly::load_and_swap(p + 0x364); + executable_type = poly::load_and_swap(p + 0x365); + disc_number = poly::load_and_swap(p + 0x366); + disc_in_set = poly::load_and_swap(p + 0x367); + save_game_id = poly::load_and_swap(p + 0x368); xe_copy_struct(console_id, p + 0x36C, 0x5); xe_copy_struct(profile_id, p + 0x371, 0x8); - data_file_count = XEGETUINT32BE(p + 0x39D); - data_file_combined_size = XEGETUINT64BE(p + 0x3A1); - descriptor_type = (STFSDescriptorType)XEGETUINT8BE(p + 0x3A9); + data_file_count = poly::load_and_swap(p + 0x39D); + data_file_combined_size = poly::load_and_swap(p + 0x3A1); + descriptor_type = (STFSDescriptorType)poly::load_and_swap(p + 0x3A9); if (descriptor_type != STFS_DESCRIPTOR_STFS) { XELOGE("STFS descriptor format not supported: %d", descriptor_type); return false; @@ -70,16 +78,16 @@ bool STFSHeader::Read(const uint8_t* p) { } xe_copy_struct(device_id, p + 0x3FD, 0x14); for (size_t n = 0; n < 0x900 / 2; n++) { - display_names[n] = XEGETUINT16BE(p + 0x411 + n * 2); - display_descs[n] = XEGETUINT16BE(p + 0xD11 + n * 2); + display_names[n] = poly::load_and_swap(p + 0x411 + n * 2); + display_descs[n] = poly::load_and_swap(p + 0xD11 + n * 2); } for (size_t n = 0; n < 0x80 / 2; n++) { - publisher_name[n] = XEGETUINT16BE(p + 0x1611 + n * 2); - title_name[n] = XEGETUINT16BE(p + 0x1691 + n * 2); + publisher_name[n] = poly::load_and_swap(p + 0x1611 + n * 2); + title_name[n] = poly::load_and_swap(p + 0x1691 + n * 2); } - transfer_flags = XEGETUINT8BE(p + 0x1711); - thumbnail_image_size = XEGETUINT32BE(p + 0x1712); - title_thumbnail_image_size = XEGETUINT32BE(p + 0x1716); + transfer_flags = poly::load_and_swap(p + 0x1711); + thumbnail_image_size = poly::load_and_swap(p + 0x1712); + title_thumbnail_image_size = poly::load_and_swap(p + 0x1716); xe_copy_struct(thumbnail_image, p + 0x171A, 0x4000); xe_copy_struct(title_thumbnail_image, p + 0x571A, 0x4000); return true; @@ -203,13 +211,13 @@ STFS::Error STFS::ReadAllEntries(const uint8_t* map_ptr) { // Done. break; } - uint8_t filename_length_flags = XEGETUINT8BE(p + 0x28); + uint8_t filename_length_flags = poly::load_and_swap(p + 0x28); uint32_t allocated_block_count = XEGETUINT24LE(p + 0x29); uint32_t start_block_index = XEGETUINT24LE(p + 0x2F); - uint16_t path_indicator = XEGETUINT16BE(p + 0x32); - uint32_t file_size = XEGETUINT32BE(p + 0x34); - uint32_t update_timestamp = XEGETUINT32BE(p + 0x38); - uint32_t access_timestamp = XEGETUINT32BE(p + 0x3C); + uint16_t path_indicator = poly::load_and_swap(p + 0x32); + uint32_t file_size = poly::load_and_swap(p + 0x34); + uint32_t update_timestamp = poly::load_and_swap(p + 0x38); + uint32_t access_timestamp = poly::load_and_swap(p + 0x3C); p += 0x40; STFSEntry* entry = new STFSEntry(); @@ -337,7 +345,7 @@ STFS::BlockHash_t STFS::GetBlockHash( //table_index += table_offset - (1 << table_size_shift_); const uint8_t* hash_data = map_ptr + BlockToOffset(table_index); const uint8_t* record_data = hash_data + record * 0x18; - uint32_t info = XEGETUINT8BE(record_data + 0x14); + uint32_t info = poly::load_and_swap(record_data + 0x14); uint32_t next_block_index = XEGETUINT24BE(record_data + 0x15); return{ next_block_index, info }; } diff --git a/src/xenia/kernel/native_list.cc b/src/xenia/kernel/native_list.cc index bc922d31d..c910bd667 100644 --- a/src/xenia/kernel/native_list.cc +++ b/src/xenia/kernel/native_list.cc @@ -21,40 +21,40 @@ NativeList::NativeList(Memory* memory) : void NativeList::Insert(uint32_t ptr) { uint8_t* mem = memory_->membase(); - XESETUINT32BE(mem + ptr + 0, head_); - XESETUINT32BE(mem + ptr + 4, 0); + poly::store_and_swap(mem + ptr + 0, head_); + poly::store_and_swap(mem + ptr + 4, 0); if (head_) { - XESETUINT32BE(mem + head_ + 4, ptr); + poly::store_and_swap(mem + head_ + 4, ptr); } head_ = ptr; } bool NativeList::IsQueued(uint32_t ptr) { uint8_t* mem = memory_->membase(); - uint32_t flink = XEGETUINT32BE(mem + ptr + 0); - uint32_t blink = XEGETUINT32BE(mem + ptr + 4); + uint32_t flink = poly::load_and_swap(mem + ptr + 0); + uint32_t blink = poly::load_and_swap(mem + ptr + 4); return head_ == ptr || flink || blink; } void NativeList::Remove(uint32_t ptr) { uint8_t* mem = memory_->membase(); - uint32_t flink = XEGETUINT32BE(mem + ptr + 0); - uint32_t blink = XEGETUINT32BE(mem + ptr + 4); + uint32_t flink = poly::load_and_swap(mem + ptr + 0); + uint32_t blink = poly::load_and_swap(mem + ptr + 4); if (ptr == head_) { head_ = flink; if (flink) { - XESETUINT32BE(mem + flink + 4, 0); + poly::store_and_swap(mem + flink + 4, 0); } } else { if (blink) { - XESETUINT32BE(mem + blink + 0, flink); + poly::store_and_swap(mem + blink + 0, flink); } if (flink) { - XESETUINT32BE(mem + flink + 4, blink); + poly::store_and_swap(mem + flink + 4, blink); } } - XESETUINT32BE(mem + ptr + 0, 0); - XESETUINT32BE(mem + ptr + 4, 0); + poly::store_and_swap(mem + ptr + 0, 0); + poly::store_and_swap(mem + ptr + 4, 0); } uint32_t NativeList::Shift() { diff --git a/src/xenia/kernel/objects/xfile.h b/src/xenia/kernel/objects/xfile.h index 61852af41..ecb944413 100644 --- a/src/xenia/kernel/objects/xfile.h +++ b/src/xenia/kernel/objects/xfile.h @@ -33,14 +33,14 @@ public: X_FILE_ATTRIBUTES attributes; void Write(uint8_t* base, uint32_t p) { - XESETUINT64BE(base + p, creation_time); - XESETUINT64BE(base + p + 8, last_access_time); - XESETUINT64BE(base + p + 16, last_write_time); - XESETUINT64BE(base + p + 24, change_time); - XESETUINT64BE(base + p + 32, allocation_size); - XESETUINT64BE(base + p + 40, file_length); - XESETUINT32BE(base + p + 48, attributes); - XESETUINT32BE(base + p + 52, 0); // pad + poly::store_and_swap(base + p, creation_time); + poly::store_and_swap(base + p + 8, last_access_time); + poly::store_and_swap(base + p + 16, last_write_time); + poly::store_and_swap(base + p + 24, change_time); + poly::store_and_swap(base + p + 32, allocation_size); + poly::store_and_swap(base + p + 40, file_length); + poly::store_and_swap(base + p + 48, attributes); + poly::store_and_swap(base + p + 52, 0); // pad } }; @@ -65,16 +65,16 @@ public: XDirectoryInfo* info; do { info = (XDirectoryInfo*)src; - XESETUINT32BE(dst, info->next_entry_offset); - XESETUINT32BE(dst + 4, info->file_index); - XESETUINT64BE(dst + 8, info->creation_time); - XESETUINT64BE(dst + 16, info->last_access_time); - XESETUINT64BE(dst + 24, info->last_write_time); - XESETUINT64BE(dst + 32, info->change_time); - XESETUINT64BE(dst + 40, info->end_of_file); - XESETUINT64BE(dst + 48, info->allocation_size); - XESETUINT32BE(dst + 56, info->attributes); - XESETUINT32BE(dst + 60, info->file_name_length); + poly::store_and_swap(dst, info->next_entry_offset); + poly::store_and_swap(dst + 4, info->file_index); + poly::store_and_swap(dst + 8, info->creation_time); + poly::store_and_swap(dst + 16, info->last_access_time); + poly::store_and_swap(dst + 24, info->last_write_time); + poly::store_and_swap(dst + 32, info->change_time); + poly::store_and_swap(dst + 40, info->end_of_file); + poly::store_and_swap(dst + 48, info->allocation_size); + poly::store_and_swap(dst + 56, info->attributes); + poly::store_and_swap(dst + 60, info->file_name_length); xe_copy_memory(dst + 64, info->file_name_length, info->file_name, info->file_name_length); dst += info->next_entry_offset; src += info->next_entry_offset; @@ -95,10 +95,10 @@ public: void Write(uint8_t* base, uint32_t p) { uint8_t* dst = base + p; - XESETUINT64BE(dst + 0, this->creation_time); - XESETUINT32BE(dst + 8, this->serial_number); - XESETUINT32BE(dst + 12, this->label_length); - XESETUINT32BE(dst + 16, this->supports_objects); + poly::store_and_swap(dst + 0, this->creation_time); + poly::store_and_swap(dst + 8, this->serial_number); + poly::store_and_swap(dst + 12, this->label_length); + poly::store_and_swap(dst + 16, this->supports_objects); xe_copy_memory(dst + 20, this->label_length, this->label, this->label_length); } }; @@ -115,9 +115,9 @@ public: void Write(uint8_t* base, uint32_t p) { uint8_t* dst = base + p; - XESETUINT32BE(dst + 0, this->attributes); - XESETUINT32BE(dst + 4, this->maximum_component_name_length); - XESETUINT32BE(dst + 8, this->fs_name_length); + poly::store_and_swap(dst + 0, this->attributes); + poly::store_and_swap(dst + 4, this->maximum_component_name_length); + poly::store_and_swap(dst + 8, this->fs_name_length); xe_copy_memory(dst + 12, this->fs_name_length, this->fs_name, this->fs_name_length); } }; diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index ad58f0ff7..0e3dab0c5 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -120,7 +120,7 @@ uint32_t XThread::GetCurrentThreadHandle() { } uint32_t XThread::GetCurrentThreadId(const uint8_t* thread_state_block) { - return XEGETUINT32BE(thread_state_block + 0x14C); + return poly::load_and_swap(thread_state_block + 0x14C); } uint32_t XThread::thread_state() { @@ -133,12 +133,12 @@ uint32_t XThread::thread_id() { uint32_t XThread::last_error() { uint8_t *p = memory()->Translate(thread_state_address_); - return XEGETUINT32BE(p + 0x160); + return poly::load_and_swap(p + 0x160); } void XThread::set_last_error(uint32_t error_code) { uint8_t *p = memory()->Translate(thread_state_address_); - XESETUINT32BE(p + 0x160, error_code); + poly::store_and_swap(p + 0x160, error_code); } void XThread::set_name(const char* name) { @@ -221,11 +221,11 @@ X_STATUS XThread::Create() { // Setup the thread state block (last error/etc). uint8_t *p = memory()->Translate(thread_state_address_); - XESETUINT32BE(p + 0x000, tls_address_); - XESETUINT32BE(p + 0x100, thread_state_address_); - XESETUINT32BE(p + 0x14C, thread_id_); - XESETUINT32BE(p + 0x150, 0); // ? - XESETUINT32BE(p + 0x160, 0); // last error + poly::store_and_swap(p + 0x000, tls_address_); + poly::store_and_swap(p + 0x100, thread_state_address_); + poly::store_and_swap(p + 0x14C, thread_id_); + poly::store_and_swap(p + 0x150, 0); // ? + poly::store_and_swap(p + 0x160, 0); // last error // Allocate processor thread state. // This is thread safe. @@ -440,25 +440,25 @@ void XThread::DeliverAPCs(void* data) { // Calling the routine may delete the memory/overwrite it. uint32_t apc_address = apc_list->Shift() - 8; uint8_t* apc_ptr = membase + apc_address; - uint32_t kernel_routine = XEGETUINT32BE(apc_ptr + 16); - uint32_t normal_routine = XEGETUINT32BE(apc_ptr + 24); - uint32_t normal_context = XEGETUINT32BE(apc_ptr + 28); - uint32_t system_arg1 = XEGETUINT32BE(apc_ptr + 32); - uint32_t system_arg2 = XEGETUINT32BE(apc_ptr + 36); + uint32_t kernel_routine = poly::load_and_swap(apc_ptr + 16); + uint32_t normal_routine = poly::load_and_swap(apc_ptr + 24); + uint32_t normal_context = poly::load_and_swap(apc_ptr + 28); + uint32_t system_arg1 = poly::load_and_swap(apc_ptr + 32); + uint32_t system_arg2 = poly::load_and_swap(apc_ptr + 36); // Mark as uninserted so that it can be reinserted again by the routine. - uint32_t old_flags = XEGETUINT32BE(apc_ptr + 40); - XESETUINT32BE(apc_ptr + 40, old_flags & ~0xFF00); + uint32_t old_flags = poly::load_and_swap(apc_ptr + 40); + poly::store_and_swap(apc_ptr + 40, old_flags & ~0xFF00); // Call kernel routine. // The routine can modify all of its arguments before passing it on. // Since we need to give guest accessible pointers over, we copy things // into and out of scratch. uint8_t* scratch_ptr = membase + thread->scratch_address_; - XESETUINT32BE(scratch_ptr + 0, normal_routine); - XESETUINT32BE(scratch_ptr + 4, normal_context); - XESETUINT32BE(scratch_ptr + 8, system_arg1); - XESETUINT32BE(scratch_ptr + 12, system_arg2); + poly::store_and_swap(scratch_ptr + 0, normal_routine); + poly::store_and_swap(scratch_ptr + 4, normal_context); + poly::store_and_swap(scratch_ptr + 8, system_arg1); + poly::store_and_swap(scratch_ptr + 12, system_arg2); // kernel_routine(apc_address, &normal_routine, &normal_context, &system_arg1, &system_arg2) uint64_t kernel_args[] = { apc_address, @@ -469,10 +469,10 @@ void XThread::DeliverAPCs(void* data) { }; processor->ExecuteInterrupt( 0, kernel_routine, kernel_args, XECOUNT(kernel_args)); - normal_routine = XEGETUINT32BE(scratch_ptr + 0); - normal_context = XEGETUINT32BE(scratch_ptr + 4); - system_arg1 = XEGETUINT32BE(scratch_ptr + 8); - system_arg2 = XEGETUINT32BE(scratch_ptr + 12); + normal_routine = poly::load_and_swap(scratch_ptr + 0); + normal_context = poly::load_and_swap(scratch_ptr + 4); + system_arg1 = poly::load_and_swap(scratch_ptr + 8); + system_arg2 = poly::load_and_swap(scratch_ptr + 12); // Call the normal routine. Note that it may have been killed by the kernel // routine. @@ -496,11 +496,11 @@ void XThread::RundownAPCs() { // Calling the routine may delete the memory/overwrite it. uint32_t apc_address = apc_list_->Shift() - 8; uint8_t* apc_ptr = membase + apc_address; - uint32_t rundown_routine = XEGETUINT32BE(apc_ptr + 20); + uint32_t rundown_routine = poly::load_and_swap(apc_ptr + 20); // Mark as uninserted so that it can be reinserted again by the routine. - uint32_t old_flags = XEGETUINT32BE(apc_ptr + 40); - XESETUINT32BE(apc_ptr + 40, old_flags & ~0xFF00); + uint32_t old_flags = poly::load_and_swap(apc_ptr + 40); + poly::store_and_swap(apc_ptr + 40, old_flags & ~0xFF00); // Call the rundown routine. if (rundown_routine) { diff --git a/src/xenia/kernel/util/shim_utils.h b/src/xenia/kernel/util/shim_utils.h index e5eb082fe..92245a9a8 100644 --- a/src/xenia/kernel/util/shim_utils.h +++ b/src/xenia/kernel/util/shim_utils.h @@ -35,15 +35,15 @@ using PPCContext = alloy::frontend::ppc::PPCContext; #define SHIM_MEM_ADDR(a) (a ? (ppc_state->membase + a) : NULL) #define SHIM_MEM_8(a) (*(uint8_t*)SHIM_MEM_ADDR(a)) -#define SHIM_MEM_16(a) (uint16_t)XEGETUINT16BE(SHIM_MEM_ADDR(a)) -#define SHIM_MEM_32(a) (uint32_t)XEGETUINT32BE(SHIM_MEM_ADDR(a)) -#define SHIM_MEM_64(a) (uint64_t)XEGETUINT64BE(SHIM_MEM_ADDR(a)) +#define SHIM_MEM_16(a) (uint16_t)poly::load_and_swap(SHIM_MEM_ADDR(a)) +#define SHIM_MEM_32(a) (uint32_t)poly::load_and_swap(SHIM_MEM_ADDR(a)) +#define SHIM_MEM_64(a) (uint64_t)poly::load_and_swap(SHIM_MEM_ADDR(a)) #define SHIM_SET_MEM_8(a, v) (*(uint8_t*)SHIM_MEM_ADDR(a)) = v -#define SHIM_SET_MEM_16(a, v) (*(uint16_t*)SHIM_MEM_ADDR(a)) = XESWAP16(v) -#define SHIM_SET_MEM_32(a, v) (*(uint32_t*)SHIM_MEM_ADDR(a)) = XESWAP32(v) -#define SHIM_SET_MEM_64(a, v) (*(uint64_t*)SHIM_MEM_ADDR(a)) = XESWAP64(v) -#define SHIM_SET_MEM_F32(a, v) (*(float*)SHIM_MEM_ADDR(a)) = XESWAPF32BE(v) -#define SHIM_SET_MEM_F64(a, v) (*(double*)SHIM_MEM_ADDR(a)) = XESWAPF64BE(v) +#define SHIM_SET_MEM_16(a, v) (*(uint16_t*)SHIM_MEM_ADDR(a)) = poly::byte_swap(v) +#define SHIM_SET_MEM_32(a, v) (*(uint32_t*)SHIM_MEM_ADDR(a)) = poly::byte_swap(v) +#define SHIM_SET_MEM_64(a, v) (*(uint64_t*)SHIM_MEM_ADDR(a)) = poly::byte_swap(v) +#define SHIM_SET_MEM_F32(a, v) (*(float*)SHIM_MEM_ADDR(a)) = poly::byte_swap(v) +#define SHIM_SET_MEM_F64(a, v) (*(double*)SHIM_MEM_ADDR(a)) = poly::byte_swap(v) #define SHIM_GPR_8(n) (uint8_t)(ppc_state->r[n]) #define SHIM_GPR_16(n) (uint16_t)(ppc_state->r[n]) @@ -63,11 +63,11 @@ using PPCContext = alloy::frontend::ppc::PPCContext; #define IMPL_MEM_ADDR(a) (a ? state->memory()->Translate(a) : NULL) #define IMPL_MEM_8(a) (*(uint8_t*)(IMPL_MEM_ADDR(a))) -#define IMPL_MEM_16(a) (uint16_t)XEGETUINT16BE(IMPL_MEM_ADDR(a)) -#define IMPL_MEM_32(a) (uint32_t)XEGETUINT32BE(IMPL_MEM_ADDR(a)) +#define IMPL_MEM_16(a) (uint16_t)poly::load_and_swap(IMPL_MEM_ADDR(a)) +#define IMPL_MEM_32(a) (uint32_t)poly::load_and_swap(IMPL_MEM_ADDR(a)) #define IMPL_SET_MEM_8(a, v) (*(uint8_t*)IMPL_MEM_ADDR(a)) = v -#define IMPL_SET_MEM_16(a, v) (*(uint16_t*)IMPL_MEM_ADDR(a)) = XESWAP16(v) -#define IMPL_SET_MEM_32(a, v) (*(uint32_t*)IMPL_MEM_ADDR(a)) = XESWAP32(v) +#define IMPL_SET_MEM_16(a, v) (*(uint16_t*)IMPL_MEM_ADDR(a)) = poly::byte_swap(v) +#define IMPL_SET_MEM_32(a, v) (*(uint32_t*)IMPL_MEM_ADDR(a)) = poly::byte_swap(v) } // namespace kernel diff --git a/src/xenia/kernel/util/xex2.cc b/src/xenia/kernel/util/xex2.cc index 50cf442cf..1f2f7b6ed 100644 --- a/src/xenia/kernel/util/xex2.cc +++ b/src/xenia/kernel/util/xex2.cc @@ -125,21 +125,21 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, const uint8_t *ps; xe_xex2_loader_info_t *ldr; - header->xex2 = XEGETUINT32BE(p + 0x00); + header->xex2 = poly::load_and_swap(p + 0x00); if (header->xex2 != 0x58455832) { return 1; } - header->module_flags = (xe_xex2_module_flags)XEGETUINT32BE(p + 0x04); - header->exe_offset = XEGETUINT32BE(p + 0x08); - header->unknown0 = XEGETUINT32BE(p + 0x0C); - header->certificate_offset = XEGETUINT32BE(p + 0x10); - header->header_count = XEGETUINT32BE(p + 0x14); + header->module_flags = (xe_xex2_module_flags)poly::load_and_swap(p + 0x04); + header->exe_offset = poly::load_and_swap(p + 0x08); + header->unknown0 = poly::load_and_swap(p + 0x0C); + header->certificate_offset = poly::load_and_swap(p + 0x10); + header->header_count = poly::load_and_swap(p + 0x14); for (size_t n = 0; n < header->header_count; n++) { const uint8_t *ph = p + 0x18 + (n * 8); - const uint32_t key = XEGETUINT32BE(ph + 0x00); - const uint32_t data_offset = XEGETUINT32BE(ph + 0x04); + const uint32_t key = poly::load_and_swap(ph + 0x00); + const uint32_t data_offset = poly::load_and_swap(ph + 0x04); xe_xex2_opt_header_t *opt_header = &header->headers[n]; opt_header->key = key; @@ -151,7 +151,7 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, break; case 0xFF: // dataOffset = offset (first dword in data is size) - opt_header->length = XEGETUINT32BE(p + data_offset); + opt_header->length = poly::load_and_swap(p + data_offset); opt_header->offset = data_offset; break; default: @@ -176,8 +176,8 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, auto& res = header->resource_infos[n]; XEEXPECTZERO(xe_copy_memory(res.name, sizeof(res.name), ph + 0x00, 8)); - res.address = XEGETUINT32BE(ph + 0x08); - res.size = XEGETUINT32BE(ph + 0x0C); + res.address = poly::load_and_swap(ph + 0x08); + res.size = poly::load_and_swap(ph + 0x0C); ph += 16; } } @@ -185,41 +185,41 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, case XEX_HEADER_EXECUTION_INFO: { xe_xex2_execution_info_t *ex = &header->execution_info; - ex->media_id = XEGETUINT32BE(pp + 0x00); - ex->version.value = XEGETUINT32BE(pp + 0x04); - ex->base_version.value = XEGETUINT32BE(pp + 0x08); - ex->title_id = XEGETUINT32BE(pp + 0x0C); - ex->platform = XEGETUINT8BE(pp + 0x10); - ex->executable_table = XEGETUINT8BE(pp + 0x11); - ex->disc_number = XEGETUINT8BE(pp + 0x12); - ex->disc_count = XEGETUINT8BE(pp + 0x13); - ex->savegame_id = XEGETUINT32BE(pp + 0x14); + ex->media_id = poly::load_and_swap(pp + 0x00); + ex->version.value = poly::load_and_swap(pp + 0x04); + ex->base_version.value = poly::load_and_swap(pp + 0x08); + ex->title_id = poly::load_and_swap(pp + 0x0C); + ex->platform = poly::load_and_swap(pp + 0x10); + ex->executable_table = poly::load_and_swap(pp + 0x11); + ex->disc_number = poly::load_and_swap(pp + 0x12); + ex->disc_count = poly::load_and_swap(pp + 0x13); + ex->savegame_id = poly::load_and_swap(pp + 0x14); } break; case XEX_HEADER_GAME_RATINGS: { xe_xex2_game_ratings_t *ratings = &header->game_ratings; - ratings->esrb = (xe_xex2_rating_esrb_value)XEGETUINT8BE(pp + 0x00); - ratings->pegi = (xe_xex2_rating_pegi_value)XEGETUINT8BE(pp + 0x01); - ratings->pegifi = (xe_xex2_rating_pegi_fi_value)XEGETUINT8BE(pp + 0x02); - ratings->pegipt = (xe_xex2_rating_pegi_pt_value)XEGETUINT8BE(pp + 0x03); - ratings->bbfc = (xe_xex2_rating_bbfc_value)XEGETUINT8BE(pp + 0x04); - ratings->cero = (xe_xex2_rating_cero_value)XEGETUINT8BE(pp + 0x05); - ratings->usk = (xe_xex2_rating_usk_value)XEGETUINT8BE(pp + 0x06); - ratings->oflcau = (xe_xex2_rating_oflc_au_value)XEGETUINT8BE(pp + 0x07); - ratings->oflcnz = (xe_xex2_rating_oflc_nz_value)XEGETUINT8BE(pp + 0x08); - ratings->kmrb = (xe_xex2_rating_kmrb_value)XEGETUINT8BE(pp + 0x09); - ratings->brazil = (xe_xex2_rating_brazil_value)XEGETUINT8BE(pp + 0x0A); - ratings->fpb = (xe_xex2_rating_fpb_value)XEGETUINT8BE(pp + 0x0B); + ratings->esrb = (xe_xex2_rating_esrb_value)poly::load_and_swap(pp + 0x00); + ratings->pegi = (xe_xex2_rating_pegi_value)poly::load_and_swap(pp + 0x01); + ratings->pegifi = (xe_xex2_rating_pegi_fi_value)poly::load_and_swap(pp + 0x02); + ratings->pegipt = (xe_xex2_rating_pegi_pt_value)poly::load_and_swap(pp + 0x03); + ratings->bbfc = (xe_xex2_rating_bbfc_value)poly::load_and_swap(pp + 0x04); + ratings->cero = (xe_xex2_rating_cero_value)poly::load_and_swap(pp + 0x05); + ratings->usk = (xe_xex2_rating_usk_value)poly::load_and_swap(pp + 0x06); + ratings->oflcau = (xe_xex2_rating_oflc_au_value)poly::load_and_swap(pp + 0x07); + ratings->oflcnz = (xe_xex2_rating_oflc_nz_value)poly::load_and_swap(pp + 0x08); + ratings->kmrb = (xe_xex2_rating_kmrb_value)poly::load_and_swap(pp + 0x09); + ratings->brazil = (xe_xex2_rating_brazil_value)poly::load_and_swap(pp + 0x0A); + ratings->fpb = (xe_xex2_rating_fpb_value)poly::load_and_swap(pp + 0x0B); } break; case XEX_HEADER_TLS_INFO: { xe_xex2_tls_info_t *tls = &header->tls_info; - tls->slot_count = XEGETUINT32BE(pp + 0x00); - tls->raw_data_address = XEGETUINT32BE(pp + 0x04); - tls->data_size = XEGETUINT32BE(pp + 0x08); - tls->raw_data_size = XEGETUINT32BE(pp + 0x0C); + tls->slot_count = poly::load_and_swap(pp + 0x00); + tls->raw_data_address = poly::load_and_swap(pp + 0x04); + tls->data_size = poly::load_and_swap(pp + 0x08); + tls->raw_data_size = poly::load_and_swap(pp + 0x0C); } break; case XEX_HEADER_IMAGE_BASE_ADDRESS: @@ -237,7 +237,7 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, case XEX_HEADER_IMPORT_LIBRARIES: { const size_t max_count = XECOUNT(header->import_libraries); - size_t count = XEGETUINT32BE(pp + 0x08); + size_t count = poly::load_and_swap(pp + 0x08); assert_true(count <= max_count); if (count > max_count) { XELOGW("ignoring %zu extra entries in XEX_HEADER_IMPORT_LIBRARIES", @@ -246,7 +246,7 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, } header->import_library_count = count; - uint32_t string_table_size = XEGETUINT32BE(pp + 0x04); + uint32_t string_table_size = poly::load_and_swap(pp + 0x04); const char *string_table = (const char*)(pp + 0x0C); pp += 12 + string_table_size; @@ -254,11 +254,11 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, xe_xex2_import_library_t *library = &header->import_libraries[m]; XEEXPECTZERO(xe_copy_memory(library->digest, sizeof(library->digest), pp + 0x04, 20)); - library->import_id = XEGETUINT32BE(pp + 0x18); - library->version.value = XEGETUINT32BE(pp + 0x1C); - library->min_version.value = XEGETUINT32BE(pp + 0x20); + library->import_id = poly::load_and_swap(pp + 0x18); + library->version.value = poly::load_and_swap(pp + 0x1C); + library->min_version.value = poly::load_and_swap(pp + 0x20); - const uint16_t name_index = XEGETUINT16BE(pp + 0x24) & 0xFF; + const uint16_t name_index = poly::load_and_swap(pp + 0x24) & 0xFF; for (size_t i = 0, j = 0; i < string_table_size;) { assert_true(j <= 0xFF); if (j == name_index) { @@ -277,13 +277,13 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, } } - library->record_count = XEGETUINT16BE(pp + 0x26); + library->record_count = poly::load_and_swap(pp + 0x26); library->records = (uint32_t*)xe_calloc( library->record_count * sizeof(uint32_t)); XEEXPECTNOTNULL(library->records); pp += 0x28; for (size_t i = 0; i < library->record_count; i++) { - library->records[i] = XEGETUINT32BE(pp); + library->records[i] = poly::load_and_swap(pp); pp += 4; } } @@ -306,10 +306,10 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, XEEXPECTZERO(xe_copy_memory(library->name, sizeof(library->name), pp + 0x00, 8)); library->name[8] = 0; - library->major = XEGETUINT16BE(pp + 0x08); - library->minor = XEGETUINT16BE(pp + 0x0A); - library->build = XEGETUINT16BE(pp + 0x0C); - uint16_t qfeapproval = XEGETUINT16BE(pp + 0x0E); + library->major = poly::load_and_swap(pp + 0x08); + library->minor = poly::load_and_swap(pp + 0x0A); + library->build = poly::load_and_swap(pp + 0x0C); + uint16_t qfeapproval = poly::load_and_swap(pp + 0x0E); library->approval = (xe_xex2_approval_type)(qfeapproval & 0x8000); library->qfe = qfeapproval & ~0x8000; pp += 16; @@ -320,9 +320,9 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, { xe_xex2_file_format_info_t *fmt = &header->file_format_info; fmt->encryption_type = - (xe_xex2_encryption_type)XEGETUINT16BE(pp + 0x04); + (xe_xex2_encryption_type)poly::load_and_swap(pp + 0x04); fmt->compression_type = - (xe_xex2_compression_type)XEGETUINT16BE(pp + 0x06); + (xe_xex2_compression_type)poly::load_and_swap(pp + 0x06); switch (fmt->compression_type) { case XEX_COMPRESSION_NONE: // TODO: XEX_COMPRESSION_NONE @@ -332,7 +332,7 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, { xe_xex2_file_basic_compression_info_t *comp_info = &fmt->compression_info.basic; - uint32_t info_size = XEGETUINT32BE(pp + 0x00); + uint32_t info_size = poly::load_and_swap(pp + 0x00); comp_info->block_count = (info_size - 8) / 8; comp_info->blocks = (xe_xex2_file_basic_compression_block_t*) xe_calloc(comp_info->block_count * @@ -341,8 +341,8 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, for (size_t m = 0; m < comp_info->block_count; m++) { xe_xex2_file_basic_compression_block_t *block = &comp_info->blocks[m]; - block->data_size = XEGETUINT32BE(pp + 0x08 + (m * 8)); - block->zero_size = XEGETUINT32BE(pp + 0x0C + (m * 8)); + block->data_size = poly::load_and_swap(pp + 0x08 + (m * 8)); + block->zero_size = poly::load_and_swap(pp + 0x0C + (m * 8)); } } break; @@ -350,7 +350,7 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, { xe_xex2_file_normal_compression_info_t *comp_info = &fmt->compression_info.normal; - uint32_t window_size = XEGETUINT32BE(pp + 0x08); + uint32_t window_size = poly::load_and_swap(pp + 0x08); uint32_t window_bits = 0; for (size_t m = 0; m < 32; m++, window_bits++) { window_size <<= 1; @@ -358,9 +358,9 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, break; } } - comp_info->window_size = XEGETUINT32BE(pp + 0x08); + comp_info->window_size = poly::load_and_swap(pp + 0x08); comp_info->window_bits = window_bits; - comp_info->block_size = XEGETUINT32BE(pp + 0x0C); + comp_info->block_size = poly::load_and_swap(pp + 0x0C); XEEXPECTZERO(xe_copy_memory(comp_info->block_hash, sizeof(comp_info->block_hash), pp + 0x10, 20)); @@ -379,16 +379,16 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, // Loader info. pc = p + header->certificate_offset; ldr = &header->loader_info; - ldr->header_size = XEGETUINT32BE(pc + 0x000); - ldr->image_size = XEGETUINT32BE(pc + 0x004); + ldr->header_size = poly::load_and_swap(pc + 0x000); + ldr->image_size = poly::load_and_swap(pc + 0x004); XEEXPECTZERO(xe_copy_memory(ldr->rsa_signature, sizeof(ldr->rsa_signature), pc + 0x008, 256)); - ldr->unklength = XEGETUINT32BE(pc + 0x108); - ldr->image_flags = (xe_xex2_image_flags)XEGETUINT32BE(pc + 0x10C); - ldr->load_address = XEGETUINT32BE(pc + 0x110); + ldr->unklength = poly::load_and_swap(pc + 0x108); + ldr->image_flags = (xe_xex2_image_flags)poly::load_and_swap(pc + 0x10C); + ldr->load_address = poly::load_and_swap(pc + 0x110); XEEXPECTZERO(xe_copy_memory(ldr->section_digest, sizeof(ldr->section_digest), pc + 0x114, 20)); - ldr->import_table_count = XEGETUINT32BE(pc + 0x128); + ldr->import_table_count = poly::load_and_swap(pc + 0x128); XEEXPECTZERO(xe_copy_memory(ldr->import_table_digest, sizeof(ldr->import_table_digest), pc + 0x12C, 20)); @@ -396,22 +396,22 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, pc + 0x140, 16)); XEEXPECTZERO(xe_copy_memory(ldr->file_key, sizeof(ldr->file_key), pc + 0x150, 16)); - ldr->export_table = XEGETUINT32BE(pc + 0x160); + ldr->export_table = poly::load_and_swap(pc + 0x160); XEEXPECTZERO(xe_copy_memory(ldr->header_digest, sizeof(ldr->header_digest), pc + 0x164, 20)); - ldr->game_regions = (xe_xex2_region_flags)XEGETUINT32BE(pc + 0x178); - ldr->media_flags = (xe_xex2_media_flags)XEGETUINT32BE(pc + 0x17C); + ldr->game_regions = (xe_xex2_region_flags)poly::load_and_swap(pc + 0x178); + ldr->media_flags = (xe_xex2_media_flags)poly::load_and_swap(pc + 0x17C); // Section info follows loader info. ps = p + header->certificate_offset + 0x180; - header->section_count = XEGETUINT32BE(ps + 0x000); + header->section_count = poly::load_and_swap(ps + 0x000); ps += 4; header->sections = (xe_xex2_section_t*)xe_calloc( header->section_count * sizeof(xe_xex2_section_t)); XEEXPECTNOTNULL(header->sections); for (size_t n = 0; n < header->section_count; n++) { xe_xex2_section_t *section = &header->sections[n]; - section->info.value = XEGETUINT32BE(ps); + section->info.value = poly::load_and_swap(ps); ps += 4; XEEXPECTZERO(xe_copy_memory(section->digest, sizeof(section->digest), ps, sizeof(section->digest))); @@ -717,7 +717,7 @@ int xe_xex2_read_image_compressed(const xe_xex2_header_t *header, block_size = header->file_format_info.compression_info.normal.block_size; while (block_size) { const uint8_t *pnext = p + block_size; - const size_t next_size = XEGETINT32BE(p); + const size_t next_size = poly::load_and_swap(p); p += 4; p += 20; // skip 20b hash @@ -935,7 +935,7 @@ int xe_xex2_find_import_infos(xe_xex2_ref xex, size_t info_count = 0; for (size_t n = 0; n < library->record_count; n++) { const uint32_t record = library->records[n]; - const uint32_t value = XEGETUINT32BE(mem + record); + const uint32_t value = poly::load_and_swap(mem + record); if (value & 0xFF000000) { // Thunk for previous record - ignore. } else { @@ -954,7 +954,7 @@ int xe_xex2_find_import_infos(xe_xex2_ref xex, // Construct infos. for (size_t n = 0, i = 0; n < library->record_count; n++) { const uint32_t record = library->records[n]; - const uint32_t value = XEGETUINT32BE(mem + record); + const uint32_t value = poly::load_and_swap(mem + record); const uint32_t type = (value & 0xFF000000) >> 24; // Verify library index matches given library. diff --git a/src/xenia/kernel/xboxkrnl_audio.cc b/src/xenia/kernel/xboxkrnl_audio.cc index 76495c0bb..96972d5d9 100644 --- a/src/xenia/kernel/xboxkrnl_audio.cc +++ b/src/xenia/kernel/xboxkrnl_audio.cc @@ -125,7 +125,7 @@ SHIM_CALL XAudioRegisterRenderDriverClient_shim( } assert_true(!(index & ~0x0000FFFF)); - SHIM_SET_MEM_32(driver_ptr, 0x41550000 | (index & 0x0000FFFF)); + SHIM_SET_MEM_32(driver_ptr, 0x41550000 | (static_cast(index) & 0x0000FFFF)); SHIM_SET_RETURN_32(X_ERROR_SUCCESS); } diff --git a/src/xenia/kernel/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl_io.cc index 2a07b4dbc..fcc83c567 100644 --- a/src/xenia/kernel/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl_io.cc @@ -435,7 +435,7 @@ SHIM_CALL NtQueryInformationFile_shim( if (XSUCCEEDED(result)) { if (bytes_read == sizeof(magic)) { info = 4; - SHIM_SET_MEM_32(file_info_ptr, magic == XESWAP32BE(0x0FF512ED)); + SHIM_SET_MEM_32(file_info_ptr, magic == poly::byte_swap(0x0FF512ED)); } else { result = X_STATUS_UNSUCCESSFUL; diff --git a/src/xenia/kernel/xboxkrnl_module.cc b/src/xenia/kernel/xboxkrnl_module.cc index ae0612ff0..b695d44bc 100644 --- a/src/xenia/kernel/xboxkrnl_module.cc +++ b/src/xenia/kernel/xboxkrnl_module.cc @@ -63,7 +63,7 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) : export_resolver_->SetVariableMapping( "xboxkrnl.exe", ordinals::KeDebugMonitorData, pKeDebugMonitorData); - XESETUINT32BE(mem + pKeDebugMonitorData, 0); + poly::store_and_swap(mem + pKeDebugMonitorData, 0); // KeCertMonitorData (?*) // Always set to zero, ignored. @@ -71,7 +71,7 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) : export_resolver_->SetVariableMapping( "xboxkrnl.exe", ordinals::KeCertMonitorData, pKeCertMonitorData); - XESETUINT32BE(mem + pKeCertMonitorData, 0); + poly::store_and_swap(mem + pKeCertMonitorData, 0); // XboxHardwareInfo (XboxHardwareInfo_t, 16b) // flags cpu# ? ? ? ? ? ? @@ -82,8 +82,8 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) : export_resolver_->SetVariableMapping( "xboxkrnl.exe", ordinals::XboxHardwareInfo, pXboxHardwareInfo); - XESETUINT32BE(mem + pXboxHardwareInfo + 0, 0x00000000); // flags - XESETUINT8BE (mem + pXboxHardwareInfo + 4, 0x06); // cpu count + poly::store_and_swap(mem + pXboxHardwareInfo + 0, 0x00000000); // flags + poly::store_and_swap (mem + pXboxHardwareInfo + 4, 0x06); // cpu count // Remaining 11b are zeroes? // XexExecutableModuleHandle (?**) @@ -101,8 +101,8 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) : ppXexExecutableModuleHandle); uint32_t pXexExecutableModuleHandle = (uint32_t)memory_->HeapAlloc(0, 256, 0); - XESETUINT32BE(mem + ppXexExecutableModuleHandle, pXexExecutableModuleHandle); - XESETUINT32BE(mem + pXexExecutableModuleHandle + 0x58, 0x80101100); + poly::store_and_swap(mem + ppXexExecutableModuleHandle, pXexExecutableModuleHandle); + poly::store_and_swap(mem + pXexExecutableModuleHandle + 0x58, 0x80101100); // ExLoadedCommandLine (char*) // The name of the xex. Not sure this is ever really used on real devices. @@ -123,19 +123,19 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) : export_resolver_->SetVariableMapping( "xboxkrnl.exe", ordinals::XboxKrnlVersion, pXboxKrnlVersion); - XESETUINT16BE(mem + pXboxKrnlVersion + 0, 2); - XESETUINT16BE(mem + pXboxKrnlVersion + 2, 0xFFFF); - XESETUINT16BE(mem + pXboxKrnlVersion + 4, 0xFFFF); - XESETUINT16BE(mem + pXboxKrnlVersion + 6, 0xFFFF); + poly::store_and_swap(mem + pXboxKrnlVersion + 0, 2); + poly::store_and_swap(mem + pXboxKrnlVersion + 2, 0xFFFF); + poly::store_and_swap(mem + pXboxKrnlVersion + 4, 0xFFFF); + poly::store_and_swap(mem + pXboxKrnlVersion + 6, 0xFFFF); // KeTimeStampBundle (ad) uint32_t pKeTimeStampBundle = (uint32_t)memory_->HeapAlloc(0, 24, 0); export_resolver_->SetVariableMapping( "xboxkrnl.exe", ordinals::KeTimeStampBundle, pKeTimeStampBundle); - XESETUINT64BE(mem + pKeTimeStampBundle + 0, 0); - XESETUINT64BE(mem + pKeTimeStampBundle + 8, 0); - XESETUINT32BE(mem + pKeTimeStampBundle + 12, 0); + poly::store_and_swap(mem + pKeTimeStampBundle + 0, 0); + poly::store_and_swap(mem + pKeTimeStampBundle + 8, 0); + poly::store_and_swap(mem + pKeTimeStampBundle + 12, 0); } XboxkrnlModule::~XboxkrnlModule() { diff --git a/src/xenia/kernel/xboxkrnl_modules.cc b/src/xenia/kernel/xboxkrnl_modules.cc index b45724f4a..6a9882280 100644 --- a/src/xenia/kernel/xboxkrnl_modules.cc +++ b/src/xenia/kernel/xboxkrnl_modules.cc @@ -97,7 +97,7 @@ X_STATUS xeExGetXConfigSetting( } if (buffer) { - XESETUINT32BE(buffer, value); + poly::store_and_swap(buffer, value); } if (required_size) { *required_size = setting_size; diff --git a/src/xenia/kernel/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl_rtl.cc index ebf874eb3..d9fd7fddc 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl_rtl.cc @@ -91,7 +91,7 @@ uint32_t xeRtlCompareMemoryUlong(uint32_t source_ptr, uint32_t length, // TODO(benvanik): ensure byte order of pattern is correct. // Since we are doing byte-by-byte comparison we may not want to swap. // GET_ARG swaps, so this is a swap back. Ugly. - const uint32_t pb32 = XESWAP32BE(pattern); + const uint32_t pb32 = poly::byte_swap(pattern); const uint8_t* pb = (uint8_t*)&pb32; uint32_t c = 0; @@ -138,7 +138,7 @@ void xeRtlFillMemoryUlong(uint32_t destination_ptr, uint32_t length, // swapped arg value. uint32_t count = length >> 2; - uint32_t native_pattern = XESWAP32BE(pattern); + uint32_t native_pattern = poly::byte_swap(pattern); // TODO: unroll loop? @@ -364,7 +364,7 @@ SHIM_CALL RtlMultiByteToUnicodeN_shim( auto destination = (uint16_t*)SHIM_MEM_ADDR(destination_ptr); for (uint32_t i = 0; i < copy_len; i++) { - *destination++ = XESWAP16(*source++); + *destination++ = poly::byte_swap(*source++); } if (written_ptr != 0) @@ -393,7 +393,7 @@ SHIM_CALL RtlUnicodeToMultiByteN_shim( auto destination = (uint8_t*)SHIM_MEM_ADDR(destination_ptr); for (uint32_t i = 0; i < copy_len; i++) { - uint16_t c = XESWAP16(*source++); + uint16_t c = poly::byte_swap(*source++); *destination++ = c < 256 ? (uint8_t)c : '?'; } diff --git a/src/xenia/kernel/xboxkrnl_strings.cc b/src/xenia/kernel/xboxkrnl_strings.cc index f6815c01e..fc7f0d989 100644 --- a/src/xenia/kernel/xboxkrnl_strings.cc +++ b/src/xenia/kernel/xboxkrnl_strings.cc @@ -472,9 +472,8 @@ SHIM_CALL _vswprintf_shim( // swap the format buffer wchar_t* swapped_format = (wchar_t*)xe_malloc((format_length + 1) * sizeof(wchar_t)); - for (size_t i = 0; i < format_length; ++i) - { - swapped_format[i] = XESWAP16(format[i]); + for (size_t i = 0; i < format_length; ++i) { + swapped_format[i] = poly::byte_swap(format[i]); } swapped_format[format_length] = '\0'; @@ -676,9 +675,8 @@ SHIM_CALL _vswprintf_shim( const wchar_t* data = (const wchar_t*)SHIM_MEM_ADDR(value); size_t data_length = wcslen(data); wchar_t* swapped_data = (wchar_t*)xe_malloc((data_length + 1) * sizeof(wchar_t)); - for (size_t i = 0; i < data_length; ++i) - { - swapped_data[i] = XESWAP16(data[i]); + for (size_t i = 0; i < data_length; ++i) { + swapped_data[i] = poly::byte_swap(data[i]); } swapped_data[data_length] = '\0'; int result = wsprintf(b, local, swapped_data); @@ -703,7 +701,7 @@ SHIM_CALL _vswprintf_shim( // swap the result buffer for (wchar_t* swap = buffer; swap != b; ++swap) { - *swap = XESWAP16(*swap); + *swap = poly::byte_swap(*swap); } SHIM_SET_RETURN_32((uint32_t)((b - buffer) / sizeof(wchar_t))); diff --git a/src/xenia/kernel/xboxkrnl_video.cc b/src/xenia/kernel/xboxkrnl_video.cc index fa7d319c1..66fb241ae 100644 --- a/src/xenia/kernel/xboxkrnl_video.cc +++ b/src/xenia/kernel/xboxkrnl_video.cc @@ -117,15 +117,15 @@ void xeVdQueryVideoMode(X_VIDEO_MODE *video_mode, bool swap) { video_mode->unknown_0x01 = 0x01; if (swap) { - video_mode->display_width = XESWAP32BE(video_mode->display_width); - video_mode->display_height = XESWAP32BE(video_mode->display_height); - video_mode->is_interlaced = XESWAP32BE(video_mode->is_interlaced); - video_mode->is_widescreen = XESWAP32BE(video_mode->is_widescreen); - video_mode->is_hi_def = XESWAP32BE(video_mode->is_hi_def); - video_mode->refresh_rate = XESWAPF32BE(video_mode->refresh_rate); - video_mode->video_standard = XESWAP32BE(video_mode->video_standard); - video_mode->unknown_0x8a = XESWAP32BE(video_mode->unknown_0x8a); - video_mode->unknown_0x01 = XESWAP32BE(video_mode->unknown_0x01); + video_mode->display_width = poly::byte_swap(video_mode->display_width); + video_mode->display_height = poly::byte_swap(video_mode->display_height); + video_mode->is_interlaced = poly::byte_swap(video_mode->is_interlaced); + video_mode->is_widescreen = poly::byte_swap(video_mode->is_widescreen); + video_mode->is_hi_def = poly::byte_swap(video_mode->is_hi_def); + video_mode->refresh_rate = poly::byte_swap(video_mode->refresh_rate); + video_mode->video_standard = poly::byte_swap(video_mode->video_standard); + video_mode->unknown_0x8a = poly::byte_swap(video_mode->unknown_0x8a); + video_mode->unknown_0x01 = poly::byte_swap(video_mode->unknown_0x01); } } @@ -430,9 +430,9 @@ SHIM_CALL VdSwap_shim( // use this method. xe_zero_struct(SHIM_MEM_ADDR(unk0), 64 * 4); auto dwords = reinterpret_cast(SHIM_MEM_ADDR(unk0)); - dwords[0] = XESWAP32((0x03 << 30) | - ((1 - 1) << 16) | - (xenos::PM4_XE_SWAP << 8)); + dwords[0] = poly::byte_swap((0x03 << 30) | + ((1 - 1) << 16) | + (xenos::PM4_XE_SWAP << 8)); SHIM_SET_RETURN_64(0); } @@ -472,7 +472,7 @@ void xe::kernel::xboxkrnl::RegisterVideoExports( export_resolver->SetVariableMapping( "xboxkrnl.exe", ordinals::VdGlobalDevice, pVdGlobalDevice); - XESETUINT32BE(mem + pVdGlobalDevice, 0); + poly::store_and_swap(mem + pVdGlobalDevice, 0); // VdGlobalXamDevice (4b) // Pointer to the XAM D3D device, which we don't have. @@ -480,7 +480,7 @@ void xe::kernel::xboxkrnl::RegisterVideoExports( export_resolver->SetVariableMapping( "xboxkrnl.exe", ordinals::VdGlobalXamDevice, pVdGlobalXamDevice); - XESETUINT32BE(mem + pVdGlobalXamDevice, 0); + poly::store_and_swap(mem + pVdGlobalXamDevice, 0); // VdGpuClockInMHz (4b) // GPU clock. Xenos is 500MHz. Hope nothing is relying on this timing... @@ -488,7 +488,7 @@ void xe::kernel::xboxkrnl::RegisterVideoExports( export_resolver->SetVariableMapping( "xboxkrnl.exe", ordinals::VdGpuClockInMHz, pVdGpuClockInMHz); - XESETUINT32BE(mem + pVdGpuClockInMHz, 500); + poly::store_and_swap(mem + pVdGpuClockInMHz, 500); // VdHSIOCalibrationLock (28b) // CriticalSection. diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index f3a48d8f7..048e4cd4d 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -162,18 +162,18 @@ void XObject::SetNativePointer(uint32_t native_ptr) { DISPATCH_HEADER* header_be = (DISPATCH_HEADER*)kernel_state_->memory()->Translate(native_ptr); DISPATCH_HEADER header; - header.type_flags = XESWAP32(header_be->type_flags); - header.signal_state = XESWAP32(header_be->signal_state); - header.wait_list_flink = XESWAP32(header_be->wait_list_flink); - header.wait_list_blink = XESWAP32(header_be->wait_list_blink); + header.type_flags = poly::byte_swap(header_be->type_flags); + header.signal_state = poly::byte_swap(header_be->signal_state); + header.wait_list_flink = poly::byte_swap(header_be->wait_list_flink); + header.wait_list_blink = poly::byte_swap(header_be->wait_list_blink); assert_true(!(header.wait_list_blink & 0x1)); // Stash pointer in struct. uint64_t object_ptr = reinterpret_cast(this); object_ptr |= 0x1; - header_be->wait_list_flink = XESWAP32((uint32_t)(object_ptr >> 32)); - header_be->wait_list_blink = XESWAP32((uint32_t)(object_ptr & 0xFFFFFFFF)); + header_be->wait_list_flink = poly::byte_swap((uint32_t)(object_ptr >> 32)); + header_be->wait_list_blink = poly::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF)); XObject::UnlockType(); } @@ -193,10 +193,10 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr, DISPATCH_HEADER* header_be = (DISPATCH_HEADER*)native_ptr; DISPATCH_HEADER header; - header.type_flags = XESWAP32(header_be->type_flags); - header.signal_state = XESWAP32(header_be->signal_state); - header.wait_list_flink = XESWAP32(header_be->wait_list_flink); - header.wait_list_blink = XESWAP32(header_be->wait_list_blink); + header.type_flags = poly::byte_swap(header_be->type_flags); + header.signal_state = poly::byte_swap(header_be->signal_state); + header.wait_list_flink = poly::byte_swap(header_be->wait_list_flink); + header.wait_list_blink = poly::byte_swap(header_be->wait_list_blink); if (as_type == -1) { as_type = header.type_flags & 0xFF; @@ -260,8 +260,8 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr, // Stash pointer in struct. uint64_t object_ptr = reinterpret_cast(object); object_ptr |= 0x1; - header_be->wait_list_flink = XESWAP32((uint32_t)(object_ptr >> 32)); - header_be->wait_list_blink = XESWAP32((uint32_t)(object_ptr & 0xFFFFFFFF)); + header_be->wait_list_flink = poly::byte_swap((uint32_t)(object_ptr >> 32)); + header_be->wait_list_blink = poly::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF)); XObject::UnlockType(); return object; diff --git a/src/xenia/sources.gypi b/src/xenia/sources.gypi index 48bb82f59..568c231ec 100644 --- a/src/xenia/sources.gypi +++ b/src/xenia/sources.gypi @@ -1,7 +1,6 @@ # Copyright 2013 Ben Vanik. All Rights Reserved. { 'sources': [ - 'byte_order.h', 'common.h', 'config.h', 'core.h', diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index fcf079751..8e24fa3a4 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -205,10 +205,10 @@ public: Read(base, p); } void Read(const uint8_t* base, uint32_t p) { - length = XEGETUINT16BE(base + p); - maximum_length = XEGETUINT16BE(base + p + 2); + length = poly::load_and_swap(base + p); + maximum_length = poly::load_and_swap(base + p + 2); if (maximum_length) { - buffer = (const char*)(base + XEGETUINT32BE(base + p + 4)); + buffer = (const char*)(base + poly::load_and_swap(base + p + 4)); } else { buffer = 0; } @@ -242,14 +242,14 @@ public: Read(base, p); } void Read(const uint8_t* base, uint32_t p) { - root_directory = XEGETUINT32BE(base + p); - object_name_ptr = XEGETUINT32BE(base + p + 4); + root_directory = poly::load_and_swap(base + p); + object_name_ptr = poly::load_and_swap(base + p + 4); if (object_name_ptr) { object_name.Read(base, object_name_ptr); } else { object_name.Zero(); } - attributes = XEGETUINT32BE(base + p + 8); + attributes = poly::load_and_swap(base + p + 8); } void Zero() { root_directory = 0; @@ -302,22 +302,22 @@ public: Read(base, p); } void Read(const uint8_t* base, uint32_t p) { - buttons = XEGETUINT16BE(base + p); - left_trigger = XEGETUINT8BE(base + p + 2); - right_trigger = XEGETUINT8BE(base + p + 3); - thumb_lx = XEGETINT16BE(base + p + 4); - thumb_ly = XEGETINT16BE(base + p + 6); - thumb_rx = XEGETINT16BE(base + p + 8); - thumb_ry = XEGETINT16BE(base + p + 10); + buttons = poly::load_and_swap(base + p); + left_trigger = poly::load_and_swap(base + p + 2); + right_trigger = poly::load_and_swap(base + p + 3); + thumb_lx = poly::load_and_swap(base + p + 4); + thumb_ly = poly::load_and_swap(base + p + 6); + thumb_rx = poly::load_and_swap(base + p + 8); + thumb_ry = poly::load_and_swap(base + p + 10); } void Write(uint8_t* base, uint32_t p) { - XESETUINT16BE(base + p, buttons); - XESETUINT8BE(base + p + 2, left_trigger); - XESETUINT8BE(base + p + 3, right_trigger); - XESETINT16BE(base + p + 4, thumb_lx); - XESETINT16BE(base + p + 6, thumb_ly); - XESETINT16BE(base + p + 8, thumb_rx); - XESETINT16BE(base + p + 10, thumb_ry); + poly::store_and_swap(base + p, buttons); + poly::store_and_swap(base + p + 2, left_trigger); + poly::store_and_swap(base + p + 3, right_trigger); + poly::store_and_swap(base + p + 4, thumb_lx); + poly::store_and_swap(base + p + 6, thumb_ly); + poly::store_and_swap(base + p + 8, thumb_rx); + poly::store_and_swap(base + p + 10, thumb_ry); } void Zero() { buttons = 0; @@ -337,11 +337,11 @@ public: Read(base, p); } void Read(const uint8_t* base, uint32_t p) { - packet_number = XEGETUINT32BE(base + p); + packet_number = poly::load_and_swap(base + p); gamepad.Read(base, p + 4); } void Write(uint8_t* base, uint32_t p) { - XESETUINT32BE(base + p, packet_number); + poly::store_and_swap(base + p, packet_number); gamepad.Write(base, p + 4); } void Zero() { @@ -361,12 +361,12 @@ public: Read(base, p); } void Read(const uint8_t* base, uint32_t p) { - left_motor_speed = XEGETUINT16BE(base + p); - right_motor_speed = XEGETUINT16BE(base + p + 2); + left_motor_speed = poly::load_and_swap(base + p); + right_motor_speed = poly::load_and_swap(base + p + 2); } void Write(uint8_t* base, uint32_t p) { - XESETUINT16BE(base + p, left_motor_speed); - XESETUINT16BE(base + p + 2, right_motor_speed); + poly::store_and_swap(base + p, left_motor_speed); + poly::store_and_swap(base + p + 2, right_motor_speed); } void Zero() { left_motor_speed = right_motor_speed = 0; @@ -387,16 +387,16 @@ public: Read(base, p); } void Read(const uint8_t* base, uint32_t p) { - type = XEGETUINT8BE(base + p); - sub_type = XEGETUINT8BE(base + p + 1); - flags = XEGETUINT16BE(base + p + 2); + type = poly::load_and_swap(base + p); + sub_type = poly::load_and_swap(base + p + 1); + flags = poly::load_and_swap(base + p + 2); gamepad.Read(base, p + 4); vibration.Read(base, p + 4 + 12); } void Write(uint8_t* base, uint32_t p) { - XESETUINT8BE(base + p, type); - XESETUINT8BE(base + p + 1, sub_type); - XESETUINT16BE(base + p + 2, flags); + poly::store_and_swap(base + p, type); + poly::store_and_swap(base + p + 1, sub_type); + poly::store_and_swap(base + p + 2, flags); gamepad.Write(base, p + 4); vibration.Write(base, p + 4 + 12); } @@ -424,18 +424,18 @@ public: Read(base, p); } void Read(const uint8_t* base, uint32_t p) { - virtual_key = XEGETUINT16BE(base + p + 0); - unicode = XEGETUINT16BE(base + p + 2); - flags = XEGETUINT16BE(base + p + 4); - user_index = XEGETUINT8BE(base + p + 6); - hid_code = XEGETUINT8BE(base + p + 7); + virtual_key = poly::load_and_swap(base + p + 0); + unicode = poly::load_and_swap(base + p + 2); + flags = poly::load_and_swap(base + p + 4); + user_index = poly::load_and_swap(base + p + 6); + hid_code = poly::load_and_swap(base + p + 7); } void Write(uint8_t* base, uint32_t p) { - XESETUINT16BE(base + p + 0, virtual_key); - XESETUINT16BE(base + p + 2, unicode); - XESETUINT16BE(base + p + 4, flags); - XESETUINT8BE(base + p + 6, user_index); - XESETUINT8BE(base + p + 7, hid_code); + poly::store_and_swap(base + p + 0, virtual_key); + poly::store_and_swap(base + p + 2, unicode); + poly::store_and_swap(base + p + 4, flags); + poly::store_and_swap(base + p + 6, user_index); + poly::store_and_swap(base + p + 7, hid_code); } void Zero() { virtual_key = 0; From 3197198cf225292d549313f6ff8278d549887044 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 17 Jul 2014 19:38:14 -0700 Subject: [PATCH 034/388] Trying travis build. Will fail. --- .travis.yml | 16 ++++++++++++++++ test/run-tests.sh | 4 ++++ 2 files changed, 20 insertions(+) create mode 100644 .travis.yml create mode 100644 test/run-tests.sh diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..44106930b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +language: cpp +compiler: + - clang + # - gcc don't really care + +os: + - linux + - osx # beta only + +# Run setup to build ninja/gyp/etc and actually build xenia. +before_script: + - travis_retry ./xenia-build.py setup + - ./xenia-build.py build + +# Run test suite. +script: ./test/run-tests.sh diff --git a/test/run-tests.sh b/test/run-tests.sh new file mode 100644 index 000000000..7d31e8a0c --- /dev/null +++ b/test/run-tests.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +# TODO(benvanik): tests :) +exit 0 From 4cbd267a528e47c899e3271f1a092848cbbda601 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 17 Jul 2014 19:49:58 -0700 Subject: [PATCH 035/388] Fixing path case. --- .travis.yml | 2 +- xenia-build.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 44106930b..5bc48c98d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ os: # Run setup to build ninja/gyp/etc and actually build xenia. before_script: - travis_retry ./xenia-build.py setup - - ./xenia-build.py build + - ./xenia-build.py build --debug # Run test suite. script: ./test/run-tests.sh diff --git a/xenia-build.py b/xenia-build.py index 248128236..ff5fd32d6 100755 --- a/xenia-build.py +++ b/xenia-build.py @@ -416,7 +416,7 @@ class BuildCommand(Command): # TODO(benvanik): add arguments: # --force debug = '--debug' in args - config = 'debug' if debug else 'release' + config = 'Debug' if debug else 'Release' print('Building %s...' % (config)) print('') From 19b6e90b63c0ff32ae526cddfc35797aa73a0732 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 17 Jul 2014 20:43:27 -0700 Subject: [PATCH 036/388] Alloy now builds on clang. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hopefully not just bouncing back to MSVC failures… --- src/alloy/backend/x64/x64_sequence.inl | 75 ++++++----- src/alloy/backend/x64/x64_sequences.cc | 124 +++++++++--------- .../compiler/passes/value_reduction_pass.cc | 4 +- src/alloy/frontend/ppc/ppc_disasm.cc | 3 + src/alloy/hir/value.h | 2 +- src/poly/cxx_compat.h | 7 + src/poly/threading.h | 2 +- 7 files changed, 121 insertions(+), 96 deletions(-) diff --git a/src/alloy/backend/x64/x64_sequence.inl b/src/alloy/backend/x64/x64_sequence.inl index 50466b3af..d0f9e539d 100644 --- a/src/alloy/backend/x64/x64_sequence.inl +++ b/src/alloy/backend/x64/x64_sequence.inl @@ -183,33 +183,37 @@ protected: template struct I8 : ValueOp, KEY_TYPE_V_I8, Reg8, int8_t, TAG> { + typedef ValueOp, KEY_TYPE_V_I8, Reg8, int8_t, TAG> BASE; const int8_t constant() const { - assert_true(is_constant); - return value->constant.i8; + assert_true(BASE::is_constant); + return BASE::value->constant.i8; } }; template struct I16 : ValueOp, KEY_TYPE_V_I16, Reg16, int16_t, TAG> { + typedef ValueOp, KEY_TYPE_V_I16, Reg16, int16_t, TAG> BASE; const int16_t constant() const { - assert_true(is_constant); - return value->constant.i16; + assert_true(BASE::is_constant); + return BASE::value->constant.i16; } }; template struct I32 : ValueOp, KEY_TYPE_V_I32, Reg32, int32_t, TAG> { + typedef ValueOp, KEY_TYPE_V_I32, Reg32, int32_t, TAG> BASE; const int32_t constant() const { - assert_true(is_constant); - return value->constant.i32; + assert_true(BASE::is_constant); + return BASE::value->constant.i32; } }; template struct I64 : ValueOp, KEY_TYPE_V_I64, Reg64, int64_t, TAG> { + typedef ValueOp, KEY_TYPE_V_I64, Reg64, int64_t, TAG> BASE; const int64_t constant() const { - assert_true(is_constant); - return value->constant.i64; + assert_true(BASE::is_constant); + return BASE::value->constant.i64; } bool ConstantFitsIn32Reg() const override { - int64_t v = value->constant.i64; + int64_t v = BASE::value->constant.i64; if ((v & ~0x7FFFFFFF) == 0) { // Fits under 31 bits, so just load using normal mov. return true; @@ -222,23 +226,26 @@ struct I64 : ValueOp, KEY_TYPE_V_I64, Reg64, int64_t, TAG> { }; template struct F32 : ValueOp, KEY_TYPE_V_F32, Xmm, float, TAG> { + typedef ValueOp, KEY_TYPE_V_F32, Xmm, float, TAG> BASE; const float constant() const { - assert_true(is_constant); - return value->constant.f32; + assert_true(BASE::is_constant); + return BASE::value->constant.f32; } }; template struct F64 : ValueOp, KEY_TYPE_V_F64, Xmm, double, TAG> { + typedef ValueOp, KEY_TYPE_V_F64, Xmm, double, TAG> BASE; const double constant() const { - assert_true(is_constant); - return value->constant.f64; + assert_true(BASE::is_constant); + return BASE::value->constant.f64; } }; template struct V128 : ValueOp, KEY_TYPE_V_V128, Xmm, vec128_t, TAG> { + typedef ValueOp, KEY_TYPE_V_V128, Xmm, vec128_t, TAG> BASE; const vec128_t& constant() const { - assert_true(is_constant); - return value->constant.v128; + assert_true(BASE::is_constant); + return BASE::value->constant.v128; } }; @@ -308,6 +315,7 @@ template struct I; template struct I : DestField { + typedef DestField BASE; static const hir::Opcode opcode = OPCODE; static const uint32_t key = InstrKey::Construct::value; static const KeyType dest_type = DEST::key_type; @@ -316,7 +324,7 @@ protected: template friend struct SequenceFields; bool Load(const Instr* i, TagTable& tag_table) { if (InstrKey(i).value == key && - LoadDest(i, tag_table)) { + BASE::LoadDest(i, tag_table)) { instr = i; return true; } @@ -325,6 +333,7 @@ protected: }; template struct I : DestField { + typedef DestField BASE; static const hir::Opcode opcode = OPCODE; static const uint32_t key = InstrKey::Construct::value; static const KeyType dest_type = DEST::key_type; @@ -335,7 +344,7 @@ protected: template friend struct SequenceFields; bool Load(const Instr* i, TagTable& tag_table) { if (InstrKey(i).value == key && - LoadDest(i, tag_table) && + BASE::LoadDest(i, tag_table) && tag_table.CheckTag(i->src1)) { instr = i; src1.Load(i->src1); @@ -346,6 +355,7 @@ protected: }; template struct I : DestField { + typedef DestField BASE; static const hir::Opcode opcode = OPCODE; static const uint32_t key = InstrKey::Construct::value; static const KeyType dest_type = DEST::key_type; @@ -358,7 +368,7 @@ protected: template friend struct SequenceFields; bool Load(const Instr* i, TagTable& tag_table) { if (InstrKey(i).value == key && - LoadDest(i, tag_table) && + BASE::LoadDest(i, tag_table) && tag_table.CheckTag(i->src1) && tag_table.CheckTag(i->src2)) { instr = i; @@ -371,6 +381,7 @@ protected: }; template struct I : DestField { + typedef DestField BASE; static const hir::Opcode opcode = OPCODE; static const uint32_t key = InstrKey::Construct::value; static const KeyType dest_type = DEST::key_type; @@ -385,7 +396,7 @@ protected: template friend struct SequenceFields; bool Load(const Instr* i, TagTable& tag_table) { if (InstrKey(i).value == key && - LoadDest(i, tag_table) && + BASE::LoadDest(i, tag_table) && tag_table.CheckTag(i->src1) && tag_table.CheckTag(i->src2) && tag_table.CheckTag(i->src3)) { @@ -404,7 +415,6 @@ struct SequenceFields; template struct SequenceFields { I1 i1; - typedef typename I1 I1Type; protected: template friend struct Sequence; bool Check(const Instr* i, TagTable& tag_table, const Instr** new_tail) { @@ -516,9 +526,10 @@ const Reg64 GetTempReg(X64Emitter& e) { template struct SingleSequence : public Sequence, T> { + typedef Sequence, T> BASE; typedef T EmitArgType; static const uint32_t head_key = T::key; - static void Emit(X64Emitter& e, const EmitArgs& _) { + static void Emit(X64Emitter& e, const typename BASE::EmitArgs& _) { SEQ::Emit(e, _.i1); } @@ -547,7 +558,7 @@ struct SingleSequence : public Sequence, T> { if (i.src1.ConstantFitsIn32Reg()) { reg_const_fn(e, i.dest, static_cast(i.src1.constant())); } else { - auto temp = GetTempReg(e); + auto temp = GetTempReg(e); e.mov(temp, i.src1.constant()); reg_reg_fn(e, i.dest, temp); } @@ -560,7 +571,7 @@ struct SingleSequence : public Sequence, T> { if (i.src2.ConstantFitsIn32Reg()) { reg_const_fn(e, i.dest, static_cast(i.src2.constant())); } else { - auto temp = GetTempReg(e); + auto temp = GetTempReg(e); e.mov(temp, i.src2.constant()); reg_reg_fn(e, i.dest, temp); } @@ -586,7 +597,7 @@ struct SingleSequence : public Sequence, T> { if (i.src1.is_constant) { assert_true(!i.src2.is_constant); if (i.dest == i.src2) { - auto temp = GetTempReg(e); + auto temp = GetTempReg(e); e.mov(temp, i.src2); e.mov(i.dest, i.src1.constant()); reg_reg_fn(e, i.dest, temp); @@ -599,7 +610,7 @@ struct SingleSequence : public Sequence, T> { if (i.src2.ConstantFitsIn32Reg()) { reg_const_fn(e, i.dest, static_cast(i.src2.constant())); } else { - auto temp = GetTempReg(e); + auto temp = GetTempReg(e); e.mov(temp, i.src2.constant()); reg_reg_fn(e, i.dest, temp); } @@ -608,7 +619,7 @@ struct SingleSequence : public Sequence, T> { if (i.src2.ConstantFitsIn32Reg()) { reg_const_fn(e, i.dest, static_cast(i.src2.constant())); } else { - auto temp = GetTempReg(e); + auto temp = GetTempReg(e); e.mov(temp, i.src2.constant()); reg_reg_fn(e, i.dest, temp); } @@ -617,7 +628,7 @@ struct SingleSequence : public Sequence, T> { if (i.dest == i.src1) { reg_reg_fn(e, i.dest, i.src2); } else if (i.dest == i.src2) { - auto temp = GetTempReg(e); + auto temp = GetTempReg(e); e.mov(temp, i.src2); e.mov(i.dest, i.src1); reg_reg_fn(e, i.dest, temp); @@ -667,7 +678,7 @@ struct SingleSequence : public Sequence, T> { if (i.src1.ConstantFitsIn32Reg()) { reg_const_fn(e, i.src2, static_cast(i.src1.constant())); } else { - auto temp = GetTempReg(e); + auto temp = GetTempReg(e); e.mov(temp, i.src1.constant()); reg_reg_fn(e, i.src2, temp); } @@ -675,7 +686,7 @@ struct SingleSequence : public Sequence, T> { if (i.src2.ConstantFitsIn32Reg()) { reg_const_fn(e, i.src1, static_cast(i.src2.constant())); } else { - auto temp = GetTempReg(e); + auto temp = GetTempReg(e); e.mov(temp, i.src2.constant()); reg_reg_fn(e, i.src1, temp); } @@ -692,7 +703,7 @@ struct SingleSequence : public Sequence, T> { if (i.src1.ConstantFitsIn32Reg()) { reg_const_fn(e, i.dest, i.src2, static_cast(i.src1.constant()), true); } else { - auto temp = GetTempReg(e); + auto temp = GetTempReg(e); e.mov(temp, i.src1.constant()); reg_reg_fn(e, i.dest, i.src2, temp, true); } @@ -700,7 +711,7 @@ struct SingleSequence : public Sequence, T> { if (i.src2.ConstantFitsIn32Reg()) { reg_const_fn(e, i.dest, i.src1, static_cast(i.src2.constant()), false); } else { - auto temp = GetTempReg(e); + auto temp = GetTempReg(e); e.mov(temp, i.src2.constant()); reg_reg_fn(e, i.dest, i.src1, temp, false); } @@ -721,8 +732,6 @@ static const tag_t TAG5 = 5; static const tag_t TAG6 = 6; static const tag_t TAG7 = 7; -typedef bool (*SequenceSelectFn)(X64Emitter&, const Instr*, const Instr**); - template void Register() { sequence_table.insert({ T::head_key, T::Select }); diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index b89916585..cb6f7d260 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -39,11 +39,12 @@ using namespace Xbyak; using namespace alloy::hir; using namespace alloy::runtime; +typedef bool (*SequenceSelectFn)(X64Emitter&, const Instr*, const Instr**); +std::unordered_multimap sequence_table; + // Utilities/types used only in this file: #include -std::unordered_multimap sequence_table; - // Selects the right byte/word/etc from a vector. We need to flip logical // indices (0,1,2,3,4,5,6,7,...) = (3,2,1,0,7,6,5,4,...) #define VEC128_B(n) ((n) ^ 0x3) @@ -63,7 +64,7 @@ EMITTER(COMMENT, MATCH(I)) { // TODO(benvanik): don't just leak this memory. auto str_copy = strdup(str); e.mov(e.rdx, reinterpret_cast(str_copy)); - e.CallNative(TraceString); + e.CallNative(reinterpret_cast(TraceString)); } } }; @@ -1104,12 +1105,7 @@ EMITTER(LOAD_CLOCK, MATCH(I>)) { e.mov(i.dest, e.rax); } static uint64_t LoadClock(void* raw_context) { - LARGE_INTEGER counter; - uint64_t time = 0; - if (QueryPerformanceCounter(&counter)) { - time = counter.QuadPart; - } - return time; + return poly::threading::ticks(); } }; EMITTER_OPCODE_TABLE( @@ -1245,7 +1241,7 @@ EMITTER(LOAD_CONTEXT_I8, MATCH(I, OffsetOp>)) { if (IsTracingData()) { e.mov(e.r8, e.byte[addr]); e.mov(e.rdx, i.src1.value); - e.CallNative(TraceContextLoadI8); + e.CallNative(reinterpret_cast(TraceContextLoadI8)); } } }; @@ -1256,7 +1252,7 @@ EMITTER(LOAD_CONTEXT_I16, MATCH(I, OffsetOp>)) { if (IsTracingData()) { e.mov(e.r8, e.word[addr]); e.mov(e.rdx, i.src1.value); - e.CallNative(TraceContextLoadI16); + e.CallNative(reinterpret_cast(TraceContextLoadI16)); } } }; @@ -1267,7 +1263,7 @@ EMITTER(LOAD_CONTEXT_I32, MATCH(I, OffsetOp>)) { if (IsTracingData()) { e.mov(e.r8, e.dword[addr]); e.mov(e.rdx, i.src1.value); - e.CallNative(TraceContextLoadI32); + e.CallNative(reinterpret_cast(TraceContextLoadI32)); } } }; @@ -1278,7 +1274,7 @@ EMITTER(LOAD_CONTEXT_I64, MATCH(I, OffsetOp>)) { if (IsTracingData()) { e.mov(e.r8, e.qword[addr]); e.mov(e.rdx, i.src1.value); - e.CallNative(TraceContextLoadI64); + e.CallNative(reinterpret_cast(TraceContextLoadI64)); } } }; @@ -1289,7 +1285,7 @@ EMITTER(LOAD_CONTEXT_F32, MATCH(I, OffsetOp>)) { if (IsTracingData()) { e.lea(e.r8, e.dword[addr]); e.mov(e.rdx, i.src1.value); - e.CallNative(TraceContextLoadF32); + e.CallNative(reinterpret_cast(TraceContextLoadF32)); } } }; @@ -1300,7 +1296,7 @@ EMITTER(LOAD_CONTEXT_F64, MATCH(I, OffsetOp>)) { if (IsTracingData()) { e.lea(e.r8, e.qword[addr]); e.mov(e.rdx, i.src1.value); - e.CallNative(TraceContextLoadF64); + e.CallNative(reinterpret_cast(TraceContextLoadF64)); } } }; @@ -1311,7 +1307,7 @@ EMITTER(LOAD_CONTEXT_V128, MATCH(I, OffsetOp>)) { if (IsTracingData()) { e.lea(e.r8, e.ptr[addr]); e.mov(e.rdx, i.src1.value); - e.CallNative(TraceContextLoadV128); + e.CallNative(reinterpret_cast(TraceContextLoadV128)); } } }; @@ -1341,7 +1337,7 @@ EMITTER(STORE_CONTEXT_I8, MATCH(I>) if (IsTracingData()) { e.mov(e.r8, e.byte[addr]); e.mov(e.rdx, i.src1.value); - e.CallNative(TraceContextStoreI8); + e.CallNative(reinterpret_cast(TraceContextStoreI8)); } } }; @@ -1356,7 +1352,7 @@ EMITTER(STORE_CONTEXT_I16, MATCH(I if (IsTracingData()) { e.mov(e.r8, e.word[addr]); e.mov(e.rdx, i.src1.value); - e.CallNative(TraceContextStoreI16); + e.CallNative(reinterpret_cast(TraceContextStoreI16)); } } }; @@ -1371,7 +1367,7 @@ EMITTER(STORE_CONTEXT_I32, MATCH(I if (IsTracingData()) { e.mov(e.r8, e.dword[addr]); e.mov(e.rdx, i.src1.value); - e.CallNative(TraceContextStoreI32); + e.CallNative(reinterpret_cast(TraceContextStoreI32)); } } }; @@ -1386,7 +1382,7 @@ EMITTER(STORE_CONTEXT_I64, MATCH(I if (IsTracingData()) { e.mov(e.r8, e.qword[addr]); e.mov(e.rdx, i.src1.value); - e.CallNative(TraceContextStoreI64); + e.CallNative(reinterpret_cast(TraceContextStoreI64)); } } }; @@ -1401,7 +1397,7 @@ EMITTER(STORE_CONTEXT_F32, MATCH(I if (IsTracingData()) { e.lea(e.r8, e.dword[addr]); e.mov(e.rdx, i.src1.value); - e.CallNative(TraceContextStoreF32); + e.CallNative(reinterpret_cast(TraceContextStoreF32)); } } }; @@ -1416,7 +1412,7 @@ EMITTER(STORE_CONTEXT_F64, MATCH(I if (IsTracingData()) { e.lea(e.r8, e.qword[addr]); e.mov(e.rdx, i.src1.value); - e.CallNative(TraceContextStoreF64); + e.CallNative(reinterpret_cast(TraceContextStoreF64)); } } }; @@ -1432,7 +1428,7 @@ EMITTER(STORE_CONTEXT_V128, MATCH(I(TraceContextStoreV128)); } } }; @@ -1473,7 +1469,7 @@ EMITTER(LOAD_I8, MATCH(I, I64<>>)) { if (IsTracingData()) { e.mov(e.r8b, i.dest); e.lea(e.rdx, e.ptr[addr]); - e.CallNative(TraceMemoryLoadI8); + e.CallNative(reinterpret_cast(TraceMemoryLoadI8)); } } }; @@ -1484,7 +1480,7 @@ EMITTER(LOAD_I16, MATCH(I, I64<>>)) { if (IsTracingData()) { e.mov(e.r8w, i.dest); e.lea(e.rdx, e.ptr[addr]); - e.CallNative(TraceMemoryLoadI16); + e.CallNative(reinterpret_cast(TraceMemoryLoadI16)); } } }; @@ -1495,7 +1491,7 @@ EMITTER(LOAD_I32, MATCH(I, I64<>>)) { if (IsTracingData()) { e.mov(e.r8d, i.dest); e.lea(e.rdx, e.ptr[addr]); - e.CallNative(TraceMemoryLoadI32); + e.CallNative(reinterpret_cast(TraceMemoryLoadI32)); } } }; @@ -1506,7 +1502,7 @@ EMITTER(LOAD_I64, MATCH(I, I64<>>)) { if (IsTracingData()) { e.mov(e.r8, i.dest); e.lea(e.rdx, e.ptr[addr]); - e.CallNative(TraceMemoryLoadI64); + e.CallNative(reinterpret_cast(TraceMemoryLoadI64)); } } }; @@ -1517,7 +1513,7 @@ EMITTER(LOAD_F32, MATCH(I, I64<>>)) { if (IsTracingData()) { e.lea(e.r8, e.dword[addr]); e.lea(e.rdx, e.ptr[addr]); - e.CallNative(TraceMemoryLoadF32); + e.CallNative(reinterpret_cast(TraceMemoryLoadF32)); } } }; @@ -1528,7 +1524,7 @@ EMITTER(LOAD_F64, MATCH(I, I64<>>)) { if (IsTracingData()) { e.lea(e.r8, e.qword[addr]); e.lea(e.rdx, e.ptr[addr]); - e.CallNative(TraceMemoryLoadF64); + e.CallNative(reinterpret_cast(TraceMemoryLoadF64)); } } }; @@ -1540,7 +1536,7 @@ EMITTER(LOAD_V128, MATCH(I, I64<>>)) { if (IsTracingData()) { e.lea(e.r8, e.ptr[addr]); e.lea(e.rdx, e.ptr[addr]); - e.CallNative(TraceMemoryLoadV128); + e.CallNative(reinterpret_cast(TraceMemoryLoadV128)); } } }; @@ -1578,7 +1574,7 @@ EMITTER(STORE_I8, MATCH(I, I8<>>)) { auto addr = ComputeMemoryAddress(e, i.src1); e.mov(e.r8b, e.byte[addr]); e.lea(e.rdx, e.ptr[addr]); - e.CallNative(TraceMemoryStoreI8); + e.CallNative(reinterpret_cast(TraceMemoryStoreI8)); } } }; @@ -1595,7 +1591,7 @@ EMITTER(STORE_I16, MATCH(I, I16<>>)) { auto addr = ComputeMemoryAddress(e, i.src1); e.mov(e.r8w, e.word[addr]); e.lea(e.rdx, e.ptr[addr]); - e.CallNative(TraceMemoryStoreI16); + e.CallNative(reinterpret_cast(TraceMemoryStoreI16)); } } }; @@ -1612,7 +1608,7 @@ EMITTER(STORE_I32, MATCH(I, I32<>>)) { auto addr = ComputeMemoryAddress(e, i.src1); e.mov(e.r8d, e.dword[addr]); e.lea(e.rdx, e.ptr[addr]); - e.CallNative(TraceMemoryStoreI32); + e.CallNative(reinterpret_cast(TraceMemoryStoreI32)); } } }; @@ -1629,7 +1625,7 @@ EMITTER(STORE_I64, MATCH(I, I64<>>)) { auto addr = ComputeMemoryAddress(e, i.src1); e.mov(e.r8, e.qword[addr]); e.lea(e.rdx, e.ptr[addr]); - e.CallNative(TraceMemoryStoreI64); + e.CallNative(reinterpret_cast(TraceMemoryStoreI64)); } } }; @@ -1646,7 +1642,7 @@ EMITTER(STORE_F32, MATCH(I, F32<>>)) { auto addr = ComputeMemoryAddress(e, i.src1); e.lea(e.r8, e.ptr[addr]); e.lea(e.rdx, e.ptr[addr]); - e.CallNative(TraceMemoryStoreF32); + e.CallNative(reinterpret_cast(TraceMemoryStoreF32)); } } }; @@ -1663,7 +1659,7 @@ EMITTER(STORE_F64, MATCH(I, F64<>>)) { auto addr = ComputeMemoryAddress(e, i.src1); e.lea(e.r8, e.ptr[addr]); e.lea(e.rdx, e.ptr[addr]); - e.CallNative(TraceMemoryStoreF64); + e.CallNative(reinterpret_cast(TraceMemoryStoreF64)); } } }; @@ -1681,7 +1677,7 @@ EMITTER(STORE_V128, MATCH(I, V128<>>)) { auto addr = ComputeMemoryAddress(e, i.src1); e.lea(e.r8, e.ptr[addr]); e.lea(e.rdx, e.ptr[addr]); - e.CallNative(TraceMemoryStoreV128); + e.CallNative(reinterpret_cast(TraceMemoryStoreV128)); } } }; @@ -2099,7 +2095,7 @@ EMITTER_OPCODE_TABLE( // OPCODE_COMPARE_* // ============================================================================ #define EMITTER_ASSOCIATIVE_COMPARE_INT(op, instr, inverse_instr, type, reg_type) \ - EMITTER(COMPARE_##op##_##type, MATCH(I, type<>, type<>>)) { \ + EMITTER(COMPARE_##op##_##type, MATCH(I, type<>, type<>>)) { \ static void Emit(X64Emitter& e, const EmitArgType& i) { \ EmitAssociativeCompareOp( \ e, i, \ @@ -2119,7 +2115,7 @@ EMITTER_OPCODE_TABLE( EMITTER_ASSOCIATIVE_COMPARE_INT(op, instr, inverse_instr, I32, Reg32); \ EMITTER_ASSOCIATIVE_COMPARE_INT(op, instr, inverse_instr, I64, Reg64); \ EMITTER_OPCODE_TABLE( \ - OPCODE_COMPARE_##op##, \ + OPCODE_COMPARE_##op, \ COMPARE_##op##_I8, \ COMPARE_##op##_I16, \ COMPARE_##op##_I32, \ @@ -2135,13 +2131,13 @@ EMITTER_ASSOCIATIVE_COMPARE_XX(UGE, setae, setb); // http://x86.renejeschke.de/html/file_module_x86_id_288.html #define EMITTER_ASSOCIATIVE_COMPARE_FLT_XX(op, instr) \ - EMITTER(COMPARE_##op##_F32, MATCH(I, F32<>, F32<>>)) { \ + EMITTER(COMPARE_##op##_F32, MATCH(I, F32<>, F32<>>)) { \ static void Emit(X64Emitter& e, const EmitArgType& i) { \ e.vcomiss(i.src1, i.src2); \ e.instr(i.dest); \ } \ }; \ - EMITTER(COMPARE_##op##_F64, MATCH(I, F64<>, F64<>>)) { \ + EMITTER(COMPARE_##op##_F64, MATCH(I, F64<>, F64<>>)) { \ static void Emit(X64Emitter& e, const EmitArgType& i) { \ if (i.src1.is_constant) { \ e.LoadConstantXmm(e.xmm0, i.src1.constant()); \ @@ -3479,39 +3475,44 @@ EMITTER_OPCODE_TABLE( // http://jrfonseca.blogspot.com/2008/09/fast-sse2-pow-tables-or-polynomials.html EMITTER(POW2_F32, MATCH(I, F32<>>)) { static __m128 EmulatePow2(__m128 src) { - float result = static_cast(pow(2, src.m128_f32[0])); + float src_value; + _mm_store_ss(&src_value, src); + float result = std::pow(2, src_value); return _mm_load_ss(&result); } static void Emit(X64Emitter& e, const EmitArgType& i) { assert_always(); e.lea(e.r8, e.StashXmm(i.src1)); - e.CallNativeSafe(EmulatePow2); + e.CallNativeSafe(reinterpret_cast(EmulatePow2)); e.vmovaps(i.dest, e.xmm0); } }; EMITTER(POW2_F64, MATCH(I, F64<>>)) { static __m128d EmulatePow2(__m128 src) { - double result = pow(2, src.m128_f32[0]); + double src_value; + _mm_store_sd(&src_value, src); + double result = std::pow(2, src_value); return _mm_load_sd(&result); } static void Emit(X64Emitter& e, const EmitArgType& i) { assert_always(); e.lea(e.r8, e.StashXmm(i.src1)); - e.CallNativeSafe(EmulatePow2); + e.CallNativeSafe(reinterpret_cast(EmulatePow2)); e.vmovaps(i.dest, e.xmm0); } }; EMITTER(POW2_V128, MATCH(I, V128<>>)) { static __m128 EmulatePow2(__m128 src) { - __m128 result; + alignas(16) float values[4]; + _mm_store_ps(values, src); for (size_t i = 0; i < 4; ++i) { - result.m128_f32[i] = static_cast(pow(2, src.m128_f32[i])); + values[i] = std::pow(2, values[i]); } - return result; + return _mm_load_ps(values); } static void Emit(X64Emitter& e, const EmitArgType& i) { e.lea(e.r8, e.StashXmm(i.src1)); - e.CallNativeSafe(EmulatePow2); + e.CallNativeSafe(reinterpret_cast(EmulatePow2)); e.vmovaps(i.dest, e.xmm0); } }; @@ -3530,39 +3531,44 @@ EMITTER_OPCODE_TABLE( // TODO(benvanik): this emulated fn destroys all xmm registers! don't do it! EMITTER(LOG2_F32, MATCH(I, F32<>>)) { static __m128 EmulateLog2(__m128 src) { - float result = log2(src.m128_f32[0]); + float src_value; + _mm_store_ss(&src_value, src); + float result = std::log2(src_value); return _mm_load_ss(&result); } static void Emit(X64Emitter& e, const EmitArgType& i) { assert_always(); e.lea(e.r8, e.StashXmm(i.src1)); - e.CallNativeSafe(EmulateLog2); + e.CallNativeSafe(reinterpret_cast(EmulateLog2)); e.vmovaps(i.dest, e.xmm0); } }; EMITTER(LOG2_F64, MATCH(I, F64<>>)) { static __m128d EmulateLog2(__m128d src) { - double result = log2(src.m128d_f64[0]); + double src_value; + _mm_store_sd(&src_value, src); + double result = std::log2(src_value); return _mm_load_sd(&result); } static void Emit(X64Emitter& e, const EmitArgType& i) { assert_always(); e.lea(e.r8, e.StashXmm(i.src1)); - e.CallNativeSafe(EmulateLog2); + e.CallNativeSafe(reinterpret_cast(EmulateLog2)); e.vmovaps(i.dest, e.xmm0); } }; EMITTER(LOG2_V128, MATCH(I, V128<>>)) { static __m128 EmulateLog2(__m128 src) { - __m128 result; + alignas(16) float values[4]; + _mm_store_ps(values, src); for (size_t i = 0; i < 4; ++i) { - result.m128_f32[i] = log2(src.m128_f32[i]); + values[i] = std::log2(values[i]); } - return result; + return _mm_load_ps(values); } static void Emit(X64Emitter& e, const EmitArgType& i) { e.lea(e.r8, e.StashXmm(i.src1)); - e.CallNativeSafe(EmulateLog2); + e.CallNativeSafe(reinterpret_cast(EmulateLog2)); e.vmovaps(i.dest, e.xmm0); } }; @@ -4996,7 +5002,7 @@ EMITTER_OPCODE_TABLE( -void alloy::backend::x64::RegisterSequences() { +void RegisterSequences() { #define REGISTER_EMITTER_OPCODE_TABLE(opcode) Register_##opcode() REGISTER_EMITTER_OPCODE_TABLE(OPCODE_COMMENT); REGISTER_EMITTER_OPCODE_TABLE(OPCODE_NOP); @@ -5109,7 +5115,7 @@ void alloy::backend::x64::RegisterSequences() { //REGISTER_EMITTER_OPCODE_TABLE(OPCODE_ATOMIC_SUB); } -bool alloy::backend::x64::SelectSequence(X64Emitter& e, const Instr* i, const Instr** new_tail) { +bool SelectSequence(X64Emitter& e, const Instr* i, const Instr** new_tail) { const InstrKey key(i); const auto its = sequence_table.equal_range(key); for (auto it = its.first; it != its.second; ++it) { diff --git a/src/alloy/compiler/passes/value_reduction_pass.cc b/src/alloy/compiler/passes/value_reduction_pass.cc index 4c5cf2e28..1d51de912 100644 --- a/src/alloy/compiler/passes/value_reduction_pass.cc +++ b/src/alloy/compiler/passes/value_reduction_pass.cc @@ -43,7 +43,7 @@ void ValueReductionPass::ComputeLastUse(Value* value) { // Note that this list isn't sorted (unfortunately), so we have to scan // them all. uint32_t max_ordinal = 0; - Value::Use* last_use = NULL; + Value::Use* last_use = nullptr; auto use = value->use_head; while (use) { if (!last_use || use->instr->ordinal >= max_ordinal) { @@ -52,7 +52,7 @@ void ValueReductionPass::ComputeLastUse(Value* value) { } use = use->next; } - value->last_use = last_use->instr; + value->last_use = last_use ? last_use->instr : nullptr; } int ValueReductionPass::Run(HIRBuilder* builder) { diff --git a/src/alloy/frontend/ppc/ppc_disasm.cc b/src/alloy/frontend/ppc/ppc_disasm.cc index 8c832ce2f..d7a46b561 100644 --- a/src/alloy/frontend/ppc/ppc_disasm.cc +++ b/src/alloy/frontend/ppc/ppc_disasm.cc @@ -248,6 +248,9 @@ void Disasm_dcbf(InstrData& i, StringBuffer* str) { case 3: name = "dcbflp"; break; + default: + name = "dcbf.??"; + break; } str->Append("%-8s r%d, r%d", name, i.X.RA, i.X.RB); } diff --git a/src/alloy/hir/value.h b/src/alloy/hir/value.h index f88f5d6cd..1a3097480 100644 --- a/src/alloy/hir/value.h +++ b/src/alloy/hir/value.h @@ -34,7 +34,7 @@ enum TypeName { MAX_TYPENAME, }; -static size_t GetTypeSize(TypeName type_name) { +inline size_t GetTypeSize(TypeName type_name) { switch (type_name) { case INT8_TYPE: return 1; diff --git a/src/poly/cxx_compat.h b/src/poly/cxx_compat.h index d2d03897f..ba68ca0a8 100644 --- a/src/poly/cxx_compat.h +++ b/src/poly/cxx_compat.h @@ -23,6 +23,13 @@ #define thread_local __thread #endif // XE_COMPILER_MSVC +// C++11 alignas keyword. +// This will hopefully be coming soon, as most of the alignment spec is in the +// latest CTP. +#if XE_COMPILER_MSVC +#define alignas(N) __declspec(align(N)) +#endif // XE_COMPILER_MSVC + namespace poly {} // namespace poly #endif // POLY_CXX_COMPAT_H_ diff --git a/src/poly/threading.h b/src/poly/threading.h index 5059aaf3a..431dda291 100644 --- a/src/poly/threading.h +++ b/src/poly/threading.h @@ -18,7 +18,7 @@ namespace poly { namespace threading { -// Gets the current high-perforance tick count. +// Gets the current high-performance tick count. uint64_t ticks(); // Gets a stable thread-specific ID, but may not be. Use for informative From 0c5110ac3e3ee9b9ad1a234a3a207333ae9825bb Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 17 Jul 2014 20:52:56 -0700 Subject: [PATCH 037/388] Fixing warnings. --- src/alloy/backend/x64/x64_sequences.cc | 6 ++-- src/xenia/kernel/util/shim_utils.h | 38 +++++++++++++------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index cb6f7d260..80e481a33 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -3477,7 +3477,7 @@ EMITTER(POW2_F32, MATCH(I, F32<>>)) { static __m128 EmulatePow2(__m128 src) { float src_value; _mm_store_ss(&src_value, src); - float result = std::pow(2, src_value); + float result = std::pow(2.0f, src_value); return _mm_load_ss(&result); } static void Emit(X64Emitter& e, const EmitArgType& i) { @@ -3488,7 +3488,7 @@ EMITTER(POW2_F32, MATCH(I, F32<>>)) { } }; EMITTER(POW2_F64, MATCH(I, F64<>>)) { - static __m128d EmulatePow2(__m128 src) { + static __m128d EmulatePow2(__m128d src) { double src_value; _mm_store_sd(&src_value, src); double result = std::pow(2, src_value); @@ -3506,7 +3506,7 @@ EMITTER(POW2_V128, MATCH(I, V128<>>)) { alignas(16) float values[4]; _mm_store_ps(values, src); for (size_t i = 0; i < 4; ++i) { - values[i] = std::pow(2, values[i]); + values[i] = std::pow(2.0f, values[i]); } return _mm_load_ps(values); } diff --git a/src/xenia/kernel/util/shim_utils.h b/src/xenia/kernel/util/shim_utils.h index 92245a9a8..7dfd948ff 100644 --- a/src/xenia/kernel/util/shim_utils.h +++ b/src/xenia/kernel/util/shim_utils.h @@ -29,21 +29,21 @@ using PPCContext = alloy::frontend::ppc::PPCContext; library_name, ordinals::##export_name, \ shim_data, \ (xe_kernel_export_shim_fn)export_name##_shim, \ - NULL); + nullptr); #define SHIM_MEM_BASE ppc_state->membase -#define SHIM_MEM_ADDR(a) (a ? (ppc_state->membase + a) : NULL) +#define SHIM_MEM_ADDR(a) (a ? (ppc_state->membase + a) : nullptr) -#define SHIM_MEM_8(a) (*(uint8_t*)SHIM_MEM_ADDR(a)) -#define SHIM_MEM_16(a) (uint16_t)poly::load_and_swap(SHIM_MEM_ADDR(a)) -#define SHIM_MEM_32(a) (uint32_t)poly::load_and_swap(SHIM_MEM_ADDR(a)) -#define SHIM_MEM_64(a) (uint64_t)poly::load_and_swap(SHIM_MEM_ADDR(a)) -#define SHIM_SET_MEM_8(a, v) (*(uint8_t*)SHIM_MEM_ADDR(a)) = v -#define SHIM_SET_MEM_16(a, v) (*(uint16_t*)SHIM_MEM_ADDR(a)) = poly::byte_swap(v) -#define SHIM_SET_MEM_32(a, v) (*(uint32_t*)SHIM_MEM_ADDR(a)) = poly::byte_swap(v) -#define SHIM_SET_MEM_64(a, v) (*(uint64_t*)SHIM_MEM_ADDR(a)) = poly::byte_swap(v) -#define SHIM_SET_MEM_F32(a, v) (*(float*)SHIM_MEM_ADDR(a)) = poly::byte_swap(v) -#define SHIM_SET_MEM_F64(a, v) (*(double*)SHIM_MEM_ADDR(a)) = poly::byte_swap(v) +#define SHIM_MEM_8(a) poly::load_and_swap(SHIM_MEM_ADDR(a)) +#define SHIM_MEM_16(a) poly::load_and_swap(SHIM_MEM_ADDR(a)) +#define SHIM_MEM_32(a) poly::load_and_swap(SHIM_MEM_ADDR(a)) +#define SHIM_MEM_64(a) poly::load_and_swap(SHIM_MEM_ADDR(a)) +#define SHIM_SET_MEM_8(a, v) poly::store_and_swap(SHIM_MEM_ADDR(a), v) +#define SHIM_SET_MEM_16(a, v) poly::store_and_swap(SHIM_MEM_ADDR(a), v) +#define SHIM_SET_MEM_32(a, v) poly::store_and_swap(SHIM_MEM_ADDR(a), v) +#define SHIM_SET_MEM_64(a, v) poly::store_and_swap(SHIM_MEM_ADDR(a), v) +#define SHIM_SET_MEM_F32(a, v) poly::store_and_swap(SHIM_MEM_ADDR(a), v) +#define SHIM_SET_MEM_F64(a, v) poly::store_and_swap(SHIM_MEM_ADDR(a), v) #define SHIM_GPR_8(n) (uint8_t)(ppc_state->r[n]) #define SHIM_GPR_16(n) (uint16_t)(ppc_state->r[n]) @@ -60,14 +60,14 @@ using PPCContext = alloy::frontend::ppc::PPCContext; #define SHIM_SET_RETURN_64(v) SHIM_SET_GPR_64(3, v) -#define IMPL_MEM_ADDR(a) (a ? state->memory()->Translate(a) : NULL) +#define IMPL_MEM_ADDR(a) (a ? state->memory()->Translate(a) : nullptr) -#define IMPL_MEM_8(a) (*(uint8_t*)(IMPL_MEM_ADDR(a))) -#define IMPL_MEM_16(a) (uint16_t)poly::load_and_swap(IMPL_MEM_ADDR(a)) -#define IMPL_MEM_32(a) (uint32_t)poly::load_and_swap(IMPL_MEM_ADDR(a)) -#define IMPL_SET_MEM_8(a, v) (*(uint8_t*)IMPL_MEM_ADDR(a)) = v -#define IMPL_SET_MEM_16(a, v) (*(uint16_t*)IMPL_MEM_ADDR(a)) = poly::byte_swap(v) -#define IMPL_SET_MEM_32(a, v) (*(uint32_t*)IMPL_MEM_ADDR(a)) = poly::byte_swap(v) +#define IMPL_MEM_8(a) poly::load_and_swap(IMPL_MEM_ADDR(a)) +#define IMPL_MEM_16(a) poly::load_and_swap(IMPL_MEM_ADDR(a)) +#define IMPL_MEM_32(a) poly::load_and_swap(IMPL_MEM_ADDR(a)) +#define IMPL_SET_MEM_8(a, v) poly::store_and_swap(IMPL_MEM_ADDR(a), v) +#define IMPL_SET_MEM_16(a, v) poly::store_and_swap(IMPL_MEM_ADDR(a), v) +#define IMPL_SET_MEM_32(a, v) poly::store_and_swap(IMPL_MEM_ADDR(a), v) } // namespace kernel From d56ae60460444b37d1cb3921d7c9fdbdc1bfc91d Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 29 Jul 2014 20:29:50 -0700 Subject: [PATCH 038/388] More mac fixups. --- src/alloy/backend/x64/x64_assembler.cc | 2 +- src/alloy/backend/x64/x64_code_cache_posix.cc | 4 +- src/alloy/backend/x64/x64_emitter.cc | 2 +- src/alloy/frontend/ppc/ppc_hir_builder.cc | 4 +- src/alloy/frontend/ppc/ppc_translator.cc | 5 +- src/alloy/runtime/entry_table.cc | 5 +- src/alloy/runtime/entry_table.h | 1 + src/alloy/runtime/function.cc | 5 +- src/alloy/runtime/thread_state.h | 5 +- src/alloy/string_buffer.cc | 2 +- src/alloy/string_buffer.h | 1 + src/poly/cxx_compat.h | 12 ++ src/poly/debugging.h | 29 +++++ src/poly/debugging_mac.cc | 29 +++++ src/poly/debugging_win.cc | 20 ++++ src/poly/platform.h | 105 +++++++++--------- src/poly/sources.gypi | 3 + tools/alloy-sandbox/alloy-sandbox.cc | 1 + 18 files changed, 165 insertions(+), 70 deletions(-) create mode 100644 src/poly/debugging.h create mode 100644 src/poly/debugging_mac.cc create mode 100644 src/poly/debugging_win.cc diff --git a/src/alloy/backend/x64/x64_assembler.cc b/src/alloy/backend/x64/x64_assembler.cc index be3777b1c..1fd0e2223 100644 --- a/src/alloy/backend/x64/x64_assembler.cc +++ b/src/alloy/backend/x64/x64_assembler.cc @@ -19,7 +19,7 @@ namespace BE { #include -} +} // namespace BE namespace alloy { namespace backend { diff --git a/src/alloy/backend/x64/x64_code_cache_posix.cc b/src/alloy/backend/x64/x64_code_cache_posix.cc index 09dbeccb5..7570e119d 100644 --- a/src/alloy/backend/x64/x64_code_cache_posix.cc +++ b/src/alloy/backend/x64/x64_code_cache_posix.cc @@ -9,9 +9,9 @@ #include -#include +#include -#include +#include namespace alloy { namespace backend { diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index bb409622c..a30ccf053 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -370,7 +370,7 @@ void X64Emitter::CallIndirect(const hir::Instr* instr, const Reg64& reg) { uint64_t UndefinedCallExtern(void* raw_context, uint64_t symbol_info_ptr) { auto symbol_info = reinterpret_cast(symbol_info_ptr); XELOGW("undefined extern call to %.8llX %s", symbol_info->address(), - symbol_info->name()); + symbol_info->name().c_str()); return 0; } void X64Emitter::CallExtern(const hir::Instr* instr, diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index 8f0977992..da30e8971 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -55,9 +55,9 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, bool with_debug_info) { with_debug_info_ = with_debug_info; if (with_debug_info_) { - Comment("%s fn %.8X-%.8X %s", symbol_info->module()->name(), + Comment("%s fn %.8X-%.8X %s", symbol_info->module()->name().c_str(), symbol_info->address(), symbol_info->end_address(), - symbol_info->name()); + symbol_info->name().c_str()); } // Allocate offset list. diff --git a/src/alloy/frontend/ppc/ppc_translator.cc b/src/alloy/frontend/ppc/ppc_translator.cc index ab7404b61..ff6145256 100644 --- a/src/alloy/frontend/ppc/ppc_translator.cc +++ b/src/alloy/frontend/ppc/ppc_translator.cc @@ -161,9 +161,10 @@ void PPCTranslator::DumpSource(runtime::FunctionInfo* symbol_info, Memory* memory = frontend_->memory(); const uint8_t* p = memory->membase(); - string_buffer->Append("%s fn %.8X-%.8X %s\n", symbol_info->module()->name(), + string_buffer->Append("%s fn %.8X-%.8X %s\n", + symbol_info->module()->name().c_str(), symbol_info->address(), symbol_info->end_address(), - symbol_info->name()); + symbol_info->name().c_str()); auto blocks = scanner_->FindBlocks(symbol_info); diff --git a/src/alloy/runtime/entry_table.cc b/src/alloy/runtime/entry_table.cc index 043623f4d..17c737bb9 100644 --- a/src/alloy/runtime/entry_table.cc +++ b/src/alloy/runtime/entry_table.cc @@ -18,9 +18,8 @@ EntryTable::EntryTable() = default; EntryTable::~EntryTable() { std::lock_guard guard(lock_); - auto& it = map_.begin(); - for (; it != map_.end(); ++it) { - Entry* entry = it->second; + for (auto it : map_) { + Entry* entry = it.second; delete entry; } } diff --git a/src/alloy/runtime/entry_table.h b/src/alloy/runtime/entry_table.h index d2a0fa225..1fe466a8a 100644 --- a/src/alloy/runtime/entry_table.h +++ b/src/alloy/runtime/entry_table.h @@ -12,6 +12,7 @@ #include #include +#include #include diff --git a/src/alloy/runtime/function.cc b/src/alloy/runtime/function.cc index 4be19f45e..06c0a68c2 100644 --- a/src/alloy/runtime/function.cc +++ b/src/alloy/runtime/function.cc @@ -17,8 +17,7 @@ namespace alloy { namespace runtime { Function::Function(FunctionInfo* symbol_info) - : address_(symbol_info->address()), - symbol_info_(symbol_info) {} + : address_(symbol_info->address()), symbol_info_(symbol_info) {} Function::~Function() = default; @@ -81,7 +80,7 @@ int Function::Call(ThreadState* thread_state, uint64_t return_address) { symbol_info_->extern_arg1()); } else { XELOGW("undefined extern call to %.8llX %s", symbol_info_->address(), - symbol_info_->name()); + symbol_info_->name().c_str()); result = 1; } } else { diff --git a/src/alloy/runtime/thread_state.h b/src/alloy/runtime/thread_state.h index be6655438..9cb2f7e96 100644 --- a/src/alloy/runtime/thread_state.h +++ b/src/alloy/runtime/thread_state.h @@ -10,6 +10,8 @@ #ifndef ALLOY_RUNTIME_THREAD_STATE_H_ #define ALLOY_RUNTIME_THREAD_STATE_H_ +#include + #include #include @@ -32,7 +34,8 @@ class ThreadState { void* backend_data() const { return backend_data_; } void* raw_context() const { return raw_context_; } - virtual int Suspend(uint32_t timeout_ms = UINT_MAX) { return 1; } + int Suspend() { return Suspend(~0); } + virtual int Suspend(uint32_t timeout_ms) { return 1; } virtual int Resume(bool force = false) { return 1; } static void Bind(ThreadState* thread_state); diff --git a/src/alloy/string_buffer.cc b/src/alloy/string_buffer.cc index ca667f997..c35885e95 100644 --- a/src/alloy/string_buffer.cc +++ b/src/alloy/string_buffer.cc @@ -23,7 +23,7 @@ void StringBuffer::Reset() { } void StringBuffer::Append(const std::string& value) { - Append(value.c_str()); + AppendBytes(reinterpret_cast(value.data()), value.size()); } void StringBuffer::Append(const char* format, ...) { diff --git a/src/alloy/string_buffer.h b/src/alloy/string_buffer.h index ca553d343..16f6bab76 100644 --- a/src/alloy/string_buffer.h +++ b/src/alloy/string_buffer.h @@ -10,6 +10,7 @@ #ifndef ALLOY_STRING_BUFFER_H_ #define ALLOY_STRING_BUFFER_H_ +#include #include #include diff --git a/src/poly/cxx_compat.h b/src/poly/cxx_compat.h index ba68ca0a8..fa471eca0 100644 --- a/src/poly/cxx_compat.h +++ b/src/poly/cxx_compat.h @@ -10,6 +10,8 @@ #ifndef POLY_CXX_COMPAT_H_ #define POLY_CXX_COMPAT_H_ +#include + #include // C++11 thread local storage. @@ -30,6 +32,16 @@ #define alignas(N) __declspec(align(N)) #endif // XE_COMPILER_MSVC +// C++1y make_unique. +// http://herbsutter.com/2013/05/29/gotw-89-solution-smart-pointers/ +// This is present in clang with -std=c++1y, but not otherwise. +namespace std { +template +unique_ptr make_unique(Args&&... args) { + return unique_ptr(new T(forward(args)...)); +} +} // namespace std + namespace poly {} // namespace poly #endif // POLY_CXX_COMPAT_H_ diff --git a/src/poly/debugging.h b/src/poly/debugging.h new file mode 100644 index 000000000..f784e4c29 --- /dev/null +++ b/src/poly/debugging.h @@ -0,0 +1,29 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef POLY_DEBUGGING_H_ +#define POLY_DEBUGGING_H_ + +#include + +#include + +namespace poly { +namespace debugging { + +// Returns true if a debugger is attached to this process. +// The state may change at any time (attach after launch, etc), so do not +// cache this value. Determining if the debugger is attached is expensive, +// though, so avoid calling it frequently. +bool IsDebuggerAttached(); + +} // namespace debugging +} // namespace poly + +#endif // POLY_DEBUGGING_H_ diff --git a/src/poly/debugging_mac.cc b/src/poly/debugging_mac.cc new file mode 100644 index 000000000..ec060db86 --- /dev/null +++ b/src/poly/debugging_mac.cc @@ -0,0 +1,29 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include +#include + +namespace poly { +namespace debugging { + +bool IsDebuggerAttached() { + // https://developer.apple.com/library/mac/qa/qa1361/_index.html + kinfo_proc info; + info.kp_proc.p_flag = 0; + int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()}; + size_t size = sizeof(info); + sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0); + return (info.kp_proc.p_flag & P_TRACED) != 0; +} + +} // namespace debugging +} // namespace poly diff --git a/src/poly/debugging_win.cc b/src/poly/debugging_win.cc new file mode 100644 index 000000000..0c6bad97f --- /dev/null +++ b/src/poly/debugging_win.cc @@ -0,0 +1,20 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +namespace poly { +namespace debugging { + +bool IsDebuggerAttached() { + return IsDebuggerPresent() ? true : false; +} + +} // namespace debugging +} // namespace poly diff --git a/src/poly/platform.h b/src/poly/platform.h index 10efb54c3..b0463c0bc 100644 --- a/src/poly/platform.h +++ b/src/poly/platform.h @@ -27,109 +27,106 @@ XE_CPU: 32BIT | 64BIT | BIGENDIAN | LITTLEENDIAN #include #endif -#if (defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED ) || \ - (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE ) || \ +#if (defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED) || \ + (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || \ (defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR) -#define XE_PLATFORM_IOS 1 -#define XE_LIKE_OSX 1 -#define XE_PROFILE_EMBEDDED 1 +#define XE_PLATFORM_IOS 1 +#define XE_LIKE_OSX 1 +#define XE_PROFILE_EMBEDDED 1 #if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR // EMBEDDED *and* SIMULATOR -#define XE_PROFILE_SIMULATOR 1 +#define XE_PROFILE_SIMULATOR 1 #endif #elif defined(TARGET_OS_MAC) && TARGET_OS_MAC -#define XE_PLATFORM_OSX 1 -#define XE_LIKE_OSX 1 -#define XE_PROFILE_DESKTOP 1 +#define XE_PLATFORM_OSX 1 +#define XE_LIKE_OSX 1 +#define XE_PROFILE_DESKTOP 1 #elif defined(_XBOX) -#define XE_PLATFORM_XBOX360 1 -#define XE_LIKE_WIN32 1 -#define XE_PROFILE_EMBEDDED 1 +#define XE_PLATFORM_XBOX360 1 +#define XE_LIKE_WIN32 1 +#define XE_PROFILE_EMBEDDED 1 #elif defined(_WIN32_WCE) -#define XE_PLATFORM_WINCE 1 -#define XE_LIKE_WIN32 1 -#define XE_PROFILE_EMBEDDED 1 +#define XE_PLATFORM_WINCE 1 +#define XE_LIKE_WIN32 1 +#define XE_PROFILE_EMBEDDED 1 #elif defined(__CYGWIN__) -#define XE_PLATFORM_CYGWIN 1 -#define XE_LIKE_POSIX 1 -#define XE_PROFILE_DESKTOP 1 +#define XE_PLATFORM_CYGWIN 1 +#define XE_LIKE_POSIX 1 +#define XE_PROFILE_DESKTOP 1 #elif defined(WIN32) || defined(_WIN32) -#define XE_PLATFORM_WIN32 1 -#define XE_LIKE_WIN32 1 -#define XE_PROFILE_DESKTOP 1 +#define XE_PLATFORM_WIN32 1 +#define XE_LIKE_WIN32 1 +#define XE_PROFILE_DESKTOP 1 #elif defined(ANDROID) -#define XE_PLATFORM_ANDROID 1 -#define XE_LIKE_POSIX 1 -#define XE_PROFILE_EMBEDDED 1 +#define XE_PLATFORM_ANDROID 1 +#define XE_LIKE_POSIX 1 +#define XE_PROFILE_EMBEDDED 1 #elif defined(__native_client__) -#define XE_PLATFORM_NACL 1 -#define XE_LIKE_POSIX 1 -#define XE_PROFILE_DESKTOP 1 +#define XE_PLATFORM_NACL 1 +#define XE_LIKE_POSIX 1 +#define XE_PROFILE_DESKTOP 1 #else -#define XE_PLATFORM_UNIX 1 -#define XE_LIKE_POSIX 1 -#define XE_PROFILE_DESKTOP 1 +#define XE_PLATFORM_UNIX 1 +#define XE_LIKE_POSIX 1 +#define XE_PROFILE_DESKTOP 1 #endif #if defined(__clang__) -#define XE_COMPILER_CLANG 1 +#define XE_COMPILER_CLANG 1 #elif defined(__GNUC__) -#define XE_COMPILER_GNUC 1 +#define XE_COMPILER_GNUC 1 #elif defined(_MSC_VER) -#define XE_COMPILER_MSVC 1 +#define XE_COMPILER_MSVC 1 #elif defined(__MINGW32) -#define XE_COMPILER_MINGW32 1 +#define XE_COMPILER_MINGW32 1 #elif defined(__INTEL_COMPILER) -#define XE_COMPILER_INTEL 1 +#define XE_COMPILER_INTEL 1 #else -#define XE_COMPILER_UNKNOWN 1 +#define XE_COMPILER_UNKNOWN 1 #endif -#if defined(__ia64__) || defined(_M_IA64) || \ - defined(__ppc64__) || defined(__PPC64__) || \ - defined(__arch64__) || \ - defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) || \ - defined(__LP64__) || defined(__LLP64) || \ - defined(_WIN64) || \ - (__WORDSIZE == 64) -#define XE_CPU_64BIT 1 +#if defined(__ia64__) || defined(_M_IA64) || defined(__ppc64__) || \ + defined(__PPC64__) || defined(__arch64__) || defined(__x86_64__) || \ + defined(_M_X64) || defined(_M_AMD64) || defined(__LP64__) || \ + defined(__LLP64) || defined(_WIN64) || (__WORDSIZE == 64) +#define XE_CPU_64BIT 1 #else -#define XE_CPU_32BIT 1 +#define XE_CPU_32BIT 1 #endif // [64bit flags] -#if defined(__ppc__) || defined(__PPC__) || defined(__powerpc__) || defined(__powerpc) || defined(__POWERPC__) || defined(_M_PPC) || defined(__PPC) || \ - defined(__ppc64__) || defined(__PPC64__) || \ - defined(__ARMEB__) || defined(__THUMBEB__) || \ - defined(__AARCH64EB__) || \ +#if defined(__ppc__) || defined(__PPC__) || defined(__powerpc__) || \ + defined(__powerpc) || defined(__POWERPC__) || defined(_M_PPC) || \ + defined(__PPC) || defined(__ppc64__) || defined(__PPC64__) || \ + defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \ defined(__BIG_ENDIAN) || defined(__BIG_ENDIAN__) -#define XE_CPU_BIGENDIAN 1 +#define XE_CPU_BIGENDIAN 1 #else -#define XE_CPU_LITTLEENDIAN 1 +#define XE_CPU_LITTLEENDIAN 1 #endif // [big endian flags] #if XE_CPU_32BIT -#define XE_ALIGNMENT 8 +#define XE_ALIGNMENT 8 #else -#define XE_ALIGNMENT 16 +#define XE_ALIGNMENT 16 #endif // 32BIT #if XE_PLATFORM_WINCE || XE_PLATFORM_WIN32 @@ -168,7 +165,7 @@ const char path_separator = '\\'; const size_t max_path = _MAX_PATH; #else const char path_separator = '/'; -const size_t max_path = PATH_MAX; +const size_t max_path = 1024; // PATH_MAX #endif // WIN32 } // namespace poly diff --git a/src/poly/sources.gypi b/src/poly/sources.gypi index 49154f817..6765121fa 100644 --- a/src/poly/sources.gypi +++ b/src/poly/sources.gypi @@ -4,6 +4,7 @@ 'assert.h', 'atomic.h', 'byte_order.h', + 'debugging.h', 'config.h', 'cxx_compat.h', 'math.cc', @@ -28,11 +29,13 @@ }], ['OS == "mac"', { 'sources': [ + 'debugging_mac.cc', 'threading_mac.cc', ], }], ['OS == "win"', { 'sources': [ + 'debugging_win.cc', 'threading_win.cc', ], }], diff --git a/tools/alloy-sandbox/alloy-sandbox.cc b/tools/alloy-sandbox/alloy-sandbox.cc index 437204d2d..db1886d26 100644 --- a/tools/alloy-sandbox/alloy-sandbox.cc +++ b/tools/alloy-sandbox/alloy-sandbox.cc @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include From 0129a9622519b62b7a0f4929ea9501e539256617 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 29 Jul 2014 22:12:39 -0700 Subject: [PATCH 039/388] Cross-platformizing MMIO stuff. MSVC build likely needs some fixes. --- src/poly/debugging.h | 4 + src/poly/debugging_mac.cc | 6 + src/poly/debugging_win.cc | 4 + src/poly/poly.h | 1 + src/xenia/cpu/mmio_handler.cc | 192 ++++++++++++++++++++++++ src/xenia/cpu/mmio_handler.h | 67 +++++++++ src/xenia/cpu/mmio_handler_mac.cc | 237 ++++++++++++++++++++++++++++++ src/xenia/cpu/mmio_handler_win.cc | 91 ++++++++++++ src/xenia/cpu/sources.gypi | 23 +++ src/xenia/cpu/xenon_memory.cc | 186 +++-------------------- src/xenia/cpu/xenon_memory.h | 16 +- 11 files changed, 651 insertions(+), 176 deletions(-) create mode 100644 src/xenia/cpu/mmio_handler.cc create mode 100644 src/xenia/cpu/mmio_handler.h create mode 100644 src/xenia/cpu/mmio_handler_mac.cc create mode 100644 src/xenia/cpu/mmio_handler_win.cc diff --git a/src/poly/debugging.h b/src/poly/debugging.h index f784e4c29..a9c60ff25 100644 --- a/src/poly/debugging.h +++ b/src/poly/debugging.h @@ -23,6 +23,10 @@ namespace debugging { // though, so avoid calling it frequently. bool IsDebuggerAttached(); +// Breaks into the debugger if it is attached. +// If no debugger is present, a signal will be raised. +void Break(); + } // namespace debugging } // namespace poly diff --git a/src/poly/debugging_mac.cc b/src/poly/debugging_mac.cc index ec060db86..a99639743 100644 --- a/src/poly/debugging_mac.cc +++ b/src/poly/debugging_mac.cc @@ -25,5 +25,11 @@ bool IsDebuggerAttached() { return (info.kp_proc.p_flag & P_TRACED) != 0; } +// TODO(benvanik): find a more reliable way. +void Break() { + // __asm__("int $3"); + __builtin_debugtrap(); +} + } // namespace debugging } // namespace poly diff --git a/src/poly/debugging_win.cc b/src/poly/debugging_win.cc index 0c6bad97f..419547f34 100644 --- a/src/poly/debugging_win.cc +++ b/src/poly/debugging_win.cc @@ -16,5 +16,9 @@ bool IsDebuggerAttached() { return IsDebuggerPresent() ? true : false; } +void Break() { + __debugbreak(); +} + } // namespace debugging } // namespace poly diff --git a/src/poly/poly.h b/src/poly/poly.h index 80700dac8..1cdadbed6 100644 --- a/src/poly/poly.h +++ b/src/poly/poly.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/src/xenia/cpu/mmio_handler.cc b/src/xenia/cpu/mmio_handler.cc new file mode 100644 index 000000000..5408f9890 --- /dev/null +++ b/src/xenia/cpu/mmio_handler.cc @@ -0,0 +1,192 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include + +namespace BE { +#include +} // namespace BE + +namespace xe { +namespace cpu { + +MMIOHandler* MMIOHandler::global_handler_ = nullptr; + +// Implemented in the platform cc file. +std::unique_ptr CreateMMIOHandler(); + +std::unique_ptr MMIOHandler::Install() { + // There can be only one handler at a time. + assert_null(global_handler_); + if (global_handler_) { + return nullptr; + } + + // Create the platform-specific handler. + auto handler = CreateMMIOHandler(); + + // Platform-specific initialization for the handler. + if (!handler->Initialize()) { + return nullptr; + } + + global_handler_ = handler.get(); + return handler; +} + +MMIOHandler::~MMIOHandler() { + assert_true(global_handler_ == this); + global_handler_ = nullptr; + + // Platform-specific handler uninstall. + Uninstall(); +} + +bool MMIOHandler::RegisterRange(uint64_t address, uint64_t mask, uint64_t size, + void* context, MMIOReadCallback read_callback, + MMIOWriteCallback write_callback) { + mapped_ranges_.emplace_back({ + reinterpret_cast(mapping_base_) | address, + 0xFFFFFFFF00000000ull | mask, size, context, read_callback, + write_callback, + }); +} + +bool MMIOHandler::CheckLoad(uint64_t address, uint64_t* out_value) { + for (const auto& range : mapped_ranges_) { + if (((address | (uint64_t)mapping_base_) & range.mask) == range.address) { + *out_value = static_cast(range.read(range.context, address)); + return true; + } + } + return false; +} + +bool MMIOHandler::CheckStore(uint64_t address, uint64_t value) { + for (const auto& range : mapped_ranges_) { + if (((address | (uint64_t)mapping_base_) & range.mask) == range.address) { + range.write(range.context, address, value); + return true; + } + } + return false; +} + +bool MMIOHandler::HandleAccessFault(void* thread_state, + uint64_t fault_address) { + // Access violations are pretty rare, so we can do a linear search here. + const MMIORange* range = nullptr; + for (const auto& test_range : mapped_ranges_) { + if ((fault_address & test_range.mask) == test_range.address) { + // Address is within the range of this mapping. + range = &test_range; + break; + } + } + if (!range) { + // Access is not found within any range, so fail and let the caller handle + // it (likely by aborting). + return false; + } + + // TODO(benvanik): replace with simple check of mov (that's all + // we care about). + auto rip = GetThreadStateRip(thread_state); + BE::DISASM disasm = {0}; + disasm.Archi = 64; + disasm.Options = BE::MasmSyntax + BE::PrefixedNumeral; + disasm.EIP = static_cast(rip); + size_t instr_length = BE::Disasm(&disasm); + if (instr_length == BE::UNKNOWN_OPCODE) { + // Failed to decode instruction. Either it's an unhandled mov case or + // not a mov. + assert_always(); + return false; + } + + int32_t arg1_type = disasm.Argument1.ArgType; + int32_t arg2_type = disasm.Argument2.ArgType; + bool is_load = (arg1_type & BE::REGISTER_TYPE) == BE::REGISTER_TYPE && + (arg1_type & BE::GENERAL_REG) == BE::GENERAL_REG && + (disasm.Argument1.AccessMode & BE::WRITE) == BE::WRITE; + bool is_store = (arg1_type & BE::MEMORY_TYPE) == BE::MEMORY_TYPE && + (((arg2_type & BE::REGISTER_TYPE) == BE::REGISTER_TYPE && + (arg2_type & BE::GENERAL_REG) == BE::GENERAL_REG) || + (arg2_type & BE::CONSTANT_TYPE) == BE::CONSTANT_TYPE) && + (disasm.Argument1.AccessMode & BE::WRITE) == BE::WRITE; + if (is_load) { + // Load of a memory value - read from range, swap, and store in the + // register. + uint64_t value = range->read(range->context, fault_address & 0xFFFFFFFF); + uint32_t be_reg_index; + if (!poly::bit_scan_forward(arg1_type & 0xFFFF, &be_reg_index)) { + be_reg_index = 0; + } + uint64_t* reg_ptr = GetThreadStateRegPtr(thread_state, be_reg_index); + switch (disasm.Argument1.ArgSize) { + case 8: + *reg_ptr = static_cast(value); + break; + case 16: + *reg_ptr = poly::byte_swap(static_cast(value)); + break; + case 32: + *reg_ptr = poly::byte_swap(static_cast(value)); + break; + case 64: + *reg_ptr = poly::byte_swap(static_cast(value)); + break; + } + } else if (is_store) { + // Store of a register value - read register, swap, write to range. + uint64_t value; + if ((arg2_type & BE::REGISTER_TYPE) == BE::REGISTER_TYPE) { + uint32_t be_reg_index; + if (!poly::bit_scan_forward(arg2_type & 0xFFFF, &be_reg_index)) { + be_reg_index = 0; + } + uint64_t* reg_ptr = GetThreadStateRegPtr(thread_state, arg2_type); + value = *reg_ptr; + } else if ((arg2_type & BE::CONSTANT_TYPE) == BE::CONSTANT_TYPE) { + value = disasm.Instruction.Immediat; + } else { + // Unknown destination type in mov. + assert_always(); + } + switch (disasm.Argument2.ArgSize) { + case 8: + value = static_cast(value); + break; + case 16: + value = poly::byte_swap(static_cast(value)); + break; + case 32: + value = poly::byte_swap(static_cast(value)); + break; + case 64: + value = poly::byte_swap(static_cast(value)); + break; + } + range->write(range->context, fault_address & 0xFFFFFFFF, value); + } else { + // Unknown MMIO instruction type. + assert_always(); + return false; + } + + // Advance RIP to the next instruction so that we resume properly. + SetThreadStateRip(thread_state, rip + instr_length); + + return true; +} + +} // namespace cpu +} // namespace xe diff --git a/src/xenia/cpu/mmio_handler.h b/src/xenia/cpu/mmio_handler.h new file mode 100644 index 000000000..44eeea985 --- /dev/null +++ b/src/xenia/cpu/mmio_handler.h @@ -0,0 +1,67 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_CPU_MMIO_HANDLER_H_ +#define XENIA_CPU_MMIO_HANDLER_H_ + +#include +#include + +namespace xe { +namespace cpu { + +typedef uint64_t (*MMIOReadCallback)(void* context, uint64_t addr); +typedef void (*MMIOWriteCallback)(void* context, uint64_t addr, uint64_t value); + +// NOTE: only one can exist at a time! +class MMIOHandler { + public: + virtual ~MMIOHandler(); + + static std::unique_ptr Install(); + static MMIOHandler* global_handler() { return global_handler_; } + + bool RegisterRange(uint64_t address, uint64_t mask, uint64_t size, + void* context, MMIOReadCallback read_callback, + MMIOWriteCallback write_callback); + + bool CheckLoad(uint64_t address, uint64_t* out_value); + bool CheckStore(uint64_t address, uint64_t value); + + public: + bool HandleAccessFault(void* thread_state, uint64_t fault_address); + + protected: + MMIOHandler() = default; + + virtual bool Initialize() = 0; + virtual void Uninstall() = 0; + + virtual uint64_t GetThreadStateRip(void* thread_state_ptr) = 0; + virtual void SetThreadStateRip(void* thread_state_ptr, uint64_t rip) = 0; + virtual uint64_t* GetThreadStateRegPtr(void* thread_state_ptr, + int32_t be_reg_index) = 0; + + struct MMIORange { + uint64_t address; + uint64_t mask; + uint64_t size; + void* context; + MMIOReadCallback read; + MMIOWriteCallback write; + }; + std::vector mapped_ranges_; + + static MMIOHandler* global_handler_; +}; + +} // namespace cpu +} // namespace xe + +#endif // XENIA_CPU_MMIO_HANDLER_H_ diff --git a/src/xenia/cpu/mmio_handler_mac.cc b/src/xenia/cpu/mmio_handler_mac.cc new file mode 100644 index 000000000..193bd3f5c --- /dev/null +++ b/src/xenia/cpu/mmio_handler_mac.cc @@ -0,0 +1,237 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include +#include + +#include + +#include +#include + +// Mach internal function, not defined in any header. +// http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/exc_server.html +extern "C" boolean_t exc_server(mach_msg_header_t* request_msg, + mach_msg_header_t* reply_msg); + +// Exported for the kernel to call back into. +// http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/catch_exception_raise.html +extern "C" kern_return_t catch_exception_raise( + mach_port_t exception_port, mach_port_t thread, mach_port_t task, + exception_type_t exception, exception_data_t code, + mach_msg_type_number_t code_count); + +namespace xe { +namespace cpu { + +class MachMMIOHandler : public MMIOHandler { + public: + MachMMIOHandler(); + + protected: + bool Initialize() override; + void Uninstall() override; + + uint64_t GetThreadStateRip(void* thread_state_ptr) override; + void SetThreadStateRip(void* thread_state_ptr, uint64_t rip) override; + uint64_t* GetThreadStateRegPtr(void* thread_state_ptr, + int32_t be_reg_index) override; + + private: + void ThreadEntry(); + + // Worker thread processing exceptions. + std::unique_ptr thread_; + // Port listening for exceptions on the worker thread. + mach_port_t listen_port_; +}; + +std::unique_ptr CreateMMIOHandler() { + return std::make_unique(); +} + +MachMMIOHandler::MachMMIOHandler() : listen_port_(0) {} + +bool MachMMIOHandler::Initialize() { + // Allocates the port that listens for exceptions. + // This will be freed in the dtor. + if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, + &listen_port_) != KERN_SUCCESS) { + XELOGE("Unable to allocate listen port"); + return false; + } + + // http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/mach_port_insert_right.html + if (mach_port_insert_right(mach_task_self(), listen_port_, listen_port_, + MACH_MSG_TYPE_MAKE_SEND) != KERN_SUCCESS) { + XELOGE("Unable to insert listen port right"); + return false; + } + + // Sets our exception filter so that any BAD_ACCESS exceptions go to it. + // http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/task_set_exception_ports.html + if (task_set_exception_ports(mach_task_self(), EXC_MASK_BAD_ACCESS, + listen_port_, EXCEPTION_DEFAULT, + MACHINE_THREAD_STATE) != KERN_SUCCESS) { + XELOGE("Unable to set exception port"); + return false; + } + + // Spin up the worker thread. + std::unique_ptr thread( + new std::thread([this]() { ThreadEntry(); })); + thread->detach(); + thread_ = std::move(thread); + return true; +} + +void MachMMIOHandler::Uninstall() { + task_set_exception_ports(mach_task_self(), EXC_MASK_BAD_ACCESS, 0, + EXCEPTION_DEFAULT, 0); + mach_port_deallocate(mach_task_self(), listen_port_); +} + +void MachMMIOHandler::ThreadEntry() { + while (true) { + struct { + mach_msg_header_t head; + mach_msg_body_t msgh_body; + char data[1024]; + } msg; + struct { + mach_msg_header_t head; + char data[1024]; + } reply; + + // Wait for a message on the exception port. + mach_msg_return_t ret = + mach_msg(&msg.head, MACH_RCV_MSG | MACH_RCV_LARGE, 0, sizeof(msg), + listen_port_, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + if (ret != MACH_MSG_SUCCESS) { + XELOGE("mach_msg receive failed with %d %s", ret, mach_error_string(ret)); + poly::debugging::Break(); + break; + } + + // Call exc_server, which will dispatch the catch_exception_raise. + exc_server(&msg.head, &reply.head); + + // Send the reply. + if (mach_msg(&reply.head, MACH_SEND_MSG, reply.head.msgh_size, 0, + MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, + MACH_PORT_NULL) != MACH_MSG_SUCCESS) { + XELOGE("mach_msg reply send failed"); + poly::debugging::Break(); + break; + } + } +} + +// Kills the app when a bad access exception is unhandled. +void FailBadAccess() { + raise(SIGSEGV); + abort(); +} + +kern_return_t CatchExceptionRaise(mach_port_t thread) { + auto state_count = x86_EXCEPTION_STATE64_COUNT; + x86_exception_state64_t exc_state; + if (thread_get_state(thread, x86_EXCEPTION_STATE64, + reinterpret_cast(&exc_state), + &state_count) != KERN_SUCCESS) { + XELOGE("thread_get_state failed to get exception state"); + return KERN_FAILURE; + } + state_count = x86_THREAD_STATE64_COUNT; + x86_thread_state64_t thread_state; + if (thread_get_state(thread, x86_THREAD_STATE64, + reinterpret_cast(&thread_state), + &state_count) != KERN_SUCCESS) { + XELOGE("thread_get_state failed to get thread state"); + return KERN_FAILURE; + } + + auto fault_address = exc_state.__faultvaddr; + auto mmio_handler = + static_cast(MMIOHandler::global_handler()); + bool handled = mmio_handler->HandleAccessFault(&thread_state, fault_address); + if (!handled) { + // Unhandled - raise to the system. + XELOGE("MMIO unhandled bad access for %llx, bubbling", fault_address); + // TODO(benvanik): manipulate stack so that we can rip = break_handler or + // something and have the stack trace be valid. + poly::debugging::Break(); + + // When the thread resumes, kill it. + thread_state.__rip = reinterpret_cast(FailBadAccess); + + // Mach docs say we can return this to continue searching for handlers, but + // OSX doesn't seem to have it. + // return MIG_DESTROY_REQUEST; + } + + // Set the thread state - as we've likely changed it. + if (thread_set_state(thread, x86_THREAD_STATE64, + reinterpret_cast(&thread_state), + state_count) != KERN_SUCCESS) { + XELOGE("thread_set_state failed to set thread state for continue"); + return KERN_FAILURE; + } + return KERN_SUCCESS; +} + +uint64_t MachMMIOHandler::GetThreadStateRip(void* thread_state_ptr) { + auto thread_state = reinterpret_cast(thread_state_ptr); + return thread_state->__rip; +} + +void MachMMIOHandler::SetThreadStateRip(void* thread_state_ptr, uint64_t rip) { + auto thread_state = reinterpret_cast(thread_state_ptr); + thread_state->__rip = rip; +} + +uint64_t* MachMMIOHandler::GetThreadStateRegPtr(void* thread_state_ptr, + int32_t be_reg_index) { + // Map from BeaEngine register order to x86_thread_state64 order. + static const uint32_t mapping[] = { + 0, // REG0 / RAX -> 0 + 2, // REG1 / RCX -> 2 + 3, // REG2 / RDX -> 3 + 1, // REG3 / RBX -> 1 + 7, // REG4 / RSP -> 7 + 6, // REG5 / RBP -> 6 + 5, // REG6 / RSI -> 5 + 4, // REG7 / RDI -> 4 + 8, // REG8 / R8 -> 8 + 9, // REG9 / R9 -> 9 + 10, // REG10 / R10 -> 10 + 11, // REG11 / R11 -> 11 + 12, // REG12 / R12 -> 12 + 13, // REG13 / R13 -> 13 + 14, // REG14 / R14 -> 14 + 15, // REG15 / R15 -> 15 + }; + auto thread_state = reinterpret_cast(thread_state_ptr); + return &thread_state->__rax + mapping[be_reg_index]; +} + +} // namespace cpu +} // namespace xe + +// Exported and called by exc_server. +extern "C" kern_return_t catch_exception_raise( + mach_port_t exception_port, mach_port_t thread, mach_port_t task, + exception_type_t exception, exception_data_t code, + mach_msg_type_number_t code_count) { + // We get/set the states manually instead of using catch_exception_raise_state + // variant because that truncates everything to 32bit. + return xe::cpu::CatchExceptionRaise(thread); +} diff --git a/src/xenia/cpu/mmio_handler_win.cc b/src/xenia/cpu/mmio_handler_win.cc new file mode 100644 index 000000000..31647ab18 --- /dev/null +++ b/src/xenia/cpu/mmio_handler_win.cc @@ -0,0 +1,91 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +namespace xe { +namespace cpu { + +LONG CALLBACK MMIOExceptionHandler(PEXCEPTION_POINTERS ex_info); + +class WinMMIOHandler : public MMIOHandler { + public: + WinMMIOHandler() = default; + + protected: + bool Initialize() override; + void Uninstall() override; + + uint64_t GetThreadStateRip(void* thread_state_ptr) override; + void SetThreadStateRip(void* thread_state_ptr, uint64_t rip) override; + uint64_t* GetThreadStateRegPtr(void* thread_state_ptr, + int32_t be_reg_index) override; +}; + +std::unique_ptr CreateMMIOHandler() { + return std::make_unique(); +} + +bool WinMMIOHandler::Initialize() { + // If there is a debugger attached the normal exception handler will not + // fire and we must instead add the continue handler. + AddVectoredExceptionHandler(1, MMIOExceptionHandler); + if (IsDebuggerPresent()) { + // TODO(benvanik): is this really required? + // AddVectoredContinueHandler(1, MMIOExceptionHandler); + } + return true; +} + +void WinMMIOHandler::Uninstall() { + // Remove exception handlers. + RemoveVectoredExceptionHandler(MMIOExceptionHandler); + RemoveVectoredContinueHandler(MMIOExceptionHandler); +} + +// Handles potential accesses to mmio. We look for access violations to +// addresses in our range and call into the registered handlers, if any. +// If there are none, we continue. +LONG CALLBACK MMIOExceptionHandler(PEXCEPTION_POINTERS ex_info) { + // http://msdn.microsoft.com/en-us/library/ms679331(v=vs.85).aspx + // http://msdn.microsoft.com/en-us/library/aa363082(v=vs.85).aspx + auto code = ex_info->ExceptionRecord->ExceptionCode; + if (code == STATUS_ACCESS_VIOLATION) { + auto fault_address = ex_info->ExceptionRecord->ExceptionInformation[1]; + if (HandleAccessFault(ex_info->ContextRecord, fault_address)) { + // Handled successfully - RIP has been updated and we can continue. + return EXCEPTION_CONTINUE_EXECUTION; + } else { + // Failed to handle; continue search for a handler (and die if no other + // handler is found). + return EXCEPTION_CONTINUE_SEARCH; + } + } + return EXCEPTION_CONTINUE_SEARCH; +} + +uint64_t WinMMIOHandler::GetThreadStateRip(void* thread_state_ptr) { + auto context = reinterpret_cast(thread_state_ptr); + return context->Rip; +} + +void WinMMIOHandler::SetThreadStateRip(void* thread_state_ptr, uint64_t rip) { + auto context = reinterpret_cast(thread_state_ptr); + context->Rip = rip; +} + +uint64_t* WinMMIOHandler::GetThreadStateRegPtr(void* thread_state_ptr, + int32_t be_reg_index) { + auto context = reinterpret_cast(thread_state_ptr); + // BeaEngine register indices line up with the CONTEXT structure format. + return &context->Rax + be_reg_index; +} + +} // namespace cpu +} // namespace xe diff --git a/src/xenia/cpu/sources.gypi b/src/xenia/cpu/sources.gypi index f7e38d6d7..46c524816 100644 --- a/src/xenia/cpu/sources.gypi +++ b/src/xenia/cpu/sources.gypi @@ -4,6 +4,8 @@ 'cpu-private.h', 'cpu.cc', 'cpu.h', + 'mmio_handler.cc', + 'mmio_handler.h', 'processor.cc', 'processor.h', 'xenon_memory.cc', @@ -15,4 +17,25 @@ 'xex_module.cc', 'xex_module.h', ], + + 'conditions': [ + ['OS == "mac" or OS == "linux"', { + 'sources': [ + ], + }], + ['OS == "linux"', { + 'sources': [ + ], + }], + ['OS == "mac"', { + 'sources': [ + 'mmio_handler_mac.cc', + ], + }], + ['OS == "win"', { + 'sources': [ + 'mmio_handler_win.cc', + ], + }], + ], } diff --git a/src/xenia/cpu/xenon_memory.cc b/src/xenia/cpu/xenon_memory.cc index c32d1400d..e9dcd9b79 100644 --- a/src/xenia/cpu/xenon_memory.cc +++ b/src/xenia/cpu/xenon_memory.cc @@ -118,117 +118,6 @@ private: }; uint32_t XenonMemoryHeap::next_heap_id_ = 1; -namespace { - -namespace BE { -#include -} - -struct MMIORange { - uint64_t address; - uint64_t mask; - uint64_t size; - void* context; - MMIOReadCallback read; - MMIOWriteCallback write; -}; -MMIORange g_mapped_ranges_[16] = { 0 }; -int g_mapped_range_count_ = 0; - -uint64_t* GetContextRegPtr(BE::Int32 arg_type, PCONTEXT context) { - DWORD index = 0; - _BitScanForward(&index, arg_type); - return &context->Rax + index; -} - -// Handles potential accesses to mmio. We look for access violations to -// addresses in our range and call into the registered handlers, if any. -// If there are none, we continue. -LONG CALLBACK CheckMMIOHandler(PEXCEPTION_POINTERS ex_info) { - // http://msdn.microsoft.com/en-us/library/ms679331(v=vs.85).aspx - // http://msdn.microsoft.com/en-us/library/aa363082(v=vs.85).aspx - auto code = ex_info->ExceptionRecord->ExceptionCode; - if (code == STATUS_ACCESS_VIOLATION) { - // Access violations are pretty rare, so we can do a linear search here. - auto address = ex_info->ExceptionRecord->ExceptionInformation[1]; - for (int i = 0; i < g_mapped_range_count_; ++i) { - const auto& range = g_mapped_ranges_[i]; - if ((address & range.mask) == range.address) { - // Within our range. - - // TODO(benvanik): replace with simple check of mov (that's all - // we care about). - BE::DISASM disasm = { 0 }; - disasm.Archi = 64; - disasm.Options = BE::MasmSyntax + BE::PrefixedNumeral; - disasm.EIP = (BE::UIntPtr)ex_info->ExceptionRecord->ExceptionAddress; - BE::UIntPtr eip_end = disasm.EIP + 20; - size_t len = BE::Disasm(&disasm); - if (len == BE::UNKNOWN_OPCODE) { - break; - } - - auto action = ex_info->ExceptionRecord->ExceptionInformation[0]; - if (action == 0) { - uint64_t value = range.read(range.context, address & 0xFFFFFFFF); - assert_true((disasm.Argument1.ArgType & BE::REGISTER_TYPE) == - BE::REGISTER_TYPE); - uint64_t* reg_ptr = GetContextRegPtr(disasm.Argument1.ArgType, - ex_info->ContextRecord); - switch (disasm.Argument1.ArgSize) { - case 8: - *reg_ptr = static_cast(value); - break; - case 16: - *reg_ptr = poly::byte_swap(static_cast(value)); - break; - case 32: - *reg_ptr = poly::byte_swap(static_cast(value)); - break; - case 64: - *reg_ptr = poly::byte_swap(static_cast(value)); - break; - } - ex_info->ContextRecord->Rip += len; - return EXCEPTION_CONTINUE_EXECUTION; - } else if (action == 1) { - uint64_t value; - if ((disasm.Argument2.ArgType & BE::REGISTER_TYPE) == BE::REGISTER_TYPE) { - uint64_t* reg_ptr = GetContextRegPtr(disasm.Argument2.ArgType, - ex_info->ContextRecord); - value = *reg_ptr; - } else if ((disasm.Argument2.ArgType & BE::CONSTANT_TYPE) == BE::CONSTANT_TYPE) { - value = disasm.Instruction.Immediat; - } else { - assert_always(); - } - switch (disasm.Argument2.ArgSize) { - case 8: - value = static_cast(value); - break; - case 16: - value = poly::byte_swap(static_cast(value)); - break; - case 32: - value = poly::byte_swap(static_cast(value)); - break; - case 64: - value = poly::byte_swap(static_cast(value)); - break; - } - range.write(range.context, address & 0xFFFFFFFF, value); - ex_info->ContextRecord->Rip += len; - return EXCEPTION_CONTINUE_EXECUTION; - } - } - } - } - return EXCEPTION_CONTINUE_SEARCH; -} - -} // namespace - - XenonMemory::XenonMemory() : Memory(), mapping_(0), mapping_base_(0), page_table_(0) { @@ -237,9 +126,9 @@ XenonMemory::XenonMemory() } XenonMemory::~XenonMemory() { - // Remove exception handlers. - RemoveVectoredExceptionHandler(CheckMMIOHandler); - RemoveVectoredContinueHandler(CheckMMIOHandler); + // Uninstall the MMIO handler, as we won't be able to service more + // requests. + mmio_handler_.reset(); // Unallocate mapped ranges. for (int i = 0; i < g_mapped_range_count_; ++i) { @@ -319,12 +208,11 @@ int XenonMemory::Initialize() { MEM_COMMIT, PAGE_READWRITE); // Add handlers for MMIO. - // If there is a debugger attached the normal exception handler will not - // fire and we must instead add the continue handler. - AddVectoredExceptionHandler(1, CheckMMIOHandler); - if (IsDebuggerPresent()) { - // TODO(benvanik): is this really required? - //AddVectoredContinueHandler(1, CheckMMIOHandler); + mmio_handler_ = MMIOHandler::Install(); + if (!mmio_handler_) { + XELOGE("Unable to install MMIO handlers"); + assert_always(); + XEFAIL(); } // Allocate dirty page table. @@ -382,44 +270,19 @@ bool XenonMemory::AddMappedRange(uint64_t address, uint64_t mask, uint64_t size, void* context, MMIOReadCallback read_callback, MMIOWriteCallback write_callback) { - DWORD protect = 0; - if (read_callback && write_callback) { - protect = PAGE_NOACCESS; - } else if (write_callback) { - protect = PAGE_READONLY; - } else { - // Write-only memory is not supported. - assert_always(); - } + DWORD protect = PAGE_NOACCESS; if (!VirtualAlloc(Translate(address), size, MEM_COMMIT, protect)) { + XELOGE("Unable to map range; commit/protect failed"); return false; } - assert_true(g_mapped_range_count_ + 1 < XECOUNT(g_mapped_ranges_)); - g_mapped_ranges_[g_mapped_range_count_++] = { - reinterpret_cast(mapping_base_) | address, - 0xFFFFFFFF00000000 | mask, - size, context, - read_callback, write_callback, - }; - return true; -} - -bool XenonMemory::CheckMMIOLoad(uint64_t address, uint64_t* out_value) { - for (int i = 0; i < g_mapped_range_count_; ++i) { - const auto& range = g_mapped_ranges_[i]; - if (((address | (uint64_t)mapping_base_) & range.mask) == range.address) { - *out_value = static_cast(range.read(range.context, address)); - return true; - } - } - return false; + return mmio_handler_->RegisterRange(address, mask, size, context, read_callback, write_callback); } uint8_t XenonMemory::LoadI8(uint64_t address) { uint64_t value; - if (!CheckMMIOLoad(address, &value)) { + if (!mmio_handler_->CheckLoad(address, &value)) { value = *reinterpret_cast(Translate(address)); } return static_cast(value); @@ -427,7 +290,7 @@ uint8_t XenonMemory::LoadI8(uint64_t address) { uint16_t XenonMemory::LoadI16(uint64_t address) { uint64_t value; - if (!CheckMMIOLoad(address, &value)) { + if (!mmio_handler_->CheckLoad(address, &value)) { value = *reinterpret_cast(Translate(address)); } return static_cast(value); @@ -435,7 +298,7 @@ uint16_t XenonMemory::LoadI16(uint64_t address) { uint32_t XenonMemory::LoadI32(uint64_t address) { uint64_t value; - if (!CheckMMIOLoad(address, &value)) { + if (!mmio_handler_->CheckLoad(address, &value)) { value = *reinterpret_cast(Translate(address)); } return static_cast(value); @@ -443,43 +306,32 @@ uint32_t XenonMemory::LoadI32(uint64_t address) { uint64_t XenonMemory::LoadI64(uint64_t address) { uint64_t value; - if (!CheckMMIOLoad(address, &value)) { + if (!mmio_handler_->CheckLoad(address, &value)) { value = *reinterpret_cast(Translate(address)); } return static_cast(value); } -bool XenonMemory::CheckMMIOStore(uint64_t address, uint64_t value) { - for (int i = 0; i < g_mapped_range_count_; ++i) { - const auto& range = g_mapped_ranges_[i]; - if (((address | (uint64_t)mapping_base_) & range.mask) == range.address) { - range.write(range.context, address, value); - return true; - } - } - return false; -} - void XenonMemory::StoreI8(uint64_t address, uint8_t value) { - if (!CheckMMIOStore(address, value)) { + if (!mmio_handler_->CheckStore(address, value)) { *reinterpret_cast(Translate(address)) = value; } } void XenonMemory::StoreI16(uint64_t address, uint16_t value) { - if (!CheckMMIOStore(address, value)) { + if (!mmio_handler_->CheckStore(address, value)) { *reinterpret_cast(Translate(address)) = value; } } void XenonMemory::StoreI32(uint64_t address, uint32_t value) { - if (!CheckMMIOStore(address, value)) { + if (!mmio_handler_->CheckStore(address, value)) { *reinterpret_cast(Translate(address)) = value; } } void XenonMemory::StoreI64(uint64_t address, uint64_t value) { - if (!CheckMMIOStore(address, value)) { + if (!mmio_handler_->CheckStore(address, value)) { *reinterpret_cast(Translate(address)) = value; } } diff --git a/src/xenia/cpu/xenon_memory.h b/src/xenia/cpu/xenon_memory.h index 05872d12e..dc5ff9354 100644 --- a/src/xenia/cpu/xenon_memory.h +++ b/src/xenia/cpu/xenon_memory.h @@ -10,9 +10,12 @@ #ifndef XENIA_CPU_XENON_MEMORY_H_ #define XENIA_CPU_XENON_MEMORY_H_ +#include + #include #include +#include typedef struct xe_ppc_state xe_ppc_state_t; @@ -22,10 +25,6 @@ namespace cpu { class XenonMemoryHeap; -typedef uint64_t (*MMIOReadCallback)(void* context, uint64_t addr); -typedef void (*MMIOWriteCallback)(void* context, uint64_t addr, - uint64_t value); - class XenonMemory : public alloy::Memory { public: XenonMemory(); @@ -38,8 +37,8 @@ public: bool AddMappedRange(uint64_t address, uint64_t mask, uint64_t size, void* context, - MMIOReadCallback read_callback = nullptr, - MMIOWriteCallback write_callback = nullptr); + MMIOReadCallback read_callback, + MMIOWriteCallback write_callback); uint8_t LoadI8(uint64_t address) override; uint16_t LoadI16(uint64_t address) override; @@ -64,9 +63,6 @@ private: int MapViews(uint8_t* mapping_base); void UnmapViews(); - bool CheckMMIOLoad(uint64_t address, uint64_t* out_value); - bool CheckMMIOStore(uint64_t address, uint64_t value); - private: HANDLE mapping_; uint8_t* mapping_base_; @@ -82,6 +78,8 @@ private: uint8_t* all_views[6]; } views_; + std::unique_ptr mmio_handler_; + XenonMemoryHeap* virtual_heap_; XenonMemoryHeap* physical_heap_; From b24835be2728952877cbcfdb2c2e6702d4e0cb53 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 29 Jul 2014 22:44:56 -0700 Subject: [PATCH 040/388] Removing some xenia requirements from alloy sandbox. --- tools/alloy-sandbox/alloy-sandbox.cc | 127 +++++++++++++++++++-------- 1 file changed, 92 insertions(+), 35 deletions(-) diff --git a/tools/alloy-sandbox/alloy-sandbox.cc b/tools/alloy-sandbox/alloy-sandbox.cc index db1886d26..162721ddb 100644 --- a/tools/alloy-sandbox/alloy-sandbox.cc +++ b/tools/alloy-sandbox/alloy-sandbox.cc @@ -10,62 +10,119 @@ #include #include #include +#include +#include #include #include -#include #include -#include -#include #include -using namespace alloy; -using namespace alloy::backend; -using namespace alloy::runtime; -using namespace xe; -using namespace xe::cpu; +namespace alloy { +namespace sandbox { -int alloy_sandbox(int argc, xechar_t** argv) { - Profiler::Initialize(); +using alloy::frontend::ppc::PPCContext; +using alloy::runtime::Runtime; + +class ThreadState : public alloy::runtime::ThreadState { + public: + ThreadState(Runtime* runtime, uint32_t thread_id, size_t stack_size, + uint64_t thread_state_address) + : alloy::runtime::ThreadState(runtime, thread_id), + stack_size_(stack_size), + thread_state_address_(thread_state_address) { + stack_address_ = memory_->HeapAlloc(0, stack_size, MEMORY_FLAG_ZERO); + + // Allocate with 64b alignment. + context_ = (PPCContext*)xe_malloc_aligned(sizeof(PPCContext)); + assert_true((reinterpret_cast(context_) & 0xF) == 0); + memset(&context_, 0, sizeof(PPCContext)); + + // Stash pointers to common structures that callbacks may need. + context_->reserve_address = memory_->reserve_address(); + context_->membase = memory_->membase(); + context_->runtime = runtime; + context_->thread_state = this; + + // Set initial registers. + context_->r[1] = stack_address_ + stack_size; + context_->r[13] = thread_state_address_; + + // Pad out stack a bit, as some games seem to overwrite the caller by about + // 16 to 32b. + context_->r[1] -= 64; + + raw_context_ = context_; + + runtime_->debugger()->OnThreadCreated(this); + } + ~ThreadState() override { + runtime_->debugger()->OnThreadDestroyed(this); + xe_free_aligned(context_); + memory_->HeapFree(stack_address_, stack_size_); + } + + PPCContext* context() const { return context_; } + + private: + uint64_t stack_address_; + size_t stack_size_; + uint64_t thread_state_address_; + + // NOTE: must be 64b aligned for SSE ops. + PPCContext* context_; +}; + +// TODO(benvanik): simple memory? move more into core? + +int main(int argc, xechar_t** argv) { + xe::Profiler::Initialize(); xe::Profiler::ThreadEnter("main"); - XenonMemory* memory = new XenonMemory(); + auto memory = std::make_unique(); + auto runtime = std::make_unique(memory.get()); - ExportResolver* export_resolver = new ExportResolver(); - XenonRuntime* runtime = new XenonRuntime(memory, export_resolver); + auto frontend = + std::make_unique(runtime.get()); + std::unique_ptr backend; + // auto backend = + // std::make_unique(runtime.get()); + // auto backend = + // std::make_unique(runtime.get()); + runtime->Initialize(std::move(frontend), std::move(backend)); - std::unique_ptr backend; - // backend.reset(new alloy::backend::ivm::IVMBackend(runtime)); - // backend.reset(new alloy::backend::x64::X64Backend(runtime)); - runtime->Initialize(std::move(backend)); - - auto module = std::make_unique(runtime); + auto module = std::make_unique(runtime.get()); module->LoadFile(0x82000000, "test\\codegen\\instr_add.bin"); runtime->AddModule(std::move(module)); - XenonThreadState* thread_state = - new XenonThreadState(runtime, 100, 64 * 1024, 0); + { + auto thread_state = + std::make_unique(runtime.get(), 100, 64 * 1024, 0); - Function* fn; - runtime->ResolveFunction(0x82000000, &fn); - auto ctx = thread_state->context(); - ctx->lr = 0xBEBEBEBE; - ctx->r[5] = 10; - ctx->r[25] = 25; - fn->Call(thread_state, ctx->lr); - auto result = ctx->r[11]; - printf("%llu", result); + alloy::runtime::Function* fn; + runtime->ResolveFunction(0x82000000, &fn); + auto ctx = thread_state->context(); + ctx->lr = 0xBEBEBEBE; + ctx->r[5] = 10; + ctx->r[25] = 25; + fn->Call(thread_state.get(), ctx->lr); + auto result = ctx->r[11]; + printf("%llu", result); + } - delete thread_state; - - delete runtime; - delete memory; + runtime.reset(); + memory.reset(); xe::Profiler::Dump(); xe::Profiler::ThreadExit(); return 0; } + +} // namespace sandbox +} // namespace alloy + +// TODO(benvanik): move main thunk into poly // ehhh #include -XE_MAIN_THUNK(alloy_sandbox, "alloy-sandbox"); +XE_MAIN_THUNK(alloy::sandbox::main, "alloy-sandbox"); From 4beaacb62203c3ab14fa51dd5ee494f787489e71 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 31 Jul 2014 21:56:51 -0700 Subject: [PATCH 041/388] Fixing build on linux. --- src/poly/atomic.h | 4 ++-- xenia.gyp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/poly/atomic.h b/src/poly/atomic.h index 634b2d101..51c0ec9de 100644 --- a/src/poly/atomic.h +++ b/src/poly/atomic.h @@ -88,8 +88,8 @@ inline int64_t atomic_exchange(int64_t new_value, volatile int64_t* value) { inline int32_t atomic_cas(int32_t old_value, int32_t new_value, volatile int32_t* value) { - return __sync_bool_compare_and_swap(reinterpret_cast(value), - old_value, new_value); + return __sync_bool_compare_and_swap( + reinterpret_cast(value), old_value, new_value); } #else diff --git a/xenia.gyp b/xenia.gyp index e00108f76..06ad0d428 100644 --- a/xenia.gyp +++ b/xenia.gyp @@ -60,7 +60,7 @@ ], 'cflags': [ - #'-std=c99', + '-std=c++11', ], 'configurations': { From 12f734d7a016379f03d444eb799499e742f2f680 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 1 Aug 2014 20:28:52 -0700 Subject: [PATCH 042/388] VC++ has std::make_unique. --- src/poly/cxx_compat.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/poly/cxx_compat.h b/src/poly/cxx_compat.h index fa471eca0..fd0f26d81 100644 --- a/src/poly/cxx_compat.h +++ b/src/poly/cxx_compat.h @@ -32,6 +32,7 @@ #define alignas(N) __declspec(align(N)) #endif // XE_COMPILER_MSVC +#if !XE_COMPILER_MSVC // C++1y make_unique. // http://herbsutter.com/2013/05/29/gotw-89-solution-smart-pointers/ // This is present in clang with -std=c++1y, but not otherwise. @@ -41,6 +42,7 @@ unique_ptr make_unique(Args&&... args) { return unique_ptr(new T(forward(args)...)); } } // namespace std +#endif // !XE_COMPILER_MSVC namespace poly {} // namespace poly From 4ad7662ef7c6fa6db4ef03fc128277c39195d4ca Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 1 Aug 2014 20:29:57 -0700 Subject: [PATCH 043/388] Fixing MMIO build on Windows. --- src/poly/debugging_win.cc | 2 ++ src/xenia/cpu/mmio_handler.cc | 14 ++++++-------- src/xenia/cpu/mmio_handler.h | 7 ++++--- src/xenia/cpu/mmio_handler_mac.cc | 13 +++++++------ src/xenia/cpu/mmio_handler_win.cc | 15 +++++++++------ src/xenia/cpu/xenon_memory.cc | 9 +-------- 6 files changed, 29 insertions(+), 31 deletions(-) diff --git a/src/poly/debugging_win.cc b/src/poly/debugging_win.cc index 419547f34..05916f700 100644 --- a/src/poly/debugging_win.cc +++ b/src/poly/debugging_win.cc @@ -9,6 +9,8 @@ #include +#include + namespace poly { namespace debugging { diff --git a/src/xenia/cpu/mmio_handler.cc b/src/xenia/cpu/mmio_handler.cc index 5408f9890..299d2704e 100644 --- a/src/xenia/cpu/mmio_handler.cc +++ b/src/xenia/cpu/mmio_handler.cc @@ -21,9 +21,9 @@ namespace cpu { MMIOHandler* MMIOHandler::global_handler_ = nullptr; // Implemented in the platform cc file. -std::unique_ptr CreateMMIOHandler(); +std::unique_ptr CreateMMIOHandler(uint8_t* mapping_base); -std::unique_ptr MMIOHandler::Install() { +std::unique_ptr MMIOHandler::Install(uint8_t* mapping_base) { // There can be only one handler at a time. assert_null(global_handler_); if (global_handler_) { @@ -31,7 +31,7 @@ std::unique_ptr MMIOHandler::Install() { } // Create the platform-specific handler. - auto handler = CreateMMIOHandler(); + auto handler = CreateMMIOHandler(mapping_base); // Platform-specific initialization for the handler. if (!handler->Initialize()) { @@ -45,19 +45,17 @@ std::unique_ptr MMIOHandler::Install() { MMIOHandler::~MMIOHandler() { assert_true(global_handler_ == this); global_handler_ = nullptr; - - // Platform-specific handler uninstall. - Uninstall(); } bool MMIOHandler::RegisterRange(uint64_t address, uint64_t mask, uint64_t size, void* context, MMIOReadCallback read_callback, MMIOWriteCallback write_callback) { - mapped_ranges_.emplace_back({ + mapped_ranges_.push_back({ reinterpret_cast(mapping_base_) | address, 0xFFFFFFFF00000000ull | mask, size, context, read_callback, write_callback, }); + return true; } bool MMIOHandler::CheckLoad(uint64_t address, uint64_t* out_value) { @@ -153,7 +151,7 @@ bool MMIOHandler::HandleAccessFault(void* thread_state, if (!poly::bit_scan_forward(arg2_type & 0xFFFF, &be_reg_index)) { be_reg_index = 0; } - uint64_t* reg_ptr = GetThreadStateRegPtr(thread_state, arg2_type); + uint64_t* reg_ptr = GetThreadStateRegPtr(thread_state, be_reg_index); value = *reg_ptr; } else if ((arg2_type & BE::CONSTANT_TYPE) == BE::CONSTANT_TYPE) { value = disasm.Instruction.Immediat; diff --git a/src/xenia/cpu/mmio_handler.h b/src/xenia/cpu/mmio_handler.h index 44eeea985..586c04840 100644 --- a/src/xenia/cpu/mmio_handler.h +++ b/src/xenia/cpu/mmio_handler.h @@ -24,7 +24,7 @@ class MMIOHandler { public: virtual ~MMIOHandler(); - static std::unique_ptr Install(); + static std::unique_ptr Install(uint8_t* mapping_base); static MMIOHandler* global_handler() { return global_handler_; } bool RegisterRange(uint64_t address, uint64_t mask, uint64_t size, @@ -38,16 +38,17 @@ class MMIOHandler { bool HandleAccessFault(void* thread_state, uint64_t fault_address); protected: - MMIOHandler() = default; + MMIOHandler(uint8_t* mapping_base) : mapping_base_(mapping_base) {} virtual bool Initialize() = 0; - virtual void Uninstall() = 0; virtual uint64_t GetThreadStateRip(void* thread_state_ptr) = 0; virtual void SetThreadStateRip(void* thread_state_ptr, uint64_t rip) = 0; virtual uint64_t* GetThreadStateRegPtr(void* thread_state_ptr, int32_t be_reg_index) = 0; + uint8_t* mapping_base_; + struct MMIORange { uint64_t address; uint64_t mask; diff --git a/src/xenia/cpu/mmio_handler_mac.cc b/src/xenia/cpu/mmio_handler_mac.cc index 193bd3f5c..9e540ffa2 100644 --- a/src/xenia/cpu/mmio_handler_mac.cc +++ b/src/xenia/cpu/mmio_handler_mac.cc @@ -34,11 +34,11 @@ namespace cpu { class MachMMIOHandler : public MMIOHandler { public: - MachMMIOHandler(); + MachMMIOHandler(uint8_t* mapping_base); + ~MachMMIOHandler() override; protected: bool Initialize() override; - void Uninstall() override; uint64_t GetThreadStateRip(void* thread_state_ptr) override; void SetThreadStateRip(void* thread_state_ptr, uint64_t rip) override; @@ -54,11 +54,12 @@ class MachMMIOHandler : public MMIOHandler { mach_port_t listen_port_; }; -std::unique_ptr CreateMMIOHandler() { - return std::make_unique(); +std::unique_ptr CreateMMIOHandler(uint8_t* mapping_base) { + return std::make_unique(mapping_base); } -MachMMIOHandler::MachMMIOHandler() : listen_port_(0) {} +MachMMIOHandler::MachMMIOHandler(uint8_t* mapping_base) + : MMIOHandler(mapping_base), listen_port_(0) {} bool MachMMIOHandler::Initialize() { // Allocates the port that listens for exceptions. @@ -93,7 +94,7 @@ bool MachMMIOHandler::Initialize() { return true; } -void MachMMIOHandler::Uninstall() { +MachMMIOHandler::~MachMMIOHandler() { task_set_exception_ports(mach_task_self(), EXC_MASK_BAD_ACCESS, 0, EXCEPTION_DEFAULT, 0); mach_port_deallocate(mach_task_self(), listen_port_); diff --git a/src/xenia/cpu/mmio_handler_win.cc b/src/xenia/cpu/mmio_handler_win.cc index 31647ab18..e645c0a64 100644 --- a/src/xenia/cpu/mmio_handler_win.cc +++ b/src/xenia/cpu/mmio_handler_win.cc @@ -9,6 +9,8 @@ #include +#include + namespace xe { namespace cpu { @@ -16,11 +18,11 @@ LONG CALLBACK MMIOExceptionHandler(PEXCEPTION_POINTERS ex_info); class WinMMIOHandler : public MMIOHandler { public: - WinMMIOHandler() = default; + WinMMIOHandler(uint8_t* mapping_base) : MMIOHandler(mapping_base) {} + ~WinMMIOHandler() override; protected: bool Initialize() override; - void Uninstall() override; uint64_t GetThreadStateRip(void* thread_state_ptr) override; void SetThreadStateRip(void* thread_state_ptr, uint64_t rip) override; @@ -28,8 +30,8 @@ class WinMMIOHandler : public MMIOHandler { int32_t be_reg_index) override; }; -std::unique_ptr CreateMMIOHandler() { - return std::make_unique(); +std::unique_ptr CreateMMIOHandler(uint8_t* mapping_base) { + return std::make_unique(mapping_base); } bool WinMMIOHandler::Initialize() { @@ -43,7 +45,7 @@ bool WinMMIOHandler::Initialize() { return true; } -void WinMMIOHandler::Uninstall() { +WinMMIOHandler::~WinMMIOHandler() { // Remove exception handlers. RemoveVectoredExceptionHandler(MMIOExceptionHandler); RemoveVectoredContinueHandler(MMIOExceptionHandler); @@ -58,7 +60,8 @@ LONG CALLBACK MMIOExceptionHandler(PEXCEPTION_POINTERS ex_info) { auto code = ex_info->ExceptionRecord->ExceptionCode; if (code == STATUS_ACCESS_VIOLATION) { auto fault_address = ex_info->ExceptionRecord->ExceptionInformation[1]; - if (HandleAccessFault(ex_info->ContextRecord, fault_address)) { + if (MMIOHandler::global_handler()->HandleAccessFault(ex_info->ContextRecord, + fault_address)) { // Handled successfully - RIP has been updated and we can continue. return EXCEPTION_CONTINUE_EXECUTION; } else { diff --git a/src/xenia/cpu/xenon_memory.cc b/src/xenia/cpu/xenon_memory.cc index e9dcd9b79..9e3942649 100644 --- a/src/xenia/cpu/xenon_memory.cc +++ b/src/xenia/cpu/xenon_memory.cc @@ -130,13 +130,6 @@ XenonMemory::~XenonMemory() { // requests. mmio_handler_.reset(); - // Unallocate mapped ranges. - for (int i = 0; i < g_mapped_range_count_; ++i) { - const auto& range = g_mapped_ranges_[i]; - VirtualFree(reinterpret_cast(range.address), range.size, - MEM_DECOMMIT); - } - if (mapping_base_) { // GPU writeback. VirtualFree( @@ -208,7 +201,7 @@ int XenonMemory::Initialize() { MEM_COMMIT, PAGE_READWRITE); // Add handlers for MMIO. - mmio_handler_ = MMIOHandler::Install(); + mmio_handler_ = MMIOHandler::Install(mapping_base_); if (!mmio_handler_) { XELOGE("Unable to install MMIO handlers"); assert_always(); From 3f2baafb4bbbc46bd8a6d37e35372c4d35648157 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 1 Aug 2014 21:43:52 -0700 Subject: [PATCH 044/388] mmap, but ehh virtualquery... --- src/xenia/cpu/xenon_memory.cc | 49 ++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/src/xenia/cpu/xenon_memory.cc b/src/xenia/cpu/xenon_memory.cc index 9e3942649..dd277efac 100644 --- a/src/xenia/cpu/xenon_memory.cc +++ b/src/xenia/cpu/xenon_memory.cc @@ -158,12 +158,19 @@ int XenonMemory::Initialize() { // Create main page file-backed mapping. This is all reserved but // uncommitted (so it shouldn't expand page file). +#if XE_PLATFORM_WIN32 mapping_ = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_RESERVE, 1, 0, // entire 4gb space NULL); +#else + char mapping_path[] = "/xenia/mapping/XXXXXX"; + mktemp(mapping_path); + mapping_ = shm_open(mapping_path, O_CREAT, 0); + ftruncate(mapping_, 0x100000000); +#endif // XE_PLATFORM_WIN32 if (!mapping_) { XELOGE("Unable to reserve the 4gb guest address space."); assert_not_null(mapping_); @@ -221,27 +228,34 @@ XECLEANUP: return result; } +const static struct { + uint64_t virtual_address_start; + uint64_t virtual_address_end; + uint64_t target_address; +} map_info[] = { + 0x00000000, 0x3FFFFFFF, 0x00000000, // (1024mb) - virtual 4k pages + 0x40000000, 0x7FFFFFFF, 0x40000000, // (1024mb) - virtual 64k pages + 0x80000000, 0x9FFFFFFF, 0x80000000, // (512mb) - xex pages + 0xA0000000, 0xBFFFFFFF, 0x00000000, // (512mb) - physical 64k pages + 0xC0000000, 0xDFFFFFFF, 0x00000000, // - physical 16mb pages + 0xE0000000, 0xFFFFFFFF, 0x00000000, // - physical 4k pages +}; int XenonMemory::MapViews(uint8_t* mapping_base) { - static struct { - uint64_t virtual_address_start; - uint64_t virtual_address_end; - uint64_t target_address; - } map_info[] = { - 0x00000000, 0x3FFFFFFF, 0x00000000, // (1024mb) - virtual 4k pages - 0x40000000, 0x7FFFFFFF, 0x40000000, // (1024mb) - virtual 64k pages - 0x80000000, 0x9FFFFFFF, 0x80000000, // (512mb) - xex pages - 0xA0000000, 0xBFFFFFFF, 0x00000000, // (512mb) - physical 64k pages - 0xC0000000, 0xDFFFFFFF, 0x00000000, // - physical 16mb pages - 0xE0000000, 0xFFFFFFFF, 0x00000000, // - physical 4k pages - }; assert_true(XECOUNT(map_info) == XECOUNT(views_.all_views)); for (size_t n = 0; n < XECOUNT(map_info); n++) { - views_.all_views[n] = (uint8_t*)MapViewOfFileEx( +#if XE_PLATFORM_WIN32 + views_.all_views[n] = reinterpret_cast(MapViewOfFileEx( mapping_, FILE_MAP_ALL_ACCESS, 0x00000000, (DWORD)map_info[n].target_address, map_info[n].virtual_address_end - map_info[n].virtual_address_start + 1, - mapping_base + map_info[n].virtual_address_start); + mapping_base + map_info[n].virtual_address_start)); +#else + views_.all_views[n] = reinterpret_cast(mmap( + map_info[n].virtual_address_start + mapping_base, + map_info[n].virtual_address_end - map_info[n].virtual_address_start + 1, + PROT_NONE, MAP_SHARED | MAP_FIXED, mapping_, map_info[n].target_address)); +#endif // XE_PLATFORM_WIN32 XEEXPECTNOTNULL(views_.all_views[n]); } return 0; @@ -254,7 +268,12 @@ XECLEANUP: void XenonMemory::UnmapViews() { for (size_t n = 0; n < XECOUNT(views_.all_views); n++) { if (views_.all_views[n]) { +#if XE_PLATFORM_WIN32 UnmapViewOfFile(views_.all_views[n]); +#else + size_t length = map_info[n].virtual_address_end - map_info[n].virtual_address_start + 1; + munmap(views_.all_views[n], length); +#endif // XE_PLATFORM_WIN32 } } } @@ -404,7 +423,7 @@ size_t XenonMemory::QuerySize(uint64_t base_address) { base_address < XENON_MEMORY_PHYSICAL_HEAP_HIGH) { return physical_heap_->QuerySize(base_address); } else { - // A placed address. Decommit. + // A placed address. uint8_t* p = Translate(base_address); MEMORY_BASIC_INFORMATION mem_info; if (VirtualQuery(p, &mem_info, sizeof(mem_info))) { From f04c7b866146b68f31684ca777e4905a8c797e5e Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 2 Aug 2014 16:23:02 -0700 Subject: [PATCH 045/388] ExAllocatePoolTypeWithTag --- src/xenia/kernel/xboxkrnl_memory.cc | 41 +++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/xenia/kernel/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl_memory.cc index ab153a625..9f10b4fba 100644 --- a/src/xenia/kernel/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl_memory.cc @@ -448,6 +448,44 @@ SHIM_CALL MmGetPhysicalAddress_shim( } +SHIM_CALL ExAllocatePoolTypeWithTag_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t size = SHIM_GET_ARG_32(0); + uint32_t tag = SHIM_GET_ARG_32(1); + uint32_t zero = SHIM_GET_ARG_32(2); + + XELOGD( + "ExAllocatePoolTypeWithTag(%d, %.8X, %d)", + size, tag, zero); + + uint32_t alignment = 8; + uint32_t adjusted_size = size; + if (adjusted_size < 4 * 1024) { + adjusted_size = XEROUNDUP(adjusted_size, 4 * 1024); + } else { + alignment = 4 * 1024; + } + + uint32_t addr = (uint32_t)state->memory()->HeapAlloc( + 0, adjusted_size, MEMORY_FLAG_ZERO, alignment); + + SHIM_SET_RETURN_32(addr); +} + + + +SHIM_CALL ExFreePool_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t base_address = SHIM_GET_ARG_32(0); + + XELOGD( + "ExFreePool(%.8X)", + base_address); + + state->memory()->HeapFree(base_address, 0); +} + + SHIM_CALL KeLockL2_shim( PPCContext* ppc_state, KernelState* state) { // Ignored for now. This is just a perf optimization, I think. @@ -483,6 +521,9 @@ void xe::kernel::xboxkrnl::RegisterMemoryExports( SHIM_SET_MAPPING("xboxkrnl.exe", MmQueryStatistics, state); SHIM_SET_MAPPING("xboxkrnl.exe", MmGetPhysicalAddress, state); + SHIM_SET_MAPPING("xboxkrnl.exe", ExAllocatePoolTypeWithTag, state); + SHIM_SET_MAPPING("xboxkrnl.exe", ExFreePool, state); + SHIM_SET_MAPPING("xboxkrnl.exe", KeLockL2, state); SHIM_SET_MAPPING("xboxkrnl.exe", KeUnlockL2, state); } From 19149bbba6bccfeb931fb0f578cfa58cbc656fae Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 2 Aug 2014 21:37:11 -0700 Subject: [PATCH 046/388] Stubbed out enumeration. --- src/xenia/kernel/objects/sources.gypi | 2 ++ src/xenia/kernel/objects/xenumerator.cc | 25 ++++++++++++++ src/xenia/kernel/objects/xenumerator.h | 37 +++++++++++++++++++++ src/xenia/kernel/xam_info.cc | 39 ++++++++++++++++++++++ src/xenia/kernel/xam_msg.cc | 43 ++++++++++++++++++++++++- src/xenia/kernel/xam_user.cc | 26 +++++++++++++++ src/xenia/kernel/xobject.h | 1 + src/xenia/xbox.h | 30 +++++++++++++++++ 8 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 src/xenia/kernel/objects/xenumerator.cc create mode 100644 src/xenia/kernel/objects/xenumerator.h diff --git a/src/xenia/kernel/objects/sources.gypi b/src/xenia/kernel/objects/sources.gypi index 7e849919a..49c07754a 100644 --- a/src/xenia/kernel/objects/sources.gypi +++ b/src/xenia/kernel/objects/sources.gypi @@ -1,6 +1,8 @@ # Copyright 2013 Ben Vanik. All Rights Reserved. { 'sources': [ + 'xenumerator.cc', + 'xenumerator.h', 'xevent.cc', 'xevent.h', 'xfile.cc', diff --git a/src/xenia/kernel/objects/xenumerator.cc b/src/xenia/kernel/objects/xenumerator.cc new file mode 100644 index 000000000..b4516d813 --- /dev/null +++ b/src/xenia/kernel/objects/xenumerator.cc @@ -0,0 +1,25 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + + +using namespace xe; +using namespace xe::kernel; + + +XEnumerator::XEnumerator(KernelState* kernel_state) : + XObject(kernel_state, kTypeEnumerator) { +} + +XEnumerator::~XEnumerator() { +} + +void XEnumerator::Initialize() { +} diff --git a/src/xenia/kernel/objects/xenumerator.h b/src/xenia/kernel/objects/xenumerator.h new file mode 100644 index 000000000..fa3a0dbde --- /dev/null +++ b/src/xenia/kernel/objects/xenumerator.h @@ -0,0 +1,37 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_KERNEL_XBOXKRNL_XENUMERATOR_H_ +#define XENIA_KERNEL_XBOXKRNL_XENUMERATOR_H_ + +#include + +#include + + +namespace xe { +namespace kernel { + + +class XEnumerator : public XObject { +public: + XEnumerator(KernelState* kernel_state); + virtual ~XEnumerator(); + + void Initialize(); + +private: +}; + + +} // namespace kernel +} // namespace xe + + +#endif // XENIA_KERNEL_XBOXKRNL_XENUMERATOR_H_ diff --git a/src/xenia/kernel/xam_info.cc b/src/xenia/kernel/xam_info.cc index a8c1b1b22..3a05acab9 100644 --- a/src/xenia/kernel/xam_info.cc +++ b/src/xenia/kernel/xam_info.cc @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -102,6 +103,42 @@ SHIM_CALL XamLoaderGetLaunchData_shim( } +SHIM_CALL XamEnumerate_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t handle = SHIM_GET_ARG_32(0); + uint32_t zero = SHIM_GET_ARG_32(1); + uint32_t buffer_ptr = SHIM_GET_ARG_32(2); + uint32_t buffer_length = SHIM_GET_ARG_32(3); + uint32_t item_count_ptr = SHIM_GET_ARG_32(4); + uint32_t overlapped_ptr = SHIM_GET_ARG_32(5); + + XELOGD( + "XamEnumerate(%.8X, %d, %d, %.8X, %d, %.8X, %.8X)", + handle, zero, buffer_ptr, buffer_length, item_count_ptr, + overlapped_ptr); + + XEnumerator* e = nullptr; + if (XFAILED(state->object_table()->GetObject( + handle, (XObject**)&e))) { + SHIM_SET_RETURN_64(X_ERROR_INVALID_HANDLE); + return; + } + + if (item_count_ptr) { + SHIM_SET_MEM_32(item_count_ptr, 0); + } else if (overlapped_ptr) { + // TODO(benvanik): overlapped IO. + assert_zero(overlapped_ptr); + } else { + assert_always(); + } + + e->Release(); + + SHIM_SET_RETURN_64(0); +} + + } // namespace kernel } // namespace xe @@ -115,4 +152,6 @@ void xe::kernel::xam::RegisterInfoExports( SHIM_SET_MAPPING("xam.xex", XamLoaderGetLaunchDataSize, state); SHIM_SET_MAPPING("xam.xex", XamLoaderGetLaunchData, state); + + SHIM_SET_MAPPING("xam.xex", XamEnumerate, state); } diff --git a/src/xenia/kernel/xam_msg.cc b/src/xenia/kernel/xam_msg.cc index ded24cee1..72f2b2eca 100644 --- a/src/xenia/kernel/xam_msg.cc +++ b/src/xenia/kernel/xam_msg.cc @@ -74,8 +74,48 @@ SHIM_CALL XMsgInProcessCall_shim( } +SHIM_CALL XMsgStartIORequest_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t app = SHIM_GET_ARG_32(0); + uint32_t message = SHIM_GET_ARG_32(1); + uint32_t overlapped_ptr = SHIM_GET_ARG_32(2); + uint32_t buffer = SHIM_GET_ARG_32(3); + uint32_t buffer_length = SHIM_GET_ARG_32(4); + + XELOGD( + "XMsgStartIORequest(%.8X, %.8X, %.8X, %.8X, %d)", + app, message, overlapped_ptr, buffer, buffer_length); + + bool handled = false; + + assert_zero(overlapped_ptr); + + // TODO(benvanik): build XMsg pump? async/sync/etc + if (app == 0xFA) { + // XMP = music + // http://freestyledash.googlecode.com/svn-history/r1/trunk/Freestyle/Scenes/Media/Music/ScnMusic.cpp + if (message == 0x00070009) { + assert(buffer_length == 8); + uint32_t a = SHIM_MEM_32(buffer + 0); // 0x00000002 + uint32_t b = SHIM_MEM_32(buffer + 4); // out ptr to 4b - expect 0 + XELOGD("XMPGetStatusEx(%.8X, %.8X)", a, b); + assert_true(a == 2); + SHIM_SET_MEM_32(b, 0); + Sleep(1); + handled = true; + } + } + + if (!handled) { + XELOGE("Unimplemented XMsgStartIORequest message!"); + } + + SHIM_SET_RETURN_32(handled ? X_ERROR_SUCCESS : X_ERROR_NOT_FOUND); +} + + SHIM_CALL XMsgCancelIORequest_shim( - PPCContext* ppc_state, KernelState* state) { + PPCContext* ppc_state, KernelState* state) { uint32_t overlapped_ptr = SHIM_GET_ARG_32(0); uint32_t wait = SHIM_GET_ARG_32(1); @@ -97,5 +137,6 @@ SHIM_CALL XMsgCancelIORequest_shim( void xe::kernel::xam::RegisterMsgExports( ExportResolver* export_resolver, KernelState* state) { SHIM_SET_MAPPING("xam.xex", XMsgInProcessCall, state); + SHIM_SET_MAPPING("xam.xex", XMsgStartIORequest, state); SHIM_SET_MAPPING("xam.xex", XMsgCancelIORequest, state); } diff --git a/src/xenia/kernel/xam_user.cc b/src/xenia/kernel/xam_user.cc index 85ebc4835..560c41623 100644 --- a/src/xenia/kernel/xam_user.cc +++ b/src/xenia/kernel/xam_user.cc @@ -11,6 +11,7 @@ #include #include +#include #include @@ -191,6 +192,30 @@ SHIM_CALL XamShowSigninUI_shim( } +SHIM_CALL XamUserCreateAchievementEnumerator_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t title_id = SHIM_GET_ARG_32(0); + uint32_t user_index = SHIM_GET_ARG_32(1); + uint32_t xuid = SHIM_GET_ARG_32(2); + uint32_t flags = SHIM_GET_ARG_32(3); + uint32_t offset = SHIM_GET_ARG_32(4); + uint32_t count = SHIM_GET_ARG_32(5); + uint32_t buffer = SHIM_GET_ARG_32(6); + uint32_t handle_ptr = SHIM_GET_ARG_32(7); + + XELOGD( + "XamUserCreateAchievementEnumerator(%.8X, %d, %.8X, %.8X, %d, %d, %.8X, %.8X)", + title_id, user_index, xuid, flags, offset, count, buffer, handle_ptr); + + XEnumerator* e = new XEnumerator(state); + e->Initialize(); + + SHIM_SET_MEM_32(handle_ptr, e->handle()); + + SHIM_SET_RETURN_32(X_ERROR_SUCCESS); +} + + } // namespace kernel } // namespace xe @@ -203,4 +228,5 @@ void xe::kernel::xam::RegisterUserExports( SHIM_SET_MAPPING("xam.xex", XamUserGetName, state); SHIM_SET_MAPPING("xam.xex", XamUserReadProfileSettings, state); SHIM_SET_MAPPING("xam.xex", XamShowSigninUI, state); + SHIM_SET_MAPPING("xam.xex", XamUserCreateAchievementEnumerator, state); } diff --git a/src/xenia/kernel/xobject.h b/src/xenia/kernel/xobject.h index 7733db4ab..9be1a632e 100644 --- a/src/xenia/kernel/xobject.h +++ b/src/xenia/kernel/xobject.h @@ -41,6 +41,7 @@ public: kTypeNotifyListener, kTypeMutant, kTypeTimer, + kTypeEnumerator, }; XObject(KernelState* kernel_state, Type type); diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index 8e24fa3a4..9c47ced22 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -63,6 +63,7 @@ typedef uint32_t X_RESULT; #define X_HRESULT_FROM_WIN32(x) ((X_RESULT)(x) <= 0 ? ((X_RESULT)(x)) : ((X_RESULT) (((x) & 0x0000FFFF) | (X_FACILITY_WIN32 << 16) | 0x80000000))) #define X_ERROR_SUCCESS X_HRESULT_FROM_WIN32(0x00000000L) #define X_ERROR_ACCESS_DENIED X_HRESULT_FROM_WIN32(0x00000005L) +#define X_ERROR_INVALID_HANDLE X_HRESULT_FROM_WIN32(0x00000006L) #define X_ERROR_NO_MORE_FILES X_HRESULT_FROM_WIN32(0x00000018L) #define X_ERROR_INSUFFICIENT_BUFFER X_HRESULT_FROM_WIN32(0x0000007AL) #define X_ERROR_BAD_ARGUMENTS X_HRESULT_FROM_WIN32(0x000000A0L) @@ -191,6 +192,35 @@ typedef enum _X_FILE_INFORMATION_CLASS { } X_FILE_INFORMATION_CLASS; +inline void XOverlappedSetResult(void* ptr, uint32_t value) { + auto p = reinterpret_cast(ptr); + p[0] = value; +} +inline void XOverlappedSetLength(void* ptr, uint32_t value) { + auto p = reinterpret_cast(ptr); + p[1] = value; +} +inline void XOverlappedSetContext(void* ptr, uint32_t value) { + auto p = reinterpret_cast(ptr); + p[2] = value; +} +inline void XOverlappedSetExtendedError(void* ptr, uint32_t value) { + auto p = reinterpret_cast(ptr); + p[7] = value; +} +inline X_HANDLE XOverlappedGetEvent(void* ptr) { + auto p = reinterpret_cast(ptr); + return p[4]; +} +inline uint32_t XOverlappedGetCompletionRoutine(void* ptr) { + auto p = reinterpret_cast(ptr); + return p[5]; +} +inline uint32_t XOverlappedGetCompletionContext(void* ptr) { + auto p = reinterpret_cast(ptr); + return p[6]; +} + class X_ANSI_STRING { private: uint16_t length; From 57dda9c75593daabe557443d1125258620feadb8 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 3 Aug 2014 14:38:04 -0700 Subject: [PATCH 047/388] Factoring out XMsg app stuff. --- src/xenia/kernel/app.cc | 50 ++++++++++++++ src/xenia/kernel/app.h | 62 +++++++++++++++++ src/xenia/kernel/apps/apps.cc | 27 ++++++++ src/xenia/kernel/apps/apps.h | 33 +++++++++ src/xenia/kernel/apps/sources.gypi | 9 +++ src/xenia/kernel/apps/xmp_app.cc | 107 +++++++++++++++++++++++++++++ src/xenia/kernel/apps/xmp_app.h | 42 +++++++++++ src/xenia/kernel/kernel_state.cc | 8 +++ src/xenia/kernel/kernel_state.h | 7 ++ src/xenia/kernel/sources.gypi | 3 + src/xenia/kernel/xam_msg.cc | 66 ++---------------- 11 files changed, 354 insertions(+), 60 deletions(-) create mode 100644 src/xenia/kernel/app.cc create mode 100644 src/xenia/kernel/app.h create mode 100644 src/xenia/kernel/apps/apps.cc create mode 100644 src/xenia/kernel/apps/apps.h create mode 100644 src/xenia/kernel/apps/sources.gypi create mode 100644 src/xenia/kernel/apps/xmp_app.cc create mode 100644 src/xenia/kernel/apps/xmp_app.h diff --git a/src/xenia/kernel/app.cc b/src/xenia/kernel/app.cc new file mode 100644 index 000000000..0a037fb64 --- /dev/null +++ b/src/xenia/kernel/app.cc @@ -0,0 +1,50 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include + + +namespace xe { +namespace kernel { + + +XApp::XApp(KernelState* kernel_state, uint32_t app_id) + : kernel_state_(kernel_state), app_id_(app_id), + membase_(kernel_state->memory()->membase()) {} + + +void XAppManager::RegisterApp(std::unique_ptr app) { + assert_zero(app_lookup_.count(app->app_id())); + app_lookup_.insert({ app->app_id(), app.get() }); + apps_.push_back(std::move(app)); +} + + +X_RESULT XAppManager::DispatchMessageSync(uint32_t app_id, uint32_t message, uint32_t arg1, uint32_t arg2) { + const auto& it = app_lookup_.find(app_id); + if (it == app_lookup_.end()) { + return X_ERROR_NOT_FOUND; + } + return it->second->DispatchMessageSync(message, arg1, arg2); +} + + +X_RESULT XAppManager::DispatchMessageAsync(uint32_t app_id, uint32_t message, uint32_t buffer_ptr, size_t buffer_length) { + const auto& it = app_lookup_.find(app_id); + if (it == app_lookup_.end()) { + return X_ERROR_NOT_FOUND; + } + return it->second->DispatchMessageAsync(message, buffer_ptr, buffer_length); +} + + +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/app.h b/src/xenia/kernel/app.h new file mode 100644 index 000000000..ab60006e2 --- /dev/null +++ b/src/xenia/kernel/app.h @@ -0,0 +1,62 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_KERNEL_XBOXKRNL_APP_H_ +#define XENIA_KERNEL_XBOXKRNL_APP_H_ + +#include +#include + +#include +#include + +#include + + +namespace xe { +namespace kernel { + + +class KernelState; + + +class XApp { +public: + uint32_t app_id() const { return app_id_; } + + virtual X_RESULT DispatchMessageSync(uint32_t message, uint32_t arg1, uint32_t arg2) = 0; + virtual X_RESULT DispatchMessageAsync(uint32_t message, uint32_t buffer_ptr, size_t buffer_length) = 0; + +protected: + XApp(KernelState* kernel_state, uint32_t app_id); + + KernelState* kernel_state_; + uint32_t app_id_; + uint8_t* membase_; +}; + + +class XAppManager { +public: + void RegisterApp(std::unique_ptr app); + + X_RESULT DispatchMessageSync(uint32_t app_id, uint32_t message, uint32_t arg1, uint32_t arg2); + X_RESULT DispatchMessageAsync(uint32_t app_id, uint32_t message, uint32_t buffer_ptr, size_t buffer_length); + +private: + std::vector> apps_; + std::unordered_map app_lookup_; +}; + + +} // namespace kernel +} // namespace xe + + +#endif // XENIA_KERNEL_XBOXKRNL_APP_H_ diff --git a/src/xenia/kernel/apps/apps.cc b/src/xenia/kernel/apps/apps.cc new file mode 100644 index 000000000..9d18c80ec --- /dev/null +++ b/src/xenia/kernel/apps/apps.cc @@ -0,0 +1,27 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include + + +namespace xe { +namespace kernel { +namespace apps { + + +void RegisterApps(KernelState* kernel_state, XAppManager* manager) { + manager->RegisterApp(std::make_unique(kernel_state)); +} + + +} // namespace apps +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/apps/apps.h b/src/xenia/kernel/apps/apps.h new file mode 100644 index 000000000..b18e08fdb --- /dev/null +++ b/src/xenia/kernel/apps/apps.h @@ -0,0 +1,33 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_KERNEL_XBOXKRNL_APPS_APPS_H_ +#define XENIA_KERNEL_XBOXKRNL_APPS_APPS_H_ + +#include +#include + +#include +#include + + +namespace xe { +namespace kernel { +namespace apps { + + +void RegisterApps(KernelState* kernel_state, XAppManager* manager); + + +} // namespace apps +} // namespace kernel +} // namespace xe + + +#endif // XENIA_KERNEL_XBOXKRNL_APPS_APPS_H_ diff --git a/src/xenia/kernel/apps/sources.gypi b/src/xenia/kernel/apps/sources.gypi new file mode 100644 index 000000000..26c6663e2 --- /dev/null +++ b/src/xenia/kernel/apps/sources.gypi @@ -0,0 +1,9 @@ +# Copyright 2013 Ben Vanik. All Rights Reserved. +{ + 'sources': [ + 'apps.cc', + 'apps.h', + 'xmp_app.cc', + 'xmp_app.h', + ], +} diff --git a/src/xenia/kernel/apps/xmp_app.cc b/src/xenia/kernel/apps/xmp_app.cc new file mode 100644 index 000000000..b5b4af54c --- /dev/null +++ b/src/xenia/kernel/apps/xmp_app.cc @@ -0,0 +1,107 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + + +namespace xe { +namespace kernel { +namespace apps { + + +X_RESULT XXMPApp::XMPGetStatus(uint32_t unk, uint32_t status_ptr) { + // Some stupid games will hammer this on a thread - induce a delay + // here to keep from starving real threads. + Sleep(1); + + XELOGD("XMPGetStatus(%.8X, %.8X)", unk, status_ptr); + + assert_true(unk == 2); + poly::store_and_swap(membase_ + status_ptr, 0); + + return X_ERROR_SUCCESS; +} + +X_RESULT XXMPApp::XMPGetStatusEx(uint32_t unk, uint32_t unk_ptr, uint32_t disabled_ptr) { + // Some stupid games will hammer this on a thread - induce a delay + // here to keep from starving real threads. + Sleep(1); + + XELOGD("XMPGetStatusEx(%.8X, %.8X, %.8X)", unk, unk_ptr, disabled_ptr); + + assert_true(unk == 2); + poly::store_and_swap(membase_ + unk_ptr, 0); + poly::store_and_swap(membase_ + disabled_ptr, 1); + + return X_ERROR_SUCCESS; +} + +X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t arg1, uint32_t arg2) { + // http://freestyledash.googlecode.com/svn-history/r1/trunk/Freestyle/Scenes/Media/Music/ScnMusic.cpp + switch (message) { + case 0x00070009: { + uint32_t unk = + poly::load_and_swap(membase_ + arg1 + 0); // 0x00000002 + uint32_t status_ptr = poly::load_and_swap( + membase_ + arg1 + 4); // out ptr to 4b - expect 0 + assert_zero(arg2); + return XMPGetStatus(unk, status_ptr); + } + case 0x0007001A: { + // dcz + // arg1 = ? + // arg2 = 0 + break; + } + case 0x0007001B: { + uint32_t unk = + poly::load_and_swap(membase_ + arg1 + 0); // 0x00000002 + uint32_t unk_ptr = poly::load_and_swap( + membase_ + arg1 + 4); // out ptr to 4b - expect 0 + uint32_t disabled_ptr = poly::load_and_swap( + membase_ + arg1 + 8); // out ptr to 4b - expect 1 (to skip) + assert_zero(arg2); + return XMPGetStatusEx(unk, unk_ptr, disabled_ptr); + } + } + XELOGE("Unimplemented XMsg message app=%.8X, msg=%.8X, arg1=%.8X, arg2=%.8X", + app_id(), message, arg1, arg2); + return X_ERROR_NOT_FOUND; +} + +X_RESULT XXMPApp::DispatchMessageAsync(uint32_t message, uint32_t buffer_ptr, size_t buffer_length) { + switch (message) { + case 0x00070009: { + uint32_t unk = + poly::load_and_swap(membase_ + buffer_ptr + 0); // 0x00000002 + uint32_t status_ptr = poly::load_and_swap( + membase_ + buffer_ptr + 4); // out ptr to 4b - expect 0 + assert_true(buffer_length == 8); + return XMPGetStatus(unk, status_ptr); + } + case 0x0007001B: { + uint32_t unk = + poly::load_and_swap(membase_ + buffer_ptr + 0); // 0x00000002 + uint32_t unk_ptr = poly::load_and_swap( + membase_ + buffer_ptr + 4); // out ptr to 4b - expect 0 + uint32_t disabled_ptr = poly::load_and_swap( + membase_ + buffer_ptr + 8); // out ptr to 4b - expect 1 (to skip) + assert_true(buffer_length == 0xC); + return XMPGetStatusEx(unk, unk_ptr, disabled_ptr); + } + } + XELOGE("Unimplemented XMsg message app=%.8X, msg=%.8X, buffer=%.8X, len=%d", + app_id(), message, buffer_ptr, buffer_length); + return X_ERROR_NOT_FOUND; +} + + +} // namespace apps +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/apps/xmp_app.h b/src/xenia/kernel/apps/xmp_app.h new file mode 100644 index 000000000..754ca9593 --- /dev/null +++ b/src/xenia/kernel/apps/xmp_app.h @@ -0,0 +1,42 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_KERNEL_XBOXKRNL_APPS_XMP_APP_H_ +#define XENIA_KERNEL_XBOXKRNL_APPS_XMP_APP_H_ + +#include +#include + +#include +#include + + +namespace xe { +namespace kernel { +namespace apps { + + +class XXMPApp : public XApp { +public: + XXMPApp(KernelState* kernel_state) : XApp(kernel_state, 0xFA) {} + + X_RESULT XMPGetStatus(uint32_t unk, uint32_t status_ptr); + X_RESULT XMPGetStatusEx(uint32_t unk, uint32_t unk_ptr, uint32_t disabled_ptr); + + X_RESULT DispatchMessageSync(uint32_t message, uint32_t arg1, uint32_t arg2) override; + X_RESULT DispatchMessageAsync(uint32_t message, uint32_t buffer_ptr, size_t buffer_length) override; +}; + + +} // namespace apps +} // namespace kernel +} // namespace xe + + +#endif // XENIA_KERNEL_XBOXKRNL_APPS_XMP_APP_H_ diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index 025fcc990..f2d3b676d 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -39,11 +40,15 @@ KernelState::KernelState(Emulator* emulator) : dispatcher_ = new Dispatcher(this); + app_manager_ = std::make_unique(); + object_table_ = new ObjectTable(); object_mutex_ = xe_mutex_alloc(10000); assert_null(shared_kernel_state_); shared_kernel_state_ = this; + + apps::RegisterApps(this, app_manager_.get()); } KernelState::~KernelState() { @@ -53,6 +58,9 @@ KernelState::~KernelState() { xe_mutex_free(object_mutex_); delete object_table_; + // Shutdown apps. + app_manager_.reset(); + delete dispatcher_; assert_true(shared_kernel_state_ == this); diff --git a/src/xenia/kernel/kernel_state.h b/src/xenia/kernel/kernel_state.h index f2fb3f47e..4a7884724 100644 --- a/src/xenia/kernel/kernel_state.h +++ b/src/xenia/kernel/kernel_state.h @@ -10,11 +10,14 @@ #ifndef XENIA_KERNEL_KERNEL_STATE_H_ #define XENIA_KERNEL_KERNEL_STATE_H_ +#include + #include #include #include #include +#include #include #include @@ -47,6 +50,8 @@ public: Dispatcher* dispatcher() const { return dispatcher_; } + XAppManager* app_manager() const { return app_manager_.get(); } + ObjectTable* object_table() const { return object_table_; } XModule* GetModule(const char* name); @@ -69,6 +74,8 @@ private: Dispatcher* dispatcher_; + std::unique_ptr app_manager_; + ObjectTable* object_table_; xe_mutex_t* object_mutex_; std::unordered_map threads_by_id_; diff --git a/src/xenia/kernel/sources.gypi b/src/xenia/kernel/sources.gypi index 7a23d285e..2c393a0ab 100644 --- a/src/xenia/kernel/sources.gypi +++ b/src/xenia/kernel/sources.gypi @@ -1,6 +1,8 @@ # Copyright 2013 Ben Vanik. All Rights Reserved. { 'sources': [ + 'app.cc', + 'app.h', 'async_request.cc', 'async_request.h', 'dispatcher.cc', @@ -70,6 +72,7 @@ ], 'includes': [ + 'apps/sources.gypi', 'fs/sources.gypi', 'objects/sources.gypi', 'util/sources.gypi', diff --git a/src/xenia/kernel/xam_msg.cc b/src/xenia/kernel/xam_msg.cc index 72f2b2eca..f15efcaa3 100644 --- a/src/xenia/kernel/xam_msg.cc +++ b/src/xenia/kernel/xam_msg.cc @@ -34,43 +34,9 @@ SHIM_CALL XMsgInProcessCall_shim( "XMsgInProcessCall(%.8X, %.8X, %.8X, %.8X)", app, message, arg1, arg2); - bool handled = false; - - // TODO(benvanik): build XMsg pump? async/sync/etc - if (app == 0xFA) { - // XMP = music - // http://freestyledash.googlecode.com/svn-history/r1/trunk/Freestyle/Scenes/Media/Music/ScnMusic.cpp - if (message == 0x00070009) { - uint32_t a = SHIM_MEM_32(arg1 + 0); // 0x00000002 - uint32_t b = SHIM_MEM_32(arg1 + 4); // out ptr to 4b - expect 0 - XELOGD("XMPGetStatusEx(%.8X, %.8X)", a, b); - assert_zero(arg2); - assert_true(a == 2); - SHIM_SET_MEM_32(b, 0); - handled = true; - } else if (message == 0x0007001A) { - // dcz - // arg1 = ? - // arg2 = 0 - } else if (message == 0x0007001B) { - // Some stupid games will hammer this on a thread - induce a delay - // here to keep from starving real threads. - Sleep(1); - uint32_t a = SHIM_MEM_32(arg1 + 0); // 0x00000002 - uint32_t b = SHIM_MEM_32(arg1 + 4); // out ptr to 4b - expect 0 - XELOGD("XMPGetStatus(%.8X, %.8X)", a, b); - assert_zero(arg2); - assert_true(a == 2); - SHIM_SET_MEM_32(b, 0); - handled = true; - } - } - - if (!handled) { - XELOGE("Unimplemented XMsgInProcessCall message!"); - } - - SHIM_SET_RETURN_32(handled ? X_ERROR_SUCCESS : X_ERROR_NOT_FOUND); + auto result = state->app_manager()->DispatchMessageSync( + app, message, arg1, arg2); + SHIM_SET_RETURN_32(result); } @@ -86,31 +52,11 @@ SHIM_CALL XMsgStartIORequest_shim( "XMsgStartIORequest(%.8X, %.8X, %.8X, %.8X, %d)", app, message, overlapped_ptr, buffer, buffer_length); - bool handled = false; - assert_zero(overlapped_ptr); - // TODO(benvanik): build XMsg pump? async/sync/etc - if (app == 0xFA) { - // XMP = music - // http://freestyledash.googlecode.com/svn-history/r1/trunk/Freestyle/Scenes/Media/Music/ScnMusic.cpp - if (message == 0x00070009) { - assert(buffer_length == 8); - uint32_t a = SHIM_MEM_32(buffer + 0); // 0x00000002 - uint32_t b = SHIM_MEM_32(buffer + 4); // out ptr to 4b - expect 0 - XELOGD("XMPGetStatusEx(%.8X, %.8X)", a, b); - assert_true(a == 2); - SHIM_SET_MEM_32(b, 0); - Sleep(1); - handled = true; - } - } - - if (!handled) { - XELOGE("Unimplemented XMsgStartIORequest message!"); - } - - SHIM_SET_RETURN_32(handled ? X_ERROR_SUCCESS : X_ERROR_NOT_FOUND); + auto result = state->app_manager()->DispatchMessageAsync( + app, message, buffer, buffer_length); + SHIM_SET_RETURN_32(result); } From 0a9d936f1ea5c41b564a5eb1c5d56ea9ff781b5c Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 3 Aug 2014 21:26:10 -0700 Subject: [PATCH 048/388] Better faking of the user profile. --- src/xenia/kernel/kernel_state.cc | 35 ++++ src/xenia/kernel/kernel_state.h | 6 + src/xenia/kernel/objects/xnotify_listener.cc | 4 +- src/xenia/kernel/sources.gypi | 2 + src/xenia/kernel/user_profile.cc | 98 ++++++++++ src/xenia/kernel/user_profile.h | 189 +++++++++++++++++++ src/xenia/kernel/xam_user.cc | 105 ++++++++--- src/xenia/xbox.h | 21 ++- 8 files changed, 419 insertions(+), 41 deletions(-) create mode 100644 src/xenia/kernel/user_profile.cc create mode 100644 src/xenia/kernel/user_profile.h diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index f2d3b676d..b806253b3 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,7 @@ KernelState::KernelState(Emulator* emulator) : dispatcher_ = new Dispatcher(this); app_manager_ = std::make_unique(); + user_profile_ = std::make_unique(); object_table_ = new ObjectTable(); object_mutex_ = xe_mutex_alloc(10000); @@ -171,3 +173,36 @@ void KernelState::BroadcastNotification(XNotificationID id, uint32_t data) { } xe_mutex_unlock(object_mutex_); } + +void KernelState::CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result, uint32_t length) { + auto ptr = memory()->membase() + overlapped_ptr; + XOverlappedSetResult(ptr, result); + XOverlappedSetLength(ptr, length); + XOverlappedSetExtendedError(ptr, result); + X_HANDLE event_handle = XOverlappedGetEvent(ptr); + if (event_handle) { + XEvent* ev = nullptr; + if (XSUCCEEDED(object_table()->GetObject( + event_handle, reinterpret_cast(&ev)))) { + ev->Set(0, false); + ev->Release(); + } + } + if (XOverlappedGetCompletionRoutine(ptr)) { + assert_always(); + X_HANDLE thread_handle = XOverlappedGetContext(ptr); + XThread* thread = nullptr; + if (XSUCCEEDED(object_table()->GetObject( + thread_handle, reinterpret_cast(&thread)))) { + // TODO(benvanik): queue APC on the thread that requested the overlapped operation. + thread->Release(); + } + } +} + +void KernelState::CompleteOverlappedImmediate(uint32_t overlapped_ptr, X_RESULT result, uint32_t length) { + auto ptr = memory()->membase() + overlapped_ptr; + XOverlappedSetContext(ptr, + XThread::GetCurrentThreadHandle()); + CompleteOverlapped(overlapped_ptr, result, length); +} diff --git a/src/xenia/kernel/kernel_state.h b/src/xenia/kernel/kernel_state.h index 4a7884724..77173a8f2 100644 --- a/src/xenia/kernel/kernel_state.h +++ b/src/xenia/kernel/kernel_state.h @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -51,6 +52,7 @@ public: Dispatcher* dispatcher() const { return dispatcher_; } XAppManager* app_manager() const { return app_manager_.get(); } + UserProfile* user_profile() const { return user_profile_.get(); } ObjectTable* object_table() const { return object_table_; } @@ -66,6 +68,9 @@ public: void UnregisterNotifyListener(XNotifyListener* listener); void BroadcastNotification(XNotificationID id, uint32_t data); + void CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result, uint32_t length = 0); + void CompleteOverlappedImmediate(uint32_t overlapped_ptr, X_RESULT result, uint32_t length = 0); + private: Emulator* emulator_; Memory* memory_; @@ -75,6 +80,7 @@ private: Dispatcher* dispatcher_; std::unique_ptr app_manager_; + std::unique_ptr user_profile_; ObjectTable* object_table_; xe_mutex_t* object_mutex_; diff --git a/src/xenia/kernel/objects/xnotify_listener.cc b/src/xenia/kernel/objects/xnotify_listener.cc index 2f874c988..e205f6b6d 100644 --- a/src/xenia/kernel/objects/xnotify_listener.cc +++ b/src/xenia/kernel/objects/xnotify_listener.cc @@ -44,13 +44,13 @@ void XNotifyListener::EnqueueNotification(XNotificationID id, uint32_t data) { } xe_mutex_lock(lock_); - auto existing = notifications_.find(id); - if (existing != notifications_.end()) { + if (notifications_.count(id)) { // Already exists. Overwrite. notifications_[id] = data; } else { // New. notification_count_++; + notifications_.insert({ id, data }); } SetEvent(wait_handle_); xe_mutex_unlock(lock_); diff --git a/src/xenia/kernel/sources.gypi b/src/xenia/kernel/sources.gypi index 2c393a0ab..e96dbee36 100644 --- a/src/xenia/kernel/sources.gypi +++ b/src/xenia/kernel/sources.gypi @@ -15,6 +15,8 @@ 'native_list.h', 'object_table.cc', 'object_table.h', + 'user_profile.cc', + 'user_profile.h', 'xam_content.cc', 'xam_content.h', 'xam_info.cc', diff --git a/src/xenia/kernel/user_profile.cc b/src/xenia/kernel/user_profile.cc new file mode 100644 index 000000000..a401b8185 --- /dev/null +++ b/src/xenia/kernel/user_profile.cc @@ -0,0 +1,98 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + + +namespace xe { +namespace kernel { + + +UserProfile::UserProfile() { + xuid_ = 0xBABEBABEBABEBABE; + name_ = "User"; + + // http://cs.rin.ru/forum/viewtopic.php?f=38&t=60668&hilit=gfwl+live&start=195 + // XPROFILE_GAMER_YAXIS_INVERSION + AddSetting(std::make_unique(0x10040002, 0)); + // XPROFILE_OPTION_CONTROLLER_VIBRATION + AddSetting(std::make_unique(0x10040003, 3)); + // XPROFILE_GAMERCARD_ZONE + AddSetting(std::make_unique(0x10040004, 0)); + // XPROFILE_GAMERCARD_REGION + AddSetting(std::make_unique(0x10040005, 0)); + // XPROFILE_GAMERCARD_CRED + AddSetting(std::make_unique(0x10040006, 0xFA)); + // XPROFILE_GAMERCARD_REP + AddSetting(std::make_unique(0x5004000B, 0.0f)); + // XPROFILE_OPTION_VOICE_MUTED + AddSetting(std::make_unique(0x1004000C, 0)); + // XPROFILE_OPTION_VOICE_THRU_SPEAKERS + AddSetting(std::make_unique(0x1004000D, 0)); + // XPROFILE_OPTION_VOICE_VOLUME + AddSetting(std::make_unique(0x1004000E, 0x64)); + // XPROFILE_GAMERCARD_MOTTO + AddSetting(std::make_unique(0x402C0011, L"")); + // XPROFILE_GAMERCARD_TITLES_PLAYED + AddSetting(std::make_unique(0x10040012, 1)); + // XPROFILE_GAMERCARD_ACHIEVEMENTS_EARNED + AddSetting(std::make_unique(0x10040013, 0)); + // XPROFILE_GAMER_DIFFICULTY + AddSetting(std::make_unique(0x10040015, 0)); + // XPROFILE_GAMER_ACTION_AUTO_AIM + AddSetting(std::make_unique(0x10040022, 1)); + // XPROFILE_GAMER_ACTION_AUTO_CENTER + AddSetting(std::make_unique(0x10040023, 0)); + // XPROFILE_GAMER_ACTION_MOVEMENT_CONTROL + AddSetting(std::make_unique(0x10040024, 0)); + // XPROFILE_GAMER_RACE_TRANSMISSION + AddSetting(std::make_unique(0x10040026, 0)); + // XPROFILE_GAMER_RACE_CAMERA_LOCATION + AddSetting(std::make_unique(0x10040027, 0)); + // XPROFILE_GAMER_RACE_BRAKE_CONTROL + AddSetting(std::make_unique(0x10040028, 0)); + // XPROFILE_GAMER_RACE_ACCELERATOR_CONTROL + AddSetting(std::make_unique(0x10040029, 0)); + // XPROFILE_GAMERCARD_TITLE_CRED_EARNED + AddSetting(std::make_unique(0x10040038, 0)); + // XPROFILE_GAMERCARD_TITLE_ACHIEVEMENTS_EARNED + AddSetting(std::make_unique(0x10040039, 0)); + + // If we set this, games will try to get it. + // XPROFILE_GAMERCARD_PICTURE_KEY + // AddSetting(WStringSetting(0x4064000F, L"")); + + std::vector zeros; + zeros.resize(1000); + // XPROFILE_TITLE_SPECIFIC1 + AddSetting(std::make_unique(0x63E83FFF, zeros)); + // XPROFILE_TITLE_SPECIFIC2 + AddSetting(std::make_unique(0x63E83FFE, zeros)); + // XPROFILE_TITLE_SPECIFIC3 + AddSetting(std::make_unique(0x63E83FFD, zeros)); +} + + +void UserProfile::AddSetting(std::unique_ptr setting) { + settings_.insert({ setting->setting_id, setting.get() }); + setting_list_.push_back(std::move(setting)); +} + + +UserProfile::Setting* UserProfile::GetSetting(uint32_t setting_id) { + const auto& it = settings_.find(setting_id); + if (it == settings_.end()) { + return nullptr; + } + return it->second; +} + + +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/user_profile.h b/src/xenia/kernel/user_profile.h new file mode 100644 index 000000000..183bfd84d --- /dev/null +++ b/src/xenia/kernel/user_profile.h @@ -0,0 +1,189 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_KERNEL_XBOXKRNL_USER_PROFILE_H_ +#define XENIA_KERNEL_XBOXKRNL_USER_PROFILE_H_ + +#include +#include +#include +#include + +#include +#include + +#include + + +namespace xe { +namespace kernel { + + +class UserProfile { +public: + struct Setting { + enum class Type { + UNKNOWN = 0, + INT32 = 1, + INT64 = 2, + DOUBLE = 3, + WSTRING = 4, + FLOAT = 5, + BINARY = 6, + DATETIME = 7, + INVALID = 0xFF, + }; + union Key { + struct { + uint32_t id : 14; + uint32_t unk : 2; + uint32_t size : 12; + uint32_t type : 4; + }; + uint32_t value; + }; + uint32_t setting_id; + Type type; + size_t size; + Setting(uint32_t setting_id, Type type, size_t size) + : setting_id(setting_id), type(type), size(size) {} + virtual size_t extra_size() const { return 0; } + virtual size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) { + poly::store_and_swap(user_data + kTypeOffset, static_cast(type)); + return buffer_offset; + } + bool is_title_specific() const { + return (setting_id & 0x3F00) == 0x3F00; + } + protected: + const size_t kTypeOffset = 0; + const size_t kValueOffset = 8; + const size_t kPointerOffset = 12; + }; + struct Int32Setting : public Setting { + Int32Setting(uint32_t setting_id, int32_t value) + : Setting(setting_id, Type::INT32, 4), value(value) {} + int32_t value; + size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) override { + buffer_offset = Setting::Append(user_data, buffer, buffer_offset); + poly::store_and_swap(user_data + kValueOffset, value); + return buffer_offset; + } + }; + struct Int64Setting : public Setting { + Int64Setting(uint32_t setting_id, int64_t value) + : Setting(setting_id, Type::INT64, 8), value(value) {} + int64_t value; + size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) override { + buffer_offset = Setting::Append(user_data, buffer, buffer_offset); + poly::store_and_swap(user_data + kValueOffset, value); + return buffer_offset; + } + }; + struct DoubleSetting : public Setting { + DoubleSetting(uint32_t setting_id, double value) + : Setting(setting_id, Type::DOUBLE, 8), value(value) {} + double value; + size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) override { + buffer_offset = Setting::Append(user_data, buffer, buffer_offset); + poly::store_and_swap(user_data + kValueOffset, value); + return buffer_offset; + } + }; + struct UnicodeSetting : public Setting { + UnicodeSetting(uint32_t setting_id, const std::wstring& value) + : Setting(setting_id, Type::WSTRING, 8), value(value) {} + std::wstring value; + size_t extra_size() const override { + return value.empty() ? 0 : 2 * (static_cast(value.size()) + 1); + } + size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) override { + buffer_offset = Setting::Append(user_data, buffer, buffer_offset); + int32_t length; + if (value.empty()) { + length = 0; + poly::store_and_swap(user_data + kValueOffset, 0); + poly::store_and_swap(user_data + kPointerOffset, 0); + } else { + length = 2 * (static_cast(value.size()) + 1); + poly::store_and_swap(user_data + kValueOffset, length); + poly::store_and_swap(user_data + kPointerOffset, + static_cast(buffer_offset)); + memcpy(buffer + buffer_offset, value.data(), length); + } + return buffer_offset + length; + } + }; + struct FloatSetting : public Setting { + FloatSetting(uint32_t setting_id, float value) + : Setting(setting_id, Type::FLOAT, 4), value(value) {} + float value; + size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) override { + buffer_offset = Setting::Append(user_data, buffer, buffer_offset); + poly::store_and_swap(user_data + kValueOffset, value); + return buffer_offset; + } + }; + struct BinarySetting : public Setting { + BinarySetting(uint32_t setting_id, const std::vector& value) + : Setting(setting_id, Type::BINARY, 8), value(value) {} + std::vector value; + size_t extra_size() const override { + return static_cast(value.size()); + } + size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) override { + buffer_offset = Setting::Append(user_data, buffer, buffer_offset); + int32_t length; + if (value.empty()) { + length = 0; + poly::store_and_swap(user_data + kValueOffset, 0); + poly::store_and_swap(user_data + kPointerOffset, 0); + } else { + length = static_cast(value.size()); + poly::store_and_swap(user_data + kValueOffset, length); + poly::store_and_swap(user_data + kPointerOffset, + static_cast(buffer_offset)); + memcpy(buffer + buffer_offset, value.data(), length); + } + return buffer_offset + length; + } + }; + struct DateTimeSetting : public Setting { + DateTimeSetting(uint32_t setting_id, int64_t value) + : Setting(setting_id, Type::DATETIME, 8), value(value) {} + int64_t value; + size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) override { + buffer_offset = Setting::Append(user_data, buffer, buffer_offset); + poly::store_and_swap(user_data + kValueOffset, value); + return buffer_offset; + } + }; + + UserProfile(); + + uint64_t xuid() const { return xuid_; } + std::string name() const { return name_; } + uint32_t signin_state() const { return 1; } + + void AddSetting(std::unique_ptr setting); + Setting* GetSetting(uint32_t setting_id); + +private: + uint64_t xuid_; + std::string name_; + std::vector> setting_list_; + std::unordered_map settings_; +}; + + +} // namespace kernel +} // namespace xe + + +#endif // XENIA_KERNEL_XBOXKRNL_USER_PROFILE_H_ diff --git a/src/xenia/kernel/xam_user.cc b/src/xenia/kernel/xam_user.cc index 560c41623..bf22088b8 100644 --- a/src/xenia/kernel/xam_user.cc +++ b/src/xenia/kernel/xam_user.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include @@ -37,8 +38,9 @@ SHIM_CALL XamUserGetXUID_shim( xuid_ptr); if (user_index == 0) { + const auto& user_profile = state->user_profile(); if (xuid_ptr) { - SHIM_SET_MEM_32(xuid_ptr, 0xBABEBABE); + SHIM_SET_MEM_64(xuid_ptr, user_profile->xuid()); } SHIM_SET_RETURN_32(0); } else { @@ -59,7 +61,8 @@ SHIM_CALL XamUserGetSigninState_shim( // This should keep games from asking us to sign in and also keep them // from initializing the network. if (user_index == 0) { - SHIM_SET_RETURN_64(1); + const auto& user_profile = state->user_profile(); + SHIM_SET_RETURN_64(user_profile->signin_state()); } else { SHIM_SET_RETURN_64(0); } @@ -77,13 +80,14 @@ SHIM_CALL XamUserGetSigninInfo_shim( user_index, flags, info_ptr); if (user_index == 0) { - SHIM_SET_MEM_32(info_ptr + 0, 0xBABEBABE); // XUID - SHIM_SET_MEM_32(info_ptr + 4, 1); // maybe zero? - SHIM_SET_MEM_32(info_ptr + 8, 1); // signin state, same as above - SHIM_SET_MEM_32(info_ptr + 12, 0); // ? + const auto& user_profile = state->user_profile(); + SHIM_SET_MEM_64(info_ptr + 0, user_profile->xuid()); + SHIM_SET_MEM_32(info_ptr + 8, 0); // maybe zero? + SHIM_SET_MEM_32(info_ptr + 12, user_profile->signin_state()); SHIM_SET_MEM_32(info_ptr + 16, 0); // ? - char* buffer = (char*)SHIM_MEM_ADDR(info_ptr + 20); - xestrncpya(buffer, 0x10, "User0", 5); + SHIM_SET_MEM_32(info_ptr + 20, 0); // ? + char* buffer = (char*)SHIM_MEM_ADDR(info_ptr + 24); + strcpy(buffer, user_profile->name().data()); SHIM_SET_RETURN_32(0); } else { SHIM_SET_RETURN_32(X_ERROR_NO_SUCH_USER); @@ -102,8 +106,9 @@ SHIM_CALL XamUserGetName_shim( user_index, buffer_ptr, buffer_len); if (user_index == 0) { + const auto& user_profile = state->user_profile(); char* buffer = (char*)SHIM_MEM_ADDR(buffer_ptr); - xestrncpya(buffer, buffer_len, "User0", 5); + strcpy(buffer, user_profile->name().data()); SHIM_SET_RETURN_32(0); } else { SHIM_SET_RETURN_32(X_ERROR_NO_SUCH_USER); @@ -136,42 +141,80 @@ SHIM_CALL XamUserReadProfileSettings_shim( // Title ID = 0 means us. // 0xfffe07d1 = profile? - // TODO(benvanik): implement overlapped support - assert_zero(overlapped_ptr); + if (user_index) { + // Only support user 0. + SHIM_SET_RETURN_32(X_ERROR_NOT_FOUND); + return; + } + const auto& user_profile = state->user_profile(); // First call asks for size (fill buffer_size_ptr). // Second call asks for buffer contents with that size. + // http://cs.rin.ru/forum/viewtopic.php?f=38&t=60668&hilit=gfwl+live&start=195 // Result buffer is: // uint32_t setting_count - // [repeated X_USER_PROFILE_SETTING structs] + // struct { + // uint32_t source; + // (4b pad) + // uint32_t user_index; + // (4b pad) + // uint32_t setting_id; + // (4b pad) + // + // } settings[setting_count] + const size_t kSettingSize = 4 + 4 + 4 + 4 + 4 + 4 + 16; - typedef union { - struct { - uint32_t id : 14; - uint32_t unk : 2; - uint32_t size : 12; - uint32_t type : 4; - }; - uint32_t value; - } x_profile_setting_t; - - // Compute sizes. - uint32_t size_needed = 4; - for (uint32_t n = 0; n < setting_count; n++) { - x_profile_setting_t setting; - setting.value = SHIM_MEM_32(setting_ids_ptr + n * 4); - size_needed += setting.size; + // Compute required size. + uint32_t size_needed = 4 + 4 + setting_count * kSettingSize; + for (uint32_t n = 0; n < setting_count; ++n) { + uint32_t setting_id = SHIM_MEM_32(setting_ids_ptr + n * 4); + auto setting = user_profile->GetSetting(setting_id); + if (setting) { + auto extra_size = static_cast(setting->extra_size());; + size_needed += extra_size; + } } SHIM_SET_MEM_32(buffer_size_ptr, size_needed); if (buffer_size < size_needed) { + if (overlapped_ptr) { + state->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_INSUFFICIENT_BUFFER); + } SHIM_SET_RETURN_32(X_ERROR_INSUFFICIENT_BUFFER); return; } - // TODO(benvanik): read profile data. - // For now, just return signed out. - SHIM_SET_RETURN_32(X_ERROR_NOT_FOUND); + SHIM_SET_MEM_32(buffer_ptr + 0, setting_count); + SHIM_SET_MEM_32(buffer_ptr + 4, buffer_ptr + 8); + + size_t buffer_offset = 4 + setting_count * kSettingSize; + size_t user_data_ptr = buffer_ptr + 8; + for (uint32_t n = 0; n < setting_count; ++n) { + uint32_t setting_id = SHIM_MEM_32(setting_ids_ptr + n * 4); + auto setting = user_profile->GetSetting(setting_id); + if (setting) { + SHIM_SET_MEM_32(user_data_ptr + 0, setting->is_title_specific() ? 2 : 1); + } else { + SHIM_SET_MEM_32(user_data_ptr + 0, 0); + } + SHIM_SET_MEM_32(user_data_ptr + 8, user_index); + SHIM_SET_MEM_32(user_data_ptr + 16, setting_id); + if (setting) { + buffer_offset = setting->Append(SHIM_MEM_ADDR(user_data_ptr + 24), + SHIM_MEM_ADDR(buffer_ptr), + buffer_offset); + } else { + memset(SHIM_MEM_ADDR(user_data_ptr + 24), 0, 16); + } + user_data_ptr += kSettingSize; + } + + if (overlapped_ptr) { + state->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS); + SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); + } else { + SHIM_SET_RETURN_32(X_ERROR_SUCCESS); + } } diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index 9c47ced22..e597e63bb 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -60,11 +60,12 @@ typedef uint32_t X_STATUS; // Adding as needed. typedef uint32_t X_RESULT; #define X_FACILITY_WIN32 7 -#define X_HRESULT_FROM_WIN32(x) ((X_RESULT)(x) <= 0 ? ((X_RESULT)(x)) : ((X_RESULT) (((x) & 0x0000FFFF) | (X_FACILITY_WIN32 << 16) | 0x80000000))) +#define X_HRESULT_FROM_WIN32(x) x //((X_RESULT)(x) <= 0 ? ((X_RESULT)(x)) : ((X_RESULT) (((x) & 0x0000FFFF) | (X_FACILITY_WIN32 << 16) | 0x80000000))) #define X_ERROR_SUCCESS X_HRESULT_FROM_WIN32(0x00000000L) #define X_ERROR_ACCESS_DENIED X_HRESULT_FROM_WIN32(0x00000005L) #define X_ERROR_INVALID_HANDLE X_HRESULT_FROM_WIN32(0x00000006L) #define X_ERROR_NO_MORE_FILES X_HRESULT_FROM_WIN32(0x00000018L) +#define X_ERROR_IO_PENDING X_HRESULT_FROM_WIN32(0x000003E5L) #define X_ERROR_INSUFFICIENT_BUFFER X_HRESULT_FROM_WIN32(0x0000007AL) #define X_ERROR_BAD_ARGUMENTS X_HRESULT_FROM_WIN32(0x000000A0L) #define X_ERROR_BUSY X_HRESULT_FROM_WIN32(0x000000AAL) @@ -194,31 +195,35 @@ typedef enum _X_FILE_INFORMATION_CLASS { inline void XOverlappedSetResult(void* ptr, uint32_t value) { auto p = reinterpret_cast(ptr); - p[0] = value; + poly::store_and_swap(&p[0], value); } inline void XOverlappedSetLength(void* ptr, uint32_t value) { auto p = reinterpret_cast(ptr); - p[1] = value; + poly::store_and_swap(&p[1], value); +} +inline uint32_t XOverlappedGetContext(void* ptr) { + auto p = reinterpret_cast(ptr); + return poly::load_and_swap(&p[2]); } inline void XOverlappedSetContext(void* ptr, uint32_t value) { auto p = reinterpret_cast(ptr); - p[2] = value; + poly::store_and_swap(&p[2], value); } inline void XOverlappedSetExtendedError(void* ptr, uint32_t value) { auto p = reinterpret_cast(ptr); - p[7] = value; + poly::store_and_swap(&p[7], value); } inline X_HANDLE XOverlappedGetEvent(void* ptr) { auto p = reinterpret_cast(ptr); - return p[4]; + return poly::load_and_swap(&p[4]); } inline uint32_t XOverlappedGetCompletionRoutine(void* ptr) { auto p = reinterpret_cast(ptr); - return p[5]; + return poly::load_and_swap(&p[5]); } inline uint32_t XOverlappedGetCompletionContext(void* ptr) { auto p = reinterpret_cast(ptr); - return p[6]; + return poly::load_and_swap(&p[6]); } class X_ANSI_STRING { From 35885f761c0a44ac222fd07d561b1a354ed4aa24 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 3 Aug 2014 22:25:38 -0700 Subject: [PATCH 049/388] Misc fixes (overlapped IO, etc). --- src/xenia/kernel/xam_content.cc | 9 ++++++--- src/xenia/kernel/xam_info.cc | 5 +++-- src/xenia/kernel/xam_msg.cc | 18 ++++++++++++++++-- src/xenia/kernel/xam_user.cc | 4 ++++ src/xenia/kernel/xboxkrnl_threading.cc | 10 +++++----- 5 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/xenia/kernel/xam_content.cc b/src/xenia/kernel/xam_content.cc index 4b045c1dd..e5fd8913c 100644 --- a/src/xenia/kernel/xam_content.cc +++ b/src/xenia/kernel/xam_content.cc @@ -33,14 +33,17 @@ SHIM_CALL XamContentGetLicenseMask_shim( mask_ptr, overlapped_ptr); - assert_zero(overlapped_ptr); - // Arcade games seem to call this and check the result mask for random bits. // If we fail, the games seem to use a hardcoded mask, which is likely trial. // To be clever, let's just try setting all the bits. SHIM_SET_MEM_32(mask_ptr, 0xFFFFFFFF); - SHIM_SET_RETURN_32(X_ERROR_SUCCESS); + if (overlapped_ptr) { + state->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS); + SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); + } else { + SHIM_SET_RETURN_32(X_ERROR_SUCCESS); + } } diff --git a/src/xenia/kernel/xam_info.cc b/src/xenia/kernel/xam_info.cc index 3a05acab9..debb8b62b 100644 --- a/src/xenia/kernel/xam_info.cc +++ b/src/xenia/kernel/xam_info.cc @@ -125,10 +125,11 @@ SHIM_CALL XamEnumerate_shim( } if (item_count_ptr) { + assert_zero(overlapped_ptr); SHIM_SET_MEM_32(item_count_ptr, 0); } else if (overlapped_ptr) { - // TODO(benvanik): overlapped IO. - assert_zero(overlapped_ptr); + assert_zero(item_count_ptr); + state->CompleteOverlappedImmediate(overlapped_ptr, 0, 0); } else { assert_always(); } diff --git a/src/xenia/kernel/xam_msg.cc b/src/xenia/kernel/xam_msg.cc index f15efcaa3..fa24c6e05 100644 --- a/src/xenia/kernel/xam_msg.cc +++ b/src/xenia/kernel/xam_msg.cc @@ -11,6 +11,7 @@ #include #include +#include #include @@ -36,6 +37,9 @@ SHIM_CALL XMsgInProcessCall_shim( auto result = state->app_manager()->DispatchMessageSync( app, message, arg1, arg2); + if (result == X_ERROR_NOT_FOUND) { + XELOGE("XMsgStartIORequest: app not found"); + } SHIM_SET_RETURN_32(result); } @@ -56,6 +60,9 @@ SHIM_CALL XMsgStartIORequest_shim( auto result = state->app_manager()->DispatchMessageAsync( app, message, buffer, buffer_length); + if (result == X_ERROR_NOT_FOUND) { + XELOGE("XMsgStartIORequest: app not found"); + } SHIM_SET_RETURN_32(result); } @@ -69,8 +76,15 @@ SHIM_CALL XMsgCancelIORequest_shim( "XMsgCancelIORequest(%.8X, %d)", overlapped_ptr, wait); - // ? - XELOGW("XMsgCancelIORequest NOT IMPLEMENTED (wait?)"); + X_HANDLE event_handle = XOverlappedGetEvent(SHIM_MEM_ADDR(overlapped_ptr)); + if (event_handle && wait) { + XEvent* ev = nullptr; + if (XSUCCEEDED(state->object_table()->GetObject( + event_handle, reinterpret_cast(&ev)))) { + ev->Wait(0, 0, true, nullptr); + ev->Release(); + } + } SHIM_SET_RETURN_32(0); } diff --git a/src/xenia/kernel/xam_user.cc b/src/xenia/kernel/xam_user.cc index bf22088b8..7f9b7ce9b 100644 --- a/src/xenia/kernel/xam_user.cc +++ b/src/xenia/kernel/xam_user.cc @@ -141,6 +141,10 @@ SHIM_CALL XamUserReadProfileSettings_shim( // Title ID = 0 means us. // 0xfffe07d1 = profile? + if (user_index == 255) { + user_index = 0; + } + if (user_index) { // Only support user 0. SHIM_SET_RETURN_32(X_ERROR_NOT_FOUND); diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index 6aaa8b78c..17991b47a 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -388,8 +388,8 @@ uint64_t xeKeQueryPerformanceFrequency() { SHIM_CALL KeQueryPerformanceFrequency_shim( PPCContext* ppc_state, KernelState* state) { - XELOGD( - "KeQueryPerformanceFrequency()"); + // XELOGD( + // "KeQueryPerformanceFrequency()"); uint64_t result = xeKeQueryPerformanceFrequency(); SHIM_SET_RETURN_64(result); @@ -410,9 +410,9 @@ SHIM_CALL KeDelayExecutionThread_shim( uint32_t interval_ptr = SHIM_GET_ARG_32(2); uint64_t interval = SHIM_MEM_64(interval_ptr); - XELOGD( - "KeDelayExecutionThread(%.8X, %d, %.8X(%.16llX)", - processor_mode, alertable, interval_ptr, interval); + // XELOGD( + // "KeDelayExecutionThread(%.8X, %d, %.8X(%.16llX)", + // processor_mode, alertable, interval_ptr, interval); X_STATUS result = xeKeDelayExecutionThread( processor_mode, alertable, interval); From a98b9458b6707be85b83d95fdff5e7ade646fa63 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 4 Aug 2014 14:56:34 -0700 Subject: [PATCH 050/388] Adding XamVoice stubs. --- src/xenia/kernel/sources.gypi | 2 + src/xenia/kernel/xam_module.cc | 1 + src/xenia/kernel/xam_private.h | 1 + src/xenia/kernel/xam_voice.cc | 78 ++++++++++++++++++++++++++++++++++ src/xenia/kernel/xam_voice.h | 29 +++++++++++++ 5 files changed, 111 insertions(+) create mode 100644 src/xenia/kernel/xam_voice.cc create mode 100644 src/xenia/kernel/xam_voice.h diff --git a/src/xenia/kernel/sources.gypi b/src/xenia/kernel/sources.gypi index e96dbee36..2a7cb929b 100644 --- a/src/xenia/kernel/sources.gypi +++ b/src/xenia/kernel/sources.gypi @@ -38,6 +38,8 @@ 'xam_user.h', 'xam_video.cc', 'xam_video.h', + 'xam_voice.cc', + 'xam_voice.h', 'xboxkrnl_audio.cc', 'xboxkrnl_audio.h', 'xboxkrnl_debug.cc', diff --git a/src/xenia/kernel/xam_module.cc b/src/xenia/kernel/xam_module.cc index 494863fd3..d8f85547e 100644 --- a/src/xenia/kernel/xam_module.cc +++ b/src/xenia/kernel/xam_module.cc @@ -39,6 +39,7 @@ XamModule::XamModule(Emulator* emulator, KernelState* kernel_state) : RegisterNotifyExports(export_resolver_, kernel_state); RegisterUserExports(export_resolver_, kernel_state); RegisterVideoExports(export_resolver_, kernel_state); + RegisterVoiceExports(export_resolver_, kernel_state); } XamModule::~XamModule() { diff --git a/src/xenia/kernel/xam_private.h b/src/xenia/kernel/xam_private.h index d1cc95ce7..715fc44e6 100644 --- a/src/xenia/kernel/xam_private.h +++ b/src/xenia/kernel/xam_private.h @@ -31,6 +31,7 @@ void RegisterNetExports(ExportResolver* export_resolver, KernelState* state); void RegisterNotifyExports(ExportResolver* export_resolver, KernelState* state); void RegisterUserExports(ExportResolver* export_resolver, KernelState* state); void RegisterVideoExports(ExportResolver* export_resolver, KernelState* state); +void RegisterVoiceExports(ExportResolver* export_resolver, KernelState* state); } // namespace xam } // namespace kernel diff --git a/src/xenia/kernel/xam_voice.cc b/src/xenia/kernel/xam_voice.cc new file mode 100644 index 000000000..068b45f84 --- /dev/null +++ b/src/xenia/kernel/xam_voice.cc @@ -0,0 +1,78 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2013 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include +#include +#include +#include + + +using namespace xe; +using namespace xe::hid; +using namespace xe::kernel; +using namespace xe::kernel::xam; + + +namespace xe { +namespace kernel { + + +SHIM_CALL XamVoiceCreate_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t unk1 = SHIM_GET_ARG_32(0); // 0 + uint32_t unk2 = SHIM_GET_ARG_32(1); // 0xF + uint32_t out_voice_ptr = SHIM_GET_ARG_32(2); + + XELOGD( + "XamVoiceCreate(%.8X, %.8X, %.8X)", + unk1, unk2, out_voice_ptr); + + // Null out the ptr. + SHIM_SET_MEM_32(out_voice_ptr, 0); + + SHIM_SET_RETURN_32(X_ERROR_ACCESS_DENIED); +} + + +SHIM_CALL XamVoiceClose_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t voice_ptr = SHIM_GET_ARG_32(0); + + XELOGD( + "XamVoiceClose(%.8X)", + voice_ptr); + + SHIM_SET_RETURN_32(0); +} + + +SHIM_CALL XamVoiceHeadsetPresent_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t voice_ptr = SHIM_GET_ARG_32(0); + + XELOGD( + "XamVoiceHeadsetPresent(%.8X)", + voice_ptr); + + SHIM_SET_RETURN_32(0); +} + + +} // namespace kernel +} // namespace xe + + +void xe::kernel::xam::RegisterVoiceExports( + ExportResolver* export_resolver, KernelState* state) { + SHIM_SET_MAPPING("xam.xex", XamVoiceCreate, state); + SHIM_SET_MAPPING("xam.xex", XamVoiceClose, state); + SHIM_SET_MAPPING("xam.xex", XamVoiceHeadsetPresent, state); +} diff --git a/src/xenia/kernel/xam_voice.h b/src/xenia/kernel/xam_voice.h new file mode 100644 index 000000000..2ab9e527e --- /dev/null +++ b/src/xenia/kernel/xam_voice.h @@ -0,0 +1,29 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_KERNEL_XAM_VOICE_H_ +#define XENIA_KERNEL_XAM_VOICE_H_ + +#include +#include + +#include + + +namespace xe { +namespace kernel { + + + + +} // namespace kernel +} // namespace xe + + +#endif // XENIA_KERNEL_XAM_VOICE_H_ From fd9585851600e59d9bc653cfd7c8b61d659b6ac6 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 4 Aug 2014 15:01:39 -0700 Subject: [PATCH 051/388] XamUserCheckPrivilege --- src/xenia/kernel/xam_user.cc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/xenia/kernel/xam_user.cc b/src/xenia/kernel/xam_user.cc index 7f9b7ce9b..268b912fb 100644 --- a/src/xenia/kernel/xam_user.cc +++ b/src/xenia/kernel/xam_user.cc @@ -222,6 +222,23 @@ SHIM_CALL XamUserReadProfileSettings_shim( } +SHIM_CALL XamUserCheckPrivilege_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t user_index = SHIM_GET_ARG_32(0); + uint32_t mask = SHIM_GET_ARG_32(1); + uint32_t out_value_ptr = SHIM_GET_ARG_32(2); + + XELOGD( + "XamUserCheckPrivilege(%d, %.8X, %.8X)", + user_index, mask, out_value_ptr); + + // If we deny everything, games should hopefully not try to do stuff. + SHIM_SET_MEM_32(out_value_ptr, 0); + + SHIM_SET_RETURN_32(X_ERROR_SUCCESS); +} + + SHIM_CALL XamShowSigninUI_shim( PPCContext* ppc_state, KernelState* state) { uint32_t unk_0 = SHIM_GET_ARG_32(0); @@ -274,6 +291,7 @@ void xe::kernel::xam::RegisterUserExports( SHIM_SET_MAPPING("xam.xex", XamUserGetSigninInfo, state); SHIM_SET_MAPPING("xam.xex", XamUserGetName, state); SHIM_SET_MAPPING("xam.xex", XamUserReadProfileSettings, state); + SHIM_SET_MAPPING("xam.xex", XamUserCheckPrivilege, state); SHIM_SET_MAPPING("xam.xex", XamShowSigninUI, state); SHIM_SET_MAPPING("xam.xex", XamUserCreateAchievementEnumerator, state); } From 296bb5c87a2b7e1d40654740b01977136e4857e6 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 4 Aug 2014 15:39:42 -0700 Subject: [PATCH 052/388] Dummy IRQL stuff to silence warnings. --- src/xenia/cpu/processor.cc | 11 +++++ src/xenia/cpu/processor.h | 12 ++++++ src/xenia/kernel/xboxkrnl_threading.cc | 57 ++++++++++++++++++-------- 3 files changed, 63 insertions(+), 17 deletions(-) diff --git a/src/xenia/cpu/processor.cc b/src/xenia/cpu/processor.cc index c5cea7411..21512acbb 100644 --- a/src/xenia/cpu/processor.cc +++ b/src/xenia/cpu/processor.cc @@ -135,6 +135,17 @@ uint64_t Processor::Execute( return context->r[3]; } +Irql Processor::RaiseIrql(Irql new_value) { + return static_cast( + poly::atomic_exchange(static_cast(new_value), + reinterpret_cast(&irql_))); +} + +void Processor::LowerIrql(Irql old_value) { + poly::atomic_exchange(static_cast(old_value), + reinterpret_cast(&irql_)); +} + uint64_t Processor::ExecuteInterrupt( uint32_t cpu, uint64_t address, uint64_t args[], size_t arg_count) { SCOPE_profile_cpu_f("cpu"); diff --git a/src/xenia/cpu/processor.h b/src/xenia/cpu/processor.h index f13587ef5..d5e79b0f8 100644 --- a/src/xenia/cpu/processor.h +++ b/src/xenia/cpu/processor.h @@ -27,6 +27,14 @@ namespace xe { namespace cpu { +enum class Irql : uint32_t { + PASSIVE = 0, + APC = 1, + DISPATCH = 2, + DPC = 3, +}; + + class Processor { public: Processor(Emulator* emulator); @@ -44,6 +52,9 @@ public: XenonThreadState* thread_state, uint64_t address, uint64_t args[], size_t arg_count); + Irql RaiseIrql(Irql new_value); + void LowerIrql(Irql old_value); + uint64_t ExecuteInterrupt( uint32_t cpu, uint64_t address, uint64_t args[], size_t arg_count); @@ -54,6 +65,7 @@ private: XenonRuntime* runtime_; Memory* memory_; + Irql irql_; xe_mutex_t* interrupt_thread_lock_; XenonThreadState* interrupt_thread_state_; uint64_t interrupt_thread_block_; diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index 17991b47a..0078dbfc7 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -1275,9 +1276,9 @@ SHIM_CALL KfAcquireSpinLock_shim( PPCContext* ppc_state, KernelState* state) { uint32_t lock_ptr = SHIM_GET_ARG_32(0); - XELOGD( - "KfAcquireSpinLock(%.8X)", - lock_ptr); + // XELOGD( + // "KfAcquireSpinLock(%.8X)", + // lock_ptr); auto lock = reinterpret_cast(SHIM_MEM_ADDR(lock_ptr)); uint32_t old_irql = xeKfAcquireSpinLock(lock); @@ -1301,10 +1302,10 @@ SHIM_CALL KfReleaseSpinLock_shim( uint32_t lock_ptr = SHIM_GET_ARG_32(0); uint32_t old_irql = SHIM_GET_ARG_32(1); - XELOGD( - "KfReleaseSpinLock(%.8X, %d)", - lock_ptr, - old_irql); + // XELOGD( + // "KfReleaseSpinLock(%.8X, %d)", + // lock_ptr, + // old_irql); xeKfReleaseSpinLock(reinterpret_cast(SHIM_MEM_ADDR(lock_ptr)), old_irql); @@ -1315,9 +1316,9 @@ SHIM_CALL KeAcquireSpinLockAtRaisedIrql_shim( PPCContext* ppc_state, KernelState* state) { uint32_t lock_ptr = SHIM_GET_ARG_32(0); - XELOGD( - "KeAcquireSpinLockAtRaisedIrql(%.8X)", - lock_ptr); + // XELOGD( + // "KeAcquireSpinLockAtRaisedIrql(%.8X)", + // lock_ptr); // Lock. auto lock = reinterpret_cast(SHIM_MEM_ADDR(lock_ptr)); @@ -1332,9 +1333,9 @@ SHIM_CALL KeReleaseSpinLockFromRaisedIrql_shim( PPCContext* ppc_state, KernelState* state) { uint32_t lock_ptr = SHIM_GET_ARG_32(0); - XELOGD( - "KeReleaseSpinLockFromRaisedIrql(%.8X)", - lock_ptr); + // XELOGD( + // "KeReleaseSpinLockFromRaisedIrql(%.8X)", + // lock_ptr); // Unlock. auto lock = reinterpret_cast(SHIM_MEM_ADDR(lock_ptr)); @@ -1349,8 +1350,8 @@ void xeKeEnterCriticalRegion() { SHIM_CALL KeEnterCriticalRegion_shim( PPCContext* ppc_state, KernelState* state) { - XELOGD( - "KeEnterCriticalRegion()"); + // XELOGD( + // "KeEnterCriticalRegion()"); xeKeEnterCriticalRegion(); } @@ -1362,12 +1363,31 @@ void xeKeLeaveCriticalRegion() { SHIM_CALL KeLeaveCriticalRegion_shim( PPCContext* ppc_state, KernelState* state) { - XELOGD( - "KeLeaveCriticalRegion()"); + // XELOGD( + // "KeLeaveCriticalRegion()"); xeKeLeaveCriticalRegion(); } +SHIM_CALL KeRaiseIrqlToDpcLevel_shim( + PPCContext* ppc_state, KernelState* state) { + // XELOGD( + // "KeRaiseIrqlToDpcLevel()"); + auto old_value = state->processor()->RaiseIrql(cpu::Irql::DPC); + SHIM_SET_RETURN_32(old_value); +} + + +SHIM_CALL KfLowerIrql_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t old_value = SHIM_GET_ARG_32(0); + // XELOGD( + // "KfLowerIrql(%d)", + // old_value); + state->processor()->LowerIrql(static_cast(old_value)); +} + + SHIM_CALL NtQueueApcThread_shim( PPCContext* ppc_state, KernelState* state) { uint32_t thread_handle = SHIM_GET_ARG_32(0); @@ -1673,6 +1693,9 @@ void xe::kernel::xboxkrnl::RegisterThreadingExports( SHIM_SET_MAPPING("xboxkrnl.exe", KeEnterCriticalRegion, state); SHIM_SET_MAPPING("xboxkrnl.exe", KeLeaveCriticalRegion, state); + SHIM_SET_MAPPING("xboxkrnl.exe", KeRaiseIrqlToDpcLevel, state); + SHIM_SET_MAPPING("xboxkrnl.exe", KfLowerIrql, state); + //SHIM_SET_MAPPING("xboxkrnl.exe", NtQueueApcThread, state); SHIM_SET_MAPPING("xboxkrnl.exe", KeInitializeApc, state); SHIM_SET_MAPPING("xboxkrnl.exe", KeInsertQueueApc, state); From e6275691cb8220051a902ee2f0346c8bdc4ab604 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 4 Aug 2014 15:46:52 -0700 Subject: [PATCH 053/388] KeEnableFpuExceptions stub. --- src/xenia/kernel/xboxkrnl_debug.cc | 26 ++++++++++++++++++++++++++ src/xenia/kernel/xboxkrnl_misc.cc | 27 +++++---------------------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/xenia/kernel/xboxkrnl_debug.cc b/src/xenia/kernel/xboxkrnl_debug.cc index 9db006604..e5ae66591 100644 --- a/src/xenia/kernel/xboxkrnl_debug.cc +++ b/src/xenia/kernel/xboxkrnl_debug.cc @@ -303,6 +303,30 @@ SHIM_CALL RtlRaiseException_shim( } +void xeKeBugCheckEx(uint32_t code, uint32_t param1, uint32_t param2, uint32_t param3, uint32_t param4) { + XELOGD("*** STOP: 0x%.8X (0x%.8X, 0x%.8X, 0x%.8X, 0x%.8X)", code, param1, param2, param3, param4); + fflush(stdout); + DebugBreak(); + assert_always(); +} + +SHIM_CALL KeBugCheck_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t code = SHIM_GET_ARG_32(0); + xeKeBugCheckEx(code, 0, 0, 0, 0); +} + +SHIM_CALL KeBugCheckEx_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t code = SHIM_GET_ARG_32(0); + uint32_t param1 = SHIM_GET_ARG_32(1); + uint32_t param2 = SHIM_GET_ARG_32(2); + uint32_t param3 = SHIM_GET_ARG_32(3); + uint32_t param4 = SHIM_GET_ARG_32(4); + xeKeBugCheckEx(code, param1, param2, param3, param4); +} + + } // namespace kernel } // namespace xe @@ -312,4 +336,6 @@ void xe::kernel::xboxkrnl::RegisterDebugExports( SHIM_SET_MAPPING("xboxkrnl.exe", DbgPrint, state); SHIM_SET_MAPPING("xboxkrnl.exe", DbgBreakPoint, state); SHIM_SET_MAPPING("xboxkrnl.exe", RtlRaiseException, state); + SHIM_SET_MAPPING("xboxkrnl.exe", KeBugCheck, state); + SHIM_SET_MAPPING("xboxkrnl.exe", KeBugCheckEx, state); } diff --git a/src/xenia/kernel/xboxkrnl_misc.cc b/src/xenia/kernel/xboxkrnl_misc.cc index 1354d4806..f08664eab 100644 --- a/src/xenia/kernel/xboxkrnl_misc.cc +++ b/src/xenia/kernel/xboxkrnl_misc.cc @@ -24,27 +24,11 @@ namespace xe { namespace kernel { -void xeKeBugCheckEx(uint32_t code, uint32_t param1, uint32_t param2, uint32_t param3, uint32_t param4) { - XELOGD("*** STOP: 0x%.8X (0x%.8X, 0x%.8X, 0x%.8X, 0x%.8X)", code, param1, param2, param3, param4); - fflush(stdout); - DebugBreak(); - assert_always(); -} - -SHIM_CALL KeBugCheck_shim( +SHIM_CALL KeEnableFpuExceptions_shim( PPCContext* ppc_state, KernelState* state) { - uint32_t code = SHIM_GET_ARG_32(0); - xeKeBugCheckEx(code, 0, 0, 0, 0); -} - -SHIM_CALL KeBugCheckEx_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t code = SHIM_GET_ARG_32(0); - uint32_t param1 = SHIM_GET_ARG_32(1); - uint32_t param2 = SHIM_GET_ARG_32(2); - uint32_t param3 = SHIM_GET_ARG_32(3); - uint32_t param4 = SHIM_GET_ARG_32(4); - xeKeBugCheckEx(code, param1, param2, param3, param4); + uint32_t enabled = SHIM_GET_ARG_32(0); + XELOGD("KeEnableFpuExceptions(%d)", enabled); + // TODO(benvanik): can we do anything about exceptions? } @@ -54,6 +38,5 @@ SHIM_CALL KeBugCheckEx_shim( void xe::kernel::xboxkrnl::RegisterMiscExports( ExportResolver* export_resolver, KernelState* state) { - SHIM_SET_MAPPING("xboxkrnl.exe", KeBugCheck, state); - SHIM_SET_MAPPING("xboxkrnl.exe", KeBugCheckEx, state); + SHIM_SET_MAPPING("xboxkrnl.exe", KeEnableFpuExceptions, state); } From f0e9fd92a0a9a3dfb8e7387a6c30d922f1697fcb Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 4 Aug 2014 18:54:06 -0700 Subject: [PATCH 054/388] VECTOR_MIN and VECTOR_MAX instructions. --- src/alloy/backend/ivm/ivm_intcode.cc | 163 +++++++++++++++++++-- src/alloy/backend/x64/x64_sequences.cc | 96 ++++++++++++ src/alloy/frontend/ppc/ppc_emit_altivec.cc | 78 +++++++--- src/alloy/hir/hir_builder.cc | 26 ++++ src/alloy/hir/hir_builder.h | 4 + src/alloy/hir/opcodes.h | 2 + src/alloy/hir/opcodes.inl | 12 ++ 7 files changed, 348 insertions(+), 33 deletions(-) diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index fdc4ed8d7..04a306b69 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -9,6 +9,8 @@ #include +#include + #include #include #include @@ -1636,6 +1638,77 @@ int Translate_MAX(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, fns[i->dest->type]); } +uint32_t IntCode_VECTOR_MAX_I8_UNSIGNED(IntCodeState& ics, const IntCode* i) { + const vec128_t& src1 = ics.rf[i->src1_reg].v128; + const vec128_t& src2 = ics.rf[i->src2_reg].v128; + vec128_t& dest = ics.rf[i->dest_reg].v128; + for (int n = 0; n < 16; n++) { + dest.b16[n] = std::max(src1.b16[n], src2.b16[n]); + } + return IA_NEXT; +} +uint32_t IntCode_VECTOR_MAX_I16_UNSIGNED(IntCodeState& ics, const IntCode* i) { + const vec128_t& src1 = ics.rf[i->src1_reg].v128; + const vec128_t& src2 = ics.rf[i->src2_reg].v128; + vec128_t& dest = ics.rf[i->dest_reg].v128; + for (int n = 0; n < 8; n++) { + dest.s8[n] = std::max(src1.s8[n], src2.s8[n]); + } + return IA_NEXT; +} +uint32_t IntCode_VECTOR_MAX_I32_UNSIGNED(IntCodeState& ics, const IntCode* i) { + const vec128_t& src1 = ics.rf[i->src1_reg].v128; + const vec128_t& src2 = ics.rf[i->src2_reg].v128; + vec128_t& dest = ics.rf[i->dest_reg].v128; + for (int n = 0; n < 4; n++) { + dest.i4[n] = std::max(src1.i4[n], src2.i4[n]); + } + return IA_NEXT; +} +uint32_t IntCode_VECTOR_MAX_I8_SIGNED(IntCodeState& ics, const IntCode* i) { + const vec128_t& src1 = ics.rf[i->src1_reg].v128; + const vec128_t& src2 = ics.rf[i->src2_reg].v128; + vec128_t& dest = ics.rf[i->dest_reg].v128; + for (int n = 0; n < 16; n++) { + dest.b16[n] = std::max((int8_t)src1.b16[n], (int8_t)src2.b16[n]); + } + return IA_NEXT; +} +uint32_t IntCode_VECTOR_MAX_I16_SIGNED(IntCodeState& ics, const IntCode* i) { + const vec128_t& src1 = ics.rf[i->src1_reg].v128; + const vec128_t& src2 = ics.rf[i->src2_reg].v128; + vec128_t& dest = ics.rf[i->dest_reg].v128; + for (int n = 0; n < 8; n++) { + dest.s8[n] = std::max((int16_t)src1.s8[n], (int16_t)src2.s8[n]); + } + return IA_NEXT; +} +uint32_t IntCode_VECTOR_MAX_I32_SIGNED(IntCodeState& ics, const IntCode* i) { + const vec128_t& src1 = ics.rf[i->src1_reg].v128; + const vec128_t& src2 = ics.rf[i->src2_reg].v128; + vec128_t& dest = ics.rf[i->dest_reg].v128; + for (int n = 0; n < 4; n++) { + dest.i4[n] = std::max((int32_t)src1.i4[n], (int32_t)src2.i4[n]); + } + return IA_NEXT; +} +int Translate_VECTOR_MAX(TranslationContext& ctx, Instr* i) { + static IntCodeFn unsigned_fns[] = { + IntCode_VECTOR_MAX_I8_UNSIGNED, IntCode_VECTOR_MAX_I16_UNSIGNED, + IntCode_VECTOR_MAX_I32_UNSIGNED, + }; + static IntCodeFn signed_fns[] = { + IntCode_VECTOR_MAX_I8_SIGNED, IntCode_VECTOR_MAX_I16_SIGNED, + IntCode_VECTOR_MAX_I32_SIGNED, + }; + uint32_t part_type = i->flags >> 8; + if (i->flags & ARITHMETIC_UNSIGNED) { + return DispatchToC(ctx, i, unsigned_fns[part_type]); + } else { + return DispatchToC(ctx, i, signed_fns[part_type]); + } +} + uint32_t IntCode_MIN_I8_I8(IntCodeState& ics, const IntCode* i) { int8_t a = ics.rf[i->src1_reg].i8; int8_t b = ics.rf[i->src2_reg].i8; @@ -1688,6 +1761,77 @@ int Translate_MIN(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, fns[i->dest->type]); } +uint32_t IntCode_VECTOR_MIN_I8_UNSIGNED(IntCodeState& ics, const IntCode* i) { + const vec128_t& src1 = ics.rf[i->src1_reg].v128; + const vec128_t& src2 = ics.rf[i->src2_reg].v128; + vec128_t& dest = ics.rf[i->dest_reg].v128; + for (int n = 0; n < 16; n++) { + dest.b16[n] = std::min(src1.b16[n], src2.b16[n]); + } + return IA_NEXT; +} +uint32_t IntCode_VECTOR_MIN_I16_UNSIGNED(IntCodeState& ics, const IntCode* i) { + const vec128_t& src1 = ics.rf[i->src1_reg].v128; + const vec128_t& src2 = ics.rf[i->src2_reg].v128; + vec128_t& dest = ics.rf[i->dest_reg].v128; + for (int n = 0; n < 8; n++) { + dest.s8[n] = std::min(src1.s8[n], src2.s8[n]); + } + return IA_NEXT; +} +uint32_t IntCode_VECTOR_MIN_I32_UNSIGNED(IntCodeState& ics, const IntCode* i) { + const vec128_t& src1 = ics.rf[i->src1_reg].v128; + const vec128_t& src2 = ics.rf[i->src2_reg].v128; + vec128_t& dest = ics.rf[i->dest_reg].v128; + for (int n = 0; n < 4; n++) { + dest.i4[n] = std::min(src1.i4[n], src2.i4[n]); + } + return IA_NEXT; +} +uint32_t IntCode_VECTOR_MIN_I8_SIGNED(IntCodeState& ics, const IntCode* i) { + const vec128_t& src1 = ics.rf[i->src1_reg].v128; + const vec128_t& src2 = ics.rf[i->src2_reg].v128; + vec128_t& dest = ics.rf[i->dest_reg].v128; + for (int n = 0; n < 16; n++) { + dest.b16[n] = std::min((int8_t)src1.b16[n], (int8_t)src2.b16[n]); + } + return IA_NEXT; +} +uint32_t IntCode_VECTOR_MIN_I16_SIGNED(IntCodeState& ics, const IntCode* i) { + const vec128_t& src1 = ics.rf[i->src1_reg].v128; + const vec128_t& src2 = ics.rf[i->src2_reg].v128; + vec128_t& dest = ics.rf[i->dest_reg].v128; + for (int n = 0; n < 8; n++) { + dest.s8[n] = std::min((int16_t)src1.s8[n], (int16_t)src2.s8[n]); + } + return IA_NEXT; +} +uint32_t IntCode_VECTOR_MIN_I32_SIGNED(IntCodeState& ics, const IntCode* i) { + const vec128_t& src1 = ics.rf[i->src1_reg].v128; + const vec128_t& src2 = ics.rf[i->src2_reg].v128; + vec128_t& dest = ics.rf[i->dest_reg].v128; + for (int n = 0; n < 4; n++) { + dest.i4[n] = std::min((int32_t)src1.i4[n], (int32_t)src2.i4[n]); + } + return IA_NEXT; +} +int Translate_VECTOR_MIN(TranslationContext& ctx, Instr* i) { + static IntCodeFn unsigned_fns[] = { + IntCode_VECTOR_MIN_I8_UNSIGNED, IntCode_VECTOR_MIN_I16_UNSIGNED, + IntCode_VECTOR_MIN_I32_UNSIGNED, + }; + static IntCodeFn signed_fns[] = { + IntCode_VECTOR_MIN_I8_SIGNED, IntCode_VECTOR_MIN_I16_SIGNED, + IntCode_VECTOR_MIN_I32_SIGNED, + }; + uint32_t part_type = i->flags >> 8; + if (i->flags & ARITHMETIC_UNSIGNED) { + return DispatchToC(ctx, i, unsigned_fns[part_type]); + } else { + return DispatchToC(ctx, i, signed_fns[part_type]); + } +} + uint32_t IntCode_SELECT_I8(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 ? ics.rf[i->src2_reg].i8 : ics.rf[i->src3_reg].i8; @@ -2174,13 +2318,13 @@ int Translate_DID_SATURATE(TranslationContext& ctx, Instr* i) { } \ return IA_NEXT; -uint32_t IntCode_VECTOR_COMPARE_EQ_I8(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_VECTOR_COMPARE_EQ_I8(IntCodeState& ics, const IntCode* i){ VECTOR_COMPARER(uint8_t, b16, b16, 16, == )}; -uint32_t IntCode_VECTOR_COMPARE_EQ_I16(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_VECTOR_COMPARE_EQ_I16(IntCodeState& ics, const IntCode* i){ VECTOR_COMPARER(uint16_t, s8, s8, 8, == )}; -uint32_t IntCode_VECTOR_COMPARE_EQ_I32(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_VECTOR_COMPARE_EQ_I32(IntCodeState& ics, const IntCode* i){ VECTOR_COMPARER(uint32_t, i4, i4, 4, == )}; -uint32_t IntCode_VECTOR_COMPARE_EQ_F32(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_VECTOR_COMPARE_EQ_F32(IntCodeState& ics, const IntCode* i){ VECTOR_COMPARER(float, f4, i4, 4, == )}; int Translate_VECTOR_COMPARE_EQ(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { @@ -2192,13 +2336,13 @@ int Translate_VECTOR_COMPARE_EQ(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, fns[i->flags]); } -uint32_t IntCode_VECTOR_COMPARE_SGT_I8(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_VECTOR_COMPARE_SGT_I8(IntCodeState& ics, const IntCode* i){ VECTOR_COMPARER(int8_t, b16, b16, 16, > )}; -uint32_t IntCode_VECTOR_COMPARE_SGT_I16(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_VECTOR_COMPARE_SGT_I16(IntCodeState& ics, const IntCode* i){ VECTOR_COMPARER(int16_t, s8, s8, 8, > )}; -uint32_t IntCode_VECTOR_COMPARE_SGT_I32(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_VECTOR_COMPARE_SGT_I32(IntCodeState& ics, const IntCode* i){ VECTOR_COMPARER(int32_t, i4, i4, 4, > )}; -uint32_t IntCode_VECTOR_COMPARE_SGT_F32(IntCodeState& ics, const IntCode* i) { +uint32_t IntCode_VECTOR_COMPARE_SGT_F32(IntCodeState& ics, const IntCode* i){ VECTOR_COMPARER(float, f4, i4, 4, > )}; int Translate_VECTOR_COMPARE_SGT(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { @@ -4041,7 +4185,8 @@ static const TranslateFn dispatch_table[] = { Translate_LOAD_CONTEXT, Translate_STORE_CONTEXT, Translate_LOAD, Translate_STORE, Translate_PREFETCH, Translate_MAX, - Translate_MIN, Translate_SELECT, + Translate_VECTOR_MAX, Translate_MIN, + Translate_VECTOR_MIN, Translate_SELECT, Translate_IS_TRUE, Translate_IS_FALSE, Translate_COMPARE_EQ, Translate_COMPARE_NE, Translate_COMPARE_SLT, Translate_COMPARE_SLE, diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index 80e481a33..52d4df79c 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -1739,6 +1739,53 @@ EMITTER_OPCODE_TABLE( MAX_V128); +// ============================================================================ +// OPCODE_VECTOR_MAX +// ============================================================================ +EMITTER(VECTOR_MAX, MATCH(I, V128<>, V128<>>)) { + static void Emit(X64Emitter& e, const EmitArgType& i) { + EmitCommutativeBinaryXmmOp(e, i, + [&i](X64Emitter& e, Xmm dest, Xmm src1, Xmm src2) { + uint32_t part_type = i.instr->flags >> 8; + if (i.instr->flags & ARITHMETIC_UNSIGNED) { + switch (part_type) { + case INT8_TYPE: + e.vpmaxub(dest, src1, src2); + break; + case INT16_TYPE: + e.vpmaxuw(dest, src1, src2); + break; + case INT32_TYPE: + e.vpmaxud(dest, src1, src2); + break; + default: + assert_unhandled_case(part_type); + break; + } + } else { + switch (part_type) { + case INT8_TYPE: + e.vpmaxsb(dest, src1, src2); + break; + case INT16_TYPE: + e.vpmaxsw(dest, src1, src2); + break; + case INT32_TYPE: + e.vpmaxsd(dest, src1, src2); + break; + default: + assert_unhandled_case(part_type); + break; + } + } + }); + } +}; +EMITTER_OPCODE_TABLE( + OPCODE_VECTOR_MAX, + VECTOR_MAX); + + // ============================================================================ // OPCODE_MIN // ============================================================================ @@ -1773,6 +1820,53 @@ EMITTER_OPCODE_TABLE( MIN_V128); +// ============================================================================ +// OPCODE_VECTOR_MIN +// ============================================================================ +EMITTER(VECTOR_MIN, MATCH(I, V128<>, V128<>>)) { + static void Emit(X64Emitter& e, const EmitArgType& i) { + EmitCommutativeBinaryXmmOp(e, i, + [&i](X64Emitter& e, Xmm dest, Xmm src1, Xmm src2) { + uint32_t part_type = i.instr->flags >> 8; + if (i.instr->flags & ARITHMETIC_UNSIGNED) { + switch (part_type) { + case INT8_TYPE: + e.vpminub(dest, src1, src2); + break; + case INT16_TYPE: + e.vpminuw(dest, src1, src2); + break; + case INT32_TYPE: + e.vpminud(dest, src1, src2); + break; + default: + assert_unhandled_case(part_type); + break; + } + } else { + switch (part_type) { + case INT8_TYPE: + e.vpminsb(dest, src1, src2); + break; + case INT16_TYPE: + e.vpminsw(dest, src1, src2); + break; + case INT32_TYPE: + e.vpminsd(dest, src1, src2); + break; + default: + assert_unhandled_case(part_type); + break; + } + } + }); + } +}; +EMITTER_OPCODE_TABLE( + OPCODE_VECTOR_MIN, + VECTOR_MIN); + + // ============================================================================ // OPCODE_SELECT // ============================================================================ @@ -5042,7 +5136,9 @@ void RegisterSequences() { REGISTER_EMITTER_OPCODE_TABLE(OPCODE_STORE); REGISTER_EMITTER_OPCODE_TABLE(OPCODE_PREFETCH); REGISTER_EMITTER_OPCODE_TABLE(OPCODE_MAX); + REGISTER_EMITTER_OPCODE_TABLE(OPCODE_VECTOR_MAX); REGISTER_EMITTER_OPCODE_TABLE(OPCODE_MIN); + REGISTER_EMITTER_OPCODE_TABLE(OPCODE_VECTOR_MIN); REGISTER_EMITTER_OPCODE_TABLE(OPCODE_SELECT); REGISTER_EMITTER_OPCODE_TABLE(OPCODE_IS_TRUE); REGISTER_EMITTER_OPCODE_TABLE(OPCODE_IS_FALSE); diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index b52102555..c3915c258 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -803,33 +803,48 @@ XEEMITTER(vmaxfp128, VX128(6, 640), VX128)(PPCHIRBuilder& f, InstrData& i) { } XEEMITTER(vmaxsb, 0x10000102, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD) <- max((VA), (VB)) (signed int8) + Value* v = f.VectorMax(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT8_TYPE); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vmaxsh, 0x10000142, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD) <- max((VA), (VB)) (signed int16) + Value* v = f.VectorMax(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT16_TYPE); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vmaxsw, 0x10000182, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD) <- max((VA), (VB)) (signed int32) + Value* v = f.VectorMax(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT32_TYPE); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vmaxub, 0x10000002, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD) <- max((VA), (VB)) (unsigned int8) + Value* v = f.VectorMax(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT8_TYPE, + ARITHMETIC_UNSIGNED); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vmaxuh, 0x10000042, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD) <- max((VA), (VB)) (unsigned int16) + Value* v = f.VectorMax(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT16_TYPE, + ARITHMETIC_UNSIGNED); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vmaxuw, 0x10000082, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD) <- max((VA), (VB)) (unsigned int32) + Value* v = f.VectorMax(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT32_TYPE, + ARITHMETIC_UNSIGNED); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vmhaddshs, 0x10000020, VXA)(PPCHIRBuilder& f, InstrData& i) { @@ -856,33 +871,48 @@ XEEMITTER(vminfp128, VX128(6, 704), VX128)(PPCHIRBuilder& f, InstrData& i) { } XEEMITTER(vminsb, 0x10000302, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD) <- min((VA), (VB)) (signed int8) + Value* v = f.VectorMin(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT8_TYPE); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vminsh, 0x10000342, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD) <- min((VA), (VB)) (signed int16) + Value* v = f.VectorMin(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT16_TYPE); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vminsw, 0x10000382, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD) <- min((VA), (VB)) (signed int32) + Value* v = f.VectorMin(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT32_TYPE); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vminub, 0x10000202, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD) <- min((VA), (VB)) (unsigned int8) + Value* v = f.VectorMin(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT8_TYPE, + ARITHMETIC_UNSIGNED); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vminuh, 0x10000242, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD) <- min((VA), (VB)) (unsigned int16) + Value* v = f.VectorMin(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT16_TYPE, + ARITHMETIC_UNSIGNED); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vminuw, 0x10000282, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD) <- min((VA), (VB)) (unsigned int32) + Value* v = f.VectorMin(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT32_TYPE, + ARITHMETIC_UNSIGNED); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vmladduhm, 0x10000022, VXA)(PPCHIRBuilder& f, InstrData& i) { diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index 11d9b836a..acdb6b95a 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -1035,6 +1035,19 @@ Value* HIRBuilder::Max(Value* value1, Value* value2) { return i->dest; } +Value* HIRBuilder::VectorMax(Value* value1, Value* value2, TypeName part_type, + uint32_t arithmetic_flags) { + ASSERT_TYPES_EQUAL(value1, value2); + + uint16_t flags = arithmetic_flags | (part_type << 8); + Instr* i = + AppendInstr(OPCODE_VECTOR_MAX_info, flags, AllocValue(value1->type)); + i->set_src1(value1); + i->set_src2(value2); + i->src3.value = NULL; + return i->dest; +} + Value* HIRBuilder::Min(Value* value1, Value* value2) { ASSERT_TYPES_EQUAL(value1, value2); @@ -1050,6 +1063,19 @@ Value* HIRBuilder::Min(Value* value1, Value* value2) { return i->dest; } +Value* HIRBuilder::VectorMin(Value* value1, Value* value2, TypeName part_type, + uint32_t arithmetic_flags) { + ASSERT_TYPES_EQUAL(value1, value2); + + uint16_t flags = arithmetic_flags | (part_type << 8); + Instr* i = + AppendInstr(OPCODE_VECTOR_MIN_info, flags, AllocValue(value1->type)); + i->set_src1(value1); + i->set_src2(value2); + i->src3.value = NULL; + return i->dest; +} + Value* HIRBuilder::Select(Value* cond, Value* value1, Value* value2) { assert_true(cond->type == INT8_TYPE); // for now ASSERT_TYPES_EQUAL(value1, value2); diff --git a/src/alloy/hir/hir_builder.h b/src/alloy/hir/hir_builder.h index 4d6d53e7c..8bcd53c33 100644 --- a/src/alloy/hir/hir_builder.h +++ b/src/alloy/hir/hir_builder.h @@ -136,7 +136,11 @@ class HIRBuilder { void Prefetch(Value* address, size_t length, uint32_t prefetch_flags = 0); Value* Max(Value* value1, Value* value2); + Value* VectorMax(Value* value1, Value* value2, TypeName part_type, + uint32_t arithmetic_flags = 0); Value* Min(Value* value1, Value* value2); + Value* VectorMin(Value* value1, Value* value2, TypeName part_type, + uint32_t arithmetic_flags = 0); Value* Select(Value* cond, Value* value1, Value* value2); Value* IsTrue(Value* value); Value* IsFalse(Value* value); diff --git a/src/alloy/hir/opcodes.h b/src/alloy/hir/opcodes.h index 841d1f134..c163ca5d0 100644 --- a/src/alloy/hir/opcodes.h +++ b/src/alloy/hir/opcodes.h @@ -112,7 +112,9 @@ enum Opcode { OPCODE_STORE, OPCODE_PREFETCH, OPCODE_MAX, + OPCODE_VECTOR_MAX, OPCODE_MIN, + OPCODE_VECTOR_MIN, OPCODE_SELECT, OPCODE_IS_TRUE, OPCODE_IS_FALSE, diff --git a/src/alloy/hir/opcodes.inl b/src/alloy/hir/opcodes.inl index deb789675..b09ea29c7 100644 --- a/src/alloy/hir/opcodes.inl +++ b/src/alloy/hir/opcodes.inl @@ -236,12 +236,24 @@ DEFINE_OPCODE( OPCODE_SIG_V_V_V, 0) +DEFINE_OPCODE( + OPCODE_VECTOR_MAX, + "vector_max", + OPCODE_SIG_V_V_V, + 0) + DEFINE_OPCODE( OPCODE_MIN, "min", OPCODE_SIG_V_V_V, 0) +DEFINE_OPCODE( + OPCODE_VECTOR_MIN, + "vector_min", + OPCODE_SIG_V_V_V, + 0) + DEFINE_OPCODE( OPCODE_SELECT, "select", From a593d940ebdb255fca676448db99e0357cb0cf82 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 4 Aug 2014 18:54:44 -0700 Subject: [PATCH 055/388] std min/max. --- src/alloy/backend/ivm/ivm_intcode.cc | 32 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index 04a306b69..d69abd773 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -1163,7 +1163,7 @@ static uint8_t __lvsr_table[17][16] = { }; uint32_t IntCode_LOAD_VECTOR_SHL(IntCodeState& ics, const IntCode* i) { - int8_t sh = MIN(16, ics.rf[i->src1_reg].i8); + int8_t sh = std::min(16, ics.rf[i->src1_reg].i8); vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 16; n++) { VECB16(dest, n) = __lvsl_table[sh][n]; @@ -1175,7 +1175,7 @@ int Translate_LOAD_VECTOR_SHL(TranslationContext& ctx, Instr* i) { } uint32_t IntCode_LOAD_VECTOR_SHR(IntCodeState& ics, const IntCode* i) { - int8_t sh = MIN(16, ics.rf[i->src1_reg].i8); + int8_t sh = std::min(16, ics.rf[i->src1_reg].i8); vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 16; n++) { VECB16(dest, n) = __lvsr_table[sh][n]; @@ -1589,35 +1589,35 @@ int Translate_PREFETCH(TranslationContext& ctx, Instr* i) { uint32_t IntCode_MAX_I8_I8(IntCodeState& ics, const IntCode* i) { int8_t a = ics.rf[i->src1_reg].i8; int8_t b = ics.rf[i->src2_reg].i8; - ics.rf[i->dest_reg].i8 = MAX(a, b); + ics.rf[i->dest_reg].i8 = std::max(a, b); return IA_NEXT; } uint32_t IntCode_MAX_I16_I16(IntCodeState& ics, const IntCode* i) { int16_t a = ics.rf[i->src1_reg].i16; int16_t b = ics.rf[i->src2_reg].i16; - ics.rf[i->dest_reg].i16 = MAX(a, b); + ics.rf[i->dest_reg].i16 = std::max(a, b); return IA_NEXT; } uint32_t IntCode_MAX_I32_I32(IntCodeState& ics, const IntCode* i) { int32_t a = ics.rf[i->src1_reg].i32; int32_t b = ics.rf[i->src2_reg].i32; - ics.rf[i->dest_reg].i32 = MAX(a, b); + ics.rf[i->dest_reg].i32 = std::max(a, b); return IA_NEXT; } uint32_t IntCode_MAX_I64_I64(IntCodeState& ics, const IntCode* i) { int64_t a = ics.rf[i->src1_reg].i64; int64_t b = ics.rf[i->src2_reg].i64; - ics.rf[i->dest_reg].i64 = MAX(a, b); + ics.rf[i->dest_reg].i64 = std::max(a, b); return IA_NEXT; } uint32_t IntCode_MAX_F32_F32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].f32 = - MAX(ics.rf[i->src1_reg].f32, ics.rf[i->src2_reg].f32); + std::max(ics.rf[i->src1_reg].f32, ics.rf[i->src2_reg].f32); return IA_NEXT; } uint32_t IntCode_MAX_F64_F64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].f64 = - MAX(ics.rf[i->src1_reg].f64, ics.rf[i->src2_reg].f64); + std::max(ics.rf[i->src1_reg].f64, ics.rf[i->src2_reg].f64); return IA_NEXT; } uint32_t IntCode_MAX_V128_V128(IntCodeState& ics, const IntCode* i) { @@ -1625,7 +1625,7 @@ uint32_t IntCode_MAX_V128_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - dest.f4[n] = MAX(src1.f4[n], src2.f4[n]); + dest.f4[n] = std::max(src1.f4[n], src2.f4[n]); } return IA_NEXT; } @@ -1712,35 +1712,35 @@ int Translate_VECTOR_MAX(TranslationContext& ctx, Instr* i) { uint32_t IntCode_MIN_I8_I8(IntCodeState& ics, const IntCode* i) { int8_t a = ics.rf[i->src1_reg].i8; int8_t b = ics.rf[i->src2_reg].i8; - ics.rf[i->dest_reg].i8 = MIN(a, b); + ics.rf[i->dest_reg].i8 = std::min(a, b); return IA_NEXT; } uint32_t IntCode_MIN_I16_I16(IntCodeState& ics, const IntCode* i) { int16_t a = ics.rf[i->src1_reg].i16; int16_t b = ics.rf[i->src2_reg].i16; - ics.rf[i->dest_reg].i16 = MIN(a, b); + ics.rf[i->dest_reg].i16 = std::min(a, b); return IA_NEXT; } uint32_t IntCode_MIN_I32_I32(IntCodeState& ics, const IntCode* i) { int32_t a = ics.rf[i->src1_reg].i32; int32_t b = ics.rf[i->src2_reg].i32; - ics.rf[i->dest_reg].i32 = MIN(a, b); + ics.rf[i->dest_reg].i32 = std::min(a, b); return IA_NEXT; } uint32_t IntCode_MIN_I64_I64(IntCodeState& ics, const IntCode* i) { int64_t a = ics.rf[i->src1_reg].i64; int64_t b = ics.rf[i->src2_reg].i64; - ics.rf[i->dest_reg].i64 = MIN(a, b); + ics.rf[i->dest_reg].i64 = std::min(a, b); return IA_NEXT; } uint32_t IntCode_MIN_F32_F32(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].f32 = - MIN(ics.rf[i->src1_reg].f32, ics.rf[i->src2_reg].f32); + std::min(ics.rf[i->src1_reg].f32, ics.rf[i->src2_reg].f32); return IA_NEXT; } uint32_t IntCode_MIN_F64_F64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].f64 = - MIN(ics.rf[i->src1_reg].f64, ics.rf[i->src2_reg].f64); + std::min(ics.rf[i->src1_reg].f64, ics.rf[i->src2_reg].f64); return IA_NEXT; } uint32_t IntCode_MIN_V128_V128(IntCodeState& ics, const IntCode* i) { @@ -1748,7 +1748,7 @@ uint32_t IntCode_MIN_V128_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - dest.f4[n] = MIN(src1.f4[n], src2.f4[n]); + dest.f4[n] = std::min(src1.f4[n], src2.f4[n]); } return IA_NEXT; } From 66d2a8aec2414760285e9e6927bb3a5a0ca70043 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 4 Aug 2014 18:55:00 -0700 Subject: [PATCH 056/388] Setting XMA pointer to make errors clearer. --- src/xenia/kernel/xboxkrnl_audio.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/xenia/kernel/xboxkrnl_audio.cc b/src/xenia/kernel/xboxkrnl_audio.cc index 96972d5d9..53359d302 100644 --- a/src/xenia/kernel/xboxkrnl_audio.cc +++ b/src/xenia/kernel/xboxkrnl_audio.cc @@ -35,6 +35,8 @@ SHIM_CALL XMACreateContext_shim( context_ptr); // TODO(benvanik): allocate and return -- see if size required or just dummy? + // Games will call MmGetPhysicalAddress on the result. + SHIM_SET_MEM_32(context_ptr, 0xAAAABABE); SHIM_SET_RETURN_32(X_STATUS_SUCCESS); } From 64d8ee386b1bc5d657903ad3f093923ced7a1b8c Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 4 Aug 2014 20:24:08 -0700 Subject: [PATCH 057/388] XamShowMessageBoxUI (that auto-advances). --- src/poly/memory.h | 28 +++++++++++++ src/xenia/kernel/sources.gypi | 2 + src/xenia/kernel/xam_module.cc | 1 + src/xenia/kernel/xam_private.h | 1 + src/xenia/kernel/xam_ui.cc | 76 ++++++++++++++++++++++++++++++++++ src/xenia/kernel/xam_ui.h | 28 +++++++++++++ src/xenia/kernel/xam_user.cc | 2 +- 7 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 src/xenia/kernel/xam_ui.cc create mode 100644 src/xenia/kernel/xam_ui.h diff --git a/src/poly/memory.h b/src/poly/memory.h index a8a26c95f..531c0ea4d 100644 --- a/src/poly/memory.h +++ b/src/poly/memory.h @@ -10,6 +10,8 @@ #ifndef POLY_MEMORY_H_ #define POLY_MEMORY_H_ +#include + #include namespace poly { @@ -101,6 +103,32 @@ template <> inline double load_and_swap(const void* mem) { return byte_swap(*reinterpret_cast(mem)); } +template <> +inline std::string load_and_swap(const void* mem) { + std::string value; + for (int i = 0;; ++i) { + auto c = + poly::load_and_swap(reinterpret_cast(mem) + i); + if (!c) { + break; + } + value.push_back(static_cast(c)); + } + return value; +} +template <> +inline std::wstring load_and_swap(const void* mem) { + std::wstring value; + for (int i = 0;; ++i) { + auto c = poly::load_and_swap( + reinterpret_cast(mem) + i); + if (!c) { + break; + } + value.push_back(static_cast(c)); + } + return value; +} template void store(void* mem, T value); diff --git a/src/xenia/kernel/sources.gypi b/src/xenia/kernel/sources.gypi index 2a7cb929b..f6f5356d0 100644 --- a/src/xenia/kernel/sources.gypi +++ b/src/xenia/kernel/sources.gypi @@ -34,6 +34,8 @@ 'xam_ordinals.h', 'xam_private.h', 'xam_table.inc', + 'xam_ui.cc', + 'xam_ui.h', 'xam_user.cc', 'xam_user.h', 'xam_video.cc', diff --git a/src/xenia/kernel/xam_module.cc b/src/xenia/kernel/xam_module.cc index d8f85547e..2a5aa6217 100644 --- a/src/xenia/kernel/xam_module.cc +++ b/src/xenia/kernel/xam_module.cc @@ -37,6 +37,7 @@ XamModule::XamModule(Emulator* emulator, KernelState* kernel_state) : RegisterMsgExports(export_resolver_, kernel_state); RegisterNetExports(export_resolver_, kernel_state); RegisterNotifyExports(export_resolver_, kernel_state); + RegisterUIExports(export_resolver_, kernel_state); RegisterUserExports(export_resolver_, kernel_state); RegisterVideoExports(export_resolver_, kernel_state); RegisterVoiceExports(export_resolver_, kernel_state); diff --git a/src/xenia/kernel/xam_private.h b/src/xenia/kernel/xam_private.h index 715fc44e6..1884397e1 100644 --- a/src/xenia/kernel/xam_private.h +++ b/src/xenia/kernel/xam_private.h @@ -29,6 +29,7 @@ void RegisterInputExports(ExportResolver* export_resolver, KernelState* state); void RegisterMsgExports(ExportResolver* export_resolver, KernelState* state); void RegisterNetExports(ExportResolver* export_resolver, KernelState* state); void RegisterNotifyExports(ExportResolver* export_resolver, KernelState* state); +void RegisterUIExports(ExportResolver* export_resolver, KernelState* state); void RegisterUserExports(ExportResolver* export_resolver, KernelState* state); void RegisterVideoExports(ExportResolver* export_resolver, KernelState* state); void RegisterVoiceExports(ExportResolver* export_resolver, KernelState* state); diff --git a/src/xenia/kernel/xam_ui.cc b/src/xenia/kernel/xam_ui.cc new file mode 100644 index 000000000..803934fd6 --- /dev/null +++ b/src/xenia/kernel/xam_ui.cc @@ -0,0 +1,76 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include +#include +#include + + +using namespace xe; +using namespace xe::kernel; +using namespace xe::kernel::xam; + + +namespace xe { +namespace kernel { + +// http://www.se7ensins.com/forums/threads/working-xshowmessageboxui.844116/?jdfwkey=sb0vm +SHIM_CALL XamShowMessageBoxUI_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t user_index = SHIM_GET_ARG_32(0); + uint32_t title_ptr = SHIM_GET_ARG_32(1); + uint32_t text_ptr = SHIM_GET_ARG_32(2); + uint32_t button_count = SHIM_GET_ARG_32(3); + uint32_t button_ptrs = SHIM_GET_ARG_32(4); + uint32_t active_button = SHIM_GET_ARG_32(5); + uint32_t flags = SHIM_GET_ARG_32(6); + uint32_t result_ptr = SHIM_GET_ARG_32(7); + // arg8 is in stack! + uint32_t sp = (uint32_t)ppc_state->r[1]; + uint32_t overlapped_ptr = SHIM_MEM_32(sp + 0x54); + + auto title = poly::load_and_swap(SHIM_MEM_ADDR(title_ptr)); + auto text = poly::load_and_swap(SHIM_MEM_ADDR(text_ptr)); + std::vector buttons; + std::wstring all_buttons; + for (uint32_t j = 0; j < button_count; ++j) { + uint32_t button_ptr = SHIM_MEM_32(button_ptrs + j * 4); + auto button = poly::load_and_swap(SHIM_MEM_ADDR(button_ptr)); + all_buttons.append(button); + if (j + 1 < button_count) { + all_buttons.append(L" | "); + } + buttons.push_back(button); + } + + XELOGD( + "XamShowMessageBoxUI(%d, %.8X(%S), %.8X(%S), %d, %.8X(%S), %d, %X, %.8X, " + "%.8X)", + user_index, title_ptr, title.c_str(), text_ptr, text.c_str(), + button_count, button_ptrs, all_buttons.c_str(), active_button, flags, + result_ptr, overlapped_ptr); + + // Auto-pick the focused button. + SHIM_SET_MEM_32(result_ptr, active_button); + + state->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS); + SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); +} + + +} // namespace kernel +} // namespace xe + + +void xe::kernel::xam::RegisterUIExports( + ExportResolver* export_resolver, KernelState* state) { + SHIM_SET_MAPPING("xam.xex", XamShowMessageBoxUI, state); +} diff --git a/src/xenia/kernel/xam_ui.h b/src/xenia/kernel/xam_ui.h new file mode 100644 index 000000000..629491ec4 --- /dev/null +++ b/src/xenia/kernel/xam_ui.h @@ -0,0 +1,28 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_KERNEL_XAM_UI_H_ +#define XENIA_KERNEL_XAM_UI_H_ + +#include +#include + +#include + + +namespace xe { +namespace kernel { + + + +} // namespace kernel +} // namespace xe + + +#endif // XENIA_KERNEL_XAM_UI_H_ diff --git a/src/xenia/kernel/xam_user.cc b/src/xenia/kernel/xam_user.cc index 268b912fb..0c7c3ea4c 100644 --- a/src/xenia/kernel/xam_user.cc +++ b/src/xenia/kernel/xam_user.cc @@ -60,7 +60,7 @@ SHIM_CALL XamUserGetSigninState_shim( // Lie and say we are signed in, but local-only. // This should keep games from asking us to sign in and also keep them // from initializing the network. - if (user_index == 0) { + if (user_index == 0 || (user_index & 0xFF) == 0xFF) { const auto& user_profile = state->user_profile(); SHIM_SET_RETURN_64(user_profile->signin_state()); } else { From 8471408273798ad9a9d7ea1853beaadc48019ce7 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 4 Aug 2014 20:46:14 -0700 Subject: [PATCH 058/388] lhau(x), fixes #110. --- src/alloy/frontend/ppc/ppc_emit_memory.cc | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/alloy/frontend/ppc/ppc_emit_memory.cc b/src/alloy/frontend/ppc/ppc_emit_memory.cc index a7264f50c..9ac067641 100644 --- a/src/alloy/frontend/ppc/ppc_emit_memory.cc +++ b/src/alloy/frontend/ppc/ppc_emit_memory.cc @@ -143,13 +143,25 @@ XEEMITTER(lha, 0xA8000000, D)(PPCHIRBuilder& f, InstrData& i) { } XEEMITTER(lhau, 0xAC000000, D)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // EA <- (RA) + EXTS(D) + // RT <- EXTS(MEM(EA, 2)) + // RA <- EA + Value* ea = CalculateEA_i(f, i.D.RA, XEEXTS16(i.D.DS)); + Value* rt = f.SignExtend(f.ByteSwap(f.Load(ea, INT16_TYPE)), INT64_TYPE); + f.StoreGPR(i.D.RT, rt); + f.StoreGPR(i.D.RA, ea); + return 0; } XEEMITTER(lhaux, 0x7C0002EE, X)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // EA <- (RA) + (RB) + // RT <- EXTS(MEM(EA, 2)) + // RA <- EA + Value* ea = CalculateEA(f, i.X.RA, i.X.RB); + Value* rt = f.SignExtend(f.ByteSwap(f.Load(ea, INT16_TYPE)), INT64_TYPE); + f.StoreGPR(i.X.RT, rt); + f.StoreGPR(i.X.RA, ea); + return 0; } XEEMITTER(lhax, 0x7C0002AE, X)(PPCHIRBuilder& f, InstrData& i) { From 8460afadd36eac4e9857926c5cf6fe523d079bdc Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 4 Aug 2014 21:54:09 -0700 Subject: [PATCH 059/388] RtlUnicodeStringToAnsiString --- src/xenia/kernel/xboxkrnl_rtl.cc | 64 +++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/src/xenia/kernel/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl_rtl.cc index d9fd7fddc..2f77b6995 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl_rtl.cc @@ -9,6 +9,9 @@ #include +#include +#include + #include #include #include @@ -212,9 +215,12 @@ void xeRtlFreeAnsiString(uint32_t string_ptr) { // VOID // _Inout_ PANSI_STRING AnsiString - //uint32_t buffer = SHIM_MEM_32(string_ptr + 4); - // TODO(benvanik): free the buffer - XELOGE("RtlFreeAnsiString leaking buffer"); + uint32_t buffer = IMPL_MEM_32(string_ptr + 4); + if (!buffer) { + return; + } + uint32_t length = IMPL_MEM_16(string_ptr + 2); + state->memory()->HeapFree(buffer, length); IMPL_SET_MEM_16(string_ptr + 0, 0); IMPL_SET_MEM_16(string_ptr + 2, 0); @@ -286,9 +292,12 @@ void xeRtlFreeUnicodeString(uint32_t string_ptr) { // VOID // _Inout_ PUNICODE_STRING UnicodeString - //uint32_t buffer = IMPL_MEM_32(string_ptr + 4); - // TODO(benvanik): free the buffer - XELOGE("RtlFreeUnicodeString leaking buffer"); + uint32_t buffer = IMPL_MEM_32(string_ptr + 4); + if (!buffer) { + return; + } + uint32_t length = IMPL_MEM_16(string_ptr + 2); + state->memory()->HeapFree(buffer, length); IMPL_SET_MEM_16(string_ptr + 0, 0); IMPL_SET_MEM_16(string_ptr + 2, 0); @@ -307,8 +316,9 @@ SHIM_CALL RtlFreeUnicodeString_shim( // http://msdn.microsoft.com/en-us/library/ff562969 -X_STATUS xeRtlUnicodeStringToAnsiString( - uint32_t destination_ptr, uint32_t source_ptr, uint32_t alloc_dest) { +X_STATUS xeRtlUnicodeStringToAnsiString(uint32_t destination_ptr, + uint32_t source_ptr, + uint32_t alloc_dest) { KernelState* state = shared_kernel_state_; assert_not_null(state); @@ -317,18 +327,36 @@ X_STATUS xeRtlUnicodeStringToAnsiString( // _In_ PCUNICODE_STRING SourceString, // _In_ BOOLEAN AllocateDestinationString - XELOGE("RtlUnicodeStringToAnsiString not yet implemented"); - assert_always(); - - if (alloc_dest) { - // Allocate a new buffer to place the string into. - //IMPL_SET_MEM_32(destination_ptr + 4, buffer_ptr); - } else { - // Reuse the buffer in the target. - //uint32_t buffer_size = IMPL_MEM_16(destination_ptr + 2); + std::wstring unicode_str = poly::load_and_swap( + IMPL_MEM_ADDR(IMPL_MEM_32(source_ptr + 4))); + std::wstring_convert> converter; + std::string ansi_str = converter.to_bytes(unicode_str); + if (ansi_str.size() > 0xFFFF - 1) { + return X_STATUS_INVALID_PARAMETER_2; } - return X_STATUS_UNSUCCESSFUL; + X_STATUS result = X_STATUS_SUCCESS; + if (alloc_dest) { + auto buffer_ptr = state->memory()->HeapAlloc(0, ansi_str.size() + 1, 0); + memcpy(IMPL_MEM_ADDR(buffer_ptr), ansi_str.data(), ansi_str.size() + 1); + IMPL_SET_MEM_16(destination_ptr + 0, + static_cast(ansi_str.size())); + IMPL_SET_MEM_16(destination_ptr + 2, + static_cast(ansi_str.size() + 1)); + IMPL_SET_MEM_32(destination_ptr + 4, static_cast(buffer_ptr)); + } else { + uint32_t buffer_capacity = IMPL_MEM_16(destination_ptr + 2); + uint32_t buffer_ptr = IMPL_MEM_32(destination_ptr + 4); + if (buffer_capacity < ansi_str.size() + 1) { + // Too large - we just write what we can. + result = X_STATUS_BUFFER_OVERFLOW; + memcpy(IMPL_MEM_ADDR(buffer_ptr), ansi_str.data(), buffer_capacity - 1); + } else { + memcpy(IMPL_MEM_ADDR(buffer_ptr), ansi_str.data(), ansi_str.size() + 1); + } + IMPL_SET_MEM_8(buffer_ptr + buffer_capacity - 1, 0); // \0 + } + return result; } From 4e276695bfcd23a8ba627580b70f68c89e19315a Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 4 Aug 2014 22:02:19 -0700 Subject: [PATCH 060/388] XamUserGetDeviceContext --- src/xenia/kernel/xam_input.cc | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/xenia/kernel/xam_input.cc b/src/xenia/kernel/xam_input.cc index 5e6266cbd..b4f272447 100644 --- a/src/xenia/kernel/xam_input.cc +++ b/src/xenia/kernel/xam_input.cc @@ -202,6 +202,30 @@ SHIM_CALL XamInputGetKeystrokeEx_shim( } +SHIM_CALL XamUserGetDeviceContext_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t user_index = SHIM_GET_ARG_32(0); + uint32_t unk = SHIM_GET_ARG_32(1); + uint32_t out_ptr = SHIM_GET_ARG_32(2); + + XELOGD( + "XamUserGetDeviceContext(%d, %d, %.8X)", + user_index, + unk, + out_ptr); + + // Games check the result - usually with some masking. + // If this function fails they assume zero, so let's fail AND + // set zero just to be safe. + SHIM_SET_MEM_32(out_ptr, 0); + if (!user_index || (user_index & 0xFF) == 0xFF) { + SHIM_SET_RETURN_32(0); + } else { + SHIM_SET_RETURN_32(-1); + } +} + + } // namespace kernel } // namespace xe @@ -215,4 +239,5 @@ void xe::kernel::xam::RegisterInputExports( SHIM_SET_MAPPING("xam.xex", XamInputSetState, state); SHIM_SET_MAPPING("xam.xex", XamInputGetKeystroke, state); SHIM_SET_MAPPING("xam.xex", XamInputGetKeystrokeEx, state); + SHIM_SET_MAPPING("xam.xex", XamUserGetDeviceContext, state); } From 2d4ae9ba6463730c4bb5278ce66f96d14f68a125 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 4 Aug 2014 22:02:28 -0700 Subject: [PATCH 061/388] XAudioEnableDucker --- src/xenia/kernel/xboxkrnl_audio.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/xenia/kernel/xboxkrnl_audio.cc b/src/xenia/kernel/xboxkrnl_audio.cc index 53359d302..34744bbe9 100644 --- a/src/xenia/kernel/xboxkrnl_audio.cc +++ b/src/xenia/kernel/xboxkrnl_audio.cc @@ -105,6 +105,18 @@ SHIM_CALL XAudioGetVoiceCategoryVolume_shim( } +SHIM_CALL XAudioEnableDucker_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t unk = SHIM_GET_ARG_32(0); + + XELOGD( + "XAudioEnableDucker(%.8X)", + unk); + + SHIM_SET_RETURN_32(X_ERROR_SUCCESS); +} + + SHIM_CALL XAudioRegisterRenderDriverClient_shim( PPCContext* ppc_state, KernelState* state) { uint32_t callback_ptr = SHIM_GET_ARG_32(0); @@ -195,9 +207,9 @@ void xe::kernel::xboxkrnl::RegisterAudioExports( // SHIM_SET_MAPPING("xboxkrnl.exe", XMAGetInputBufferReadOffset, state); SHIM_SET_MAPPING("xboxkrnl.exe", XAudioGetSpeakerConfig, state); - SHIM_SET_MAPPING("xboxkrnl.exe", XAudioGetVoiceCategoryVolumeChangeMask, state); SHIM_SET_MAPPING("xboxkrnl.exe", XAudioGetVoiceCategoryVolume, state); + SHIM_SET_MAPPING("xboxkrnl.exe", XAudioEnableDucker, state); SHIM_SET_MAPPING("xboxkrnl.exe", XAudioRegisterRenderDriverClient, state); SHIM_SET_MAPPING("xboxkrnl.exe", XAudioUnregisterRenderDriverClient, state); From 3150f41ea0591f47256a3849a7631c358b5fb1a4 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 5 Aug 2014 09:10:00 -0700 Subject: [PATCH 062/388] oh ffs - properly suspending threads on creation. --- src/xenia/kernel/objects/xthread.cc | 20 ++++++++++++++++++-- src/xenia/kernel/objects/xthread.h | 1 + src/xenia/kernel/xboxkrnl_threading.cc | 3 +-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index 0e3dab0c5..f10306baf 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -9,6 +9,8 @@ #include +#include + #include #include #include @@ -47,6 +49,9 @@ XThread::XThread(KernelState* kernel_state, creation_params_.xapi_thread_startup = xapi_thread_startup; creation_params_.start_address = start_address; creation_params_.start_context = start_context; + + // top 8 bits = processor ID (or 0 for default) + // bit 0 = 1 to create suspended creation_params_.creation_flags = creation_flags; // Adjust stack size - min of 16k. @@ -244,6 +249,11 @@ X_STATUS XThread::Create() { xesnprintfa(thread_name, XECOUNT(thread_name), "XThread%04X", handle()); set_name(thread_name); + uint32_t proc_mask = creation_params_.creation_flags >> 24; + if (proc_mask) { + SetAffinity(proc_mask); + } + module->Release(); return X_STATUS_SUCCESS; } @@ -277,12 +287,13 @@ static uint32_t __stdcall XThreadStartCallbackWin32(void* param) { } X_STATUS XThread::PlatformCreate() { + bool suspended = creation_params_.creation_flags & 0x1; thread_handle_ = CreateThread( NULL, creation_params_.stack_size, (LPTHREAD_START_ROUTINE)XThreadStartCallbackWin32, this, - creation_params_.creation_flags, + suspended ? CREATE_SUSPENDED : 0, NULL); if (!thread_handle_) { uint32_t last_error = GetLastError(); @@ -325,7 +336,7 @@ X_STATUS XThread::PlatformCreate() { pthread_attr_setstacksize(&attr, creation_params_.stack_size); int result_code; - if (creation_params_.creation_flags & X_CREATE_SUSPENDED) { + if (creation_params_.creation_flags & 0x1) { #if XE_PLATFORM_OSX result_code = pthread_create_suspended_np( reinterpret_cast(&thread_handle_), @@ -521,6 +532,11 @@ void XThread::SetPriority(int32_t increment) { SetThreadPriority(thread_handle_, increment); } +void XThread::SetAffinity(uint32_t affinity) { + // TODO(benvanik): implement. + XELOGW("KeSetAffinityThread not implemented"); +} + X_STATUS XThread::Resume(uint32_t* out_suspend_count) { DWORD result = ResumeThread(thread_handle_); if (result >= 0) { diff --git a/src/xenia/kernel/objects/xthread.h b/src/xenia/kernel/objects/xthread.h index cec3c4dce..3b1f236aa 100644 --- a/src/xenia/kernel/objects/xthread.h +++ b/src/xenia/kernel/objects/xthread.h @@ -62,6 +62,7 @@ public: int32_t QueryPriority(); void SetPriority(int32_t increment); + void SetAffinity(uint32_t affinity); X_STATUS Resume(uint32_t* out_suspend_count); X_STATUS Suspend(uint32_t* out_suspend_count); diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index 0078dbfc7..4b6e72258 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -281,8 +281,7 @@ uint32_t xeKeSetAffinityThread(void* thread_ptr, uint32_t affinity) { XThread* thread = (XThread*)XObject::GetObject(state, thread_ptr); if (thread) { - // TODO(benvanik): implement. - XELOGW("KeSetAffinityThread not implemented"); + thread->SetAffinity(affinity); } return affinity; From 86241d0ae8e24182a1ab224484ea54c3d72a191f Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 5 Aug 2014 10:12:15 -0700 Subject: [PATCH 063/388] XNetCleanup/XNetRandom stubs. --- src/xenia/kernel/xam_net.cc | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/xenia/kernel/xam_net.cc b/src/xenia/kernel/xam_net.cc index 18094a2ed..7ba5b887b 100644 --- a/src/xenia/kernel/xam_net.cc +++ b/src/xenia/kernel/xam_net.cc @@ -38,6 +38,38 @@ SHIM_CALL NetDll_XNetStartup_shim( SHIM_SET_RETURN_64(0); } +SHIM_CALL NetDll_XNetCleanup_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t arg0 = SHIM_GET_ARG_32(0); + uint32_t params_ptr = SHIM_GET_ARG_32(1); + + XELOGD( + "NetDll_XNetCleanup(%d, %.8X)", + arg0, + params_ptr); + + SHIM_SET_RETURN_64(0); +} + +SHIM_CALL NetDll_XNetRandom_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t arg0 = SHIM_GET_ARG_32(0); + uint32_t buffer_ptr = SHIM_GET_ARG_32(1); + uint32_t length = SHIM_GET_ARG_32(2); + + XELOGD( + "NetDll_XNetRandom(%d, %.8X, %d)", + arg0, + buffer_ptr, + length); + + // For now, constant values. + // This makes replicating things easier. + memset(SHIM_MEM_ADDR(buffer_ptr), 0xBB, length); + + SHIM_SET_RETURN_64(0); +} + SHIM_CALL NetDll_WSAStartup_shim( PPCContext* ppc_state, KernelState* state) { uint32_t arg0 = SHIM_GET_ARG_32(0); @@ -213,6 +245,8 @@ SHIM_CALL NetDll_send_shim( void xe::kernel::xam::RegisterNetExports( ExportResolver* export_resolver, KernelState* state) { SHIM_SET_MAPPING("xam.xex", NetDll_XNetStartup, state); + SHIM_SET_MAPPING("xam.xex", NetDll_XNetCleanup, state); + SHIM_SET_MAPPING("xam.xex", NetDll_XNetRandom, state); SHIM_SET_MAPPING("xam.xex", NetDll_WSAStartup, state); SHIM_SET_MAPPING("xam.xex", NetDll_WSAGetLastError, state); SHIM_SET_MAPPING("xam.xex", NetDll_XNetGetTitleXnAddr, state); From 2854841753f3667c91ba443806ae0c2234f1a561 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 5 Aug 2014 10:44:55 -0700 Subject: [PATCH 064/388] Better XMsg errors. --- src/xenia/kernel/xam_msg.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xenia/kernel/xam_msg.cc b/src/xenia/kernel/xam_msg.cc index fa24c6e05..a4b61866b 100644 --- a/src/xenia/kernel/xam_msg.cc +++ b/src/xenia/kernel/xam_msg.cc @@ -38,7 +38,7 @@ SHIM_CALL XMsgInProcessCall_shim( auto result = state->app_manager()->DispatchMessageSync( app, message, arg1, arg2); if (result == X_ERROR_NOT_FOUND) { - XELOGE("XMsgStartIORequest: app not found"); + XELOGE("XMsgInProcessCall: app %.8X undefined", app); } SHIM_SET_RETURN_32(result); } @@ -61,7 +61,7 @@ SHIM_CALL XMsgStartIORequest_shim( auto result = state->app_manager()->DispatchMessageAsync( app, message, buffer, buffer_length); if (result == X_ERROR_NOT_FOUND) { - XELOGE("XMsgStartIORequest: app not found"); + XELOGE("XMsgStartIORequest: app %.8X undefined", app); } SHIM_SET_RETURN_32(result); } From 810c256f2114e458ad356a971c0750667fefcbf1 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 5 Aug 2014 11:48:45 -0700 Subject: [PATCH 065/388] Fix register allocator with STORE_LOCAL. May indicate redundant stores. --- src/alloy/compiler/passes/register_allocation_pass.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/alloy/compiler/passes/register_allocation_pass.cc b/src/alloy/compiler/passes/register_allocation_pass.cc index 6f5189ba7..00f60179a 100644 --- a/src/alloy/compiler/passes/register_allocation_pass.cc +++ b/src/alloy/compiler/passes/register_allocation_pass.cc @@ -112,9 +112,11 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) { if (!instr->src1_use->next) { // Pull off preferred register. We will try to reuse this for the // dest. - has_preferred_reg = true; - preferred_reg = instr->src1.value->reg; - assert_not_null(preferred_reg.set); + // NOTE: set may be null if this is a store local. + if (preferred_reg.set) { + has_preferred_reg = true; + preferred_reg = instr->src1.value->reg; + } } } From 07afc58264f0aeccd0bc1a02579c573f744f4f90 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 5 Aug 2014 11:49:59 -0700 Subject: [PATCH 066/388] Untested VECTOR_SHA 16 variable and VECTOR_SHL 16 variable. --- src/alloy/backend/x64/x64_emitter.cc | 4 ++++ src/alloy/backend/x64/x64_emitter.h | 2 ++ src/alloy/backend/x64/x64_sequences.cc | 32 +++++++++++++++++++++++++- 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index a30ccf053..b9850b80f 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -539,6 +539,10 @@ Address X64Emitter::GetXmmConstPtr(XmmConst id) { 0xFFFFFF0Cu, 0xFFFFFF0Fu), /* XMMOneOver255 */ vec128f(1.0f / 255.0f, 1.0f / 255.0f, 1.0f / 255.0f, 1.0f / 255.0f), + /* XMMMaskEvenPI16 */ vec128i(0x0000FFFFu, 0x0000FFFFu, + 0x0000FFFFu, 0x0000FFFFu), + /* XMMShiftMaskEvenPI16 */ vec128i(0x0000000Fu, 0x0000000Fu, + 0x0000000Fu, 0x0000000Fu), /* XMMShiftMaskPS */ vec128i(0x0000001Fu, 0x0000001Fu, 0x0000001Fu, 0x0000001Fu), /* XMMShiftByteMask */ vec128i(0x000000FFu, 0x000000FFu, diff --git a/src/alloy/backend/x64/x64_emitter.h b/src/alloy/backend/x64/x64_emitter.h index 086a1d689..414a94899 100644 --- a/src/alloy/backend/x64/x64_emitter.h +++ b/src/alloy/backend/x64/x64_emitter.h @@ -54,6 +54,8 @@ enum XmmConst { XMMPackD3DCOLOR, XMMUnpackD3DCOLOR, XMMOneOver255, + XMMMaskEvenPI16, + XMMShiftMaskEvenPI16, XMMShiftMaskPS, XMMShiftByteMask, XMMUnsignedDwordMax, diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index 52d4df79c..fb6e80d18 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -4150,7 +4150,23 @@ EMITTER(VECTOR_SHL_V128, MATCH(I, V128<>, V128<>>)) { } } else { // Fully variable shift. - assert_always(); + // TODO(benvanik): find a better sequence. + Xmm temp = i.dest; + if (i.dest == i.src1 || i.dest == i.src2) { + temp = e.xmm2; + } + // Even: + e.vpand(e.xmm0, i.src2, e.GetXmmConstPtr(XMMShiftMaskEvenPI16)); + e.vpsllvd(e.xmm1, i.src1, e.xmm0); + e.vpand(e.xmm1, e.GetXmmConstPtr(XMMMaskEvenPI16)); + // Odd: + e.vpsrld(e.xmm0, i.src2, 16); + e.vpand(e.xmm0, e.GetXmmConstPtr(XMMShiftMaskEvenPI16)); + e.vpsrld(i.dest, i.src1, 16); + e.vpsllvd(i.dest, i.dest, e.xmm0); + e.vpslld(i.dest, 8); + // Merge: + e.vpor(i.dest, e.xmm1); } } static void EmitInt32(X64Emitter& e, const EmitArgType& i) { @@ -4308,6 +4324,20 @@ EMITTER_OPCODE_TABLE( EMITTER(VECTOR_SHA_V128, MATCH(I, V128<>, V128<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { switch (i.instr->flags) { + case INT16_TYPE: + // Even halfwords: + e.vpand(e.xmm0, i.src2, e.GetXmmConstPtr(XMMShiftMaskEvenPI16)); + e.vpslld(e.xmm1, i.src1, 16); + e.vpsrad(e.xmm1, 8); + e.vpsravd(e.xmm1, e.xmm1, e.xmm0); + // Odd halfwords: + e.vpsrld(e.xmm0, i.src2, 16); + e.vpand(e.xmm0, e.GetXmmConstPtr(XMMShiftMaskEvenPI16)); + e.vpslld(i.dest, i.src1, 16); + e.vpsravd(i.dest, i.dest, e.xmm0); + // Merge: + e.vpor(i.dest, e.xmm1); + break; case INT32_TYPE: // src shift mask may have values >31, and x86 sets to zero when // that happens so we mask. From 1d7b08b85ba091a2b3a916e94a09cbba06d4c731 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 5 Aug 2014 12:05:27 -0700 Subject: [PATCH 067/388] dlmalloc does not fail when it runs out of memory... --- src/xenia/cpu/xenon_memory.cc | 1 + src/xenia/cpu/xenon_thread_state.cc | 1 + 2 files changed, 2 insertions(+) diff --git a/src/xenia/cpu/xenon_memory.cc b/src/xenia/cpu/xenon_memory.cc index dd277efac..37bac9c61 100644 --- a/src/xenia/cpu/xenon_memory.cc +++ b/src/xenia/cpu/xenon_memory.cc @@ -508,6 +508,7 @@ uint64_t XenonMemoryHeap::Alloc( space_, alignment, alloc_size + heap_guard_size * 2); + assert_true(reinterpret_cast(p) <= 0xFFFFFFFFFull); if (FLAGS_heap_guard_pages) { size_t real_size = mspace_usable_size(p); DWORD old_protect; diff --git a/src/xenia/cpu/xenon_thread_state.cc b/src/xenia/cpu/xenon_thread_state.cc index 9b09c5608..a3403f0d2 100644 --- a/src/xenia/cpu/xenon_thread_state.cc +++ b/src/xenia/cpu/xenon_thread_state.cc @@ -24,6 +24,7 @@ XenonThreadState::XenonThreadState(XenonRuntime* runtime, uint32_t thread_id, stack_size_(stack_size), thread_state_address_(thread_state_address) { stack_address_ = memory_->HeapAlloc(0, stack_size, MEMORY_FLAG_ZERO); + assert_not_zero(stack_address_); // Allocate with 64b alignment. context_ = (PPCContext*)xe_malloc_aligned(sizeof(PPCContext)); From 31f886d8d95713b6d7ba416900fb84b4620baadf Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 5 Aug 2014 12:05:45 -0700 Subject: [PATCH 068/388] Fixing overallocation of thread stacks (expending heap). --- src/xenia/kernel/objects/xthread.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index f10306baf..0b6b93d06 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -55,8 +55,8 @@ XThread::XThread(KernelState* kernel_state, creation_params_.creation_flags = creation_flags; // Adjust stack size - min of 16k. - if (creation_params_.stack_size < 16 * 1024 * 1024) { - creation_params_.stack_size = 16 * 1024 * 1024; + if (creation_params_.stack_size < 16 * 1024) { + creation_params_.stack_size = 16 * 1024; } apc_lock_ = xe_mutex_alloc(); From b58b7c17832742eaecb3721e16bd115df81a4fb8 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 5 Aug 2014 12:51:01 -0700 Subject: [PATCH 069/388] Debug cleanup. --- src/xenia/gpu/xenos/ucode_disassembler.cc | 8 ++++++-- src/xenia/kernel/xboxkrnl_rtl.cc | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/xenia/gpu/xenos/ucode_disassembler.cc b/src/xenia/gpu/xenos/ucode_disassembler.cc index 6a062f817..db3ad44eb 100644 --- a/src/xenia/gpu/xenos/ucode_disassembler.cc +++ b/src/xenia/gpu/xenos/ucode_disassembler.cc @@ -590,8 +590,12 @@ int disasm_fetch( dwords[0], dwords[1], dwords[2]); output->append(" %sFETCH:\t", sync ? "(S)" : " "); - output->append("%s", fetch_instructions[fetch->opc].name); - fetch_instructions[fetch->opc].fxn(output, fetch); + if (fetch_instructions[fetch->opc].fxn) { + output->append("%s", fetch_instructions[fetch->opc].name); + fetch_instructions[fetch->opc].fxn(output, fetch); + } else { + output->append("???"); + } output->append("\n"); return 0; diff --git a/src/xenia/kernel/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl_rtl.cc index 2f77b6995..97fe9efc5 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl_rtl.cc @@ -705,7 +705,7 @@ SHIM_CALL RtlTryEnterCriticalSection_shim( PPCContext* ppc_state, KernelState* state) { uint32_t cs_ptr = SHIM_GET_ARG_32(0); - XELOGD("RtlTryEnterCriticalSection(%.8X)", cs_ptr); + // XELOGD("RtlTryEnterCriticalSection(%.8X)", cs_ptr); const uint8_t* thread_state_block = ppc_state->membase + ppc_state->r[13]; uint32_t thread_id = XThread::GetCurrentThreadId(thread_state_block); From f149a23367acd39a6766ffd0ffeec14e822a40fe Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 5 Aug 2014 13:06:33 -0700 Subject: [PATCH 070/388] XUsbcamCreate stub. --- src/xenia/kernel/sources.gypi | 2 ++ src/xenia/kernel/xboxkrnl_module.cc | 1 + src/xenia/kernel/xboxkrnl_private.h | 1 + src/xenia/kernel/xboxkrnl_usbcam.cc | 45 +++++++++++++++++++++++++++++ src/xenia/kernel/xboxkrnl_usbcam.h | 28 ++++++++++++++++++ 5 files changed, 77 insertions(+) create mode 100644 src/xenia/kernel/xboxkrnl_usbcam.cc create mode 100644 src/xenia/kernel/xboxkrnl_usbcam.h diff --git a/src/xenia/kernel/sources.gypi b/src/xenia/kernel/sources.gypi index f6f5356d0..6b3fe4c2b 100644 --- a/src/xenia/kernel/sources.gypi +++ b/src/xenia/kernel/sources.gypi @@ -71,6 +71,8 @@ 'xboxkrnl_table.inc', 'xboxkrnl_threading.cc', 'xboxkrnl_threading.h', + 'xboxkrnl_usbcam.cc', + 'xboxkrnl_usbcam.h', 'xboxkrnl_video.cc', 'xboxkrnl_video.h', 'xobject.cc', diff --git a/src/xenia/kernel/xboxkrnl_module.cc b/src/xenia/kernel/xboxkrnl_module.cc index b695d44bc..4fe8c4ace 100644 --- a/src/xenia/kernel/xboxkrnl_module.cc +++ b/src/xenia/kernel/xboxkrnl_module.cc @@ -51,6 +51,7 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) : RegisterRtlExports(export_resolver_, kernel_state_); RegisterStringExports(export_resolver_, kernel_state_); RegisterThreadingExports(export_resolver_, kernel_state); + RegisterUsbcamExports(export_resolver_, kernel_state); RegisterVideoExports(export_resolver_, kernel_state); uint8_t* mem = memory_->membase(); diff --git a/src/xenia/kernel/xboxkrnl_private.h b/src/xenia/kernel/xboxkrnl_private.h index db1f66a7e..b0612f0ca 100644 --- a/src/xenia/kernel/xboxkrnl_private.h +++ b/src/xenia/kernel/xboxkrnl_private.h @@ -36,6 +36,7 @@ void RegisterRtlExports(ExportResolver* export_resolver, KernelState* state); void RegisterStringExports(ExportResolver* export_resolver, KernelState* state); void RegisterThreadingExports(ExportResolver* export_resolver, KernelState* state); +void RegisterUsbcamExports(ExportResolver* export_resolver, KernelState* state); void RegisterVideoExports(ExportResolver* export_resolver, KernelState* state); } // namespace xboxkrnl diff --git a/src/xenia/kernel/xboxkrnl_usbcam.cc b/src/xenia/kernel/xboxkrnl_usbcam.cc new file mode 100644 index 000000000..e30966e0f --- /dev/null +++ b/src/xenia/kernel/xboxkrnl_usbcam.cc @@ -0,0 +1,45 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include +#include +#include + + +using namespace xe; +using namespace xe::kernel; +using namespace xe::kernel::xboxkrnl; + + +namespace xe { +namespace kernel { + +SHIM_CALL XUsbcamCreate_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t unk1 = SHIM_GET_ARG_32(0); + uint32_t unk2 = SHIM_GET_ARG_32(1); + + XELOGD( + "XUsbcamCreate(%.8X, %.8X)", + unk1, unk2); + + SHIM_SET_RETURN_32(-1); +} + + +} // namespace kernel +} // namespace xe + + +void xe::kernel::xboxkrnl::RegisterUsbcamExports( + ExportResolver* export_resolver, KernelState* state) { + SHIM_SET_MAPPING("xboxkrnl.exe", XUsbcamCreate, state); +} diff --git a/src/xenia/kernel/xboxkrnl_usbcam.h b/src/xenia/kernel/xboxkrnl_usbcam.h new file mode 100644 index 000000000..7a69b65f6 --- /dev/null +++ b/src/xenia/kernel/xboxkrnl_usbcam.h @@ -0,0 +1,28 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_KERNEL_XBOXKRNL_USBCAM_H_ +#define XENIA_KERNEL_XBOXKRNL_USBCAM_H_ + +#include +#include + +#include + + +namespace xe { +namespace kernel { + + + +} // namespace kernel +} // namespace xe + + +#endif // XENIA_KERNEL_XBOXKRNL_USBCAM_H_ From 75eb87f33ddd4bc1299a112fd6872723f387f03e Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 5 Aug 2014 14:03:49 -0700 Subject: [PATCH 071/388] Adding VECTOR_SUB for vsub*. --- src/alloy/backend/ivm/ivm_intcode.cc | 40 ++++++++------ src/alloy/backend/x64/x64_sequences.cc | 61 ++++++++++++++++++++++ src/alloy/frontend/ppc/ppc_emit_altivec.cc | 58 +++++++++++++------- src/alloy/hir/hir_builder.cc | 17 ++++++ src/alloy/hir/hir_builder.h | 2 + src/alloy/hir/opcodes.h | 1 + src/alloy/hir/opcodes.inl | 6 +++ 7 files changed, 148 insertions(+), 37 deletions(-) diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index d69abd773..5e8d7c9c4 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -2735,6 +2735,12 @@ int Translate_SUB(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, fns[i->dest->type]); } +int Translate_VECTOR_SUB(TranslationContext& ctx, Instr* i) { + // TODO(benvanik): VECTOR_SUB in IVM. + assert_always(); + return 1; +} + uint32_t IntCode_MUL_I8_I8(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 * ics.rf[i->src2_reg].i8; return IA_NEXT; @@ -4200,23 +4206,23 @@ static const TranslateFn dispatch_table[] = { Translate_VECTOR_COMPARE_UGT, Translate_VECTOR_COMPARE_UGE, Translate_ADD, Translate_ADD_CARRY, Translate_VECTOR_ADD, Translate_SUB, - Translate_MUL, Translate_MUL_HI, - Translate_DIV, Translate_MUL_ADD, - Translate_MUL_SUB, Translate_NEG, - Translate_ABS, Translate_SQRT, - Translate_RSQRT, Translate_POW2, - Translate_LOG2, Translate_DOT_PRODUCT_3, - Translate_DOT_PRODUCT_4, Translate_AND, - Translate_OR, Translate_XOR, - Translate_NOT, Translate_SHL, - Translate_VECTOR_SHL, Translate_SHR, - Translate_VECTOR_SHR, Translate_SHA, - Translate_VECTOR_SHA, Translate_ROTATE_LEFT, - Translate_BYTE_SWAP, Translate_CNTLZ, - Translate_INSERT, Translate_EXTRACT, - Translate_SPLAT, Translate_PERMUTE, - Translate_SWIZZLE, Translate_PACK, - Translate_UNPACK, + Translate_VECTOR_SUB, Translate_MUL, + Translate_MUL_HI, Translate_DIV, + Translate_MUL_ADD, Translate_MUL_SUB, + Translate_NEG, Translate_ABS, + Translate_SQRT, Translate_RSQRT, + Translate_POW2, Translate_LOG2, + Translate_DOT_PRODUCT_3, Translate_DOT_PRODUCT_4, + Translate_AND, Translate_OR, + Translate_XOR, Translate_NOT, + Translate_SHL, Translate_VECTOR_SHL, + Translate_SHR, Translate_VECTOR_SHR, + Translate_SHA, Translate_VECTOR_SHA, + Translate_ROTATE_LEFT, Translate_BYTE_SWAP, + Translate_CNTLZ, Translate_INSERT, + Translate_EXTRACT, Translate_SPLAT, + Translate_PERMUTE, Translate_SWIZZLE, + Translate_PACK, Translate_UNPACK, TranslateInvalid, // Translate_COMPARE_EXCHANGE, Translate_ATOMIC_EXCHANGE, TranslateInvalid, // Translate_ATOMIC_ADD, diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index fb6e80d18..aaa34ff2c 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -2854,6 +2854,66 @@ EMITTER_OPCODE_TABLE( SUB_V128); +// ============================================================================ +// OPCODE_VECTOR_SUB +// ============================================================================ +EMITTER(VECTOR_SUB, MATCH(I, V128<>, V128<>>)) { + static void Emit(X64Emitter& e, const EmitArgType& i) { + EmitCommutativeBinaryXmmOp(e, i, + [&i](X64Emitter& e, const Xmm& dest, const Xmm& src1, const Xmm& src2) { + const TypeName part_type = static_cast(i.instr->flags & 0xFF); + const uint32_t arithmetic_flags = i.instr->flags >> 8; + bool is_unsigned = !!(arithmetic_flags & ARITHMETIC_UNSIGNED); + bool saturate = !!(arithmetic_flags & ARITHMETIC_SATURATE); + switch (part_type) { + case INT8_TYPE: + if (saturate) { + // TODO(benvanik): trace DID_SATURATE + if (is_unsigned) { + e.vpsubusb(dest, src1, src2); + } else { + e.vpsubsb(dest, src1, src2); + } + } else { + e.vpsubb(dest, src1, src2); + } + break; + case INT16_TYPE: + if (saturate) { + // TODO(benvanik): trace DID_SATURATE + if (is_unsigned) { + e.vpsubusw(dest, src1, src2); + } else { + e.vpsubsw(dest, src1, src2); + } + } else { + e.vpsubw(dest, src1, src2); + } + break; + case INT32_TYPE: + if (saturate) { + if (is_unsigned) { + assert_always(); + } else { + assert_always(); + } + } else { + e.vpsubd(dest, src1, src2); + } + break; + case FLOAT32_TYPE: + e.vsubps(dest, src1, src2); + break; + default: assert_unhandled_case(part_type); break; + } + }); + } +}; +EMITTER_OPCODE_TABLE( + OPCODE_VECTOR_SUB, + VECTOR_SUB); + + // ============================================================================ // OPCODE_MUL // ============================================================================ @@ -5202,6 +5262,7 @@ void RegisterSequences() { REGISTER_EMITTER_OPCODE_TABLE(OPCODE_ADD_CARRY); REGISTER_EMITTER_OPCODE_TABLE(OPCODE_VECTOR_ADD); REGISTER_EMITTER_OPCODE_TABLE(OPCODE_SUB); + REGISTER_EMITTER_OPCODE_TABLE(OPCODE_VECTOR_SUB); REGISTER_EMITTER_OPCODE_TABLE(OPCODE_MUL); REGISTER_EMITTER_OPCODE_TABLE(OPCODE_MUL_HI); REGISTER_EMITTER_OPCODE_TABLE(OPCODE_DIV); diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index c3915c258..46288ad80 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -1572,18 +1572,27 @@ XEEMITTER(vsubfp128, VX128(5, 80), VX128)(PPCHIRBuilder& f, InstrData& i) { } XEEMITTER(vsubsbs, 0x10000700, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD) <- clamp(EXTS(VA) + ¬EXTS(VB) + 1, -128, 127) + Value* v = f.VectorSub(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT8_TYPE, + ARITHMETIC_SATURATE); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vsubshs, 0x10000740, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD) <- clamp(EXTS(VA) + ¬EXTS(VB) + 1, -2^15, 2^15-1) + Value* v = f.VectorSub(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT16_TYPE, + ARITHMETIC_SATURATE); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vsubsws, 0x10000780, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD) <- clamp(EXTS(VA) + ¬EXTS(VB) + 1, -2^31, 2^31-1) + Value* v = f.VectorSub(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT32_TYPE, + ARITHMETIC_SATURATE); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vsububm, 0x10000400, VX)(PPCHIRBuilder& f, InstrData& i) { @@ -1591,29 +1600,38 @@ XEEMITTER(vsububm, 0x10000400, VX)(PPCHIRBuilder& f, InstrData& i) { return 1; } -XEEMITTER(vsububs, 0x10000600, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; -} - XEEMITTER(vsubuhm, 0x10000440, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } -XEEMITTER(vsubuhs, 0x10000640, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; -} - XEEMITTER(vsubuwm, 0x10000480, VX)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } +XEEMITTER(vsububs, 0x10000600, VX)(PPCHIRBuilder& f, InstrData& i) { + // (VD) <- clamp(EXTZ(VA) + ¬EXTZ(VB) + 1, 0, 256) + Value* v = f.VectorSub(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT8_TYPE, + ARITHMETIC_SATURATE | ARITHMETIC_UNSIGNED); + f.StoreVR(i.VX.VD, v); + return 0; +} + +XEEMITTER(vsubuhs, 0x10000640, VX)(PPCHIRBuilder& f, InstrData& i) { + // (VD) <- clamp(EXTZ(VA) + ¬EXTZ(VB) + 1, 0, 2^16-1) + Value* v = f.VectorSub(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT16_TYPE, + ARITHMETIC_SATURATE | ARITHMETIC_UNSIGNED); + f.StoreVR(i.VX.VD, v); + return 0; +} + XEEMITTER(vsubuws, 0x10000680, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD) <- clamp(EXTZ(VA) + ¬EXTZ(VB) + 1, 0, 2^32-1) + Value* v = f.VectorSub(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT32_TYPE, + ARITHMETIC_SATURATE | ARITHMETIC_UNSIGNED); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vsumsws, 0x10000788, VX)(PPCHIRBuilder& f, InstrData& i) { @@ -2132,10 +2150,10 @@ void RegisterEmitCategoryAltivec() { XEREGISTERINSTR(vsubshs, 0x10000740); XEREGISTERINSTR(vsubsws, 0x10000780); XEREGISTERINSTR(vsububm, 0x10000400); - XEREGISTERINSTR(vsububs, 0x10000600); XEREGISTERINSTR(vsubuhm, 0x10000440); - XEREGISTERINSTR(vsubuhs, 0x10000640); XEREGISTERINSTR(vsubuwm, 0x10000480); + XEREGISTERINSTR(vsububs, 0x10000600); + XEREGISTERINSTR(vsubuhs, 0x10000640); XEREGISTERINSTR(vsubuws, 0x10000680); XEREGISTERINSTR(vsumsws, 0x10000788); XEREGISTERINSTR(vsum2sws, 0x10000688); diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index acdb6b95a..30ac78358 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -1299,6 +1299,23 @@ Value* HIRBuilder::Sub(Value* value1, Value* value2, return i->dest; } +Value* HIRBuilder::VectorSub(Value* value1, Value* value2, TypeName part_type, + uint32_t arithmetic_flags) { + ASSERT_VECTOR_TYPE(value1); + ASSERT_VECTOR_TYPE(value2); + + // This is shady. + uint32_t flags = part_type | (arithmetic_flags << 8); + assert_zero(flags >> 16); + + Instr* i = AppendInstr(OPCODE_VECTOR_SUB_info, (uint16_t)flags, + AllocValue(value1->type)); + i->set_src1(value1); + i->set_src2(value2); + i->src3.value = NULL; + return i->dest; +} + Value* HIRBuilder::Mul(Value* value1, Value* value2, uint32_t arithmetic_flags) { ASSERT_TYPES_EQUAL(value1, value2); diff --git a/src/alloy/hir/hir_builder.h b/src/alloy/hir/hir_builder.h index 8bcd53c33..44f149b8b 100644 --- a/src/alloy/hir/hir_builder.h +++ b/src/alloy/hir/hir_builder.h @@ -169,6 +169,8 @@ class HIRBuilder { Value* VectorAdd(Value* value1, Value* value2, TypeName part_type, uint32_t arithmetic_flags = 0); Value* Sub(Value* value1, Value* value2, uint32_t arithmetic_flags = 0); + Value* VectorSub(Value* value1, Value* value2, TypeName part_type, + uint32_t arithmetic_flags = 0); Value* Mul(Value* value1, Value* value2, uint32_t arithmetic_flags = 0); Value* MulHi(Value* value1, Value* value2, uint32_t arithmetic_flags = 0); Value* Div(Value* value1, Value* value2, uint32_t arithmetic_flags = 0); diff --git a/src/alloy/hir/opcodes.h b/src/alloy/hir/opcodes.h index c163ca5d0..c7b3c0e50 100644 --- a/src/alloy/hir/opcodes.h +++ b/src/alloy/hir/opcodes.h @@ -140,6 +140,7 @@ enum Opcode { OPCODE_ADD_CARRY, OPCODE_VECTOR_ADD, OPCODE_SUB, + OPCODE_VECTOR_SUB, OPCODE_MUL, OPCODE_MUL_HI, // TODO(benvanik): remove this and add INT128 type. OPCODE_DIV, diff --git a/src/alloy/hir/opcodes.inl b/src/alloy/hir/opcodes.inl index b09ea29c7..b1c153c71 100644 --- a/src/alloy/hir/opcodes.inl +++ b/src/alloy/hir/opcodes.inl @@ -389,6 +389,12 @@ DEFINE_OPCODE( OPCODE_SIG_V_V_V, 0) +DEFINE_OPCODE( + OPCODE_VECTOR_SUB, + "vector_sub", + OPCODE_SIG_V_V_V, + 0) + DEFINE_OPCODE( OPCODE_MUL, "mul", From f668dcd56b36cbcb2b13ecd6c665ea446e449d2c Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 5 Aug 2014 14:59:48 -0700 Subject: [PATCH 072/388] cr* operations. --- src/alloy/frontend/ppc/ppc_emit_control.cc | 64 ++++++++++++++++------ src/alloy/frontend/ppc/ppc_hir_builder.cc | 4 ++ src/alloy/frontend/ppc/ppc_hir_builder.h | 1 + 3 files changed, 53 insertions(+), 16 deletions(-) diff --git a/src/alloy/frontend/ppc/ppc_emit_control.cc b/src/alloy/frontend/ppc/ppc_emit_control.cc index 439a1f02d..5b409eaa4 100644 --- a/src/alloy/frontend/ppc/ppc_emit_control.cc +++ b/src/alloy/frontend/ppc/ppc_emit_control.cc @@ -338,43 +338,75 @@ XEEMITTER(bclrx, 0x4C000020, XL)(PPCHIRBuilder& f, InstrData& i) { // Condition register logical (A-23) XEEMITTER(crand, 0x4C000202, XL)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // CR[bt] <- CR[ba] & CR[bb] bt=bo, ba=bi, bb=bb + Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3); + Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3); + Value* bt = f.And(ba, bb); + f.StoreCRField(i.XL.BO >> 2, i.XL.BO & 3, bt); + return 0; } XEEMITTER(crandc, 0x4C000102, XL)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // CR[bt] <- CR[ba] & ¬CR[bb] bt=bo, ba=bi, bb=bb + Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3); + Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3); + Value* bt = f.And(ba, f.Not(bb)); + f.StoreCRField(i.XL.BO >> 2, i.XL.BO & 3, bt); + return 0; } XEEMITTER(creqv, 0x4C000242, XL)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // CR[bt] <- CR[ba] == CR[bb] bt=bo, ba=bi, bb=bb + Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3); + Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3); + Value* bt = f.CompareEQ(ba, bb); + f.StoreCRField(i.XL.BO >> 2, i.XL.BO & 3, bt); + return 0; } XEEMITTER(crnand, 0x4C0001C2, XL)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // CR[bt] <- ¬(CR[ba] & CR[bb]) bt=bo, ba=bi, bb=bb + Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3); + Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3); + Value* bt = f.Not(f.And(ba, bb)); + f.StoreCRField(i.XL.BO >> 2, i.XL.BO & 3, bt); + return 0; } XEEMITTER(crnor, 0x4C000042, XL)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // CR[bt] <- ¬(CR[ba] | CR[bb]) bt=bo, ba=bi, bb=bb + Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3); + Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3); + Value* bt = f.Not(f.Or(ba, bb)); + f.StoreCRField(i.XL.BO >> 2, i.XL.BO & 3, bt); + return 0; } XEEMITTER(cror, 0x4C000382, XL)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // CR[bt] <- CR[ba] | CR[bb] bt=bo, ba=bi, bb=bb + Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3); + Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3); + Value* bt = f.Or(ba, bb); + f.StoreCRField(i.XL.BO >> 2, i.XL.BO & 3, bt); + return 0; } XEEMITTER(crorc, 0x4C000342, XL)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // CR[bt] <- CR[ba] | ¬CR[bb] bt=bo, ba=bi, bb=bb + Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3); + Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3); + Value* bt = f.Or(ba, f.Not(bb)); + f.StoreCRField(i.XL.BO >> 2, i.XL.BO & 3, bt); + return 0; } XEEMITTER(crxor, 0x4C000182, XL)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // CR[bt] <- CR[ba] xor CR[bb] bt=bo, ba=bi, bb=bb + Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3); + Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3); + Value* bt = f.Xor(ba, bb); + f.StoreCRField(i.XL.BO >> 2, i.XL.BO & 3, bt); + return 0; } XEEMITTER(mcrf, 0x4C000000, XL)(PPCHIRBuilder& f, InstrData& i) { diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index da30e8971..64bf1dae4 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -230,6 +230,10 @@ void PPCHIRBuilder::StoreCR(uint32_t n, Value* value) { assert_always(); } +void PPCHIRBuilder::StoreCRField(uint32_t n, uint32_t bit, Value* value) { + StoreContext(offsetof(PPCContext, cr0) + (4 * n) + bit, value); +} + void PPCHIRBuilder::UpdateCR(uint32_t n, Value* lhs, bool is_signed) { UpdateCR(n, lhs, LoadZero(lhs->type), is_signed); } diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.h b/src/alloy/frontend/ppc/ppc_hir_builder.h index 120bc4d3c..67aeb350b 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.h +++ b/src/alloy/frontend/ppc/ppc_hir_builder.h @@ -46,6 +46,7 @@ class PPCHIRBuilder : public hir::HIRBuilder { Value* LoadCR(uint32_t n); Value* LoadCRField(uint32_t n, uint32_t bit); void StoreCR(uint32_t n, Value* value); + void StoreCRField(uint32_t n, uint32_t bit, Value* value); void UpdateCR(uint32_t n, Value* lhs, bool is_signed = true); void UpdateCR(uint32_t n, Value* lhs, Value* rhs, bool is_signed = true); void UpdateCR6(Value* src_value); From 333fc71b44e5af706d7c2d8e2a1fc34b02caaa86 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 5 Aug 2014 15:14:01 -0700 Subject: [PATCH 073/388] vsubu*m --- src/alloy/frontend/ppc/ppc_emit_altivec.cc | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index 46288ad80..04ab5eebf 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -1596,18 +1596,27 @@ XEEMITTER(vsubsws, 0x10000780, VX)(PPCHIRBuilder& f, InstrData& i) { } XEEMITTER(vsububm, 0x10000400, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD) <- (EXTZ(VA) + ¬EXTZ(VB) + 1) % 256 + Value* v = f.VectorSub(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT8_TYPE, + ARITHMETIC_UNSIGNED); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vsubuhm, 0x10000440, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD) <- (EXTZ(VA) + ¬EXTZ(VB) + 1) % 2^16 + Value* v = f.VectorSub(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT16_TYPE, + ARITHMETIC_UNSIGNED); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vsubuwm, 0x10000480, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD) <- (EXTZ(VA) + ¬EXTZ(VB) + 1) % 2^32 + Value* v = f.VectorSub(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT32_TYPE, + ARITHMETIC_UNSIGNED); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vsububs, 0x10000600, VX)(PPCHIRBuilder& f, InstrData& i) { From ff59f23de07b95b1a66c2063bf5ad53c51ba74d3 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 5 Aug 2014 18:57:34 -0700 Subject: [PATCH 074/388] VectorRotateLeft for vrl*. --- src/alloy/backend/ivm/ivm_intcode.cc | 36 +++++------ src/alloy/backend/x64/x64_emitter.cc | 1 + src/alloy/backend/x64/x64_emitter.h | 1 + src/alloy/backend/x64/x64_sequences.cc | 71 ++++++++++++++++++++++ src/alloy/frontend/ppc/ppc_emit_altivec.cc | 24 +++++--- src/alloy/hir/hir_builder.cc | 11 ++++ src/alloy/hir/hir_builder.h | 1 + src/alloy/hir/opcodes.h | 1 + src/alloy/hir/opcodes.inl | 6 ++ src/poly/math.h | 23 +++++++ 10 files changed, 150 insertions(+), 25 deletions(-) diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index 5e8d7c9c4..741b167ae 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -3640,30 +3640,26 @@ int Translate_VECTOR_SHA(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, fns[i->flags]); } -template -T ROTL(T v, int8_t sh) { - return (T(v) << sh) | (T(v) >> ((sizeof(T) * 8) - sh)); -} uint32_t IntCode_ROTATE_LEFT_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = - ROTL(ics.rf[i->src1_reg].i8, ics.rf[i->src2_reg].i8); + ics.rf[i->dest_reg].i8 = poly::rotate_left(ics.rf[i->src1_reg].i8, + ics.rf[i->src2_reg].i8); return IA_NEXT; } uint32_t IntCode_ROTATE_LEFT_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = - ROTL(ics.rf[i->src1_reg].i16, ics.rf[i->src2_reg].i8); + ics.rf[i->dest_reg].i16 = poly::rotate_left(ics.rf[i->src1_reg].i16, + ics.rf[i->src2_reg].i8); return IA_NEXT; } uint32_t IntCode_ROTATE_LEFT_I32(IntCodeState& ics, const IntCode* i) { // TODO(benvanik): use _rtol on vc++ - ics.rf[i->dest_reg].i32 = - ROTL(ics.rf[i->src1_reg].i32, ics.rf[i->src2_reg].i8); + ics.rf[i->dest_reg].i32 = poly::rotate_left(ics.rf[i->src1_reg].i32, + ics.rf[i->src2_reg].i8); return IA_NEXT; } uint32_t IntCode_ROTATE_LEFT_I64(IntCodeState& ics, const IntCode* i) { // TODO(benvanik): use _rtol64 on vc++ - ics.rf[i->dest_reg].i64 = - ROTL(ics.rf[i->src1_reg].i64, ics.rf[i->src2_reg].i8); + ics.rf[i->dest_reg].i64 = poly::rotate_left(ics.rf[i->src1_reg].i64, + ics.rf[i->src2_reg].i8); return IA_NEXT; } int Translate_ROTATE_LEFT(TranslationContext& ctx, Instr* i) { @@ -3675,6 +3671,11 @@ int Translate_ROTATE_LEFT(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, fns[i->dest->type]); } +int Translate_VECTOR_ROTATE_LEFT(TranslationContext& ctx, Instr* i) { + assert_always(); + return 1; +} + uint32_t IntCode_BYTE_SWAP_I16(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].i16 = poly::byte_swap(ics.rf[i->src1_reg].i16); return IA_NEXT; @@ -4218,11 +4219,12 @@ static const TranslateFn dispatch_table[] = { Translate_SHL, Translate_VECTOR_SHL, Translate_SHR, Translate_VECTOR_SHR, Translate_SHA, Translate_VECTOR_SHA, - Translate_ROTATE_LEFT, Translate_BYTE_SWAP, - Translate_CNTLZ, Translate_INSERT, - Translate_EXTRACT, Translate_SPLAT, - Translate_PERMUTE, Translate_SWIZZLE, - Translate_PACK, Translate_UNPACK, + Translate_ROTATE_LEFT, Translate_VECTOR_ROTATE_LEFT, + Translate_BYTE_SWAP, Translate_CNTLZ, + Translate_INSERT, Translate_EXTRACT, + Translate_SPLAT, Translate_PERMUTE, + Translate_SWIZZLE, Translate_PACK, + Translate_UNPACK, TranslateInvalid, // Translate_COMPARE_EXCHANGE, Translate_ATOMIC_EXCHANGE, TranslateInvalid, // Translate_ATOMIC_ADD, diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index b9850b80f..a7997334c 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -550,6 +550,7 @@ Address X64Emitter::GetXmmConstPtr(XmmConst id) { /* XMMUnsignedDwordMax */ vec128i(0xFFFFFFFFu, 0x00000000u, 0xFFFFFFFFu, 0x00000000u), /* XMM255 */ vec128f(255.0f, 255.0f, 255.0f, 255.0f), + /* XMMPI32 */ vec128i(32, 32, 32, 32), /* XMMSignMaskI8 */ vec128i(0x80808080u, 0x80808080u, 0x80808080u, 0x80808080u), /* XMMSignMaskI16 */ vec128i(0x80008000u, 0x80008000u, diff --git a/src/alloy/backend/x64/x64_emitter.h b/src/alloy/backend/x64/x64_emitter.h index 414a94899..785108d71 100644 --- a/src/alloy/backend/x64/x64_emitter.h +++ b/src/alloy/backend/x64/x64_emitter.h @@ -60,6 +60,7 @@ enum XmmConst { XMMShiftByteMask, XMMUnsignedDwordMax, XMM255, + XMMPI32, XMMSignMaskI8, XMMSignMaskI16, XMMSignMaskI32, diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index aaa34ff2c..064c76295 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -4475,6 +4475,76 @@ EMITTER_OPCODE_TABLE( ROTATE_LEFT_I64); +// ============================================================================ +// OPCODE_VECTOR_ROTATE_LEFT +// ============================================================================ +// TODO(benvanik): AVX512 has a native variable rotate (rolv). +EMITTER(VECTOR_ROTATE_LEFT_V128, MATCH(I, V128<>, V128<>>)) { + static __m128i EmulateVectorRotateLeftI8(__m128i src1, __m128i src2) { + alignas(16) __m128i value; + alignas(16) __m128i shamt; + _mm_store_si128(&value, src1); + _mm_store_si128(&shamt, src2); + for (size_t i = 0; i < 16; ++i) { + value.m128i_u8[i] = poly::rotate_left( + value.m128i_u8[i], shamt.m128i_u8[i] & 0x3); + } + return _mm_load_si128(&value); + } + static __m128i EmulateVectorRotateLeftI16(__m128i src1, __m128i src2) { + alignas(16) __m128i value; + alignas(16) __m128i shamt; + _mm_store_si128(&value, src1); + _mm_store_si128(&shamt, src2); + for (size_t i = 0; i < 8; ++i) { + value.m128i_u16[i] = poly::rotate_left( + value.m128i_u16[i], shamt.m128i_u16[i] & 0xF); + } + return _mm_load_si128(&value); + } + static void Emit(X64Emitter& e, const EmitArgType& i) { + switch (i.instr->flags) { + case INT8_TYPE: + // TODO(benvanik): native version (with shift magic). + e.lea(e.r8, e.StashXmm(i.src1)); + e.lea(e.r9, e.StashXmm(i.src2)); + e.CallNativeSafe(reinterpret_cast(EmulateVectorRotateLeftI8)); + e.vmovaps(i.dest, e.xmm0); + break; + case INT16_TYPE: + // TODO(benvanik): native version (with shift magic). + e.lea(e.r8, e.StashXmm(i.src1)); + e.lea(e.r9, e.StashXmm(i.src2)); + e.CallNativeSafe(reinterpret_cast(EmulateVectorRotateLeftI16)); + e.vmovaps(i.dest, e.xmm0); + break; + case INT32_TYPE: { + Xmm temp = i.dest; + if (i.dest == i.src1 || i.dest == i.src2) { + temp = e.xmm2; + } + // Shift left (to get high bits): + e.vpand(e.xmm0, i.src2, e.GetXmmConstPtr(XMMShiftMaskPS)); + e.vpsllvd(e.xmm1, i.src1, e.xmm0); + // Shift right (to get low bits): + e.vmovaps(temp, e.GetXmmConstPtr(XMMPI32)); + e.vpsubd(temp, e.xmm0); + e.vpsrlvd(i.dest, i.src1, e.xmm0); + // Merge: + e.vpor(i.dest, e.xmm1); + break; + } + default: + assert_always(); + break; + } + } +}; +EMITTER_OPCODE_TABLE( + OPCODE_VECTOR_ROTATE_LEFT, + VECTOR_ROTATE_LEFT_V128); + + // ============================================================================ // OPCODE_BYTE_SWAP // ============================================================================ @@ -5287,6 +5357,7 @@ void RegisterSequences() { REGISTER_EMITTER_OPCODE_TABLE(OPCODE_VECTOR_SHR); REGISTER_EMITTER_OPCODE_TABLE(OPCODE_VECTOR_SHA); REGISTER_EMITTER_OPCODE_TABLE(OPCODE_ROTATE_LEFT); + REGISTER_EMITTER_OPCODE_TABLE(OPCODE_VECTOR_ROTATE_LEFT); REGISTER_EMITTER_OPCODE_TABLE(OPCODE_BYTE_SWAP); REGISTER_EMITTER_OPCODE_TABLE(OPCODE_CNTLZ); //REGISTER_EMITTER_OPCODE_TABLE(OPCODE_INSERT); diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index 04ab5eebf..a75c20026 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -1212,22 +1212,30 @@ XEEMITTER(vrfiz128, VX128_3(6, 1008), VX128_3)(PPCHIRBuilder& f, InstrData& i) { } XEEMITTER(vrlb, 0x10000004, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD) <- ROTL((VA), (VB)&0x3) + Value* v = f.VectorRotateLeft(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT8_TYPE); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vrlh, 0x10000044, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD) <- ROTL((VA), (VB)&0xF) + Value* v = f.VectorRotateLeft(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT16_TYPE); + f.StoreVR(i.VX.VD, v); + return 0; } +int InstrEmit_vrlw_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { + // (VD) <- ROTL((VA), (VB)&0x1F) + Value* v = f.VectorRotateLeft(f.LoadVR(va), f.LoadVR(vb), INT32_TYPE); + f.StoreVR(vd, v); + return 0; +} XEEMITTER(vrlw, 0x10000084, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + return InstrEmit_vrlw_(f, i.VX.VD, i.VX.VA, i.VX.VB); } XEEMITTER(vrlw128, VX128(6, 80), VX128)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + return InstrEmit_vrlw_(f, VX128_VD128, VX128_VA128, VX128_VB128); } XEEMITTER(vrlimi128, VX128_4(6, 1808), VX128_4)(PPCHIRBuilder& f, diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index 30ac78358..29d404af1 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -1661,6 +1661,17 @@ Value* HIRBuilder::RotateLeft(Value* value1, Value* value2) { return i->dest; } +Value* HIRBuilder::VectorRotateLeft(Value* value1, Value* value2, TypeName part_type) { + ASSERT_VECTOR_TYPE(value1); + ASSERT_VECTOR_TYPE(value2); + + Instr* i = AppendInstr(OPCODE_VECTOR_ROTATE_LEFT_info, part_type, AllocValue(value1->type)); + i->set_src1(value1); + i->set_src2(value2); + i->src3.value = NULL; + return i->dest; +} + Value* HIRBuilder::ByteSwap(Value* value) { if (value->type == INT8_TYPE) { return value; diff --git a/src/alloy/hir/hir_builder.h b/src/alloy/hir/hir_builder.h index 44f149b8b..c4440e6b5 100644 --- a/src/alloy/hir/hir_builder.h +++ b/src/alloy/hir/hir_builder.h @@ -199,6 +199,7 @@ class HIRBuilder { Value* Sha(Value* value1, int8_t value2); Value* VectorSha(Value* value1, Value* value2, TypeName part_type); Value* RotateLeft(Value* value1, Value* value2); + Value* VectorRotateLeft(Value* value1, Value* value2, TypeName part_type); Value* ByteSwap(Value* value); Value* CountLeadingZeros(Value* value); Value* Insert(Value* value, Value* index, Value* part); diff --git a/src/alloy/hir/opcodes.h b/src/alloy/hir/opcodes.h index c7b3c0e50..ca63f69eb 100644 --- a/src/alloy/hir/opcodes.h +++ b/src/alloy/hir/opcodes.h @@ -165,6 +165,7 @@ enum Opcode { OPCODE_SHA, OPCODE_VECTOR_SHA, OPCODE_ROTATE_LEFT, + OPCODE_VECTOR_ROTATE_LEFT, OPCODE_BYTE_SWAP, OPCODE_CNTLZ, OPCODE_INSERT, diff --git a/src/alloy/hir/opcodes.inl b/src/alloy/hir/opcodes.inl index b1c153c71..14c1dbf8b 100644 --- a/src/alloy/hir/opcodes.inl +++ b/src/alloy/hir/opcodes.inl @@ -539,6 +539,12 @@ DEFINE_OPCODE( OPCODE_SIG_V_V_V, 0) +DEFINE_OPCODE( + OPCODE_VECTOR_ROTATE_LEFT, + "vector_rotate_left", + OPCODE_SIG_V_V_V, + 0) + DEFINE_OPCODE( OPCODE_BYTE_SWAP, "byte_swap", diff --git a/src/poly/math.h b/src/poly/math.h index 57b0190d1..1783eb02a 100644 --- a/src/poly/math.h +++ b/src/poly/math.h @@ -108,6 +108,29 @@ inline bool bit_scan_forward(int64_t v, uint32_t* out_first_set_index) { return bit_scan_forward(static_cast(v), out_first_set_index); } +template +inline T rotate_left(T v, uint8_t sh) { + return (T(v) << sh) | (T(v) >> ((sizeof(T) * 8) - sh)); +} +#if XE_COMPILER_MSVC +template <> +inline uint8_t rotate_left(uint8_t v, uint8_t sh) { + return _rotl8(v, sh); +} +template <> +inline uint16_t rotate_left(uint16_t v, uint8_t sh) { + return _rotl16(v, sh); +} +template <> +inline uint32_t rotate_left(uint32_t v, uint8_t sh) { + return _rotl(v, sh); +} +template <> +inline uint64_t rotate_left(uint64_t v, uint8_t sh) { + return _rotl64(v, sh); +} +#endif // XE_COMPILER_MSVC + // Utilities for SSE values. template float m128_f32(const __m128& v) { From 19274ef26d65303294cfc5a37e2b28536fc1cffc Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 6 Aug 2014 09:00:59 -0700 Subject: [PATCH 075/388] Better validation that values aren't moving between blocks. --- src/alloy/compiler/passes/register_allocation_pass.cc | 6 +++++- src/alloy/compiler/passes/register_allocation_pass.h | 3 ++- src/alloy/compiler/passes/validation_pass.cc | 9 +++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/alloy/compiler/passes/register_allocation_pass.cc b/src/alloy/compiler/passes/register_allocation_pass.cc index 00f60179a..1481e80d4 100644 --- a/src/alloy/compiler/passes/register_allocation_pass.cc +++ b/src/alloy/compiler/passes/register_allocation_pass.cc @@ -143,7 +143,7 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) { if (!allocated) { // Failed to allocate register -- need to spill and try again. // We spill only those registers we aren't using. - if (!SpillOneRegister(builder, instr->dest->type)) { + if (!SpillOneRegister(builder, block, instr->dest->type)) { // Unable to spill anything - this shouldn't happen. XELOGE("Unable to spill any registers"); assert_always(); @@ -237,6 +237,8 @@ void RegisterAllocationPass::AdvanceUses(Instr* instr) { // Remove the iterator. auto value = it->value; it = upcoming_uses.erase(it); + assert_true(next_use->instr->block == instr->block); + assert_true(value->def->block == instr->block); upcoming_uses.emplace_back(value, next_use); } } @@ -336,6 +338,8 @@ bool RegisterAllocationPass::SpillOneRegister(HIRBuilder* builder, auto furthest_usage = std::max_element(usage_set->upcoming_uses.begin(), usage_set->upcoming_uses.end(), RegisterUsage::Comparer()); + assert_true(furthest_usage->value->def->block == block); + assert_true(furthest_usage->use->instr->block == block); auto spill_value = furthest_usage->value; Value::Use* prev_use = furthest_usage->use->prev; Value::Use* next_use = furthest_usage->use; diff --git a/src/alloy/compiler/passes/register_allocation_pass.h b/src/alloy/compiler/passes/register_allocation_pass.h index aa8b03fb2..6090ed527 100644 --- a/src/alloy/compiler/passes/register_allocation_pass.h +++ b/src/alloy/compiler/passes/register_allocation_pass.h @@ -62,7 +62,8 @@ class RegisterAllocationPass : public CompilerPass { bool TryAllocateRegister(hir::Value* value, const hir::RegAssignment& preferred_reg); bool TryAllocateRegister(hir::Value* value); - bool SpillOneRegister(hir::HIRBuilder* builder, hir::TypeName required_type); + bool SpillOneRegister(hir::HIRBuilder* builder, hir::Block* block, + hir::TypeName required_type); RegisterSetUsage* RegisterSetForValue(const hir::Value* value); diff --git a/src/alloy/compiler/passes/validation_pass.cc b/src/alloy/compiler/passes/validation_pass.cc index 27e85f7b6..bc6c8d536 100644 --- a/src/alloy/compiler/passes/validation_pass.cc +++ b/src/alloy/compiler/passes/validation_pass.cc @@ -72,6 +72,15 @@ int ValidationPass::ValidateInstruction(Block* block, Instr* instr) { return 1; } + if (instr->dest) { + assert_true(instr->dest->def == instr); + auto use = instr->dest->use_head; + while (use) { + assert_true(use->instr->block == block); + use = use->next; + } + } + uint32_t signature = instr->opcode->signature; if (GET_OPCODE_SIG_TYPE_SRC1(signature) == OPCODE_SIG_TYPE_V) { if (ValidateValue(block, instr, instr->src1.value)) { From d8502c2aa9f0917c49056ea3ffba2c2569666873 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 6 Aug 2014 09:01:36 -0700 Subject: [PATCH 076/388] Trap without fragmenting blocks. --- src/alloy/frontend/ppc/ppc_emit_control.cc | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/alloy/frontend/ppc/ppc_emit_control.cc b/src/alloy/frontend/ppc/ppc_emit_control.cc index 5b409eaa4..dc8c11c3a 100644 --- a/src/alloy/frontend/ppc/ppc_emit_control.cc +++ b/src/alloy/frontend/ppc/ppc_emit_control.cc @@ -436,25 +436,34 @@ int InstrEmit_trap(PPCHIRBuilder& f, InstrData& i, Value* va, Value* vb, if (!TO) { return 0; } + Value* v = nullptr; if (TO & (1 << 4)) { // a < b - f.TrapTrue(f.CompareSLT(va, vb)); + auto cmp = f.CompareSLT(va, vb); + v = v ? f.Or(v, cmp) : cmp; } if (TO & (1 << 3)) { // a > b - f.TrapTrue(f.CompareSGT(va, vb)); + auto cmp = f.CompareSGT(va, vb); + v = v ? f.Or(v, cmp) : cmp; } if (TO & (1 << 2)) { // a = b - f.TrapTrue(f.CompareEQ(va, vb)); + auto cmp = f.CompareEQ(va, vb); + v = v ? f.Or(v, cmp) : cmp; } if (TO & (1 << 1)) { // a u b - f.TrapTrue(f.CompareUGT(va, vb)); + auto cmp = f.CompareUGT(va, vb); + v = v ? f.Or(v, cmp) : cmp; + } + if (v) { + f.TrapTrue(v); } return 0; } From a085dc547e3d644633007858aea5b8f4f329ad63 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 6 Aug 2014 11:36:16 -0700 Subject: [PATCH 077/388] Fix potential heap corruption in code cache. --- src/alloy/backend/x64/x64_code_cache_win.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/alloy/backend/x64/x64_code_cache_win.cc b/src/alloy/backend/x64/x64_code_cache_win.cc index f3e96455b..bb55fec6a 100644 --- a/src/alloy/backend/x64/x64_code_cache_win.cc +++ b/src/alloy/backend/x64/x64_code_cache_win.cc @@ -88,7 +88,6 @@ void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size, // Add entry to fn table. active_chunk_->AddTableEntry(final_address, code_size, stack_size); - lock_.unlock(); // Copy code. @@ -210,8 +209,7 @@ void X64CodeChunk::AddTableEntry(uint8_t* code, size_t code_size, // Allocate unwind data. We know we have space because we overallocated. // This should be the tailing 16b with 16b alignment. - size_t unwind_info_offset = offset; - offset += UNWIND_INFO_SIZE; + size_t unwind_info_offset = offset - UNWIND_INFO_SIZE; if (!stack_size) { // http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx From 5162d69ab27f9850face42ab0b6cd94c920fc586 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 6 Aug 2014 11:37:16 -0700 Subject: [PATCH 078/388] String buffer using std::vector (and fixing an allocation bug). --- src/alloy/string_buffer.cc | 48 ++++++++++++++++++++------------------ src/alloy/string_buffer.h | 5 ++-- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/alloy/string_buffer.cc b/src/alloy/string_buffer.cc index c35885e95..f461c92c3 100644 --- a/src/alloy/string_buffer.cc +++ b/src/alloy/string_buffer.cc @@ -9,17 +9,26 @@ #include +#include + namespace alloy { -StringBuffer::StringBuffer(size_t initial_capacity) : offset_(0) { - buffer_.resize(MAX(initial_capacity, 1024)); +StringBuffer::StringBuffer(size_t initial_capacity) { + buffer_.reserve(MAX(initial_capacity, 1024)); } StringBuffer::~StringBuffer() = default; -void StringBuffer::Reset() { - offset_ = 0; - buffer_[0] = 0; +void StringBuffer::Reset() { buffer_.resize(0); } + +void StringBuffer::Grow(size_t additional_length) { + size_t old_capacity = buffer_.capacity(); + if (buffer_.size() + additional_length <= old_capacity) { + return; + } + size_t new_capacity = + std::max(buffer_.size() + additional_length, old_capacity * 2); + buffer_.reserve(new_capacity); } void StringBuffer::Append(const std::string& value) { @@ -34,27 +43,20 @@ void StringBuffer::Append(const char* format, ...) { } void StringBuffer::AppendVarargs(const char* format, va_list args) { - while (true) { - int len = vsnprintf(buffer_.data() + offset_, buffer_.size() - offset_ - 1, - format, args); - if (len == -1) { - buffer_.resize(buffer_.size() * 2); - continue; - } else { - offset_ += len; - break; - } - } - buffer_[offset_] = 0; + int length = vsnprintf(nullptr, 0, format, args); + auto offset = buffer_.size(); + Grow(length + 1); + buffer_.resize(buffer_.size() + length); + vsnprintf(buffer_.data() + offset, buffer_.capacity() - 1, format, args); + buffer_[buffer_.size()] = 0; } void StringBuffer::AppendBytes(const uint8_t* buffer, size_t length) { - if (offset_ + length > buffer_.size()) { - buffer_.resize(MAX(buffer_.size() * 2, buffer_.size() + length)); - } - memcpy(buffer_.data() + offset_, buffer, length); - offset_ += length; - buffer_[offset_] = 0; + auto offset = buffer_.size(); + Grow(length + 1); + buffer_.resize(buffer_.size() + length); + memcpy(buffer_.data() + offset, buffer, length); + buffer_[buffer_.size()] = 0; } const char* StringBuffer::GetString() const { return buffer_.data(); } diff --git a/src/alloy/string_buffer.h b/src/alloy/string_buffer.h index 16f6bab76..d6c2fcd0d 100644 --- a/src/alloy/string_buffer.h +++ b/src/alloy/string_buffer.h @@ -22,7 +22,7 @@ class StringBuffer { StringBuffer(size_t initial_capacity = 0); ~StringBuffer(); - size_t length() const { return offset_; } + size_t length() const { return buffer_.size(); } void Reset(); @@ -36,8 +36,9 @@ class StringBuffer { char* EncodeBase64(); private: + void Grow(size_t additional_length); + std::vector buffer_; - size_t offset_; }; } // namespace alloy From b6046b186009fec0fd24b306b8042037d934f20f Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 6 Aug 2014 11:37:54 -0700 Subject: [PATCH 079/388] Move cr update to StoreRelease - prevents extra block. --- src/alloy/frontend/ppc/ppc_emit_memory.cc | 6 ++---- src/alloy/frontend/ppc/ppc_hir_builder.cc | 1 + 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/alloy/frontend/ppc/ppc_emit_memory.cc b/src/alloy/frontend/ppc/ppc_emit_memory.cc index 9ac067641..f0f63ac52 100644 --- a/src/alloy/frontend/ppc/ppc_emit_memory.cc +++ b/src/alloy/frontend/ppc/ppc_emit_memory.cc @@ -712,8 +712,7 @@ XEEMITTER(stdcx, 0x7C0001AD, X)(PPCHIRBuilder& f, InstrData& i) { // CR0[LT GT EQ SO] = 0b00 || n || XER[SO] Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB); Value* rt = f.ByteSwap(f.LoadGPR(i.X.RT)); - Value* stored = f.StoreRelease(ea, rt); - f.StoreContext(offsetof(PPCContext, cr0.cr0_eq), stored); + f.StoreRelease(ea, rt); // also updates cr0 return 0; } @@ -729,8 +728,7 @@ XEEMITTER(stwcx, 0x7C00012D, X)(PPCHIRBuilder& f, InstrData& i) { // CR0[LT GT EQ SO] = 0b00 || n || XER[SO] Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB); Value* rt = f.ByteSwap(f.Truncate(f.LoadGPR(i.X.RT), INT32_TYPE)); - Value* stored = f.StoreRelease(ea, rt); - f.StoreContext(offsetof(PPCContext, cr0.cr0_eq), stored); + f.StoreRelease(ea, rt); // also updates cr0 return 0; } diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index 64bf1dae4..3d5cf5f41 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -341,6 +341,7 @@ Value* PPCHIRBuilder::StoreRelease(Value* address, Value* value, LoadContext(offsetof(PPCContext, reserve_address), INT64_TYPE), LoadZero(INT32_TYPE)); Value* eq = CompareEQ(Truncate(address, INT32_TYPE), old_address); + StoreContext(offsetof(PPCContext, cr0.cr0_eq), eq); auto skip_label = NewLabel(); BranchFalse(eq, skip_label, BRANCH_UNLIKELY); Store(address, value, store_flags); From 9efd372d9236d362f47322571f11cca4dae4e285 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 6 Aug 2014 11:38:36 -0700 Subject: [PATCH 080/388] Reset CFG edge tracking on re-run. --- src/alloy/compiler/compiler.cc | 3 ++- .../compiler/passes/control_flow_analysis_pass.cc | 12 ++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/alloy/compiler/compiler.cc b/src/alloy/compiler/compiler.cc index 2ad7ca527..b74ada3cf 100644 --- a/src/alloy/compiler/compiler.cc +++ b/src/alloy/compiler/compiler.cc @@ -33,7 +33,8 @@ int Compiler::Compile(HIRBuilder* builder) { // TODO(benvanik): sophisticated stuff. Run passes in parallel, run until they // stop changing things, etc. - for (auto& pass : passes_) { + for (size_t i = 0; i < passes_.size(); ++i) { + auto& pass = passes_[i]; scratch_arena_.Reset(); if (pass->Run(builder)) { return 1; diff --git a/src/alloy/compiler/passes/control_flow_analysis_pass.cc b/src/alloy/compiler/passes/control_flow_analysis_pass.cc index 312fa3441..85b2bcfe4 100644 --- a/src/alloy/compiler/passes/control_flow_analysis_pass.cc +++ b/src/alloy/compiler/passes/control_flow_analysis_pass.cc @@ -30,10 +30,18 @@ ControlFlowAnalysisPass::~ControlFlowAnalysisPass() {} int ControlFlowAnalysisPass::Run(HIRBuilder* builder) { SCOPE_profile_cpu_f("alloy"); - // TODO(benvanik): reset edges for all blocks? Needed to be re-runnable. + // Reset edges for all blocks. Needed to be re-runnable. + // Note that this wastes a bunch of arena memory, so we shouldn't + // re-run too often. + auto block = builder->first_block(); + while (block) { + block->incoming_edge_head = nullptr; + block->outgoing_edge_head = nullptr; + block = block->next; + } // Add edges. - auto block = builder->first_block(); + block = builder->first_block(); while (block) { auto instr = block->instr_tail; while (instr) { From 646b32ad4fef92722f6eb97ed84edbc0f92ffa09 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 6 Aug 2014 11:40:10 -0700 Subject: [PATCH 081/388] Prevent context promotion across instructions marked volatile. --- .../compiler/passes/context_promotion_pass.cc | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/alloy/compiler/passes/context_promotion_pass.cc b/src/alloy/compiler/passes/context_promotion_pass.cc index 1b028464c..088111235 100644 --- a/src/alloy/compiler/passes/context_promotion_pass.cc +++ b/src/alloy/compiler/passes/context_promotion_pass.cc @@ -98,7 +98,10 @@ void ContextPromotionPass::PromoteBlock(Block* block) { Instr* i = block->instr_head; while (i) { - if (i->opcode == &OPCODE_LOAD_CONTEXT_info) { + if (i->opcode->flags & OPCODE_FLAG_VOLATILE) { + // Volatile instruction - requires all context values be flushed. + xe_zero_struct(context_values_, context_values_size_); + } else if (i->opcode == &OPCODE_LOAD_CONTEXT_info) { size_t offset = i->src1.offset; Value* previous_value = context_values_[offset]; if (previous_value) { @@ -123,18 +126,22 @@ void ContextPromotionPass::PromoteBlock(Block* block) { void ContextPromotionPass::RemoveDeadStoresBlock(Block* block) { // TODO(benvanik): use a bitvector. // To avoid clearing the structure, we use a token. - auto token = (Value*)block; + // Upper bits are block address, lower bits increment each reset. + uint64_t token = reinterpret_cast(block) << 16; // Walk backwards and mark offsets that are written to. // If the offset was written to earlier, ignore the store. Instr* i = block->instr_tail; while (i) { Instr* prev = i->prev; - if (i->opcode == &OPCODE_STORE_CONTEXT_info) { + if (i->opcode->flags & OPCODE_FLAG_VOLATILE) { + // Volatile instruction - requires all context values be flushed. + ++token; + } else if (i->opcode == &OPCODE_STORE_CONTEXT_info) { size_t offset = i->src1.offset; - if (context_values_[offset] != token) { + if (context_values_[offset] != reinterpret_cast(token)) { // Mark offset as written to. - context_values_[offset] = token; + context_values_[offset] = reinterpret_cast(token); } else { // Already written to. Remove this store. i->Remove(); From a53ee330ce85ca00ae429a27fa1b87ccbbbd33e4 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 6 Aug 2014 11:41:37 -0700 Subject: [PATCH 082/388] Marking branches/calls as volatile. --- .../compiler/passes/register_allocation_pass.cc | 1 + src/alloy/hir/opcodes.inl | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/alloy/compiler/passes/register_allocation_pass.cc b/src/alloy/compiler/passes/register_allocation_pass.cc index 1481e80d4..171610744 100644 --- a/src/alloy/compiler/passes/register_allocation_pass.cc +++ b/src/alloy/compiler/passes/register_allocation_pass.cc @@ -321,6 +321,7 @@ bool RegisterAllocationPass::TryAllocateRegister(Value* value) { } bool RegisterAllocationPass::SpillOneRegister(HIRBuilder* builder, + Block* block, TypeName required_type) { // Get the set that we will be picking from. RegisterSetUsage* usage_set; diff --git a/src/alloy/hir/opcodes.inl b/src/alloy/hir/opcodes.inl index 14c1dbf8b..a5c22c89b 100644 --- a/src/alloy/hir/opcodes.inl +++ b/src/alloy/hir/opcodes.inl @@ -54,43 +54,43 @@ DEFINE_OPCODE( OPCODE_CALL, "call", OPCODE_SIG_X_S, - OPCODE_FLAG_BRANCH) + OPCODE_FLAG_BRANCH | OPCODE_FLAG_VOLATILE) DEFINE_OPCODE( OPCODE_CALL_TRUE, "call_true", OPCODE_SIG_X_V_S, - OPCODE_FLAG_BRANCH) + OPCODE_FLAG_BRANCH | OPCODE_FLAG_VOLATILE) DEFINE_OPCODE( OPCODE_CALL_INDIRECT, "call_indirect", OPCODE_SIG_X_V, - OPCODE_FLAG_BRANCH) + OPCODE_FLAG_BRANCH | OPCODE_FLAG_VOLATILE) DEFINE_OPCODE( OPCODE_CALL_INDIRECT_TRUE, "call_indirect_true", OPCODE_SIG_X_V_V, - OPCODE_FLAG_BRANCH) + OPCODE_FLAG_BRANCH | OPCODE_FLAG_VOLATILE) DEFINE_OPCODE( OPCODE_CALL_EXTERN, "call_extern", OPCODE_SIG_X_S, - OPCODE_FLAG_BRANCH) + OPCODE_FLAG_BRANCH | OPCODE_FLAG_VOLATILE) DEFINE_OPCODE( OPCODE_RETURN, "return", OPCODE_SIG_X, - OPCODE_FLAG_BRANCH) + OPCODE_FLAG_BRANCH | OPCODE_FLAG_VOLATILE) DEFINE_OPCODE( OPCODE_RETURN_TRUE, "return_true", OPCODE_SIG_X_V, - OPCODE_FLAG_BRANCH) + OPCODE_FLAG_BRANCH | OPCODE_FLAG_VOLATILE) DEFINE_OPCODE( OPCODE_SET_RETURN_ADDRESS, From 2de7b6723d1d345a4e770becb06613c39131ecf2 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 6 Aug 2014 11:51:37 -0700 Subject: [PATCH 083/388] Fixed unwind info getting overwritten sometimes. --- src/alloy/backend/x64/x64_code_cache_win.cc | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/alloy/backend/x64/x64_code_cache_win.cc b/src/alloy/backend/x64/x64_code_cache_win.cc index bb55fec6a..6b0bfb750 100644 --- a/src/alloy/backend/x64/x64_code_cache_win.cc +++ b/src/alloy/backend/x64/x64_code_cache_win.cc @@ -60,20 +60,22 @@ void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size, size_t stack_size) { SCOPE_profile_cpu_f("alloy"); + size_t alloc_size = code_size; + // Add unwind info into the allocation size. Keep things 16b aligned. - code_size += XEROUNDUP(X64CodeChunk::UNWIND_INFO_SIZE, 16); + alloc_size += XEROUNDUP(X64CodeChunk::UNWIND_INFO_SIZE, 16); // Always move the code to land on 16b alignment. We do this by rounding up // to 16b so that all offsets are aligned. - code_size = XEROUNDUP(code_size, 16); + alloc_size = XEROUNDUP(alloc_size, 16); lock_.lock(); if (active_chunk_) { - if (active_chunk_->capacity - active_chunk_->offset < code_size) { + if (active_chunk_->capacity - active_chunk_->offset < alloc_size) { auto next = active_chunk_->next; if (!next) { - assert_true(code_size < chunk_size_, "need to support larger chunks"); + assert_true(alloc_size < chunk_size_, "need to support larger chunks"); next = new X64CodeChunk(chunk_size_); active_chunk_->next = next; } @@ -84,17 +86,18 @@ void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size, } uint8_t* final_address = active_chunk_->buffer + active_chunk_->offset; - active_chunk_->offset += code_size; + active_chunk_->offset += alloc_size; // Add entry to fn table. - active_chunk_->AddTableEntry(final_address, code_size, stack_size); + active_chunk_->AddTableEntry(final_address, alloc_size, stack_size); + lock_.unlock(); // Copy code. xe_copy_struct(final_address, machine_code, code_size); // This isn't needed on x64 (probably), but is convention. - FlushInstructionCache(GetCurrentProcess(), final_address, code_size); + FlushInstructionCache(GetCurrentProcess(), final_address, alloc_size); return final_address; } From 71ca8993b9e4fc9bbf0f4d7c652a7d2e04b70f75 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 6 Aug 2014 13:07:01 -0700 Subject: [PATCH 084/388] Constant src1 VectorSHL --- src/alloy/backend/x64/x64_sequences.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index 064c76295..6cc3c7ad8 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -4211,18 +4211,18 @@ EMITTER(VECTOR_SHL_V128, MATCH(I, V128<>, V128<>>)) { } else { // Fully variable shift. // TODO(benvanik): find a better sequence. - Xmm temp = i.dest; - if (i.dest == i.src1 || i.dest == i.src2) { - temp = e.xmm2; + Xmm src1 = !i.src1.is_constant ? i.src1 : e.xmm2; + if (i.src1.is_constant) { + e.LoadConstantXmm(src1, i.src1.constant()); } // Even: e.vpand(e.xmm0, i.src2, e.GetXmmConstPtr(XMMShiftMaskEvenPI16)); - e.vpsllvd(e.xmm1, i.src1, e.xmm0); + e.vpsllvd(e.xmm1, src1, e.xmm0); e.vpand(e.xmm1, e.GetXmmConstPtr(XMMMaskEvenPI16)); // Odd: e.vpsrld(e.xmm0, i.src2, 16); e.vpand(e.xmm0, e.GetXmmConstPtr(XMMShiftMaskEvenPI16)); - e.vpsrld(i.dest, i.src1, 16); + e.vpsrld(i.dest, src1, 16); e.vpsllvd(i.dest, i.dest, e.xmm0); e.vpslld(i.dest, 8); // Merge: From bba3315f585d57abf52a149f9f45b8fbd1af8e7a Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 6 Aug 2014 14:19:07 -0700 Subject: [PATCH 085/388] Make context promotion pass use bitmaps. --- .../compiler/passes/context_promotion_pass.cc | 47 ++++++++----------- .../compiler/passes/context_promotion_pass.h | 14 +++++- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/alloy/compiler/passes/context_promotion_pass.cc b/src/alloy/compiler/passes/context_promotion_pass.cc index 088111235..f00d605b5 100644 --- a/src/alloy/compiler/passes/context_promotion_pass.cc +++ b/src/alloy/compiler/passes/context_promotion_pass.cc @@ -30,14 +30,9 @@ using alloy::hir::HIRBuilder; using alloy::hir::Instr; using alloy::hir::Value; -ContextPromotionPass::ContextPromotionPass() - : CompilerPass(), context_values_size_(0), context_values_(0) {} +ContextPromotionPass::ContextPromotionPass() : CompilerPass() {} -ContextPromotionPass::~ContextPromotionPass() { - if (context_values_) { - xe_free(context_values_); - } -} +ContextPromotionPass::~ContextPromotionPass() {} int ContextPromotionPass::Initialize(Compiler* compiler) { if (CompilerPass::Initialize(compiler)) { @@ -46,8 +41,8 @@ int ContextPromotionPass::Initialize(Compiler* compiler) { // This is a terrible implementation. ContextInfo* context_info = runtime_->frontend()->context_info(); - context_values_size_ = context_info->size() * sizeof(Value*); - context_values_ = (Value**)xe_calloc(context_values_size_); + context_values_.resize(context_info->size()); + context_validity_.resize(static_cast(context_info->size())); return 0; } @@ -91,57 +86,55 @@ int ContextPromotionPass::Run(HIRBuilder* builder) { } void ContextPromotionPass::PromoteBlock(Block* block) { - // Clear the context values list. - // TODO(benvanik): new data structure that isn't so stupid. - // Bitvector of validity, perhaps? - xe_zero_struct(context_values_, context_values_size_); + auto& validity = context_validity_; + validity.reset(); Instr* i = block->instr_head; while (i) { + auto next = i->next; if (i->opcode->flags & OPCODE_FLAG_VOLATILE) { // Volatile instruction - requires all context values be flushed. - xe_zero_struct(context_values_, context_values_size_); + validity.reset(); } else if (i->opcode == &OPCODE_LOAD_CONTEXT_info) { size_t offset = i->src1.offset; - Value* previous_value = context_values_[offset]; - if (previous_value) { + if (validity.test(static_cast(offset))) { // Legit previous value, reuse. + Value* previous_value = context_values_[offset]; i->opcode = &hir::OPCODE_ASSIGN_info; i->set_src1(previous_value); } else { // Store the loaded value into the table. context_values_[offset] = i->dest; + validity.set(static_cast(offset)); } } else if (i->opcode == &OPCODE_STORE_CONTEXT_info) { size_t offset = i->src1.offset; Value* value = i->src2.value; // Store value into the table for later. context_values_[offset] = value; + validity.set(static_cast(offset)); } - - i = i->next; + i = next; } } void ContextPromotionPass::RemoveDeadStoresBlock(Block* block) { - // TODO(benvanik): use a bitvector. - // To avoid clearing the structure, we use a token. - // Upper bits are block address, lower bits increment each reset. - uint64_t token = reinterpret_cast(block) << 16; + auto& validity = context_validity_; + validity.reset(); // Walk backwards and mark offsets that are written to. // If the offset was written to earlier, ignore the store. Instr* i = block->instr_tail; while (i) { Instr* prev = i->prev; - if (i->opcode->flags & OPCODE_FLAG_VOLATILE) { + if (i->opcode->flags & (OPCODE_FLAG_VOLATILE | OPCODE_FLAG_BRANCH)) { // Volatile instruction - requires all context values be flushed. - ++token; + validity.reset(); } else if (i->opcode == &OPCODE_STORE_CONTEXT_info) { size_t offset = i->src1.offset; - if (context_values_[offset] != reinterpret_cast(token)) { - // Mark offset as written to. - context_values_[offset] = reinterpret_cast(token); + if (!validity.test(static_cast(offset))) { + // Offset not yet written, mark and continue. + validity.set(static_cast(offset)); } else { // Already written to. Remove this store. i->Remove(); diff --git a/src/alloy/compiler/passes/context_promotion_pass.h b/src/alloy/compiler/passes/context_promotion_pass.h index a9b8bc95b..0f4758af1 100644 --- a/src/alloy/compiler/passes/context_promotion_pass.h +++ b/src/alloy/compiler/passes/context_promotion_pass.h @@ -12,6 +12,16 @@ #include +#if XE_COMPILER_MSVC +#pragma warning(push) +#pragma warning(disable : 4244) +#pragma warning(disable : 4267) +#include +#pragma warning(pop) +#else +#include +#endif // XE_COMPILER_MSVC + namespace alloy { namespace compiler { namespace passes { @@ -30,8 +40,8 @@ class ContextPromotionPass : public CompilerPass { void RemoveDeadStoresBlock(hir::Block* block); private: - size_t context_values_size_; - hir::Value** context_values_; + std::vector context_values_; + llvm::BitVector context_validity_; }; } // namespace passes From b02ce5e95e499982ea75ee67a5b1730a2aa41319 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 6 Aug 2014 14:19:42 -0700 Subject: [PATCH 086/388] Adding control flow simplification pass to compensate for lack of phi. --- src/alloy/compiler/compiler_passes.h | 3 +- .../control_flow_simplification_pass.cc | 60 ++++++++++++++ .../passes/control_flow_simplification_pass.h | 33 ++++++++ .../passes/register_allocation_pass.cc | 3 +- src/alloy/compiler/passes/sources.gypi | 2 + src/alloy/frontend/ppc/ppc_translator.cc | 5 +- src/alloy/hir/hir_builder.cc | 82 +++++++++++++++++++ src/alloy/hir/hir_builder.h | 1 + src/alloy/hir/opcodes.inl | 4 +- src/xenia/kernel/xboxkrnl_rtl.cc | 2 - 10 files changed, 187 insertions(+), 8 deletions(-) create mode 100644 src/alloy/compiler/passes/control_flow_simplification_pass.cc create mode 100644 src/alloy/compiler/passes/control_flow_simplification_pass.h diff --git a/src/alloy/compiler/compiler_passes.h b/src/alloy/compiler/compiler_passes.h index a01896e44..935b8397b 100644 --- a/src/alloy/compiler/compiler_passes.h +++ b/src/alloy/compiler/compiler_passes.h @@ -11,8 +11,9 @@ #define ALLOY_COMPILER_COMPILER_PASSES_H_ #include -#include #include +#include +#include #include #include //#include diff --git a/src/alloy/compiler/passes/control_flow_simplification_pass.cc b/src/alloy/compiler/passes/control_flow_simplification_pass.cc new file mode 100644 index 000000000..1891f2d7b --- /dev/null +++ b/src/alloy/compiler/passes/control_flow_simplification_pass.cc @@ -0,0 +1,60 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include +#include +#include + +namespace alloy { +namespace compiler { +namespace passes { + +// TODO(benvanik): remove when enums redefined. +using namespace alloy::hir; + +using alloy::hir::Edge; +using alloy::hir::HIRBuilder; + +ControlFlowSimplificationPass::ControlFlowSimplificationPass() + : CompilerPass() {} + +ControlFlowSimplificationPass::~ControlFlowSimplificationPass() {} + +int ControlFlowSimplificationPass::Run(HIRBuilder* builder) { + SCOPE_profile_cpu_f("alloy"); + + // Walk backwards and merge blocks if possible. + bool merged_any = false; + auto block = builder->last_block(); + while (block) { + auto prev_block = block->prev; + const uint32_t expected = Edge::DOMINATES | Edge::UNCONDITIONAL; + if (block->incoming_edge_head && + (block->incoming_edge_head->flags & expected) == expected) { + // Dominated by the incoming block. + // If that block comes immediately before us then we can merge the + // two blocks (assuming it's not a volatile instruction like Trap). + if (block->prev == block->incoming_edge_head->src && + block->prev->instr_tail && + !(block->prev->instr_tail->opcode->flags & OPCODE_FLAG_VOLATILE)) { + builder->MergeAdjacentBlocks(block->prev, block); + merged_any = true; + } + } + block = prev_block; + } + + return 0; +} + +} // namespace passes +} // namespace compiler +} // namespace alloy diff --git a/src/alloy/compiler/passes/control_flow_simplification_pass.h b/src/alloy/compiler/passes/control_flow_simplification_pass.h new file mode 100644 index 000000000..350ed4d9d --- /dev/null +++ b/src/alloy/compiler/passes/control_flow_simplification_pass.h @@ -0,0 +1,33 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef ALLOY_COMPILER_PASSES_CONTROL_FLOW_SIMPLIFICATION_PASS_H_ +#define ALLOY_COMPILER_PASSES_CONTROL_FLOW_SIMPLIFICATION_PASS_H_ + +#include + +namespace alloy { +namespace compiler { +namespace passes { + +class ControlFlowSimplificationPass : public CompilerPass { + public: + ControlFlowSimplificationPass(); + ~ControlFlowSimplificationPass() override; + + int Run(hir::HIRBuilder* builder) override; + + private: +}; + +} // namespace passes +} // namespace compiler +} // namespace alloy + +#endif // ALLOY_COMPILER_PASSES_CONTROL_FLOW_SIMPLIFICATION_PASS_H_ diff --git a/src/alloy/compiler/passes/register_allocation_pass.cc b/src/alloy/compiler/passes/register_allocation_pass.cc index 171610744..2175765c2 100644 --- a/src/alloy/compiler/passes/register_allocation_pass.cc +++ b/src/alloy/compiler/passes/register_allocation_pass.cc @@ -320,8 +320,7 @@ bool RegisterAllocationPass::TryAllocateRegister(Value* value) { return false; } -bool RegisterAllocationPass::SpillOneRegister(HIRBuilder* builder, - Block* block, +bool RegisterAllocationPass::SpillOneRegister(HIRBuilder* builder, Block* block, TypeName required_type) { // Get the set that we will be picking from. RegisterSetUsage* usage_set; diff --git a/src/alloy/compiler/passes/sources.gypi b/src/alloy/compiler/passes/sources.gypi index ed16920ad..12f16e695 100644 --- a/src/alloy/compiler/passes/sources.gypi +++ b/src/alloy/compiler/passes/sources.gypi @@ -7,6 +7,8 @@ 'context_promotion_pass.h', 'control_flow_analysis_pass.cc', 'control_flow_analysis_pass.h', + 'control_flow_simplification_pass.cc', + 'control_flow_simplification_pass.h', 'data_flow_analysis_pass.cc', 'data_flow_analysis_pass.h', 'dead_code_elimination_pass.cc', diff --git a/src/alloy/frontend/ppc/ppc_translator.cc b/src/alloy/frontend/ppc/ppc_translator.cc index ff6145256..e1720f523 100644 --- a/src/alloy/frontend/ppc/ppc_translator.cc +++ b/src/alloy/frontend/ppc/ppc_translator.cc @@ -43,7 +43,10 @@ PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) { bool validate = FLAGS_validate_hir; - // Build the CFG first. + // Merge blocks early. This will let us use more context in other passes. + // The CFG is required for simplification and dirtied by it. + compiler_->AddPass(std::make_unique()); + compiler_->AddPass(std::make_unique()); compiler_->AddPass(std::make_unique()); // Passes are executed in the order they are added. Multiple of the same diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index 29d404af1..87d9f75f9 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -436,6 +436,88 @@ void HIRBuilder::AddEdge(Block* src, Block* dest, uint32_t flags) { dest->incoming_edge_head = edge; } +void HIRBuilder::MergeAdjacentBlocks(Block* left, Block* right) { + assert_true(left->next == right && right->prev == left); + assert_true(!right->incoming_edge_head || + right->incoming_edge_head->flags & Edge::DOMINATES); + + // If the left block ends with a branch to the right block, drop it. + if (left->instr_tail && + left->instr_tail->opcode->flags & OPCODE_FLAG_BRANCH) { + auto sig = left->instr_tail->opcode->signature; + if (GET_OPCODE_SIG_TYPE_SRC1(sig) == OPCODE_SIG_TYPE_L) { + if (left->instr_tail->src1.label->block == right) { + left->instr_tail->Remove(); + } + } + if (GET_OPCODE_SIG_TYPE_SRC2(sig) == OPCODE_SIG_TYPE_L) { + if (left->instr_tail->src2.label->block == right) { + left->instr_tail->Remove(); + } + } + } + + // Walk through the right instructions and shift each one back into the left. + while (right->instr_head) { + auto instr = right->instr_head; + auto next = instr->next; + + // Link into block list. + instr->next = nullptr; + instr->prev = left->instr_tail; + if (left->instr_tail) { + left->instr_tail->next = instr; + } else { + left->instr_head = left->instr_tail = instr; + } + left->instr_tail = instr; + + // Unlink from old block list; + right->instr_head = next; + if (right->instr_tail == instr) { + right->instr_tail = nullptr; + } + if (next) { + next->prev = nullptr; + } + + // Update state. + instr->block = left; + } + + // Move/remove labels. + // We only need to preserve named labels. + while (right->label_head) { + auto label = right->label_head; + if (label->name) { + // Label is named - move it. + label->block = left; + label->prev = left->label_tail; + if (left->label_tail) { + left->label_tail->next = label; + } + left->label_tail = label; + if (!left->label_head) { + left->label_head = label; + } + } + right->label_head = label->next; + if (right->label_tail == label) { + right->label_tail = nullptr; + } + label->next = nullptr; + } + + // Remove the right block from the block list. + left->next = right->next; + if (right->next) { + right->next->prev = left; + } + if (block_tail_ == right) { + block_tail_ = left; + } +} + Block* HIRBuilder::AppendBlock() { Block* block = arena_->Alloc(); block->arena = arena_; diff --git a/src/alloy/hir/hir_builder.h b/src/alloy/hir/hir_builder.h index c4440e6b5..a6ec2ef4d 100644 --- a/src/alloy/hir/hir_builder.h +++ b/src/alloy/hir/hir_builder.h @@ -61,6 +61,7 @@ class HIRBuilder { void ResetLabelTags(); void AddEdge(Block* src, Block* dest, uint32_t flags); + void MergeAdjacentBlocks(Block* left, Block* right); // static allocations: // Value* AllocStatic(size_t length); diff --git a/src/alloy/hir/opcodes.inl b/src/alloy/hir/opcodes.inl index a5c22c89b..77c51bb5a 100644 --- a/src/alloy/hir/opcodes.inl +++ b/src/alloy/hir/opcodes.inl @@ -108,13 +108,13 @@ DEFINE_OPCODE( OPCODE_BRANCH_TRUE, "branch_true", OPCODE_SIG_X_V_L, - OPCODE_FLAG_BRANCH) + OPCODE_FLAG_BRANCH | OPCODE_FLAG_VOLATILE) DEFINE_OPCODE( OPCODE_BRANCH_FALSE, "branch_false", OPCODE_SIG_X_V_L, - OPCODE_FLAG_BRANCH) + OPCODE_FLAG_BRANCH | OPCODE_FLAG_VOLATILE) DEFINE_OPCODE( OPCODE_ASSIGN, diff --git a/src/xenia/kernel/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl_rtl.cc index 97fe9efc5..3173229ca 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl_rtl.cc @@ -663,8 +663,6 @@ spin: SHIM_CALL RtlEnterCriticalSection_shim( PPCContext* ppc_state, KernelState* state) { - SCOPE_profile_cpu_f("kernel"); - uint32_t cs_ptr = SHIM_GET_ARG_32(0); // XELOGD("RtlEnterCriticalSection(%.8X)", cs_ptr); From 4ce81fcda86e372d9d7241d3201162eca057bdd6 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 6 Aug 2014 15:48:31 -0700 Subject: [PATCH 087/388] CAS should return a bool. --- src/poly/atomic.h | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/src/poly/atomic.h b/src/poly/atomic.h index 51c0ec9de..721db37dc 100644 --- a/src/poly/atomic.h +++ b/src/poly/atomic.h @@ -40,11 +40,16 @@ inline int64_t atomic_exchange(int64_t new_value, volatile int64_t* value) { return OSAtomicCompareAndSwap64Barrier(*value, new_value, value); } -inline int32_t atomic_cas(int32_t old_value, int32_t new_value, - volatile int32_t* value) { +inline bool atomic_cas(int32_t old_value, int32_t new_value, + volatile int32_t* value) { return OSAtomicCompareAndSwap32Barrier( old_value, new_value, reinterpret_cast(value)); } +inline bool atomic_cas(int64_t old_value, int64_t new_value, + volatile int32_t* value) { + return OSAtomicCompareAndSwap64Barrier( + old_value, new_value, reinterpret_cast(value)); +} #elif XE_LIKE_WIN32 @@ -64,11 +69,16 @@ inline int64_t atomic_exchange(int64_t new_value, volatile int64_t* value) { new_value); } -inline int32_t atomic_cas(int32_t old_value, int32_t new_value, - volatile int32_t* value) { +inline bool atomic_cas(int32_t old_value, int32_t new_value, + volatile int32_t* value) { return InterlockedCompareExchange(reinterpret_cast(value), new_value, old_value) == old_value; } +inline bool atomic_cas(int64_t old_value, int64_t new_value, + volatile int64_t* value) { + return InterlockedCompareExchange64(reinterpret_cast(value), + new_value, old_value) == old_value; +} #elif XE_LIKE_POSIX @@ -86,11 +96,16 @@ inline int64_t atomic_exchange(int64_t new_value, volatile int64_t* value) { return __sync_val_compare_and_swap(*value, value, new_value); } -inline int32_t atomic_cas(int32_t old_value, int32_t new_value, - volatile int32_t* value) { +inline bool atomic_cas(int32_t old_value, int32_t new_value, + volatile int32_t* value) { return __sync_bool_compare_and_swap( reinterpret_cast(value), old_value, new_value); } +inline bool atomic_cas(int64_t old_value, int64_t new_value, + volatile int64_t* value) { + return __sync_bool_compare_and_swap( + reinterpret_cast(value), old_value, new_value); +} #else @@ -118,11 +133,17 @@ inline uint64_t atomic_exchange(uint64_t new_value, volatile uint64_t* value) { reinterpret_cast(value))); } -inline uint32_t atomic_cas(uint32_t old_value, uint32_t new_value, - volatile uint32_t* value) { - return static_cast(atomic_cas( - static_cast(old_value), static_cast(new_value), - reinterpret_cast(value))); +inline bool atomic_cas(uint32_t old_value, uint32_t new_value, + volatile uint32_t* value) { + return atomic_cas(static_cast(old_value), + static_cast(new_value), + reinterpret_cast(value)); +} +inline bool atomic_cas(uint64_t old_value, uint64_t new_value, + volatile uint64_t* value) { + return atomic_cas(static_cast(old_value), + static_cast(new_value), + reinterpret_cast(value)); } } // namespace poly From 6b581bcc752f0fe23b0548196189c23a5bc25885 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 6 Aug 2014 16:31:38 -0700 Subject: [PATCH 088/388] Simple IC for indirect calls. --- src/alloy/backend/x64/x64_emitter.cc | 122 +++++++++++++++++++++---- src/alloy/backend/x64/x64_emitter.h | 2 + src/alloy/backend/x64/x64_sequences.cc | 12 +-- 3 files changed, 114 insertions(+), 22 deletions(-) diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index a7997334c..2661c54d1 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -239,18 +239,6 @@ void X64Emitter::UnimplementedInstr(const hir::Instr* i) { const size_t TOTAL_RESOLVE_SIZE = 27; const size_t ASM_OFFSET = 2 + 2 + 8 + 2 + 8; -// Length Assembly Byte Sequence -// ================================================================================= -// 2 bytes 66 NOP 66 90H -// 3 bytes NOP DWORD ptr [EAX] 0F 1F 00H -// 4 bytes NOP DWORD ptr [EAX + 00H] 0F 1F 40 00H -// 5 bytes NOP DWORD ptr [EAX + EAX*1 + 00H] 0F 1F 44 00 00H -// 6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H -// 7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H -// 8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H -// 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00000000H] 66 0F 1F 84 00 00 00 00 -// 00H - uint64_t ResolveFunctionSymbol(void* raw_context, uint64_t symbol_info_ptr) { // TODO(benvanik): generate this thunk at runtime? or a shim? auto thread_state = *reinterpret_cast(raw_context); @@ -281,6 +269,7 @@ uint64_t ResolveFunctionSymbol(void* raw_context, uint64_t symbol_info_ptr) { uint8_t mov_rcx[5]; }; #pragma pack(pop) + static_assert_size(Asm, TOTAL_RESOLVE_SIZE); Asm* code = reinterpret_cast(return_address - ASM_OFFSET); code->rax_constant = addr; code->call_rax = 0x9066; @@ -293,7 +282,6 @@ void X64Emitter::Call(const hir::Instr* instr, runtime::FunctionInfo* symbol_info) { auto fn = reinterpret_cast(symbol_info->function()); // Resolve address to the function to call and store in rax. - // TODO(benvanik): caching/etc. For now this makes debugging easier. if (fn) { mov(rax, reinterpret_cast(fn->machine_code())); } else { @@ -325,18 +313,66 @@ void X64Emitter::Call(const hir::Instr* instr, } } +// NOTE: slot count limited by short jump size. +const int kICSlotCount = 4; +const int kICSlotSize = 23; +const uint64_t kICSlotInvalidTargetAddress = 0x0F0F0F0F0F0F0F0F; + uint64_t ResolveFunctionAddress(void* raw_context, uint64_t target_address) { // TODO(benvanik): generate this thunk at runtime? or a shim? auto thread_state = *reinterpret_cast(raw_context); // TODO(benvanik): required? target_address &= 0xFFFFFFFF; + assert_not_zero(target_address); Function* fn = NULL; thread_state->runtime()->ResolveFunction(target_address, &fn); assert_not_null(fn); auto x64_fn = static_cast(fn); - return reinterpret_cast(x64_fn->machine_code()); + uint64_t addr = reinterpret_cast(x64_fn->machine_code()); + +// Add an IC slot, if there is room. +#if XE_LIKE_WIN32 + uint64_t return_address = reinterpret_cast(_ReturnAddress()); +#else + uint64_t return_address = + reinterpret_cast(__builtin_return_address(0)); +#endif // XE_WIN32_LIKE +#pragma pack(push, 1) + struct Asm { + uint16_t cmp_rdx; + uint32_t address_constant; + uint16_t jmp_next_slot; + uint16_t mov_rax; + uint64_t target_constant; + uint8_t jmp_skip_resolve[5]; + }; +#pragma pack(pop) + static_assert_size(Asm, kICSlotSize); + // The return address points to ReloadRCX work after the call. + // To get the top of the table, look back a ways. + uint64_t table_start = return_address - 12 - kICSlotSize * kICSlotCount; + // NOTE: order matters here - we update the address BEFORE we switch the code + // over to passing the compare. + Asm* table_slot = reinterpret_cast(table_start); + bool wrote_ic = false; + for (int i = 0; i < kICSlotCount; ++i) { + if (poly::atomic_cas(kICSlotInvalidTargetAddress, addr, + &table_slot->target_constant)) { + // Got slot! Just write the compare and we're done. + table_slot->address_constant = static_cast(target_address); + wrote_ic = true; + break; + } + ++table_slot; + } + if (!wrote_ic) { + // TODO(benvanik): log that IC table is full. + } + + // We need to return the target in rax so that it gets called. + return addr; } void X64Emitter::CallIndirect(const hir::Instr* instr, const Reg64& reg) { @@ -346,14 +382,49 @@ void X64Emitter::CallIndirect(const hir::Instr* instr, const Reg64& reg) { je("epilog", CodeGenerator::T_NEAR); } - // Resolve address to the function to call and store in rax. - // TODO(benvanik): caching/etc. For now this makes debugging easier. if (reg.getIdx() != rdx.getIdx()) { mov(rdx, reg); } + + inLocalLabel(); + Xbyak::Label skip_resolve; + + // TODO(benvanik): make empty tables skippable (cmp, jump right to resolve). + + // IC table, initially empty. + // This will get filled in as functions are resolved. + // Note that we only have a limited cache, and once it's full all calls + // will fall through. + // TODO(benvanik): check miss rate when full and add a 2nd-level table? + // 0000000264BD4DC3 81 FA 0F0F0F0F cmp edx,0F0F0F0Fh + // 0000000264BD4DC9 75 0C jne 0000000264BD4DD7 + // 0000000264BD4DCB 48 B8 0F0F0F0F0F0F0F0F mov rax,0F0F0F0F0F0F0F0Fh + // 0000000264BD4DD5 EB XXXXXXXX jmp 0000000264BD4E00 + size_t table_start = getSize(); + for (int i = 0; i < kICSlotCount; ++i) { + // Compare target address with constant, if matches jump there. + // Otherwise, fall through. + // 6b + cmp(edx, 0x0F0F0F0F); + Xbyak::Label next_slot; + // 2b + jne(next_slot, T_SHORT); + // Match! Load up rax and skip down to the jmp code. + // 10b + mov(rax, kICSlotInvalidTargetAddress); + // 5b + jmp(skip_resolve, T_NEAR); + L(next_slot); + } + size_t table_size = getSize() - table_start; + assert_true(table_size == kICSlotSize * kICSlotCount); + + // Resolve address to the function to call and store in rax. + // We fall through to this when there are no hits in the IC table. CallNative(ResolveFunctionAddress); // Actually jump/call to rax. + L(skip_resolve); if (instr->flags & CALL_TAIL) { // Pass the callers return address over. mov(rdx, qword[rsp + StackLayout::GUEST_RET_ADDR]); @@ -365,6 +436,8 @@ void X64Emitter::CallIndirect(const hir::Instr* instr, const Reg64& reg) { mov(rdx, qword[rsp + StackLayout::GUEST_CALL_RET_ADDR]); call(rax); } + + outLocalLabel(); } uint64_t UndefinedCallExtern(void* raw_context, uint64_t symbol_info_ptr) { @@ -451,6 +524,23 @@ void X64Emitter::ReloadEDX() { mov(rdx, qword[rcx + 8]); // membase } +// Len Assembly Byte Sequence +// ============================================================================ +// 2b 66 NOP 66 90H +// 3b NOP DWORD ptr [EAX] 0F 1F 00H +// 4b NOP DWORD ptr [EAX + 00H] 0F 1F 40 00H +// 5b NOP DWORD ptr [EAX + EAX*1 + 00H] 0F 1F 44 00 00H +// 6b 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H +// 7b NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H +// 8b NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H +// 9b 66 NOP DWORD ptr [EAX + EAX*1 + 00000000H] 66 0F 1F 84 00 00 00 00 00H +void X64Emitter::nop(size_t length) { + // TODO(benvanik): fat nop + for (size_t i = 0; i < length; ++i) { + db(0x90); + } +} + void X64Emitter::LoadEflags() { #if STORE_EFLAGS mov(eax, dword[rsp + STASH_OFFSET]); diff --git a/src/alloy/backend/x64/x64_emitter.h b/src/alloy/backend/x64/x64_emitter.h index 785108d71..05131d55a 100644 --- a/src/alloy/backend/x64/x64_emitter.h +++ b/src/alloy/backend/x64/x64_emitter.h @@ -138,6 +138,8 @@ class X64Emitter : public Xbyak::CodeGenerator { void ReloadECX(); void ReloadEDX(); + void nop(size_t length = 1); + // TODO(benvanik): Label for epilog (don't use strings). void LoadEflags(); diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index 6cc3c7ad8..8bf8aefd2 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -366,7 +366,7 @@ EMITTER(CALL_INDIRECT_TRUE_I8, MATCH(I, static void Emit(X64Emitter& e, const EmitArgType& i) { e.test(i.src1, i.src1); Xbyak::Label skip; - e.jz(skip); + e.jz(skip, CodeGenerator::T_NEAR); e.CallIndirect(i.instr, i.src2); e.L(skip); } @@ -375,7 +375,7 @@ EMITTER(CALL_INDIRECT_TRUE_I16, MATCH(I static void Emit(X64Emitter& e, const EmitArgType& i) { e.test(i.src1, i.src1); Xbyak::Label skip; - e.jz(skip); + e.jz(skip, CodeGenerator::T_NEAR); e.CallIndirect(i.instr, i.src2); e.L(skip); } @@ -384,7 +384,7 @@ EMITTER(CALL_INDIRECT_TRUE_I32, MATCH(I static void Emit(X64Emitter& e, const EmitArgType& i) { e.test(i.src1, i.src1); Xbyak::Label skip; - e.jz(skip); + e.jz(skip, CodeGenerator::T_NEAR); e.CallIndirect(i.instr, i.src2); e.L(skip); } @@ -393,7 +393,7 @@ EMITTER(CALL_INDIRECT_TRUE_I64, MATCH(I static void Emit(X64Emitter& e, const EmitArgType& i) { e.test(i.src1, i.src1); Xbyak::Label skip; - e.jz(skip); + e.jz(skip, CodeGenerator::T_NEAR); e.CallIndirect(i.instr, i.src2); e.L(skip); } @@ -402,7 +402,7 @@ EMITTER(CALL_INDIRECT_TRUE_F32, MATCH(I static void Emit(X64Emitter& e, const EmitArgType& i) { e.vptest(i.src1, i.src1); Xbyak::Label skip; - e.jz(skip); + e.jz(skip, CodeGenerator::T_NEAR); e.CallIndirect(i.instr, i.src2); e.L(skip); } @@ -411,7 +411,7 @@ EMITTER(CALL_INDIRECT_TRUE_F64, MATCH(I static void Emit(X64Emitter& e, const EmitArgType& i) { e.vptest(i.src1, i.src1); Xbyak::Label skip; - e.jz(skip); + e.jz(skip, CodeGenerator::T_NEAR); e.CallIndirect(i.instr, i.src2); e.L(skip); } From 04a3e53e50ae24a5ec88dc19278812e19f1c6257 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 6 Aug 2014 17:05:15 -0700 Subject: [PATCH 089/388] Fixing IVM. --- src/alloy/backend/ivm/ivm_intcode.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index 741b167ae..f82ae39e7 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -101,7 +101,7 @@ uint32_t AllocConstant(TranslationContext& ctx, Value* value) { uint32_t AllocLabel(TranslationContext& ctx, Label* label) { // If it's a back-branch to an already tagged label avoid setting up // a reference. - uint32_t value = *reinterpret_cast(label->tag); + uint32_t value = reinterpret_cast(label->tag); if (value & 0x80000000) { // Already set. return AllocConstant(ctx, value & ~0x80000000); @@ -124,7 +124,7 @@ uint32_t AllocLabel(TranslationContext& ctx, Label* label) { uint32_t AllocDynamicRegister(TranslationContext& ctx, Value* value) { if (value->flags & VALUE_IS_ALLOCATED) { - return *reinterpret_cast(value->tag); + return reinterpret_cast(value->tag); } else { value->flags |= VALUE_IS_ALLOCATED; auto reg = ctx.register_count++; From 31ee323b3802565c2147ac6849e2584bc4103c49 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 7 Aug 2014 13:22:51 -0700 Subject: [PATCH 090/388] VECTOR_ADD signed/saturate. --- src/alloy/backend/x64/x64_sequences.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index 8bf8aefd2..f5709d0d8 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -2745,7 +2745,17 @@ EMITTER(VECTOR_ADD, MATCH(I, V128<>, V128<>>)) { // dest.f[n] = xmm1.f[n] ? xmm1.f[n] : dest.f[n]; e.vblendvps(dest, dest, e.xmm1, e.xmm1); } else { - assert_always(); + // https://software.intel.com/en-us/forums/topic/285219 + // We reuse all these temps... + assert_true(src1 != e.xmm0 && src1 != e.xmm1 && src1 != e.xmm2); + assert_true(src2 != e.xmm0 && src2 != e.xmm1 && src2 != e.xmm2); + e.vpaddd(e.xmm0, src1, src2); // res + e.vpand(e.xmm1, src1, src2); // sign_and + e.vpandn(e.xmm2, e.xmm0, e.xmm1); // min_sat_mask + e.vblendvps(e.xmm2, e.xmm0, e.GetXmmConstPtr(XMMSignMaskPS), e.xmm2); + e.vpor(e.xmm1, src1, src2); // sign_or + e.vpandn(e.xmm1, e.xmm0); // max_sat_mask + e.vblendvps(e.xmm2, e.GetXmmConstPtr(XMMAbsMaskPS), e.xmm1); } } else { e.vpaddd(dest, src1, src2); From e4485bdab17b6dcde2521450e3144a83744c8a21 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 7 Aug 2014 13:23:25 -0700 Subject: [PATCH 091/388] Fixing tracing format to match IVM and aligned loads of doubles. --- src/alloy/backend/x64/x64_tracers.cc | 72 +++++++++++++++------------- src/alloy/backend/x64/x64_tracers.h | 34 ++++++------- 2 files changed, 56 insertions(+), 50 deletions(-) diff --git a/src/alloy/backend/x64/x64_tracers.cc b/src/alloy/backend/x64/x64_tracers.cc index e47d1eda8..86b1948c2 100644 --- a/src/alloy/backend/x64/x64_tracers.cc +++ b/src/alloy/backend/x64/x64_tracers.cc @@ -72,10 +72,12 @@ void TraceContextLoadF32(void* raw_context, uint64_t offset, __m128 value) { DPRINT("%e (%X) = ctx f32 +%llu\n", poly::m128_f32<0>(value), poly::m128_i32<0>(value), offset); } -void TraceContextLoadF64(void* raw_context, uint64_t offset, __m128 value) { +void TraceContextLoadF64(void* raw_context, uint64_t offset, + const double* value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("%le (%llX) = ctx f64 +%llu\n", poly::m128_f64<0>(value), - poly::m128_i64<0>(value), offset); + auto v = _mm_loadu_pd(value); + DPRINT("%le (%llX) = ctx f64 +%llu\n", poly::m128_f64<0>(v), + poly::m128_i64<0>(v), offset); } void TraceContextLoadV128(void* raw_context, uint64_t offset, __m128 value) { auto thread_state = *((ThreadState**)raw_context); @@ -107,10 +109,12 @@ void TraceContextStoreF32(void* raw_context, uint64_t offset, __m128 value) { DPRINT("ctx f32 +%llu = %e (%X)\n", offset, poly::m128_f32<0>(value), poly::m128_i32<0>(value)); } -void TraceContextStoreF64(void* raw_context, uint64_t offset, __m128 value) { +void TraceContextStoreF64(void* raw_context, uint64_t offset, + const double* value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("ctx f64 +%llu = %le (%llX)\n", offset, poly::m128_f64<0>(value), - poly::m128_i64<0>(value)); + auto v = _mm_loadu_pd(value); + DPRINT("ctx f64 +%llu = %le (%llX)\n", offset, poly::m128_f64<0>(v), + poly::m128_i64<0>(v)); } void TraceContextStoreV128(void* raw_context, uint64_t offset, __m128 value) { auto thread_state = *((ThreadState**)raw_context); @@ -121,70 +125,70 @@ void TraceContextStoreV128(void* raw_context, uint64_t offset, __m128 value) { poly::m128_i32<2>(value), poly::m128_i32<3>(value)); } -void TraceMemoryLoadI8(void* raw_context, uint64_t address, uint8_t value) { +void TraceMemoryLoadI8(void* raw_context, uint32_t address, uint8_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("%d (%X) = load.i8 %.8llX\n", (int8_t)value, value, address); + DPRINT("%d (%X) = load.i8 %.8X\n", (int8_t)value, value, address); } -void TraceMemoryLoadI16(void* raw_context, uint64_t address, uint16_t value) { +void TraceMemoryLoadI16(void* raw_context, uint32_t address, uint16_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("%d (%X) = load.i16 %.8llX\n", (int16_t)value, value, address); + DPRINT("%d (%X) = load.i16 %.8X\n", (int16_t)value, value, address); } -void TraceMemoryLoadI32(void* raw_context, uint64_t address, uint32_t value) { +void TraceMemoryLoadI32(void* raw_context, uint32_t address, uint32_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("%d (%X) = load.i32 %.8llX\n", (int32_t)value, value, address); + DPRINT("%d (%X) = load.i32 %.8X\n", (int32_t)value, value, address); } -void TraceMemoryLoadI64(void* raw_context, uint64_t address, uint64_t value) { +void TraceMemoryLoadI64(void* raw_context, uint32_t address, uint64_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("%lld (%llX) = load.i64 %.8llX\n", (int64_t)value, value, address); + DPRINT("%lld (%llX) = load.i64 %.8X\n", (int64_t)value, value, address); } -void TraceMemoryLoadF32(void* raw_context, uint64_t address, __m128 value) { +void TraceMemoryLoadF32(void* raw_context, uint32_t address, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("%e (%X) = load.f32 %.8llX\n", poly::m128_f32<0>(value), + DPRINT("%e (%X) = load.f32 %.8X\n", poly::m128_f32<0>(value), poly::m128_i32<0>(value), address); } -void TraceMemoryLoadF64(void* raw_context, uint64_t address, __m128 value) { +void TraceMemoryLoadF64(void* raw_context, uint32_t address, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("%le (%llX) = load.f64 %.8llX\n", poly::m128_f64<0>(value), + DPRINT("%le (%llX) = load.f64 %.8X\n", poly::m128_f64<0>(value), poly::m128_i64<0>(value), address); } -void TraceMemoryLoadV128(void* raw_context, uint64_t address, __m128 value) { +void TraceMemoryLoadV128(void* raw_context, uint32_t address, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = load.v128 %.8llX\n", + DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = load.v128 %.8X\n", poly::m128_f32<0>(value), poly::m128_f32<1>(value), poly::m128_f32<2>(value), poly::m128_f32<3>(value), poly::m128_i32<0>(value), poly::m128_i32<1>(value), poly::m128_i32<2>(value), poly::m128_i32<3>(value), address); } -void TraceMemoryStoreI8(void* raw_context, uint64_t address, uint8_t value) { +void TraceMemoryStoreI8(void* raw_context, uint32_t address, uint8_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("store.i8 %.8llX = %d (%X)\n", address, (int8_t)value, value); + DPRINT("store.i8 %.8X = %d (%X)\n", address, (int8_t)value, value); } -void TraceMemoryStoreI16(void* raw_context, uint64_t address, uint16_t value) { +void TraceMemoryStoreI16(void* raw_context, uint32_t address, uint16_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("store.i16 %.8llX = %d (%X)\n", address, (int16_t)value, value); + DPRINT("store.i16 %.8X = %d (%X)\n", address, (int16_t)value, value); } -void TraceMemoryStoreI32(void* raw_context, uint64_t address, uint32_t value) { +void TraceMemoryStoreI32(void* raw_context, uint32_t address, uint32_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("store.i32 %.8llX = %d (%X)\n", address, (int32_t)value, value); + DPRINT("store.i32 %.8X = %d (%X)\n", address, (int32_t)value, value); } -void TraceMemoryStoreI64(void* raw_context, uint64_t address, uint64_t value) { +void TraceMemoryStoreI64(void* raw_context, uint32_t address, uint64_t value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("store.i64 %.8llX = %lld (%llX)\n", address, (int64_t)value, value); + DPRINT("store.i64 %.8X = %lld (%llX)\n", address, (int64_t)value, value); } -void TraceMemoryStoreF32(void* raw_context, uint64_t address, __m128 value) { +void TraceMemoryStoreF32(void* raw_context, uint32_t address, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("store.f32 %.8llX = %e (%X)\n", address, poly::m128_f32<0>(value), + DPRINT("store.f32 %.8X = %e (%X)\n", address, poly::m128_f32<0>(value), poly::m128_i32<0>(value)); } -void TraceMemoryStoreF64(void* raw_context, uint64_t address, __m128 value) { +void TraceMemoryStoreF64(void* raw_context, uint32_t address, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("store.f64 %.8llX = %le (%llX)\n", address, poly::m128_f64<0>(value), + DPRINT("store.f64 %.8X = %le (%llX)\n", address, poly::m128_f64<0>(value), poly::m128_i64<0>(value)); } -void TraceMemoryStoreV128(void* raw_context, uint64_t address, __m128 value) { +void TraceMemoryStoreV128(void* raw_context, uint32_t address, __m128 value) { auto thread_state = *((ThreadState**)raw_context); - DPRINT("store.v128 %.8llX = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", + DPRINT("store.v128 %.8X = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", address, poly::m128_f32<0>(value), poly::m128_f32<1>(value), poly::m128_f32<2>(value), poly::m128_f32<3>(value), poly::m128_i32<0>(value), poly::m128_i32<1>(value), diff --git a/src/alloy/backend/x64/x64_tracers.h b/src/alloy/backend/x64/x64_tracers.h index 6ef29927b..9b50ce610 100644 --- a/src/alloy/backend/x64/x64_tracers.h +++ b/src/alloy/backend/x64/x64_tracers.h @@ -35,7 +35,8 @@ void TraceContextLoadI16(void* raw_context, uint64_t offset, uint16_t value); void TraceContextLoadI32(void* raw_context, uint64_t offset, uint32_t value); void TraceContextLoadI64(void* raw_context, uint64_t offset, uint64_t value); void TraceContextLoadF32(void* raw_context, uint64_t offset, __m128 value); -void TraceContextLoadF64(void* raw_context, uint64_t offset, __m128 value); +void TraceContextLoadF64(void* raw_context, uint64_t offset, + const double* value); void TraceContextLoadV128(void* raw_context, uint64_t offset, __m128 value); void TraceContextStoreI8(void* raw_context, uint64_t offset, uint8_t value); @@ -43,24 +44,25 @@ void TraceContextStoreI16(void* raw_context, uint64_t offset, uint16_t value); void TraceContextStoreI32(void* raw_context, uint64_t offset, uint32_t value); void TraceContextStoreI64(void* raw_context, uint64_t offset, uint64_t value); void TraceContextStoreF32(void* raw_context, uint64_t offset, __m128 value); -void TraceContextStoreF64(void* raw_context, uint64_t offset, __m128 value); +void TraceContextStoreF64(void* raw_context, uint64_t offset, + const double* value); void TraceContextStoreV128(void* raw_context, uint64_t offset, __m128 value); -void TraceMemoryLoadI8(void* raw_context, uint64_t address, uint8_t value); -void TraceMemoryLoadI16(void* raw_context, uint64_t address, uint16_t value); -void TraceMemoryLoadI32(void* raw_context, uint64_t address, uint32_t value); -void TraceMemoryLoadI64(void* raw_context, uint64_t address, uint64_t value); -void TraceMemoryLoadF32(void* raw_context, uint64_t address, __m128 value); -void TraceMemoryLoadF64(void* raw_context, uint64_t address, __m128 value); -void TraceMemoryLoadV128(void* raw_context, uint64_t address, __m128 value); +void TraceMemoryLoadI8(void* raw_context, uint32_t address, uint8_t value); +void TraceMemoryLoadI16(void* raw_context, uint32_t address, uint16_t value); +void TraceMemoryLoadI32(void* raw_context, uint32_t address, uint32_t value); +void TraceMemoryLoadI64(void* raw_context, uint32_t address, uint64_t value); +void TraceMemoryLoadF32(void* raw_context, uint32_t address, __m128 value); +void TraceMemoryLoadF64(void* raw_context, uint32_t address, __m128 value); +void TraceMemoryLoadV128(void* raw_context, uint32_t address, __m128 value); -void TraceMemoryStoreI8(void* raw_context, uint64_t address, uint8_t value); -void TraceMemoryStoreI16(void* raw_context, uint64_t address, uint16_t value); -void TraceMemoryStoreI32(void* raw_context, uint64_t address, uint32_t value); -void TraceMemoryStoreI64(void* raw_context, uint64_t address, uint64_t value); -void TraceMemoryStoreF32(void* raw_context, uint64_t address, __m128 value); -void TraceMemoryStoreF64(void* raw_context, uint64_t address, __m128 value); -void TraceMemoryStoreV128(void* raw_context, uint64_t address, __m128 value); +void TraceMemoryStoreI8(void* raw_context, uint32_t address, uint8_t value); +void TraceMemoryStoreI16(void* raw_context, uint32_t address, uint16_t value); +void TraceMemoryStoreI32(void* raw_context, uint32_t address, uint32_t value); +void TraceMemoryStoreI64(void* raw_context, uint32_t address, uint64_t value); +void TraceMemoryStoreF32(void* raw_context, uint32_t address, __m128 value); +void TraceMemoryStoreF64(void* raw_context, uint32_t address, __m128 value); +void TraceMemoryStoreV128(void* raw_context, uint32_t address, __m128 value); } // namespace x64 } // namespace backend From fa1693d3a31a9f6c8a1938d9fa53b06492b006cb Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 7 Aug 2014 13:23:44 -0700 Subject: [PATCH 092/388] ADD_CARRY constant prop for load-CA cases. --- .../passes/constant_propagation_pass.cc | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/alloy/compiler/passes/constant_propagation_pass.cc b/src/alloy/compiler/passes/constant_propagation_pass.cc index 330e93fac..64eeb5f1d 100644 --- a/src/alloy/compiler/passes/constant_propagation_pass.cc +++ b/src/alloy/compiler/passes/constant_propagation_pass.cc @@ -300,6 +300,26 @@ int ConstantPropagationPass::Run(HIRBuilder* builder) { } break; // TODO(benvanik): ADD_CARRY (w/ ARITHMETIC_SET_CARRY) + case OPCODE_ADD_CARRY: + if (i->src1.value->IsConstantZero() && i->src2.value->IsConstantZero()) { + Value* ca = i->src3.value; + // If carry is set find the DID_CARRY and fix it. + if (!!(i->flags & ARITHMETIC_SET_CARRY)) { + auto next = i->dest->use_head; + while (next) { + auto use = next; + next = use->next; + if (use->instr->opcode == &OPCODE_DID_CARRY_info) { + // Replace carry value. + use->instr->Replace(&OPCODE_ASSIGN_info, 0); + use->instr->set_src1(ca); + } + } + } + i->Replace(&OPCODE_ASSIGN_info, 0); + i->set_src1(ca); + } + break; case OPCODE_SUB: if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { v->set_from(i->src1.value); From a5a0fd61e2c28e355e9a677aff35f9fd61517614 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 8 Aug 2014 15:24:48 -0700 Subject: [PATCH 093/388] Full display info struct. --- src/xenia/kernel/xboxkrnl_video.cc | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/xenia/kernel/xboxkrnl_video.cc b/src/xenia/kernel/xboxkrnl_video.cc index 66fb241ae..1a6adead1 100644 --- a/src/xenia/kernel/xboxkrnl_video.cc +++ b/src/xenia/kernel/xboxkrnl_video.cc @@ -77,17 +77,34 @@ SHIM_CALL VdGetCurrentDisplayInformation_shim( ptr); // Expecting a length 0x58 struct of stuff. - SHIM_SET_MEM_32(ptr + 0x10, 1280); - SHIM_SET_MEM_32(ptr + 0x14, 720); - SHIM_SET_MEM_16(ptr + 0x48, 1280); - SHIM_SET_MEM_16(ptr + 0x4A, 720); - SHIM_SET_MEM_16(ptr + 0x56, 1280); + SHIM_SET_MEM_32(ptr + 0, (1280 << 16) | 720); + SHIM_SET_MEM_32(ptr + 4, 0); + SHIM_SET_MEM_32(ptr + 8, 0); + SHIM_SET_MEM_32(ptr + 12, 0); + SHIM_SET_MEM_32(ptr + 16, 1280); // backbuffer width? + SHIM_SET_MEM_32(ptr + 20, 720); // backbuffer height? + SHIM_SET_MEM_32(ptr + 24, 1280); + SHIM_SET_MEM_32(ptr + 28, 720); + SHIM_SET_MEM_32(ptr + 32, 1); + SHIM_SET_MEM_32(ptr + 36, 0); + SHIM_SET_MEM_32(ptr + 40, 0); + SHIM_SET_MEM_32(ptr + 44, 0); + SHIM_SET_MEM_32(ptr + 48, 1); + SHIM_SET_MEM_32(ptr + 52, 0); + SHIM_SET_MEM_32(ptr + 56, 0); + SHIM_SET_MEM_32(ptr + 60, 0); + SHIM_SET_MEM_32(ptr + 64, 0x014000B4); // ? + SHIM_SET_MEM_32(ptr + 68, 0x014000B4); // ? + SHIM_SET_MEM_32(ptr + 72, (1280 << 16) | 720); // actual display size? + SHIM_SET_MEM_32(ptr + 76, 0x42700000); + SHIM_SET_MEM_32(ptr + 80, 0); + SHIM_SET_MEM_32(ptr + 84, 1280); // display width } uint32_t xeVdQueryVideoFlags() { // ? - return 0x00000007; + return 0x00000006; } From b5826e0e942868225a9cd19dab6952d4da358524 Mon Sep 17 00:00:00 2001 From: wszechpolak Date: Thu, 14 Aug 2014 21:37:57 +0200 Subject: [PATCH 094/388] Added stub of NtQueryVirtualMemory --- src/xenia/kernel/xboxkrnl_memory.cc | 43 +++++++++++++++++++++++++++++ src/xenia/kernel/xboxkrnl_memory.h | 14 ++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/xenia/kernel/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl_memory.cc index 9f10b4fba..abe96d4a0 100644 --- a/src/xenia/kernel/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl_memory.cc @@ -189,6 +189,48 @@ SHIM_CALL NtFreeVirtualMemory_shim( } +X_STATUS xeNtQueryVirtualMemory( + uint32_t* base_addr_ptr, X_MEMORY_BASIC_INFORMATION *memory_basic_information, bool swap) { + + memory_basic_information->base_address = XEROUNDUP(*base_addr_ptr, 4096); + memory_basic_information->allocation_base = NULL; + memory_basic_information->allocation_protect = 0; + memory_basic_information->region_size = 0; + memory_basic_information->state = X_MEM_FREE; + memory_basic_information->protect = X_PAGE_NOACCESS; + memory_basic_information->type = 0; + + if (swap) { + memory_basic_information->base_address = poly::byte_swap(memory_basic_information->base_address); + memory_basic_information->allocation_base = poly::byte_swap(memory_basic_information->allocation_base); + memory_basic_information->allocation_protect = poly::byte_swap(memory_basic_information->allocation_protect); + memory_basic_information->region_size = poly::byte_swap(memory_basic_information->region_size); + memory_basic_information->state = poly::byte_swap(memory_basic_information->state); + memory_basic_information->protect = poly::byte_swap(memory_basic_information->protect); + memory_basic_information->type = poly::byte_swap(memory_basic_information->type); + } + + XELOGE("NtQueryVirtualMemory NOT IMPLEMENTED"); + + return X_STATUS_SUCCESS; +} + + +SHIM_CALL NtQueryVirtualMemory_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t base_addr_ptr = SHIM_GET_ARG_32(0); + uint32_t memory_basic_information_ptr = SHIM_GET_ARG_32(1); + X_MEMORY_BASIC_INFORMATION *memory_basic_information = (X_MEMORY_BASIC_INFORMATION*)SHIM_MEM_ADDR(memory_basic_information_ptr); + + XELOGD( + "NtQueryVirtualMemory(%.8X, %.8X)", + base_addr_ptr, memory_basic_information_ptr); + + X_STATUS result = xeNtQueryVirtualMemory(&base_addr_ptr, memory_basic_information, true); + SHIM_SET_RETURN_32(result); +} + + uint32_t xeMmAllocatePhysicalMemoryEx( uint32_t type, uint32_t region_size, uint32_t protect_bits, uint32_t min_addr_range, uint32_t max_addr_range, uint32_t alignment) { @@ -513,6 +555,7 @@ void xe::kernel::xboxkrnl::RegisterMemoryExports( ExportResolver* export_resolver, KernelState* state) { SHIM_SET_MAPPING("xboxkrnl.exe", NtAllocateVirtualMemory, state); SHIM_SET_MAPPING("xboxkrnl.exe", NtFreeVirtualMemory, state); + SHIM_SET_MAPPING("xboxkrnl.exe", NtQueryVirtualMemory, state); //SHIM_SET_MAPPING("xboxkrnl.exe", MmAllocatePhysicalMemory, state); SHIM_SET_MAPPING("xboxkrnl.exe", MmAllocatePhysicalMemoryEx, state); SHIM_SET_MAPPING("xboxkrnl.exe", MmFreePhysicalMemory, state); diff --git a/src/xenia/kernel/xboxkrnl_memory.h b/src/xenia/kernel/xboxkrnl_memory.h index 0796dd78b..0b59f5420 100644 --- a/src/xenia/kernel/xboxkrnl_memory.h +++ b/src/xenia/kernel/xboxkrnl_memory.h @@ -20,6 +20,20 @@ namespace xe { namespace kernel { +#pragma pack(push, 1) +typedef struct { + uint32_t base_address; + uint32_t allocation_base; + uint32_t allocation_protect; + uint32_t region_size; + uint32_t state; + uint32_t protect; + uint32_t type; +} +X_MEMORY_BASIC_INFORMATION; +#pragma pack(pop) + + X_STATUS xeNtAllocateVirtualMemory( uint32_t* base_addr_ptr, uint32_t* region_size_ptr, uint32_t allocation_type, uint32_t protect_bits, From b618f38e6296eee0e13303500aeb949261a2faca Mon Sep 17 00:00:00 2001 From: wszechpolak Date: Thu, 14 Aug 2014 22:10:11 +0200 Subject: [PATCH 095/388] Pass base address without reference --- src/xenia/kernel/xboxkrnl_memory.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/xenia/kernel/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl_memory.cc index abe96d4a0..487d4757a 100644 --- a/src/xenia/kernel/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl_memory.cc @@ -190,9 +190,10 @@ SHIM_CALL NtFreeVirtualMemory_shim( X_STATUS xeNtQueryVirtualMemory( - uint32_t* base_addr_ptr, X_MEMORY_BASIC_INFORMATION *memory_basic_information, bool swap) { + uint32_t base_address, X_MEMORY_BASIC_INFORMATION *memory_basic_information, bool swap) { - memory_basic_information->base_address = XEROUNDUP(*base_addr_ptr, 4096); + // Just pretend that there is no virtual address allocated at given base address + memory_basic_information->base_address = XEROUNDUP(base_address, 4096); memory_basic_information->allocation_base = NULL; memory_basic_information->allocation_protect = 0; memory_basic_information->region_size = 0; @@ -218,15 +219,15 @@ X_STATUS xeNtQueryVirtualMemory( SHIM_CALL NtQueryVirtualMemory_shim( PPCContext* ppc_state, KernelState* state) { - uint32_t base_addr_ptr = SHIM_GET_ARG_32(0); + uint32_t base_address = SHIM_GET_ARG_32(0); uint32_t memory_basic_information_ptr = SHIM_GET_ARG_32(1); X_MEMORY_BASIC_INFORMATION *memory_basic_information = (X_MEMORY_BASIC_INFORMATION*)SHIM_MEM_ADDR(memory_basic_information_ptr); XELOGD( "NtQueryVirtualMemory(%.8X, %.8X)", - base_addr_ptr, memory_basic_information_ptr); + base_address, memory_basic_information_ptr); - X_STATUS result = xeNtQueryVirtualMemory(&base_addr_ptr, memory_basic_information, true); + X_STATUS result = xeNtQueryVirtualMemory(base_address, memory_basic_information, true); SHIM_SET_RETURN_32(result); } From 50684f8f0d6c981649c31bbd396ff3980c5d147b Mon Sep 17 00:00:00 2001 From: wszechpolak Date: Fri, 15 Aug 2014 08:14:57 +0200 Subject: [PATCH 096/388] Implemented NtQueryVirtualMemory --- src/alloy/memory.h | 1 + src/xenia/cpu/xenon_memory.cc | 6 ++++++ src/xenia/cpu/xenon_memory.h | 1 + src/xenia/kernel/xboxkrnl_memory.cc | 24 ++++++++++++++++-------- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/alloy/memory.h b/src/alloy/memory.h index a29d12170..0a1f861ad 100644 --- a/src/alloy/memory.h +++ b/src/alloy/memory.h @@ -55,6 +55,7 @@ class Memory { uint32_t alignment = 0x20) = 0; virtual int HeapFree(uint64_t address, size_t size) = 0; + virtual size_t QueryInformation(uint64_t base_address, MEMORY_BASIC_INFORMATION mem_info) = 0; virtual size_t QuerySize(uint64_t base_address) = 0; virtual int Protect(uint64_t address, size_t size, uint32_t access) = 0; diff --git a/src/xenia/cpu/xenon_memory.cc b/src/xenia/cpu/xenon_memory.cc index 37bac9c61..c04bb7083 100644 --- a/src/xenia/cpu/xenon_memory.cc +++ b/src/xenia/cpu/xenon_memory.cc @@ -415,6 +415,12 @@ int XenonMemory::HeapFree(uint64_t address, size_t size) { } } +size_t XenonMemory::QueryInformation(uint64_t base_address, MEMORY_BASIC_INFORMATION mem_info) { + uint8_t* p = Translate(base_address); + + return VirtualQuery(p, &mem_info, sizeof(mem_info)); +} + size_t XenonMemory::QuerySize(uint64_t base_address) { if (base_address >= XENON_MEMORY_VIRTUAL_HEAP_LOW && base_address < XENON_MEMORY_VIRTUAL_HEAP_HIGH) { diff --git a/src/xenia/cpu/xenon_memory.h b/src/xenia/cpu/xenon_memory.h index dc5ff9354..4015dd08f 100644 --- a/src/xenia/cpu/xenon_memory.h +++ b/src/xenia/cpu/xenon_memory.h @@ -54,6 +54,7 @@ public: uint32_t alignment = 0x20) override; int HeapFree(uint64_t address, size_t size) override; + size_t QueryInformation(uint64_t base_address, MEMORY_BASIC_INFORMATION mem_info) override; size_t QuerySize(uint64_t base_address) override; int Protect(uint64_t address, size_t size, uint32_t access) override; diff --git a/src/xenia/kernel/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl_memory.cc index 487d4757a..9a9b8b258 100644 --- a/src/xenia/kernel/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl_memory.cc @@ -191,15 +191,23 @@ SHIM_CALL NtFreeVirtualMemory_shim( X_STATUS xeNtQueryVirtualMemory( uint32_t base_address, X_MEMORY_BASIC_INFORMATION *memory_basic_information, bool swap) { + KernelState* state = shared_kernel_state_; + assert_not_null(state); - // Just pretend that there is no virtual address allocated at given base address - memory_basic_information->base_address = XEROUNDUP(base_address, 4096); - memory_basic_information->allocation_base = NULL; - memory_basic_information->allocation_protect = 0; - memory_basic_information->region_size = 0; - memory_basic_information->state = X_MEM_FREE; - memory_basic_information->protect = X_PAGE_NOACCESS; - memory_basic_information->type = 0; + MEMORY_BASIC_INFORMATION mem_info; + size_t result = state->memory()->QueryInformation(base_address, mem_info); + + if (!result) { + return STATUS_INVALID_PARAMETER; + } + + memory_basic_information->base_address = (uint32_t) mem_info.BaseAddress; + memory_basic_information->allocation_base = (uint32_t) mem_info.AllocationBase; + memory_basic_information->allocation_protect = mem_info.AllocationProtect; + memory_basic_information->region_size = mem_info.RegionSize; + memory_basic_information->state = mem_info.State; + memory_basic_information->protect = mem_info.Protect; + memory_basic_information->type = mem_info.Type; if (swap) { memory_basic_information->base_address = poly::byte_swap(memory_basic_information->base_address); From cebf5959582fde54f91e76618e07ce870adb194a Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 9 Aug 2014 10:32:16 -0700 Subject: [PATCH 097/388] Skeleton for xdb. --- .gitmodules | 3 ++ src/xdb/sources.gypi | 10 ++++ src/xdb/xdb.cc | 13 ++++++ src/xdb/xdb.h | 18 ++++++++ third_party/wxWidgets | 1 + tools/tools.gypi | 1 + tools/xenia-debug/xenia-debug.cc | 34 ++++++++++++++ tools/xenia-debug/xenia-debug.gypi | 28 ++++++++++++ tools/xenia-run/xenia-run.gypi | 2 +- xenia-build.py | 18 ++++++++ xenia.gyp | 73 ++++++++++++++++++++++++++++++ 11 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 src/xdb/sources.gypi create mode 100644 src/xdb/xdb.cc create mode 100644 src/xdb/xdb.h create mode 160000 third_party/wxWidgets create mode 100644 tools/xenia-debug/xenia-debug.cc create mode 100644 tools/xenia-debug/xenia-debug.gypi diff --git a/.gitmodules b/.gitmodules index db77456b2..31ad04ace 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,6 @@ [submodule "third_party/ninja"] path = third_party/ninja url = https://chromium.googlesource.com/external/martine/ninja +[submodule "third_party/wxWidgets"] + path = third_party/wxWidgets + url = https://github.com/wxWidgets/wxWidgets.git diff --git a/src/xdb/sources.gypi b/src/xdb/sources.gypi new file mode 100644 index 000000000..f5ffe8297 --- /dev/null +++ b/src/xdb/sources.gypi @@ -0,0 +1,10 @@ +# Copyright 2014 Ben Vanik. All Rights Reserved. +{ + 'sources': [ + 'xdb.cc', + 'xdb.h', + ], + + 'includes': [ + ], +} diff --git a/src/xdb/xdb.cc b/src/xdb/xdb.cc new file mode 100644 index 000000000..f6d955728 --- /dev/null +++ b/src/xdb/xdb.cc @@ -0,0 +1,13 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +void test() { +} diff --git a/src/xdb/xdb.h b/src/xdb/xdb.h new file mode 100644 index 000000000..dbe6052ac --- /dev/null +++ b/src/xdb/xdb.h @@ -0,0 +1,18 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XDB_H_ +#define XDB_H_ + +#include +#include +#include +#include + +#endif // XDB_H_ diff --git a/third_party/wxWidgets b/third_party/wxWidgets new file mode 160000 index 000000000..ae2f2a1ec --- /dev/null +++ b/third_party/wxWidgets @@ -0,0 +1 @@ +Subproject commit ae2f2a1ece3b62a734b1c40d0d989fad49e075dc diff --git a/tools/tools.gypi b/tools/tools.gypi index 07a980f97..ab8e44c99 100644 --- a/tools/tools.gypi +++ b/tools/tools.gypi @@ -2,6 +2,7 @@ { 'includes': [ 'alloy-sandbox/alloy-sandbox.gypi', + 'xenia-debug/xenia-debug.gypi', 'xenia-run/xenia-run.gypi', #'xenia-test/xenia-test.gypi', ], diff --git a/tools/xenia-debug/xenia-debug.cc b/tools/xenia-debug/xenia-debug.cc new file mode 100644 index 000000000..630491c20 --- /dev/null +++ b/tools/xenia-debug/xenia-debug.cc @@ -0,0 +1,34 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include + + +//using namespace xdb; + + +int xenia_debug(int argc, xechar_t** argv) { + int result_code = 1; + + // Create platform abstraction layer. + xe_pal_options_t pal_options; + xe_zero_struct(&pal_options, sizeof(pal_options)); + XEEXPECTZERO(xe_pal_init(pal_options)); + + + result_code = 0; +XECLEANUP: + if (result_code) { + XEFATAL("Failed to launch debugger: %d", result_code); + } + return result_code; +} +XE_MAIN_WINDOW_THUNK(xenia_debug, XETEXT("xenia-debug"), "xenia-debug"); diff --git a/tools/xenia-debug/xenia-debug.gypi b/tools/xenia-debug/xenia-debug.gypi new file mode 100644 index 000000000..14ef1c990 --- /dev/null +++ b/tools/xenia-debug/xenia-debug.gypi @@ -0,0 +1,28 @@ +# Copyright 2013 Ben Vanik. All Rights Reserved. +{ + 'targets': [ + { + 'target_name': 'xenia-debug', + 'type': 'executable', + + 'msvs_settings': { + 'VCLinkerTool': { + 'SubSystem': '2' + } + }, + + 'dependencies': [ + 'xdb', + 'xenia', + ], + + 'include_dirs': [ + '.', + ], + + 'sources': [ + 'xenia-debug.cc', + ], + }, + ], +} diff --git a/tools/xenia-run/xenia-run.gypi b/tools/xenia-run/xenia-run.gypi index 6b9ba5c23..150cb062f 100644 --- a/tools/xenia-run/xenia-run.gypi +++ b/tools/xenia-run/xenia-run.gypi @@ -7,7 +7,7 @@ 'msvs_settings': { 'VCLinkerTool': { - #'SubSystem': '2' + 'SubSystem': '2' } }, diff --git a/xenia-build.py b/xenia-build.py index ff5fd32d6..702dcfdb4 100755 --- a/xenia-build.py +++ b/xenia-build.py @@ -282,6 +282,24 @@ class SetupCommand(Command): shell_call('python third_party/ninja/bootstrap.py ' + extra_args) print('') + # wxWidgets. + print('- wxWidgets...') + os.chdir('third_party/wxWidgets') + if sys.platform == 'win32': + shutil.copyfile('include/wx/msw/setup0.h', 'include/wx/msw/setup.h') + shell_call(' '.join([ + 'msbuild', + 'build\msw\wx_vc10.sln', + '/nologo', + '/verbosity:quiet', + '/p:Configuration=Release', + '/p:Platform=x64', + ])) + else: + print('WARNING: wxWidgets build not supported yet'); + os.chdir(cwd) + print('') + # Binutils. # TODO(benvanik): disable on Windows print('- binutils...') diff --git a/xenia.gyp b/xenia.gyp index 06ad0d428..ea353f570 100644 --- a/xenia.gyp +++ b/xenia.gyp @@ -444,5 +444,78 @@ 'src/xenia/sources.gypi', ], }, + + { + 'target_name': 'xdb', + 'product_name': 'xdb', + 'type': 'static_library', + + 'dependencies': [ + 'gflags', + 'xenia', + ], + 'export_dependent_settings': [ + 'gflags', + 'xenia', + ], + + 'direct_dependent_settings': { + 'include_dirs': [ + 'src/', + 'third_party/wxWidgets/include/', + ], + + 'target_conditions': [ + ['_type=="shared_library"', { + 'cflags': [ + ], + }], + ['_type=="executable"', { + 'conditions': [ + ['OS == "win"', { + 'libraries': [ + 'kernel32', + 'user32', + 'ole32', + 'wsock32', + 'Ws2_32', + 'Shell32', + # TODO(benvanik): root dir + '../../third_party/wxWidgets/lib/vc_x64_lib/wxbase31u', + '../../third_party/wxWidgets/lib/vc_x64_lib/wxmsw31u_core', + '../../third_party/wxWidgets/lib/vc_x64_lib/wxmsw31u_aui', + '../../third_party/wxWidgets/lib/vc_x64_lib/wxmsw31u_stc', + ], + }], + ['OS == "mac"', { + 'xcode_settings': { + 'OTHER_LDFLAGS': [ + ], + }, + }], + ['OS == "linux"', { + 'libraries': [ + '-lpthread', + '-ldl', + ], + }], + ], + }], + ], + }, + + 'cflags': [ + ], + + 'include_dirs': [ + '.', + 'src/', + 'third_party/wxWidgets/include/', + ], + + 'includes': [ + 'src/xdb/sources.gypi', + ], + }, ], } From c2755625943b87f543c35bd8ba76b1dcb32412da Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 14 Aug 2014 20:28:44 -0700 Subject: [PATCH 098/388] Mostly complete tracing. Probably a lot of bugs. --- .gitignore | 6 + src/alloy/backend/assembler.h | 1 + src/alloy/backend/ivm/ivm_assembler.cc | 2 +- src/alloy/backend/ivm/ivm_assembler.h | 2 +- src/alloy/backend/ivm/ivm_intcode.cc | 73 ++++--- src/alloy/backend/ivm/sources.gypi | 1 + src/alloy/backend/x64/x64_assembler.cc | 4 +- src/alloy/backend/x64/x64_assembler.h | 2 +- src/alloy/backend/x64/x64_emitter.cc | 196 ++++++++++++++++- src/alloy/backend/x64/x64_emitter.h | 10 +- src/alloy/frontend/context_info.cc | 7 +- src/alloy/frontend/context_info.h | 5 +- src/alloy/frontend/frontend.h | 2 +- src/alloy/frontend/ppc/ppc_context.h | 58 ++---- src/alloy/frontend/ppc/ppc_emit_fpu.cc | 9 +- src/alloy/frontend/ppc/ppc_frontend.cc | 6 +- src/alloy/frontend/ppc/ppc_frontend.h | 12 +- src/alloy/frontend/ppc/ppc_hir_builder.cc | 67 +++++- src/alloy/frontend/ppc/ppc_hir_builder.h | 19 +- src/alloy/frontend/ppc/ppc_translator.cc | 18 +- src/alloy/frontend/ppc/ppc_translator.h | 2 +- src/alloy/hir/hir_builder.cc | 28 ++- src/alloy/hir/hir_builder.h | 4 + src/alloy/hir/opcodes.h | 3 + src/alloy/hir/opcodes.inl | 6 + src/alloy/memory.cc | 2 +- src/alloy/memory.h | 4 + src/alloy/runtime/debug_info.h | 9 + src/alloy/runtime/function.cc | 31 +++ src/alloy/runtime/runtime.cc | 21 +- src/alloy/runtime/runtime.h | 6 +- src/poly/atomic.h | 30 +++ src/xdb/protocol.h | 232 +++++++++++++++++++++ src/xdb/sources.gypi | 1 + src/xdb/xdb.cc | 7 +- src/xenia/cpu/cpu-private.h | 10 +- src/xenia/cpu/cpu.cc | 34 ++- src/xenia/cpu/processor.cc | 22 +- src/xenia/cpu/xenon_runtime.cc | 11 +- src/xenia/cpu/xenon_runtime.h | 11 +- src/xenia/cpu/xenon_thread_state.cc | 27 +++ src/xenia/cpu/xenon_thread_state.h | 7 + src/xenia/debug_agent.cc | 79 +++++++ src/xenia/debug_agent.h | 44 ++++ src/xenia/emulator.cc | 28 +++ src/xenia/emulator.h | 7 +- src/xenia/kernel/kernel_state.cc | 4 + src/xenia/kernel/kernel_state.h | 2 + src/xenia/kernel/objects/xkernel_module.cc | 2 + src/xenia/kernel/objects/xmodule.cc | 19 ++ src/xenia/kernel/objects/xmodule.h | 2 + src/xenia/kernel/objects/xthread.cc | 14 ++ src/xenia/kernel/objects/xuser_module.cc | 2 + src/xenia/sources.gypi | 2 + 54 files changed, 1052 insertions(+), 161 deletions(-) create mode 100644 src/xdb/protocol.h create mode 100644 src/xenia/debug_agent.cc create mode 100644 src/xenia/debug_agent.h diff --git a/.gitignore b/.gitignore index e41172231..57cc0de77 100644 --- a/.gitignore +++ b/.gitignore @@ -49,6 +49,7 @@ tmtags npm-debug.log private/ +*.trace # ============================================================================== # Build system output @@ -70,3 +71,8 @@ build-out/ build-gen/ build-bin/ build-test/ + +# ============================================================================== +# Local-only paths +# ============================================================================== +attic/ diff --git a/src/alloy/backend/assembler.h b/src/alloy/backend/assembler.h index 161142389..5e721dbd9 100644 --- a/src/alloy/backend/assembler.h +++ b/src/alloy/backend/assembler.h @@ -43,6 +43,7 @@ class Assembler { virtual int Assemble(runtime::FunctionInfo* symbol_info, hir::HIRBuilder* builder, uint32_t debug_info_flags, std::unique_ptr debug_info, + uint32_t trace_flags, runtime::Function** out_function) = 0; protected: diff --git a/src/alloy/backend/ivm/ivm_assembler.cc b/src/alloy/backend/ivm/ivm_assembler.cc index 53d78e336..7585b7457 100644 --- a/src/alloy/backend/ivm/ivm_assembler.cc +++ b/src/alloy/backend/ivm/ivm_assembler.cc @@ -50,7 +50,7 @@ void IVMAssembler::Reset() { int IVMAssembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder, uint32_t debug_info_flags, std::unique_ptr debug_info, - Function** out_function) { + uint32_t trace_flags, Function** out_function) { SCOPE_profile_cpu_f("alloy"); // Reset when we leave. diff --git a/src/alloy/backend/ivm/ivm_assembler.h b/src/alloy/backend/ivm/ivm_assembler.h index eda2e864c..4fe079b37 100644 --- a/src/alloy/backend/ivm/ivm_assembler.h +++ b/src/alloy/backend/ivm/ivm_assembler.h @@ -31,7 +31,7 @@ class IVMAssembler : public Assembler { int Assemble(runtime::FunctionInfo* symbol_info, hir::HIRBuilder* builder, uint32_t debug_info_flags, std::unique_ptr debug_info, - runtime::Function** out_function) override; + uint32_t trace_flags, runtime::Function** out_function) override; private: Arena intcode_arena_; diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index f82ae39e7..b9122604d 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -11,11 +11,12 @@ #include -#include #include #include #include #include +#include +#include // TODO(benvanik): make a compile time flag? //#define DYNAMIC_REGISTER_ACCESS_CHECK(address) false @@ -246,6 +247,22 @@ int Translate_SOURCE_OFFSET(TranslationContext& ctx, Instr* i) { return 0; } +// TODO(benvanik): dispatch of register forms. +uint32_t IntCode_TRACE_SOURCE(IntCodeState& ics, const IntCode* i) { + // TODO(benvanik): append to active trace writer. + uint64_t trace_base = ics.thread_state->memory()->trace_base(); + if (trace_base) { + auto ev = xdb::protocol::InstrEvent::Append(trace_base); + ev->type = xdb::protocol::EventType::INSTR; + ev->thread_id = ics.thread_state->thread_id(); + ev->address = ics.rf[i->src1_reg].i32; + } + return IA_NEXT; +} +int Translate_TRACE_SOURCE(TranslationContext& ctx, Instr* i) { + return DispatchToC(ctx, i, IntCode_TRACE_SOURCE); +} + uint32_t IntCode_DEBUG_BREAK(IntCodeState& ics, const IntCode* i) { DFLUSH(); __debugbreak(); @@ -4174,33 +4191,33 @@ int Translate_ATOMIC_EXCHANGE(TranslationContext& ctx, Instr* i) { typedef int (*TranslateFn)(TranslationContext& ctx, Instr* i); static const TranslateFn dispatch_table[] = { Translate_COMMENT, Translate_NOP, - Translate_SOURCE_OFFSET, Translate_DEBUG_BREAK, - Translate_DEBUG_BREAK_TRUE, Translate_TRAP, - Translate_TRAP_TRUE, Translate_CALL, - Translate_CALL_TRUE, Translate_CALL_INDIRECT, - Translate_CALL_INDIRECT_TRUE, Translate_CALL_EXTERN, - Translate_RETURN, Translate_RETURN_TRUE, - Translate_SET_RETURN_ADDRESS, Translate_BRANCH, - Translate_BRANCH_TRUE, Translate_BRANCH_FALSE, - Translate_ASSIGN, Translate_CAST, - Translate_ZERO_EXTEND, Translate_SIGN_EXTEND, - Translate_TRUNCATE, Translate_CONVERT, - Translate_ROUND, Translate_VECTOR_CONVERT_I2F, - Translate_VECTOR_CONVERT_F2I, Translate_LOAD_VECTOR_SHL, - Translate_LOAD_VECTOR_SHR, Translate_LOAD_CLOCK, - Translate_LOAD_LOCAL, Translate_STORE_LOCAL, - Translate_LOAD_CONTEXT, Translate_STORE_CONTEXT, - Translate_LOAD, Translate_STORE, - Translate_PREFETCH, Translate_MAX, - Translate_VECTOR_MAX, Translate_MIN, - Translate_VECTOR_MIN, Translate_SELECT, - Translate_IS_TRUE, Translate_IS_FALSE, - Translate_COMPARE_EQ, Translate_COMPARE_NE, - Translate_COMPARE_SLT, Translate_COMPARE_SLE, - Translate_COMPARE_SGT, Translate_COMPARE_SGE, - Translate_COMPARE_ULT, Translate_COMPARE_ULE, - Translate_COMPARE_UGT, Translate_COMPARE_UGE, - Translate_DID_CARRY, + Translate_SOURCE_OFFSET, Translate_TRACE_SOURCE, + Translate_DEBUG_BREAK, Translate_DEBUG_BREAK_TRUE, + Translate_TRAP, Translate_TRAP_TRUE, + Translate_CALL, Translate_CALL_TRUE, + Translate_CALL_INDIRECT, Translate_CALL_INDIRECT_TRUE, + Translate_CALL_EXTERN, Translate_RETURN, + Translate_RETURN_TRUE, Translate_SET_RETURN_ADDRESS, + Translate_BRANCH, Translate_BRANCH_TRUE, + Translate_BRANCH_FALSE, Translate_ASSIGN, + Translate_CAST, Translate_ZERO_EXTEND, + Translate_SIGN_EXTEND, Translate_TRUNCATE, + Translate_CONVERT, Translate_ROUND, + Translate_VECTOR_CONVERT_I2F, Translate_VECTOR_CONVERT_F2I, + Translate_LOAD_VECTOR_SHL, Translate_LOAD_VECTOR_SHR, + Translate_LOAD_CLOCK, Translate_LOAD_LOCAL, + Translate_STORE_LOCAL, Translate_LOAD_CONTEXT, + Translate_STORE_CONTEXT, Translate_LOAD, + Translate_STORE, Translate_PREFETCH, + Translate_MAX, Translate_VECTOR_MAX, + Translate_MIN, Translate_VECTOR_MIN, + Translate_SELECT, Translate_IS_TRUE, + Translate_IS_FALSE, Translate_COMPARE_EQ, + Translate_COMPARE_NE, Translate_COMPARE_SLT, + Translate_COMPARE_SLE, Translate_COMPARE_SGT, + Translate_COMPARE_SGE, Translate_COMPARE_ULT, + Translate_COMPARE_ULE, Translate_COMPARE_UGT, + Translate_COMPARE_UGE, Translate_DID_CARRY, TranslateInvalid, // Translate_DID_OVERFLOW, Translate_DID_SATURATE, Translate_VECTOR_COMPARE_EQ, Translate_VECTOR_COMPARE_SGT, Translate_VECTOR_COMPARE_SGE, diff --git a/src/alloy/backend/ivm/sources.gypi b/src/alloy/backend/ivm/sources.gypi index c13431404..20306f9fb 100644 --- a/src/alloy/backend/ivm/sources.gypi +++ b/src/alloy/backend/ivm/sources.gypi @@ -8,6 +8,7 @@ 'ivm_backend.cc', 'ivm_backend.h', 'ivm_function.cc', + 'ivm_function.h', 'ivm_stack.cc', 'ivm_stack.h', ], diff --git a/src/alloy/backend/x64/x64_assembler.cc b/src/alloy/backend/x64/x64_assembler.cc index 1fd0e2223..34b8928b2 100644 --- a/src/alloy/backend/x64/x64_assembler.cc +++ b/src/alloy/backend/x64/x64_assembler.cc @@ -58,7 +58,7 @@ void X64Assembler::Reset() { int X64Assembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder, uint32_t debug_info_flags, std::unique_ptr debug_info, - Function** out_function) { + uint32_t trace_flags, Function** out_function) { SCOPE_profile_cpu_f("alloy"); // Reset when we leave. @@ -68,7 +68,7 @@ int X64Assembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder, void* machine_code = 0; size_t code_size = 0; int result = emitter_->Emit(builder, debug_info_flags, debug_info.get(), - machine_code, code_size); + trace_flags, machine_code, code_size); if (result) { return result; } diff --git a/src/alloy/backend/x64/x64_assembler.h b/src/alloy/backend/x64/x64_assembler.h index 9959a1135..a1b81e198 100644 --- a/src/alloy/backend/x64/x64_assembler.h +++ b/src/alloy/backend/x64/x64_assembler.h @@ -37,7 +37,7 @@ class X64Assembler : public Assembler { int Assemble(runtime::FunctionInfo* symbol_info, hir::HIRBuilder* builder, uint32_t debug_info_flags, std::unique_ptr debug_info, - runtime::Function** out_function) override; + uint32_t trace_flags, runtime::Function** out_function) override; private: void DumpMachineCode(runtime::DebugInfo* debug_info, void* machine_code, diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index 2661c54d1..bf583829d 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -19,6 +19,7 @@ #include #include #include +#include namespace alloy { namespace backend { @@ -66,8 +67,8 @@ X64Emitter::~X64Emitter() {} int X64Emitter::Initialize() { return 0; } int X64Emitter::Emit(HIRBuilder* builder, uint32_t debug_info_flags, - runtime::DebugInfo* debug_info, void*& out_code_address, - size_t& out_code_size) { + runtime::DebugInfo* debug_info, uint32_t trace_flags, + void*& out_code_address, size_t& out_code_size) { SCOPE_profile_cpu_f("alloy"); // Reset. @@ -75,6 +76,7 @@ int X64Emitter::Emit(HIRBuilder* builder, uint32_t debug_info_flags, source_map_count_ = 0; source_map_arena_.Reset(); } + trace_flags_ = trace_flags; // Fill the generator with code. size_t stack_size = 0; @@ -151,6 +153,19 @@ int X64Emitter::Emit(HIRBuilder* builder, size_t& out_stack_size) { mov(rdx, qword[rcx + 8]); // membase } + uint64_t trace_base = runtime_->memory()->trace_base(); + if (trace_base && trace_flags_ & TRACE_USER_CALLS) { + mov(rax, trace_base); + mov(r8d, static_cast(sizeof(xdb::protocol::UserCallEvent))); + lock(); + xadd(qword[rax], r8); + mov(rax, static_cast(xdb::protocol::EventType::USER_CALL) | + (static_cast(0) << 8) | (0ull << 32)); + mov(qword[r8], rax); + EmitGetCurrentThreadId(); + mov(word[r8 + 2], ax); + } + // Body. auto block = builder->first_block(); while (block) { @@ -165,6 +180,16 @@ int X64Emitter::Emit(HIRBuilder* builder, size_t& out_stack_size) { const Instr* instr = block->instr_head; while (instr) { const Instr* new_tail = instr; + + // Special handling of TRACE_SOURCE. + if (instr->opcode == &OPCODE_TRACE_SOURCE_info) { + if (trace_flags_ & TRACE_SOURCE) { + EmitTraceSource(instr); + } + instr = instr->next; + continue; + } + if (!SelectSequence(*this, instr, &new_tail)) { // No sequence found! assert_always(); @@ -179,6 +204,7 @@ int X64Emitter::Emit(HIRBuilder* builder, size_t& out_stack_size) { // Function epilog. L("epilog"); + EmitTraceUserCallReturn(); if (emit_prolog) { mov(rcx, qword[rsp + StackLayout::GUEST_RCX_HOME]); add(rsp, (uint32_t)stack_size); @@ -204,6 +230,129 @@ void X64Emitter::MarkSourceOffset(const Instr* i) { source_map_count_++; } +void X64Emitter::EmitTraceSource(const Instr* instr) { + uint64_t trace_base = runtime_->memory()->trace_base(); + if (!trace_base || !(trace_flags_ & TRACE_SOURCE)) { + return; + } + + // TODO(benvanik): make this a function call to some append fn. + + uint8_t dest_reg_0 = instr->flags & 0xFF; + uint8_t dest_reg_1 = instr->flags >> 8; + + xdb::protocol::EventType event_type; + size_t event_size; + if (dest_reg_0 == 100) { + event_type = xdb::protocol::EventType::INSTR; + event_size = sizeof(xdb::protocol::InstrEvent); + } else if (dest_reg_1 == 100) { + if (dest_reg_0 & (1 << 7)) { + event_type = xdb::protocol::EventType::INSTR_R16; + event_size = sizeof(xdb::protocol::InstrEventR16); + } else { + event_type = xdb::protocol::EventType::INSTR_R8; + event_size = sizeof(xdb::protocol::InstrEventR8); + } + } else { + if (dest_reg_0 & (1 << 7) && dest_reg_1 & (1 << 7)) { + event_type = xdb::protocol::EventType::INSTR_R16_R16; + event_size = sizeof(xdb::protocol::InstrEventR16R16); + } else if (dest_reg_0 & (1 << 7) && !(dest_reg_1 & (1 << 7))) { + event_type = xdb::protocol::EventType::INSTR_R16_R8; + event_size = sizeof(xdb::protocol::InstrEventR16R8); + } else if (!(dest_reg_0 & (1 << 7)) && dest_reg_1 & (1 << 7)) { + event_type = xdb::protocol::EventType::INSTR_R8_R16; + event_size = sizeof(xdb::protocol::InstrEventR8R16); + } else if (!(dest_reg_0 & (1 << 7)) && !(dest_reg_1 & (1 << 7))) { + event_type = xdb::protocol::EventType::INSTR_R8_R8; + event_size = sizeof(xdb::protocol::InstrEventR8R8); + } + } + + mov(rax, trace_base); + mov(r8d, static_cast(event_size)); + lock(); + xadd(qword[rax], r8); + // r8 is now the pointer where we can write our event. + + // Write the header, which is the same for everything (pretty much). + // Some event types ignore the dest reg, and that's fine. + uint64_t qword_0 = static_cast(event_type) | + (static_cast(dest_reg_0) << 8) | + (instr->src1.offset << 32); + mov(rax, qword_0); + mov(qword[r8], rax); + + // Write thread ID. + EmitGetCurrentThreadId(); + mov(word[r8 + 2], ax); + + switch (event_type) { + case xdb::protocol::EventType::INSTR: + break; + case xdb::protocol::EventType::INSTR_R8: + case xdb::protocol::EventType::INSTR_R16: + if (dest_reg_0 & (1 << 7)) { + EmitTraceSourceAppendValue(instr->src2.value, 8); + } else { + EmitTraceSourceAppendValue(instr->src2.value, 8); + } + break; + case xdb::protocol::EventType::INSTR_R8_R8: + case xdb::protocol::EventType::INSTR_R8_R16: + case xdb::protocol::EventType::INSTR_R16_R8: + case xdb::protocol::EventType::INSTR_R16_R16: + mov(word[r8 + 8], dest_reg_0 | static_cast(dest_reg_1 << 8)); + size_t offset = 8; + if (dest_reg_0 & (1 << 7)) { + EmitTraceSourceAppendValue(instr->src2.value, offset); + offset += 16; + } else { + EmitTraceSourceAppendValue(instr->src2.value, offset); + offset += 8; + } + if (dest_reg_1 & (1 << 7)) { + EmitTraceSourceAppendValue(instr->src3.value, offset); + offset += 16; + } else { + EmitTraceSourceAppendValue(instr->src3.value, offset); + offset += 8; + } + break; + } +} + +void X64Emitter::EmitTraceSourceAppendValue(const Value* value, + size_t r8_offset) { + // +} + +void X64Emitter::EmitGetCurrentThreadId() { + // rcx must point to context. We could fetch from the stack if needed. + mov(ax, + word[rcx + runtime_->frontend()->context_info()->thread_id_offset()]); +} + +void X64Emitter::EmitTraceUserCallReturn() { + auto trace_base = runtime_->memory()->trace_base(); + if (!trace_base || !(trace_flags_ & TRACE_USER_CALLS)) { + return; + } + mov(rdx, rax); + mov(rax, trace_base); + mov(r8d, static_cast(sizeof(xdb::protocol::UserCallReturnEvent))); + lock(); + xadd(qword[rax], r8); + mov(rax, static_cast(xdb::protocol::EventType::USER_CALL_RETURN) | + (static_cast(0) << 8) | (0ull << 32)); + mov(qword[r8], rax); + EmitGetCurrentThreadId(); + mov(word[r8 + 2], ax); + mov(rax, rdx); + ReloadEDX(); +} + void X64Emitter::DebugBreak() { // TODO(benvanik): notify debugger. db(0xCC); @@ -258,7 +407,7 @@ uint64_t ResolveFunctionSymbol(void* raw_context, uint64_t symbol_info_ptr) { #else uint64_t return_address = reinterpret_cast(__builtin_return_address(0)); -#endif // XE_WIN32_LIKE +#endif // XE_LIKE_WIN32 #pragma pack(push, 1) struct Asm { uint16_t mov_rax; @@ -301,6 +450,9 @@ void X64Emitter::Call(const hir::Instr* instr, // Actually jump/call to rax. if (instr->flags & CALL_TAIL) { + // Since we skip the prolog we need to mark the return here. + EmitTraceUserCallReturn(); + // Pass the callers return address over. mov(rdx, qword[rsp + StackLayout::GUEST_RET_ADDR]); @@ -338,7 +490,7 @@ uint64_t ResolveFunctionAddress(void* raw_context, uint64_t target_address) { #else uint64_t return_address = reinterpret_cast(__builtin_return_address(0)); -#endif // XE_WIN32_LIKE +#endif // XE_LIKE_WIN32 #pragma pack(push, 1) struct Asm { uint16_t cmp_rdx; @@ -426,6 +578,9 @@ void X64Emitter::CallIndirect(const hir::Instr* instr, const Reg64& reg) { // Actually jump/call to rax. L(skip_resolve); if (instr->flags & CALL_TAIL) { + // Since we skip the prolog we need to mark the return here. + EmitTraceUserCallReturn(); + // Pass the callers return address over. mov(rdx, qword[rsp + StackLayout::GUEST_RET_ADDR]); @@ -449,6 +604,24 @@ uint64_t UndefinedCallExtern(void* raw_context, uint64_t symbol_info_ptr) { void X64Emitter::CallExtern(const hir::Instr* instr, const FunctionInfo* symbol_info) { assert_true(symbol_info->behavior() == FunctionInfo::BEHAVIOR_EXTERN); + + uint64_t trace_base = runtime_->memory()->trace_base(); + if (trace_base & trace_flags_ & TRACE_EXTERN_CALLS) { + mov(rax, trace_base); + mov(r8d, static_cast(sizeof(xdb::protocol::KernelCallEvent))); + lock(); + xadd(qword[rax], r8); + // TODO(benvanik): get module/ordinal. + uint32_t module_id = 0; + uint32_t ordinal = 0; + mov(rax, static_cast(xdb::protocol::EventType::KERNEL_CALL) | + (static_cast(0) << 8) | (module_id << 16) | + (ordinal)); + mov(qword[r8], rax); + EmitGetCurrentThreadId(); + mov(word[r8 + 2], ax); + } + if (!symbol_info->extern_handler()) { CallNative(UndefinedCallExtern, reinterpret_cast(symbol_info)); } else { @@ -466,6 +639,21 @@ void X64Emitter::CallExtern(const hir::Instr* instr, ReloadEDX(); // rax = host return } + if (trace_base && trace_flags_ & TRACE_EXTERN_CALLS) { + mov(rax, trace_base); + mov(r8d, + static_cast(sizeof(xdb::protocol::KernelCallReturnEvent))); + lock(); + xadd(qword[rax], r8); + uint32_t module_id = 0; + uint32_t ordinal = 0; + mov(rax, + static_cast(xdb::protocol::EventType::KERNEL_CALL_RETURN) | + (static_cast(0) << 8) | (0)); + mov(qword[r8], rax); + EmitGetCurrentThreadId(); + mov(word[r8 + 2], ax); + } } void X64Emitter::CallNative(void* fn) { diff --git a/src/alloy/backend/x64/x64_emitter.h b/src/alloy/backend/x64/x64_emitter.h index 05131d55a..86ffba7db 100644 --- a/src/alloy/backend/x64/x64_emitter.h +++ b/src/alloy/backend/x64/x64_emitter.h @@ -84,8 +84,8 @@ class X64Emitter : public Xbyak::CodeGenerator { int Initialize(); int Emit(hir::HIRBuilder* builder, uint32_t debug_info_flags, - runtime::DebugInfo* debug_info, void*& out_code_address, - size_t& out_code_size); + runtime::DebugInfo* debug_info, uint32_t trace_flags, + void*& out_code_address, size_t& out_code_size); public: // Reserved: rsp @@ -163,6 +163,10 @@ class X64Emitter : public Xbyak::CodeGenerator { protected: void* Emplace(size_t stack_size); int Emit(hir::HIRBuilder* builder, size_t& out_stack_size); + void EmitTraceSource(const hir::Instr* instr); + void EmitTraceSourceAppendValue(const hir::Value* value, size_t r8_offset); + void EmitGetCurrentThreadId(); + void EmitTraceUserCallReturn(); protected: runtime::Runtime* runtime_; @@ -177,6 +181,8 @@ class X64Emitter : public Xbyak::CodeGenerator { size_t stack_size_; + uint32_t trace_flags_; + static const uint32_t gpr_reg_map_[GPR_COUNT]; static const uint32_t xmm_reg_map_[XMM_COUNT]; }; diff --git a/src/alloy/frontend/context_info.cc b/src/alloy/frontend/context_info.cc index 126b77448..f14109124 100644 --- a/src/alloy/frontend/context_info.cc +++ b/src/alloy/frontend/context_info.cc @@ -12,8 +12,11 @@ namespace alloy { namespace frontend { -ContextInfo::ContextInfo(size_t size, uintptr_t thread_state_offset) - : size_(size), thread_state_offset_(thread_state_offset) {} +ContextInfo::ContextInfo(size_t size, uintptr_t thread_state_offset, + uintptr_t thread_id_offset) + : size_(size), + thread_state_offset_(thread_state_offset), + thread_id_offset_(thread_id_offset) {} ContextInfo::~ContextInfo() {} diff --git a/src/alloy/frontend/context_info.h b/src/alloy/frontend/context_info.h index 47cc8ae06..f9bf530d4 100644 --- a/src/alloy/frontend/context_info.h +++ b/src/alloy/frontend/context_info.h @@ -17,16 +17,19 @@ namespace frontend { class ContextInfo { public: - ContextInfo(size_t size, uintptr_t thread_state_offset); + ContextInfo(size_t size, uintptr_t thread_state_offset, + uintptr_t thread_id_offset); ~ContextInfo(); size_t size() const { return size_; } uintptr_t thread_state_offset() const { return thread_state_offset_; } + uintptr_t thread_id_offset() const { return thread_id_offset_; } private: size_t size_; uintptr_t thread_state_offset_; + uintptr_t thread_id_offset_; }; } // namespace frontend diff --git a/src/alloy/frontend/frontend.h b/src/alloy/frontend/frontend.h index ec43bee3d..7555324b3 100644 --- a/src/alloy/frontend/frontend.h +++ b/src/alloy/frontend/frontend.h @@ -40,7 +40,7 @@ class Frontend { virtual int DeclareFunction(runtime::FunctionInfo* symbol_info) = 0; virtual int DefineFunction(runtime::FunctionInfo* symbol_info, - uint32_t debug_info_flags, + uint32_t debug_info_flags, uint32_t trace_flags, runtime::Function** out_function) = 0; protected: diff --git a/src/alloy/frontend/ppc/ppc_context.h b/src/alloy/frontend/ppc/ppc_context.h index 6833f46cd..b9858323a 100644 --- a/src/alloy/frontend/ppc/ppc_context.h +++ b/src/alloy/frontend/ppc/ppc_context.h @@ -13,55 +13,28 @@ #include #include - namespace alloy { namespace runtime { class Runtime; class ThreadState; } } - namespace alloy { namespace frontend { namespace ppc { - using vec128_t = alloy::vec128_t; - -typedef union { - uint32_t value; - struct { - uint8_t lt :1; // Negative (LT) - result is negative - uint8_t gt :1; // Positive (GT) - result is positive (and not zero) - uint8_t eq :1; // Zero (EQ) - result is zero or a stwcx/stdcx completed successfully - uint8_t so :1; // Summary Overflow (SO) - copy of XER[SO] - } cr0; - struct { - uint8_t fx :1; // FP exception summary - copy of FPSCR[FX] - uint8_t fex :1; // FP enabled exception summary - copy of FPSCR[FEX] - uint8_t vx :1; // FP invalid operation exception summary - copy of FPSCR[VX] - uint8_t ox :1; // FP overflow exception - copy of FPSCR[OX] - } cr1; - struct { - uint8_t value :4; - } cr2; - struct { - uint8_t value :4; - } cr3; - struct { - uint8_t value :4; - } cr4; - struct { - uint8_t value :4; - } cr5; - struct { - uint8_t value :4; - } cr6; - struct { - uint8_t value :4; - } cr7; -} PPCCR; - +// Map: +// 0-31: GPR +// 32-63: FPR +// 64: LR +// 65: CTR +// 66: XER +// 67: FPSCR +// 68: VSCR +// 69-76: CR0-7 +// 100: invalid +// 128-256: VR #pragma pack(push, 4) typedef struct XECACHEALIGN64 PPCContext_s { @@ -194,12 +167,15 @@ typedef struct XECACHEALIGN64 PPCContext_s { // fpscr.value = (fpscr.value & ~0x000F8000) | v; // } + // Thread ID assigned to this context. + uint32_t thread_id; + // Reserve address for load acquire/store release. Shared. - uint32_t* reserve_address; + uint32_t* reserve_address; // Runtime-specific data pointer. Used on callbacks to get access to the // current runtime and its data. - runtime::Runtime* runtime; + runtime::Runtime* runtime; void SetRegFromString(const char* name, const char* value); bool CompareRegWithString(const char* name, const char* value, @@ -207,10 +183,8 @@ typedef struct XECACHEALIGN64 PPCContext_s { } PPCContext; #pragma pack(pop) - } // namespace ppc } // namespace frontend } // namespace alloy - #endif // ALLOY_FRONTEND_PPC_PPC_CONTEXT_H_ diff --git a/src/alloy/frontend/ppc/ppc_emit_fpu.cc b/src/alloy/frontend/ppc/ppc_emit_fpu.cc index c651c6d6e..8a332bf68 100644 --- a/src/alloy/frontend/ppc/ppc_emit_fpu.cc +++ b/src/alloy/frontend/ppc/ppc_emit_fpu.cc @@ -297,8 +297,8 @@ XEEMITTER(fnmsubsx, 0xEC00003C, A)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(fcfidx, 0xFC00069C, X)(PPCHIRBuilder& f, InstrData& i) { // frD <- signed_int64_to_double( frB ) - Value* v = f.Convert(f.Cast(f.LoadFPR(i.A.FRB), INT64_TYPE), FLOAT64_TYPE); - f.StoreFPR(i.A.FRT, v); + Value* v = f.Convert(f.Cast(f.LoadFPR(i.X.RB), INT64_TYPE), FLOAT64_TYPE); + f.StoreFPR(i.X.RT, v); // f.UpdateFPRF(v); if (i.A.Rc) { // e.update_cr_with_cond(1, v); @@ -337,7 +337,7 @@ XEEMITTER(fctiwx, 0xFC00001C, X)(PPCHIRBuilder& f, InstrData& i) { v = f.Cast(f.ZeroExtend(v, INT64_TYPE), FLOAT64_TYPE); f.StoreFPR(i.X.RT, v); // f.UpdateFPRF(v); - if (i.A.Rc) { + if (i.X.Rc) { // e.update_cr_with_cond(1, v); XEINSTRNOTIMPLEMENTED(); return 1; @@ -409,7 +409,8 @@ XEEMITTER(mffsx, 0xFC00048E, X)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } - f.StoreFPR(i.X.RT, f.Cast(f.LoadFPSCR(), FLOAT64_TYPE)); + Value* v = f.Cast(f.LoadFPSCR(), FLOAT64_TYPE); + f.StoreFPR(i.X.RT, v); return 0; } diff --git a/src/alloy/frontend/ppc/ppc_frontend.cc b/src/alloy/frontend/ppc/ppc_frontend.cc index 33451e21f..ce14ddfe3 100644 --- a/src/alloy/frontend/ppc/ppc_frontend.cc +++ b/src/alloy/frontend/ppc/ppc_frontend.cc @@ -47,7 +47,8 @@ PPCFrontend::PPCFrontend(Runtime* runtime) : Frontend(runtime) { InitializeIfNeeded(); std::unique_ptr context_info( - new ContextInfo(sizeof(PPCContext), offsetof(PPCContext, thread_state))); + new ContextInfo(sizeof(PPCContext), offsetof(PPCContext, thread_state), + offsetof(PPCContext, thread_id))); // Add fields/etc. context_info_ = std::move(context_info); } @@ -77,10 +78,11 @@ int PPCFrontend::DeclareFunction(FunctionInfo* symbol_info) { int PPCFrontend::DefineFunction(FunctionInfo* symbol_info, uint32_t debug_info_flags, + uint32_t trace_flags, Function** out_function) { PPCTranslator* translator = translator_pool_.Allocate(this); int result = - translator->Translate(symbol_info, debug_info_flags, out_function); + translator->Translate(symbol_info, debug_info_flags, trace_flags, out_function); translator_pool_.Release(translator); return result; } diff --git a/src/alloy/frontend/ppc/ppc_frontend.h b/src/alloy/frontend/ppc/ppc_frontend.h index 76e37f4a9..50608f934 100644 --- a/src/alloy/frontend/ppc/ppc_frontend.h +++ b/src/alloy/frontend/ppc/ppc_frontend.h @@ -24,14 +24,14 @@ class PPCTranslator; class PPCFrontend : public Frontend { public: PPCFrontend(runtime::Runtime* runtime); - virtual ~PPCFrontend(); + ~PPCFrontend() override; - virtual int Initialize(); + int Initialize() override; - virtual int DeclareFunction(runtime::FunctionInfo* symbol_info); - virtual int DefineFunction(runtime::FunctionInfo* symbol_info, - uint32_t debug_info_flags, - runtime::Function** out_function); + int DeclareFunction(runtime::FunctionInfo* symbol_info) override; + int DefineFunction(runtime::FunctionInfo* symbol_info, + uint32_t debug_info_flags, uint32_t trace_flags, + runtime::Function** out_function) override; private: TypePool translator_pool_; diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index 3d5cf5f41..660ac1107 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -43,7 +43,7 @@ void PPCHIRBuilder::Reset() { HIRBuilder::Reset(); } -int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, bool with_debug_info) { +int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) { SCOPE_profile_cpu_f("alloy"); Memory* memory = frontend_->memory(); @@ -53,7 +53,7 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, bool with_debug_info) { start_address_ = symbol_info->address(); instr_count_ = (symbol_info->end_address() - symbol_info->address()) / 4 + 1; - with_debug_info_ = with_debug_info; + with_debug_info_ = (flags & EMIT_DEBUG_COMMENTS) == EMIT_DEBUG_COMMENTS; if (with_debug_info_) { Comment("%s fn %.8X-%.8X %s", symbol_info->module()->name().c_str(), symbol_info->address(), symbol_info->end_address(), @@ -84,6 +84,7 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, bool with_debug_info) { i.code = poly::load_and_swap(p + address); // TODO(benvanik): find a way to avoid using the opcode tables. i.type = GetInstrType(i.code); + trace_info_.dest_count = 0; // Mark label, if we were assigned one earlier on in the walk. // We may still get a label, but it'll be inserted by LookupLabel @@ -136,6 +137,30 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, bool with_debug_info) { // DebugBreak(); // TraceInvalidInstruction(i); } + + if (flags & EMIT_TRACE_SOURCE) { + if (flags & EMIT_TRACE_SOURCE_VALUES) { + switch (trace_info_.dest_count) { + case 0: + TraceSource(i.address); + break; + case 1: + TraceSource(i.address, trace_info_.dests[0].reg, + trace_info_.dests[0].value); + break; + case 2: + TraceSource(i.address, trace_info_.dests[0].reg, + trace_info_.dests[0].value, trace_info_.dests[1].reg, + trace_info_.dests[1].value); + break; + default: + assert_unhandled_case(trace_info_.dest_count); + break; + } + } else { + TraceSource(i.address); + } + } } return Finalize(); @@ -205,6 +230,10 @@ Value* PPCHIRBuilder::LoadLR() { void PPCHIRBuilder::StoreLR(Value* value) { assert_true(value->type == INT64_TYPE); StoreContext(offsetof(PPCContext, lr), value); + + auto& trace_reg = trace_info_.dests[trace_info_.dest_count++]; + trace_reg.reg = 64; + trace_reg.value = value; } Value* PPCHIRBuilder::LoadCTR() { @@ -214,6 +243,10 @@ Value* PPCHIRBuilder::LoadCTR() { void PPCHIRBuilder::StoreCTR(Value* value) { assert_true(value->type == INT64_TYPE); StoreContext(offsetof(PPCContext, ctr), value); + + auto& trace_reg = trace_info_.dests[trace_info_.dest_count++]; + trace_reg.reg = 65; + trace_reg.value = value; } Value* PPCHIRBuilder::LoadCR(uint32_t n) { @@ -232,6 +265,8 @@ void PPCHIRBuilder::StoreCR(uint32_t n, Value* value) { void PPCHIRBuilder::StoreCRField(uint32_t n, uint32_t bit, Value* value) { StoreContext(offsetof(PPCContext, cr0) + (4 * n) + bit, value); + + // TODO(benvanik): trace CR. } void PPCHIRBuilder::UpdateCR(uint32_t n, Value* lhs, bool is_signed) { @@ -256,6 +291,8 @@ void PPCHIRBuilder::UpdateCR(uint32_t n, Value* lhs, Value* rhs, // Value* so = AllocValue(UINT8_TYPE); // StoreContext(offsetof(PPCContext, cr) + (4 * n) + 3, so); + + // TOOD(benvanik): trace CR. } void PPCHIRBuilder::UpdateCR6(Value* src_value) { @@ -265,6 +302,8 @@ void PPCHIRBuilder::UpdateCR6(Value* src_value) { StoreContext(offsetof(PPCContext, cr6.cr6_all_equal), IsFalse(Not(src_value))); StoreContext(offsetof(PPCContext, cr6.cr6_none_equal), IsFalse(src_value)); + + // TOOD(benvanik): trace CR. } Value* PPCHIRBuilder::LoadFPSCR() { @@ -274,6 +313,10 @@ Value* PPCHIRBuilder::LoadFPSCR() { void PPCHIRBuilder::StoreFPSCR(Value* value) { assert_true(value->type == INT64_TYPE); StoreContext(offsetof(PPCContext, fpscr), value); + + auto& trace_reg = trace_info_.dests[trace_info_.dest_count++]; + trace_reg.reg = 67; + trace_reg.value = value; } Value* PPCHIRBuilder::LoadXER() { @@ -290,6 +333,10 @@ Value* PPCHIRBuilder::LoadCA() { void PPCHIRBuilder::StoreCA(Value* value) { assert_true(value->type == INT8_TYPE); StoreContext(offsetof(PPCContext, xer_ca), value); + + auto& trace_reg = trace_info_.dests[trace_info_.dest_count++]; + trace_reg.reg = 66; + trace_reg.value = value; } Value* PPCHIRBuilder::LoadSAT() { @@ -299,6 +346,10 @@ Value* PPCHIRBuilder::LoadSAT() { void PPCHIRBuilder::StoreSAT(Value* value) { value = Truncate(value, INT8_TYPE); StoreContext(offsetof(PPCContext, vscr_sat), value); + + auto& trace_reg = trace_info_.dests[trace_info_.dest_count++]; + trace_reg.reg = 44; + trace_reg.value = value; } Value* PPCHIRBuilder::LoadGPR(uint32_t reg) { @@ -308,6 +359,10 @@ Value* PPCHIRBuilder::LoadGPR(uint32_t reg) { void PPCHIRBuilder::StoreGPR(uint32_t reg, Value* value) { assert_true(value->type == INT64_TYPE); StoreContext(offsetof(PPCContext, r) + reg * 8, value); + + auto& trace_reg = trace_info_.dests[trace_info_.dest_count++]; + trace_reg.reg = reg; + trace_reg.value = value; } Value* PPCHIRBuilder::LoadFPR(uint32_t reg) { @@ -317,6 +372,10 @@ Value* PPCHIRBuilder::LoadFPR(uint32_t reg) { void PPCHIRBuilder::StoreFPR(uint32_t reg, Value* value) { assert_true(value->type == FLOAT64_TYPE); StoreContext(offsetof(PPCContext, f) + reg * 8, value); + + auto& trace_reg = trace_info_.dests[trace_info_.dest_count++]; + trace_reg.reg = reg + 32; + trace_reg.value = value; } Value* PPCHIRBuilder::LoadVR(uint32_t reg) { @@ -326,6 +385,10 @@ Value* PPCHIRBuilder::LoadVR(uint32_t reg) { void PPCHIRBuilder::StoreVR(uint32_t reg, Value* value) { assert_true(value->type == VEC128_TYPE); StoreContext(offsetof(PPCContext, v) + reg * 16, value); + + auto& trace_reg = trace_info_.dests[trace_info_.dest_count++]; + trace_reg.reg = 128 + reg; + trace_reg.value = value; } Value* PPCHIRBuilder::LoadAcquire(Value* address, TypeName type, diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.h b/src/alloy/frontend/ppc/ppc_hir_builder.h index 67aeb350b..afbece4e3 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.h +++ b/src/alloy/frontend/ppc/ppc_hir_builder.h @@ -33,7 +33,15 @@ class PPCHIRBuilder : public hir::HIRBuilder { virtual void Reset(); - int Emit(runtime::FunctionInfo* symbol_info, bool with_debug_info); + enum EmitFlags { + // Emit comment nodes. + EMIT_DEBUG_COMMENTS = 1 << 0, + // Emit TraceSource nodes. + EMIT_TRACE_SOURCE = 1 << 1, + // Emit TraceSource nodes with the resulting values of the operations. + EMIT_TRACE_SOURCE_VALUES = EMIT_TRACE_SOURCE | (1 << 2), + }; + int Emit(runtime::FunctionInfo* symbol_info, uint32_t flags); runtime::FunctionInfo* symbol_info() const { return symbol_info_; } runtime::FunctionInfo* LookupFunction(uint64_t address); @@ -89,6 +97,15 @@ class PPCHIRBuilder : public hir::HIRBuilder { uint64_t instr_count_; Instr** instr_offset_list_; Label** label_list_; + + // Reset each instruction. + struct { + uint32_t dest_count; + struct { + uint8_t reg; + Value* value; + } dests[4]; + } trace_info_; }; } // namespace ppc diff --git a/src/alloy/frontend/ppc/ppc_translator.cc b/src/alloy/frontend/ppc/ppc_translator.cc index e1720f523..a6059459d 100644 --- a/src/alloy/frontend/ppc/ppc_translator.cc +++ b/src/alloy/frontend/ppc/ppc_translator.cc @@ -85,7 +85,7 @@ PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) { PPCTranslator::~PPCTranslator() = default; int PPCTranslator::Translate(FunctionInfo* symbol_info, - uint32_t debug_info_flags, + uint32_t debug_info_flags, uint32_t trace_flags, Function** out_function) { SCOPE_profile_cpu_f("alloy"); @@ -124,7 +124,16 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info, } // Emit function. - int result = builder_->Emit(symbol_info, debug_info != nullptr); + uint32_t emit_flags = 0; + if (debug_info) { + emit_flags |= PPCHIRBuilder::EMIT_DEBUG_COMMENTS; + } + if (trace_flags & TRACE_SOURCE_VALUES) { + emit_flags |= PPCHIRBuilder::EMIT_TRACE_SOURCE_VALUES; + } else if (trace_flags & TRACE_SOURCE) { + emit_flags |= PPCHIRBuilder::EMIT_TRACE_SOURCE; + } + int result = builder_->Emit(symbol_info, emit_flags); if (result) { return result; } @@ -150,8 +159,9 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info, } // Assemble to backend machine code. - result = assembler_->Assemble(symbol_info, builder_.get(), debug_info_flags, - std::move(debug_info), out_function); + result = + assembler_->Assemble(symbol_info, builder_.get(), debug_info_flags, + std::move(debug_info), trace_flags, out_function); if (result) { return result; } diff --git a/src/alloy/frontend/ppc/ppc_translator.h b/src/alloy/frontend/ppc/ppc_translator.h index 5b359f836..4c95e94b4 100644 --- a/src/alloy/frontend/ppc/ppc_translator.h +++ b/src/alloy/frontend/ppc/ppc_translator.h @@ -32,7 +32,7 @@ class PPCTranslator { ~PPCTranslator(); int Translate(runtime::FunctionInfo* symbol_info, uint32_t debug_info_flags, - runtime::Function** out_function); + uint32_t trace_flags, runtime::Function** out_function); private: void DumpSource(runtime::FunctionInfo* symbol_info, diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index 87d9f75f9..ac6eec173 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -649,6 +649,28 @@ void HIRBuilder::SourceOffset(uint64_t offset) { i->src2.value = i->src3.value = NULL; } +void HIRBuilder::TraceSource(uint64_t offset) { + Instr* i = AppendInstr(OPCODE_TRACE_SOURCE_info, 100 | (100 << 8)); + i->src1.offset = offset; + i->set_src2(LoadZero(INT64_TYPE)); + i->set_src3(LoadZero(INT64_TYPE)); +} + +void HIRBuilder::TraceSource(uint64_t offset, uint8_t index, Value* value) { + Instr* i = AppendInstr(OPCODE_TRACE_SOURCE_info, index | (100 << 8)); + i->src1.offset = offset; + i->set_src2(value); + i->set_src3(LoadZero(INT64_TYPE)); +} + +void HIRBuilder::TraceSource(uint64_t offset, uint8_t index_0, Value* value_0, + uint8_t index_1, Value* value_1) { + Instr* i = AppendInstr(OPCODE_TRACE_SOURCE_info, index_0 | (index_1 << 8)); + i->src1.offset = offset; + i->set_src2(value_0); + i->set_src3(value_1); +} + void HIRBuilder::DebugBreak() { Instr* i = AppendInstr(OPCODE_DEBUG_BREAK_info, 0); i->src1.value = i->src2.value = i->src3.value = NULL; @@ -1743,11 +1765,13 @@ Value* HIRBuilder::RotateLeft(Value* value1, Value* value2) { return i->dest; } -Value* HIRBuilder::VectorRotateLeft(Value* value1, Value* value2, TypeName part_type) { +Value* HIRBuilder::VectorRotateLeft(Value* value1, Value* value2, + TypeName part_type) { ASSERT_VECTOR_TYPE(value1); ASSERT_VECTOR_TYPE(value2); - Instr* i = AppendInstr(OPCODE_VECTOR_ROTATE_LEFT_info, part_type, AllocValue(value1->type)); + Instr* i = AppendInstr(OPCODE_VECTOR_ROTATE_LEFT_info, part_type, + AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); i->src3.value = NULL; diff --git a/src/alloy/hir/hir_builder.h b/src/alloy/hir/hir_builder.h index a6ec2ef4d..ae0b23e55 100644 --- a/src/alloy/hir/hir_builder.h +++ b/src/alloy/hir/hir_builder.h @@ -71,6 +71,10 @@ class HIRBuilder { void Nop(); void SourceOffset(uint64_t offset); + void TraceSource(uint64_t offset); + void TraceSource(uint64_t offset, uint8_t index, Value* value); + void TraceSource(uint64_t offset, uint8_t index_0, Value* value_0, + uint8_t index_1, Value* value_1); // trace info/etc void DebugBreak(); diff --git a/src/alloy/hir/opcodes.h b/src/alloy/hir/opcodes.h index ca63f69eb..cfca101a0 100644 --- a/src/alloy/hir/opcodes.h +++ b/src/alloy/hir/opcodes.h @@ -77,6 +77,7 @@ enum Opcode { OPCODE_COMMENT, OPCODE_NOP, OPCODE_SOURCE_OFFSET, + OPCODE_TRACE_SOURCE, OPCODE_DEBUG_BREAK, OPCODE_DEBUG_BREAK_TRUE, OPCODE_TRAP, @@ -207,6 +208,8 @@ enum OpcodeSignature { OPCODE_SIG_X_O = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_O << 3), OPCODE_SIG_X_O_V = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_O << 3) | (OPCODE_SIG_TYPE_V << 6), + OPCODE_SIG_X_O_V_V = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_O << 3) | + (OPCODE_SIG_TYPE_V << 6) | (OPCODE_SIG_TYPE_V << 9), OPCODE_SIG_X_S = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_S << 3), OPCODE_SIG_X_V = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3), OPCODE_SIG_X_V_L = diff --git a/src/alloy/hir/opcodes.inl b/src/alloy/hir/opcodes.inl index 77c51bb5a..3baf405c8 100644 --- a/src/alloy/hir/opcodes.inl +++ b/src/alloy/hir/opcodes.inl @@ -26,6 +26,12 @@ DEFINE_OPCODE( OPCODE_SIG_X_O, OPCODE_FLAG_IGNORE | OPCODE_FLAG_HIDE) +DEFINE_OPCODE( + OPCODE_TRACE_SOURCE, + "trace_source", + OPCODE_SIG_X_O_V_V, + OPCODE_FLAG_IGNORE | OPCODE_FLAG_HIDE) + DEFINE_OPCODE( OPCODE_DEBUG_BREAK, "debug_break", diff --git a/src/alloy/memory.cc b/src/alloy/memory.cc index b744a24b9..abc0a8635 100644 --- a/src/alloy/memory.cc +++ b/src/alloy/memory.cc @@ -13,7 +13,7 @@ namespace alloy { -Memory::Memory() : membase_(nullptr), reserve_address_(0) { +Memory::Memory() : membase_(nullptr), reserve_address_(0), trace_base_(0) { system_page_size_ = poly::page_size(); } diff --git a/src/alloy/memory.h b/src/alloy/memory.h index 0a1f861ad..5fe4069a4 100644 --- a/src/alloy/memory.h +++ b/src/alloy/memory.h @@ -33,6 +33,9 @@ class Memory { virtual uint64_t page_table() const = 0; + uint64_t trace_base() const { return trace_base_; } + void set_trace_base(uint64_t value) { trace_base_ = value; } + virtual int Initialize(); void Zero(uint64_t address, size_t size); @@ -65,6 +68,7 @@ class Memory { size_t system_page_size_; uint8_t* membase_; uint32_t reserve_address_; + uint64_t trace_base_; }; } // namespace alloy diff --git a/src/alloy/runtime/debug_info.h b/src/alloy/runtime/debug_info.h index 8ed6b0b34..fa4ee4f3a 100644 --- a/src/alloy/runtime/debug_info.h +++ b/src/alloy/runtime/debug_info.h @@ -26,6 +26,15 @@ enum DebugInfoFlags { DEBUG_INFO_ALL_DISASM = 0xFFFF, }; +enum TraceFlags { + TRACE_NONE = 0, + TRACE_EXTERN_CALLS = (1 << 0), + TRACE_USER_CALLS = (1 << 1), + TRACE_SOURCE = (1 << 2), + TRACE_SOURCE_VALUES = (1 << 3), + TRACE_FUNCTION_GENERATION = (1 << 4), +}; + typedef struct SourceMapEntry_s { uint64_t source_offset; // Original source address/offset. uint64_t hir_offset; // Block ordinal (16b) | Instr ordinal (16b) diff --git a/src/alloy/runtime/function.cc b/src/alloy/runtime/function.cc index 06c0a68c2..6f7f2762a 100644 --- a/src/alloy/runtime/function.cc +++ b/src/alloy/runtime/function.cc @@ -12,6 +12,7 @@ #include #include #include +#include namespace alloy { namespace runtime { @@ -73,8 +74,18 @@ int Function::Call(ThreadState* thread_state, uint64_t return_address) { int result = 0; + uint64_t trace_base = thread_state->memory()->trace_base(); if (symbol_info_->behavior() == FunctionInfo::BEHAVIOR_EXTERN) { auto handler = symbol_info_->extern_handler(); + + if (trace_base && true) { + auto ev = xdb::protocol::KernelCallEvent::Append(trace_base); + ev->type = xdb::protocol::EventType::KERNEL_CALL; + ev->thread_id = thread_state->thread_id(); + ev->module_id = 0; + ev->ordinal = 0; + } + if (handler) { handler(thread_state->raw_context(), symbol_info_->extern_arg0(), symbol_info_->extern_arg1()); @@ -83,8 +94,28 @@ int Function::Call(ThreadState* thread_state, uint64_t return_address) { symbol_info_->name().c_str()); result = 1; } + + if (trace_base && true) { + auto ev = xdb::protocol::KernelCallReturnEvent::Append(trace_base); + ev->type = xdb::protocol::EventType::KERNEL_CALL_RETURN; + ev->thread_id = thread_state->thread_id(); + } } else { + if (trace_base && true) { + auto ev = xdb::protocol::UserCallEvent::Append(trace_base); + ev->type = xdb::protocol::EventType::USER_CALL; + ev->call_type = 0; // ? + ev->thread_id = thread_state->thread_id(); + ev->address = static_cast(symbol_info_->address()); + } + CallImpl(thread_state, return_address); + + if (trace_base && true) { + auto ev = xdb::protocol::UserCallReturnEvent::Append(trace_base); + ev->type = xdb::protocol::EventType::USER_CALL_RETURN; + ev->thread_id = thread_state->thread_id(); + } } if (original_thread_state != thread_state) { diff --git a/src/alloy/runtime/runtime.cc b/src/alloy/runtime/runtime.cc index 8f9ebd832..9189cc299 100644 --- a/src/alloy/runtime/runtime.cc +++ b/src/alloy/runtime/runtime.cc @@ -13,6 +13,7 @@ #include #include +#include // TODO(benvanik): based on compiler support #include @@ -26,7 +27,11 @@ namespace runtime { using alloy::backend::Backend; using alloy::frontend::Frontend; -Runtime::Runtime(Memory* memory) : memory_(memory) {} +Runtime::Runtime(Memory* memory, uint32_t debug_info_flags, + uint32_t trace_flags) + : memory_(memory), + debug_info_flags_(debug_info_flags), + trace_flags_(trace_flags) {} Runtime::~Runtime() { { @@ -224,14 +229,24 @@ int Runtime::DemandFunction(FunctionInfo* symbol_info, if (symbol_status == SymbolInfo::STATUS_NEW) { // Symbol is undefined, so define now. Function* function = nullptr; - int result = - frontend_->DefineFunction(symbol_info, DEBUG_INFO_DEFAULT, &function); + int result = frontend_->DefineFunction(symbol_info, debug_info_flags_, + trace_flags_, &function); if (result) { symbol_info->set_status(SymbolInfo::STATUS_FAILED); return result; } symbol_info->set_function(function); + auto trace_base = memory()->trace_base(); + if (trace_base && trace_flags_ & TRACE_FUNCTION_GENERATION) { + auto ev = xdb::protocol::FunctionCompiledEvent::Append(trace_base); + ev->type = xdb::protocol::EventType::FUNCTION_COMPILED; + ev->flags = 0; + ev->address = static_cast(symbol_info->address()); + ev->length = + static_cast(symbol_info->end_address() - ev->address); + } + // Before we give the symbol back to the rest, let the debugger know. debugger_->OnFunctionDefined(symbol_info, function); diff --git a/src/alloy/runtime/runtime.h b/src/alloy/runtime/runtime.h index 2fd5d1498..a9fe9c374 100644 --- a/src/alloy/runtime/runtime.h +++ b/src/alloy/runtime/runtime.h @@ -29,7 +29,8 @@ namespace runtime { class Runtime { public: - explicit Runtime(Memory* memory); + explicit Runtime(Memory* memory, uint32_t debug_info_flags = 0, + uint32_t trace_flags = 0); virtual ~Runtime(); Memory* memory() const { return memory_; } @@ -60,6 +61,9 @@ class Runtime { protected: Memory* memory_; + uint32_t debug_info_flags_; + uint32_t trace_flags_; + std::unique_ptr debugger_; std::unique_ptr frontend_; diff --git a/src/poly/atomic.h b/src/poly/atomic.h index 721db37dc..4d8473e23 100644 --- a/src/poly/atomic.h +++ b/src/poly/atomic.h @@ -40,6 +40,11 @@ inline int64_t atomic_exchange(int64_t new_value, volatile int64_t* value) { return OSAtomicCompareAndSwap64Barrier(*value, new_value, value); } +//inline int32_t atomic_exchange_add(int32_t amount, volatile int32_t* value) { +//} +//inline int64_t atomic_exchange_add(int64_t amount, volatile int64_t* value) { +//} + inline bool atomic_cas(int32_t old_value, int32_t new_value, volatile int32_t* value) { return OSAtomicCompareAndSwap32Barrier( @@ -69,6 +74,15 @@ inline int64_t atomic_exchange(int64_t new_value, volatile int64_t* value) { new_value); } +inline int32_t atomic_exchange_add(int32_t amount, volatile int32_t* value) { + return InterlockedExchangeAdd(reinterpret_cast(value), + amount); +} +inline int64_t atomic_exchange_add(int64_t amount, volatile int64_t* value) { + return InterlockedExchangeAdd64(reinterpret_cast(value), + amount); +} + inline bool atomic_cas(int32_t old_value, int32_t new_value, volatile int32_t* value) { return InterlockedCompareExchange(reinterpret_cast(value), @@ -96,6 +110,11 @@ inline int64_t atomic_exchange(int64_t new_value, volatile int64_t* value) { return __sync_val_compare_and_swap(*value, value, new_value); } +//inline int32_t atomic_exchange_add(int32_t amount, volatile int32_t* value) { +//} +//inline int64_t atomic_exchange_add(int64_t amount, volatile int64_t* value) { +//} + inline bool atomic_cas(int32_t old_value, int32_t new_value, volatile int32_t* value) { return __sync_bool_compare_and_swap( @@ -133,6 +152,17 @@ inline uint64_t atomic_exchange(uint64_t new_value, volatile uint64_t* value) { reinterpret_cast(value))); } +inline uint32_t atomic_exchange_add(uint32_t amount, volatile uint32_t* value) { + return static_cast( + atomic_exchange_add(static_cast(amount), + reinterpret_cast(value))); +} +inline uint64_t atomic_exchange_add(uint64_t amount, volatile uint64_t* value) { + return static_cast( + atomic_exchange_add(static_cast(amount), + reinterpret_cast(value))); +} + inline bool atomic_cas(uint32_t old_value, uint32_t new_value, volatile uint32_t* value) { return atomic_cas(static_cast(old_value), diff --git a/src/xdb/protocol.h b/src/xdb/protocol.h new file mode 100644 index 000000000..51f9628da --- /dev/null +++ b/src/xdb/protocol.h @@ -0,0 +1,232 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XDB_PROTOCOL_H_ +#define XDB_PROTOCOL_H_ + +#include + +#include +#include + +namespace xdb { +namespace protocol { + +using vec128_t = alloy::vec128_t; + +#pragma pack(push, 4) + +enum class EventType : uint8_t { + SETUP, + + PROCESS_START, + PROCESS_EXIT, + MODULE_LOAD, + MODULE_UNLOAD, + THREAD_CREATE, + THREAD_INFO, + THREAD_EXIT, + + FUNCTION_COMPILED, + + OUTPUT_STRING, + + KERNEL_CALL, + KERNEL_CALL_RETURN, + USER_CALL, + USER_CALL_RETURN, + + INSTR, + INSTR_R8, + INSTR_R8_R8, + INSTR_R8_R16, + INSTR_R16, + INSTR_R16_R8, + INSTR_R16_R16, +}; + +template +struct Event { + static T* Append(uint64_t trace_base) { + if (!trace_base) { + return nullptr; + } + uint64_t ptr = poly::atomic_exchange_add( + sizeof(T), reinterpret_cast(trace_base)); + return reinterpret_cast(ptr); + } +}; + +struct SetupEvent : public Event { + EventType type; + uint64_t membase; +}; + +struct ProcessStartEvent : public Event { + EventType type; +}; + +struct ProcessExitEvent : public Event { + EventType type; +}; + +struct ModuleInfo { + uint32_t module_id; +}; + +struct ModuleLoadEvent : public Event { + EventType type; + uint32_t module_id; + ModuleInfo module_info; +}; + +struct ModuleUnloadEvent : public Event { + EventType type; + uint32_t module_id; +}; + +struct Registers { + uint64_t lr; + uint64_t ctr; + uint32_t xer; + uint32_t cr[8]; + uint32_t fpscr; + uint32_t vscr; + uint64_t gpr[32]; + double fpr[32]; + alloy::vec128_t vr[128]; +}; + +struct ThreadCreateEvent : public Event { + EventType type; + uint16_t thread_id; + Registers registers; +}; + +struct ThreadInfoEvent : public Event { + EventType type; + uint16_t thread_id; +}; + +struct ThreadExitEvent : public Event { + EventType type; + uint16_t thread_id; +}; + +struct FunctionCompiledEvent : public Event { + EventType type; + uint8_t _reserved; + uint16_t flags; // RECOMPILED? user/extern? etc + uint32_t address; + uint32_t length; + // timing? +}; + +struct OutputStringEvent : public Event { + EventType type; + uint16_t thread_id; + // ? +}; + +struct KernelCallEvent : public Event { + EventType type; + uint8_t _reserved; + uint16_t thread_id; + uint16_t module_id; + uint16_t ordinal; +}; +struct KernelCallReturnEvent : public Event { + EventType type; + uint8_t _reserved; + uint16_t thread_id; +}; + +struct UserCallEvent : public Event { + EventType type; + uint8_t call_type; // TAIL? + uint16_t thread_id; + uint32_t address; +}; +struct UserCallReturnEvent : public Event { + EventType type; + uint8_t _reserved; + uint16_t thread_id; +}; + +struct InstrEvent : public Event { + EventType type; + uint8_t _reserved; + uint16_t thread_id; + uint32_t address; +}; +struct InstrEventR8 : public Event { + EventType type; + uint8_t dest_reg; + uint16_t thread_id; + uint32_t address; + uint64_t dest_value; +}; +struct InstrEventR8R8 : public Event { + EventType type; + uint8_t _reserved0; + uint16_t thread_id; + uint32_t address; + uint8_t dest_reg_0; + uint8_t dest_reg_1; + uint16_t _reserved1; + uint64_t dest_value_0; + uint64_t dest_value_1; +}; +struct InstrEventR8R16 : public Event { + EventType type; + uint8_t _reserved0; + uint16_t thread_id; + uint32_t address; + uint8_t dest_reg_0; + uint8_t dest_reg_1; + uint16_t _reserved1; + uint64_t dest_value_0; + vec128_t dest_value_1; +}; +struct InstrEventR16 : public Event { + EventType type; + uint8_t dest_reg; + uint16_t thread_id; + uint32_t address; + vec128_t dest_value; +}; +struct InstrEventR16R8 : public Event { + EventType type; + uint8_t _reserved0; + uint16_t thread_id; + uint32_t address; + uint8_t dest_reg_0; + uint8_t dest_reg_1; + uint16_t _reserved1; + vec128_t dest_value_0; + uint64_t dest_value_1; +}; +struct InstrEventR16R16 : public Event { + EventType type; + uint8_t _reserved0; + uint16_t thread_id; + uint32_t address; + uint8_t dest_reg_0; + uint8_t dest_reg_1; + uint16_t _reserved1; + vec128_t dest_value_0; + vec128_t dest_value_1; +}; + +#pragma pack(pop) + +} // namespace protocol +} // namespace xdb + +#endif // XDB_PROTOCOL_H_ diff --git a/src/xdb/sources.gypi b/src/xdb/sources.gypi index f5ffe8297..4cf583f01 100644 --- a/src/xdb/sources.gypi +++ b/src/xdb/sources.gypi @@ -1,6 +1,7 @@ # Copyright 2014 Ben Vanik. All Rights Reserved. { 'sources': [ + 'protocol.h', 'xdb.cc', 'xdb.h', ], diff --git a/src/xdb/xdb.cc b/src/xdb/xdb.cc index f6d955728..5a89bf8c7 100644 --- a/src/xdb/xdb.cc +++ b/src/xdb/xdb.cc @@ -9,5 +9,8 @@ #include -void test() { -} +namespace xdb { + +void test() {} + +} // namespace xdb diff --git a/src/xenia/cpu/cpu-private.h b/src/xenia/cpu/cpu-private.h index 3272d2ece..0c2c33313 100644 --- a/src/xenia/cpu/cpu-private.h +++ b/src/xenia/cpu/cpu-private.h @@ -12,18 +12,14 @@ #include - +DECLARE_bool(trace_function_generation); +DECLARE_bool(trace_kernel_calls); +DECLARE_bool(trace_user_calls); DECLARE_bool(trace_instructions); DECLARE_bool(trace_registers); -DECLARE_bool(trace_branches); -DECLARE_bool(trace_user_calls); -DECLARE_bool(trace_kernel_calls); -DECLARE_uint64(trace_thread_mask); - DECLARE_string(load_module_map); DECLARE_string(dump_path); DECLARE_bool(dump_module_map); - #endif // XENIA_CPU_PRIVATE_H_ diff --git a/src/xenia/cpu/cpu.cc b/src/xenia/cpu/cpu.cc index 389aeee18..61ed9ac61 100644 --- a/src/xenia/cpu/cpu.cc +++ b/src/xenia/cpu/cpu.cc @@ -9,32 +9,22 @@ #include - -// Tracing: -DEFINE_bool(trace_instructions, false, - "Trace all instructions."); -DEFINE_bool(trace_registers, false, - "Trace register values when tracing instructions."); -DEFINE_bool(trace_branches, false, - "Trace all branches."); -DEFINE_bool(trace_user_calls, false, - "Trace all user function calls."); -DEFINE_bool(trace_kernel_calls, false, - "Trace all kernel function calls."); -DEFINE_uint64(trace_thread_mask, -1, - "Trace threads with IDs in the mask, or -1 for all."); - - // Debugging: -DEFINE_string(load_module_map, "", +DEFINE_bool(trace_function_generation, false, + "Trace function generation/JITing."); +DEFINE_bool(trace_kernel_calls, false, "Trace all kernel function calls."); +DEFINE_bool(trace_user_calls, false, "Trace all user function calls."); +DEFINE_bool(trace_instructions, false, "Trace all instructions."); +DEFINE_bool(trace_registers, false, + "Trace register values when tracing instructions."); +DEFINE_string( + load_module_map, "", "Loads a .map for symbol names and to diff with the generated symbol " "database."); - // Dumping: DEFINE_string(dump_path, "build/", - "Directory that dump files are placed into."); + "Directory that dump files are placed into."); DEFINE_bool(dump_module_bitcode, true, - "Writes the module bitcode both before and after optimizations."); -DEFINE_bool(dump_module_map, true, - "Dumps the module symbol database."); + "Writes the module bitcode both before and after optimizations."); +DEFINE_bool(dump_module_map, true, "Dumps the module symbol database."); diff --git a/src/xenia/cpu/processor.cc b/src/xenia/cpu/processor.cc index 21512acbb..f94ecf588 100644 --- a/src/xenia/cpu/processor.cc +++ b/src/xenia/cpu/processor.cc @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -70,7 +71,26 @@ Processor::~Processor() { int Processor::Setup() { assert_null(runtime_); - runtime_ = new XenonRuntime(memory_, export_resolver_); + uint32_t debug_info_flags = DEBUG_INFO_DEFAULT; + uint32_t trace_flags = 0; + if (FLAGS_trace_function_generation) { + trace_flags |= TRACE_FUNCTION_GENERATION; + } + if (FLAGS_trace_kernel_calls) { + trace_flags |= TRACE_EXTERN_CALLS; + } + if (FLAGS_trace_user_calls) { + trace_flags |= TRACE_USER_CALLS; + } + if (FLAGS_trace_instructions) { + trace_flags |= TRACE_SOURCE; + } + if (FLAGS_trace_registers) { + trace_flags |= TRACE_SOURCE_VALUES; + } + + runtime_ = new XenonRuntime(memory_, export_resolver_, debug_info_flags, + trace_flags); if (!runtime_) { return 1; } diff --git a/src/xenia/cpu/xenon_runtime.cc b/src/xenia/cpu/xenon_runtime.cc index 46fe20d5f..1ae38b8c9 100644 --- a/src/xenia/cpu/xenon_runtime.cc +++ b/src/xenia/cpu/xenon_runtime.cc @@ -19,12 +19,11 @@ using namespace alloy::runtime; using namespace xe; using namespace xe::cpu; - -XenonRuntime::XenonRuntime( - alloy::Memory* memory, ExportResolver* export_resolver) : - Runtime(memory), - export_resolver_(export_resolver) { -} +XenonRuntime::XenonRuntime(alloy::Memory* memory, + ExportResolver* export_resolver, + uint32_t debug_info_flags, uint32_t trace_flags) + : Runtime(memory, debug_info_flags, trace_flags), + export_resolver_(export_resolver) {} XenonRuntime::~XenonRuntime() = default; diff --git a/src/xenia/cpu/xenon_runtime.h b/src/xenia/cpu/xenon_runtime.h index 3b6c219b7..de90e167d 100644 --- a/src/xenia/cpu/xenon_runtime.h +++ b/src/xenia/cpu/xenon_runtime.h @@ -17,29 +17,26 @@ XEDECLARECLASS1(xe, ExportResolver); - namespace xe { namespace cpu { class XenonThreadState; - class XenonRuntime : public alloy::runtime::Runtime { -public: - XenonRuntime(Memory* memory, ExportResolver* export_resolver); + public: + XenonRuntime(Memory* memory, ExportResolver* export_resolver, + uint32_t debug_info_flags, uint32_t trace_flags); virtual ~XenonRuntime(); ExportResolver* export_resolver() const { return export_resolver_; } virtual int Initialize(std::unique_ptr backend = 0); -private: + private: ExportResolver* export_resolver_; }; - } // namespace cpu } // namespace xe - #endif // XENIA_CPU_XENON_RUNTIME_H_ diff --git a/src/xenia/cpu/xenon_thread_state.cc b/src/xenia/cpu/xenon_thread_state.cc index a3403f0d2..0a4190573 100644 --- a/src/xenia/cpu/xenon_thread_state.cc +++ b/src/xenia/cpu/xenon_thread_state.cc @@ -9,6 +9,7 @@ #include +#include #include using namespace alloy; @@ -36,6 +37,7 @@ XenonThreadState::XenonThreadState(XenonRuntime* runtime, uint32_t thread_id, context_->membase = memory_->membase(); context_->runtime = runtime; context_->thread_state = this; + context_->thread_id = thread_id_; // Set initial registers. context_->r[1] = stack_address_ + stack_size; @@ -56,3 +58,28 @@ XenonThreadState::~XenonThreadState() { xe_free_aligned(context_); memory_->HeapFree(stack_address_, stack_size_); } + +void XenonThreadState::WriteRegisters(xdb::protocol::Registers* registers) { + registers->lr = context_->lr; + registers->ctr = context_->ctr; + registers->xer = 0xFEFEFEFE; + registers->cr[0] = context_->cr0.value; + registers->cr[1] = context_->cr1.value; + registers->cr[2] = context_->cr2.value; + registers->cr[3] = context_->cr3.value; + registers->cr[4] = context_->cr4.value; + registers->cr[5] = context_->cr5.value; + registers->cr[6] = context_->cr6.value; + registers->cr[7] = context_->cr7.value; + registers->fpscr = context_->fpscr.value; + registers->vscr = context_->vscr_sat; + static_assert(sizeof(registers->gpr) == sizeof(context_->r), + "structs must match"); + static_assert(sizeof(registers->fpr) == sizeof(context_->f), + "structs must match"); + static_assert(sizeof(registers->vr) == sizeof(context_->v), + "structs must match"); + memcpy(registers->gpr, context_->r, sizeof(context_->r)); + memcpy(registers->fpr, context_->f, sizeof(context_->f)); + memcpy(registers->vr, context_->v, sizeof(context_->v)); +} diff --git a/src/xenia/cpu/xenon_thread_state.h b/src/xenia/cpu/xenon_thread_state.h index 0bda965fa..409d85a97 100644 --- a/src/xenia/cpu/xenon_thread_state.h +++ b/src/xenia/cpu/xenon_thread_state.h @@ -14,6 +14,11 @@ #include #include +namespace xdb { +namespace protocol { +struct Registers; +} // namespace protocol +} // namespace xdb namespace xe { namespace cpu { @@ -34,6 +39,8 @@ public: uint64_t thread_state_address() const { return thread_state_address_; } PPCContext* context() const { return context_; } + void WriteRegisters(xdb::protocol::Registers* registers); + private: uint64_t stack_address_; size_t stack_size_; diff --git a/src/xenia/debug_agent.cc b/src/xenia/debug_agent.cc new file mode 100644 index 000000000..3b2c63c82 --- /dev/null +++ b/src/xenia/debug_agent.cc @@ -0,0 +1,79 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include + +#include + +DEFINE_string(trace_file, "", "Trace to the given file."); +DEFINE_uint64(trace_capacity, 0x40000000, "Trace file capacity to allocate."); + +namespace xe { + +DebugAgent::DebugAgent(Emulator* emulator) + : emulator_(emulator), + file_(nullptr), + file_mapping_(nullptr), + trace_base_(0) {} + +DebugAgent::~DebugAgent() { + if (trace_base_) { + UnmapViewOfFile(trace_base_); + } + + CloseHandle(file_mapping_); + CloseHandle(file_); +} + +int DebugAgent::Initialize() { + if (!FLAGS_trace_file.empty()) { + if (SetupTracing(FLAGS_trace_file, FLAGS_trace_capacity)) { + XELOGE("Failed to setup tracing - out of disk space?"); + return 1; + } + } + + return 0; +} + +int DebugAgent::SetupTracing(const std::string& trace_file, uint64_t capacity) { + std::wstring_convert> cvt; + auto file_path = cvt.from_bytes(trace_file); + file_ = CreateFile(file_path.c_str(), GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, + nullptr); + if (!file_) { + XELOGE("Could not open trace file for writing"); + return 1; + } + + file_mapping_ = CreateFileMapping( + file_, nullptr, PAGE_READWRITE, static_cast(capacity >> 32), + static_cast(capacity), L"Local\\xenia_xdb_trace"); + if (!file_mapping_) { + XELOGE("Could not create trace file mapping - out of disk space?"); + return 1; + } + + trace_base_ = MapViewOfFile(file_mapping_, FILE_MAP_WRITE, 0, 0, 0); + if (!trace_base_) { + XELOGE("Could not map view of trace file - out of disk space?"); + return 1; + } + + // Store initial trace base. + poly::store(trace_base_, trace_base() + 8); + + return 0; +} + +} // namespace xe diff --git a/src/xenia/debug_agent.h b/src/xenia/debug_agent.h new file mode 100644 index 000000000..33a970a3d --- /dev/null +++ b/src/xenia/debug_agent.h @@ -0,0 +1,44 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_DEBUG_AGENT_H_ +#define XENIA_DEBUG_AGENT_H_ + +#include + +#include + +namespace xe { + +class Emulator; + +class DebugAgent { + public: + DebugAgent(Emulator* emulator); + ~DebugAgent(); + + uint64_t trace_base() const { + return reinterpret_cast(trace_base_); + } + + int Initialize(); + + private: + int SetupTracing(const std::string& trace_file, uint64_t capacity); + + Emulator* emulator_; + + HANDLE file_; + HANDLE file_mapping_; + void* trace_base_; +}; + +} // namespace xe + +#endif // XENIA_DEBUG_AGENT_H_ diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index 1b3dbbcac..5cbc64675 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -44,10 +45,17 @@ Emulator::Emulator(const xechar_t* command_line) : Emulator::~Emulator() { // Note that we delete things in the reverse order they were initialized. + auto ev = xdb::protocol::ProcessExitEvent::Append(memory()->trace_base()); + if (ev) { + ev->type = xdb::protocol::EventType::PROCESS_EXIT; + } + if (main_window_) { main_window_->Close(); } + debug_agent_.reset(); + delete xam_; delete xboxkrnl_; delete kernel_state_; @@ -70,11 +78,16 @@ Emulator::~Emulator() { X_STATUS Emulator::Setup() { X_STATUS result = X_STATUS_UNSUCCESSFUL; + debug_agent_.reset(new DebugAgent(this)); + result = debug_agent_->Initialize(); + XEEXPECTZERO(result); + // Create memory system first, as it is required for other systems. memory_ = new XenonMemory(); XEEXPECTNOTNULL(memory_); result = memory_->Initialize(); XEEXPECTZERO(result); + memory_->set_trace_base(debug_agent_->trace_base()); // Shared export resolver used to attach and query for HLE exports. export_resolver_ = new ExportResolver(); @@ -144,6 +157,11 @@ X_STATUS Emulator::LaunchXexFile(const xechar_t* path) { // and then get that symlinked to game:\, so // -> game:\foo.xex + auto ev = xdb::protocol::ProcessStartEvent::Append(memory()->trace_base()); + if (ev) { + ev->type = xdb::protocol::EventType::PROCESS_START; + } + int result_code = 0; // Get just the filename (foo.xex). @@ -193,6 +211,11 @@ X_STATUS Emulator::LaunchXexFile(const xechar_t* path) { X_STATUS Emulator::LaunchDiscImage(const xechar_t* path) { int result_code = 0; + auto ev = xdb::protocol::ProcessStartEvent::Append(memory()->trace_base()); + if (ev) { + ev->type = xdb::protocol::EventType::PROCESS_START; + } + // Register the disc image in the virtual filesystem. result_code = file_system_->RegisterDiscImageDevice( "\\Device\\Cdrom0", path); @@ -216,6 +239,11 @@ X_STATUS Emulator::LaunchDiscImage(const xechar_t* path) { X_STATUS Emulator::LaunchSTFSTitle(const xechar_t* path) { int result_code = 0; + auto ev = xdb::protocol::ProcessStartEvent::Append(memory()->trace_base()); + if (ev) { + ev->type = xdb::protocol::EventType::PROCESS_START; + } + // TODO(benvanik): figure out paths. // Register the disc image in the virtual filesystem. diff --git a/src/xenia/emulator.h b/src/xenia/emulator.h index 3548e5d2c..f3120c8d5 100644 --- a/src/xenia/emulator.h +++ b/src/xenia/emulator.h @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -19,7 +20,6 @@ XEDECLARECLASS1(xe, ExportResolver); XEDECLARECLASS2(xe, apu, AudioSystem); XEDECLARECLASS2(xe, cpu, Processor); -XEDECLARECLASS2(xe, debug, DebugServer); XEDECLARECLASS2(xe, gpu, GraphicsSystem); XEDECLARECLASS2(xe, hid, InputSystem); XEDECLARECLASS2(xe, kernel, KernelState); @@ -31,7 +31,6 @@ XEDECLARECLASS2(xe, ui, Window); namespace xe { - class Emulator { public: Emulator(const xechar_t* command_line); @@ -44,7 +43,7 @@ public: cpu::XenonMemory* memory() const { return memory_; } - debug::DebugServer* debug_server() const { return debug_server_; } + DebugAgent* debug_agent() const { return debug_agent_.get(); } cpu::Processor* processor() const { return processor_; } apu::AudioSystem* audio_system() const { return audio_system_; } @@ -71,7 +70,7 @@ private: cpu::XenonMemory* memory_; - debug::DebugServer* debug_server_; + std::unique_ptr debug_agent_; cpu::Processor* processor_; apu::AudioSystem* audio_system_; diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index b806253b3..f885e03fd 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -73,6 +73,10 @@ KernelState* KernelState::shared() { return shared_kernel_state_; } +void KernelState::RegisterModule(XModule* module) {} + +void KernelState::UnregisterModule(XModule* module) {} + XModule* KernelState::GetModule(const char* name) { if (!name) { // NULL name = self. diff --git a/src/xenia/kernel/kernel_state.h b/src/xenia/kernel/kernel_state.h index 77173a8f2..55033aef6 100644 --- a/src/xenia/kernel/kernel_state.h +++ b/src/xenia/kernel/kernel_state.h @@ -56,6 +56,8 @@ public: ObjectTable* object_table() const { return object_table_; } + void RegisterModule(XModule* module); + void UnregisterModule(XModule* module); XModule* GetModule(const char* name); XUserModule* GetExecutableModule(); void SetExecutableModule(XUserModule* module); diff --git a/src/xenia/kernel/objects/xkernel_module.cc b/src/xenia/kernel/objects/xkernel_module.cc index 506cc0b8e..d5419f2fc 100644 --- a/src/xenia/kernel/objects/xkernel_module.cc +++ b/src/xenia/kernel/objects/xkernel_module.cc @@ -24,6 +24,8 @@ XKernelModule::XKernelModule(KernelState* kernel_state, const char* path) : emulator_ = kernel_state->emulator(); memory_ = emulator_->memory(); export_resolver_ = kernel_state->emulator()->export_resolver(); + + OnLoad(); } XKernelModule::~XKernelModule() { diff --git a/src/xenia/kernel/objects/xmodule.cc b/src/xenia/kernel/objects/xmodule.cc index c6efc9361..462d76ac4 100644 --- a/src/xenia/kernel/objects/xmodule.cc +++ b/src/xenia/kernel/objects/xmodule.cc @@ -9,6 +9,8 @@ #include +#include + using namespace xe; using namespace xe::cpu; @@ -32,6 +34,23 @@ XModule::XModule(KernelState* kernel_state, const char* path) : } XModule::~XModule() { + auto ev = xdb::protocol::ModuleUnloadEvent::Append(memory()->trace_base()); + if (ev) { + ev->type = xdb::protocol::EventType::MODULE_UNLOAD; + ev->module_id = handle(); + } + + kernel_state_->UnregisterModule(this); +} + +void XModule::OnLoad() { + auto ev = xdb::protocol::ModuleLoadEvent::Append(memory()->trace_base()); + if (ev) { + ev->type = xdb::protocol::EventType::MODULE_LOAD; + ev->module_id = handle(); + } + + kernel_state_->RegisterModule(this); } X_STATUS XModule::GetSection( diff --git a/src/xenia/kernel/objects/xmodule.h b/src/xenia/kernel/objects/xmodule.h index c19a4961f..9537adbcd 100644 --- a/src/xenia/kernel/objects/xmodule.h +++ b/src/xenia/kernel/objects/xmodule.h @@ -33,6 +33,8 @@ public: uint32_t* out_section_data, uint32_t* out_section_size); protected: + void OnLoad(); + char name_[256]; char path_[poly::max_path]; }; diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index 0b6b93d06..7c3f6b0be 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -11,6 +11,7 @@ #include +#include #include #include #include @@ -70,6 +71,12 @@ XThread::XThread(KernelState* kernel_state, } XThread::~XThread() { + auto ev = xdb::protocol::ThreadExitEvent::Append(memory()->trace_base()); + if (ev) { + ev->type = xdb::protocol::EventType::THREAD_EXIT; + ev->thread_id = handle(); + } + // Unregister first to prevent lookups while deleting. kernel_state_->UnregisterThread(this); @@ -254,6 +261,13 @@ X_STATUS XThread::Create() { SetAffinity(proc_mask); } + auto ev = xdb::protocol::ThreadCreateEvent::Append(memory()->trace_base()); + if (ev) { + ev->type = xdb::protocol::EventType::THREAD_CREATE; + ev->thread_id = handle(); + thread_state_->WriteRegisters(&ev->registers); + } + module->Release(); return X_STATUS_SUCCESS; } diff --git a/src/xenia/kernel/objects/xuser_module.cc b/src/xenia/kernel/objects/xuser_module.cc index 2008aa94a..7d566ce7c 100644 --- a/src/xenia/kernel/objects/xuser_module.cc +++ b/src/xenia/kernel/objects/xuser_module.cc @@ -122,6 +122,8 @@ X_STATUS XUserModule::LoadFromMemory(const void* addr, const size_t length) { return X_STATUS_UNSUCCESSFUL; } + OnLoad(); + return X_STATUS_SUCCESS; } diff --git a/src/xenia/sources.gypi b/src/xenia/sources.gypi index 568c231ec..db918c4e9 100644 --- a/src/xenia/sources.gypi +++ b/src/xenia/sources.gypi @@ -4,6 +4,8 @@ 'common.h', 'config.h', 'core.h', + 'debug_agent.cc', + 'debug_agent.h', 'emulator.cc', 'emulator.h', 'export_resolver.cc', From bae26f7dfcb5e606feadb7e672567b8053048bea Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 14 Aug 2014 20:36:00 -0700 Subject: [PATCH 099/388] Skeleton xdb UI. --- src/xdb/sources.gypi | 3 + src/xdb/ui/main_frame.cc | 18 ++ src/xdb/ui/main_frame.h | 30 ++ src/xdb/ui/sources.gypi | 12 + src/xdb/ui/xdb-ui.fbp | 540 +++++++++++++++++++++++++++++++ src/xdb/ui/xdb_ui.cpp | 49 +++ src/xdb/ui/xdb_ui.h | 64 ++++ src/xdb/xdb_app.cc | 29 ++ src/xdb/xdb_app.h | 31 ++ tools/xenia-debug/xenia-debug.cc | 51 ++- xenia.gyp | 13 +- 11 files changed, 821 insertions(+), 19 deletions(-) create mode 100644 src/xdb/ui/main_frame.cc create mode 100644 src/xdb/ui/main_frame.h create mode 100644 src/xdb/ui/sources.gypi create mode 100644 src/xdb/ui/xdb-ui.fbp create mode 100644 src/xdb/ui/xdb_ui.cpp create mode 100644 src/xdb/ui/xdb_ui.h create mode 100644 src/xdb/xdb_app.cc create mode 100644 src/xdb/xdb_app.h diff --git a/src/xdb/sources.gypi b/src/xdb/sources.gypi index 4cf583f01..7e08a9fc7 100644 --- a/src/xdb/sources.gypi +++ b/src/xdb/sources.gypi @@ -4,8 +4,11 @@ 'protocol.h', 'xdb.cc', 'xdb.h', + 'xdb_app.cc', + 'xdb_app.h', ], 'includes': [ + 'ui/sources.gypi', ], } diff --git a/src/xdb/ui/main_frame.cc b/src/xdb/ui/main_frame.cc new file mode 100644 index 000000000..606da3f44 --- /dev/null +++ b/src/xdb/ui/main_frame.cc @@ -0,0 +1,18 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +namespace xdb { +namespace ui { + +MainFrame::MainFrame() : MainFrameBase(nullptr) {} + +} // namespace ui +} // namespace xdb diff --git a/src/xdb/ui/main_frame.h b/src/xdb/ui/main_frame.h new file mode 100644 index 000000000..9f6ba8ffd --- /dev/null +++ b/src/xdb/ui/main_frame.h @@ -0,0 +1,30 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XDB_UI_MAIN_FRAME_H_ +#define XDB_UI_MAIN_FRAME_H_ + +#include + +#include + +namespace xdb { +namespace ui { + +class MainFrame : public MainFrameBase { + public: + MainFrame(); + protected: + // +}; + +} // namespace ui +} // namespace xdb + +#endif // XDB_UI_MAIN_FRAME_H_ diff --git a/src/xdb/ui/sources.gypi b/src/xdb/ui/sources.gypi new file mode 100644 index 000000000..3673fcf7a --- /dev/null +++ b/src/xdb/ui/sources.gypi @@ -0,0 +1,12 @@ +# Copyright 2014 Ben Vanik. All Rights Reserved. +{ + 'sources': [ + 'main_frame.cc', + 'main_frame.h', + 'xdb_ui.cpp', + 'xdb_ui.h', + ], + + 'includes': [ + ], +} diff --git a/src/xdb/ui/xdb-ui.fbp b/src/xdb/ui/xdb-ui.fbp new file mode 100644 index 000000000..4a40d2e42 --- /dev/null +++ b/src/xdb/ui/xdb-ui.fbp @@ -0,0 +1,540 @@ + + + + + + C++ + 1 + source_name + 0 + 0 + res + UTF-8 + connect + + 1000 + none + 0 + xdb + "xdb" "ui" + . + + 1 + 1 + 1 + 1 + UI + 1 + 0 + + 1 + wxAUI_MGR_DEFAULT|wxAUI_MGR_LIVE_RESIZE + + wxBOTH + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + MainFrameBase + + 1024,768 + wxDEFAULT_FRAME_STYLE + + xenia debugger + + + + wxTAB_TRAVERSAL + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + + + 0 + wxID_ANY + Main Menu + + + menu_bar_ + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + File + file + protected + + + + 0 + 0 + 0 + 1 + 10 + + + + + + + + 0 + 0 + 0 + + 1 + 0 + Dock + 0 + Top + 1 + + 1 + + 0 + 0 + wxID_ANY + 0 + + + 0 + + + 0 + + 1 + tool_bar_ + 1 + 1 + + + protected + 0 + + Resizable + 5 + 1 + + wxAUI_TB_HORZ_LAYOUT + + label + 1 + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + wxID_ANY + wxITEM_NORMAL + tool + tool_test_ + protected + + + + + + + + + + + + + + + + + + 1 + 1 + + 1 + + 0 + wxID_ANY + + + status_bar_ + protected + + + wxST_SIZEGRIP + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0 + 0 + + + + + + + + 0 + 0 + 0 + + 1 + 0 + Dock + 0 + Center + 1 + + 0 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 0 + notebook_ + 0 + + + protected + 0 + + Resizable + 1 + + wxAUI_NB_TAB_EXTERNAL_MOVE|wxAUI_NB_TAB_MOVE|wxAUI_NB_TAB_SPLIT|wxAUI_NB_TOP|wxAUI_NB_WINDOWLIST_BUTTON + + -1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + a page + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_panel3 + 1 + + + protected + 1 + + Resizable + 1 + + + 0 + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + + a page + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 1 + 1 + + 1 + 0 + Dock + 0 + Center + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_panel4 + 1 + + + protected + 1 + + Resizable + 1 + + + 0 + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/xdb/ui/xdb_ui.cpp b/src/xdb/ui/xdb_ui.cpp new file mode 100644 index 000000000..c537f8f6a --- /dev/null +++ b/src/xdb/ui/xdb_ui.cpp @@ -0,0 +1,49 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Jun 5 2014) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "xdb_ui.h" + +/////////////////////////////////////////////////////////////////////////// +using namespace xdb::ui; + +MainFrameBase::MainFrameBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + m_mgr.SetManagedWindow(this); + m_mgr.SetFlags(wxAUI_MGR_DEFAULT|wxAUI_MGR_LIVE_RESIZE); + + menu_bar_ = new wxMenuBar( 0 ); + file = new wxMenu(); + menu_bar_->Append( file, wxT("File") ); + + this->SetMenuBar( menu_bar_ ); + + tool_bar_ = new wxAuiToolBar( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_TB_HORZ_LAYOUT ); + tool_test_ = tool_bar_->AddTool( wxID_ANY, wxT("tool"), wxNullBitmap, wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString, NULL ); + + tool_bar_->Realize(); + m_mgr.AddPane( tool_bar_, wxAuiPaneInfo().Top().CaptionVisible( false ).CloseButton( false ).Dock().Resizable().FloatingSize( wxDefaultSize ).DockFixed( false ).BottomDockable( false ).LeftDockable( false ).RightDockable( false ).Layer( 10 ).ToolbarPane() ); + + status_bar_ = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY ); + notebook_ = new wxAuiNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TAB_EXTERNAL_MOVE|wxAUI_NB_TAB_MOVE|wxAUI_NB_TAB_SPLIT|wxAUI_NB_TOP|wxAUI_NB_WINDOWLIST_BUTTON ); + m_mgr.AddPane( notebook_, wxAuiPaneInfo() .Center() .CaptionVisible( false ).CloseButton( false ).PaneBorder( false ).Movable( false ).Dock().Resizable().FloatingSize( wxDefaultSize ).DockFixed( false ).BottomDockable( false ).TopDockable( false ).LeftDockable( false ).RightDockable( false ).Floatable( false ) ); + + m_panel3 = new wxPanel( notebook_, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + notebook_->AddPage( m_panel3, wxT("a page"), false, wxNullBitmap ); + m_panel4 = new wxPanel( notebook_, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + notebook_->AddPage( m_panel4, wxT("a page"), true, wxNullBitmap ); + + + m_mgr.Update(); + this->Centre( wxBOTH ); +} + +MainFrameBase::~MainFrameBase() +{ + m_mgr.UnInit(); + +} diff --git a/src/xdb/ui/xdb_ui.h b/src/xdb/ui/xdb_ui.h new file mode 100644 index 000000000..421f89942 --- /dev/null +++ b/src/xdb/ui/xdb_ui.h @@ -0,0 +1,64 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Jun 5 2014) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#ifndef __XDB_UI_H__ +#define __XDB_UI_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + +namespace xdb +{ + namespace ui + { + /////////////////////////////////////////////////////////////////////////////// + /// Class MainFrameBase + /////////////////////////////////////////////////////////////////////////////// + class MainFrameBase : public wxFrame + { + private: + + protected: + wxMenuBar* menu_bar_; + wxMenu* file; + wxAuiToolBar* tool_bar_; + wxAuiToolBarItem* tool_test_; + wxStatusBar* status_bar_; + wxAuiNotebook* notebook_; + wxPanel* m_panel3; + wxPanel* m_panel4; + + public: + + MainFrameBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("xenia debugger"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 1024,768 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL ); + wxAuiManager m_mgr; + + ~MainFrameBase(); + + }; + + } // namespace ui +} // namespace xdb + +#endif //__XDB_UI_H__ diff --git a/src/xdb/xdb_app.cc b/src/xdb/xdb_app.cc new file mode 100644 index 000000000..b91672189 --- /dev/null +++ b/src/xdb/xdb_app.cc @@ -0,0 +1,29 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +namespace xdb { + +IMPLEMENT_APP(XdbApp); + +bool XdbApp::OnInit() { + main_frame_.reset(new ui::MainFrame()); + + main_frame_->Show(); + return true; +} + +int XdbApp::OnExit() { + // Top level windows are deleted by wx automatically. + main_frame_.release(); + return 0; +} + +} // namespace xdb diff --git a/src/xdb/xdb_app.h b/src/xdb/xdb_app.h new file mode 100644 index 000000000..b373ab7fe --- /dev/null +++ b/src/xdb/xdb_app.h @@ -0,0 +1,31 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XDB_XDB_APP_H_ +#define XDB_XDB_APP_H_ + +#include + +#include +#include + +namespace xdb { + +class XdbApp : public wxApp { + public: + bool OnInit() override; + int OnExit() override; + + private: + std::unique_ptr main_frame_; +}; + +} // namespace xdb + +#endif // XDB_XDB_APP_H_ diff --git a/tools/xenia-debug/xenia-debug.cc b/tools/xenia-debug/xenia-debug.cc index 630491c20..6fc239eb6 100644 --- a/tools/xenia-debug/xenia-debug.cc +++ b/tools/xenia-debug/xenia-debug.cc @@ -9,26 +9,49 @@ #include +#include + #include +#include +#include +#include +namespace xdb { -//using namespace xdb; - - -int xenia_debug(int argc, xechar_t** argv) { - int result_code = 1; - +int main(int argc, xechar_t** argv) { // Create platform abstraction layer. xe_pal_options_t pal_options; xe_zero_struct(&pal_options, sizeof(pal_options)); - XEEXPECTZERO(xe_pal_init(pal_options)); - - - result_code = 0; -XECLEANUP: - if (result_code) { - XEFATAL("Failed to launch debugger: %d", result_code); + if (xe_pal_init(pal_options)) { + XEFATAL("Failed to initialize PAL"); + return 1; } + + wxInitializer init; + if (!init.IsOk()) { + XEFATAL("Failed to initialize wxWidgets"); + return 1; + } + + // App is auto-freed by wx. + auto app = new XdbApp(); + wxApp::SetInstance(app); + if (!wxEntryStart(0, nullptr)) { + XEFATAL("Failed to enter wxWidgets app"); + return 1; + } + if (!app->OnInit()) { + XEFATAL("Failed to init app"); + return 1; + } + app->OnRun(); + int result_code = app->OnExit(); + wxEntryCleanup(); return result_code; } -XE_MAIN_WINDOW_THUNK(xenia_debug, XETEXT("xenia-debug"), "xenia-debug"); + +} // namespace xdb + +// TODO(benvanik): move main thunk into poly +// ehhh +XE_MAIN_WINDOW_THUNK(xdb::main, L"xenia-debug", "xenia-debug"); diff --git a/xenia.gyp b/xenia.gyp index ea353f570..736900825 100644 --- a/xenia.gyp +++ b/xenia.gyp @@ -96,6 +96,7 @@ #'LinkIncremental': '1', # 1 = NO, 2 = YES 'TargetMachine': '17', # x86 - 64 'AdditionalLibraryDirectories': [ + '..\\..\\third_party\\wxWidgets\\lib\\vc_x64_lib\\', ], }, }, @@ -463,6 +464,7 @@ 'include_dirs': [ 'src/', 'third_party/wxWidgets/include/', + 'third_party/wxWidgets/include/msvc/', ], 'target_conditions': [ @@ -480,11 +482,11 @@ 'wsock32', 'Ws2_32', 'Shell32', - # TODO(benvanik): root dir - '../../third_party/wxWidgets/lib/vc_x64_lib/wxbase31u', - '../../third_party/wxWidgets/lib/vc_x64_lib/wxmsw31u_core', - '../../third_party/wxWidgets/lib/vc_x64_lib/wxmsw31u_aui', - '../../third_party/wxWidgets/lib/vc_x64_lib/wxmsw31u_stc', + 'Msimg32', + 'wxbase31u', + 'wxmsw31u_core', + 'wxmsw31u_aui', + 'wxmsw31u_stc', ], }], ['OS == "mac"', { @@ -511,6 +513,7 @@ '.', 'src/', 'third_party/wxWidgets/include/', + 'third_party/wxWidgets/include/msvc/', ], 'includes': [ From 21225b5917f59c13f93a5ed605a82dd3514f263e Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 14 Aug 2014 23:53:10 -0700 Subject: [PATCH 100/388] xdb progress; skeleton trace loading. --- src/xdb/debug_target.cc | 16 + src/xdb/debug_target.h | 23 + src/xdb/postmortem_debug_target.cc | 38 ++ src/xdb/postmortem_debug_target.h | 33 ++ src/xdb/sources.gypi | 5 + src/xdb/sym/map_symbol_database.cc | 20 + src/xdb/sym/map_symbol_database.h | 26 + src/xdb/sym/sources.gypi | 14 + src/xdb/sym/symbol_database.cc | 18 + src/xdb/sym/symbol_database.h | 50 ++ src/xdb/sym/symbol_provider.cc | 25 + src/xdb/sym/symbol_provider.h | 33 ++ src/xdb/ui/main_frame.cc | 3 +- src/xdb/ui/main_frame.h | 9 +- src/xdb/ui/open_postmortem_trace_dialog.h | 33 ++ src/xdb/ui/sources.gypi | 1 + src/xdb/ui/xdb-ui.fbp | 639 +++++++++++++++++++++- src/xdb/ui/xdb_ui.cpp | 84 ++- src/xdb/ui/xdb_ui.h | 33 +- src/xdb/xdb_app.cc | 116 +++- src/xdb/xdb_app.h | 23 +- tools/xenia-debug/xenia-debug.cc | 12 + 22 files changed, 1236 insertions(+), 18 deletions(-) create mode 100644 src/xdb/debug_target.cc create mode 100644 src/xdb/debug_target.h create mode 100644 src/xdb/postmortem_debug_target.cc create mode 100644 src/xdb/postmortem_debug_target.h create mode 100644 src/xdb/sym/map_symbol_database.cc create mode 100644 src/xdb/sym/map_symbol_database.h create mode 100644 src/xdb/sym/sources.gypi create mode 100644 src/xdb/sym/symbol_database.cc create mode 100644 src/xdb/sym/symbol_database.h create mode 100644 src/xdb/sym/symbol_provider.cc create mode 100644 src/xdb/sym/symbol_provider.h create mode 100644 src/xdb/ui/open_postmortem_trace_dialog.h diff --git a/src/xdb/debug_target.cc b/src/xdb/debug_target.cc new file mode 100644 index 000000000..197ab2be6 --- /dev/null +++ b/src/xdb/debug_target.cc @@ -0,0 +1,16 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +namespace xdb { + +// + +} // namespace xdb diff --git a/src/xdb/debug_target.h b/src/xdb/debug_target.h new file mode 100644 index 000000000..2ff238f5d --- /dev/null +++ b/src/xdb/debug_target.h @@ -0,0 +1,23 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XDB_DEBUG_TARGET_H_ +#define XDB_DEBUG_TARGET_H_ + +namespace xdb { + +class DebugTarget { + public: + protected: + DebugTarget() = default; +}; + +} // namespace xdb + +#endif // XDB_DEBUG_TARGET_H_ diff --git a/src/xdb/postmortem_debug_target.cc b/src/xdb/postmortem_debug_target.cc new file mode 100644 index 000000000..fa541a72d --- /dev/null +++ b/src/xdb/postmortem_debug_target.cc @@ -0,0 +1,38 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +namespace xdb { + +bool PostmortemDebugTarget::LoadTrace(const std::wstring& path) { + // TODO(benvanik): memory map trace. + return true; +} + +bool PostmortemDebugTarget::LoadContent(const std::wstring& path) { + // If no path is provided attempt to infer from the trace. + if (path.empty()) { + // TODO(benvanik): find process info block and read source path. + } + // TODO(benvanik): initialize filesystem and load iso/stfs/etc to get at xex. + return true; +} + +bool PostmortemDebugTarget::Prepare() { + std::atomic cancelled(false); + return Prepare(cancelled); +} + +bool PostmortemDebugTarget::Prepare(std::atomic& cancelled) { + // TODO(benvanik): scan file, build indicies, etc. + return true; +} + +} // namespace xdb diff --git a/src/xdb/postmortem_debug_target.h b/src/xdb/postmortem_debug_target.h new file mode 100644 index 000000000..4071ea19e --- /dev/null +++ b/src/xdb/postmortem_debug_target.h @@ -0,0 +1,33 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XDB_POSTMORTEM_DEBUG_TARGET_H_ +#define XDB_POSTMORTEM_DEBUG_TARGET_H_ + +#include +#include + +#include + +namespace xdb { + +class PostmortemDebugTarget : public DebugTarget { + public: + PostmortemDebugTarget() = default; + + bool LoadTrace(const std::wstring& path); + bool LoadContent(const std::wstring& path = L""); + + bool Prepare(); + bool Prepare(std::atomic& cancelled); +}; + +} // namespace xdb + +#endif // XDB_POSTMORTEM_DEBUG_TARGET_H_ diff --git a/src/xdb/sources.gypi b/src/xdb/sources.gypi index 7e08a9fc7..621a218e1 100644 --- a/src/xdb/sources.gypi +++ b/src/xdb/sources.gypi @@ -1,6 +1,10 @@ # Copyright 2014 Ben Vanik. All Rights Reserved. { 'sources': [ + 'debug_target.cc', + 'debug_target.h', + 'postmortem_debug_target.cc', + 'postmortem_debug_target.h', 'protocol.h', 'xdb.cc', 'xdb.h', @@ -9,6 +13,7 @@ ], 'includes': [ + 'sym/sources.gypi', 'ui/sources.gypi', ], } diff --git a/src/xdb/sym/map_symbol_database.cc b/src/xdb/sym/map_symbol_database.cc new file mode 100644 index 000000000..f8fba81d8 --- /dev/null +++ b/src/xdb/sym/map_symbol_database.cc @@ -0,0 +1,20 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +namespace xdb { +namespace sym { + +Symbol* MapSymbolDatabase::Lookup(uint32_t address) { + return nullptr; +} + +} // namespace sym +} // namespace xdb diff --git a/src/xdb/sym/map_symbol_database.h b/src/xdb/sym/map_symbol_database.h new file mode 100644 index 000000000..25d9ef19c --- /dev/null +++ b/src/xdb/sym/map_symbol_database.h @@ -0,0 +1,26 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XDB_SYM_MAP_SYMBOL_DATABASE_H_ +#define XDB_SYM_MAP_SYMBOL_DATABASE_H_ + +#include + +namespace xdb { +namespace sym { + +class MapSymbolDatabase : public SymbolDatabase { + public: + Symbol* Lookup(uint32_t address) override; +}; + +} // namespace sym +} // namespace xdb + +#endif // XDB_SYM_MAP_SYMBOL_DATABASE_H_ diff --git a/src/xdb/sym/sources.gypi b/src/xdb/sym/sources.gypi new file mode 100644 index 000000000..ecff8910f --- /dev/null +++ b/src/xdb/sym/sources.gypi @@ -0,0 +1,14 @@ +# Copyright 2014 Ben Vanik. All Rights Reserved. +{ + 'sources': [ + 'map_symbol_database.cc', + 'map_symbol_database.h', + 'symbol_database.cc', + 'symbol_database.h', + 'symbol_provider.cc', + 'symbol_provider.h', + ], + + 'includes': [ + ], +} diff --git a/src/xdb/sym/symbol_database.cc b/src/xdb/sym/symbol_database.cc new file mode 100644 index 000000000..e2bc02f2d --- /dev/null +++ b/src/xdb/sym/symbol_database.cc @@ -0,0 +1,18 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +namespace xdb { +namespace sym { + +// + +} // namespace sym +} // namespace xdb diff --git a/src/xdb/sym/symbol_database.h b/src/xdb/sym/symbol_database.h new file mode 100644 index 000000000..bf43a38e2 --- /dev/null +++ b/src/xdb/sym/symbol_database.h @@ -0,0 +1,50 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XDB_SYM_SYMBOL_DATABASE_H_ +#define XDB_SYM_SYMBOL_DATABASE_H_ + +#include +#include + +namespace xdb { +namespace sym { + +class ObjectFile { + public: + std::string library; + std::string name; +}; + +enum class SymbolType { + FUNCTION, + VARIABLE, +}; + +class Symbol { + public: + uint32_t address; + ObjectFile* object_file; + std::string name; + SymbolType type; + bool is_inlined; +}; + +class SymbolDatabase { + public: + virtual Symbol* Lookup(uint32_t address) = 0; + + protected: + SymbolDatabase() = default; +}; + +} // namespace sym +} // namespace xdb + +#endif // XDB_SYM_SYMBOL_DATABASE_H_ diff --git a/src/xdb/sym/symbol_provider.cc b/src/xdb/sym/symbol_provider.cc new file mode 100644 index 000000000..3b5748290 --- /dev/null +++ b/src/xdb/sym/symbol_provider.cc @@ -0,0 +1,25 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +namespace xdb { +namespace sym { + +void SymbolProvider::AddSearchPath(const std::string& path) { + // +} + +std::unique_ptr SymbolProvider::LoadDatabase( + const std::string& module_path) { + return nullptr; +} + +} // namespace sym +} // namespace xdb diff --git a/src/xdb/sym/symbol_provider.h b/src/xdb/sym/symbol_provider.h new file mode 100644 index 000000000..89c1291aa --- /dev/null +++ b/src/xdb/sym/symbol_provider.h @@ -0,0 +1,33 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XDB_SYM_SYMBOL_PROVIDER_H_ +#define XDB_SYM_SYMBOL_PROVIDER_H_ + +#include +#include + +#include + +namespace xdb { +namespace sym { + +class SymbolProvider { + public: + SymbolProvider() = default; + + void AddSearchPath(const std::string& path); + + std::unique_ptr LoadDatabase(const std::string& module_path); +}; + +} // namespace sym +} // namespace xdb + +#endif // XDB_SYM_SYMBOL_PROVIDER_H_ diff --git a/src/xdb/ui/main_frame.cc b/src/xdb/ui/main_frame.cc index 606da3f44..1542435d6 100644 --- a/src/xdb/ui/main_frame.cc +++ b/src/xdb/ui/main_frame.cc @@ -12,7 +12,8 @@ namespace xdb { namespace ui { -MainFrame::MainFrame() : MainFrameBase(nullptr) {} +MainFrame::MainFrame(std::unique_ptr debug_target) + : MainFrameBase(nullptr), debug_target_(std::move(debug_target)) {} } // namespace ui } // namespace xdb diff --git a/src/xdb/ui/main_frame.h b/src/xdb/ui/main_frame.h index 9f6ba8ffd..2c7228dcc 100644 --- a/src/xdb/ui/main_frame.h +++ b/src/xdb/ui/main_frame.h @@ -10,8 +10,9 @@ #ifndef XDB_UI_MAIN_FRAME_H_ #define XDB_UI_MAIN_FRAME_H_ -#include +#include +#include #include namespace xdb { @@ -19,9 +20,13 @@ namespace ui { class MainFrame : public MainFrameBase { public: - MainFrame(); + MainFrame(std::unique_ptr debug_target); + protected: // + + private: + std::unique_ptr debug_target_; }; } // namespace ui diff --git a/src/xdb/ui/open_postmortem_trace_dialog.h b/src/xdb/ui/open_postmortem_trace_dialog.h new file mode 100644 index 000000000..64944029f --- /dev/null +++ b/src/xdb/ui/open_postmortem_trace_dialog.h @@ -0,0 +1,33 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XDB_UI_OPEN_POSTMORTEM_TRACE_DIALOG_H_ +#define XDB_UI_OPEN_POSTMORTEM_TRACE_DIALOG_H_ + +#include + +namespace xdb { +namespace ui { + +class OpenPostmortemTraceDialog : public OpenPostmortemTraceDialogBase { + public: + OpenPostmortemTraceDialog() : OpenPostmortemTraceDialogBase(nullptr) {} + + const std::wstring trace_file_path() const { + return trace_file_picker_->GetFileName().GetFullPath().ToStdWstring(); + } + const std::wstring content_file_path() const { + return content_file_picker_->GetFileName().GetFullPath().ToStdWstring(); + } +}; + +} // namespace ui +} // namespace xdb + +#endif // XDB_UI_OPEN_POSTMORTEM_TRACE_DIALOG_H_ diff --git a/src/xdb/ui/sources.gypi b/src/xdb/ui/sources.gypi index 3673fcf7a..bc406dd7d 100644 --- a/src/xdb/ui/sources.gypi +++ b/src/xdb/ui/sources.gypi @@ -3,6 +3,7 @@ 'sources': [ 'main_frame.cc', 'main_frame.h', + 'open_postmortem_trace_dialog.h', 'xdb_ui.cpp', 'xdb_ui.h', ], diff --git a/src/xdb/ui/xdb-ui.fbp b/src/xdb/ui/xdb-ui.fbp index 4a40d2e42..7166732f5 100644 --- a/src/xdb/ui/xdb-ui.fbp +++ b/src/xdb/ui/xdb-ui.fbp @@ -11,7 +11,7 @@ res UTF-8 connect - + xdb_ui 1000 none 0 @@ -46,7 +46,7 @@ 1024,768 wxDEFAULT_FRAME_STYLE - + ; xenia debugger @@ -135,7 +135,7 @@ File - file + file_menu_ protected @@ -536,5 +536,638 @@ + + 0 + + + wxBOTH + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + OpenPostmortemTraceDialogBase + + -1,-1 + wxDEFAULT_DIALOG_STYLE + + Open Postmortem Trace + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + root_panel_outer + wxVERTICAL + none + + 10 + wxEXPAND | wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + root_panel + 1 + + + none + 1 + + Resizable + 1 + + + 0 + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + 1 + wxVERTICAL + 0 + + 0 + + root_sizer + wxFLEX_GROWMODE_SPECIFIED + none + 0 + 0 + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Use --trace_file= to specify the output file path when running xenia-run. + + 0 + + + 0 + + 1 + info_label + 1 + + + none + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 2 + wxBOTH + 1 + + 0 + + content_sizer + wxFLEX_GROWMODE_SPECIFIED + none + 0 + 0 + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Trace File: + + 0 + + + 0 + + 1 + trace_file_label + 1 + + + none + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER|wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + Select a .trace file + + 0 + + 1 + trace_file_picker_ + 1 + + + protected + 1 + + Resizable + 1 + + wxFLP_DEFAULT_STYLE|wxFLP_FILE_MUST_EXIST|wxFLP_OPEN|wxFLP_USE_TEXTCTRL + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + *.trace + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Content Path: + + 0 + + + 0 + + 1 + content_file_label + 1 + + + none + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER|wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + Select the source content path + + 0 + + 1 + content_file_picker_ + 1 + + + protected + 1 + + Resizable + 1 + + wxFLP_FILE_MUST_EXIST|wxFLP_OPEN|wxFLP_USE_TEXTCTRL + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + *.xex;*.iso;*.* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + wxEXPAND + 1 + + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + + dialog_buttons_ + protected + + OnCancelButtonClick + + + + OnOKButtonClick + + + + + + + + + diff --git a/src/xdb/ui/xdb_ui.cpp b/src/xdb/ui/xdb_ui.cpp index c537f8f6a..0ec24af81 100644 --- a/src/xdb/ui/xdb_ui.cpp +++ b/src/xdb/ui/xdb_ui.cpp @@ -17,8 +17,8 @@ MainFrameBase::MainFrameBase( wxWindow* parent, wxWindowID id, const wxString& t m_mgr.SetFlags(wxAUI_MGR_DEFAULT|wxAUI_MGR_LIVE_RESIZE); menu_bar_ = new wxMenuBar( 0 ); - file = new wxMenu(); - menu_bar_->Append( file, wxT("File") ); + file_menu_ = new wxMenu(); + menu_bar_->Append( file_menu_, wxT("File") ); this->SetMenuBar( menu_bar_ ); @@ -47,3 +47,83 @@ MainFrameBase::~MainFrameBase() m_mgr.UnInit(); } + +OpenPostmortemTraceDialogBase::OpenPostmortemTraceDialogBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + wxBoxSizer* root_panel_outer; + root_panel_outer = new wxBoxSizer( wxVERTICAL ); + + wxPanel* root_panel; + root_panel = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxFlexGridSizer* root_sizer; + root_sizer = new wxFlexGridSizer( 0, 1, 0, 0 ); + root_sizer->AddGrowableCol( 0 ); + root_sizer->SetFlexibleDirection( wxVERTICAL ); + root_sizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + wxStaticText* info_label; + info_label = new wxStaticText( root_panel, wxID_ANY, wxT("Use --trace_file= to specify the output file path when running xenia-run."), wxDefaultPosition, wxDefaultSize, 0 ); + info_label->Wrap( -1 ); + root_sizer->Add( info_label, 0, wxALL, 5 ); + + wxFlexGridSizer* content_sizer; + content_sizer = new wxFlexGridSizer( 0, 2, 0, 0 ); + content_sizer->AddGrowableCol( 1 ); + content_sizer->SetFlexibleDirection( wxBOTH ); + content_sizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + wxStaticText* trace_file_label; + trace_file_label = new wxStaticText( root_panel, wxID_ANY, wxT("Trace File:"), wxDefaultPosition, wxDefaultSize, 0 ); + trace_file_label->Wrap( -1 ); + content_sizer->Add( trace_file_label, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 ); + + trace_file_picker_ = new wxFilePickerCtrl( root_panel, wxID_ANY, wxEmptyString, wxT("Select a .trace file"), wxT("*.trace"), wxDefaultPosition, wxDefaultSize, wxFLP_DEFAULT_STYLE|wxFLP_FILE_MUST_EXIST|wxFLP_OPEN|wxFLP_USE_TEXTCTRL ); + content_sizer->Add( trace_file_picker_, 1, wxALIGN_CENTER|wxALL|wxEXPAND, 5 ); + + wxStaticText* content_file_label; + content_file_label = new wxStaticText( root_panel, wxID_ANY, wxT("Content Path:"), wxDefaultPosition, wxDefaultSize, 0 ); + content_file_label->Wrap( -1 ); + content_sizer->Add( content_file_label, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 ); + + content_file_picker_ = new wxFilePickerCtrl( root_panel, wxID_ANY, wxEmptyString, wxT("Select the source content path"), wxT("*.xex;*.iso;*.*"), wxDefaultPosition, wxDefaultSize, wxFLP_FILE_MUST_EXIST|wxFLP_OPEN|wxFLP_USE_TEXTCTRL ); + content_sizer->Add( content_file_picker_, 1, wxALIGN_CENTER|wxALL|wxEXPAND, 5 ); + + + root_sizer->Add( content_sizer, 0, wxEXPAND, 5 ); + + dialog_buttons_ = new wxStdDialogButtonSizer(); + dialog_buttons_OK = new wxButton( root_panel, wxID_OK ); + dialog_buttons_->AddButton( dialog_buttons_OK ); + dialog_buttons_Cancel = new wxButton( root_panel, wxID_CANCEL ); + dialog_buttons_->AddButton( dialog_buttons_Cancel ); + dialog_buttons_->Realize(); + + root_sizer->Add( dialog_buttons_, 1, wxEXPAND, 0 ); + + + root_panel->SetSizer( root_sizer ); + root_panel->Layout(); + root_sizer->Fit( root_panel ); + root_panel_outer->Add( root_panel, 1, wxEXPAND | wxALL, 10 ); + + + this->SetSizer( root_panel_outer ); + this->Layout(); + root_panel_outer->Fit( this ); + + this->Centre( wxBOTH ); + + // Connect Events + dialog_buttons_Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( OpenPostmortemTraceDialogBase::OnCancelButtonClick ), NULL, this ); + dialog_buttons_OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( OpenPostmortemTraceDialogBase::OnOKButtonClick ), NULL, this ); +} + +OpenPostmortemTraceDialogBase::~OpenPostmortemTraceDialogBase() +{ + // Disconnect Events + dialog_buttons_Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( OpenPostmortemTraceDialogBase::OnCancelButtonClick ), NULL, this ); + dialog_buttons_OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( OpenPostmortemTraceDialogBase::OnOKButtonClick ), NULL, this ); + +} diff --git a/src/xdb/ui/xdb_ui.h b/src/xdb/ui/xdb_ui.h index 421f89942..31e418046 100644 --- a/src/xdb/ui/xdb_ui.h +++ b/src/xdb/ui/xdb_ui.h @@ -25,6 +25,11 @@ #include #include #include +#include +#include +#include +#include +#include /////////////////////////////////////////////////////////////////////////// @@ -41,7 +46,7 @@ namespace xdb protected: wxMenuBar* menu_bar_; - wxMenu* file; + wxMenu* file_menu_; wxAuiToolBar* tool_bar_; wxAuiToolBarItem* tool_test_; wxStatusBar* status_bar_; @@ -58,6 +63,32 @@ namespace xdb }; + /////////////////////////////////////////////////////////////////////////////// + /// Class OpenPostmortemTraceDialogBase + /////////////////////////////////////////////////////////////////////////////// + class OpenPostmortemTraceDialogBase : public wxDialog + { + private: + + protected: + wxFilePickerCtrl* trace_file_picker_; + wxFilePickerCtrl* content_file_picker_; + wxStdDialogButtonSizer* dialog_buttons_; + wxButton* dialog_buttons_OK; + wxButton* dialog_buttons_Cancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnCancelButtonClick( wxCommandEvent& event ) { event.Skip(); } + virtual void OnOKButtonClick( wxCommandEvent& event ) { event.Skip(); } + + + public: + + OpenPostmortemTraceDialogBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Open Postmortem Trace"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE ); + ~OpenPostmortemTraceDialogBase(); + + }; + } // namespace ui } // namespace xdb diff --git a/src/xdb/xdb_app.cc b/src/xdb/xdb_app.cc index b91672189..2da4cf668 100644 --- a/src/xdb/xdb_app.cc +++ b/src/xdb/xdb_app.cc @@ -9,21 +9,123 @@ #include +#include +#include +#include + +#include +#include +#include +#include +#include + namespace xdb { IMPLEMENT_APP(XdbApp); -bool XdbApp::OnInit() { - main_frame_.reset(new ui::MainFrame()); - - main_frame_->Show(); - return true; -} +bool XdbApp::OnInit() { return true; } int XdbApp::OnExit() { // Top level windows are deleted by wx automatically. - main_frame_.release(); return 0; } +void XdbApp::OpenEmpty() { + while (true) { + ui::OpenPostmortemTraceDialog dialog; + if (dialog.ShowModal() == wxID_CANCEL) { + Exit(); + return; + } + if (OpenTraceFile(dialog.trace_file_path(), dialog.content_file_path())) { + break; + } + } +} + +bool XdbApp::OpenTraceFile(const std::string& trace_file_path, + const std::string& content_file_path) { + std::wstring_convert> converter; + return OpenTraceFile(converter.from_bytes(trace_file_path), + converter.from_bytes(content_file_path)); +} + +bool XdbApp::OpenTraceFile(const std::wstring& trace_file_path, + const std::wstring& content_file_path) { + std::unique_ptr target(new PostmortemDebugTarget()); + + if (!target->LoadTrace(trace_file_path)) { + HandleOpenError("Unable to load trace file."); + return false; + } + + if (!target->LoadContent(content_file_path)) { + HandleOpenError("Unable to load source game content module."); + return false; + } + + wxProgressDialog progress_dialog( + "Preparing trace...", "This may take some time.", 100, nullptr, + wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_SMOOTH | wxPD_CAN_ABORT | + wxPD_ELAPSED_TIME | wxPD_ELAPSED_TIME); + progress_dialog.Show(); + + enum class PrepareStatus { + PROCESSING, + SUCCEEDED, + FAILED, + }; + std::atomic status(PrepareStatus::PROCESSING); + std::atomic cancelled; + std::thread preparation_thread([&target, &cancelled, &status]() { + status = target->Prepare(cancelled) ? PrepareStatus::SUCCEEDED + : PrepareStatus::FAILED; + }); + + do { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } while (status == PrepareStatus::PROCESSING && progress_dialog.Pulse()); + cancelled = progress_dialog.WasCancelled(); + preparation_thread.join(); + progress_dialog.Hide(); + if (cancelled) { + return false; + } + if (status == PrepareStatus::FAILED) { + HandleOpenError("Invalid trace file; unable to process."); + return false; + } + + return OpenDebugTarget(std::move(target)); +} + +bool XdbApp::OpenDebugTarget(std::unique_ptr debug_target) { + auto main_frame = new ui::MainFrame(std::move(debug_target)); + + main_frames_.push_back(main_frame); + main_frame->Connect(wxEVT_DESTROY, wxEventHandler(XdbApp::OnMainFrameDestroy), + nullptr, this); + + main_frame->Show(); + main_frame->SetFocus(); + + return true; +} + +void XdbApp::HandleOpenError(const std::string& message) { + wxMessageDialog dialog(nullptr, message, "Error", + wxOK | wxOK_DEFAULT | wxICON_ERROR); + dialog.ShowModal(); +} + +void XdbApp::OnMainFrameDestroy(wxEvent& event) { + for (auto it = main_frames_.begin(); it != main_frames_.end(); ++it) { + if (*it == event.GetEventObject()) { + main_frames_.erase(it); + return; + } + } + assert_always(); +} + } // namespace xdb diff --git a/src/xdb/xdb_app.h b/src/xdb/xdb_app.h index b373ab7fe..1aa607042 100644 --- a/src/xdb/xdb_app.h +++ b/src/xdb/xdb_app.h @@ -11,10 +11,18 @@ #define XDB_XDB_APP_H_ #include +#include +#include -#include +#include #include +namespace xdb { +namespace ui { +class MainFrame; +} // namespace ui +} // namespace xdb + namespace xdb { class XdbApp : public wxApp { @@ -22,8 +30,19 @@ class XdbApp : public wxApp { bool OnInit() override; int OnExit() override; + void OpenEmpty(); + bool OpenTraceFile(const std::string& trace_file_path, + const std::string& content_file_path = ""); + bool OpenTraceFile(const std::wstring& trace_file_path, + const std::wstring& content_file_path = L""); + bool OpenDebugTarget(std::unique_ptr debug_target); + private: - std::unique_ptr main_frame_; + void HandleOpenError(const std::string& message); + + void OnMainFrameDestroy(wxEvent& event); + + std::vector main_frames_; }; } // namespace xdb diff --git a/tools/xenia-debug/xenia-debug.cc b/tools/xenia-debug/xenia-debug.cc index 6fc239eb6..090975438 100644 --- a/tools/xenia-debug/xenia-debug.cc +++ b/tools/xenia-debug/xenia-debug.cc @@ -16,6 +16,10 @@ #include #include +DEFINE_string(trace_file, "", "Trace file to load on startup."); +DEFINE_string(content_file, "", + "ISO/STFS/XEX file the specified trace_file should reference."); + namespace xdb { int main(int argc, xechar_t** argv) { @@ -44,6 +48,14 @@ int main(int argc, xechar_t** argv) { XEFATAL("Failed to init app"); return 1; } + + if (!FLAGS_trace_file.empty()) { + // Trace file specified on command line. + app->OpenTraceFile(FLAGS_trace_file, FLAGS_content_file); + } else { + app->OpenEmpty(); + } + app->OnRun(); int result_code = app->OnExit(); wxEntryCleanup(); From 4768f2fc0b4d9054ca4fe8bfbbddd50d29bf9284 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 15 Aug 2014 07:24:27 -0700 Subject: [PATCH 101/388] Moving XdbApp under ui::. --- src/xdb/sources.gypi | 2 -- src/xdb/ui/sources.gypi | 2 ++ src/xdb/{ => ui}/xdb_app.cc | 8 +++++--- src/xdb/{ => ui}/xdb_app.h | 14 ++++++-------- tools/xenia-debug/xenia-debug.cc | 4 ++-- 5 files changed, 15 insertions(+), 15 deletions(-) rename src/xdb/{ => ui}/xdb_app.cc (95%) rename src/xdb/{ => ui}/xdb_app.h (89%) diff --git a/src/xdb/sources.gypi b/src/xdb/sources.gypi index 621a218e1..eec8b4a15 100644 --- a/src/xdb/sources.gypi +++ b/src/xdb/sources.gypi @@ -8,8 +8,6 @@ 'protocol.h', 'xdb.cc', 'xdb.h', - 'xdb_app.cc', - 'xdb_app.h', ], 'includes': [ diff --git a/src/xdb/ui/sources.gypi b/src/xdb/ui/sources.gypi index bc406dd7d..9f4541a7b 100644 --- a/src/xdb/ui/sources.gypi +++ b/src/xdb/ui/sources.gypi @@ -4,6 +4,8 @@ 'main_frame.cc', 'main_frame.h', 'open_postmortem_trace_dialog.h', + 'xdb_app.cc', + 'xdb_app.h', 'xdb_ui.cpp', 'xdb_ui.h', ], diff --git a/src/xdb/xdb_app.cc b/src/xdb/ui/xdb_app.cc similarity index 95% rename from src/xdb/xdb_app.cc rename to src/xdb/ui/xdb_app.cc index 2da4cf668..c902142b7 100644 --- a/src/xdb/xdb_app.cc +++ b/src/xdb/ui/xdb_app.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include #include #include @@ -20,6 +20,7 @@ #include namespace xdb { +namespace ui { IMPLEMENT_APP(XdbApp); @@ -32,7 +33,7 @@ int XdbApp::OnExit() { void XdbApp::OpenEmpty() { while (true) { - ui::OpenPostmortemTraceDialog dialog; + OpenPostmortemTraceDialog dialog; if (dialog.ShowModal() == wxID_CANCEL) { Exit(); return; @@ -100,7 +101,7 @@ bool XdbApp::OpenTraceFile(const std::wstring& trace_file_path, } bool XdbApp::OpenDebugTarget(std::unique_ptr debug_target) { - auto main_frame = new ui::MainFrame(std::move(debug_target)); + auto main_frame = new MainFrame(std::move(debug_target)); main_frames_.push_back(main_frame); main_frame->Connect(wxEVT_DESTROY, wxEventHandler(XdbApp::OnMainFrameDestroy), @@ -128,4 +129,5 @@ void XdbApp::OnMainFrameDestroy(wxEvent& event) { assert_always(); } +} // namespace ui } // namespace xdb diff --git a/src/xdb/xdb_app.h b/src/xdb/ui/xdb_app.h similarity index 89% rename from src/xdb/xdb_app.h rename to src/xdb/ui/xdb_app.h index 1aa607042..c6c3bfd7d 100644 --- a/src/xdb/xdb_app.h +++ b/src/xdb/ui/xdb_app.h @@ -7,8 +7,8 @@ ****************************************************************************** */ -#ifndef XDB_XDB_APP_H_ -#define XDB_XDB_APP_H_ +#ifndef XDB_UI_XDB_APP_H_ +#define XDB_UI_XDB_APP_H_ #include #include @@ -19,11 +19,8 @@ namespace xdb { namespace ui { -class MainFrame; -} // namespace ui -} // namespace xdb -namespace xdb { +class MainFrame; class XdbApp : public wxApp { public: @@ -42,9 +39,10 @@ class XdbApp : public wxApp { void OnMainFrameDestroy(wxEvent& event); - std::vector main_frames_; + std::vector main_frames_; }; +} // namespace ui } // namespace xdb -#endif // XDB_XDB_APP_H_ +#endif // XDB_UI_XDB_APP_H_ diff --git a/tools/xenia-debug/xenia-debug.cc b/tools/xenia-debug/xenia-debug.cc index 090975438..2adeaf618 100644 --- a/tools/xenia-debug/xenia-debug.cc +++ b/tools/xenia-debug/xenia-debug.cc @@ -14,7 +14,7 @@ #include #include #include -#include +#include DEFINE_string(trace_file, "", "Trace file to load on startup."); DEFINE_string(content_file, "", @@ -38,7 +38,7 @@ int main(int argc, xechar_t** argv) { } // App is auto-freed by wx. - auto app = new XdbApp(); + auto app = new ui::XdbApp(); wxApp::SetInstance(app); if (!wxEntryStart(0, nullptr)) { XEFATAL("Failed to enter wxWidgets app"); From 3de39aaf10333cee9ed70c3c9e11e4773d507302 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 15 Aug 2014 10:19:59 -0700 Subject: [PATCH 102/388] Postmortem debug target now loads/scans the trace and inits the filesystem. --- src/poly/memory.h | 29 +++ src/poly/poly.h | 1 + src/poly/sources.gypi | 2 + src/poly/string.cc | 26 +++ src/poly/string.h | 24 +++ src/xdb/debug_target.cc | 16 +- src/xdb/debug_target.h | 10 + src/xdb/postmortem_debug_target.cc | 196 +++++++++++++++++- src/xdb/postmortem_debug_target.h | 18 +- src/xdb/protocol.h | 11 +- src/xdb/ui/xdb_app.cc | 15 +- src/xenia/debug_agent.cc | 6 +- src/xenia/emulator.cc | 134 ++++-------- src/xenia/emulator.h | 15 +- src/xenia/kernel/fs/device.cc | 14 +- src/xenia/kernel/fs/device.h | 19 +- .../kernel/fs/devices/disc_image_device.cc | 14 +- .../kernel/fs/devices/disc_image_device.h | 26 ++- .../kernel/fs/devices/host_path_device.cc | 14 +- .../kernel/fs/devices/host_path_device.h | 23 +- .../fs/devices/stfs_container_device.cc | 15 +- .../kernel/fs/devices/stfs_container_device.h | 26 ++- src/xenia/kernel/fs/filesystem.cc | 75 ++++++- src/xenia/kernel/fs/filesystem.h | 30 ++- src/xenia/kernel/xboxkrnl_rtl.cc | 7 +- tools/xenia-debug/xenia-debug.cc | 5 +- tools/xenia-run/xenia-run.cc | 25 +-- 27 files changed, 541 insertions(+), 255 deletions(-) create mode 100644 src/poly/string.cc create mode 100644 src/poly/string.h diff --git a/src/poly/memory.h b/src/poly/memory.h index 531c0ea4d..e4d24a3f9 100644 --- a/src/poly/memory.h +++ b/src/poly/memory.h @@ -12,6 +12,7 @@ #include +#include #include namespace poly { @@ -60,6 +61,20 @@ template <> inline double load(const void* mem) { return *reinterpret_cast(mem); } +template +inline T load(const void* mem) { + if (sizeof(T) == 1) { + return static_cast(load(mem)); + } else if (sizeof(T) == 2) { + return static_cast(load(mem)); + } else if (sizeof(T) == 4) { + return static_cast(load(mem)); + } else if (sizeof(T) == 8) { + return static_cast(load(mem)); + } else { + assert_always("Invalid poly::load size"); + } +} template T load_and_swap(const void* mem); @@ -172,6 +187,20 @@ template <> inline void store(void* mem, double value) { *reinterpret_cast(mem) = value; } +template +inline void store(const void* mem, T value) { + if (sizeof(T) == 1) { + store(mem, static_cast(value)); + } else if (sizeof(T) == 2) { + store(mem, static_cast(value)); + } else if (sizeof(T) == 4) { + store(mem, static_cast(value)); + } else if (sizeof(T) == 8) { + store(mem, static_cast(value)); + } else { + assert_always("Invalid poly::store size"); + } +} template void store_and_swap(void* mem, T value); diff --git a/src/poly/poly.h b/src/poly/poly.h index 1cdadbed6..4fc966b73 100644 --- a/src/poly/poly.h +++ b/src/poly/poly.h @@ -19,6 +19,7 @@ #include #include #include +#include #include namespace poly {} // namespace poly diff --git a/src/poly/sources.gypi b/src/poly/sources.gypi index 6765121fa..19e08905b 100644 --- a/src/poly/sources.gypi +++ b/src/poly/sources.gypi @@ -15,6 +15,8 @@ 'poly-private.h', 'poly.cc', 'poly.h', + 'string.cc', + 'string.h', 'threading.h', ], diff --git a/src/poly/string.cc b/src/poly/string.cc new file mode 100644 index 000000000..1d8bb53e2 --- /dev/null +++ b/src/poly/string.cc @@ -0,0 +1,26 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include + +namespace poly { + +std::string to_string(const std::wstring& source) { + static std::wstring_convert> converter; + return converter.to_bytes(source); +} + +std::wstring to_wstring(const std::string& source) { + static std::wstring_convert> converter; + return converter.from_bytes(source); +} + +} // namespace poly diff --git a/src/poly/string.h b/src/poly/string.h new file mode 100644 index 000000000..20b684e6d --- /dev/null +++ b/src/poly/string.h @@ -0,0 +1,24 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef POLY_STRING_H_ +#define POLY_STRING_H_ + +#include + +#include + +namespace poly { + +std::string to_string(const std::wstring& source); +std::wstring to_wstring(const std::string& source); + +} // namespace poly + +#endif // POLY_STRING_H_ diff --git a/src/xdb/debug_target.cc b/src/xdb/debug_target.cc index 197ab2be6..65b1ea810 100644 --- a/src/xdb/debug_target.cc +++ b/src/xdb/debug_target.cc @@ -11,6 +11,20 @@ namespace xdb { -// +bool DebugTarget::InitializeFileSystem(const std::wstring& path) { + file_system_.reset(new xe::kernel::fs::FileSystem()); + + // Infer the type (stfs/iso/etc) from the path. + auto file_system_type = file_system_->InferType(path); + + // Setup the file system exactly like the emulator does - this way we can + // access all the same files. + if (file_system_->InitializeFromPath(file_system_type, path)) { + XELOGE("Unable to initialize filesystem from path"); + return false; + } + + return true; +} } // namespace xdb diff --git a/src/xdb/debug_target.h b/src/xdb/debug_target.h index 2ff238f5d..7724daefd 100644 --- a/src/xdb/debug_target.h +++ b/src/xdb/debug_target.h @@ -10,12 +10,22 @@ #ifndef XDB_DEBUG_TARGET_H_ #define XDB_DEBUG_TARGET_H_ +#include + namespace xdb { class DebugTarget { public: + virtual ~DebugTarget() = default; + + xe::kernel::fs::FileSystem* file_system() const { return file_system_.get(); } + protected: DebugTarget() = default; + + bool InitializeFileSystem(const std::wstring& path); + + std::unique_ptr file_system_; }; } // namespace xdb diff --git a/src/xdb/postmortem_debug_target.cc b/src/xdb/postmortem_debug_target.cc index fa541a72d..6a3009385 100644 --- a/src/xdb/postmortem_debug_target.cc +++ b/src/xdb/postmortem_debug_target.cc @@ -9,19 +9,109 @@ #include +#include +#include + namespace xdb { -bool PostmortemDebugTarget::LoadTrace(const std::wstring& path) { - // TODO(benvanik): memory map trace. - return true; +using xdb::protocol::EventType; + +// Matches the EventType ordering to allow for quick event size checks. +const size_t event_sizes[] = { + 0, + sizeof(protocol::ProcessStartEvent), + sizeof(protocol::ProcessExitEvent), + sizeof(protocol::ModuleLoadEvent), + sizeof(protocol::ModuleUnloadEvent), + sizeof(protocol::ThreadCreateEvent), + sizeof(protocol::ThreadInfoEvent), + sizeof(protocol::ThreadExitEvent), + sizeof(protocol::FunctionCompiledEvent), + sizeof(protocol::OutputStringEvent), + sizeof(protocol::KernelCallEvent), + sizeof(protocol::KernelCallReturnEvent), + sizeof(protocol::UserCallEvent), + sizeof(protocol::UserCallReturnEvent), + sizeof(protocol::InstrEvent), + sizeof(protocol::InstrEventR8), + sizeof(protocol::InstrEventR8R8), + sizeof(protocol::InstrEventR8R16), + sizeof(protocol::InstrEventR16), + sizeof(protocol::InstrEventR16R8), + sizeof(protocol::InstrEventR16R16), +}; + +PostmortemDebugTarget::PostmortemDebugTarget() + : file_(nullptr), + file_mapping_(nullptr), + trace_base_(0), + process_start_event_(nullptr), + process_exit_event_(nullptr) {} + +PostmortemDebugTarget::~PostmortemDebugTarget() { + if (trace_base_) { + UnmapViewOfFile(trace_base_); + } + CloseHandle(file_mapping_); + CloseHandle(file_); } -bool PostmortemDebugTarget::LoadContent(const std::wstring& path) { - // If no path is provided attempt to infer from the trace. - if (path.empty()) { - // TODO(benvanik): find process info block and read source path. +bool PostmortemDebugTarget::LoadTrace(const std::wstring& path, + const std::wstring& content_path) { + file_ = CreateFile(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, nullptr); + if (!file_) { + XELOGE("Could not open trace file for writing"); + return false; } - // TODO(benvanik): initialize filesystem and load iso/stfs/etc to get at xex. + + file_mapping_ = CreateFileMapping(file_, nullptr, PAGE_READONLY, 0, 0, + L"Local\\xenia_xdb_trace"); + if (!file_mapping_) { + XELOGE("Could not create trace file mapping"); + return false; + } + + trace_base_ = reinterpret_cast( + MapViewOfFile(file_mapping_, FILE_MAP_READ, 0, 0, 0)); + if (!trace_base_) { + XELOGE("Could not map view of trace file"); + return false; + } + + // Find the process start event - it should be near the top and we need it for + // path lookup. + const uint8_t* ptr = trace_base_ + 8; + EventType event_type; + while ((event_type = poly::load(ptr)) != + EventType::END_OF_STREAM) { + switch (event_type) { + case EventType::PROCESS_START: { + process_start_event_ = protocol::ProcessStartEvent::Get(ptr); + break; + } + } + if (process_start_event_) { + break; + } + ptr += event_sizes[static_cast(event_type)]; + } + + bool initialized_filesystem = false; + if (!content_path.empty()) { + initialized_filesystem = InitializeFileSystem(content_path); + } else { + // If no path was provided just use what's in the trace. + auto trace_content_path = + poly::to_wstring(std::string(process_start_event_->launch_path)); + initialized_filesystem = InitializeFileSystem(trace_content_path); + } + if (!initialized_filesystem) { + XELOGE("Unable to initialize filesystem."); + return false; + } + return true; } @@ -32,6 +122,96 @@ bool PostmortemDebugTarget::Prepare() { bool PostmortemDebugTarget::Prepare(std::atomic& cancelled) { // TODO(benvanik): scan file, build indicies, etc. + + const uint8_t* ptr = trace_base_ + 8; + EventType event_type; + while ((event_type = poly::load(ptr)) != + EventType::END_OF_STREAM) { + switch (event_type) { + case EventType::PROCESS_START: { + process_start_event_ = protocol::ProcessStartEvent::Get(ptr); + break; + } + case EventType::PROCESS_EXIT: { + process_exit_event_ = protocol::ProcessExitEvent::Get(ptr); + break; + } + case EventType::MODULE_LOAD: { + auto ev = protocol::ModuleLoadEvent::Get(ptr); + break; + } + case EventType::MODULE_UNLOAD: { + auto ev = protocol::ModuleUnloadEvent::Get(ptr); + break; + } + case EventType::THREAD_CREATE: { + auto ev = protocol::ThreadCreateEvent::Get(ptr); + break; + } + case EventType::THREAD_INFO: { + auto ev = protocol::ThreadInfoEvent::Get(ptr); + break; + } + case EventType::THREAD_EXIT: { + auto ev = protocol::ThreadExitEvent::Get(ptr); + break; + } + case EventType::FUNCTION_COMPILED: { + auto ev = protocol::FunctionCompiledEvent::Get(ptr); + break; + } + case EventType::OUTPUT_STRING: { + auto ev = protocol::OutputStringEvent::Get(ptr); + break; + } + case EventType::KERNEL_CALL: { + auto ev = protocol::KernelCallEvent::Get(ptr); + break; + } + case EventType::KERNEL_CALL_RETURN: { + auto ev = protocol::KernelCallReturnEvent::Get(ptr); + break; + } + case EventType::USER_CALL: { + auto ev = protocol::UserCallEvent::Get(ptr); + break; + } + case EventType::USER_CALL_RETURN: { + auto ev = protocol::UserCallReturnEvent::Get(ptr); + break; + } + case EventType::INSTR: { + auto ev = protocol::InstrEvent::Get(ptr); + break; + } + case EventType::INSTR_R8: { + auto ev = protocol::InstrEventR8::Get(ptr); + break; + } + case EventType::INSTR_R8_R8: { + auto ev = protocol::InstrEventR8R8::Get(ptr); + break; + } + case EventType::INSTR_R8_R16: { + auto ev = protocol::InstrEventR8R16::Get(ptr); + break; + } + case EventType::INSTR_R16: { + auto ev = protocol::InstrEventR16::Get(ptr); + break; + } + case EventType::INSTR_R16_R8: { + auto ev = protocol::InstrEventR16R8::Get(ptr); + break; + } + case EventType::INSTR_R16_R16: { + auto ev = protocol::InstrEventR16R16::Get(ptr); + break; + } + } + ptr += event_sizes[static_cast(event_type)]; + }; + return true; } diff --git a/src/xdb/postmortem_debug_target.h b/src/xdb/postmortem_debug_target.h index 4071ea19e..6f4575337 100644 --- a/src/xdb/postmortem_debug_target.h +++ b/src/xdb/postmortem_debug_target.h @@ -10,22 +10,34 @@ #ifndef XDB_POSTMORTEM_DEBUG_TARGET_H_ #define XDB_POSTMORTEM_DEBUG_TARGET_H_ +// TODO(benvanik): abstract mapping type. +#include #include #include #include +#include namespace xdb { class PostmortemDebugTarget : public DebugTarget { public: - PostmortemDebugTarget() = default; + PostmortemDebugTarget(); + ~PostmortemDebugTarget() override; - bool LoadTrace(const std::wstring& path); - bool LoadContent(const std::wstring& path = L""); + bool LoadTrace(const std::wstring& path, + const std::wstring& content_path = L""); bool Prepare(); bool Prepare(std::atomic& cancelled); + + private: + HANDLE file_; + HANDLE file_mapping_; + const uint8_t* trace_base_; + + const protocol::ProcessStartEvent* process_start_event_; + const protocol::ProcessExitEvent* process_exit_event_; }; } // namespace xdb diff --git a/src/xdb/protocol.h b/src/xdb/protocol.h index 51f9628da..b1b4be039 100644 --- a/src/xdb/protocol.h +++ b/src/xdb/protocol.h @@ -23,7 +23,7 @@ using vec128_t = alloy::vec128_t; #pragma pack(push, 4) enum class EventType : uint8_t { - SETUP, + END_OF_STREAM = 0, PROCESS_START, PROCESS_EXIT, @@ -61,15 +61,16 @@ struct Event { sizeof(T), reinterpret_cast(trace_base)); return reinterpret_cast(ptr); } -}; -struct SetupEvent : public Event { - EventType type; - uint64_t membase; + static const T* Get(const void* ptr) { + return reinterpret_cast(ptr); + } }; struct ProcessStartEvent : public Event { EventType type; + uint64_t membase; + char launch_path[256]; }; struct ProcessExitEvent : public Event { diff --git a/src/xdb/ui/xdb_app.cc b/src/xdb/ui/xdb_app.cc index c902142b7..d02c67136 100644 --- a/src/xdb/ui/xdb_app.cc +++ b/src/xdb/ui/xdb_app.cc @@ -10,10 +10,9 @@ #include #include -#include #include -#include +#include #include #include #include @@ -46,25 +45,19 @@ void XdbApp::OpenEmpty() { bool XdbApp::OpenTraceFile(const std::string& trace_file_path, const std::string& content_file_path) { - std::wstring_convert> converter; - return OpenTraceFile(converter.from_bytes(trace_file_path), - converter.from_bytes(content_file_path)); + return OpenTraceFile(poly::to_wstring(trace_file_path), + poly::to_wstring(content_file_path)); } bool XdbApp::OpenTraceFile(const std::wstring& trace_file_path, const std::wstring& content_file_path) { std::unique_ptr target(new PostmortemDebugTarget()); - if (!target->LoadTrace(trace_file_path)) { + if (!target->LoadTrace(trace_file_path, content_file_path)) { HandleOpenError("Unable to load trace file."); return false; } - if (!target->LoadContent(content_file_path)) { - HandleOpenError("Unable to load source game content module."); - return false; - } - wxProgressDialog progress_dialog( "Preparing trace...", "This may take some time.", 100, nullptr, wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_SMOOTH | wxPD_CAN_ABORT | diff --git a/src/xenia/debug_agent.cc b/src/xenia/debug_agent.cc index 3b2c63c82..4c552a31a 100644 --- a/src/xenia/debug_agent.cc +++ b/src/xenia/debug_agent.cc @@ -9,8 +9,7 @@ #include -#include - +#include #include DEFINE_string(trace_file, "", "Trace to the given file."); @@ -45,8 +44,7 @@ int DebugAgent::Initialize() { } int DebugAgent::SetupTracing(const std::string& trace_file, uint64_t capacity) { - std::wstring_convert> cvt; - auto file_path = cvt.from_bytes(trace_file); + auto file_path = poly::to_wstring(trace_file); file_ = CreateFile(file_path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index 5cbc64675..fc054e6fc 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -149,7 +150,7 @@ void Emulator::set_main_window(Window* window) { }); } -X_STATUS Emulator::LaunchXexFile(const xechar_t* path) { +X_STATUS Emulator::LaunchXexFile(const std::wstring& path) { // We create a virtual filesystem pointing to its directory and symlink // that to the game filesystem. // e.g., /my/files/foo.xex will get a local fs at: @@ -157,111 +158,60 @@ X_STATUS Emulator::LaunchXexFile(const xechar_t* path) { // and then get that symlinked to game:\, so // -> game:\foo.xex - auto ev = xdb::protocol::ProcessStartEvent::Append(memory()->trace_base()); - if (ev) { - ev->type = xdb::protocol::EventType::PROCESS_START; + int result_code = + file_system_->InitializeFromPath(FileSystemType::XEX_FILE, path); + if (result_code) { + return X_STATUS_INVALID_PARAMETER; } - int result_code = 0; - // Get just the filename (foo.xex). - const xechar_t* file_name = xestrrchr(path, poly::path_separator); - if (file_name) { - // Skip slash. - file_name++; - } else { + std::wstring file_name; + auto last_slash = path.find_last_of(poly::path_separator); + if (last_slash == std::string::npos) { // No slash found, whole thing is a file. file_name = path; + } else { + // Skip slash. + file_name = path.substr(last_slash + 1); } - // Get the parent path of the file. - xechar_t parent_path[poly::max_path]; - XEIGNORE(xestrcpy(parent_path, XECOUNT(parent_path), path)); - parent_path[file_name - path] = 0; - - // Register the local directory in the virtual filesystem. - result_code = file_system_->RegisterHostPathDevice( - "\\Device\\Harddisk1\\Partition0", parent_path); - if (result_code) { - XELOGE("Unable to mount local directory"); - return result_code; - } - - // Create symlinks to the device. - file_system_->CreateSymbolicLink( - "game:", "\\Device\\Harddisk1\\Partition0"); - file_system_->CreateSymbolicLink( - "d:", "\\Device\\Harddisk1\\Partition0"); - - // Get the file name of the module to load from the filesystem. - char fs_path[poly::max_path]; - XEIGNORE(xestrcpya(fs_path, XECOUNT(fs_path), "game:\\")); - char* fs_path_ptr = fs_path + xestrlena(fs_path); - *fs_path_ptr = 0; -#if XE_WCHAR - XEIGNORE(xestrnarrow(fs_path_ptr, XECOUNT(fs_path), file_name)); -#else - XEIGNORE(xestrcpya(fs_path_ptr, XECOUNT(fs_path), file_name)); -#endif - // Launch the game. - return xboxkrnl_->LaunchModule(fs_path); + std::string fs_path = "game:\\" + poly::to_string(file_name); + return CompleteLaunch(path, fs_path); } -X_STATUS Emulator::LaunchDiscImage(const xechar_t* path) { - int result_code = 0; +X_STATUS Emulator::LaunchDiscImage(const std::wstring& path) { + int result_code = + file_system_->InitializeFromPath(FileSystemType::DISC_IMAGE, path); + if (result_code) { + return X_STATUS_INVALID_PARAMETER; + } + // Launch the game. + return CompleteLaunch(path, "game:\\default.xex"); +} + +X_STATUS Emulator::LaunchSTFSTitle(const std::wstring& path) { + int result_code = + file_system_->InitializeFromPath(FileSystemType::STFS_TITLE, path); + if (result_code) { + return X_STATUS_INVALID_PARAMETER; + } + + // Launch the game. + return CompleteLaunch(path, "game:\\default.xex"); +} + +X_STATUS Emulator::CompleteLaunch(const std::wstring& path, + const std::string& module_path) { auto ev = xdb::protocol::ProcessStartEvent::Append(memory()->trace_base()); if (ev) { ev->type = xdb::protocol::EventType::PROCESS_START; + ev->membase = reinterpret_cast(memory()->membase()); + auto path_length = poly::to_string(path) + .copy(ev->launch_path, sizeof(ev->launch_path) - 1); + ev->launch_path[path_length] = 0; } - // Register the disc image in the virtual filesystem. - result_code = file_system_->RegisterDiscImageDevice( - "\\Device\\Cdrom0", path); - if (result_code) { - XELOGE("Unable to mount disc image"); - return result_code; - } - - // Create symlinks to the device. - file_system_->CreateSymbolicLink( - "game:", - "\\Device\\Cdrom0"); - file_system_->CreateSymbolicLink( - "d:", - "\\Device\\Cdrom0"); - - // Launch the game. - return xboxkrnl_->LaunchModule("game:\\default.xex"); -} - -X_STATUS Emulator::LaunchSTFSTitle(const xechar_t* path) { - int result_code = 0; - - auto ev = xdb::protocol::ProcessStartEvent::Append(memory()->trace_base()); - if (ev) { - ev->type = xdb::protocol::EventType::PROCESS_START; - } - - // TODO(benvanik): figure out paths. - - // Register the disc image in the virtual filesystem. - result_code = file_system_->RegisterSTFSContainerDevice( - "\\Device\\Cdrom0", path); - if (result_code) { - XELOGE("Unable to mount STFS container"); - return result_code; - } - - // Create symlinks to the device. - file_system_->CreateSymbolicLink( - "game:", - "\\Device\\Cdrom0"); - file_system_->CreateSymbolicLink( - "d:", - "\\Device\\Cdrom0"); - - // Launch the game. - return xboxkrnl_->LaunchModule("game:\\default.xex"); + return xboxkrnl_->LaunchModule(module_path.c_str()); } diff --git a/src/xenia/emulator.h b/src/xenia/emulator.h index f3120c8d5..23d24bf37 100644 --- a/src/xenia/emulator.h +++ b/src/xenia/emulator.h @@ -10,6 +10,8 @@ #ifndef XENIA_EMULATOR_H_ #define XENIA_EMULATOR_H_ +#include + #include #include #include @@ -32,7 +34,7 @@ XEDECLARECLASS2(xe, ui, Window); namespace xe { class Emulator { -public: + public: Emulator(const xechar_t* command_line); ~Emulator(); @@ -59,11 +61,14 @@ public: X_STATUS Setup(); // TODO(benvanik): raw binary. - X_STATUS LaunchXexFile(const xechar_t* path); - X_STATUS LaunchDiscImage(const xechar_t* path); - X_STATUS LaunchSTFSTitle(const xechar_t* path); + X_STATUS LaunchXexFile(const std::wstring& path); + X_STATUS LaunchDiscImage(const std::wstring& path); + X_STATUS LaunchSTFSTitle(const std::wstring& path); + + private: + X_STATUS CompleteLaunch(const std::wstring& path, + const std::string& module_path); -private: xechar_t command_line_[poly::max_path]; ui::Window* main_window_; diff --git a/src/xenia/kernel/fs/device.cc b/src/xenia/kernel/fs/device.cc index d49c56362..c9c37664a 100644 --- a/src/xenia/kernel/fs/device.cc +++ b/src/xenia/kernel/fs/device.cc @@ -9,20 +9,12 @@ #include - using namespace xe; using namespace xe::kernel; using namespace xe::kernel::fs; +Device::Device(const std::string& path) : path_(path) {} -Device::Device(const char* path) { - path_ = xestrdupa(path); -} +Device::~Device() {} -Device::~Device() { - xe_free(path_); -} - -const char* Device::path() { - return path_; -} +const char* Device::path() const { return path_.c_str(); } diff --git a/src/xenia/kernel/fs/device.h b/src/xenia/kernel/fs/device.h index 1c76b63f7..01215e47a 100644 --- a/src/xenia/kernel/fs/device.h +++ b/src/xenia/kernel/fs/device.h @@ -10,37 +10,36 @@ #ifndef XENIA_KERNEL_FS_DEVICE_H_ #define XENIA_KERNEL_FS_DEVICE_H_ +#include + #include #include #include - namespace xe { namespace kernel { namespace fs { - class Device { -public: - Device(const char* path); + public: + Device(const std::string& path); virtual ~Device(); - const char* path(); + const char* path() const; virtual Entry* ResolvePath(const char* path) = 0; virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) = 0; - virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length) = 0; + virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, + size_t length) = 0; -protected: - char* path_; + protected: + std::string path_; }; - } // namespace fs } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_FS_DEVICE_H_ diff --git a/src/xenia/kernel/fs/devices/disc_image_device.cc b/src/xenia/kernel/fs/devices/disc_image_device.cc index b64172919..da8b8912a 100644 --- a/src/xenia/kernel/fs/devices/disc_image_device.cc +++ b/src/xenia/kernel/fs/devices/disc_image_device.cc @@ -17,23 +17,17 @@ using namespace xe; using namespace xe::kernel; using namespace xe::kernel::fs; - - -DiscImageDevice::DiscImageDevice(const char* path, const xechar_t* local_path) : - Device(path) { - local_path_ = xestrdup(local_path); - mmap_ = NULL; - gdfx_ = NULL; -} +DiscImageDevice::DiscImageDevice(const std::string& path, + const std::wstring& local_path) + : Device(path), local_path_(local_path), mmap_(nullptr), gdfx_(nullptr) {} DiscImageDevice::~DiscImageDevice() { delete gdfx_; xe_mmap_release(mmap_); - xe_free(local_path_); } int DiscImageDevice::Init() { - mmap_ = xe_mmap_open(kXEFileModeRead, local_path_, 0, 0); + mmap_ = xe_mmap_open(kXEFileModeRead, local_path_.c_str(), 0, 0); if (!mmap_) { XELOGE("Disc image could not be mapped"); return 1; diff --git a/src/xenia/kernel/fs/devices/disc_image_device.h b/src/xenia/kernel/fs/devices/disc_image_device.h index 05a65aabd..c625357b3 100644 --- a/src/xenia/kernel/fs/devices/disc_image_device.h +++ b/src/xenia/kernel/fs/devices/disc_image_device.h @@ -10,42 +10,40 @@ #ifndef XENIA_KERNEL_FS_DEVICES_DISC_IMAGE_DEVICE_H_ #define XENIA_KERNEL_FS_DEVICES_DISC_IMAGE_DEVICE_H_ +#include + #include #include #include - namespace xe { namespace kernel { namespace fs { - class GDFX; - class DiscImageDevice : public Device { -public: - DiscImageDevice(const char* path, const xechar_t* local_path); - virtual ~DiscImageDevice(); + public: + DiscImageDevice(const std::string& path, const std::wstring& local_path); + ~DiscImageDevice() override; int Init(); - virtual Entry* ResolvePath(const char* path); + Entry* ResolvePath(const char* path) override; - virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length); - virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length); + X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) override; + X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, + size_t length) override; -private: - xechar_t* local_path_; + private: + std::wstring local_path_; xe_mmap_ref mmap_; - GDFX* gdfx_; + GDFX* gdfx_; }; - } // namespace fs } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_FS_DEVICES_DISC_IMAGE_DEVICE_H_ diff --git a/src/xenia/kernel/fs/devices/host_path_device.cc b/src/xenia/kernel/fs/devices/host_path_device.cc index 9eed206f0..c134071ba 100644 --- a/src/xenia/kernel/fs/devices/host_path_device.cc +++ b/src/xenia/kernel/fs/devices/host_path_device.cc @@ -17,15 +17,11 @@ using namespace xe; using namespace xe::kernel; using namespace xe::kernel::fs; +HostPathDevice::HostPathDevice(const std::string& path, + const std::wstring& local_path) + : Device(path), local_path_(local_path) {} -HostPathDevice::HostPathDevice(const char* path, const xechar_t* local_path) : - Device(path) { - local_path_ = xestrdup(local_path); -} - -HostPathDevice::~HostPathDevice() { - xe_free(local_path_); -} +HostPathDevice::~HostPathDevice() {} Entry* HostPathDevice::ResolvePath(const char* path) { // The filesystem will have stripped our prefix off already, so the path will @@ -42,7 +38,7 @@ Entry* HostPathDevice::ResolvePath(const char* path) { #endif xechar_t full_path[poly::max_path]; - xe_path_join(local_path_, rel_path, full_path, XECOUNT(full_path)); + xe_path_join(local_path_.c_str(), rel_path, full_path, XECOUNT(full_path)); // Swap around path separators. if (poly::path_separator != '\\') { diff --git a/src/xenia/kernel/fs/devices/host_path_device.h b/src/xenia/kernel/fs/devices/host_path_device.h index f249911d2..95b265ab7 100644 --- a/src/xenia/kernel/fs/devices/host_path_device.h +++ b/src/xenia/kernel/fs/devices/host_path_device.h @@ -10,35 +10,34 @@ #ifndef XENIA_KERNEL_FS_DEVICES_HOST_PATH_DEVICE_H_ #define XENIA_KERNEL_FS_DEVICES_HOST_PATH_DEVICE_H_ +#include + #include #include #include - namespace xe { namespace kernel { namespace fs { - class HostPathDevice : public Device { -public: - HostPathDevice(const char* path, const xechar_t* local_path); - virtual ~HostPathDevice(); + public: + HostPathDevice(const std::string& path, const std::wstring& local_path); + ~HostPathDevice() override; - virtual Entry* ResolvePath(const char* path); + Entry* ResolvePath(const char* path) override; - virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length); - virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length); + X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) override; + X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, + size_t length) override; -private: - xechar_t* local_path_; + private: + std::wstring local_path_; }; - } // namespace fs } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_FS_DEVICES_HOST_PATH_DEVICE_H_ diff --git a/src/xenia/kernel/fs/devices/stfs_container_device.cc b/src/xenia/kernel/fs/devices/stfs_container_device.cc index 4d0d97127..da37bc4bf 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_device.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_device.cc @@ -17,24 +17,17 @@ using namespace xe; using namespace xe::kernel; using namespace xe::kernel::fs; - - -STFSContainerDevice::STFSContainerDevice( - const char* path, const xechar_t* local_path) : - Device(path) { - local_path_ = xestrdup(local_path); - mmap_ = NULL; - stfs_ = NULL; -} +STFSContainerDevice::STFSContainerDevice(const std::string& path, + const std::wstring& local_path) + : Device(path), local_path_(local_path), mmap_(nullptr), stfs_(nullptr) {} STFSContainerDevice::~STFSContainerDevice() { delete stfs_; xe_mmap_release(mmap_); - xe_free(local_path_); } int STFSContainerDevice::Init() { - mmap_ = xe_mmap_open(kXEFileModeRead, local_path_, 0, 0); + mmap_ = xe_mmap_open(kXEFileModeRead, local_path_.c_str(), 0, 0); if (!mmap_) { XELOGE("STFS container could not be mapped"); return 1; diff --git a/src/xenia/kernel/fs/devices/stfs_container_device.h b/src/xenia/kernel/fs/devices/stfs_container_device.h index 09e37fb36..e0a368d79 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_device.h +++ b/src/xenia/kernel/fs/devices/stfs_container_device.h @@ -10,42 +10,40 @@ #ifndef XENIA_KERNEL_FS_DEVICES_STFS_CONTAINER_DEVICE_H_ #define XENIA_KERNEL_FS_DEVICES_STFS_CONTAINER_DEVICE_H_ +#include + #include #include #include - namespace xe { namespace kernel { namespace fs { - class STFS; - class STFSContainerDevice : public Device { -public: - STFSContainerDevice(const char* path, const xechar_t* local_path); - virtual ~STFSContainerDevice(); + public: + STFSContainerDevice(const std::string& path, const std::wstring& local_path); + ~STFSContainerDevice() override; int Init(); - virtual Entry* ResolvePath(const char* path); + Entry* ResolvePath(const char* path) override; - virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length); - virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length); + X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) override; + X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, + size_t length) override; -private: - xechar_t* local_path_; + private: + std::wstring local_path_; xe_mmap_ref mmap_; - STFS* stfs_; + STFS* stfs_; }; - } // namespace fs } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_FS_DEVICES_STFS_CONTAINER_DEVICE_H_ diff --git a/src/xenia/kernel/fs/filesystem.cc b/src/xenia/kernel/fs/filesystem.cc index 2b53acd0e..538959329 100644 --- a/src/xenia/kernel/fs/filesystem.cc +++ b/src/xenia/kernel/fs/filesystem.cc @@ -33,19 +33,86 @@ FileSystem::~FileSystem() { symlinks_.clear(); } -int FileSystem::RegisterDevice(const char* path, Device* device) { +fs::FileSystemType FileSystem::InferType(const std::wstring& local_path) { + auto last_dot = local_path.find_last_of('.'); + if (last_dot == std::wstring::npos) { + // Likely an STFS container. + return FileSystemType::STFS_TITLE; + } else if (local_path.substr(last_dot) == L".xex") { + // Treat as a naked xex file. + return FileSystemType::XEX_FILE; + } else { + // Assume a disc image. + return FileSystemType::DISC_IMAGE; + } +} + +int FileSystem::InitializeFromPath(fs::FileSystemType type, + const std::wstring& local_path) { + switch (type) { + case FileSystemType::STFS_TITLE: { + // Register the container in the virtual filesystem. + int result_code = + RegisterSTFSContainerDevice("\\Device\\Cdrom0", local_path); + if (result_code) { + XELOGE("Unable to mount STFS container"); + return result_code; + } + + // TODO(benvanik): figure out paths. + // Create symlinks to the device. + CreateSymbolicLink("game:", "\\Device\\Cdrom0"); + CreateSymbolicLink("d:", "\\Device\\Cdrom0"); + break; + } + case FileSystemType::XEX_FILE: { + // Get the parent path of the file. + auto last_slash = local_path.find_last_of(poly::path_separator); + std::wstring parent_path = local_path.substr(0, last_slash); + + // Register the local directory in the virtual filesystem. + int result_code = RegisterHostPathDevice( + "\\Device\\Harddisk1\\Partition0", parent_path); + if (result_code) { + XELOGE("Unable to mount local directory"); + return result_code; + } + + // Create symlinks to the device. + CreateSymbolicLink("game:", "\\Device\\Harddisk1\\Partition0"); + CreateSymbolicLink("d:", "\\Device\\Harddisk1\\Partition0"); + break; + } + case FileSystemType::DISC_IMAGE: { + // Register the disc image in the virtual filesystem. + int result_code = RegisterDiscImageDevice("\\Device\\Cdrom0", local_path); + if (result_code) { + XELOGE("Unable to mount disc image"); + return result_code; + } + + // Create symlinks to the device. + CreateSymbolicLink("game:", "\\Device\\Cdrom0"); + CreateSymbolicLink("d:", "\\Device\\Cdrom0"); + break; + } + } + return 0; +} + +int FileSystem::RegisterDevice(const std::string& path, Device* device) { devices_.push_back(device); return 0; } int FileSystem::RegisterHostPathDevice( - const char* path, const xechar_t* local_path) { + const std::string& path, const std::wstring& local_path) { Device* device = new HostPathDevice(path, local_path); return RegisterDevice(path, device); } int FileSystem::RegisterDiscImageDevice( - const char* path, const xechar_t* local_path) { + const std::string& path, const std::wstring& local_path) { DiscImageDevice* device = new DiscImageDevice(path, local_path); if (device->Init()) { return 1; @@ -54,7 +121,7 @@ int FileSystem::RegisterDiscImageDevice( } int FileSystem::RegisterSTFSContainerDevice( - const char* path, const xechar_t* local_path) { + const std::string& path, const std::wstring& local_path) { STFSContainerDevice* device = new STFSContainerDevice(path, local_path); if (device->Init()) { return 1; diff --git a/src/xenia/kernel/fs/filesystem.h b/src/xenia/kernel/fs/filesystem.h index b252d5e61..76d6ab549 100644 --- a/src/xenia/kernel/fs/filesystem.h +++ b/src/xenia/kernel/fs/filesystem.h @@ -10,6 +10,7 @@ #ifndef XENIA_KERNEL_FS_FILESYSTEM_H_ #define XENIA_KERNEL_FS_FILESYSTEM_H_ +#include #include #include @@ -18,39 +19,46 @@ #include - namespace xe { namespace kernel { namespace fs { - class Device; +enum class FileSystemType { + STFS_TITLE, + DISC_IMAGE, + XEX_FILE, +}; class FileSystem { -public: + public: FileSystem(); ~FileSystem(); - int RegisterDevice(const char* path, Device* device); - int RegisterHostPathDevice(const char* path, const xechar_t* local_path); - int RegisterDiscImageDevice(const char* path, const xechar_t* local_path); - int RegisterSTFSContainerDevice(const char* path, const xechar_t* local_path); + FileSystemType InferType(const std::wstring& local_path); + int InitializeFromPath(FileSystemType type, const std::wstring& local_path); + + int RegisterDevice(const std::string& path, Device* device); + int RegisterHostPathDevice(const std::string& path, + const std::wstring& local_path); + int RegisterDiscImageDevice(const std::string& path, + const std::wstring& local_path); + int RegisterSTFSContainerDevice(const std::string& path, + const std::wstring& local_path); int CreateSymbolicLink(const char* path, const char* target); int DeleteSymbolicLink(const char* path); Entry* ResolvePath(const char* path); -private: - std::vector devices_; + private: + std::vector devices_; std::unordered_map symlinks_; }; - } // namespace fs } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_FS_FILESYSTEM_H_ diff --git a/src/xenia/kernel/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl_rtl.cc index 3173229ca..6214e6f97 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl_rtl.cc @@ -9,9 +9,7 @@ #include -#include -#include - +#include #include #include #include @@ -329,8 +327,7 @@ X_STATUS xeRtlUnicodeStringToAnsiString(uint32_t destination_ptr, std::wstring unicode_str = poly::load_and_swap( IMPL_MEM_ADDR(IMPL_MEM_32(source_ptr + 4))); - std::wstring_convert> converter; - std::string ansi_str = converter.to_bytes(unicode_str); + std::string ansi_str = poly::to_string(unicode_str); if (ansi_str.size() > 0xFFFF - 1) { return X_STATUS_INVALID_PARAMETER_2; } diff --git a/tools/xenia-debug/xenia-debug.cc b/tools/xenia-debug/xenia-debug.cc index 2adeaf618..05f0bf846 100644 --- a/tools/xenia-debug/xenia-debug.cc +++ b/tools/xenia-debug/xenia-debug.cc @@ -51,7 +51,10 @@ int main(int argc, xechar_t** argv) { if (!FLAGS_trace_file.empty()) { // Trace file specified on command line. - app->OpenTraceFile(FLAGS_trace_file, FLAGS_content_file); + if (!app->OpenTraceFile(FLAGS_trace_file, FLAGS_content_file)) { + XEFATAL("Failed to open trace file"); + return 1; + } } else { app->OpenEmpty(); } diff --git a/tools/xenia-run/xenia-run.cc b/tools/xenia-run/xenia-run.cc index f684d14eb..fed8c3ae7 100644 --- a/tools/xenia-run/xenia-run.cc +++ b/tools/xenia-run/xenia-run.cc @@ -55,10 +55,6 @@ int xenia_run(int argc, xechar_t** argv) { xechar_t abs_path[poly::max_path]; xe_path_get_absolute(path, abs_path, XECOUNT(abs_path)); - // Grab file extension. - // May be NULL if an STFS file. - const xechar_t* dot = xestrrchr(abs_path, '.'); - // Create the emulator. emulator = new Emulator(L""); XEEXPECTNOTNULL(emulator); @@ -70,16 +66,17 @@ int xenia_run(int argc, xechar_t** argv) { // Launch based on file type. // This is a silly guess based on file extension. - // NOTE: the runtime launch routine will wait until the module exits. - if (!dot) { - // Likely an STFS container. - result = emulator->LaunchSTFSTitle(abs_path); - } else if (xestrcmp(dot, L".xex") == 0) { - // Treat as a naked xex file. - result = emulator->LaunchXexFile(abs_path); - } else { - // Assume a disc image. - result = emulator->LaunchDiscImage(abs_path); + auto file_system_type = emulator->file_system()->InferType(abs_path); + switch (file_system_type) { + case kernel::fs::FileSystemType::STFS_TITLE: + result = emulator->LaunchSTFSTitle(abs_path); + break; + case kernel::fs::FileSystemType::XEX_FILE: + result = emulator->LaunchXexFile(abs_path); + break; + case kernel::fs::FileSystemType::DISC_IMAGE: + result = emulator->LaunchDiscImage(abs_path); + break; } if (XFAILED(result)) { XELOGE("Failed to launch target: %.8X", result); From 1a39f5bd065e8379c9dd4b33bc3899ddd9332ca9 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 15 Aug 2014 13:53:02 -0700 Subject: [PATCH 103/388] Experimenting with xdb API, starting on compare tool. --- src/alloy/backend/ivm/ivm_intcode.cc | 3 +- src/alloy/delegate.h | 40 ++++-- src/xdb/cursor.cc | 16 +++ src/xdb/cursor.h | 57 ++++++++ src/xdb/debug_target.cc | 12 ++ src/xdb/debug_target.h | 17 +++ src/xdb/module.cc | 16 +++ src/xdb/module.h | 25 ++++ src/xdb/postmortem_cursor.cc | 181 +++++++++++++++++++++++++ src/xdb/postmortem_cursor.h | 46 +++++++ src/xdb/postmortem_debug_target.cc | 44 ++---- src/xdb/postmortem_debug_target.h | 6 + src/xdb/protocol.h | 30 +++- src/xdb/sources.gypi | 8 ++ src/xdb/thread.cc | 16 +++ src/xdb/thread.h | 26 ++++ src/xdb/ui/main_frame.cc | 27 +++- src/xdb/ui/main_frame.h | 5 +- src/xdb/ui/xdb-ui.fbp | 24 ++-- src/xdb/ui/xdb_ui.cpp | 6 + src/xdb/ui/xdb_ui.h | 4 + tools/tools.gypi | 1 + tools/xenia-compare/xenia-compare.cc | 51 +++++++ tools/xenia-compare/xenia-compare.gypi | 28 ++++ 24 files changed, 627 insertions(+), 62 deletions(-) create mode 100644 src/xdb/cursor.cc create mode 100644 src/xdb/cursor.h create mode 100644 src/xdb/module.cc create mode 100644 src/xdb/module.h create mode 100644 src/xdb/postmortem_cursor.cc create mode 100644 src/xdb/postmortem_cursor.h create mode 100644 src/xdb/thread.cc create mode 100644 src/xdb/thread.h create mode 100644 tools/xenia-compare/xenia-compare.cc create mode 100644 tools/xenia-compare/xenia-compare.gypi diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index b9122604d..6d38409ac 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -249,7 +249,6 @@ int Translate_SOURCE_OFFSET(TranslationContext& ctx, Instr* i) { // TODO(benvanik): dispatch of register forms. uint32_t IntCode_TRACE_SOURCE(IntCodeState& ics, const IntCode* i) { - // TODO(benvanik): append to active trace writer. uint64_t trace_base = ics.thread_state->memory()->trace_base(); if (trace_base) { auto ev = xdb::protocol::InstrEvent::Append(trace_base); @@ -323,7 +322,7 @@ uint32_t IntCode_TRAP(IntCodeState& ics, const IntCode* i) { switch (i->flags) { case 20: // 0x0FE00014 is a 'debug print' where r3 = buffer r4 = length - break; + return IA_NEXT; case 22: // Always trap? break; diff --git a/src/alloy/delegate.h b/src/alloy/delegate.h index 53d4eae72..1c6ca5f42 100644 --- a/src/alloy/delegate.h +++ b/src/alloy/delegate.h @@ -20,6 +20,9 @@ namespace alloy { // TODO(benvanik): go lockfree, and don't hold the lock while emitting. +template +class Delegate; + template class Delegate { public: @@ -30,16 +33,6 @@ class Delegate { listeners_.push_back(listener); } - void RemoveListener(Listener const& listener) { - std::lock_guard guard(lock_); - for (auto it = listeners_.begin(); it != listeners_.end(); ++it) { - if (it == listener) { - listeners_.erase(it); - break; - } - } - } - void RemoveAllListeners() { std::lock_guard guard(lock_); listeners_.clear(); @@ -57,6 +50,33 @@ class Delegate { std::vector listeners_; }; +template <> +class Delegate { + public: + typedef std::function Listener; + + void AddListener(Listener const& listener) { + std::lock_guard guard(lock_); + listeners_.push_back(listener); + } + + void RemoveAllListeners() { + std::lock_guard guard(lock_); + listeners_.clear(); + } + + void operator()() { + std::lock_guard guard(lock_); + for (auto& listener : listeners_) { + listener(); + } + } + + private: + std::mutex lock_; + std::vector listeners_; +}; + } // namespace alloy #endif // ALLOY_DELEGATE_H_ diff --git a/src/xdb/cursor.cc b/src/xdb/cursor.cc new file mode 100644 index 000000000..13d9a2174 --- /dev/null +++ b/src/xdb/cursor.cc @@ -0,0 +1,16 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +namespace xdb { + +// + +} // namespace xdb diff --git a/src/xdb/cursor.h b/src/xdb/cursor.h new file mode 100644 index 000000000..8c9fa2481 --- /dev/null +++ b/src/xdb/cursor.h @@ -0,0 +1,57 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XDB_CURSOR_H_ +#define XDB_CURSOR_H_ + +#include + +#include +#include +#include +#include + +namespace xdb { + +class Cursor { + public: + virtual ~Cursor() = default; + + virtual bool can_step() const = 0; + + // TODO(benvanik): breakpoints/events + + alloy::Delegate end_of_stream; + + std::vector modules(); + std::vector threads(); + + alloy::Delegate module_loaded; + alloy::Delegate module_unloaded; + alloy::Delegate thread_created; + alloy::Delegate thread_exited; + + // TODO(benvanik): memory access + + virtual void Continue(Thread* thread = nullptr) = 0; + virtual void ContinueTo(uint32_t address, Thread* thread = nullptr) = 0; + virtual void ContinueToNextCall(Thread* thread = nullptr) = 0; + virtual void ContinueToReturn(Thread* thread = nullptr) = 0; + virtual void ContinueUntil( + const std::function predicate, + Thread* thread = nullptr) = 0; + virtual void Break() = 0; + + protected: + Cursor() = default; +}; + +} // namespace xdb + +#endif // XDB_CURSOR_H_ diff --git a/src/xdb/debug_target.cc b/src/xdb/debug_target.cc index 65b1ea810..7baa9b5b1 100644 --- a/src/xdb/debug_target.cc +++ b/src/xdb/debug_target.cc @@ -27,4 +27,16 @@ bool DebugTarget::InitializeFileSystem(const std::wstring& path) { return true; } +Module* DebugTarget::GetModule(uint16_t module_id) { + std::lock_guard lock(object_lock_); + auto it = module_map_.find(module_id); + return it != module_map_.end() ? it->second : nullptr; +} + +Thread* DebugTarget::GetThread(uint16_t thread_id) { + std::lock_guard lock(object_lock_); + auto it = thread_map_.find(thread_id); + return it != thread_map_.end() ? it->second : nullptr; +} + } // namespace xdb diff --git a/src/xdb/debug_target.h b/src/xdb/debug_target.h index 7724daefd..41ec61d69 100644 --- a/src/xdb/debug_target.h +++ b/src/xdb/debug_target.h @@ -10,6 +10,12 @@ #ifndef XDB_DEBUG_TARGET_H_ #define XDB_DEBUG_TARGET_H_ +#include +#include +#include +#include + +#include #include namespace xdb { @@ -20,12 +26,23 @@ class DebugTarget { xe::kernel::fs::FileSystem* file_system() const { return file_system_.get(); } + virtual std::unique_ptr CreateCursor() = 0; + + Module* GetModule(uint16_t module_id); + Thread* GetThread(uint16_t thread_id); + protected: DebugTarget() = default; bool InitializeFileSystem(const std::wstring& path); std::unique_ptr file_system_; + + std::mutex object_lock_; + std::vector> modules_; + std::vector> threads_; + std::unordered_map module_map_; + std::unordered_map thread_map_; }; } // namespace xdb diff --git a/src/xdb/module.cc b/src/xdb/module.cc new file mode 100644 index 000000000..897ebb39a --- /dev/null +++ b/src/xdb/module.cc @@ -0,0 +1,16 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +namespace xdb { + +// + +} // namespace xdb diff --git a/src/xdb/module.h b/src/xdb/module.h new file mode 100644 index 000000000..8be42b0be --- /dev/null +++ b/src/xdb/module.h @@ -0,0 +1,25 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XDB_MODULE_H_ +#define XDB_MODULE_H_ + +#include + +namespace xdb { + +class Module { + public: + uint16_t module_id; + // info +}; + +} // namespace xdb + +#endif // XDB_MODULE_H_ diff --git a/src/xdb/postmortem_cursor.cc b/src/xdb/postmortem_cursor.cc new file mode 100644 index 000000000..c1e6e3e00 --- /dev/null +++ b/src/xdb/postmortem_cursor.cc @@ -0,0 +1,181 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +namespace xdb { + +using xdb::protocol::EventType; + +struct Command { + enum class Type { + EXIT, + CONTINUE, + }; + Type type; + + protected: + Command(Type type) : type(type) {} +}; + +struct ExitCommand : public Command { + ExitCommand() : Command(Type::EXIT) {} +}; + +struct ContinueCommand : public Command { + ContinueCommand() : Command(Type::CONTINUE), thread(nullptr) {} + Thread* thread; +}; + +class PostmortemCursor::Executor { + public: + Executor(PostmortemCursor* cursor) : cursor_(cursor), running_(true) { + trace_ptr_ = cursor->target_->trace_base(); + + // Must be last, as it'll spin up here. + thread_ = std::thread(std::bind(&Executor::ExecutionThread, this)); + } + ~Executor() { + running_ = false; + IssueCommand(std::make_unique()); + thread_.join(); + } + + bool eof() const { return eof_; } + + void IssueCommand(std::unique_ptr command) { + { + std::unique_lock lock(queue_lock_); + queue_.push(std::move(command)); + pending_commands_ = true; + } + queue_cond_.notify_one(); + } + + private: + void ExecutionThread() { + while (running_) { + auto command = AwaitCommand(); + if (!running_ || !command || command->type == Command::Type::EXIT) { + break; + } + + switch (command->type) { + case Command::Type::CONTINUE: { + auto cmd = static_cast(command.get()); + cmd->thread; + break; + } + } + + // + Process(pending_commands_); + } + } + + void Process(std::atomic& exit_signal) { + if (eof_) { + return; + } + while (!exit_signal) { + auto event_type = poly::load(trace_ptr_); + switch (event_type) { + case EventType::END_OF_STREAM: { + eof_= true; + cursor_->end_of_stream(); + return; + } + case EventType::MODULE_LOAD: { + auto ev = protocol::ModuleLoadEvent::Get(trace_ptr_); + break; + } + case EventType::MODULE_UNLOAD: { + auto ev = protocol::ModuleLoadEvent::Get(trace_ptr_); + break; + } + case EventType::THREAD_CREATE: { + auto ev = protocol::ThreadCreateEvent::Get(trace_ptr_); + break; + } + case EventType::THREAD_INFO: { + auto ev = protocol::ThreadInfoEvent::Get(trace_ptr_); + break; + } + case EventType::THREAD_EXIT: { + auto ev = protocol::ThreadExitEvent::Get(trace_ptr_); + break; + } + } + trace_ptr_ += protocol::kEventSizes[static_cast(event_type)]; + } + } + + std::unique_ptr AwaitCommand() { + std::unique_lock lock(queue_lock_); + while (queue_.empty()) { + queue_cond_.wait(lock); + } + auto command = std::move(queue_.front()); + queue_.pop(); + pending_commands_ = !queue_.empty(); + return command; + } + + PostmortemCursor* cursor_; + std::atomic running_; + const uint8_t* trace_ptr_; + std::atomic eof_; + std::thread thread_; + + std::queue> queue_; + std::mutex queue_lock_; + std::condition_variable queue_cond_; + std::atomic pending_commands_; +}; + +PostmortemCursor::PostmortemCursor(PostmortemDebugTarget* target) + : target_(target) { + executor_.reset(new Executor(this)); +} + +PostmortemCursor::~PostmortemCursor() { executor_.reset(); } + +bool PostmortemCursor::can_step() const { + // TODO(benvanik): check trace flags. + return true; +} + +void PostmortemCursor::Continue(Thread* thread) { + auto cmd = std::make_unique(); + cmd->thread = thread; + executor_->IssueCommand(std::move(cmd)); +} + +void PostmortemCursor::ContinueTo(uint32_t address, Thread* thread) {} + +void PostmortemCursor::ContinueToNextCall(Thread* thread) {} + +void PostmortemCursor::ContinueToReturn(Thread* thread) {} + +void PostmortemCursor::ContinueUntil( + const std::function predicate, + Thread* thread) {} + +void PostmortemCursor::Break() {} + +} // namespace xdb diff --git a/src/xdb/postmortem_cursor.h b/src/xdb/postmortem_cursor.h new file mode 100644 index 000000000..e8d3595cc --- /dev/null +++ b/src/xdb/postmortem_cursor.h @@ -0,0 +1,46 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XDB_POSTMORTEM_CURSOR_H_ +#define XDB_POSTMORTEM_CURSOR_H_ + +#include + +#include + +namespace xdb { + +class PostmortemDebugTarget; + +class PostmortemCursor : public Cursor { + public: + PostmortemCursor(PostmortemDebugTarget* target); + ~PostmortemCursor() override; + + bool can_step() const override; + + void Continue(Thread* thread = nullptr) override; + void ContinueTo(uint32_t address, Thread* thread = nullptr) override; + void ContinueToNextCall(Thread* thread = nullptr) override; + void ContinueToReturn(Thread* thread = nullptr) override; + void ContinueUntil( + const std::function predicate, + Thread* thread = nullptr) override; + void Break() override; + + private: + class Executor; + + PostmortemDebugTarget* target_; + std::unique_ptr executor_; +}; + +} // namespace xdb + +#endif // XDB_POSTMORTEM_CURSOR_H_ diff --git a/src/xdb/postmortem_debug_target.cc b/src/xdb/postmortem_debug_target.cc index 6a3009385..ffad63348 100644 --- a/src/xdb/postmortem_debug_target.cc +++ b/src/xdb/postmortem_debug_target.cc @@ -10,37 +10,13 @@ #include #include +#include #include namespace xdb { using xdb::protocol::EventType; -// Matches the EventType ordering to allow for quick event size checks. -const size_t event_sizes[] = { - 0, - sizeof(protocol::ProcessStartEvent), - sizeof(protocol::ProcessExitEvent), - sizeof(protocol::ModuleLoadEvent), - sizeof(protocol::ModuleUnloadEvent), - sizeof(protocol::ThreadCreateEvent), - sizeof(protocol::ThreadInfoEvent), - sizeof(protocol::ThreadExitEvent), - sizeof(protocol::FunctionCompiledEvent), - sizeof(protocol::OutputStringEvent), - sizeof(protocol::KernelCallEvent), - sizeof(protocol::KernelCallReturnEvent), - sizeof(protocol::UserCallEvent), - sizeof(protocol::UserCallReturnEvent), - sizeof(protocol::InstrEvent), - sizeof(protocol::InstrEventR8), - sizeof(protocol::InstrEventR8R8), - sizeof(protocol::InstrEventR8R16), - sizeof(protocol::InstrEventR16), - sizeof(protocol::InstrEventR16R8), - sizeof(protocol::InstrEventR16R16), -}; - PostmortemDebugTarget::PostmortemDebugTarget() : file_(nullptr), file_mapping_(nullptr), @@ -66,8 +42,8 @@ bool PostmortemDebugTarget::LoadTrace(const std::wstring& path, return false; } - file_mapping_ = CreateFileMapping(file_, nullptr, PAGE_READONLY, 0, 0, - L"Local\\xenia_xdb_trace"); + file_mapping_ = + CreateFileMapping(file_, nullptr, PAGE_READONLY, 0, 0, nullptr); if (!file_mapping_) { XELOGE("Could not create trace file mapping"); return false; @@ -95,7 +71,7 @@ bool PostmortemDebugTarget::LoadTrace(const std::wstring& path, if (process_start_event_) { break; } - ptr += event_sizes[static_cast(event_type)]; + ptr += protocol::kEventSizes[static_cast(event_type)]; } bool initialized_filesystem = false; @@ -129,7 +105,8 @@ bool PostmortemDebugTarget::Prepare(std::atomic& cancelled) { EventType::END_OF_STREAM) { switch (event_type) { case EventType::PROCESS_START: { - process_start_event_ = protocol::ProcessStartEvent::Get(ptr); + assert_true(process_start_event_ == + protocol::ProcessStartEvent::Get(ptr)); break; } case EventType::PROCESS_EXIT: { @@ -209,10 +186,17 @@ bool PostmortemDebugTarget::Prepare(std::atomic& cancelled) { break; } } - ptr += event_sizes[static_cast(event_type)]; + ptr += protocol::kEventSizes[static_cast(event_type)]; }; + trace_length_ = ptr - trace_base_; + return true; } +std::unique_ptr PostmortemDebugTarget::CreateCursor() { + auto cursor = std::make_unique(this); + return std::unique_ptr(cursor.release()); +} + } // namespace xdb diff --git a/src/xdb/postmortem_debug_target.h b/src/xdb/postmortem_debug_target.h index 6f4575337..715b64456 100644 --- a/src/xdb/postmortem_debug_target.h +++ b/src/xdb/postmortem_debug_target.h @@ -25,16 +25,22 @@ class PostmortemDebugTarget : public DebugTarget { PostmortemDebugTarget(); ~PostmortemDebugTarget() override; + const uint8_t* trace_base() const { return trace_base_ + 8; } + size_t trace_length() const { return trace_length_; } + bool LoadTrace(const std::wstring& path, const std::wstring& content_path = L""); bool Prepare(); bool Prepare(std::atomic& cancelled); + std::unique_ptr CreateCursor() override; + private: HANDLE file_; HANDLE file_mapping_; const uint8_t* trace_base_; + size_t trace_length_; const protocol::ProcessStartEvent* process_start_event_; const protocol::ProcessExitEvent* process_exit_event_; diff --git a/src/xdb/protocol.h b/src/xdb/protocol.h index b1b4be039..85536ab9f 100644 --- a/src/xdb/protocol.h +++ b/src/xdb/protocol.h @@ -77,14 +77,9 @@ struct ProcessExitEvent : public Event { EventType type; }; -struct ModuleInfo { - uint32_t module_id; -}; - struct ModuleLoadEvent : public Event { EventType type; uint32_t module_id; - ModuleInfo module_info; }; struct ModuleUnloadEvent : public Event { @@ -227,6 +222,31 @@ struct InstrEventR16R16 : public Event { #pragma pack(pop) +// Matches the EventType ordering to allow for quick event size checks. +const size_t kEventSizes[] = { + 0, + sizeof(protocol::ProcessStartEvent), + sizeof(protocol::ProcessExitEvent), + sizeof(protocol::ModuleLoadEvent), + sizeof(protocol::ModuleUnloadEvent), + sizeof(protocol::ThreadCreateEvent), + sizeof(protocol::ThreadInfoEvent), + sizeof(protocol::ThreadExitEvent), + sizeof(protocol::FunctionCompiledEvent), + sizeof(protocol::OutputStringEvent), + sizeof(protocol::KernelCallEvent), + sizeof(protocol::KernelCallReturnEvent), + sizeof(protocol::UserCallEvent), + sizeof(protocol::UserCallReturnEvent), + sizeof(protocol::InstrEvent), + sizeof(protocol::InstrEventR8), + sizeof(protocol::InstrEventR8R8), + sizeof(protocol::InstrEventR8R16), + sizeof(protocol::InstrEventR16), + sizeof(protocol::InstrEventR16R8), + sizeof(protocol::InstrEventR16R16), +}; + } // namespace protocol } // namespace xdb diff --git a/src/xdb/sources.gypi b/src/xdb/sources.gypi index eec8b4a15..8f052078f 100644 --- a/src/xdb/sources.gypi +++ b/src/xdb/sources.gypi @@ -1,11 +1,19 @@ # Copyright 2014 Ben Vanik. All Rights Reserved. { 'sources': [ + 'cursor.cc', + 'cursor.h', 'debug_target.cc', 'debug_target.h', + 'module.cc', + 'module.h', + 'postmortem_cursor.cc', + 'postmortem_cursor.h', 'postmortem_debug_target.cc', 'postmortem_debug_target.h', 'protocol.h', + 'thread.cc', + 'thread.h', 'xdb.cc', 'xdb.h', ], diff --git a/src/xdb/thread.cc b/src/xdb/thread.cc new file mode 100644 index 000000000..163c979ce --- /dev/null +++ b/src/xdb/thread.cc @@ -0,0 +1,16 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +namespace xdb { + +// + +} // namespace xdb diff --git a/src/xdb/thread.h b/src/xdb/thread.h new file mode 100644 index 000000000..425b45c44 --- /dev/null +++ b/src/xdb/thread.h @@ -0,0 +1,26 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XDB_THREAD_H_ +#define XDB_THREAD_H_ + +#include + +namespace xdb { + +class Thread { + public: + uint16_t thread_id; + // name + // etc +}; + +} // namespace xdb + +#endif // XDB_THREAD_H_ diff --git a/src/xdb/ui/main_frame.cc b/src/xdb/ui/main_frame.cc index 1542435d6..08453647f 100644 --- a/src/xdb/ui/main_frame.cc +++ b/src/xdb/ui/main_frame.cc @@ -13,7 +13,32 @@ namespace xdb { namespace ui { MainFrame::MainFrame(std::unique_ptr debug_target) - : MainFrameBase(nullptr), debug_target_(std::move(debug_target)) {} + : MainFrameBase(nullptr), debug_target_(std::move(debug_target)) { + cursor_ = std::move(debug_target_->CreateCursor()); + cursor_->end_of_stream.AddListener([]() { + XELOGI("eos"); + }); + cursor_->module_loaded.AddListener([](Module* module) { + // + XELOGI("mod load"); + }); + cursor_->module_unloaded.AddListener([](Module* module) { + // + XELOGI("mod unload"); + }); + cursor_->thread_created.AddListener([](Thread* thread) { + // + XELOGI("thread create"); + }); + cursor_->thread_exited.AddListener([](Thread* thread) { + // + XELOGI("thread exit"); + }); + cursor_->Continue(); +} + +void MainFrame::OnIdle(wxIdleEvent& event) { +} } // namespace ui } // namespace xdb diff --git a/src/xdb/ui/main_frame.h b/src/xdb/ui/main_frame.h index 2c7228dcc..eae87642d 100644 --- a/src/xdb/ui/main_frame.h +++ b/src/xdb/ui/main_frame.h @@ -23,10 +23,11 @@ class MainFrame : public MainFrameBase { MainFrame(std::unique_ptr debug_target); protected: - // + void OnIdle(wxIdleEvent& event) override; private: - std::unique_ptr debug_target_; + std::unique_ptr debug_target_; + std::unique_ptr cursor_; }; } // namespace ui diff --git a/src/xdb/ui/xdb-ui.fbp b/src/xdb/ui/xdb-ui.fbp index 7166732f5..0c3a7aca3 100644 --- a/src/xdb/ui/xdb-ui.fbp +++ b/src/xdb/ui/xdb-ui.fbp @@ -67,7 +67,7 @@ - + OnIdle @@ -536,7 +536,7 @@ - + 0 @@ -598,16 +598,16 @@ - + root_panel_outer wxVERTICAL none - + 10 wxEXPAND | wxALL 1 - + 1 1 1 @@ -681,7 +681,7 @@ - + 1 wxVERTICAL 0 @@ -693,11 +693,11 @@ none 0 0 - + 5 wxALL 0 - + 1 1 1 @@ -776,11 +776,11 @@ - + 5 wxEXPAND 0 - + 2 wxBOTH 1 @@ -1138,11 +1138,11 @@ - + 0 wxEXPAND 1 - + 0 1 0 diff --git a/src/xdb/ui/xdb_ui.cpp b/src/xdb/ui/xdb_ui.cpp index 0ec24af81..28e247680 100644 --- a/src/xdb/ui/xdb_ui.cpp +++ b/src/xdb/ui/xdb_ui.cpp @@ -40,10 +40,16 @@ MainFrameBase::MainFrameBase( wxWindow* parent, wxWindowID id, const wxString& t m_mgr.Update(); this->Centre( wxBOTH ); + + // Connect Events + this->Connect( wxEVT_IDLE, wxIdleEventHandler( MainFrameBase::OnIdle ) ); } MainFrameBase::~MainFrameBase() { + // Disconnect Events + this->Disconnect( wxEVT_IDLE, wxIdleEventHandler( MainFrameBase::OnIdle ) ); + m_mgr.UnInit(); } diff --git a/src/xdb/ui/xdb_ui.h b/src/xdb/ui/xdb_ui.h index 31e418046..778cfeddc 100644 --- a/src/xdb/ui/xdb_ui.h +++ b/src/xdb/ui/xdb_ui.h @@ -53,6 +53,10 @@ namespace xdb wxAuiNotebook* notebook_; wxPanel* m_panel3; wxPanel* m_panel4; + + // Virtual event handlers, overide them in your derived class + virtual void OnIdle( wxIdleEvent& event ) { event.Skip(); } + public: diff --git a/tools/tools.gypi b/tools/tools.gypi index ab8e44c99..3e6a56ffd 100644 --- a/tools/tools.gypi +++ b/tools/tools.gypi @@ -2,6 +2,7 @@ { 'includes': [ 'alloy-sandbox/alloy-sandbox.gypi', + 'xenia-compare/xenia-compare.gypi', 'xenia-debug/xenia-debug.gypi', 'xenia-run/xenia-run.gypi', #'xenia-test/xenia-test.gypi', diff --git a/tools/xenia-compare/xenia-compare.cc b/tools/xenia-compare/xenia-compare.cc new file mode 100644 index 000000000..7fb6c9488 --- /dev/null +++ b/tools/xenia-compare/xenia-compare.cc @@ -0,0 +1,51 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include +#include +#include +#include + +DEFINE_string(trace_file_left, "", "Trace file to compare (original)."); +DEFINE_string(trace_file_right, "", "Trace file to compare (new)."); + +namespace xc { + +using xdb::PostmortemDebugTarget; + +int main(int argc, xechar_t** argv) { + // Create platform abstraction layer. + xe_pal_options_t pal_options; + xe_zero_struct(&pal_options, sizeof(pal_options)); + if (xe_pal_init(pal_options)) { + XEFATAL("Failed to initialize PAL"); + return 1; + } + + auto left_target = std::make_unique(); + if (!left_target->LoadTrace(poly::to_wstring(FLAGS_trace_file_left))) { + XEFATAL("Unable to load left trace file: %s", + FLAGS_trace_file_left.c_str()); + } + auto right_target = std::make_unique(); + if (!right_target->LoadTrace(poly::to_wstring(FLAGS_trace_file_right))) { + XEFATAL("Unable to load right trace file: %s", + FLAGS_trace_file_right.c_str()); + } + + return 0; +} + +} // namespace xc + +// TODO(benvanik): move main thunk into poly +// ehhh +XE_MAIN_WINDOW_THUNK(xc::main, L"xenia-compare", "xenia-compare"); diff --git a/tools/xenia-compare/xenia-compare.gypi b/tools/xenia-compare/xenia-compare.gypi new file mode 100644 index 000000000..2b43a2883 --- /dev/null +++ b/tools/xenia-compare/xenia-compare.gypi @@ -0,0 +1,28 @@ +# Copyright 2014 Ben Vanik. All Rights Reserved. +{ + 'targets': [ + { + 'target_name': 'xenia-compare', + 'type': 'executable', + + 'msvs_settings': { + 'VCLinkerTool': { + 'SubSystem': '2' + } + }, + + 'dependencies': [ + 'xdb', + 'xenia', + ], + + 'include_dirs': [ + '.', + ], + + 'sources': [ + 'xenia-compare.cc', + ], + }, + ], +} From 48fbefa75e89e3ffe9e217f7bf616053db546b66 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 15 Aug 2014 22:27:07 -0700 Subject: [PATCH 104/388] Fixing warnings/bug in NtQueryVirtualMemory. --- src/alloy/memory.h | 3 +- src/xenia/cpu/xenon_memory.cc | 5 ++-- src/xenia/cpu/xenon_memory.h | 3 +- src/xenia/kernel/xboxkrnl_memory.cc | 45 ++++++++++++++++++----------- 4 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/alloy/memory.h b/src/alloy/memory.h index 5fe4069a4..0b2faf25e 100644 --- a/src/alloy/memory.h +++ b/src/alloy/memory.h @@ -58,7 +58,8 @@ class Memory { uint32_t alignment = 0x20) = 0; virtual int HeapFree(uint64_t address, size_t size) = 0; - virtual size_t QueryInformation(uint64_t base_address, MEMORY_BASIC_INFORMATION mem_info) = 0; + virtual size_t QueryInformation(uint64_t base_address, + MEMORY_BASIC_INFORMATION* mem_info) = 0; virtual size_t QuerySize(uint64_t base_address) = 0; virtual int Protect(uint64_t address, size_t size, uint32_t access) = 0; diff --git a/src/xenia/cpu/xenon_memory.cc b/src/xenia/cpu/xenon_memory.cc index c04bb7083..f7f2fdbfa 100644 --- a/src/xenia/cpu/xenon_memory.cc +++ b/src/xenia/cpu/xenon_memory.cc @@ -415,10 +415,11 @@ int XenonMemory::HeapFree(uint64_t address, size_t size) { } } -size_t XenonMemory::QueryInformation(uint64_t base_address, MEMORY_BASIC_INFORMATION mem_info) { +size_t XenonMemory::QueryInformation(uint64_t base_address, + MEMORY_BASIC_INFORMATION* mem_info) { uint8_t* p = Translate(base_address); - return VirtualQuery(p, &mem_info, sizeof(mem_info)); + return VirtualQuery(p, mem_info, sizeof(MEMORY_BASIC_INFORMATION)); } size_t XenonMemory::QuerySize(uint64_t base_address) { diff --git a/src/xenia/cpu/xenon_memory.h b/src/xenia/cpu/xenon_memory.h index 4015dd08f..c71c6ccd9 100644 --- a/src/xenia/cpu/xenon_memory.h +++ b/src/xenia/cpu/xenon_memory.h @@ -54,7 +54,8 @@ public: uint32_t alignment = 0x20) override; int HeapFree(uint64_t address, size_t size) override; - size_t QueryInformation(uint64_t base_address, MEMORY_BASIC_INFORMATION mem_info) override; + size_t QueryInformation(uint64_t base_address, + MEMORY_BASIC_INFORMATION* mem_info) override; size_t QuerySize(uint64_t base_address) override; int Protect(uint64_t address, size_t size, uint32_t access) override; diff --git a/src/xenia/kernel/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl_memory.cc index 9a9b8b258..bcef1834c 100644 --- a/src/xenia/kernel/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl_memory.cc @@ -195,28 +195,39 @@ X_STATUS xeNtQueryVirtualMemory( assert_not_null(state); MEMORY_BASIC_INFORMATION mem_info; - size_t result = state->memory()->QueryInformation(base_address, mem_info); + size_t result = state->memory()->QueryInformation(base_address, &mem_info); if (!result) { return STATUS_INVALID_PARAMETER; } - memory_basic_information->base_address = (uint32_t) mem_info.BaseAddress; - memory_basic_information->allocation_base = (uint32_t) mem_info.AllocationBase; - memory_basic_information->allocation_protect = mem_info.AllocationProtect; - memory_basic_information->region_size = mem_info.RegionSize; - memory_basic_information->state = mem_info.State; - memory_basic_information->protect = mem_info.Protect; - memory_basic_information->type = mem_info.Type; + auto membase = state->memory()->membase(); + memory_basic_information->base_address = static_cast( + reinterpret_cast(mem_info.BaseAddress) - membase); + memory_basic_information->allocation_base = static_cast( + reinterpret_cast(mem_info.AllocationBase) - membase); + memory_basic_information->allocation_protect = mem_info.AllocationProtect; + memory_basic_information->region_size = + static_cast(mem_info.RegionSize); + memory_basic_information->state = mem_info.State; + memory_basic_information->protect = mem_info.Protect; + memory_basic_information->type = mem_info.Type; if (swap) { - memory_basic_information->base_address = poly::byte_swap(memory_basic_information->base_address); - memory_basic_information->allocation_base = poly::byte_swap(memory_basic_information->allocation_base); - memory_basic_information->allocation_protect = poly::byte_swap(memory_basic_information->allocation_protect); - memory_basic_information->region_size = poly::byte_swap(memory_basic_information->region_size); - memory_basic_information->state = poly::byte_swap(memory_basic_information->state); - memory_basic_information->protect = poly::byte_swap(memory_basic_information->protect); - memory_basic_information->type = poly::byte_swap(memory_basic_information->type); + memory_basic_information->base_address = + poly::byte_swap(memory_basic_information->base_address); + memory_basic_information->allocation_base = + poly::byte_swap(memory_basic_information->allocation_base); + memory_basic_information->allocation_protect = + poly::byte_swap(memory_basic_information->allocation_protect); + memory_basic_information->region_size = + poly::byte_swap(memory_basic_information->region_size); + memory_basic_information->state = + poly::byte_swap(memory_basic_information->state); + memory_basic_information->protect = + poly::byte_swap(memory_basic_information->protect); + memory_basic_information->type = + poly::byte_swap(memory_basic_information->type); } XELOGE("NtQueryVirtualMemory NOT IMPLEMENTED"); @@ -232,8 +243,8 @@ SHIM_CALL NtQueryVirtualMemory_shim( X_MEMORY_BASIC_INFORMATION *memory_basic_information = (X_MEMORY_BASIC_INFORMATION*)SHIM_MEM_ADDR(memory_basic_information_ptr); XELOGD( - "NtQueryVirtualMemory(%.8X, %.8X)", - base_address, memory_basic_information_ptr); + "NtQueryVirtualMemory(%.8X, %.8X)", + base_address, memory_basic_information_ptr); X_STATUS result = xeNtQueryVirtualMemory(base_address, memory_basic_information, true); SHIM_SET_RETURN_32(result); From 56ce363ac5841f77f051055c2465cbb9218738a2 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 15 Aug 2014 22:31:44 -0700 Subject: [PATCH 105/388] Removing export impl. --- src/xenia/export_resolver.cc | 5 +---- src/xenia/export_resolver.h | 7 +------ src/xenia/kernel/util/shim_utils.h | 3 +-- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/xenia/export_resolver.cc b/src/xenia/export_resolver.cc index 8d37240e3..c311819b8 100644 --- a/src/xenia/export_resolver.cc +++ b/src/xenia/export_resolver.cc @@ -32,7 +32,6 @@ void ExportResolver::RegisterTable( exports[n].variable_ptr = 0; exports[n].function_data.shim_data = NULL; exports[n].function_data.shim = NULL; - exports[n].function_data.impl = NULL; } } @@ -93,12 +92,10 @@ void ExportResolver::SetVariableMapping(const char* library_name, void ExportResolver::SetFunctionMapping( const char* library_name, const uint32_t ordinal, - void* shim_data, xe_kernel_export_shim_fn shim, - xe_kernel_export_impl_fn impl) { + void* shim_data, xe_kernel_export_shim_fn shim) { KernelExport* kernel_export = GetExportByOrdinal(library_name, ordinal); assert_not_null(kernel_export); kernel_export->is_implemented = true; kernel_export->function_data.shim_data = shim_data; kernel_export->function_data.shim = shim; - kernel_export->function_data.impl = impl; } diff --git a/src/xenia/export_resolver.h b/src/xenia/export_resolver.h index 487e8bd9c..50d328209 100644 --- a/src/xenia/export_resolver.h +++ b/src/xenia/export_resolver.h @@ -21,7 +21,6 @@ typedef struct xe_ppc_state xe_ppc_state_t; namespace xe { -typedef void (*xe_kernel_export_impl_fn)(); typedef void (*xe_kernel_export_shim_fn)(xe_ppc_state_t*, void*); class KernelExport { @@ -52,9 +51,6 @@ public: // This is called directly from generated code. // It should parse args, do fixups, and call the impl. xe_kernel_export_shim_fn shim; - - // Real function implementation. - xe_kernel_export_impl_fn impl; } function_data; }; }; @@ -79,8 +75,7 @@ public: void SetVariableMapping(const char* library_name, const uint32_t ordinal, uint32_t value); void SetFunctionMapping(const char* library_name, const uint32_t ordinal, - void* shim_data, xe_kernel_export_shim_fn shim, - xe_kernel_export_impl_fn impl); + void* shim_data, xe_kernel_export_shim_fn shim); private: class ExportTable { diff --git a/src/xenia/kernel/util/shim_utils.h b/src/xenia/kernel/util/shim_utils.h index 7dfd948ff..ef44874ea 100644 --- a/src/xenia/kernel/util/shim_utils.h +++ b/src/xenia/kernel/util/shim_utils.h @@ -28,8 +28,7 @@ using PPCContext = alloy::frontend::ppc::PPCContext; export_resolver->SetFunctionMapping( \ library_name, ordinals::##export_name, \ shim_data, \ - (xe_kernel_export_shim_fn)export_name##_shim, \ - nullptr); + (xe_kernel_export_shim_fn)export_name##_shim); #define SHIM_MEM_BASE ppc_state->membase #define SHIM_MEM_ADDR(a) (a ? (ppc_state->membase + a) : nullptr) From 916dc397ab02903cd878b77451e0e6b5162a47a8 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 15 Aug 2014 22:59:28 -0700 Subject: [PATCH 106/388] Part 1 of kernel simplification/cleanup: removing externs. --- .gitignore | 1 + src/xenia/kernel/objects/xthread.cc | 18 ++++--- src/xenia/kernel/sources.gypi | 24 ---------- src/xenia/kernel/xam_content.cc | 5 +- src/xenia/kernel/xam_content.h | 29 ----------- src/xenia/kernel/xam_info.cc | 5 +- src/xenia/kernel/xam_info.h | 29 ----------- src/xenia/kernel/xam_input.cc | 5 +- src/xenia/kernel/xam_input.h | 29 ----------- src/xenia/kernel/xam_module.h | 4 -- src/xenia/kernel/xam_msg.cc | 5 +- src/xenia/kernel/xam_msg.h | 29 ----------- src/xenia/kernel/xam_net.cc | 5 +- src/xenia/kernel/xam_net.h | 29 ----------- src/xenia/kernel/xam_notify.cc | 5 +- src/xenia/kernel/xam_notify.h | 28 ----------- src/xenia/kernel/xam_ui.cc | 5 +- src/xenia/kernel/xam_ui.h | 28 ----------- src/xenia/kernel/xam_user.cc | 5 +- src/xenia/kernel/xam_user.h | 28 ----------- src/xenia/kernel/xam_video.cc | 10 ++-- src/xenia/kernel/xam_video.h | 27 ----------- src/xenia/kernel/xam_voice.cc | 5 +- src/xenia/kernel/xam_voice.h | 29 ----------- src/xenia/kernel/xboxkrnl_audio.cc | 5 +- src/xenia/kernel/xboxkrnl_audio.h | 27 ----------- src/xenia/kernel/xboxkrnl_debug.cc | 5 +- src/xenia/kernel/xboxkrnl_debug.h | 30 ------------ src/xenia/kernel/xboxkrnl_hal.cc | 5 +- src/xenia/kernel/xboxkrnl_hal.h | 30 ------------ src/xenia/kernel/xboxkrnl_io.cc | 5 +- src/xenia/kernel/xboxkrnl_io.h | 27 ----------- src/xenia/kernel/xboxkrnl_memory.cc | 5 +- src/xenia/kernel/xboxkrnl_memory.h | 57 ---------------------- src/xenia/kernel/xboxkrnl_misc.cc | 5 +- src/xenia/kernel/xboxkrnl_misc.h | 27 ----------- src/xenia/kernel/xboxkrnl_module.cc | 1 - src/xenia/kernel/xboxkrnl_module.h | 6 --- src/xenia/kernel/xboxkrnl_modules.cc | 5 +- src/xenia/kernel/xboxkrnl_modules.h | 37 --------------- src/xenia/kernel/xboxkrnl_nt.cc | 32 ------------- src/xenia/kernel/xboxkrnl_nt.h | 27 ----------- src/xenia/kernel/xboxkrnl_ob.cc | 5 +- src/xenia/kernel/xboxkrnl_ob.h | 27 ----------- src/xenia/kernel/xboxkrnl_private.h | 1 - src/xenia/kernel/xboxkrnl_rtl.cc | 26 ++++++++++ src/xenia/kernel/xboxkrnl_rtl.h | 21 -------- src/xenia/kernel/xboxkrnl_strings.cc | 5 +- src/xenia/kernel/xboxkrnl_strings.h | 27 ----------- src/xenia/kernel/xboxkrnl_threading.cc | 5 +- src/xenia/kernel/xboxkrnl_threading.h | 66 -------------------------- src/xenia/kernel/xboxkrnl_usbcam.cc | 5 +- src/xenia/kernel/xboxkrnl_usbcam.h | 28 ----------- src/xenia/kernel/xboxkrnl_video.cc | 5 +- src/xenia/kernel/xboxkrnl_video.h | 55 --------------------- src/xenia/xbox.h | 33 +++++++++++++ 56 files changed, 136 insertions(+), 896 deletions(-) delete mode 100644 src/xenia/kernel/xam_content.h delete mode 100644 src/xenia/kernel/xam_info.h delete mode 100644 src/xenia/kernel/xam_input.h delete mode 100644 src/xenia/kernel/xam_msg.h delete mode 100644 src/xenia/kernel/xam_net.h delete mode 100644 src/xenia/kernel/xam_notify.h delete mode 100644 src/xenia/kernel/xam_ui.h delete mode 100644 src/xenia/kernel/xam_user.h delete mode 100644 src/xenia/kernel/xam_video.h delete mode 100644 src/xenia/kernel/xam_voice.h delete mode 100644 src/xenia/kernel/xboxkrnl_audio.h delete mode 100644 src/xenia/kernel/xboxkrnl_debug.h delete mode 100644 src/xenia/kernel/xboxkrnl_hal.h delete mode 100644 src/xenia/kernel/xboxkrnl_io.h delete mode 100644 src/xenia/kernel/xboxkrnl_memory.h delete mode 100644 src/xenia/kernel/xboxkrnl_misc.h delete mode 100644 src/xenia/kernel/xboxkrnl_modules.h delete mode 100644 src/xenia/kernel/xboxkrnl_nt.cc delete mode 100644 src/xenia/kernel/xboxkrnl_nt.h delete mode 100644 src/xenia/kernel/xboxkrnl_ob.h delete mode 100644 src/xenia/kernel/xboxkrnl_strings.h delete mode 100644 src/xenia/kernel/xboxkrnl_threading.h delete mode 100644 src/xenia/kernel/xboxkrnl_usbcam.h delete mode 100644 src/xenia/kernel/xboxkrnl_video.h diff --git a/.gitignore b/.gitignore index 57cc0de77..1a83a9bd8 100644 --- a/.gitignore +++ b/.gitignore @@ -76,3 +76,4 @@ build-test/ # Local-only paths # ============================================================================== attic/ +third_party/vasm/ diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index 7c3f6b0be..d24127db8 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -9,12 +9,10 @@ #include -#include - +#include #include #include #include -#include #include #include @@ -27,7 +25,7 @@ using namespace xe::kernel; namespace { static uint32_t next_xthread_id = 0; - static uint32_t current_thread_tls = xeKeTlsAlloc(); + static thread_local XThread* current_thread_tls; static xe_mutex_t* critical_region_ = xe_mutex_alloc(10000); static XThread* shared_kernel_thread_ = 0; } @@ -110,7 +108,7 @@ XThread::~XThread() { } XThread* XThread::GetCurrentThread() { - XThread* thread = (XThread*)xeKeTlsGetValue(current_thread_tls); + XThread* thread = current_thread_tls; if (!thread) { // Assume this is some shared interrupt thread/etc. XThread::EnterCriticalRegion(); @@ -119,7 +117,7 @@ XThread* XThread::GetCurrentThread() { thread = new XThread( KernelState::shared(), 32 * 1024, 0, 0, 0, 0); shared_kernel_thread_ = thread; - xeKeTlsSetValue(current_thread_tls, (uint64_t)thread); + current_thread_tls = thread; } XThread::LeaveCriticalRegion(); } @@ -292,9 +290,9 @@ X_STATUS XThread::Exit(int exit_code) { static uint32_t __stdcall XThreadStartCallbackWin32(void* param) { XThread* thread = reinterpret_cast(param); xe::Profiler::ThreadEnter(thread->name()); - xeKeTlsSetValue(current_thread_tls, (uint64_t)thread); + current_thread_tls = thread; thread->Execute(); - xeKeTlsSetValue(current_thread_tls, NULL); + current_thread_tls = nullptr; thread->Release(); xe::Profiler::ThreadExit(); return 0; @@ -335,9 +333,9 @@ X_STATUS XThread::PlatformExit(int exit_code) { static void* XThreadStartCallbackPthreads(void* param) { XThread* thread = reinterpret_cast(param); xe::Profiler::ThreadEnter(thread->name()); - xeKeTlsSetValue(current_thread_tls, (uint64_t)thread); + current_thread_tls = thread; thread->Execute(); - xeKeTlsSetValue(current_thread_tls, NULL); + current_thread_tls = nullptr; thread->Release(); xe::Profiler::ThreadExit(); return 0; diff --git a/src/xenia/kernel/sources.gypi b/src/xenia/kernel/sources.gypi index 6b3fe4c2b..760d0a069 100644 --- a/src/xenia/kernel/sources.gypi +++ b/src/xenia/kernel/sources.gypi @@ -18,63 +18,39 @@ 'user_profile.cc', 'user_profile.h', 'xam_content.cc', - 'xam_content.h', 'xam_info.cc', - 'xam_info.h', 'xam_input.cc', - 'xam_input.h', 'xam_module.cc', 'xam_module.h', 'xam_msg.cc', - 'xam_msg.h', 'xam_net.cc', - 'xam_net.h', 'xam_notify.cc', - 'xam_notify.h', 'xam_ordinals.h', 'xam_private.h', 'xam_table.inc', 'xam_ui.cc', - 'xam_ui.h', 'xam_user.cc', - 'xam_user.h', 'xam_video.cc', - 'xam_video.h', 'xam_voice.cc', - 'xam_voice.h', 'xboxkrnl_audio.cc', - 'xboxkrnl_audio.h', 'xboxkrnl_debug.cc', - 'xboxkrnl_debug.h', 'xboxkrnl_hal.cc', - 'xboxkrnl_hal.h', 'xboxkrnl_io.cc', - 'xboxkrnl_io.h', 'xboxkrnl_memory.cc', - 'xboxkrnl_memory.h', 'xboxkrnl_misc.cc', - 'xboxkrnl_misc.h', 'xboxkrnl_module.cc', 'xboxkrnl_module.h', 'xboxkrnl_modules.cc', - 'xboxkrnl_modules.h', - 'xboxkrnl_nt.cc', - 'xboxkrnl_nt.h', 'xboxkrnl_ob.cc', - 'xboxkrnl_ob.h', 'xboxkrnl_ordinals.h', 'xboxkrnl_private.h', 'xboxkrnl_rtl.cc', 'xboxkrnl_rtl.h', 'xboxkrnl_strings.cc', - 'xboxkrnl_strings.h', 'xboxkrnl_table.inc', 'xboxkrnl_threading.cc', - 'xboxkrnl_threading.h', 'xboxkrnl_usbcam.cc', - 'xboxkrnl_usbcam.h', 'xboxkrnl_video.cc', - 'xboxkrnl_video.h', 'xobject.cc', 'xobject.h', ], diff --git a/src/xenia/kernel/xam_content.cc b/src/xenia/kernel/xam_content.cc index e5fd8913c..b367504c3 100644 --- a/src/xenia/kernel/xam_content.cc +++ b/src/xenia/kernel/xam_content.cc @@ -7,8 +7,9 @@ ****************************************************************************** */ -#include - +#include +#include +#include #include #include #include diff --git a/src/xenia/kernel/xam_content.h b/src/xenia/kernel/xam_content.h deleted file mode 100644 index 6cd6c7e2e..000000000 --- a/src/xenia/kernel/xam_content.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XAM_CONTENT_H_ -#define XENIA_KERNEL_XAM_CONTENT_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XAM_CONTENT_H_ diff --git a/src/xenia/kernel/xam_info.cc b/src/xenia/kernel/xam_info.cc index debb8b62b..1827019d2 100644 --- a/src/xenia/kernel/xam_info.cc +++ b/src/xenia/kernel/xam_info.cc @@ -7,8 +7,9 @@ ****************************************************************************** */ -#include - +#include +#include +#include #include #include #include diff --git a/src/xenia/kernel/xam_info.h b/src/xenia/kernel/xam_info.h deleted file mode 100644 index 7757d18c2..000000000 --- a/src/xenia/kernel/xam_info.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XAM_INFO_H_ -#define XENIA_KERNEL_XAM_INFO_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XAM_INFO_H_ diff --git a/src/xenia/kernel/xam_input.cc b/src/xenia/kernel/xam_input.cc index b4f272447..4ef44b0a5 100644 --- a/src/xenia/kernel/xam_input.cc +++ b/src/xenia/kernel/xam_input.cc @@ -7,8 +7,9 @@ ****************************************************************************** */ -#include - +#include +#include +#include #include #include #include diff --git a/src/xenia/kernel/xam_input.h b/src/xenia/kernel/xam_input.h deleted file mode 100644 index 43ab24342..000000000 --- a/src/xenia/kernel/xam_input.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XAM_INPUT_H_ -#define XENIA_KERNEL_XAM_INPUT_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XAM_INPUT_H_ diff --git a/src/xenia/kernel/xam_module.h b/src/xenia/kernel/xam_module.h index 52440fc77..773ce1149 100644 --- a/src/xenia/kernel/xam_module.h +++ b/src/xenia/kernel/xam_module.h @@ -17,10 +17,6 @@ #include #include -// All of the exported functions: -#include - - namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam_msg.cc b/src/xenia/kernel/xam_msg.cc index a4b61866b..0317210eb 100644 --- a/src/xenia/kernel/xam_msg.cc +++ b/src/xenia/kernel/xam_msg.cc @@ -7,8 +7,9 @@ ****************************************************************************** */ -#include - +#include +#include +#include #include #include #include diff --git a/src/xenia/kernel/xam_msg.h b/src/xenia/kernel/xam_msg.h deleted file mode 100644 index fb5f3b327..000000000 --- a/src/xenia/kernel/xam_msg.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XAM_MSG_H_ -#define XENIA_KERNEL_XAM_MSG_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XAM_MSG_H_ diff --git a/src/xenia/kernel/xam_net.cc b/src/xenia/kernel/xam_net.cc index 7ba5b887b..8f5815404 100644 --- a/src/xenia/kernel/xam_net.cc +++ b/src/xenia/kernel/xam_net.cc @@ -9,8 +9,9 @@ #include -#include - +#include +#include +#include #include #include #include diff --git a/src/xenia/kernel/xam_net.h b/src/xenia/kernel/xam_net.h deleted file mode 100644 index 3820b5d05..000000000 --- a/src/xenia/kernel/xam_net.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XAM_NET_H_ -#define XENIA_KERNEL_XAM_NET_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XAM_NET_H_ diff --git a/src/xenia/kernel/xam_notify.cc b/src/xenia/kernel/xam_notify.cc index 6521f9876..356fbc269 100644 --- a/src/xenia/kernel/xam_notify.cc +++ b/src/xenia/kernel/xam_notify.cc @@ -7,8 +7,9 @@ ****************************************************************************** */ -#include - +#include +#include +#include #include #include #include diff --git a/src/xenia/kernel/xam_notify.h b/src/xenia/kernel/xam_notify.h deleted file mode 100644 index 8bf8b2c88..000000000 --- a/src/xenia/kernel/xam_notify.h +++ /dev/null @@ -1,28 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XAM_NOTIFY_H_ -#define XENIA_KERNEL_XAM_NOTIFY_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XAM_NOTIFY_H_ diff --git a/src/xenia/kernel/xam_ui.cc b/src/xenia/kernel/xam_ui.cc index 803934fd6..0824b8eb9 100644 --- a/src/xenia/kernel/xam_ui.cc +++ b/src/xenia/kernel/xam_ui.cc @@ -7,8 +7,9 @@ ****************************************************************************** */ -#include - +#include +#include +#include #include #include #include diff --git a/src/xenia/kernel/xam_ui.h b/src/xenia/kernel/xam_ui.h deleted file mode 100644 index 629491ec4..000000000 --- a/src/xenia/kernel/xam_ui.h +++ /dev/null @@ -1,28 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2014 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XAM_UI_H_ -#define XENIA_KERNEL_XAM_UI_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XAM_UI_H_ diff --git a/src/xenia/kernel/xam_user.cc b/src/xenia/kernel/xam_user.cc index 0c7c3ea4c..c05d2e97a 100644 --- a/src/xenia/kernel/xam_user.cc +++ b/src/xenia/kernel/xam_user.cc @@ -7,8 +7,9 @@ ****************************************************************************** */ -#include - +#include +#include +#include #include #include #include diff --git a/src/xenia/kernel/xam_user.h b/src/xenia/kernel/xam_user.h deleted file mode 100644 index d34a82d1e..000000000 --- a/src/xenia/kernel/xam_user.h +++ /dev/null @@ -1,28 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XAM_USER_H_ -#define XENIA_KERNEL_XAM_USER_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XAM_USER_H_ diff --git a/src/xenia/kernel/xam_video.cc b/src/xenia/kernel/xam_video.cc index b64e395c8..2bba399cc 100644 --- a/src/xenia/kernel/xam_video.cc +++ b/src/xenia/kernel/xam_video.cc @@ -7,14 +7,13 @@ ****************************************************************************** */ -#include - +#include +#include +#include #include #include #include -#include - using namespace xe; using namespace xe::kernel; @@ -24,7 +23,8 @@ using namespace xe::kernel::xam; namespace xe { namespace kernel { - +// TODO(benvanik): actually check to see if these are the same. +void xeVdQueryVideoMode(X_VIDEO_MODE *video_mode, bool swap); SHIM_CALL XGetVideoMode_shim( PPCContext* ppc_state, KernelState* state) { uint32_t video_mode_ptr = SHIM_GET_ARG_32(0); diff --git a/src/xenia/kernel/xam_video.h b/src/xenia/kernel/xam_video.h deleted file mode 100644 index 1bafb43ca..000000000 --- a/src/xenia/kernel/xam_video.h +++ /dev/null @@ -1,27 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XAM_VIDEO_H_ -#define XENIA_KERNEL_XAM_VIDEO_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XAM_VIDEO_H_ diff --git a/src/xenia/kernel/xam_voice.cc b/src/xenia/kernel/xam_voice.cc index 068b45f84..30b94bcdd 100644 --- a/src/xenia/kernel/xam_voice.cc +++ b/src/xenia/kernel/xam_voice.cc @@ -7,8 +7,9 @@ ****************************************************************************** */ -#include - +#include +#include +#include #include #include #include diff --git a/src/xenia/kernel/xam_voice.h b/src/xenia/kernel/xam_voice.h deleted file mode 100644 index 2ab9e527e..000000000 --- a/src/xenia/kernel/xam_voice.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2014 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XAM_VOICE_H_ -#define XENIA_KERNEL_XAM_VOICE_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XAM_VOICE_H_ diff --git a/src/xenia/kernel/xboxkrnl_audio.cc b/src/xenia/kernel/xboxkrnl_audio.cc index 34744bbe9..970abfd69 100644 --- a/src/xenia/kernel/xboxkrnl_audio.cc +++ b/src/xenia/kernel/xboxkrnl_audio.cc @@ -7,8 +7,9 @@ ****************************************************************************** */ -#include - +#include +#include +#include #include #include #include diff --git a/src/xenia/kernel/xboxkrnl_audio.h b/src/xenia/kernel/xboxkrnl_audio.h deleted file mode 100644 index c57498a7d..000000000 --- a/src/xenia/kernel/xboxkrnl_audio.h +++ /dev/null @@ -1,27 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XBOXKRNL_AUDIO_H_ -#define XENIA_KERNEL_XBOXKRNL_AUDIO_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XBOXKRNL_AUDIO_H_ diff --git a/src/xenia/kernel/xboxkrnl_debug.cc b/src/xenia/kernel/xboxkrnl_debug.cc index e5ae66591..ae594a7d0 100644 --- a/src/xenia/kernel/xboxkrnl_debug.cc +++ b/src/xenia/kernel/xboxkrnl_debug.cc @@ -7,8 +7,9 @@ ****************************************************************************** */ -#include - +#include +#include +#include #include #include #include diff --git a/src/xenia/kernel/xboxkrnl_debug.h b/src/xenia/kernel/xboxkrnl_debug.h deleted file mode 100644 index 3d08ba531..000000000 --- a/src/xenia/kernel/xboxkrnl_debug.h +++ /dev/null @@ -1,30 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XBOXKRNL_DEBUG_H_ -#define XENIA_KERNEL_XBOXKRNL_DEBUG_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - -void xeDbgBreakPoint(); - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XBOXKRNL_DEBUG_H_ diff --git a/src/xenia/kernel/xboxkrnl_hal.cc b/src/xenia/kernel/xboxkrnl_hal.cc index e083ceca5..dbde18fca 100644 --- a/src/xenia/kernel/xboxkrnl_hal.cc +++ b/src/xenia/kernel/xboxkrnl_hal.cc @@ -7,8 +7,9 @@ ****************************************************************************** */ -#include - +#include +#include +#include #include #include #include diff --git a/src/xenia/kernel/xboxkrnl_hal.h b/src/xenia/kernel/xboxkrnl_hal.h deleted file mode 100644 index 7e09fdf6f..000000000 --- a/src/xenia/kernel/xboxkrnl_hal.h +++ /dev/null @@ -1,30 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XBOXKRNL_HAL_H_ -#define XENIA_KERNEL_XBOXKRNL_HAL_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - -void xeHalReturnToFirmware(uint32_t routine); - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XBOXKRNL_HAL_H_ diff --git a/src/xenia/kernel/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl_io.cc index fcc83c567..caee0e283 100644 --- a/src/xenia/kernel/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl_io.cc @@ -7,8 +7,9 @@ ****************************************************************************** */ -#include - +#include +#include +#include #include #include #include diff --git a/src/xenia/kernel/xboxkrnl_io.h b/src/xenia/kernel/xboxkrnl_io.h deleted file mode 100644 index 84aecd8cc..000000000 --- a/src/xenia/kernel/xboxkrnl_io.h +++ /dev/null @@ -1,27 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XBOXKRNL_IO_H_ -#define XENIA_KERNEL_XBOXKRNL_IO_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XBOXKRNL_IO_H_ diff --git a/src/xenia/kernel/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl_memory.cc index bcef1834c..9cd028c9e 100644 --- a/src/xenia/kernel/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl_memory.cc @@ -7,8 +7,9 @@ ****************************************************************************** */ -#include - +#include +#include +#include #include #include #include diff --git a/src/xenia/kernel/xboxkrnl_memory.h b/src/xenia/kernel/xboxkrnl_memory.h deleted file mode 100644 index 0b59f5420..000000000 --- a/src/xenia/kernel/xboxkrnl_memory.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XBOXKRNL_MEMORY_H_ -#define XENIA_KERNEL_XBOXKRNL_MEMORY_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - -#pragma pack(push, 1) -typedef struct { - uint32_t base_address; - uint32_t allocation_base; - uint32_t allocation_protect; - uint32_t region_size; - uint32_t state; - uint32_t protect; - uint32_t type; -} -X_MEMORY_BASIC_INFORMATION; -#pragma pack(pop) - - -X_STATUS xeNtAllocateVirtualMemory( - uint32_t* base_addr_ptr, uint32_t* region_size_ptr, - uint32_t allocation_type, uint32_t protect_bits, - uint32_t unknown); -X_STATUS xeNtFreeVirtualMemory( - uint32_t* base_addr_ptr, uint32_t* region_size_ptr, - uint32_t free_type, uint32_t unknown); - -uint32_t xeMmAllocatePhysicalMemoryEx( - uint32_t type, uint32_t region_size, uint32_t protect_bits, - uint32_t min_addr_range, uint32_t max_addr_range, uint32_t alignment); -void xeMmFreePhysicalMemory(uint32_t type, uint32_t base_address); -uint32_t xeMmQueryAddressProtect(uint32_t base_address); -uint32_t xeMmGetPhysicalAddress(uint32_t base_address); - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XBOXKRNL_MEMORY_H_ diff --git a/src/xenia/kernel/xboxkrnl_misc.cc b/src/xenia/kernel/xboxkrnl_misc.cc index f08664eab..73d7c0f87 100644 --- a/src/xenia/kernel/xboxkrnl_misc.cc +++ b/src/xenia/kernel/xboxkrnl_misc.cc @@ -7,8 +7,9 @@ ****************************************************************************** */ -#include - +#include +#include +#include #include #include #include diff --git a/src/xenia/kernel/xboxkrnl_misc.h b/src/xenia/kernel/xboxkrnl_misc.h deleted file mode 100644 index d0c9dd06d..000000000 --- a/src/xenia/kernel/xboxkrnl_misc.h +++ /dev/null @@ -1,27 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XBOXKRNL_MISC_H_ -#define XENIA_KERNEL_XBOXKRNL_MISC_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XBOXKRNL_MISC_H_ diff --git a/src/xenia/kernel/xboxkrnl_module.cc b/src/xenia/kernel/xboxkrnl_module.cc index 4fe8c4ace..4b20f0710 100644 --- a/src/xenia/kernel/xboxkrnl_module.cc +++ b/src/xenia/kernel/xboxkrnl_module.cc @@ -46,7 +46,6 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) : RegisterMemoryExports(export_resolver_, kernel_state); RegisterMiscExports(export_resolver_, kernel_state); RegisterModuleExports(export_resolver_, kernel_state); - RegisterNtExports(export_resolver_, kernel_state); RegisterObExports(export_resolver_, kernel_state); RegisterRtlExports(export_resolver_, kernel_state_); RegisterStringExports(export_resolver_, kernel_state_); diff --git a/src/xenia/kernel/xboxkrnl_module.h b/src/xenia/kernel/xboxkrnl_module.h index 357e901b4..627cf850a 100644 --- a/src/xenia/kernel/xboxkrnl_module.h +++ b/src/xenia/kernel/xboxkrnl_module.h @@ -18,13 +18,7 @@ #include // All of the exported functions: -#include -#include -#include -#include #include -#include -#include namespace xe { diff --git a/src/xenia/kernel/xboxkrnl_modules.cc b/src/xenia/kernel/xboxkrnl_modules.cc index 6a9882280..f38a6d0f8 100644 --- a/src/xenia/kernel/xboxkrnl_modules.cc +++ b/src/xenia/kernel/xboxkrnl_modules.cc @@ -7,8 +7,9 @@ ****************************************************************************** */ -#include - +#include +#include +#include #include #include #include diff --git a/src/xenia/kernel/xboxkrnl_modules.h b/src/xenia/kernel/xboxkrnl_modules.h deleted file mode 100644 index 1c4997c31..000000000 --- a/src/xenia/kernel/xboxkrnl_modules.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XBOXKRNL_MODULES_H_ -#define XENIA_KERNEL_XBOXKRNL_MODULES_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - -X_STATUS xeExGetXConfigSetting( - uint16_t category, uint16_t setting, void* buffer, uint16_t buffer_size, - uint16_t* required_size); - -int xeXexCheckExecutablePriviledge(uint32_t privilege); - -int xeXexGetModuleHandle(const char* module_name, - X_HANDLE* module_handle_ptr); - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XBOXKRNL_MODULES_H_ diff --git a/src/xenia/kernel/xboxkrnl_nt.cc b/src/xenia/kernel/xboxkrnl_nt.cc deleted file mode 100644 index c0ab764a1..000000000 --- a/src/xenia/kernel/xboxkrnl_nt.cc +++ /dev/null @@ -1,32 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include -#include -#include - - -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xboxkrnl; - - -namespace xe { -namespace kernel { - - -} // namespace kernel -} // namespace xe - - -void xe::kernel::xboxkrnl::RegisterNtExports( - ExportResolver* export_resolver, KernelState* state) { -} diff --git a/src/xenia/kernel/xboxkrnl_nt.h b/src/xenia/kernel/xboxkrnl_nt.h deleted file mode 100644 index 72ea2bef1..000000000 --- a/src/xenia/kernel/xboxkrnl_nt.h +++ /dev/null @@ -1,27 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XBOXKRNL_NT_H_ -#define XENIA_KERNEL_XBOXKRNL_NT_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XBOXKRNL_NT_H_ diff --git a/src/xenia/kernel/xboxkrnl_ob.cc b/src/xenia/kernel/xboxkrnl_ob.cc index a1e1c573c..9631c3cd9 100644 --- a/src/xenia/kernel/xboxkrnl_ob.cc +++ b/src/xenia/kernel/xboxkrnl_ob.cc @@ -7,8 +7,9 @@ ****************************************************************************** */ -#include - +#include +#include +#include #include #include #include diff --git a/src/xenia/kernel/xboxkrnl_ob.h b/src/xenia/kernel/xboxkrnl_ob.h deleted file mode 100644 index 0158fba73..000000000 --- a/src/xenia/kernel/xboxkrnl_ob.h +++ /dev/null @@ -1,27 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XBOXKRNL_OB_H_ -#define XENIA_KERNEL_XBOXKRNL_OB_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XBOXKRNL_OB_H_ diff --git a/src/xenia/kernel/xboxkrnl_private.h b/src/xenia/kernel/xboxkrnl_private.h index b0612f0ca..c23d02d3f 100644 --- a/src/xenia/kernel/xboxkrnl_private.h +++ b/src/xenia/kernel/xboxkrnl_private.h @@ -30,7 +30,6 @@ void RegisterIoExports(ExportResolver* export_resolver, KernelState* state); void RegisterMemoryExports(ExportResolver* export_resolver, KernelState* state); void RegisterMiscExports(ExportResolver* export_resolver, KernelState* state); void RegisterModuleExports(ExportResolver* export_resolver, KernelState* state); -void RegisterNtExports(ExportResolver* export_resolver, KernelState* state); void RegisterObExports(ExportResolver* export_resolver, KernelState* state); void RegisterRtlExports(ExportResolver* export_resolver, KernelState* state); void RegisterStringExports(ExportResolver* export_resolver, KernelState* state); diff --git a/src/xenia/kernel/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl_rtl.cc index 6214e6f97..1b23dafc6 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl_rtl.cc @@ -27,6 +27,32 @@ namespace xe { namespace kernel { +//RtlCompareMemory +struct x { +}; + +struct RtlCompareMemoryExport { + KernelState* state; + static void Call(PPCContext* ppc_state) { + uint32_t source1 = SHIM_GET_ARG_32(0); + uint32_t source2 = SHIM_GET_ARG_32(1); + uint32_t length = SHIM_GET_ARG_32(2); + + XELOGD( + "RtlCompareMemory(%.8X, %.8X, %d)", + source1, source2, length); + + uint32_t result = 0; + SHIM_SET_RETURN_64(result); + } + virtual void Log() { + // + } + X_STATUS RtlCompareMemory(uint32_t source1_ptr, uint32_t source2_ptr, uint32_t length) { + } +}; + + // http://msdn.microsoft.com/en-us/library/ff561778 uint32_t xeRtlCompareMemory(uint32_t source1_ptr, uint32_t source2_ptr, uint32_t length) { diff --git a/src/xenia/kernel/xboxkrnl_rtl.h b/src/xenia/kernel/xboxkrnl_rtl.h index 7606be241..d462516e9 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.h +++ b/src/xenia/kernel/xboxkrnl_rtl.h @@ -12,7 +12,6 @@ #include #include - #include @@ -20,26 +19,6 @@ namespace xe { namespace kernel { -uint32_t xeRtlCompareMemory(uint32_t source1_ptr, uint32_t source2_ptr, - uint32_t length); -uint32_t xeRtlCompareMemoryUlong(uint32_t source_ptr, uint32_t length, - uint32_t pattern); -void xeRtlFillMemoryUlong(uint32_t destination_ptr, uint32_t length, - uint32_t pattern); - -void xeRtlInitAnsiString(uint32_t destination_ptr, uint32_t source_ptr); -void xeRtlFreeAnsiString(uint32_t string_ptr); - -void xeRtlInitUnicodeString(uint32_t destination_ptr, uint32_t source_ptr); -void xeRtlFreeUnicodeString(uint32_t string_ptr); -X_STATUS xeRtlUnicodeStringToAnsiString( - uint32_t destination_ptr, uint32_t source_ptr, uint32_t alloc_dest); - -uint32_t xeRtlNtStatusToDosError(X_STATUS status); - -uint32_t xeRtlImageXexHeaderField(uint32_t xex_header_base_ptr, - uint32_t image_field); - void xeRtlInitializeCriticalSection(uint32_t cs_ptr); X_STATUS xeRtlInitializeCriticalSectionAndSpinCount( uint32_t cs_ptr, uint32_t spin_count); diff --git a/src/xenia/kernel/xboxkrnl_strings.cc b/src/xenia/kernel/xboxkrnl_strings.cc index fc7f0d989..05095d537 100644 --- a/src/xenia/kernel/xboxkrnl_strings.cc +++ b/src/xenia/kernel/xboxkrnl_strings.cc @@ -7,8 +7,9 @@ ****************************************************************************** */ -#include - +#include +#include +#include #include #include #include diff --git a/src/xenia/kernel/xboxkrnl_strings.h b/src/xenia/kernel/xboxkrnl_strings.h deleted file mode 100644 index 859acda85..000000000 --- a/src/xenia/kernel/xboxkrnl_strings.h +++ /dev/null @@ -1,27 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XBOXKRNL_STRINGS_H_ -#define XENIA_KERNEL_XBOXKRNL_STRINGS_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XBOXKRNL_STRINGS_H_ diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index 4b6e72258..c4a087187 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -7,8 +7,9 @@ ****************************************************************************** */ -#include - +#include +#include +#include #include #include #include diff --git a/src/xenia/kernel/xboxkrnl_threading.h b/src/xenia/kernel/xboxkrnl_threading.h deleted file mode 100644 index 62f807065..000000000 --- a/src/xenia/kernel/xboxkrnl_threading.h +++ /dev/null @@ -1,66 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XBOXKRNL_THREADING_H_ -#define XENIA_KERNEL_XBOXKRNL_THREADING_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - -X_STATUS xeExCreateThread( - uint32_t* handle_ptr, uint32_t stack_size, uint32_t* thread_id_ptr, - uint32_t xapi_thread_startup, - uint32_t start_address, uint32_t start_context, uint32_t creation_flags); - -X_STATUS xeNtResumeThread(uint32_t handle, uint32_t* out_suspend_count); -X_STATUS xeNtSuspendThread(uint32_t handle, uint32_t* out_suspend_count); - -uint32_t xeKeSetAffinityThread(void* thread_ptr, uint32_t affinity); - -uint32_t xeKeGetCurrentProcessType(); - -uint64_t xeKeQueryPerformanceFrequency(); -void xeKeQuerySystemTime(uint64_t* time_ptr); - -X_STATUS xeKeDelayExecutionThread( - uint32_t processor_mode, uint32_t alertable, uint64_t interval); - -uint32_t xeKeTlsAlloc(); -int KeTlsFree(uint32_t tls_index); -uint64_t xeKeTlsGetValue(uint32_t tls_index); -int xeKeTlsSetValue(uint32_t tls_index, uint64_t tls_value); - -X_STATUS xeNtCreateEvent(uint32_t* handle_ptr, void* obj_attributes, - uint32_t event_type, uint32_t initial_state); -int32_t xeKeSetEvent(void* event_ptr, uint32_t increment, uint32_t wait); -int32_t xeKeResetEvent(void* event_ptr); - -X_STATUS xeKeWaitForSingleObject( - void* object_ptr, uint32_t wait_reason, uint32_t processor_mode, - uint32_t alertable, uint64_t* opt_timeout); - -uint32_t xeKfAcquireSpinLock(uint32_t* lock_ptr); -void xeKfReleaseSpinLock(uint32_t* lock_ptr, uint32_t old_irql); - -void xeKeEnterCriticalRegion(); -void xeKeLeaveCriticalRegion(); - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XBOXKRNL_THREADING_H_ diff --git a/src/xenia/kernel/xboxkrnl_usbcam.cc b/src/xenia/kernel/xboxkrnl_usbcam.cc index e30966e0f..b68c02796 100644 --- a/src/xenia/kernel/xboxkrnl_usbcam.cc +++ b/src/xenia/kernel/xboxkrnl_usbcam.cc @@ -7,8 +7,9 @@ ****************************************************************************** */ -#include - +#include +#include +#include #include #include #include diff --git a/src/xenia/kernel/xboxkrnl_usbcam.h b/src/xenia/kernel/xboxkrnl_usbcam.h deleted file mode 100644 index 7a69b65f6..000000000 --- a/src/xenia/kernel/xboxkrnl_usbcam.h +++ /dev/null @@ -1,28 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2014 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XBOXKRNL_USBCAM_H_ -#define XENIA_KERNEL_XBOXKRNL_USBCAM_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XBOXKRNL_USBCAM_H_ diff --git a/src/xenia/kernel/xboxkrnl_video.cc b/src/xenia/kernel/xboxkrnl_video.cc index 1a6adead1..7576b21bb 100644 --- a/src/xenia/kernel/xboxkrnl_video.cc +++ b/src/xenia/kernel/xboxkrnl_video.cc @@ -7,8 +7,9 @@ ****************************************************************************** */ -#include - +#include +#include +#include #include #include #include diff --git a/src/xenia/kernel/xboxkrnl_video.h b/src/xenia/kernel/xboxkrnl_video.h deleted file mode 100644 index 6c62811af..000000000 --- a/src/xenia/kernel/xboxkrnl_video.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_KERNEL_XBOXKRNL_VIDEO_H_ -#define XENIA_KERNEL_XBOXKRNL_VIDEO_H_ - -#include -#include - -#include - - -namespace xe { -namespace kernel { - - -// http://ffplay360.googlecode.com/svn/trunk/Common/XTLOnPC.h -#pragma pack(push, 1) -typedef struct { - uint32_t display_width; - uint32_t display_height; - uint32_t is_interlaced; - uint32_t is_widescreen; - uint32_t is_hi_def; - float refresh_rate; - uint32_t video_standard; - uint32_t unknown_0x8a; - uint32_t unknown_0x01; - uint32_t reserved[3]; -} -X_VIDEO_MODE; -#pragma pack(pop) -static_assert_size(X_VIDEO_MODE, 48); - -void xeVdGetCurrentDisplayGamma(uint32_t* arg0, float* arg1); -uint32_t xeVdQueryVideoFlags(); -void xeVdQueryVideoMode(X_VIDEO_MODE *video_mode, bool swap); - -void xeVdInitializeEngines(uint32_t unk0, uint32_t callback, uint32_t unk1, - uint32_t unk2_ptr, uint32_t unk3_ptr); -void xeVdSetGraphicsInterruptCallback(uint32_t callback, uint32_t user_data); -void xeVdEnableRingBufferRPtrWriteBack(uint32_t ptr, uint32_t block_size); - - -} // namespace kernel -} // namespace xe - - -#endif // XENIA_KERNEL_XBOXKRNL_VIDEO_H_ diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index e597e63bb..633477a9c 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -17,6 +17,9 @@ namespace xe { +#pragma pack(push, 4) + + typedef uint32_t X_HANDLE; #define X_INVALID_HANDLE_VALUE ((X_HANDLE)-1) @@ -193,6 +196,17 @@ typedef enum _X_FILE_INFORMATION_CLASS { } X_FILE_INFORMATION_CLASS; +struct X_MEMORY_BASIC_INFORMATION { + uint32_t base_address; + uint32_t allocation_base; + uint32_t allocation_protect; + uint32_t region_size; + uint32_t state; + uint32_t protect; + uint32_t type; +}; + + inline void XOverlappedSetResult(void* ptr, uint32_t value) { auto p = reinterpret_cast(ptr); poly::store_and_swap(&p[0], value); @@ -299,6 +313,22 @@ public: typedef uint32_t XNotificationID; +// http://ffplay360.googlecode.com/svn/trunk/Common/XTLOnPC.h +struct X_VIDEO_MODE { + uint32_t display_width; + uint32_t display_height; + uint32_t is_interlaced; + uint32_t is_widescreen; + uint32_t is_hi_def; + float refresh_rate; + uint32_t video_standard; + uint32_t unknown_0x8a; + uint32_t unknown_0x01; + uint32_t reserved[3]; +}; +static_assert_size(X_VIDEO_MODE, 48); + + typedef enum _X_INPUT_FLAG { X_INPUT_FLAG_GAMEPAD = 0x00000001, } X_INPUT_FLAG; @@ -482,6 +512,9 @@ public: }; +#pragma pack(pop) + + } // namespace xe From bf48e9fbbdda75eaaa5b66ce085308e358690b3d Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 16 Aug 2014 00:11:24 -0700 Subject: [PATCH 107/388] Part 2 of kernel cleanup: merging functions into shims. --- src/xenia/kernel/kernel_state.cc | 7 +- src/xenia/kernel/kernel_state.h | 7 - src/xenia/kernel/util/shim_utils.h | 10 - src/xenia/kernel/xam_video.cc | 8 +- src/xenia/kernel/xboxkrnl_debug.cc | 6 +- src/xenia/kernel/xboxkrnl_hal.cc | 22 +- src/xenia/kernel/xboxkrnl_memory.cc | 344 ++++++--------- src/xenia/kernel/xboxkrnl_modules.cc | 65 +-- src/xenia/kernel/xboxkrnl_rtl.cc | 478 ++++++++------------ src/xenia/kernel/xboxkrnl_rtl.h | 17 +- src/xenia/kernel/xboxkrnl_threading.cc | 587 ++++++++----------------- src/xenia/kernel/xboxkrnl_video.cc | 196 +++------ src/xenia/kernel/xobject.cc | 6 +- 13 files changed, 594 insertions(+), 1159 deletions(-) diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index f885e03fd..92d10810f 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -30,8 +30,11 @@ using namespace xe::kernel; // This is a global object initialized with the XboxkrnlModule. // It references the current kernel state object that all kernel methods should // be using to stash their variables. -KernelState* xe::kernel::shared_kernel_state_ = NULL; - +namespace xe { +namespace kernel { +KernelState* shared_kernel_state_ = nullptr; +} // namespace kernel +} // namespace xe KernelState::KernelState(Emulator* emulator) : emulator_(emulator), memory_(emulator->memory()), diff --git a/src/xenia/kernel/kernel_state.h b/src/xenia/kernel/kernel_state.h index 55033aef6..097566f90 100644 --- a/src/xenia/kernel/kernel_state.h +++ b/src/xenia/kernel/kernel_state.h @@ -95,13 +95,6 @@ private: }; -// This is a global object initialized with the KernelState ctor. -// It references the current kernel state object that all kernel methods should -// be using to stash their variables. -// This sucks, but meh. -extern KernelState* shared_kernel_state_; - - } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/util/shim_utils.h b/src/xenia/kernel/util/shim_utils.h index ef44874ea..d68ea4da8 100644 --- a/src/xenia/kernel/util/shim_utils.h +++ b/src/xenia/kernel/util/shim_utils.h @@ -59,16 +59,6 @@ using PPCContext = alloy::frontend::ppc::PPCContext; #define SHIM_SET_RETURN_64(v) SHIM_SET_GPR_64(3, v) -#define IMPL_MEM_ADDR(a) (a ? state->memory()->Translate(a) : nullptr) - -#define IMPL_MEM_8(a) poly::load_and_swap(IMPL_MEM_ADDR(a)) -#define IMPL_MEM_16(a) poly::load_and_swap(IMPL_MEM_ADDR(a)) -#define IMPL_MEM_32(a) poly::load_and_swap(IMPL_MEM_ADDR(a)) -#define IMPL_SET_MEM_8(a, v) poly::store_and_swap(IMPL_MEM_ADDR(a), v) -#define IMPL_SET_MEM_16(a, v) poly::store_and_swap(IMPL_MEM_ADDR(a), v) -#define IMPL_SET_MEM_32(a, v) poly::store_and_swap(IMPL_MEM_ADDR(a), v) - - } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/xam_video.cc b/src/xenia/kernel/xam_video.cc index 2bba399cc..1106f9bb7 100644 --- a/src/xenia/kernel/xam_video.cc +++ b/src/xenia/kernel/xam_video.cc @@ -23,13 +23,13 @@ using namespace xe::kernel::xam; namespace xe { namespace kernel { + // TODO(benvanik): actually check to see if these are the same. -void xeVdQueryVideoMode(X_VIDEO_MODE *video_mode, bool swap); -SHIM_CALL XGetVideoMode_shim( - PPCContext* ppc_state, KernelState* state) { +void xeVdQueryVideoMode(X_VIDEO_MODE* video_mode); +SHIM_CALL XGetVideoMode_shim(PPCContext* ppc_state, KernelState* state) { uint32_t video_mode_ptr = SHIM_GET_ARG_32(0); X_VIDEO_MODE* video_mode = (X_VIDEO_MODE*)SHIM_MEM_ADDR(video_mode_ptr); - xeVdQueryVideoMode(video_mode, true); + xeVdQueryVideoMode(video_mode); } diff --git a/src/xenia/kernel/xboxkrnl_debug.cc b/src/xenia/kernel/xboxkrnl_debug.cc index ae594a7d0..3ff845c0d 100644 --- a/src/xenia/kernel/xboxkrnl_debug.cc +++ b/src/xenia/kernel/xboxkrnl_debug.cc @@ -244,14 +244,10 @@ SHIM_CALL DbgPrint_shim( } -void xeDbgBreakPoint() { - DebugBreak(); -} - - SHIM_CALL DbgBreakPoint_shim( PPCContext* ppc_state, KernelState* state) { XELOGD("DbgBreakPoint()"); + DebugBreak(); } diff --git a/src/xenia/kernel/xboxkrnl_hal.cc b/src/xenia/kernel/xboxkrnl_hal.cc index dbde18fca..5e208eb11 100644 --- a/src/xenia/kernel/xboxkrnl_hal.cc +++ b/src/xenia/kernel/xboxkrnl_hal.cc @@ -24,9 +24,13 @@ namespace xe { namespace kernel { -void xeHalReturnToFirmware(uint32_t routine) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); +SHIM_CALL HalReturnToFirmware_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t routine = SHIM_GET_ARG_32(0); + + XELOGD( + "HalReturnToFirmware(%d)", + routine); // void // IN FIRMWARE_REENTRY Routine @@ -41,18 +45,6 @@ void xeHalReturnToFirmware(uint32_t routine) { } -SHIM_CALL HalReturnToFirmware_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t routine = SHIM_GET_ARG_32(0); - - XELOGD( - "HalReturnToFirmware(%d)", - routine); - - xeHalReturnToFirmware(routine); -} - - } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl_memory.cc index 9cd028c9e..fba730d7e 100644 --- a/src/xenia/kernel/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl_memory.cc @@ -25,12 +25,21 @@ namespace xe { namespace kernel { -X_STATUS xeNtAllocateVirtualMemory( - uint32_t* base_addr_ptr, uint32_t* region_size_ptr, - uint32_t allocation_type, uint32_t protect_bits, - uint32_t unknown) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); +SHIM_CALL NtAllocateVirtualMemory_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t base_addr_ptr = SHIM_GET_ARG_32(0); + uint32_t base_addr_value = SHIM_MEM_32(base_addr_ptr); + uint32_t region_size_ptr = SHIM_GET_ARG_32(1); + uint32_t region_size_value = SHIM_MEM_32(region_size_ptr); + uint32_t allocation_type = SHIM_GET_ARG_32(2); // X_MEM_* bitmask + uint32_t protect_bits = SHIM_GET_ARG_32(3); // X_PAGE_* bitmask + uint32_t unknown = SHIM_GET_ARG_32(4); + + XELOGD( + "NtAllocateVirtualMemory(%.8X(%.8X), %.8X(%.8X), %.8X, %.8X, %.8X)", + base_addr_ptr, base_addr_value, + region_size_ptr, region_size_value, + allocation_type, protect_bits, unknown); // NTSTATUS // _Inout_ PVOID *BaseAddress, @@ -48,117 +57,59 @@ X_STATUS xeNtAllocateVirtualMemory( // it's simple today we could extend it to do better things in the future. // Must request a size. - if (!*region_size_ptr) { - return X_STATUS_INVALID_PARAMETER; + if (!region_size_value) { + SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER); + return; } // Check allocation type. if (!(allocation_type & (X_MEM_COMMIT | X_MEM_RESET | X_MEM_RESERVE))) { - return X_STATUS_INVALID_PARAMETER; + SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER); + return; } // If MEM_RESET is set only MEM_RESET can be set. if (allocation_type & X_MEM_RESET && (allocation_type & ~X_MEM_RESET)) { - return X_STATUS_INVALID_PARAMETER; + SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER); + return; } // Don't allow games to set execute bits. if (protect_bits & (X_PAGE_EXECUTE | X_PAGE_EXECUTE_READ | X_PAGE_EXECUTE_READWRITE | X_PAGE_EXECUTE_WRITECOPY)) { - return X_STATUS_ACCESS_DENIED; + SHIM_SET_RETURN_32(X_STATUS_ACCESS_DENIED); + return; } // Adjust size. - uint32_t adjusted_size = *region_size_ptr; + uint32_t adjusted_size = region_size_value; // TODO(benvanik): adjust based on page size flags/etc? // TODO(benvanik): support different allocation types. // Right now we treat everything as a commit and ignore allocations that have // already happened. - if (*base_addr_ptr) { + if (base_addr_value) { // Having a pointer already means that this is likely a follow-on COMMIT. assert_true(!(allocation_type & X_MEM_RESERVE) && (allocation_type & X_MEM_COMMIT)); - return X_STATUS_SUCCESS; + SHIM_SET_MEM_32(base_addr_ptr, base_addr_value); + SHIM_SET_MEM_32(region_size_ptr, adjusted_size); + SHIM_SET_RETURN_32(X_STATUS_SUCCESS); + return; } // Allocate. uint32_t flags = (allocation_type & X_MEM_NOZERO); uint32_t addr = (uint32_t)state->memory()->HeapAlloc( - *base_addr_ptr, adjusted_size, flags); + base_addr_value, adjusted_size, flags); if (!addr) { // Failed - assume no memory available. - return X_STATUS_NO_MEMORY; + SHIM_SET_RETURN_32(X_STATUS_NO_MEMORY); + return; } // Stash back. // Maybe set X_STATUS_ALREADY_COMMITTED if MEM_COMMIT? - *base_addr_ptr = addr; - *region_size_ptr = adjusted_size; - return X_STATUS_SUCCESS; -} - - -SHIM_CALL NtAllocateVirtualMemory_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t base_addr_ptr = SHIM_GET_ARG_32(0); - uint32_t base_addr_value = SHIM_MEM_32(base_addr_ptr); - uint32_t region_size_ptr = SHIM_GET_ARG_32(1); - uint32_t region_size_value = SHIM_MEM_32(region_size_ptr); - uint32_t allocation_type = SHIM_GET_ARG_32(2); // X_MEM_* bitmask - uint32_t protect_bits = SHIM_GET_ARG_32(3); // X_PAGE_* bitmask - uint32_t unknown = SHIM_GET_ARG_32(4); - - XELOGD( - "NtAllocateVirtualMemory(%.8X(%.8X), %.8X(%.8X), %.8X, %.8X, %.8X)", - base_addr_ptr, base_addr_value, - region_size_ptr, region_size_value, - allocation_type, protect_bits, unknown); - - X_STATUS result = xeNtAllocateVirtualMemory( - &base_addr_value, ®ion_size_value, - allocation_type, protect_bits, unknown); - - if (XSUCCEEDED(result)) { - SHIM_SET_MEM_32(base_addr_ptr, base_addr_value); - SHIM_SET_MEM_32(region_size_ptr, region_size_value); - } - SHIM_SET_RETURN_32(result); -} - - -X_STATUS xeNtFreeVirtualMemory( - uint32_t* base_addr_ptr, uint32_t* region_size_ptr, - uint32_t free_type, uint32_t unknown) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - // NTSTATUS - // _Inout_ PVOID *BaseAddress, - // _Inout_ PSIZE_T RegionSize, - // _In_ ULONG FreeType - // ? handle? - - // I've only seen zero. - assert_true(unknown == 0); - - if (!*base_addr_ptr) { - return X_STATUS_MEMORY_NOT_ALLOCATED; - } - - // TODO(benvanik): ignore decommits for now. - if (free_type == X_MEM_DECOMMIT) { - return X_STATUS_SUCCESS; - } - - // Free. - uint32_t flags = 0; - uint32_t freed_size = state->memory()->HeapFree( - *base_addr_ptr, flags); - if (!freed_size) { - return X_STATUS_UNSUCCESSFUL; - } - - // Stash back. - *region_size_ptr = freed_size; - return X_STATUS_SUCCESS; + SHIM_SET_MEM_32(base_addr_ptr, addr); + SHIM_SET_MEM_32(region_size_ptr, adjusted_size); + SHIM_SET_RETURN_32(X_STATUS_SUCCESS); } @@ -178,28 +129,55 @@ SHIM_CALL NtFreeVirtualMemory_shim( region_size_ptr, region_size_value, free_type, unknown); - X_STATUS result = xeNtFreeVirtualMemory( - &base_addr_value, ®ion_size_value, - free_type, unknown); + // NTSTATUS + // _Inout_ PVOID *BaseAddress, + // _Inout_ PSIZE_T RegionSize, + // _In_ ULONG FreeType + // ? handle? - if (XSUCCEEDED(result)) { - SHIM_SET_MEM_32(base_addr_ptr, base_addr_value); - SHIM_SET_MEM_32(region_size_ptr, region_size_value); + // I've only seen zero. + assert_true(unknown == 0); + + if (!base_addr_value) { + SHIM_SET_RETURN_32(X_STATUS_MEMORY_NOT_ALLOCATED); + return; } - SHIM_SET_RETURN_32(result); + + // TODO(benvanik): ignore decommits for now. + if (free_type == X_MEM_DECOMMIT) { + SHIM_SET_RETURN_32(X_STATUS_SUCCESS); + return; + } + + // Free. + uint32_t flags = 0; + uint32_t freed_size = state->memory()->HeapFree( + base_addr_value, flags); + if (!freed_size) { + SHIM_SET_RETURN_32(X_STATUS_UNSUCCESSFUL); + return; + } + + SHIM_SET_MEM_32(base_addr_ptr, base_addr_value); + SHIM_SET_MEM_32(region_size_ptr, freed_size); + SHIM_SET_RETURN_32(X_STATUS_SUCCESS); } +SHIM_CALL NtQueryVirtualMemory_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t base_address = SHIM_GET_ARG_32(0); + uint32_t memory_basic_information_ptr = SHIM_GET_ARG_32(1); + X_MEMORY_BASIC_INFORMATION *memory_basic_information = (X_MEMORY_BASIC_INFORMATION*)SHIM_MEM_ADDR(memory_basic_information_ptr); -X_STATUS xeNtQueryVirtualMemory( - uint32_t base_address, X_MEMORY_BASIC_INFORMATION *memory_basic_information, bool swap) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); + XELOGD( + "NtQueryVirtualMemory(%.8X, %.8X)", + base_address, memory_basic_information_ptr); MEMORY_BASIC_INFORMATION mem_info; size_t result = state->memory()->QueryInformation(base_address, &mem_info); - if (!result) { - return STATUS_INVALID_PARAMETER; + SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER); + return; } auto membase = state->memory()->membase(); @@ -214,49 +192,41 @@ X_STATUS xeNtQueryVirtualMemory( memory_basic_information->protect = mem_info.Protect; memory_basic_information->type = mem_info.Type; - if (swap) { - memory_basic_information->base_address = - poly::byte_swap(memory_basic_information->base_address); - memory_basic_information->allocation_base = - poly::byte_swap(memory_basic_information->allocation_base); - memory_basic_information->allocation_protect = - poly::byte_swap(memory_basic_information->allocation_protect); - memory_basic_information->region_size = - poly::byte_swap(memory_basic_information->region_size); - memory_basic_information->state = - poly::byte_swap(memory_basic_information->state); - memory_basic_information->protect = - poly::byte_swap(memory_basic_information->protect); - memory_basic_information->type = - poly::byte_swap(memory_basic_information->type); - } + // TODO(benvanik): auto swap structure. + memory_basic_information->base_address = + poly::byte_swap(memory_basic_information->base_address); + memory_basic_information->allocation_base = + poly::byte_swap(memory_basic_information->allocation_base); + memory_basic_information->allocation_protect = + poly::byte_swap(memory_basic_information->allocation_protect); + memory_basic_information->region_size = + poly::byte_swap(memory_basic_information->region_size); + memory_basic_information->state = + poly::byte_swap(memory_basic_information->state); + memory_basic_information->protect = + poly::byte_swap(memory_basic_information->protect); + memory_basic_information->type = + poly::byte_swap(memory_basic_information->type); XELOGE("NtQueryVirtualMemory NOT IMPLEMENTED"); - return X_STATUS_SUCCESS; + SHIM_SET_RETURN_32(X_STATUS_SUCCESS); } -SHIM_CALL NtQueryVirtualMemory_shim( +SHIM_CALL MmAllocatePhysicalMemoryEx_shim( PPCContext* ppc_state, KernelState* state) { - uint32_t base_address = SHIM_GET_ARG_32(0); - uint32_t memory_basic_information_ptr = SHIM_GET_ARG_32(1); - X_MEMORY_BASIC_INFORMATION *memory_basic_information = (X_MEMORY_BASIC_INFORMATION*)SHIM_MEM_ADDR(memory_basic_information_ptr); + uint32_t type = SHIM_GET_ARG_32(0); + uint32_t region_size = SHIM_GET_ARG_32(1); + uint32_t protect_bits = SHIM_GET_ARG_32(2); + uint32_t min_addr_range = SHIM_GET_ARG_32(3); + uint32_t max_addr_range = SHIM_GET_ARG_32(4); + uint32_t alignment = SHIM_GET_ARG_32(5); XELOGD( - "NtQueryVirtualMemory(%.8X, %.8X)", - base_address, memory_basic_information_ptr); - - X_STATUS result = xeNtQueryVirtualMemory(base_address, memory_basic_information, true); - SHIM_SET_RETURN_32(result); -} - - -uint32_t xeMmAllocatePhysicalMemoryEx( - uint32_t type, uint32_t region_size, uint32_t protect_bits, - uint32_t min_addr_range, uint32_t max_addr_range, uint32_t alignment) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); + "MmAllocatePhysicalMemoryEx(%d, %.8X, %.8X, %.8X, %.8X, %.8X)", + type, region_size, protect_bits, + min_addr_range, max_addr_range, alignment); // Type will usually be 0 (user request?), where 1 and 2 are sometimes made // by D3D/etc. @@ -264,7 +234,8 @@ uint32_t xeMmAllocatePhysicalMemoryEx( // Check protection bits. if (!(protect_bits & (X_PAGE_READONLY | X_PAGE_READWRITE))) { XELOGE("MmAllocatePhysicalMemoryEx: bad protection bits"); - return 0; + SHIM_SET_RETURN_32(0); + return; } // Either may be OR'ed into protect_bits: @@ -302,7 +273,8 @@ uint32_t xeMmAllocatePhysicalMemoryEx( 0, adjusted_size, flags, adjusted_alignment); if (!base_address) { // Failed - assume no memory available. - return 0; + SHIM_SET_RETURN_32(0); + return; } // Move the address into the right range. @@ -315,36 +287,19 @@ uint32_t xeMmAllocatePhysicalMemoryEx( //} base_address += 0xA0000000; - return base_address; -} - - -SHIM_CALL MmAllocatePhysicalMemoryEx_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t type = SHIM_GET_ARG_32(0); - uint32_t region_size = SHIM_GET_ARG_32(1); - uint32_t protect_bits = SHIM_GET_ARG_32(2); - uint32_t min_addr_range = SHIM_GET_ARG_32(3); - uint32_t max_addr_range = SHIM_GET_ARG_32(4); - uint32_t alignment = SHIM_GET_ARG_32(5); - - XELOGD( - "MmAllocatePhysicalMemoryEx(%d, %.8X, %.8X, %.8X, %.8X, %.8X)", - type, region_size, protect_bits, - min_addr_range, max_addr_range, alignment); - - uint32_t base_address = xeMmAllocatePhysicalMemoryEx( - type, region_size, protect_bits, - min_addr_range, max_addr_range, alignment); - SHIM_SET_RETURN_32(base_address); } -void xeMmFreePhysicalMemory(uint32_t type, uint32_t base_address) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); +SHIM_CALL MmFreePhysicalMemory_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t type = SHIM_GET_ARG_32(0); + uint32_t base_address = SHIM_GET_ARG_32(1); + XELOGD( + "MmFreePhysicalAddress(%d, %.8X)", + type, base_address); + // base_address = result of MmAllocatePhysicalMemory. // Strip off physical bits before passing down. @@ -358,29 +313,6 @@ void xeMmFreePhysicalMemory(uint32_t type, uint32_t base_address) { } -SHIM_CALL MmFreePhysicalMemory_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t type = SHIM_GET_ARG_32(0); - uint32_t base_address = SHIM_GET_ARG_32(1); - - XELOGD( - "MmFreePhysicalAddress(%d, %.8X)", - type, base_address); - - xeMmFreePhysicalMemory(type, base_address); -} - - -uint32_t xeMmQueryAddressProtect(uint32_t base_address) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - uint32_t access = state->memory()->QueryProtect(base_address); - - return access; -} - - SHIM_CALL MmQueryAddressProtect_shim( PPCContext* ppc_state, KernelState* state) { uint32_t base_address = SHIM_GET_ARG_32(0); @@ -389,19 +321,9 @@ SHIM_CALL MmQueryAddressProtect_shim( "MmQueryAddressProtect(%.8X)", base_address); - uint32_t result = xeMmQueryAddressProtect(base_address); + uint32_t access = state->memory()->QueryProtect(base_address); - SHIM_SET_RETURN_32(result); -} - - -uint32_t xeMmQueryAllocationSize(uint32_t base_address) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - size_t size = state->memory()->QuerySize(base_address); - - return (uint32_t)size; + SHIM_SET_RETURN_32(access); } @@ -412,10 +334,10 @@ SHIM_CALL MmQueryAllocationSize_shim( XELOGD( "MmQueryAllocationSize(%.8X)", base_address); + + size_t size = state->memory()->QuerySize(base_address); - uint32_t result = xeMmQueryAllocationSize(base_address); - - SHIM_SET_RETURN_32(result); + SHIM_SET_RETURN_32(static_cast(size)); } @@ -427,7 +349,7 @@ SHIM_CALL MmQueryStatistics_shim( "MmQueryStatistics(%.8X)", stats_ptr); -uint32_t size = SHIM_MEM_32(stats_ptr + 0); + uint32_t size = SHIM_MEM_32(stats_ptr + 0); if (size != 104) { SHIM_SET_RETURN_32(X_STATUS_BUFFER_TOO_SMALL); return; @@ -475,7 +397,14 @@ uint32_t size = SHIM_MEM_32(stats_ptr + 0); // http://msdn.microsoft.com/en-us/library/windows/hardware/ff554547(v=vs.85).aspx -uint32_t xeMmGetPhysicalAddress(uint32_t base_address) { +SHIM_CALL MmGetPhysicalAddress_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t base_address = SHIM_GET_ARG_32(0); + + XELOGD( + "MmGetPhysicalAddress(%.8X)", + base_address); + // PHYSICAL_ADDRESS MmGetPhysicalAddress( // _In_ PVOID BaseAddress // ); @@ -493,21 +422,7 @@ uint32_t xeMmGetPhysicalAddress(uint32_t base_address) { base_address |= 0xE0000000; }*/ - return base_address; -} - - -SHIM_CALL MmGetPhysicalAddress_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t base_address = SHIM_GET_ARG_32(0); - - XELOGD( - "MmGetPhysicalAddress(%.8X)", - base_address); - - uint32_t result = xeMmGetPhysicalAddress(base_address); - - SHIM_SET_RETURN_32(result); + SHIM_SET_RETURN_32(base_address); } @@ -536,7 +451,6 @@ SHIM_CALL ExAllocatePoolTypeWithTag_shim( } - SHIM_CALL ExFreePool_shim( PPCContext* ppc_state, KernelState* state) { uint32_t base_address = SHIM_GET_ARG_32(0); diff --git a/src/xenia/kernel/xboxkrnl_modules.cc b/src/xenia/kernel/xboxkrnl_modules.cc index f38a6d0f8..bc659eb55 100644 --- a/src/xenia/kernel/xboxkrnl_modules.cc +++ b/src/xenia/kernel/xboxkrnl_modules.cc @@ -133,9 +133,13 @@ SHIM_CALL ExGetXConfigSetting_shim( } -int xeXexCheckExecutablePriviledge(uint32_t privilege) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); +SHIM_CALL XexCheckExecutablePrivilege_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t privilege = SHIM_GET_ARG_32(0); + + XELOGD( + "XexCheckExecutablePrivilege(%.8X)", + privilege); // BOOL // DWORD Privilege @@ -146,7 +150,8 @@ int xeXexCheckExecutablePriviledge(uint32_t privilege) { XUserModule* module = state->GetExecutableModule(); if (!module) { - return 0; + SHIM_SET_RETURN_32(0); + return; } xe_xex2_ref xex = module->xex(); @@ -156,47 +161,10 @@ int xeXexCheckExecutablePriviledge(uint32_t privilege) { xe_xex2_release(xex); module->Release(); - return result; -} - - -SHIM_CALL XexCheckExecutablePrivilege_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t privilege = SHIM_GET_ARG_32(0); - - XELOGD( - "XexCheckExecutablePrivilege(%.8X)", - privilege); - - int result = xeXexCheckExecutablePriviledge(privilege); - SHIM_SET_RETURN_32(result); } -int xeXexGetModuleHandle(const char* module_name, - X_HANDLE* module_handle_ptr) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - // BOOL - // LPCSZ ModuleName - // LPHMODULE ModuleHandle - - XModule* module = state->GetModule(module_name); - if (!module) { - return 0; - } - - // NOTE: we don't retain the handle for return. - *module_handle_ptr = module->handle(); - - module->Release(); - - return 1; -} - - SHIM_CALL XexGetModuleHandle_shim( PPCContext* ppc_state, KernelState* state) { uint32_t module_name_ptr = SHIM_GET_ARG_32(0); @@ -207,11 +175,18 @@ SHIM_CALL XexGetModuleHandle_shim( "XexGetModuleHandle(%s, %.8X)", module_name, module_handle_ptr); - X_HANDLE module_handle = 0; - int result = xeXexGetModuleHandle(module_name, &module_handle); - SHIM_SET_MEM_32(module_handle_ptr, module_handle); + XModule* module = state->GetModule(module_name); + if (!module) { + SHIM_SET_RETURN_32(X_ERROR_NOT_FOUND); + return; + } - SHIM_SET_RETURN_32(result); + // NOTE: we don't retain the handle for return. + SHIM_SET_MEM_32(module_handle_ptr, module->handle()); + + module->Release(); + + SHIM_SET_RETURN_32(X_ERROR_SUCCESS); } diff --git a/src/xenia/kernel/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl_rtl.cc index 1b23dafc6..9c9285026 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl_rtl.cc @@ -27,45 +27,24 @@ namespace xe { namespace kernel { -//RtlCompareMemory -struct x { -}; - -struct RtlCompareMemoryExport { - KernelState* state; - static void Call(PPCContext* ppc_state) { - uint32_t source1 = SHIM_GET_ARG_32(0); - uint32_t source2 = SHIM_GET_ARG_32(1); - uint32_t length = SHIM_GET_ARG_32(2); - - XELOGD( - "RtlCompareMemory(%.8X, %.8X, %d)", - source1, source2, length); - - uint32_t result = 0; - SHIM_SET_RETURN_64(result); - } - virtual void Log() { - // - } - X_STATUS RtlCompareMemory(uint32_t source1_ptr, uint32_t source2_ptr, uint32_t length) { - } -}; - - // http://msdn.microsoft.com/en-us/library/ff561778 -uint32_t xeRtlCompareMemory(uint32_t source1_ptr, uint32_t source2_ptr, - uint32_t length) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); +SHIM_CALL RtlCompareMemory_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t source1_ptr = SHIM_GET_ARG_32(0); + uint32_t source2_ptr = SHIM_GET_ARG_32(1); + uint32_t length = SHIM_GET_ARG_32(2); + + XELOGD( + "RtlCompareMemory(%.8X, %.8X, %d)", + source1_ptr, source2_ptr, length); // SIZE_T // _In_ const VOID *Source1, // _In_ const VOID *Source2, // _In_ SIZE_T Length - uint8_t* p1 = IMPL_MEM_ADDR(source1_ptr); - uint8_t* p2 = IMPL_MEM_ADDR(source2_ptr); + uint8_t* p1 = SHIM_MEM_ADDR(source1_ptr); + uint8_t* p2 = SHIM_MEM_ADDR(source2_ptr); // Note that the return value is the number of bytes that match, so it's best // we just do this ourselves vs. using memcmp. @@ -78,30 +57,20 @@ uint32_t xeRtlCompareMemory(uint32_t source1_ptr, uint32_t source2_ptr, } } - return c; -} - - -SHIM_CALL RtlCompareMemory_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t source1 = SHIM_GET_ARG_32(0); - uint32_t source2 = SHIM_GET_ARG_32(1); - uint32_t length = SHIM_GET_ARG_32(2); - - XELOGD( - "RtlCompareMemory(%.8X, %.8X, %d)", - source1, source2, length); - - uint32_t result = xeRtlCompareMemory(source1, source2, length); - SHIM_SET_RETURN_64(result); + SHIM_SET_RETURN_64(c); } // http://msdn.microsoft.com/en-us/library/ff552123 -uint32_t xeRtlCompareMemoryUlong(uint32_t source_ptr, uint32_t length, - uint32_t pattern) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); +SHIM_CALL RtlCompareMemoryUlong_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t source_ptr = SHIM_GET_ARG_32(0); + uint32_t length = SHIM_GET_ARG_32(1); + uint32_t pattern = SHIM_GET_ARG_32(2); + + XELOGD( + "RtlCompareMemoryUlong(%.8X, %d, %.8X)", + source_ptr, length, pattern); // SIZE_T // _In_ PVOID Source, @@ -109,10 +78,11 @@ uint32_t xeRtlCompareMemoryUlong(uint32_t source_ptr, uint32_t length, // _In_ ULONG Pattern if ((source_ptr % 4) || (length % 4)) { - return 0; + SHIM_SET_RETURN_64(0); + return; } - uint8_t* p = IMPL_MEM_ADDR(source_ptr); + uint8_t* p = SHIM_MEM_ADDR(source_ptr); // Swap pattern. // TODO(benvanik): ensure byte order of pattern is correct. @@ -128,30 +98,20 @@ uint32_t xeRtlCompareMemoryUlong(uint32_t source_ptr, uint32_t length, } } - return c; -} - - -SHIM_CALL RtlCompareMemoryUlong_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t source = SHIM_GET_ARG_32(0); - uint32_t length = SHIM_GET_ARG_32(1); - uint32_t pattern = SHIM_GET_ARG_32(2); - - XELOGD( - "RtlCompareMemoryUlong(%.8X, %d, %.8X)", - source, length, pattern); - - uint32_t result = xeRtlCompareMemoryUlong(source, length, pattern); - SHIM_SET_RETURN_64(result); + SHIM_SET_RETURN_64(c); } // http://msdn.microsoft.com/en-us/library/ff552263 -void xeRtlFillMemoryUlong(uint32_t destination_ptr, uint32_t length, - uint32_t pattern) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); +SHIM_CALL RtlFillMemoryUlong_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t destination_ptr = SHIM_GET_ARG_32(0); + uint32_t length = SHIM_GET_ARG_32(1); + uint32_t pattern = SHIM_GET_ARG_32(2); + + XELOGD( + "RtlFillMemoryUlong(%.8X, %d, %.8X)", + destination_ptr, length, pattern); // VOID // _Out_ PVOID Destination, @@ -159,7 +119,7 @@ void xeRtlFillMemoryUlong(uint32_t destination_ptr, uint32_t length, // _In_ ULONG Pattern // NOTE: length must be % 4, so we can work on uint32s. - uint32_t* p = (uint32_t*)IMPL_MEM_ADDR(destination_ptr); + uint32_t* p = (uint32_t*)SHIM_MEM_ADDR(destination_ptr); // TODO(benvanik): ensure byte order is correct - we're writing back the // swapped arg value. @@ -175,20 +135,6 @@ void xeRtlFillMemoryUlong(uint32_t destination_ptr, uint32_t length, } -SHIM_CALL RtlFillMemoryUlong_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t destination = SHIM_GET_ARG_32(0); - uint32_t length = SHIM_GET_ARG_32(1); - uint32_t pattern = SHIM_GET_ARG_32(2); - - XELOGD( - "RtlFillMemoryUlong(%.8X, %d, %.8X)", - destination, length, pattern); - - xeRtlFillMemoryUlong(destination, length, pattern); -} - - // typedef struct _STRING { // USHORT Length; // USHORT MaximumLength; @@ -197,27 +143,6 @@ SHIM_CALL RtlFillMemoryUlong_shim( // http://msdn.microsoft.com/en-us/library/ff561918 -void xeRtlInitAnsiString(uint32_t destination_ptr, uint32_t source_ptr) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - // VOID - // _Out_ PANSI_STRING DestinationString, - // _In_opt_ PCSZ SourceString - - if (source_ptr != 0) { - const char* source = (char*)IMPL_MEM_ADDR(source_ptr); - uint16_t length = (uint16_t)xestrlena(source); - IMPL_SET_MEM_16(destination_ptr + 0, length); - IMPL_SET_MEM_16(destination_ptr + 2, length + 1); - } else { - IMPL_SET_MEM_16(destination_ptr + 0, 0); - IMPL_SET_MEM_16(destination_ptr + 2, 0); - } - IMPL_SET_MEM_32(destination_ptr + 4, source_ptr); -} - - SHIM_CALL RtlInitAnsiString_shim( PPCContext* ppc_state, KernelState* state) { uint32_t destination_ptr = SHIM_GET_ARG_32(0); @@ -227,38 +152,43 @@ SHIM_CALL RtlInitAnsiString_shim( XELOGD("RtlInitAnsiString(%.8X, %.8X = %s)", destination_ptr, source_ptr, source ? source : ""); - xeRtlInitAnsiString(destination_ptr, source_ptr); + // VOID + // _Out_ PANSI_STRING DestinationString, + // _In_opt_ PCSZ SourceString + + if (source_ptr != 0) { + const char* source = (char*)SHIM_MEM_ADDR(source_ptr); + uint16_t length = (uint16_t)xestrlena(source); + SHIM_SET_MEM_16(destination_ptr + 0, length); + SHIM_SET_MEM_16(destination_ptr + 2, length + 1); + } else { + SHIM_SET_MEM_16(destination_ptr + 0, 0); + SHIM_SET_MEM_16(destination_ptr + 2, 0); + } + SHIM_SET_MEM_32(destination_ptr + 4, source_ptr); } // http://msdn.microsoft.com/en-us/library/ff561899 -void xeRtlFreeAnsiString(uint32_t string_ptr) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - // VOID - // _Inout_ PANSI_STRING AnsiString - - uint32_t buffer = IMPL_MEM_32(string_ptr + 4); - if (!buffer) { - return; - } - uint32_t length = IMPL_MEM_16(string_ptr + 2); - state->memory()->HeapFree(buffer, length); - - IMPL_SET_MEM_16(string_ptr + 0, 0); - IMPL_SET_MEM_16(string_ptr + 2, 0); - IMPL_SET_MEM_32(string_ptr + 4, 0); -} - - SHIM_CALL RtlFreeAnsiString_shim( PPCContext* ppc_state, KernelState* state) { uint32_t string_ptr = SHIM_GET_ARG_32(0); XELOGD("RtlFreeAnsiString(%.8X)", string_ptr); - xeRtlFreeAnsiString(string_ptr); + // VOID + // _Inout_ PANSI_STRING AnsiString + + uint32_t buffer = SHIM_MEM_32(string_ptr + 4); + if (!buffer) { + return; + } + uint32_t length = SHIM_MEM_16(string_ptr + 2); + state->memory()->HeapFree(buffer, length); + + SHIM_SET_MEM_16(string_ptr + 0, 0); + SHIM_SET_MEM_16(string_ptr + 2, 0); + SHIM_SET_MEM_32(string_ptr + 4, 0); } @@ -270,30 +200,6 @@ SHIM_CALL RtlFreeAnsiString_shim( // http://msdn.microsoft.com/en-us/library/ff561934 -void xeRtlInitUnicodeString(uint32_t destination_ptr, uint32_t source_ptr) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - // VOID - // _Out_ PUNICODE_STRING DestinationString, - // _In_opt_ PCWSTR SourceString - - const wchar_t* source = - source_ptr ? (const wchar_t*)IMPL_MEM_ADDR(source_ptr) : NULL; - - if (source) { - uint16_t length = (uint16_t)xestrlenw(source); - IMPL_SET_MEM_16(destination_ptr + 0, length * 2); - IMPL_SET_MEM_16(destination_ptr + 2, (length + 1) * 2); - IMPL_SET_MEM_32(destination_ptr + 4, source_ptr); - } else { - IMPL_SET_MEM_16(destination_ptr + 0, 0); - IMPL_SET_MEM_16(destination_ptr + 2, 0); - IMPL_SET_MEM_32(destination_ptr + 4, 0); - } -} - - SHIM_CALL RtlInitUnicodeString_shim( PPCContext* ppc_state, KernelState* state) { uint32_t destination_ptr = SHIM_GET_ARG_32(0); @@ -304,85 +210,47 @@ SHIM_CALL RtlInitUnicodeString_shim( XELOGD("RtlInitUnicodeString(%.8X, %.8X = %ls)", destination_ptr, source_ptr, source ? source : L""); - xeRtlInitUnicodeString(destination_ptr, source_ptr); + // VOID + // _Out_ PUNICODE_STRING DestinationString, + // _In_opt_ PCWSTR SourceString + + if (source) { + uint16_t length = (uint16_t)xestrlenw(source); + SHIM_SET_MEM_16(destination_ptr + 0, length * 2); + SHIM_SET_MEM_16(destination_ptr + 2, (length + 1) * 2); + SHIM_SET_MEM_32(destination_ptr + 4, source_ptr); + } else { + SHIM_SET_MEM_16(destination_ptr + 0, 0); + SHIM_SET_MEM_16(destination_ptr + 2, 0); + SHIM_SET_MEM_32(destination_ptr + 4, 0); + } } // http://msdn.microsoft.com/en-us/library/ff561903 -void xeRtlFreeUnicodeString(uint32_t string_ptr) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - // VOID - // _Inout_ PUNICODE_STRING UnicodeString - - uint32_t buffer = IMPL_MEM_32(string_ptr + 4); - if (!buffer) { - return; - } - uint32_t length = IMPL_MEM_16(string_ptr + 2); - state->memory()->HeapFree(buffer, length); - - IMPL_SET_MEM_16(string_ptr + 0, 0); - IMPL_SET_MEM_16(string_ptr + 2, 0); - IMPL_SET_MEM_32(string_ptr + 4, 0); -} - - SHIM_CALL RtlFreeUnicodeString_shim( PPCContext* ppc_state, KernelState* state) { uint32_t string_ptr = SHIM_GET_ARG_32(0); XELOGD("RtlFreeUnicodeString(%.8X)", string_ptr); - xeRtlFreeUnicodeString(string_ptr); + // VOID + // _Inout_ PUNICODE_STRING UnicodeString + + uint32_t buffer = SHIM_MEM_32(string_ptr + 4); + if (!buffer) { + return; + } + uint32_t length = SHIM_MEM_16(string_ptr + 2); + state->memory()->HeapFree(buffer, length); + + SHIM_SET_MEM_16(string_ptr + 0, 0); + SHIM_SET_MEM_16(string_ptr + 2, 0); + SHIM_SET_MEM_32(string_ptr + 4, 0); } // http://msdn.microsoft.com/en-us/library/ff562969 -X_STATUS xeRtlUnicodeStringToAnsiString(uint32_t destination_ptr, - uint32_t source_ptr, - uint32_t alloc_dest) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - // NTSTATUS - // _Inout_ PANSI_STRING DestinationString, - // _In_ PCUNICODE_STRING SourceString, - // _In_ BOOLEAN AllocateDestinationString - - std::wstring unicode_str = poly::load_and_swap( - IMPL_MEM_ADDR(IMPL_MEM_32(source_ptr + 4))); - std::string ansi_str = poly::to_string(unicode_str); - if (ansi_str.size() > 0xFFFF - 1) { - return X_STATUS_INVALID_PARAMETER_2; - } - - X_STATUS result = X_STATUS_SUCCESS; - if (alloc_dest) { - auto buffer_ptr = state->memory()->HeapAlloc(0, ansi_str.size() + 1, 0); - memcpy(IMPL_MEM_ADDR(buffer_ptr), ansi_str.data(), ansi_str.size() + 1); - IMPL_SET_MEM_16(destination_ptr + 0, - static_cast(ansi_str.size())); - IMPL_SET_MEM_16(destination_ptr + 2, - static_cast(ansi_str.size() + 1)); - IMPL_SET_MEM_32(destination_ptr + 4, static_cast(buffer_ptr)); - } else { - uint32_t buffer_capacity = IMPL_MEM_16(destination_ptr + 2); - uint32_t buffer_ptr = IMPL_MEM_32(destination_ptr + 4); - if (buffer_capacity < ansi_str.size() + 1) { - // Too large - we just write what we can. - result = X_STATUS_BUFFER_OVERFLOW; - memcpy(IMPL_MEM_ADDR(buffer_ptr), ansi_str.data(), buffer_capacity - 1); - } else { - memcpy(IMPL_MEM_ADDR(buffer_ptr), ansi_str.data(), ansi_str.size() + 1); - } - IMPL_SET_MEM_8(buffer_ptr + buffer_capacity - 1, 0); // \0 - } - return result; -} - - SHIM_CALL RtlUnicodeStringToAnsiString_shim( PPCContext* ppc_state, KernelState* state) { uint32_t destination_ptr = SHIM_GET_ARG_32(0); @@ -392,8 +260,40 @@ SHIM_CALL RtlUnicodeStringToAnsiString_shim( XELOGD("RtlUnicodeStringToAnsiString(%.8X, %.8X, %d)", destination_ptr, source_ptr, alloc_dest); - X_STATUS result = xeRtlUnicodeStringToAnsiString( - destination_ptr, source_ptr, alloc_dest); + // NTSTATUS + // _Inout_ PANSI_STRING DestinationString, + // _In_ PCUNICODE_STRING SourceString, + // _In_ BOOLEAN AllocateDestinationString + + std::wstring unicode_str = poly::load_and_swap( + SHIM_MEM_ADDR(SHIM_MEM_32(source_ptr + 4))); + std::string ansi_str = poly::to_string(unicode_str); + if (ansi_str.size() > 0xFFFF - 1) { + SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER_2); + return; + } + + X_STATUS result = X_STATUS_SUCCESS; + if (alloc_dest) { + auto buffer_ptr = state->memory()->HeapAlloc(0, ansi_str.size() + 1, 0); + memcpy(SHIM_MEM_ADDR(buffer_ptr), ansi_str.data(), ansi_str.size() + 1); + SHIM_SET_MEM_16(destination_ptr + 0, + static_cast(ansi_str.size())); + SHIM_SET_MEM_16(destination_ptr + 2, + static_cast(ansi_str.size() + 1)); + SHIM_SET_MEM_32(destination_ptr + 4, static_cast(buffer_ptr)); + } else { + uint32_t buffer_capacity = SHIM_MEM_16(destination_ptr + 2); + uint32_t buffer_ptr = SHIM_MEM_32(destination_ptr + 4); + if (buffer_capacity < ansi_str.size() + 1) { + // Too large - we just write what we can. + result = X_STATUS_BUFFER_OVERFLOW; + memcpy(SHIM_MEM_ADDR(buffer_ptr), ansi_str.data(), buffer_capacity - 1); + } else { + memcpy(SHIM_MEM_ADDR(buffer_ptr), ansi_str.data(), ansi_str.size() + 1); + } + SHIM_SET_MEM_8(buffer_ptr + buffer_capacity - 1, 0); // \0 + } SHIM_SET_RETURN_32(result); } @@ -457,22 +357,6 @@ SHIM_CALL RtlUnicodeToMultiByteN_shim( } -uint32_t xeRtlNtStatusToDosError(X_STATUS status) { - if (!status || (status & 0x20000000)) { - // Success. - return status; - } else if ((status & 0xF0000000) == 0xD0000000) { - // High bit doesn't matter. - status &= ~0x10000000; - } - - // TODO(benvanik): implement lookup table. - XELOGE("RtlNtStatusToDosError lookup NOT IMPLEMENTED"); - - return 317; // ERROR_MR_MID_NOT_FOUND -} - - SHIM_CALL RtlNtStatusToDosError_shim( PPCContext* ppc_state, KernelState* state) { uint32_t status = SHIM_GET_ARG_32(0); @@ -481,15 +365,39 @@ SHIM_CALL RtlNtStatusToDosError_shim( "RtlNtStatusToDosError(%.4X)", status); - uint32_t result = xeRtlNtStatusToDosError(status); + if (!status || (status & 0x20000000)) { + // Success. + SHIM_SET_RETURN_32(0); + return; + } else if ((status & 0xF0000000) == 0xD0000000) { + // High bit doesn't matter. + status &= ~0x10000000; + } + + // TODO(benvanik): implement lookup table. + XELOGE("RtlNtStatusToDosError lookup NOT SHIMEMENTED"); + + uint32_t result = 317; // ERROR_MR_MID_NOT_FOUND + SHIM_SET_RETURN_32(result); } -uint32_t xeRtlImageXexHeaderField(uint32_t xex_header_base_ptr, - uint32_t image_field) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); +SHIM_CALL RtlImageXexHeaderField_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t xex_header_base = SHIM_GET_ARG_32(0); + uint32_t image_field = SHIM_GET_ARG_32(1); + + // NOTE: this is totally faked! + // We set the XexExecutableModuleHandle pointer to a block that has at offset + // 0x58 a pointer to our XexHeaderBase. If the value passed doesn't match + // then die. + // The only ImageField I've seen in the wild is + // 0x20401 (XEX_HEADER_DEFAULT_HEAP_SIZE), so that's all we'll support. + + XELOGD( + "RtlImageXexHeaderField(%.8X, %.8X)", + xex_header_base, image_field); // PVOID // PVOID XexHeaderBase @@ -512,34 +420,15 @@ uint32_t xeRtlImageXexHeaderField(uint32_t xex_header_base_ptr, const xe_xex2_header_t* xex_header = module->xex_header(); for (size_t n = 0; n < xex_header->header_count; n++) { if (xex_header->headers[n].key == image_field) { + uint32_t value = xex_header->headers[n].value; module->Release(); - return xex_header->headers[n].value; + SHIM_SET_RETURN_64(value); + return; } } module->Release(); - return 0; -} - - -SHIM_CALL RtlImageXexHeaderField_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t xex_header_base = SHIM_GET_ARG_32(0); - uint32_t image_field = SHIM_GET_ARG_32(1); - - // NOTE: this is totally faked! - // We set the XexExecutableModuleHandle pointer to a block that has at offset - // 0x58 a pointer to our XexHeaderBase. If the value passed doesn't match - // then die. - // The only ImageField I've seen in the wild is - // 0x20401 (XEX_HEADER_DEFAULT_HEAP_SIZE), so that's all we'll support. - - XELOGD( - "RtlImageXexHeaderField(%.8X, %.8X)", - xex_header_base, image_field); - - uint32_t result = xeRtlImageXexHeaderField(xex_header_base, image_field); - SHIM_SET_RETURN_64(result); + SHIM_SET_RETURN_64(0); } @@ -560,9 +449,8 @@ SHIM_CALL RtlImageXexHeaderField_shim( // This structure tries to match the one on the 360 as best I can figure out. // Unfortunately some games have the critical sections pre-initialized in // their embedded data and InitializeCriticalSection will never be called. -namespace { #pragma pack(push, 1) -typedef struct { +struct X_RTL_CRITICAL_SECTION { uint8_t unknown00; uint8_t spin_count_div_256; // * 256 uint8_t __padding[6]; @@ -572,20 +460,14 @@ typedef struct { int32_t lock_count; // -1 -> 0 on first lock 0x10 uint32_t recursion_count; // 0 -> 1 on first lock 0x14 uint32_t owning_thread_id; // 0 unless locked 0x18 -} X_RTL_CRITICAL_SECTION; +}; #pragma pack(pop) -} - static_assert_size(X_RTL_CRITICAL_SECTION, 28); -void xeRtlInitializeCriticalSection(uint32_t cs_ptr) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - +void xeRtlInitializeCriticalSection(X_RTL_CRITICAL_SECTION* cs) { // VOID // _Out_ LPCRITICAL_SECTION lpCriticalSection - X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)IMPL_MEM_ADDR(cs_ptr); cs->unknown00 = 1; cs->spin_count_div_256 = 0; cs->lock_count = -1; @@ -600,15 +482,13 @@ SHIM_CALL RtlInitializeCriticalSection_shim( XELOGD("RtlInitializeCriticalSection(%.8X)", cs_ptr); - xeRtlInitializeCriticalSection(cs_ptr); + auto cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr); + xeRtlInitializeCriticalSection(cs); } X_STATUS xeRtlInitializeCriticalSectionAndSpinCount( - uint32_t cs_ptr, uint32_t spin_count) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - + X_RTL_CRITICAL_SECTION* cs, uint32_t spin_count) { // NTSTATUS // _Out_ LPCRITICAL_SECTION lpCriticalSection, // _In_ DWORD dwSpinCount @@ -620,7 +500,6 @@ X_STATUS xeRtlInitializeCriticalSectionAndSpinCount( spin_count_div_256 = 255; } - X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)IMPL_MEM_ADDR(cs_ptr); cs->unknown00 = 1; cs->spin_count_div_256 = spin_count_div_256; cs->lock_count = -1; @@ -639,22 +518,18 @@ SHIM_CALL RtlInitializeCriticalSectionAndSpinCount_shim( XELOGD("RtlInitializeCriticalSectionAndSpinCount(%.8X, %d)", cs_ptr, spin_count); + auto cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr); X_STATUS result = xeRtlInitializeCriticalSectionAndSpinCount( - cs_ptr, spin_count); + cs, spin_count); SHIM_SET_RETURN_32(result); } // TODO(benvanik): remove the need for passing in thread_id. -void xeRtlEnterCriticalSection(uint32_t cs_ptr, uint32_t thread_id) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - +void xeRtlEnterCriticalSection(X_RTL_CRITICAL_SECTION* cs, uint32_t thread_id) { // VOID // _Inout_ LPCRITICAL_SECTION lpCriticalSection - X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)IMPL_MEM_ADDR(cs_ptr); - uint32_t spin_wait_remaining = cs->spin_count_div_256 * 256; spin: if (poly::atomic_inc(&cs->lock_count) != 0) { @@ -693,20 +568,16 @@ SHIM_CALL RtlEnterCriticalSection_shim( const uint8_t* thread_state_block = ppc_state->membase + ppc_state->r[13]; uint32_t thread_id = XThread::GetCurrentThreadId(thread_state_block); - xeRtlEnterCriticalSection(cs_ptr, thread_id); + auto cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr); + xeRtlEnterCriticalSection(cs, thread_id); } // TODO(benvanik): remove the need for passing in thread_id. -uint32_t xeRtlTryEnterCriticalSection(uint32_t cs_ptr, uint32_t thread_id) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - +uint32_t xeRtlTryEnterCriticalSection(X_RTL_CRITICAL_SECTION* cs, uint32_t thread_id) { // DWORD // _Inout_ LPCRITICAL_SECTION lpCriticalSection - X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)IMPL_MEM_ADDR(cs_ptr); - if (poly::atomic_cas(-1, 0, &cs->lock_count)) { // Able to steal the lock right away. cs->owning_thread_id = thread_id; @@ -731,20 +602,16 @@ SHIM_CALL RtlTryEnterCriticalSection_shim( const uint8_t* thread_state_block = ppc_state->membase + ppc_state->r[13]; uint32_t thread_id = XThread::GetCurrentThreadId(thread_state_block); - uint32_t result = xeRtlTryEnterCriticalSection(cs_ptr, thread_id); + auto cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr); + uint32_t result = xeRtlTryEnterCriticalSection(cs, thread_id); SHIM_SET_RETURN_64(result); } -void xeRtlLeaveCriticalSection(uint32_t cs_ptr) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - +void xeRtlLeaveCriticalSection(X_RTL_CRITICAL_SECTION* cs) { // VOID // _Inout_ LPCRITICAL_SECTION lpCriticalSection - X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)IMPL_MEM_ADDR(cs_ptr); - // Drop recursion count - if we are still not zero'ed return. uint32_t recursion_count = --cs->recursion_count; if (recursion_count) { @@ -768,7 +635,8 @@ SHIM_CALL RtlLeaveCriticalSection_shim( // XELOGD("RtlLeaveCriticalSection(%.8X)", cs_ptr); - xeRtlLeaveCriticalSection(cs_ptr); + auto cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr); + xeRtlLeaveCriticalSection(cs); } diff --git a/src/xenia/kernel/xboxkrnl_rtl.h b/src/xenia/kernel/xboxkrnl_rtl.h index d462516e9..fa959bc3a 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.h +++ b/src/xenia/kernel/xboxkrnl_rtl.h @@ -14,21 +14,20 @@ #include #include - namespace xe { namespace kernel { +struct X_RTL_CRITICAL_SECTION; -void xeRtlInitializeCriticalSection(uint32_t cs_ptr); -X_STATUS xeRtlInitializeCriticalSectionAndSpinCount( - uint32_t cs_ptr, uint32_t spin_count); -void xeRtlEnterCriticalSection(uint32_t cs_ptr, uint32_t thread_id); -uint32_t xeRtlTryEnterCriticalSection(uint32_t cs_ptr, uint32_t thread_id); -void xeRtlLeaveCriticalSection(uint32_t cs_ptr); - +void xeRtlInitializeCriticalSection(X_RTL_CRITICAL_SECTION* cs); +X_STATUS xeRtlInitializeCriticalSectionAndSpinCount(X_RTL_CRITICAL_SECTION* cs, + uint32_t spin_count); +void xeRtlEnterCriticalSection(X_RTL_CRITICAL_SECTION* cs, uint32_t thread_id); +uint32_t xeRtlTryEnterCriticalSection(X_RTL_CRITICAL_SECTION* cs, + uint32_t thread_id); +void xeRtlLeaveCriticalSection(X_RTL_CRITICAL_SECTION* cs); } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_RTL_H_ diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index c4a087187..517345552 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -66,44 +66,6 @@ namespace kernel { // } -X_STATUS xeExCreateThread( - uint32_t* handle_ptr, uint32_t stack_size, uint32_t* thread_id_ptr, - uint32_t xapi_thread_startup, - uint32_t start_address, uint32_t start_context, uint32_t creation_flags) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - // DWORD - // LPHANDLE Handle, - // DWORD StackSize, - // LPDWORD ThreadId, - // LPVOID XapiThreadStartup, ?? often 0 - // LPVOID StartAddress, - // LPVOID StartContext, - // DWORD CreationFlags // 0x80? - - XThread* thread = new XThread( - state, stack_size, xapi_thread_startup, start_address, start_context, - creation_flags); - - X_STATUS result_code = thread->Create(); - if (XFAILED(result_code)) { - // Failed! - thread->Release(); - XELOGE("Thread creation failed: %.8X", result_code); - return result_code; - } - - if (handle_ptr) { - *handle_ptr = thread->handle(); - } - if (thread_id_ptr) { - *thread_id_ptr = thread->thread_id(); - } - return result_code; -} - - SHIM_CALL ExCreateThread_shim( PPCContext* ppc_state, KernelState* state) { uint32_t handle_ptr = SHIM_GET_ARG_32(0); @@ -124,18 +86,34 @@ SHIM_CALL ExCreateThread_shim( start_context, creation_flags); - uint32_t handle; - uint32_t thread_id; - X_STATUS result = xeExCreateThread( - &handle, stack_size, &thread_id, xapi_thread_startup, - start_address, start_context, creation_flags); + // DWORD + // LPHANDLE Handle, + // DWORD StackSize, + // LPDWORD ThreadId, + // LPVOID XapiThreadStartup, ?? often 0 + // LPVOID StartAddress, + // LPVOID StartContext, + // DWORD CreationFlags // 0x80? + + XThread* thread = new XThread( + state, stack_size, xapi_thread_startup, start_address, start_context, + creation_flags); + + X_STATUS result = thread->Create(); + if (XFAILED(result)) { + // Failed! + thread->Release(); + XELOGE("Thread creation failed: %.8X", result); + SHIM_SET_RETURN_32(result); + return; + } if (XSUCCEEDED(result)) { if (handle_ptr) { - SHIM_SET_MEM_32(handle_ptr, handle); + SHIM_SET_MEM_32(handle_ptr, thread->handle()); } if (thread_id_ptr) { - SHIM_SET_MEM_32(thread_id_ptr, thread_id); + SHIM_SET_MEM_32(thread_id_ptr, thread->thread_id()); } } SHIM_SET_RETURN_32(result); @@ -158,24 +136,6 @@ SHIM_CALL ExTerminateThread_shim( } -X_STATUS xeNtResumeThread(uint32_t handle, uint32_t* out_suspend_count) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - X_STATUS result = X_STATUS_SUCCESS; - - XThread* thread = NULL; - result = state->object_table()->GetObject( - handle, (XObject**)&thread); - if (XSUCCEEDED(result)) { - result = thread->Resume(out_suspend_count); - thread->Release(); - } - - return result; -} - - SHIM_CALL NtResumeThread_shim( PPCContext* ppc_state, KernelState* state) { uint32_t handle = SHIM_GET_ARG_32(0); @@ -186,8 +146,14 @@ SHIM_CALL NtResumeThread_shim( handle, suspend_count_ptr); + XThread* thread = NULL; + X_STATUS result = state->object_table()->GetObject( + handle, (XObject**)&thread); uint32_t suspend_count; - X_STATUS result = xeNtResumeThread(handle, &suspend_count); + if (XSUCCEEDED(result)) { + result = thread->Resume(&suspend_count); + thread->Release(); + } if (XSUCCEEDED(result)) { if (suspend_count_ptr) { SHIM_SET_MEM_32(suspend_count_ptr, suspend_count); @@ -198,34 +164,22 @@ SHIM_CALL NtResumeThread_shim( } -X_STATUS xeKeResumeThread(void* thread_ptr, uint32_t* out_suspend_count) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - X_STATUS result = X_STATUS_SUCCESS; - - XThread* thread = (XThread*)XObject::GetObject(state, thread_ptr); - if (thread) { - result = thread->Resume(out_suspend_count); - } - - return result; -} - - SHIM_CALL KeResumeThread_shim( PPCContext* ppc_state, KernelState* state) { - uint32_t thread = SHIM_GET_ARG_32(0); + uint32_t thread_ptr = SHIM_GET_ARG_32(0); uint32_t suspend_count_ptr = SHIM_GET_ARG_32(1); XELOGD( "KeResumeThread(%.8X, %.8X)", - thread, + thread_ptr, suspend_count_ptr); - void* thread_ptr = SHIM_MEM_ADDR(thread); + X_STATUS result; + XThread* thread = (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); uint32_t suspend_count; - X_STATUS result = xeKeResumeThread(thread_ptr, &suspend_count); + if (thread) { + result = thread->Resume(&suspend_count); + } if (XSUCCEEDED(result)) { if (suspend_count_ptr) { SHIM_SET_MEM_32(suspend_count_ptr, suspend_count); @@ -236,24 +190,6 @@ SHIM_CALL KeResumeThread_shim( } -X_STATUS xeNtSuspendThread(uint32_t handle, uint32_t* out_suspend_count) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - X_STATUS result = X_STATUS_SUCCESS; - - XThread* thread = NULL; - result = state->object_table()->GetObject( - handle, (XObject**)&thread); - if (XSUCCEEDED(result)) { - result = thread->Suspend(out_suspend_count); - thread->Release(); - } - - return result; -} - - SHIM_CALL NtSuspendThread_shim( PPCContext* ppc_state, KernelState* state) { uint32_t handle = SHIM_GET_ARG_32(0); @@ -264,8 +200,15 @@ SHIM_CALL NtSuspendThread_shim( handle, suspend_count_ptr); + XThread* thread = NULL; + X_STATUS result = state->object_table()->GetObject( + handle, (XObject**)&thread); uint32_t suspend_count; - X_STATUS result = xeNtSuspendThread(handle, &suspend_count); + if (XSUCCEEDED(result)) { + result = thread->Suspend(&suspend_count); + thread->Release(); + } + if (XSUCCEEDED(result)) { if (suspend_count_ptr) { SHIM_SET_MEM_32(suspend_count_ptr, suspend_count); @@ -276,32 +219,22 @@ SHIM_CALL NtSuspendThread_shim( } -uint32_t xeKeSetAffinityThread(void* thread_ptr, uint32_t affinity) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - XThread* thread = (XThread*)XObject::GetObject(state, thread_ptr); - if (thread) { - thread->SetAffinity(affinity); - } - - return affinity; -} - - SHIM_CALL KeSetAffinityThread_shim( PPCContext* ppc_state, KernelState* state) { - uint32_t thread = SHIM_GET_ARG_32(0); + uint32_t thread_ptr = SHIM_GET_ARG_32(0); uint32_t affinity = SHIM_GET_ARG_32(1); XELOGD( "KeSetAffinityThread(%.8X, %.8X)", - thread, + thread_ptr, affinity); - void* thread_ptr = SHIM_MEM_ADDR(thread); - uint32_t result = xeKeSetAffinityThread(thread_ptr, affinity); - SHIM_SET_RETURN_32(result); + XThread* thread = (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); + if (thread) { + thread->SetAffinity(affinity); + } + + SHIM_SET_RETURN_32(affinity); } @@ -325,45 +258,26 @@ SHIM_CALL KeQueryBasePriorityThread_shim( } -uint32_t xeKeSetBasePriorityThread(void* thread_ptr, int32_t increment) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); +SHIM_CALL KeSetBasePriorityThread_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t thread_ptr = SHIM_GET_ARG_32(0); + uint32_t increment = SHIM_GET_ARG_32(1); + + XELOGD( + "KeSetBasePriorityThread(%.8X, %.8X)", + thread_ptr, + increment); int32_t prev_priority = 0; - XThread* thread = (XThread*)XObject::GetObject(state, thread_ptr); + XThread* thread = + (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); if (thread) { prev_priority = thread->QueryPriority(); thread->SetPriority(increment); } - return prev_priority; -} - - -SHIM_CALL KeSetBasePriorityThread_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t thread = SHIM_GET_ARG_32(0); - uint32_t increment = SHIM_GET_ARG_32(1); - - XELOGD( - "KeSetBasePriorityThread(%.8X, %.8X)", - thread, - increment); - - void* thread_ptr = SHIM_MEM_ADDR(thread); - uint32_t result = xeKeSetBasePriorityThread(thread_ptr, increment); - SHIM_SET_RETURN_32(result); -} - - -uint32_t xeKeGetCurrentProcessType() { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - // DWORD - - return X_PROCTYPE_USER; + SHIM_SET_RETURN_32(prev_priority); } @@ -372,38 +286,27 @@ SHIM_CALL KeGetCurrentProcessType_shim( // XELOGD( // "KeGetCurrentProcessType()"); - int result = xeKeGetCurrentProcessType(); + // DWORD + + int result = X_PROCTYPE_USER; SHIM_SET_RETURN_64(result); } -uint64_t xeKeQueryPerformanceFrequency() { - LARGE_INTEGER frequency; - if (QueryPerformanceFrequency(&frequency)) { - return frequency.QuadPart; - } else { - return 0; - } -} - - SHIM_CALL KeQueryPerformanceFrequency_shim( PPCContext* ppc_state, KernelState* state) { // XELOGD( // "KeQueryPerformanceFrequency()"); - uint64_t result = xeKeQueryPerformanceFrequency(); + uint64_t result = 0; + LARGE_INTEGER frequency; + if (QueryPerformanceFrequency(&frequency)) { + result = frequency.QuadPart; + } SHIM_SET_RETURN_64(result); } -X_STATUS xeKeDelayExecutionThread( - uint32_t processor_mode, uint32_t alertable, uint64_t interval) { - XThread* thread = XThread::GetCurrentThread(); - return thread->Delay(processor_mode, alertable, interval); -} - - SHIM_CALL KeDelayExecutionThread_shim( PPCContext* ppc_state, KernelState* state) { uint32_t processor_mode = SHIM_GET_ARG_32(0); @@ -415,8 +318,8 @@ SHIM_CALL KeDelayExecutionThread_shim( // "KeDelayExecutionThread(%.8X, %d, %.8X(%.16llX)", // processor_mode, alertable, interval_ptr, interval); - X_STATUS result = xeKeDelayExecutionThread( - processor_mode, alertable, interval); + XThread* thread = XThread::GetCurrentThread(); + X_STATUS result = thread->Delay(processor_mode, alertable, interval); SHIM_SET_RETURN_32(result); } @@ -425,18 +328,12 @@ SHIM_CALL KeDelayExecutionThread_shim( SHIM_CALL NtYieldExecution_shim( PPCContext* ppc_state, KernelState* state) { XELOGD("NtYieldExecution()"); - xeKeDelayExecutionThread(0, 0, 0); + XThread* thread = XThread::GetCurrentThread(); + X_STATUS result = thread->Delay(0, 0, 0); SHIM_SET_RETURN_64(0); } -void xeKeQuerySystemTime(uint64_t* time_ptr) { - FILETIME t; - GetSystemTimeAsFileTime(&t); - *time_ptr = ((uint64_t)t.dwHighDateTime << 32) | t.dwLowDateTime; -} - - SHIM_CALL KeQuerySystemTime_shim( PPCContext* ppc_state, KernelState* state) { uint32_t time_ptr = SHIM_GET_ARG_32(0); @@ -445,8 +342,9 @@ SHIM_CALL KeQuerySystemTime_shim( "KeQuerySystemTime(%.8X)", time_ptr); - uint64_t time; - xeKeQuerySystemTime(&time); + FILETIME t; + GetSystemTimeAsFileTime(&t); + uint64_t time = ((uint64_t)t.dwHighDateTime << 32) | t.dwLowDateTime; if (time_ptr) { SHIM_SET_MEM_64(time_ptr, time); @@ -461,8 +359,10 @@ SHIM_CALL KeQuerySystemTime_shim( // http://msdn.microsoft.com/en-us/library/ms686801 -uint32_t xeKeTlsAlloc() { - // DWORD +SHIM_CALL KeTlsAlloc_shim( + PPCContext* ppc_state, KernelState* state) { + XELOGD( + "KeTlsAlloc()"); uint32_t tls_index; @@ -477,41 +377,11 @@ uint32_t xeKeTlsAlloc() { } #endif // WIN32 - return tls_index; -} - - -SHIM_CALL KeTlsAlloc_shim( - PPCContext* ppc_state, KernelState* state) { - XELOGD( - "KeTlsAlloc()"); - - uint32_t result = xeKeTlsAlloc(); - SHIM_SET_RETURN_64(result); + SHIM_SET_RETURN_64(tls_index); } // http://msdn.microsoft.com/en-us/library/ms686804 -int KeTlsFree(uint32_t tls_index) { - // BOOL - // _In_ DWORD dwTlsIndex - - if (tls_index == X_TLS_OUT_OF_INDEXES) { - return 0; - } - - int result_code = 0; - -#if XE_PLATFORM_WIN32 - result_code = TlsFree(tls_index); -#else - result_code = pthread_key_delete(tls_index) == 0; -#endif // WIN32 - - return result_code; -} - - SHIM_CALL KeTlsFree_shim( PPCContext* ppc_state, KernelState* state) { uint32_t tls_index = SHIM_GET_ARG_32(0); @@ -520,15 +390,32 @@ SHIM_CALL KeTlsFree_shim( "KeTlsFree(%.8X)", tls_index); - int result = xeKeTlsAlloc(); + if (tls_index == X_TLS_OUT_OF_INDEXES) { + SHIM_SET_RETURN_64(0); + return; + } + + int result = 0; + +#if XE_PLATFORM_WIN32 + result = TlsFree(tls_index); +#else + result = pthread_key_delete(tls_index) == 0; +#endif // WIN32 + SHIM_SET_RETURN_64(result); } // http://msdn.microsoft.com/en-us/library/ms686812 -uint64_t xeKeTlsGetValue(uint32_t tls_index) { - // LPVOID - // _In_ DWORD dwTlsIndex +SHIM_CALL KeTlsGetValue_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t tls_index = SHIM_GET_ARG_32(0); + + // Logging disabled, as some games spam this. + //XELOGD( + // "KeTlsGetValue(%.8X)", + // tls_index); uint64_t value = 0; @@ -539,46 +426,15 @@ uint64_t xeKeTlsGetValue(uint32_t tls_index) { #endif // WIN32 if (!value) { - XELOGW("KeTlsGetValue should SetLastError if result is NULL"); + // XELOGW("KeTlsGetValue should SetLastError if result is NULL"); // TODO(benvanik): SetLastError } - return value; -} - - -SHIM_CALL KeTlsGetValue_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t tls_index = SHIM_GET_ARG_32(0); - - // Logging disabled, as some games spam this. - //XELOGD( - // "KeTlsGetValue(%.8X)", - // tls_index); - - uint64_t result = xeKeTlsGetValue(tls_index); - SHIM_SET_RETURN_64(result); + SHIM_SET_RETURN_64(value); } // http://msdn.microsoft.com/en-us/library/ms686818 -int xeKeTlsSetValue(uint32_t tls_index, uint64_t tls_value) { - // BOOL - // _In_ DWORD dwTlsIndex, - // _In_opt_ LPVOID lpTlsValue - - int result_code = 0; - -#if XE_PLATFORM_WIN32 - result_code = TlsSetValue(tls_index, (LPVOID)tls_value); -#else - result_code = pthread_setspecific(tls_index, (void*)tls_value) == 0; -#endif // WIN32 - - return result_code; -} - - SHIM_CALL KeTlsSetValue_shim( PPCContext* ppc_state, KernelState* state) { uint32_t tls_index = SHIM_GET_ARG_32(0); @@ -588,30 +444,18 @@ SHIM_CALL KeTlsSetValue_shim( "KeTlsSetValue(%.8X, %.8X)", tls_index, tls_value); - int result = xeKeTlsSetValue(tls_index, tls_value); + int result = 0; + +#if XE_PLATFORM_WIN32 + result = TlsSetValue(tls_index, (LPVOID)tls_value); +#else + result = pthread_setspecific(tls_index, (void*)tls_value) == 0; +#endif // WIN32 + SHIM_SET_RETURN_64(result); } -X_STATUS xeNtCreateEvent(uint32_t* handle_ptr, void* obj_attributes, - uint32_t event_type, uint32_t initial_state) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - XEvent* ev = new XEvent(state); - ev->Initialize(!event_type, !!initial_state); - - // obj_attributes may have a name inside of it, if != NULL. - if (obj_attributes) { - //ev->SetName(...); - } - - *handle_ptr = ev->handle(); - - return X_STATUS_SUCCESS; -} - - SHIM_CALL NtCreateEvent_shim( PPCContext* ppc_state, KernelState* state) { uint32_t handle_ptr = SHIM_GET_ARG_32(0); @@ -623,31 +467,19 @@ SHIM_CALL NtCreateEvent_shim( "NtCreateEvent(%.8X, %.8X, %d, %d)", handle_ptr, obj_attributes_ptr, event_type, initial_state); - uint32_t handle; - X_STATUS result = xeNtCreateEvent( - &handle, SHIM_MEM_ADDR(obj_attributes_ptr), - event_type, initial_state); + XEvent* ev = new XEvent(state); + ev->Initialize(!event_type, !!initial_state); - if (XSUCCEEDED(result)) { - if (handle_ptr) { - SHIM_SET_MEM_32(handle_ptr, handle); - } - } - SHIM_SET_RETURN_32(result); -} - - -int32_t xeKeSetEvent(void* event_ptr, uint32_t increment, uint32_t wait) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - XEvent* ev = (XEvent*)XObject::GetObject(state, event_ptr); - assert_not_null(ev); - if (!ev) { - return 0; + // obj_attributes may have a name inside of it, if != NULL. + auto obj_attributes = SHIM_MEM_ADDR(obj_attributes_ptr); + if (obj_attributes) { + //ev->SetName(...); } - return ev->Set(increment, !!wait); + if (handle_ptr) { + SHIM_SET_MEM_32(handle_ptr, ev->handle()); + } + SHIM_SET_RETURN_32(X_STATUS_SUCCESS); } @@ -662,8 +494,15 @@ SHIM_CALL KeSetEvent_shim( event_ref, increment, wait); void* event_ptr = SHIM_MEM_ADDR(event_ref); - int32_t result = xeKeSetEvent(event_ptr, increment, wait); + XEvent* ev = (XEvent*)XObject::GetObject(state, event_ptr); + assert_not_null(ev); + if (!ev) { + SHIM_SET_RETURN_64(0); + return; + } + + auto result = ev->Set(increment, !!wait); SHIM_SET_RETURN_64(result); } @@ -745,20 +584,6 @@ SHIM_CALL NtPulseEvent_shim( } -int32_t xeKeResetEvent(void* event_ptr) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - XEvent* ev = (XEvent*)XEvent::GetObject(state, event_ptr); - assert_not_null(ev); - if (!ev) { - return 0; - } - - return ev->Reset(); -} - - SHIM_CALL KeResetEvent_shim( PPCContext* ppc_state, KernelState* state) { uint32_t event_ref = SHIM_GET_ARG_32(0); @@ -768,8 +593,14 @@ SHIM_CALL KeResetEvent_shim( event_ref); void* event_ptr = SHIM_MEM_ADDR(event_ref); - int32_t result = xeKeResetEvent(event_ptr); + XEvent* ev = (XEvent*)XEvent::GetObject(state, event_ptr); + assert_not_null(ev); + if (!ev) { + SHIM_SET_RETURN_64(0); + return; + } + auto result = ev->Reset(); SHIM_SET_RETURN_64(result); } @@ -823,22 +654,6 @@ SHIM_CALL NtCreateSemaphore_shim( } -void xeKeInitializeSemaphore( - void* semaphore_ptr, int32_t count, int32_t limit) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - XSemaphore* sem = (XSemaphore*)XSemaphore::GetObject( - state, semaphore_ptr, 5 /* SemaphoreObject */); - assert_not_null(sem); - if (!sem) { - return; - } - - sem->Initialize(count, limit); -} - - SHIM_CALL KeInitializeSemaphore_shim( PPCContext* ppc_state, KernelState* state) { uint32_t semaphore_ref = SHIM_GET_ARG_32(0); @@ -850,25 +665,14 @@ SHIM_CALL KeInitializeSemaphore_shim( semaphore_ref, count, limit); void* semaphore_ptr = SHIM_MEM_ADDR(semaphore_ref); - xeKeInitializeSemaphore(semaphore_ptr, count, limit); -} - - -int32_t xeKeReleaseSemaphore( - void* semaphore_ptr, int32_t increment, int32_t adjustment, bool wait) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - XSemaphore* sem = (XSemaphore*)XSemaphore::GetObject(state, semaphore_ptr); + XSemaphore* sem = (XSemaphore*)XSemaphore::GetObject( + state, semaphore_ptr, 5 /* SemaphoreObject */); assert_not_null(sem); if (!sem) { - return 0; + return; } - // TODO(benvanik): increment thread priority? - // TODO(benvanik): wait? - - return sem->ReleaseSemaphore(adjustment); + sem->Initialize(count, limit); } @@ -884,9 +688,17 @@ SHIM_CALL KeReleaseSemaphore_shim( semaphore_ref, increment, adjustment, wait); void* semaphore_ptr = SHIM_MEM_ADDR(semaphore_ref); - int32_t result = xeKeReleaseSemaphore( - semaphore_ptr, increment, adjustment, wait == 1); + XSemaphore* sem = (XSemaphore*)XSemaphore::GetObject(state, semaphore_ptr); + assert_not_null(sem); + if (!sem) { + SHIM_SET_RETURN_64(0); + return; + } + // TODO(benvanik): increment thread priority? + // TODO(benvanik): wait? + + int32_t result = sem->ReleaseSemaphore(adjustment); SHIM_SET_RETURN_64(result); } @@ -1072,25 +884,9 @@ SHIM_CALL NtCancelTimer_shim( } -X_STATUS xeKeWaitForSingleObject( - void* object_ptr, uint32_t wait_reason, uint32_t processor_mode, - uint32_t alertable, uint64_t* opt_timeout) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - - XObject* object = XObject::GetObject(state, object_ptr); - if (!object) { - // The only kind-of failure code. - return X_STATUS_ABANDONED_WAIT_0; - } - - return object->Wait(wait_reason, processor_mode, alertable, opt_timeout); -} - - SHIM_CALL KeWaitForSingleObject_shim( PPCContext* ppc_state, KernelState* state) { - uint32_t object = SHIM_GET_ARG_32(0); + uint32_t object_ptr = SHIM_GET_ARG_32(0); uint32_t wait_reason = SHIM_GET_ARG_32(1); uint32_t processor_mode = SHIM_GET_ARG_32(2); uint32_t alertable = SHIM_GET_ARG_32(3); @@ -1098,13 +894,18 @@ SHIM_CALL KeWaitForSingleObject_shim( XELOGD( "KeWaitForSingleObject(%.8X, %.8X, %.8X, %.1X, %.8X)", - object, wait_reason, processor_mode, alertable, timeout_ptr); + object_ptr, wait_reason, processor_mode, alertable, timeout_ptr); + + XObject* object = XObject::GetObject(state, SHIM_MEM_ADDR(object_ptr)); + if (!object) { + // The only kind-of failure code. + SHIM_SET_RETURN_32(X_STATUS_ABANDONED_WAIT_0); + return; + } - void* object_ptr = SHIM_MEM_ADDR(object); uint64_t timeout = timeout_ptr ? SHIM_MEM_64(timeout_ptr) : 0; - X_STATUS result = xeKeWaitForSingleObject( - object_ptr, wait_reason, processor_mode, alertable, - timeout_ptr ? &timeout : NULL); + X_STATUS result = object->Wait(wait_reason, processor_mode, alertable, + timeout_ptr ? &timeout : nullptr); SHIM_SET_RETURN_32(result); } @@ -1259,19 +1060,6 @@ SHIM_CALL NtSignalAndWaitForSingleObjectEx_shim( } -uint32_t xeKfAcquireSpinLock(uint32_t* lock_ptr) { - // Lock. - while (!poly::atomic_cas(0, 1, lock_ptr)) { - // Spin! - // TODO(benvanik): error on deadlock? - } - - // Raise IRQL to DISPATCH. - XThread* thread = XThread::GetCurrentThread(); - return thread->RaiseIrql(2); -} - - SHIM_CALL KfAcquireSpinLock_shim( PPCContext* ppc_state, KernelState* state) { uint32_t lock_ptr = SHIM_GET_ARG_32(0); @@ -1280,23 +1068,21 @@ SHIM_CALL KfAcquireSpinLock_shim( // "KfAcquireSpinLock(%.8X)", // lock_ptr); + // Lock. auto lock = reinterpret_cast(SHIM_MEM_ADDR(lock_ptr)); - uint32_t old_irql = xeKfAcquireSpinLock(lock); + while (!poly::atomic_cas(0, 1, lock)) { + // Spin! + // TODO(benvanik): error on deadlock? + } + + // Raise IRQL to DISPATCH. + XThread* thread = XThread::GetCurrentThread(); + auto old_irql = thread->RaiseIrql(2); SHIM_SET_RETURN_64(old_irql); } -void xeKfReleaseSpinLock(uint32_t* lock_ptr, uint32_t old_irql) { - // Restore IRQL. - XThread* thread = XThread::GetCurrentThread(); - thread->LowerIrql(old_irql); - - // Unlock. - poly::atomic_dec(lock_ptr); -} - - SHIM_CALL KfReleaseSpinLock_shim( PPCContext* ppc_state, KernelState* state) { uint32_t lock_ptr = SHIM_GET_ARG_32(0); @@ -1307,8 +1093,13 @@ SHIM_CALL KfReleaseSpinLock_shim( // lock_ptr, // old_irql); - xeKfReleaseSpinLock(reinterpret_cast(SHIM_MEM_ADDR(lock_ptr)), - old_irql); + // Restore IRQL. + XThread* thread = XThread::GetCurrentThread(); + thread->LowerIrql(old_irql); + + // Unlock. + auto lock = reinterpret_cast(SHIM_MEM_ADDR(lock_ptr)); + poly::atomic_dec(lock); } @@ -1343,21 +1134,11 @@ SHIM_CALL KeReleaseSpinLockFromRaisedIrql_shim( } -void xeKeEnterCriticalRegion() { - XThread::EnterCriticalRegion(); -} - - SHIM_CALL KeEnterCriticalRegion_shim( PPCContext* ppc_state, KernelState* state) { // XELOGD( // "KeEnterCriticalRegion()"); - xeKeEnterCriticalRegion(); -} - - -void xeKeLeaveCriticalRegion() { - XThread::LeaveCriticalRegion(); + XThread::EnterCriticalRegion(); } @@ -1365,7 +1146,7 @@ SHIM_CALL KeLeaveCriticalRegion_shim( PPCContext* ppc_state, KernelState* state) { // XELOGD( // "KeLeaveCriticalRegion()"); - xeKeLeaveCriticalRegion(); + XThread::LeaveCriticalRegion(); } diff --git a/src/xenia/kernel/xboxkrnl_video.cc b/src/xenia/kernel/xboxkrnl_video.cc index 7576b21bb..cbabd6cab 100644 --- a/src/xenia/kernel/xboxkrnl_video.cc +++ b/src/xenia/kernel/xboxkrnl_video.cc @@ -43,12 +43,6 @@ namespace kernel { // http://www.microsoft.com/en-za/download/details.aspx?id=5313 -- "Stripped Down Direct3D: Xbox 360 Command Buffer and Resource Management" -void xeVdGetCurrentDisplayGamma(uint32_t* arg0, float* arg1) { - *arg0 = 2; - *arg1 = 2.22222233f; -} - - SHIM_CALL VdGetCurrentDisplayGamma_shim( PPCContext* ppc_state, KernelState* state) { uint32_t arg0_ptr = SHIM_GET_ARG_32(0); @@ -58,14 +52,8 @@ SHIM_CALL VdGetCurrentDisplayGamma_shim( "VdGetCurrentDisplayGamma(%.8X, %.8X)", arg0_ptr, arg1_ptr); - uint32_t arg0 = 0; - union { - float float_value; - uint32_t uint_value; - } arg1; - xeVdGetCurrentDisplayGamma(&arg0, &arg1.float_value); - SHIM_SET_MEM_32(arg0_ptr, arg0); - SHIM_SET_MEM_32(arg1_ptr, arg1.uint_value); + SHIM_SET_MEM_32(arg0_ptr, 2); + SHIM_SET_MEM_F32(arg1_ptr, 2.22222233f); } @@ -103,22 +91,16 @@ SHIM_CALL VdGetCurrentDisplayInformation_shim( } -uint32_t xeVdQueryVideoFlags() { - // ? - return 0x00000006; -} - - SHIM_CALL VdQueryVideoFlags_shim( PPCContext* ppc_state, KernelState* state) { XELOGD( "VdQueryVideoFlags()"); - SHIM_SET_RETURN_64(xeVdQueryVideoFlags()); + SHIM_SET_RETURN_64(0x00000006); } -void xeVdQueryVideoMode(X_VIDEO_MODE *video_mode, bool swap) { +void xeVdQueryVideoMode(X_VIDEO_MODE* video_mode) { if (video_mode == NULL) { return; } @@ -134,17 +116,16 @@ void xeVdQueryVideoMode(X_VIDEO_MODE *video_mode, bool swap) { video_mode->unknown_0x8a = 0x8A; video_mode->unknown_0x01 = 0x01; - if (swap) { - video_mode->display_width = poly::byte_swap(video_mode->display_width); - video_mode->display_height = poly::byte_swap(video_mode->display_height); - video_mode->is_interlaced = poly::byte_swap(video_mode->is_interlaced); - video_mode->is_widescreen = poly::byte_swap(video_mode->is_widescreen); - video_mode->is_hi_def = poly::byte_swap(video_mode->is_hi_def); - video_mode->refresh_rate = poly::byte_swap(video_mode->refresh_rate); - video_mode->video_standard = poly::byte_swap(video_mode->video_standard); - video_mode->unknown_0x8a = poly::byte_swap(video_mode->unknown_0x8a); - video_mode->unknown_0x01 = poly::byte_swap(video_mode->unknown_0x01); - } + // TODO(benvanik): auto swap structure. + video_mode->display_width = poly::byte_swap(video_mode->display_width); + video_mode->display_height = poly::byte_swap(video_mode->display_height); + video_mode->is_interlaced = poly::byte_swap(video_mode->is_interlaced); + video_mode->is_widescreen = poly::byte_swap(video_mode->is_widescreen); + video_mode->is_hi_def = poly::byte_swap(video_mode->is_hi_def); + video_mode->refresh_rate = poly::byte_swap(video_mode->refresh_rate); + video_mode->video_standard = poly::byte_swap(video_mode->video_standard); + video_mode->unknown_0x8a = poly::byte_swap(video_mode->unknown_0x8a); + video_mode->unknown_0x01 = poly::byte_swap(video_mode->unknown_0x01); } @@ -157,23 +138,7 @@ SHIM_CALL VdQueryVideoMode_shim( "VdQueryVideoMode(%.8X)", video_mode_ptr); - xeVdQueryVideoMode(video_mode, true); -} - - -void xeVdInitializeEngines(uint32_t unk0, uint32_t callback, uint32_t unk1, - uint32_t unk2_ptr, uint32_t unk3_ptr) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - GraphicsSystem* gs = state->emulator()->graphics_system(); - if (!gs) { - return; - } - - // r3 = 0x4F810000 - // r4 = function ptr (cleanup callback?) - // r5 = 0 - // r6/r7 = some binary data in .data + xeVdQueryVideoMode(video_mode); } @@ -188,8 +153,11 @@ SHIM_CALL VdInitializeEngines_shim( XELOGD( "VdInitializeEngines(%.8X, %.8X, %.8X, %.8X, %.8X)", unk0, callback, unk1, unk2_ptr, unk3_ptr); - - xeVdInitializeEngines(unk0, callback, unk1, unk2_ptr, unk3_ptr); + + // r3 = 0x4F810000 + // r4 = function ptr (cleanup callback?) + // r5 = 0 + // r6/r7 = some binary data in .data } @@ -204,9 +172,15 @@ SHIM_CALL VdShutdownEngines_shim( } -void xeVdSetGraphicsInterruptCallback(uint32_t callback, uint32_t user_data) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); +SHIM_CALL VdSetGraphicsInterruptCallback_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t callback = SHIM_GET_ARG_32(0); + uint32_t user_data = SHIM_GET_ARG_32(1); + + XELOGD( + "VdSetGraphicsInterruptCallback(%.8X, %.8X)", + callback, user_data); + GraphicsSystem* gs = state->emulator()->graphics_system(); if (!gs) { return; @@ -220,22 +194,15 @@ void xeVdSetGraphicsInterruptCallback(uint32_t callback, uint32_t user_data) { } -SHIM_CALL VdSetGraphicsInterruptCallback_shim( +SHIM_CALL VdInitializeRingBuffer_shim( PPCContext* ppc_state, KernelState* state) { - uint32_t callback = SHIM_GET_ARG_32(0); - uint32_t user_data = SHIM_GET_ARG_32(1); + uint32_t ptr = SHIM_GET_ARG_32(0); + uint32_t page_count = SHIM_GET_ARG_32(1); XELOGD( - "VdSetGraphicsInterruptCallback(%.8X, %.8X)", - callback, user_data); - - xeVdSetGraphicsInterruptCallback(callback, user_data); -} - - -void xeVdInitializeRingBuffer(uint32_t ptr, uint32_t page_count) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); + "VdInitializeRingBuffer(%.8X, %.8X)", + ptr, page_count); + GraphicsSystem* gs = state->emulator()->graphics_system(); if (!gs) { return; @@ -252,22 +219,15 @@ void xeVdInitializeRingBuffer(uint32_t ptr, uint32_t page_count) { } -SHIM_CALL VdInitializeRingBuffer_shim( +SHIM_CALL VdEnableRingBufferRPtrWriteBack_shim( PPCContext* ppc_state, KernelState* state) { uint32_t ptr = SHIM_GET_ARG_32(0); - uint32_t page_count = SHIM_GET_ARG_32(1); + uint32_t block_size = SHIM_GET_ARG_32(1); XELOGD( - "VdInitializeRingBuffer(%.8X, %.8X)", - ptr, page_count); + "VdEnableRingBufferRPtrWriteBack(%.8X, %.8X)", + ptr, block_size); - xeVdInitializeRingBuffer(ptr, page_count); -} - - -void xeVdEnableRingBufferRPtrWriteBack(uint32_t ptr, uint32_t block_size) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); GraphicsSystem* gs = state->emulator()->graphics_system(); if (!gs) { return; @@ -284,37 +244,18 @@ void xeVdEnableRingBufferRPtrWriteBack(uint32_t ptr, uint32_t block_size) { //((p + 0x3C) & 0x1FFFFFFF) + ((((p + 0x3C) >> 20) + 0x200) & 0x1000) //also 0x3C offset into WriteBacks is PrimaryRingBufferReadIndex -//(1:17:38 AM) Rick: .text:8201B348 lwz r11, 0x2B10(r31) -//(1:17:38 AM) Rick: .text:8201B34C addi r11, r11, 0x3C -//(1:17:38 AM) Rick: .text:8201B350 srwi r10, r11, 20 # r10 = r11 >> 20 -//(1:17:38 AM) Rick: .text:8201B354 clrlwi r11, r11, 3 # r11 = r11 & 0x1FFFFFFF -//(1:17:38 AM) Rick: .text:8201B358 addi r10, r10, 0x200 -//(1:17:39 AM) Rick: .text:8201B35C rlwinm r10, r10, 0,19,19 # r10 = r10 & 0x1000 -//(1:17:39 AM) Rick: .text:8201B360 add r3, r10, r11 -//(1:17:39 AM) Rick: .text:8201B364 bl VdEnableRingBufferRPtrWriteBack + //(1:17:38 AM) Rick: .text:8201B348 lwz r11, 0x2B10(r31) + //(1:17:38 AM) Rick: .text:8201B34C addi r11, r11, 0x3C + //(1:17:38 AM) Rick: .text:8201B350 srwi r10, r11, 20 # r10 = r11 >> 20 + //(1:17:38 AM) Rick: .text:8201B354 clrlwi r11, r11, 3 # r11 = r11 & 0x1FFFFFFF + //(1:17:38 AM) Rick: .text:8201B358 addi r10, r10, 0x200 + //(1:17:39 AM) Rick: .text:8201B35C rlwinm r10, r10, 0,19,19 # r10 = r10 & 0x1000 + //(1:17:39 AM) Rick: .text:8201B360 add r3, r10, r11 + //(1:17:39 AM) Rick: .text:8201B364 bl VdEnableRingBufferRPtrWriteBack // TODO(benvanik): something? } -SHIM_CALL VdEnableRingBufferRPtrWriteBack_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t ptr = SHIM_GET_ARG_32(0); - uint32_t block_size = SHIM_GET_ARG_32(1); - - XELOGD( - "VdEnableRingBufferRPtrWriteBack(%.8X, %.8X)", - ptr, block_size); - - xeVdEnableRingBufferRPtrWriteBack(ptr, block_size); -} - - -void xeVdGetSystemCommandBuffer(uint32_t* p0, uint32_t* p1) { - *p0 = 0xBEEF0000; - *p1 = 0xBEEF0001; -} - - SHIM_CALL VdGetSystemCommandBuffer_shim( PPCContext* ppc_state, KernelState* state) { uint32_t p0_ptr = SHIM_GET_ARG_32(0); @@ -325,23 +266,8 @@ SHIM_CALL VdGetSystemCommandBuffer_shim( p0_ptr, p1_ptr); - uint32_t p0 = 0; - uint32_t p1 = 0; - xeVdGetSystemCommandBuffer(&p0, &p1); - SHIM_SET_MEM_32(p0_ptr, p0); - SHIM_SET_MEM_32(p1_ptr, p1); -} - - -void xeVdSetSystemCommandBufferGpuIdentifierAddress(uint32_t unk) { - KernelState* state = shared_kernel_state_; - assert_not_null(state); - GraphicsSystem* gs = state->emulator()->graphics_system(); - if (!gs) { - return; - } - - // r3 = 0x2B10(d3d?) + 8 + SHIM_SET_MEM_32(p0_ptr, 0xBEEF0000); + SHIM_SET_MEM_32(p1_ptr, 0xBEEF0001); } @@ -352,8 +278,8 @@ SHIM_CALL VdSetSystemCommandBufferGpuIdentifierAddress_shim( XELOGD( "VdSetSystemCommandBufferGpuIdentifierAddress(%.8X)", unk); - - xeVdSetSystemCommandBufferGpuIdentifierAddress(unk); + + // r3 = 0x2B10(d3d?) + 8 } @@ -487,32 +413,30 @@ void xe::kernel::xboxkrnl::RegisterVideoExports( // Pointer to a global D3D device. Games only seem to set this, so we don't // have to do anything. We may want to read it back later, though. uint32_t pVdGlobalDevice = (uint32_t)memory->HeapAlloc(0, 4, 0); - export_resolver->SetVariableMapping( - "xboxkrnl.exe", ordinals::VdGlobalDevice, - pVdGlobalDevice); + export_resolver->SetVariableMapping("xboxkrnl.exe", ordinals::VdGlobalDevice, + pVdGlobalDevice); poly::store_and_swap(mem + pVdGlobalDevice, 0); // VdGlobalXamDevice (4b) // Pointer to the XAM D3D device, which we don't have. uint32_t pVdGlobalXamDevice = (uint32_t)memory->HeapAlloc(0, 4, 0); export_resolver->SetVariableMapping( - "xboxkrnl.exe", ordinals::VdGlobalXamDevice, - pVdGlobalXamDevice); + "xboxkrnl.exe", ordinals::VdGlobalXamDevice, pVdGlobalXamDevice); poly::store_and_swap(mem + pVdGlobalXamDevice, 0); // VdGpuClockInMHz (4b) // GPU clock. Xenos is 500MHz. Hope nothing is relying on this timing... uint32_t pVdGpuClockInMHz = (uint32_t)memory->HeapAlloc(0, 4, 0); - export_resolver->SetVariableMapping( - "xboxkrnl.exe", ordinals::VdGpuClockInMHz, - pVdGpuClockInMHz); + export_resolver->SetVariableMapping("xboxkrnl.exe", ordinals::VdGpuClockInMHz, + pVdGpuClockInMHz); poly::store_and_swap(mem + pVdGpuClockInMHz, 500); // VdHSIOCalibrationLock (28b) // CriticalSection. uint32_t pVdHSIOCalibrationLock = (uint32_t)memory->HeapAlloc(0, 28, 0); export_resolver->SetVariableMapping( - "xboxkrnl.exe", ordinals::VdHSIOCalibrationLock, - pVdHSIOCalibrationLock); - xeRtlInitializeCriticalSectionAndSpinCount(pVdHSIOCalibrationLock, 10000); + "xboxkrnl.exe", ordinals::VdHSIOCalibrationLock, pVdHSIOCalibrationLock); + auto hsio_lock = + reinterpret_cast(mem + pVdHSIOCalibrationLock); + xeRtlInitializeCriticalSectionAndSpinCount(hsio_lock, 10000); } diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index 048e4cd4d..8f2b1eccf 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -68,7 +68,7 @@ void XObject::Release() { } X_STATUS XObject::Delete() { - return shared_kernel_state_->object_table()->RemoveHandle(handle_); + return kernel_state_->object_table()->RemoveHandle(handle_); } uint32_t XObject::TimeoutTicksToMs(int64_t timeout_ticks) { @@ -149,11 +149,11 @@ X_STATUS XObject::WaitMultiple( } void XObject::LockType() { - xe_mutex_lock(shared_kernel_state_->object_mutex_); + xe_mutex_lock(KernelState::shared()->object_mutex_); } void XObject::UnlockType() { - xe_mutex_unlock(shared_kernel_state_->object_mutex_); + xe_mutex_unlock(KernelState::shared()->object_mutex_); } void XObject::SetNativePointer(uint32_t native_ptr) { From c84fcc70a4f1828b38034d2b2ca547f4841d2d7c Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 16 Aug 2014 00:25:13 -0700 Subject: [PATCH 108/388] Cleaning up kernel namespaces. --- src/xenia/kernel/async_request.cc | 11 ++++---- src/xenia/kernel/dispatcher.cc | 7 +++-- src/xenia/kernel/kernel_state.cc | 12 ++++---- src/xenia/kernel/native_list.cc | 7 +++-- src/xenia/kernel/object_table.cc | 7 +++-- src/xenia/kernel/xam_content.cc | 5 ---- src/xenia/kernel/xam_info.cc | 5 ---- src/xenia/kernel/xam_input.cc | 8 ++---- src/xenia/kernel/xam_module.cc | 28 ++++++++++--------- src/xenia/kernel/xam_msg.cc | 5 ---- src/xenia/kernel/xam_net.cc | 5 ---- src/xenia/kernel/xam_notify.cc | 5 ---- src/xenia/kernel/xam_ui.cc | 5 ---- src/xenia/kernel/xam_user.cc | 5 ---- src/xenia/kernel/xam_video.cc | 5 ---- src/xenia/kernel/xam_voice.cc | 6 ---- src/xenia/kernel/xboxkrnl_audio.cc | 6 ---- src/xenia/kernel/xboxkrnl_debug.cc | 5 ---- src/xenia/kernel/xboxkrnl_hal.cc | 5 ---- src/xenia/kernel/xboxkrnl_io.cc | 7 ++--- src/xenia/kernel/xboxkrnl_memory.cc | 10 ++----- src/xenia/kernel/xboxkrnl_misc.cc | 5 ---- src/xenia/kernel/xboxkrnl_module.cc | 38 ++++++++++++++------------ src/xenia/kernel/xboxkrnl_modules.cc | 5 ---- src/xenia/kernel/xboxkrnl_ob.cc | 5 ---- src/xenia/kernel/xboxkrnl_rtl.cc | 5 ---- src/xenia/kernel/xboxkrnl_strings.cc | 5 ---- src/xenia/kernel/xboxkrnl_threading.cc | 5 ---- src/xenia/kernel/xboxkrnl_usbcam.cc | 5 ---- src/xenia/kernel/xboxkrnl_video.cc | 10 ++----- src/xenia/kernel/xobject.cc | 8 ++++-- 31 files changed, 76 insertions(+), 174 deletions(-) diff --git a/src/xenia/kernel/async_request.cc b/src/xenia/kernel/async_request.cc index 9992ecdb7..fd0359cac 100644 --- a/src/xenia/kernel/async_request.cc +++ b/src/xenia/kernel/async_request.cc @@ -13,9 +13,8 @@ #include -using namespace std; -using namespace xe; -using namespace xe::kernel; +namespace xe { +namespace kernel { XAsyncRequest::XAsyncRequest( @@ -28,8 +27,7 @@ XAsyncRequest::XAsyncRequest( } XAsyncRequest::~XAsyncRequest() { - for (vector::iterator it = wait_events_.begin(); - it != wait_events_.end(); ++it) { + for (auto it = wait_events_.begin(); it != wait_events_.end(); ++it) { (*it)->Release(); } object_->Release(); @@ -39,3 +37,6 @@ void XAsyncRequest::AddWaitEvent(XEvent* ev) { ev->Retain(); wait_events_.push_back(ev); } + +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/dispatcher.cc b/src/xenia/kernel/dispatcher.cc index 30d1639a2..df11b62f4 100644 --- a/src/xenia/kernel/dispatcher.cc +++ b/src/xenia/kernel/dispatcher.cc @@ -13,8 +13,8 @@ #include -using namespace xe; -using namespace xe::kernel; +namespace xe { +namespace kernel { Dispatcher::Dispatcher(KernelState* kernel_state) : @@ -35,3 +35,6 @@ void Dispatcher::Lock() { void Dispatcher::Unlock() { xe_mutex_unlock(lock_); } + +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index 92d10810f..1d1b81a07 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -23,18 +23,15 @@ #include -using namespace xe; -using namespace xe::kernel; +namespace xe { +namespace kernel { // This is a global object initialized with the XboxkrnlModule. // It references the current kernel state object that all kernel methods should // be using to stash their variables. -namespace xe { -namespace kernel { KernelState* shared_kernel_state_ = nullptr; -} // namespace kernel -} // namespace xe + KernelState::KernelState(Emulator* emulator) : emulator_(emulator), memory_(emulator->memory()), @@ -213,3 +210,6 @@ void KernelState::CompleteOverlappedImmediate(uint32_t overlapped_ptr, X_RESULT XThread::GetCurrentThreadHandle()); CompleteOverlapped(overlapped_ptr, result, length); } + +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/native_list.cc b/src/xenia/kernel/native_list.cc index c910bd667..fa87663d1 100644 --- a/src/xenia/kernel/native_list.cc +++ b/src/xenia/kernel/native_list.cc @@ -10,8 +10,8 @@ #include -using namespace xe; -using namespace xe::kernel; +namespace xe { +namespace kernel { NativeList::NativeList(Memory* memory) : @@ -70,3 +70,6 @@ uint32_t NativeList::Shift() { bool NativeList::HasPending() { return head_ != kInvalidPointer; } + +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/object_table.cc b/src/xenia/kernel/object_table.cc index 746821bf0..0b338d072 100644 --- a/src/xenia/kernel/object_table.cc +++ b/src/xenia/kernel/object_table.cc @@ -13,8 +13,8 @@ #include -using namespace xe; -using namespace xe::kernel; +namespace xe { +namespace kernel { ObjectTable::ObjectTable() : @@ -206,3 +206,6 @@ X_HANDLE ObjectTable::TranslateHandle(X_HANDLE handle) { return handle; } } + +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/xam_content.cc b/src/xenia/kernel/xam_content.cc index b367504c3..bc8a6675f 100644 --- a/src/xenia/kernel/xam_content.cc +++ b/src/xenia/kernel/xam_content.cc @@ -15,11 +15,6 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xam; - - namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam_info.cc b/src/xenia/kernel/xam_info.cc index 1827019d2..32c7c8e9d 100644 --- a/src/xenia/kernel/xam_info.cc +++ b/src/xenia/kernel/xam_info.cc @@ -17,11 +17,6 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xam; - - namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam_input.cc b/src/xenia/kernel/xam_input.cc index 4ef44b0a5..196d2dbde 100644 --- a/src/xenia/kernel/xam_input.cc +++ b/src/xenia/kernel/xam_input.cc @@ -17,15 +17,11 @@ #include -using namespace xe; -using namespace xe::hid; -using namespace xe::kernel; -using namespace xe::kernel::xam; - - namespace xe { namespace kernel { +using xe::hid::InputSystem; + SHIM_CALL XamResetInactivity_shim( PPCContext* ppc_state, KernelState* state) { diff --git a/src/xenia/kernel/xam_module.cc b/src/xenia/kernel/xam_module.cc index 2a5aa6217..b67bc2da7 100644 --- a/src/xenia/kernel/xam_module.cc +++ b/src/xenia/kernel/xam_module.cc @@ -14,9 +14,8 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xam; +namespace xe { +namespace kernel { XamModule::XamModule(Emulator* emulator, KernelState* kernel_state) : @@ -31,17 +30,20 @@ XamModule::XamModule(Emulator* emulator, KernelState* kernel_state) : "xam.xex", xam_export_table, XECOUNT(xam_export_table)); // Register all exported functions. - RegisterContentExports(export_resolver_, kernel_state); - RegisterInfoExports(export_resolver_, kernel_state); - RegisterInputExports(export_resolver_, kernel_state); - RegisterMsgExports(export_resolver_, kernel_state); - RegisterNetExports(export_resolver_, kernel_state); - RegisterNotifyExports(export_resolver_, kernel_state); - RegisterUIExports(export_resolver_, kernel_state); - RegisterUserExports(export_resolver_, kernel_state); - RegisterVideoExports(export_resolver_, kernel_state); - RegisterVoiceExports(export_resolver_, kernel_state); + xam::RegisterContentExports(export_resolver_, kernel_state); + xam::RegisterInfoExports(export_resolver_, kernel_state); + xam::RegisterInputExports(export_resolver_, kernel_state); + xam::RegisterMsgExports(export_resolver_, kernel_state); + xam::RegisterNetExports(export_resolver_, kernel_state); + xam::RegisterNotifyExports(export_resolver_, kernel_state); + xam::RegisterUIExports(export_resolver_, kernel_state); + xam::RegisterUserExports(export_resolver_, kernel_state); + xam::RegisterVideoExports(export_resolver_, kernel_state); + xam::RegisterVoiceExports(export_resolver_, kernel_state); } XamModule::~XamModule() { } + +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/xam_msg.cc b/src/xenia/kernel/xam_msg.cc index 0317210eb..54399c7a9 100644 --- a/src/xenia/kernel/xam_msg.cc +++ b/src/xenia/kernel/xam_msg.cc @@ -16,11 +16,6 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xam; - - namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam_net.cc b/src/xenia/kernel/xam_net.cc index 8f5815404..eacec8169 100644 --- a/src/xenia/kernel/xam_net.cc +++ b/src/xenia/kernel/xam_net.cc @@ -17,11 +17,6 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xam; - - namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam_notify.cc b/src/xenia/kernel/xam_notify.cc index 356fbc269..83e673ce5 100644 --- a/src/xenia/kernel/xam_notify.cc +++ b/src/xenia/kernel/xam_notify.cc @@ -16,11 +16,6 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xam; - - namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam_ui.cc b/src/xenia/kernel/xam_ui.cc index 0824b8eb9..fa477d877 100644 --- a/src/xenia/kernel/xam_ui.cc +++ b/src/xenia/kernel/xam_ui.cc @@ -15,11 +15,6 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xam; - - namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam_user.cc b/src/xenia/kernel/xam_user.cc index c05d2e97a..521358997 100644 --- a/src/xenia/kernel/xam_user.cc +++ b/src/xenia/kernel/xam_user.cc @@ -17,11 +17,6 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xam; - - namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam_video.cc b/src/xenia/kernel/xam_video.cc index 1106f9bb7..b5f6f2693 100644 --- a/src/xenia/kernel/xam_video.cc +++ b/src/xenia/kernel/xam_video.cc @@ -15,11 +15,6 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xam; - - namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam_voice.cc b/src/xenia/kernel/xam_voice.cc index 30b94bcdd..f3c5e9f3a 100644 --- a/src/xenia/kernel/xam_voice.cc +++ b/src/xenia/kernel/xam_voice.cc @@ -16,12 +16,6 @@ #include -using namespace xe; -using namespace xe::hid; -using namespace xe::kernel; -using namespace xe::kernel::xam; - - namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_audio.cc b/src/xenia/kernel/xboxkrnl_audio.cc index 970abfd69..1c04f25a1 100644 --- a/src/xenia/kernel/xboxkrnl_audio.cc +++ b/src/xenia/kernel/xboxkrnl_audio.cc @@ -17,12 +17,6 @@ #include -using namespace xe; -using namespace xe::apu; -using namespace xe::kernel; -using namespace xe::kernel::xboxkrnl; - - namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_debug.cc b/src/xenia/kernel/xboxkrnl_debug.cc index 3ff845c0d..7da596771 100644 --- a/src/xenia/kernel/xboxkrnl_debug.cc +++ b/src/xenia/kernel/xboxkrnl_debug.cc @@ -16,11 +16,6 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xboxkrnl; - - namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_hal.cc b/src/xenia/kernel/xboxkrnl_hal.cc index 5e208eb11..7e225077f 100644 --- a/src/xenia/kernel/xboxkrnl_hal.cc +++ b/src/xenia/kernel/xboxkrnl_hal.cc @@ -15,11 +15,6 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xboxkrnl; - - namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl_io.cc index caee0e283..6cd9c0fb3 100644 --- a/src/xenia/kernel/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl_io.cc @@ -18,14 +18,11 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::fs; - - namespace xe { namespace kernel { +using namespace xe::kernel::fs; + SHIM_CALL NtCreateFile_shim( PPCContext* ppc_state, KernelState* state) { diff --git a/src/xenia/kernel/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl_memory.cc index fba730d7e..bd34eaa99 100644 --- a/src/xenia/kernel/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl_memory.cc @@ -15,12 +15,6 @@ #include -using namespace alloy; -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xboxkrnl; - - namespace xe { namespace kernel { @@ -268,7 +262,7 @@ SHIM_CALL MmAllocatePhysicalMemoryEx_shim( assert_true(max_addr_range == 0xFFFFFFFF); // Allocate. - uint32_t flags = MEMORY_FLAG_PHYSICAL; + uint32_t flags = alloy::MEMORY_FLAG_PHYSICAL; uint32_t base_address = (uint32_t)state->memory()->HeapAlloc( 0, adjusted_size, flags, adjusted_alignment); if (!base_address) { @@ -445,7 +439,7 @@ SHIM_CALL ExAllocatePoolTypeWithTag_shim( } uint32_t addr = (uint32_t)state->memory()->HeapAlloc( - 0, adjusted_size, MEMORY_FLAG_ZERO, alignment); + 0, adjusted_size, alloy::MEMORY_FLAG_ZERO, alignment); SHIM_SET_RETURN_32(addr); } diff --git a/src/xenia/kernel/xboxkrnl_misc.cc b/src/xenia/kernel/xboxkrnl_misc.cc index 73d7c0f87..6a4b2db99 100644 --- a/src/xenia/kernel/xboxkrnl_misc.cc +++ b/src/xenia/kernel/xboxkrnl_misc.cc @@ -16,11 +16,6 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xboxkrnl; - - namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_module.cc b/src/xenia/kernel/xboxkrnl_module.cc index 4b20f0710..f9daefb54 100644 --- a/src/xenia/kernel/xboxkrnl_module.cc +++ b/src/xenia/kernel/xboxkrnl_module.cc @@ -18,15 +18,14 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xboxkrnl; - - DEFINE_bool(abort_before_entry, false, "Abort execution right before launching the module."); +namespace xe { +namespace kernel { + + XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) : XKernelModule(kernel_state, "xe:\\xboxkrnl.exe") { // Build the export table used for resolution. @@ -39,19 +38,19 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) : "xboxkrnl.exe", xboxkrnl_export_table, XECOUNT(xboxkrnl_export_table)); // Register all exported functions. - RegisterAudioExports(export_resolver_, kernel_state); - RegisterDebugExports(export_resolver_, kernel_state); - RegisterHalExports(export_resolver_, kernel_state); - RegisterIoExports(export_resolver_, kernel_state); - RegisterMemoryExports(export_resolver_, kernel_state); - RegisterMiscExports(export_resolver_, kernel_state); - RegisterModuleExports(export_resolver_, kernel_state); - RegisterObExports(export_resolver_, kernel_state); - RegisterRtlExports(export_resolver_, kernel_state_); - RegisterStringExports(export_resolver_, kernel_state_); - RegisterThreadingExports(export_resolver_, kernel_state); - RegisterUsbcamExports(export_resolver_, kernel_state); - RegisterVideoExports(export_resolver_, kernel_state); + xboxkrnl::RegisterAudioExports(export_resolver_, kernel_state); + xboxkrnl::RegisterDebugExports(export_resolver_, kernel_state); + xboxkrnl::RegisterHalExports(export_resolver_, kernel_state); + xboxkrnl::RegisterIoExports(export_resolver_, kernel_state); + xboxkrnl::RegisterMemoryExports(export_resolver_, kernel_state); + xboxkrnl::RegisterMiscExports(export_resolver_, kernel_state); + xboxkrnl::RegisterModuleExports(export_resolver_, kernel_state); + xboxkrnl::RegisterObExports(export_resolver_, kernel_state); + xboxkrnl::RegisterRtlExports(export_resolver_, kernel_state_); + xboxkrnl::RegisterStringExports(export_resolver_, kernel_state_); + xboxkrnl::RegisterThreadingExports(export_resolver_, kernel_state); + xboxkrnl::RegisterUsbcamExports(export_resolver_, kernel_state); + xboxkrnl::RegisterVideoExports(export_resolver_, kernel_state); uint8_t* mem = memory_->membase(); @@ -177,3 +176,6 @@ int XboxkrnlModule::LaunchModule(const char* path) { return 0; } + +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/xboxkrnl_modules.cc b/src/xenia/kernel/xboxkrnl_modules.cc index bc659eb55..ec7bf3fc6 100644 --- a/src/xenia/kernel/xboxkrnl_modules.cc +++ b/src/xenia/kernel/xboxkrnl_modules.cc @@ -17,11 +17,6 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xboxkrnl; - - namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_ob.cc b/src/xenia/kernel/xboxkrnl_ob.cc index 9631c3cd9..7cb5a42d6 100644 --- a/src/xenia/kernel/xboxkrnl_ob.cc +++ b/src/xenia/kernel/xboxkrnl_ob.cc @@ -17,11 +17,6 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xboxkrnl; - - namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl_rtl.cc index 9c9285026..5ac309ae6 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl_rtl.cc @@ -18,11 +18,6 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xboxkrnl; - - namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_strings.cc b/src/xenia/kernel/xboxkrnl_strings.cc index 05095d537..bc5340a8d 100644 --- a/src/xenia/kernel/xboxkrnl_strings.cc +++ b/src/xenia/kernel/xboxkrnl_strings.cc @@ -18,11 +18,6 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xboxkrnl; - - namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index 517345552..7de07269f 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -23,11 +23,6 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xboxkrnl; - - namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_usbcam.cc b/src/xenia/kernel/xboxkrnl_usbcam.cc index b68c02796..5eb79cb28 100644 --- a/src/xenia/kernel/xboxkrnl_usbcam.cc +++ b/src/xenia/kernel/xboxkrnl_usbcam.cc @@ -15,11 +15,6 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xboxkrnl; - - namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_video.cc b/src/xenia/kernel/xboxkrnl_video.cc index cbabd6cab..37bd71456 100644 --- a/src/xenia/kernel/xboxkrnl_video.cc +++ b/src/xenia/kernel/xboxkrnl_video.cc @@ -20,15 +20,11 @@ #include -using namespace xe; -using namespace xe::gpu; -using namespace xe::kernel; -using namespace xe::kernel::xboxkrnl; - - namespace xe { namespace kernel { +using xe::gpu::GraphicsSystem; + // http://www.tweakoz.com/orkid/ // http://www.tweakoz.com/orkid/dox/d3/d52/xb360init_8cpp_source.html @@ -376,7 +372,7 @@ SHIM_CALL VdSwap_shim( auto dwords = reinterpret_cast(SHIM_MEM_ADDR(unk0)); dwords[0] = poly::byte_swap((0x03 << 30) | ((1 - 1) << 16) | - (xenos::PM4_XE_SWAP << 8)); + (xe::gpu::xenos::PM4_XE_SWAP << 8)); SHIM_SET_RETURN_64(0); } diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index 8f2b1eccf..5574b3454 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -15,9 +15,8 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::xboxkrnl; +namespace xe { +namespace kernel { XObject::XObject(KernelState* kernel_state, Type type) : @@ -267,3 +266,6 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr, return object; } } + +} // namespace kernel +} // namespace xe From 96fb484dd902081329f63cac3155db77b4ea115b Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 16 Aug 2014 00:36:18 -0700 Subject: [PATCH 109/388] Removing unused crc32/file code from core. --- src/xenia/core.h | 2 - src/xenia/core/crc32.cc | 334 ------------------------------------ src/xenia/core/crc32.h | 19 -- src/xenia/core/file.cc | 84 --------- src/xenia/core/file.h | 36 ---- src/xenia/core/mmap.h | 5 +- src/xenia/core/sources.gypi | 4 - 7 files changed, 4 insertions(+), 480 deletions(-) delete mode 100644 src/xenia/core/crc32.cc delete mode 100644 src/xenia/core/crc32.h delete mode 100644 src/xenia/core/file.cc delete mode 100644 src/xenia/core/file.h diff --git a/src/xenia/core.h b/src/xenia/core.h index 5b0d57046..8368a6eb0 100644 --- a/src/xenia/core.h +++ b/src/xenia/core.h @@ -17,8 +17,6 @@ namespace xe { using Memory = alloy::Memory; } // namespace xe -#include -#include #include #include #include diff --git a/src/xenia/core/crc32.cc b/src/xenia/core/crc32.cc deleted file mode 100644 index c28b768ac..000000000 --- a/src/xenia/core/crc32.cc +++ /dev/null @@ -1,334 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - - -// Code from: http://create.stephan-brumme.com/crc32/Crc32.cpp -// http://create.stephan-brumme.com/crc32/#slicing-by-8-overview - - -const uint32_t xe_crc32_lookup_[8][256] = { - // same algorithm as crc32_bitwise - //for (int i = 0; i <= 0xFF; i++) { - // uint32_t crc = i; - // for (int j = 0; j < 8; j++) - // crc = (crc >> 1) ^ ((crc & 1) * Polynomial); - // xe_crc32_lookup_[0][i] = crc; - //} - // ... and the following slicing-by-8 algorithm (from Intel): - // http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf - // http://sourceforge.net/projects/slicing-by-8/ - //for (int i = 0; i <= 0xFF; i++) { - // xe_crc32_lookup_[1][i] = (xe_crc32_lookup_[0][i] >> 8) ^ xe_crc32_lookup_[0][xe_crc32_lookup_[0][i] & 0xFF]; - // xe_crc32_lookup_[2][i] = (xe_crc32_lookup_[1][i] >> 8) ^ xe_crc32_lookup_[0][xe_crc32_lookup_[1][i] & 0xFF]; - // xe_crc32_lookup_[3][i] = (xe_crc32_lookup_[2][i] >> 8) ^ xe_crc32_lookup_[0][xe_crc32_lookup_[2][i] & 0xFF]; - // xe_crc32_lookup_[4][i] = (xe_crc32_lookup_[3][i] >> 8) ^ xe_crc32_lookup_[0][xe_crc32_lookup_[3][i] & 0xFF]; - // xe_crc32_lookup_[5][i] = (xe_crc32_lookup_[4][i] >> 8) ^ xe_crc32_lookup_[0][xe_crc32_lookup_[4][i] & 0xFF]; - // xe_crc32_lookup_[6][i] = (xe_crc32_lookup_[5][i] >> 8) ^ xe_crc32_lookup_[0][xe_crc32_lookup_[5][i] & 0xFF]; - // xe_crc32_lookup_[7][i] = (xe_crc32_lookup_[6][i] >> 8) ^ xe_crc32_lookup_[0][xe_crc32_lookup_[6][i] & 0xFF]; - //} - { 0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,0xE963A535,0x9E6495A3, - 0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,0x09B64C2B,0x7EB17CBD,0xE7B82D07,0x90BF1D91, - 0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE,0x1ADAD47D,0x6DDDE4EB,0xF4D4B551,0x83D385C7, - 0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5, - 0x3B6E20C8,0x4C69105E,0xD56041E4,0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B, - 0x35B5A8FA,0x42B2986C,0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59, - 0x26D930AC,0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423,0xCFBA9599,0xB8BDA50F, - 0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,0x2F6F7C87,0x58684C11,0xC1611DAB,0xB6662D3D, - 0x76DC4190,0x01DB7106,0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F,0x9FBFE4A5,0xE8B8D433, - 0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB,0x086D3D2D,0x91646C97,0xE6635C01, - 0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E,0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457, - 0x65B0D9C6,0x12B7E950,0x8BBEB8EA,0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65, - 0x4DB26158,0x3AB551CE,0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,0xA4D1C46D,0xD3D6F4FB, - 0x4369E96A,0x346ED9FC,0xAD678846,0xDA60B8D0,0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9, - 0x5005713C,0x270241AA,0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409,0xCE61E49F, - 0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81,0xB7BD5C3B,0xC0BA6CAD, - 0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A,0xEAD54739,0x9DD277AF,0x04DB2615,0x73DC1683, - 0xE3630B12,0x94643B84,0x0D6D6A3E,0x7A6A5AA8,0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1, - 0xF00F9344,0x8708A3D2,0x1E01F268,0x6906C2FE,0xF762575D,0x806567CB,0x196C3671,0x6E6B06E7, - 0xFED41B76,0x89D32BE0,0x10DA7A5A,0x67DD4ACC,0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5, - 0xD6D6A3E8,0xA1D1937E,0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B, - 0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55,0x316E8EEF,0x4669BE79, - 0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236,0xCC0C7795,0xBB0B4703,0x220216B9,0x5505262F, - 0xC5BA3BBE,0xB2BD0B28,0x2BB45A92,0x5CB36A04,0xC2D7FFA7,0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D, - 0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A,0x9C0906A9,0xEB0E363F,0x72076785,0x05005713, - 0x95BF4A82,0xE2B87A14,0x7BB12BAE,0x0CB61B38,0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21, - 0x86D3D2D4,0xF1D4E242,0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777, - 0x88085AE6,0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,0x616BFFD3,0x166CCF45, - 0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,0xA7672661,0xD06016F7,0x4969474D,0x3E6E77DB, - 0xAED16A4A,0xD9D65ADC,0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,0x47B2CF7F,0x30B5FFE9, - 0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,0xCDD70693,0x54DE5729,0x23D967BF, - 0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94,0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D }, - { 0x00000000,0x191B3141,0x32366282,0x2B2D53C3,0x646CC504,0x7D77F445,0x565AA786,0x4F4196C7, - 0xC8D98A08,0xD1C2BB49,0xFAEFE88A,0xE3F4D9CB,0xACB54F0C,0xB5AE7E4D,0x9E832D8E,0x87981CCF, - 0x4AC21251,0x53D92310,0x78F470D3,0x61EF4192,0x2EAED755,0x37B5E614,0x1C98B5D7,0x05838496, - 0x821B9859,0x9B00A918,0xB02DFADB,0xA936CB9A,0xE6775D5D,0xFF6C6C1C,0xD4413FDF,0xCD5A0E9E, - 0x958424A2,0x8C9F15E3,0xA7B24620,0xBEA97761,0xF1E8E1A6,0xE8F3D0E7,0xC3DE8324,0xDAC5B265, - 0x5D5DAEAA,0x44469FEB,0x6F6BCC28,0x7670FD69,0x39316BAE,0x202A5AEF,0x0B07092C,0x121C386D, - 0xDF4636F3,0xC65D07B2,0xED705471,0xF46B6530,0xBB2AF3F7,0xA231C2B6,0x891C9175,0x9007A034, - 0x179FBCFB,0x0E848DBA,0x25A9DE79,0x3CB2EF38,0x73F379FF,0x6AE848BE,0x41C51B7D,0x58DE2A3C, - 0xF0794F05,0xE9627E44,0xC24F2D87,0xDB541CC6,0x94158A01,0x8D0EBB40,0xA623E883,0xBF38D9C2, - 0x38A0C50D,0x21BBF44C,0x0A96A78F,0x138D96CE,0x5CCC0009,0x45D73148,0x6EFA628B,0x77E153CA, - 0xBABB5D54,0xA3A06C15,0x888D3FD6,0x91960E97,0xDED79850,0xC7CCA911,0xECE1FAD2,0xF5FACB93, - 0x7262D75C,0x6B79E61D,0x4054B5DE,0x594F849F,0x160E1258,0x0F152319,0x243870DA,0x3D23419B, - 0x65FD6BA7,0x7CE65AE6,0x57CB0925,0x4ED03864,0x0191AEA3,0x188A9FE2,0x33A7CC21,0x2ABCFD60, - 0xAD24E1AF,0xB43FD0EE,0x9F12832D,0x8609B26C,0xC94824AB,0xD05315EA,0xFB7E4629,0xE2657768, - 0x2F3F79F6,0x362448B7,0x1D091B74,0x04122A35,0x4B53BCF2,0x52488DB3,0x7965DE70,0x607EEF31, - 0xE7E6F3FE,0xFEFDC2BF,0xD5D0917C,0xCCCBA03D,0x838A36FA,0x9A9107BB,0xB1BC5478,0xA8A76539, - 0x3B83984B,0x2298A90A,0x09B5FAC9,0x10AECB88,0x5FEF5D4F,0x46F46C0E,0x6DD93FCD,0x74C20E8C, - 0xF35A1243,0xEA412302,0xC16C70C1,0xD8774180,0x9736D747,0x8E2DE606,0xA500B5C5,0xBC1B8484, - 0x71418A1A,0x685ABB5B,0x4377E898,0x5A6CD9D9,0x152D4F1E,0x0C367E5F,0x271B2D9C,0x3E001CDD, - 0xB9980012,0xA0833153,0x8BAE6290,0x92B553D1,0xDDF4C516,0xC4EFF457,0xEFC2A794,0xF6D996D5, - 0xAE07BCE9,0xB71C8DA8,0x9C31DE6B,0x852AEF2A,0xCA6B79ED,0xD37048AC,0xF85D1B6F,0xE1462A2E, - 0x66DE36E1,0x7FC507A0,0x54E85463,0x4DF36522,0x02B2F3E5,0x1BA9C2A4,0x30849167,0x299FA026, - 0xE4C5AEB8,0xFDDE9FF9,0xD6F3CC3A,0xCFE8FD7B,0x80A96BBC,0x99B25AFD,0xB29F093E,0xAB84387F, - 0x2C1C24B0,0x350715F1,0x1E2A4632,0x07317773,0x4870E1B4,0x516BD0F5,0x7A468336,0x635DB277, - 0xCBFAD74E,0xD2E1E60F,0xF9CCB5CC,0xE0D7848D,0xAF96124A,0xB68D230B,0x9DA070C8,0x84BB4189, - 0x03235D46,0x1A386C07,0x31153FC4,0x280E0E85,0x674F9842,0x7E54A903,0x5579FAC0,0x4C62CB81, - 0x8138C51F,0x9823F45E,0xB30EA79D,0xAA1596DC,0xE554001B,0xFC4F315A,0xD7626299,0xCE7953D8, - 0x49E14F17,0x50FA7E56,0x7BD72D95,0x62CC1CD4,0x2D8D8A13,0x3496BB52,0x1FBBE891,0x06A0D9D0, - 0x5E7EF3EC,0x4765C2AD,0x6C48916E,0x7553A02F,0x3A1236E8,0x230907A9,0x0824546A,0x113F652B, - 0x96A779E4,0x8FBC48A5,0xA4911B66,0xBD8A2A27,0xF2CBBCE0,0xEBD08DA1,0xC0FDDE62,0xD9E6EF23, - 0x14BCE1BD,0x0DA7D0FC,0x268A833F,0x3F91B27E,0x70D024B9,0x69CB15F8,0x42E6463B,0x5BFD777A, - 0xDC656BB5,0xC57E5AF4,0xEE530937,0xF7483876,0xB809AEB1,0xA1129FF0,0x8A3FCC33,0x9324FD72 }, - { 0x00000000,0x01C26A37,0x0384D46E,0x0246BE59,0x0709A8DC,0x06CBC2EB,0x048D7CB2,0x054F1685, - 0x0E1351B8,0x0FD13B8F,0x0D9785D6,0x0C55EFE1,0x091AF964,0x08D89353,0x0A9E2D0A,0x0B5C473D, - 0x1C26A370,0x1DE4C947,0x1FA2771E,0x1E601D29,0x1B2F0BAC,0x1AED619B,0x18ABDFC2,0x1969B5F5, - 0x1235F2C8,0x13F798FF,0x11B126A6,0x10734C91,0x153C5A14,0x14FE3023,0x16B88E7A,0x177AE44D, - 0x384D46E0,0x398F2CD7,0x3BC9928E,0x3A0BF8B9,0x3F44EE3C,0x3E86840B,0x3CC03A52,0x3D025065, - 0x365E1758,0x379C7D6F,0x35DAC336,0x3418A901,0x3157BF84,0x3095D5B3,0x32D36BEA,0x331101DD, - 0x246BE590,0x25A98FA7,0x27EF31FE,0x262D5BC9,0x23624D4C,0x22A0277B,0x20E69922,0x2124F315, - 0x2A78B428,0x2BBADE1F,0x29FC6046,0x283E0A71,0x2D711CF4,0x2CB376C3,0x2EF5C89A,0x2F37A2AD, - 0x709A8DC0,0x7158E7F7,0x731E59AE,0x72DC3399,0x7793251C,0x76514F2B,0x7417F172,0x75D59B45, - 0x7E89DC78,0x7F4BB64F,0x7D0D0816,0x7CCF6221,0x798074A4,0x78421E93,0x7A04A0CA,0x7BC6CAFD, - 0x6CBC2EB0,0x6D7E4487,0x6F38FADE,0x6EFA90E9,0x6BB5866C,0x6A77EC5B,0x68315202,0x69F33835, - 0x62AF7F08,0x636D153F,0x612BAB66,0x60E9C151,0x65A6D7D4,0x6464BDE3,0x662203BA,0x67E0698D, - 0x48D7CB20,0x4915A117,0x4B531F4E,0x4A917579,0x4FDE63FC,0x4E1C09CB,0x4C5AB792,0x4D98DDA5, - 0x46C49A98,0x4706F0AF,0x45404EF6,0x448224C1,0x41CD3244,0x400F5873,0x4249E62A,0x438B8C1D, - 0x54F16850,0x55330267,0x5775BC3E,0x56B7D609,0x53F8C08C,0x523AAABB,0x507C14E2,0x51BE7ED5, - 0x5AE239E8,0x5B2053DF,0x5966ED86,0x58A487B1,0x5DEB9134,0x5C29FB03,0x5E6F455A,0x5FAD2F6D, - 0xE1351B80,0xE0F771B7,0xE2B1CFEE,0xE373A5D9,0xE63CB35C,0xE7FED96B,0xE5B86732,0xE47A0D05, - 0xEF264A38,0xEEE4200F,0xECA29E56,0xED60F461,0xE82FE2E4,0xE9ED88D3,0xEBAB368A,0xEA695CBD, - 0xFD13B8F0,0xFCD1D2C7,0xFE976C9E,0xFF5506A9,0xFA1A102C,0xFBD87A1B,0xF99EC442,0xF85CAE75, - 0xF300E948,0xF2C2837F,0xF0843D26,0xF1465711,0xF4094194,0xF5CB2BA3,0xF78D95FA,0xF64FFFCD, - 0xD9785D60,0xD8BA3757,0xDAFC890E,0xDB3EE339,0xDE71F5BC,0xDFB39F8B,0xDDF521D2,0xDC374BE5, - 0xD76B0CD8,0xD6A966EF,0xD4EFD8B6,0xD52DB281,0xD062A404,0xD1A0CE33,0xD3E6706A,0xD2241A5D, - 0xC55EFE10,0xC49C9427,0xC6DA2A7E,0xC7184049,0xC25756CC,0xC3953CFB,0xC1D382A2,0xC011E895, - 0xCB4DAFA8,0xCA8FC59F,0xC8C97BC6,0xC90B11F1,0xCC440774,0xCD866D43,0xCFC0D31A,0xCE02B92D, - 0x91AF9640,0x906DFC77,0x922B422E,0x93E92819,0x96A63E9C,0x976454AB,0x9522EAF2,0x94E080C5, - 0x9FBCC7F8,0x9E7EADCF,0x9C381396,0x9DFA79A1,0x98B56F24,0x99770513,0x9B31BB4A,0x9AF3D17D, - 0x8D893530,0x8C4B5F07,0x8E0DE15E,0x8FCF8B69,0x8A809DEC,0x8B42F7DB,0x89044982,0x88C623B5, - 0x839A6488,0x82580EBF,0x801EB0E6,0x81DCDAD1,0x8493CC54,0x8551A663,0x8717183A,0x86D5720D, - 0xA9E2D0A0,0xA820BA97,0xAA6604CE,0xABA46EF9,0xAEEB787C,0xAF29124B,0xAD6FAC12,0xACADC625, - 0xA7F18118,0xA633EB2F,0xA4755576,0xA5B73F41,0xA0F829C4,0xA13A43F3,0xA37CFDAA,0xA2BE979D, - 0xB5C473D0,0xB40619E7,0xB640A7BE,0xB782CD89,0xB2CDDB0C,0xB30FB13B,0xB1490F62,0xB08B6555, - 0xBBD72268,0xBA15485F,0xB853F606,0xB9919C31,0xBCDE8AB4,0xBD1CE083,0xBF5A5EDA,0xBE9834ED }, - { 0x00000000,0xB8BC6765,0xAA09C88B,0x12B5AFEE,0x8F629757,0x37DEF032,0x256B5FDC,0x9DD738B9, - 0xC5B428EF,0x7D084F8A,0x6FBDE064,0xD7018701,0x4AD6BFB8,0xF26AD8DD,0xE0DF7733,0x58631056, - 0x5019579F,0xE8A530FA,0xFA109F14,0x42ACF871,0xDF7BC0C8,0x67C7A7AD,0x75720843,0xCDCE6F26, - 0x95AD7F70,0x2D111815,0x3FA4B7FB,0x8718D09E,0x1ACFE827,0xA2738F42,0xB0C620AC,0x087A47C9, - 0xA032AF3E,0x188EC85B,0x0A3B67B5,0xB28700D0,0x2F503869,0x97EC5F0C,0x8559F0E2,0x3DE59787, - 0x658687D1,0xDD3AE0B4,0xCF8F4F5A,0x7733283F,0xEAE41086,0x525877E3,0x40EDD80D,0xF851BF68, - 0xF02BF8A1,0x48979FC4,0x5A22302A,0xE29E574F,0x7F496FF6,0xC7F50893,0xD540A77D,0x6DFCC018, - 0x359FD04E,0x8D23B72B,0x9F9618C5,0x272A7FA0,0xBAFD4719,0x0241207C,0x10F48F92,0xA848E8F7, - 0x9B14583D,0x23A83F58,0x311D90B6,0x89A1F7D3,0x1476CF6A,0xACCAA80F,0xBE7F07E1,0x06C36084, - 0x5EA070D2,0xE61C17B7,0xF4A9B859,0x4C15DF3C,0xD1C2E785,0x697E80E0,0x7BCB2F0E,0xC377486B, - 0xCB0D0FA2,0x73B168C7,0x6104C729,0xD9B8A04C,0x446F98F5,0xFCD3FF90,0xEE66507E,0x56DA371B, - 0x0EB9274D,0xB6054028,0xA4B0EFC6,0x1C0C88A3,0x81DBB01A,0x3967D77F,0x2BD27891,0x936E1FF4, - 0x3B26F703,0x839A9066,0x912F3F88,0x299358ED,0xB4446054,0x0CF80731,0x1E4DA8DF,0xA6F1CFBA, - 0xFE92DFEC,0x462EB889,0x549B1767,0xEC277002,0x71F048BB,0xC94C2FDE,0xDBF98030,0x6345E755, - 0x6B3FA09C,0xD383C7F9,0xC1366817,0x798A0F72,0xE45D37CB,0x5CE150AE,0x4E54FF40,0xF6E89825, - 0xAE8B8873,0x1637EF16,0x048240F8,0xBC3E279D,0x21E91F24,0x99557841,0x8BE0D7AF,0x335CB0CA, - 0xED59B63B,0x55E5D15E,0x47507EB0,0xFFEC19D5,0x623B216C,0xDA874609,0xC832E9E7,0x708E8E82, - 0x28ED9ED4,0x9051F9B1,0x82E4565F,0x3A58313A,0xA78F0983,0x1F336EE6,0x0D86C108,0xB53AA66D, - 0xBD40E1A4,0x05FC86C1,0x1749292F,0xAFF54E4A,0x322276F3,0x8A9E1196,0x982BBE78,0x2097D91D, - 0x78F4C94B,0xC048AE2E,0xD2FD01C0,0x6A4166A5,0xF7965E1C,0x4F2A3979,0x5D9F9697,0xE523F1F2, - 0x4D6B1905,0xF5D77E60,0xE762D18E,0x5FDEB6EB,0xC2098E52,0x7AB5E937,0x680046D9,0xD0BC21BC, - 0x88DF31EA,0x3063568F,0x22D6F961,0x9A6A9E04,0x07BDA6BD,0xBF01C1D8,0xADB46E36,0x15080953, - 0x1D724E9A,0xA5CE29FF,0xB77B8611,0x0FC7E174,0x9210D9CD,0x2AACBEA8,0x38191146,0x80A57623, - 0xD8C66675,0x607A0110,0x72CFAEFE,0xCA73C99B,0x57A4F122,0xEF189647,0xFDAD39A9,0x45115ECC, - 0x764DEE06,0xCEF18963,0xDC44268D,0x64F841E8,0xF92F7951,0x41931E34,0x5326B1DA,0xEB9AD6BF, - 0xB3F9C6E9,0x0B45A18C,0x19F00E62,0xA14C6907,0x3C9B51BE,0x842736DB,0x96929935,0x2E2EFE50, - 0x2654B999,0x9EE8DEFC,0x8C5D7112,0x34E11677,0xA9362ECE,0x118A49AB,0x033FE645,0xBB838120, - 0xE3E09176,0x5B5CF613,0x49E959FD,0xF1553E98,0x6C820621,0xD43E6144,0xC68BCEAA,0x7E37A9CF, - 0xD67F4138,0x6EC3265D,0x7C7689B3,0xC4CAEED6,0x591DD66F,0xE1A1B10A,0xF3141EE4,0x4BA87981, - 0x13CB69D7,0xAB770EB2,0xB9C2A15C,0x017EC639,0x9CA9FE80,0x241599E5,0x36A0360B,0x8E1C516E, - 0x866616A7,0x3EDA71C2,0x2C6FDE2C,0x94D3B949,0x090481F0,0xB1B8E695,0xA30D497B,0x1BB12E1E, - 0x43D23E48,0xFB6E592D,0xE9DBF6C3,0x516791A6,0xCCB0A91F,0x740CCE7A,0x66B96194,0xDE0506F1 }, - { 0x00000000,0x3D6029B0,0x7AC05360,0x47A07AD0,0xF580A6C0,0xC8E08F70,0x8F40F5A0,0xB220DC10, - 0x30704BC1,0x0D106271,0x4AB018A1,0x77D03111,0xC5F0ED01,0xF890C4B1,0xBF30BE61,0x825097D1, - 0x60E09782,0x5D80BE32,0x1A20C4E2,0x2740ED52,0x95603142,0xA80018F2,0xEFA06222,0xD2C04B92, - 0x5090DC43,0x6DF0F5F3,0x2A508F23,0x1730A693,0xA5107A83,0x98705333,0xDFD029E3,0xE2B00053, - 0xC1C12F04,0xFCA106B4,0xBB017C64,0x866155D4,0x344189C4,0x0921A074,0x4E81DAA4,0x73E1F314, - 0xF1B164C5,0xCCD14D75,0x8B7137A5,0xB6111E15,0x0431C205,0x3951EBB5,0x7EF19165,0x4391B8D5, - 0xA121B886,0x9C419136,0xDBE1EBE6,0xE681C256,0x54A11E46,0x69C137F6,0x2E614D26,0x13016496, - 0x9151F347,0xAC31DAF7,0xEB91A027,0xD6F18997,0x64D15587,0x59B17C37,0x1E1106E7,0x23712F57, - 0x58F35849,0x659371F9,0x22330B29,0x1F532299,0xAD73FE89,0x9013D739,0xD7B3ADE9,0xEAD38459, - 0x68831388,0x55E33A38,0x124340E8,0x2F236958,0x9D03B548,0xA0639CF8,0xE7C3E628,0xDAA3CF98, - 0x3813CFCB,0x0573E67B,0x42D39CAB,0x7FB3B51B,0xCD93690B,0xF0F340BB,0xB7533A6B,0x8A3313DB, - 0x0863840A,0x3503ADBA,0x72A3D76A,0x4FC3FEDA,0xFDE322CA,0xC0830B7A,0x872371AA,0xBA43581A, - 0x9932774D,0xA4525EFD,0xE3F2242D,0xDE920D9D,0x6CB2D18D,0x51D2F83D,0x167282ED,0x2B12AB5D, - 0xA9423C8C,0x9422153C,0xD3826FEC,0xEEE2465C,0x5CC29A4C,0x61A2B3FC,0x2602C92C,0x1B62E09C, - 0xF9D2E0CF,0xC4B2C97F,0x8312B3AF,0xBE729A1F,0x0C52460F,0x31326FBF,0x7692156F,0x4BF23CDF, - 0xC9A2AB0E,0xF4C282BE,0xB362F86E,0x8E02D1DE,0x3C220DCE,0x0142247E,0x46E25EAE,0x7B82771E, - 0xB1E6B092,0x8C869922,0xCB26E3F2,0xF646CA42,0x44661652,0x79063FE2,0x3EA64532,0x03C66C82, - 0x8196FB53,0xBCF6D2E3,0xFB56A833,0xC6368183,0x74165D93,0x49767423,0x0ED60EF3,0x33B62743, - 0xD1062710,0xEC660EA0,0xABC67470,0x96A65DC0,0x248681D0,0x19E6A860,0x5E46D2B0,0x6326FB00, - 0xE1766CD1,0xDC164561,0x9BB63FB1,0xA6D61601,0x14F6CA11,0x2996E3A1,0x6E369971,0x5356B0C1, - 0x70279F96,0x4D47B626,0x0AE7CCF6,0x3787E546,0x85A73956,0xB8C710E6,0xFF676A36,0xC2074386, - 0x4057D457,0x7D37FDE7,0x3A978737,0x07F7AE87,0xB5D77297,0x88B75B27,0xCF1721F7,0xF2770847, - 0x10C70814,0x2DA721A4,0x6A075B74,0x576772C4,0xE547AED4,0xD8278764,0x9F87FDB4,0xA2E7D404, - 0x20B743D5,0x1DD76A65,0x5A7710B5,0x67173905,0xD537E515,0xE857CCA5,0xAFF7B675,0x92979FC5, - 0xE915E8DB,0xD475C16B,0x93D5BBBB,0xAEB5920B,0x1C954E1B,0x21F567AB,0x66551D7B,0x5B3534CB, - 0xD965A31A,0xE4058AAA,0xA3A5F07A,0x9EC5D9CA,0x2CE505DA,0x11852C6A,0x562556BA,0x6B457F0A, - 0x89F57F59,0xB49556E9,0xF3352C39,0xCE550589,0x7C75D999,0x4115F029,0x06B58AF9,0x3BD5A349, - 0xB9853498,0x84E51D28,0xC34567F8,0xFE254E48,0x4C059258,0x7165BBE8,0x36C5C138,0x0BA5E888, - 0x28D4C7DF,0x15B4EE6F,0x521494BF,0x6F74BD0F,0xDD54611F,0xE03448AF,0xA794327F,0x9AF41BCF, - 0x18A48C1E,0x25C4A5AE,0x6264DF7E,0x5F04F6CE,0xED242ADE,0xD044036E,0x97E479BE,0xAA84500E, - 0x4834505D,0x755479ED,0x32F4033D,0x0F942A8D,0xBDB4F69D,0x80D4DF2D,0xC774A5FD,0xFA148C4D, - 0x78441B9C,0x4524322C,0x028448FC,0x3FE4614C,0x8DC4BD5C,0xB0A494EC,0xF704EE3C,0xCA64C78C }, - { 0x00000000,0xCB5CD3A5,0x4DC8A10B,0x869472AE,0x9B914216,0x50CD91B3,0xD659E31D,0x1D0530B8, - 0xEC53826D,0x270F51C8,0xA19B2366,0x6AC7F0C3,0x77C2C07B,0xBC9E13DE,0x3A0A6170,0xF156B2D5, - 0x03D6029B,0xC88AD13E,0x4E1EA390,0x85427035,0x9847408D,0x531B9328,0xD58FE186,0x1ED33223, - 0xEF8580F6,0x24D95353,0xA24D21FD,0x6911F258,0x7414C2E0,0xBF481145,0x39DC63EB,0xF280B04E, - 0x07AC0536,0xCCF0D693,0x4A64A43D,0x81387798,0x9C3D4720,0x57619485,0xD1F5E62B,0x1AA9358E, - 0xEBFF875B,0x20A354FE,0xA6372650,0x6D6BF5F5,0x706EC54D,0xBB3216E8,0x3DA66446,0xF6FAB7E3, - 0x047A07AD,0xCF26D408,0x49B2A6A6,0x82EE7503,0x9FEB45BB,0x54B7961E,0xD223E4B0,0x197F3715, - 0xE82985C0,0x23755665,0xA5E124CB,0x6EBDF76E,0x73B8C7D6,0xB8E41473,0x3E7066DD,0xF52CB578, - 0x0F580A6C,0xC404D9C9,0x4290AB67,0x89CC78C2,0x94C9487A,0x5F959BDF,0xD901E971,0x125D3AD4, - 0xE30B8801,0x28575BA4,0xAEC3290A,0x659FFAAF,0x789ACA17,0xB3C619B2,0x35526B1C,0xFE0EB8B9, - 0x0C8E08F7,0xC7D2DB52,0x4146A9FC,0x8A1A7A59,0x971F4AE1,0x5C439944,0xDAD7EBEA,0x118B384F, - 0xE0DD8A9A,0x2B81593F,0xAD152B91,0x6649F834,0x7B4CC88C,0xB0101B29,0x36846987,0xFDD8BA22, - 0x08F40F5A,0xC3A8DCFF,0x453CAE51,0x8E607DF4,0x93654D4C,0x58399EE9,0xDEADEC47,0x15F13FE2, - 0xE4A78D37,0x2FFB5E92,0xA96F2C3C,0x6233FF99,0x7F36CF21,0xB46A1C84,0x32FE6E2A,0xF9A2BD8F, - 0x0B220DC1,0xC07EDE64,0x46EAACCA,0x8DB67F6F,0x90B34FD7,0x5BEF9C72,0xDD7BEEDC,0x16273D79, - 0xE7718FAC,0x2C2D5C09,0xAAB92EA7,0x61E5FD02,0x7CE0CDBA,0xB7BC1E1F,0x31286CB1,0xFA74BF14, - 0x1EB014D8,0xD5ECC77D,0x5378B5D3,0x98246676,0x852156CE,0x4E7D856B,0xC8E9F7C5,0x03B52460, - 0xF2E396B5,0x39BF4510,0xBF2B37BE,0x7477E41B,0x6972D4A3,0xA22E0706,0x24BA75A8,0xEFE6A60D, - 0x1D661643,0xD63AC5E6,0x50AEB748,0x9BF264ED,0x86F75455,0x4DAB87F0,0xCB3FF55E,0x006326FB, - 0xF135942E,0x3A69478B,0xBCFD3525,0x77A1E680,0x6AA4D638,0xA1F8059D,0x276C7733,0xEC30A496, - 0x191C11EE,0xD240C24B,0x54D4B0E5,0x9F886340,0x828D53F8,0x49D1805D,0xCF45F2F3,0x04192156, - 0xF54F9383,0x3E134026,0xB8873288,0x73DBE12D,0x6EDED195,0xA5820230,0x2316709E,0xE84AA33B, - 0x1ACA1375,0xD196C0D0,0x5702B27E,0x9C5E61DB,0x815B5163,0x4A0782C6,0xCC93F068,0x07CF23CD, - 0xF6999118,0x3DC542BD,0xBB513013,0x700DE3B6,0x6D08D30E,0xA65400AB,0x20C07205,0xEB9CA1A0, - 0x11E81EB4,0xDAB4CD11,0x5C20BFBF,0x977C6C1A,0x8A795CA2,0x41258F07,0xC7B1FDA9,0x0CED2E0C, - 0xFDBB9CD9,0x36E74F7C,0xB0733DD2,0x7B2FEE77,0x662ADECF,0xAD760D6A,0x2BE27FC4,0xE0BEAC61, - 0x123E1C2F,0xD962CF8A,0x5FF6BD24,0x94AA6E81,0x89AF5E39,0x42F38D9C,0xC467FF32,0x0F3B2C97, - 0xFE6D9E42,0x35314DE7,0xB3A53F49,0x78F9ECEC,0x65FCDC54,0xAEA00FF1,0x28347D5F,0xE368AEFA, - 0x16441B82,0xDD18C827,0x5B8CBA89,0x90D0692C,0x8DD55994,0x46898A31,0xC01DF89F,0x0B412B3A, - 0xFA1799EF,0x314B4A4A,0xB7DF38E4,0x7C83EB41,0x6186DBF9,0xAADA085C,0x2C4E7AF2,0xE712A957, - 0x15921919,0xDECECABC,0x585AB812,0x93066BB7,0x8E035B0F,0x455F88AA,0xC3CBFA04,0x089729A1, - 0xF9C19B74,0x329D48D1,0xB4093A7F,0x7F55E9DA,0x6250D962,0xA90C0AC7,0x2F987869,0xE4C4ABCC }, - { 0x00000000,0xA6770BB4,0x979F1129,0x31E81A9D,0xF44F2413,0x52382FA7,0x63D0353A,0xC5A73E8E, - 0x33EF4E67,0x959845D3,0xA4705F4E,0x020754FA,0xC7A06A74,0x61D761C0,0x503F7B5D,0xF64870E9, - 0x67DE9CCE,0xC1A9977A,0xF0418DE7,0x56368653,0x9391B8DD,0x35E6B369,0x040EA9F4,0xA279A240, - 0x5431D2A9,0xF246D91D,0xC3AEC380,0x65D9C834,0xA07EF6BA,0x0609FD0E,0x37E1E793,0x9196EC27, - 0xCFBD399C,0x69CA3228,0x582228B5,0xFE552301,0x3BF21D8F,0x9D85163B,0xAC6D0CA6,0x0A1A0712, - 0xFC5277FB,0x5A257C4F,0x6BCD66D2,0xCDBA6D66,0x081D53E8,0xAE6A585C,0x9F8242C1,0x39F54975, - 0xA863A552,0x0E14AEE6,0x3FFCB47B,0x998BBFCF,0x5C2C8141,0xFA5B8AF5,0xCBB39068,0x6DC49BDC, - 0x9B8CEB35,0x3DFBE081,0x0C13FA1C,0xAA64F1A8,0x6FC3CF26,0xC9B4C492,0xF85CDE0F,0x5E2BD5BB, - 0x440B7579,0xE27C7ECD,0xD3946450,0x75E36FE4,0xB044516A,0x16335ADE,0x27DB4043,0x81AC4BF7, - 0x77E43B1E,0xD19330AA,0xE07B2A37,0x460C2183,0x83AB1F0D,0x25DC14B9,0x14340E24,0xB2430590, - 0x23D5E9B7,0x85A2E203,0xB44AF89E,0x123DF32A,0xD79ACDA4,0x71EDC610,0x4005DC8D,0xE672D739, - 0x103AA7D0,0xB64DAC64,0x87A5B6F9,0x21D2BD4D,0xE47583C3,0x42028877,0x73EA92EA,0xD59D995E, - 0x8BB64CE5,0x2DC14751,0x1C295DCC,0xBA5E5678,0x7FF968F6,0xD98E6342,0xE86679DF,0x4E11726B, - 0xB8590282,0x1E2E0936,0x2FC613AB,0x89B1181F,0x4C162691,0xEA612D25,0xDB8937B8,0x7DFE3C0C, - 0xEC68D02B,0x4A1FDB9F,0x7BF7C102,0xDD80CAB6,0x1827F438,0xBE50FF8C,0x8FB8E511,0x29CFEEA5, - 0xDF879E4C,0x79F095F8,0x48188F65,0xEE6F84D1,0x2BC8BA5F,0x8DBFB1EB,0xBC57AB76,0x1A20A0C2, - 0x8816EAF2,0x2E61E146,0x1F89FBDB,0xB9FEF06F,0x7C59CEE1,0xDA2EC555,0xEBC6DFC8,0x4DB1D47C, - 0xBBF9A495,0x1D8EAF21,0x2C66B5BC,0x8A11BE08,0x4FB68086,0xE9C18B32,0xD82991AF,0x7E5E9A1B, - 0xEFC8763C,0x49BF7D88,0x78576715,0xDE206CA1,0x1B87522F,0xBDF0599B,0x8C184306,0x2A6F48B2, - 0xDC27385B,0x7A5033EF,0x4BB82972,0xEDCF22C6,0x28681C48,0x8E1F17FC,0xBFF70D61,0x198006D5, - 0x47ABD36E,0xE1DCD8DA,0xD034C247,0x7643C9F3,0xB3E4F77D,0x1593FCC9,0x247BE654,0x820CEDE0, - 0x74449D09,0xD23396BD,0xE3DB8C20,0x45AC8794,0x800BB91A,0x267CB2AE,0x1794A833,0xB1E3A387, - 0x20754FA0,0x86024414,0xB7EA5E89,0x119D553D,0xD43A6BB3,0x724D6007,0x43A57A9A,0xE5D2712E, - 0x139A01C7,0xB5ED0A73,0x840510EE,0x22721B5A,0xE7D525D4,0x41A22E60,0x704A34FD,0xD63D3F49, - 0xCC1D9F8B,0x6A6A943F,0x5B828EA2,0xFDF58516,0x3852BB98,0x9E25B02C,0xAFCDAAB1,0x09BAA105, - 0xFFF2D1EC,0x5985DA58,0x686DC0C5,0xCE1ACB71,0x0BBDF5FF,0xADCAFE4B,0x9C22E4D6,0x3A55EF62, - 0xABC30345,0x0DB408F1,0x3C5C126C,0x9A2B19D8,0x5F8C2756,0xF9FB2CE2,0xC813367F,0x6E643DCB, - 0x982C4D22,0x3E5B4696,0x0FB35C0B,0xA9C457BF,0x6C636931,0xCA146285,0xFBFC7818,0x5D8B73AC, - 0x03A0A617,0xA5D7ADA3,0x943FB73E,0x3248BC8A,0xF7EF8204,0x519889B0,0x6070932D,0xC6079899, - 0x304FE870,0x9638E3C4,0xA7D0F959,0x01A7F2ED,0xC400CC63,0x6277C7D7,0x539FDD4A,0xF5E8D6FE, - 0x647E3AD9,0xC209316D,0xF3E12BF0,0x55962044,0x90311ECA,0x3646157E,0x07AE0FE3,0xA1D90457, - 0x579174BE,0xF1E67F0A,0xC00E6597,0x66796E23,0xA3DE50AD,0x05A95B19,0x34414184,0x92364A30 }, - { 0x00000000,0xCCAA009E,0x4225077D,0x8E8F07E3,0x844A0EFA,0x48E00E64,0xC66F0987,0x0AC50919, - 0xD3E51BB5,0x1F4F1B2B,0x91C01CC8,0x5D6A1C56,0x57AF154F,0x9B0515D1,0x158A1232,0xD92012AC, - 0x7CBB312B,0xB01131B5,0x3E9E3656,0xF23436C8,0xF8F13FD1,0x345B3F4F,0xBAD438AC,0x767E3832, - 0xAF5E2A9E,0x63F42A00,0xED7B2DE3,0x21D12D7D,0x2B142464,0xE7BE24FA,0x69312319,0xA59B2387, - 0xF9766256,0x35DC62C8,0xBB53652B,0x77F965B5,0x7D3C6CAC,0xB1966C32,0x3F196BD1,0xF3B36B4F, - 0x2A9379E3,0xE639797D,0x68B67E9E,0xA41C7E00,0xAED97719,0x62737787,0xECFC7064,0x205670FA, - 0x85CD537D,0x496753E3,0xC7E85400,0x0B42549E,0x01875D87,0xCD2D5D19,0x43A25AFA,0x8F085A64, - 0x562848C8,0x9A824856,0x140D4FB5,0xD8A74F2B,0xD2624632,0x1EC846AC,0x9047414F,0x5CED41D1, - 0x299DC2ED,0xE537C273,0x6BB8C590,0xA712C50E,0xADD7CC17,0x617DCC89,0xEFF2CB6A,0x2358CBF4, - 0xFA78D958,0x36D2D9C6,0xB85DDE25,0x74F7DEBB,0x7E32D7A2,0xB298D73C,0x3C17D0DF,0xF0BDD041, - 0x5526F3C6,0x998CF358,0x1703F4BB,0xDBA9F425,0xD16CFD3C,0x1DC6FDA2,0x9349FA41,0x5FE3FADF, - 0x86C3E873,0x4A69E8ED,0xC4E6EF0E,0x084CEF90,0x0289E689,0xCE23E617,0x40ACE1F4,0x8C06E16A, - 0xD0EBA0BB,0x1C41A025,0x92CEA7C6,0x5E64A758,0x54A1AE41,0x980BAEDF,0x1684A93C,0xDA2EA9A2, - 0x030EBB0E,0xCFA4BB90,0x412BBC73,0x8D81BCED,0x8744B5F4,0x4BEEB56A,0xC561B289,0x09CBB217, - 0xAC509190,0x60FA910E,0xEE7596ED,0x22DF9673,0x281A9F6A,0xE4B09FF4,0x6A3F9817,0xA6959889, - 0x7FB58A25,0xB31F8ABB,0x3D908D58,0xF13A8DC6,0xFBFF84DF,0x37558441,0xB9DA83A2,0x7570833C, - 0x533B85DA,0x9F918544,0x111E82A7,0xDDB48239,0xD7718B20,0x1BDB8BBE,0x95548C5D,0x59FE8CC3, - 0x80DE9E6F,0x4C749EF1,0xC2FB9912,0x0E51998C,0x04949095,0xC83E900B,0x46B197E8,0x8A1B9776, - 0x2F80B4F1,0xE32AB46F,0x6DA5B38C,0xA10FB312,0xABCABA0B,0x6760BA95,0xE9EFBD76,0x2545BDE8, - 0xFC65AF44,0x30CFAFDA,0xBE40A839,0x72EAA8A7,0x782FA1BE,0xB485A120,0x3A0AA6C3,0xF6A0A65D, - 0xAA4DE78C,0x66E7E712,0xE868E0F1,0x24C2E06F,0x2E07E976,0xE2ADE9E8,0x6C22EE0B,0xA088EE95, - 0x79A8FC39,0xB502FCA7,0x3B8DFB44,0xF727FBDA,0xFDE2F2C3,0x3148F25D,0xBFC7F5BE,0x736DF520, - 0xD6F6D6A7,0x1A5CD639,0x94D3D1DA,0x5879D144,0x52BCD85D,0x9E16D8C3,0x1099DF20,0xDC33DFBE, - 0x0513CD12,0xC9B9CD8C,0x4736CA6F,0x8B9CCAF1,0x8159C3E8,0x4DF3C376,0xC37CC495,0x0FD6C40B, - 0x7AA64737,0xB60C47A9,0x3883404A,0xF42940D4,0xFEEC49CD,0x32464953,0xBCC94EB0,0x70634E2E, - 0xA9435C82,0x65E95C1C,0xEB665BFF,0x27CC5B61,0x2D095278,0xE1A352E6,0x6F2C5505,0xA386559B, - 0x061D761C,0xCAB77682,0x44387161,0x889271FF,0x825778E6,0x4EFD7878,0xC0727F9B,0x0CD87F05, - 0xD5F86DA9,0x19526D37,0x97DD6AD4,0x5B776A4A,0x51B26353,0x9D1863CD,0x1397642E,0xDF3D64B0, - 0x83D02561,0x4F7A25FF,0xC1F5221C,0x0D5F2282,0x079A2B9B,0xCB302B05,0x45BF2CE6,0x89152C78, - 0x50353ED4,0x9C9F3E4A,0x121039A9,0xDEBA3937,0xD47F302E,0x18D530B0,0x965A3753,0x5AF037CD, - 0xFF6B144A,0x33C114D4,0xBD4E1337,0x71E413A9,0x7B211AB0,0xB78B1A2E,0x39041DCD,0xF5AE1D53, - 0x2C8E0FFF,0xE0240F61,0x6EAB0882,0xA201081C,0xA8C40105,0x646E019B,0xEAE10678,0x264B06E6 } -}; - - -uint32_t xe_crc32(const void* data, size_t length, uint32_t previous_crc) { - uint32_t crc = ~previous_crc; // same as previous_crc ^ 0xFFFFFFFF - - // Process eight bytes at once (Slicing-by-8). - const uint32_t* current = (const uint32_t*)data; - while (length >= 8) { -#if XE_CPU_BIGENDIAN - uint32_t one = *current++ ^ poly::byte_swap(crc); - uint32_t two = *current++; - crc = xe_crc32_lookup_[0][ two & 0xFF] ^ - xe_crc32_lookup_[1][(two>> 8) & 0xFF] ^ - xe_crc32_lookup_[2][(two>>16) & 0xFF] ^ - xe_crc32_lookup_[3][(two>>24) & 0xFF] ^ - xe_crc32_lookup_[4][ one & 0xFF] ^ - xe_crc32_lookup_[5][(one>> 8) & 0xFF] ^ - xe_crc32_lookup_[6][(one>>16) & 0xFF] ^ - xe_crc32_lookup_[7][(one>>24) & 0xFF]; -#else - uint32_t one = *current++ ^ crc; - uint32_t two = *current++; - crc = xe_crc32_lookup_[0][(two>>24) & 0xFF] ^ - xe_crc32_lookup_[1][(two>>16) & 0xFF] ^ - xe_crc32_lookup_[2][(two>> 8) & 0xFF] ^ - xe_crc32_lookup_[3][ two & 0xFF] ^ - xe_crc32_lookup_[4][(one>>24) & 0xFF] ^ - xe_crc32_lookup_[5][(one>>16) & 0xFF] ^ - xe_crc32_lookup_[6][(one>> 8) & 0xFF] ^ - xe_crc32_lookup_[7][ one & 0xFF]; -#endif // BIGENDIAN - length -= 8; - } - - // Remaining 1 to 7 bytes (standard algorithm). - const uint8_t* current_char = (const uint8_t*)current; - while (length-- > 0) { - crc = (crc >> 8) ^ xe_crc32_lookup_[0][(crc & 0xFF) ^ *current_char++]; - } - return ~crc; // same as crc ^ 0xFFFFFFFF -} diff --git a/src/xenia/core/crc32.h b/src/xenia/core/crc32.h deleted file mode 100644 index 556bf7c53..000000000 --- a/src/xenia/core/crc32.h +++ /dev/null @@ -1,19 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_CORE_CRC32_H_ -#define XENIA_CORE_CRC32_H_ - -#include - - -uint32_t xe_crc32(const void* data, size_t length, uint32_t previous_crc = 0); - - -#endif // XENIA_CORE_CRC32_H_ diff --git a/src/xenia/core/file.cc b/src/xenia/core/file.cc deleted file mode 100644 index 2c8bfd616..000000000 --- a/src/xenia/core/file.cc +++ /dev/null @@ -1,84 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - - -typedef struct xe_file { - xe_ref_t ref; - - void* handle; -} xe_file_t; - - -#if XE_LIKE_WIN32 -#define fseeko _fseeki64 -#define ftello _ftelli64 -#endif // WIN32 - - -xe_file_ref xe_file_open(const xe_file_mode mode, const xechar_t *path) { - xe_file_ref file = (xe_file_ref)xe_calloc(sizeof(xe_file_t)); - xe_ref_init((xe_ref)file); - - xechar_t mode_string[10]; - mode_string[0] = 0; - if (mode & kXEFileModeRead) { - XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), L"r")); - } - if (mode & kXEFileModeWrite) { - XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), L"w")); - } - XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), L"b")); - -#if XE_LIKE_WIN32 && XE_WCHAR - XEEXPECTZERO(_wfopen_s((FILE**)&file->handle, path, mode_string)); -#else - file->handle = fopen(path, mode_string); - XEEXPECTNOTNULL(file->handle); -#endif // WIN32 - - return file; - -XECLEANUP: - xe_file_release(file); - return NULL; -} - -void xe_file_dealloc(xe_file_ref file) { - FILE* handle = (FILE*)file->handle; - fclose(handle); - file->handle = NULL; -} - -xe_file_ref xe_file_retain(xe_file_ref file) { - xe_ref_retain((xe_ref)file); - return file; -} - -void xe_file_release(xe_file_ref file) { - xe_ref_release((xe_ref)file, (xe_ref_dealloc_t)xe_file_dealloc); -} - -size_t xe_file_get_length(xe_file_ref file) { - FILE* handle = (FILE*)file->handle; - - fseeko(handle, 0, SEEK_END); - return ftello(handle); -} - -size_t xe_file_read(xe_file_ref file, const size_t offset, - uint8_t *buffer, const size_t buffer_size) { - FILE* handle = (FILE*)file->handle; - if (fseeko(handle, offset, SEEK_SET) != 0) { - return -1; - } - - return fread(buffer, 1, buffer_size, handle); -} diff --git a/src/xenia/core/file.h b/src/xenia/core/file.h deleted file mode 100644 index 038b00c0e..000000000 --- a/src/xenia/core/file.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_CORE_FILE_H_ -#define XENIA_CORE_FILE_H_ - -#include -#include -#include - - -struct xe_file; -typedef struct xe_file* xe_file_ref; - - -typedef enum { - kXEFileModeRead = (1 << 0), - kXEFileModeWrite = (1 << 1), -} xe_file_mode; - - -xe_file_ref xe_file_open(const xe_file_mode mode, const xechar_t *path); -xe_file_ref xe_file_retain(xe_file_ref file); -void xe_file_release(xe_file_ref file); -size_t xe_file_get_length(xe_file_ref file); -size_t xe_file_read(xe_file_ref file, const size_t offset, - uint8_t *buffer, const size_t buffer_size); - - -#endif // XENIA_CORE_FILE_H_ diff --git a/src/xenia/core/mmap.h b/src/xenia/core/mmap.h index cf1dc91e5..29178c963 100644 --- a/src/xenia/core/mmap.h +++ b/src/xenia/core/mmap.h @@ -11,13 +11,16 @@ #define XENIA_CORE_MMAP_H_ #include -#include #include struct xe_mmap; typedef struct xe_mmap* xe_mmap_ref; +typedef enum { + kXEFileModeRead = (1 << 0), + kXEFileModeWrite = (1 << 1), +} xe_file_mode; xe_mmap_ref xe_mmap_open(const xe_file_mode mode, const xechar_t *path, const size_t offset, const size_t length); diff --git a/src/xenia/core/sources.gypi b/src/xenia/core/sources.gypi index c4822b89b..b4c226cc1 100644 --- a/src/xenia/core/sources.gypi +++ b/src/xenia/core/sources.gypi @@ -1,10 +1,6 @@ # Copyright 2013 Ben Vanik. All Rights Reserved. { 'sources': [ - 'crc32.cc', - 'crc32.h', - 'file.cc', - 'file.h', 'hash.cc', 'hash.h', 'mmap.h', From bca49bed4b07603cba197ee706249e381cc85007 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 16 Aug 2014 00:56:50 -0700 Subject: [PATCH 110/388] Removing xe_mutex_t. --- src/xenia/apu/audio_system.cc | 15 +-- src/xenia/apu/audio_system.h | 7 +- src/xenia/core.h | 2 +- src/xenia/core/mutex.h | 27 ----- src/xenia/core/mutex_posix.cc | 60 ---------- src/xenia/core/mutex_win.cc | 50 -------- src/xenia/core/run_loop_win.cc | 1 - src/xenia/core/sources.gypi | 3 - src/xenia/cpu/processor.cc | 7 +- src/xenia/cpu/processor.h | 6 +- src/xenia/kernel/dispatcher.cc | 6 +- src/xenia/kernel/dispatcher.h | 4 +- .../kernel/fs/devices/host_path_device.cc | 2 +- src/xenia/kernel/kernel_state.cc | 20 +--- src/xenia/kernel/kernel_state.h | 4 +- src/xenia/kernel/object_table.cc | 108 +++++++++--------- src/xenia/kernel/object_table.h | 4 +- src/xenia/kernel/objects/xnotify_listener.cc | 13 +-- src/xenia/kernel/objects/xnotify_listener.h | 4 +- src/xenia/kernel/objects/xthread.cc | 12 +- src/xenia/kernel/objects/xthread.h | 3 +- src/xenia/kernel/xobject.cc | 17 +-- src/xenia/kernel/xobject.h | 2 - 23 files changed, 101 insertions(+), 276 deletions(-) delete mode 100644 src/xenia/core/mutex.h delete mode 100644 src/xenia/core/mutex_posix.cc delete mode 100644 src/xenia/core/mutex_win.cc diff --git a/src/xenia/apu/audio_system.cc b/src/xenia/apu/audio_system.cc index 464211411..4eb659120 100644 --- a/src/xenia/apu/audio_system.cc +++ b/src/xenia/apu/audio_system.cc @@ -23,7 +23,6 @@ using namespace xe::cpu; AudioSystem::AudioSystem(Emulator* emulator) : emulator_(emulator), memory_(emulator->memory()), thread_(0), running_(false) { - lock_ = xe_mutex_alloc(); memset(clients_, 0, sizeof(clients_)); for (size_t i = 0; i < maximum_client_count_; ++i) { client_wait_handles_[i] = CreateEvent(NULL, TRUE, FALSE, NULL); @@ -35,7 +34,6 @@ AudioSystem::~AudioSystem() { for (size_t i = 0; i < maximum_client_count_; ++i) { CloseHandle(client_wait_handles_[i]); } - xe_mutex_free(lock_); } X_STATUS AudioSystem::Setup() { @@ -90,10 +88,10 @@ void AudioSystem::ThreadStart() { if (result >= WAIT_OBJECT_0 && result <= WAIT_OBJECT_0 + (maximum_client_count_ - 1)) { size_t index = result - WAIT_OBJECT_0; do { - xe_mutex_lock(lock_); + lock_.lock(); uint32_t client_callback = clients_[index].callback; uint32_t client_callback_arg = clients_[index].wrapped_callback_arg; - xe_mutex_unlock(lock_); + lock_.unlock(); if (client_callback) { uint64_t args[] = { client_callback_arg }; processor->Execute(thread_state_, client_callback, args, XECOUNT(args)); @@ -132,7 +130,7 @@ void AudioSystem::Shutdown() { X_STATUS AudioSystem::RegisterClient( uint32_t callback, uint32_t callback_arg, size_t* out_index) { assert_true(unused_clients_.size()); - xe_mutex_lock(lock_); + std::lock_guard lock(lock_); auto index = unused_clients_.front(); @@ -157,30 +155,27 @@ X_STATUS AudioSystem::RegisterClient( *out_index = index; } - xe_mutex_unlock(lock_); return X_STATUS_SUCCESS; } void AudioSystem::SubmitFrame(size_t index, uint32_t samples_ptr) { SCOPE_profile_cpu_f("apu"); - xe_mutex_lock(lock_); + std::lock_guard lock(lock_); assert_true(index < maximum_client_count_); assert_true(clients_[index].driver != NULL); (clients_[index].driver)->SubmitFrame(samples_ptr); ResetEvent(client_wait_handles_[index]); - xe_mutex_unlock(lock_); } void AudioSystem::UnregisterClient(size_t index) { SCOPE_profile_cpu_f("apu"); - xe_mutex_lock(lock_); + std::lock_guard lock(lock_); assert_true(index < maximum_client_count_); DestroyDriver(clients_[index].driver); clients_[index] = { 0 }; unused_clients_.push(index); - xe_mutex_unlock(lock_); } // free60 may be useful here, however it looks like it's using a different diff --git a/src/xenia/apu/audio_system.h b/src/xenia/apu/audio_system.h index 964e331cf..4eadcaa71 100644 --- a/src/xenia/apu/audio_system.h +++ b/src/xenia/apu/audio_system.h @@ -10,11 +10,12 @@ #ifndef XENIA_APU_AUDIO_SYSTEM_H_ #define XENIA_APU_AUDIO_SYSTEM_H_ +#include +#include + #include #include -#include - XEDECLARECLASS1(xe, Emulator); XEDECLARECLASS2(xe, cpu, Processor); XEDECLARECLASS2(xe, cpu, XenonThreadState); @@ -74,7 +75,7 @@ protected: uint32_t thread_block_; bool running_; - xe_mutex_t* lock_; + std::mutex lock_; static const size_t maximum_client_count_ = 8; diff --git a/src/xenia/core.h b/src/xenia/core.h index 8368a6eb0..a447d6167 100644 --- a/src/xenia/core.h +++ b/src/xenia/core.h @@ -19,8 +19,8 @@ namespace xe { #include #include -#include #include +#include #include #include #include diff --git a/src/xenia/core/mutex.h b/src/xenia/core/mutex.h deleted file mode 100644 index 74856d878..000000000 --- a/src/xenia/core/mutex.h +++ /dev/null @@ -1,27 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_CORE_MUTEX_H_ -#define XENIA_CORE_MUTEX_H_ - -#include - - -typedef struct xe_mutex xe_mutex_t; - - -xe_mutex_t* xe_mutex_alloc(uint32_t spin_count = 10000); -void xe_mutex_free(xe_mutex_t* mutex); - -int xe_mutex_lock(xe_mutex_t* mutex); -int xe_mutex_trylock(xe_mutex_t* mutex); -int xe_mutex_unlock(xe_mutex_t* mutex); - - -#endif // XENIA_CORE_MUTEX_H_ diff --git a/src/xenia/core/mutex_posix.cc b/src/xenia/core/mutex_posix.cc deleted file mode 100644 index aae3d042c..000000000 --- a/src/xenia/core/mutex_posix.cc +++ /dev/null @@ -1,60 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - - -struct xe_mutex { - pthread_mutex_t value; -}; - -xe_mutex_t* xe_mutex_alloc(uint32_t spin_count) { - xe_mutex_t* mutex = (xe_mutex_t*)xe_calloc(sizeof(xe_mutex_t)); - - int result = pthread_mutex_init(&mutex->value, NULL); - switch (result) { - case ENOMEM: - case EINVAL: - xe_free(mutex); - return NULL; - } - - return mutex; -} - -void xe_mutex_free(xe_mutex_t* mutex) { - int result = pthread_mutex_destroy(&mutex->value); - switch (result) { - case EBUSY: - case EINVAL: - break; - default: - break; - } - xe_free(mutex); -} - -int xe_mutex_lock(xe_mutex_t* mutex) { - return pthread_mutex_lock(&mutex->value) == EINVAL ? 1 : 0; -} - -int xe_mutex_trylock(xe_mutex_t* mutex) { - int result = pthread_mutex_trylock(&mutex->value); - switch (result) { - case EBUSY: - case EINVAL: - return 1; - default: - return 0; - } -} - -int xe_mutex_unlock(xe_mutex_t* mutex) { - return pthread_mutex_unlock(&mutex->value) == EINVAL ? 1 : 0; -} diff --git a/src/xenia/core/mutex_win.cc b/src/xenia/core/mutex_win.cc deleted file mode 100644 index 575786aec..000000000 --- a/src/xenia/core/mutex_win.cc +++ /dev/null @@ -1,50 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - - -struct xe_mutex { - CRITICAL_SECTION value; -}; - -xe_mutex_t* xe_mutex_alloc(uint32_t spin_count) { - xe_mutex_t* mutex = (xe_mutex_t*)xe_calloc(sizeof(xe_mutex_t)); - - if (spin_count) { - InitializeCriticalSectionAndSpinCount(&mutex->value, spin_count); - } else { - InitializeCriticalSection(&mutex->value); - } - - return mutex; -} - -void xe_mutex_free(xe_mutex_t* mutex) { - DeleteCriticalSection(&mutex->value); - xe_free(mutex); -} - -int xe_mutex_lock(xe_mutex_t* mutex) { - EnterCriticalSection(&mutex->value); - return 0; -} - -int xe_mutex_trylock(xe_mutex_t* mutex) { - if (TryEnterCriticalSection(&mutex->value) == TRUE) { - return 0; - } else { - return 1; - } -} - -int xe_mutex_unlock(xe_mutex_t* mutex) { - LeaveCriticalSection(&mutex->value); - return 0; -} diff --git a/src/xenia/core/run_loop_win.cc b/src/xenia/core/run_loop_win.cc index a2f9efaba..0365bfd93 100644 --- a/src/xenia/core/run_loop_win.cc +++ b/src/xenia/core/run_loop_win.cc @@ -9,7 +9,6 @@ #include -#include #include diff --git a/src/xenia/core/sources.gypi b/src/xenia/core/sources.gypi index b4c226cc1..ae943948b 100644 --- a/src/xenia/core/sources.gypi +++ b/src/xenia/core/sources.gypi @@ -4,7 +4,6 @@ 'hash.cc', 'hash.h', 'mmap.h', - 'mutex.h', 'pal.h', 'path.cc', 'path.h', @@ -20,7 +19,6 @@ ['OS == "mac" or OS == "linux"', { 'sources': [ 'mmap_posix.cc', - 'mutex_posix.cc', 'path_posix.cc', 'socket_posix.cc', ], @@ -38,7 +36,6 @@ ['OS == "win"', { 'sources': [ 'mmap_win.cc', - 'mutex_win.cc', 'pal_win.cc', 'path_win.cc', 'run_loop_win.cc', diff --git a/src/xenia/cpu/processor.cc b/src/xenia/cpu/processor.cc index f94ecf588..220c9dd4a 100644 --- a/src/xenia/cpu/processor.cc +++ b/src/xenia/cpu/processor.cc @@ -53,7 +53,7 @@ namespace { Processor::Processor(Emulator* emulator) : emulator_(emulator), export_resolver_(emulator->export_resolver()), runtime_(0), memory_(emulator->memory()), - interrupt_thread_lock_(NULL), interrupt_thread_state_(NULL), + interrupt_thread_state_(NULL), interrupt_thread_block_(0) { InitializeIfNeeded(); } @@ -62,7 +62,6 @@ Processor::~Processor() { if (interrupt_thread_block_) { memory_->HeapFree(interrupt_thread_block_, 2048); delete interrupt_thread_state_; - xe_mutex_free(interrupt_thread_lock_); } delete runtime_; @@ -103,7 +102,6 @@ int Processor::Setup() { return result; } - interrupt_thread_lock_ = xe_mutex_alloc(10000); interrupt_thread_state_ = new XenonThreadState( runtime_, 0, 16 * 1024, 0); interrupt_thread_state_->set_name("Interrupt"); @@ -171,7 +169,7 @@ uint64_t Processor::ExecuteInterrupt( SCOPE_profile_cpu_f("cpu"); // Acquire lock on interrupt thread (we can only dispatch one at a time). - xe_mutex_lock(interrupt_thread_lock_); + std::lock_guard lock(interrupt_thread_lock_); // Set 0x10C(r13) to the current CPU ID. uint8_t* p = memory_->membase(); @@ -180,6 +178,5 @@ uint64_t Processor::ExecuteInterrupt( // Execute interrupt. uint64_t result = Execute(interrupt_thread_state_, address, args, arg_count); - xe_mutex_unlock(interrupt_thread_lock_); return result; } diff --git a/src/xenia/cpu/processor.h b/src/xenia/cpu/processor.h index d5e79b0f8..6dc1634bd 100644 --- a/src/xenia/cpu/processor.h +++ b/src/xenia/cpu/processor.h @@ -10,9 +10,11 @@ #ifndef XENIA_CPU_PROCESSOR_H_ #define XENIA_CPU_PROCESSOR_H_ +#include +#include + #include -#include XEDECLARECLASS2(alloy, runtime, Breakpoint); XEDECLARECLASS1(xe, Emulator); @@ -66,7 +68,7 @@ private: Memory* memory_; Irql irql_; - xe_mutex_t* interrupt_thread_lock_; + std::mutex interrupt_thread_lock_; XenonThreadState* interrupt_thread_state_; uint64_t interrupt_thread_block_; }; diff --git a/src/xenia/kernel/dispatcher.cc b/src/xenia/kernel/dispatcher.cc index df11b62f4..1781ef76a 100644 --- a/src/xenia/kernel/dispatcher.cc +++ b/src/xenia/kernel/dispatcher.cc @@ -19,21 +19,19 @@ namespace kernel { Dispatcher::Dispatcher(KernelState* kernel_state) : kernel_state_(kernel_state) { - lock_ = xe_mutex_alloc(); dpc_list_ = new NativeList(kernel_state->memory()); } Dispatcher::~Dispatcher() { delete dpc_list_; - xe_mutex_free(lock_); } void Dispatcher::Lock() { - xe_mutex_lock(lock_); + lock_.lock(); } void Dispatcher::Unlock() { - xe_mutex_unlock(lock_); + lock_.unlock(); } } // namespace kernel diff --git a/src/xenia/kernel/dispatcher.h b/src/xenia/kernel/dispatcher.h index 6f8bb6cf4..ff7e9b189 100644 --- a/src/xenia/kernel/dispatcher.h +++ b/src/xenia/kernel/dispatcher.h @@ -10,6 +10,8 @@ #ifndef XENIA_KERNEL_XBOXKRNL_DISPATCHER_H_ #define XENIA_KERNEL_XBOXKRNL_DISPATCHER_H_ +#include + #include #include @@ -40,7 +42,7 @@ private: private: KernelState* kernel_state_; - xe_mutex_t* lock_; + std::mutex lock_; NativeList* dpc_list_; }; diff --git a/src/xenia/kernel/fs/devices/host_path_device.cc b/src/xenia/kernel/fs/devices/host_path_device.cc index c134071ba..9bd4c4a29 100644 --- a/src/xenia/kernel/fs/devices/host_path_device.cc +++ b/src/xenia/kernel/fs/devices/host_path_device.cc @@ -9,8 +9,8 @@ #include +#include #include - #include using namespace xe; diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index 1d1b81a07..ed3537af2 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -45,7 +45,6 @@ KernelState::KernelState(Emulator* emulator) : user_profile_ = std::make_unique(); object_table_ = new ObjectTable(); - object_mutex_ = xe_mutex_alloc(10000); assert_null(shared_kernel_state_); shared_kernel_state_ = this; @@ -57,7 +56,6 @@ KernelState::~KernelState() { SetExecutableModule(NULL); // Delete all objects. - xe_mutex_free(object_mutex_); delete object_table_; // Shutdown apps. @@ -124,41 +122,37 @@ void KernelState::SetExecutableModule(XUserModule* module) { } void KernelState::RegisterThread(XThread* thread) { - xe_mutex_lock(object_mutex_); + std::lock_guard lock(object_mutex_); threads_by_id_[thread->thread_id()] = thread; - xe_mutex_unlock(object_mutex_); } void KernelState::UnregisterThread(XThread* thread) { - xe_mutex_lock(object_mutex_); + std::lock_guard lock(object_mutex_); auto it = threads_by_id_.find(thread->thread_id()); if (it != threads_by_id_.end()) { threads_by_id_.erase(it); } - xe_mutex_unlock(object_mutex_); } XThread* KernelState::GetThreadByID(uint32_t thread_id) { + std::lock_guard lock(object_mutex_); XThread* thread = NULL; - xe_mutex_lock(object_mutex_); auto it = threads_by_id_.find(thread_id); if (it != threads_by_id_.end()) { thread = it->second; // Caller must release. thread->Retain(); } - xe_mutex_unlock(object_mutex_); return thread; } void KernelState::RegisterNotifyListener(XNotifyListener* listener) { - xe_mutex_lock(object_mutex_); + std::lock_guard lock(object_mutex_); notify_listeners_.push_back(listener); - xe_mutex_unlock(object_mutex_); } void KernelState::UnregisterNotifyListener(XNotifyListener* listener) { - xe_mutex_lock(object_mutex_); + std::lock_guard lock(object_mutex_); for (auto it = notify_listeners_.begin(); it != notify_listeners_.end(); ++it) { if (*it == listener) { @@ -166,16 +160,14 @@ void KernelState::UnregisterNotifyListener(XNotifyListener* listener) { break; } } - xe_mutex_unlock(object_mutex_); } void KernelState::BroadcastNotification(XNotificationID id, uint32_t data) { - xe_mutex_lock(object_mutex_); + std::lock_guard lock(object_mutex_); for (auto it = notify_listeners_.begin(); it != notify_listeners_.end(); ++it) { (*it)->EnqueueNotification(id, data); } - xe_mutex_unlock(object_mutex_); } void KernelState::CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result, uint32_t length) { diff --git a/src/xenia/kernel/kernel_state.h b/src/xenia/kernel/kernel_state.h index 097566f90..3587e3c46 100644 --- a/src/xenia/kernel/kernel_state.h +++ b/src/xenia/kernel/kernel_state.h @@ -11,6 +11,7 @@ #define XENIA_KERNEL_KERNEL_STATE_H_ #include +#include #include #include @@ -55,6 +56,7 @@ public: UserProfile* user_profile() const { return user_profile_.get(); } ObjectTable* object_table() const { return object_table_; } + std::mutex& object_mutex() { return object_mutex_; } void RegisterModule(XModule* module); void UnregisterModule(XModule* module); @@ -85,7 +87,7 @@ private: std::unique_ptr user_profile_; ObjectTable* object_table_; - xe_mutex_t* object_mutex_; + std::mutex object_mutex_; std::unordered_map threads_by_id_; std::vector notify_listeners_; diff --git a/src/xenia/kernel/object_table.cc b/src/xenia/kernel/object_table.cc index 0b338d072..b6199db69 100644 --- a/src/xenia/kernel/object_table.cc +++ b/src/xenia/kernel/object_table.cc @@ -21,12 +21,10 @@ ObjectTable::ObjectTable() : table_capacity_(0), table_(NULL), last_free_entry_(0) { - table_mutex_ = xe_mutex_alloc(0); - assert_not_null(table_mutex_); } ObjectTable::~ObjectTable() { - xe_mutex_lock(table_mutex_); + std::lock_guard lock(table_mutex_); // Release all objects. for (uint32_t n = 0; n < table_capacity_; n++) { @@ -41,11 +39,6 @@ ObjectTable::~ObjectTable() { last_free_entry_ = 0; xe_free(table_); table_ = NULL; - - xe_mutex_unlock(table_mutex_); - - xe_mutex_free(table_mutex_); - table_mutex_ = NULL; } X_STATUS ObjectTable::FindFreeSlot(uint32_t* out_slot) { @@ -91,25 +84,25 @@ X_STATUS ObjectTable::AddHandle(XObject* object, X_HANDLE* out_handle) { assert_not_null(out_handle); X_STATUS result = X_STATUS_SUCCESS; - - xe_mutex_lock(table_mutex_); - - // Find a free slot. + uint32_t slot = 0; - result = FindFreeSlot(&slot); + { + std::lock_guard lock(table_mutex_); - // Stash. - if (XSUCCEEDED(result)) { - ObjectTableEntry& entry = table_[slot]; - entry.object = object; + // Find a free slot. + result = FindFreeSlot(&slot); - // Retain so long as the object is in the table. - object->RetainHandle(); - object->Retain(); + // Stash. + if (XSUCCEEDED(result)) { + ObjectTableEntry& entry = table_[slot]; + entry.object = object; + + // Retain so long as the object is in the table. + object->RetainHandle(); + object->Retain(); + } } - xe_mutex_unlock(table_mutex_); - if (XSUCCEEDED(result)) { *out_handle = slot << 2; } @@ -125,27 +118,27 @@ X_STATUS ObjectTable::RemoveHandle(X_HANDLE handle) { return X_STATUS_INVALID_HANDLE; } - xe_mutex_lock(table_mutex_); - - // Lower 2 bits are ignored. - uint32_t slot = handle >> 2; - - // Verify slot. XObject* object = NULL; - if (slot > table_capacity_) { - result = X_STATUS_INVALID_HANDLE; - } else { - ObjectTableEntry& entry = table_[slot]; - if (entry.object) { - // Release after we lose the lock. - object = entry.object; - } else { + { + std::lock_guard lock(table_mutex_); + + // Lower 2 bits are ignored. + uint32_t slot = handle >> 2; + + // Verify slot. + if (slot > table_capacity_) { result = X_STATUS_INVALID_HANDLE; + } else { + ObjectTableEntry& entry = table_[slot]; + if (entry.object) { + // Release after we lose the lock. + object = entry.object; + } else { + result = X_STATUS_INVALID_HANDLE; + } } } - xe_mutex_unlock(table_mutex_); - if (object) { // Release the object handle now that it is out of the table. object->ReleaseHandle(); @@ -165,30 +158,31 @@ X_STATUS ObjectTable::GetObject(X_HANDLE handle, XObject** out_object) { return X_STATUS_INVALID_HANDLE; } - xe_mutex_lock(table_mutex_); - - // Lower 2 bits are ignored. - uint32_t slot = handle >> 2; - - // Verify slot. XObject* object = NULL; - if (slot > table_capacity_) { - result = X_STATUS_INVALID_HANDLE; - } else { - ObjectTableEntry& entry = table_[slot]; - if (entry.object) { - object = entry.object; - } else { + { + std::lock_guard lock(table_mutex_); + + // Lower 2 bits are ignored. + uint32_t slot = handle >> 2; + + // Verify slot. + if (slot > table_capacity_) { result = X_STATUS_INVALID_HANDLE; + } else { + ObjectTableEntry& entry = table_[slot]; + if (entry.object) { + object = entry.object; + } else { + result = X_STATUS_INVALID_HANDLE; + } } - } - // Retain the object pointer. - if (object) { - object->Retain(); - } + // Retain the object pointer. + if (object) { + object->Retain(); + } - xe_mutex_unlock(table_mutex_); + } *out_object = object; return result; diff --git a/src/xenia/kernel/object_table.h b/src/xenia/kernel/object_table.h index ddd0dc4cc..3cd5cf87e 100644 --- a/src/xenia/kernel/object_table.h +++ b/src/xenia/kernel/object_table.h @@ -10,6 +10,8 @@ #ifndef XENIA_KERNEL_XBOXKRNL_OBJECT_TABLE_H_ #define XENIA_KERNEL_XBOXKRNL_OBJECT_TABLE_H_ +#include + #include #include @@ -40,7 +42,7 @@ private: XObject* object; } ObjectTableEntry; - xe_mutex_t* table_mutex_; + std::mutex table_mutex_; uint32_t table_capacity_; ObjectTableEntry* table_; uint32_t last_free_entry_; diff --git a/src/xenia/kernel/objects/xnotify_listener.cc b/src/xenia/kernel/objects/xnotify_listener.cc index e205f6b6d..9de2224ea 100644 --- a/src/xenia/kernel/objects/xnotify_listener.cc +++ b/src/xenia/kernel/objects/xnotify_listener.cc @@ -16,12 +16,11 @@ using namespace xe::kernel; XNotifyListener::XNotifyListener(KernelState* kernel_state) : XObject(kernel_state, kTypeNotifyListener), - wait_handle_(NULL), lock_(0), mask_(0), notification_count_(0) { + wait_handle_(NULL), mask_(0), notification_count_(0) { } XNotifyListener::~XNotifyListener() { kernel_state_->UnregisterNotifyListener(this); - xe_mutex_free(lock_); if (wait_handle_) { CloseHandle(wait_handle_); } @@ -30,7 +29,6 @@ XNotifyListener::~XNotifyListener() { void XNotifyListener::Initialize(uint64_t mask) { assert_null(wait_handle_); - lock_ = xe_mutex_alloc(); wait_handle_ = CreateEvent(NULL, TRUE, FALSE, NULL); mask_ = mask; @@ -43,7 +41,7 @@ void XNotifyListener::EnqueueNotification(XNotificationID id, uint32_t data) { return; } - xe_mutex_lock(lock_); + std::lock_guard lock(lock_); if (notifications_.count(id)) { // Already exists. Overwrite. notifications_[id] = data; @@ -53,13 +51,12 @@ void XNotifyListener::EnqueueNotification(XNotificationID id, uint32_t data) { notifications_.insert({ id, data }); } SetEvent(wait_handle_); - xe_mutex_unlock(lock_); } bool XNotifyListener::DequeueNotification( XNotificationID* out_id, uint32_t* out_data) { + std::lock_guard lock(lock_); bool dequeued = false; - xe_mutex_lock(lock_); if (notification_count_) { dequeued = true; auto it = notifications_.begin(); @@ -71,14 +68,13 @@ bool XNotifyListener::DequeueNotification( ResetEvent(wait_handle_); } } - xe_mutex_unlock(lock_); return dequeued; } bool XNotifyListener::DequeueNotification( XNotificationID id, uint32_t* out_data) { + std::lock_guard lock(lock_); bool dequeued = false; - xe_mutex_lock(lock_); if (notification_count_) { dequeued = true; auto it = notifications_.find(id); @@ -91,6 +87,5 @@ bool XNotifyListener::DequeueNotification( } } } - xe_mutex_unlock(lock_); return dequeued; } diff --git a/src/xenia/kernel/objects/xnotify_listener.h b/src/xenia/kernel/objects/xnotify_listener.h index 436c4434a..7a7fc6e6a 100644 --- a/src/xenia/kernel/objects/xnotify_listener.h +++ b/src/xenia/kernel/objects/xnotify_listener.h @@ -13,6 +13,8 @@ #ifndef XENIA_KERNEL_XBOXKRNL_XNOTIFY_LISTENER_H_ #define XENIA_KERNEL_XBOXKRNL_XNOTIFY_LISTENER_H_ +#include + #include #include @@ -37,7 +39,7 @@ public: private: HANDLE wait_handle_; - xe_mutex_t* lock_; + std::mutex lock_; std::unordered_map notifications_; size_t notification_count_; uint64_t mask_; diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index d24127db8..70918dd8c 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -26,7 +26,7 @@ using namespace xe::kernel; namespace { static uint32_t next_xthread_id = 0; static thread_local XThread* current_thread_tls; - static xe_mutex_t* critical_region_ = xe_mutex_alloc(10000); + static std::mutex critical_region_; static XThread* shared_kernel_thread_ = 0; } @@ -58,7 +58,6 @@ XThread::XThread(KernelState* kernel_state, creation_params_.stack_size = 16 * 1024; } - apc_lock_ = xe_mutex_alloc(); apc_list_ = new NativeList(kernel_state->memory()); event_ = new XEvent(kernel_state); @@ -79,7 +78,6 @@ XThread::~XThread() { kernel_state_->UnregisterThread(this); delete apc_list_; - xe_mutex_free(apc_lock_); event_->Release(); @@ -421,11 +419,11 @@ void XThread::Execute() { void XThread::EnterCriticalRegion() { // Global critical region. This isn't right, but is easy. - xe_mutex_lock(critical_region_); + critical_region_.lock(); } void XThread::LeaveCriticalRegion() { - xe_mutex_unlock(critical_region_); + critical_region_.unlock(); } uint32_t XThread::RaiseIrql(uint32_t new_irql) { @@ -437,12 +435,12 @@ void XThread::LowerIrql(uint32_t new_irql) { } void XThread::LockApc() { - xe_mutex_lock(apc_lock_); + apc_lock_.lock(); } void XThread::UnlockApc() { bool needs_apc = apc_list_->HasPending(); - xe_mutex_unlock(apc_lock_); + apc_lock_.unlock(); if (needs_apc) { QueueUserAPC(reinterpret_cast(DeliverAPCs), thread_handle_, diff --git a/src/xenia/kernel/objects/xthread.h b/src/xenia/kernel/objects/xthread.h index 3b1f236aa..06c93fc73 100644 --- a/src/xenia/kernel/objects/xthread.h +++ b/src/xenia/kernel/objects/xthread.h @@ -11,6 +11,7 @@ #define XENIA_KERNEL_XBOXKRNL_XTHREAD_H_ #include +#include #include @@ -98,7 +99,7 @@ private: char* name_; std::atomic irql_; - xe_mutex_t* apc_lock_; + std::mutex apc_lock_; NativeList* apc_list_; XEvent* event_; diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index 5574b3454..555271832 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -147,16 +147,8 @@ X_STATUS XObject::WaitMultiple( return result; } -void XObject::LockType() { - xe_mutex_lock(KernelState::shared()->object_mutex_); -} - -void XObject::UnlockType() { - xe_mutex_unlock(KernelState::shared()->object_mutex_); -} - void XObject::SetNativePointer(uint32_t native_ptr) { - XObject::LockType(); + std::lock_guard lock(kernel_state_->object_mutex()); DISPATCH_HEADER* header_be = (DISPATCH_HEADER*)kernel_state_->memory()->Translate(native_ptr); @@ -173,8 +165,6 @@ void XObject::SetNativePointer(uint32_t native_ptr) { object_ptr |= 0x1; header_be->wait_list_flink = poly::byte_swap((uint32_t)(object_ptr >> 32)); header_be->wait_list_blink = poly::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF)); - - XObject::UnlockType(); } XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr, @@ -188,7 +178,7 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr, // We identify this by checking the low bit of wait_list_blink - if it's 1, // we have already put our pointer in there. - XObject::LockType(); + std::lock_guard lock(kernel_state->object_mutex()); DISPATCH_HEADER* header_be = (DISPATCH_HEADER*)native_ptr; DISPATCH_HEADER header; @@ -208,7 +198,6 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr, ((header.wait_list_blink) & ~0x1); XObject* object = reinterpret_cast(object_ptr); // TODO(benvanik): assert nothing has been changed in the struct. - XObject::UnlockType(); return object; } else { // First use, create new. @@ -252,7 +241,6 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr, case 24: // ThreadedDpcObject default: assert_always(); - XObject::UnlockType(); return NULL; } @@ -262,7 +250,6 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr, header_be->wait_list_flink = poly::byte_swap((uint32_t)(object_ptr >> 32)); header_be->wait_list_blink = poly::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF)); - XObject::UnlockType(); return object; } } diff --git a/src/xenia/kernel/xobject.h b/src/xenia/kernel/xobject.h index 9be1a632e..3f267579a 100644 --- a/src/xenia/kernel/xobject.h +++ b/src/xenia/kernel/xobject.h @@ -74,8 +74,6 @@ public: uint32_t wait_type, uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable, uint64_t* opt_timeout); - static void LockType(); - static void UnlockType(); static XObject* GetObject(KernelState* kernel_state, void* native_ptr, int32_t as_type = -1); From 01f0b14250a57752354345427020e7d3cecf0176 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 16 Aug 2014 01:36:45 -0700 Subject: [PATCH 111/388] Removing xe_thread_t. --- src/poly/threading.h | 4 + src/poly/threading_mac.cc | 8 ++ src/poly/threading_win.cc | 30 ++++++ src/xenia/apu/audio_system.cc | 16 ++-- src/xenia/apu/audio_system.h | 9 +- src/xenia/core.h | 1 - src/xenia/core/run_loop_win.cc | 2 - src/xenia/core/sources.gypi | 2 - src/xenia/core/thread.cc | 153 ------------------------------- src/xenia/core/thread.h | 34 ------- src/xenia/gpu/graphics_system.cc | 16 ++-- src/xenia/gpu/graphics_system.h | 10 +- 12 files changed, 69 insertions(+), 216 deletions(-) delete mode 100644 src/xenia/core/thread.cc delete mode 100644 src/xenia/core/thread.h diff --git a/src/poly/threading.h b/src/poly/threading.h index 431dda291..61e74a300 100644 --- a/src/poly/threading.h +++ b/src/poly/threading.h @@ -12,6 +12,7 @@ #include #include +#include #include @@ -25,6 +26,9 @@ uint64_t ticks(); // purposes only. uint32_t current_thread_id(); +// Sets the current thread name. +void set_name(const std::string& name); + // Yields the current thread to the scheduler. Maybe. void Yield(); diff --git a/src/poly/threading_mac.cc b/src/poly/threading_mac.cc index 5ee15b677..b0ec61406 100644 --- a/src/poly/threading_mac.cc +++ b/src/poly/threading_mac.cc @@ -24,6 +24,14 @@ uint32_t current_thread_id() { return static_cast(tid); } +void set_name(const std::string& name) { +#if XE_LIKE_OSX + pthread_setname_np(name.c_str()); +#else + pthread_setname_np(pthread_self(), name.c_str()); +#endif // XE_LIKE_OSX +} + void Yield() { pthread_yield_np(); } void Sleep(std::chrono::microseconds duration) { diff --git a/src/poly/threading_win.cc b/src/poly/threading_win.cc index 27689ab28..d5a1a2b3f 100644 --- a/src/poly/threading_win.cc +++ b/src/poly/threading_win.cc @@ -27,6 +27,36 @@ uint32_t current_thread_id() { return static_cast(GetCurrentThreadId()); } +// http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx +#pragma pack(push, 8) +struct THREADNAME_INFO { + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. +}; +#pragma pack(pop) + +void set_name(DWORD thread_id, const std::string& name) { + if (!IsDebuggerPresent()) { + return; + } + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = name.c_str(); + info.dwThreadID = thread_id; + info.dwFlags = 0; + __try { + RaiseException(0x406D1388, 0, sizeof(info) / sizeof(ULONG_PTR), + reinterpret_cast(&info)); + } + __except(EXCEPTION_EXECUTE_HANDLER) {} +} + +void set_name(const std::string& name) { + set_name(static_cast(-1), name); +} + void Yield() { SwitchToThread(); } void Sleep(std::chrono::microseconds duration) { diff --git a/src/xenia/apu/audio_system.cc b/src/xenia/apu/audio_system.cc index 4eb659120..c61e1fe84 100644 --- a/src/xenia/apu/audio_system.cc +++ b/src/xenia/apu/audio_system.cc @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -22,7 +23,7 @@ using namespace xe::cpu; AudioSystem::AudioSystem(Emulator* emulator) : emulator_(emulator), memory_(emulator->memory()), - thread_(0), running_(false) { + running_(false) { memset(clients_, 0, sizeof(clients_)); for (size_t i = 0; i < maximum_client_count_; ++i) { client_wait_handles_[i] = CreateEvent(NULL, TRUE, FALSE, NULL); @@ -61,15 +62,15 @@ X_STATUS AudioSystem::Setup() { // Init needs to happen there so that any thread-local stuff // is created on the right thread. running_ = true; - thread_ = xe_thread_create( - "AudioSystem", - (xe_thread_callback)ThreadStartThunk, this); - xe_thread_start(thread_); + thread_ = std::thread(std::bind(&AudioSystem::ThreadStart, this)); return X_STATUS_SUCCESS; } void AudioSystem::ThreadStart() { + poly::threading::set_name("AudioSystemThread"); + xe::Profiler::ThreadEnter("AudioSystemThread"); + // Initialize driver and ringbuffer. Initialize(); @@ -113,6 +114,8 @@ void AudioSystem::ThreadStart() { running_ = false; // TODO(benvanik): call module API to kill? + + xe::Profiler::ThreadExit(); } void AudioSystem::Initialize() { @@ -120,8 +123,7 @@ void AudioSystem::Initialize() { void AudioSystem::Shutdown() { running_ = false; - xe_thread_join(thread_); - xe_thread_release(thread_); + thread_.join(); delete thread_state_; memory()->HeapFree(thread_block_, 0); diff --git a/src/xenia/apu/audio_system.h b/src/xenia/apu/audio_system.h index 4eadcaa71..25f871745 100644 --- a/src/xenia/apu/audio_system.h +++ b/src/xenia/apu/audio_system.h @@ -10,8 +10,10 @@ #ifndef XENIA_APU_AUDIO_SYSTEM_H_ #define XENIA_APU_AUDIO_SYSTEM_H_ +#include #include #include +#include #include #include @@ -50,9 +52,6 @@ protected: virtual void Initialize(); private: - static void ThreadStartThunk(AudioSystem* this_ptr) { - this_ptr->ThreadStart(); - } void ThreadStart(); static uint64_t MMIOReadRegisterThunk(AudioSystem* as, uint64_t addr) { @@ -70,10 +69,10 @@ protected: Memory* memory_; cpu::Processor* processor_; - xe_thread_ref thread_; + std::thread thread_; cpu::XenonThreadState* thread_state_; uint32_t thread_block_; - bool running_; + std::atomic running_; std::mutex lock_; diff --git a/src/xenia/core.h b/src/xenia/core.h index a447d6167..3f606cc7a 100644 --- a/src/xenia/core.h +++ b/src/xenia/core.h @@ -24,6 +24,5 @@ namespace xe { #include #include #include -#include #endif // XENIA_CORE_H_ diff --git a/src/xenia/core/run_loop_win.cc b/src/xenia/core/run_loop_win.cc index 0365bfd93..164932f1b 100644 --- a/src/xenia/core/run_loop_win.cc +++ b/src/xenia/core/run_loop_win.cc @@ -9,8 +9,6 @@ #include -#include - typedef struct xe_run_loop { xe_ref_t ref; diff --git a/src/xenia/core/sources.gypi b/src/xenia/core/sources.gypi index ae943948b..450a12cbd 100644 --- a/src/xenia/core/sources.gypi +++ b/src/xenia/core/sources.gypi @@ -11,8 +11,6 @@ 'ref.h', 'run_loop.h', 'socket.h', - 'thread.cc', - 'thread.h', ], 'conditions': [ diff --git a/src/xenia/core/thread.cc b/src/xenia/core/thread.cc deleted file mode 100644 index 8aace9ee4..000000000 --- a/src/xenia/core/thread.cc +++ /dev/null @@ -1,153 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - - -typedef struct xe_thread { - xe_ref_t ref; - - char* name; - - xe_thread_callback callback; - void* callback_param; - - void* handle; -} xe_thread_t; - - - -xe_thread_ref xe_thread_create( - const char* name, xe_thread_callback callback, void* param) { - xe_thread_ref thread = (xe_thread_ref)xe_calloc(sizeof(xe_thread_t)); - xe_ref_init((xe_ref)thread); - - thread->name = xestrdupa(name); - thread->callback = callback; - thread->callback_param = param; - - return thread; -} - -void xe_thread_dealloc(xe_thread_ref thread) { - thread->handle = NULL; - xe_free(thread->name); -} - -xe_thread_ref xe_thread_retain(xe_thread_ref thread) { - xe_ref_retain((xe_ref)thread); - return thread; -} - -void xe_thread_release(xe_thread_ref thread) { - xe_ref_release((xe_ref)thread, (xe_ref_dealloc_t)xe_thread_dealloc); -} - -#if XE_PLATFORM_WIN32 - -// http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx -#pragma pack(push,8) -typedef struct tagTHREADNAME_INFO -{ - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1=caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. -} THREADNAME_INFO; -#pragma pack(pop) - -#pragma warning(disable : 6320; disable : 6322) -static uint32_t __stdcall xe_thread_callback_win32(void* param) { - xe_thread_t* thread = reinterpret_cast(param); - - if (IsDebuggerPresent()) { - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = thread->name; - info.dwThreadID = (DWORD)-1; - info.dwFlags = 0; - __try { - RaiseException(0x406D1388, 0, sizeof(info) / sizeof(ULONG_PTR), - (ULONG_PTR*)&info); - } __except(EXCEPTION_EXECUTE_HANDLER) { - } - } - - xe::Profiler::ThreadEnter(thread->name); - thread->callback(thread->callback_param); - xe::Profiler::ThreadExit(); - return 0; -} -#pragma warning(default : 6320; default : 6322) - -int xe_thread_start(xe_thread_ref thread) { - HANDLE thread_handle = CreateThread( - NULL, - 0, - (LPTHREAD_START_ROUTINE)xe_thread_callback_win32, - thread, - 0, - NULL); - if (!thread_handle) { - uint32_t last_error = GetLastError(); - // TODO(benvanik): translate? - XELOGE("CreateThread failed with %d", last_error); - return last_error; - } - - thread->handle = reinterpret_cast(thread_handle); - - return 0; -} - -void xe_thread_join(xe_thread_ref thread) { - HANDLE thread_handle = (HANDLE)thread->handle; - WaitForSingleObject(thread_handle, INFINITE); -} - -#else - -static void* xe_thread_callback_pthreads(void* param) { - xe_thread_t* thread = reinterpret_cast(param); -#if XE_LIKE_OSX - XEIGNORE(pthread_setname_np(thread->name)); -#else - pthread_setname_np(pthread_self(), thread->name); -#endif // OSX - xe::Profiler::ThreadEnter(thread->name); - thread->callback(thread->callback_param); - xe::Profiler::ThreadExit(); - return 0; -} - -int xe_thread_start(xe_thread_ref thread) { - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_t thread_handle; - int result_code = pthread_create( - &thread_handle, - &attr, - &xe_thread_callback_pthreads, - thread); - pthread_attr_destroy(&attr); - if (result_code) { - return result_code; - } - - thread->handle = reinterpret_cast(thread_handle); - - return 0; -} - -void xe_thread_join(xe_thread_ref thread) { - pthread_join((pthread_t)thread->handle, NULL); -} - -#endif // WIN32 diff --git a/src/xenia/core/thread.h b/src/xenia/core/thread.h deleted file mode 100644 index 1aa8fb0bb..000000000 --- a/src/xenia/core/thread.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_CORE_THREAD_H_ -#define XENIA_CORE_THREAD_H_ - -#include -#include -#include - - -struct xe_thread; -typedef struct xe_thread* xe_thread_ref; - - -typedef void (*xe_thread_callback)(void* param); - - -xe_thread_ref xe_thread_create( - const char* name, xe_thread_callback callback, void* param); -xe_thread_ref xe_thread_retain(xe_thread_ref thread); -void xe_thread_release(xe_thread_ref thread); - -int xe_thread_start(xe_thread_ref thread); -void xe_thread_join(xe_thread_ref thread); - - -#endif // XENIA_CORE_THREAD_H_ diff --git a/src/xenia/gpu/graphics_system.cc b/src/xenia/gpu/graphics_system.cc index abd03e2d6..6ab0d14ff 100644 --- a/src/xenia/gpu/graphics_system.cc +++ b/src/xenia/gpu/graphics_system.cc @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -25,7 +26,7 @@ using namespace xe::gpu::xenos; GraphicsSystem::GraphicsSystem(Emulator* emulator) : emulator_(emulator), memory_(emulator->memory()), - thread_(nullptr), running_(false), driver_(nullptr), + running_(false), driver_(nullptr), command_processor_(nullptr), interrupt_callback_(0), interrupt_callback_data_(0), last_interrupt_time_(0), thread_wait_(nullptr) { @@ -59,15 +60,15 @@ X_STATUS GraphicsSystem::Setup() { // Init needs to happen there so that any thread-local stuff // is created on the right thread. running_ = true; - thread_ = xe_thread_create( - "GraphicsSystem", - (xe_thread_callback)ThreadStartThunk, this); - xe_thread_start(thread_); + thread_ = std::thread(std::bind(&GraphicsSystem::ThreadStart, this)); WaitForSingleObject(thread_wait_, INFINITE); return X_STATUS_SUCCESS; } void GraphicsSystem::ThreadStart() { + poly::threading::set_name("GraphicsSystemThread"); + xe::Profiler::ThreadEnter("GraphicsSystemThread"); + xe_run_loop_ref run_loop = xe_run_loop_retain(run_loop_); // Initialize driver and ringbuffer. @@ -101,6 +102,8 @@ void GraphicsSystem::ThreadStart() { running_ = false; xe_run_loop_release(run_loop); + + xe::Profiler::ThreadExit(); } void GraphicsSystem::Initialize() { @@ -108,8 +111,7 @@ void GraphicsSystem::Initialize() { void GraphicsSystem::Shutdown() { running_ = false; - xe_thread_join(thread_); - xe_thread_release(thread_); + thread_.join(); delete command_processor_; diff --git a/src/xenia/gpu/graphics_system.h b/src/xenia/gpu/graphics_system.h index 3b8fdabb1..84685db79 100644 --- a/src/xenia/gpu/graphics_system.h +++ b/src/xenia/gpu/graphics_system.h @@ -10,6 +10,9 @@ #ifndef XENIA_GPU_GRAPHICS_SYSTEM_H_ #define XENIA_GPU_GRAPHICS_SYSTEM_H_ +#include +#include + #include #include @@ -52,9 +55,6 @@ protected: virtual void Pump() = 0; private: - static void ThreadStartThunk(GraphicsSystem* this_ptr) { - this_ptr->ThreadStart(); - } void ThreadStart(); static uint64_t MMIOReadRegisterThunk(GraphicsSystem* gs, uint64_t addr) { @@ -73,8 +73,8 @@ protected: cpu::Processor* processor_; xe_run_loop_ref run_loop_; - xe_thread_ref thread_; - bool running_; + std::thread thread_; + std::atomic running_; GraphicsDriver* driver_; CommandProcessor* command_processor_; From a4dfc23abcc1d463caf8b94d3571745917225b39 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 16 Aug 2014 02:30:23 -0700 Subject: [PATCH 112/388] Working on switching to std::string. --- src/alloy/frontend/ppc/ppc_context.cc | 4 +- src/poly/sources.gypi | 1 + src/poly/string.cc | 16 ++++++ src/poly/string.h | 10 +++- src/poly/threading.h | 3 ++ src/poly/threading_mac.cc | 8 +-- src/poly/threading_posix.cc | 42 +++++++++++++++ src/poly/threading_win.cc | 4 ++ src/xenia/export_resolver.cc | 4 +- src/xenia/gpu/d3d11/d3d11_shader_resource.cc | 4 +- src/xenia/gpu/xenos/ucode_disassembler.cc | 2 +- src/xenia/kernel/fs/device.cc | 4 +- src/xenia/kernel/fs/device.h | 2 +- .../kernel/fs/devices/disc_image_file.cc | 6 +-- src/xenia/kernel/fs/devices/disc_image_file.h | 34 ++++++------ src/xenia/kernel/fs/devices/host_path_file.cc | 6 +-- src/xenia/kernel/fs/devices/host_path_file.h | 38 +++++++------ .../kernel/fs/devices/stfs_container_file.cc | 6 +-- .../kernel/fs/devices/stfs_container_file.h | 34 ++++++------ src/xenia/kernel/fs/entry.cc | 27 +++------- src/xenia/kernel/fs/entry.h | 16 +++--- src/xenia/kernel/fs/filesystem.cc | 54 ++++++++----------- src/xenia/kernel/fs/filesystem.h | 6 +-- src/xenia/kernel/fs/gdfx.cc | 2 +- src/xenia/kernel/fs/stfs.cc | 2 +- src/xenia/kernel/kernel_state.cc | 6 +-- src/xenia/kernel/objects/xfile.h | 13 ++--- src/xenia/kernel/objects/xthread.cc | 38 ++----------- src/xenia/kernel/objects/xthread.h | 7 +-- src/xenia/kernel/objects/xuser_module.cc | 2 +- src/xenia/kernel/util/xex2.cc | 2 +- src/xenia/sources.gypi | 1 - src/xenia/string.cc | 33 ------------ src/xenia/string.h | 24 +-------- 34 files changed, 211 insertions(+), 250 deletions(-) create mode 100644 src/poly/threading_posix.cc delete mode 100644 src/xenia/string.cc diff --git a/src/alloy/frontend/ppc/ppc_context.cc b/src/alloy/frontend/ppc/ppc_context.cc index b6eeb336c..b6b743621 100644 --- a/src/alloy/frontend/ppc/ppc_context.cc +++ b/src/alloy/frontend/ppc/ppc_context.cc @@ -13,7 +13,9 @@ namespace alloy { namespace frontend { namespace ppc { -uint64_t ParseInt64(const char* value) { return xestrtoulla(value, NULL, 0); } +uint64_t ParseInt64(const char* value) { + return std::strtoull(value, nullptr, 0); +} void PPCContext::SetRegFromString(const char* name, const char* value) { int n; diff --git a/src/poly/sources.gypi b/src/poly/sources.gypi index 19e08905b..547d9e838 100644 --- a/src/poly/sources.gypi +++ b/src/poly/sources.gypi @@ -27,6 +27,7 @@ }], ['OS == "linux"', { 'sources': [ + 'threading_posix.cc', ], }], ['OS == "mac"', { diff --git a/src/poly/string.cc b/src/poly/string.cc index 1d8bb53e2..4716c0a32 100644 --- a/src/poly/string.cc +++ b/src/poly/string.cc @@ -23,4 +23,20 @@ std::wstring to_wstring(const std::string& source) { return converter.from_bytes(source); } +std::string::size_type find_first_of_case(const std::string& target, + const std::string& search) { + const char* str = target.c_str(); + while (*str) { + if (!strncasecmp(str, search.c_str(), search.size())) { + break; + } + str++; + } + if (*str) { + return str - target.c_str(); + } else { + return std::string::npos; + } +} + } // namespace poly diff --git a/src/poly/string.h b/src/poly/string.h index 20b684e6d..7d360abd2 100644 --- a/src/poly/string.h +++ b/src/poly/string.h @@ -12,13 +12,21 @@ #include -#include +#include + +#if XE_LIKE_WIN32 +#define strcasecmp _stricmp +#define strncasecmp _strnicmp +#endif // XE_LIKE_WIN32 namespace poly { std::string to_string(const std::wstring& source); std::wstring to_wstring(const std::string& source); +std::string::size_type find_first_of_case(const std::string& target, + const std::string& search); + } // namespace poly #endif // POLY_STRING_H_ diff --git a/src/poly/threading.h b/src/poly/threading.h index 61e74a300..4c8284bf5 100644 --- a/src/poly/threading.h +++ b/src/poly/threading.h @@ -13,6 +13,7 @@ #include #include #include +#include #include @@ -28,6 +29,8 @@ uint32_t current_thread_id(); // Sets the current thread name. void set_name(const std::string& name); +// Sets the target thread name. +void set_name(std::thread::native_handle_type handle, const std::string& name); // Yields the current thread to the scheduler. Maybe. void Yield(); diff --git a/src/poly/threading_mac.cc b/src/poly/threading_mac.cc index b0ec61406..6d448315c 100644 --- a/src/poly/threading_mac.cc +++ b/src/poly/threading_mac.cc @@ -25,11 +25,11 @@ uint32_t current_thread_id() { } void set_name(const std::string& name) { -#if XE_LIKE_OSX pthread_setname_np(name.c_str()); -#else - pthread_setname_np(pthread_self(), name.c_str()); -#endif // XE_LIKE_OSX +} + +void set_name(std::thread::native_handle_type handle, const std::string& name) { + // ? } void Yield() { pthread_yield_np(); } diff --git a/src/poly/threading_posix.cc b/src/poly/threading_posix.cc new file mode 100644 index 000000000..005a708d6 --- /dev/null +++ b/src/poly/threading_posix.cc @@ -0,0 +1,42 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include +#include + +namespace poly { +namespace threading { + +//uint64_t ticks() { return mach_absolute_time(); } + +// uint32_t current_thread_id() { +// mach_port_t tid = pthread_mach_thread_np(pthread_self()); +// return static_cast(tid); +// } + +void set_name(const std::string& name) { + pthread_setname_np(pthread_self(), name.c_str()); +} + +void set_name(std::thread::native_handle_type handle, const std::string& name) { + pthread_setname_np(pthread_self(), name.c_str()); +} + +void Yield() { pthread_yield_np(); } + +void Sleep(std::chrono::microseconds duration) { + timespec rqtp = {duration.count() / 1000000, duration.count() % 1000}; + nanosleep(&rqtp, nullptr); + // TODO(benvanik): spin while rmtp >0? +} + +} // namespace threading +} // namespace poly diff --git a/src/poly/threading_win.cc b/src/poly/threading_win.cc index d5a1a2b3f..a75c73fac 100644 --- a/src/poly/threading_win.cc +++ b/src/poly/threading_win.cc @@ -57,6 +57,10 @@ void set_name(const std::string& name) { set_name(static_cast(-1), name); } +void set_name(std::thread::native_handle_type handle, const std::string& name) { + set_name(GetThreadId(handle), name); +} + void Yield() { SwitchToThread(); } void Sleep(std::chrono::microseconds duration) { diff --git a/src/xenia/export_resolver.cc b/src/xenia/export_resolver.cc index c311819b8..19a29cce1 100644 --- a/src/xenia/export_resolver.cc +++ b/src/xenia/export_resolver.cc @@ -38,7 +38,7 @@ void ExportResolver::RegisterTable( uint16_t ExportResolver::GetLibraryOrdinal(const char* library_name) { uint16_t n = 0; for (auto it = tables_.begin(); it != tables_.end(); ++it, n++) { - if (!xestrcmpa(library_name, it->name)) { + if (!strcmp(library_name, it->name)) { return n; } } @@ -61,7 +61,7 @@ KernelExport* ExportResolver::GetExportByOrdinal(const char* library_name, const uint32_t ordinal) { for (std::vector::iterator it = tables_.begin(); it != tables_.end(); ++it) { - if (!xestrcmpa(library_name, it->name)) { + if (!strcmp(library_name, it->name)) { // TODO(benvanik): binary search? for (size_t n = 0; n < it->count; n++) { if (it->exports[n].ordinal == ordinal) { diff --git a/src/xenia/gpu/d3d11/d3d11_shader_resource.cc b/src/xenia/gpu/d3d11/d3d11_shader_resource.cc index c9c3e033f..7fc40905f 100644 --- a/src/xenia/gpu/d3d11/d3d11_shader_resource.cc +++ b/src/xenia/gpu/d3d11/d3d11_shader_resource.cc @@ -128,7 +128,7 @@ int D3D11VertexShaderResource::Prepare( XELOGE("D3D11: failed to translate vertex shader"); return ret; } - translated_src_ = xestrdupa(translator.translated_src()); + translated_src_ = strdup(translator.translated_src()); ID3D10Blob* shader_blob = D3D11ShaderCompile( XE_GPU_SHADER_TYPE_VERTEX, translated_src_, disasm_src()); @@ -351,7 +351,7 @@ int D3D11PixelShaderResource::Prepare(const xe_gpu_program_cntl_t& program_cntl, XELOGE("D3D11: failed to translate pixel shader"); return ret; } - translated_src_ = xestrdupa(translator.translated_src()); + translated_src_ = strdup(translator.translated_src()); ID3D10Blob* shader_blob = D3D11ShaderCompile( XE_GPU_SHADER_TYPE_PIXEL, translated_src_, disasm_src()); diff --git a/src/xenia/gpu/xenos/ucode_disassembler.cc b/src/xenia/gpu/xenos/ucode_disassembler.cc index db3ad44eb..0e0ac9875 100644 --- a/src/xenia/gpu/xenos/ucode_disassembler.cc +++ b/src/xenia/gpu/xenos/ucode_disassembler.cc @@ -754,7 +754,7 @@ char* xenos::DisassembleShader( } } - char* result = xestrdupa(output->buffer); + char* result = strdup(output->buffer); delete output; return result; } diff --git a/src/xenia/kernel/fs/device.cc b/src/xenia/kernel/fs/device.cc index c9c37664a..9bc191b27 100644 --- a/src/xenia/kernel/fs/device.cc +++ b/src/xenia/kernel/fs/device.cc @@ -15,6 +15,4 @@ using namespace xe::kernel::fs; Device::Device(const std::string& path) : path_(path) {} -Device::~Device() {} - -const char* Device::path() const { return path_.c_str(); } +Device::~Device() = default; diff --git a/src/xenia/kernel/fs/device.h b/src/xenia/kernel/fs/device.h index 01215e47a..81d409761 100644 --- a/src/xenia/kernel/fs/device.h +++ b/src/xenia/kernel/fs/device.h @@ -26,7 +26,7 @@ class Device { Device(const std::string& path); virtual ~Device(); - const char* path() const; + const std::string& path() const { return path_; } virtual Entry* ResolvePath(const char* path) = 0; diff --git a/src/xenia/kernel/fs/devices/disc_image_file.cc b/src/xenia/kernel/fs/devices/disc_image_file.cc index c094dbef7..3f78efd5b 100644 --- a/src/xenia/kernel/fs/devices/disc_image_file.cc +++ b/src/xenia/kernel/fs/devices/disc_image_file.cc @@ -29,15 +29,15 @@ DiscImageFile::DiscImageFile( DiscImageFile::~DiscImageFile() { } -const char* DiscImageFile::path(void) const { +const std::string& DiscImageFile::path() const { return entry_->path(); } -const char* DiscImageFile::absolute_path(void) const { +const std::string& DiscImageFile::absolute_path() const { return entry_->absolute_path(); } -const char* DiscImageFile::name(void) const { +const std::string& DiscImageFile::name() const { return entry_->name(); } diff --git a/src/xenia/kernel/fs/devices/disc_image_file.h b/src/xenia/kernel/fs/devices/disc_image_file.h index b43f89863..e138705de 100644 --- a/src/xenia/kernel/fs/devices/disc_image_file.h +++ b/src/xenia/kernel/fs/devices/disc_image_file.h @@ -15,43 +15,39 @@ #include - namespace xe { namespace kernel { namespace fs { class DiscImageEntry; - class DiscImageFile : public XFile { -public: + public: DiscImageFile(KernelState* kernel_state, uint32_t desired_access, DiscImageEntry* entry); - virtual ~DiscImageFile(); + ~DiscImageFile() override; - virtual const char* path(void) const; - virtual const char* absolute_path(void) const; - virtual const char* name(void) const; + const std::string& path() const override; + const std::string& absolute_path() const override; + const std::string& name() const override; - virtual X_STATUS QueryInfo(XFileInfo* out_info); - virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info, - size_t length, const char* file_name, bool restart); - virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length); - virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length); + X_STATUS QueryInfo(XFileInfo* out_info) override; + X_STATUS QueryDirectory(XDirectoryInfo* out_info, size_t length, + const char* file_name, bool restart) override; + X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) override; + X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, + size_t length) override; -protected: - virtual X_STATUS ReadSync( - void* buffer, size_t buffer_length, size_t byte_offset, - size_t* out_bytes_read); + protected: + X_STATUS ReadSync(void* buffer, size_t buffer_length, size_t byte_offset, + size_t* out_bytes_read) override; -private: + private: DiscImageEntry* entry_; }; - } // namespace fs } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_FS_DEVICES_DISC_IMAGE_FILE_H_ diff --git a/src/xenia/kernel/fs/devices/host_path_file.cc b/src/xenia/kernel/fs/devices/host_path_file.cc index b36f9f890..166a57bc9 100644 --- a/src/xenia/kernel/fs/devices/host_path_file.cc +++ b/src/xenia/kernel/fs/devices/host_path_file.cc @@ -29,15 +29,15 @@ HostPathFile::~HostPathFile() { CloseHandle(file_handle_); } -const char* HostPathFile::path(void) const { +const std::string& HostPathFile::path() const { return entry_->path(); } -const char* HostPathFile::absolute_path(void) const { +const std::string& HostPathFile::absolute_path() const { return entry_->absolute_path(); } -const char* HostPathFile::name(void) const { +const std::string& HostPathFile::name() const { return entry_->name(); } diff --git a/src/xenia/kernel/fs/devices/host_path_file.h b/src/xenia/kernel/fs/devices/host_path_file.h index e759ba763..9ef850c4c 100644 --- a/src/xenia/kernel/fs/devices/host_path_file.h +++ b/src/xenia/kernel/fs/devices/host_path_file.h @@ -10,49 +10,47 @@ #ifndef XENIA_KERNEL_FS_DEVICES_HOST_PATH_FILE_H_ #define XENIA_KERNEL_FS_DEVICES_HOST_PATH_FILE_H_ +#include + #include #include #include - namespace xe { namespace kernel { namespace fs { class HostPathEntry; - class HostPathFile : public XFile { -public: + public: HostPathFile(KernelState* kernel_state, uint32_t desired_access, HostPathEntry* entry, HANDLE file_handle); - virtual ~HostPathFile(); + ~HostPathFile() override; - virtual const char* path(void) const; - virtual const char* absolute_path(void) const; - virtual const char* name(void) const; + const std::string& path() const override; + const std::string& absolute_path() const override; + const std::string& name() const override; - virtual X_STATUS QueryInfo(XFileInfo* out_info); - virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info, - size_t length, const char* file_name, bool restart); - virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length); - virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length); + X_STATUS QueryInfo(XFileInfo* out_info) override; + X_STATUS QueryDirectory(XDirectoryInfo* out_info, size_t length, + const char* file_name, bool restart) override; + X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) override; + X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, + size_t length) override; -protected: - virtual X_STATUS ReadSync( - void* buffer, size_t buffer_length, size_t byte_offset, - size_t* out_bytes_read); + protected: + X_STATUS ReadSync(void* buffer, size_t buffer_length, size_t byte_offset, + size_t* out_bytes_read) override; -private: + private: HostPathEntry* entry_; - HANDLE file_handle_; + HANDLE file_handle_; }; - } // namespace fs } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_FS_DEVICES_HOST_PATH_FILE_H_ diff --git a/src/xenia/kernel/fs/devices/stfs_container_file.cc b/src/xenia/kernel/fs/devices/stfs_container_file.cc index 4f9f25a53..fbba72a99 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_file.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_file.cc @@ -29,15 +29,15 @@ STFSContainerFile::STFSContainerFile( STFSContainerFile::~STFSContainerFile() { } -const char* STFSContainerFile::path(void) const { +const std::string& STFSContainerFile::path() const { return entry_->path(); } -const char* STFSContainerFile::absolute_path(void) const { +const std::string& STFSContainerFile::absolute_path() const { return entry_->absolute_path(); } -const char* STFSContainerFile::name(void) const { +const std::string& STFSContainerFile::name() const { return entry_->name(); } diff --git a/src/xenia/kernel/fs/devices/stfs_container_file.h b/src/xenia/kernel/fs/devices/stfs_container_file.h index 778404eaf..eed3e232d 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_file.h +++ b/src/xenia/kernel/fs/devices/stfs_container_file.h @@ -15,43 +15,39 @@ #include - namespace xe { namespace kernel { namespace fs { class STFSContainerEntry; - class STFSContainerFile : public XFile { -public: + public: STFSContainerFile(KernelState* kernel_state, uint32_t desired_access, STFSContainerEntry* entry); - virtual ~STFSContainerFile(); + ~STFSContainerFile() override; - virtual const char* path(void) const; - virtual const char* absolute_path(void) const; - virtual const char* name(void) const; + const std::string& path() const override; + const std::string& absolute_path() const override; + const std::string& name() const override; - virtual X_STATUS QueryInfo(XFileInfo* out_info); - virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info, - size_t length, const char* file_name, bool restart); - virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length); - virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length); + X_STATUS QueryInfo(XFileInfo* out_info) override; + X_STATUS QueryDirectory(XDirectoryInfo* out_info, size_t length, + const char* file_name, bool restart) override; + X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) override; + X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, + size_t length) override; -protected: - virtual X_STATUS ReadSync( - void* buffer, size_t buffer_length, size_t byte_offset, - size_t* out_bytes_read); + protected: + X_STATUS ReadSync(void* buffer, size_t buffer_length, size_t byte_offset, + size_t* out_bytes_read) override; -private: + private: STFSContainerEntry* entry_; }; - } // namespace fs } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_FS_DEVICES_STFS_CONTAINER_FILE_H_ diff --git a/src/xenia/kernel/fs/entry.cc b/src/xenia/kernel/fs/entry.cc index 0658d0f7b..30b18d74b 100644 --- a/src/xenia/kernel/fs/entry.cc +++ b/src/xenia/kernel/fs/entry.cc @@ -14,28 +14,17 @@ using namespace xe; using namespace xe::kernel; using namespace xe::kernel::fs; +MemoryMapping::MemoryMapping(uint8_t* address, size_t length) + : address_(address), length_(length) {} -MemoryMapping::MemoryMapping(uint8_t* address, size_t length) : - address_(address), length_(length) { -} +MemoryMapping::~MemoryMapping() {} -MemoryMapping::~MemoryMapping() { -} - - -Entry::Entry(Type type, Device* device, const char* path) : - type_(type), - device_(device) { +Entry::Entry(Type type, Device* device, const std::string& path) + : type_(type), device_(device), path_(path) { assert_not_null(device); - path_ = xestrdupa(path); - // TODO(benvanik): *shudder* - absolute_path_ = xestrdupa((std::string(device->path()) + std::string(path)).c_str()); + absolute_path_ = device->path() + path; // TODO(benvanik): last index of \, unless \ at end, then before that - name_ = NULL; + name_ = ""; } -Entry::~Entry() { - xe_free(name_); - xe_free(path_); - xe_free(absolute_path_); -} +Entry::~Entry() = default; diff --git a/src/xenia/kernel/fs/entry.h b/src/xenia/kernel/fs/entry.h index c21b57a16..1f5b09d1a 100644 --- a/src/xenia/kernel/fs/entry.h +++ b/src/xenia/kernel/fs/entry.h @@ -10,6 +10,8 @@ #ifndef XENIA_KERNEL_FS_ENTRY_H_ #define XENIA_KERNEL_FS_ENTRY_H_ +#include + #include #include @@ -52,14 +54,14 @@ public: kTypeDirectory, }; - Entry(Type type, Device* device, const char* path); + Entry(Type type, Device* device, const std::string& path); virtual ~Entry(); Type type() const { return type_; } Device* device() const { return device_; } - const char* path() const { return path_; } - const char* absolute_path() const { return absolute_path_; } - const char* name() const { return name_; } + const std::string& path() const { return path_; } + const std::string& absolute_path() const { return absolute_path_; } + const std::string& name() const { return name_; } virtual X_STATUS QueryInfo(XFileInfo* out_info) = 0; virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info, @@ -79,9 +81,9 @@ public: private: Type type_; Device* device_; - char* path_; - char* absolute_path_; - char* name_; + std::string path_; + std::string absolute_path_; + std::string name_; }; diff --git a/src/xenia/kernel/fs/filesystem.cc b/src/xenia/kernel/fs/filesystem.cc index 538959329..26cc4b35d 100644 --- a/src/xenia/kernel/fs/filesystem.cc +++ b/src/xenia/kernel/fs/filesystem.cc @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -129,24 +130,22 @@ int FileSystem::RegisterSTFSContainerDevice( return RegisterDevice(path, device); } -int FileSystem::CreateSymbolicLink(const char* path, const char* target) { - symlinks_.insert(std::pair( - xestrdupa(path), - xestrdupa(target))); +int FileSystem::CreateSymbolicLink(const std::string& path, + const std::string& target) { + symlinks_.insert({path, target}); return 0; } -int FileSystem::DeleteSymbolicLink(const char* path) { - std::unordered_map::iterator it = - symlinks_.find(std::string(path)); - if (it != symlinks_.end()) { - symlinks_.erase(it); - return 0; +int FileSystem::DeleteSymbolicLink(const std::string& path) { + auto& it = symlinks_.find(path); + if (it == symlinks_.end()) { + return 1; } - return 1; + symlinks_.erase(it); + return 0; } -Entry* FileSystem::ResolvePath(const char* path) { +Entry* FileSystem::ResolvePath(const std::string& path) { // Strip off prefix and pass to device. // e.g., d:\some\PATH.foo -> some\PATH.foo // Support both symlinks and device specifiers, like: @@ -158,33 +157,24 @@ Entry* FileSystem::ResolvePath(const char* path) { // Resolve symlinks. // TODO(benvanik): more robust symlink handling - right now we assume simple // drive path -> device mappings with nothing nested. - char full_path[poly::max_path]; - XEIGNORE(xestrcpya(full_path, XECOUNT(full_path), path)); - for (std::unordered_map::iterator it = - symlinks_.begin(); it != symlinks_.end(); ++it) { - if (xestrcasestra(path, it->first.c_str()) == path) { - // Found symlink, fixup. - const char* after_path = path + it->first.size(); - XEIGNORE(xesnprintfa(full_path, XECOUNT(full_path), "%s%s", - it->second.c_str(), after_path)); + std::string full_path = path; + for (const auto& it : symlinks_) { + if (poly::find_first_of_case(path, it.first) == 0) { + // Found symlink, fixup by replacing the prefix. + full_path = it.second + full_path.substr(it.first.size()); break; } } // Scan all devices. - for (std::vector::iterator it = devices_.begin(); - it != devices_.end(); ++it) { - Device* device = *it; - if (xestrcasestra(full_path, device->path()) == full_path) { - // Found! - // Trim the device prefix off and pass down. - char device_path[poly::max_path]; - XEIGNORE(xestrcpya(device_path, XECOUNT(device_path), - full_path + xestrlena(device->path()))); - return device->ResolvePath(device_path); + for (auto& device : devices_) { + if (poly::find_first_of_case(full_path, device->path()) == 0) { + // Found! Trim the device prefix off and pass down. + auto device_path = full_path.substr(device->path().size()); + return device->ResolvePath(device_path.c_str()); } } - XELOGE("ResolvePath(%s) failed - no root found", path); + XELOGE("ResolvePath(%s) failed - no root found", path.c_str()); return NULL; } diff --git a/src/xenia/kernel/fs/filesystem.h b/src/xenia/kernel/fs/filesystem.h index 76d6ab549..de0107fac 100644 --- a/src/xenia/kernel/fs/filesystem.h +++ b/src/xenia/kernel/fs/filesystem.h @@ -47,10 +47,10 @@ class FileSystem { int RegisterSTFSContainerDevice(const std::string& path, const std::wstring& local_path); - int CreateSymbolicLink(const char* path, const char* target); - int DeleteSymbolicLink(const char* path); + int CreateSymbolicLink(const std::string& path, const std::string& target); + int DeleteSymbolicLink(const std::string& path); - Entry* ResolvePath(const char* path); + Entry* ResolvePath(const std::string& path); private: std::vector devices_; diff --git a/src/xenia/kernel/fs/gdfx.cc b/src/xenia/kernel/fs/gdfx.cc index 4e2f52abd..27a948e7a 100644 --- a/src/xenia/kernel/fs/gdfx.cc +++ b/src/xenia/kernel/fs/gdfx.cc @@ -40,7 +40,7 @@ GDFXEntry* GDFXEntry::GetChild(const char* name) { for (std::vector::iterator it = children.begin(); it != children.end(); ++it) { GDFXEntry* entry = *it; - if (xestrcasecmpa(entry->name.c_str(), name) == 0) { + if (strcasecmp(entry->name.c_str(), name) == 0) { return entry; } } diff --git a/src/xenia/kernel/fs/stfs.cc b/src/xenia/kernel/fs/stfs.cc index b7662f35e..b3e4a8788 100644 --- a/src/xenia/kernel/fs/stfs.cc +++ b/src/xenia/kernel/fs/stfs.cc @@ -108,7 +108,7 @@ STFSEntry* STFSEntry::GetChild(const char* name) { // TODO(benvanik): a faster search for (auto it = children.begin(); it != children.end(); ++it) { STFSEntry* entry = *it; - if (xestrcasecmpa(entry->name.c_str(), name) == 0) { + if (strcasecmp(entry->name.c_str(), name) == 0) { return entry; } } diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index ed3537af2..ab789a4aa 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -80,15 +80,15 @@ XModule* KernelState::GetModule(const char* name) { // NULL name = self. // TODO(benvanik): lookup module from caller address. return GetExecutableModule(); - } else if (xestrcasecmpa(name, "xam.xex") == 0) { + } else if (strcasecmp(name, "xam.xex") == 0) { auto module = emulator_->xam(); module->Retain(); return module; - } else if (xestrcasecmpa(name, "xboxkrnl.exe") == 0) { + } else if (strcasecmp(name, "xboxkrnl.exe") == 0) { auto module = emulator_->xboxkrnl(); module->Retain(); return module; - } else if (xestrcasecmpa(name, "kernel32.dll") == 0) { + } else if (strcasecmp(name, "kernel32.dll") == 0) { // Some games request this, for some reason. wtf. return NULL; } else { diff --git a/src/xenia/kernel/objects/xfile.h b/src/xenia/kernel/objects/xfile.h index ecb944413..49bec2e16 100644 --- a/src/xenia/kernel/objects/xfile.h +++ b/src/xenia/kernel/objects/xfile.h @@ -127,18 +127,19 @@ class XFile : public XObject { public: virtual ~XFile(); - virtual const char* path(void) const = 0; - virtual const char* absolute_path(void) const = 0; - virtual const char* name(void) const = 0; + virtual const std::string& path() const = 0; + virtual const std::string& absolute_path() const = 0; + virtual const std::string& name() const = 0; size_t position() const { return position_; } void set_position(size_t value) { position_ = value; } virtual X_STATUS QueryInfo(XFileInfo* out_info) = 0; - virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info, - size_t length, const char* file_name, bool restart) = 0; + virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info, size_t length, + const char* file_name, bool restart) = 0; virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) = 0; - virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length) = 0; + virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, + size_t length) = 0; X_STATUS Read(void* buffer, size_t buffer_length, size_t byte_offset, size_t* out_bytes_read); diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index 70918dd8c..68f11c7f4 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -42,7 +42,6 @@ XThread::XThread(KernelState* kernel_state, thread_state_address_(0), thread_state_(0), event_(NULL), - name_(0), irql_(0) { creation_params_.stack_size = stack_size; creation_params_.xapi_thread_startup = xapi_thread_startup; @@ -95,9 +94,6 @@ XThread::~XThread() { if (thread_state_address_) { kernel_state()->memory()->HeapFree(thread_state_address_, 0); } - if (name_) { - xe_free(name_); - } if (thread_handle_) { // TODO(benvanik): platform kill @@ -149,35 +145,9 @@ void XThread::set_last_error(uint32_t error_code) { poly::store_and_swap(p + 0x160, error_code); } -void XThread::set_name(const char* name) { - if (name == name_) { - return; - } - if (name_) { - xe_free(name_); - } - name_ = xestrdupa(name); - -#if XE_PLATFORM_WIN32 - // Do the nasty set for us. - #pragma pack(push, 8) - typedef struct tagTHREADNAME_INFO { - DWORD dwType; // must be 0x1000 - LPCSTR szName; // pointer to name (in user addr space) - DWORD dwThreadID; // thread ID (-1=caller thread) - DWORD dwFlags; // reserved for future use, must be zero - } THREADNAME_INFO; - #pragma pack(pop) - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = name_; - info.dwThreadID = ::GetThreadId(thread_handle_); - info.dwFlags = 0; - __try { - RaiseException(0x406D1388, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info); - } __except(EXCEPTION_CONTINUE_EXECUTION) { - } -#endif // WIN32 +void XThread::set_name(const std::string& name) { + name_ = name; + poly::threading::set_name(thread_handle_, name); } X_STATUS XThread::Create() { @@ -287,7 +257,7 @@ X_STATUS XThread::Exit(int exit_code) { static uint32_t __stdcall XThreadStartCallbackWin32(void* param) { XThread* thread = reinterpret_cast(param); - xe::Profiler::ThreadEnter(thread->name()); + xe::Profiler::ThreadEnter(thread->name().c_str()); current_thread_tls = thread; thread->Execute(); current_thread_tls = nullptr; diff --git a/src/xenia/kernel/objects/xthread.h b/src/xenia/kernel/objects/xthread.h index 06c93fc73..591a41b19 100644 --- a/src/xenia/kernel/objects/xthread.h +++ b/src/xenia/kernel/objects/xthread.h @@ -12,6 +12,7 @@ #include #include +#include #include @@ -44,8 +45,8 @@ public: uint32_t thread_id(); uint32_t last_error(); void set_last_error(uint32_t error_code); - const char* name() const { return name_; } - void set_name(const char* name); + const std::string& name() const { return name_; } + void set_name(const std::string& name); X_STATUS Create(); X_STATUS Exit(int exit_code); @@ -96,7 +97,7 @@ private: uint32_t thread_state_address_; cpu::XenonThreadState* thread_state_; - char* name_; + std::string name_; std::atomic irql_; std::mutex apc_lock_; diff --git a/src/xenia/kernel/objects/xuser_module.cc b/src/xenia/kernel/objects/xuser_module.cc index 7d566ce7c..c8f5c86e0 100644 --- a/src/xenia/kernel/objects/xuser_module.cc +++ b/src/xenia/kernel/objects/xuser_module.cc @@ -139,7 +139,7 @@ X_STATUS XUserModule::GetSection( auto header = xe_xex2_get_header(xex_); for (size_t n = 0; n < header->resource_info_count; n++) { auto& res = header->resource_infos[n]; - if (xestrcmpa(name, res.name) == 0) { + if (strcmp(name, res.name) == 0) { // Found! *out_section_data = res.address; *out_section_size = res.size; diff --git a/src/xenia/kernel/util/xex2.cc b/src/xenia/kernel/util/xex2.cc index 1f2f7b6ed..93ec53ca2 100644 --- a/src/xenia/kernel/util/xex2.cc +++ b/src/xenia/kernel/util/xex2.cc @@ -902,7 +902,7 @@ int xe_xex2_load_pe(xe_xex2_ref xex) { const PESection* xe_xex2_get_pe_section(xe_xex2_ref xex, const char* name) { for (std::vector::iterator it = xex->sections->begin(); it != xex->sections->end(); ++it) { - if (!xestrcmpa((*it)->name, name)) { + if (!strcmp((*it)->name, name)) { return *it; } } diff --git a/src/xenia/sources.gypi b/src/xenia/sources.gypi index db918c4e9..88a621e58 100644 --- a/src/xenia/sources.gypi +++ b/src/xenia/sources.gypi @@ -18,7 +18,6 @@ 'platform.h', 'profiling.cc', 'profiling.h', - 'string.cc', 'string.h', 'types.h', 'xbox.h', diff --git a/src/xenia/string.cc b/src/xenia/string.cc deleted file mode 100644 index 9d90f2952..000000000 --- a/src/xenia/string.cc +++ /dev/null @@ -1,33 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include - - -#if XE_PLATFORM_WIN32 - -char* xestrcasestra(const char* str, const char* substr) { - const size_t len = xestrlena(substr); - while (*str) { - if (!_strnicmp(str, substr, len)) { - break; - } - str++; - } - - if (*str) { - return (char*)str; - } else { - return NULL; - } -} - -#endif // WIN32 diff --git a/src/xenia/string.h b/src/xenia/string.h index 4f4c44642..f2f9b51cc 100644 --- a/src/xenia/string.h +++ b/src/xenia/string.h @@ -11,46 +11,32 @@ #define XENIA_STRING_H_ #include - +#include // NOTE: these differing implementations should behave pretty much the same. // If they don't, then they will have to be abstracted out. -#define XEInvalidSize ((size_t)(-1)) - #if !XE_LIKE_WIN32 int strncpy_s(char* dest, size_t destLength, const char* source, size_t count); #define strcpy_s(dest, destLength, source) !(strcpy(dest, source) == dest + (destLength*0)) #define strcat_s(dest, destLength, source) !(strcat(dest, source) == dest + (destLength*0)) #define _snprintf_s(dest, destLength, x, format, ...) snprintf(dest, destLength, format, ##__VA_ARGS__) #define xestrdupa strdup -#define xestrtoulla strtoull -#define xestrcasestra strcasestr #else -#define strcasecmp _stricmp #define xestrdupa _strdup -#define xestrtoullw _wcstoui64 -#define xestrtoulla _strtoui64 -char* xestrcasestra(const char* str, const char* substr); #endif // !WIN32 #define xestrlenw wcslen -#define xestrcmpw wcscmp -#define xestrcasecmpw _wcsicmp #define xestrdupw _wcsdup #define xestrchrw wcschr #define xestrrchrw wcsrchr -#define xestrcasestrw ?? #define xestrcpyw(dest, destLength, source) (wcscpy_s(dest, destLength, source) == 0) #define xestrncpyw(dest, destLength, source, count) (wcsncpy_s(dest, destLength, source, count) == 0) #define xestrcatw(dest, destLength, source) (wcscat_s(dest, destLength, source) == 0) #define xesnprintfw(buffer, bufferCount, format, ...) _snwprintf_s(buffer, bufferCount, (bufferCount) ? (bufferCount - 1) : 0, format, ##__VA_ARGS__) #define xevsnprintfw(buffer, bufferCount, format, args) _vsnwprintf_s(buffer, bufferCount, (bufferCount) ? (bufferCount - 1) : 0, format, args) -#define xevscprintfw(format, args) _vscwprintf(format, args) #define xestrlena strlen -#define xestrcmpa strcmp -#define xestrcasecmpa strcasecmp #define xestrchra strchr #define xestrrchra strrchr #define xestrcpya(dest, destLength, source) (strcpy_s(dest, destLength, source) == 0) @@ -65,13 +51,9 @@ typedef wchar_t xechar_t; #define XE_WCHAR 1 #define xestrlen xestrlenw -#define xestrcmp xestrcmpw -#define xestrcasecmp xestrcasecmpw #define xestrdup xestrdupw #define xestrchr xestrchrw #define xestrrchr xestrrchrw -#define xestrcasestr xestrcasestrw -#define xestrtoull xestrtoullw #define xestrcpy xestrcpyw #define xestrncpy xestrncpyw #define xestrcat xestrcatw @@ -86,13 +68,9 @@ typedef char xechar_t; #define XE_CHAR 1 #define xestrlen xestrlena -#define xestrcmp xestrcmpa -#define xestrcasecmp xestrcasecmpa #define xestrdup xestrdupa #define xestrchr xestrchra #define xestrrchr xestrrchra -#define xestrcasestr xestrcasestra -#define xestrtoull xestrtoulla #define xestrcpy xestrcpya #define xestrncpy xestrncpya #define xestrcat xestrcata From 66d2336e38b6dbf5cfdac32d5d420b3df7bc03e8 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 16 Aug 2014 02:50:08 -0700 Subject: [PATCH 113/388] More string conversion. --- src/xenia/gpu/d3d11/d3d11_graphics_system.cc | 2 +- src/xenia/gpu/d3d11/d3d11_window.cc | 3 +- src/xenia/gpu/d3d11/d3d11_window.h | 7 ++-- .../kernel/fs/devices/host_path_entry.cc | 38 +++++++++---------- src/xenia/kernel/fs/devices/host_path_entry.h | 31 +++++++-------- src/xenia/kernel/xboxkrnl_io.cc | 3 +- src/xenia/string.h | 27 ++++--------- src/xenia/ui/win32/win32_window.cc | 7 ++-- src/xenia/ui/win32/win32_window.h | 29 +++++++------- src/xenia/ui/window.cc | 35 +++++++---------- src/xenia/ui/window.h | 33 ++++++++-------- 11 files changed, 94 insertions(+), 121 deletions(-) diff --git a/src/xenia/gpu/d3d11/d3d11_graphics_system.cc b/src/xenia/gpu/d3d11/d3d11_graphics_system.cc index 11d113ca4..e6fb9454f 100644 --- a/src/xenia/gpu/d3d11/d3d11_graphics_system.cc +++ b/src/xenia/gpu/d3d11/d3d11_graphics_system.cc @@ -113,7 +113,7 @@ void D3D11GraphicsSystem::Initialize() { // will take place. assert_null(window_); window_ = new D3D11Window(run_loop_, dxgi_factory_, device_); - if (window_->Initialize("Xenia D3D11", 1280, 720)) { + if (window_->Initialize(L"Xenia D3D11", 1280, 720)) { XELOGE("Failed to create D3D11Window"); exit(1); return; diff --git a/src/xenia/gpu/d3d11/d3d11_window.cc b/src/xenia/gpu/d3d11/d3d11_window.cc index da33ab6bb..7b4fa5cbd 100644 --- a/src/xenia/gpu/d3d11/d3d11_window.cc +++ b/src/xenia/gpu/d3d11/d3d11_window.cc @@ -49,7 +49,8 @@ D3D11Window::~D3D11Window() { XESAFERELEASE(dxgi_factory_); } -int D3D11Window::Initialize(const char* title, uint32_t width, uint32_t height) { +int D3D11Window::Initialize(const std::wstring& title, uint32_t width, + uint32_t height) { int result = Win32Window::Initialize(title, width, height); if (result) { return result; diff --git a/src/xenia/gpu/d3d11/d3d11_window.h b/src/xenia/gpu/d3d11/d3d11_window.h index df470df0f..888a797ae 100644 --- a/src/xenia/gpu/d3d11/d3d11_window.h +++ b/src/xenia/gpu/d3d11/d3d11_window.h @@ -27,18 +27,19 @@ public: D3D11Window( xe_run_loop_ref run_loop, IDXGIFactory1* dxgi_factory, ID3D11Device* device); - virtual ~D3D11Window(); + ~D3D11Window() override; ID3D11Device* device() const { return device_; } IDXGISwapChain* swap_chain() const { return swap_chain_; } ID3D11DeviceContext* context() const { return context_; } - virtual int Initialize(const char* title, uint32_t width, uint32_t height); + int Initialize(const std::wstring& title, uint32_t width, + uint32_t height) override; void Swap(); protected: - virtual bool OnResize(uint32_t width, uint32_t height); + bool OnResize(uint32_t width, uint32_t height) override; private: IDXGIFactory1* dxgi_factory_; diff --git a/src/xenia/kernel/fs/devices/host_path_entry.cc b/src/xenia/kernel/fs/devices/host_path_entry.cc index f37f30008..86084a9d1 100644 --- a/src/xenia/kernel/fs/devices/host_path_entry.cc +++ b/src/xenia/kernel/fs/devices/host_path_entry.cc @@ -36,19 +36,16 @@ private: } - HostPathEntry::HostPathEntry(Type type, Device* device, const char* path, - const xechar_t* local_path) : - Entry(type, device, path), - find_file_(INVALID_HANDLE_VALUE) { - local_path_ = xestrdup(local_path); -} + const std::wstring& local_path) + : Entry(type, device, path), + local_path_(local_path), + find_file_(INVALID_HANDLE_VALUE) {} HostPathEntry::~HostPathEntry() { if (find_file_ != INVALID_HANDLE_VALUE) { FindClose(find_file_); } - xe_free(local_path_); } #define COMBINE_TIME(t) (((uint64_t)t.dwHighDateTime << 32) | t.dwLowDateTime) @@ -58,7 +55,7 @@ X_STATUS HostPathEntry::QueryInfo(XFileInfo* out_info) { WIN32_FILE_ATTRIBUTE_DATA data; if (!GetFileAttributesEx( - local_path_, GetFileExInfoStandard, &data)) { + local_path_.c_str(), GetFileExInfoStandard, &data)) { return X_STATUS_ACCESS_DENIED; } @@ -87,16 +84,13 @@ X_STATUS HostPathEntry::QueryDirectory( } if (handle == INVALID_HANDLE_VALUE) { - xechar_t target_path[poly::max_path]; - xestrcpy(target_path, poly::max_path, local_path_); - if (file_name == NULL) { - xestrcat(target_path, poly::max_path, L"*"); + std::wstring target_path = local_path_; + if (!file_name) { + target_path += L"*"; + } else { + target_path += poly::to_wstring(file_name); } - else { - auto target_length = xestrlen(local_path_); - xestrwiden(target_path + target_length, XECOUNT(target_path) - target_length, file_name); - } - handle = find_file_ = FindFirstFile(target_path, &ffd); + handle = find_file_ = FindFirstFile(target_path.c_str(), &ffd); if (handle == INVALID_HANDLE_VALUE) { if (GetLastError() == ERROR_FILE_NOT_FOUND) { return X_STATUS_NO_MORE_FILES; @@ -140,9 +134,11 @@ X_STATUS HostPathEntry::QueryDirectory( return X_STATUS_SUCCESS; } -MemoryMapping* HostPathEntry::CreateMemoryMapping( - xe_file_mode file_mode, const size_t offset, const size_t length) { - xe_mmap_ref mmap = xe_mmap_open(file_mode, local_path_, offset, length); +MemoryMapping* HostPathEntry::CreateMemoryMapping(xe_file_mode file_mode, + const size_t offset, + const size_t length) { + xe_mmap_ref mmap = + xe_mmap_open(file_mode, local_path_.c_str(), offset, length); if (!mmap) { return NULL; } @@ -163,7 +159,7 @@ X_STATUS HostPathEntry::Open( DWORD creation_disposition = OPEN_EXISTING; DWORD flags_and_attributes = async ? FILE_FLAG_OVERLAPPED : 0; HANDLE file = CreateFile( - local_path_, + local_path_.c_str(), desired_access, share_mode, NULL, diff --git a/src/xenia/kernel/fs/devices/host_path_entry.h b/src/xenia/kernel/fs/devices/host_path_entry.h index 3406033b0..c13b7eb34 100644 --- a/src/xenia/kernel/fs/devices/host_path_entry.h +++ b/src/xenia/kernel/fs/devices/host_path_entry.h @@ -15,42 +15,37 @@ #include - namespace xe { namespace kernel { namespace fs { - class HostPathEntry : public Entry { -public: + public: HostPathEntry(Type type, Device* device, const char* path, - const xechar_t* local_path); + const std::wstring& local_path); virtual ~HostPathEntry(); - const xechar_t* local_path() { return local_path_; } + const std::wstring& local_path() { return local_path_; } virtual X_STATUS QueryInfo(XFileInfo* out_info); - virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info, - size_t length, const char* file_name, bool restart); + virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info, size_t length, + const char* file_name, bool restart); virtual bool can_map() { return true; } - virtual MemoryMapping* CreateMemoryMapping( - xe_file_mode file_mode, const size_t offset, const size_t length); + virtual MemoryMapping* CreateMemoryMapping(xe_file_mode file_mode, + const size_t offset, + const size_t length); - virtual X_STATUS Open( - KernelState* kernel_state, - uint32_t desired_access, bool async, - XFile** out_file); + virtual X_STATUS Open(KernelState* kernel_state, uint32_t desired_access, + bool async, XFile** out_file); -private: - xechar_t* local_path_; - HANDLE find_file_; + private: + std::wstring local_path_; + HANDLE find_file_; }; - } // namespace fs } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_FS_DEVICES_HOST_PATH_ENTRY_H_ diff --git a/src/xenia/kernel/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl_io.cc index 6cd9c0fb3..804e3c98d 100644 --- a/src/xenia/kernel/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl_io.cc @@ -72,9 +72,8 @@ SHIM_CALL NtCreateFile_shim( assert_true(root_file->type() == XObject::Type::kTypeFile); auto root_path = root_file->absolute_path(); - auto target_path = xestrdupa((std::string(root_path) + std::string(object_name)).c_str()); + auto target_path = root_path + object_name; entry = fs->ResolvePath(target_path); - xe_free(target_path); } else { // Resolve the file using the virtual file system. diff --git a/src/xenia/string.h b/src/xenia/string.h index f2f9b51cc..0f6b9be2c 100644 --- a/src/xenia/string.h +++ b/src/xenia/string.h @@ -21,20 +21,13 @@ int strncpy_s(char* dest, size_t destLength, const char* source, size_t count); #define strcpy_s(dest, destLength, source) !(strcpy(dest, source) == dest + (destLength*0)) #define strcat_s(dest, destLength, source) !(strcat(dest, source) == dest + (destLength*0)) #define _snprintf_s(dest, destLength, x, format, ...) snprintf(dest, destLength, format, ##__VA_ARGS__) -#define xestrdupa strdup -#else -#define xestrdupa _strdup #endif // !WIN32 #define xestrlenw wcslen -#define xestrdupw _wcsdup #define xestrchrw wcschr -#define xestrrchrw wcsrchr #define xestrcpyw(dest, destLength, source) (wcscpy_s(dest, destLength, source) == 0) -#define xestrncpyw(dest, destLength, source, count) (wcsncpy_s(dest, destLength, source, count) == 0) #define xestrcatw(dest, destLength, source) (wcscat_s(dest, destLength, source) == 0) #define xesnprintfw(buffer, bufferCount, format, ...) _snwprintf_s(buffer, bufferCount, (bufferCount) ? (bufferCount - 1) : 0, format, ##__VA_ARGS__) -#define xevsnprintfw(buffer, bufferCount, format, args) _vsnwprintf_s(buffer, bufferCount, (bufferCount) ? (bufferCount - 1) : 0, format, args) #define xestrlena strlen #define xestrchra strchr @@ -50,15 +43,17 @@ int strncpy_s(char* dest, size_t destLength, const char* source, size_t count); typedef wchar_t xechar_t; #define XE_WCHAR 1 -#define xestrlen xestrlenw -#define xestrdup xestrdupw -#define xestrchr xestrchrw -#define xestrrchr xestrrchrw +// xestrchr 2 uses in fs +// xestrrchra xmodule/logging +// xestrcpy fs + module +// xestrncpya one use in xbox.h +// xestrcat 2 uses in platform +// xesnprintf many uses - only remove some? +// xevsnprintf logging, disasm + #define xestrcpy xestrcpyw -#define xestrncpy xestrncpyw #define xestrcat xestrcatw #define xesnprintf xesnprintfw -#define xevsnprintf xevsnprintfw #define xestrnarrow(dest, destLength, source) (wcstombs_s(NULL, dest, destLength, source, _TRUNCATE) == 0) #define xestrwiden(dest, destLength, source) (mbstowcs_s(NULL, dest, destLength, source, _TRUNCATE) == 0) @@ -67,15 +62,9 @@ typedef wchar_t xechar_t; typedef char xechar_t; #define XE_CHAR 1 -#define xestrlen xestrlena -#define xestrdup xestrdupa -#define xestrchr xestrchra -#define xestrrchr xestrrchra #define xestrcpy xestrcpya -#define xestrncpy xestrncpya #define xestrcat xestrcata #define xesnprintf xesnprintfa -#define xevsnprintf xevsnprintfa #define xestrnarrow(dest, destLength, source) xestrcpy(dest, destLength, source) #define xestrwiden(dest, destLength, source) xestrcpy(dest, destLength, source) diff --git a/src/xenia/ui/win32/win32_window.cc b/src/xenia/ui/win32/win32_window.cc index 5e4b12738..78f87bbf4 100644 --- a/src/xenia/ui/win32/win32_window.cc +++ b/src/xenia/ui/win32/win32_window.cc @@ -53,7 +53,8 @@ Win32Window::~Win32Window() { } } -int Win32Window::Initialize(const char* title, uint32_t width, uint32_t height) { +int Win32Window::Initialize(const std::wstring& title, uint32_t width, + uint32_t height) { int result = Window::Initialize(title, width, height); if (result) { return result; @@ -164,11 +165,11 @@ void Win32Window::EnableMMCSS() { FreeLibrary(hLibrary); } -bool Win32Window::set_title(const char* title) { +bool Win32Window::set_title(const std::wstring& title) { if (!Window::set_title(title)) { return false; } - XEIGNORE(SetWindowTextA(handle_, title)); + XEIGNORE(SetWindowText(handle_, title.c_str())); return true; } diff --git a/src/xenia/ui/win32/win32_window.h b/src/xenia/ui/win32/win32_window.h index 20be6dafe..600907574 100644 --- a/src/xenia/ui/win32/win32_window.h +++ b/src/xenia/ui/win32/win32_window.h @@ -10,46 +10,45 @@ #ifndef XENIA_UI_WIN32_WIN32_WINDOW_H_ #define XENIA_UI_WIN32_WIN32_WINDOW_H_ +#include + #include #include - namespace xe { namespace ui { namespace win32 { - class Win32Window : public Window { -public: + public: Win32Window(xe_run_loop_ref run_loop); - virtual ~Win32Window(); + ~Win32Window() override; - virtual int Initialize(const char* title, uint32_t width, uint32_t height); + int Initialize(const std::wstring& title, uint32_t width, + uint32_t height) override; - virtual bool set_title(const char* title); - virtual bool set_cursor_visible(bool value); + bool set_title(const std::wstring& title) override; + bool set_cursor_visible(bool value) override; HWND handle() const { return handle_; } LRESULT WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); -protected: - virtual bool SetSize(uint32_t width, uint32_t height); - virtual void OnClose(); + protected: + bool SetSize(uint32_t width, uint32_t height) override; + void OnClose() override; -private: + private: void EnableMMCSS(); bool HandleMouse(UINT message, WPARAM wParam, LPARAM lParam); bool HandleKeyboard(UINT message, WPARAM wParam, LPARAM lParam); - HWND handle_; - bool closing_; + HWND handle_; + bool closing_; }; - } // namespace win32 } // namespace ui } // namespace xe - #endif // XENIA_UI_WIN32_WIN32_WINDOW_H_ diff --git a/src/xenia/ui/window.cc b/src/xenia/ui/window.cc index 0a37b1f1c..91a43dde0 100644 --- a/src/xenia/ui/window.cc +++ b/src/xenia/ui/window.cc @@ -9,39 +9,33 @@ #include - using namespace xe; using namespace xe::ui; - -Window::Window(xe_run_loop_ref run_loop) : - title_(0), is_visible_(true), is_cursor_visible_(true), - width_(0), height_(0) { +Window::Window(xe_run_loop_ref run_loop) + : title_(L"Window"), + is_visible_(true), + is_cursor_visible_(true), + width_(0), + height_(0) { run_loop_ = xe_run_loop_retain(run_loop); } -Window::~Window() { - if (title_) { - xe_free(title_); - } - xe_run_loop_release(run_loop_); -} +Window::~Window() { xe_run_loop_release(run_loop_); } -int Window::Initialize(const char* title, uint32_t width, uint32_t height) { - title_ = xestrdupa(title); +int Window::Initialize(const std::wstring& title, uint32_t width, + uint32_t height) { + title_ = title; width_ = width; height_ = height; return 0; } -bool Window::set_title(const char* title) { +bool Window::set_title(const std::wstring& title) { if (title == title_) { return false; } - if (title_) { - xe_free(title_); - } - title_ = xestrdupa(title); + title_ = title; return true; } @@ -74,7 +68,7 @@ void Window::OnHide() { void Window::Resize(uint32_t width, uint32_t height) { BeginResizing(); SetSize(width, height); - OnResize(width, height); // redundant? + OnResize(width, height); // redundant? EndResizing(); } @@ -116,5 +110,4 @@ void Window::Close() { closed(e); } -void Window::OnClose() { -} +void Window::OnClose() {} diff --git a/src/xenia/ui/window.h b/src/xenia/ui/window.h index cdc7b2c39..551458ba1 100644 --- a/src/xenia/ui/window.h +++ b/src/xenia/ui/window.h @@ -10,27 +10,28 @@ #ifndef XENIA_UI_WINDOW_H_ #define XENIA_UI_WINDOW_H_ +#include + #include #include #include - namespace xe { namespace ui { - class Window { -public: + public: Window(xe_run_loop_ref run_loop); virtual ~Window(); - virtual int Initialize(const char* title, uint32_t width, uint32_t height); + virtual int Initialize(const std::wstring& title, uint32_t width, + uint32_t height); xe_run_loop_ref run_loop() const { return run_loop_; } - const char* title() const { return title_; } - virtual bool set_title(const char* title); + const std::wstring& title() const { return title_; } + virtual bool set_title(const std::wstring& title); bool is_visible() const { return is_visible_; } bool is_cursor_visible() const { return is_cursor_visible_; } virtual bool set_cursor_visible(bool value); @@ -40,7 +41,7 @@ public: void Close(); -public: + public: alloy::Delegate shown; alloy::Delegate hidden; alloy::Delegate resizing; @@ -56,7 +57,7 @@ public: alloy::Delegate mouse_up; alloy::Delegate mouse_wheel; -protected: + protected: void OnShow(); void OnHide(); @@ -67,19 +68,17 @@ protected: virtual void OnClose(); -private: + private: xe_run_loop_ref run_loop_; - char* title_; - bool is_visible_; - bool is_cursor_visible_; - bool resizing_; - uint32_t width_; - uint32_t height_; + std::wstring title_; + bool is_visible_; + bool is_cursor_visible_; + bool resizing_; + uint32_t width_; + uint32_t height_; }; - } // namespace ui } // namespace xe - #endif // XENIA_UI_WINDOW_H_ From 2f12585af98416ab3d073de0968f9cdac6b0cc86 Mon Sep 17 00:00:00 2001 From: wszechpolak Date: Sat, 16 Aug 2014 12:17:43 +0200 Subject: [PATCH 114/388] Added XamWriteGamerTile - should fix #109 --- src/xenia/kernel/xam_user.cc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/xenia/kernel/xam_user.cc b/src/xenia/kernel/xam_user.cc index 521358997..15bf258df 100644 --- a/src/xenia/kernel/xam_user.cc +++ b/src/xenia/kernel/xam_user.cc @@ -276,6 +276,23 @@ SHIM_CALL XamUserCreateAchievementEnumerator_shim( } +SHIM_CALL XamWriteGamerTile_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t arg0 = SHIM_GET_ARG_32(0); + uint32_t arg1 = SHIM_GET_ARG_32(1); + uint32_t arg2 = SHIM_GET_ARG_32(2); + uint32_t arg3 = SHIM_GET_ARG_32(3); + uint32_t arg4 = SHIM_GET_ARG_32(4); + uint32_t arg5 = SHIM_GET_ARG_32(5); + + XELOGD( + "XamWriteGamerTile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", + arg0, arg1, arg2, arg3, arg4, arg5); + + SHIM_SET_RETURN_32(0x3E5); +} + + } // namespace kernel } // namespace xe @@ -290,4 +307,5 @@ void xe::kernel::xam::RegisterUserExports( SHIM_SET_MAPPING("xam.xex", XamUserCheckPrivilege, state); SHIM_SET_MAPPING("xam.xex", XamShowSigninUI, state); SHIM_SET_MAPPING("xam.xex", XamUserCreateAchievementEnumerator, state); + SHIM_SET_MAPPING("xam.xex", XamWriteGamerTile, state); } From 1361fda8849c7ab548e05eb1871af4a6fffe65a1 Mon Sep 17 00:00:00 2001 From: wszechpolak Date: Sat, 16 Aug 2014 22:47:08 +0200 Subject: [PATCH 115/388] Fix XamWriteGamerTile to make it support both sync/async requests --- src/xenia/kernel/xam_user.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/xenia/kernel/xam_user.cc b/src/xenia/kernel/xam_user.cc index 15bf258df..4524d743a 100644 --- a/src/xenia/kernel/xam_user.cc +++ b/src/xenia/kernel/xam_user.cc @@ -283,13 +283,19 @@ SHIM_CALL XamWriteGamerTile_shim( uint32_t arg2 = SHIM_GET_ARG_32(2); uint32_t arg3 = SHIM_GET_ARG_32(3); uint32_t arg4 = SHIM_GET_ARG_32(4); - uint32_t arg5 = SHIM_GET_ARG_32(5); + uint32_t overlapped_ptr = SHIM_GET_ARG_32(5); XELOGD( "XamWriteGamerTile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", - arg0, arg1, arg2, arg3, arg4, arg5); + arg0, arg1, arg2, arg3, arg4, overlapped_ptr); - SHIM_SET_RETURN_32(0x3E5); + if (overlapped_ptr) { + state->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS); + SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); + } + else { + SHIM_SET_RETURN_32(X_ERROR_SUCCESS); + } } From b449e9f5cc0dd53a1eeb05e5c4637556c8cbec90 Mon Sep 17 00:00:00 2001 From: wszechpolak Date: Sat, 16 Aug 2014 22:49:13 +0200 Subject: [PATCH 116/388] Add X_ERROR_FUNCTION_FAILED --- src/xenia/xbox.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index 633477a9c..52bc8f31e 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -76,6 +76,7 @@ typedef uint32_t X_RESULT; #define X_ERROR_NOT_FOUND X_HRESULT_FROM_WIN32(0x00000490L) #define X_ERROR_CANCELLED X_HRESULT_FROM_WIN32(0x000004C7L) #define X_ERROR_NO_SUCH_USER X_HRESULT_FROM_WIN32(0x00000525L) +#define X_ERROR_FUNCTION_FAILED X_HRESULT_FROM_WIN32(0x0000065BL) #define X_ERROR_EMPTY X_HRESULT_FROM_WIN32(0x000010D2L) // MEM_*, used by NtAllocateVirtualMemory From 1f8cfb6fce8c2214e25cfb5b874b153294001f82 Mon Sep 17 00:00:00 2001 From: wszechpolak Date: Sat, 16 Aug 2014 22:49:50 +0200 Subject: [PATCH 117/388] Clean --- src/xenia/kernel/xam_content.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xenia/kernel/xam_content.cc b/src/xenia/kernel/xam_content.cc index bc8a6675f..3abd40fb6 100644 --- a/src/xenia/kernel/xam_content.cc +++ b/src/xenia/kernel/xam_content.cc @@ -76,7 +76,7 @@ SHIM_CALL XamShowDeviceSelectorUI_shim( XELOGD( "XamShowDeviceSelectorUI(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", arg0, arg1, arg2, arg3, arg4, arg5); - SHIM_SET_RETURN_32(997); + SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); } From 2c4c7e11dc5295da7a8cd64c0ef2a23fed41f5f4 Mon Sep 17 00:00:00 2001 From: wszechpolak Date: Sun, 17 Aug 2014 00:32:13 +0200 Subject: [PATCH 118/388] Add XamUserWriteProfileSettings stub --- src/xenia/kernel/xam_user.cc | 41 ++++++++++++++++++++++++++++++++++++ src/xenia/xbox.h | 1 + 2 files changed, 42 insertions(+) diff --git a/src/xenia/kernel/xam_user.cc b/src/xenia/kernel/xam_user.cc index 4524d743a..300cbf07b 100644 --- a/src/xenia/kernel/xam_user.cc +++ b/src/xenia/kernel/xam_user.cc @@ -218,6 +218,46 @@ SHIM_CALL XamUserReadProfileSettings_shim( } +SHIM_CALL XamUserWriteProfileSettings_shim( + PPCContext* ppc_state, KernelState* state) { + uint32_t user_index = SHIM_GET_ARG_32(0); + uint32_t unknown = SHIM_GET_ARG_32(1); + uint32_t setting_count = SHIM_GET_ARG_32(2); + uint32_t settings_ptr = SHIM_GET_ARG_32(3); + uint32_t overlapped_ptr = SHIM_GET_ARG_32(4); + + XELOGD( + "XamUserWriteProfileSettings(%.8X, %d, %d, %d, %d, %.8X, %.8X(%d), %.8X, %.8X)", + user_index, unknown, setting_count, settings_ptr, overlapped_ptr); + + if (!setting_count || !settings_ptr) { + SHIM_SET_RETURN_32(X_ERROR_INVALID_PARAMETER); + } + + if (user_index == 255) { + user_index = 0; + } + + if (user_index) { + // Only support user 0. + SHIM_SET_RETURN_32(X_ERROR_NOT_FOUND); + return; + } + + const auto& user_profile = state->user_profile(); + + // TODO: Update and save settings. + + if (overlapped_ptr) { + state->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS); + SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); + } + else { + SHIM_SET_RETURN_32(X_ERROR_SUCCESS); + } +} + + SHIM_CALL XamUserCheckPrivilege_shim( PPCContext* ppc_state, KernelState* state) { uint32_t user_index = SHIM_GET_ARG_32(0); @@ -310,6 +350,7 @@ void xe::kernel::xam::RegisterUserExports( SHIM_SET_MAPPING("xam.xex", XamUserGetSigninInfo, state); SHIM_SET_MAPPING("xam.xex", XamUserGetName, state); SHIM_SET_MAPPING("xam.xex", XamUserReadProfileSettings, state); + SHIM_SET_MAPPING("xam.xex", XamUserWriteProfileSettings, state); SHIM_SET_MAPPING("xam.xex", XamUserCheckPrivilege, state); SHIM_SET_MAPPING("xam.xex", XamShowSigninUI, state); SHIM_SET_MAPPING("xam.xex", XamUserCreateAchievementEnumerator, state); diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index 52bc8f31e..b3ca8dd24 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -68,6 +68,7 @@ typedef uint32_t X_RESULT; #define X_ERROR_ACCESS_DENIED X_HRESULT_FROM_WIN32(0x00000005L) #define X_ERROR_INVALID_HANDLE X_HRESULT_FROM_WIN32(0x00000006L) #define X_ERROR_NO_MORE_FILES X_HRESULT_FROM_WIN32(0x00000018L) +#define X_ERROR_INVALID_PARAMETER X_HRESULT_FROM_WIN32(0x00000057L) #define X_ERROR_IO_PENDING X_HRESULT_FROM_WIN32(0x000003E5L) #define X_ERROR_INSUFFICIENT_BUFFER X_HRESULT_FROM_WIN32(0x0000007AL) #define X_ERROR_BAD_ARGUMENTS X_HRESULT_FROM_WIN32(0x000000A0L) From 7c5fa886615582c648f4b33d3ad04dd9fa19567e Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 16 Aug 2014 16:34:04 -0700 Subject: [PATCH 119/388] More string swapping and cleaning up main(). --- src/alloy/core.h | 1 - src/poly/main.h | 37 +++++ src/poly/main_posix.cc | 41 ++++++ src/poly/main_win.cc | 105 +++++++++++++++ src/poly/poly-private.h | 15 --- src/poly/poly.cc | 13 -- src/poly/sources.gypi | 5 +- src/poly/string.cc | 48 +++++++ src/poly/string.h | 13 ++ src/xenia/common.h | 1 - src/xenia/core.h | 1 - src/xenia/core/path.cc | 35 ----- src/xenia/core/path.h | 25 ---- src/xenia/core/path_posix.cc | 16 --- src/xenia/core/path_win.cc | 17 --- src/xenia/core/sources.gypi | 4 - .../kernel/fs/devices/disc_image_device.cc | 2 +- .../kernel/fs/devices/host_path_device.cc | 25 +--- .../fs/devices/stfs_container_device.cc | 2 +- src/xenia/kernel/objects/xmodule.cc | 23 ++-- src/xenia/kernel/objects/xmodule.h | 12 +- src/xenia/kernel/xboxkrnl_rtl.cc | 16 +-- src/xenia/logging.cc | 9 +- src/xenia/logging.h | 1 - src/xenia/platform.cc | 126 ------------------ src/xenia/platform.h | 44 ------ src/xenia/profiling.h | 1 - src/xenia/sources.gypi | 2 - src/xenia/string.h | 18 --- src/xenia/types.h | 2 +- tools/alloy-sandbox/alloy-sandbox.cc | 8 +- tools/alloy-sandbox/alloy-sandbox.gypi | 6 + tools/xenia-compare/xenia-compare.cc | 7 +- tools/xenia-compare/xenia-compare.gypi | 4 +- tools/xenia-debug/xenia-debug.cc | 7 +- tools/xenia-debug/xenia-debug.gypi | 2 +- tools/xenia-run/xenia-run.cc | 29 ++-- tools/xenia-run/xenia-run.gypi | 2 +- tools/xenia-test/xenia-test.cc | 7 +- tools/xenia-test/xenia-test.gypi | 6 + xenia.gyp | 1 + 41 files changed, 326 insertions(+), 413 deletions(-) create mode 100644 src/poly/main.h create mode 100644 src/poly/main_posix.cc create mode 100644 src/poly/main_win.cc delete mode 100644 src/poly/poly-private.h delete mode 100644 src/poly/poly.cc delete mode 100644 src/xenia/core/path.cc delete mode 100644 src/xenia/core/path.h delete mode 100644 src/xenia/core/path_posix.cc delete mode 100644 src/xenia/core/path_win.cc delete mode 100644 src/xenia/platform.cc delete mode 100644 src/xenia/platform.h diff --git a/src/alloy/core.h b/src/alloy/core.h index f5fd3040c..5f90cb31a 100644 --- a/src/alloy/core.h +++ b/src/alloy/core.h @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/src/poly/main.h b/src/poly/main.h new file mode 100644 index 000000000..82c02576d --- /dev/null +++ b/src/poly/main.h @@ -0,0 +1,37 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef POLY_MAIN_H_ +#define POLY_MAIN_H_ + +#include +#include + +#include + +namespace poly { + +// Returns true if there is a user-visible console attached to receive stdout. +bool has_console_attached(); + +// Extern defined by user code. This must be present for the application to +// launch. +struct EntryInfo { + std::wstring name; + std::wstring usage; + int (*entry_point)(std::vector& args); +}; +EntryInfo GetEntryInfo(); + +#define DEFINE_ENTRY_POINT(name, usage, entry_point) \ + poly::EntryInfo poly::GetEntryInfo() { return {name, usage, entry_point}; } + +} // namespace poly + +#endif // POLY_MAIN_H_ diff --git a/src/poly/main_posix.cc b/src/poly/main_posix.cc new file mode 100644 index 000000000..5af8b2437 --- /dev/null +++ b/src/poly/main_posix.cc @@ -0,0 +1,41 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include + +namespace poly { + +bool has_console_attached() { + return true; +} + +} // namespace poly + + +extern "C" int main(int argc, char** argv) { + auto entry_info = poly::GetEntryInfo(); + + google::SetUsageMessage(std::string("usage: ") + + poly::to_string(entry_info.usage)); + google::SetVersionString("1.0"); + google::ParseCommandLineFlags(&argc, &argv, true); + + std::vector args; + for (int n = 0; n < argc; n++) { + args.push_back(poly::to_wstring(argv[n])); + } + + // Call app-provided entry point. + int result = entry_info.entry_point(args); + + google::ShutDownCommandLineFlags(); + return result; +} diff --git a/src/poly/main_win.cc b/src/poly/main_win.cc new file mode 100644 index 000000000..b4bdad74f --- /dev/null +++ b/src/poly/main_win.cc @@ -0,0 +1,105 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include +#include +#include + +#include +#include + +namespace poly { + +bool has_console_attached_ = true; + +bool has_console_attached() { return has_console_attached_; } + +void AttachConsole() { + bool has_console = ::AttachConsole(ATTACH_PARENT_PROCESS) == TRUE; + if (!has_console) { + // We weren't launched from a console, so just return. + // We could alloc our own console, but meh: + // has_console = AllocConsole() == TRUE; + has_console_attached_ = false; + return; + } + has_console_attached_ = true; + + auto std_handle = (intptr_t)GetStdHandle(STD_OUTPUT_HANDLE); + auto con_handle = _open_osfhandle(std_handle, _O_TEXT); + auto fp = _fdopen(con_handle, "w"); + *stdout = *fp; + setvbuf(stdout, NULL, _IONBF, 0); + + std_handle = (intptr_t)GetStdHandle(STD_ERROR_HANDLE); + con_handle = _open_osfhandle(std_handle, _O_TEXT); + fp = _fdopen(con_handle, "w"); + *stderr = *fp; + setvbuf(stderr, NULL, _IONBF, 0); +} + +} // namespace poly + +// Used in console mode apps; automatically picked based on subsystem. +int wmain(int argc, wchar_t* argv[]) { + auto entry_info = poly::GetEntryInfo(); + + google::SetUsageMessage(std::string("usage: ") + + poly::to_string(entry_info.usage)); + google::SetVersionString("1.0"); + + // Convert all args to narrow, as gflags doesn't support wchar. + int argca = argc; + char** argva = (char**)alloca(sizeof(char*) * argca); + for (int n = 0; n < argca; n++) { + size_t len = wcslen(argv[n]); + argva[n] = (char*)alloca(len + 1); + wcstombs_s(NULL, argva[n], len + 1, argv[n], _TRUNCATE); + } + + // Parse flags; this may delete some of them. + google::ParseCommandLineFlags(&argc, &argva, true); + + // Widen all remaining flags and convert to usable strings. + std::vector args; + for (int n = 0; n < argc; n++) { + args.push_back(poly::to_wstring(argva[n])); + } + + // Call app-provided entry point. + int result = entry_info.entry_point(args); + + google::ShutDownCommandLineFlags(); + return result; +} + +// Used in windowed apps; automatically picked based on subsystem. +int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR command_line, int) { + // Attach a console so we can write output to stdout. If the user hasn't + // redirected output themselves it'll pop up a window. + poly::AttachConsole(); + + auto entry_info = poly::GetEntryInfo(); + + // Convert to an argv-like format so we can share code/use gflags. + std::wstring buffer = entry_info.name + L" " + command_line; + int argc; + wchar_t** argv = CommandLineToArgvW(buffer.c_str(), &argc); + if (!argv) { + return 1; + } + + // Run normal entry point. + int result = wmain(argc, argv); + + LocalFree(argv); + return result; +} diff --git a/src/poly/poly-private.h b/src/poly/poly-private.h deleted file mode 100644 index 500cddd52..000000000 --- a/src/poly/poly-private.h +++ /dev/null @@ -1,15 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2014 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef POLY_POLY_PRIVATE_H_ -#define POLY_POLY_PRIVATE_H_ - -#include - -#endif // POLY_POLY_PRIVATE_H_ diff --git a/src/poly/poly.cc b/src/poly/poly.cc deleted file mode 100644 index 2e306025b..000000000 --- a/src/poly/poly.cc +++ /dev/null @@ -1,13 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2014 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include -#include - -namespace poly {} // namespace poly diff --git a/src/poly/sources.gypi b/src/poly/sources.gypi index 547d9e838..b5faa8083 100644 --- a/src/poly/sources.gypi +++ b/src/poly/sources.gypi @@ -7,13 +7,12 @@ 'debugging.h', 'config.h', 'cxx_compat.h', + 'main.h', 'math.cc', 'math.h', 'memory.cc', 'memory.h', 'platform.h', - 'poly-private.h', - 'poly.cc', 'poly.h', 'string.cc', 'string.h', @@ -23,6 +22,7 @@ 'conditions': [ ['OS == "mac" or OS == "linux"', { 'sources': [ + 'main_posix.cc', ], }], ['OS == "linux"', { @@ -39,6 +39,7 @@ ['OS == "win"', { 'sources': [ 'debugging_win.cc', + 'main_win.cc', 'threading_win.cc', ], }], diff --git a/src/poly/string.cc b/src/poly/string.cc index 4716c0a32..0525b5541 100644 --- a/src/poly/string.cc +++ b/src/poly/string.cc @@ -39,4 +39,52 @@ std::string::size_type find_first_of_case(const std::string& target, } } +std::wstring to_absolute_path(const std::wstring& path) { +#if XE_LIKE_WIN32 + wchar_t buffer[poly::max_path]; + _wfullpath(buffer, path.c_str(), sizeof(buffer) / sizeof(wchar_t)); + return buffer; +#else + char buffer[poly::max_path]; + realpath(poly::to_string(path).c_str(), buffer); + return poly::to_wstring(buffer); +#endif // XE_LIKE_WIN32 +} + +std::wstring join_paths(const std::wstring& left, const std::wstring& right, + wchar_t sep) { + if (!left.size()) { + return right; + } else if (!right.size()) { + return left; + } + if (left[left.size() - 1] == sep) { + return left + right; + } else { + return left + sep + right; + } +} + +std::wstring fix_path_separators(const std::wstring& source, wchar_t new_sep) { + // Swap all separators to new_sep. + wchar_t old_sep = new_sep == '\\' ? '/' : '\\'; + std::wstring::size_type pos = 0; + std::wstring dest = source; + while ((pos = source.find_first_of(old_sep, pos)) != std::wstring::npos) { + dest[pos] = new_sep; + ++pos; + } + // Replace redundant separators. + pos = 0; + while ((pos = dest.find_first_of(new_sep, pos)) != std::wstring::npos) { + if (pos < dest.size() - 1) { + if (dest[pos + 1] == new_sep) { + dest.erase(pos + 1, 1); + } + } + ++pos; + } + return dest; +} + } // namespace poly diff --git a/src/poly/string.h b/src/poly/string.h index 7d360abd2..688dd4c1b 100644 --- a/src/poly/string.h +++ b/src/poly/string.h @@ -24,9 +24,22 @@ namespace poly { std::string to_string(const std::wstring& source); std::wstring to_wstring(const std::string& source); +// find_first_of string, case insensitive. std::string::size_type find_first_of_case(const std::string& target, const std::string& search); +// Converts the given path to an absolute path based on cwd. +std::wstring to_absolute_path(const std::wstring& path); + +// Joins two path segments with the given separator. +std::wstring join_paths(const std::wstring& left, const std::wstring& right, + wchar_t sep = poly::path_separator); + +// Replaces all path separators with the given value and removes redundant +// separators. +std::wstring fix_path_separators(const std::wstring& source, + wchar_t new_sep = poly::path_separator); + } // namespace poly #endif // POLY_STRING_H_ diff --git a/src/xenia/common.h b/src/xenia/common.h index 048829080..9288f0d24 100644 --- a/src/xenia/common.h +++ b/src/xenia/common.h @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/src/xenia/core.h b/src/xenia/core.h index 3f606cc7a..12d7dfb93 100644 --- a/src/xenia/core.h +++ b/src/xenia/core.h @@ -20,7 +20,6 @@ namespace xe { #include #include #include -#include #include #include #include diff --git a/src/xenia/core/path.cc b/src/xenia/core/path.cc deleted file mode 100644 index c24d22966..000000000 --- a/src/xenia/core/path.cc +++ /dev/null @@ -1,35 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - - -void xe_path_join(const xechar_t* left, const xechar_t* right, - xechar_t* out_path, size_t out_path_size) { -#if XE_WCHAR - xesnprintf(out_path, out_path_size, L"%ls%c%ls", - left, poly::path_separator, right); -#else - xesnprintf(out_path, out_path_size, L"%s%c%s", - left, poly::path_separator, right); -#endif // XE_WCHAR -} - -void xe_path_get_absolute(const xechar_t* path, xechar_t* out_abs_path, - size_t abs_path_size) { -#if XE_PLATFORM_WIN32 -#if XE_WCHAR - _wfullpath(out_abs_path, path, abs_path_size); -#else - _fullpath(out_abs_path, path, abs_path_size); -#endif // XE_WCHAR -#else - realpath(path, out_abs_path); -#endif // WIN32 -} diff --git a/src/xenia/core/path.h b/src/xenia/core/path.h deleted file mode 100644 index 7ccfde28b..000000000 --- a/src/xenia/core/path.h +++ /dev/null @@ -1,25 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_CORE_PATH_H_ -#define XENIA_CORE_PATH_H_ - -#include -#include -#include - - -void xe_path_join(const xechar_t* left, const xechar_t* right, - xechar_t* out_path, size_t out_path_size); -void xe_path_get_absolute(const xechar_t* path, xechar_t* out_abs_path, - size_t abs_path_size); - -const xechar_t* xe_path_get_tmp(const xechar_t* prefix); - -#endif // XENIA_CORE_PATH_H_ diff --git a/src/xenia/core/path_posix.cc b/src/xenia/core/path_posix.cc deleted file mode 100644 index 0dc9aadec..000000000 --- a/src/xenia/core/path_posix.cc +++ /dev/null @@ -1,16 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - - -const xechar_t* xe_path_get_tmp(const xechar_t* prefix) { - // - assert_always(); -} diff --git a/src/xenia/core/path_win.cc b/src/xenia/core/path_win.cc deleted file mode 100644 index ded9bf388..000000000 --- a/src/xenia/core/path_win.cc +++ /dev/null @@ -1,17 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - - -const xechar_t* xe_path_get_tmp(const xechar_t* prefix) { - // - assert_always(); - return NULL; -} diff --git a/src/xenia/core/sources.gypi b/src/xenia/core/sources.gypi index 450a12cbd..206ae0e60 100644 --- a/src/xenia/core/sources.gypi +++ b/src/xenia/core/sources.gypi @@ -5,8 +5,6 @@ 'hash.h', 'mmap.h', 'pal.h', - 'path.cc', - 'path.h', 'ref.cc', 'ref.h', 'run_loop.h', @@ -17,7 +15,6 @@ ['OS == "mac" or OS == "linux"', { 'sources': [ 'mmap_posix.cc', - 'path_posix.cc', 'socket_posix.cc', ], }], @@ -35,7 +32,6 @@ 'sources': [ 'mmap_win.cc', 'pal_win.cc', - 'path_win.cc', 'run_loop_win.cc', 'socket_win.cc', ], diff --git a/src/xenia/kernel/fs/devices/disc_image_device.cc b/src/xenia/kernel/fs/devices/disc_image_device.cc index da8b8912a..584fe6e21 100644 --- a/src/xenia/kernel/fs/devices/disc_image_device.cc +++ b/src/xenia/kernel/fs/devices/disc_image_device.cc @@ -59,7 +59,7 @@ Entry* DiscImageDevice::ResolvePath(const char* path) { char remaining[poly::max_path]; XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), path)); while (remaining[0]) { - char* next_slash = xestrchra(remaining, '\\'); + char* next_slash = strchr(remaining, '\\'); if (next_slash == remaining) { // Leading slash - shift XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), remaining + 1)); diff --git a/src/xenia/kernel/fs/devices/host_path_device.cc b/src/xenia/kernel/fs/devices/host_path_device.cc index 9bd4c4a29..ff6b55601 100644 --- a/src/xenia/kernel/fs/devices/host_path_device.cc +++ b/src/xenia/kernel/fs/devices/host_path_device.cc @@ -9,7 +9,6 @@ #include -#include #include #include @@ -30,27 +29,9 @@ Entry* HostPathDevice::ResolvePath(const char* path) { XELOGFS("HostPathDevice::ResolvePath(%s)", path); -#if XE_WCHAR - xechar_t rel_path[poly::max_path]; - XEIGNORE(xestrwiden(rel_path, XECOUNT(rel_path), path)); -#else - const xechar_t* rel_path = path; -#endif - - xechar_t full_path[poly::max_path]; - xe_path_join(local_path_.c_str(), rel_path, full_path, XECOUNT(full_path)); - - // Swap around path separators. - if (poly::path_separator != '\\') { - for (size_t n = 0; n < XECOUNT(full_path); n++) { - if (full_path[n] == 0) { - break; - } - if (full_path[n] == '\\') { - full_path[n] = poly::path_separator; - } - } - } + auto rel_path = poly::to_wstring(path); + auto full_path = poly::join_paths(local_path_, rel_path); + full_path = poly::fix_path_separators(full_path); // TODO(benvanik): get file info // TODO(benvanik): fail if does not exit diff --git a/src/xenia/kernel/fs/devices/stfs_container_device.cc b/src/xenia/kernel/fs/devices/stfs_container_device.cc index da37bc4bf..dd35202dc 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_device.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_device.cc @@ -59,7 +59,7 @@ Entry* STFSContainerDevice::ResolvePath(const char* path) { char remaining[poly::max_path]; XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), path)); while (remaining[0]) { - char* next_slash = xestrchra(remaining, '\\'); + char* next_slash = strchr(remaining, '\\'); if (next_slash == remaining) { // Leading slash - shift XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), remaining + 1)); diff --git a/src/xenia/kernel/objects/xmodule.cc b/src/xenia/kernel/objects/xmodule.cc index 462d76ac4..406534556 100644 --- a/src/xenia/kernel/objects/xmodule.cc +++ b/src/xenia/kernel/objects/xmodule.cc @@ -17,19 +17,20 @@ using namespace xe::cpu; using namespace xe::kernel; -XModule::XModule(KernelState* kernel_state, const char* path) : - XObject(kernel_state, kTypeModule) { - XEIGNORE(xestrcpya(path_, XECOUNT(path_), path)); - const char* slash = xestrrchra(path, '/'); - if (!slash) { - slash = xestrrchra(path, '\\'); +XModule::XModule(KernelState* kernel_state, const std::string& path) : + XObject(kernel_state, kTypeModule), path_(path) { + auto last_slash = path.find_last_of('/'); + if (last_slash == path.npos) { + last_slash = path.find_last_of('\\'); } - if (slash) { - XEIGNORE(xestrcpya(name_, XECOUNT(name_), slash + 1)); + if (last_slash == path.npos) { + name_ = path_; + } else { + name_ = path_.substr(last_slash + 1); } - char* dot = xestrrchra(name_, '.'); - if (dot) { - *dot = 0; + auto dot = name_.find_last_of('.'); + if (dot != name_.npos) { + name_ = name_.substr(0, dot); } } diff --git a/src/xenia/kernel/objects/xmodule.h b/src/xenia/kernel/objects/xmodule.h index 9537adbcd..1af9e3ea8 100644 --- a/src/xenia/kernel/objects/xmodule.h +++ b/src/xenia/kernel/objects/xmodule.h @@ -10,6 +10,8 @@ #ifndef XENIA_KERNEL_XBOXKRNL_XMODULE_H_ #define XENIA_KERNEL_XBOXKRNL_XMODULE_H_ +#include + #include #include @@ -21,11 +23,11 @@ namespace kernel { class XModule : public XObject { public: - XModule(KernelState* kernel_state, const char* path); + XModule(KernelState* kernel_state, const std::string& path); virtual ~XModule(); - const char* path() const { return path_; } - const char* name() const { return name_; } + const std::string& path() const { return path_; } + const std::string& name() const { return name_; } virtual void* GetProcAddressByOrdinal(uint16_t ordinal) = 0; virtual X_STATUS GetSection( @@ -35,8 +37,8 @@ public: protected: void OnLoad(); - char name_[256]; - char path_[poly::max_path]; + std::string name_; + std::string path_; }; diff --git a/src/xenia/kernel/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl_rtl.cc index 5ac309ae6..b08b0bcf7 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl_rtl.cc @@ -200,19 +200,19 @@ SHIM_CALL RtlInitUnicodeString_shim( uint32_t destination_ptr = SHIM_GET_ARG_32(0); uint32_t source_ptr = SHIM_GET_ARG_32(1); - const wchar_t* source = - source_ptr ? (const wchar_t*)SHIM_MEM_ADDR(source_ptr) : NULL; - XELOGD("RtlInitUnicodeString(%.8X, %.8X = %ls)", - destination_ptr, source_ptr, source ? source : L""); + auto source = + source_ptr ? poly::load_and_swap(SHIM_MEM_ADDR(source_ptr)) + : L""; + XELOGD("RtlInitUnicodeString(%.8X, %.8X = %ls)", destination_ptr, source_ptr, + source.empty() ? L"" : source.c_str()); // VOID // _Out_ PUNICODE_STRING DestinationString, // _In_opt_ PCWSTR SourceString - if (source) { - uint16_t length = (uint16_t)xestrlenw(source); - SHIM_SET_MEM_16(destination_ptr + 0, length * 2); - SHIM_SET_MEM_16(destination_ptr + 2, (length + 1) * 2); + if (source.size()) { + SHIM_SET_MEM_16(destination_ptr + 0, source.size() * 2); + SHIM_SET_MEM_16(destination_ptr + 2, (source.size() + 1) * 2); SHIM_SET_MEM_32(destination_ptr + 4, source_ptr); } else { SHIM_SET_MEM_16(destination_ptr + 0, 0); diff --git a/src/xenia/logging.cc b/src/xenia/logging.cc index 1f387ad57..6ed64352d 100644 --- a/src/xenia/logging.cc +++ b/src/xenia/logging.cc @@ -11,10 +11,9 @@ #include -#include - #include - +#include +#include DEFINE_bool(fast_stdout, false, "Don't lock around stdout/stderr. May introduce weirdness."); @@ -31,7 +30,7 @@ void xe_format_log_line( const char* function_name, const char level_char, const char* fmt, va_list args) { // Strip out just the filename from the path. - const char* filename = xestrrchra(file_path, poly::path_separator); + const char* filename = strrchr(file_path, poly::path_separator); if (filename) { // Slash - skip over it. filename++; @@ -108,7 +107,7 @@ void xe_handle_fatal( } #if XE_LIKE_WIN32 - if (!xe_has_console()) { + if (!poly::has_console_attached()) { MessageBoxA(NULL, buffer, "Xenia Error", MB_OK | MB_ICONERROR | MB_APPLMODAL | MB_SETFOREGROUND); } diff --git a/src/xenia/logging.h b/src/xenia/logging.h index c030f4465..d8b7c30ae 100644 --- a/src/xenia/logging.h +++ b/src/xenia/logging.h @@ -12,7 +12,6 @@ #include -#include #include #include diff --git a/src/xenia/platform.cc b/src/xenia/platform.cc deleted file mode 100644 index c9d4d063b..000000000 --- a/src/xenia/platform.cc +++ /dev/null @@ -1,126 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include - -#include - - -namespace { - -typedef int (*user_main_t)(int argc, xechar_t** argv); - -bool _has_console = true; - -} // namespace - - -#if XE_LIKE_WIN32 && defined(UNICODE) && UNICODE - -#include -#include -#include -#include - -int xe_main_thunk( - int argc, wchar_t* argv[], - void* user_main, const char* usage) { - google::SetUsageMessage(std::string("usage: ") + usage); - google::SetVersionString("1.0"); - - int argca = argc; - char** argva = (char**)alloca(sizeof(char*) * argca); - for (int n = 0; n < argca; n++) { - size_t len = xestrlenw(argv[n]); - argva[n] = (char*)alloca(len + 1); - xestrnarrow(argva[n], len + 1, argv[n]); - } - - google::ParseCommandLineFlags(&argc, &argva, true); - - // Parse may have deleted flags - so widen again. - int argcw = argc; - wchar_t** argvw = (wchar_t**)alloca(sizeof(wchar_t*) * argca); - for (int n = 0; n < argc; n++) { - size_t len = xestrlena(argva[n]); - argvw[n] = (wchar_t*)alloca(sizeof(wchar_t) * (len + 1)); - xestrwiden(argvw[n], len + 1, argva[n]); - } - - int result = ((user_main_t)user_main)(argcw, (xechar_t**)argvw); - google::ShutDownCommandLineFlags(); - return result; -} - -bool xe_has_console() { - return _has_console; -} - -void xe_attach_console() { - bool has_console = AttachConsole(ATTACH_PARENT_PROCESS) == TRUE; - if (!has_console) { - // We weren't launched from a console, so just return. - // We could alloc our own console, but meh: - // has_console = AllocConsole() == TRUE; - _has_console = false; - return; - } - _has_console = true; - - auto std_handle = (intptr_t)GetStdHandle(STD_OUTPUT_HANDLE); - auto con_handle = _open_osfhandle(std_handle, _O_TEXT); - auto fp = _fdopen(con_handle, "w"); - *stdout = *fp; - setvbuf(stdout, NULL, _IONBF, 0); - - std_handle = (intptr_t)GetStdHandle(STD_ERROR_HANDLE); - con_handle = _open_osfhandle(std_handle, _O_TEXT); - fp = _fdopen(con_handle, "w"); - *stderr = *fp; - setvbuf(stderr, NULL, _IONBF, 0); -} - -int xe_main_window_thunk( - wchar_t* command_line, - void* user_main, const wchar_t* name, const char* usage) { - xe_attach_console(); - wchar_t buffer[2048]; - xestrcpy(buffer, XECOUNT(buffer), name); - xestrcat(buffer, XECOUNT(buffer), L" "); - xestrcat(buffer, XECOUNT(buffer), command_line); - int argc; - wchar_t** argv = CommandLineToArgvW(buffer, &argc); - if (!argv) { - return 1; - } - int result = xe_main_thunk(argc, argv, user_main, usage); - LocalFree(argv); - return result; -} - -#else - -bool xe_has_console() { - return _has_console; -} - -int xe_main_thunk( - int argc, char** argv, - void* user_main, const char* usage) { - google::SetUsageMessage(std::string("usage: ") + usage); - google::SetVersionString("1.0"); - google::ParseCommandLineFlags(&argc, &argv, true); - int result = ((user_main_t)user_main)(argc, argv); - google::ShutDownCommandLineFlags(); - return result; -} - -#endif // WIN32 diff --git a/src/xenia/platform.h b/src/xenia/platform.h deleted file mode 100644 index 060b992e5..000000000 --- a/src/xenia/platform.h +++ /dev/null @@ -1,44 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_PLATFORM_H_ -#define XENIA_PLATFORM_H_ - -#include - -bool xe_has_console(); -#if XE_LIKE_WIN32 && defined(UNICODE) && UNICODE -int xe_main_thunk( - int argc, wchar_t* argv[], - void* user_main, const char* usage); -#define XE_MAIN_THUNK(NAME, USAGE) \ - int wmain(int argc, wchar_t *argv[]) { \ - return xe_main_thunk(argc, argv, NAME, USAGE); \ - } -int xe_main_window_thunk( - wchar_t* command_line, - void* user_main, const wchar_t* name, const char* usage); -#define XE_MAIN_WINDOW_THUNK(NAME, APP_NAME, USAGE) \ - int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPTSTR command_line, int) { \ - return xe_main_window_thunk(command_line, NAME, APP_NAME, USAGE); \ - } -#else -int xe_main_thunk( - int argc, char** argv, - void* user_main, const char* usage); -#define XE_MAIN_THUNK(NAME, USAGE) \ - int main(int argc, char **argv) { \ - return xe_main_thunk(argc, argv, (void*)NAME, USAGE); \ - } -#define XE_MAIN_WINDOW_THUNK(NAME, APP_NAME, USAGE) \ - XE_MAIN_THUNK(NAME, USAGE) -#endif // WIN32 - - -#endif // XENIA_PLATFORM_H_ diff --git a/src/xenia/profiling.h b/src/xenia/profiling.h index 3747bbd9b..03ebdf720 100644 --- a/src/xenia/profiling.h +++ b/src/xenia/profiling.h @@ -13,7 +13,6 @@ #include #include -#include #include #include diff --git a/src/xenia/sources.gypi b/src/xenia/sources.gypi index 88a621e58..9eaf39280 100644 --- a/src/xenia/sources.gypi +++ b/src/xenia/sources.gypi @@ -14,8 +14,6 @@ 'logging.h', 'malloc.cc', 'malloc.h', - 'platform.cc', - 'platform.h', 'profiling.cc', 'profiling.h', 'string.h', diff --git a/src/xenia/string.h b/src/xenia/string.h index 0f6b9be2c..076fded47 100644 --- a/src/xenia/string.h +++ b/src/xenia/string.h @@ -10,7 +10,6 @@ #ifndef XENIA_STRING_H_ #define XENIA_STRING_H_ -#include #include // NOTE: these differing implementations should behave pretty much the same. @@ -23,39 +22,25 @@ int strncpy_s(char* dest, size_t destLength, const char* source, size_t count); #define _snprintf_s(dest, destLength, x, format, ...) snprintf(dest, destLength, format, ##__VA_ARGS__) #endif // !WIN32 -#define xestrlenw wcslen -#define xestrchrw wcschr #define xestrcpyw(dest, destLength, source) (wcscpy_s(dest, destLength, source) == 0) -#define xestrcatw(dest, destLength, source) (wcscat_s(dest, destLength, source) == 0) #define xesnprintfw(buffer, bufferCount, format, ...) _snwprintf_s(buffer, bufferCount, (bufferCount) ? (bufferCount - 1) : 0, format, ##__VA_ARGS__) #define xestrlena strlen -#define xestrchra strchr -#define xestrrchra strrchr #define xestrcpya(dest, destLength, source) (strcpy_s(dest, destLength, source) == 0) #define xestrncpya(dest, destLength, source, count) (strncpy_s(dest, destLength, source, count) == 0) -#define xestrcata(dest, destLength, source) (strcat_s(dest, destLength, source) == 0) #define xesnprintfa(buffer, bufferCount, format, ...) _snprintf_s(buffer, bufferCount, bufferCount, format, ##__VA_ARGS__) #define xevsnprintfa(buffer, bufferCount, format, args) vsnprintf(buffer, bufferCount, format, args) #if XE_PLATFORM_WIN32 && defined(UNICODE) && UNICODE typedef wchar_t xechar_t; -#define XE_WCHAR 1 -// xestrchr 2 uses in fs -// xestrrchra xmodule/logging // xestrcpy fs + module // xestrncpya one use in xbox.h -// xestrcat 2 uses in platform // xesnprintf many uses - only remove some? -// xevsnprintf logging, disasm #define xestrcpy xestrcpyw -#define xestrcat xestrcatw #define xesnprintf xesnprintfw -#define xestrnarrow(dest, destLength, source) (wcstombs_s(NULL, dest, destLength, source, _TRUNCATE) == 0) -#define xestrwiden(dest, destLength, source) (mbstowcs_s(NULL, dest, destLength, source, _TRUNCATE) == 0) #else @@ -63,10 +48,7 @@ typedef char xechar_t; #define XE_CHAR 1 #define xestrcpy xestrcpya -#define xestrcat xestrcata #define xesnprintf xesnprintfa -#define xestrnarrow(dest, destLength, source) xestrcpy(dest, destLength, source) -#define xestrwiden(dest, destLength, source) xestrcpy(dest, destLength, source) #endif // WIN32 diff --git a/src/xenia/types.h b/src/xenia/types.h index 59a07c8da..972cad6c7 100644 --- a/src/xenia/types.h +++ b/src/xenia/types.h @@ -13,7 +13,7 @@ #include #include -#include +#include #define XE_EMPTY_MACRO do { } while(0) diff --git a/tools/alloy-sandbox/alloy-sandbox.cc b/tools/alloy-sandbox/alloy-sandbox.cc index 162721ddb..508ede3c9 100644 --- a/tools/alloy-sandbox/alloy-sandbox.cc +++ b/tools/alloy-sandbox/alloy-sandbox.cc @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -75,7 +76,7 @@ class ThreadState : public alloy::runtime::ThreadState { // TODO(benvanik): simple memory? move more into core? -int main(int argc, xechar_t** argv) { +int main(std::vector& args) { xe::Profiler::Initialize(); xe::Profiler::ThreadEnter("main"); @@ -122,7 +123,4 @@ int main(int argc, xechar_t** argv) { } // namespace sandbox } // namespace alloy -// TODO(benvanik): move main thunk into poly -// ehhh -#include -XE_MAIN_THUNK(alloy::sandbox::main, "alloy-sandbox"); +DEFINE_ENTRY_POINT(L"alloy-sandbox", L"?", alloy::sandbox::main); diff --git a/tools/alloy-sandbox/alloy-sandbox.gypi b/tools/alloy-sandbox/alloy-sandbox.gypi index 4c824dce8..7988e708f 100644 --- a/tools/alloy-sandbox/alloy-sandbox.gypi +++ b/tools/alloy-sandbox/alloy-sandbox.gypi @@ -5,6 +5,12 @@ 'target_name': 'alloy-sandbox', 'type': 'executable', + 'msvs_settings': { + 'VCLinkerTool': { + 'SubSystem': '1' + }, + }, + 'dependencies': [ 'alloy', 'xenia', diff --git a/tools/xenia-compare/xenia-compare.cc b/tools/xenia-compare/xenia-compare.cc index 7fb6c9488..e5f338d48 100644 --- a/tools/xenia-compare/xenia-compare.cc +++ b/tools/xenia-compare/xenia-compare.cc @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -21,7 +22,7 @@ namespace xc { using xdb::PostmortemDebugTarget; -int main(int argc, xechar_t** argv) { +int main(std::vector& args) { // Create platform abstraction layer. xe_pal_options_t pal_options; xe_zero_struct(&pal_options, sizeof(pal_options)); @@ -46,6 +47,4 @@ int main(int argc, xechar_t** argv) { } // namespace xc -// TODO(benvanik): move main thunk into poly -// ehhh -XE_MAIN_WINDOW_THUNK(xc::main, L"xenia-compare", "xenia-compare"); +DEFINE_ENTRY_POINT(L"xenia-compare", L"xenia-compare", xc::main); diff --git a/tools/xenia-compare/xenia-compare.gypi b/tools/xenia-compare/xenia-compare.gypi index 2b43a2883..1a75f3f34 100644 --- a/tools/xenia-compare/xenia-compare.gypi +++ b/tools/xenia-compare/xenia-compare.gypi @@ -7,8 +7,8 @@ 'msvs_settings': { 'VCLinkerTool': { - 'SubSystem': '2' - } + 'SubSystem': '1' + }, }, 'dependencies': [ diff --git a/tools/xenia-debug/xenia-debug.cc b/tools/xenia-debug/xenia-debug.cc index 05f0bf846..f16e2401f 100644 --- a/tools/xenia-debug/xenia-debug.cc +++ b/tools/xenia-debug/xenia-debug.cc @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -22,7 +23,7 @@ DEFINE_string(content_file, "", namespace xdb { -int main(int argc, xechar_t** argv) { +int main(std::vector& args) { // Create platform abstraction layer. xe_pal_options_t pal_options; xe_zero_struct(&pal_options, sizeof(pal_options)); @@ -67,6 +68,4 @@ int main(int argc, xechar_t** argv) { } // namespace xdb -// TODO(benvanik): move main thunk into poly -// ehhh -XE_MAIN_WINDOW_THUNK(xdb::main, L"xenia-debug", "xenia-debug"); +DEFINE_ENTRY_POINT(L"xenia-debug", L"xenia-debug", xdb::main); diff --git a/tools/xenia-debug/xenia-debug.gypi b/tools/xenia-debug/xenia-debug.gypi index 14ef1c990..412439497 100644 --- a/tools/xenia-debug/xenia-debug.gypi +++ b/tools/xenia-debug/xenia-debug.gypi @@ -8,7 +8,7 @@ 'msvs_settings': { 'VCLinkerTool': { 'SubSystem': '2' - } + }, }, 'dependencies': [ diff --git a/tools/xenia-run/xenia-run.cc b/tools/xenia-run/xenia-run.cc index fed8c3ae7..51a6dcb3f 100644 --- a/tools/xenia-run/xenia-run.cc +++ b/tools/xenia-run/xenia-run.cc @@ -10,16 +10,13 @@ #include #include - +#include using namespace xe; +DEFINE_string(target, "", "Specifies the target .xex or .iso to execute."); -DEFINE_string(target, "", - "Specifies the target .xex or .iso to execute."); - - -int xenia_run(int argc, xechar_t** argv) { +int xenia_run(std::vector& args) { int result_code = 1; Profiler::Initialize(); @@ -28,33 +25,28 @@ int xenia_run(int argc, xechar_t** argv) { Emulator* emulator = NULL; // Grab path from the flag or unnamed argument. - if (!FLAGS_target.size() && argc < 2) { + if (!FLAGS_target.size() && args.size() < 2) { google::ShowUsageWithFlags("xenia-run"); XEFATAL("Pass a file to launch."); return 1; } - const xechar_t* path = NULL; + std::wstring path; if (FLAGS_target.size()) { // Passed as a named argument. // TODO(benvanik): find something better than gflags that supports unicode. - xechar_t buffer[poly::max_path]; - XEIGNORE(xestrwiden(buffer, sizeof(buffer), FLAGS_target.c_str())); - path = buffer; + path = poly::to_wstring(FLAGS_target); } else { // Passed as an unnamed argument. - path = argv[1]; + path = args[1]; } + // Normalize the path and make absolute. + std::wstring abs_path = poly::to_absolute_path(path); // Create platform abstraction layer. xe_pal_options_t pal_options; xe_zero_struct(&pal_options, sizeof(pal_options)); XEEXPECTZERO(xe_pal_init(pal_options)); - // Normalize the path and make absolute. - // TODO(benvanik): move this someplace common. - xechar_t abs_path[poly::max_path]; - xe_path_get_absolute(path, abs_path, XECOUNT(abs_path)); - // Create the emulator. emulator = new Emulator(L""); XEEXPECTNOTNULL(emulator); @@ -93,4 +85,5 @@ XECLEANUP: Profiler::Shutdown(); return result_code; } -XE_MAIN_WINDOW_THUNK(xenia_run, L"xenia-run", "xenia-run some.xex"); + +DEFINE_ENTRY_POINT(L"xenia-run", L"xenia-run some.xex", xenia_run); diff --git a/tools/xenia-run/xenia-run.gypi b/tools/xenia-run/xenia-run.gypi index 150cb062f..2d2702ac7 100644 --- a/tools/xenia-run/xenia-run.gypi +++ b/tools/xenia-run/xenia-run.gypi @@ -8,7 +8,7 @@ 'msvs_settings': { 'VCLinkerTool': { 'SubSystem': '2' - } + }, }, 'dependencies': [ diff --git a/tools/xenia-test/xenia-test.cc b/tools/xenia-test/xenia-test.cc index 302b68384..955cc2eda 100644 --- a/tools/xenia-test/xenia-test.cc +++ b/tools/xenia-test/xenia-test.cc @@ -14,6 +14,8 @@ #endif // !WIN32 #include +#include + using namespace std; using namespace xe; @@ -273,7 +275,7 @@ int xenia_test(int argc, xechar_t **argv) { if (argc >= 2) { test_name = argv[1]; } - + string test_name_str; if (test_name) { #if XE_WCHAR @@ -290,4 +292,5 @@ int xenia_test(int argc, xechar_t **argv) { return result_code; } -XE_MAIN_THUNK(xenia_test, "xenia-test some.xex"); + +DEFINE_ENTRY_POINT(L"xenia-test", L"xenia-test some.xex", xenia_test); diff --git a/tools/xenia-test/xenia-test.gypi b/tools/xenia-test/xenia-test.gypi index c682fbc74..60ae68dff 100644 --- a/tools/xenia-test/xenia-test.gypi +++ b/tools/xenia-test/xenia-test.gypi @@ -5,6 +5,12 @@ 'target_name': 'xenia-test', 'type': 'executable', + 'msvs_settings': { + 'VCLinkerTool': { + 'SubSystem': '1', + }, + }, + 'dependencies': [ 'xenia', ], diff --git a/xenia.gyp b/xenia.gyp index 736900825..e98acf017 100644 --- a/xenia.gyp +++ b/xenia.gyp @@ -98,6 +98,7 @@ 'AdditionalLibraryDirectories': [ '..\\..\\third_party\\wxWidgets\\lib\\vc_x64_lib\\', ], + 'EntryPointSymbol': 'wWinMainCRTStartup', }, }, From ead74f2cdb19678027d9b2b0526ddaa085f890d9 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 16 Aug 2014 16:46:20 -0700 Subject: [PATCH 120/388] More string switching. --- src/xenia/emulator.cc | 23 +++++++++++-------- src/xenia/emulator.h | 6 ++--- src/xenia/gpu/d3d11/d3d11_geometry_shader.cc | 2 +- src/xenia/gpu/d3d11/d3d11_profiler_display.cc | 4 ++-- src/xenia/gpu/d3d11/d3d11_shader_resource.cc | 2 +- .../kernel/fs/devices/disc_image_entry.cc | 9 ++++---- .../kernel/fs/devices/stfs_container_entry.cc | 9 ++++---- src/xenia/kernel/xboxkrnl_rtl.cc | 8 ++++--- src/xenia/string.h | 8 ------- src/xenia/xbox.h | 4 ++-- 10 files changed, 35 insertions(+), 40 deletions(-) diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index fc054e6fc..6eedbf4a1 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -32,16 +32,19 @@ using namespace xe::kernel; using namespace xe::kernel::fs; using namespace xe::ui; - -Emulator::Emulator(const xechar_t* command_line) : - main_window_(0), - memory_(0), - processor_(0), - audio_system_(0), graphics_system_(0), input_system_(0), - export_resolver_(0), file_system_(0), - kernel_state_(0), xam_(0), xboxkrnl_(0) { - XEIGNORE(xestrcpy(command_line_, XECOUNT(command_line_), command_line)); -} +Emulator::Emulator(const std::wstring& command_line) + : command_line_(command_line), + main_window_(0), + memory_(0), + processor_(0), + audio_system_(0), + graphics_system_(0), + input_system_(0), + export_resolver_(0), + file_system_(0), + kernel_state_(0), + xam_(0), + xboxkrnl_(0) {} Emulator::~Emulator() { // Note that we delete things in the reverse order they were initialized. diff --git a/src/xenia/emulator.h b/src/xenia/emulator.h index 23d24bf37..0c05d3d0b 100644 --- a/src/xenia/emulator.h +++ b/src/xenia/emulator.h @@ -35,10 +35,10 @@ namespace xe { class Emulator { public: - Emulator(const xechar_t* command_line); + Emulator(const std::wstring& command_line); ~Emulator(); - const xechar_t* command_line() const { return command_line_; } + const std::wstring& command_line() const { return command_line_; } ui::Window* main_window() const { return main_window_; } void set_main_window(ui::Window* window); @@ -69,7 +69,7 @@ class Emulator { X_STATUS CompleteLaunch(const std::wstring& path, const std::string& module_path); - xechar_t command_line_[poly::max_path]; + std::wstring command_line_; ui::Window* main_window_; diff --git a/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc b/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc index 071395b7e..0ab44c282 100644 --- a/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc +++ b/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc @@ -95,7 +95,7 @@ ID3D10Blob* D3D11GeometryShader::Compile(const char* shader_source) { if (FLAGS_dump_shaders.size()) { base_path = FLAGS_dump_shaders.c_str(); } - uint64_t hash = xe_hash64(shader_source, xestrlena(shader_source)); // ? + uint64_t hash = xe_hash64(shader_source, strlen(shader_source)); // ? char file_name[poly::max_path]; xesnprintfa(file_name, XECOUNT(file_name), "%s/gen_%.16llX.gs", diff --git a/src/xenia/gpu/d3d11/d3d11_profiler_display.cc b/src/xenia/gpu/d3d11/d3d11_profiler_display.cc index 8bcefd0e7..bf9774730 100644 --- a/src/xenia/gpu/d3d11/d3d11_profiler_display.cc +++ b/src/xenia/gpu/d3d11/d3d11_profiler_display.cc @@ -203,7 +203,7 @@ bool D3D11ProfilerDisplay::SetupShaders() { ID3DBlob* vs_code_blob = nullptr; ID3DBlob* vs_errors = nullptr; hr = D3DCompile( - shader_code, xestrlena(shader_code), + shader_code, strlen(shader_code), "D3D11ProfilerDisplay.vs", nullptr, nullptr, @@ -229,7 +229,7 @@ bool D3D11ProfilerDisplay::SetupShaders() { ID3DBlob* ps_code_blob = nullptr; ID3DBlob* ps_errors = nullptr; hr = D3DCompile( - shader_code, xestrlena(shader_code), + shader_code, strlen(shader_code), "D3D11ProfilerDisplay.ps", nullptr, nullptr, diff --git a/src/xenia/gpu/d3d11/d3d11_shader_resource.cc b/src/xenia/gpu/d3d11/d3d11_shader_resource.cc index 7fc40905f..f32e3f714 100644 --- a/src/xenia/gpu/d3d11/d3d11_shader_resource.cc +++ b/src/xenia/gpu/d3d11/d3d11_shader_resource.cc @@ -46,7 +46,7 @@ ID3D10Blob* D3D11ShaderCompile(XE_GPU_SHADER_TYPE type, if (FLAGS_dump_shaders.size()) { base_path = FLAGS_dump_shaders.c_str(); } - size_t hash = xe_hash64(disasm_source, xestrlena(disasm_source)); // ? + size_t hash = xe_hash64(disasm_source, strlen(disasm_source)); // ? char file_name[poly::max_path]; xesnprintfa(file_name, XECOUNT(file_name), "%s/gen_%.16llX.%s", diff --git a/src/xenia/kernel/fs/devices/disc_image_entry.cc b/src/xenia/kernel/fs/devices/disc_image_entry.cc index a11f98088..4bde7943f 100644 --- a/src/xenia/kernel/fs/devices/disc_image_entry.cc +++ b/src/xenia/kernel/fs/devices/disc_image_entry.cc @@ -87,10 +87,9 @@ X_STATUS DiscImageEntry::QueryDirectory( auto end = (uint8_t*)out_info + length; auto entry = *gdfx_entry_iterator_; - auto entry_name = entry->name.c_str(); - size_t entry_name_length = xestrlena(entry_name); + auto entry_name = entry->name; - if (((uint8_t*)&out_info->file_name[0]) + entry_name_length > end) { + if (((uint8_t*)&out_info->file_name[0]) + entry_name.size() > end) { gdfx_entry_iterator_ = gdfx_entry_->children.end(); return X_STATUS_UNSUCCESSFUL; } @@ -104,8 +103,8 @@ X_STATUS DiscImageEntry::QueryDirectory( out_info->end_of_file = entry->size; out_info->allocation_size = 2048; out_info->attributes = (X_FILE_ATTRIBUTES)entry->attributes; - out_info->file_name_length = (uint32_t)entry_name_length; - memcpy(out_info->file_name, entry_name, entry_name_length); + out_info->file_name_length = static_cast(entry_name.size()); + memcpy(out_info->file_name, entry_name.c_str(), entry_name.size()); return X_STATUS_SUCCESS; } diff --git a/src/xenia/kernel/fs/devices/stfs_container_entry.cc b/src/xenia/kernel/fs/devices/stfs_container_entry.cc index 318b11bf7..1af716c67 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_entry.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_entry.cc @@ -66,10 +66,9 @@ X_STATUS STFSContainerEntry::QueryDirectory( auto end = (uint8_t*)out_info + length; auto entry = *stfs_entry_iterator_; - auto entry_name = entry->name.c_str(); - size_t entry_name_length = xestrlena(entry_name); + auto entry_name = entry->name; - if (((uint8_t*)&out_info->file_name[0]) + entry_name_length > end) { + if (((uint8_t*)&out_info->file_name[0]) + entry_name.size() > end) { stfs_entry_iterator_ = stfs_entry_->children.end(); return X_STATUS_UNSUCCESSFUL; } @@ -82,8 +81,8 @@ X_STATUS STFSContainerEntry::QueryDirectory( out_info->end_of_file = entry->size; out_info->allocation_size = 4096; out_info->attributes = entry->attributes; - out_info->file_name_length = (uint32_t)entry_name_length; - memcpy(out_info->file_name, entry_name, entry_name_length); + out_info->file_name_length = static_cast(entry_name.size()); + memcpy(out_info->file_name, entry_name.c_str(), entry_name.size()); return X_STATUS_SUCCESS; } diff --git a/src/xenia/kernel/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl_rtl.cc index b08b0bcf7..d2f67949a 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl_rtl.cc @@ -153,7 +153,7 @@ SHIM_CALL RtlInitAnsiString_shim( if (source_ptr != 0) { const char* source = (char*)SHIM_MEM_ADDR(source_ptr); - uint16_t length = (uint16_t)xestrlena(source); + uint16_t length = (uint16_t)strlen(source); SHIM_SET_MEM_16(destination_ptr + 0, length); SHIM_SET_MEM_16(destination_ptr + 2, length + 1); } else { @@ -211,8 +211,10 @@ SHIM_CALL RtlInitUnicodeString_shim( // _In_opt_ PCWSTR SourceString if (source.size()) { - SHIM_SET_MEM_16(destination_ptr + 0, source.size() * 2); - SHIM_SET_MEM_16(destination_ptr + 2, (source.size() + 1) * 2); + SHIM_SET_MEM_16(destination_ptr + 0, + static_cast(source.size() * 2)); + SHIM_SET_MEM_16(destination_ptr + 2, + static_cast((source.size() + 1) * 2)); SHIM_SET_MEM_32(destination_ptr + 4, source_ptr); } else { SHIM_SET_MEM_16(destination_ptr + 0, 0); diff --git a/src/xenia/string.h b/src/xenia/string.h index 076fded47..2a166ad78 100644 --- a/src/xenia/string.h +++ b/src/xenia/string.h @@ -18,16 +18,12 @@ #if !XE_LIKE_WIN32 int strncpy_s(char* dest, size_t destLength, const char* source, size_t count); #define strcpy_s(dest, destLength, source) !(strcpy(dest, source) == dest + (destLength*0)) -#define strcat_s(dest, destLength, source) !(strcat(dest, source) == dest + (destLength*0)) #define _snprintf_s(dest, destLength, x, format, ...) snprintf(dest, destLength, format, ##__VA_ARGS__) #endif // !WIN32 -#define xestrcpyw(dest, destLength, source) (wcscpy_s(dest, destLength, source) == 0) #define xesnprintfw(buffer, bufferCount, format, ...) _snwprintf_s(buffer, bufferCount, (bufferCount) ? (bufferCount - 1) : 0, format, ##__VA_ARGS__) -#define xestrlena strlen #define xestrcpya(dest, destLength, source) (strcpy_s(dest, destLength, source) == 0) -#define xestrncpya(dest, destLength, source, count) (strncpy_s(dest, destLength, source, count) == 0) #define xesnprintfa(buffer, bufferCount, format, ...) _snprintf_s(buffer, bufferCount, bufferCount, format, ##__VA_ARGS__) #define xevsnprintfa(buffer, bufferCount, format, args) vsnprintf(buffer, bufferCount, format, args) @@ -36,18 +32,14 @@ int strncpy_s(char* dest, size_t destLength, const char* source, size_t count); typedef wchar_t xechar_t; // xestrcpy fs + module -// xestrncpya one use in xbox.h // xesnprintf many uses - only remove some? -#define xestrcpy xestrcpyw #define xesnprintf xesnprintfw #else typedef char xechar_t; -#define XE_CHAR 1 -#define xestrcpy xestrcpya #define xesnprintf xesnprintfa #endif // WIN32 diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index b3ca8dd24..8bb0c600c 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -272,8 +272,8 @@ public: if (buffer == NULL || length == 0) { return NULL; } - auto copy = (char*)xe_calloc(length+1); - xestrncpya(copy, length+1, buffer, length); + auto copy = (char*)xe_calloc(length + 1); + std::strncpy(copy, buffer, length); return copy; } }; From 54ce9db7433d7c493f782468b2a422969bb9dd1c Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 16 Aug 2014 16:57:00 -0700 Subject: [PATCH 121/388] Starting to remove some macros. --- src/alloy/frontend/ppc/ppc_scanner.cc | 13 +++--- src/alloy/string_buffer.cc | 2 +- src/xenia/core/pal_win.cc | 7 ++-- src/xenia/core/socket_win.cc | 2 +- src/xenia/cpu/xenon_memory.cc | 11 +++-- src/xenia/cpu/xex_module.cc | 8 +++- src/xenia/export_resolver.cc | 2 +- src/xenia/gpu/command_processor.cc | 7 +++- src/xenia/gpu/d3d11/d3d11_profiler_display.cc | 6 ++- .../gpu/d3d11/d3d11_shader_translator.cc | 4 +- .../kernel/fs/devices/disc_image_device.cc | 6 +-- .../kernel/fs/devices/disc_image_entry.cc | 4 +- .../kernel/fs/devices/disc_image_file.cc | 7 ++-- .../fs/devices/stfs_container_device.cc | 6 +-- .../kernel/fs/devices/stfs_container_file.cc | 17 ++++---- src/xenia/kernel/fs/stfs.cc | 3 +- src/xenia/kernel/object_table.cc | 7 ++-- src/xenia/kernel/util/xex2.cc | 12 +++--- src/xenia/logging.cc | 4 +- src/xenia/types.h | 41 ------------------- src/xenia/ui/win32/win32_window.cc | 2 +- 21 files changed, 74 insertions(+), 97 deletions(-) diff --git a/src/alloy/frontend/ppc/ppc_scanner.cc b/src/alloy/frontend/ppc/ppc_scanner.cc index f23d10623..e27827792 100644 --- a/src/alloy/frontend/ppc/ppc_scanner.cc +++ b/src/alloy/frontend/ppc/ppc_scanner.cc @@ -9,6 +9,7 @@ #include +#include #include #include @@ -49,10 +50,10 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { XELOGSDB("Analyzing function %.8X...", symbol_info->address()); - uint64_t start_address = symbol_info->address(); - uint64_t end_address = symbol_info->end_address(); - uint64_t address = start_address; - uint64_t furthest_target = start_address; + uint32_t start_address = symbol_info->address(); + uint32_t end_address = symbol_info->end_address(); + uint32_t address = start_address; + uint32_t furthest_target = start_address; size_t blocks_found = 0; bool in_block = false; bool starts_with_mfspr_lr = false; @@ -191,7 +192,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { */ if (!ends_fn && !IsRestGprLr(target)) { - furthest_target = MAX(furthest_target, target); + furthest_target = std::max(furthest_target, target); // TODO(benvanik): perhaps queue up for a speculative check? I think // we are running over tail-call functions here that branch to @@ -217,7 +218,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { // TODO(benvanik): GetOrInsertFunction? it's likely a BB if (!IsRestGprLr(target)) { - furthest_target = MAX(furthest_target, target); + furthest_target = std::max(furthest_target, target); } } ends_block = true; diff --git a/src/alloy/string_buffer.cc b/src/alloy/string_buffer.cc index f461c92c3..aa9a0897e 100644 --- a/src/alloy/string_buffer.cc +++ b/src/alloy/string_buffer.cc @@ -14,7 +14,7 @@ namespace alloy { StringBuffer::StringBuffer(size_t initial_capacity) { - buffer_.reserve(MAX(initial_capacity, 1024)); + buffer_.reserve(std::max(initial_capacity, 1024ull)); } StringBuffer::~StringBuffer() = default; diff --git a/src/xenia/core/pal_win.cc b/src/xenia/core/pal_win.cc index 5f6498e5b..c0b0a90a3 100644 --- a/src/xenia/core/pal_win.cc +++ b/src/xenia/core/pal_win.cc @@ -9,6 +9,7 @@ #include +#include namespace { typedef struct xe_pal_win { @@ -38,7 +39,7 @@ int xe_pal_init(xe_pal_options_t options) { // Setup COM on the main thread. // NOTE: this may fail if COM has already been initialized - that's OK. - XEIGNORE(CoInitializeEx(NULL, COINIT_MULTITHREADED)); + CoInitializeEx(NULL, COINIT_MULTITHREADED); atexit(xe_pal_dealloc); return 0; @@ -114,9 +115,9 @@ int xe_pal_get_system_info(xe_system_info* out_info) { } out_info->processors.physical_count = - MAX(1, out_info->processors.physical_count); + std::max(1u, out_info->processors.physical_count); out_info->processors.logical_count = - MAX(1, out_info->processors.logical_count); + std::max(1u, out_info->processors.logical_count); result_code = 0; XECLEANUP: diff --git a/src/xenia/core/socket_win.cc b/src/xenia/core/socket_win.cc index 1f2eba015..0adc79f9e 100644 --- a/src/xenia/core/socket_win.cc +++ b/src/xenia/core/socket_win.cc @@ -264,7 +264,7 @@ int xe_socket_loop_poll(xe_socket_loop_t* loop, loop->pending_queued_write = loop->events[1].revents != 0; if (loop->pending_queued_write) { char dummy; - XEIGNORE(recv(loop->notify_rd_id, &dummy, 1, 0)); + recv(loop->notify_rd_id, &dummy, 1, 0); } loop->events[1].revents = 0; loop->events[1].events = POLLIN; diff --git a/src/xenia/cpu/xenon_memory.cc b/src/xenia/cpu/xenon_memory.cc index f7f2fdbfa..eaff6bc95 100644 --- a/src/xenia/cpu/xenon_memory.cc +++ b/src/xenia/cpu/xenon_memory.cc @@ -9,6 +9,7 @@ #include +#include #include #include @@ -482,7 +483,7 @@ XenonMemoryHeap::~XenonMemoryHeap() { } if (ptr_) { - XEIGNORE(VirtualFree(ptr_, 0, MEM_RELEASE)); + VirtualFree(ptr_, 0, MEM_RELEASE); } } @@ -508,13 +509,11 @@ uint64_t XenonMemoryHeap::Alloc( size_t alloc_size = size; size_t heap_guard_size = FLAGS_heap_guard_pages * 4096; if (heap_guard_size) { - alignment = (uint32_t)MAX(alignment, heap_guard_size); + alignment = std::max(alignment, static_cast(heap_guard_size)); alloc_size = (uint32_t)XEROUNDUP(size, heap_guard_size); } - uint8_t* p = (uint8_t*)mspace_memalign( - space_, - alignment, - alloc_size + heap_guard_size * 2); + uint8_t* p = (uint8_t*)mspace_memalign(space_, alignment, + alloc_size + heap_guard_size * 2); assert_true(reinterpret_cast(p) <= 0xFFFFFFFFFull); if (FLAGS_heap_guard_pages) { size_t real_size = mspace_usable_size(p); diff --git a/src/xenia/cpu/xex_module.cc b/src/xenia/cpu/xex_module.cc index 61796c952..d2c0b0957 100644 --- a/src/xenia/cpu/xex_module.cc +++ b/src/xenia/cpu/xex_module.cc @@ -9,6 +9,8 @@ #include +#include + #include #include #include @@ -54,8 +56,10 @@ int XexModule::Load(const std::string& name, const std::string& path, xe_xex2_re const size_t end_address = start_address + (section->info.page_count * xe_xex2_section_length); if (section->info.type == XEX_SECTION_CODE) { - low_address_ = (uint32_t)MIN(low_address_, start_address); - high_address_ = (uint32_t)MAX(high_address_, end_address); + low_address_ = + static_cast(std::min(low_address_, start_address)); + high_address_ = + static_cast(std::max(high_address_, end_address)); } i += section->info.page_count; } diff --git a/src/xenia/export_resolver.cc b/src/xenia/export_resolver.cc index 19a29cce1..ae7204f80 100644 --- a/src/xenia/export_resolver.cc +++ b/src/xenia/export_resolver.cc @@ -22,7 +22,7 @@ ExportResolver::~ExportResolver() { void ExportResolver::RegisterTable( const char* library_name, KernelExport* exports, const size_t count) { ExportTable table; - XEIGNORE(xestrcpya(table.name, XECOUNT(table.name), library_name)); + xestrcpya(table.name, XECOUNT(table.name), library_name); table.exports = exports; table.count = count; tables_.push_back(table); diff --git a/src/xenia/gpu/command_processor.cc b/src/xenia/gpu/command_processor.cc index 081b315a7..8e891f3ca 100644 --- a/src/xenia/gpu/command_processor.cc +++ b/src/xenia/gpu/command_processor.cc @@ -9,6 +9,8 @@ #include +#include + #include #include #include @@ -79,8 +81,9 @@ void CommandProcessor::EnableReadPointerWriteBack(uint32_t ptr, } void CommandProcessor::UpdateWritePointer(uint32_t value) { - write_ptr_max_index_ = MAX(write_ptr_max_index_, value); - write_ptr_index_ = value; + write_ptr_max_index_ = + std::max(static_cast(write_ptr_max_index_), value); + write_ptr_index_ = value; SetEvent(write_ptr_index_event_); } diff --git a/src/xenia/gpu/d3d11/d3d11_profiler_display.cc b/src/xenia/gpu/d3d11/d3d11_profiler_display.cc index bf9774730..3fed309e0 100644 --- a/src/xenia/gpu/d3d11/d3d11_profiler_display.cc +++ b/src/xenia/gpu/d3d11/d3d11_profiler_display.cc @@ -9,6 +9,8 @@ #include +#include + #include #include @@ -548,8 +550,8 @@ void D3D11ProfilerDisplay::DrawBox( uint32_t r = 0xFF & (color >> 16); uint32_t g = 0xFF & (color >> 8); uint32_t b = 0xFF & color; - uint32_t max_c = MAX(MAX(MAX(r, g), b), 30u); - uint32_t min_c = MIN(MIN(MIN(r, g), b), 180u); + uint32_t max_c = std::max(std::max(std::max(r, g), b), 30u); + uint32_t min_c = std::min(std::min(std::min(r, g), b), 180u); uint32_t r0 = 0xFF & ((r + max_c)/2); uint32_t g0 = 0xFF & ((g + max_c)/2); uint32_t b0 = 0xFF & ((b + max_c)/2); diff --git a/src/xenia/gpu/d3d11/d3d11_shader_translator.cc b/src/xenia/gpu/d3d11/d3d11_shader_translator.cc index 1d7c74940..92a3d856d 100644 --- a/src/xenia/gpu/d3d11/d3d11_shader_translator.cc +++ b/src/xenia/gpu/d3d11/d3d11_shader_translator.cc @@ -9,6 +9,8 @@ #include +#include + #include #include #include @@ -282,7 +284,7 @@ int D3D11ShaderTranslator::TranslatePixelShader( // Add temporary registers. uint32_t temp_regs = program_cntl.vs_regs + program_cntl.ps_regs; - for (uint32_t n = 0; n <= MAX(15, temp_regs); n++) { + for (uint32_t n = 0; n <= std::max(15u, temp_regs); n++) { append( " float4 r%d = c[%d];\n", n, n + 256); } diff --git a/src/xenia/kernel/fs/devices/disc_image_device.cc b/src/xenia/kernel/fs/devices/disc_image_device.cc index 584fe6e21..e7bfda041 100644 --- a/src/xenia/kernel/fs/devices/disc_image_device.cc +++ b/src/xenia/kernel/fs/devices/disc_image_device.cc @@ -57,12 +57,12 @@ Entry* DiscImageDevice::ResolvePath(const char* path) { // Walk the path, one separator at a time. // We copy it into the buffer and shift it left over and over. char remaining[poly::max_path]; - XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), path)); + xestrcpya(remaining, XECOUNT(remaining), path); while (remaining[0]) { char* next_slash = strchr(remaining, '\\'); if (next_slash == remaining) { // Leading slash - shift - XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), remaining + 1)); + xestrcpya(remaining, XECOUNT(remaining), remaining + 1); continue; } @@ -82,7 +82,7 @@ Entry* DiscImageDevice::ResolvePath(const char* path) { if (!next_slash) { break; } - XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), next_slash + 1)); + xestrcpya(remaining, XECOUNT(remaining), next_slash + 1); } Entry::Type type = gdfx_entry->attributes & X_FILE_ATTRIBUTE_DIRECTORY ? diff --git a/src/xenia/kernel/fs/devices/disc_image_entry.cc b/src/xenia/kernel/fs/devices/disc_image_entry.cc index 4bde7943f..8b4886975 100644 --- a/src/xenia/kernel/fs/devices/disc_image_entry.cc +++ b/src/xenia/kernel/fs/devices/disc_image_entry.cc @@ -9,6 +9,8 @@ #include +#include + #include #include @@ -118,7 +120,7 @@ MemoryMapping* DiscImageEntry::CreateMemoryMapping( size_t real_offset = gdfx_entry_->offset + offset; size_t real_length = length ? - MIN(length, gdfx_entry_->size) : gdfx_entry_->size; + std::min(length, gdfx_entry_->size) : gdfx_entry_->size; return new DiscImageMemoryMapping( xe_mmap_get_addr(mmap_) + real_offset, real_length, diff --git a/src/xenia/kernel/fs/devices/disc_image_file.cc b/src/xenia/kernel/fs/devices/disc_image_file.cc index 3f78efd5b..c0f0d114a 100644 --- a/src/xenia/kernel/fs/devices/disc_image_file.cc +++ b/src/xenia/kernel/fs/devices/disc_image_file.cc @@ -9,10 +9,11 @@ #include -#include -#include +#include #include +#include +#include using namespace xe; using namespace xe::kernel; @@ -67,7 +68,7 @@ X_STATUS DiscImageFile::ReadSync( return X_STATUS_END_OF_FILE; } size_t real_offset = gdfx_entry->offset + byte_offset; - size_t real_length = MIN(buffer_length, gdfx_entry->size - byte_offset); + size_t real_length = std::min(buffer_length, gdfx_entry->size - byte_offset); xe_copy_memory( buffer, buffer_length, xe_mmap_get_addr(mmap) + real_offset, real_length); diff --git a/src/xenia/kernel/fs/devices/stfs_container_device.cc b/src/xenia/kernel/fs/devices/stfs_container_device.cc index dd35202dc..a0f176df2 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_device.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_device.cc @@ -57,12 +57,12 @@ Entry* STFSContainerDevice::ResolvePath(const char* path) { // Walk the path, one separator at a time. // We copy it into the buffer and shift it left over and over. char remaining[poly::max_path]; - XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), path)); + xestrcpya(remaining, XECOUNT(remaining), path); while (remaining[0]) { char* next_slash = strchr(remaining, '\\'); if (next_slash == remaining) { // Leading slash - shift - XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), remaining + 1)); + xestrcpya(remaining, XECOUNT(remaining), remaining + 1); continue; } @@ -82,7 +82,7 @@ Entry* STFSContainerDevice::ResolvePath(const char* path) { if (!next_slash) { break; } - XEIGNORE(xestrcpya(remaining, XECOUNT(remaining), next_slash + 1)); + xestrcpya(remaining, XECOUNT(remaining), next_slash + 1); } Entry::Type type = stfs_entry->attributes & X_FILE_ATTRIBUTE_DIRECTORY ? diff --git a/src/xenia/kernel/fs/devices/stfs_container_file.cc b/src/xenia/kernel/fs/devices/stfs_container_file.cc index fbba72a99..2c2a74675 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_file.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_file.cc @@ -9,10 +9,11 @@ #include -#include -#include +#include #include +#include +#include using namespace xe; using namespace xe::kernel; @@ -71,20 +72,20 @@ X_STATUS STFSContainerFile::ReadSync( // Each block is 4096. // Blocks may not be sequential, so we need to read by blocks and handle the // offsets. - size_t real_length = MIN(buffer_length, stfs_entry->size - byte_offset); + size_t real_length = std::min(buffer_length, stfs_entry->size - byte_offset); size_t start_block = byte_offset / 4096; - size_t end_block = MIN( - stfs_entry->block_list.size(), - (size_t)ceil((byte_offset + real_length) / 4096.0)); + size_t end_block = + std::min(stfs_entry->block_list.size(), + (size_t)ceil((byte_offset + real_length) / 4096.0)); uint8_t* dest_ptr = (uint8_t*)buffer; size_t remaining_length = real_length; for (size_t n = start_block; n < end_block; n++) { auto& record = stfs_entry->block_list[n]; size_t offset = record.offset; - size_t read_length = MIN(remaining_length, record.length); + size_t read_length = std::min(remaining_length, record.length); if (n == start_block) { offset += byte_offset % 4096; - read_length = MIN(read_length, record.length - (byte_offset % 4096)); + read_length = std::min(read_length, record.length - (byte_offset % 4096)); } xe_copy_struct(dest_ptr, map_ptr + offset, read_length); dest_ptr += read_length; diff --git a/src/xenia/kernel/fs/stfs.cc b/src/xenia/kernel/fs/stfs.cc index b3e4a8788..a72c6e57b 100644 --- a/src/xenia/kernel/fs/stfs.cc +++ b/src/xenia/kernel/fs/stfs.cc @@ -11,6 +11,7 @@ #include +#include using namespace xe; using namespace xe::kernel; @@ -257,7 +258,7 @@ STFS::Error STFS::ReadAllEntries(const uint8_t* map_ptr) { while (remaining_size && block_index && info >= 0x80) { - size_t block_size = MIN(0x1000, remaining_size); + size_t block_size = std::min(0x1000ull, remaining_size); size_t offset = BlockToOffset(ComputeBlockNumber(block_index)); entry->block_list.push_back({ offset, block_size }); remaining_size -= block_size; diff --git a/src/xenia/kernel/object_table.cc b/src/xenia/kernel/object_table.cc index b6199db69..afdca7994 100644 --- a/src/xenia/kernel/object_table.cc +++ b/src/xenia/kernel/object_table.cc @@ -9,6 +9,8 @@ #include +#include + #include #include @@ -61,10 +63,9 @@ X_STATUS ObjectTable::FindFreeSlot(uint32_t* out_slot) { } // Table out of slots, expand. - uint32_t new_table_capacity = MAX(16 * 1024, table_capacity_ * 2); + uint32_t new_table_capacity = std::max(16 * 1024u, table_capacity_ * 2); ObjectTableEntry* new_table = (ObjectTableEntry*)xe_recalloc( - table_, - table_capacity_ * sizeof(ObjectTableEntry), + table_, table_capacity_ * sizeof(ObjectTableEntry), new_table_capacity * sizeof(ObjectTableEntry)); if (!new_table) { return X_STATUS_NO_MEMORY; diff --git a/src/xenia/kernel/util/xex2.cc b/src/xenia/kernel/util/xex2.cc index 93ec53ca2..9ce9ddb86 100644 --- a/src/xenia/kernel/util/xex2.cc +++ b/src/xenia/kernel/util/xex2.cc @@ -9,6 +9,7 @@ #include +#include #include #include @@ -262,8 +263,8 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, for (size_t i = 0, j = 0; i < string_table_size;) { assert_true(j <= 0xFF); if (j == name_index) { - XEIGNORE(xestrcpya(library->name, XECOUNT(library->name), - string_table + i)); + xestrcpya(library->name, XECOUNT(library->name), + string_table + i); break; } if (string_table[i] == 0) { @@ -481,7 +482,7 @@ void mspack_memory_close(mspack_memory_file *file) { int mspack_memory_read(struct mspack_file *file, void *buffer, int chars) { mspack_memory_file *memfile = (mspack_memory_file*)file; const off_t remaining = memfile->buffer_size - memfile->offset; - const off_t total = MIN(chars, remaining); + const off_t total = std::min(static_cast(chars), remaining); if (xe_copy_memory(buffer, total, (uint8_t*)memfile->buffer + memfile->offset, total)) { return -1; @@ -492,7 +493,7 @@ int mspack_memory_read(struct mspack_file *file, void *buffer, int chars) { int mspack_memory_write(struct mspack_file *file, void *buffer, int chars) { mspack_memory_file *memfile = (mspack_memory_file*)file; const off_t remaining = memfile->buffer_size - memfile->offset; - const off_t total = MIN(chars, remaining); + const off_t total = std::min(static_cast(chars), remaining); if (xe_copy_memory((uint8_t*)memfile->buffer + memfile->offset, memfile->buffer_size - memfile->offset, buffer, total)) { return -1; @@ -501,7 +502,6 @@ int mspack_memory_write(struct mspack_file *file, void *buffer, int chars) { return (int)total; } void *mspack_memory_alloc(struct mspack_system *sys, size_t chars) { - XEUNREFERENCED(sys); return xe_calloc(chars); } void mspack_memory_free(void *ptr) { @@ -876,7 +876,7 @@ int xe_xex2_load_pe(xe_xex2_ref xex) { for (size_t n = 0; n < filehdr->NumberOfSections; n++, sechdr++) { const size_t physical_address = opthdr->ImageBase + sechdr->VirtualAddress; upper_address = - MAX(upper_address, physical_address + sechdr->Misc.VirtualSize); + std::max(upper_address, physical_address + sechdr->Misc.VirtualSize); } // Setup/load sections. diff --git a/src/xenia/logging.cc b/src/xenia/logging.cc index 6ed64352d..0d181e26e 100644 --- a/src/xenia/logging.cc +++ b/src/xenia/logging.cc @@ -74,7 +74,7 @@ void xe_log_line(const char* file_path, const uint32_t line_number, #if 0// defined(OutputDebugString) OutputDebugStringA(buffer); #else - XEIGNORE(fprintf(stdout, buffer)); + fprintf(stdout, buffer); fflush(stdout); #endif // OutputDebugString if (!FLAGS_fast_stdout) { @@ -99,7 +99,7 @@ void xe_handle_fatal( #if defined(OutputDebugString) OutputDebugStringA(buffer); #else - XEIGNORE(fprintf(stderr, buffer)); + fprintf(stderr, buffer); fflush(stderr); #endif // OutputDebugString if (!FLAGS_fast_stdout) { diff --git a/src/xenia/types.h b/src/xenia/types.h index 972cad6c7..c15836d9f 100644 --- a/src/xenia/types.h +++ b/src/xenia/types.h @@ -18,8 +18,6 @@ #define XE_EMPTY_MACRO do { } while(0) -#define XEUNREFERENCED(expr) (void)(expr) - #define XEDECLARECLASS1(ns1, name) \ namespace ns1 { class name; } #define XEDECLARECLASS2(ns1, ns2, name) \ @@ -35,28 +33,6 @@ class name; \ } } } } -#if XE_COMPILER_MSVC -#define XEASSUME(expr) __analysis_assume(expr) -#else -#define XEASSUME(expr) -#endif // MSVC - -#if XE_COMPILER_MSVC -#define XECDECL __cdecl -#else -#define XECDECL -#endif // MSVC - -#if defined(__cplusplus) -#define XEEXTERNC extern "C" -#define XEEXTERNC_BEGIN extern "C" { -#define XEEXTERNC_END } -#else -#define XEEXTERNC extern -#define XEEXTERNC_BEGIN -#define XEEXTERNC_END -#endif // __cplusplus - #if XE_COMPILER_MSVC // http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx #define XEFORCEINLINE static __forceinline @@ -115,21 +91,6 @@ typedef XECACHEALIGN volatile void xe_aligned_void_t; #define XECOUNT(array) (sizeof(array) / sizeof(array[0])) #endif // MSVC -#if !defined(MIN) -#if XE_COMPILER_GNUC -#define MIN(A, B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); (__a < __b) ? __a : __b; }) -#define MAX(A, B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); (__a < __b) ? __b : __a; }) -//#elif XE_COMPILER_MSVC -// TODO(benvanik): experiment with decltype: -// http://msdn.microsoft.com/en-us/library/dd537655.aspx -#else -// NOTE: this implementation will evaluate the arguments twice - may be worth -// writing an inline function instead. -#define MIN(A, B) ( ((A) < (B)) ? (A) : (B) ) -#define MAX(A, B) ( ((A) < (B)) ? (B) : (A) ) -#endif // GNUC -#endif // !MIN - XEFORCEINLINE size_t hash_combine(size_t seed) { return seed; } @@ -153,7 +114,6 @@ static inline uint32_t XENEXTPOW2(uint32_t v) { } #define XEALIGN(value, align) ((value + align - 1) & ~(align - 1)) -#define XESUCCEED() goto XECLEANUP #define XEFAIL() goto XECLEANUP #define XEEXPECT(expr) if (!(expr) ) { goto XECLEANUP; } #define XEEXPECTTRUE(expr) if (!(expr) ) { goto XECLEANUP; } @@ -162,7 +122,6 @@ static inline uint32_t XENEXTPOW2(uint32_t v) { #define XEEXPECTNOTZERO(expr) if ( (expr) == 0 ) { goto XECLEANUP; } #define XEEXPECTNULL(expr) if ( (expr) != NULL ) { goto XECLEANUP; } #define XEEXPECTNOTNULL(expr) if ( (expr) == NULL ) { goto XECLEANUP; } -#define XEIGNORE(expr) do { (void)(expr); } while(0) #endif // XENIA_TYPES_H_ diff --git a/src/xenia/ui/win32/win32_window.cc b/src/xenia/ui/win32/win32_window.cc index 78f87bbf4..10f6aa6a6 100644 --- a/src/xenia/ui/win32/win32_window.cc +++ b/src/xenia/ui/win32/win32_window.cc @@ -169,7 +169,7 @@ bool Win32Window::set_title(const std::wstring& title) { if (!Window::set_title(title)) { return false; } - XEIGNORE(SetWindowText(handle_, title.c_str())); + SetWindowText(handle_, title.c_str()); return true; } From 5b83cf5fd1cf6d3d39ff5f1eefe0ec9fce5dcfa7 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 16 Aug 2014 17:18:20 -0700 Subject: [PATCH 122/388] Moving around some math macros. --- src/alloy/backend/ivm/ivm_assembler.cc | 4 +- src/alloy/backend/x64/x64_code_cache_win.cc | 7 +- src/alloy/backend/x64/x64_emitter.cc | 4 +- src/alloy/frontend/ppc/ppc_disasm.cc | 10 +-- src/alloy/frontend/ppc/ppc_emit_control.cc | 20 ++--- src/alloy/frontend/ppc/ppc_instr.cc | 34 +++---- src/alloy/frontend/ppc/ppc_instr.h | 8 ++ src/alloy/frontend/ppc/ppc_instr_tables.h | 4 +- src/alloy/frontend/ppc/ppc_scanner.cc | 4 +- src/poly/math.h | 26 ++++++ src/xenia/core.h | 1 - src/xenia/core/hash.cc | 94 ++++++++------------ src/xenia/core/hash.h | 13 ++- src/xenia/cpu/xenon_memory.cc | 3 +- src/xenia/gpu/d3d11/d3d11_geometry_shader.cc | 3 +- src/xenia/gpu/d3d11/d3d11_graphics_driver.cc | 1 + src/xenia/gpu/d3d11/d3d11_shader_resource.cc | 3 +- src/xenia/gpu/resource_cache.cc | 3 +- src/xenia/gpu/sampler_state_resource.h | 1 + src/xenia/gpu/texture_resource.cc | 13 +-- src/xenia/kernel/xboxkrnl_io.cc | 3 +- src/xenia/kernel/xboxkrnl_memory.cc | 7 +- src/xenia/types.h | 19 ---- 23 files changed, 148 insertions(+), 137 deletions(-) diff --git a/src/alloy/backend/ivm/ivm_assembler.cc b/src/alloy/backend/ivm/ivm_assembler.cc index 7585b7457..6bdb846b8 100644 --- a/src/alloy/backend/ivm/ivm_assembler.cc +++ b/src/alloy/backend/ivm/ivm_assembler.cc @@ -78,12 +78,12 @@ int IVMAssembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder, auto slot = *it; size_t type_size = GetTypeSize(slot->type); // Align to natural size. - stack_offset = XEALIGN(stack_offset, type_size); + stack_offset = poly::align(stack_offset, type_size); slot->set_constant((uint32_t)stack_offset); stack_offset += type_size; } // Ensure 16b alignment. - stack_offset = XEALIGN(stack_offset, 16); + stack_offset = poly::align(stack_offset, 16ull); ctx.stack_size = stack_offset; auto block = builder->first_block(); diff --git a/src/alloy/backend/x64/x64_code_cache_win.cc b/src/alloy/backend/x64/x64_code_cache_win.cc index 6b0bfb750..1084b0508 100644 --- a/src/alloy/backend/x64/x64_code_cache_win.cc +++ b/src/alloy/backend/x64/x64_code_cache_win.cc @@ -63,11 +63,11 @@ void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size, size_t alloc_size = code_size; // Add unwind info into the allocation size. Keep things 16b aligned. - alloc_size += XEROUNDUP(X64CodeChunk::UNWIND_INFO_SIZE, 16); + alloc_size += poly::round_up(X64CodeChunk::UNWIND_INFO_SIZE, 16); // Always move the code to land on 16b alignment. We do this by rounding up // to 16b so that all offsets are aligned. - alloc_size = XEROUNDUP(alloc_size, 16); + alloc_size = poly::round_up(alloc_size, 16); lock_.lock(); @@ -106,7 +106,8 @@ X64CodeChunk::X64CodeChunk(size_t chunk_size) buffer = (uint8_t*)VirtualAlloc(NULL, capacity, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); - fn_table_capacity = (uint32_t)XEROUNDUP(capacity / ESTIMATED_FN_SIZE, 16); + fn_table_capacity = + static_cast(poly::round_up(capacity / ESTIMATED_FN_SIZE, 16)); size_t table_size = fn_table_capacity * sizeof(RUNTIME_FUNCTION); fn_table = (RUNTIME_FUNCTION*)xe_malloc(table_size); fn_table_count = 0; diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index bf583829d..00c84936e 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -121,13 +121,13 @@ int X64Emitter::Emit(HIRBuilder* builder, size_t& out_stack_size) { auto slot = *it; size_t type_size = GetTypeSize(slot->type); // Align to natural size. - stack_offset = XEALIGN(stack_offset, type_size); + stack_offset = poly::align(stack_offset, type_size); slot->set_constant((uint32_t)stack_offset); stack_offset += type_size; } // Ensure 16b alignment. stack_offset -= StackLayout::GUEST_STACK_SIZE; - stack_offset = XEALIGN(stack_offset, 16); + stack_offset = poly::align(stack_offset, 16ull); // Function prolog. // Must be 16b aligned. diff --git a/src/alloy/frontend/ppc/ppc_disasm.cc b/src/alloy/frontend/ppc/ppc_disasm.cc index d7a46b561..94fd1325e 100644 --- a/src/alloy/frontend/ppc/ppc_disasm.cc +++ b/src/alloy/frontend/ppc/ppc_disasm.cc @@ -287,13 +287,13 @@ void Disasm_bx(InstrData& i, StringBuffer* str) { void Disasm_bcx(InstrData& i, StringBuffer* str) { const char* s0 = i.B.LK ? "lr, " : ""; const char* s1; - if (!XESELECTBITS(i.B.BO, 2, 2)) { + if (!select_bits(i.B.BO, 2, 2)) { s1 = "ctr, "; } else { s1 = ""; } char s2[8] = {0}; - if (!XESELECTBITS(i.B.BO, 4, 4)) { + if (!select_bits(i.B.BO, 4, 4)) { xesnprintfa(s2, XECOUNT(s2), "cr%d, ", i.B.BI >> 2); } uint32_t nia; @@ -309,7 +309,7 @@ void Disasm_bcctrx(InstrData& i, StringBuffer* str) { // TODO(benvanik): mnemonics const char* s0 = i.XL.LK ? "lr, " : ""; char s2[8] = {0}; - if (!XESELECTBITS(i.XL.BO, 4, 4)) { + if (!select_bits(i.XL.BO, 4, 4)) { xesnprintfa(s2, XECOUNT(s2), "cr%d, ", i.XL.BI >> 2); } str->Append("%-8s %s%sctr", i.type->name, s0, s2); @@ -321,13 +321,13 @@ void Disasm_bclrx(InstrData& i, StringBuffer* str) { name = "blr"; } const char* s1; - if (!XESELECTBITS(i.XL.BO, 2, 2)) { + if (!select_bits(i.XL.BO, 2, 2)) { s1 = "ctr, "; } else { s1 = ""; } char s2[8] = {0}; - if (!XESELECTBITS(i.XL.BO, 4, 4)) { + if (!select_bits(i.XL.BO, 4, 4)) { xesnprintfa(s2, XECOUNT(s2), "cr%d, ", i.XL.BI >> 2); } str->Append("%-8s %s%s", name, s1, s2); diff --git a/src/alloy/frontend/ppc/ppc_emit_control.cc b/src/alloy/frontend/ppc/ppc_emit_control.cc index dc8c11c3a..fccddfc7b 100644 --- a/src/alloy/frontend/ppc/ppc_emit_control.cc +++ b/src/alloy/frontend/ppc/ppc_emit_control.cc @@ -176,7 +176,7 @@ XEEMITTER(bcx, 0x40000000, B)(PPCHIRBuilder& f, InstrData& i) { // 43210 (real) Value* ctr_ok = NULL; - if (XESELECTBITS(i.B.BO, 2, 2)) { + if (select_bits(i.B.BO, 2, 2)) { // Ignore ctr. } else { // Decrement counter. @@ -187,7 +187,7 @@ XEEMITTER(bcx, 0x40000000, B)(PPCHIRBuilder& f, InstrData& i) { ctr = f.Truncate(ctr, INT32_TYPE); // TODO(benvanik): could do something similar to cond and avoid the // is_true/branch_true pairing. - if (XESELECTBITS(i.B.BO, 1, 1)) { + if (select_bits(i.B.BO, 1, 1)) { ctr_ok = f.IsFalse(ctr); } else { ctr_ok = f.IsTrue(ctr); @@ -196,12 +196,12 @@ XEEMITTER(bcx, 0x40000000, B)(PPCHIRBuilder& f, InstrData& i) { Value* cond_ok = NULL; bool not_cond_ok = false; - if (XESELECTBITS(i.B.BO, 4, 4)) { + if (select_bits(i.B.BO, 4, 4)) { // Ignore cond. } else { Value* cr = f.LoadCRField(i.B.BI >> 2, i.B.BI & 3); cond_ok = cr; - if (XESELECTBITS(i.B.BO, 3, 3)) { + if (select_bits(i.B.BO, 3, 3)) { // Expect true. not_cond_ok = false; } else { @@ -248,12 +248,12 @@ XEEMITTER(bcctrx, 0x4C000420, XL)(PPCHIRBuilder& f, InstrData& i) { Value* cond_ok = NULL; bool not_cond_ok = false; - if (XESELECTBITS(i.XL.BO, 4, 4)) { + if (select_bits(i.XL.BO, 4, 4)) { // Ignore cond. } else { Value* cr = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3); cond_ok = cr; - if (XESELECTBITS(i.XL.BO, 3, 3)) { + if (select_bits(i.XL.BO, 3, 3)) { // Expect true. not_cond_ok = false; } else { @@ -282,7 +282,7 @@ XEEMITTER(bclrx, 0x4C000020, XL)(PPCHIRBuilder& f, InstrData& i) { // 43210 (real) Value* ctr_ok = NULL; - if (XESELECTBITS(i.XL.BO, 2, 2)) { + if (select_bits(i.XL.BO, 2, 2)) { // Ignore ctr. } else { // Decrement counter. @@ -293,7 +293,7 @@ XEEMITTER(bclrx, 0x4C000020, XL)(PPCHIRBuilder& f, InstrData& i) { ctr = f.Truncate(ctr, INT32_TYPE); // TODO(benvanik): could do something similar to cond and avoid the // is_true/branch_true pairing. - if (XESELECTBITS(i.XL.BO, 1, 1)) { + if (select_bits(i.XL.BO, 1, 1)) { ctr_ok = f.IsFalse(ctr); } else { ctr_ok = f.IsTrue(ctr); @@ -302,12 +302,12 @@ XEEMITTER(bclrx, 0x4C000020, XL)(PPCHIRBuilder& f, InstrData& i) { Value* cond_ok = NULL; bool not_cond_ok = false; - if (XESELECTBITS(i.XL.BO, 4, 4)) { + if (select_bits(i.XL.BO, 4, 4)) { // Ignore cond. } else { Value* cr = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3); cond_ok = cr; - if (XESELECTBITS(i.XL.BO, 3, 3)) { + if (select_bits(i.XL.BO, 3, 3)) { // Expect true. not_cond_ok = false; } else { diff --git a/src/alloy/frontend/ppc/ppc_instr.cc b/src/alloy/frontend/ppc/ppc_instr.cc index df3a59206..43b52d759 100644 --- a/src/alloy/frontend/ppc/ppc_instr.cc +++ b/src/alloy/frontend/ppc/ppc_instr.cc @@ -322,48 +322,48 @@ InstrType* GetInstrType(uint32_t code) { switch (code >> 26) { case 4: // Opcode = 4, index = bits 10-0 (10) - slot = alloy::frontend::ppc::tables::instr_table_4[XESELECTBITS(code, 0, - 10)]; + slot = + alloy::frontend::ppc::tables::instr_table_4[select_bits(code, 0, 10)]; break; case 19: // Opcode = 19, index = bits 10-1 (10) - slot = alloy::frontend::ppc::tables::instr_table_19[XESELECTBITS(code, 1, - 10)]; + slot = alloy::frontend::ppc::tables::instr_table_19[select_bits(code, 1, + 10)]; break; case 30: // Opcode = 30, index = bits 4-1 (4) // Special cased to an uber instruction. - slot = alloy::frontend::ppc::tables::instr_table_30[XESELECTBITS(code, 0, - 0)]; + slot = + alloy::frontend::ppc::tables::instr_table_30[select_bits(code, 0, 0)]; break; case 31: // Opcode = 31, index = bits 10-1 (10) - slot = alloy::frontend::ppc::tables::instr_table_31[XESELECTBITS(code, 1, - 10)]; + slot = alloy::frontend::ppc::tables::instr_table_31[select_bits(code, 1, + 10)]; break; case 58: // Opcode = 58, index = bits 1-0 (2) - slot = alloy::frontend::ppc::tables::instr_table_58[XESELECTBITS(code, 0, - 1)]; + slot = + alloy::frontend::ppc::tables::instr_table_58[select_bits(code, 0, 1)]; break; case 59: // Opcode = 59, index = bits 5-1 (5) - slot = alloy::frontend::ppc::tables::instr_table_59[XESELECTBITS(code, 1, - 5)]; + slot = + alloy::frontend::ppc::tables::instr_table_59[select_bits(code, 1, 5)]; break; case 62: // Opcode = 62, index = bits 1-0 (2) - slot = alloy::frontend::ppc::tables::instr_table_62[XESELECTBITS(code, 0, - 1)]; + slot = + alloy::frontend::ppc::tables::instr_table_62[select_bits(code, 0, 1)]; break; case 63: // Opcode = 63, index = bits 10-1 (10) - slot = alloy::frontend::ppc::tables::instr_table_63[XESELECTBITS(code, 1, - 10)]; + slot = alloy::frontend::ppc::tables::instr_table_63[select_bits(code, 1, + 10)]; break; default: slot = - alloy::frontend::ppc::tables::instr_table[XESELECTBITS(code, 26, 31)]; + alloy::frontend::ppc::tables::instr_table[select_bits(code, 26, 31)]; break; } if (slot && slot->opcode) { diff --git a/src/alloy/frontend/ppc/ppc_instr.h b/src/alloy/frontend/ppc/ppc_instr.h index 6baf95464..c080f82b1 100644 --- a/src/alloy/frontend/ppc/ppc_instr.h +++ b/src/alloy/frontend/ppc/ppc_instr.h @@ -23,6 +23,14 @@ namespace alloy { namespace frontend { namespace ppc { +inline uint32_t make_bitmask(uint32_t a, uint32_t b) { + return (static_cast(-1) >> (31 - b)) & ~((1u << a) - 1); +} + +inline uint32_t select_bits(uint32_t value, uint32_t a, uint32_t b) { + return (value & make_bitmask(a, b)) >> a; +} + // TODO(benvanik): rename these typedef enum { kXEPPCInstrFormatI = 0, diff --git a/src/alloy/frontend/ppc/ppc_instr_tables.h b/src/alloy/frontend/ppc/ppc_instr_tables.h index 336d28c7d..65f1ddc49 100644 --- a/src/alloy/frontend/ppc/ppc_instr_tables.h +++ b/src/alloy/frontend/ppc/ppc_instr_tables.h @@ -96,7 +96,7 @@ static InstrType** instr_table_prep(InstrType* unprep, int unprep_count, int a, int prep_count = (int)pow(2.0, b - a + 1); InstrType** prep = (InstrType**)xe_calloc(prep_count * sizeof(void*)); for (int n = 0; n < unprep_count; n++) { - int ordinal = XESELECTBITS(unprep[n].opcode, a, b); + int ordinal = select_bits(unprep[n].opcode, a, b); prep[ordinal] = &unprep[n]; } return prep; @@ -108,7 +108,7 @@ static InstrType** instr_table_prep_63(InstrType* unprep, int unprep_count, int prep_count = (int)pow(2.0, b - a + 1); InstrType** prep = (InstrType**)xe_calloc(prep_count * sizeof(void*)); for (int n = 0; n < unprep_count; n++) { - int ordinal = XESELECTBITS(unprep[n].opcode, a, b); + int ordinal = select_bits(unprep[n].opcode, a, b); if (unprep[n].format == kXEPPCInstrFormatA) { // Must splat this into all of the slots that it could be in. for (int m = 0; m < 32; m++) { diff --git a/src/alloy/frontend/ppc/ppc_scanner.cc b/src/alloy/frontend/ppc/ppc_scanner.cc index e27827792..882b920b4 100644 --- a/src/alloy/frontend/ppc/ppc_scanner.cc +++ b/src/alloy/frontend/ppc/ppc_scanner.cc @@ -50,8 +50,8 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { XELOGSDB("Analyzing function %.8X...", symbol_info->address()); - uint32_t start_address = symbol_info->address(); - uint32_t end_address = symbol_info->end_address(); + uint32_t start_address = static_cast(symbol_info->address()); + uint32_t end_address = static_cast(symbol_info->end_address()); uint32_t address = start_address; uint32_t furthest_target = start_address; size_t blocks_found = 0; diff --git a/src/poly/math.h b/src/poly/math.h index 1783eb02a..69a8597d3 100644 --- a/src/poly/math.h +++ b/src/poly/math.h @@ -20,6 +20,32 @@ namespace poly { +// Rounds up the given value to the given alignment. +template +T align(T value, T alignment) { + return (value + alignment - 1) & ~(alignment - 1); +} + +// Rounds the given number up to the next highest multiple. +template +T round_up(T value, V multiple) { + return value + multiple - 1 - (value - 1) % multiple; +} + +// Gets the next power of two value that is greater than or equal to the given +// value. +template +T next_pow2(T value) { + value--; + value |= value >> 1; + value |= value >> 2; + value |= value >> 4; + value |= value >> 8; + value |= value >> 16; + value++; + return value; +} + // lzcnt instruction, typed for integers of all sizes. // The number of leading zero bits in the value parameter. If value is zero, the // return value is the size of the input operand (8, 16, 32, or 64). If the most diff --git a/src/xenia/core.h b/src/xenia/core.h index 12d7dfb93..7179804da 100644 --- a/src/xenia/core.h +++ b/src/xenia/core.h @@ -17,7 +17,6 @@ namespace xe { using Memory = alloy::Memory; } // namespace xe -#include #include #include #include diff --git a/src/xenia/core/hash.cc b/src/xenia/core/hash.cc index a57afaa01..4e7785d38 100644 --- a/src/xenia/core/hash.cc +++ b/src/xenia/core/hash.cc @@ -38,19 +38,21 @@ #include +#include #include -#include // for memcpy and memset + +namespace xe { namespace { typedef std::pair uint128_t; -inline uint64_t Uint128Low64(const uint128_t& x) { return x.first; } -inline uint64_t Uint128High64(const uint128_t& x) { return x.second; } +inline uint64_t Uint128Low64(const uint128_t &x) { return x.first; } +inline uint64_t Uint128High64(const uint128_t &x) { return x.second; } // Hash 128 input bits down to 64 bits of output. // This is intended to be a reasonably good hash function. -inline uint64_t Hash128to64(const uint128_t& x) { +inline uint64_t Hash128to64(const uint128_t &x) { // Murmur-inspired hashing. const uint64_t kMul = 0x9ddfea08eb382d69ULL; uint64_t a = (Uint128Low64(x) ^ Uint128High64(x)) * kMul; @@ -61,37 +63,14 @@ inline uint64_t Hash128to64(const uint128_t& x) { return b; } -using namespace std; - -#if 0 -static uint64_t UNALIGNED_LOAD64(const char *p) { - uint64_t result; - memcpy(&result, p, sizeof(result)); - return result; -} -static uint32_t UNALIGNED_LOAD32(const char *p) { - uint32_t result; - memcpy(&result, p, sizeof(result)); - return result; -} -#else XEFORCEINLINE uint64_t UNALIGNED_LOAD64(const char *p) { - const uint64_t* p64 = (const uint64_t*)p; + const uint64_t *p64 = (const uint64_t *)p; return *p64; } XEFORCEINLINE uint32_t UNALIGNED_LOAD32(const char *p) { - const uint32_t* p32 = (const uint32_t*)p; + const uint32_t *p32 = (const uint32_t *)p; return *p32; } -#endif - -#if XE_CPU_BIGENDIAN -#define uint32_t_in_expected_order(x) (poly::byte_swap(x)) -#define uint64_in_expected_order(x) (poly::byte_swap(x)) -#else -#define uint32_t_in_expected_order(x) (x) -#define uint64_in_expected_order(x) (x) -#endif // XE_CPU_BIGENDIAN #if !defined(LIKELY) #if HAVE_BUILTIN_EXPECT @@ -101,13 +80,9 @@ XEFORCEINLINE uint32_t UNALIGNED_LOAD32(const char *p) { #endif #endif -static uint64_t Fetch64(const char *p) { - return uint64_in_expected_order(UNALIGNED_LOAD64(p)); -} +static uint64_t Fetch64(const char *p) { return UNALIGNED_LOAD64(p); } -static uint32_t Fetch32(const char *p) { - return uint32_t_in_expected_order(UNALIGNED_LOAD32(p)); -} +static uint32_t Fetch32(const char *p) { return UNALIGNED_LOAD32(p); } // Some primes between 2^63 and 2^64 for various uses. static const uint64_t k0 = 0xc3a5c85c97cb3127ULL; @@ -119,8 +94,7 @@ static const uint32_t c1 = 0xcc9e2d51; static const uint32_t c2 = 0x1b873593; // A 32-bit to 32-bit integer hash copied from Murmur3. -static uint32_t fmix(uint32_t h) -{ +static uint32_t fmix(uint32_t h) { h ^= h >> 16; h *= 0x85ebca6b; h ^= h >> 13; @@ -135,7 +109,11 @@ static uint32_t Rotate32(uint32_t val, int shift) { } #undef PERMUTE3 -#define PERMUTE3(a, b, c) do { std::swap(a, b); std::swap(a, c); } while (0) +#define PERMUTE3(a, b, c) \ + do { \ + std::swap(a, b); \ + std::swap(a, c); \ + } while (0) static uint32_t Mur(uint32_t a, uint32_t h) { // Helper from Murmur3 for combining two 32-bit values. @@ -180,9 +158,9 @@ static uint32_t Hash32Len5to12(const char *s, size_t len) { uint32_t CityHash32(const char *s, size_t len) { if (len <= 24) { - return len <= 12 ? - (len <= 4 ? Hash32Len0to4(s, len) : Hash32Len5to12(s, len)) : - Hash32Len13to24(s, len); + return len <= 12 + ? (len <= 4 ? Hash32Len0to4(s, len) : Hash32Len5to12(s, len)) + : Hash32Len13to24(s, len); } // len > 24 @@ -254,9 +232,7 @@ static uint64_t Rotate(uint64_t val, int shift) { return shift == 0 ? val : ((val >> shift) | (val << (64 - shift))); } -static uint64_t ShiftMix(uint64_t val) { - return val ^ (val >> 47); -} +static uint64_t ShiftMix(uint64_t val) { return val ^ (val >> 47); } static uint64_t HashLen16(uint64_t u, uint64_t v) { return Hash128to64(uint128_t(u, v)); @@ -311,7 +287,7 @@ static uint64_t HashLen17to32(const char *s, size_t len) { // Return a 16-byte hash for 48 bytes. Quick and dirty. // Callers do best to use "random-looking" values for a and b. -static pair WeakHashLen32WithSeeds( +static std::pair WeakHashLen32WithSeeds( uint64_t w, uint64_t x, uint64_t y, uint64_t z, uint64_t a, uint64_t b) { a += w; b = Rotate(b + a + z, 21); @@ -319,18 +295,15 @@ static pair WeakHashLen32WithSeeds( a += x; a += y; b += Rotate(a, 44); - return make_pair(a + z, b + c); + return std::make_pair(a + z, b + c); } // Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty. -static pair WeakHashLen32WithSeeds( - const char* s, uint64_t a, uint64_t b) { - return WeakHashLen32WithSeeds(Fetch64(s), - Fetch64(s + 8), - Fetch64(s + 16), - Fetch64(s + 24), - a, - b); +static std::pair WeakHashLen32WithSeeds(const char *s, + uint64_t a, + uint64_t b) { + return WeakHashLen32WithSeeds(Fetch64(s), Fetch64(s + 8), Fetch64(s + 16), + Fetch64(s + 24), a, b); } // Return an 8-byte hash for 33 to 64 bytes. @@ -371,8 +344,10 @@ uint64_t CityHash64(const char *s, size_t len) { uint64_t x = Fetch64(s + len - 40); uint64_t y = Fetch64(s + len - 16) + Fetch64(s + len - 56); uint64_t z = HashLen16(Fetch64(s + len - 48) + len, Fetch64(s + len - 24)); - pair v = WeakHashLen32WithSeeds(s + len - 64, len, z); - pair w = WeakHashLen32WithSeeds(s + len - 32, y + k1, x); + std::pair v = + WeakHashLen32WithSeeds(s + len - 64, len, z); + std::pair w = + WeakHashLen32WithSeeds(s + len - 32, y + k1, x); x = x * k1 + Fetch64(s); // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks. @@ -395,7 +370,8 @@ uint64_t CityHash64(const char *s, size_t len) { } // anonymous namespace - -uint64_t xe_hash64(const void* data, size_t length, uint64_t seed) { - return HashLen16(CityHash64((const char*)data, length) - k2, seed); +uint64_t hash64(const void *data, size_t length, uint64_t seed) { + return HashLen16(CityHash64((const char *)data, length) - k2, seed); } + +} // namespace xe \ No newline at end of file diff --git a/src/xenia/core/hash.h b/src/xenia/core/hash.h index 2ba390013..2002724ad 100644 --- a/src/xenia/core/hash.h +++ b/src/xenia/core/hash.h @@ -12,8 +12,19 @@ #include +namespace xe { -uint64_t xe_hash64(const void* data, size_t length, uint64_t seed = 0); +inline size_t hash_combine(size_t seed) { return seed; } +template +size_t hash_combine(size_t seed, const T& v, const Ts&... vs) { + std::hash hasher; + seed ^= hasher(v) + 0x9E3779B9 + (seed << 6) + (seed >> 2); + return hash_combine(seed, vs...); +} + +uint64_t hash64(const void* data, size_t length, uint64_t seed = 0); + +} // namespace xe #endif // XENIA_CORE_HASH_H_ diff --git a/src/xenia/cpu/xenon_memory.cc b/src/xenia/cpu/xenon_memory.cc index eaff6bc95..c8f73064c 100644 --- a/src/xenia/cpu/xenon_memory.cc +++ b/src/xenia/cpu/xenon_memory.cc @@ -13,6 +13,7 @@ #include #include +#include using namespace alloy; using namespace xe::cpu; @@ -510,7 +511,7 @@ uint64_t XenonMemoryHeap::Alloc( size_t heap_guard_size = FLAGS_heap_guard_pages * 4096; if (heap_guard_size) { alignment = std::max(alignment, static_cast(heap_guard_size)); - alloc_size = (uint32_t)XEROUNDUP(size, heap_guard_size); + alloc_size = static_cast(poly::round_up(size, heap_guard_size)); } uint8_t* p = (uint8_t*)mspace_memalign(space_, alignment, alloc_size + heap_guard_size * 2); diff --git a/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc b/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc index 0ab44c282..42660b462 100644 --- a/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc +++ b/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -95,7 +96,7 @@ ID3D10Blob* D3D11GeometryShader::Compile(const char* shader_source) { if (FLAGS_dump_shaders.size()) { base_path = FLAGS_dump_shaders.c_str(); } - uint64_t hash = xe_hash64(shader_source, strlen(shader_source)); // ? + uint64_t hash = hash64(shader_source, strlen(shader_source)); // ? char file_name[poly::max_path]; xesnprintfa(file_name, XECOUNT(file_name), "%s/gen_%.16llX.gs", diff --git a/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc b/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc index 4ea0b6210..78e5d703d 100644 --- a/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc +++ b/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc @@ -9,6 +9,7 @@ #include +#include #include #include #include diff --git a/src/xenia/gpu/d3d11/d3d11_shader_resource.cc b/src/xenia/gpu/d3d11/d3d11_shader_resource.cc index f32e3f714..a2371a282 100644 --- a/src/xenia/gpu/d3d11/d3d11_shader_resource.cc +++ b/src/xenia/gpu/d3d11/d3d11_shader_resource.cc @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -46,7 +47,7 @@ ID3D10Blob* D3D11ShaderCompile(XE_GPU_SHADER_TYPE type, if (FLAGS_dump_shaders.size()) { base_path = FLAGS_dump_shaders.c_str(); } - size_t hash = xe_hash64(disasm_source, strlen(disasm_source)); // ? + size_t hash = hash64(disasm_source, strlen(disasm_source)); // ? char file_name[poly::max_path]; xesnprintfa(file_name, XECOUNT(file_name), "%s/gen_%.16llX.%s", diff --git a/src/xenia/gpu/resource_cache.cc b/src/xenia/gpu/resource_cache.cc index 5641c8318..3288125ef 100644 --- a/src/xenia/gpu/resource_cache.cc +++ b/src/xenia/gpu/resource_cache.cc @@ -11,6 +11,7 @@ #include +#include using namespace std; using namespace xe; @@ -108,7 +109,7 @@ VertexBufferResource* ResourceCache::FetchVertexBuffer( uint64_t ResourceCache::HashRange(const MemoryRange& memory_range) { // We could do something smarter here to potentially early exit. - return xe_hash64(memory_range.host_base, memory_range.length); + return hash64(memory_range.host_base, memory_range.length); } void ResourceCache::SyncRange(uint32_t address, int length) { diff --git a/src/xenia/gpu/sampler_state_resource.h b/src/xenia/gpu/sampler_state_resource.h index c0a3c4ab3..1a14cef4d 100644 --- a/src/xenia/gpu/sampler_state_resource.h +++ b/src/xenia/gpu/sampler_state_resource.h @@ -10,6 +10,7 @@ #ifndef XENIA_GPU_SAMPLER_STATE_RESOURCE_H_ #define XENIA_GPU_SAMPLER_STATE_RESOURCE_H_ +#include #include #include #include diff --git a/src/xenia/gpu/texture_resource.cc b/src/xenia/gpu/texture_resource.cc index 81857df6f..05ec4f81e 100644 --- a/src/xenia/gpu/texture_resource.cc +++ b/src/xenia/gpu/texture_resource.cc @@ -9,6 +9,7 @@ #include +#include #include #include @@ -253,16 +254,16 @@ void TextureResource::Info::CalculateTextureSizes2D( width_multiple = minimum_multiple; } } - size_2d.input_width = XEROUNDUP(size_2d.logical_width, width_multiple); - size_2d.input_height = XEROUNDUP(size_2d.logical_height, 32); + size_2d.input_width = poly::round_up(size_2d.logical_width, width_multiple); + size_2d.input_height = poly::round_up(size_2d.logical_height, 32); size_2d.output_width = size_2d.logical_width; size_2d.output_height = size_2d.logical_height; } else { // must be 128x128 - size_2d.input_width = XEROUNDUP(size_2d.logical_width, 128); - size_2d.input_height = XEROUNDUP(size_2d.logical_height, 128); - size_2d.output_width = XENEXTPOW2(size_2d.logical_width); - size_2d.output_height = XENEXTPOW2(size_2d.logical_height); + size_2d.input_width = poly::round_up(size_2d.logical_width, 128); + size_2d.input_height = poly::round_up(size_2d.logical_height, 128); + size_2d.output_width = poly::next_pow2(size_2d.logical_width); + size_2d.output_height = poly::next_pow2(size_2d.logical_height); } size_2d.logical_pitch = (size_2d.logical_width / block_size) * texel_pitch; diff --git a/src/xenia/kernel/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl_io.cc index 804e3c98d..9aa4aa1c3 100644 --- a/src/xenia/kernel/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl_io.cc @@ -9,13 +9,14 @@ #include #include -#include +#include #include #include #include #include #include #include +#include namespace xe { diff --git a/src/xenia/kernel/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl_memory.cc index bd34eaa99..85a587946 100644 --- a/src/xenia/kernel/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl_memory.cc @@ -7,6 +7,7 @@ ****************************************************************************** */ +#include #include #include #include @@ -251,8 +252,8 @@ SHIM_CALL MmAllocatePhysicalMemoryEx_shim( } // Round up the region size and alignment to the next page. - uint32_t adjusted_size = XEROUNDUP(region_size, page_size); - uint32_t adjusted_alignment = XEROUNDUP(alignment, page_size); + uint32_t adjusted_size = poly::round_up(region_size, page_size); + uint32_t adjusted_alignment = poly::round_up(alignment, page_size); // Callers can pick an address to allocate with min_addr_range/max_addr_range // and the memory must be allocated there. I haven't seen a game do this, @@ -433,7 +434,7 @@ SHIM_CALL ExAllocatePoolTypeWithTag_shim( uint32_t alignment = 8; uint32_t adjusted_size = size; if (adjusted_size < 4 * 1024) { - adjusted_size = XEROUNDUP(adjusted_size, 4 * 1024); + adjusted_size = poly::round_up(adjusted_size, 4 * 1024); } else { alignment = 4 * 1024; } diff --git a/src/xenia/types.h b/src/xenia/types.h index c15836d9f..f664e6d12 100644 --- a/src/xenia/types.h +++ b/src/xenia/types.h @@ -91,29 +91,10 @@ typedef XECACHEALIGN volatile void xe_aligned_void_t; #define XECOUNT(array) (sizeof(array) / sizeof(array[0])) #endif // MSVC -XEFORCEINLINE size_t hash_combine(size_t seed) { - return seed; -} -template -size_t hash_combine(size_t seed, const T& v, const Ts&... vs) { - std::hash hasher; - seed ^= hasher(v) + 0x9E3779B9 + (seed << 6) + (seed >> 2); - return hash_combine(seed, vs...); -} - #if XE_PLATFORM_WIN32 #define XESAFERELEASE(p) if (p) { p->Release(); } #endif // WIN32 -#define XEBITMASK(a, b) (((unsigned) -1 >> (31 - (b))) & ~((1U << (a)) - 1)) -#define XESELECTBITS(value, a, b) ((value & XEBITMASK(a, b)) >> a) - -#define XEROUNDUP(v, multiple) ((v) + (multiple) - 1 - ((v) - 1) % (multiple)) -static inline uint32_t XENEXTPOW2(uint32_t v) { - v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; -} -#define XEALIGN(value, align) ((value + align - 1) & ~(align - 1)) - #define XEFAIL() goto XECLEANUP #define XEEXPECT(expr) if (!(expr) ) { goto XECLEANUP; } #define XEEXPECTTRUE(expr) if (!(expr) ) { goto XECLEANUP; } From 187d0ad2772be088460ecfa3774a1f2360069f94 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 16 Aug 2014 17:33:24 -0700 Subject: [PATCH 123/388] Removing XESAFERELEASE. --- src/xenia/apu/xaudio2/xaudio2_audio_driver.cc | 2 +- src/xenia/gpu/d3d11/d3d11_buffer_resource.cc | 4 +- src/xenia/gpu/d3d11/d3d11_buffer_resource.h | 4 +- src/xenia/gpu/d3d11/d3d11_geometry_shader.cc | 8 ++-- src/xenia/gpu/d3d11/d3d11_geometry_shader.h | 3 +- src/xenia/gpu/d3d11/d3d11_gpu-private.h | 13 +++--- src/xenia/gpu/d3d11/d3d11_graphics_driver.cc | 40 +++++++++---------- src/xenia/gpu/d3d11/d3d11_graphics_driver.h | 2 - src/xenia/gpu/d3d11/d3d11_graphics_system.cc | 4 +- src/xenia/gpu/d3d11/d3d11_graphics_system.h | 2 - src/xenia/gpu/d3d11/d3d11_profiler_display.cc | 20 +++++----- src/xenia/gpu/d3d11/d3d11_profiler_display.h | 3 +- src/xenia/gpu/d3d11/d3d11_resource_cache.cc | 4 +- src/xenia/gpu/d3d11/d3d11_resource_cache.h | 3 +- .../gpu/d3d11/d3d11_sampler_state_resource.cc | 2 +- .../gpu/d3d11/d3d11_sampler_state_resource.h | 3 +- src/xenia/gpu/d3d11/d3d11_shader_resource.cc | 12 +++--- src/xenia/gpu/d3d11/d3d11_texture_resource.cc | 4 +- src/xenia/gpu/d3d11/d3d11_texture_resource.h | 3 +- src/xenia/gpu/d3d11/d3d11_window.cc | 10 ++--- src/xenia/gpu/d3d11/d3d11_window.h | 3 +- src/xenia/types.h | 4 -- 22 files changed, 70 insertions(+), 83 deletions(-) diff --git a/src/xenia/apu/xaudio2/xaudio2_audio_driver.cc b/src/xenia/apu/xaudio2/xaudio2_audio_driver.cc index 4360ad5f5..e81140463 100644 --- a/src/xenia/apu/xaudio2/xaudio2_audio_driver.cc +++ b/src/xenia/apu/xaudio2/xaudio2_audio_driver.cc @@ -162,7 +162,7 @@ void XAudio2AudioDriver::Shutdown() { mastering_voice_ = NULL; audio_->StopEngine(); - XESAFERELEASE(audio_); + audio_->Release(); delete voice_callback_; CloseHandle(wait_handle_); diff --git a/src/xenia/gpu/d3d11/d3d11_buffer_resource.cc b/src/xenia/gpu/d3d11/d3d11_buffer_resource.cc index 1bb28f81f..9f05c7ec9 100644 --- a/src/xenia/gpu/d3d11/d3d11_buffer_resource.cc +++ b/src/xenia/gpu/d3d11/d3d11_buffer_resource.cc @@ -29,7 +29,7 @@ D3D11IndexBufferResource::D3D11IndexBufferResource( } D3D11IndexBufferResource::~D3D11IndexBufferResource() { - XESAFERELEASE(handle_); + SafeRelease(handle_); } int D3D11IndexBufferResource::CreateHandle() { @@ -95,7 +95,7 @@ D3D11VertexBufferResource::D3D11VertexBufferResource( } D3D11VertexBufferResource::~D3D11VertexBufferResource() { - XESAFERELEASE(handle_); + SafeRelease(handle_); } int D3D11VertexBufferResource::CreateHandle() { diff --git a/src/xenia/gpu/d3d11/d3d11_buffer_resource.h b/src/xenia/gpu/d3d11/d3d11_buffer_resource.h index 2e8071ae1..1860c2e07 100644 --- a/src/xenia/gpu/d3d11/d3d11_buffer_resource.h +++ b/src/xenia/gpu/d3d11/d3d11_buffer_resource.h @@ -11,11 +11,9 @@ #define XENIA_GPU_D3D11_D3D11_BUFFER_RESOURCE_H_ #include +#include #include -#include - - namespace xe { namespace gpu { namespace d3d11 { diff --git a/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc b/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc index 42660b462..e59f9823b 100644 --- a/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc +++ b/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc @@ -31,8 +31,8 @@ D3D11GeometryShader::D3D11GeometryShader(ID3D11Device* device) } D3D11GeometryShader::~D3D11GeometryShader() { - XESAFERELEASE(handle_); - XESAFERELEASE(device_); + SafeRelease(handle_); + SafeRelease(device_); } int D3D11GeometryShader::Prepare(D3D11VertexShaderResource* vertex_shader) { @@ -61,7 +61,7 @@ int D3D11GeometryShader::Prepare(D3D11VertexShaderResource* vertex_shader) { byte_code = xe_malloc(byte_code_length); xe_copy_struct( byte_code, shader_blob->GetBufferPointer(), byte_code_length); - XESAFERELEASE(shader_blob); + SafeRelease(shader_blob); // Create shader. HRESULT hr = device_->CreateGeometryShader( @@ -124,7 +124,7 @@ ID3D10Blob* D3D11GeometryShader::Compile(const char* shader_source) { char* msg = (char*)error_blob->GetBufferPointer(); XELOGE("D3D11: shader compile failed with %s", msg); } - XESAFERELEASE(error_blob); + SafeRelease(error_blob); if (FAILED(hr)) { return NULL; } diff --git a/src/xenia/gpu/d3d11/d3d11_geometry_shader.h b/src/xenia/gpu/d3d11/d3d11_geometry_shader.h index 89529b2a4..7e519f236 100644 --- a/src/xenia/gpu/d3d11/d3d11_geometry_shader.h +++ b/src/xenia/gpu/d3d11/d3d11_geometry_shader.h @@ -13,8 +13,7 @@ #include #include - -#include +#include namespace xe { diff --git a/src/xenia/gpu/d3d11/d3d11_gpu-private.h b/src/xenia/gpu/d3d11/d3d11_gpu-private.h index 7032de896..924e4b144 100644 --- a/src/xenia/gpu/d3d11/d3d11_gpu-private.h +++ b/src/xenia/gpu/d3d11/d3d11_gpu-private.h @@ -12,20 +12,23 @@ #include -#include +#include +#include namespace xe { namespace gpu { namespace d3d11 { - - - +template +void SafeRelease(T* ptr) { + if (ptr) { + ptr->Release(); + } +} } // namespace d3d11 } // namespace gpu } // namespace xe - #endif // XENIA_GPU_D3D11_D3D11_GPU_PRIVATE_H_ diff --git a/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc b/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc index 78e5d703d..31c38880a 100644 --- a/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc +++ b/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc @@ -67,29 +67,29 @@ D3D11GraphicsDriver::D3D11GraphicsDriver( D3D11GraphicsDriver::~D3D11GraphicsDriver() { RebuildRenderTargets(0, 0); - XESAFERELEASE(state_.constant_buffers.float_constants); - XESAFERELEASE(state_.constant_buffers.bool_constants); - XESAFERELEASE(state_.constant_buffers.loop_constants); - XESAFERELEASE(state_.constant_buffers.vs_consts); - XESAFERELEASE(state_.constant_buffers.gs_consts); + SafeRelease(state_.constant_buffers.float_constants); + SafeRelease(state_.constant_buffers.bool_constants); + SafeRelease(state_.constant_buffers.loop_constants); + SafeRelease(state_.constant_buffers.vs_consts); + SafeRelease(state_.constant_buffers.gs_consts); for (auto it = rasterizer_state_cache_.begin(); it != rasterizer_state_cache_.end(); ++it) { - XESAFERELEASE(it->second); + SafeRelease(it->second); } for (auto it = blend_state_cache_.begin(); it != blend_state_cache_.end(); ++it) { - XESAFERELEASE(it->second); + SafeRelease(it->second); } for (auto it = depth_stencil_state_cache_.begin(); it != depth_stencil_state_cache_.end(); ++it) { - XESAFERELEASE(it->second); + SafeRelease(it->second); } - XESAFERELEASE(invalid_texture_view_); - XESAFERELEASE(invalid_texture_sampler_state_); + SafeRelease(invalid_texture_view_); + SafeRelease(invalid_texture_sampler_state_); delete resource_cache_; - XESAFERELEASE(context_); - XESAFERELEASE(device_); - XESAFERELEASE(swap_chain_); + SafeRelease(context_); + SafeRelease(device_); + SafeRelease(swap_chain_); } int D3D11GraphicsDriver::Initialize() { @@ -138,7 +138,7 @@ void D3D11GraphicsDriver::InitializeInvalidTexture() { texture_view_desc.Texture2D.MostDetailedMip = 0; hr = device_->CreateShaderResourceView( texture, &texture_view_desc, &invalid_texture_view_); - XESAFERELEASE(texture); + SafeRelease(texture); D3D11_SAMPLER_DESC sampler_desc; xe_zero_struct(&sampler_desc, sizeof(sampler_desc)); @@ -826,12 +826,12 @@ int D3D11GraphicsDriver::RebuildRenderTargets(uint32_t width, // Remove old versions. for (int n = 0; n < XECOUNT(render_targets_.color_buffers); n++) { auto& cb = render_targets_.color_buffers[n]; - XESAFERELEASE(cb.buffer); - XESAFERELEASE(cb.color_view_8888); + SafeRelease(cb.buffer); + SafeRelease(cb.color_view_8888); } - XESAFERELEASE(render_targets_.depth_buffer); - XESAFERELEASE(render_targets_.depth_view_d28s8); - XESAFERELEASE(render_targets_.depth_view_d28fs8); + SafeRelease(render_targets_.depth_buffer); + SafeRelease(render_targets_.depth_view_d28s8); + SafeRelease(render_targets_.depth_view_d28fs8); render_targets_.width = width; render_targets_.height = height; @@ -917,7 +917,7 @@ int D3D11GraphicsDriver::Resolve() { } else { // TODO(benvanik): scale size using a quad draw. } - XESAFERELEASE(back_buffer); + SafeRelease(back_buffer); // TODO(benvanik): remove! float color[4] = { 0.5f, 0.5f, 0.0f, 1.0f }; diff --git a/src/xenia/gpu/d3d11/d3d11_graphics_driver.h b/src/xenia/gpu/d3d11/d3d11_graphics_driver.h index 2d23b142f..568d08478 100644 --- a/src/xenia/gpu/d3d11/d3d11_graphics_driver.h +++ b/src/xenia/gpu/d3d11/d3d11_graphics_driver.h @@ -17,8 +17,6 @@ #include #include -#include - namespace xe { namespace gpu { diff --git a/src/xenia/gpu/d3d11/d3d11_graphics_system.cc b/src/xenia/gpu/d3d11/d3d11_graphics_system.cc index e6fb9454f..9942ce0b6 100644 --- a/src/xenia/gpu/d3d11/d3d11_graphics_system.cc +++ b/src/xenia/gpu/d3d11/d3d11_graphics_system.cc @@ -188,9 +188,9 @@ void D3D11GraphicsSystem::Shutdown() { DeleteTimerQueueEx(timer_queue_, NULL); } - XESAFERELEASE(device_); + SafeRelease(device_); device_ = 0; - XESAFERELEASE(dxgi_factory_); + SafeRelease(dxgi_factory_); dxgi_factory_ = 0; delete window_; window_ = 0; diff --git a/src/xenia/gpu/d3d11/d3d11_graphics_system.h b/src/xenia/gpu/d3d11/d3d11_graphics_system.h index 7bd641667..487e21821 100644 --- a/src/xenia/gpu/d3d11/d3d11_graphics_system.h +++ b/src/xenia/gpu/d3d11/d3d11_graphics_system.h @@ -15,8 +15,6 @@ #include #include -#include - namespace xe { namespace gpu { diff --git a/src/xenia/gpu/d3d11/d3d11_profiler_display.cc b/src/xenia/gpu/d3d11/d3d11_profiler_display.cc index 3fed309e0..9d0bcde7f 100644 --- a/src/xenia/gpu/d3d11/d3d11_profiler_display.cc +++ b/src/xenia/gpu/d3d11/d3d11_profiler_display.cc @@ -369,7 +369,7 @@ bool D3D11ProfilerDisplay::SetupFont() { texture_view_desc.Texture2D.MostDetailedMip = 0; hr = device->CreateShaderResourceView( font_texture, &texture_view_desc, &font_texture_view_); - XESAFERELEASE(font_texture); + SafeRelease(font_texture); if (FAILED(hr)) { XELOGE("Unable to create profiler font texture view"); return false; @@ -403,15 +403,15 @@ bool D3D11ProfilerDisplay::SetupFont() { } D3D11ProfilerDisplay::~D3D11ProfilerDisplay() { - XESAFERELEASE(blend_state_); - XESAFERELEASE(depth_stencil_state_); - XESAFERELEASE(vertex_shader_); - XESAFERELEASE(pixel_shader_); - XESAFERELEASE(shader_constants_); - XESAFERELEASE(shader_layout_); - XESAFERELEASE(font_texture_view_); - XESAFERELEASE(font_sampler_state_); - XESAFERELEASE(vertex_buffer_); + SafeRelease(blend_state_); + SafeRelease(depth_stencil_state_); + SafeRelease(vertex_shader_); + SafeRelease(pixel_shader_); + SafeRelease(shader_constants_); + SafeRelease(shader_layout_); + SafeRelease(font_texture_view_); + SafeRelease(font_sampler_state_); + SafeRelease(vertex_buffer_); } uint32_t D3D11ProfilerDisplay::width() const { diff --git a/src/xenia/gpu/d3d11/d3d11_profiler_display.h b/src/xenia/gpu/d3d11/d3d11_profiler_display.h index fd9f970f9..24489f8b7 100644 --- a/src/xenia/gpu/d3d11/d3d11_profiler_display.h +++ b/src/xenia/gpu/d3d11/d3d11_profiler_display.h @@ -11,8 +11,7 @@ #define XENIA_GPU_D3D11_D3D11_PROFILER_DISPLAY_H_ #include - -#include +#include namespace xe { diff --git a/src/xenia/gpu/d3d11/d3d11_resource_cache.cc b/src/xenia/gpu/d3d11/d3d11_resource_cache.cc index 145e3d395..aaab4148e 100644 --- a/src/xenia/gpu/d3d11/d3d11_resource_cache.cc +++ b/src/xenia/gpu/d3d11/d3d11_resource_cache.cc @@ -31,8 +31,8 @@ D3D11ResourceCache::D3D11ResourceCache(Memory* memory, } D3D11ResourceCache::~D3D11ResourceCache() { - XESAFERELEASE(device_); - XESAFERELEASE(context_); + SafeRelease(device_); + SafeRelease(context_); } VertexShaderResource* D3D11ResourceCache::CreateVertexShader( diff --git a/src/xenia/gpu/d3d11/d3d11_resource_cache.h b/src/xenia/gpu/d3d11/d3d11_resource_cache.h index 27248eb9c..064d6ca46 100644 --- a/src/xenia/gpu/d3d11/d3d11_resource_cache.h +++ b/src/xenia/gpu/d3d11/d3d11_resource_cache.h @@ -12,10 +12,9 @@ #include +#include #include -#include - namespace xe { namespace gpu { diff --git a/src/xenia/gpu/d3d11/d3d11_sampler_state_resource.cc b/src/xenia/gpu/d3d11/d3d11_sampler_state_resource.cc index 7fb09858a..1f9971ae4 100644 --- a/src/xenia/gpu/d3d11/d3d11_sampler_state_resource.cc +++ b/src/xenia/gpu/d3d11/d3d11_sampler_state_resource.cc @@ -27,7 +27,7 @@ D3D11SamplerStateResource::D3D11SamplerStateResource( } D3D11SamplerStateResource::~D3D11SamplerStateResource() { - XESAFERELEASE(handle_); + SafeRelease(handle_); } int D3D11SamplerStateResource::Prepare() { diff --git a/src/xenia/gpu/d3d11/d3d11_sampler_state_resource.h b/src/xenia/gpu/d3d11/d3d11_sampler_state_resource.h index 6097339b4..35447dbc9 100644 --- a/src/xenia/gpu/d3d11/d3d11_sampler_state_resource.h +++ b/src/xenia/gpu/d3d11/d3d11_sampler_state_resource.h @@ -10,12 +10,11 @@ #ifndef XENIA_GPU_D3D11_D3D11_SAMPLER_STATE_RESOURCE_H_ #define XENIA_GPU_D3D11_D3D11_SAMPLER_STATE_RESOURCE_H_ +#include #include #include #include -#include - namespace xe { namespace gpu { diff --git a/src/xenia/gpu/d3d11/d3d11_shader_resource.cc b/src/xenia/gpu/d3d11/d3d11_shader_resource.cc index a2371a282..ed95ee39b 100644 --- a/src/xenia/gpu/d3d11/d3d11_shader_resource.cc +++ b/src/xenia/gpu/d3d11/d3d11_shader_resource.cc @@ -80,7 +80,7 @@ ID3D10Blob* D3D11ShaderCompile(XE_GPU_SHADER_TYPE type, char* msg = (char*)error_blob->GetBufferPointer(); XELOGE("D3D11: shader compile failed with %s", msg); } - XESAFERELEASE(error_blob); + SafeRelease(error_blob); if (FAILED(hr)) { return nullptr; } @@ -103,8 +103,8 @@ D3D11VertexShaderResource::D3D11VertexShaderResource( } D3D11VertexShaderResource::~D3D11VertexShaderResource() { - XESAFERELEASE(handle_); - XESAFERELEASE(input_layout_); + SafeRelease(handle_); + SafeRelease(input_layout_); for (int i = 0; i < XECOUNT(geometry_shaders_); ++i) { delete geometry_shaders_[i]; } @@ -140,7 +140,7 @@ int D3D11VertexShaderResource::Prepare( byte_code = xe_malloc(byte_code_length); xe_copy_struct( byte_code, shader_blob->GetBufferPointer(), byte_code_length); - XESAFERELEASE(shader_blob); + SafeRelease(shader_blob); // Create shader. HRESULT hr = resource_cache_->device()->CreateVertexShader( @@ -328,7 +328,7 @@ D3D11PixelShaderResource::D3D11PixelShaderResource( } D3D11PixelShaderResource::~D3D11PixelShaderResource() { - XESAFERELEASE(handle_); + SafeRelease(handle_); xe_free(translated_src_); } @@ -363,7 +363,7 @@ int D3D11PixelShaderResource::Prepare(const xe_gpu_program_cntl_t& program_cntl, byte_code = xe_malloc(byte_code_length); xe_copy_struct( byte_code, shader_blob->GetBufferPointer(), byte_code_length); - XESAFERELEASE(shader_blob); + SafeRelease(shader_blob); // Create shader. HRESULT hr = resource_cache_->device()->CreatePixelShader( diff --git a/src/xenia/gpu/d3d11/d3d11_texture_resource.cc b/src/xenia/gpu/d3d11/d3d11_texture_resource.cc index 301638ffd..201d86f56 100644 --- a/src/xenia/gpu/d3d11/d3d11_texture_resource.cc +++ b/src/xenia/gpu/d3d11/d3d11_texture_resource.cc @@ -30,8 +30,8 @@ D3D11TextureResource::D3D11TextureResource( } D3D11TextureResource::~D3D11TextureResource() { - XESAFERELEASE(texture_); - XESAFERELEASE(handle_); + SafeRelease(texture_); + SafeRelease(handle_); } int D3D11TextureResource::CreateHandle() { diff --git a/src/xenia/gpu/d3d11/d3d11_texture_resource.h b/src/xenia/gpu/d3d11/d3d11_texture_resource.h index 4e59662a4..9ca3bd0e5 100644 --- a/src/xenia/gpu/d3d11/d3d11_texture_resource.h +++ b/src/xenia/gpu/d3d11/d3d11_texture_resource.h @@ -10,11 +10,10 @@ #ifndef XENIA_GPU_D3D11_D3D11_TEXTURE_RESOURCE_H_ #define XENIA_GPU_D3D11_D3D11_TEXTURE_RESOURCE_H_ +#include #include #include -#include - namespace xe { namespace gpu { diff --git a/src/xenia/gpu/d3d11/d3d11_window.cc b/src/xenia/gpu/d3d11/d3d11_window.cc index 7b4fa5cbd..192e87225 100644 --- a/src/xenia/gpu/d3d11/d3d11_window.cc +++ b/src/xenia/gpu/d3d11/d3d11_window.cc @@ -42,11 +42,11 @@ D3D11Window::~D3D11Window() { if (context_) { context_->ClearState(); } - XESAFERELEASE(render_target_view_); - XESAFERELEASE(context_); - XESAFERELEASE(swap_chain_); - XESAFERELEASE(device_); - XESAFERELEASE(dxgi_factory_); + SafeRelease(render_target_view_); + SafeRelease(context_); + SafeRelease(swap_chain_); + SafeRelease(device_); + SafeRelease(dxgi_factory_); } int D3D11Window::Initialize(const std::wstring& title, uint32_t width, diff --git a/src/xenia/gpu/d3d11/d3d11_window.h b/src/xenia/gpu/d3d11/d3d11_window.h index 888a797ae..8c6d92052 100644 --- a/src/xenia/gpu/d3d11/d3d11_window.h +++ b/src/xenia/gpu/d3d11/d3d11_window.h @@ -12,10 +12,9 @@ #include +#include #include -#include - namespace xe { namespace gpu { diff --git a/src/xenia/types.h b/src/xenia/types.h index f664e6d12..3d4209a24 100644 --- a/src/xenia/types.h +++ b/src/xenia/types.h @@ -91,10 +91,6 @@ typedef XECACHEALIGN volatile void xe_aligned_void_t; #define XECOUNT(array) (sizeof(array) / sizeof(array[0])) #endif // MSVC -#if XE_PLATFORM_WIN32 -#define XESAFERELEASE(p) if (p) { p->Release(); } -#endif // WIN32 - #define XEFAIL() goto XECLEANUP #define XEEXPECT(expr) if (!(expr) ) { goto XECLEANUP; } #define XEEXPECTTRUE(expr) if (!(expr) ) { goto XECLEANUP; } From f2a9fa3bf9e68ad0bd3e95d1afa553eeeb9cc094 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 16 Aug 2014 17:58:33 -0700 Subject: [PATCH 124/388] XECOUNT to countof. --- src/alloy/backend/x64/x64_sequences.cc | 4 +- .../passes/register_allocation_pass.cc | 8 +-- src/alloy/frontend/ppc/ppc_disasm.cc | 6 +-- src/alloy/frontend/ppc/ppc_hir_builder.cc | 3 +- src/alloy/frontend/ppc/ppc_instr.cc | 4 +- src/alloy/frontend/ppc/ppc_instr_tables.h | 27 +++++----- src/poly/math.h | 5 ++ src/xenia/apu/audio_system.cc | 48 ++++++++--------- src/xenia/core/socket_win.cc | 7 ++- src/xenia/cpu/xenon_memory.cc | 6 +-- src/xenia/cpu/xex_module.cc | 35 +++++++------ src/xenia/export_resolver.cc | 3 +- src/xenia/gpu/d3d11/d3d11_geometry_shader.cc | 3 +- src/xenia/gpu/d3d11/d3d11_graphics_driver.cc | 33 ++++++------ src/xenia/gpu/d3d11/d3d11_graphics_system.cc | 3 +- src/xenia/gpu/d3d11/d3d11_profiler_display.cc | 52 ++++++++++++------- src/xenia/gpu/d3d11/d3d11_shader_resource.cc | 5 +- src/xenia/gpu/graphics_system.cc | 4 +- src/xenia/gpu/shader_resource.cc | 7 +-- .../kernel/fs/devices/disc_image_device.cc | 7 +-- .../fs/devices/stfs_container_device.cc | 7 +-- src/xenia/kernel/fs/gdfx.cc | 3 +- src/xenia/kernel/objects/xthread.cc | 31 +++++------ src/xenia/kernel/util/export_table_pre.inc | 2 +- src/xenia/kernel/util/xex2.cc | 7 +-- src/xenia/kernel/xam_module.cc | 3 +- src/xenia/kernel/xboxkrnl_module.cc | 8 +-- src/xenia/logging.cc | 5 +- src/xenia/types.h | 9 ---- tools/xenia-run/xenia-run.cc | 25 ++++----- 30 files changed, 195 insertions(+), 175 deletions(-) diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index f5709d0d8..fed77e3a4 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -1017,7 +1017,7 @@ EMITTER(LOAD_VECTOR_SHL_I8, MATCH(I, I8<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { if (i.src1.is_constant) { auto sh = i.src1.constant(); - assert_true(sh < XECOUNT(lvsl_table)); + assert_true(sh < poly::countof(lvsl_table)); e.mov(e.rax, (uintptr_t)&lvsl_table[sh]); e.vmovaps(i.dest, e.ptr[e.rax]); } else { @@ -1069,7 +1069,7 @@ EMITTER(LOAD_VECTOR_SHR_I8, MATCH(I, I8<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { if (i.src1.is_constant) { auto sh = i.src1.constant(); - assert_true(sh < XECOUNT(lvsr_table)); + assert_true(sh < poly::countof(lvsr_table)); e.mov(e.rax, (uintptr_t)&lvsr_table[sh]); e.vmovaps(i.dest, e.ptr[e.rax]); } else { diff --git a/src/alloy/compiler/passes/register_allocation_pass.cc b/src/alloy/compiler/passes/register_allocation_pass.cc index 2175765c2..cdfe910ad 100644 --- a/src/alloy/compiler/passes/register_allocation_pass.cc +++ b/src/alloy/compiler/passes/register_allocation_pass.cc @@ -55,7 +55,7 @@ RegisterAllocationPass::RegisterAllocationPass(const MachineInfo* machine_info) } RegisterAllocationPass::~RegisterAllocationPass() { - for (size_t n = 0; n < XECOUNT(usage_sets_.all_sets); n++) { + for (size_t n = 0; n < poly::countof(usage_sets_.all_sets); n++) { if (!usage_sets_.all_sets[n]) { break; } @@ -171,7 +171,7 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) { void RegisterAllocationPass::DumpUsage(const char* name) { #if 0 fprintf(stdout, "\n%s:\n", name); - for (size_t i = 0; i < XECOUNT(usage_sets_.all_sets); ++i) { + for (size_t i = 0; i < poly::countof(usage_sets_.all_sets); ++i) { auto usage_set = usage_sets_.all_sets[i]; if (usage_set) { fprintf(stdout, "set %s:\n", usage_set->set->name); @@ -190,7 +190,7 @@ void RegisterAllocationPass::DumpUsage(const char* name) { } void RegisterAllocationPass::PrepareBlockState() { - for (size_t i = 0; i < XECOUNT(usage_sets_.all_sets); ++i) { + for (size_t i = 0; i < poly::countof(usage_sets_.all_sets); ++i) { auto usage_set = usage_sets_.all_sets[i]; if (usage_set) { usage_set->availability.set(); @@ -201,7 +201,7 @@ void RegisterAllocationPass::PrepareBlockState() { } void RegisterAllocationPass::AdvanceUses(Instr* instr) { - for (size_t i = 0; i < XECOUNT(usage_sets_.all_sets); ++i) { + for (size_t i = 0; i < poly::countof(usage_sets_.all_sets); ++i) { auto usage_set = usage_sets_.all_sets[i]; if (!usage_set) { break; diff --git a/src/alloy/frontend/ppc/ppc_disasm.cc b/src/alloy/frontend/ppc/ppc_disasm.cc index 94fd1325e..726e5486e 100644 --- a/src/alloy/frontend/ppc/ppc_disasm.cc +++ b/src/alloy/frontend/ppc/ppc_disasm.cc @@ -294,7 +294,7 @@ void Disasm_bcx(InstrData& i, StringBuffer* str) { } char s2[8] = {0}; if (!select_bits(i.B.BO, 4, 4)) { - xesnprintfa(s2, XECOUNT(s2), "cr%d, ", i.B.BI >> 2); + xesnprintfa(s2, poly::countof(s2), "cr%d, ", i.B.BI >> 2); } uint32_t nia; if (i.B.AA) { @@ -310,7 +310,7 @@ void Disasm_bcctrx(InstrData& i, StringBuffer* str) { const char* s0 = i.XL.LK ? "lr, " : ""; char s2[8] = {0}; if (!select_bits(i.XL.BO, 4, 4)) { - xesnprintfa(s2, XECOUNT(s2), "cr%d, ", i.XL.BI >> 2); + xesnprintfa(s2, poly::countof(s2), "cr%d, ", i.XL.BI >> 2); } str->Append("%-8s %s%sctr", i.type->name, s0, s2); // TODO(benvanik): resolve target name? @@ -328,7 +328,7 @@ void Disasm_bclrx(InstrData& i, StringBuffer* str) { } char s2[8] = {0}; if (!select_bits(i.XL.BO, 4, 4)) { - xesnprintfa(s2, XECOUNT(s2), "cr%d, ", i.XL.BI >> 2); + xesnprintfa(s2, poly::countof(s2), "cr%d, ", i.XL.BI >> 2); } str->Append("%-8s %s%s", name, s1, s2); } diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index 660ac1107..a426dd257 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -168,7 +168,8 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) { void PPCHIRBuilder::AnnotateLabel(uint64_t address, Label* label) { char name_buffer[13]; - xesnprintfa(name_buffer, XECOUNT(name_buffer), "loc_%.8X", (uint32_t)address); + xesnprintfa(name_buffer, poly::countof(name_buffer), "loc_%.8X", + (uint32_t)address); label->name = (char*)arena_->Alloc(sizeof(name_buffer)); xe_copy_struct(label->name, name_buffer, sizeof(name_buffer)); } diff --git a/src/alloy/frontend/ppc/ppc_instr.cc b/src/alloy/frontend/ppc/ppc_instr.cc index 43b52d759..0410a1502 100644 --- a/src/alloy/frontend/ppc/ppc_instr.cc +++ b/src/alloy/frontend/ppc/ppc_instr.cc @@ -25,7 +25,7 @@ void InstrOperand::Dump(std::string& out_str) { } char buffer[32]; - const size_t max_count = XECOUNT(buffer); + const size_t max_count = poly::countof(buffer); switch (type) { case InstrOperand::kRegister: switch (reg.set) { @@ -373,7 +373,7 @@ InstrType* GetInstrType(uint32_t code) { // Slow lookup via linear scan. // This is primarily due to laziness. It could be made fast like the others. for (size_t n = 0; - n < XECOUNT(alloy::frontend::ppc::tables::instr_table_scan); n++) { + n < poly::countof(alloy::frontend::ppc::tables::instr_table_scan); n++) { slot = &(alloy::frontend::ppc::tables::instr_table_scan[n]); if (slot->opcode == (code & slot->opcode_mask)) { return slot; diff --git a/src/alloy/frontend/ppc/ppc_instr_tables.h b/src/alloy/frontend/ppc/ppc_instr_tables.h index 65f1ddc49..ccab23c49 100644 --- a/src/alloy/frontend/ppc/ppc_instr_tables.h +++ b/src/alloy/frontend/ppc/ppc_instr_tables.h @@ -13,6 +13,7 @@ #include #include +#include namespace alloy { namespace frontend { @@ -91,8 +92,8 @@ void Disasm_vspltisw(InstrData& i, StringBuffer* str); namespace tables { -static InstrType** instr_table_prep(InstrType* unprep, int unprep_count, int a, - int b) { +static InstrType** instr_table_prep(InstrType* unprep, size_t unprep_count, + int a, int b) { int prep_count = (int)pow(2.0, b - a + 1); InstrType** prep = (InstrType**)xe_calloc(prep_count * sizeof(void*)); for (int n = 0; n < unprep_count; n++) { @@ -102,7 +103,7 @@ static InstrType** instr_table_prep(InstrType* unprep, int unprep_count, int a, return prep; } -static InstrType** instr_table_prep_63(InstrType* unprep, int unprep_count, +static InstrType** instr_table_prep_63(InstrType* unprep, size_t unprep_count, int a, int b) { // Special handling for A format instructions. int prep_count = (int)pow(2.0, b - a + 1); @@ -362,7 +363,7 @@ static InstrType instr_table_4_unprep[] = { "Vector Logical XOR"), }; static InstrType** instr_table_4 = instr_table_prep( - instr_table_4_unprep, XECOUNT(instr_table_4_unprep), 0, 11); + instr_table_4_unprep, poly::countof(instr_table_4_unprep), 0, 11); // Opcode = 19, index = bits 10-1 (10) static InstrType instr_table_19_unprep[] = { @@ -382,7 +383,7 @@ static InstrType instr_table_19_unprep[] = { "Branch Conditional to Count Register"), }; static InstrType** instr_table_19 = instr_table_prep( - instr_table_19_unprep, XECOUNT(instr_table_19_unprep), 1, 10); + instr_table_19_unprep, poly::countof(instr_table_19_unprep), 1, 10); // Opcode = 30, index = bits 4-1 (4) static InstrType instr_table_30_unprep[] = { @@ -398,7 +399,7 @@ static InstrType instr_table_30_unprep[] = { // INSTRUCTION(rldcrx, 0x78000012, MDS, General , 0), }; static InstrType** instr_table_30 = instr_table_prep( - instr_table_30_unprep, XECOUNT(instr_table_30_unprep), 0, 0); + instr_table_30_unprep, poly::countof(instr_table_30_unprep), 0, 0); // Opcode = 31, index = bits 10-1 (10) static InstrType instr_table_31_unprep[] = { @@ -645,7 +646,7 @@ static InstrType instr_table_31_unprep[] = { "Store Vector Right Indexed LRU"), }; static InstrType** instr_table_31 = instr_table_prep( - instr_table_31_unprep, XECOUNT(instr_table_31_unprep), 1, 10); + instr_table_31_unprep, poly::countof(instr_table_31_unprep), 1, 10); // Opcode = 58, index = bits 1-0 (2) static InstrType instr_table_58_unprep[] = { @@ -656,7 +657,7 @@ static InstrType instr_table_58_unprep[] = { "Load Word Algebraic"), }; static InstrType** instr_table_58 = instr_table_prep( - instr_table_58_unprep, XECOUNT(instr_table_58_unprep), 0, 1); + instr_table_58_unprep, poly::countof(instr_table_58_unprep), 0, 1); // Opcode = 59, index = bits 5-1 (5) static InstrType instr_table_59_unprep[] = { @@ -682,7 +683,7 @@ static InstrType instr_table_59_unprep[] = { "Floating Negative Multiply-Add [Single]"), }; static InstrType** instr_table_59 = instr_table_prep( - instr_table_59_unprep, XECOUNT(instr_table_59_unprep), 1, 5); + instr_table_59_unprep, poly::countof(instr_table_59_unprep), 1, 5); // Opcode = 62, index = bits 1-0 (2) static InstrType instr_table_62_unprep[] = { @@ -691,7 +692,7 @@ static InstrType instr_table_62_unprep[] = { "Store Doubleword with Update"), }; static InstrType** instr_table_62 = instr_table_prep( - instr_table_62_unprep, XECOUNT(instr_table_62_unprep), 0, 1); + instr_table_62_unprep, poly::countof(instr_table_62_unprep), 0, 1); // Opcode = 63, index = bits 10-1 (10) // NOTE: the A format instructions need some special handling because @@ -751,7 +752,7 @@ static InstrType instr_table_63_unprep[] = { "Floating Convert From Integer Doubleword"), }; static InstrType** instr_table_63 = instr_table_prep_63( - instr_table_63_unprep, XECOUNT(instr_table_63_unprep), 1, 10); + instr_table_63_unprep, poly::countof(instr_table_63_unprep), 1, 10); // Main table, index = bits 31-26 (6) : (code >> 26) static InstrType instr_table_unprep[64] = { @@ -830,8 +831,8 @@ static InstrType instr_table_unprep[64] = { INSTRUCTION(stfdu, 0xDC000000, D, General, D_FRT_RA_I, "Store Floating-Point Double with Update"), }; -static InstrType** instr_table = - instr_table_prep(instr_table_unprep, XECOUNT(instr_table_unprep), 26, 31); +static InstrType** instr_table = instr_table_prep( + instr_table_unprep, poly::countof(instr_table_unprep), 26, 31); // Altivec instructions. // TODO(benvanik): build a table like the other instructions. diff --git a/src/poly/math.h b/src/poly/math.h index 69a8597d3..1b059c53d 100644 --- a/src/poly/math.h +++ b/src/poly/math.h @@ -20,6 +20,11 @@ namespace poly { +template +size_t countof(T (&arr)[N]) { + return std::extent::value; +} + // Rounds up the given value to the given alignment. template T align(T value, T alignment) { diff --git a/src/xenia/apu/audio_system.cc b/src/xenia/apu/audio_system.cc index c61e1fe84..bf73c5d90 100644 --- a/src/xenia/apu/audio_system.cc +++ b/src/xenia/apu/audio_system.cc @@ -10,20 +10,17 @@ #include #include -#include +#include #include #include #include - using namespace xe; using namespace xe::apu; using namespace xe::cpu; - -AudioSystem::AudioSystem(Emulator* emulator) : - emulator_(emulator), memory_(emulator->memory()), - running_(false) { +AudioSystem::AudioSystem(Emulator* emulator) + : emulator_(emulator), memory_(emulator->memory()), running_(false) { memset(clients_, 0, sizeof(clients_)); for (size_t i = 0; i < maximum_client_count_; ++i) { client_wait_handles_[i] = CreateEvent(NULL, TRUE, FALSE, NULL); @@ -42,19 +39,16 @@ X_STATUS AudioSystem::Setup() { // Let the processor know we want register access callbacks. emulator_->memory()->AddMappedRange( - 0x7FEA0000, - 0xFFFF0000, - 0x0000FFFF, - this, + 0x7FEA0000, 0xFFFF0000, 0x0000FFFF, this, reinterpret_cast(MMIOReadRegisterThunk), reinterpret_cast(MMIOWriteRegisterThunk)); // Setup worker thread state. This lets us make calls into guest code. - thread_state_ = new XenonThreadState( - emulator_->processor()->runtime(), 0, 16 * 1024, 0); + thread_state_ = + new XenonThreadState(emulator_->processor()->runtime(), 0, 16 * 1024, 0); thread_state_->set_name("Audio Worker"); - thread_block_ = (uint32_t)memory_->HeapAlloc( - 0, 2048, alloy::MEMORY_FLAG_ZERO); + thread_block_ = + (uint32_t)memory_->HeapAlloc(0, 2048, alloy::MEMORY_FLAG_ZERO); thread_state_->context()->r[13] = thread_block_; // Create worker thread. @@ -78,7 +72,8 @@ void AudioSystem::ThreadStart() { // Main run loop. while (running_) { - auto result = WaitForMultipleObjectsEx(maximum_client_count_, client_wait_handles_, FALSE, INFINITE, FALSE); + auto result = WaitForMultipleObjectsEx( + maximum_client_count_, client_wait_handles_, FALSE, INFINITE, FALSE); if (result == WAIT_FAILED) { DWORD err = GetLastError(); assert_always(); @@ -86,7 +81,8 @@ void AudioSystem::ThreadStart() { } size_t pumped = 0; - if (result >= WAIT_OBJECT_0 && result <= WAIT_OBJECT_0 + (maximum_client_count_ - 1)) { + if (result >= WAIT_OBJECT_0 && + result <= WAIT_OBJECT_0 + (maximum_client_count_ - 1)) { size_t index = result - WAIT_OBJECT_0; do { lock_.lock(); @@ -94,12 +90,15 @@ void AudioSystem::ThreadStart() { uint32_t client_callback_arg = clients_[index].wrapped_callback_arg; lock_.unlock(); if (client_callback) { - uint64_t args[] = { client_callback_arg }; - processor->Execute(thread_state_, client_callback, args, XECOUNT(args)); + uint64_t args[] = {client_callback_arg}; + processor->Execute(thread_state_, client_callback, args, + poly::countof(args)); } pumped++; index++; - } while (index < maximum_client_count_ && WaitForSingleObject(client_wait_handles_[index], 0) == WAIT_OBJECT_0); + } while (index < maximum_client_count_ && + WaitForSingleObject(client_wait_handles_[index], 0) == + WAIT_OBJECT_0); } if (!running_) { @@ -118,8 +117,7 @@ void AudioSystem::ThreadStart() { xe::Profiler::ThreadExit(); } -void AudioSystem::Initialize() { -} +void AudioSystem::Initialize() {} void AudioSystem::Shutdown() { running_ = false; @@ -129,8 +127,8 @@ void AudioSystem::Shutdown() { memory()->HeapFree(thread_block_, 0); } -X_STATUS AudioSystem::RegisterClient( - uint32_t callback, uint32_t callback_arg, size_t* out_index) { +X_STATUS AudioSystem::RegisterClient(uint32_t callback, uint32_t callback_arg, + size_t* out_index) { assert_true(unused_clients_.size()); std::lock_guard lock(lock_); @@ -151,7 +149,7 @@ X_STATUS AudioSystem::RegisterClient( auto mem = memory()->membase(); poly::store_and_swap(mem + ptr, callback_arg); - clients_[index] = { driver, callback, callback_arg, ptr }; + clients_[index] = {driver, callback, callback_arg, ptr}; if (out_index) { *out_index = index; @@ -176,7 +174,7 @@ void AudioSystem::UnregisterClient(size_t index) { std::lock_guard lock(lock_); assert_true(index < maximum_client_count_); DestroyDriver(clients_[index].driver); - clients_[index] = { 0 }; + clients_[index] = {0}; unused_clients_.push(index); } diff --git a/src/xenia/core/socket_win.cc b/src/xenia/core/socket_win.cc index 0adc79f9e..c95b231d8 100644 --- a/src/xenia/core/socket_win.cc +++ b/src/xenia/core/socket_win.cc @@ -9,6 +9,8 @@ #include +#include + #include #include #include @@ -121,7 +123,7 @@ int xe_socket_accept(socket_t socket, xe_socket_connection_t* out_client_info) { int client_ip = client_addr.sin_addr.s_addr; inet_ntop(AF_INET, &client_ip, - out_client_info->addr, XECOUNT(out_client_info->addr)); + out_client_info->addr, poly::countof(out_client_info->addr)); return 0; } @@ -250,7 +252,8 @@ int xe_socket_loop_poll(xe_socket_loop_t* loop, } // Poll. - int r = WSAPoll(loop->events, XECOUNT(loop->events), -1); + int r = WSAPoll(loop->events, static_cast(poly::countof(loop->events)), + -1); if (r == -1) { return 1; } diff --git a/src/xenia/cpu/xenon_memory.cc b/src/xenia/cpu/xenon_memory.cc index c8f73064c..9c95609b5 100644 --- a/src/xenia/cpu/xenon_memory.cc +++ b/src/xenia/cpu/xenon_memory.cc @@ -243,8 +243,8 @@ const static struct { 0xE0000000, 0xFFFFFFFF, 0x00000000, // - physical 4k pages }; int XenonMemory::MapViews(uint8_t* mapping_base) { - assert_true(XECOUNT(map_info) == XECOUNT(views_.all_views)); - for (size_t n = 0; n < XECOUNT(map_info); n++) { + assert_true(poly::countof(map_info) == poly::countof(views_.all_views)); + for (size_t n = 0; n < poly::countof(map_info); n++) { #if XE_PLATFORM_WIN32 views_.all_views[n] = reinterpret_cast(MapViewOfFileEx( mapping_, @@ -268,7 +268,7 @@ XECLEANUP: } void XenonMemory::UnmapViews() { - for (size_t n = 0; n < XECOUNT(views_.all_views); n++) { + for (size_t n = 0; n < poly::countof(views_.all_views); n++) { if (views_.all_views[n]) { #if XE_PLATFORM_WIN32 UnmapViewOfFile(views_.all_views[n]); diff --git a/src/xenia/cpu/xex_module.cc b/src/xenia/cpu/xex_module.cc index d2c0b0957..05bc443ef 100644 --- a/src/xenia/cpu/xex_module.cc +++ b/src/xenia/cpu/xex_module.cc @@ -11,6 +11,7 @@ #include +#include #include #include #include @@ -113,12 +114,12 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) { if (kernel_export) { if (info->thunk_address) { - xesnprintfa(name, XECOUNT(name), "__imp_%s", kernel_export->name); + xesnprintfa(name, poly::countof(name), "__imp_%s", kernel_export->name); } else { - xesnprintfa(name, XECOUNT(name), "%s", kernel_export->name); + xesnprintfa(name, poly::countof(name), "%s", kernel_export->name); } } else { - xesnprintfa(name, XECOUNT(name), "__imp_%s_%.3X", library->name, + xesnprintfa(name, poly::countof(name), "__imp_%s_%.3X", library->name, info->ordinal); } @@ -158,10 +159,10 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) { if (info->thunk_address) { if (kernel_export) { - xesnprintfa(name, XECOUNT(name), "%s", kernel_export->name); + xesnprintfa(name, poly::countof(name), "%s", kernel_export->name); } else { - xesnprintfa(name, XECOUNT(name), "__kernel_%s_%.3X", library->name, - info->ordinal); + xesnprintfa(name, poly::countof(name), "__kernel_%s_%.3X", + library->name, info->ordinal); } // On load we have something like this in memory: @@ -398,17 +399,17 @@ int XexModule::FindSaveRest() { if (!gplr_start) { gplr_start = memory_->SearchAligned( start_address, end_address, - gprlr_code_values, XECOUNT(gprlr_code_values)); + gprlr_code_values, poly::countof(gprlr_code_values)); } if (!fpr_start) { fpr_start = memory_->SearchAligned( start_address, end_address, - fpr_code_values, XECOUNT(fpr_code_values)); + fpr_code_values, poly::countof(fpr_code_values)); } if (!vmx_start) { vmx_start = memory_->SearchAligned( start_address, end_address, - vmx_code_values, XECOUNT(vmx_code_values)); + vmx_code_values, poly::countof(vmx_code_values)); } if (gplr_start && fpr_start && vmx_start) { break; @@ -422,7 +423,7 @@ int XexModule::FindSaveRest() { if (gplr_start) { uint64_t address = gplr_start; for (int n = 14; n <= 31; n++) { - xesnprintfa(name, XECOUNT(name), "__savegprlr_%d", n); + xesnprintfa(name, poly::countof(name), "__savegprlr_%d", n); FunctionInfo* symbol_info; DeclareFunction(address, &symbol_info); symbol_info->set_end_address(address + (31 - n) * 4 + 2 * 4); @@ -435,7 +436,7 @@ int XexModule::FindSaveRest() { } address = gplr_start + 20 * 4; for (int n = 14; n <= 31; n++) { - xesnprintfa(name, XECOUNT(name), "__restgprlr_%d", n); + xesnprintfa(name, poly::countof(name), "__restgprlr_%d", n); FunctionInfo* symbol_info; DeclareFunction(address, &symbol_info); symbol_info->set_end_address(address + (31 - n) * 4 + 3 * 4); @@ -450,7 +451,7 @@ int XexModule::FindSaveRest() { if (fpr_start) { uint64_t address = fpr_start; for (int n = 14; n <= 31; n++) { - xesnprintfa(name, XECOUNT(name), "__savefpr_%d", n); + xesnprintfa(name, poly::countof(name), "__savefpr_%d", n); FunctionInfo* symbol_info; DeclareFunction(address, &symbol_info); symbol_info->set_end_address(address + (31 - n) * 4 + 1 * 4); @@ -463,7 +464,7 @@ int XexModule::FindSaveRest() { } address = fpr_start + (18 * 4) + (1 * 4); for (int n = 14; n <= 31; n++) { - xesnprintfa(name, XECOUNT(name), "__restfpr_%d", n); + xesnprintfa(name, poly::countof(name), "__restfpr_%d", n); FunctionInfo* symbol_info; DeclareFunction(address, &symbol_info); symbol_info->set_end_address(address + (31 - n) * 4 + 1 * 4); @@ -483,7 +484,7 @@ int XexModule::FindSaveRest() { // 64-127 rest uint64_t address = vmx_start; for (int n = 14; n <= 31; n++) { - xesnprintfa(name, XECOUNT(name), "__savevmx_%d", n); + xesnprintfa(name, poly::countof(name), "__savevmx_%d", n); FunctionInfo* symbol_info; DeclareFunction(address, &symbol_info); symbol_info->set_name(name); @@ -495,7 +496,7 @@ int XexModule::FindSaveRest() { } address += 4; for (int n = 64; n <= 127; n++) { - xesnprintfa(name, XECOUNT(name), "__savevmx_%d", n); + xesnprintfa(name, poly::countof(name), "__savevmx_%d", n); FunctionInfo* symbol_info; DeclareFunction(address, &symbol_info); symbol_info->set_name(name); @@ -507,7 +508,7 @@ int XexModule::FindSaveRest() { } address = vmx_start + (18 * 2 * 4) + (1 * 4) + (64 * 2 * 4) + (1 * 4); for (int n = 14; n <= 31; n++) { - xesnprintfa(name, XECOUNT(name), "__restvmx_%d", n); + xesnprintfa(name, poly::countof(name), "__restvmx_%d", n); FunctionInfo* symbol_info; DeclareFunction(address, &symbol_info); symbol_info->set_name(name); @@ -519,7 +520,7 @@ int XexModule::FindSaveRest() { } address += 4; for (int n = 64; n <= 127; n++) { - xesnprintfa(name, XECOUNT(name), "__restvmx_%d", n); + xesnprintfa(name, poly::countof(name), "__restvmx_%d", n); FunctionInfo* symbol_info; DeclareFunction(address, &symbol_info); symbol_info->set_name(name); diff --git a/src/xenia/export_resolver.cc b/src/xenia/export_resolver.cc index ae7204f80..7f56d89a1 100644 --- a/src/xenia/export_resolver.cc +++ b/src/xenia/export_resolver.cc @@ -9,6 +9,7 @@ #include +#include using namespace xe; @@ -22,7 +23,7 @@ ExportResolver::~ExportResolver() { void ExportResolver::RegisterTable( const char* library_name, KernelExport* exports, const size_t count) { ExportTable table; - xestrcpya(table.name, XECOUNT(table.name), library_name); + xestrcpya(table.name, poly::countof(table.name), library_name); table.exports = exports; table.count = count; tables_.push_back(table); diff --git a/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc b/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc index e59f9823b..511d8dd93 100644 --- a/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc +++ b/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -98,7 +99,7 @@ ID3D10Blob* D3D11GeometryShader::Compile(const char* shader_source) { } uint64_t hash = hash64(shader_source, strlen(shader_source)); // ? char file_name[poly::max_path]; - xesnprintfa(file_name, XECOUNT(file_name), + xesnprintfa(file_name, poly::countof(file_name), "%s/gen_%.16llX.gs", base_path, hash); diff --git a/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc b/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc index 31c38880a..1bdccf3ec 100644 --- a/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc +++ b/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -249,7 +250,7 @@ int D3D11GraphicsDriver::UpdateState(const DrawCommand& command) { register_file_[XE_GPU_REG_RB_COLOR3_INFO].u32, }; ID3D11RenderTargetView* render_target_views[4] = { 0 }; - for (int n = 0; n < XECOUNT(color_info); n++) { + for (int n = 0; n < poly::countof(color_info); n++) { auto cb = render_targets_.color_buffers[n]; uint32_t color_format = (color_info[n] >> 16) & 0xF; switch (color_format) { @@ -484,7 +485,7 @@ int D3D11GraphicsDriver::SetupBlendState(const DrawCommand& command) { //blend_desc.AlphaToCoverageEnable = false; // ? blend_desc.IndependentBlendEnable = true; - for (int n = 0; n < XECOUNT(blend_control); n++) { + for (int n = 0; n < poly::countof(blend_control); n++) { // A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND blend_desc.RenderTarget[n].SrcBlend = blend_map[(blend_control[n] & 0x0000001F) >> 0]; // A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND @@ -642,13 +643,14 @@ int D3D11GraphicsDriver::SetupShaders(const DrawCommand& command) { // Set constant buffers. ID3D11Buffer* vs_constant_buffers[] = { - state_.constant_buffers.float_constants, - state_.constant_buffers.bool_constants, - state_.constant_buffers.loop_constants, - state_.constant_buffers.vs_consts, + state_.constant_buffers.float_constants, + state_.constant_buffers.bool_constants, + state_.constant_buffers.loop_constants, + state_.constant_buffers.vs_consts, }; - context_->VSSetConstantBuffers(0, XECOUNT(vs_constant_buffers), - vs_constant_buffers); + context_->VSSetConstantBuffers( + 0, static_cast(poly::countof(vs_constant_buffers)), + vs_constant_buffers); // Setup input layout (as encoded in vertex shader). auto vs = static_cast(command.vertex_shader); @@ -666,12 +668,13 @@ int D3D11GraphicsDriver::SetupShaders(const DrawCommand& command) { // Set constant buffers. ID3D11Buffer* vs_constant_buffers[] = { - state_.constant_buffers.float_constants, - state_.constant_buffers.bool_constants, - state_.constant_buffers.loop_constants, + state_.constant_buffers.float_constants, + state_.constant_buffers.bool_constants, + state_.constant_buffers.loop_constants, }; - context_->PSSetConstantBuffers(0, XECOUNT(vs_constant_buffers), - vs_constant_buffers); + context_->PSSetConstantBuffers( + 0, static_cast(poly::countof(vs_constant_buffers)), + vs_constant_buffers); } else { context_->PSSetShader(nullptr, nullptr, 0); return 1; @@ -824,7 +827,7 @@ int D3D11GraphicsDriver::RebuildRenderTargets(uint32_t width, SCOPE_profile_cpu_f("gpu"); // Remove old versions. - for (int n = 0; n < XECOUNT(render_targets_.color_buffers); n++) { + for (int n = 0; n < poly::countof(render_targets_.color_buffers); n++) { auto& cb = render_targets_.color_buffers[n]; SafeRelease(cb.buffer); SafeRelease(cb.color_view_8888); @@ -841,7 +844,7 @@ int D3D11GraphicsDriver::RebuildRenderTargets(uint32_t width, return 0; } - for (int n = 0; n < XECOUNT(render_targets_.color_buffers); n++) { + for (int n = 0; n < poly::countof(render_targets_.color_buffers); n++) { auto& cb = render_targets_.color_buffers[n]; D3D11_TEXTURE2D_DESC color_buffer_desc; xe_zero_struct(&color_buffer_desc, sizeof(color_buffer_desc)); diff --git a/src/xenia/gpu/d3d11/d3d11_graphics_system.cc b/src/xenia/gpu/d3d11/d3d11_graphics_system.cc index 9942ce0b6..f88977bac 100644 --- a/src/xenia/gpu/d3d11/d3d11_graphics_system.cc +++ b/src/xenia/gpu/d3d11/d3d11_graphics_system.cc @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -89,7 +90,7 @@ void D3D11GraphicsSystem::Initialize() { 0, // software driver HMODULE flags, feature_levels, - XECOUNT(feature_levels), + static_cast(poly::countof(feature_levels)), D3D11_SDK_VERSION, &device_, &actual_feature_level, diff --git a/src/xenia/gpu/d3d11/d3d11_profiler_display.cc b/src/xenia/gpu/d3d11/d3d11_profiler_display.cc index 9d0bcde7f..5b23ea3ec 100644 --- a/src/xenia/gpu/d3d11/d3d11_profiler_display.cc +++ b/src/xenia/gpu/d3d11/d3d11_profiler_display.cc @@ -11,6 +11,7 @@ #include +#include #include #include @@ -267,14 +268,23 @@ bool D3D11ProfilerDisplay::SetupShaders() { } D3D11_INPUT_ELEMENT_DESC element_descs[] = { - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0, }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0, }, - { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0, }, + { + "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, + D3D11_INPUT_PER_VERTEX_DATA, 0, + }, + { + "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, + D3D11_INPUT_PER_VERTEX_DATA, 0, + }, + { + "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D11_APPEND_ALIGNED_ELEMENT, + D3D11_INPUT_PER_VERTEX_DATA, 0, + }, }; - hr = device->CreateInputLayout(element_descs, (UINT)XECOUNT(element_descs), - vs_code_blob->GetBufferPointer(), - vs_code_blob->GetBufferSize(), - &shader_layout_); + hr = device->CreateInputLayout( + element_descs, (UINT)poly::countof(element_descs), + vs_code_blob->GetBufferPointer(), vs_code_blob->GetBufferSize(), + &shader_layout_); if (FAILED(hr)) { XELOGE("Failed to create profiler input layout"); return false; @@ -298,7 +308,7 @@ bool D3D11ProfilerDisplay::SetupFont() { auto device = window_->device(); // Setup font lookup table. - for (uint32_t i = 0; i < XECOUNT(font_description_.char_offsets); ++i) { + for (uint32_t i = 0; i < poly::countof(font_description_.char_offsets); ++i) { font_description_.char_offsets[i] = 206; } for (uint32_t i = 'A'; i <= 'Z'; ++i) { @@ -468,12 +478,14 @@ void D3D11ProfilerDisplay::Begin() { font_sampler_state_, nullptr, }; - context->PSSetSamplers(0, XECOUNT(ps_samplers), ps_samplers); - ID3D11ShaderResourceView* ps_resources[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = { - font_texture_view_, - nullptr, - }; - context->PSSetShaderResources(0, XECOUNT(ps_resources), ps_resources); + context->PSSetSamplers(0, static_cast(poly::countof(ps_samplers)), + ps_samplers); + ID3D11ShaderResourceView* + ps_resources[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = { + font_texture_view_, nullptr, + }; + context->PSSetShaderResources( + 0, static_cast(poly::countof(ps_resources)), ps_resources); context->IASetInputLayout(shader_layout_); } @@ -483,19 +495,23 @@ void D3D11ProfilerDisplay::End() { D3D11ProfilerDisplay::Vertex* D3D11ProfilerDisplay::AllocateVertices( D3D_PRIMITIVE_TOPOLOGY primitive, size_t count) { - if (draw_state_.vertex_index + count > XECOUNT(draw_state_.vertex_buffer)) { + if (draw_state_.vertex_index + count > + poly::countof(draw_state_.vertex_buffer)) { Flush(); } - assert_true(draw_state_.vertex_index + count <= XECOUNT(draw_state_.vertex_buffer)); + assert_true(draw_state_.vertex_index + count <= + poly::countof(draw_state_.vertex_buffer)); size_t head = draw_state_.vertex_index; draw_state_.vertex_index += count; if (draw_state_.command_index && - draw_state_.commands[draw_state_.command_index - 1].primitive == primitive) { + draw_state_.commands[draw_state_.command_index - 1].primitive == + primitive) { draw_state_.commands[draw_state_.command_index - 1].vertex_count += count; } else { - assert_true(draw_state_.command_index < XECOUNT(draw_state_.commands)); + assert_true(draw_state_.command_index < + poly::countof(draw_state_.commands)); draw_state_.commands[draw_state_.command_index].primitive = primitive; draw_state_.commands[draw_state_.command_index].vertex_count = count; ++draw_state_.command_index; diff --git a/src/xenia/gpu/d3d11/d3d11_shader_resource.cc b/src/xenia/gpu/d3d11/d3d11_shader_resource.cc index ed95ee39b..e8bb26956 100644 --- a/src/xenia/gpu/d3d11/d3d11_shader_resource.cc +++ b/src/xenia/gpu/d3d11/d3d11_shader_resource.cc @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -49,7 +50,7 @@ ID3D10Blob* D3D11ShaderCompile(XE_GPU_SHADER_TYPE type, } size_t hash = hash64(disasm_source, strlen(disasm_source)); // ? char file_name[poly::max_path]; - xesnprintfa(file_name, XECOUNT(file_name), + xesnprintfa(file_name, poly::countof(file_name), "%s/gen_%.16llX.%s", base_path, hash, @@ -105,7 +106,7 @@ D3D11VertexShaderResource::D3D11VertexShaderResource( D3D11VertexShaderResource::~D3D11VertexShaderResource() { SafeRelease(handle_); SafeRelease(input_layout_); - for (int i = 0; i < XECOUNT(geometry_shaders_); ++i) { + for (int i = 0; i < poly::countof(geometry_shaders_); ++i) { delete geometry_shaders_[i]; } xe_free(translated_src_); diff --git a/src/xenia/gpu/graphics_system.cc b/src/xenia/gpu/graphics_system.cc index 6ab0d14ff..93b69984e 100644 --- a/src/xenia/gpu/graphics_system.cc +++ b/src/xenia/gpu/graphics_system.cc @@ -9,7 +9,7 @@ #include -#include +#include #include #include #include @@ -199,5 +199,5 @@ void GraphicsSystem::DispatchInterruptCallback( } uint64_t args[] = { source, interrupt_callback_data_ }; processor_->ExecuteInterrupt( - cpu, interrupt_callback_, args, XECOUNT(args)); + cpu, interrupt_callback_, args, poly::countof(args)); } diff --git a/src/xenia/gpu/shader_resource.cc b/src/xenia/gpu/shader_resource.cc index 8f6458e41..42986bf74 100644 --- a/src/xenia/gpu/shader_resource.cc +++ b/src/xenia/gpu/shader_resource.cc @@ -9,6 +9,7 @@ #include +#include #include @@ -188,7 +189,7 @@ void ShaderResource::GatherVertexFetch(const instr_fetch_vtx_t* vtx) { auto& desc = inputs.descs[n]; auto& info = desc.info; if (desc.fetch_slot == fetch_slot) { - assert_true(info.element_count <= XECOUNT(info.elements)); + assert_true(info.element_count <= poly::countof(info.elements)); // It may not hold that all strides are equal, but I hope it does. assert_true(!vtx->stride || info.stride_words == vtx->stride); el = &info.elements[info.element_count++]; @@ -197,7 +198,7 @@ void ShaderResource::GatherVertexFetch(const instr_fetch_vtx_t* vtx) { } if (!el) { assert_not_zero(vtx->stride); - assert_true(inputs.count + 1 < XECOUNT(inputs.descs)); + assert_true(inputs.count + 1 < poly::countof(inputs.descs)); auto& desc = inputs.descs[inputs.count++]; desc.input_index = inputs.count - 1; desc.fetch_slot = fetch_slot; @@ -251,7 +252,7 @@ void ShaderResource::GatherVertexFetch(const instr_fetch_vtx_t* vtx) { void ShaderResource::GatherTextureFetch(const xenos::instr_fetch_tex_t* tex) { // TODO(benvanik): check dest_swiz to see if we are writing anything. - assert_true(sampler_inputs_.count + 1 < XECOUNT(sampler_inputs_.descs)); + assert_true(sampler_inputs_.count + 1 < poly::countof(sampler_inputs_.descs)); auto& input = sampler_inputs_.descs[sampler_inputs_.count++]; input.input_index = sampler_inputs_.count - 1; input.fetch_slot = tex->const_idx & 0xF; // ? diff --git a/src/xenia/kernel/fs/devices/disc_image_device.cc b/src/xenia/kernel/fs/devices/disc_image_device.cc index e7bfda041..0e282af49 100644 --- a/src/xenia/kernel/fs/devices/disc_image_device.cc +++ b/src/xenia/kernel/fs/devices/disc_image_device.cc @@ -9,6 +9,7 @@ #include +#include #include #include @@ -57,12 +58,12 @@ Entry* DiscImageDevice::ResolvePath(const char* path) { // Walk the path, one separator at a time. // We copy it into the buffer and shift it left over and over. char remaining[poly::max_path]; - xestrcpya(remaining, XECOUNT(remaining), path); + xestrcpya(remaining, poly::countof(remaining), path); while (remaining[0]) { char* next_slash = strchr(remaining, '\\'); if (next_slash == remaining) { // Leading slash - shift - xestrcpya(remaining, XECOUNT(remaining), remaining + 1); + xestrcpya(remaining, poly::countof(remaining), remaining + 1); continue; } @@ -82,7 +83,7 @@ Entry* DiscImageDevice::ResolvePath(const char* path) { if (!next_slash) { break; } - xestrcpya(remaining, XECOUNT(remaining), next_slash + 1); + xestrcpya(remaining, poly::countof(remaining), next_slash + 1); } Entry::Type type = gdfx_entry->attributes & X_FILE_ATTRIBUTE_DIRECTORY ? diff --git a/src/xenia/kernel/fs/devices/stfs_container_device.cc b/src/xenia/kernel/fs/devices/stfs_container_device.cc index a0f176df2..219d8bdee 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_device.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_device.cc @@ -9,6 +9,7 @@ #include +#include #include #include @@ -57,12 +58,12 @@ Entry* STFSContainerDevice::ResolvePath(const char* path) { // Walk the path, one separator at a time. // We copy it into the buffer and shift it left over and over. char remaining[poly::max_path]; - xestrcpya(remaining, XECOUNT(remaining), path); + xestrcpya(remaining, poly::countof(remaining), path); while (remaining[0]) { char* next_slash = strchr(remaining, '\\'); if (next_slash == remaining) { // Leading slash - shift - xestrcpya(remaining, XECOUNT(remaining), remaining + 1); + xestrcpya(remaining, poly::countof(remaining), remaining + 1); continue; } @@ -82,7 +83,7 @@ Entry* STFSContainerDevice::ResolvePath(const char* path) { if (!next_slash) { break; } - xestrcpya(remaining, XECOUNT(remaining), next_slash + 1); + xestrcpya(remaining, poly::countof(remaining), next_slash + 1); } Entry::Type type = stfs_entry->attributes & X_FILE_ATTRIBUTE_DIRECTORY ? diff --git a/src/xenia/kernel/fs/gdfx.cc b/src/xenia/kernel/fs/gdfx.cc index 27a948e7a..9f275ff33 100644 --- a/src/xenia/kernel/fs/gdfx.cc +++ b/src/xenia/kernel/fs/gdfx.cc @@ -11,6 +11,7 @@ #include +#include using namespace xe; using namespace xe::kernel; @@ -105,7 +106,7 @@ GDFX::Error GDFX::Verify(ParseState& state) { 0x00000000, 0x0000FB20, 0x00020600, 0x0FD90000, }; bool magic_found = false; - for (size_t n = 0; n < XECOUNT(likely_offsets); n++) { + for (size_t n = 0; n < poly::countof(likely_offsets); n++) { state.game_offset = likely_offsets[n]; if (VerifyMagic(state, state.game_offset + (32 * kXESectorSize))) { magic_found = true; diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index 68f11c7f4..646178c8a 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -219,7 +219,7 @@ X_STATUS XThread::Create() { } char thread_name[32]; - xesnprintfa(thread_name, XECOUNT(thread_name), "XThread%04X", handle()); + xesnprintfa(thread_name, poly::countof(thread_name), "XThread%04X", handle()); set_name(thread_name); uint32_t proc_mask = creation_params_.creation_flags >> 24; @@ -366,22 +366,19 @@ void XThread::Execute() { // If a XapiThreadStartup value is present, we use that as a trampoline. // Otherwise, we are a raw thread. if (creation_params_.xapi_thread_startup) { - uint64_t args[] = { - creation_params_.start_address, - creation_params_.start_context - }; - kernel_state()->processor()->Execute( - thread_state_, - creation_params_.xapi_thread_startup, args, XECOUNT(args)); + uint64_t args[] = {creation_params_.start_address, + creation_params_.start_context}; + kernel_state()->processor()->Execute(thread_state_, + creation_params_.xapi_thread_startup, + args, poly::countof(args)); } else { // Run user code. - uint64_t args[] = { - creation_params_.start_context - }; + uint64_t args[] = {creation_params_.start_context}; int exit_code = (int)kernel_state()->processor()->Execute( - thread_state_, - creation_params_.start_address, args, XECOUNT(args)); - // If we got here it means the execute completed without an exit being called. + thread_state_, creation_params_.start_address, args, + poly::countof(args)); + // If we got here it means the execute completed without an exit being + // called. // Treat the return code as an implicit exit code. Exit(exit_code); } @@ -459,7 +456,7 @@ void XThread::DeliverAPCs(void* data) { thread->scratch_address_ + 12, }; processor->ExecuteInterrupt( - 0, kernel_routine, kernel_args, XECOUNT(kernel_args)); + 0, kernel_routine, kernel_args, poly::countof(kernel_args)); normal_routine = poly::load_and_swap(scratch_ptr + 0); normal_context = poly::load_and_swap(scratch_ptr + 4); system_arg1 = poly::load_and_swap(scratch_ptr + 8); @@ -472,7 +469,7 @@ void XThread::DeliverAPCs(void* data) { // normal_routine(normal_context, system_arg1, system_arg2) uint64_t normal_args[] = { normal_context, system_arg1, system_arg2 }; processor->ExecuteInterrupt( - 0, normal_routine, normal_args, XECOUNT(normal_args)); + 0, normal_routine, normal_args, poly::countof(normal_args)); thread->LockApc(); } } @@ -498,7 +495,7 @@ void XThread::RundownAPCs() { // rundown_routine(apc) uint64_t args[] = { apc_address }; kernel_state()->processor()->ExecuteInterrupt( - 0, rundown_routine, args, XECOUNT(args)); + 0, rundown_routine, args, poly::countof(args)); } } UnlockApc(); diff --git a/src/xenia/kernel/util/export_table_pre.inc b/src/xenia/kernel/util/export_table_pre.inc index d7c14a751..a03a01d4c 100644 --- a/src/xenia/kernel/util/export_table_pre.inc +++ b/src/xenia/kernel/util/export_table_pre.inc @@ -19,7 +19,7 @@ * #include * export_resolver_->RegisterTable( * "my_module.xex", - * my_module_export_table, XECOUNT(my_module_export_table)); + * my_module_export_table, poly::countof(my_module_export_table)); */ diff --git a/src/xenia/kernel/util/xex2.cc b/src/xenia/kernel/util/xex2.cc index 9ce9ddb86..23308e96b 100644 --- a/src/xenia/kernel/util/xex2.cc +++ b/src/xenia/kernel/util/xex2.cc @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -237,7 +238,7 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, break; case XEX_HEADER_IMPORT_LIBRARIES: { - const size_t max_count = XECOUNT(header->import_libraries); + const size_t max_count = poly::countof(header->import_libraries); size_t count = poly::load_and_swap(pp + 0x08); assert_true(count <= max_count); if (count > max_count) { @@ -263,7 +264,7 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, for (size_t i = 0, j = 0; i < string_table_size;) { assert_true(j <= 0xFF); if (j == name_index) { - xestrcpya(library->name, XECOUNT(library->name), + xestrcpya(library->name, poly::countof(library->name), string_table + i); break; } @@ -292,7 +293,7 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, break; case XEX_HEADER_STATIC_LIBRARIES: { - const size_t max_count = XECOUNT(header->static_libraries); + const size_t max_count = poly::countof(header->static_libraries); size_t count = (opt_header->length - 4) / 16; assert_true(count <= max_count); if (count > max_count) { diff --git a/src/xenia/kernel/xam_module.cc b/src/xenia/kernel/xam_module.cc index b67bc2da7..51649628e 100644 --- a/src/xenia/kernel/xam_module.cc +++ b/src/xenia/kernel/xam_module.cc @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -27,7 +28,7 @@ XamModule::XamModule(Emulator* emulator, KernelState* kernel_state) : }; #include export_resolver_->RegisterTable( - "xam.xex", xam_export_table, XECOUNT(xam_export_table)); + "xam.xex", xam_export_table, poly::countof(xam_export_table)); // Register all exported functions. xam::RegisterContentExports(export_resolver_, kernel_state); diff --git a/src/xenia/kernel/xboxkrnl_module.cc b/src/xenia/kernel/xboxkrnl_module.cc index f9daefb54..f98e7a16d 100644 --- a/src/xenia/kernel/xboxkrnl_module.cc +++ b/src/xenia/kernel/xboxkrnl_module.cc @@ -10,7 +10,7 @@ #include #include - +#include #include #include #include @@ -34,8 +34,8 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) : #include }; #include - export_resolver_->RegisterTable( - "xboxkrnl.exe", xboxkrnl_export_table, XECOUNT(xboxkrnl_export_table)); + export_resolver_->RegisterTable("xboxkrnl.exe", xboxkrnl_export_table, + poly::countof(xboxkrnl_export_table)); // Register all exported functions. xboxkrnl::RegisterAudioExports(export_resolver_, kernel_state); @@ -113,7 +113,7 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) : pExLoadedCommandLine); char command_line[] = "\"default.xex\""; xe_copy_memory(mem + pExLoadedCommandLine, 1024, - command_line, XECOUNT(command_line) + 1); + command_line, poly::countof(command_line) + 1); // XboxKrnlVersion (8b) // Kernel version, looks like 2b.2b.2b.2b. diff --git a/src/xenia/logging.cc b/src/xenia/logging.cc index 0d181e26e..f585bddf1 100644 --- a/src/xenia/logging.cc +++ b/src/xenia/logging.cc @@ -13,6 +13,7 @@ #include #include +#include #include DEFINE_bool(fast_stdout, false, @@ -63,7 +64,7 @@ void xe_log_line(const char* file_path, const uint32_t line_number, char buffer[2048]; va_list args; va_start(args, fmt); - xe_format_log_line(buffer, XECOUNT(buffer), + xe_format_log_line(buffer, poly::countof(buffer), file_path, line_number, function_name, level_char, fmt, args); va_end(args); @@ -88,7 +89,7 @@ void xe_handle_fatal( char buffer[2048]; va_list args; va_start(args, fmt); - xe_format_log_line(buffer, XECOUNT(buffer), + xe_format_log_line(buffer, poly::countof(buffer), file_path, line_number, function_name, 'X', fmt, args); va_end(args); diff --git a/src/xenia/types.h b/src/xenia/types.h index 3d4209a24..41aea7c3b 100644 --- a/src/xenia/types.h +++ b/src/xenia/types.h @@ -82,15 +82,6 @@ #endif // MSVC typedef XECACHEALIGN volatile void xe_aligned_void_t; -#if XE_COMPILER_MSVC -// http://msdn.microsoft.com/en-us/library/ms175773.aspx -#define XECOUNT(array) _countof(array) -#elif XE_COMPILER_GNUC -#define XECOUNT(array) (sizeof(array) / sizeof(__typeof__(array[0]))) -#else -#define XECOUNT(array) (sizeof(array) / sizeof(array[0])) -#endif // MSVC - #define XEFAIL() goto XECLEANUP #define XEEXPECT(expr) if (!(expr) ) { goto XECLEANUP; } #define XEEXPECTTRUE(expr) if (!(expr) ) { goto XECLEANUP; } diff --git a/tools/xenia-run/xenia-run.cc b/tools/xenia-run/xenia-run.cc index 51a6dcb3f..6c2c38802 100644 --- a/tools/xenia-run/xenia-run.cc +++ b/tools/xenia-run/xenia-run.cc @@ -17,13 +17,9 @@ using namespace xe; DEFINE_string(target, "", "Specifies the target .xex or .iso to execute."); int xenia_run(std::vector& args) { - int result_code = 1; - Profiler::Initialize(); Profiler::ThreadEnter("main"); - Emulator* emulator = NULL; - // Grab path from the flag or unnamed argument. if (!FLAGS_target.size() && args.size() < 2) { google::ShowUsageWithFlags("xenia-run"); @@ -45,15 +41,17 @@ int xenia_run(std::vector& args) { // Create platform abstraction layer. xe_pal_options_t pal_options; xe_zero_struct(&pal_options, sizeof(pal_options)); - XEEXPECTZERO(xe_pal_init(pal_options)); + if (xe_pal_init(pal_options)) { + XELOGE("Failed to initialize PAL"); + return 1; + } // Create the emulator. - emulator = new Emulator(L""); - XEEXPECTNOTNULL(emulator); + auto emulator = std::make_unique(L""); X_STATUS result = emulator->Setup(); if (XFAILED(result)) { XELOGE("Failed to setup emulator: %.8X", result); - XEFAIL(); + return 1; } // Launch based on file type. @@ -72,18 +70,13 @@ int xenia_run(std::vector& args) { } if (XFAILED(result)) { XELOGE("Failed to launch target: %.8X", result); - XEFAIL(); + return 1; } - result_code = 0; -XECLEANUP: - delete emulator; - if (result_code) { - XEFATAL("Failed to launch emulator: %d", result_code); - } + emulator.reset(); Profiler::Dump(); Profiler::Shutdown(); - return result_code; + return 0; } DEFINE_ENTRY_POINT(L"xenia-run", L"xenia-run some.xex", xenia_run); From 27bc4ba40597923b3680ccac0cfe286c17fe8ef6 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 16 Aug 2014 18:19:35 -0700 Subject: [PATCH 125/388] Removing XEINLINE*. --- src/alloy/vec128.h | 6 +++--- src/xenia/core/hash.cc | 4 ++-- src/xenia/gpu/xenos/xenos.h | 6 +++--- src/xenia/types.h | 17 ----------------- 4 files changed, 8 insertions(+), 25 deletions(-) diff --git a/src/alloy/vec128.h b/src/alloy/vec128.h index 7d251b0ff..cedb39bc9 100644 --- a/src/alloy/vec128.h +++ b/src/alloy/vec128.h @@ -42,7 +42,7 @@ typedef struct XECACHEALIGN vec128_s { return low == b.low && high == b.high; } } vec128_t; -XEFORCEINLINE vec128_t vec128i(uint32_t x, uint32_t y, uint32_t z, uint32_t w) { +static inline vec128_t vec128i(uint32_t x, uint32_t y, uint32_t z, uint32_t w) { vec128_t v; v.i4[0] = x; v.i4[1] = y; @@ -50,7 +50,7 @@ XEFORCEINLINE vec128_t vec128i(uint32_t x, uint32_t y, uint32_t z, uint32_t w) { v.i4[3] = w; return v; } -XEFORCEINLINE vec128_t vec128f(float x, float y, float z, float w) { +static inline vec128_t vec128f(float x, float y, float z, float w) { vec128_t v; v.f4[0] = x; v.f4[1] = y; @@ -58,7 +58,7 @@ XEFORCEINLINE vec128_t vec128f(float x, float y, float z, float w) { v.f4[3] = w; return v; } -XEFORCEINLINE vec128_t vec128b(uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, +static inline vec128_t vec128b(uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t y0, uint8_t y1, uint8_t y2, uint8_t y3, uint8_t z0, uint8_t z1, uint8_t z2, uint8_t z3, uint8_t w0, uint8_t w1, uint8_t w2, uint8_t w3) { diff --git a/src/xenia/core/hash.cc b/src/xenia/core/hash.cc index 4e7785d38..d2b9afb06 100644 --- a/src/xenia/core/hash.cc +++ b/src/xenia/core/hash.cc @@ -63,11 +63,11 @@ inline uint64_t Hash128to64(const uint128_t &x) { return b; } -XEFORCEINLINE uint64_t UNALIGNED_LOAD64(const char *p) { +inline uint64_t UNALIGNED_LOAD64(const char *p) { const uint64_t *p64 = (const uint64_t *)p; return *p64; } -XEFORCEINLINE uint32_t UNALIGNED_LOAD32(const char *p) { +inline uint32_t UNALIGNED_LOAD32(const char *p) { const uint32_t *p32 = (const uint32_t *)p; return *p32; } diff --git a/src/xenia/gpu/xenos/xenos.h b/src/xenia/gpu/xenos/xenos.h index ccd9a174d..c224f336b 100644 --- a/src/xenia/gpu/xenos/xenos.h +++ b/src/xenia/gpu/xenos/xenos.h @@ -73,7 +73,7 @@ typedef enum { XE_GPU_SWIZZLE_R000 = XE_GPU_MAKE_SWIZZLE(R, 0, 0, 0), } XE_GPU_SWIZZLE; -XEFORCEINLINE uint32_t GpuSwap(uint32_t value, XE_GPU_ENDIAN endianness) { +inline uint32_t GpuSwap(uint32_t value, XE_GPU_ENDIAN endianness) { switch (endianness) { default: case XE_GPU_ENDIAN_NONE: // No swap. @@ -89,11 +89,11 @@ XEFORCEINLINE uint32_t GpuSwap(uint32_t value, XE_GPU_ENDIAN endianness) { } } -XEFORCEINLINE uint32_t GpuToCpu(uint32_t p) { +inline uint32_t GpuToCpu(uint32_t p) { return p; } -XEFORCEINLINE uint32_t GpuToCpu(uint32_t base, uint32_t p) { +inline uint32_t GpuToCpu(uint32_t base, uint32_t p) { uint32_t upper = base & 0xFF000000; uint32_t lower = p & 0x00FFFFFF; return upper + lower;// -(((base >> 20) + 0x200) & 0x1000); diff --git a/src/xenia/types.h b/src/xenia/types.h index 41aea7c3b..559fc9917 100644 --- a/src/xenia/types.h +++ b/src/xenia/types.h @@ -33,23 +33,6 @@ class name; \ } } } } -#if XE_COMPILER_MSVC -// http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx -#define XEFORCEINLINE static __forceinline -#define XENOINLINE __declspec(noinline) -#elif XE_COMPILER_GNUC -// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html -#if (__GNUC__ >= 4) -#define XEFORCEINLINE static __inline__ __attribute__((always_inline)) -#else -#define XEFORCEINLINE static __inline__ -#endif -#define XENOINLINE -#else -#define XEFORCEINLINE -#define XENOINLINE -#endif // MSVC - #if XE_COMPILER_MSVC #define XEPACKEDSTRUCT(name, value) \ __pragma(pack(push, 1)) struct name##_s value __pragma(pack(pop)); \ From 4675161902424b12f65eb4aedad16c2b43d2aac2 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 16 Aug 2014 18:31:54 -0700 Subject: [PATCH 126/388] Header cleanup. --- src/alloy/core.h | 1 - src/xenia/common.h | 1 - src/xenia/config.h | 38 ------------------ src/xenia/logging.h | 12 +++++- src/xenia/profiling.cc | 71 ++++++++++++++-------------------- src/xenia/profiling.h | 75 +++++++++++++++++++++++------------- src/xenia/sources.gypi | 2 - src/xenia/xenia.h | 24 ------------ tools/xenia-run/xenia-run.cc | 4 +- 9 files changed, 90 insertions(+), 138 deletions(-) delete mode 100644 src/xenia/config.h delete mode 100644 src/xenia/xenia.h diff --git a/src/alloy/core.h b/src/alloy/core.h index 5f90cb31a..c465fe9d5 100644 --- a/src/alloy/core.h +++ b/src/alloy/core.h @@ -11,7 +11,6 @@ #define ALLOY_CORE_H_ // TODO(benvanik): move the common stuff into here? -#include #include #include #include diff --git a/src/xenia/common.h b/src/xenia/common.h index 9288f0d24..3e027f858 100644 --- a/src/xenia/common.h +++ b/src/xenia/common.h @@ -15,7 +15,6 @@ #include #include -#include #include #include #include diff --git a/src/xenia/config.h b/src/xenia/config.h deleted file mode 100644 index 0804277bf..000000000 --- a/src/xenia/config.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_CONFIG_H_ -#define XENIA_CONFIG_H_ - - -// Enable compile-time and runtime-time assertions. -#define XE_OPTION_ENABLE_ASSERTS 1 - -// Enable general logging. -#define XE_OPTION_ENABLE_LOGGING 1 -#define XE_OPTION_LOG_ERROR 1 -#define XE_OPTION_LOG_WARNING 1 -#define XE_OPTION_LOG_INFO 1 -#define XE_OPTION_LOG_DEBUG 1 -#define XE_OPTION_LOG_CPU 1 -#define XE_OPTION_LOG_SDB 0 -#define XE_OPTION_LOG_APU 1 -#define XE_OPTION_LOG_GPU 1 -#define XE_OPTION_LOG_KERNEL 1 -#define XE_OPTION_LOG_FS 1 - -// Enable profiling. -#define XE_OPTION_PROFILING 1 - -// TODO(benvanik): make this a runtime option -#define XE_OPTION_OPTIMIZED 0 - - -#endif // XENIA_CONFIG_H_ - diff --git a/src/xenia/logging.h b/src/xenia/logging.h index d8b7c30ae..9b29ea778 100644 --- a/src/xenia/logging.h +++ b/src/xenia/logging.h @@ -12,9 +12,19 @@ #include -#include #include +#define XE_OPTION_ENABLE_LOGGING 1 +#define XE_OPTION_LOG_ERROR 1 +#define XE_OPTION_LOG_WARNING 1 +#define XE_OPTION_LOG_INFO 1 +#define XE_OPTION_LOG_DEBUG 1 +#define XE_OPTION_LOG_CPU 1 +#define XE_OPTION_LOG_SDB 0 +#define XE_OPTION_LOG_APU 1 +#define XE_OPTION_LOG_GPU 1 +#define XE_OPTION_LOG_KERNEL 1 +#define XE_OPTION_LOG_FS 1 #if XE_COMPILER_GNUC #define XE_LOG_LINE_ATTRIBUTE __attribute__ ((format (printf, 5, 6))) diff --git a/src/xenia/profiling.cc b/src/xenia/profiling.cc index ce3a4ece0..649c686fc 100644 --- a/src/xenia/profiling.cc +++ b/src/xenia/profiling.cc @@ -22,9 +22,7 @@ void Profiler::Initialize() { MicroProfileSetDisplayMode(1); } -void Profiler::Dump() { - MicroProfileDumpTimers(); -} +void Profiler::Dump() { MicroProfileDumpTimers(); } void Profiler::Shutdown() { display_.reset(); @@ -41,31 +39,29 @@ void Profiler::ThreadEnter(const char* name) { MicroProfileOnThreadCreate(name); } -void Profiler::ThreadExit() { - MicroProfileOnThreadExit(); -} +void Profiler::ThreadExit() { MicroProfileOnThreadExit(); } bool Profiler::OnKeyDown(int key_code) { // http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx switch (key_code) { - case VK_TAB: - MicroProfileToggleDisplayMode(); - return true; - case VK_OEM_3: // ` - MicroProfileTogglePause(); - return true; - case 0x31: // 1 - MicroProfileModKey(1); - return true; + case VK_TAB: + MicroProfileToggleDisplayMode(); + return true; + case VK_OEM_3: // ` + MicroProfileTogglePause(); + return true; + case 0x31: // 1 + MicroProfileModKey(1); + return true; } return false; } bool Profiler::OnKeyUp(int key_code) { switch (key_code) { - case 0x31: // 1 - MicroProfileModKey(0); - return true; + case 0x31: // 1 + MicroProfileModKey(0); + return true; } return false; } @@ -74,13 +70,9 @@ void Profiler::OnMouseDown(bool left_button, bool right_button) { MicroProfileMouseButton(left_button, right_button); } -void Profiler::OnMouseUp() { - MicroProfileMouseButton(0, 0); -} +void Profiler::OnMouseUp() { MicroProfileMouseButton(0, 0); } -void Profiler::OnMouseMove(int x, int y) { - MicroProfileMousePosition(x, y, 0); -} +void Profiler::OnMouseMove(int x, int y) { MicroProfileMousePosition(x, y, 0); } void Profiler::OnMouseWheel(int x, int y, int dy) { MicroProfileMousePosition(x, y, dy); @@ -124,34 +116,26 @@ void Profiler::Present() {} #if XE_OPTION_PROFILING -uint32_t MicroProfileGpuInsertTimeStamp() { - return 0; -} +uint32_t MicroProfileGpuInsertTimeStamp() { return 0; } -uint64_t MicroProfileGpuGetTimeStamp(uint32_t nKey) { - return 0; -} +uint64_t MicroProfileGpuGetTimeStamp(uint32_t nKey) { return 0; } -uint64_t MicroProfileTicksPerSecondGpu() { - return 0; -} +uint64_t MicroProfileTicksPerSecondGpu() { return 0; } -const char* MicroProfileGetThreadName() { - return "TODO: get thread name!"; -} +const char* MicroProfileGetThreadName() { return "TODO: get thread name!"; } -void MicroProfileDrawBox(int nX, int nY, int nX1, int nY1, uint32_t nColor, MicroProfileBoxType type) { +void MicroProfileDrawBox(int nX, int nY, int nX1, int nY1, uint32_t nColor, + MicroProfileBoxType type) { auto display = xe::Profiler::display(); if (!display) { return; } - display->DrawBox( - nX, nY, nX1, nY1, - nColor, - static_cast(type)); + display->DrawBox(nX, nY, nX1, nY1, nColor, + static_cast(type)); } -void MicroProfileDrawLine2D(uint32_t nVertices, float* pVertices, uint32_t nColor) { +void MicroProfileDrawLine2D(uint32_t nVertices, float* pVertices, + uint32_t nColor) { auto display = xe::Profiler::display(); if (!display) { return; @@ -159,7 +143,8 @@ void MicroProfileDrawLine2D(uint32_t nVertices, float* pVertices, uint32_t nColo display->DrawLine2D(nVertices, pVertices, nColor); } -void MicroProfileDrawText(int nX, int nY, uint32_t nColor, const char* pText, uint32_t nLen) { +void MicroProfileDrawText(int nX, int nY, uint32_t nColor, const char* pText, + uint32_t nLen) { auto display = xe::Profiler::display(); if (!display) { return; diff --git a/src/xenia/profiling.h b/src/xenia/profiling.h index 03ebdf720..88c63c994 100644 --- a/src/xenia/profiling.h +++ b/src/xenia/profiling.h @@ -12,10 +12,11 @@ #include -#include #include #include +#define XE_OPTION_PROFILING 1 + #if XE_OPTION_PROFILING // Pollutes the global namespace. Yuck. #include @@ -28,7 +29,8 @@ namespace xe { // Defines a profiling scope for CPU tasks. // Use `SCOPE_profile_cpu(name)` to activate the scope. #define DEFINE_profile_cpu(name, group_name, scope_name) \ - MICROPROFILE_DEFINE(name, group_name, scope_name, xe::Profiler::GetColor(scope_name)) + MICROPROFILE_DEFINE(name, group_name, scope_name, \ + xe::Profiler::GetColor(scope_name)) // Declares a previously defined profile scope. Use in a translation unit. #define DECLARE_profile_cpu(name) MICROPROFILE_DECLARE(name) @@ -36,40 +38,43 @@ namespace xe { // Defines a profiling scope for GPU tasks. // Use `COUNT_profile_gpu(name)` to activate the scope. #define DEFINE_profile_gpu(name, group_name, scope_name) \ - MICROPROFILE_DEFINE_GPU(name, group_name, scope_name, xe::Profiler::GetColor(scope_name)) + MICROPROFILE_DEFINE_GPU(name, group_name, scope_name, \ + xe::Profiler::GetColor(scope_name)) // Declares a previously defined profile scope. Use in a translation unit. #define DECLARE_profile_gpu(name) MICROPROFILE_DECLARE_GPU(name) // Enters a previously defined CPU profiling scope, active for the duration // of the containing block. -#define SCOPE_profile_cpu(name) \ - MICROPROFILE_SCOPE(name) +#define SCOPE_profile_cpu(name) MICROPROFILE_SCOPE(name) // Enters a CPU profiling scope, active for the duration of the containing // block. No previous definition required. #define SCOPE_profile_cpu_i(group_name, scope_name) \ - MICROPROFILE_SCOPEI(group_name, scope_name, xe::Profiler::GetColor(scope_name)) + MICROPROFILE_SCOPEI(group_name, scope_name, \ + xe::Profiler::GetColor(scope_name)) // Enters a CPU profiling scope by function name, active for the duration of // the containing block. No previous definition required. -#define SCOPE_profile_cpu_f(group_name) \ - MICROPROFILE_SCOPEI(group_name, __FUNCTION__, xe::Profiler::GetColor(__FUNCTION__)) +#define SCOPE_profile_cpu_f(group_name) \ + MICROPROFILE_SCOPEI(group_name, __FUNCTION__, \ + xe::Profiler::GetColor(__FUNCTION__)) // Enters a previously defined GPU profiling scope, active for the duration // of the containing block. -#define SCOPE_profile_gpu(name) \ - MICROPROFILE_SCOPEGPU(name) +#define SCOPE_profile_gpu(name) MICROPROFILE_SCOPEGPU(name) // Enters a GPU profiling scope, active for the duration of the containing // block. No previous definition required. #define SCOPE_profile_gpu_i(group_name, scope_name) \ - MICROPROFILE_SCOPEGPUI(group_name, scope_name, xe::Profiler::GetColor(scope_name)) + MICROPROFILE_SCOPEGPUI(group_name, scope_name, \ + xe::Profiler::GetColor(scope_name)) // Enters a GPU profiling scope by function name, active for the duration of // the containing block. No previous definition required. -#define SCOPE_profile_gpu_f(group_name) \ - MICROPROFILE_SCOPEGPUI(group_name, __FUNCTION__, xe::Profiler::GetColor(__FUNCTION__)) +#define SCOPE_profile_gpu_f(group_name) \ + MICROPROFILE_SCOPEGPUI(group_name, __FUNCTION__, \ + xe::Profiler::GetColor(__FUNCTION__)) // Tracks a CPU value counter. #define COUNT_profile_cpu(name, count) MICROPROFILE_META_CPU(name, count) @@ -83,14 +88,30 @@ namespace xe { #define DEFINE_profile_gpu(name, group_name, scope_name) #define DECLARE_profile_cpu(name) #define DECLARE_profile_gpu(name) -#define SCOPE_profile_cpu(name) do {} while (false) -#define SCOPE_profile_cpu_f(name) do {} while (false) -#define SCOPE_profile_cpu_i(group_name, scope_name) do {} while (false) -#define SCOPE_profile_gpu(name) do {} while (false) -#define SCOPE_profile_gpu_f(name) do {} while (false) -#define SCOPE_profile_gpu_i(group_name, scope_name) do {} while (false) -#define COUNT_profile_cpu(name, count) do {} while (false) -#define COUNT_profile_gpu(name, count) do {} while (false) +#define SCOPE_profile_cpu(name) \ + do { \ + } while (false) +#define SCOPE_profile_cpu_f(name) \ + do { \ + } while (false) +#define SCOPE_profile_cpu_i(group_name, scope_name) \ + do { \ + } while (false) +#define SCOPE_profile_gpu(name) \ + do { \ + } while (false) +#define SCOPE_profile_gpu_f(name) \ + do { \ + } while (false) +#define SCOPE_profile_gpu_i(group_name, scope_name) \ + do { \ + } while (false) +#define COUNT_profile_cpu(name, count) \ + do { \ + } while (false) +#define COUNT_profile_gpu(name, count) \ + do { \ + } while (false) #define MICROPROFILE_TEXT_WIDTH 1 #define MICROPROFILE_TEXT_HEIGHT 1 @@ -98,7 +119,7 @@ namespace xe { #endif // XE_OPTION_PROFILING class ProfilerDisplay { -public: + public: enum BoxType { #if XE_OPTION_PROFILING BOX_TYPE_BAR = MicroProfileBoxTypeBar, @@ -116,13 +137,15 @@ public: virtual void Begin() = 0; virtual void End() = 0; - virtual void DrawBox(int x, int y, int x1, int y1, uint32_t color, BoxType type) = 0; + virtual void DrawBox(int x, int y, int x1, int y1, uint32_t color, + BoxType type) = 0; virtual void DrawLine2D(uint32_t count, float* vertices, uint32_t color) = 0; - virtual void DrawText(int x, int y, uint32_t color, const char* text, size_t text_length) = 0; + virtual void DrawText(int x, int y, uint32_t color, const char* text, + size_t text_length) = 0; }; class Profiler { -public: + public: #if XE_OPTION_PROFILING static bool is_enabled() { return true; } #else @@ -161,7 +184,7 @@ public: // TODO(benvanik): display mode/pause/etc? -private: + private: static std::unique_ptr display_; }; diff --git a/src/xenia/sources.gypi b/src/xenia/sources.gypi index 9eaf39280..0afc479e1 100644 --- a/src/xenia/sources.gypi +++ b/src/xenia/sources.gypi @@ -2,7 +2,6 @@ { 'sources': [ 'common.h', - 'config.h', 'core.h', 'debug_agent.cc', 'debug_agent.h', @@ -19,7 +18,6 @@ 'string.h', 'types.h', 'xbox.h', - 'xenia.h', ], 'includes': [ diff --git a/src/xenia/xenia.h b/src/xenia/xenia.h deleted file mode 100644 index ebb04559d..000000000 --- a/src/xenia/xenia.h +++ /dev/null @@ -1,24 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_H_ -#define XENIA_H_ - -#include -#include -#include -#include - -#include -#include -#include -#include - - -#endif // XENIA_H_ diff --git a/tools/xenia-run/xenia-run.cc b/tools/xenia-run/xenia-run.cc index 6c2c38802..4f95bbf2b 100644 --- a/tools/xenia-run/xenia-run.cc +++ b/tools/xenia-run/xenia-run.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include - #include #include +#include +#include using namespace xe; From 6cb9ca432f913ad3199c7c01e2ced47653f08387 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 16 Aug 2014 19:07:21 -0700 Subject: [PATCH 127/388] More shared header cleanup. --- src/alloy/core.h | 2 -- src/alloy/frontend/ppc/ppc_context.h | 3 +- src/alloy/vec128.h | 3 +- src/poly/platform.h | 6 ---- src/xenia/emulator.h | 42 +++++++++++++++--------- src/xenia/gpu/xenos/ucode.h | 19 +++++++++++ src/xenia/gpu/xenos/xenos.h | 2 +- src/xenia/kernel/kernel_state.h | 45 ++++++++++++------------- src/xenia/logging.h | 2 ++ src/xenia/malloc.h | 1 + src/xenia/types.h | 49 ---------------------------- 11 files changed, 77 insertions(+), 97 deletions(-) diff --git a/src/alloy/core.h b/src/alloy/core.h index c465fe9d5..e8a2c6637 100644 --- a/src/alloy/core.h +++ b/src/alloy/core.h @@ -14,7 +14,5 @@ #include #include #include -#include -#include #endif // ALLOY_CORE_H_ diff --git a/src/alloy/frontend/ppc/ppc_context.h b/src/alloy/frontend/ppc/ppc_context.h index b9858323a..f3365e192 100644 --- a/src/alloy/frontend/ppc/ppc_context.h +++ b/src/alloy/frontend/ppc/ppc_context.h @@ -12,6 +12,7 @@ #include #include +#include namespace alloy { namespace runtime { class Runtime; @@ -37,7 +38,7 @@ using vec128_t = alloy::vec128_t; // 128-256: VR #pragma pack(push, 4) -typedef struct XECACHEALIGN64 PPCContext_s { +typedef struct alignas(64) PPCContext_s { // Must be stored at 0x0 for now. // TODO(benvanik): find a nice way to describe this to the JIT. runtime::ThreadState* thread_state; diff --git a/src/alloy/vec128.h b/src/alloy/vec128.h index cedb39bc9..35caef5d1 100644 --- a/src/alloy/vec128.h +++ b/src/alloy/vec128.h @@ -11,10 +11,11 @@ #define ALLOY_VEC128_H_ #include +#include namespace alloy { -typedef struct XECACHEALIGN vec128_s { +typedef struct alignas(16) vec128_s { union { struct { float x; diff --git a/src/poly/platform.h b/src/poly/platform.h index b0463c0bc..05be89e48 100644 --- a/src/poly/platform.h +++ b/src/poly/platform.h @@ -123,12 +123,6 @@ XE_CPU: 32BIT | 64BIT | BIGENDIAN | LITTLEENDIAN #define XE_CPU_LITTLEENDIAN 1 #endif // [big endian flags] -#if XE_CPU_32BIT -#define XE_ALIGNMENT 8 -#else -#define XE_ALIGNMENT 16 -#endif // 32BIT - #if XE_PLATFORM_WINCE || XE_PLATFORM_WIN32 #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN diff --git a/src/xenia/emulator.h b/src/xenia/emulator.h index 0c05d3d0b..77ffabd40 100644 --- a/src/xenia/emulator.h +++ b/src/xenia/emulator.h @@ -14,24 +14,36 @@ #include #include -#include -#include #include - - -XEDECLARECLASS1(xe, ExportResolver); -XEDECLARECLASS2(xe, apu, AudioSystem); -XEDECLARECLASS2(xe, cpu, Processor); -XEDECLARECLASS2(xe, gpu, GraphicsSystem); -XEDECLARECLASS2(xe, hid, InputSystem); -XEDECLARECLASS2(xe, kernel, KernelState); -XEDECLARECLASS2(xe, kernel, XamModule); -XEDECLARECLASS2(xe, kernel, XboxkrnlModule); -XEDECLARECLASS3(xe, kernel, fs, FileSystem); -XEDECLARECLASS2(xe, ui, Window); - +#include +#include +#include namespace xe { +namespace apu { +class AudioSystem; +} // namespace apu +namespace cpu { +class Processor; +} // namespace cpu +namespace gpu { +class GraphicsSystem; +} // namespace gpu +namespace hid { +class InputSystem; +} // namespace hid +namespace kernel { +class XamModule; +class XboxkrnlModule; +} // namespace kernel +namespace ui { +class Window; +} // namespace ui +} // namespace xe + +namespace xe { + +class ExportResolver; class Emulator { public: diff --git a/src/xenia/gpu/xenos/ucode.h b/src/xenia/gpu/xenos/ucode.h index 2727b0328..f6130bcd3 100644 --- a/src/xenia/gpu/xenos/ucode.h +++ b/src/xenia/gpu/xenos/ucode.h @@ -18,6 +18,25 @@ namespace gpu { namespace xenos { +#if XE_COMPILER_MSVC +#define XEPACKEDSTRUCT(name, value) \ + __pragma(pack(push, 1)) struct name##_s value __pragma(pack(pop)); \ + typedef struct name##_s name; +#define XEPACKEDSTRUCTANONYMOUS(value) \ + __pragma(pack(push, 1)) struct value __pragma(pack(pop)); +#define XEPACKEDUNION(name, value) \ + __pragma(pack(push, 1)) union name##_s value __pragma(pack(pop)); \ + typedef union name##_s name; +#elif XE_COMPILER_GNUC +#define XEPACKEDSTRUCT(name, value) \ + struct __attribute__((packed)) name +#define XEPACKEDSTRUCTANONYMOUS(value) \ + struct __attribute__((packed)) +#define XEPACKEDUNION(name, value) \ + union __attribute__((packed)) name +#endif // MSVC + + // This code comes from the freedreno project: // https://github.com/freedreno/freedreno/blob/master/includes/instr-a2xx.h /* diff --git a/src/xenia/gpu/xenos/xenos.h b/src/xenia/gpu/xenos/xenos.h index c224f336b..ef5837fe2 100644 --- a/src/xenia/gpu/xenos/xenos.h +++ b/src/xenia/gpu/xenos/xenos.h @@ -11,7 +11,7 @@ #define XENIA_GPU_XENOS_XENOS_H_ #include - +#include namespace xe { namespace gpu { diff --git a/src/xenia/kernel/kernel_state.h b/src/xenia/kernel/kernel_state.h index 3587e3c46..611c5cb27 100644 --- a/src/xenia/kernel/kernel_state.h +++ b/src/xenia/kernel/kernel_state.h @@ -23,23 +23,24 @@ #include #include - -XEDECLARECLASS1(xe, Emulator); -XEDECLARECLASS2(xe, cpu, Processor); -XEDECLARECLASS2(xe, kernel, Dispatcher); -XEDECLARECLASS2(xe, kernel, XModule); -XEDECLARECLASS2(xe, kernel, XNotifyListener); -XEDECLARECLASS2(xe, kernel, XThread); -XEDECLARECLASS2(xe, kernel, XUserModule); -XEDECLARECLASS3(xe, kernel, fs, FileSystem); - +namespace xe { +class Emulator; +namespace cpu { +class Processor; +} // namespace cpu +} // namespace xe namespace xe { namespace kernel { +class Dispatcher; +class XModule; +class XNotifyListener; +class XThread; +class XUserModule; class KernelState { -public: + public: KernelState(Emulator* emulator); ~KernelState(); @@ -72,33 +73,33 @@ public: void UnregisterNotifyListener(XNotifyListener* listener); void BroadcastNotification(XNotificationID id, uint32_t data); - void CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result, uint32_t length = 0); - void CompleteOverlappedImmediate(uint32_t overlapped_ptr, X_RESULT result, uint32_t length = 0); + void CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result, + uint32_t length = 0); + void CompleteOverlappedImmediate(uint32_t overlapped_ptr, X_RESULT result, + uint32_t length = 0); -private: - Emulator* emulator_; - Memory* memory_; + private: + Emulator* emulator_; + Memory* memory_; cpu::Processor* processor_; fs::FileSystem* file_system_; - Dispatcher* dispatcher_; + Dispatcher* dispatcher_; std::unique_ptr app_manager_; std::unique_ptr user_profile_; - ObjectTable* object_table_; - std::mutex object_mutex_; + ObjectTable* object_table_; + std::mutex object_mutex_; std::unordered_map threads_by_id_; std::vector notify_listeners_; - XUserModule* executable_module_; + XUserModule* executable_module_; friend class XObject; }; - } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_KERNEL_STATE_H_ diff --git a/src/xenia/logging.h b/src/xenia/logging.h index 9b29ea778..8e2f29fd5 100644 --- a/src/xenia/logging.h +++ b/src/xenia/logging.h @@ -26,6 +26,8 @@ #define XE_OPTION_LOG_KERNEL 1 #define XE_OPTION_LOG_FS 1 +#define XE_EMPTY_MACRO do { } while(0) + #if XE_COMPILER_GNUC #define XE_LOG_LINE_ATTRIBUTE __attribute__ ((format (printf, 5, 6))) #else diff --git a/src/xenia/malloc.h b/src/xenia/malloc.h index c3f5ec754..cfe6304e5 100644 --- a/src/xenia/malloc.h +++ b/src/xenia/malloc.h @@ -21,6 +21,7 @@ void *xe_realloc(void *ptr, const size_t old_size, const size_t new_size); void *xe_recalloc(void *ptr, const size_t old_size, const size_t new_size); void xe_free(void *ptr); +typedef __declspec(align(16)) volatile void xe_aligned_void_t; xe_aligned_void_t *xe_malloc_aligned(const size_t size); void xe_free_aligned(xe_aligned_void_t *ptr); diff --git a/src/xenia/types.h b/src/xenia/types.h index 559fc9917..0fe6f7661 100644 --- a/src/xenia/types.h +++ b/src/xenia/types.h @@ -10,60 +10,12 @@ #ifndef XENIA_TYPES_H_ #define XENIA_TYPES_H_ -#include -#include - -#include - - -#define XE_EMPTY_MACRO do { } while(0) - #define XEDECLARECLASS1(ns1, name) \ namespace ns1 { class name; } #define XEDECLARECLASS2(ns1, ns2, name) \ namespace ns1 { namespace ns2 { \ class name; \ } } -#define XEDECLARECLASS3(ns1, ns2, ns3, name) \ - namespace ns1 { namespace ns2 { namespace ns3 { \ - class name; \ - } } } -#define XEDECLARECLASS4(ns1, ns2, ns3, ns4, name) \ - namespace ns1 { namespace ns2 { namespace ns3 { namespace ns4 { \ - class name; \ - } } } } - -#if XE_COMPILER_MSVC -#define XEPACKEDSTRUCT(name, value) \ - __pragma(pack(push, 1)) struct name##_s value __pragma(pack(pop)); \ - typedef struct name##_s name; -#define XEPACKEDSTRUCTANONYMOUS(value) \ - __pragma(pack(push, 1)) struct value __pragma(pack(pop)); -#define XEPACKEDUNION(name, value) \ - __pragma(pack(push, 1)) union name##_s value __pragma(pack(pop)); \ - typedef union name##_s name; -#elif XE_COMPILER_GNUC -#define XEPACKEDSTRUCT(name, value) \ - struct __attribute__((packed)) name -#define XEPACKEDSTRUCTANONYMOUS(value) \ - struct __attribute__((packed)) -#define XEPACKEDUNION(name, value) \ - union __attribute__((packed)) name -#endif // MSVC - -#if XE_COMPILER_MSVC -// http://msdn.microsoft.com/en-us/library/83ythb65.aspx -#define XECACHEALIGN __declspec(align(XE_ALIGNMENT)) -#define XECACHEALIGN64 __declspec(align(64)) -#elif XE_COMPILER_GNUC -// http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html -#define XECACHEALIGN __attribute__ ((aligned(XE_ALIGNMENT))) -#define XECACHEALIGN64 __attribute__ ((aligned(64))) -#else -#define XECACHEALIGN -#define XECACHEALIGN64 -#endif // MSVC -typedef XECACHEALIGN volatile void xe_aligned_void_t; #define XEFAIL() goto XECLEANUP #define XEEXPECT(expr) if (!(expr) ) { goto XECLEANUP; } @@ -74,5 +26,4 @@ typedef XECACHEALIGN volatile void xe_aligned_void_t; #define XEEXPECTNULL(expr) if ( (expr) != NULL ) { goto XECLEANUP; } #define XEEXPECTNOTNULL(expr) if ( (expr) == NULL ) { goto XECLEANUP; } - #endif // XENIA_TYPES_H_ From fdab7880173357dd2bad7b74d23d0bc7e540be83 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 16 Aug 2014 21:19:21 -0700 Subject: [PATCH 128/388] Removing PAL. --- src/poly/main_win.cc | 10 +- src/xenia/core.h | 1 - src/xenia/core/pal.h | 37 ----- src/xenia/core/pal_mac.cc | 84 ----------- src/xenia/core/pal_posix.cc | 62 -------- src/xenia/core/pal_win.cc | 146 ------------------- src/xenia/core/sources.gypi | 4 - src/xenia/gpu/d3d11/d3d11_graphics_system.cc | 12 +- src/xenia/gpu/d3d11/d3d11_graphics_system.h | 2 +- src/xenia/gpu/graphics_system.cc | 3 +- src/xenia/gpu/graphics_system.h | 1 - tools/xenia-compare/xenia-compare.cc | 8 - tools/xenia-debug/xenia-debug.cc | 8 - tools/xenia-run/xenia-run.cc | 8 - tools/xenia-test/xenia-test.cc | 4 - 15 files changed, 16 insertions(+), 374 deletions(-) delete mode 100644 src/xenia/core/pal.h delete mode 100644 src/xenia/core/pal_mac.cc delete mode 100644 src/xenia/core/pal_posix.cc delete mode 100644 src/xenia/core/pal_win.cc diff --git a/src/poly/main_win.cc b/src/poly/main_win.cc index b4bdad74f..c01705ba7 100644 --- a/src/poly/main_win.cc +++ b/src/poly/main_win.cc @@ -37,13 +37,13 @@ void AttachConsole() { auto con_handle = _open_osfhandle(std_handle, _O_TEXT); auto fp = _fdopen(con_handle, "w"); *stdout = *fp; - setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stdout, nullptr, _IONBF, 0); std_handle = (intptr_t)GetStdHandle(STD_ERROR_HANDLE); con_handle = _open_osfhandle(std_handle, _O_TEXT); fp = _fdopen(con_handle, "w"); *stderr = *fp; - setvbuf(stderr, NULL, _IONBF, 0); + setvbuf(stderr, nullptr, _IONBF, 0); } } // namespace poly @@ -62,7 +62,7 @@ int wmain(int argc, wchar_t* argv[]) { for (int n = 0; n < argca; n++) { size_t len = wcslen(argv[n]); argva[n] = (char*)alloca(len + 1); - wcstombs_s(NULL, argva[n], len + 1, argv[n], _TRUNCATE); + wcstombs_s(nullptr, argva[n], len + 1, argv[n], _TRUNCATE); } // Parse flags; this may delete some of them. @@ -74,6 +74,10 @@ int wmain(int argc, wchar_t* argv[]) { args.push_back(poly::to_wstring(argva[n])); } + // Setup COM on the main thread. + // NOTE: this may fail if COM has already been initialized - that's OK. + CoInitializeEx(nullptr, COINIT_MULTITHREADED); + // Call app-provided entry point. int result = entry_info.entry_point(args); diff --git a/src/xenia/core.h b/src/xenia/core.h index 7179804da..c89428f74 100644 --- a/src/xenia/core.h +++ b/src/xenia/core.h @@ -18,7 +18,6 @@ namespace xe { } // namespace xe #include -#include #include #include #include diff --git a/src/xenia/core/pal.h b/src/xenia/core/pal.h deleted file mode 100644 index 7ba8d232f..000000000 --- a/src/xenia/core/pal.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_CORE_PAL_H_ -#define XENIA_CORE_PAL_H_ - -#include -#include - - -typedef struct { - int reserved; -} xe_pal_options_t; - - -int xe_pal_init(xe_pal_options_t options); - - -typedef struct { - struct { - uint32_t physical_count; - uint32_t logical_count; - } processors; -} xe_system_info; - -int xe_pal_get_system_info(xe_system_info* out_info); - -double xe_pal_now(); - - -#endif // XENIA_CORE_PAL_H_ diff --git a/src/xenia/core/pal_mac.cc b/src/xenia/core/pal_mac.cc deleted file mode 100644 index edcfef4aa..000000000 --- a/src/xenia/core/pal_mac.cc +++ /dev/null @@ -1,84 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include -#include -#include -#include -#include -#include - - -namespace { -typedef struct xe_pal_mac { - double time_to_sec; -} xe_pal_mac_t; - -xe_pal_mac_t* pal; -} - - -void xe_pal_dealloc(); -int xe_pal_init(xe_pal_options_t options) { - pal = (xe_pal_mac_t*)xe_calloc(sizeof(pal)); - - mach_timebase_info_data_t info; - mach_timebase_info(&info); - pal->time_to_sec = (double)((info.numer / info.denom) / 1000000000.0); - - atexit(xe_pal_dealloc); - return 0; -} - -void xe_pal_dealloc() { - // - - xe_free(pal); -} - -int xe_pal_get_system_info(xe_system_info* out_info) { - xe_zero_struct(out_info, sizeof(xe_system_info)); - out_info->processors.physical_count = 1; - out_info->processors.logical_count = 1; - - // http://geekinfo.googlecode.com/svn-history/r74/trunk/src/macosxsystem.cpp - int count; - size_t size = sizeof(int); - if (!sysctlbyname("hw.physicalcpu", &count, &size, NULL, 0)) { - out_info->processors.physical_count = count; - } else if (!sysctlbyname("hw.packages", &count, &size, NULL, 0)) { - out_info->processors.physical_count = count; - } else { - out_info->processors.physical_count = 1; - } - if (!sysctlbyname("hw.logicalcpu", &count, &size, NULL, 0)) { - out_info->processors.logical_count = count; - } else if (!sysctlbyname("hw.ncpu", &count, &size, NULL, 0)) { - out_info->processors.logical_count = count; - } else { - out_info->processors.logical_count = 1; - } - - return 0; -} - -double xe_pal_now() { - // According to a bunch of random posts, CACurrentMediaTime is a better call: - // https://devforums.apple.com/message/118806#118806 - // CACurrentMediaTime is based on mach_absolute_time(), which doesn't have a - // dependency on QuartzCore: - // http://developer.apple.com/library/mac/#qa/qa2004/qa1398.html - - // return (double)CFAbsoluteTimeGetCurrent(); - // return (double)CACurrentMediaTime(); - - return (double)(mach_absolute_time() * pal->time_to_sec); -} diff --git a/src/xenia/core/pal_posix.cc b/src/xenia/core/pal_posix.cc deleted file mode 100644 index 93b2986f8..000000000 --- a/src/xenia/core/pal_posix.cc +++ /dev/null @@ -1,62 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - - -namespace { -typedef struct xe_pal_posix { - -} xe_pal_posix_t; - -xe_pal_posix_t* pal; -} - - -void xe_pal_dealloc(); -int xe_pal_init(xe_pal_options_t options) { - pal = (xe_pal_posix_t)xe_calloc(sizeof(pal)); - - // - - atexit(xe_pal_dealloc); - return 0; -} - -void xe_pal_dealloc() { - // - - xe_free(pal); -} - -int xe_pal_get_system_info(xe_system_info* out_info) { - xe_zero_struct(out_info, sizeof(xe_system_info)); - out_info->processors.physical_count = 1; - out_info->processors.logical_count = 1; - -#if defined(_SC_NPROCESSORS_ONLN) - int nproc = sysconf(_SC_NPROCESSORS_ONLN); - if (nproc >= 1) { - // Only able to get logical count. - sysInfo->processors.logicalCount = nproc; - } -#else -#warning no calls to get processor counts -#endif // _SC_NPROCESSORS_ONLN - - return 0; -} - -double xe_pal_now() { - // http://www.kernel.org/doc/man-pages/online/pages/man2/clock_gettime.2.html - // http://juliusdavies.ca/posix_clocks/clock_realtime_linux_faq.html - struct timespec ts; - CPIGNORE(clock_gettime(CLOCK_MONOTONIC, &ts)); - return (double)(ts.tv_sec + (ts.tv_nsec * 1000000000.0)); -} diff --git a/src/xenia/core/pal_win.cc b/src/xenia/core/pal_win.cc deleted file mode 100644 index c0b0a90a3..000000000 --- a/src/xenia/core/pal_win.cc +++ /dev/null @@ -1,146 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include - -namespace { -typedef struct xe_pal_win { - bool use_high_perf_timer; - double inv_ticks_per_sec; -} xe_pal_win_t; - -xe_pal_win_t* pal; -} - - -void xe_pal_dealloc(); -int xe_pal_init(xe_pal_options_t options) { - pal = (xe_pal_win_t*)xe_calloc(sizeof(xe_pal_win_t)); - - // Get QPC timing frequency... hopefully stable over the life of the app, - // but likely not. - // TODO(benvanik): requery periodically/etc. - LARGE_INTEGER ticks_per_sec; - if (QueryPerformanceFrequency(&ticks_per_sec)) { - pal->use_high_perf_timer = true; - pal->inv_ticks_per_sec = 1.0 / (double)ticks_per_sec.QuadPart; - } else { - pal->use_high_perf_timer = false; - XELOGW("Falling back from high performance timer"); - } - - // Setup COM on the main thread. - // NOTE: this may fail if COM has already been initialized - that's OK. - CoInitializeEx(NULL, COINIT_MULTITHREADED); - - atexit(xe_pal_dealloc); - return 0; -} - -void xe_pal_dealloc() { - // - - xe_free(pal); -} - -// http://msdn.microsoft.com/en-us/library/ms683194.aspx -namespace { -DWORD CountSetBits(ULONG_PTR bitMask) { - DWORD LSHIFT = sizeof(ULONG_PTR)*8 - 1; - DWORD bitSetCount = 0; - ULONG_PTR bitTest = (ULONG_PTR)1 << LSHIFT; - for (DWORD i = 0; i <= LSHIFT; ++i, bitTest /= 2) { - bitSetCount += ((bitMask & bitTest)?1:0); - } - return bitSetCount; -} -} -int xe_pal_get_system_info(xe_system_info* out_info) { - int result_code = 1; - xe_zero_struct(out_info, sizeof(xe_system_info)); - out_info->processors.physical_count = 1; - out_info->processors.logical_count = 1; - - typedef BOOL (WINAPI *LPFN_GLPI)( - PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD); - - HMODULE kernel32 = NULL; - LPFN_GLPI glpi = NULL; - PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL; - - kernel32 = GetModuleHandle(L"kernel32"); - XEEXPECTNOTNULL(kernel32); - glpi = (LPFN_GLPI)GetProcAddress(kernel32, "GetLogicalProcessorInformation"); - XEEXPECTNOTNULL(glpi); - - // Call GLPI once to get the buffer size, allocate it, then call again. - DWORD buffer_length = 0; - XEEXPECTFALSE(glpi(NULL, &buffer_length)); - XEEXPECT(GetLastError() == ERROR_INSUFFICIENT_BUFFER); - buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)xe_malloc(buffer_length); - XEEXPECTNOTNULL(buffer); - XEEXPECTTRUE(glpi(buffer, &buffer_length)); - XEEXPECTNOTZERO(buffer_length); - - out_info->processors.physical_count = 0; - out_info->processors.logical_count = 0; - - size_t info_count = buffer_length / - sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); - for (size_t n = 0; n < info_count; n++) { - switch (buffer[n].Relationship) { - case RelationProcessorPackage: - out_info->processors.physical_count++; - break; - case RelationProcessorCore: - if (buffer[n].ProcessorCore.Flags == 1) { - // Hyper-threaded. - // The number of processors is set as bits in ProcessorMask. - out_info->processors.logical_count += - CountSetBits(buffer[n].ProcessorMask); - } else { - // A real core - just count as one. - out_info->processors.logical_count++; - } - break; - } - } - - out_info->processors.physical_count = - std::max(1u, out_info->processors.physical_count); - out_info->processors.logical_count = - std::max(1u, out_info->processors.logical_count); - - result_code = 0; -XECLEANUP: - xe_free(buffer); - if (kernel32) { - FreeLibrary(kernel32); - } - return result_code; -} - -double xe_pal_now() { - if (pal->use_high_perf_timer) { - LARGE_INTEGER counter; - QueryPerformanceCounter(&counter); - return counter.QuadPart * pal->inv_ticks_per_sec; - } else { - // Using GetSystemTimeAsFileTime instead of GetSystemTime() as it has a - // 100ns resolution. - FILETIME ft; - GetSystemTimeAsFileTime(&ft); - ULARGE_INTEGER uli; - uli.LowPart = ft.dwLowDateTime; - uli.HighPart = ft.dwHighDateTime; - return uli.QuadPart / 10000000.0; - } -} diff --git a/src/xenia/core/sources.gypi b/src/xenia/core/sources.gypi index 206ae0e60..858a696bb 100644 --- a/src/xenia/core/sources.gypi +++ b/src/xenia/core/sources.gypi @@ -4,7 +4,6 @@ 'hash.cc', 'hash.h', 'mmap.h', - 'pal.h', 'ref.cc', 'ref.h', 'run_loop.h', @@ -20,18 +19,15 @@ }], ['OS == "linux"', { 'sources': [ - 'pal_posix.cc', ], }], ['OS == "mac"', { 'sources': [ - 'pal_mac.cc', ], }], ['OS == "win"', { 'sources': [ 'mmap_win.cc', - 'pal_win.cc', 'run_loop_win.cc', 'socket_win.cc', ], diff --git a/src/xenia/gpu/d3d11/d3d11_graphics_system.cc b/src/xenia/gpu/d3d11/d3d11_graphics_system.cc index f88977bac..7f357334a 100644 --- a/src/xenia/gpu/d3d11/d3d11_graphics_system.cc +++ b/src/xenia/gpu/d3d11/d3d11_graphics_system.cc @@ -9,6 +9,8 @@ #include +#include + #include #include #include @@ -24,8 +26,7 @@ using namespace xe::gpu::d3d11; D3D11GraphicsSystem::D3D11GraphicsSystem(Emulator* emulator) : GraphicsSystem(emulator), window_(nullptr), dxgi_factory_(nullptr), device_(nullptr), - timer_queue_(nullptr), vsync_timer_(nullptr), - last_swap_time_(0.0) { + timer_queue_(nullptr), vsync_timer_(nullptr) { } D3D11GraphicsSystem::~D3D11GraphicsSystem() { @@ -142,8 +143,9 @@ void D3D11GraphicsSystem::Initialize() { void D3D11GraphicsSystem::Pump() { SCOPE_profile_cpu_f("gpu"); - double time_since_last_swap = xe_pal_now() - last_swap_time_; - if (time_since_last_swap > 1.0) { + auto time_since_last_swap = std::chrono::duration_cast( + std::chrono::high_resolution_clock::now() - last_swap_time_); + if (time_since_last_swap.count() > 1) { // Force a swap when profiling. if (Profiler::is_enabled()) { window_->Swap(); @@ -159,7 +161,7 @@ void D3D11GraphicsSystem::Swap() { // If we are set to vsync this will block. window_->Swap(); - last_swap_time_ = xe_pal_now(); + last_swap_time_ = std::chrono::high_resolution_clock::now(); } void __stdcall D3D11GraphicsSystem::VsyncCallback(D3D11GraphicsSystem* gs, diff --git a/src/xenia/gpu/d3d11/d3d11_graphics_system.h b/src/xenia/gpu/d3d11/d3d11_graphics_system.h index 487e21821..bdefc2c21 100644 --- a/src/xenia/gpu/d3d11/d3d11_graphics_system.h +++ b/src/xenia/gpu/d3d11/d3d11_graphics_system.h @@ -49,7 +49,7 @@ private: HANDLE timer_queue_; HANDLE vsync_timer_; - double last_swap_time_; + std::chrono::high_resolution_clock::time_point last_swap_time_; }; diff --git a/src/xenia/gpu/graphics_system.cc b/src/xenia/gpu/graphics_system.cc index 93b69984e..c969e23d2 100644 --- a/src/xenia/gpu/graphics_system.cc +++ b/src/xenia/gpu/graphics_system.cc @@ -29,7 +29,7 @@ GraphicsSystem::GraphicsSystem(Emulator* emulator) : running_(false), driver_(nullptr), command_processor_(nullptr), interrupt_callback_(0), interrupt_callback_data_(0), - last_interrupt_time_(0), thread_wait_(nullptr) { + thread_wait_(nullptr) { // Create the run loop used for any windows/etc. // This must be done on the thread we create the driver. run_loop_ = xe_run_loop_create(); @@ -193,7 +193,6 @@ void GraphicsSystem::DispatchInterruptCallback( } // NOTE: we may be executing in some random thread. - last_interrupt_time_ = xe_pal_now(); if (!interrupt_callback_) { return; } diff --git a/src/xenia/gpu/graphics_system.h b/src/xenia/gpu/graphics_system.h index 84685db79..0a068ff71 100644 --- a/src/xenia/gpu/graphics_system.h +++ b/src/xenia/gpu/graphics_system.h @@ -81,7 +81,6 @@ protected: uint32_t interrupt_callback_; uint32_t interrupt_callback_data_; - double last_interrupt_time_; HANDLE thread_wait_; }; diff --git a/tools/xenia-compare/xenia-compare.cc b/tools/xenia-compare/xenia-compare.cc index e5f338d48..16200cb21 100644 --- a/tools/xenia-compare/xenia-compare.cc +++ b/tools/xenia-compare/xenia-compare.cc @@ -23,14 +23,6 @@ namespace xc { using xdb::PostmortemDebugTarget; int main(std::vector& args) { - // Create platform abstraction layer. - xe_pal_options_t pal_options; - xe_zero_struct(&pal_options, sizeof(pal_options)); - if (xe_pal_init(pal_options)) { - XEFATAL("Failed to initialize PAL"); - return 1; - } - auto left_target = std::make_unique(); if (!left_target->LoadTrace(poly::to_wstring(FLAGS_trace_file_left))) { XEFATAL("Unable to load left trace file: %s", diff --git a/tools/xenia-debug/xenia-debug.cc b/tools/xenia-debug/xenia-debug.cc index f16e2401f..ce8450d50 100644 --- a/tools/xenia-debug/xenia-debug.cc +++ b/tools/xenia-debug/xenia-debug.cc @@ -24,14 +24,6 @@ DEFINE_string(content_file, "", namespace xdb { int main(std::vector& args) { - // Create platform abstraction layer. - xe_pal_options_t pal_options; - xe_zero_struct(&pal_options, sizeof(pal_options)); - if (xe_pal_init(pal_options)) { - XEFATAL("Failed to initialize PAL"); - return 1; - } - wxInitializer init; if (!init.IsOk()) { XEFATAL("Failed to initialize wxWidgets"); diff --git a/tools/xenia-run/xenia-run.cc b/tools/xenia-run/xenia-run.cc index 4f95bbf2b..a238824df 100644 --- a/tools/xenia-run/xenia-run.cc +++ b/tools/xenia-run/xenia-run.cc @@ -38,14 +38,6 @@ int xenia_run(std::vector& args) { // Normalize the path and make absolute. std::wstring abs_path = poly::to_absolute_path(path); - // Create platform abstraction layer. - xe_pal_options_t pal_options; - xe_zero_struct(&pal_options, sizeof(pal_options)); - if (xe_pal_init(pal_options)) { - XELOGE("Failed to initialize PAL"); - return 1; - } - // Create the emulator. auto emulator = std::make_unique(L""); X_STATUS result = emulator->Setup(); diff --git a/tools/xenia-test/xenia-test.cc b/tools/xenia-test/xenia-test.cc index 955cc2eda..3a6f78b72 100644 --- a/tools/xenia-test/xenia-test.cc +++ b/tools/xenia-test/xenia-test.cc @@ -229,10 +229,6 @@ int run_tests(std::string& test_name) { vector test_files; - xe_pal_options_t pal_options; - xe_zero_struct(&pal_options, sizeof(pal_options)); - XEEXPECTZERO(xe_pal_init(pal_options)); - XEEXPECTZERO(discover_tests(FLAGS_test_path, test_files)); if (!test_files.size()) { printf("No tests discovered - invalid path?\n"); From 383d3acbb0e3a650f757339b1270990465a5d45c Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 16 Aug 2014 21:36:01 -0700 Subject: [PATCH 129/388] Some fs/ cleanup. --- src/xenia/kernel/fs/device.cc | 10 +- src/xenia/kernel/fs/device.h | 2 - .../kernel/fs/devices/stfs_container_entry.cc | 2 +- .../kernel/fs/devices/stfs_container_entry.h | 2 +- src/xenia/kernel/fs/entry.cc | 10 +- src/xenia/kernel/fs/entry.h | 55 +++-- src/xenia/kernel/fs/filesystem.cc | 27 +-- src/xenia/kernel/fs/gdfx.cc | 77 +++---- src/xenia/kernel/fs/gdfx.h | 51 +++-- src/xenia/kernel/fs/stfs.cc | 201 ++++++++---------- src/xenia/kernel/fs/stfs.h | 201 +++++++++--------- 11 files changed, 301 insertions(+), 337 deletions(-) diff --git a/src/xenia/kernel/fs/device.cc b/src/xenia/kernel/fs/device.cc index 9bc191b27..f4c32a000 100644 --- a/src/xenia/kernel/fs/device.cc +++ b/src/xenia/kernel/fs/device.cc @@ -9,10 +9,14 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::fs; +namespace xe { +namespace kernel { +namespace fs { Device::Device(const std::string& path) : path_(path) {} Device::~Device() = default; + +} // namespace fs +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/fs/device.h b/src/xenia/kernel/fs/device.h index 81d409761..af24004da 100644 --- a/src/xenia/kernel/fs/device.h +++ b/src/xenia/kernel/fs/device.h @@ -12,9 +12,7 @@ #include -#include #include - #include namespace xe { diff --git a/src/xenia/kernel/fs/devices/stfs_container_entry.cc b/src/xenia/kernel/fs/devices/stfs_container_entry.cc index 1af716c67..e738d2607 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_entry.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_entry.cc @@ -65,7 +65,7 @@ X_STATUS STFSContainerEntry::QueryDirectory( auto end = (uint8_t*)out_info + length; - auto entry = *stfs_entry_iterator_; + auto entry = stfs_entry_iterator_->get(); auto entry_name = entry->name; if (((uint8_t*)&out_info->file_name[0]) + entry_name.size() > end) { diff --git a/src/xenia/kernel/fs/devices/stfs_container_entry.h b/src/xenia/kernel/fs/devices/stfs_container_entry.h index 8858a3441..aead9c014 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_entry.h +++ b/src/xenia/kernel/fs/devices/stfs_container_entry.h @@ -46,7 +46,7 @@ public: private: xe_mmap_ref mmap_; STFSEntry* stfs_entry_; - std::vector::iterator stfs_entry_iterator_; + std::vector>::iterator stfs_entry_iterator_; }; diff --git a/src/xenia/kernel/fs/entry.cc b/src/xenia/kernel/fs/entry.cc index 30b18d74b..448207229 100644 --- a/src/xenia/kernel/fs/entry.cc +++ b/src/xenia/kernel/fs/entry.cc @@ -10,9 +10,9 @@ #include #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::fs; +namespace xe { +namespace kernel { +namespace fs { MemoryMapping::MemoryMapping(uint8_t* address, size_t length) : address_(address), length_(length) {} @@ -28,3 +28,7 @@ Entry::Entry(Type type, Device* device, const std::string& path) } Entry::~Entry() = default; + +} // namespace fs +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/fs/entry.h b/src/xenia/kernel/fs/entry.h index 1f5b09d1a..f0cb428d3 100644 --- a/src/xenia/kernel/fs/entry.h +++ b/src/xenia/kernel/fs/entry.h @@ -12,19 +12,19 @@ #include -#include #include - #include - -XEDECLARECLASS2(xe, kernel, KernelState); -XEDECLARECLASS2(xe, kernel, XFile); -XEDECLARECLASS2(xe, kernel, XFileInfo); -XEDECLARECLASS2(xe, kernel, XDirectoryInfo); -XEDECLARECLASS2(xe, kernel, XVolumeInfo); -XEDECLARECLASS2(xe, kernel, XFileSystemAttributeInfo); - +namespace xe { +namespace kernel { +class KernelState; +class XFile; +class XFileInfo; +class XFileSystemAttributeInfo; +class XDirectoryInfo; +class XVolumeInfo; +} // namespace kernel +} // namespace xe namespace xe { namespace kernel { @@ -32,23 +32,21 @@ namespace fs { class Device; - class MemoryMapping { -public: + public: MemoryMapping(uint8_t* address, size_t length); virtual ~MemoryMapping(); uint8_t* address() const { return address_; } size_t length() const { return length_; } -private: - uint8_t* address_; - size_t length_; + private: + uint8_t* address_; + size_t length_; }; - class Entry { -public: + public: enum Type { kTypeFile, kTypeDirectory, @@ -64,32 +62,29 @@ public: const std::string& name() const { return name_; } virtual X_STATUS QueryInfo(XFileInfo* out_info) = 0; - virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info, - size_t length, const char* file_name, bool restart) = 0; + virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info, size_t length, + const char* file_name, bool restart) = 0; virtual bool can_map() { return false; } - virtual MemoryMapping* CreateMemoryMapping( - xe_file_mode file_mode, const size_t offset, const size_t length) { + virtual MemoryMapping* CreateMemoryMapping(xe_file_mode file_mode, + const size_t offset, + const size_t length) { return NULL; } - virtual X_STATUS Open( - KernelState* kernel_state, - uint32_t desired_access, bool async, - XFile** out_file) = 0; + virtual X_STATUS Open(KernelState* kernel_state, uint32_t desired_access, + bool async, XFile** out_file) = 0; -private: - Type type_; - Device* device_; + private: + Type type_; + Device* device_; std::string path_; std::string absolute_path_; std::string name_; }; - } // namespace fs } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_FS_ENTRY_H_ diff --git a/src/xenia/kernel/fs/filesystem.cc b/src/xenia/kernel/fs/filesystem.cc index 26cc4b35d..0b9054359 100644 --- a/src/xenia/kernel/fs/filesystem.cc +++ b/src/xenia/kernel/fs/filesystem.cc @@ -14,14 +14,11 @@ #include #include +namespace xe { +namespace kernel { +namespace fs { -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::fs; - - -FileSystem::FileSystem() { -} +FileSystem::FileSystem() {} FileSystem::~FileSystem() { // Delete all devices. @@ -106,14 +103,14 @@ int FileSystem::RegisterDevice(const std::string& path, Device* device) { return 0; } -int FileSystem::RegisterHostPathDevice( - const std::string& path, const std::wstring& local_path) { +int FileSystem::RegisterHostPathDevice(const std::string& path, + const std::wstring& local_path) { Device* device = new HostPathDevice(path, local_path); return RegisterDevice(path, device); } -int FileSystem::RegisterDiscImageDevice( - const std::string& path, const std::wstring& local_path) { +int FileSystem::RegisterDiscImageDevice(const std::string& path, + const std::wstring& local_path) { DiscImageDevice* device = new DiscImageDevice(path, local_path); if (device->Init()) { return 1; @@ -121,8 +118,8 @@ int FileSystem::RegisterDiscImageDevice( return RegisterDevice(path, device); } -int FileSystem::RegisterSTFSContainerDevice( - const std::string& path, const std::wstring& local_path) { +int FileSystem::RegisterSTFSContainerDevice(const std::string& path, + const std::wstring& local_path) { STFSContainerDevice* device = new STFSContainerDevice(path, local_path); if (device->Init()) { return 1; @@ -178,3 +175,7 @@ Entry* FileSystem::ResolvePath(const std::string& path) { XELOGE("ResolvePath(%s) failed - no root found", path.c_str()); return NULL; } + +} // namespace fs +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/fs/gdfx.cc b/src/xenia/kernel/fs/gdfx.cc index 9f275ff33..7f70a26b7 100644 --- a/src/xenia/kernel/fs/gdfx.cc +++ b/src/xenia/kernel/fs/gdfx.cc @@ -13,21 +13,14 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::fs; +namespace xe { +namespace kernel { +namespace fs { +const size_t kXESectorSize = 2048; -namespace { - -#define kXESectorSize 2048 - -} - - -GDFXEntry::GDFXEntry() : - attributes(X_FILE_ATTRIBUTE_NONE), offset(0), size(0) { -} +GDFXEntry::GDFXEntry() + : attributes(X_FILE_ATTRIBUTE_NONE), offset(0), size(0) {} GDFXEntry::~GDFXEntry() { for (std::vector::iterator it = children.begin(); @@ -57,7 +50,6 @@ void GDFXEntry::Dump(int indent) { } } - GDFX::GDFX(xe_mmap_ref mmap) { mmap_ = xe_mmap_retain(mmap); @@ -70,28 +62,26 @@ GDFX::~GDFX() { xe_mmap_release(mmap_); } -GDFXEntry* GDFX::root_entry() { - return root_entry_; -} +GDFXEntry* GDFX::root_entry() { return root_entry_; } GDFX::Error GDFX::Load() { - Error result = kErrorOutOfMemory; - ParseState state; xe_zero_struct(&state, sizeof(state)); - state.ptr = (uint8_t*)xe_mmap_get_addr(mmap_); - state.size = xe_mmap_get_length(mmap_); + state.ptr = (uint8_t*)xe_mmap_get_addr(mmap_); + state.size = xe_mmap_get_length(mmap_); - result = Verify(state); - XEEXPECTZERO(result); + auto result = Verify(state); + if (result != kSuccess) { + return result; + } result = ReadAllEntries(state, state.ptr + state.root_offset); - XEEXPECTZERO(result); + if (result != kSuccess) { + return result; + } - result = kSuccess; -XECLEANUP: - return result; + return kSuccess; } void GDFX::Dump() { @@ -103,7 +93,7 @@ void GDFX::Dump() { GDFX::Error GDFX::Verify(ParseState& state) { // Find sector 32 of the game partition - try at a few points. const static size_t likely_offsets[] = { - 0x00000000, 0x0000FB20, 0x00020600, 0x0FD90000, + 0x00000000, 0x0000FB20, 0x00020600, 0x0FD90000, }; bool magic_found = false; for (size_t n = 0; n < poly::countof(likely_offsets); n++) { @@ -124,10 +114,9 @@ GDFX::Error GDFX::Verify(ParseState& state) { } uint8_t* fs_ptr = state.ptr + state.game_offset + (32 * kXESectorSize); state.root_sector = poly::load(fs_ptr + 20); - state.root_size = poly::load(fs_ptr + 24); + state.root_size = poly::load(fs_ptr + 24); state.root_offset = state.game_offset + (state.root_sector * kXESectorSize); - if (state.root_size < 13 || - state.root_size > 32 * 1024 * 1024) { + if (state.root_size < 13 || state.root_size > 32 * 1024 * 1024) { return kErrorDamagedFile; } @@ -143,8 +132,8 @@ GDFX::Error GDFX::ReadAllEntries(ParseState& state, const uint8_t* root_buffer) { root_entry_ = new GDFXEntry(); root_entry_->offset = 0; - root_entry_->size = 0; - root_entry_->name = ""; + root_entry_->size = 0; + root_entry_->name = ""; root_entry_->attributes = X_FILE_ATTRIBUTE_DIRECTORY; if (!ReadEntry(state, root_buffer, 0, root_entry_)) { @@ -158,13 +147,13 @@ bool GDFX::ReadEntry(ParseState& state, const uint8_t* buffer, uint16_t entry_ordinal, GDFXEntry* parent) { const uint8_t* p = buffer + (entry_ordinal * 4); - uint16_t node_l = poly::load(p + 0); - uint16_t node_r = poly::load(p + 2); - size_t sector = poly::load(p + 4); - size_t length = poly::load(p + 8); - uint8_t attributes = poly::load(p + 12); - uint8_t name_length = poly::load(p + 13); - char* name = (char*)(p + 14); + uint16_t node_l = poly::load(p + 0); + uint16_t node_r = poly::load(p + 2); + size_t sector = poly::load(p + 4); + size_t length = poly::load(p + 8); + uint8_t attributes = poly::load(p + 12); + uint8_t name_length = poly::load(p + 13); + char* name = (char*)(p + 14); if (node_l && !ReadEntry(state, buffer, node_l, parent)) { return false; @@ -181,7 +170,7 @@ bool GDFX::ReadEntry(ParseState& state, const uint8_t* buffer, if (attributes & X_FILE_ATTRIBUTE_DIRECTORY) { // Folder. entry->offset = 0; - entry->size = 0; + entry->size = 0; if (length) { // Not a leaf - read in children. if (state.size < state.game_offset + (sector * kXESectorSize)) { @@ -198,7 +187,7 @@ bool GDFX::ReadEntry(ParseState& state, const uint8_t* buffer, } else { // File. entry->offset = state.game_offset + (sector * kXESectorSize); - entry->size = length; + entry->size = length; } // Read next file in the list. @@ -208,3 +197,7 @@ bool GDFX::ReadEntry(ParseState& state, const uint8_t* buffer, return true; } + +} // namespace fs +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/fs/gdfx.h b/src/xenia/kernel/fs/gdfx.h index b6727044f..28e6d159d 100644 --- a/src/xenia/kernel/fs/gdfx.h +++ b/src/xenia/kernel/fs/gdfx.h @@ -10,25 +10,20 @@ #ifndef XENIA_KERNEL_FS_GDFX_H_ #define XENIA_KERNEL_FS_GDFX_H_ -#include -#include - #include +#include #include #include - namespace xe { namespace kernel { namespace fs { - class GDFX; - class GDFXEntry { -public: + public: GDFXEntry(); ~GDFXEntry(); @@ -36,23 +31,22 @@ public: void Dump(int indent); - std::string name; + std::string name; X_FILE_ATTRIBUTES attributes; - size_t offset; - size_t size; + size_t offset; + size_t size; std::vector children; }; - class GDFX { -public: + public: enum Error { - kSuccess = 0, - kErrorOutOfMemory = -1, - kErrorReadError = -10, - kErrorFileMismatch = -30, - kErrorDamagedFile = -31, + kSuccess = 0, + kErrorOutOfMemory = -1, + kErrorReadError = -10, + kErrorFileMismatch = -30, + kErrorDamagedFile = -31, }; GDFX(xe_mmap_ref mmap); @@ -63,17 +57,22 @@ public: Error Load(); void Dump(); -private: + private: typedef struct { - uint8_t* ptr; + uint8_t* ptr; - size_t size; // Size (bytes) of total image + // Size (bytes) of total image. + size_t size; - size_t game_offset; // Offset (bytes) of game partition + // Offset (bytes) of game partition. + size_t game_offset; - size_t root_sector; // Offset (sector) of root - size_t root_offset; // Offset (bytes) of root - size_t root_size; // Size (bytes) of root + // Offset (sector) of root. + size_t root_sector; + // Offset (bytes) of root. + size_t root_offset; + // Size (bytes) of root. + size_t root_size; } ParseState; Error Verify(ParseState& state); @@ -84,13 +83,11 @@ private: xe_mmap_ref mmap_; - GDFXEntry* root_entry_; + GDFXEntry* root_entry_; }; - } // namespace fs } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_FS_GDFX_H_ diff --git a/src/xenia/kernel/fs/stfs.cc b/src/xenia/kernel/fs/stfs.cc index a72c6e57b..6faa76f1b 100644 --- a/src/xenia/kernel/fs/stfs.cc +++ b/src/xenia/kernel/fs/stfs.cc @@ -13,63 +13,62 @@ #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::fs; +namespace xe { +namespace kernel { +namespace fs { -#define XEGETUINT24BE(p) \ - (((uint32_t)poly::load_and_swap((p) + 0) << 16) | \ - ((uint32_t)poly::load_and_swap((p) + 1) << 8) | \ - (uint32_t)poly::load_and_swap((p) + 2)) -#define XEGETUINT24LE(p) \ - (((uint32_t)poly::load((p) + 2) << 16) | \ - ((uint32_t)poly::load((p) + 1) << 8) | \ - (uint32_t)poly::load((p) + 0)) +#define XEGETUINT24BE(p) \ + (((uint32_t)poly::load_and_swap((p)+0) << 16) | \ + ((uint32_t)poly::load_and_swap((p)+1) << 8) | \ + (uint32_t)poly::load_and_swap((p)+2)) +#define XEGETUINT24LE(p) \ + (((uint32_t)poly::load((p)+2) << 16) | \ + ((uint32_t)poly::load((p)+1) << 8) | \ + (uint32_t)poly::load((p)+0)) bool STFSVolumeDescriptor::Read(const uint8_t* p) { - descriptor_size = poly::load_and_swap(p + 0x00); + descriptor_size = poly::load_and_swap(p + 0x00); if (descriptor_size != 0x24) { XELOGE("STFS volume descriptor size mismatch, expected 0x24 but got 0x%X", descriptor_size); return false; } - reserved = poly::load_and_swap(p + 0x01); - block_separation = poly::load_and_swap(p + 0x02); - file_table_block_count = poly::load_and_swap(p + 0x03); - file_table_block_number = XEGETUINT24BE(p + 0x05); + reserved = poly::load_and_swap(p + 0x01); + block_separation = poly::load_and_swap(p + 0x02); + file_table_block_count = poly::load_and_swap(p + 0x03); + file_table_block_number = XEGETUINT24BE(p + 0x05); xe_copy_struct(top_hash_table_hash, p + 0x08, 0x14); - total_allocated_block_count = poly::load_and_swap(p + 0x1C); + total_allocated_block_count = poly::load_and_swap(p + 0x1C); total_unallocated_block_count = poly::load_and_swap(p + 0x20); return true; }; - bool STFSHeader::Read(const uint8_t* p) { xe_copy_struct(license_entries, p + 0x22C, 0x100); xe_copy_struct(header_hash, p + 0x32C, 0x14); - header_size = poly::load_and_swap(p + 0x340); - content_type = (STFSContentType)poly::load_and_swap(p + 0x344); - metadata_version = poly::load_and_swap(p + 0x348); + header_size = poly::load_and_swap(p + 0x340); + content_type = (STFSContentType)poly::load_and_swap(p + 0x344); + metadata_version = poly::load_and_swap(p + 0x348); if (metadata_version > 1) { // This is a variant of thumbnail data/etc. // Can just ignore it for now (until we parse thumbnails). XELOGW("STFSContainer doesn't support version %d yet", metadata_version); } - content_size = poly::load_and_swap(p + 0x34C); - media_id = poly::load_and_swap(p + 0x354); - version = poly::load_and_swap(p + 0x358); - base_version = poly::load_and_swap(p + 0x35C); - title_id = poly::load_and_swap(p + 0x360); - platform = (STFSPlatform)poly::load_and_swap(p + 0x364); - executable_type = poly::load_and_swap(p + 0x365); - disc_number = poly::load_and_swap(p + 0x366); - disc_in_set = poly::load_and_swap(p + 0x367); - save_game_id = poly::load_and_swap(p + 0x368); + content_size = poly::load_and_swap(p + 0x34C); + media_id = poly::load_and_swap(p + 0x354); + version = poly::load_and_swap(p + 0x358); + base_version = poly::load_and_swap(p + 0x35C); + title_id = poly::load_and_swap(p + 0x360); + platform = (STFSPlatform)poly::load_and_swap(p + 0x364); + executable_type = poly::load_and_swap(p + 0x365); + disc_number = poly::load_and_swap(p + 0x366); + disc_in_set = poly::load_and_swap(p + 0x367); + save_game_id = poly::load_and_swap(p + 0x368); xe_copy_struct(console_id, p + 0x36C, 0x5); xe_copy_struct(profile_id, p + 0x371, 0x8); - data_file_count = poly::load_and_swap(p + 0x39D); - data_file_combined_size = poly::load_and_swap(p + 0x3A1); - descriptor_type = (STFSDescriptorType)poly::load_and_swap(p + 0x3A9); + data_file_count = poly::load_and_swap(p + 0x39D); + data_file_combined_size = poly::load_and_swap(p + 0x3A1); + descriptor_type = (STFSDescriptorType)poly::load_and_swap(p + 0x3A9); if (descriptor_type != STFS_DESCRIPTOR_STFS) { XELOGE("STFS descriptor format not supported: %d", descriptor_type); return false; @@ -86,76 +85,61 @@ bool STFSHeader::Read(const uint8_t* p) { publisher_name[n] = poly::load_and_swap(p + 0x1611 + n * 2); title_name[n] = poly::load_and_swap(p + 0x1691 + n * 2); } - transfer_flags = poly::load_and_swap(p + 0x1711); - thumbnail_image_size = poly::load_and_swap(p + 0x1712); - title_thumbnail_image_size = poly::load_and_swap(p + 0x1716); + transfer_flags = poly::load_and_swap(p + 0x1711); + thumbnail_image_size = poly::load_and_swap(p + 0x1712); + title_thumbnail_image_size = poly::load_and_swap(p + 0x1716); xe_copy_struct(thumbnail_image, p + 0x171A, 0x4000); xe_copy_struct(title_thumbnail_image, p + 0x571A, 0x4000); return true; } -STFSEntry::STFSEntry() : - attributes(X_FILE_ATTRIBUTE_NONE), offset(0), size(0), - update_timestamp(0), access_timestamp(0) { -} - -STFSEntry::~STFSEntry() { - for (auto it = children.begin(); it != children.end(); ++it) { - delete *it; - } -} +STFSEntry::STFSEntry() + : attributes(X_FILE_ATTRIBUTE_NONE), + offset(0), + size(0), + update_timestamp(0), + access_timestamp(0) {} STFSEntry* STFSEntry::GetChild(const char* name) { // TODO(benvanik): a faster search - for (auto it = children.begin(); it != children.end(); ++it) { - STFSEntry* entry = *it; + for (const auto& entry : children) { if (strcasecmp(entry->name.c_str(), name) == 0) { - return entry; + return entry.get(); } } - return NULL; + return nullptr; } void STFSEntry::Dump(int indent) { printf("%s%s\n", std::string(indent, ' ').c_str(), name.c_str()); - for (auto it = children.begin(); it != children.end(); ++it) { - STFSEntry* entry = *it; + for (const auto& entry : children) { entry->Dump(indent + 2); } } - STFS::STFS(xe_mmap_ref mmap) { mmap_ = xe_mmap_retain(mmap); - - root_entry_ = NULL; } STFS::~STFS() { - delete root_entry_; - xe_mmap_release(mmap_); } -STFSEntry* STFS::root_entry() { - return root_entry_; -} - STFS::Error STFS::Load() { - Error result = kErrorOutOfMemory; - uint8_t* map_ptr = (uint8_t*)xe_mmap_get_addr(mmap_); - size_t map_size = xe_mmap_get_length(mmap_); + size_t map_size = xe_mmap_get_length(mmap_); - result = ReadHeaderAndVerify(map_ptr); - XEEXPECTZERO(result); + auto result = ReadHeaderAndVerify(map_ptr); + if (result != kSuccess) { + return result; + } result = ReadAllEntries(map_ptr); - XEEXPECTZERO(result); + if (result != kSuccess) { + return result; + } - result = kSuccess; -XECLEANUP: - return result; + return kSuccess; } void STFS::Dump() { @@ -192,10 +176,7 @@ STFS::Error STFS::ReadHeaderAndVerify(const uint8_t* map_ptr) { } STFS::Error STFS::ReadAllEntries(const uint8_t* map_ptr) { - root_entry_ = new STFSEntry(); - root_entry_->offset = 0; - root_entry_->size = 0; - root_entry_->name = ""; + root_entry_.reset(new STFSEntry()); root_entry_->attributes = X_FILE_ATTRIBUTE_DIRECTORY; std::vector entries; @@ -207,21 +188,21 @@ STFS::Error STFS::ReadAllEntries(const uint8_t* map_ptr) { const uint8_t* p = map_ptr + BlockToOffset(ComputeBlockNumber(table_block_index)); for (size_t m = 0; m < 0x1000 / 0x40; m++) { - const uint8_t* filename = p; // 0x28b + const uint8_t* filename = p; // 0x28b if (filename[0] == 0) { // Done. break; } - uint8_t filename_length_flags = poly::load_and_swap(p + 0x28); - uint32_t allocated_block_count = XEGETUINT24LE(p + 0x29); - uint32_t start_block_index = XEGETUINT24LE(p + 0x2F); - uint16_t path_indicator = poly::load_and_swap(p + 0x32); - uint32_t file_size = poly::load_and_swap(p + 0x34); - uint32_t update_timestamp = poly::load_and_swap(p + 0x38); - uint32_t access_timestamp = poly::load_and_swap(p + 0x3C); + uint8_t filename_length_flags = poly::load_and_swap(p + 0x28); + uint32_t allocated_block_count = XEGETUINT24LE(p + 0x29); + uint32_t start_block_index = XEGETUINT24LE(p + 0x2F); + uint16_t path_indicator = poly::load_and_swap(p + 0x32); + uint32_t file_size = poly::load_and_swap(p + 0x34); + uint32_t update_timestamp = poly::load_and_swap(p + 0x38); + uint32_t access_timestamp = poly::load_and_swap(p + 0x3C); p += 0x40; - STFSEntry* entry = new STFSEntry(); + auto entry = std::make_unique(); entry->name = std::string((char*)filename, filename_length_flags & 0x3F); entry->name.append(1, '\0'); // bit 0x40 = consecutive blocks (not fragmented?) @@ -229,23 +210,12 @@ STFS::Error STFS::ReadAllEntries(const uint8_t* map_ptr) { entry->attributes = X_FILE_ATTRIBUTE_DIRECTORY; } else { entry->attributes = X_FILE_ATTRIBUTE_NORMAL; - entry->offset = BlockToOffset(ComputeBlockNumber(start_block_index)); - entry->size = file_size; + entry->offset = BlockToOffset(ComputeBlockNumber(start_block_index)); + entry->size = file_size; } entry->update_timestamp = update_timestamp; entry->access_timestamp = access_timestamp; - entries.push_back(entry); - - const uint8_t* p = map_ptr + entry->offset; - - if (path_indicator == 0xFFFF) { - // Root entry. - root_entry_->children.push_back(entry); - } else { - // Lookup and add. - auto parent = entries[path_indicator]; - parent->children.push_back(entry); - } + entries.push_back(entry.get()); // Fill in all block records. // It's easier to do this now and just look them up later, at the cost @@ -255,12 +225,10 @@ STFS::Error STFS::ReadAllEntries(const uint8_t* map_ptr) { uint32_t block_index = start_block_index; size_t remaining_size = file_size; uint32_t info = 0x80; - while (remaining_size && - block_index && - info >= 0x80) { + while (remaining_size && block_index && info >= 0x80) { size_t block_size = std::min(0x1000ull, remaining_size); size_t offset = BlockToOffset(ComputeBlockNumber(block_index)); - entry->block_list.push_back({ offset, block_size }); + entry->block_list.push_back({offset, block_size}); remaining_size -= block_size; auto block_hash = GetBlockHash(map_ptr, block_index, 0); if (table_size_shift_ && block_hash.info < 0x80) { @@ -270,6 +238,15 @@ STFS::Error STFS::ReadAllEntries(const uint8_t* map_ptr) { info = block_hash.info; } } + + if (path_indicator == 0xFFFF) { + // Root entry. + root_entry_->children.push_back(std::move(entry)); + } else { + // Lookup and add. + auto parent = entries[path_indicator]; + parent->children.push_back(std::move(entry)); + } } auto block_hash = GetBlockHash(map_ptr, table_block_index, 0); @@ -327,12 +304,14 @@ uint32_t STFS::ComputeBlockNumber(uint32_t block_index) { return block; } -STFS::BlockHash_t STFS::GetBlockHash( - const uint8_t* map_ptr, - uint32_t block_index, uint32_t table_offset) { +STFS::BlockHash_t STFS::GetBlockHash(const uint8_t* map_ptr, + uint32_t block_index, + uint32_t table_offset) { static const uint32_t table_spacing[] = { - 0xAB, 0x718F, 0xFE7DA, // The distance in blocks between tables - 0xAC, 0x723A, 0xFD00B, // For when tables are 1 block and when they are 2 blocks + 0xAB, 0x718F, + 0xFE7DA, // The distance in blocks between tables + 0xAC, 0x723A, + 0xFD00B, // For when tables are 1 block and when they are 2 blocks }; uint32_t record = block_index % 0xAA; uint32_t table_index = @@ -343,10 +322,14 @@ STFS::BlockHash_t STFS::GetBlockHash( table_index += 1 << table_size_shift_; } } - //table_index += table_offset - (1 << table_size_shift_); + // table_index += table_offset - (1 << table_size_shift_); const uint8_t* hash_data = map_ptr + BlockToOffset(table_index); const uint8_t* record_data = hash_data + record * 0x18; uint32_t info = poly::load_and_swap(record_data + 0x14); uint32_t next_block_index = XEGETUINT24BE(record_data + 0x15); - return{ next_block_index, info }; + return {next_block_index, info}; } + +} // namespace fs +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/fs/stfs.h b/src/xenia/kernel/fs/stfs.h index 2355b4c12..da3e82627 100644 --- a/src/xenia/kernel/fs/stfs.h +++ b/src/xenia/kernel/fs/stfs.h @@ -10,23 +10,19 @@ #ifndef XENIA_KERNEL_FS_STFS_H_ #define XENIA_KERNEL_FS_STFS_H_ -#include -#include - +#include #include +#include #include #include - namespace xe { namespace kernel { namespace fs { - class STFS; - // http://www.free60.org/STFS enum STFSPackageType { @@ -36,120 +32,116 @@ enum STFSPackageType { }; enum STFSContentType : uint32_t { - STFS_CONTENT_ARCADE_TITLE = 0x000D0000, - STFS_CONTENT_AVATAR_ITEM = 0x00009000, - STFS_CONTENT_CACHE_FILE = 0x00040000, - STFS_CONTENT_COMMUNITY_GAME = 0x02000000, - STFS_CONTENT_GAME_DEMO = 0x00080000, - STFS_CONTENT_GAMER_PICTURE = 0x00020000, - STFS_CONTENT_GAME_TITLE = 0x000A0000, - STFS_CONTENT_GAME_TRAILER = 0x000C0000, - STFS_CONTENT_GAME_VIDEO = 0x00400000, - STFS_CONTENT_INSTALLED_GAME = 0x00004000, - STFS_CONTENT_INSTALLER = 0x000B0000, - STFS_CONTENT_IPTV_PAUSE_BUFFER = 0x00002000, - STFS_CONTENT_LICENSE_STORE = 0x000F0000, - STFS_CONTENT_MARKETPLACE_CONTENT = 0x00000002, - STFS_CONTENT_MOVIE = 0x00100000, - STFS_CONTENT_MUSIC_VIDEO = 0x00300000, - STFS_CONTENT_PODCAST_VIDEO = 0x00500000, - STFS_CONTENT_PROFILE = 0x00010000, - STFS_CONTENT_PUBLISHER = 0x00000003, - STFS_CONTENT_SAVED_GAME = 0x00000001, - STFS_CONTENT_STORAGE_DOWNLOAD = 0x00050000, - STFS_CONTENT_THEME = 0x00030000, - STFS_CONTENT_TV = 0x00200000, - STFS_CONTENT_VIDEO = 0x00090000, - STFS_CONTENT_VIRAL_VIDEO = 0x00600000, - STFS_CONTENT_XBOX_DOWNLOAD = 0x00070000, - STFS_CONTENT_XBOX_ORIGINAL_GAME = 0x00005000, - STFS_CONTENT_XBOX_SAVED_GAME = 0x00060000, - STFS_CONTENT_XBOX_360_TITLE = 0x00001000, - STFS_CONTENT_XBOX_TITLE = 0x00005000, - STFS_CONTENT_XNA = 0x000E0000, + STFS_CONTENT_ARCADE_TITLE = 0x000D0000, + STFS_CONTENT_AVATAR_ITEM = 0x00009000, + STFS_CONTENT_CACHE_FILE = 0x00040000, + STFS_CONTENT_COMMUNITY_GAME = 0x02000000, + STFS_CONTENT_GAME_DEMO = 0x00080000, + STFS_CONTENT_GAMER_PICTURE = 0x00020000, + STFS_CONTENT_GAME_TITLE = 0x000A0000, + STFS_CONTENT_GAME_TRAILER = 0x000C0000, + STFS_CONTENT_GAME_VIDEO = 0x00400000, + STFS_CONTENT_INSTALLED_GAME = 0x00004000, + STFS_CONTENT_INSTALLER = 0x000B0000, + STFS_CONTENT_IPTV_PAUSE_BUFFER = 0x00002000, + STFS_CONTENT_LICENSE_STORE = 0x000F0000, + STFS_CONTENT_MARKETPLACE_CONTENT = 0x00000002, + STFS_CONTENT_MOVIE = 0x00100000, + STFS_CONTENT_MUSIC_VIDEO = 0x00300000, + STFS_CONTENT_PODCAST_VIDEO = 0x00500000, + STFS_CONTENT_PROFILE = 0x00010000, + STFS_CONTENT_PUBLISHER = 0x00000003, + STFS_CONTENT_SAVED_GAME = 0x00000001, + STFS_CONTENT_STORAGE_DOWNLOAD = 0x00050000, + STFS_CONTENT_THEME = 0x00030000, + STFS_CONTENT_TV = 0x00200000, + STFS_CONTENT_VIDEO = 0x00090000, + STFS_CONTENT_VIRAL_VIDEO = 0x00600000, + STFS_CONTENT_XBOX_DOWNLOAD = 0x00070000, + STFS_CONTENT_XBOX_ORIGINAL_GAME = 0x00005000, + STFS_CONTENT_XBOX_SAVED_GAME = 0x00060000, + STFS_CONTENT_XBOX_360_TITLE = 0x00001000, + STFS_CONTENT_XBOX_TITLE = 0x00005000, + STFS_CONTENT_XNA = 0x000E0000, }; enum STFSPlatform : uint8_t { - STFS_PLATFORM_XBOX_360 = 0x02, - STFS_PLATFORM_PC = 0x04, + STFS_PLATFORM_XBOX_360 = 0x02, + STFS_PLATFORM_PC = 0x04, }; enum STFSDescriptorType : uint32_t { - STFS_DESCRIPTOR_STFS = 0, - STFS_DESCRIPTOR_SVOD = 1, + STFS_DESCRIPTOR_STFS = 0, + STFS_DESCRIPTOR_SVOD = 1, }; - class STFSVolumeDescriptor { -public: + public: bool Read(const uint8_t* p); - uint8_t descriptor_size; - uint8_t reserved; - uint8_t block_separation; - uint16_t file_table_block_count; - uint32_t file_table_block_number; - uint8_t top_hash_table_hash[0x14]; - uint32_t total_allocated_block_count; - uint32_t total_unallocated_block_count; + uint8_t descriptor_size; + uint8_t reserved; + uint8_t block_separation; + uint16_t file_table_block_count; + uint32_t file_table_block_number; + uint8_t top_hash_table_hash[0x14]; + uint32_t total_allocated_block_count; + uint32_t total_unallocated_block_count; }; - class STFSHeader { -public: + public: bool Read(const uint8_t* p); - uint8_t license_entries[0x100]; - uint8_t header_hash[0x14]; - uint32_t header_size; + uint8_t license_entries[0x100]; + uint8_t header_hash[0x14]; + uint32_t header_size; STFSContentType content_type; - uint32_t metadata_version; - uint64_t content_size; - uint32_t media_id; - uint32_t version; - uint32_t base_version; - uint32_t title_id; - STFSPlatform platform; - uint8_t executable_type; - uint8_t disc_number; - uint8_t disc_in_set; - uint32_t save_game_id; - uint8_t console_id[0x5]; - uint8_t profile_id[0x8]; + uint32_t metadata_version; + uint64_t content_size; + uint32_t media_id; + uint32_t version; + uint32_t base_version; + uint32_t title_id; + STFSPlatform platform; + uint8_t executable_type; + uint8_t disc_number; + uint8_t disc_in_set; + uint32_t save_game_id; + uint8_t console_id[0x5]; + uint8_t profile_id[0x8]; STFSVolumeDescriptor volume_descriptor; - uint32_t data_file_count; - uint64_t data_file_combined_size; + uint32_t data_file_count; + uint64_t data_file_combined_size; STFSDescriptorType descriptor_type; - uint8_t device_id[0x14]; - wchar_t display_names[0x900 / 2]; - wchar_t display_descs[0x900 / 2]; - wchar_t publisher_name[0x80 / 2]; - wchar_t title_name[0x80 / 2]; - uint8_t transfer_flags; - uint32_t thumbnail_image_size; - uint32_t title_thumbnail_image_size; - uint8_t thumbnail_image[0x4000]; - uint8_t title_thumbnail_image[0x4000]; + uint8_t device_id[0x14]; + wchar_t display_names[0x900 / 2]; + wchar_t display_descs[0x900 / 2]; + wchar_t publisher_name[0x80 / 2]; + wchar_t title_name[0x80 / 2]; + uint8_t transfer_flags; + uint32_t thumbnail_image_size; + uint32_t title_thumbnail_image_size; + uint8_t thumbnail_image[0x4000]; + uint8_t title_thumbnail_image[0x4000]; }; - class STFSEntry { -public: + public: STFSEntry(); - ~STFSEntry(); STFSEntry* GetChild(const char* name); void Dump(int indent); - std::string name; + std::string name; X_FILE_ATTRIBUTES attributes; - size_t offset; - size_t size; - uint32_t update_timestamp; - uint32_t access_timestamp; + size_t offset; + size_t size; + uint32_t update_timestamp; + uint32_t access_timestamp; - std::vector children; + std::vector> children; typedef struct { size_t offset; @@ -158,27 +150,26 @@ public: std::vector block_list; }; - class STFS { -public: + public: enum Error { - kSuccess = 0, - kErrorOutOfMemory = -1, - kErrorReadError = -10, - kErrorFileMismatch = -30, - kErrorDamagedFile = -31, + kSuccess = 0, + kErrorOutOfMemory = -1, + kErrorReadError = -10, + kErrorFileMismatch = -30, + kErrorDamagedFile = -31, }; STFS(xe_mmap_ref mmap); virtual ~STFS(); const STFSHeader* header() const { return &header_; } - STFSEntry* root_entry(); + STFSEntry* root_entry() const { return root_entry_.get(); } Error Load(); void Dump(); -private: + private: Error ReadHeaderAndVerify(const uint8_t* map_ptr); Error ReadAllEntries(const uint8_t* map_ptr); size_t BlockToOffset(uint32_t block); @@ -188,21 +179,19 @@ private: uint32_t next_block_index; uint32_t info; } BlockHash_t; - BlockHash_t GetBlockHash(const uint8_t* map_ptr, - uint32_t block_index, uint32_t table_offset); + BlockHash_t GetBlockHash(const uint8_t* map_ptr, uint32_t block_index, + uint32_t table_offset); xe_mmap_ref mmap_; STFSPackageType package_type_; - STFSHeader header_; - uint32_t table_size_shift_; - STFSEntry* root_entry_; + STFSHeader header_; + uint32_t table_size_shift_; + std::unique_ptr root_entry_; }; - } // namespace fs } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_FS_STFS_H_ From 24fe169f36277899dc1e8896365cac5df7949815 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 17 Aug 2014 11:48:29 -0700 Subject: [PATCH 130/388] Last bit of string cleanup. string.h finally gone. --- .../compiler/passes/finalization_pass.cc | 2 +- src/alloy/frontend/ppc/ppc_context.cc | 2 +- src/alloy/frontend/ppc/ppc_disasm.cc | 6 +- src/alloy/frontend/ppc/ppc_hir_builder.cc | 4 +- src/alloy/frontend/ppc/ppc_instr.cc | 32 ++++---- src/alloy/hir/hir_builder.cc | 2 +- src/poly/string.cc | 16 ++++ src/poly/string.h | 6 ++ src/xenia/common.h | 2 +- src/xenia/core/mmap.h | 2 +- src/xenia/core/mmap_win.cc | 2 +- src/xenia/cpu/xex_module.cc | 28 +++---- src/xenia/export_resolver.cc | 77 +++++++++---------- src/xenia/export_resolver.h | 53 ++++++------- src/xenia/gpu/d3d11/d3d11_geometry_shader.cc | 6 +- src/xenia/gpu/d3d11/d3d11_shader_resource.cc | 7 +- src/xenia/gpu/d3d11/d3d11_shader_translator.h | 3 +- src/xenia/gpu/xenos/ucode_disassembler.cc | 3 +- .../kernel/fs/devices/disc_image_device.cc | 29 +------ .../fs/devices/stfs_container_device.cc | 29 +------ src/xenia/kernel/objects/xthread.cc | 2 +- src/xenia/kernel/util/xex2.cc | 9 +-- src/xenia/kernel/util/xex2.h | 1 - src/xenia/logging.cc | 9 ++- src/xenia/logging.h | 2 +- src/xenia/profiling.h | 2 +- src/xenia/sources.gypi | 1 - src/xenia/string.h | 47 ----------- 28 files changed, 148 insertions(+), 236 deletions(-) delete mode 100644 src/xenia/string.h diff --git a/src/alloy/compiler/passes/finalization_pass.cc b/src/alloy/compiler/passes/finalization_pass.cc index 5066b53ab..fcd827d1f 100644 --- a/src/alloy/compiler/passes/finalization_pass.cc +++ b/src/alloy/compiler/passes/finalization_pass.cc @@ -45,7 +45,7 @@ int FinalizationPass::Run(HIRBuilder* builder) { if (!label->name) { const size_t label_len = 6 + 4 + 1; char* name = (char*)arena->Alloc(label_len); - xesnprintfa(name, label_len, "_label%d", label->id); + snprintf(name, label_len, "_label%d", label->id); label->name = name; } label = label->next; diff --git a/src/alloy/frontend/ppc/ppc_context.cc b/src/alloy/frontend/ppc/ppc_context.cc index b6b743621..c7a070696 100644 --- a/src/alloy/frontend/ppc/ppc_context.cc +++ b/src/alloy/frontend/ppc/ppc_context.cc @@ -32,7 +32,7 @@ bool PPCContext::CompareRegWithString(const char* name, const char* value, if (sscanf(name, "r%d", &n) == 1) { uint64_t expected = ParseInt64(value); if (this->r[n] != expected) { - xesnprintfa(out_value, out_value_size, "%016llX", this->r[n]); + snprintf(out_value, out_value_size, "%016llX", this->r[n]); return false; } return true; diff --git a/src/alloy/frontend/ppc/ppc_disasm.cc b/src/alloy/frontend/ppc/ppc_disasm.cc index 726e5486e..54746b335 100644 --- a/src/alloy/frontend/ppc/ppc_disasm.cc +++ b/src/alloy/frontend/ppc/ppc_disasm.cc @@ -294,7 +294,7 @@ void Disasm_bcx(InstrData& i, StringBuffer* str) { } char s2[8] = {0}; if (!select_bits(i.B.BO, 4, 4)) { - xesnprintfa(s2, poly::countof(s2), "cr%d, ", i.B.BI >> 2); + snprintf(s2, poly::countof(s2), "cr%d, ", i.B.BI >> 2); } uint32_t nia; if (i.B.AA) { @@ -310,7 +310,7 @@ void Disasm_bcctrx(InstrData& i, StringBuffer* str) { const char* s0 = i.XL.LK ? "lr, " : ""; char s2[8] = {0}; if (!select_bits(i.XL.BO, 4, 4)) { - xesnprintfa(s2, poly::countof(s2), "cr%d, ", i.XL.BI >> 2); + snprintf(s2, poly::countof(s2), "cr%d, ", i.XL.BI >> 2); } str->Append("%-8s %s%sctr", i.type->name, s0, s2); // TODO(benvanik): resolve target name? @@ -328,7 +328,7 @@ void Disasm_bclrx(InstrData& i, StringBuffer* str) { } char s2[8] = {0}; if (!select_bits(i.XL.BO, 4, 4)) { - xesnprintfa(s2, poly::countof(s2), "cr%d, ", i.XL.BI >> 2); + snprintf(s2, poly::countof(s2), "cr%d, ", i.XL.BI >> 2); } str->Append("%-8s %s%s", name, s1, s2); } diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index a426dd257..627c4cac8 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -168,8 +168,8 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) { void PPCHIRBuilder::AnnotateLabel(uint64_t address, Label* label) { char name_buffer[13]; - xesnprintfa(name_buffer, poly::countof(name_buffer), "loc_%.8X", - (uint32_t)address); + snprintf(name_buffer, poly::countof(name_buffer), "loc_%.8X", + (uint32_t)address); label->name = (char*)arena_->Alloc(sizeof(name_buffer)); xe_copy_struct(label->name, name_buffer, sizeof(name_buffer)); } diff --git a/src/alloy/frontend/ppc/ppc_instr.cc b/src/alloy/frontend/ppc/ppc_instr.cc index 0410a1502..c90c46a37 100644 --- a/src/alloy/frontend/ppc/ppc_instr.cc +++ b/src/alloy/frontend/ppc/ppc_instr.cc @@ -30,28 +30,28 @@ void InstrOperand::Dump(std::string& out_str) { case InstrOperand::kRegister: switch (reg.set) { case InstrRegister::kXER: - xesnprintfa(buffer, max_count, "XER"); + snprintf(buffer, max_count, "XER"); break; case InstrRegister::kLR: - xesnprintfa(buffer, max_count, "LR"); + snprintf(buffer, max_count, "LR"); break; case InstrRegister::kCTR: - xesnprintfa(buffer, max_count, "CTR"); + snprintf(buffer, max_count, "CTR"); break; case InstrRegister::kCR: - xesnprintfa(buffer, max_count, "CR%d", reg.ordinal); + snprintf(buffer, max_count, "CR%d", reg.ordinal); break; case InstrRegister::kFPSCR: - xesnprintfa(buffer, max_count, "FPSCR"); + snprintf(buffer, max_count, "FPSCR"); break; case InstrRegister::kGPR: - xesnprintfa(buffer, max_count, "r%d", reg.ordinal); + snprintf(buffer, max_count, "r%d", reg.ordinal); break; case InstrRegister::kFPR: - xesnprintfa(buffer, max_count, "f%d", reg.ordinal); + snprintf(buffer, max_count, "f%d", reg.ordinal); break; case InstrRegister::kVMX: - xesnprintfa(buffer, max_count, "vr%d", reg.ordinal); + snprintf(buffer, max_count, "vr%d", reg.ordinal); break; } break; @@ -59,30 +59,30 @@ void InstrOperand::Dump(std::string& out_str) { switch (imm.width) { case 1: if (imm.is_signed) { - xesnprintfa(buffer, max_count, "%d", (int32_t)(int8_t)imm.value); + snprintf(buffer, max_count, "%d", (int32_t)(int8_t)imm.value); } else { - xesnprintfa(buffer, max_count, "0x%.2X", (uint8_t)imm.value); + snprintf(buffer, max_count, "0x%.2X", (uint8_t)imm.value); } break; case 2: if (imm.is_signed) { - xesnprintfa(buffer, max_count, "%d", (int32_t)(int16_t)imm.value); + snprintf(buffer, max_count, "%d", (int32_t)(int16_t)imm.value); } else { - xesnprintfa(buffer, max_count, "0x%.4X", (uint16_t)imm.value); + snprintf(buffer, max_count, "0x%.4X", (uint16_t)imm.value); } break; case 4: if (imm.is_signed) { - xesnprintfa(buffer, max_count, "%d", (int32_t)imm.value); + snprintf(buffer, max_count, "%d", (int32_t)imm.value); } else { - xesnprintfa(buffer, max_count, "0x%.8X", (uint32_t)imm.value); + snprintf(buffer, max_count, "0x%.8X", (uint32_t)imm.value); } break; case 8: if (imm.is_signed) { - xesnprintfa(buffer, max_count, "%lld", (int64_t)imm.value); + snprintf(buffer, max_count, "%lld", (int64_t)imm.value); } else { - xesnprintfa(buffer, max_count, "0x%.16llX", imm.value); + snprintf(buffer, max_count, "0x%.16llX", imm.value); } break; } diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index ac6eec173..2a0bec6f3 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -625,7 +625,7 @@ void HIRBuilder::Comment(const char* format, ...) { char buffer[1024]; va_list args; va_start(args, format); - xevsnprintfa(buffer, 1024, format, args); + vsnprintf(buffer, 1024, format, args); va_end(args); size_t len = strlen(buffer); if (!len) { diff --git a/src/poly/string.cc b/src/poly/string.cc index 0525b5541..8c877ec0d 100644 --- a/src/poly/string.cc +++ b/src/poly/string.cc @@ -51,6 +51,22 @@ std::wstring to_absolute_path(const std::wstring& path) { #endif // XE_LIKE_WIN32 } +std::vector split_path(const std::string& path) { + std::vector parts; + size_t n = 0; + size_t last = 0; + while ((n = path.find_first_of("\\/", last)) != path.npos) { + if (last != n) { + parts.push_back(path.substr(last, n - last)); + } + last = n + 1; + } + if (last != path.size()) { + parts.push_back(path.substr(last)); + } + return parts; +} + std::wstring join_paths(const std::wstring& left, const std::wstring& right, wchar_t sep) { if (!left.size()) { diff --git a/src/poly/string.h b/src/poly/string.h index 688dd4c1b..0787ba935 100644 --- a/src/poly/string.h +++ b/src/poly/string.h @@ -10,13 +10,16 @@ #ifndef POLY_STRING_H_ #define POLY_STRING_H_ +#include #include +#include #include #if XE_LIKE_WIN32 #define strcasecmp _stricmp #define strncasecmp _strnicmp +#define snprintf _snprintf #endif // XE_LIKE_WIN32 namespace poly { @@ -31,6 +34,9 @@ std::string::size_type find_first_of_case(const std::string& target, // Converts the given path to an absolute path based on cwd. std::wstring to_absolute_path(const std::wstring& path); +// Splits the given path on any valid path separator and returns all parts. +std::vector split_path(const std::string& path); + // Joins two path segments with the given separator. std::wstring join_paths(const std::wstring& left, const std::wstring& right, wchar_t sep = poly::path_separator); diff --git a/src/xenia/common.h b/src/xenia/common.h index 3e027f858..3b911ea0f 100644 --- a/src/xenia/common.h +++ b/src/xenia/common.h @@ -14,11 +14,11 @@ #include #include #include +#include #include #include #include -#include #include #endif // XENIA_COMMON_H_ diff --git a/src/xenia/core/mmap.h b/src/xenia/core/mmap.h index 29178c963..eaa217c46 100644 --- a/src/xenia/core/mmap.h +++ b/src/xenia/core/mmap.h @@ -22,7 +22,7 @@ typedef enum { kXEFileModeWrite = (1 << 1), } xe_file_mode; -xe_mmap_ref xe_mmap_open(const xe_file_mode mode, const xechar_t *path, +xe_mmap_ref xe_mmap_open(const xe_file_mode mode, const wchar_t *path, const size_t offset, const size_t length); xe_mmap_ref xe_mmap_retain(xe_mmap_ref mmap); void xe_mmap_release(xe_mmap_ref mmap); diff --git a/src/xenia/core/mmap_win.cc b/src/xenia/core/mmap_win.cc index 38b9ca025..4121fd2af 100644 --- a/src/xenia/core/mmap_win.cc +++ b/src/xenia/core/mmap_win.cc @@ -21,7 +21,7 @@ typedef struct xe_mmap { } xe_mmap_t; -xe_mmap_ref xe_mmap_open(const xe_file_mode mode, const xechar_t *path, +xe_mmap_ref xe_mmap_open(const xe_file_mode mode, const wchar_t *path, const size_t offset, const size_t length) { xe_mmap_ref mmap = (xe_mmap_ref)xe_calloc(sizeof(xe_mmap_t)); xe_ref_init((xe_ref)mmap); diff --git a/src/xenia/cpu/xex_module.cc b/src/xenia/cpu/xex_module.cc index 05bc443ef..9532ef16f 100644 --- a/src/xenia/cpu/xex_module.cc +++ b/src/xenia/cpu/xex_module.cc @@ -114,12 +114,12 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) { if (kernel_export) { if (info->thunk_address) { - xesnprintfa(name, poly::countof(name), "__imp_%s", kernel_export->name); + snprintf(name, poly::countof(name), "__imp_%s", kernel_export->name); } else { - xesnprintfa(name, poly::countof(name), "%s", kernel_export->name); + snprintf(name, poly::countof(name), "%s", kernel_export->name); } } else { - xesnprintfa(name, poly::countof(name), "__imp_%s_%.3X", library->name, + snprintf(name, poly::countof(name), "__imp_%s_%.3X", library->name, info->ordinal); } @@ -159,10 +159,10 @@ int XexModule::SetupLibraryImports(const xe_xex2_import_library_t* library) { if (info->thunk_address) { if (kernel_export) { - xesnprintfa(name, poly::countof(name), "%s", kernel_export->name); + snprintf(name, poly::countof(name), "%s", kernel_export->name); } else { - xesnprintfa(name, poly::countof(name), "__kernel_%s_%.3X", - library->name, info->ordinal); + snprintf(name, poly::countof(name), "__kernel_%s_%.3X", library->name, + info->ordinal); } // On load we have something like this in memory: @@ -423,7 +423,7 @@ int XexModule::FindSaveRest() { if (gplr_start) { uint64_t address = gplr_start; for (int n = 14; n <= 31; n++) { - xesnprintfa(name, poly::countof(name), "__savegprlr_%d", n); + snprintf(name, poly::countof(name), "__savegprlr_%d", n); FunctionInfo* symbol_info; DeclareFunction(address, &symbol_info); symbol_info->set_end_address(address + (31 - n) * 4 + 2 * 4); @@ -436,7 +436,7 @@ int XexModule::FindSaveRest() { } address = gplr_start + 20 * 4; for (int n = 14; n <= 31; n++) { - xesnprintfa(name, poly::countof(name), "__restgprlr_%d", n); + snprintf(name, poly::countof(name), "__restgprlr_%d", n); FunctionInfo* symbol_info; DeclareFunction(address, &symbol_info); symbol_info->set_end_address(address + (31 - n) * 4 + 3 * 4); @@ -451,7 +451,7 @@ int XexModule::FindSaveRest() { if (fpr_start) { uint64_t address = fpr_start; for (int n = 14; n <= 31; n++) { - xesnprintfa(name, poly::countof(name), "__savefpr_%d", n); + snprintf(name, poly::countof(name), "__savefpr_%d", n); FunctionInfo* symbol_info; DeclareFunction(address, &symbol_info); symbol_info->set_end_address(address + (31 - n) * 4 + 1 * 4); @@ -464,7 +464,7 @@ int XexModule::FindSaveRest() { } address = fpr_start + (18 * 4) + (1 * 4); for (int n = 14; n <= 31; n++) { - xesnprintfa(name, poly::countof(name), "__restfpr_%d", n); + snprintf(name, poly::countof(name), "__restfpr_%d", n); FunctionInfo* symbol_info; DeclareFunction(address, &symbol_info); symbol_info->set_end_address(address + (31 - n) * 4 + 1 * 4); @@ -484,7 +484,7 @@ int XexModule::FindSaveRest() { // 64-127 rest uint64_t address = vmx_start; for (int n = 14; n <= 31; n++) { - xesnprintfa(name, poly::countof(name), "__savevmx_%d", n); + snprintf(name, poly::countof(name), "__savevmx_%d", n); FunctionInfo* symbol_info; DeclareFunction(address, &symbol_info); symbol_info->set_name(name); @@ -496,7 +496,7 @@ int XexModule::FindSaveRest() { } address += 4; for (int n = 64; n <= 127; n++) { - xesnprintfa(name, poly::countof(name), "__savevmx_%d", n); + snprintf(name, poly::countof(name), "__savevmx_%d", n); FunctionInfo* symbol_info; DeclareFunction(address, &symbol_info); symbol_info->set_name(name); @@ -508,7 +508,7 @@ int XexModule::FindSaveRest() { } address = vmx_start + (18 * 2 * 4) + (1 * 4) + (64 * 2 * 4) + (1 * 4); for (int n = 14; n <= 31; n++) { - xesnprintfa(name, poly::countof(name), "__restvmx_%d", n); + snprintf(name, poly::countof(name), "__restvmx_%d", n); FunctionInfo* symbol_info; DeclareFunction(address, &symbol_info); symbol_info->set_name(name); @@ -520,7 +520,7 @@ int XexModule::FindSaveRest() { } address += 4; for (int n = 64; n <= 127; n++) { - xesnprintfa(name, poly::countof(name), "__restvmx_%d", n); + snprintf(name, poly::countof(name), "__restvmx_%d", n); FunctionInfo* symbol_info; DeclareFunction(address, &symbol_info); symbol_info->set_name(name); diff --git a/src/xenia/export_resolver.cc b/src/xenia/export_resolver.cc index 7f56d89a1..3cfa87710 100644 --- a/src/xenia/export_resolver.cc +++ b/src/xenia/export_resolver.cc @@ -11,92 +11,87 @@ #include -using namespace xe; +namespace xe { +ExportResolver::ExportResolver() {} -ExportResolver::ExportResolver() { -} +ExportResolver::~ExportResolver() {} -ExportResolver::~ExportResolver() { -} - -void ExportResolver::RegisterTable( - const char* library_name, KernelExport* exports, const size_t count) { - ExportTable table; - xestrcpya(table.name, poly::countof(table.name), library_name); - table.exports = exports; - table.count = count; - tables_.push_back(table); +void ExportResolver::RegisterTable(const std::string& library_name, + KernelExport* exports, const size_t count) { + tables_.emplace_back(library_name, exports, count); for (size_t n = 0; n < count; n++) { exports[n].is_implemented = false; exports[n].variable_ptr = 0; - exports[n].function_data.shim_data = NULL; - exports[n].function_data.shim = NULL; + exports[n].function_data.shim_data = nullptr; + exports[n].function_data.shim = nullptr; } } -uint16_t ExportResolver::GetLibraryOrdinal(const char* library_name) { +uint16_t ExportResolver::GetLibraryOrdinal(const std::string& library_name) { uint16_t n = 0; - for (auto it = tables_.begin(); it != tables_.end(); ++it, n++) { - if (!strcmp(library_name, it->name)) { + for (const auto& table : tables_) { + if (table.name != library_name) { return n; } + ++n; } return -1; } -KernelExport* ExportResolver::GetExportByOrdinal( - const uint16_t library_ordinal, const uint32_t ordinal) { - auto& table = tables_[library_ordinal]; +KernelExport* ExportResolver::GetExportByOrdinal(const uint16_t library_ordinal, + const uint32_t ordinal) { + const auto& table = tables_[library_ordinal]; // TODO(benvanik): binary search? for (size_t n = 0; n < table.count; n++) { if (table.exports[n].ordinal == ordinal) { return &table.exports[n]; } } - return NULL; + return nullptr; } -KernelExport* ExportResolver::GetExportByOrdinal(const char* library_name, - const uint32_t ordinal) { - for (std::vector::iterator it = tables_.begin(); - it != tables_.end(); ++it) { - if (!strcmp(library_name, it->name)) { +KernelExport* ExportResolver::GetExportByOrdinal( + const std::string& library_name, const uint32_t ordinal) { + for (const auto& table : tables_) { + if (table.name == library_name) { // TODO(benvanik): binary search? - for (size_t n = 0; n < it->count; n++) { - if (it->exports[n].ordinal == ordinal) { - return &it->exports[n]; + for (size_t n = 0; n < table.count; n++) { + if (table.exports[n].ordinal == ordinal) { + return &table.exports[n]; } } - return NULL; + return nullptr; } } - return NULL; + return nullptr; } -KernelExport* ExportResolver::GetExportByName(const char* library_name, - const char* name) { +KernelExport* ExportResolver::GetExportByName(const std::string& library_name, + const std::string& name) { // TODO(benvanik): lookup by name. assert_always(); - return NULL; + return nullptr; } -void ExportResolver::SetVariableMapping(const char* library_name, +void ExportResolver::SetVariableMapping(const std::string& library_name, const uint32_t ordinal, uint32_t value) { - KernelExport* kernel_export = GetExportByOrdinal(library_name, ordinal); + auto kernel_export = GetExportByOrdinal(library_name, ordinal); assert_not_null(kernel_export); kernel_export->is_implemented = true; kernel_export->variable_ptr = value; } -void ExportResolver::SetFunctionMapping( - const char* library_name, const uint32_t ordinal, - void* shim_data, xe_kernel_export_shim_fn shim) { - KernelExport* kernel_export = GetExportByOrdinal(library_name, ordinal); +void ExportResolver::SetFunctionMapping(const std::string& library_name, + const uint32_t ordinal, void* shim_data, + xe_kernel_export_shim_fn shim) { + auto kernel_export = GetExportByOrdinal(library_name, ordinal); assert_not_null(kernel_export); kernel_export->is_implemented = true; kernel_export->function_data.shim_data = shim_data; kernel_export->function_data.shim = shim; } + +} // namespace xe diff --git a/src/xenia/export_resolver.h b/src/xenia/export_resolver.h index 50d328209..057c80f37 100644 --- a/src/xenia/export_resolver.h +++ b/src/xenia/export_resolver.h @@ -12,36 +12,34 @@ #include +#include #include - typedef struct xe_ppc_state xe_ppc_state_t; - namespace xe { - typedef void (*xe_kernel_export_shim_fn)(xe_ppc_state_t*, void*); class KernelExport { -public: + public: enum ExportType { Function = 0, Variable = 1, }; - uint32_t ordinal; - ExportType type; - uint32_t flags; - char name[96]; + uint32_t ordinal; + ExportType type; + uint32_t flags; + char name[96]; - bool is_implemented; + bool is_implemented; union { // Variable data. Only valid when kXEKernelExportFlagVariable is set. // This is an address in the client memory space that the variable can // be found at. - uint32_t variable_ptr; + uint32_t variable_ptr; struct { // Second argument passed to the shim function. @@ -55,41 +53,40 @@ public: }; }; - class ExportResolver { -public: + public: ExportResolver(); ~ExportResolver(); - void RegisterTable(const char* library_name, KernelExport* exports, + void RegisterTable(const std::string& library_name, KernelExport* exports, const size_t count); - uint16_t GetLibraryOrdinal(const char* library_name); + uint16_t GetLibraryOrdinal(const std::string& library_name); KernelExport* GetExportByOrdinal(const uint16_t library_ordinal, const uint32_t ordinal); - KernelExport* GetExportByOrdinal(const char* library_name, + KernelExport* GetExportByOrdinal(const std::string& library_name, const uint32_t ordinal); - KernelExport* GetExportByName(const char* library_name, const char* name); + KernelExport* GetExportByName(const std::string& library_name, + const std::string& name); - void SetVariableMapping(const char* library_name, const uint32_t ordinal, - uint32_t value); - void SetFunctionMapping(const char* library_name, const uint32_t ordinal, - void* shim_data, xe_kernel_export_shim_fn shim); + void SetVariableMapping(const std::string& library_name, + const uint32_t ordinal, uint32_t value); + void SetFunctionMapping(const std::string& library_name, + const uint32_t ordinal, void* shim_data, + xe_kernel_export_shim_fn shim); -private: - class ExportTable { - public: - char name[32]; + private: + struct ExportTable { + std::string name; KernelExport* exports; - size_t count; + size_t count; + ExportTable(const std::string& name, KernelExport* exports, size_t count) + : name(name), exports(exports), count(count) {} }; - std::vector tables_; }; - } // namespace xe - #endif // XENIA_EXPORT_RESOLVER_H_ diff --git a/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc b/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc index 511d8dd93..64214e31a 100644 --- a/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc +++ b/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc @@ -99,10 +99,8 @@ ID3D10Blob* D3D11GeometryShader::Compile(const char* shader_source) { } uint64_t hash = hash64(shader_source, strlen(shader_source)); // ? char file_name[poly::max_path]; - xesnprintfa(file_name, poly::countof(file_name), - "%s/gen_%.16llX.gs", - base_path, - hash); + snprintf(file_name, poly::countof(file_name), "%s/gen_%.16llX.gs", base_path, + hash); if (FLAGS_dump_shaders.size()) { FILE* f = fopen(file_name, "w"); diff --git a/src/xenia/gpu/d3d11/d3d11_shader_resource.cc b/src/xenia/gpu/d3d11/d3d11_shader_resource.cc index e8bb26956..8e749ce47 100644 --- a/src/xenia/gpu/d3d11/d3d11_shader_resource.cc +++ b/src/xenia/gpu/d3d11/d3d11_shader_resource.cc @@ -50,11 +50,8 @@ ID3D10Blob* D3D11ShaderCompile(XE_GPU_SHADER_TYPE type, } size_t hash = hash64(disasm_source, strlen(disasm_source)); // ? char file_name[poly::max_path]; - xesnprintfa(file_name, poly::countof(file_name), - "%s/gen_%.16llX.%s", - base_path, - hash, - type == XE_GPU_SHADER_TYPE_VERTEX ? "vs" : "ps"); + snprintf(file_name, poly::countof(file_name), "%s/gen_%.16llX.%s", base_path, + hash, type == XE_GPU_SHADER_TYPE_VERTEX ? "vs" : "ps"); if (FLAGS_dump_shaders.size()) { FILE* f = fopen(file_name, "w"); diff --git a/src/xenia/gpu/d3d11/d3d11_shader_translator.h b/src/xenia/gpu/d3d11/d3d11_shader_translator.h index ad85c7775..1f8823cc1 100644 --- a/src/xenia/gpu/d3d11/d3d11_shader_translator.h +++ b/src/xenia/gpu/d3d11/d3d11_shader_translator.h @@ -48,8 +48,7 @@ private: void append(const char* format, ...) { va_list args; va_start(args, format); - int len = xevsnprintfa(buffer_ + offset_, capacity_ - offset_, - format, args); + int len = vsnprintf(buffer_ + offset_, capacity_ - offset_, format, args); va_end(args); offset_ += len; buffer_[offset_] = 0; diff --git a/src/xenia/gpu/xenos/ucode_disassembler.cc b/src/xenia/gpu/xenos/ucode_disassembler.cc index 0e0ac9875..92f7ad480 100644 --- a/src/xenia/gpu/xenos/ucode_disassembler.cc +++ b/src/xenia/gpu/xenos/ucode_disassembler.cc @@ -58,8 +58,7 @@ struct Output { void append(const char* format, ...) { va_list args; va_start(args, format); - int len = xevsnprintfa( - buffer + offset, capacity - offset, format, args); + int len = vsnprintf(buffer + offset, capacity - offset, format, args); va_end(args); offset += len; buffer[offset] = 0; diff --git a/src/xenia/kernel/fs/devices/disc_image_device.cc b/src/xenia/kernel/fs/devices/disc_image_device.cc index 0e282af49..9b5a381bc 100644 --- a/src/xenia/kernel/fs/devices/disc_image_device.cc +++ b/src/xenia/kernel/fs/devices/disc_image_device.cc @@ -56,34 +56,13 @@ Entry* DiscImageDevice::ResolvePath(const char* path) { GDFXEntry* gdfx_entry = gdfx_->root_entry(); // Walk the path, one separator at a time. - // We copy it into the buffer and shift it left over and over. - char remaining[poly::max_path]; - xestrcpya(remaining, poly::countof(remaining), path); - while (remaining[0]) { - char* next_slash = strchr(remaining, '\\'); - if (next_slash == remaining) { - // Leading slash - shift - xestrcpya(remaining, poly::countof(remaining), remaining + 1); - continue; - } - - // Make the buffer just the name. - if (next_slash) { - *next_slash = 0; - } - - // Look up in the entry. - gdfx_entry = gdfx_entry->GetChild(remaining); + auto path_parts = poly::split_path(path); + for (auto& part : path_parts) { + gdfx_entry = gdfx_entry->GetChild(part.c_str()); if (!gdfx_entry) { // Not found. - return NULL; + return nullptr; } - - // Shift the buffer down, unless we are at the end. - if (!next_slash) { - break; - } - xestrcpya(remaining, poly::countof(remaining), next_slash + 1); } Entry::Type type = gdfx_entry->attributes & X_FILE_ATTRIBUTE_DIRECTORY ? diff --git a/src/xenia/kernel/fs/devices/stfs_container_device.cc b/src/xenia/kernel/fs/devices/stfs_container_device.cc index 219d8bdee..7d58f1171 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_device.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_device.cc @@ -56,34 +56,13 @@ Entry* STFSContainerDevice::ResolvePath(const char* path) { STFSEntry* stfs_entry = stfs_->root_entry(); // Walk the path, one separator at a time. - // We copy it into the buffer and shift it left over and over. - char remaining[poly::max_path]; - xestrcpya(remaining, poly::countof(remaining), path); - while (remaining[0]) { - char* next_slash = strchr(remaining, '\\'); - if (next_slash == remaining) { - // Leading slash - shift - xestrcpya(remaining, poly::countof(remaining), remaining + 1); - continue; - } - - // Make the buffer just the name. - if (next_slash) { - *next_slash = 0; - } - - // Look up in the entry. - stfs_entry = stfs_entry->GetChild(remaining); + auto path_parts = poly::split_path(path); + for (auto& part : path_parts) { + stfs_entry = stfs_entry->GetChild(part.c_str()); if (!stfs_entry) { // Not found. - return NULL; + return nullptr; } - - // Shift the buffer down, unless we are at the end. - if (!next_slash) { - break; - } - xestrcpya(remaining, poly::countof(remaining), next_slash + 1); } Entry::Type type = stfs_entry->attributes & X_FILE_ATTRIBUTE_DIRECTORY ? diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index 646178c8a..65e5cb712 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -219,7 +219,7 @@ X_STATUS XThread::Create() { } char thread_name[32]; - xesnprintfa(thread_name, poly::countof(thread_name), "XThread%04X", handle()); + snprintf(thread_name, poly::countof(thread_name), "XThread%04X", handle()); set_name(thread_name); uint32_t proc_mask = creation_params_.creation_flags >> 24; diff --git a/src/xenia/kernel/util/xex2.cc b/src/xenia/kernel/util/xex2.cc index 23308e96b..fc2e0b15b 100644 --- a/src/xenia/kernel/util/xex2.cc +++ b/src/xenia/kernel/util/xex2.cc @@ -111,11 +111,6 @@ void xe_xex2_release(xe_xex2_ref xex) { xe_ref_release((xe_ref)xex, (xe_ref_dealloc_t)xe_xex2_dealloc); } -const xechar_t* xe_xex2_get_name(xe_xex2_ref xex) { - // TODO(benvanik): get name. - return NULL; -} - const xe_xex2_header_t* xe_xex2_get_header(xe_xex2_ref xex) { return &xex->header; } @@ -264,8 +259,8 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, for (size_t i = 0, j = 0; i < string_table_size;) { assert_true(j <= 0xFF); if (j == name_index) { - xestrcpya(library->name, poly::countof(library->name), - string_table + i); + std::strncpy(library->name, string_table + i, + poly::countof(library->name)); break; } if (string_table[i] == 0) { diff --git a/src/xenia/kernel/util/xex2.h b/src/xenia/kernel/util/xex2.h index 4e865bd5d..f55b71caa 100644 --- a/src/xenia/kernel/util/xex2.h +++ b/src/xenia/kernel/util/xex2.h @@ -51,7 +51,6 @@ xe_xex2_ref xe_xex2_load(xe::Memory* memory, xe_xex2_ref xe_xex2_retain(xe_xex2_ref xex); void xe_xex2_release(xe_xex2_ref xex); -const xechar_t *xe_xex2_get_name(xe_xex2_ref xex); const xe_xex2_header_t *xe_xex2_get_header(xe_xex2_ref xex); const PESection* xe_xex2_get_pe_section(xe_xex2_ref xex, const char* name); diff --git a/src/xenia/logging.cc b/src/xenia/logging.cc index f585bddf1..dbabd593a 100644 --- a/src/xenia/logging.cc +++ b/src/xenia/logging.cc @@ -42,12 +42,13 @@ void xe_format_log_line( // Format string - add a trailing newline if required. const char* outfmt = "XE[%c] %s:%d: "; - char* buffer_ptr = buffer + xesnprintfa( - buffer, buffer_count - 1, outfmt, level_char, filename, line_number); + char* buffer_ptr = buffer + snprintf(buffer, buffer_count - 1, outfmt, + level_char, filename, line_number); // Scribble args into the print buffer. - buffer_ptr = buffer_ptr + xevsnprintfa( - buffer_ptr, buffer_count - (buffer_ptr - buffer) - 1, fmt, args); + buffer_ptr = buffer_ptr + vsnprintf(buffer_ptr, + buffer_count - (buffer_ptr - buffer) - 1, + fmt, args); // Add a trailing newline. if (buffer_ptr[-1] != '\n') { diff --git a/src/xenia/logging.h b/src/xenia/logging.h index 8e2f29fd5..2f55b5b3f 100644 --- a/src/xenia/logging.h +++ b/src/xenia/logging.h @@ -12,7 +12,7 @@ #include -#include +#include #define XE_OPTION_ENABLE_LOGGING 1 #define XE_OPTION_LOG_ERROR 1 diff --git a/src/xenia/profiling.h b/src/xenia/profiling.h index 88c63c994..d3102e980 100644 --- a/src/xenia/profiling.h +++ b/src/xenia/profiling.h @@ -12,7 +12,7 @@ #include -#include +#include #include #define XE_OPTION_PROFILING 1 diff --git a/src/xenia/sources.gypi b/src/xenia/sources.gypi index 0afc479e1..cec755d15 100644 --- a/src/xenia/sources.gypi +++ b/src/xenia/sources.gypi @@ -15,7 +15,6 @@ 'malloc.h', 'profiling.cc', 'profiling.h', - 'string.h', 'types.h', 'xbox.h', ], diff --git a/src/xenia/string.h b/src/xenia/string.h deleted file mode 100644 index 2a166ad78..000000000 --- a/src/xenia/string.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_STRING_H_ -#define XENIA_STRING_H_ - -#include - -// NOTE: these differing implementations should behave pretty much the same. -// If they don't, then they will have to be abstracted out. - -#if !XE_LIKE_WIN32 -int strncpy_s(char* dest, size_t destLength, const char* source, size_t count); -#define strcpy_s(dest, destLength, source) !(strcpy(dest, source) == dest + (destLength*0)) -#define _snprintf_s(dest, destLength, x, format, ...) snprintf(dest, destLength, format, ##__VA_ARGS__) -#endif // !WIN32 - -#define xesnprintfw(buffer, bufferCount, format, ...) _snwprintf_s(buffer, bufferCount, (bufferCount) ? (bufferCount - 1) : 0, format, ##__VA_ARGS__) - -#define xestrcpya(dest, destLength, source) (strcpy_s(dest, destLength, source) == 0) -#define xesnprintfa(buffer, bufferCount, format, ...) _snprintf_s(buffer, bufferCount, bufferCount, format, ##__VA_ARGS__) -#define xevsnprintfa(buffer, bufferCount, format, args) vsnprintf(buffer, bufferCount, format, args) - -#if XE_PLATFORM_WIN32 && defined(UNICODE) && UNICODE - -typedef wchar_t xechar_t; - -// xestrcpy fs + module -// xesnprintf many uses - only remove some? - -#define xesnprintf xesnprintfw - -#else - -typedef char xechar_t; - -#define xesnprintf xesnprintfa - -#endif // WIN32 - -#endif // XENIA_STRING_H_ From 854bcdb60a900558b8929b7f5476db6f965568fb Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 17 Aug 2014 12:57:02 -0700 Subject: [PATCH 131/388] Moving mmap to poly, cleaning up devices. --- src/poly/mapped_memory.h | 46 ++++++ src/poly/mapped_memory_posix.cc | 77 ++++++++++ src/poly/mapped_memory_win.cc | 105 ++++++++++++++ src/poly/poly.h | 1 + src/poly/sources.gypi | 3 + src/xenia/core.h | 1 - src/xenia/core/mmap.h | 33 ----- src/xenia/core/mmap_posix.cc | 100 ------------- src/xenia/core/mmap_win.cc | 133 ------------------ src/xenia/core/sources.gypi | 3 - .../kernel/fs/devices/disc_image_device.cc | 35 ++--- .../kernel/fs/devices/disc_image_device.h | 5 +- .../kernel/fs/devices/disc_image_entry.cc | 112 +++++++-------- .../kernel/fs/devices/disc_image_entry.h | 32 ++--- .../kernel/fs/devices/disc_image_file.cc | 49 +++---- src/xenia/kernel/fs/devices/disc_image_file.h | 3 +- .../kernel/fs/devices/host_path_device.cc | 21 +-- .../kernel/fs/devices/host_path_device.h | 1 - .../kernel/fs/devices/host_path_entry.cc | 119 +++++++--------- src/xenia/kernel/fs/devices/host_path_entry.h | 8 +- src/xenia/kernel/fs/devices/host_path_file.cc | 53 ++++--- src/xenia/kernel/fs/devices/host_path_file.h | 5 +- .../fs/devices/stfs_container_device.cc | 37 ++--- .../kernel/fs/devices/stfs_container_device.h | 5 +- .../kernel/fs/devices/stfs_container_entry.cc | 74 +++++----- .../kernel/fs/devices/stfs_container_entry.h | 28 ++-- .../kernel/fs/devices/stfs_container_file.cc | 47 +++---- .../kernel/fs/devices/stfs_container_file.h | 2 +- src/xenia/kernel/fs/entry.h | 19 ++- src/xenia/kernel/fs/gdfx.cc | 12 +- src/xenia/kernel/fs/gdfx.h | 5 +- src/xenia/kernel/fs/stfs.cc | 11 +- src/xenia/kernel/fs/stfs.h | 5 +- src/xenia/kernel/objects/xfile.cc | 4 +- src/xenia/kernel/objects/xfile.h | 4 +- src/xenia/kernel/objects/xuser_module.cc | 7 +- src/xenia/kernel/xboxkrnl_io.cc | 16 ++- 37 files changed, 568 insertions(+), 653 deletions(-) create mode 100644 src/poly/mapped_memory.h create mode 100644 src/poly/mapped_memory_posix.cc create mode 100644 src/poly/mapped_memory_win.cc delete mode 100644 src/xenia/core/mmap.h delete mode 100644 src/xenia/core/mmap_posix.cc delete mode 100644 src/xenia/core/mmap_win.cc diff --git a/src/poly/mapped_memory.h b/src/poly/mapped_memory.h new file mode 100644 index 000000000..0d1ffffd2 --- /dev/null +++ b/src/poly/mapped_memory.h @@ -0,0 +1,46 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef POLY_MAPPED_MEMORY_H_ +#define POLY_MAPPED_MEMORY_H_ + +#include +#include + +namespace poly { + +class MappedMemory { + public: + enum class Mode { + READ, + READ_WRITE, + }; + + virtual ~MappedMemory() = default; + + static std::unique_ptr Open(const std::wstring& path, Mode mode, + size_t offset = 0, + size_t length = 0); + + uint8_t* data() const { return reinterpret_cast(data_); } + size_t size() const { return size_; } + + protected: + MappedMemory(const std::wstring& path, Mode mode) + : path_(path), mode_(mode), data_(nullptr), size_(0) {} + + std::wstring path_; + Mode mode_; + void* data_; + size_t size_; +}; + +} // namespace poly + +#endif // POLY_MAPPED_MEMORY_H_ diff --git a/src/poly/mapped_memory_posix.cc b/src/poly/mapped_memory_posix.cc new file mode 100644 index 000000000..825361983 --- /dev/null +++ b/src/poly/mapped_memory_posix.cc @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include +#include + +#include + +namespace poly { + +class PosixMappedMemory : public MappedMemory { + public: + PosixMappedMemory(const std::wstring& path, Mode mode) + : MappedMemory(path, mode), file_handle(nullptr) {} + + ~PosixMappedMemory() override { + if (data_) { + munmap(data_, size_); + } + if (file_handle) { + fclose(file_handle); + } + } + + FILE* file_handle; +}; + +std::unique_ptr MappedMemory::Open(const std::wstring& path, + Mode mode, size_t offset, + size_t length) { + const char* mode; + int prot; + switch (mode) { + case Mode::READ: + mode = "rb"; + prot = PROT_READ; + break; + case Mode::READ_WRITE: + mode = "r+b"; + prot = PROT_READ | PROT_WRITE; + break; + } + + auto mm = std::make_unique(path, mode); + + mm->file_handle = fopen(poly::to_string(path).c_str(), mode); + if (!mm->file_handle) { + return nullptr; + } + + size_t map_length; + map_length = length; + if (!length) { + fseeko(mm->file_handle, 0, SEEK_END); + map_length = ftello(mm->file_handle); + fseeko(mm->file_handle, 0, SEEK_SET); + } + mm->size_ = map_length; + + mm->data_ = + mmap(0, map_length, prot, MAP_SHARED, fileno(mm->file_handle), offset); + if (!mm->data_) { + return nullptr; + } + + return std::move(mm); +} + +} // namespace poly diff --git a/src/poly/mapped_memory_win.cc b/src/poly/mapped_memory_win.cc new file mode 100644 index 000000000..8e5b523d6 --- /dev/null +++ b/src/poly/mapped_memory_win.cc @@ -0,0 +1,105 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include + +namespace poly { + +class Win32MappedMemory : public MappedMemory { + public: + Win32MappedMemory(const std::wstring& path, Mode mode) + : MappedMemory(path, mode), + file_handle(nullptr), + mapping_handle(nullptr) {} + + ~Win32MappedMemory() override { + if (data_) { + UnmapViewOfFile(data_); + } + if (mapping_handle) { + CloseHandle(mapping_handle); + } + if (file_handle) { + CloseHandle(file_handle); + } + } + + HANDLE file_handle; + HANDLE mapping_handle; +}; + +std::unique_ptr MappedMemory::Open(const std::wstring& path, + Mode mode, size_t offset, + size_t length) { + DWORD file_access = 0; + DWORD file_share = 0; + DWORD create_mode = 0; + DWORD mapping_protect = 0; + DWORD view_access = 0; + switch (mode) { + case Mode::READ: + file_access |= GENERIC_READ; + file_share |= FILE_SHARE_READ; + create_mode |= OPEN_EXISTING; + mapping_protect |= PAGE_READONLY; + view_access |= FILE_MAP_READ; + break; + case Mode::READ_WRITE: + file_access |= GENERIC_READ | GENERIC_WRITE; + file_share |= 0; + create_mode |= OPEN_EXISTING; + mapping_protect |= PAGE_READWRITE; + view_access |= FILE_MAP_READ | FILE_MAP_WRITE; + break; + } + + SYSTEM_INFO systemInfo; + GetSystemInfo(&systemInfo); + + const size_t aligned_offset = + offset & (~(systemInfo.dwAllocationGranularity - 1)); + const size_t aligned_length = length + (offset - aligned_offset); + + auto mm = std::make_unique(path, mode); + + mm->file_handle = CreateFile(path.c_str(), file_access, file_share, nullptr, + create_mode, FILE_ATTRIBUTE_NORMAL, nullptr); + if (!mm->file_handle) { + return nullptr; + } + + mm->mapping_handle = CreateFileMapping(mm->file_handle, nullptr, + mapping_protect, 0, 0, nullptr); + //(DWORD)(aligned_length >> 32), (DWORD)(aligned_length & 0xFFFFFFFF), NULL); + if (!mm->mapping_handle) { + return nullptr; + } + + mm->data_ = reinterpret_cast(MapViewOfFile( + mm->mapping_handle, view_access, static_cast(aligned_offset >> 32), + static_cast(aligned_offset & 0xFFFFFFFF), aligned_length)); + if (!mm->data_) { + return nullptr; + } + + if (length) { + mm->size_ = aligned_length; + } else { + DWORD length_high; + size_t map_length = GetFileSize(mm->file_handle, &length_high); + map_length |= static_cast(length_high) << 32; + mm->size_ = map_length - aligned_offset; + } + + return std::move(mm); +} + +} // namespace poly diff --git a/src/poly/poly.h b/src/poly/poly.h index 4fc966b73..95cc10ec1 100644 --- a/src/poly/poly.h +++ b/src/poly/poly.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/src/poly/sources.gypi b/src/poly/sources.gypi index b5faa8083..b052dd85a 100644 --- a/src/poly/sources.gypi +++ b/src/poly/sources.gypi @@ -8,6 +8,7 @@ 'config.h', 'cxx_compat.h', 'main.h', + 'mapped_memory.h', 'math.cc', 'math.h', 'memory.cc', @@ -23,6 +24,7 @@ ['OS == "mac" or OS == "linux"', { 'sources': [ 'main_posix.cc', + 'mapped_memory_posix.cc', ], }], ['OS == "linux"', { @@ -40,6 +42,7 @@ 'sources': [ 'debugging_win.cc', 'main_win.cc', + 'mapped_memory_win.cc', 'threading_win.cc', ], }], diff --git a/src/xenia/core.h b/src/xenia/core.h index c89428f74..8193aecff 100644 --- a/src/xenia/core.h +++ b/src/xenia/core.h @@ -17,7 +17,6 @@ namespace xe { using Memory = alloy::Memory; } // namespace xe -#include #include #include #include diff --git a/src/xenia/core/mmap.h b/src/xenia/core/mmap.h deleted file mode 100644 index eaa217c46..000000000 --- a/src/xenia/core/mmap.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_CORE_MMAP_H_ -#define XENIA_CORE_MMAP_H_ - -#include -#include - - -struct xe_mmap; -typedef struct xe_mmap* xe_mmap_ref; - -typedef enum { - kXEFileModeRead = (1 << 0), - kXEFileModeWrite = (1 << 1), -} xe_file_mode; - -xe_mmap_ref xe_mmap_open(const xe_file_mode mode, const wchar_t *path, - const size_t offset, const size_t length); -xe_mmap_ref xe_mmap_retain(xe_mmap_ref mmap); -void xe_mmap_release(xe_mmap_ref mmap); -uint8_t* xe_mmap_get_addr(xe_mmap_ref mmap); -size_t xe_mmap_get_length(xe_mmap_ref mmap); - - -#endif // XENIA_CORE_MMAP_H_ diff --git a/src/xenia/core/mmap_posix.cc b/src/xenia/core/mmap_posix.cc deleted file mode 100644 index 3dc904c63..000000000 --- a/src/xenia/core/mmap_posix.cc +++ /dev/null @@ -1,100 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include - - -typedef struct xe_mmap { - xe_ref_t ref; - - void* file_handle; - void* mmap_handle; - - void* addr; - size_t length; -} xe_mmap_t; - - -xe_mmap_ref xe_mmap_open(const xe_file_mode mode, const xechar_t *path, - const size_t offset, const size_t length) { - xe_mmap_ref mmap = (xe_mmap_ref)xe_calloc(sizeof(xe_mmap_t)); - xe_ref_init((xe_ref)mmap); - - xechar_t mode_string[10]; - mode_string[0] = 0; - if (mode & kXEFileModeRead) { - XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), XT("r"))); - } - if (mode & kXEFileModeWrite) { - XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), XT("w"))); - } - XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), XT("b"))); - - int prot = 0; - if (mode & kXEFileModeRead) { - prot |= PROT_READ; - } - if (mode & kXEFileModeWrite) { - prot |= PROT_WRITE; - } - - FILE* file_handle = fopen(path, mode_string); - mmap->file_handle = file_handle; - XEEXPECTNOTNULL(mmap->file_handle); - - size_t map_length; - map_length = length; - if (!length) { - fseeko(file_handle, 0, SEEK_END); - map_length = ftello(file_handle); - } - mmap->length = map_length; - - mmap->addr = ::mmap(0, map_length, prot, MAP_SHARED, fileno(file_handle), - offset); - XEEXPECTNOTNULL(mmap->addr); - - return mmap; - -XECLEANUP: - xe_mmap_release(mmap); - return NULL; -} - -void xe_mmap_dealloc(xe_mmap_ref mmap) { - if (mmap->addr) { - munmap(mmap->addr, mmap->length); - mmap->addr = NULL; - } - - FILE* file_handle = (FILE*)mmap->file_handle; - if (file_handle) { - fclose(file_handle); - mmap->file_handle = NULL; - } -} - -xe_mmap_ref xe_mmap_retain(xe_mmap_ref mmap) { - xe_ref_retain((xe_ref)mmap); - return mmap; -} - -void xe_mmap_release(xe_mmap_ref mmap) { - xe_ref_release((xe_ref)mmap, (xe_ref_dealloc_t)xe_mmap_dealloc); -} - -uint8_t* xe_mmap_get_addr(xe_mmap_ref mmap) { - return (uint8_t*)mmap->addr; -} - -size_t xe_mmap_get_length(xe_mmap_ref mmap) { - return mmap->length; -} diff --git a/src/xenia/core/mmap_win.cc b/src/xenia/core/mmap_win.cc deleted file mode 100644 index 4121fd2af..000000000 --- a/src/xenia/core/mmap_win.cc +++ /dev/null @@ -1,133 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - - -typedef struct xe_mmap { - xe_ref_t ref; - - HANDLE file_handle; - HANDLE mmap_handle; - - void* addr; - size_t length; -} xe_mmap_t; - - -xe_mmap_ref xe_mmap_open(const xe_file_mode mode, const wchar_t *path, - const size_t offset, const size_t length) { - xe_mmap_ref mmap = (xe_mmap_ref)xe_calloc(sizeof(xe_mmap_t)); - xe_ref_init((xe_ref)mmap); - - DWORD fileAccess = 0; - DWORD fileShare = 0; - DWORD createMode = 0; - DWORD mappingProtect = 0; - DWORD viewAccess = 0; - switch (mode) { - case kXEFileModeRead: - fileAccess |= GENERIC_READ; - fileShare |= FILE_SHARE_READ; - createMode |= OPEN_EXISTING; - mappingProtect |= PAGE_READONLY; - viewAccess |= FILE_MAP_READ; - break; - case kXEFileModeWrite: - fileAccess |= GENERIC_WRITE; - fileShare |= 0; - createMode |= OPEN_ALWAYS; - mappingProtect |= PAGE_READWRITE; - viewAccess |= FILE_MAP_WRITE; - break; - case kXEFileModeRead | kXEFileModeWrite: - fileAccess |= GENERIC_READ | GENERIC_WRITE; - fileShare |= 0; - createMode |= OPEN_EXISTING; - mappingProtect |= PAGE_READWRITE; - viewAccess |= FILE_MAP_READ | FILE_MAP_WRITE; - break; - } - - SYSTEM_INFO systemInfo; - GetSystemInfo(&systemInfo); - - const size_t aligned_offset = - offset & (~(systemInfo.dwAllocationGranularity - 1)); - const size_t aligned_length = - length + (offset - aligned_offset); - - HANDLE file_handle = CreateFile( - path, fileAccess, fileShare, NULL, createMode, FILE_ATTRIBUTE_NORMAL, - NULL); - XEEXPECTNOTNULL(file_handle); - - HANDLE handle = CreateFileMapping( - file_handle, NULL, mappingProtect, 0, 0, NULL); - //(DWORD)(aligned_length >> 32), (DWORD)(aligned_length & 0xFFFFFFFF), NULL); - XEEXPECTNOTNULL(handle); - - void* address = MapViewOfFile(handle, viewAccess, - (DWORD)(aligned_offset >> 32), - (DWORD)(aligned_offset & 0xFFFFFFFF), - aligned_length); - XEEXPECTNOTNULL(address); - - mmap->file_handle = file_handle; - mmap->mmap_handle = handle; - mmap->addr = address; - if (length) { - mmap->length = length; - } else { - DWORD length_high; - size_t map_length = GetFileSize(file_handle, &length_high); - map_length |= ((uint64_t)length_high) << 32; - mmap->length = map_length; - } - - return mmap; - -XECLEANUP: - xe_mmap_release(mmap); - return NULL; -} - -void xe_mmap_dealloc(xe_mmap_ref mmap) { - if (mmap->addr) { - UnmapViewOfFile(mmap->addr); - mmap->addr = NULL; - } - - if (mmap->mmap_handle) { - CloseHandle(mmap->mmap_handle); - mmap->mmap_handle = NULL; - } - - if (mmap->file_handle) { - CloseHandle(mmap->file_handle); - mmap->file_handle = NULL; - } -} - -xe_mmap_ref xe_mmap_retain(xe_mmap_ref mmap) { - xe_ref_retain((xe_ref)mmap); - return mmap; -} - -void xe_mmap_release(xe_mmap_ref mmap) { - xe_ref_release((xe_ref)mmap, (xe_ref_dealloc_t)xe_mmap_dealloc); -} - -uint8_t* xe_mmap_get_addr(xe_mmap_ref mmap) { - return reinterpret_cast(mmap->addr); -} - -size_t xe_mmap_get_length(xe_mmap_ref mmap) { - return mmap->length; -} diff --git a/src/xenia/core/sources.gypi b/src/xenia/core/sources.gypi index 858a696bb..72d490667 100644 --- a/src/xenia/core/sources.gypi +++ b/src/xenia/core/sources.gypi @@ -3,7 +3,6 @@ 'sources': [ 'hash.cc', 'hash.h', - 'mmap.h', 'ref.cc', 'ref.h', 'run_loop.h', @@ -13,7 +12,6 @@ 'conditions': [ ['OS == "mac" or OS == "linux"', { 'sources': [ - 'mmap_posix.cc', 'socket_posix.cc', ], }], @@ -27,7 +25,6 @@ }], ['OS == "win"', { 'sources': [ - 'mmap_win.cc', 'run_loop_win.cc', 'socket_win.cc', ], diff --git a/src/xenia/kernel/fs/devices/disc_image_device.cc b/src/xenia/kernel/fs/devices/disc_image_device.cc index 9b5a381bc..9e9ab7efe 100644 --- a/src/xenia/kernel/fs/devices/disc_image_device.cc +++ b/src/xenia/kernel/fs/devices/disc_image_device.cc @@ -13,35 +13,31 @@ #include #include - -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::fs; +namespace xe { +namespace kernel { +namespace fs { DiscImageDevice::DiscImageDevice(const std::string& path, const std::wstring& local_path) - : Device(path), local_path_(local_path), mmap_(nullptr), gdfx_(nullptr) {} + : Device(path), local_path_(local_path), gdfx_(nullptr) {} -DiscImageDevice::~DiscImageDevice() { - delete gdfx_; - xe_mmap_release(mmap_); -} +DiscImageDevice::~DiscImageDevice() { delete gdfx_; } int DiscImageDevice::Init() { - mmap_ = xe_mmap_open(kXEFileModeRead, local_path_.c_str(), 0, 0); + mmap_ = poly::MappedMemory::Open(local_path_, poly::MappedMemory::Mode::READ); if (!mmap_) { XELOGE("Disc image could not be mapped"); return 1; } - gdfx_ = new GDFX(mmap_); + gdfx_ = new GDFX(mmap_.get()); GDFX::Error error = gdfx_->Load(); if (error != GDFX::kSuccess) { XELOGE("GDFX init failed: %d", error); return 1; } - //gdfx_->Dump(); + // gdfx_->Dump(); return 0; } @@ -65,10 +61,10 @@ Entry* DiscImageDevice::ResolvePath(const char* path) { } } - Entry::Type type = gdfx_entry->attributes & X_FILE_ATTRIBUTE_DIRECTORY ? - Entry::kTypeDirectory : Entry::kTypeFile; - return new DiscImageEntry( - type, this, path, mmap_, gdfx_entry); + Entry::Type type = gdfx_entry->attributes & X_FILE_ATTRIBUTE_DIRECTORY + ? Entry::Type::DIRECTORY + : Entry::Type::FILE; + return new DiscImageEntry(type, this, path, mmap_.get(), gdfx_entry); } X_STATUS DiscImageDevice::QueryVolume(XVolumeInfo* out_info, size_t length) { @@ -76,7 +72,12 @@ X_STATUS DiscImageDevice::QueryVolume(XVolumeInfo* out_info, size_t length) { return X_STATUS_NOT_IMPLEMENTED; } -X_STATUS DiscImageDevice::QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length) { +X_STATUS DiscImageDevice::QueryFileSystemAttributes( + XFileSystemAttributeInfo* out_info, size_t length) { assert_always(); return X_STATUS_NOT_IMPLEMENTED; } + +} // namespace fs +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/fs/devices/disc_image_device.h b/src/xenia/kernel/fs/devices/disc_image_device.h index c625357b3..f1fb3fb4d 100644 --- a/src/xenia/kernel/fs/devices/disc_image_device.h +++ b/src/xenia/kernel/fs/devices/disc_image_device.h @@ -10,11 +10,12 @@ #ifndef XENIA_KERNEL_FS_DEVICES_DISC_IMAGE_DEVICE_H_ #define XENIA_KERNEL_FS_DEVICES_DISC_IMAGE_DEVICE_H_ +#include #include +#include #include #include - #include namespace xe { @@ -38,7 +39,7 @@ class DiscImageDevice : public Device { private: std::wstring local_path_; - xe_mmap_ref mmap_; + std::unique_ptr mmap_; GDFX* gdfx_; }; diff --git a/src/xenia/kernel/fs/devices/disc_image_entry.cc b/src/xenia/kernel/fs/devices/disc_image_entry.cc index 8b4886975..fb74c2842 100644 --- a/src/xenia/kernel/fs/devices/disc_image_entry.cc +++ b/src/xenia/kernel/fs/devices/disc_image_entry.cc @@ -14,60 +14,45 @@ #include #include - -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::fs; - - -namespace { - +namespace xe { +namespace kernel { +namespace fs { class DiscImageMemoryMapping : public MemoryMapping { -public: - DiscImageMemoryMapping(uint8_t* address, size_t length, xe_mmap_ref mmap) : - MemoryMapping(address, length) { - mmap_ = xe_mmap_retain(mmap); - } + public: + DiscImageMemoryMapping(uint8_t* address, size_t length, + poly::MappedMemory* mmap) + : MemoryMapping(address, length), mmap_(mmap) {} - virtual ~DiscImageMemoryMapping() { - xe_mmap_release(mmap_); - } + virtual ~DiscImageMemoryMapping() {} -private: - xe_mmap_ref mmap_; + private: + poly::MappedMemory* mmap_; }; - -} - - DiscImageEntry::DiscImageEntry(Type type, Device* device, const char* path, - xe_mmap_ref mmap, GDFXEntry* gdfx_entry) : - gdfx_entry_(gdfx_entry), - gdfx_entry_iterator_(gdfx_entry->children.end()), - Entry(type, device, path) { - mmap_ = xe_mmap_retain(mmap); -} + poly::MappedMemory* mmap, GDFXEntry* gdfx_entry) + : gdfx_entry_(gdfx_entry), + gdfx_entry_iterator_(gdfx_entry->children.end()), + mmap_(mmap), + Entry(type, device, path) {} -DiscImageEntry::~DiscImageEntry() { - xe_mmap_release(mmap_); -} +DiscImageEntry::~DiscImageEntry() {} X_STATUS DiscImageEntry::QueryInfo(XFileInfo* out_info) { assert_not_null(out_info); - out_info->creation_time = 0; - out_info->last_access_time = 0; - out_info->last_write_time = 0; - out_info->change_time = 0; - out_info->allocation_size = 2048; - out_info->file_length = gdfx_entry_->size; - out_info->attributes = gdfx_entry_->attributes; + out_info->creation_time = 0; + out_info->last_access_time = 0; + out_info->last_write_time = 0; + out_info->change_time = 0; + out_info->allocation_size = 2048; + out_info->file_length = gdfx_entry_->size; + out_info->attributes = gdfx_entry_->attributes; return X_STATUS_SUCCESS; } -X_STATUS DiscImageEntry::QueryDirectory( - XDirectoryInfo* out_info, size_t length, const char* file_name, bool restart) { +X_STATUS DiscImageEntry::QueryDirectory(XDirectoryInfo* out_info, size_t length, + const char* file_name, bool restart) { assert_not_null(out_info); if (restart == true && gdfx_entry_iterator_ != gdfx_entry_->children.end()) { @@ -97,40 +82,41 @@ X_STATUS DiscImageEntry::QueryDirectory( } out_info->next_entry_offset = 0; - out_info->file_index = 0xCDCDCDCD; - out_info->creation_time = 0; - out_info->last_access_time = 0; - out_info->last_write_time = 0; - out_info->change_time = 0; - out_info->end_of_file = entry->size; - out_info->allocation_size = 2048; - out_info->attributes = (X_FILE_ATTRIBUTES)entry->attributes; - out_info->file_name_length = static_cast(entry_name.size()); + out_info->file_index = 0xCDCDCDCD; + out_info->creation_time = 0; + out_info->last_access_time = 0; + out_info->last_write_time = 0; + out_info->change_time = 0; + out_info->end_of_file = entry->size; + out_info->allocation_size = 2048; + out_info->attributes = (X_FILE_ATTRIBUTES)entry->attributes; + out_info->file_name_length = static_cast(entry_name.size()); memcpy(out_info->file_name, entry_name.c_str(), entry_name.size()); return X_STATUS_SUCCESS; } -MemoryMapping* DiscImageEntry::CreateMemoryMapping( - xe_file_mode file_mode, const size_t offset, const size_t length) { - if (file_mode & kXEFileModeWrite) { +MemoryMapping* DiscImageEntry::CreateMemoryMapping(Mode map_mode, + const size_t offset, + const size_t length) { + if (map_mode != Mode::READ) { // Only allow reads. return NULL; } size_t real_offset = gdfx_entry_->offset + offset; - size_t real_length = length ? - std::min(length, gdfx_entry_->size) : gdfx_entry_->size; - return new DiscImageMemoryMapping( - xe_mmap_get_addr(mmap_) + real_offset, - real_length, - mmap_); + size_t real_length = + length ? std::min(length, gdfx_entry_->size) : gdfx_entry_->size; + return new DiscImageMemoryMapping(mmap_->data() + real_offset, real_length, + mmap_); } -X_STATUS DiscImageEntry::Open( - KernelState* kernel_state, - uint32_t desired_access, bool async, - XFile** out_file) { - *out_file = new DiscImageFile(kernel_state, desired_access, this); +X_STATUS DiscImageEntry::Open(KernelState* kernel_state, Mode mode, + bool async, XFile** out_file) { + *out_file = new DiscImageFile(kernel_state, mode, this); return X_STATUS_SUCCESS; } + +} // namespace fs +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/fs/devices/disc_image_entry.h b/src/xenia/kernel/fs/devices/disc_image_entry.h index bbe788a3b..76c971d02 100644 --- a/src/xenia/kernel/fs/devices/disc_image_entry.h +++ b/src/xenia/kernel/fs/devices/disc_image_entry.h @@ -12,51 +12,45 @@ #include +#include #include #include - #include - namespace xe { namespace kernel { namespace fs { class GDFXEntry; - class DiscImageEntry : public Entry { -public: + public: DiscImageEntry(Type type, Device* device, const char* path, - xe_mmap_ref mmap, GDFXEntry* gdfx_entry); + poly::MappedMemory* mmap, GDFXEntry* gdfx_entry); virtual ~DiscImageEntry(); - xe_mmap_ref mmap() const { return mmap_; } + poly::MappedMemory* mmap() const { return mmap_; } GDFXEntry* gdfx_entry() const { return gdfx_entry_; } virtual X_STATUS QueryInfo(XFileInfo* out_info); - virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info, - size_t length, const char* file_name, bool restart); + virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info, size_t length, + const char* file_name, bool restart); virtual bool can_map() { return true; } - virtual MemoryMapping* CreateMemoryMapping( - xe_file_mode file_mode, const size_t offset, const size_t length); + virtual MemoryMapping* CreateMemoryMapping(Mode map_mode, const size_t offset, + const size_t length); - virtual X_STATUS Open( - KernelState* kernel_state, - uint32_t desired_access, bool async, - XFile** out_file); + virtual X_STATUS Open(KernelState* kernel_state, Mode mode, + bool async, XFile** out_file); -private: - xe_mmap_ref mmap_; - GDFXEntry* gdfx_entry_; + private: + poly::MappedMemory* mmap_; + GDFXEntry* gdfx_entry_; std::vector::iterator gdfx_entry_iterator_; }; - } // namespace fs } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_FS_DEVICES_DISC_IMAGE_ENTRY_H_ diff --git a/src/xenia/kernel/fs/devices/disc_image_file.cc b/src/xenia/kernel/fs/devices/disc_image_file.cc index c0f0d114a..45db575f0 100644 --- a/src/xenia/kernel/fs/devices/disc_image_file.cc +++ b/src/xenia/kernel/fs/devices/disc_image_file.cc @@ -15,39 +15,30 @@ #include #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::fs; +namespace xe { +namespace kernel { +namespace fs { +DiscImageFile::DiscImageFile(KernelState* kernel_state, Mode mode, + DiscImageEntry* entry) + : entry_(entry), XFile(kernel_state, mode) {} -DiscImageFile::DiscImageFile( - KernelState* kernel_state, uint32_t desired_access, - DiscImageEntry* entry) : - entry_(entry), - XFile(kernel_state, desired_access) { -} +DiscImageFile::~DiscImageFile() {} -DiscImageFile::~DiscImageFile() { -} - -const std::string& DiscImageFile::path() const { - return entry_->path(); -} +const std::string& DiscImageFile::path() const { return entry_->path(); } const std::string& DiscImageFile::absolute_path() const { return entry_->absolute_path(); } -const std::string& DiscImageFile::name() const { - return entry_->name(); -} +const std::string& DiscImageFile::name() const { return entry_->name(); } X_STATUS DiscImageFile::QueryInfo(XFileInfo* out_info) { return entry_->QueryInfo(out_info); } -X_STATUS DiscImageFile::QueryDirectory(XDirectoryInfo* out_info, - size_t length, const char* file_name, bool restart) { +X_STATUS DiscImageFile::QueryDirectory(XDirectoryInfo* out_info, size_t length, + const char* file_name, bool restart) { return entry_->QueryDirectory(out_info, length, file_name, restart); } @@ -55,23 +46,25 @@ X_STATUS DiscImageFile::QueryVolume(XVolumeInfo* out_info, size_t length) { return entry_->device()->QueryVolume(out_info, length); } -X_STATUS DiscImageFile::QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length) { +X_STATUS DiscImageFile::QueryFileSystemAttributes( + XFileSystemAttributeInfo* out_info, size_t length) { return entry_->device()->QueryFileSystemAttributes(out_info, length); } -X_STATUS DiscImageFile::ReadSync( - void* buffer, size_t buffer_length, size_t byte_offset, - size_t* out_bytes_read) { +X_STATUS DiscImageFile::ReadSync(void* buffer, size_t buffer_length, + size_t byte_offset, size_t* out_bytes_read) { GDFXEntry* gdfx_entry = entry_->gdfx_entry(); - xe_mmap_ref mmap = entry_->mmap(); if (byte_offset >= gdfx_entry->size) { return X_STATUS_END_OF_FILE; } size_t real_offset = gdfx_entry->offset + byte_offset; size_t real_length = std::min(buffer_length, gdfx_entry->size - byte_offset); - xe_copy_memory( - buffer, buffer_length, - xe_mmap_get_addr(mmap) + real_offset, real_length); + xe_copy_memory(buffer, buffer_length, entry_->mmap()->data() + real_offset, + real_length); *out_bytes_read = real_length; return X_STATUS_SUCCESS; } + +} // namespace fs +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/fs/devices/disc_image_file.h b/src/xenia/kernel/fs/devices/disc_image_file.h index e138705de..5e22187eb 100644 --- a/src/xenia/kernel/fs/devices/disc_image_file.h +++ b/src/xenia/kernel/fs/devices/disc_image_file.h @@ -12,7 +12,6 @@ #include #include - #include namespace xe { @@ -23,7 +22,7 @@ class DiscImageEntry; class DiscImageFile : public XFile { public: - DiscImageFile(KernelState* kernel_state, uint32_t desired_access, + DiscImageFile(KernelState* kernel_state, Mode desired_access, DiscImageEntry* entry); ~DiscImageFile() override; diff --git a/src/xenia/kernel/fs/devices/host_path_device.cc b/src/xenia/kernel/fs/devices/host_path_device.cc index ff6b55601..88d88ba12 100644 --- a/src/xenia/kernel/fs/devices/host_path_device.cc +++ b/src/xenia/kernel/fs/devices/host_path_device.cc @@ -12,9 +12,9 @@ #include #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::fs; +namespace xe { +namespace kernel { +namespace fs { HostPathDevice::HostPathDevice(const std::string& path, const std::wstring& local_path) @@ -37,7 +37,7 @@ Entry* HostPathDevice::ResolvePath(const char* path) { // TODO(benvanik): fail if does not exit // TODO(benvanik): switch based on type - Entry::Type type = Entry::kTypeFile; + auto type = Entry::Type::FILE; HostPathEntry* entry = new HostPathEntry(type, this, path, full_path); return entry; } @@ -45,7 +45,7 @@ Entry* HostPathDevice::ResolvePath(const char* path) { // TODO(gibbed): call into HostPathDevice? X_STATUS HostPathDevice::QueryVolume(XVolumeInfo* out_info, size_t length) { assert_not_null(out_info); - const char* name = "test"; // TODO(gibbed): actual value + const char* name = "test"; // TODO(gibbed): actual value auto end = (uint8_t*)out_info + length; size_t name_length = strlen(name); @@ -62,9 +62,10 @@ X_STATUS HostPathDevice::QueryVolume(XVolumeInfo* out_info, size_t length) { } // TODO(gibbed): call into HostPathDevice? -X_STATUS HostPathDevice::QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length) { +X_STATUS HostPathDevice::QueryFileSystemAttributes( + XFileSystemAttributeInfo* out_info, size_t length) { assert_not_null(out_info); - const char* name = "test"; // TODO(gibbed): actual value + const char* name = "test"; // TODO(gibbed): actual value auto end = (uint8_t*)out_info + length; size_t name_length = strlen(name); @@ -73,8 +74,12 @@ X_STATUS HostPathDevice::QueryFileSystemAttributes(XFileSystemAttributeInfo* out } out_info->attributes = 0; - out_info->maximum_component_name_length = 255; // TODO(gibbed): actual value + out_info->maximum_component_name_length = 255; // TODO(gibbed): actual value out_info->fs_name_length = (uint32_t)name_length; memcpy(out_info->fs_name, name, name_length); return X_STATUS_SUCCESS; } + +} // namespace fs +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/fs/devices/host_path_device.h b/src/xenia/kernel/fs/devices/host_path_device.h index 95b265ab7..0380508b2 100644 --- a/src/xenia/kernel/fs/devices/host_path_device.h +++ b/src/xenia/kernel/fs/devices/host_path_device.h @@ -14,7 +14,6 @@ #include #include - #include namespace xe { diff --git a/src/xenia/kernel/fs/devices/host_path_entry.cc b/src/xenia/kernel/fs/devices/host_path_entry.cc index 86084a9d1..783c12119 100644 --- a/src/xenia/kernel/fs/devices/host_path_entry.cc +++ b/src/xenia/kernel/fs/devices/host_path_entry.cc @@ -9,33 +9,22 @@ #include +#include #include - -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::fs; - - -namespace { - +namespace xe { +namespace kernel { +namespace fs { class HostPathMemoryMapping : public MemoryMapping { -public: - HostPathMemoryMapping(uint8_t* address, size_t length, xe_mmap_ref mmap) : - MemoryMapping(address, length) { - mmap_ = xe_mmap_retain(mmap); - } - virtual ~HostPathMemoryMapping() { - xe_mmap_release(mmap_); - } -private: - xe_mmap_ref mmap_; + public: + HostPathMemoryMapping(std::unique_ptr mmap) + : MemoryMapping(mmap->data(), mmap->size()), mmap_(std::move(mmap)) {} + + private: + std::unique_ptr mmap_; }; - -} - HostPathEntry::HostPathEntry(Type type, Device* device, const char* path, const std::wstring& local_path) : Entry(type, device, path), @@ -54,24 +43,23 @@ X_STATUS HostPathEntry::QueryInfo(XFileInfo* out_info) { assert_not_null(out_info); WIN32_FILE_ATTRIBUTE_DATA data; - if (!GetFileAttributesEx( - local_path_.c_str(), GetFileExInfoStandard, &data)) { + if (!GetFileAttributesEx(local_path_.c_str(), GetFileExInfoStandard, &data)) { return X_STATUS_ACCESS_DENIED; } - out_info->creation_time = COMBINE_TIME(data.ftCreationTime); - out_info->last_access_time = COMBINE_TIME(data.ftLastAccessTime); - out_info->last_write_time = COMBINE_TIME(data.ftLastWriteTime); - out_info->change_time = COMBINE_TIME(data.ftLastWriteTime); - out_info->allocation_size = 4096; - out_info->file_length = + out_info->creation_time = COMBINE_TIME(data.ftCreationTime); + out_info->last_access_time = COMBINE_TIME(data.ftLastAccessTime); + out_info->last_write_time = COMBINE_TIME(data.ftLastWriteTime); + out_info->change_time = COMBINE_TIME(data.ftLastWriteTime); + out_info->allocation_size = 4096; + out_info->file_length = ((uint64_t)data.nFileSizeHigh << 32) | data.nFileSizeLow; - out_info->attributes = (X_FILE_ATTRIBUTES)data.dwFileAttributes; + out_info->attributes = (X_FILE_ATTRIBUTES)data.dwFileAttributes; return X_STATUS_SUCCESS; } -X_STATUS HostPathEntry::QueryDirectory( - XDirectoryInfo* out_info, size_t length, const char* file_name, bool restart) { +X_STATUS HostPathEntry::QueryDirectory(XDirectoryInfo* out_info, size_t length, + const char* file_name, bool restart) { assert_not_null(out_info); WIN32_FIND_DATA ffd; @@ -97,8 +85,7 @@ X_STATUS HostPathEntry::QueryDirectory( } return X_STATUS_UNSUCCESSFUL; } - } - else { + } else { if (FindNextFile(handle, &ffd) == FALSE) { FindClose(handle); find_file_ = INVALID_HANDLE_VALUE; @@ -115,62 +102,62 @@ X_STATUS HostPathEntry::QueryDirectory( } out_info->next_entry_offset = 0; - out_info->file_index = 0xCDCDCDCD; - out_info->creation_time = COMBINE_TIME(ffd.ftCreationTime); - out_info->last_access_time = COMBINE_TIME(ffd.ftLastAccessTime); - out_info->last_write_time = COMBINE_TIME(ffd.ftLastWriteTime); - out_info->change_time = COMBINE_TIME(ffd.ftLastWriteTime); - out_info->end_of_file = + out_info->file_index = 0xCDCDCDCD; + out_info->creation_time = COMBINE_TIME(ffd.ftCreationTime); + out_info->last_access_time = COMBINE_TIME(ffd.ftLastAccessTime); + out_info->last_write_time = COMBINE_TIME(ffd.ftLastWriteTime); + out_info->change_time = COMBINE_TIME(ffd.ftLastWriteTime); + out_info->end_of_file = ((uint64_t)ffd.nFileSizeHigh << 32) | ffd.nFileSizeLow; - out_info->allocation_size = 4096; - out_info->attributes = (X_FILE_ATTRIBUTES)ffd.dwFileAttributes; + out_info->allocation_size = 4096; + out_info->attributes = (X_FILE_ATTRIBUTES)ffd.dwFileAttributes; - out_info->file_name_length = (uint32_t)entry_name_length; + out_info->file_name_length = (uint32_t)entry_name_length; for (size_t i = 0; i < entry_name_length; ++i) { - out_info->file_name[i] = - ffd.cFileName[i] < 256 ? (char)ffd.cFileName[i] : '?'; + out_info->file_name[i] = + ffd.cFileName[i] < 256 ? (char)ffd.cFileName[i] : '?'; } return X_STATUS_SUCCESS; } -MemoryMapping* HostPathEntry::CreateMemoryMapping(xe_file_mode file_mode, +MemoryMapping* HostPathEntry::CreateMemoryMapping(Mode map_mode, const size_t offset, const size_t length) { - xe_mmap_ref mmap = - xe_mmap_open(file_mode, local_path_.c_str(), offset, length); + auto mmap = poly::MappedMemory::Open( + local_path_, + map_mode == Mode::READ ? poly::MappedMemory::Mode::READ + : poly::MappedMemory::Mode::READ_WRITE, + offset, length); if (!mmap) { - return NULL; + return nullptr; } - HostPathMemoryMapping* lfmm = new HostPathMemoryMapping( - (uint8_t*)xe_mmap_get_addr(mmap), xe_mmap_get_length(mmap), - mmap); - xe_mmap_release(mmap); + HostPathMemoryMapping* lfmm = new HostPathMemoryMapping(std::move(mmap)); return lfmm; } -X_STATUS HostPathEntry::Open( - KernelState* kernel_state, - uint32_t desired_access, bool async, - XFile** out_file) { +X_STATUS HostPathEntry::Open(KernelState* kernel_state, Mode mode, + bool async, XFile** out_file) { + DWORD desired_access = + mode == Mode::READ ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE); DWORD share_mode = FILE_SHARE_READ; DWORD creation_disposition = OPEN_EXISTING; DWORD flags_and_attributes = async ? FILE_FLAG_OVERLAPPED : 0; - HANDLE file = CreateFile( - local_path_.c_str(), - desired_access, - share_mode, - NULL, - creation_disposition, - flags_and_attributes | FILE_FLAG_BACKUP_SEMANTICS, - NULL); + HANDLE file = + CreateFile(local_path_.c_str(), desired_access, share_mode, NULL, + creation_disposition, + flags_and_attributes | FILE_FLAG_BACKUP_SEMANTICS, NULL); if (file == INVALID_HANDLE_VALUE) { // TODO(benvanik): pick correct response. return X_STATUS_ACCESS_DENIED; } - *out_file = new HostPathFile(kernel_state, desired_access, this, file); + *out_file = new HostPathFile(kernel_state, mode, this, file); return X_STATUS_SUCCESS; } + +} // namespace fs +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/fs/devices/host_path_entry.h b/src/xenia/kernel/fs/devices/host_path_entry.h index c13b7eb34..b7624ffdf 100644 --- a/src/xenia/kernel/fs/devices/host_path_entry.h +++ b/src/xenia/kernel/fs/devices/host_path_entry.h @@ -12,7 +12,6 @@ #include #include - #include namespace xe { @@ -32,12 +31,11 @@ class HostPathEntry : public Entry { const char* file_name, bool restart); virtual bool can_map() { return true; } - virtual MemoryMapping* CreateMemoryMapping(xe_file_mode file_mode, - const size_t offset, + virtual MemoryMapping* CreateMemoryMapping(Mode map_mode, const size_t offset, const size_t length); - virtual X_STATUS Open(KernelState* kernel_state, uint32_t desired_access, - bool async, XFile** out_file); + virtual X_STATUS Open(KernelState* kernel_state, Mode mode, bool async, + XFile** out_file); private: std::wstring local_path_; diff --git a/src/xenia/kernel/fs/devices/host_path_file.cc b/src/xenia/kernel/fs/devices/host_path_file.cc index 166a57bc9..0a81b8fed 100644 --- a/src/xenia/kernel/fs/devices/host_path_file.cc +++ b/src/xenia/kernel/fs/devices/host_path_file.cc @@ -9,44 +9,35 @@ #include +#include #include -#include +namespace xe { +namespace kernel { +namespace fs { -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::fs; +HostPathFile::HostPathFile(KernelState* kernel_state, Mode mode, + HostPathEntry* entry, HANDLE file_handle) + : entry_(entry), + file_handle_(file_handle), + XFile(kernel_state, mode) {} +HostPathFile::~HostPathFile() { CloseHandle(file_handle_); } -HostPathFile::HostPathFile( - KernelState* kernel_state, uint32_t desired_access, - HostPathEntry* entry, HANDLE file_handle) : - entry_(entry), file_handle_(file_handle), - XFile(kernel_state, desired_access) { -} - -HostPathFile::~HostPathFile() { - CloseHandle(file_handle_); -} - -const std::string& HostPathFile::path() const { - return entry_->path(); -} +const std::string& HostPathFile::path() const { return entry_->path(); } const std::string& HostPathFile::absolute_path() const { return entry_->absolute_path(); } -const std::string& HostPathFile::name() const { - return entry_->name(); -} +const std::string& HostPathFile::name() const { return entry_->name(); } X_STATUS HostPathFile::QueryInfo(XFileInfo* out_info) { return entry_->QueryInfo(out_info); } -X_STATUS HostPathFile::QueryDirectory(XDirectoryInfo* out_info, - size_t length, const char* file_name, bool restart) { +X_STATUS HostPathFile::QueryDirectory(XDirectoryInfo* out_info, size_t length, + const char* file_name, bool restart) { return entry_->QueryDirectory(out_info, length, file_name, restart); } @@ -54,19 +45,19 @@ X_STATUS HostPathFile::QueryVolume(XVolumeInfo* out_info, size_t length) { return entry_->device()->QueryVolume(out_info, length); } -X_STATUS HostPathFile::QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length) { +X_STATUS HostPathFile::QueryFileSystemAttributes( + XFileSystemAttributeInfo* out_info, size_t length) { return entry_->device()->QueryFileSystemAttributes(out_info, length); } -X_STATUS HostPathFile::ReadSync( - void* buffer, size_t buffer_length, size_t byte_offset, - size_t* out_bytes_read) { +X_STATUS HostPathFile::ReadSync(void* buffer, size_t buffer_length, + size_t byte_offset, size_t* out_bytes_read) { OVERLAPPED overlapped; overlapped.Pointer = (PVOID)byte_offset; overlapped.hEvent = NULL; DWORD bytes_read = 0; - BOOL read = ReadFile( - file_handle_, buffer, (DWORD)buffer_length, &bytes_read, &overlapped); + BOOL read = ReadFile(file_handle_, buffer, (DWORD)buffer_length, &bytes_read, + &overlapped); if (read) { *out_bytes_read = bytes_read; return X_STATUS_SUCCESS; @@ -74,3 +65,7 @@ X_STATUS HostPathFile::ReadSync( return X_STATUS_END_OF_FILE; } } + +} // namespace fs +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/fs/devices/host_path_file.h b/src/xenia/kernel/fs/devices/host_path_file.h index 9ef850c4c..9acbc909d 100644 --- a/src/xenia/kernel/fs/devices/host_path_file.h +++ b/src/xenia/kernel/fs/devices/host_path_file.h @@ -14,7 +14,6 @@ #include #include - #include namespace xe { @@ -25,8 +24,8 @@ class HostPathEntry; class HostPathFile : public XFile { public: - HostPathFile(KernelState* kernel_state, uint32_t desired_access, - HostPathEntry* entry, HANDLE file_handle); + HostPathFile(KernelState* kernel_state, Mode mode, HostPathEntry* entry, + HANDLE file_handle); ~HostPathFile() override; const std::string& path() const override; diff --git a/src/xenia/kernel/fs/devices/stfs_container_device.cc b/src/xenia/kernel/fs/devices/stfs_container_device.cc index 7d58f1171..98cab9dc8 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_device.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_device.cc @@ -13,28 +13,24 @@ #include #include - -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::fs; +namespace xe { +namespace kernel { +namespace fs { STFSContainerDevice::STFSContainerDevice(const std::string& path, const std::wstring& local_path) - : Device(path), local_path_(local_path), mmap_(nullptr), stfs_(nullptr) {} + : Device(path), local_path_(local_path), stfs_(nullptr) {} -STFSContainerDevice::~STFSContainerDevice() { - delete stfs_; - xe_mmap_release(mmap_); -} +STFSContainerDevice::~STFSContainerDevice() { delete stfs_; } int STFSContainerDevice::Init() { - mmap_ = xe_mmap_open(kXEFileModeRead, local_path_.c_str(), 0, 0); + mmap_ = poly::MappedMemory::Open(local_path_, poly::MappedMemory::Mode::READ); if (!mmap_) { XELOGE("STFS container could not be mapped"); return 1; } - stfs_ = new STFS(mmap_); + stfs_ = new STFS(mmap_.get()); STFS::Error error = stfs_->Load(); if (error != STFS::kSuccess) { XELOGE("STFS init failed: %d", error); @@ -65,19 +61,24 @@ Entry* STFSContainerDevice::ResolvePath(const char* path) { } } - Entry::Type type = stfs_entry->attributes & X_FILE_ATTRIBUTE_DIRECTORY ? - Entry::kTypeDirectory : Entry::kTypeFile; - return new STFSContainerEntry( - type, this, path, mmap_, stfs_entry); + Entry::Type type = stfs_entry->attributes & X_FILE_ATTRIBUTE_DIRECTORY + ? Entry::Type::DIRECTORY + : Entry::Type::FILE; + return new STFSContainerEntry(type, this, path, mmap_.get(), stfs_entry); } - -X_STATUS STFSContainerDevice::QueryVolume(XVolumeInfo* out_info, size_t length) { +X_STATUS STFSContainerDevice::QueryVolume(XVolumeInfo* out_info, + size_t length) { assert_always(); return X_STATUS_NOT_IMPLEMENTED; } -X_STATUS STFSContainerDevice::QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length) { +X_STATUS STFSContainerDevice::QueryFileSystemAttributes( + XFileSystemAttributeInfo* out_info, size_t length) { assert_always(); return X_STATUS_NOT_IMPLEMENTED; } + +} // namespace fs +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/fs/devices/stfs_container_device.h b/src/xenia/kernel/fs/devices/stfs_container_device.h index e0a368d79..b5368bf97 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_device.h +++ b/src/xenia/kernel/fs/devices/stfs_container_device.h @@ -10,11 +10,12 @@ #ifndef XENIA_KERNEL_FS_DEVICES_STFS_CONTAINER_DEVICE_H_ #define XENIA_KERNEL_FS_DEVICES_STFS_CONTAINER_DEVICE_H_ +#include #include +#include #include #include - #include namespace xe { @@ -38,7 +39,7 @@ class STFSContainerDevice : public Device { private: std::wstring local_path_; - xe_mmap_ref mmap_; + std::unique_ptr mmap_; STFS* stfs_; }; diff --git a/src/xenia/kernel/fs/devices/stfs_container_entry.cc b/src/xenia/kernel/fs/devices/stfs_container_entry.cc index e738d2607..5012b7e3d 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_entry.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_entry.cc @@ -12,39 +12,37 @@ #include #include +namespace xe { +namespace kernel { +namespace fs { -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::fs; +STFSContainerEntry::STFSContainerEntry(Type type, Device* device, + const char* path, + poly::MappedMemory* mmap, + STFSEntry* stfs_entry) + : stfs_entry_(stfs_entry), + stfs_entry_iterator_(stfs_entry->children.end()), + mmap_(mmap), + Entry(type, device, path) {} - -STFSContainerEntry::STFSContainerEntry( - Type type, Device* device, const char* path, - xe_mmap_ref mmap, STFSEntry* stfs_entry) : - stfs_entry_(stfs_entry), - stfs_entry_iterator_(stfs_entry->children.end()), - Entry(type, device, path) { - mmap_ = xe_mmap_retain(mmap); -} - -STFSContainerEntry::~STFSContainerEntry() { - xe_mmap_release(mmap_); -} +STFSContainerEntry::~STFSContainerEntry() {} X_STATUS STFSContainerEntry::QueryInfo(XFileInfo* out_info) { assert_not_null(out_info); - out_info->creation_time = stfs_entry_->update_timestamp; - out_info->last_access_time = stfs_entry_->access_timestamp; - out_info->last_write_time = stfs_entry_->update_timestamp; - out_info->change_time = stfs_entry_->update_timestamp; - out_info->allocation_size = 4096; - out_info->file_length = stfs_entry_->size; - out_info->attributes = stfs_entry_->attributes; + out_info->creation_time = stfs_entry_->update_timestamp; + out_info->last_access_time = stfs_entry_->access_timestamp; + out_info->last_write_time = stfs_entry_->update_timestamp; + out_info->change_time = stfs_entry_->update_timestamp; + out_info->allocation_size = 4096; + out_info->file_length = stfs_entry_->size; + out_info->attributes = stfs_entry_->attributes; return X_STATUS_SUCCESS; } -X_STATUS STFSContainerEntry::QueryDirectory( - XDirectoryInfo* out_info, size_t length, const char* file_name, bool restart) { +X_STATUS STFSContainerEntry::QueryDirectory(XDirectoryInfo* out_info, + size_t length, + const char* file_name, + bool restart) { assert_not_null(out_info); if (restart && stfs_entry_iterator_ != stfs_entry_->children.end()) { @@ -73,24 +71,26 @@ X_STATUS STFSContainerEntry::QueryDirectory( return X_STATUS_UNSUCCESSFUL; } - out_info->file_index = 0xCDCDCDCD; - out_info->creation_time = entry->update_timestamp; + out_info->file_index = 0xCDCDCDCD; + out_info->creation_time = entry->update_timestamp; out_info->last_access_time = entry->access_timestamp; - out_info->last_write_time = entry->update_timestamp; - out_info->change_time = entry->update_timestamp; - out_info->end_of_file = entry->size; - out_info->allocation_size = 4096; - out_info->attributes = entry->attributes; + out_info->last_write_time = entry->update_timestamp; + out_info->change_time = entry->update_timestamp; + out_info->end_of_file = entry->size; + out_info->allocation_size = 4096; + out_info->attributes = entry->attributes; out_info->file_name_length = static_cast(entry_name.size()); memcpy(out_info->file_name, entry_name.c_str(), entry_name.size()); return X_STATUS_SUCCESS; } -X_STATUS STFSContainerEntry::Open( - KernelState* kernel_state, - uint32_t desired_access, bool async, - XFile** out_file) { - *out_file = new STFSContainerFile(kernel_state, desired_access, this); +X_STATUS STFSContainerEntry::Open(KernelState* kernel_state, Mode mode, + bool async, XFile** out_file) { + *out_file = new STFSContainerFile(kernel_state, mode, this); return X_STATUS_SUCCESS; } + +} // namespace fs +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/fs/devices/stfs_container_entry.h b/src/xenia/kernel/fs/devices/stfs_container_entry.h index aead9c014..db91161e6 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_entry.h +++ b/src/xenia/kernel/fs/devices/stfs_container_entry.h @@ -12,47 +12,41 @@ #include +#include #include #include - #include - namespace xe { namespace kernel { namespace fs { class STFSEntry; - class STFSContainerEntry : public Entry { -public: + public: STFSContainerEntry(Type type, Device* device, const char* path, - xe_mmap_ref mmap, STFSEntry* stfs_entry); + poly::MappedMemory* mmap, STFSEntry* stfs_entry); virtual ~STFSContainerEntry(); - xe_mmap_ref mmap() const { return mmap_; } + poly::MappedMemory* mmap() const { return mmap_; } STFSEntry* stfs_entry() const { return stfs_entry_; } virtual X_STATUS QueryInfo(XFileInfo* out_info); - virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info, - size_t length, const char* file_name, bool restart); + virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info, size_t length, + const char* file_name, bool restart); - virtual X_STATUS Open( - KernelState* kernel_state, - uint32_t desired_access, bool async, - XFile** out_file); + virtual X_STATUS Open(KernelState* kernel_state, Mode desired_access, + bool async, XFile** out_file); -private: - xe_mmap_ref mmap_; - STFSEntry* stfs_entry_; + private: + poly::MappedMemory* mmap_; + STFSEntry* stfs_entry_; std::vector>::iterator stfs_entry_iterator_; }; - } // namespace fs } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_FS_DEVICES_STFS_CONTAINER_ENTRY_H_ diff --git a/src/xenia/kernel/fs/devices/stfs_container_file.cc b/src/xenia/kernel/fs/devices/stfs_container_file.cc index 2c2a74675..32529fd95 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_file.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_file.cc @@ -15,39 +15,31 @@ #include #include -using namespace xe; -using namespace xe::kernel; -using namespace xe::kernel::fs; +namespace xe { +namespace kernel { +namespace fs { +STFSContainerFile::STFSContainerFile(KernelState* kernel_state, Mode mode, + STFSContainerEntry* entry) + : entry_(entry), XFile(kernel_state, mode) {} -STFSContainerFile::STFSContainerFile( - KernelState* kernel_state, uint32_t desired_access, - STFSContainerEntry* entry) : - entry_(entry), - XFile(kernel_state, desired_access) { -} +STFSContainerFile::~STFSContainerFile() {} -STFSContainerFile::~STFSContainerFile() { -} - -const std::string& STFSContainerFile::path() const { - return entry_->path(); -} +const std::string& STFSContainerFile::path() const { return entry_->path(); } const std::string& STFSContainerFile::absolute_path() const { return entry_->absolute_path(); } -const std::string& STFSContainerFile::name() const { - return entry_->name(); -} +const std::string& STFSContainerFile::name() const { return entry_->name(); } X_STATUS STFSContainerFile::QueryInfo(XFileInfo* out_info) { return entry_->QueryInfo(out_info); } X_STATUS STFSContainerFile::QueryDirectory(XDirectoryInfo* out_info, - size_t length, const char* file_name, bool restart) { + size_t length, const char* file_name, + bool restart) { return entry_->QueryDirectory(out_info, length, file_name, restart); } @@ -55,16 +47,15 @@ X_STATUS STFSContainerFile::QueryVolume(XVolumeInfo* out_info, size_t length) { return entry_->device()->QueryVolume(out_info, length); } -X_STATUS STFSContainerFile::QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, size_t length) { +X_STATUS STFSContainerFile::QueryFileSystemAttributes( + XFileSystemAttributeInfo* out_info, size_t length) { return entry_->device()->QueryFileSystemAttributes(out_info, length); } -X_STATUS STFSContainerFile::ReadSync( - void* buffer, size_t buffer_length, size_t byte_offset, - size_t* out_bytes_read) { +X_STATUS STFSContainerFile::ReadSync(void* buffer, size_t buffer_length, + size_t byte_offset, + size_t* out_bytes_read) { STFSEntry* stfs_entry = entry_->stfs_entry(); - xe_mmap_ref mmap = entry_->mmap(); - uint8_t* map_ptr = xe_mmap_get_addr(mmap); if (byte_offset >= stfs_entry->size) { return X_STATUS_END_OF_FILE; } @@ -87,10 +78,14 @@ X_STATUS STFSContainerFile::ReadSync( offset += byte_offset % 4096; read_length = std::min(read_length, record.length - (byte_offset % 4096)); } - xe_copy_struct(dest_ptr, map_ptr + offset, read_length); + xe_copy_struct(dest_ptr, entry_->mmap()->data() + offset, read_length); dest_ptr += read_length; remaining_length -= read_length; } *out_bytes_read = real_length; return X_STATUS_SUCCESS; } + +} // namespace fs +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/fs/devices/stfs_container_file.h b/src/xenia/kernel/fs/devices/stfs_container_file.h index eed3e232d..90e2e3157 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_file.h +++ b/src/xenia/kernel/fs/devices/stfs_container_file.h @@ -23,7 +23,7 @@ class STFSContainerEntry; class STFSContainerFile : public XFile { public: - STFSContainerFile(KernelState* kernel_state, uint32_t desired_access, + STFSContainerFile(KernelState* kernel_state, Mode mode, STFSContainerEntry* entry); ~STFSContainerFile() override; diff --git a/src/xenia/kernel/fs/entry.h b/src/xenia/kernel/fs/entry.h index f0cb428d3..1e3c9e0e7 100644 --- a/src/xenia/kernel/fs/entry.h +++ b/src/xenia/kernel/fs/entry.h @@ -32,6 +32,11 @@ namespace fs { class Device; +enum class Mode { + READ, + READ_WRITE, +}; + class MemoryMapping { public: MemoryMapping(uint8_t* address, size_t length); @@ -47,9 +52,9 @@ class MemoryMapping { class Entry { public: - enum Type { - kTypeFile, - kTypeDirectory, + enum class Type { + FILE, + DIRECTORY, }; Entry(Type type, Device* device, const std::string& path); @@ -66,14 +71,14 @@ class Entry { const char* file_name, bool restart) = 0; virtual bool can_map() { return false; } - virtual MemoryMapping* CreateMemoryMapping(xe_file_mode file_mode, - const size_t offset, + + virtual MemoryMapping* CreateMemoryMapping(Mode map_mode, const size_t offset, const size_t length) { return NULL; } - virtual X_STATUS Open(KernelState* kernel_state, uint32_t desired_access, - bool async, XFile** out_file) = 0; + virtual X_STATUS Open(KernelState* kernel_state, Mode mode, bool async, + XFile** out_file) = 0; private: Type type_; diff --git a/src/xenia/kernel/fs/gdfx.cc b/src/xenia/kernel/fs/gdfx.cc index 7f70a26b7..1b722ad46 100644 --- a/src/xenia/kernel/fs/gdfx.cc +++ b/src/xenia/kernel/fs/gdfx.cc @@ -50,16 +50,12 @@ void GDFXEntry::Dump(int indent) { } } -GDFX::GDFX(xe_mmap_ref mmap) { - mmap_ = xe_mmap_retain(mmap); - - root_entry_ = NULL; +GDFX::GDFX(poly::MappedMemory* mmap) : mmap_(mmap) { + root_entry_ = nullptr; } GDFX::~GDFX() { delete root_entry_; - - xe_mmap_release(mmap_); } GDFXEntry* GDFX::root_entry() { return root_entry_; } @@ -68,8 +64,8 @@ GDFX::Error GDFX::Load() { ParseState state; xe_zero_struct(&state, sizeof(state)); - state.ptr = (uint8_t*)xe_mmap_get_addr(mmap_); - state.size = xe_mmap_get_length(mmap_); + state.ptr = mmap_->data(); + state.size = mmap_->size(); auto result = Verify(state); if (result != kSuccess) { diff --git a/src/xenia/kernel/fs/gdfx.h b/src/xenia/kernel/fs/gdfx.h index 28e6d159d..682cb9f14 100644 --- a/src/xenia/kernel/fs/gdfx.h +++ b/src/xenia/kernel/fs/gdfx.h @@ -12,6 +12,7 @@ #include +#include #include #include #include @@ -49,7 +50,7 @@ class GDFX { kErrorDamagedFile = -31, }; - GDFX(xe_mmap_ref mmap); + GDFX(poly::MappedMemory* mmap); virtual ~GDFX(); GDFXEntry* root_entry(); @@ -81,7 +82,7 @@ class GDFX { bool ReadEntry(ParseState& state, const uint8_t* buffer, uint16_t entry_ordinal, GDFXEntry* parent); - xe_mmap_ref mmap_; + poly::MappedMemory* mmap_; GDFXEntry* root_entry_; }; diff --git a/src/xenia/kernel/fs/stfs.cc b/src/xenia/kernel/fs/stfs.cc index 6faa76f1b..bf6ec0617 100644 --- a/src/xenia/kernel/fs/stfs.cc +++ b/src/xenia/kernel/fs/stfs.cc @@ -117,17 +117,12 @@ void STFSEntry::Dump(int indent) { } } -STFS::STFS(xe_mmap_ref mmap) { - mmap_ = xe_mmap_retain(mmap); -} +STFS::STFS(poly::MappedMemory* mmap) : mmap_(mmap) {} -STFS::~STFS() { - xe_mmap_release(mmap_); -} +STFS::~STFS() {} STFS::Error STFS::Load() { - uint8_t* map_ptr = (uint8_t*)xe_mmap_get_addr(mmap_); - size_t map_size = xe_mmap_get_length(mmap_); + uint8_t* map_ptr = mmap_->data(); auto result = ReadHeaderAndVerify(map_ptr); if (result != kSuccess) { diff --git a/src/xenia/kernel/fs/stfs.h b/src/xenia/kernel/fs/stfs.h index da3e82627..a5291480e 100644 --- a/src/xenia/kernel/fs/stfs.h +++ b/src/xenia/kernel/fs/stfs.h @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -160,7 +161,7 @@ class STFS { kErrorDamagedFile = -31, }; - STFS(xe_mmap_ref mmap); + STFS(poly::MappedMemory* mmap); virtual ~STFS(); const STFSHeader* header() const { return &header_; } @@ -182,7 +183,7 @@ class STFS { BlockHash_t GetBlockHash(const uint8_t* map_ptr, uint32_t block_index, uint32_t table_offset); - xe_mmap_ref mmap_; + poly::MappedMemory* mmap_; STFSPackageType package_type_; STFSHeader header_; diff --git a/src/xenia/kernel/objects/xfile.cc b/src/xenia/kernel/objects/xfile.cc index 4a9df78e3..144d03c71 100644 --- a/src/xenia/kernel/objects/xfile.cc +++ b/src/xenia/kernel/objects/xfile.cc @@ -17,8 +17,8 @@ using namespace xe; using namespace xe::kernel; -XFile::XFile(KernelState* kernel_state, uint32_t desired_access) : - desired_access_(desired_access), position_(0), +XFile::XFile(KernelState* kernel_state, fs::Mode mode) : + mode_(mode), position_(0), XObject(kernel_state, kTypeFile) { async_event_ = new XEvent(kernel_state); async_event_->Initialize(false, false); diff --git a/src/xenia/kernel/objects/xfile.h b/src/xenia/kernel/objects/xfile.h index 49bec2e16..e56e0b2ac 100644 --- a/src/xenia/kernel/objects/xfile.h +++ b/src/xenia/kernel/objects/xfile.h @@ -149,13 +149,13 @@ public: virtual void* GetWaitHandle(); protected: - XFile(KernelState* kernel_state, uint32_t desired_access); + XFile(KernelState* kernel_state, fs::Mode mode); virtual X_STATUS ReadSync( void* buffer, size_t buffer_length, size_t byte_offset, size_t* out_bytes_read) = 0; private: - uint32_t desired_access_; + fs::Mode mode_; XEvent* async_event_; // TODO(benvanik): create flags, open state, etc. diff --git a/src/xenia/kernel/objects/xuser_module.cc b/src/xenia/kernel/objects/xuser_module.cc index c8f5c86e0..cee332f9a 100644 --- a/src/xenia/kernel/objects/xuser_module.cc +++ b/src/xenia/kernel/objects/xuser_module.cc @@ -50,7 +50,7 @@ X_STATUS XUserModule::LoadFromFile(const char* path) { result = X_STATUS_NO_SUCH_FILE; XEFAIL(); } - if (fs_entry->type() != fs::Entry::kTypeFile) { + if (fs_entry->type() != fs::Entry::Type::FILE) { XELOGE("Invalid file type: %s", path); result = X_STATUS_NO_SUCH_FILE; XEFAIL(); @@ -59,7 +59,8 @@ X_STATUS XUserModule::LoadFromFile(const char* path) { // If the FS supports mapping, map the file in and load from that. if (fs_entry->can_map()) { // Map. - fs::MemoryMapping* mmap = fs_entry->CreateMemoryMapping(kXEFileModeRead, 0, 0); + fs::MemoryMapping* mmap = + fs_entry->CreateMemoryMapping(fs::Mode::READ, 0, 0); XEEXPECTNOTNULL(mmap); // Load the module. @@ -76,7 +77,7 @@ X_STATUS XUserModule::LoadFromFile(const char* path) { buffer = (uint8_t*)xe_malloc(buffer_length); // Open file for reading. - result = fs_entry->Open(kernel_state(), kXEFileModeRead, false, &file); + result = fs_entry->Open(kernel_state(), fs::Mode::READ, false, &file); XEEXPECTZERO(result); // Read entire file into memory. diff --git a/src/xenia/kernel/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl_io.cc index 9aa4aa1c3..5054da354 100644 --- a/src/xenia/kernel/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl_io.cc @@ -81,12 +81,15 @@ SHIM_CALL NtCreateFile_shim( entry = fs->ResolvePath(object_name); } + auto mode = + desired_access & GENERIC_WRITE ? fs::Mode::READ_WRITE : fs::Mode::READ; + XFile* file = NULL; - if (entry && entry->type() == Entry::kTypeFile) { + if (entry && entry->type() == Entry::Type::FILE) { // Open the file. result = entry->Open( state, - desired_access, + mode, false, // TODO(benvanik): pick async mode, if needed. &file); } else { @@ -150,15 +153,18 @@ SHIM_CALL NtOpenFile_shim( assert_always(); } + auto mode = + desired_access & GENERIC_WRITE ? fs::Mode::READ_WRITE : fs::Mode::READ; + // Resolve the file using the virtual file system. FileSystem* fs = state->file_system(); Entry* entry = fs->ResolvePath(object_name); XFile* file = NULL; - if (entry && entry->type() == Entry::kTypeFile) { + if (entry && entry->type() == Entry::Type::FILE) { // Open the file. result = entry->Open( state, - desired_access, + mode, false, // TODO(benvanik): pick async mode, if needed. &file); } @@ -495,7 +501,7 @@ SHIM_CALL NtQueryFullAttributesFile_shim( // Resolve the file using the virtual file system. FileSystem* fs = state->file_system(); Entry* entry = fs->ResolvePath(object_name); - if (entry && entry->type() == Entry::kTypeFile) { + if (entry && entry->type() == Entry::Type::FILE) { // Found. XFileInfo file_info; result = entry->QueryInfo(&file_info); From 1c4dcd5e0ec83f4e755e4c85c58261974513ea1b Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 17 Aug 2014 13:13:03 -0700 Subject: [PATCH 132/388] clang-format on most of kernel/ --- src/xenia/emulator.cc | 4 +- src/xenia/kernel/app.cc | 18 +- src/xenia/kernel/app.h | 27 +- src/xenia/kernel/apps/apps.cc | 3 - src/xenia/kernel/apps/apps.h | 4 - src/xenia/kernel/apps/xmp_app.cc | 48 +- src/xenia/kernel/apps/xmp_app.h | 15 +- src/xenia/kernel/async_request.cc | 17 +- src/xenia/kernel/async_request.h | 28 +- src/xenia/kernel/dispatcher.cc | 18 +- src/xenia/kernel/dispatcher.h | 17 +- src/xenia/kernel/kernel_state.cc | 39 +- src/xenia/kernel/native_list.cc | 12 +- src/xenia/kernel/native_list.h | 10 +- src/xenia/kernel/object_table.cc | 14 +- src/xenia/kernel/object_table.h | 19 +- src/xenia/kernel/objects/xenumerator.cc | 18 +- src/xenia/kernel/objects/xenumerator.h | 9 +- src/xenia/kernel/objects/xevent.cc | 41 +- src/xenia/kernel/objects/xevent.h | 9 +- src/xenia/kernel/objects/xfile.cc | 23 +- src/xenia/kernel/objects/xfile.h | 92 +-- src/xenia/kernel/objects/xkernel_module.cc | 17 +- src/xenia/kernel/objects/xkernel_module.h | 15 +- src/xenia/kernel/objects/xmodule.cc | 19 +- src/xenia/kernel/objects/xmodule.h | 14 +- src/xenia/kernel/objects/xmutant.cc | 19 +- src/xenia/kernel/objects/xmutant.h | 9 +- src/xenia/kernel/objects/xnotify_listener.cc | 28 +- src/xenia/kernel/objects/xnotify_listener.h | 12 +- src/xenia/kernel/objects/xsemaphore.cc | 15 +- src/xenia/kernel/objects/xsemaphore.h | 9 +- src/xenia/kernel/objects/xthread.cc | 186 +++--- src/xenia/kernel/objects/xthread.h | 49 +- src/xenia/kernel/objects/xtimer.cc | 54 +- src/xenia/kernel/objects/xtimer.h | 17 +- src/xenia/kernel/objects/xuser_module.cc | 123 ++-- src/xenia/kernel/objects/xuser_module.h | 17 +- src/xenia/kernel/user_profile.cc | 7 +- src/xenia/kernel/user_profile.h | 42 +- src/xenia/kernel/util/xex2.cc | 642 +++++++++---------- src/xenia/kernel/util/xex2.h | 48 +- src/xenia/kernel/util/xex2_info.h | 2 - src/xenia/kernel/xam_content.cc | 37 +- src/xenia/kernel/xam_info.cc | 54 +- src/xenia/kernel/xam_input.cc | 91 +-- src/xenia/kernel/xam_module.cc | 21 +- src/xenia/kernel/xam_module.h | 8 +- src/xenia/kernel/xam_msg.cc | 42 +- src/xenia/kernel/xam_net.cc | 142 ++-- src/xenia/kernel/xam_notify.cc | 40 +- src/xenia/kernel/xam_ordinals.h | 5 +- src/xenia/kernel/xam_private.h | 6 +- src/xenia/kernel/xam_ui.cc | 10 +- src/xenia/kernel/xam_user.cc | 118 ++-- src/xenia/kernel/xam_video.cc | 8 +- src/xenia/kernel/xam_voice.cc | 36 +- src/xenia/kernel/xboxkrnl_audio.cc | 93 +-- src/xenia/kernel/xboxkrnl_debug.cc | 147 ++--- src/xenia/kernel/xboxkrnl_hal.cc | 15 +- src/xenia/kernel/xboxkrnl_io.cc | 426 ++++++------ src/xenia/kernel/xboxkrnl_memory.cc | 228 +++---- src/xenia/kernel/xboxkrnl_misc.cc | 12 +- src/xenia/kernel/xboxkrnl_module.cc | 67 +- src/xenia/kernel/xboxkrnl_module.h | 9 +- src/xenia/kernel/xboxkrnl_modules.cc | 190 +++--- src/xenia/kernel/xboxkrnl_ob.cc | 49 +- src/xenia/kernel/xboxkrnl_ordinals.h | 5 +- src/xenia/kernel/xboxkrnl_private.h | 3 - src/xenia/kernel/xboxkrnl_rtl.cc | 236 +++---- src/xenia/kernel/xboxkrnl_strings.cc | 300 +++------ src/xenia/kernel/xboxkrnl_threading.cc | 586 ++++++----------- src/xenia/kernel/xboxkrnl_usbcam.cc | 10 +- src/xenia/kernel/xboxkrnl_video.cc | 232 +++---- src/xenia/kernel/xobject.cc | 152 ++--- src/xenia/kernel/xobject.h | 37 +- 76 files changed, 2075 insertions(+), 3169 deletions(-) diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index 6eedbf4a1..ae6eeb75d 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -22,8 +22,8 @@ #include #include +namespace xe { -using namespace xe; using namespace xe::apu; using namespace xe::cpu; using namespace xe::gpu; @@ -218,3 +218,5 @@ X_STATUS Emulator::CompleteLaunch(const std::wstring& path, return xboxkrnl_->LaunchModule(module_path.c_str()); } + +} // namespace xe diff --git a/src/xenia/kernel/app.cc b/src/xenia/kernel/app.cc index 0a037fb64..4541ade59 100644 --- a/src/xenia/kernel/app.cc +++ b/src/xenia/kernel/app.cc @@ -11,24 +11,22 @@ #include - namespace xe { namespace kernel { - XApp::XApp(KernelState* kernel_state, uint32_t app_id) - : kernel_state_(kernel_state), app_id_(app_id), + : kernel_state_(kernel_state), + app_id_(app_id), membase_(kernel_state->memory()->membase()) {} - void XAppManager::RegisterApp(std::unique_ptr app) { assert_zero(app_lookup_.count(app->app_id())); - app_lookup_.insert({ app->app_id(), app.get() }); + app_lookup_.insert({app->app_id(), app.get()}); apps_.push_back(std::move(app)); } - -X_RESULT XAppManager::DispatchMessageSync(uint32_t app_id, uint32_t message, uint32_t arg1, uint32_t arg2) { +X_RESULT XAppManager::DispatchMessageSync(uint32_t app_id, uint32_t message, + uint32_t arg1, uint32_t arg2) { const auto& it = app_lookup_.find(app_id); if (it == app_lookup_.end()) { return X_ERROR_NOT_FOUND; @@ -36,8 +34,9 @@ X_RESULT XAppManager::DispatchMessageSync(uint32_t app_id, uint32_t message, uin return it->second->DispatchMessageSync(message, arg1, arg2); } - -X_RESULT XAppManager::DispatchMessageAsync(uint32_t app_id, uint32_t message, uint32_t buffer_ptr, size_t buffer_length) { +X_RESULT XAppManager::DispatchMessageAsync(uint32_t app_id, uint32_t message, + uint32_t buffer_ptr, + size_t buffer_length) { const auto& it = app_lookup_.find(app_id); if (it == app_lookup_.end()) { return X_ERROR_NOT_FOUND; @@ -45,6 +44,5 @@ X_RESULT XAppManager::DispatchMessageAsync(uint32_t app_id, uint32_t message, ui return it->second->DispatchMessageAsync(message, buffer_ptr, buffer_length); } - } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/app.h b/src/xenia/kernel/app.h index ab60006e2..cc6a1b45e 100644 --- a/src/xenia/kernel/app.h +++ b/src/xenia/kernel/app.h @@ -15,25 +15,23 @@ #include #include - #include - namespace xe { namespace kernel { - class KernelState; - class XApp { -public: + public: uint32_t app_id() const { return app_id_; } - virtual X_RESULT DispatchMessageSync(uint32_t message, uint32_t arg1, uint32_t arg2) = 0; - virtual X_RESULT DispatchMessageAsync(uint32_t message, uint32_t buffer_ptr, size_t buffer_length) = 0; + virtual X_RESULT DispatchMessageSync(uint32_t message, uint32_t arg1, + uint32_t arg2) = 0; + virtual X_RESULT DispatchMessageAsync(uint32_t message, uint32_t buffer_ptr, + size_t buffer_length) = 0; -protected: + protected: XApp(KernelState* kernel_state, uint32_t app_id); KernelState* kernel_state_; @@ -41,22 +39,21 @@ protected: uint8_t* membase_; }; - class XAppManager { -public: + public: void RegisterApp(std::unique_ptr app); - X_RESULT DispatchMessageSync(uint32_t app_id, uint32_t message, uint32_t arg1, uint32_t arg2); - X_RESULT DispatchMessageAsync(uint32_t app_id, uint32_t message, uint32_t buffer_ptr, size_t buffer_length); + X_RESULT DispatchMessageSync(uint32_t app_id, uint32_t message, uint32_t arg1, + uint32_t arg2); + X_RESULT DispatchMessageAsync(uint32_t app_id, uint32_t message, + uint32_t buffer_ptr, size_t buffer_length); -private: + private: std::vector> apps_; std::unordered_map app_lookup_; }; - } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_APP_H_ diff --git a/src/xenia/kernel/apps/apps.cc b/src/xenia/kernel/apps/apps.cc index 9d18c80ec..88fbb40b5 100644 --- a/src/xenia/kernel/apps/apps.cc +++ b/src/xenia/kernel/apps/apps.cc @@ -11,17 +11,14 @@ #include - namespace xe { namespace kernel { namespace apps { - void RegisterApps(KernelState* kernel_state, XAppManager* manager) { manager->RegisterApp(std::make_unique(kernel_state)); } - } // namespace apps } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/apps/apps.h b/src/xenia/kernel/apps/apps.h index b18e08fdb..723dc74ae 100644 --- a/src/xenia/kernel/apps/apps.h +++ b/src/xenia/kernel/apps/apps.h @@ -16,18 +16,14 @@ #include #include - namespace xe { namespace kernel { namespace apps { - void RegisterApps(KernelState* kernel_state, XAppManager* manager); - } // namespace apps } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_APPS_APPS_H_ diff --git a/src/xenia/kernel/apps/xmp_app.cc b/src/xenia/kernel/apps/xmp_app.cc index b5b4af54c..423a64506 100644 --- a/src/xenia/kernel/apps/xmp_app.cc +++ b/src/xenia/kernel/apps/xmp_app.cc @@ -9,12 +9,10 @@ #include - namespace xe { namespace kernel { namespace apps { - X_RESULT XXMPApp::XMPGetStatus(uint32_t unk, uint32_t status_ptr) { // Some stupid games will hammer this on a thread - induce a delay // here to keep from starving real threads. @@ -28,7 +26,8 @@ X_RESULT XXMPApp::XMPGetStatus(uint32_t unk, uint32_t status_ptr) { return X_ERROR_SUCCESS; } -X_RESULT XXMPApp::XMPGetStatusEx(uint32_t unk, uint32_t unk_ptr, uint32_t disabled_ptr) { +X_RESULT XXMPApp::XMPGetStatusEx(uint32_t unk, uint32_t unk_ptr, + uint32_t disabled_ptr) { // Some stupid games will hammer this on a thread - induce a delay // here to keep from starving real threads. Sleep(1); @@ -42,7 +41,8 @@ X_RESULT XXMPApp::XMPGetStatusEx(uint32_t unk, uint32_t unk_ptr, uint32_t disabl return X_ERROR_SUCCESS; } -X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t arg1, uint32_t arg2) { +X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t arg1, + uint32_t arg2) { // http://freestyledash.googlecode.com/svn-history/r1/trunk/Freestyle/Scenes/Media/Music/ScnMusic.cpp switch (message) { case 0x00070009: { @@ -75,33 +75,33 @@ X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t arg1, uint32_t return X_ERROR_NOT_FOUND; } -X_RESULT XXMPApp::DispatchMessageAsync(uint32_t message, uint32_t buffer_ptr, size_t buffer_length) { +X_RESULT XXMPApp::DispatchMessageAsync(uint32_t message, uint32_t buffer_ptr, + size_t buffer_length) { switch (message) { - case 0x00070009: { - uint32_t unk = - poly::load_and_swap(membase_ + buffer_ptr + 0); // 0x00000002 - uint32_t status_ptr = poly::load_and_swap( - membase_ + buffer_ptr + 4); // out ptr to 4b - expect 0 - assert_true(buffer_length == 8); - return XMPGetStatus(unk, status_ptr); - } - case 0x0007001B: { - uint32_t unk = - poly::load_and_swap(membase_ + buffer_ptr + 0); // 0x00000002 - uint32_t unk_ptr = poly::load_and_swap( - membase_ + buffer_ptr + 4); // out ptr to 4b - expect 0 - uint32_t disabled_ptr = poly::load_and_swap( - membase_ + buffer_ptr + 8); // out ptr to 4b - expect 1 (to skip) - assert_true(buffer_length == 0xC); - return XMPGetStatusEx(unk, unk_ptr, disabled_ptr); - } + case 0x00070009: { + uint32_t unk = poly::load_and_swap(membase_ + buffer_ptr + + 0); // 0x00000002 + uint32_t status_ptr = poly::load_and_swap( + membase_ + buffer_ptr + 4); // out ptr to 4b - expect 0 + assert_true(buffer_length == 8); + return XMPGetStatus(unk, status_ptr); + } + case 0x0007001B: { + uint32_t unk = poly::load_and_swap(membase_ + buffer_ptr + + 0); // 0x00000002 + uint32_t unk_ptr = poly::load_and_swap( + membase_ + buffer_ptr + 4); // out ptr to 4b - expect 0 + uint32_t disabled_ptr = poly::load_and_swap( + membase_ + buffer_ptr + 8); // out ptr to 4b - expect 1 (to skip) + assert_true(buffer_length == 0xC); + return XMPGetStatusEx(unk, unk_ptr, disabled_ptr); + } } XELOGE("Unimplemented XMsg message app=%.8X, msg=%.8X, buffer=%.8X, len=%d", app_id(), message, buffer_ptr, buffer_length); return X_ERROR_NOT_FOUND; } - } // namespace apps } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/apps/xmp_app.h b/src/xenia/kernel/apps/xmp_app.h index 754ca9593..a57cb4bc7 100644 --- a/src/xenia/kernel/apps/xmp_app.h +++ b/src/xenia/kernel/apps/xmp_app.h @@ -16,27 +16,26 @@ #include #include - namespace xe { namespace kernel { namespace apps { - class XXMPApp : public XApp { -public: + public: XXMPApp(KernelState* kernel_state) : XApp(kernel_state, 0xFA) {} X_RESULT XMPGetStatus(uint32_t unk, uint32_t status_ptr); - X_RESULT XMPGetStatusEx(uint32_t unk, uint32_t unk_ptr, uint32_t disabled_ptr); + X_RESULT XMPGetStatusEx(uint32_t unk, uint32_t unk_ptr, + uint32_t disabled_ptr); - X_RESULT DispatchMessageSync(uint32_t message, uint32_t arg1, uint32_t arg2) override; - X_RESULT DispatchMessageAsync(uint32_t message, uint32_t buffer_ptr, size_t buffer_length) override; + X_RESULT DispatchMessageSync(uint32_t message, uint32_t arg1, + uint32_t arg2) override; + X_RESULT DispatchMessageAsync(uint32_t message, uint32_t buffer_ptr, + size_t buffer_length) override; }; - } // namespace apps } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_APPS_XMP_APP_H_ diff --git a/src/xenia/kernel/async_request.cc b/src/xenia/kernel/async_request.cc index fd0359cac..f9165a188 100644 --- a/src/xenia/kernel/async_request.cc +++ b/src/xenia/kernel/async_request.cc @@ -12,17 +12,18 @@ #include #include - namespace xe { namespace kernel { - -XAsyncRequest::XAsyncRequest( - KernelState* kernel_state, XObject* object, - CompletionCallback callback, void* callback_context) : - kernel_state_(kernel_state), object_(object), - callback_(callback), callback_context_(callback_context), - apc_routine_(0), apc_context_(0) { +XAsyncRequest::XAsyncRequest(KernelState* kernel_state, XObject* object, + CompletionCallback callback, + void* callback_context) + : kernel_state_(kernel_state), + object_(object), + callback_(callback), + callback_context_(callback_context), + apc_routine_(0), + apc_context_(0) { object_->Retain(); } diff --git a/src/xenia/kernel/async_request.h b/src/xenia/kernel/async_request.h index 0af0ac6f2..93876445d 100644 --- a/src/xenia/kernel/async_request.h +++ b/src/xenia/kernel/async_request.h @@ -14,10 +14,8 @@ #include #include - #include - namespace xe { namespace kernel { @@ -25,14 +23,12 @@ class KernelState; class XEvent; class XObject; - class XAsyncRequest { -public: + public: typedef void (*CompletionCallback)(XAsyncRequest* request, void* context); - XAsyncRequest( - KernelState* kernel_state, XObject* object, - CompletionCallback callback, void* callback_context); + XAsyncRequest(KernelState* kernel_state, XObject* object, + CompletionCallback callback, void* callback_context); virtual ~XAsyncRequest(); KernelState* kernel_state() const { return kernel_state_; } @@ -42,20 +38,18 @@ public: // Complete(result) -protected: - KernelState* kernel_state_; - XObject* object_; - CompletionCallback callback_; - void* callback_context_; + protected: + KernelState* kernel_state_; + XObject* object_; + CompletionCallback callback_; + void* callback_context_; - std::vector wait_events_; - uint32_t apc_routine_; - uint32_t apc_context_; + std::vector wait_events_; + uint32_t apc_routine_; + uint32_t apc_context_; }; - } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_ASYNC_REQUEST_H_ diff --git a/src/xenia/kernel/dispatcher.cc b/src/xenia/kernel/dispatcher.cc index 1781ef76a..aa6349b34 100644 --- a/src/xenia/kernel/dispatcher.cc +++ b/src/xenia/kernel/dispatcher.cc @@ -12,27 +12,19 @@ #include #include - namespace xe { namespace kernel { - -Dispatcher::Dispatcher(KernelState* kernel_state) : - kernel_state_(kernel_state) { +Dispatcher::Dispatcher(KernelState* kernel_state) + : kernel_state_(kernel_state) { dpc_list_ = new NativeList(kernel_state->memory()); } -Dispatcher::~Dispatcher() { - delete dpc_list_; -} +Dispatcher::~Dispatcher() { delete dpc_list_; } -void Dispatcher::Lock() { - lock_.lock(); -} +void Dispatcher::Lock() { lock_.lock(); } -void Dispatcher::Unlock() { - lock_.unlock(); -} +void Dispatcher::Unlock() { lock_.unlock(); } } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/dispatcher.h b/src/xenia/kernel/dispatcher.h index ff7e9b189..2cde407b9 100644 --- a/src/xenia/kernel/dispatcher.h +++ b/src/xenia/kernel/dispatcher.h @@ -17,16 +17,14 @@ #include - namespace xe { namespace kernel { class KernelState; class NativeList; - class Dispatcher { -public: + public: Dispatcher(KernelState* kernel_state); virtual ~Dispatcher(); @@ -37,18 +35,15 @@ public: NativeList* dpc_list() const { return dpc_list_; } -private: + private: + private: + KernelState* kernel_state_; -private: - KernelState* kernel_state_; - - std::mutex lock_; - NativeList* dpc_list_; + std::mutex lock_; + NativeList* dpc_list_; }; - } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_DISPATCHER_H_ diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index ab789a4aa..67358efab 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -22,26 +22,24 @@ #include #include - namespace xe { namespace kernel { - // This is a global object initialized with the XboxkrnlModule. // It references the current kernel state object that all kernel methods should // be using to stash their variables. KernelState* shared_kernel_state_ = nullptr; +KernelState::KernelState(Emulator* emulator) + : emulator_(emulator), + memory_(emulator->memory()), + executable_module_(NULL) { + processor_ = emulator->processor(); + file_system_ = emulator->file_system(); -KernelState::KernelState(Emulator* emulator) : - emulator_(emulator), memory_(emulator->memory()), - executable_module_(NULL) { - processor_ = emulator->processor(); - file_system_ = emulator->file_system(); + dispatcher_ = new Dispatcher(this); - dispatcher_ = new Dispatcher(this); - - app_manager_ = std::make_unique(); + app_manager_ = std::make_unique(); user_profile_ = std::make_unique(); object_table_ = new ObjectTable(); @@ -67,9 +65,7 @@ KernelState::~KernelState() { shared_kernel_state_ = NULL; } -KernelState* KernelState::shared() { - return shared_kernel_state_; -} +KernelState* KernelState::shared() { return shared_kernel_state_; } void KernelState::RegisterModule(XModule* module) {} @@ -170,7 +166,8 @@ void KernelState::BroadcastNotification(XNotificationID id, uint32_t data) { } } -void KernelState::CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result, uint32_t length) { +void KernelState::CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result, + uint32_t length) { auto ptr = memory()->membase() + overlapped_ptr; XOverlappedSetResult(ptr, result); XOverlappedSetLength(ptr, length); @@ -179,7 +176,7 @@ void KernelState::CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result, u if (event_handle) { XEvent* ev = nullptr; if (XSUCCEEDED(object_table()->GetObject( - event_handle, reinterpret_cast(&ev)))) { + event_handle, reinterpret_cast(&ev)))) { ev->Set(0, false); ev->Release(); } @@ -189,17 +186,19 @@ void KernelState::CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result, u X_HANDLE thread_handle = XOverlappedGetContext(ptr); XThread* thread = nullptr; if (XSUCCEEDED(object_table()->GetObject( - thread_handle, reinterpret_cast(&thread)))) { - // TODO(benvanik): queue APC on the thread that requested the overlapped operation. + thread_handle, reinterpret_cast(&thread)))) { + // TODO(benvanik): queue APC on the thread that requested the overlapped + // operation. thread->Release(); } } } -void KernelState::CompleteOverlappedImmediate(uint32_t overlapped_ptr, X_RESULT result, uint32_t length) { +void KernelState::CompleteOverlappedImmediate(uint32_t overlapped_ptr, + X_RESULT result, + uint32_t length) { auto ptr = memory()->membase() + overlapped_ptr; - XOverlappedSetContext(ptr, - XThread::GetCurrentThreadHandle()); + XOverlappedSetContext(ptr, XThread::GetCurrentThreadHandle()); CompleteOverlapped(overlapped_ptr, result, length); } diff --git a/src/xenia/kernel/native_list.cc b/src/xenia/kernel/native_list.cc index fa87663d1..6a301e940 100644 --- a/src/xenia/kernel/native_list.cc +++ b/src/xenia/kernel/native_list.cc @@ -9,15 +9,11 @@ #include - namespace xe { namespace kernel { - -NativeList::NativeList(Memory* memory) : - memory_(memory), - head_(kInvalidPointer) { -} +NativeList::NativeList(Memory* memory) + : memory_(memory), head_(kInvalidPointer) {} void NativeList::Insert(uint32_t ptr) { uint8_t* mem = memory_->membase(); @@ -67,9 +63,7 @@ uint32_t NativeList::Shift() { return ptr; } -bool NativeList::HasPending() { - return head_ != kInvalidPointer; -} +bool NativeList::HasPending() { return head_ != kInvalidPointer; } } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/native_list.h b/src/xenia/kernel/native_list.h index d521ea937..5c29e7bb9 100644 --- a/src/xenia/kernel/native_list.h +++ b/src/xenia/kernel/native_list.h @@ -15,11 +15,9 @@ #include - namespace xe { namespace kernel { - // List is designed for storing pointers to objects in the guest heap. // All values in the list should be assumed to be in big endian. @@ -31,7 +29,7 @@ namespace kernel { // } class NativeList { -public: + public: NativeList(Memory* memory); void Insert(uint32_t list_entry_ptr); @@ -40,17 +38,15 @@ public: uint32_t Shift(); bool HasPending(); -private: + private: const uint32_t kInvalidPointer = 0xE0FE0FFF; -private: + private: Memory* memory_; uint32_t head_; }; - } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_NATIVE_LIST_H_ diff --git a/src/xenia/kernel/object_table.cc b/src/xenia/kernel/object_table.cc index afdca7994..2b2541daf 100644 --- a/src/xenia/kernel/object_table.cc +++ b/src/xenia/kernel/object_table.cc @@ -14,16 +14,11 @@ #include #include - namespace xe { namespace kernel { - -ObjectTable::ObjectTable() : - table_capacity_(0), - table_(NULL), - last_free_entry_(0) { -} +ObjectTable::ObjectTable() + : table_capacity_(0), table_(NULL), last_free_entry_(0) {} ObjectTable::~ObjectTable() { std::lock_guard lock(table_mutex_); @@ -85,7 +80,7 @@ X_STATUS ObjectTable::AddHandle(XObject* object, X_HANDLE* out_handle) { assert_not_null(out_handle); X_STATUS result = X_STATUS_SUCCESS; - + uint32_t slot = 0; { std::lock_guard lock(table_mutex_); @@ -182,7 +177,6 @@ X_STATUS ObjectTable::GetObject(X_HANDLE handle, XObject** out_object) { if (object) { object->Retain(); } - } *out_object = object; @@ -192,7 +186,7 @@ X_STATUS ObjectTable::GetObject(X_HANDLE handle, XObject** out_object) { X_HANDLE ObjectTable::TranslateHandle(X_HANDLE handle) { if (handle == 0xFFFFFFFF) { // CurrentProcess - //assert_always(); + // assert_always(); return 0; } else if (handle == 0xFFFFFFFE) { // CurrentThread diff --git a/src/xenia/kernel/object_table.h b/src/xenia/kernel/object_table.h index 3cd5cf87e..1da7e8184 100644 --- a/src/xenia/kernel/object_table.h +++ b/src/xenia/kernel/object_table.h @@ -17,16 +17,13 @@ #include - namespace xe { namespace kernel { - class XObject; - class ObjectTable { -public: + public: ObjectTable(); ~ObjectTable(); @@ -34,23 +31,19 @@ public: X_STATUS RemoveHandle(X_HANDLE handle); X_STATUS GetObject(X_HANDLE handle, XObject** out_object); -private: + private: X_HANDLE TranslateHandle(X_HANDLE handle); X_STATUS FindFreeSlot(uint32_t* out_slot); - typedef struct { - XObject* object; - } ObjectTableEntry; + typedef struct { XObject* object; } ObjectTableEntry; - std::mutex table_mutex_; - uint32_t table_capacity_; + std::mutex table_mutex_; + uint32_t table_capacity_; ObjectTableEntry* table_; - uint32_t last_free_entry_; + uint32_t last_free_entry_; }; - } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_OBJECT_TABLE_H_ diff --git a/src/xenia/kernel/objects/xenumerator.cc b/src/xenia/kernel/objects/xenumerator.cc index b4516d813..3fe25297d 100644 --- a/src/xenia/kernel/objects/xenumerator.cc +++ b/src/xenia/kernel/objects/xenumerator.cc @@ -9,17 +9,15 @@ #include +namespace xe { +namespace kernel { -using namespace xe; -using namespace xe::kernel; +XEnumerator::XEnumerator(KernelState* kernel_state) + : XObject(kernel_state, kTypeEnumerator) {} +XEnumerator::~XEnumerator() {} -XEnumerator::XEnumerator(KernelState* kernel_state) : - XObject(kernel_state, kTypeEnumerator) { -} +void XEnumerator::Initialize() {} -XEnumerator::~XEnumerator() { -} - -void XEnumerator::Initialize() { -} +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/objects/xenumerator.h b/src/xenia/kernel/objects/xenumerator.h index fa3a0dbde..b1bfd0f37 100644 --- a/src/xenia/kernel/objects/xenumerator.h +++ b/src/xenia/kernel/objects/xenumerator.h @@ -11,27 +11,22 @@ #define XENIA_KERNEL_XBOXKRNL_XENUMERATOR_H_ #include - #include - namespace xe { namespace kernel { - class XEnumerator : public XObject { -public: + public: XEnumerator(KernelState* kernel_state); virtual ~XEnumerator(); void Initialize(); -private: + private: }; - } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_XENUMERATOR_H_ diff --git a/src/xenia/kernel/objects/xevent.cc b/src/xenia/kernel/objects/xevent.cc index e1034d787..e00593409 100644 --- a/src/xenia/kernel/objects/xevent.cc +++ b/src/xenia/kernel/objects/xevent.cc @@ -9,15 +9,11 @@ #include +namespace xe { +namespace kernel { -using namespace xe; -using namespace xe::kernel; - - -XEvent::XEvent(KernelState* kernel_state) : - XObject(kernel_state, kTypeEvent), - handle_(NULL) { -} +XEvent::XEvent(KernelState* kernel_state) + : XObject(kernel_state, kTypeEvent), handle_(NULL) {} XEvent::~XEvent() { if (handle_) { @@ -36,15 +32,15 @@ void XEvent::InitializeNative(void* native_ptr, DISPATCH_HEADER& header) { bool manual_reset; switch (header.type_flags >> 24) { - case 0x00: // EventNotificationObject (manual reset) - manual_reset = true; - break; - case 0x01: // EventSynchronizationObject (auto reset) - manual_reset = false; - break; - default: - assert_always(); - return; + case 0x00: // EventNotificationObject (manual reset) + manual_reset = true; + break; + case 0x01: // EventSynchronizationObject (auto reset) + manual_reset = false; + break; + default: + assert_always(); + return; } bool initial_state = header.signal_state ? true : false; @@ -60,10 +56,9 @@ int32_t XEvent::Pulse(uint32_t priority_increment, bool wait) { return PulseEvent(handle_) ? 1 : 0; } -int32_t XEvent::Reset() { - return ResetEvent(handle_) ? 1 : 0; -} +int32_t XEvent::Reset() { return ResetEvent(handle_) ? 1 : 0; } -void XEvent::Clear() { - ResetEvent(handle_); -} +void XEvent::Clear() { ResetEvent(handle_); } + +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/objects/xevent.h b/src/xenia/kernel/objects/xevent.h index eb2b9a070..b4e944143 100644 --- a/src/xenia/kernel/objects/xevent.h +++ b/src/xenia/kernel/objects/xevent.h @@ -11,16 +11,13 @@ #define XENIA_KERNEL_XBOXKRNL_XEVENT_H_ #include - #include - namespace xe { namespace kernel { - class XEvent : public XObject { -public: + public: XEvent(KernelState* kernel_state); virtual ~XEvent(); @@ -34,13 +31,11 @@ public: virtual void* GetWaitHandle() { return handle_; } -private: + private: HANDLE handle_; }; - } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_XEVENT_H_ diff --git a/src/xenia/kernel/objects/xfile.cc b/src/xenia/kernel/objects/xfile.cc index 144d03c71..62060bb31 100644 --- a/src/xenia/kernel/objects/xfile.cc +++ b/src/xenia/kernel/objects/xfile.cc @@ -12,14 +12,11 @@ #include #include +namespace xe { +namespace kernel { -using namespace xe; -using namespace xe::kernel; - - -XFile::XFile(KernelState* kernel_state, fs::Mode mode) : - mode_(mode), position_(0), - XObject(kernel_state, kTypeFile) { +XFile::XFile(KernelState* kernel_state, fs::Mode mode) + : mode_(mode), position_(0), XObject(kernel_state, kTypeFile) { async_event_ = new XEvent(kernel_state); async_event_->Initialize(false, false); } @@ -30,9 +27,7 @@ XFile::~XFile() { async_event_->Delete(); } -void* XFile::GetWaitHandle() { - return async_event_->GetWaitHandle(); -} +void* XFile::GetWaitHandle() { return async_event_->GetWaitHandle(); } X_STATUS XFile::Read(void* buffer, size_t buffer_length, size_t byte_offset, size_t* out_bytes_read) { @@ -40,7 +35,8 @@ X_STATUS XFile::Read(void* buffer, size_t buffer_length, size_t byte_offset, // Read from current position. byte_offset = position_; } - X_STATUS result = ReadSync(buffer, buffer_length, byte_offset, out_bytes_read); + X_STATUS result = + ReadSync(buffer, buffer_length, byte_offset, out_bytes_read); if (XSUCCEEDED(result)) { position_ += *out_bytes_read; } @@ -52,7 +48,10 @@ X_STATUS XFile::Read(void* buffer, size_t buffer_length, size_t byte_offset, // Also tack on our event so that any waiters wake. request->AddWaitEvent(async_event_); position_ = byte_offset; - //return entry_->ReadAsync(buffer, buffer_length, byte_offset, request); + // return entry_->ReadAsync(buffer, buffer_length, byte_offset, request); X_STATUS result = X_STATUS_NOT_IMPLEMENTED; return result; } + +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/objects/xfile.h b/src/xenia/kernel/objects/xfile.h index e56e0b2ac..dfb2d7fe5 100644 --- a/src/xenia/kernel/objects/xfile.h +++ b/src/xenia/kernel/objects/xfile.h @@ -14,7 +14,6 @@ #include - namespace xe { namespace kernel { @@ -22,14 +21,14 @@ class XAsyncRequest; class XEvent; class XFileInfo { -public: + public: // FILE_NETWORK_OPEN_INFORMATION - uint64_t creation_time; - uint64_t last_access_time; - uint64_t last_write_time; - uint64_t change_time; - uint64_t allocation_size; - uint64_t file_length; + uint64_t creation_time; + uint64_t last_access_time; + uint64_t last_write_time; + uint64_t change_time; + uint64_t allocation_size; + uint64_t file_length; X_FILE_ATTRIBUTES attributes; void Write(uint8_t* base, uint32_t p) { @@ -40,24 +39,24 @@ public: poly::store_and_swap(base + p + 32, allocation_size); poly::store_and_swap(base + p + 40, file_length); poly::store_and_swap(base + p + 48, attributes); - poly::store_and_swap(base + p + 52, 0); // pad + poly::store_and_swap(base + p + 52, 0); // pad } }; class XDirectoryInfo { -public: + public: // FILE_DIRECTORY_INFORMATION - uint32_t next_entry_offset; - uint32_t file_index; - uint64_t creation_time; - uint64_t last_access_time; - uint64_t last_write_time; - uint64_t change_time; - uint64_t end_of_file; - uint64_t allocation_size; + uint32_t next_entry_offset; + uint32_t file_index; + uint64_t creation_time; + uint64_t last_access_time; + uint64_t last_write_time; + uint64_t change_time; + uint64_t end_of_file; + uint64_t allocation_size; X_FILE_ATTRIBUTES attributes; - uint32_t file_name_length; - char file_name[1]; + uint32_t file_name_length; + char file_name[1]; void Write(uint8_t* base, uint32_t p) { uint8_t* dst = base + p; @@ -75,7 +74,8 @@ public: poly::store_and_swap(dst + 48, info->allocation_size); poly::store_and_swap(dst + 56, info->attributes); poly::store_and_swap(dst + 60, info->file_name_length); - xe_copy_memory(dst + 64, info->file_name_length, info->file_name, info->file_name_length); + xe_copy_memory(dst + 64, info->file_name_length, info->file_name, + info->file_name_length); dst += info->next_entry_offset; src += info->next_entry_offset; } while (info->next_entry_offset != 0); @@ -85,13 +85,13 @@ static_assert_size(XDirectoryInfo, 72); // http://msdn.microsoft.com/en-us/library/windows/hardware/ff540287(v=vs.85).aspx class XVolumeInfo { -public: + public: // FILE_FS_VOLUME_INFORMATION - uint64_t creation_time; - uint32_t serial_number; - uint32_t label_length; - uint32_t supports_objects; - char label[1]; + uint64_t creation_time; + uint32_t serial_number; + uint32_t label_length; + uint32_t supports_objects; + char label[1]; void Write(uint8_t* base, uint32_t p) { uint8_t* dst = base + p; @@ -99,32 +99,35 @@ public: poly::store_and_swap(dst + 8, this->serial_number); poly::store_and_swap(dst + 12, this->label_length); poly::store_and_swap(dst + 16, this->supports_objects); - xe_copy_memory(dst + 20, this->label_length, this->label, this->label_length); + xe_copy_memory(dst + 20, this->label_length, this->label, + this->label_length); } }; static_assert_size(XVolumeInfo, 24); // http://msdn.microsoft.com/en-us/library/windows/hardware/ff540251(v=vs.85).aspx class XFileSystemAttributeInfo { -public: + public: // FILE_FS_ATTRIBUTE_INFORMATION - uint32_t attributes; - int32_t maximum_component_name_length; - uint32_t fs_name_length; - char fs_name[1]; + uint32_t attributes; + int32_t maximum_component_name_length; + uint32_t fs_name_length; + char fs_name[1]; void Write(uint8_t* base, uint32_t p) { uint8_t* dst = base + p; poly::store_and_swap(dst + 0, this->attributes); - poly::store_and_swap(dst + 4, this->maximum_component_name_length); + poly::store_and_swap(dst + 4, + this->maximum_component_name_length); poly::store_and_swap(dst + 8, this->fs_name_length); - xe_copy_memory(dst + 12, this->fs_name_length, this->fs_name, this->fs_name_length); + xe_copy_memory(dst + 12, this->fs_name_length, this->fs_name, + this->fs_name_length); } }; static_assert_size(XFileSystemAttributeInfo, 16); class XFile : public XObject { -public: + public: virtual ~XFile(); virtual const std::string& path() const = 0; @@ -148,24 +151,21 @@ public: virtual void* GetWaitHandle(); -protected: + protected: XFile(KernelState* kernel_state, fs::Mode mode); - virtual X_STATUS ReadSync( - void* buffer, size_t buffer_length, size_t byte_offset, - size_t* out_bytes_read) = 0; + virtual X_STATUS ReadSync(void* buffer, size_t buffer_length, + size_t byte_offset, size_t* out_bytes_read) = 0; -private: - fs::Mode mode_; - XEvent* async_event_; + private: + fs::Mode mode_; + XEvent* async_event_; // TODO(benvanik): create flags, open state, etc. - size_t position_; + size_t position_; }; - } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_XFILE_H_ diff --git a/src/xenia/kernel/objects/xkernel_module.cc b/src/xenia/kernel/objects/xkernel_module.cc index d5419f2fc..e9444d7e9 100644 --- a/src/xenia/kernel/objects/xkernel_module.cc +++ b/src/xenia/kernel/objects/xkernel_module.cc @@ -13,14 +13,11 @@ #include #include +namespace xe { +namespace kernel { -using namespace xe; -using namespace xe::cpu; -using namespace xe::kernel; - - -XKernelModule::XKernelModule(KernelState* kernel_state, const char* path) : - XModule(kernel_state, path) { +XKernelModule::XKernelModule(KernelState* kernel_state, const char* path) + : XModule(kernel_state, path) { emulator_ = kernel_state->emulator(); memory_ = emulator_->memory(); export_resolver_ = kernel_state->emulator()->export_resolver(); @@ -28,11 +25,13 @@ XKernelModule::XKernelModule(KernelState* kernel_state, const char* path) : OnLoad(); } -XKernelModule::~XKernelModule() { -} +XKernelModule::~XKernelModule() {} void* XKernelModule::GetProcAddressByOrdinal(uint16_t ordinal) { // TODO(benvanik): check export tables. XELOGE("GetProcAddressByOrdinal not implemented"); return NULL; } + +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/objects/xkernel_module.h b/src/xenia/kernel/objects/xkernel_module.h index 07d3d86b4..6b8c6980f 100644 --- a/src/xenia/kernel/objects/xkernel_module.h +++ b/src/xenia/kernel/objects/xkernel_module.h @@ -14,29 +14,26 @@ XEDECLARECLASS1(xe, Emulator); XEDECLARECLASS1(xe, ExportResolver); -XEDECLARECLASS2(xe, kernel, KernelState); - namespace xe { namespace kernel { +class KernelState; class XKernelModule : public XModule { -public: + public: XKernelModule(KernelState* kernel_state, const char* path); virtual ~XKernelModule(); virtual void* GetProcAddressByOrdinal(uint16_t ordinal); -protected: - Emulator* emulator_; - Memory* memory_; - ExportResolver* export_resolver_; + protected: + Emulator* emulator_; + Memory* memory_; + ExportResolver* export_resolver_; }; - } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_XKERNEL_MODULE_H_ diff --git a/src/xenia/kernel/objects/xmodule.cc b/src/xenia/kernel/objects/xmodule.cc index 406534556..aea7198f9 100644 --- a/src/xenia/kernel/objects/xmodule.cc +++ b/src/xenia/kernel/objects/xmodule.cc @@ -11,14 +11,11 @@ #include +namespace xe { +namespace kernel { -using namespace xe; -using namespace xe::cpu; -using namespace xe::kernel; - - -XModule::XModule(KernelState* kernel_state, const std::string& path) : - XObject(kernel_state, kTypeModule), path_(path) { +XModule::XModule(KernelState* kernel_state, const std::string& path) + : XObject(kernel_state, kTypeModule), path_(path) { auto last_slash = path.find_last_of('/'); if (last_slash == path.npos) { last_slash = path.find_last_of('\\'); @@ -54,8 +51,10 @@ void XModule::OnLoad() { kernel_state_->RegisterModule(this); } -X_STATUS XModule::GetSection( - const char* name, - uint32_t* out_section_data, uint32_t* out_section_size) { +X_STATUS XModule::GetSection(const char* name, uint32_t* out_section_data, + uint32_t* out_section_size) { return X_STATUS_UNSUCCESSFUL; } + +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/objects/xmodule.h b/src/xenia/kernel/objects/xmodule.h index 1af9e3ea8..dd5743684 100644 --- a/src/xenia/kernel/objects/xmodule.h +++ b/src/xenia/kernel/objects/xmodule.h @@ -13,16 +13,13 @@ #include #include - #include - namespace xe { namespace kernel { - class XModule : public XObject { -public: + public: XModule(KernelState* kernel_state, const std::string& path); virtual ~XModule(); @@ -30,20 +27,17 @@ public: const std::string& name() const { return name_; } virtual void* GetProcAddressByOrdinal(uint16_t ordinal) = 0; - virtual X_STATUS GetSection( - const char* name, - uint32_t* out_section_data, uint32_t* out_section_size); + virtual X_STATUS GetSection(const char* name, uint32_t* out_section_data, + uint32_t* out_section_size); -protected: + protected: void OnLoad(); std::string name_; std::string path_; }; - } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_XMODULE_H_ diff --git a/src/xenia/kernel/objects/xmutant.cc b/src/xenia/kernel/objects/xmutant.cc index 99eecc04a..b915f314e 100644 --- a/src/xenia/kernel/objects/xmutant.cc +++ b/src/xenia/kernel/objects/xmutant.cc @@ -9,15 +9,11 @@ #include +namespace xe { +namespace kernel { -using namespace xe; -using namespace xe::kernel; - - -XMutant::XMutant(KernelState* kernel_state) : - XObject(kernel_state, kTypeMutant), - handle_(NULL) { -} +XMutant::XMutant(KernelState* kernel_state) + : XObject(kernel_state, kTypeMutant), handle_(NULL) {} XMutant::~XMutant() { if (handle_) { @@ -38,8 +34,8 @@ void XMutant::InitializeNative(void* native_ptr, DISPATCH_HEADER& header) { assert_always(); } -X_STATUS XMutant::ReleaseMutant( - uint32_t priority_increment, bool abandon, bool wait) { +X_STATUS XMutant::ReleaseMutant(uint32_t priority_increment, bool abandon, + bool wait) { // TODO(benvanik): abandoning. assert_false(abandon); BOOL result = ReleaseMutex(handle_); @@ -49,3 +45,6 @@ X_STATUS XMutant::ReleaseMutant( return X_STATUS_MUTANT_NOT_OWNED; } } + +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/objects/xmutant.h b/src/xenia/kernel/objects/xmutant.h index f66a95572..be554676c 100644 --- a/src/xenia/kernel/objects/xmutant.h +++ b/src/xenia/kernel/objects/xmutant.h @@ -11,16 +11,13 @@ #define XENIA_KERNEL_XBOXKRNL_XMUTANT_H_ #include - #include - namespace xe { namespace kernel { - class XMutant : public XObject { -public: + public: XMutant(KernelState* kernel_state); virtual ~XMutant(); @@ -31,13 +28,11 @@ public: virtual void* GetWaitHandle() { return handle_; } -private: + private: HANDLE handle_; }; - } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_XMUTANT_H_ diff --git a/src/xenia/kernel/objects/xnotify_listener.cc b/src/xenia/kernel/objects/xnotify_listener.cc index 9de2224ea..738a5440d 100644 --- a/src/xenia/kernel/objects/xnotify_listener.cc +++ b/src/xenia/kernel/objects/xnotify_listener.cc @@ -9,15 +9,14 @@ #include +namespace xe { +namespace kernel { -using namespace xe; -using namespace xe::kernel; - - -XNotifyListener::XNotifyListener(KernelState* kernel_state) : - XObject(kernel_state, kTypeNotifyListener), - wait_handle_(NULL), mask_(0), notification_count_(0) { -} +XNotifyListener::XNotifyListener(KernelState* kernel_state) + : XObject(kernel_state, kTypeNotifyListener), + wait_handle_(NULL), + mask_(0), + notification_count_(0) {} XNotifyListener::~XNotifyListener() { kernel_state_->UnregisterNotifyListener(this); @@ -48,13 +47,13 @@ void XNotifyListener::EnqueueNotification(XNotificationID id, uint32_t data) { } else { // New. notification_count_++; - notifications_.insert({ id, data }); + notifications_.insert({id, data}); } SetEvent(wait_handle_); } -bool XNotifyListener::DequeueNotification( - XNotificationID* out_id, uint32_t* out_data) { +bool XNotifyListener::DequeueNotification(XNotificationID* out_id, + uint32_t* out_data) { std::lock_guard lock(lock_); bool dequeued = false; if (notification_count_) { @@ -71,8 +70,8 @@ bool XNotifyListener::DequeueNotification( return dequeued; } -bool XNotifyListener::DequeueNotification( - XNotificationID id, uint32_t* out_data) { +bool XNotifyListener::DequeueNotification(XNotificationID id, + uint32_t* out_data) { std::lock_guard lock(lock_); bool dequeued = false; if (notification_count_) { @@ -89,3 +88,6 @@ bool XNotifyListener::DequeueNotification( } return dequeued; } + +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/objects/xnotify_listener.h b/src/xenia/kernel/objects/xnotify_listener.h index 7a7fc6e6a..7f92f6675 100644 --- a/src/xenia/kernel/objects/xnotify_listener.h +++ b/src/xenia/kernel/objects/xnotify_listener.h @@ -7,25 +7,19 @@ ****************************************************************************** */ -// This should probably be in XAM, but I don't want to build an extensible -// object system. Meh. - #ifndef XENIA_KERNEL_XBOXKRNL_XNOTIFY_LISTENER_H_ #define XENIA_KERNEL_XBOXKRNL_XNOTIFY_LISTENER_H_ #include #include - #include - namespace xe { namespace kernel { - class XNotifyListener : public XObject { -public: + public: XNotifyListener(KernelState* kernel_state); virtual ~XNotifyListener(); @@ -37,7 +31,7 @@ public: virtual void* GetWaitHandle() { return wait_handle_; } -private: + private: HANDLE wait_handle_; std::mutex lock_; std::unordered_map notifications_; @@ -45,9 +39,7 @@ private: uint64_t mask_; }; - } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_XNOTIFY_LISTENER_H_ diff --git a/src/xenia/kernel/objects/xsemaphore.cc b/src/xenia/kernel/objects/xsemaphore.cc index c0594e8a2..c8aba8ce3 100644 --- a/src/xenia/kernel/objects/xsemaphore.cc +++ b/src/xenia/kernel/objects/xsemaphore.cc @@ -9,15 +9,11 @@ #include +namespace xe { +namespace kernel { -using namespace xe; -using namespace xe::kernel; - - -XSemaphore::XSemaphore(KernelState* kernel_state) : - XObject(kernel_state, kTypeSemaphore), - handle_(NULL) { -} +XSemaphore::XSemaphore(KernelState* kernel_state) + : XObject(kernel_state, kTypeSemaphore), handle_(NULL) {} XSemaphore::~XSemaphore() { if (handle_) { @@ -43,3 +39,6 @@ int32_t XSemaphore::ReleaseSemaphore(int32_t release_count) { ::ReleaseSemaphore(handle_, release_count, &previous_count); return previous_count; } + +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/objects/xsemaphore.h b/src/xenia/kernel/objects/xsemaphore.h index 1d58d1de1..43fb13e3d 100644 --- a/src/xenia/kernel/objects/xsemaphore.h +++ b/src/xenia/kernel/objects/xsemaphore.h @@ -11,16 +11,13 @@ #define XENIA_KERNEL_XBOXKRNL_XSEMAPHORE_H_ #include - #include - namespace xe { namespace kernel { - class XSemaphore : public XObject { -public: + public: XSemaphore(KernelState* kernel_state); virtual ~XSemaphore(); @@ -31,13 +28,11 @@ public: virtual void* GetWaitHandle() { return handle_; } -private: + private: HANDLE handle_; }; - } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_XSEMAPHORE_H_ diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index 65e5cb712..8bef9479a 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -16,41 +16,34 @@ #include #include +namespace xe { +namespace kernel { -using namespace alloy; -using namespace xe; using namespace xe::cpu; -using namespace xe::kernel; +uint32_t next_xthread_id = 0; +thread_local XThread* current_thread_tls; +std::mutex critical_region_; +XThread* shared_kernel_thread_ = 0; -namespace { - static uint32_t next_xthread_id = 0; - static thread_local XThread* current_thread_tls; - static std::mutex critical_region_; - static XThread* shared_kernel_thread_ = 0; -} - - -XThread::XThread(KernelState* kernel_state, - uint32_t stack_size, - uint32_t xapi_thread_startup, - uint32_t start_address, uint32_t start_context, - uint32_t creation_flags) : - XObject(kernel_state, kTypeThread), - thread_id_(++next_xthread_id), - thread_handle_(0), - thread_state_address_(0), - thread_state_(0), - event_(NULL), - irql_(0) { - creation_params_.stack_size = stack_size; - creation_params_.xapi_thread_startup = xapi_thread_startup; - creation_params_.start_address = start_address; - creation_params_.start_context = start_context; +XThread::XThread(KernelState* kernel_state, uint32_t stack_size, + uint32_t xapi_thread_startup, uint32_t start_address, + uint32_t start_context, uint32_t creation_flags) + : XObject(kernel_state, kTypeThread), + thread_id_(++next_xthread_id), + thread_handle_(0), + thread_state_address_(0), + thread_state_(0), + event_(NULL), + irql_(0) { + creation_params_.stack_size = stack_size; + creation_params_.xapi_thread_startup = xapi_thread_startup; + creation_params_.start_address = start_address; + creation_params_.start_context = start_context; // top 8 bits = processor ID (or 0 for default) // bit 0 = 1 to create suspended - creation_params_.creation_flags = creation_flags; + creation_params_.creation_flags = creation_flags; // Adjust stack size - min of 16k. if (creation_params_.stack_size < 16 * 1024) { @@ -108,8 +101,7 @@ XThread* XThread::GetCurrentThread() { XThread::EnterCriticalRegion(); thread = shared_kernel_thread_; if (!thread) { - thread = new XThread( - KernelState::shared(), 32 * 1024, 0, 0, 0, 0); + thread = new XThread(KernelState::shared(), 32 * 1024, 0, 0, 0, 0); shared_kernel_thread_ = thread; current_thread_tls = thread; } @@ -127,21 +119,17 @@ uint32_t XThread::GetCurrentThreadId(const uint8_t* thread_state_block) { return poly::load_and_swap(thread_state_block + 0x14C); } -uint32_t XThread::thread_state() { - return thread_state_address_; -} +uint32_t XThread::thread_state() { return thread_state_address_; } -uint32_t XThread::thread_id() { - return thread_id_; -} +uint32_t XThread::thread_id() { return thread_id_; } uint32_t XThread::last_error() { - uint8_t *p = memory()->Translate(thread_state_address_); + uint8_t* p = memory()->Translate(thread_state_address_); return poly::load_and_swap(p + 0x160); } void XThread::set_last_error(uint32_t error_code) { - uint8_t *p = memory()->Translate(thread_state_address_); + uint8_t* p = memory()->Translate(thread_state_address_); poly::store_and_swap(p + 0x160, error_code); } @@ -163,8 +151,8 @@ X_STATUS XThread::Create() { // 0x160: last error // So, at offset 0x100 we have a 4b pointer to offset 200, then have the // structure. - thread_state_address_ = (uint32_t)memory()->HeapAlloc( - 0, 2048, MEMORY_FLAG_ZERO); + thread_state_address_ = + (uint32_t)memory()->HeapAlloc(0, 2048, alloy::MEMORY_FLAG_ZERO); if (!thread_state_address_) { XELOGW("Unable to allocate thread state block"); return X_STATUS_NO_MEMORY; @@ -178,14 +166,14 @@ X_STATUS XThread::Create() { // Allocate thread scratch. // This is used by interrupts/APCs/etc so we can round-trip pointers through. scratch_size_ = 4 * 16; - scratch_address_ = (uint32_t)memory()->HeapAlloc( - 0, scratch_size_, MEMORY_FLAG_ZERO); + scratch_address_ = + (uint32_t)memory()->HeapAlloc(0, scratch_size_, alloy::MEMORY_FLAG_ZERO); // Allocate TLS block. const xe_xex2_header_t* header = module->xex_header(); uint32_t tls_size = header->tls_info.slot_count * header->tls_info.data_size; - tls_address_ = (uint32_t)memory()->HeapAlloc( - 0, tls_size, MEMORY_FLAG_ZERO); + tls_address_ = + (uint32_t)memory()->HeapAlloc(0, tls_size, alloy::MEMORY_FLAG_ZERO); if (!tls_address_) { XELOGW("Unable to allocate thread local storage block"); module->Release(); @@ -194,22 +182,21 @@ X_STATUS XThread::Create() { // Copy in default TLS info. // TODO(benvanik): is this correct? - memory()->Copy( - tls_address_, header->tls_info.raw_data_address, tls_size); + memory()->Copy(tls_address_, header->tls_info.raw_data_address, tls_size); // Setup the thread state block (last error/etc). - uint8_t *p = memory()->Translate(thread_state_address_); + uint8_t* p = memory()->Translate(thread_state_address_); poly::store_and_swap(p + 0x000, tls_address_); poly::store_and_swap(p + 0x100, thread_state_address_); poly::store_and_swap(p + 0x14C, thread_id_); - poly::store_and_swap(p + 0x150, 0); // ? - poly::store_and_swap(p + 0x160, 0); // last error + poly::store_and_swap(p + 0x150, 0); // ? + poly::store_and_swap(p + 0x160, 0); // last error // Allocate processor thread state. // This is thread safe. - thread_state_ = new XenonThreadState( - kernel_state()->processor()->runtime(), - thread_id_, creation_params_.stack_size, thread_state_address_); + thread_state_ = + new XenonThreadState(kernel_state()->processor()->runtime(), thread_id_, + creation_params_.stack_size, thread_state_address_); X_STATUS return_code = PlatformCreate(); if (XFAILED(return_code)) { @@ -268,13 +255,10 @@ static uint32_t __stdcall XThreadStartCallbackWin32(void* param) { X_STATUS XThread::PlatformCreate() { bool suspended = creation_params_.creation_flags & 0x1; - thread_handle_ = CreateThread( - NULL, - creation_params_.stack_size, - (LPTHREAD_START_ROUTINE)XThreadStartCallbackWin32, - this, - suspended ? CREATE_SUSPENDED : 0, - NULL); + thread_handle_ = + CreateThread(NULL, creation_params_.stack_size, + (LPTHREAD_START_ROUTINE)XThreadStartCallbackWin32, this, + suspended ? CREATE_SUSPENDED : 0, NULL); if (!thread_handle_) { uint32_t last_error = GetLastError(); // TODO(benvanik): translate? @@ -319,20 +303,15 @@ X_STATUS XThread::PlatformCreate() { if (creation_params_.creation_flags & 0x1) { #if XE_PLATFORM_OSX result_code = pthread_create_suspended_np( - reinterpret_cast(&thread_handle_), - &attr, - &XThreadStartCallbackPthreads, - this); + reinterpret_cast(&thread_handle_), &attr, + &XThreadStartCallbackPthreads, this); #else // TODO(benvanik): pthread_create_suspended_np on linux assert_always(); #endif // OSX } else { - result_code = pthread_create( - reinterpret_cast(&thread_handle_), - &attr, - &XThreadStartCallbackPthreads, - this); + result_code = pthread_create(reinterpret_cast(&thread_handle_), + &attr, &XThreadStartCallbackPthreads, this); } pthread_attr_destroy(&attr); @@ -389,28 +368,21 @@ void XThread::EnterCriticalRegion() { critical_region_.lock(); } -void XThread::LeaveCriticalRegion() { - critical_region_.unlock(); -} +void XThread::LeaveCriticalRegion() { critical_region_.unlock(); } uint32_t XThread::RaiseIrql(uint32_t new_irql) { return irql_.exchange(new_irql); } -void XThread::LowerIrql(uint32_t new_irql) { - irql_ = new_irql; -} +void XThread::LowerIrql(uint32_t new_irql) { irql_ = new_irql; } -void XThread::LockApc() { - apc_lock_.lock(); -} +void XThread::LockApc() { apc_lock_.lock(); } void XThread::UnlockApc() { bool needs_apc = apc_list_->HasPending(); apc_lock_.unlock(); if (needs_apc) { - QueueUserAPC(reinterpret_cast(DeliverAPCs), - thread_handle_, + QueueUserAPC(reinterpret_cast(DeliverAPCs), thread_handle_, reinterpret_cast(this)); } } @@ -447,16 +419,15 @@ void XThread::DeliverAPCs(void* data) { poly::store_and_swap(scratch_ptr + 4, normal_context); poly::store_and_swap(scratch_ptr + 8, system_arg1); poly::store_and_swap(scratch_ptr + 12, system_arg2); - // kernel_routine(apc_address, &normal_routine, &normal_context, &system_arg1, &system_arg2) + // kernel_routine(apc_address, &normal_routine, &normal_context, + // &system_arg1, &system_arg2) uint64_t kernel_args[] = { - apc_address, - thread->scratch_address_ + 0, - thread->scratch_address_ + 4, - thread->scratch_address_ + 8, - thread->scratch_address_ + 12, + apc_address, thread->scratch_address_ + 0, + thread->scratch_address_ + 4, thread->scratch_address_ + 8, + thread->scratch_address_ + 12, }; - processor->ExecuteInterrupt( - 0, kernel_routine, kernel_args, poly::countof(kernel_args)); + processor->ExecuteInterrupt(0, kernel_routine, kernel_args, + poly::countof(kernel_args)); normal_routine = poly::load_and_swap(scratch_ptr + 0); normal_context = poly::load_and_swap(scratch_ptr + 4); system_arg1 = poly::load_and_swap(scratch_ptr + 8); @@ -467,9 +438,9 @@ void XThread::DeliverAPCs(void* data) { if (normal_routine) { thread->UnlockApc(); // normal_routine(normal_context, system_arg1, system_arg2) - uint64_t normal_args[] = { normal_context, system_arg1, system_arg2 }; - processor->ExecuteInterrupt( - 0, normal_routine, normal_args, poly::countof(normal_args)); + uint64_t normal_args[] = {normal_context, system_arg1, system_arg2}; + processor->ExecuteInterrupt(0, normal_routine, normal_args, + poly::countof(normal_args)); thread->LockApc(); } } @@ -493,17 +464,15 @@ void XThread::RundownAPCs() { // Call the rundown routine. if (rundown_routine) { // rundown_routine(apc) - uint64_t args[] = { apc_address }; - kernel_state()->processor()->ExecuteInterrupt( - 0, rundown_routine, args, poly::countof(args)); + uint64_t args[] = {apc_address}; + kernel_state()->processor()->ExecuteInterrupt(0, rundown_routine, args, + poly::countof(args)); } } UnlockApc(); } -int32_t XThread::QueryPriority() { - return GetThreadPriority(thread_handle_); -} +int32_t XThread::QueryPriority() { return GetThreadPriority(thread_handle_); } void XThread::SetPriority(int32_t increment) { SetThreadPriority(thread_handle_, increment); @@ -538,8 +507,8 @@ X_STATUS XThread::Suspend(uint32_t* out_suspend_count) { } } -X_STATUS XThread::Delay( - uint32_t processor_mode, uint32_t alertable, uint64_t interval) { +X_STATUS XThread::Delay(uint32_t processor_mode, uint32_t alertable, + uint64_t interval) { int64_t timeout_ticks = interval; DWORD timeout_ms; if (timeout_ticks > 0) { @@ -549,21 +518,22 @@ X_STATUS XThread::Delay( timeout_ms = 0; } else if (timeout_ticks < 0) { // Relative time. - timeout_ms = (DWORD)(-timeout_ticks / 10000); // Ticks -> MS + timeout_ms = (DWORD)(-timeout_ticks / 10000); // Ticks -> MS } else { timeout_ms = 0; } DWORD result = SleepEx(timeout_ms, alertable ? TRUE : FALSE); switch (result) { - case 0: - return X_STATUS_SUCCESS; - case WAIT_IO_COMPLETION: - return X_STATUS_USER_APC; - default: - return X_STATUS_ALERTED; + case 0: + return X_STATUS_SUCCESS; + case WAIT_IO_COMPLETION: + return X_STATUS_USER_APC; + default: + return X_STATUS_ALERTED; } } -void* XThread::GetWaitHandle() { - return event_->GetWaitHandle(); -} +void* XThread::GetWaitHandle() { return event_->GetWaitHandle(); } + +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/objects/xthread.h b/src/xenia/kernel/objects/xthread.h index 591a41b19..3d7e9da22 100644 --- a/src/xenia/kernel/objects/xthread.h +++ b/src/xenia/kernel/objects/xthread.h @@ -15,26 +15,21 @@ #include #include - #include XEDECLARECLASS2(xe, cpu, XenonThreadState); - namespace xe { namespace kernel { class NativeList; class XEvent; - class XThread : public XObject { -public: - XThread(KernelState* kernel_state, - uint32_t stack_size, - uint32_t xapi_thread_startup, - uint32_t start_address, uint32_t start_context, - uint32_t creation_flags); + public: + XThread(KernelState* kernel_state, uint32_t stack_size, + uint32_t xapi_thread_startup, uint32_t start_address, + uint32_t start_context, uint32_t creation_flags); virtual ~XThread(); static XThread* GetCurrentThread(); @@ -68,12 +63,12 @@ public: X_STATUS Resume(uint32_t* out_suspend_count); X_STATUS Suspend(uint32_t* out_suspend_count); - X_STATUS Delay( - uint32_t processor_mode, uint32_t alertable, uint64_t interval); + X_STATUS Delay(uint32_t processor_mode, uint32_t alertable, + uint64_t interval); virtual void* GetWaitHandle(); -private: + private: X_STATUS PlatformCreate(); void PlatformDestroy(); X_STATUS PlatformExit(int exit_code); @@ -82,33 +77,31 @@ private: void RundownAPCs(); struct { - uint32_t stack_size; - uint32_t xapi_thread_startup; - uint32_t start_address; - uint32_t start_context; - uint32_t creation_flags; + uint32_t stack_size; + uint32_t xapi_thread_startup; + uint32_t start_address; + uint32_t start_context; + uint32_t creation_flags; } creation_params_; - uint32_t thread_id_; - void* thread_handle_; - uint32_t scratch_address_; - uint32_t scratch_size_; - uint32_t tls_address_; - uint32_t thread_state_address_; + uint32_t thread_id_; + void* thread_handle_; + uint32_t scratch_address_; + uint32_t scratch_size_; + uint32_t tls_address_; + uint32_t thread_state_address_; cpu::XenonThreadState* thread_state_; - std::string name_; + std::string name_; std::atomic irql_; std::mutex apc_lock_; - NativeList* apc_list_; + NativeList* apc_list_; - XEvent* event_; + XEvent* event_; }; - } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_XTHREAD_H_ diff --git a/src/xenia/kernel/objects/xtimer.cc b/src/xenia/kernel/objects/xtimer.cc index 70c8bdd90..09c5a3282 100644 --- a/src/xenia/kernel/objects/xtimer.cc +++ b/src/xenia/kernel/objects/xtimer.cc @@ -11,15 +11,11 @@ #include +namespace xe { +namespace kernel { -using namespace xe; -using namespace xe::kernel; - - -XTimer::XTimer(KernelState* kernel_state) : - XObject(kernel_state, kTypeTimer), - handle_(NULL) { -} +XTimer::XTimer(KernelState* kernel_state) + : XObject(kernel_state, kTypeTimer), handle_(NULL) {} XTimer::~XTimer() { if (handle_) { @@ -32,33 +28,32 @@ void XTimer::Initialize(uint32_t timer_type) { bool manual_reset = false; switch (timer_type) { - case 0: // NotificationTimer - manual_reset = true; - break; - case 1: // SynchronizationTimer - manual_reset = false; - break; - default: - assert_always(); - break; + case 0: // NotificationTimer + manual_reset = true; + break; + case 1: // SynchronizationTimer + manual_reset = false; + break; + default: + assert_always(); + break; } handle_ = CreateWaitableTimer(NULL, manual_reset, NULL); } -X_STATUS XTimer::SetTimer( - int64_t due_time, uint32_t period_ms, - uint32_t routine, uint32_t routine_arg, bool resume) { +X_STATUS XTimer::SetTimer(int64_t due_time, uint32_t period_ms, + uint32_t routine, uint32_t routine_arg, bool resume) { // Stash routine for callback. current_routine_ = routine; current_routine_arg_ = routine_arg; LARGE_INTEGER due_time_li; due_time_li.QuadPart = due_time; - BOOL result = SetWaitableTimer( - handle_, &due_time_li, period_ms, - routine ? (PTIMERAPCROUTINE)CompletionRoutine : NULL, this, - resume ? TRUE : FALSE); + BOOL result = + SetWaitableTimer(handle_, &due_time_li, period_ms, + routine ? (PTIMERAPCROUTINE)CompletionRoutine : NULL, + this, resume ? TRUE : FALSE); // Caller is checking for STATUS_TIMER_RESUME_IGNORED. // This occurs if result == TRUE but error is set. @@ -69,8 +64,8 @@ X_STATUS XTimer::SetTimer( return result ? X_STATUS_SUCCESS : X_STATUS_UNSUCCESSFUL; } -void XTimer::CompletionRoutine( - XTimer* timer, DWORD timer_low, DWORD timer_high) { +void XTimer::CompletionRoutine(XTimer* timer, DWORD timer_low, + DWORD timer_high) { assert_true(timer->current_routine_); // Queue APC to call back routine with (arg, low, high). @@ -81,6 +76,9 @@ void XTimer::CompletionRoutine( } X_STATUS XTimer::Cancel() { - return CancelWaitableTimer(handle_) == 0 ? - X_STATUS_SUCCESS : X_STATUS_UNSUCCESSFUL; + return CancelWaitableTimer(handle_) == 0 ? X_STATUS_SUCCESS + : X_STATUS_UNSUCCESSFUL; } + +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/objects/xtimer.h b/src/xenia/kernel/objects/xtimer.h index 586c45e41..3b52cd2fc 100644 --- a/src/xenia/kernel/objects/xtimer.h +++ b/src/xenia/kernel/objects/xtimer.h @@ -11,41 +11,36 @@ #define XENIA_KERNEL_XBOXKRNL_XTIMER_H_ #include - #include - namespace xe { namespace kernel { - class XTimer : public XObject { -public: + public: XTimer(KernelState* kernel_state); virtual ~XTimer(); void Initialize(uint32_t timer_type); // completion routine, arg to completion routine - X_STATUS SetTimer(int64_t due_time, uint32_t period_ms, - uint32_t routine, uint32_t routine_arg, bool resume); + X_STATUS SetTimer(int64_t due_time, uint32_t period_ms, uint32_t routine, + uint32_t routine_arg, bool resume); X_STATUS Cancel(); virtual void* GetWaitHandle() { return handle_; } -private: + private: HANDLE handle_; uint32_t current_routine_; uint32_t current_routine_arg_; - static void CompletionRoutine( - XTimer* timer, DWORD timer_low, DWORD timer_high); + static void CompletionRoutine(XTimer* timer, DWORD timer_low, + DWORD timer_high); }; - } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_TIMER_H_ diff --git a/src/xenia/kernel/objects/xuser_module.cc b/src/xenia/kernel/objects/xuser_module.cc index cee332f9a..65e82337c 100644 --- a/src/xenia/kernel/objects/xuser_module.cc +++ b/src/xenia/kernel/objects/xuser_module.cc @@ -14,24 +14,17 @@ #include #include +namespace xe { +namespace kernel { -using namespace xe; using namespace xe::cpu; -using namespace xe::kernel; +XUserModule::XUserModule(KernelState* kernel_state, const char* path) + : XModule(kernel_state, path), xex_(NULL) {} -XUserModule::XUserModule(KernelState* kernel_state, const char* path) : - XModule(kernel_state, path), - xex_(NULL) { -} +XUserModule::~XUserModule() { xe_xex2_release(xex_); } -XUserModule::~XUserModule() { - xe_xex2_release(xex_); -} - -xe_xex2_ref XUserModule::xex() { - return xe_xex2_retain(xex_); -} +xe_xex2_ref XUserModule::xex() { return xe_xex2_retain(xex_); } const xe_xex2_header_t* XUserModule::xex_header() { return xe_xex2_get_header(xex_); @@ -134,9 +127,8 @@ void* XUserModule::GetProcAddressByOrdinal(uint16_t ordinal) { return NULL; } -X_STATUS XUserModule::GetSection( - const char* name, - uint32_t* out_section_data, uint32_t* out_section_size) { +X_STATUS XUserModule::GetSection(const char* name, uint32_t* out_section_data, + uint32_t* out_section_size) { auto header = xe_xex2_get_header(xex_); for (size_t n = 0; n < header->resource_info_count; n++) { auto& res = header->resource_infos[n]; @@ -158,12 +150,8 @@ X_STATUS XUserModule::Launch(uint32_t flags) { Dump(); // Create a thread to run in. - XThread* thread = new XThread( - kernel_state(), - header->exe_stack_size, - 0, - header->exe_entry_point, NULL, - 0); + XThread* thread = new XThread(kernel_state(), header->exe_stack_size, 0, + header->exe_entry_point, NULL, 0); X_STATUS result = thread->Create(); if (XFAILED(result)) { @@ -196,11 +184,10 @@ void XUserModule::Dump() { printf("\n"); printf(" Execution Info:\n"); printf(" Media ID: %.8X\n", header->execution_info.media_id); - printf(" Version: %d.%d.%d.%d\n", - header->execution_info.version.major, - header->execution_info.version.minor, - header->execution_info.version.build, - header->execution_info.version.qfe); + printf( + " Version: %d.%d.%d.%d\n", header->execution_info.version.major, + header->execution_info.version.minor, + header->execution_info.version.build, header->execution_info.version.qfe); printf(" Base Version: %d.%d.%d.%d\n", header->execution_info.base_version.major, header->execution_info.base_version.minor, @@ -222,14 +209,14 @@ void XUserModule::Dump() { printf(" Slot Count: %d\n", header->tls_info.slot_count); printf(" Data Size: %db\n", header->tls_info.data_size); printf(" Address: %.8X, %db\n", header->tls_info.raw_data_address, - header->tls_info.raw_data_size); + header->tls_info.raw_data_size); printf("\n"); printf(" Headers:\n"); for (size_t n = 0; n < header->header_count; n++) { const xe_xex2_opt_header_t* opt_header = &header->headers[n]; - printf(" %.8X (%.8X, %4db) %.8X = %11d\n", - opt_header->key, opt_header->offset, opt_header->length, - opt_header->value, opt_header->value); + printf(" %.8X (%.8X, %4db) %.8X = %11d\n", opt_header->key, + opt_header->offset, opt_header->length, opt_header->value, + opt_header->value); } printf("\n"); @@ -237,8 +224,8 @@ void XUserModule::Dump() { printf("Resources:\n"); for (size_t n = 0; n < header->resource_info_count; n++) { auto& res = header->resource_infos[n]; - printf(" %-8s %.8X-%.8X, %db\n", - res.name, res.address, res.address + res.size, res.size); + printf(" %-8s %.8X-%.8X, %db\n", res.name, res.address, + res.address + res.size, res.size); } printf("\n"); @@ -248,23 +235,23 @@ void XUserModule::Dump() { const xe_xex2_section_t* section = &header->sections[n]; const char* type = "UNKNOWN"; switch (section->info.type) { - case XEX_SECTION_CODE: - type = "CODE "; - break; - case XEX_SECTION_DATA: - type = "RWDATA "; - break; - case XEX_SECTION_READONLY_DATA: - type = "RODATA "; - break; + case XEX_SECTION_CODE: + type = "CODE "; + break; + case XEX_SECTION_DATA: + type = "RWDATA "; + break; + case XEX_SECTION_READONLY_DATA: + type = "RODATA "; + break; } const size_t start_address = header->exe_address + (i * xe_xex2_section_length); const size_t end_address = start_address + (section->info.page_count * xe_xex2_section_length); - printf(" %3d %s %3d pages %.8X - %.8X (%d bytes)\n", - (int)n, type, section->info.page_count, (int)start_address, - (int)end_address, section->info.page_count * xe_xex2_section_length); + printf(" %3d %s %3d pages %.8X - %.8X (%d bytes)\n", (int)n, type, + section->info.page_count, (int)start_address, (int)end_address, + section->info.page_count * xe_xex2_section_length); i += section->info.page_count; } printf("\n"); @@ -272,9 +259,8 @@ void XUserModule::Dump() { // Static libraries. printf("Static Libraries:\n"); for (size_t n = 0; n < header->static_library_count; n++) { - const xe_xex2_static_library_t *library = &header->static_libraries[n]; - printf(" %-8s : %d.%d.%d.%d\n", - library->name, library->major, + const xe_xex2_static_library_t* library = &header->static_libraries[n]; + printf(" %-8s : %d.%d.%d.%d\n", library->name, library->major, library->minor, library->build, library->qfe); } printf("\n"); @@ -286,15 +272,15 @@ void XUserModule::Dump() { xe_xex2_import_info_t* import_infos; size_t import_info_count; - if (!xe_xex2_get_import_infos(xex_, library, - &import_infos, &import_info_count)) { + if (!xe_xex2_get_import_infos(xex_, library, &import_infos, + &import_info_count)) { printf(" %s - %d imports\n", library->name, (int)import_info_count); - printf(" Version: %d.%d.%d.%d\n", - library->version.major, library->version.minor, - library->version.build, library->version.qfe); - printf(" Min Version: %d.%d.%d.%d\n", - library->min_version.major, library->min_version.minor, - library->min_version.build, library->min_version.qfe); + printf(" Version: %d.%d.%d.%d\n", library->version.major, + library->version.minor, library->version.build, + library->version.qfe); + printf(" Min Version: %d.%d.%d.%d\n", library->min_version.major, + library->min_version.minor, library->min_version.build, + library->min_version.qfe); printf("\n"); // Counts. @@ -323,30 +309,28 @@ void XUserModule::Dump() { (int)(known_count / (float)import_info_count * 100.0f), known_count, unknown_count); printf(" Implemented: %3d%% (%d implemented, %d unimplemented)\n", - (int)(impl_count / (float)import_info_count * 100.0f), - impl_count, unimpl_count); + (int)(impl_count / (float)import_info_count * 100.0f), impl_count, + unimpl_count); printf("\n"); // Listing. for (size_t m = 0; m < import_info_count; m++) { const xe_xex2_import_info_t* info = &import_infos[m]; - KernelExport* kernel_export = export_resolver->GetExportByOrdinal( - library->name, info->ordinal); - const char *name = "UNKNOWN"; + KernelExport* kernel_export = + export_resolver->GetExportByOrdinal(library->name, info->ordinal); + const char* name = "UNKNOWN"; bool implemented = false; if (kernel_export) { name = kernel_export->name; implemented = kernel_export->is_implemented; } if (kernel_export && kernel_export->type == KernelExport::Variable) { - printf(" V %.8X %.3X (%3d) %s %s\n", - info->value_address, info->ordinal, info->ordinal, - implemented ? " " : "!!", name); + printf(" V %.8X %.3X (%3d) %s %s\n", info->value_address, + info->ordinal, info->ordinal, implemented ? " " : "!!", name); } else if (info->thunk_address) { - printf(" F %.8X %.8X %.3X (%3d) %s %s\n", - info->value_address, info->thunk_address, info->ordinal, - info->ordinal, implemented ? " " : "!!", name); - + printf(" F %.8X %.8X %.3X (%3d) %s %s\n", info->value_address, + info->thunk_address, info->ordinal, info->ordinal, + implemented ? " " : "!!", name); } } } @@ -359,3 +343,6 @@ void XUserModule::Dump() { printf(" TODO\n"); printf("\n"); } + +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/objects/xuser_module.h b/src/xenia/kernel/objects/xuser_module.h index eae6337c4..5d479c268 100644 --- a/src/xenia/kernel/objects/xuser_module.h +++ b/src/xenia/kernel/objects/xuser_module.h @@ -13,16 +13,14 @@ #include #include -#include #include - +#include namespace xe { namespace kernel { - class XUserModule : public XModule { -public: + public: XUserModule(KernelState* kernel_state, const char* path); virtual ~XUserModule(); @@ -33,23 +31,20 @@ public: X_STATUS LoadFromMemory(const void* addr, const size_t length); virtual void* GetProcAddressByOrdinal(uint16_t ordinal); - virtual X_STATUS GetSection( - const char* name, - uint32_t* out_section_data, uint32_t* out_section_size); + virtual X_STATUS GetSection(const char* name, uint32_t* out_section_data, + uint32_t* out_section_size); X_STATUS Launch(uint32_t flags); void Dump(); -private: + private: int LoadPE(); - xe_xex2_ref xex_; + xe_xex2_ref xex_; }; - } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_XUSER_MODULE_H_ diff --git a/src/xenia/kernel/user_profile.cc b/src/xenia/kernel/user_profile.cc index a401b8185..8815c5f13 100644 --- a/src/xenia/kernel/user_profile.cc +++ b/src/xenia/kernel/user_profile.cc @@ -9,11 +9,9 @@ #include - namespace xe { namespace kernel { - UserProfile::UserProfile() { xuid_ = 0xBABEBABEBABEBABE; name_ = "User"; @@ -78,13 +76,11 @@ UserProfile::UserProfile() { AddSetting(std::make_unique(0x63E83FFD, zeros)); } - void UserProfile::AddSetting(std::unique_ptr setting) { - settings_.insert({ setting->setting_id, setting.get() }); + settings_.insert({setting->setting_id, setting.get()}); setting_list_.push_back(std::move(setting)); } - UserProfile::Setting* UserProfile::GetSetting(uint32_t setting_id) { const auto& it = settings_.find(setting_id); if (it == settings_.end()) { @@ -93,6 +89,5 @@ UserProfile::Setting* UserProfile::GetSetting(uint32_t setting_id) { return it->second; } - } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/user_profile.h b/src/xenia/kernel/user_profile.h index 183bfd84d..95f40388d 100644 --- a/src/xenia/kernel/user_profile.h +++ b/src/xenia/kernel/user_profile.h @@ -20,13 +20,11 @@ #include - namespace xe { namespace kernel { - class UserProfile { -public: + public: struct Setting { enum class Type { UNKNOWN = 0, @@ -54,14 +52,15 @@ public: Setting(uint32_t setting_id, Type type, size_t size) : setting_id(setting_id), type(type), size(size) {} virtual size_t extra_size() const { return 0; } - virtual size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) { - poly::store_and_swap(user_data + kTypeOffset, static_cast(type)); + virtual size_t Append(uint8_t* user_data, uint8_t* buffer, + size_t buffer_offset) { + poly::store_and_swap(user_data + kTypeOffset, + static_cast(type)); return buffer_offset; } - bool is_title_specific() const { - return (setting_id & 0x3F00) == 0x3F00; - } - protected: + bool is_title_specific() const { return (setting_id & 0x3F00) == 0x3F00; } + + protected: const size_t kTypeOffset = 0; const size_t kValueOffset = 8; const size_t kPointerOffset = 12; @@ -70,7 +69,8 @@ public: Int32Setting(uint32_t setting_id, int32_t value) : Setting(setting_id, Type::INT32, 4), value(value) {} int32_t value; - size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) override { + size_t Append(uint8_t* user_data, uint8_t* buffer, + size_t buffer_offset) override { buffer_offset = Setting::Append(user_data, buffer, buffer_offset); poly::store_and_swap(user_data + kValueOffset, value); return buffer_offset; @@ -80,7 +80,8 @@ public: Int64Setting(uint32_t setting_id, int64_t value) : Setting(setting_id, Type::INT64, 8), value(value) {} int64_t value; - size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) override { + size_t Append(uint8_t* user_data, uint8_t* buffer, + size_t buffer_offset) override { buffer_offset = Setting::Append(user_data, buffer, buffer_offset); poly::store_and_swap(user_data + kValueOffset, value); return buffer_offset; @@ -90,7 +91,8 @@ public: DoubleSetting(uint32_t setting_id, double value) : Setting(setting_id, Type::DOUBLE, 8), value(value) {} double value; - size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) override { + size_t Append(uint8_t* user_data, uint8_t* buffer, + size_t buffer_offset) override { buffer_offset = Setting::Append(user_data, buffer, buffer_offset); poly::store_and_swap(user_data + kValueOffset, value); return buffer_offset; @@ -103,7 +105,8 @@ public: size_t extra_size() const override { return value.empty() ? 0 : 2 * (static_cast(value.size()) + 1); } - size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) override { + size_t Append(uint8_t* user_data, uint8_t* buffer, + size_t buffer_offset) override { buffer_offset = Setting::Append(user_data, buffer, buffer_offset); int32_t length; if (value.empty()) { @@ -124,7 +127,8 @@ public: FloatSetting(uint32_t setting_id, float value) : Setting(setting_id, Type::FLOAT, 4), value(value) {} float value; - size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) override { + size_t Append(uint8_t* user_data, uint8_t* buffer, + size_t buffer_offset) override { buffer_offset = Setting::Append(user_data, buffer, buffer_offset); poly::store_and_swap(user_data + kValueOffset, value); return buffer_offset; @@ -137,7 +141,8 @@ public: size_t extra_size() const override { return static_cast(value.size()); } - size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) override { + size_t Append(uint8_t* user_data, uint8_t* buffer, + size_t buffer_offset) override { buffer_offset = Setting::Append(user_data, buffer, buffer_offset); int32_t length; if (value.empty()) { @@ -158,7 +163,8 @@ public: DateTimeSetting(uint32_t setting_id, int64_t value) : Setting(setting_id, Type::DATETIME, 8), value(value) {} int64_t value; - size_t Append(uint8_t* user_data, uint8_t* buffer, size_t buffer_offset) override { + size_t Append(uint8_t* user_data, uint8_t* buffer, + size_t buffer_offset) override { buffer_offset = Setting::Append(user_data, buffer, buffer_offset); poly::store_and_swap(user_data + kValueOffset, value); return buffer_offset; @@ -174,16 +180,14 @@ public: void AddSetting(std::unique_ptr setting); Setting* GetSetting(uint32_t setting_id); -private: + private: uint64_t xuid_; std::string name_; std::vector> setting_list_; std::unordered_map settings_; }; - } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_USER_PROFILE_H_ diff --git a/src/xenia/kernel/util/xex2.cc b/src/xenia/kernel/util/xex2.cc index fc2e0b15b..e9e8aeb31 100644 --- a/src/xenia/kernel/util/xex2.cc +++ b/src/xenia/kernel/util/xex2.cc @@ -25,48 +25,44 @@ using namespace alloy; DEFINE_bool(xex_dev_key, false, "Use the devkit key."); - typedef struct xe_xex2 { xe_ref_t ref; - Memory* memory; + Memory *memory; xe_xex2_header_t header; - std::vector* sections; + std::vector *sections; struct { size_t count; - xe_xex2_import_info_t* infos; + xe_xex2_import_info_t *infos; } library_imports[16]; } xe_xex2_t; - int xe_xex2_read_header(const uint8_t *addr, const size_t length, xe_xex2_header_t *header); int xe_xex2_decrypt_key(xe_xex2_header_t *header); -int xe_xex2_read_image(xe_xex2_ref xex, - const uint8_t *xex_addr, const size_t xex_length, - Memory* memory); +int xe_xex2_read_image(xe_xex2_ref xex, const uint8_t *xex_addr, + const size_t xex_length, Memory *memory); int xe_xex2_load_pe(xe_xex2_ref xex); int xe_xex2_find_import_infos(xe_xex2_ref xex, - const xe_xex2_import_library_t* library); + const xe_xex2_import_library_t *library); - -xe_xex2_ref xe_xex2_load(Memory* memory, - const void* addr, const size_t length, +xe_xex2_ref xe_xex2_load(Memory *memory, const void *addr, const size_t length, xe_xex2_options_t options) { xe_xex2_ref xex = (xe_xex2_ref)xe_calloc(sizeof(xe_xex2)); xe_ref_init((xe_ref)xex); xex->memory = memory; - xex->sections = new std::vector(); + xex->sections = new std::vector(); - XEEXPECTZERO(xe_xex2_read_header((const uint8_t*)addr, length, &xex->header)); + XEEXPECTZERO( + xe_xex2_read_header((const uint8_t *)addr, length, &xex->header)); XEEXPECTZERO(xe_xex2_decrypt_key(&xex->header)); - XEEXPECTZERO(xe_xex2_read_image(xex, (const uint8_t*)addr, length, memory)); + XEEXPECTZERO(xe_xex2_read_image(xex, (const uint8_t *)addr, length, memory)); XEEXPECTZERO(xe_xex2_load_pe(xex)); @@ -83,7 +79,7 @@ XECLEANUP: } void xe_xex2_dealloc(xe_xex2_ref xex) { - for (std::vector::iterator it = xex->sections->begin(); + for (std::vector::iterator it = xex->sections->begin(); it != xex->sections->end(); ++it) { delete *it; } @@ -111,7 +107,7 @@ void xe_xex2_release(xe_xex2_ref xex) { xe_ref_release((xe_ref)xex, (xe_ref_dealloc_t)xe_xex2_dealloc); } -const xe_xex2_header_t* xe_xex2_get_header(xe_xex2_ref xex) { +const xe_xex2_header_t *xe_xex2_get_header(xe_xex2_ref xex) { return &xex->header; } @@ -127,11 +123,12 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, return 1; } - header->module_flags = (xe_xex2_module_flags)poly::load_and_swap(p + 0x04); - header->exe_offset = poly::load_and_swap(p + 0x08); - header->unknown0 = poly::load_and_swap(p + 0x0C); - header->certificate_offset = poly::load_and_swap(p + 0x10); - header->header_count = poly::load_and_swap(p + 0x14); + header->module_flags = + (xe_xex2_module_flags)poly::load_and_swap(p + 0x04); + header->exe_offset = poly::load_and_swap(p + 0x08); + header->unknown0 = poly::load_and_swap(p + 0x0C); + header->certificate_offset = poly::load_and_swap(p + 0x10); + header->header_count = poly::load_and_swap(p + 0x14); for (size_t n = 0; n < header->header_count; n++) { const uint8_t *ph = p + 0x18 + (n * 8); @@ -141,98 +138,106 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, xe_xex2_opt_header_t *opt_header = &header->headers[n]; opt_header->key = key; switch (key & 0xFF) { - case 0x01: - // dataOffset = data - opt_header->length = 0; - opt_header->value = data_offset; - break; - case 0xFF: - // dataOffset = offset (first dword in data is size) - opt_header->length = poly::load_and_swap(p + data_offset); - opt_header->offset = data_offset; - break; - default: - // dataOffset = size in dwords - opt_header->length = (key & 0xFF) * 4; - opt_header->offset = data_offset; - break; + case 0x01: + // dataOffset = data + opt_header->length = 0; + opt_header->value = data_offset; + break; + case 0xFF: + // dataOffset = offset (first dword in data is size) + opt_header->length = poly::load_and_swap(p + data_offset); + opt_header->offset = data_offset; + break; + default: + // dataOffset = size in dwords + opt_header->length = (key & 0xFF) * 4; + opt_header->offset = data_offset; + break; } const uint8_t *pp = p + opt_header->offset; switch (opt_header->key) { - case XEX_HEADER_SYSTEM_FLAGS: - header->system_flags = (xe_xex2_system_flags)data_offset; - break; - case XEX_HEADER_RESOURCE_INFO: - { + case XEX_HEADER_SYSTEM_FLAGS: + header->system_flags = (xe_xex2_system_flags)data_offset; + break; + case XEX_HEADER_RESOURCE_INFO: { header->resource_info_count = (opt_header->length - 4) / 16; - header->resource_infos = (xe_xex2_resource_info_t*)xe_calloc( + header->resource_infos = (xe_xex2_resource_info_t *)xe_calloc( sizeof(xe_xex2_resource_info_t) * header->resource_info_count); - const uint8_t* ph = pp + 0x04; + const uint8_t *ph = pp + 0x04; for (size_t n = 0; n < header->resource_info_count; n++) { - auto& res = header->resource_infos[n]; - XEEXPECTZERO(xe_copy_memory(res.name, - sizeof(res.name), ph + 0x00, 8)); - res.address = poly::load_and_swap(ph + 0x08); - res.size = poly::load_and_swap(ph + 0x0C); + auto &res = header->resource_infos[n]; + XEEXPECTZERO( + xe_copy_memory(res.name, sizeof(res.name), ph + 0x00, 8)); + res.address = poly::load_and_swap(ph + 0x08); + res.size = poly::load_and_swap(ph + 0x0C); ph += 16; } - } - break; - case XEX_HEADER_EXECUTION_INFO: - { + } break; + case XEX_HEADER_EXECUTION_INFO: { xe_xex2_execution_info_t *ex = &header->execution_info; - ex->media_id = poly::load_and_swap(pp + 0x00); - ex->version.value = poly::load_and_swap(pp + 0x04); - ex->base_version.value = poly::load_and_swap(pp + 0x08); - ex->title_id = poly::load_and_swap(pp + 0x0C); - ex->platform = poly::load_and_swap(pp + 0x10); - ex->executable_table = poly::load_and_swap(pp + 0x11); - ex->disc_number = poly::load_and_swap(pp + 0x12); - ex->disc_count = poly::load_and_swap(pp + 0x13); - ex->savegame_id = poly::load_and_swap(pp + 0x14); - } - break; - case XEX_HEADER_GAME_RATINGS: - { + ex->media_id = poly::load_and_swap(pp + 0x00); + ex->version.value = poly::load_and_swap(pp + 0x04); + ex->base_version.value = poly::load_and_swap(pp + 0x08); + ex->title_id = poly::load_and_swap(pp + 0x0C); + ex->platform = poly::load_and_swap(pp + 0x10); + ex->executable_table = poly::load_and_swap(pp + 0x11); + ex->disc_number = poly::load_and_swap(pp + 0x12); + ex->disc_count = poly::load_and_swap(pp + 0x13); + ex->savegame_id = poly::load_and_swap(pp + 0x14); + } break; + case XEX_HEADER_GAME_RATINGS: { xe_xex2_game_ratings_t *ratings = &header->game_ratings; - ratings->esrb = (xe_xex2_rating_esrb_value)poly::load_and_swap(pp + 0x00); - ratings->pegi = (xe_xex2_rating_pegi_value)poly::load_and_swap(pp + 0x01); - ratings->pegifi = (xe_xex2_rating_pegi_fi_value)poly::load_and_swap(pp + 0x02); - ratings->pegipt = (xe_xex2_rating_pegi_pt_value)poly::load_and_swap(pp + 0x03); - ratings->bbfc = (xe_xex2_rating_bbfc_value)poly::load_and_swap(pp + 0x04); - ratings->cero = (xe_xex2_rating_cero_value)poly::load_and_swap(pp + 0x05); - ratings->usk = (xe_xex2_rating_usk_value)poly::load_and_swap(pp + 0x06); - ratings->oflcau = (xe_xex2_rating_oflc_au_value)poly::load_and_swap(pp + 0x07); - ratings->oflcnz = (xe_xex2_rating_oflc_nz_value)poly::load_and_swap(pp + 0x08); - ratings->kmrb = (xe_xex2_rating_kmrb_value)poly::load_and_swap(pp + 0x09); - ratings->brazil = (xe_xex2_rating_brazil_value)poly::load_and_swap(pp + 0x0A); - ratings->fpb = (xe_xex2_rating_fpb_value)poly::load_and_swap(pp + 0x0B); - } - break; - case XEX_HEADER_TLS_INFO: - { + ratings->esrb = + (xe_xex2_rating_esrb_value)poly::load_and_swap(pp + 0x00); + ratings->pegi = + (xe_xex2_rating_pegi_value)poly::load_and_swap(pp + 0x01); + ratings->pegifi = + (xe_xex2_rating_pegi_fi_value)poly::load_and_swap(pp + + 0x02); + ratings->pegipt = + (xe_xex2_rating_pegi_pt_value)poly::load_and_swap(pp + + 0x03); + ratings->bbfc = + (xe_xex2_rating_bbfc_value)poly::load_and_swap(pp + 0x04); + ratings->cero = + (xe_xex2_rating_cero_value)poly::load_and_swap(pp + 0x05); + ratings->usk = + (xe_xex2_rating_usk_value)poly::load_and_swap(pp + 0x06); + ratings->oflcau = + (xe_xex2_rating_oflc_au_value)poly::load_and_swap(pp + + 0x07); + ratings->oflcnz = + (xe_xex2_rating_oflc_nz_value)poly::load_and_swap(pp + + 0x08); + ratings->kmrb = + (xe_xex2_rating_kmrb_value)poly::load_and_swap(pp + 0x09); + ratings->brazil = + (xe_xex2_rating_brazil_value)poly::load_and_swap(pp + + 0x0A); + ratings->fpb = + (xe_xex2_rating_fpb_value)poly::load_and_swap(pp + 0x0B); + } break; + case XEX_HEADER_TLS_INFO: { xe_xex2_tls_info_t *tls = &header->tls_info; - tls->slot_count = poly::load_and_swap(pp + 0x00); - tls->raw_data_address = poly::load_and_swap(pp + 0x04); - tls->data_size = poly::load_and_swap(pp + 0x08); - tls->raw_data_size = poly::load_and_swap(pp + 0x0C); - } - break; - case XEX_HEADER_IMAGE_BASE_ADDRESS: - header->exe_address = opt_header->value; - break; - case XEX_HEADER_ENTRY_POINT: - header->exe_entry_point = opt_header->value; - break; - case XEX_HEADER_DEFAULT_STACK_SIZE: - header->exe_stack_size = opt_header->value; - break; - case XEX_HEADER_DEFAULT_HEAP_SIZE: - header->exe_heap_size = opt_header->value; - break; - case XEX_HEADER_IMPORT_LIBRARIES: - { + tls->slot_count = poly::load_and_swap(pp + 0x00); + tls->raw_data_address = poly::load_and_swap(pp + 0x04); + tls->data_size = poly::load_and_swap(pp + 0x08); + tls->raw_data_size = poly::load_and_swap(pp + 0x0C); + } break; + case XEX_HEADER_IMAGE_BASE_ADDRESS: + header->exe_address = opt_header->value; + break; + case XEX_HEADER_ENTRY_POINT: + header->exe_entry_point = opt_header->value; + break; + case XEX_HEADER_DEFAULT_STACK_SIZE: + header->exe_stack_size = opt_header->value; + break; + case XEX_HEADER_DEFAULT_HEAP_SIZE: + header->exe_heap_size = opt_header->value; + break; + case XEX_HEADER_IMPORT_LIBRARIES: { const size_t max_count = poly::countof(header->import_libraries); size_t count = poly::load_and_swap(pp + 0x08); assert_true(count <= max_count); @@ -244,18 +249,19 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, header->import_library_count = count; uint32_t string_table_size = poly::load_and_swap(pp + 0x04); - const char *string_table = (const char*)(pp + 0x0C); + const char *string_table = (const char *)(pp + 0x0C); pp += 12 + string_table_size; for (size_t m = 0; m < count; m++) { xe_xex2_import_library_t *library = &header->import_libraries[m]; XEEXPECTZERO(xe_copy_memory(library->digest, sizeof(library->digest), pp + 0x04, 20)); - library->import_id = poly::load_and_swap(pp + 0x18); - library->version.value = poly::load_and_swap(pp + 0x1C); - library->min_version.value = poly::load_and_swap(pp + 0x20); + library->import_id = poly::load_and_swap(pp + 0x18); + library->version.value = poly::load_and_swap(pp + 0x1C); + library->min_version.value = poly::load_and_swap(pp + 0x20); - const uint16_t name_index = poly::load_and_swap(pp + 0x24) & 0xFF; + const uint16_t name_index = + poly::load_and_swap(pp + 0x24) & 0xFF; for (size_t i = 0, j = 0; i < string_table_size;) { assert_true(j <= 0xFF); if (j == name_index) { @@ -274,9 +280,9 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, } } - library->record_count = poly::load_and_swap(pp + 0x26); - library->records = (uint32_t*)xe_calloc( - library->record_count * sizeof(uint32_t)); + library->record_count = poly::load_and_swap(pp + 0x26); + library->records = + (uint32_t *)xe_calloc(library->record_count * sizeof(uint32_t)); XEEXPECTNOTNULL(library->records); pp += 0x28; for (size_t i = 0; i < library->record_count; i++) { @@ -284,10 +290,8 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, pp += 4; } } - } - break; - case XEX_HEADER_STATIC_LIBRARIES: - { + } break; + case XEX_HEADER_STATIC_LIBRARIES: { const size_t max_count = poly::countof(header->static_libraries); size_t count = (opt_header->length - 4) / 16; assert_true(count <= max_count); @@ -302,49 +306,47 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, xe_xex2_static_library_t *library = &header->static_libraries[m]; XEEXPECTZERO(xe_copy_memory(library->name, sizeof(library->name), pp + 0x00, 8)); - library->name[8] = 0; - library->major = poly::load_and_swap(pp + 0x08); - library->minor = poly::load_and_swap(pp + 0x0A); - library->build = poly::load_and_swap(pp + 0x0C); - uint16_t qfeapproval = poly::load_and_swap(pp + 0x0E); - library->approval = (xe_xex2_approval_type)(qfeapproval & 0x8000); - library->qfe = qfeapproval & ~0x8000; + library->name[8] = 0; + library->major = poly::load_and_swap(pp + 0x08); + library->minor = poly::load_and_swap(pp + 0x0A); + library->build = poly::load_and_swap(pp + 0x0C); + uint16_t qfeapproval = poly::load_and_swap(pp + 0x0E); + library->approval = (xe_xex2_approval_type)(qfeapproval & 0x8000); + library->qfe = qfeapproval & ~0x8000; pp += 16; } - } - break; - case XEX_HEADER_FILE_FORMAT_INFO: - { + } break; + case XEX_HEADER_FILE_FORMAT_INFO: { xe_xex2_file_format_info_t *fmt = &header->file_format_info; - fmt->encryption_type = + fmt->encryption_type = (xe_xex2_encryption_type)poly::load_and_swap(pp + 0x04); - fmt->compression_type = + fmt->compression_type = (xe_xex2_compression_type)poly::load_and_swap(pp + 0x06); switch (fmt->compression_type) { - case XEX_COMPRESSION_NONE: - // TODO: XEX_COMPRESSION_NONE - assert_always(); - break; - case XEX_COMPRESSION_BASIC: - { + case XEX_COMPRESSION_NONE: + // TODO: XEX_COMPRESSION_NONE + assert_always(); + break; + case XEX_COMPRESSION_BASIC: { xe_xex2_file_basic_compression_info_t *comp_info = &fmt->compression_info.basic; uint32_t info_size = poly::load_and_swap(pp + 0x00); - comp_info->block_count = (info_size - 8) / 8; - comp_info->blocks = (xe_xex2_file_basic_compression_block_t*) - xe_calloc(comp_info->block_count * - sizeof(xe_xex2_file_basic_compression_block_t)); + comp_info->block_count = (info_size - 8) / 8; + comp_info->blocks = + (xe_xex2_file_basic_compression_block_t *)xe_calloc( + comp_info->block_count * + sizeof(xe_xex2_file_basic_compression_block_t)); XEEXPECTNOTNULL(comp_info->blocks); for (size_t m = 0; m < comp_info->block_count; m++) { xe_xex2_file_basic_compression_block_t *block = &comp_info->blocks[m]; - block->data_size = poly::load_and_swap(pp + 0x08 + (m * 8)); - block->zero_size = poly::load_and_swap(pp + 0x0C + (m * 8)); + block->data_size = + poly::load_and_swap(pp + 0x08 + (m * 8)); + block->zero_size = + poly::load_and_swap(pp + 0x0C + (m * 8)); } - } - break; - case XEX_COMPRESSION_NORMAL: - { + } break; + case XEX_COMPRESSION_NORMAL: { xe_xex2_file_normal_compression_info_t *comp_info = &fmt->compression_info.normal; uint32_t window_size = poly::load_and_swap(pp + 0x08); @@ -355,56 +357,57 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, break; } } - comp_info->window_size = poly::load_and_swap(pp + 0x08); - comp_info->window_bits = window_bits; - comp_info->block_size = poly::load_and_swap(pp + 0x0C); + comp_info->window_size = poly::load_and_swap(pp + 0x08); + comp_info->window_bits = window_bits; + comp_info->block_size = poly::load_and_swap(pp + 0x0C); XEEXPECTZERO(xe_copy_memory(comp_info->block_hash, sizeof(comp_info->block_hash), pp + 0x10, 20)); - } - break; - case XEX_COMPRESSION_DELTA: - // TODO: XEX_COMPRESSION_DELTA - assert_always(); - break; + } break; + case XEX_COMPRESSION_DELTA: + // TODO: XEX_COMPRESSION_DELTA + assert_always(); + break; } - } - break; + } break; } } // Loader info. pc = p + header->certificate_offset; ldr = &header->loader_info; - ldr->header_size = poly::load_and_swap(pc + 0x000); - ldr->image_size = poly::load_and_swap(pc + 0x004); + ldr->header_size = poly::load_and_swap(pc + 0x000); + ldr->image_size = poly::load_and_swap(pc + 0x004); XEEXPECTZERO(xe_copy_memory(ldr->rsa_signature, sizeof(ldr->rsa_signature), pc + 0x008, 256)); - ldr->unklength = poly::load_and_swap(pc + 0x108); - ldr->image_flags = (xe_xex2_image_flags)poly::load_and_swap(pc + 0x10C); - ldr->load_address = poly::load_and_swap(pc + 0x110); + ldr->unklength = poly::load_and_swap(pc + 0x108); + ldr->image_flags = + (xe_xex2_image_flags)poly::load_and_swap(pc + 0x10C); + ldr->load_address = poly::load_and_swap(pc + 0x110); XEEXPECTZERO(xe_copy_memory(ldr->section_digest, sizeof(ldr->section_digest), pc + 0x114, 20)); ldr->import_table_count = poly::load_and_swap(pc + 0x128); XEEXPECTZERO(xe_copy_memory(ldr->import_table_digest, - sizeof(ldr->import_table_digest), - pc + 0x12C, 20)); - XEEXPECTZERO(xe_copy_memory(ldr->media_id, sizeof(ldr->media_id), - pc + 0x140, 16)); - XEEXPECTZERO(xe_copy_memory(ldr->file_key, sizeof(ldr->file_key), - pc + 0x150, 16)); - ldr->export_table = poly::load_and_swap(pc + 0x160); + sizeof(ldr->import_table_digest), pc + 0x12C, + 20)); + XEEXPECTZERO( + xe_copy_memory(ldr->media_id, sizeof(ldr->media_id), pc + 0x140, 16)); + XEEXPECTZERO( + xe_copy_memory(ldr->file_key, sizeof(ldr->file_key), pc + 0x150, 16)); + ldr->export_table = poly::load_and_swap(pc + 0x160); XEEXPECTZERO(xe_copy_memory(ldr->header_digest, sizeof(ldr->header_digest), pc + 0x164, 20)); - ldr->game_regions = (xe_xex2_region_flags)poly::load_and_swap(pc + 0x178); - ldr->media_flags = (xe_xex2_media_flags)poly::load_and_swap(pc + 0x17C); + ldr->game_regions = + (xe_xex2_region_flags)poly::load_and_swap(pc + 0x178); + ldr->media_flags = + (xe_xex2_media_flags)poly::load_and_swap(pc + 0x17C); // Section info follows loader info. ps = p + header->certificate_offset + 0x180; - header->section_count = poly::load_and_swap(ps + 0x000); + header->section_count = poly::load_and_swap(ps + 0x000); ps += 4; - header->sections = (xe_xex2_section_t*)xe_calloc( - header->section_count * sizeof(xe_xex2_section_t)); + header->sections = (xe_xex2_section_t *)xe_calloc(header->section_count * + sizeof(xe_xex2_section_t)); XEEXPECTNOTNULL(header->sections); for (size_t n = 0; n < header->section_count; n++) { xe_xex2_section_t *section = &header->sections[n]; @@ -423,13 +426,11 @@ XECLEANUP: int xe_xex2_decrypt_key(xe_xex2_header_t *header) { const static uint8_t xe_xex2_retail_key[16] = { - 0x20, 0xB1, 0x85, 0xA5, 0x9D, 0x28, 0xFD, 0xC3, - 0x40, 0x58, 0x3F, 0xBB, 0x08, 0x96, 0xBF, 0x91 - }; + 0x20, 0xB1, 0x85, 0xA5, 0x9D, 0x28, 0xFD, 0xC3, + 0x40, 0x58, 0x3F, 0xBB, 0x08, 0x96, 0xBF, 0x91}; const static uint8_t xe_xex2_devkit_key[16] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // Guess key based on file info. // TODO: better way to finding out which key to use? @@ -443,54 +444,53 @@ int xe_xex2_decrypt_key(xe_xex2_header_t *header) { // Decrypt the header key. uint32_t rk[4 * (MAXNR + 1)]; int32_t Nr = rijndaelKeySetupDec(rk, xexkey, 128); - rijndaelDecrypt(rk, Nr, - header->loader_info.file_key, header->session_key); + rijndaelDecrypt(rk, Nr, header->loader_info.file_key, header->session_key); return 0; } typedef struct mspack_memory_file_t { struct mspack_system sys; - void *buffer; + void *buffer; off_t buffer_size; off_t offset; } mspack_memory_file; -mspack_memory_file *mspack_memory_open(struct mspack_system *sys, - void* buffer, const size_t buffer_size) { +mspack_memory_file *mspack_memory_open(struct mspack_system *sys, void *buffer, + const size_t buffer_size) { assert_true(buffer_size < INT_MAX); if (buffer_size >= INT_MAX) { return NULL; } - mspack_memory_file *memfile = (mspack_memory_file*)xe_calloc( - sizeof(mspack_memory_file)); + mspack_memory_file *memfile = + (mspack_memory_file *)xe_calloc(sizeof(mspack_memory_file)); if (!memfile) { return NULL; } - memfile->buffer = buffer; - memfile->buffer_size = (off_t)buffer_size; - memfile->offset = 0; + memfile->buffer = buffer; + memfile->buffer_size = (off_t)buffer_size; + memfile->offset = 0; return memfile; } void mspack_memory_close(mspack_memory_file *file) { - mspack_memory_file *memfile = (mspack_memory_file*)file; + mspack_memory_file *memfile = (mspack_memory_file *)file; xe_free(memfile); } int mspack_memory_read(struct mspack_file *file, void *buffer, int chars) { - mspack_memory_file *memfile = (mspack_memory_file*)file; + mspack_memory_file *memfile = (mspack_memory_file *)file; const off_t remaining = memfile->buffer_size - memfile->offset; const off_t total = std::min(static_cast(chars), remaining); if (xe_copy_memory(buffer, total, - (uint8_t*)memfile->buffer + memfile->offset, total)) { + (uint8_t *)memfile->buffer + memfile->offset, total)) { return -1; } memfile->offset += total; return (int)total; } int mspack_memory_write(struct mspack_file *file, void *buffer, int chars) { - mspack_memory_file *memfile = (mspack_memory_file*)file; + mspack_memory_file *memfile = (mspack_memory_file *)file; const off_t remaining = memfile->buffer_size - memfile->offset; const off_t total = std::min(static_cast(chars), remaining); - if (xe_copy_memory((uint8_t*)memfile->buffer + memfile->offset, + if (xe_copy_memory((uint8_t *)memfile->buffer + memfile->offset, memfile->buffer_size - memfile->offset, buffer, total)) { return -1; } @@ -500,38 +500,34 @@ int mspack_memory_write(struct mspack_file *file, void *buffer, int chars) { void *mspack_memory_alloc(struct mspack_system *sys, size_t chars) { return xe_calloc(chars); } -void mspack_memory_free(void *ptr) { - xe_free(ptr); -} +void mspack_memory_free(void *ptr) { xe_free(ptr); } void mspack_memory_copy(void *src, void *dest, size_t chars) { xe_copy_memory(dest, chars, src, chars); } struct mspack_system *mspack_memory_sys_create() { - struct mspack_system *sys = (struct mspack_system *)xe_calloc( - sizeof(struct mspack_system)); + struct mspack_system *sys = + (struct mspack_system *)xe_calloc(sizeof(struct mspack_system)); if (!sys) { return NULL; } - sys->read = mspack_memory_read; - sys->write = mspack_memory_write; - sys->alloc = mspack_memory_alloc; - sys->free = mspack_memory_free; - sys->copy = mspack_memory_copy; + sys->read = mspack_memory_read; + sys->write = mspack_memory_write; + sys->alloc = mspack_memory_alloc; + sys->free = mspack_memory_free; + sys->copy = mspack_memory_copy; return sys; } -void mspack_memory_sys_destroy(struct mspack_system *sys) { - xe_free(sys); -} +void mspack_memory_sys_destroy(struct mspack_system *sys) { xe_free(sys); } void xe_xex2_decrypt_buffer(const uint8_t *session_key, const uint8_t *input_buffer, - const size_t input_size, uint8_t* output_buffer, + const size_t input_size, uint8_t *output_buffer, const size_t output_size) { uint32_t rk[4 * (MAXNR + 1)]; uint8_t ivec[16] = {0}; int32_t Nr = rijndaelKeySetupDec(rk, session_key, 128); const uint8_t *ct = input_buffer; - uint8_t* pt = output_buffer; + uint8_t *pt = output_buffer; for (size_t n = 0; n < input_size; n += 16, ct += 16, pt += 16) { // Decrypt 16 uint8_ts from input -> output. rijndaelDecrypt(rk, Nr, ct, pt); @@ -546,33 +542,31 @@ void xe_xex2_decrypt_buffer(const uint8_t *session_key, int xe_xex2_read_image_uncompressed(const xe_xex2_header_t *header, const uint8_t *xex_addr, - const size_t xex_length, - Memory* memory) { + const size_t xex_length, Memory *memory) { // Allocate in-place the XEX memory. const size_t exe_length = xex_length - header->exe_offset; size_t uncompressed_size = exe_length; uint32_t alloc_result = (uint32_t)memory->HeapAlloc( - header->exe_address, uncompressed_size, - MEMORY_FLAG_ZERO); + header->exe_address, uncompressed_size, MEMORY_FLAG_ZERO); if (!alloc_result) { - XELOGE("Unable to allocate XEX memory at %.8X-%.8X.", - header->exe_address, uncompressed_size); + XELOGE("Unable to allocate XEX memory at %.8X-%.8X.", header->exe_address, + uncompressed_size); return 2; } uint8_t *buffer = memory->Translate(header->exe_address); - const uint8_t *p = (const uint8_t*)xex_addr + header->exe_offset; + const uint8_t *p = (const uint8_t *)xex_addr + header->exe_offset; switch (header->file_format_info.encryption_type) { - case XEX_ENCRYPTION_NONE: - return xe_copy_memory(buffer, uncompressed_size, p, exe_length); - case XEX_ENCRYPTION_NORMAL: - xe_xex2_decrypt_buffer(header->session_key, p, exe_length, buffer, - uncompressed_size); - return 0; - default: - assert_always(); - return 1; + case XEX_ENCRYPTION_NONE: + return xe_copy_memory(buffer, uncompressed_size, p, exe_length); + case XEX_ENCRYPTION_NORMAL: + xe_xex2_decrypt_buffer(header->session_key, p, exe_length, buffer, + uncompressed_size); + return 0; + default: + assert_always(); + return 1; } return 0; @@ -581,14 +575,14 @@ int xe_xex2_read_image_uncompressed(const xe_xex2_header_t *header, int xe_xex2_read_image_basic_compressed(const xe_xex2_header_t *header, const uint8_t *xex_addr, const size_t xex_length, - Memory* memory) { + Memory *memory) { const size_t exe_length = xex_length - header->exe_offset; - const uint8_t* source_buffer = (const uint8_t*)xex_addr + header->exe_offset; + const uint8_t *source_buffer = (const uint8_t *)xex_addr + header->exe_offset; const uint8_t *p = source_buffer; // Calculate uncompressed length. size_t uncompressed_size = 0; - const xe_xex2_file_basic_compression_info_t* comp_info = + const xe_xex2_file_basic_compression_info_t *comp_info = &header->file_format_info.compression_info.basic; for (size_t n = 0; n < comp_info->block_count; n++) { const size_t data_size = comp_info->blocks[n].data_size; @@ -598,11 +592,10 @@ int xe_xex2_read_image_basic_compressed(const xe_xex2_header_t *header, // Allocate in-place the XEX memory. uint32_t alloc_result = (uint32_t)memory->HeapAlloc( - header->exe_address, uncompressed_size, - MEMORY_FLAG_ZERO); + header->exe_address, uncompressed_size, MEMORY_FLAG_ZERO); if (!alloc_result) { - XELOGE("Unable to allocate XEX memory at %.8X-%.8X.", - header->exe_address, uncompressed_size); + XELOGE("Unable to allocate XEX memory at %.8X-%.8X.", header->exe_address, + uncompressed_size); XEFAIL(); } uint8_t *buffer = memory->Translate(header->exe_address); @@ -617,14 +610,13 @@ int xe_xex2_read_image_basic_compressed(const xe_xex2_header_t *header, const size_t zero_size = comp_info->blocks[n].zero_size; switch (header->file_format_info.encryption_type) { - case XEX_ENCRYPTION_NONE: - XEEXPECTZERO(xe_copy_memory(d, uncompressed_size - (d - buffer), p, - exe_length - (p - source_buffer))); - break; - case XEX_ENCRYPTION_NORMAL: - { + case XEX_ENCRYPTION_NONE: + XEEXPECTZERO(xe_copy_memory(d, uncompressed_size - (d - buffer), p, + exe_length - (p - source_buffer))); + break; + case XEX_ENCRYPTION_NORMAL: { const uint8_t *ct = p; - uint8_t* pt = d; + uint8_t *pt = d; for (size_t n = 0; n < data_size; n += 16, ct += 16, pt += 16) { // Decrypt 16 uint8_ts from input -> output. rijndaelDecrypt(rk, Nr, ct, pt); @@ -635,11 +627,10 @@ int xe_xex2_read_image_basic_compressed(const xe_xex2_header_t *header, ivec[i] = ct[i]; } } - } - break; - default: - assert_always(); - return 1; + } break; + default: + assert_always(); + return 1; } p += data_size; @@ -654,10 +645,9 @@ XECLEANUP: int xe_xex2_read_image_compressed(const xe_xex2_header_t *header, const uint8_t *xex_addr, - const size_t xex_length, - Memory* memory) { + const size_t xex_length, Memory *memory) { const size_t exe_length = xex_length - header->exe_offset; - const uint8_t *exe_buffer = (const uint8_t*)xex_addr + header->exe_offset; + const uint8_t *exe_buffer = (const uint8_t *)xex_addr + header->exe_offset; // src -> dest: // - decrypt (if encrypted) @@ -685,39 +675,39 @@ int xe_xex2_read_image_compressed(const xe_xex2_header_t *header, const uint8_t *input_buffer = exe_buffer; const size_t input_size = exe_length; switch (header->file_format_info.encryption_type) { - case XEX_ENCRYPTION_NONE: - // No-op. - break; - case XEX_ENCRYPTION_NORMAL: - // TODO: a way to do without a copy/alloc? - free_input = true; - input_buffer = (const uint8_t*)xe_calloc(input_size); - XEEXPECTNOTNULL(input_buffer); - xe_xex2_decrypt_buffer(header->session_key, exe_buffer, exe_length, - (uint8_t*)input_buffer, input_size); - break; - default: - assert_always(); - return false; + case XEX_ENCRYPTION_NONE: + // No-op. + break; + case XEX_ENCRYPTION_NORMAL: + // TODO: a way to do without a copy/alloc? + free_input = true; + input_buffer = (const uint8_t *)xe_calloc(input_size); + XEEXPECTNOTNULL(input_buffer); + xe_xex2_decrypt_buffer(header->session_key, exe_buffer, exe_length, + (uint8_t *)input_buffer, input_size); + break; + default: + assert_always(); + return false; } - compress_buffer = (uint8_t*)xe_calloc(exe_length); + compress_buffer = (uint8_t *)xe_calloc(exe_length); XEEXPECTNOTNULL(compress_buffer); p = input_buffer; d = compress_buffer; // De-block. - deblock_buffer = (uint8_t*)xe_calloc(input_size); + deblock_buffer = (uint8_t *)xe_calloc(input_size); XEEXPECTNOTNULL(deblock_buffer); block_size = header->file_format_info.compression_info.normal.block_size; while (block_size) { const uint8_t *pnext = p + block_size; const size_t next_size = poly::load_and_swap(p); p += 4; - p += 20; // skip 20b hash + p += 20; // skip 20b hash - while(true) { + while (true) { const size_t chunk_size = (p[0] << 8) | p[1]; p += 2; if (!chunk_size) { @@ -736,11 +726,10 @@ int xe_xex2_read_image_compressed(const xe_xex2_header_t *header, // Allocate in-place the XEX memory. uint32_t alloc_result = (uint32_t)memory->HeapAlloc( - header->exe_address, uncompressed_size, - MEMORY_FLAG_ZERO); + header->exe_address, uncompressed_size, MEMORY_FLAG_ZERO); if (!alloc_result) { - XELOGE("Unable to allocate XEX memory at %.8X-%.8X.", - header->exe_address, uncompressed_size); + XELOGE("Unable to allocate XEX memory at %.8X-%.8X.", header->exe_address, + uncompressed_size); result_code = 2; XEFAIL(); } @@ -749,18 +738,15 @@ int xe_xex2_read_image_compressed(const xe_xex2_header_t *header, // Setup decompressor and decompress. sys = mspack_memory_sys_create(); XEEXPECTNOTNULL(sys); - lzxsrc = mspack_memory_open(sys, (void*)compress_buffer, d - compress_buffer); + lzxsrc = + mspack_memory_open(sys, (void *)compress_buffer, d - compress_buffer); XEEXPECTNOTNULL(lzxsrc); lzxdst = mspack_memory_open(sys, buffer, uncompressed_size); XEEXPECTNOTNULL(lzxdst); - lzxd = lzxd_init( - sys, - (struct mspack_file *)lzxsrc, - (struct mspack_file *)lzxdst, - header->file_format_info.compression_info.normal.window_bits, - 0, - 32768, - (off_t)header->loader_info.image_size); + lzxd = + lzxd_init(sys, (struct mspack_file *)lzxsrc, (struct mspack_file *)lzxdst, + header->file_format_info.compression_info.normal.window_bits, 0, + 32768, (off_t)header->loader_info.image_size); XEEXPECTNOTNULL(lzxd); XEEXPECTZERO(lzxd_decompress(lzxd, (off_t)header->loader_info.image_size)); @@ -786,36 +772,36 @@ XECLEANUP: xe_free(compress_buffer); xe_free(deblock_buffer); if (free_input) { - xe_free((void*)input_buffer); + xe_free((void *)input_buffer); } return result_code; } int xe_xex2_read_image(xe_xex2_ref xex, const uint8_t *xex_addr, - const size_t xex_length, Memory* memory) { + const size_t xex_length, Memory *memory) { const xe_xex2_header_t *header = &xex->header; switch (header->file_format_info.compression_type) { - case XEX_COMPRESSION_NONE: - return xe_xex2_read_image_uncompressed( - header, xex_addr, xex_length, memory); - case XEX_COMPRESSION_BASIC: - return xe_xex2_read_image_basic_compressed( - header, xex_addr, xex_length, memory); - case XEX_COMPRESSION_NORMAL: - return xe_xex2_read_image_compressed( - header, xex_addr, xex_length, memory); - default: - assert_always(); - return 1; + case XEX_COMPRESSION_NONE: + return xe_xex2_read_image_uncompressed(header, xex_addr, xex_length, + memory); + case XEX_COMPRESSION_BASIC: + return xe_xex2_read_image_basic_compressed(header, xex_addr, xex_length, + memory); + case XEX_COMPRESSION_NORMAL: + return xe_xex2_read_image_compressed(header, xex_addr, xex_length, + memory); + default: + assert_always(); + return 1; } } int xe_xex2_load_pe(xe_xex2_ref xex) { - const xe_xex2_header_t* header = &xex->header; - const uint8_t* p = xex->memory->Translate(header->exe_address); + const xe_xex2_header_t *header = &xex->header; + const uint8_t *p = xex->memory->Translate(header->exe_address); // Verify DOS signature (MZ). - const IMAGE_DOS_HEADER* doshdr = (const IMAGE_DOS_HEADER*)p; + const IMAGE_DOS_HEADER *doshdr = (const IMAGE_DOS_HEADER *)p; if (doshdr->e_magic != IMAGE_DOS_SIGNATURE) { XELOGE("PE signature mismatch; likely bad decryption/decompression"); return 1; @@ -825,16 +811,16 @@ int xe_xex2_load_pe(xe_xex2_ref xex) { p += doshdr->e_lfanew; // Verify NT signature (PE\0\0). - const IMAGE_NT_HEADERS32* nthdr = (const IMAGE_NT_HEADERS32*)(p); + const IMAGE_NT_HEADERS32 *nthdr = (const IMAGE_NT_HEADERS32 *)(p); if (nthdr->Signature != IMAGE_NT_SIGNATURE) { return 1; } // Verify matches an Xbox PE. - const IMAGE_FILE_HEADER* filehdr = &nthdr->FileHeader; + const IMAGE_FILE_HEADER *filehdr = &nthdr->FileHeader; if ((filehdr->Machine != IMAGE_FILE_MACHINE_POWERPCBE) || !(filehdr->Characteristics & IMAGE_FILE_32BIT_MACHINE)) { - return 1; + return 1; } // Verify the expected size. if (filehdr->SizeOfOptionalHeader != IMAGE_SIZEOF_NT_OPTIONAL_HEADER) { @@ -842,7 +828,7 @@ int xe_xex2_load_pe(xe_xex2_ref xex) { } // Verify optional header is 32bit. - const IMAGE_OPTIONAL_HEADER32* opthdr = &nthdr->OptionalHeader; + const IMAGE_OPTIONAL_HEADER32 *opthdr = &nthdr->OptionalHeader; if (opthdr->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) { return 1; } @@ -853,7 +839,7 @@ int xe_xex2_load_pe(xe_xex2_ref xex) { // Linker version - likely 8+ // Could be useful for recognizing certain patterns - //opthdr->MajorLinkerVersion; opthdr->MinorLinkerVersion; + // opthdr->MajorLinkerVersion; opthdr->MinorLinkerVersion; // Data directories of interest: // EXPORT IMAGE_EXPORT_DIRECTORY @@ -864,11 +850,11 @@ int xe_xex2_load_pe(xe_xex2_ref xex) { // ARCHITECTURE /IMAGE_ARCHITECTURE_HEADER/ ----- import thunks! // TLS IMAGE_TLS_DIRECTORY // IAT Import Address Table ptr - //opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_X].VirtualAddress / .Size + // opthdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_X].VirtualAddress / .Size // Quick scan to determine bounds of sections. size_t upper_address = 0; - const IMAGE_SECTION_HEADER* sechdr = IMAGE_FIRST_SECTION(nthdr); + const IMAGE_SECTION_HEADER *sechdr = IMAGE_FIRST_SECTION(nthdr); for (size_t n = 0; n < filehdr->NumberOfSections; n++, sechdr++) { const size_t physical_address = opthdr->ImageBase + sechdr->VirtualAddress; upper_address = @@ -878,25 +864,25 @@ int xe_xex2_load_pe(xe_xex2_ref xex) { // Setup/load sections. sechdr = IMAGE_FIRST_SECTION(nthdr); for (size_t n = 0; n < filehdr->NumberOfSections; n++, sechdr++) { - PESection* section = (PESection*)xe_calloc(sizeof(PESection)); - xe_copy_memory(section->name, sizeof(section->name), - sechdr->Name, sizeof(sechdr->Name)); - section->name[8] = 0; - section->raw_address = sechdr->PointerToRawData; - section->raw_size = sechdr->SizeOfRawData; - section->address = header->exe_address + sechdr->VirtualAddress; - section->size = sechdr->Misc.VirtualSize; - section->flags = sechdr->Characteristics; + PESection *section = (PESection *)xe_calloc(sizeof(PESection)); + xe_copy_memory(section->name, sizeof(section->name), sechdr->Name, + sizeof(sechdr->Name)); + section->name[8] = 0; + section->raw_address = sechdr->PointerToRawData; + section->raw_size = sechdr->SizeOfRawData; + section->address = header->exe_address + sechdr->VirtualAddress; + section->size = sechdr->Misc.VirtualSize; + section->flags = sechdr->Characteristics; xex->sections->push_back(section); } - //DumpTLSDirectory(pImageBase, pNTHeader, (PIMAGE_TLS_DIRECTORY32)0); - //DumpExportsSection(pImageBase, pNTHeader); + // DumpTLSDirectory(pImageBase, pNTHeader, (PIMAGE_TLS_DIRECTORY32)0); + // DumpExportsSection(pImageBase, pNTHeader); return 0; } -const PESection* xe_xex2_get_pe_section(xe_xex2_ref xex, const char* name) { - for (std::vector::iterator it = xex->sections->begin(); +const PESection *xe_xex2_get_pe_section(xe_xex2_ref xex, const char *name) { + for (std::vector::iterator it = xex->sections->begin(); it != xex->sections->end(); ++it) { if (!strcmp((*it)->name, name)) { return *it; @@ -907,7 +893,7 @@ const PESection* xe_xex2_get_pe_section(xe_xex2_ref xex, const char* name) { int xe_xex2_find_import_infos(xe_xex2_ref xex, const xe_xex2_import_library_t *library) { - uint8_t* mem = xex->memory->membase(); + uint8_t *mem = xex->memory->membase(); auto header = xe_xex2_get_header(xex); // Find library index for verification. @@ -941,7 +927,7 @@ int xe_xex2_find_import_infos(xe_xex2_ref xex, } // Allocate storage. - xe_xex2_import_info_t *infos = (xe_xex2_import_info_t*)xe_calloc( + xe_xex2_import_info_t *infos = (xe_xex2_import_info_t *)xe_calloc( info_count * sizeof(xe_xex2_import_info_t)); assert_not_null(infos); @@ -954,28 +940,24 @@ int xe_xex2_find_import_infos(xe_xex2_ref xex, const uint32_t type = (value & 0xFF000000) >> 24; // Verify library index matches given library. - //assert_true(library_index == ((value >> 16) & 0xFF)); + // assert_true(library_index == ((value >> 16) & 0xFF)); switch (type) { - case 0x00: - { - xe_xex2_import_info_t* info = &infos[i++]; - info->ordinal = value & 0xFFFF; + case 0x00: { + xe_xex2_import_info_t *info = &infos[i++]; + info->ordinal = value & 0xFFFF; info->value_address = record; - } - break; - case 0x01: - { + } break; + case 0x01: { // Thunk for previous record. assert_true(i > 0); - xe_xex2_import_info_t* info = &infos[i - 1]; + xe_xex2_import_info_t *info = &infos[i - 1]; assert_true(info->ordinal == (value & 0xFFFF)); info->thunk_address = record; - } - break; - default: - //assert_always(); - break; + } break; + default: + // assert_always(); + break; } } diff --git a/src/xenia/kernel/util/xex2.h b/src/xenia/kernel/util/xex2.h index f55b71caa..c6a63fd04 100644 --- a/src/xenia/kernel/util/xex2.h +++ b/src/xenia/kernel/util/xex2.h @@ -13,51 +13,47 @@ #include #include -typedef struct { - int reserved; -} xe_xex2_options_t; +typedef struct { int reserved; } xe_xex2_options_t; struct xe_xex2; typedef struct xe_xex2* xe_xex2_ref; typedef struct { uint32_t ordinal; - uint32_t value_address; // address to place value - uint32_t thunk_address; // NULL or address of thunk + uint32_t value_address; // address to place value + uint32_t thunk_address; // NULL or address of thunk } xe_xex2_import_info_t; enum xe_pe_section_flags_e { - kXEPESectionContainsCode = 0x00000020, - kXEPESectionContainsDataInit = 0x00000040, - kXEPESectionContainsDataUninit = 0x00000080, - kXEPESectionMemoryExecute = 0x20000000, - kXEPESectionMemoryRead = 0x40000000, - kXEPESectionMemoryWrite = 0x80000000, + kXEPESectionContainsCode = 0x00000020, + kXEPESectionContainsDataInit = 0x00000040, + kXEPESectionContainsDataUninit = 0x00000080, + kXEPESectionMemoryExecute = 0x20000000, + kXEPESectionMemoryRead = 0x40000000, + kXEPESectionMemoryWrite = 0x80000000, }; class PESection { -public: - char name[9]; // 8 + 1 for \0 - uint32_t raw_address; - uint32_t raw_size; - uint32_t address; - uint32_t size; - uint32_t flags; // kXEPESection* + public: + char name[9]; // 8 + 1 for \0 + uint32_t raw_address; + uint32_t raw_size; + uint32_t address; + uint32_t size; + uint32_t flags; // kXEPESection* }; -xe_xex2_ref xe_xex2_load(xe::Memory* memory, - const void* addr, const size_t length, - xe_xex2_options_t options); +xe_xex2_ref xe_xex2_load(xe::Memory* memory, const void* addr, + const size_t length, xe_xex2_options_t options); xe_xex2_ref xe_xex2_retain(xe_xex2_ref xex); void xe_xex2_release(xe_xex2_ref xex); -const xe_xex2_header_t *xe_xex2_get_header(xe_xex2_ref xex); +const xe_xex2_header_t* xe_xex2_get_header(xe_xex2_ref xex); const PESection* xe_xex2_get_pe_section(xe_xex2_ref xex, const char* name); int xe_xex2_get_import_infos(xe_xex2_ref xex, - const xe_xex2_import_library_t *library, - xe_xex2_import_info_t **out_import_infos, - size_t *out_import_info_count); - + const xe_xex2_import_library_t* library, + xe_xex2_import_info_t** out_import_infos, + size_t* out_import_info_count); #endif // XENIA_KERNEL_UTIL_XEX2_H_ diff --git a/src/xenia/kernel/util/xex2_info.h b/src/xenia/kernel/util/xex2_info.h index ea4042dff..16313a23c 100644 --- a/src/xenia/kernel/util/xex2_info.h +++ b/src/xenia/kernel/util/xex2_info.h @@ -12,7 +12,6 @@ #include - typedef enum { XEX_HEADER_RESOURCE_INFO = 0x000002FF, XEX_HEADER_FILE_FORMAT_INFO = 0x000003FF, @@ -456,5 +455,4 @@ typedef struct { xe_xex2_section_t* sections; } xe_xex2_header_t; - #endif // XENIA_KERNEL_XEX2_INFO_H_ diff --git a/src/xenia/kernel/xam_content.cc b/src/xenia/kernel/xam_content.cc index 3abd40fb6..5876181ef 100644 --- a/src/xenia/kernel/xam_content.cc +++ b/src/xenia/kernel/xam_content.cc @@ -14,20 +14,15 @@ #include #include - namespace xe { namespace kernel { - -SHIM_CALL XamContentGetLicenseMask_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamContentGetLicenseMask_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t mask_ptr = SHIM_GET_ARG_32(0); uint32_t overlapped_ptr = SHIM_GET_ARG_32(1); - XELOGD( - "XamContentGetLicenseMask(%.8X, %.8X)", - mask_ptr, - overlapped_ptr); + XELOGD("XamContentGetLicenseMask(%.8X, %.8X)", mask_ptr, overlapped_ptr); // Arcade games seem to call this and check the result mask for random bits. // If we fail, the games seem to use a hardcoded mask, which is likely trial. @@ -42,10 +37,9 @@ SHIM_CALL XamContentGetLicenseMask_shim( } } - // http://gameservice.googlecode.com/svn-history/r14/trunk/ContentManager.cpp -SHIM_CALL XamContentCreateEnumerator_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamContentCreateEnumerator_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t arg0 = SHIM_GET_ARG_32(0); uint32_t arg1 = SHIM_GET_ARG_32(1); uint32_t arg2 = SHIM_GET_ARG_32(2); @@ -54,18 +48,16 @@ SHIM_CALL XamContentCreateEnumerator_shim( uint32_t arg5 = SHIM_GET_ARG_32(5); uint32_t handle_ptr = SHIM_GET_ARG_32(6); - XELOGD( - "XamContentCreateEnumerator(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", - arg0, arg1, arg2, arg3, arg4, arg5, handle_ptr); + XELOGD("XamContentCreateEnumerator(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", + arg0, arg1, arg2, arg3, arg4, arg5, handle_ptr); SHIM_SET_MEM_32(handle_ptr, X_INVALID_HANDLE_VALUE); SHIM_SET_RETURN_32(X_ERROR_NO_MORE_FILES); } - -SHIM_CALL XamShowDeviceSelectorUI_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamShowDeviceSelectorUI_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t arg0 = SHIM_GET_ARG_32(0); uint32_t arg1 = SHIM_GET_ARG_32(1); uint32_t arg2 = SHIM_GET_ARG_32(2); @@ -73,19 +65,16 @@ SHIM_CALL XamShowDeviceSelectorUI_shim( uint32_t arg4 = SHIM_GET_ARG_32(4); uint32_t arg5 = SHIM_GET_ARG_32(5); - XELOGD( - "XamShowDeviceSelectorUI(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", - arg0, arg1, arg2, arg3, arg4, arg5); + XELOGD("XamShowDeviceSelectorUI(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", arg0, + arg1, arg2, arg3, arg4, arg5); SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); } - } // namespace kernel } // namespace xe - -void xe::kernel::xam::RegisterContentExports( - ExportResolver* export_resolver, KernelState* state) { +void xe::kernel::xam::RegisterContentExports(ExportResolver* export_resolver, + KernelState* state) { SHIM_SET_MAPPING("xam.xex", XamContentGetLicenseMask, state); SHIM_SET_MAPPING("xam.xex", XamContentCreateEnumerator, state); SHIM_SET_MAPPING("xam.xex", XamShowDeviceSelectorUI, state); diff --git a/src/xenia/kernel/xam_info.cc b/src/xenia/kernel/xam_info.cc index 32c7c8e9d..52efb89fd 100644 --- a/src/xenia/kernel/xam_info.cc +++ b/src/xenia/kernel/xam_info.cc @@ -16,13 +16,10 @@ #include #include - namespace xe { namespace kernel { - -SHIM_CALL XamGetSystemVersion_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamGetSystemVersion_shim(PPCContext* ppc_state, KernelState* state) { XELOGD("XamGetSystemVersion()"); // eh, just picking one. If we go too low we may break new games, but // this value seems to be used for conditionally loading symbols and if @@ -32,9 +29,7 @@ SHIM_CALL XamGetSystemVersion_shim( SHIM_SET_RETURN_64(0); } - -SHIM_CALL XGetAVPack_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XGetAVPack_shim(PPCContext* ppc_state, KernelState* state) { // DWORD // Not sure what the values are for this, but 6 is VGA. // Other likely values are 3/4/8 for HDMI or something. @@ -43,17 +38,13 @@ SHIM_CALL XGetAVPack_shim( SHIM_SET_RETURN_64(6); } - -SHIM_CALL XGetGameRegion_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XGetGameRegion_shim(PPCContext* ppc_state, KernelState* state) { XELOGD("XGetGameRegion()"); SHIM_SET_RETURN_64(XEX_REGION_ALL); } - -SHIM_CALL XGetLanguage_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XGetLanguage_shim(PPCContext* ppc_state, KernelState* state) { XELOGD("XGetLanguage()"); uint32_t desired_language = X_LANGUAGE_ENGLISH; @@ -71,36 +62,28 @@ SHIM_CALL XGetLanguage_shim( SHIM_SET_RETURN_64(desired_language); } - -SHIM_CALL XamLoaderGetLaunchDataSize_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamLoaderGetLaunchDataSize_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t size_ptr = SHIM_GET_ARG_32(0); - XELOGD( - "XamLoaderGetLaunchDataSize(%.8X)", - size_ptr); + XELOGD("XamLoaderGetLaunchDataSize(%.8X)", size_ptr); SHIM_SET_MEM_32(size_ptr, 0); SHIM_SET_RETURN_64(0); } - -SHIM_CALL XamLoaderGetLaunchData_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamLoaderGetLaunchData_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t buffer_ptr = SHIM_GET_ARG_32(0); uint32_t buffer_size = SHIM_GET_ARG_32(1); - XELOGD( - "XamLoaderGetLaunchData(%.8X, %d)", - buffer_ptr, buffer_size); + XELOGD("XamLoaderGetLaunchData(%.8X, %d)", buffer_ptr, buffer_size); SHIM_SET_RETURN_64(0); } - -SHIM_CALL XamEnumerate_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamEnumerate_shim(PPCContext* ppc_state, KernelState* state) { uint32_t handle = SHIM_GET_ARG_32(0); uint32_t zero = SHIM_GET_ARG_32(1); uint32_t buffer_ptr = SHIM_GET_ARG_32(2); @@ -108,14 +91,11 @@ SHIM_CALL XamEnumerate_shim( uint32_t item_count_ptr = SHIM_GET_ARG_32(4); uint32_t overlapped_ptr = SHIM_GET_ARG_32(5); - XELOGD( - "XamEnumerate(%.8X, %d, %d, %.8X, %d, %.8X, %.8X)", - handle, zero, buffer_ptr, buffer_length, item_count_ptr, - overlapped_ptr); + XELOGD("XamEnumerate(%.8X, %d, %d, %.8X, %d, %.8X, %.8X)", handle, zero, + buffer_ptr, buffer_length, item_count_ptr, overlapped_ptr); XEnumerator* e = nullptr; - if (XFAILED(state->object_table()->GetObject( - handle, (XObject**)&e))) { + if (XFAILED(state->object_table()->GetObject(handle, (XObject**)&e))) { SHIM_SET_RETURN_64(X_ERROR_INVALID_HANDLE); return; } @@ -135,13 +115,11 @@ SHIM_CALL XamEnumerate_shim( SHIM_SET_RETURN_64(0); } - } // namespace kernel } // namespace xe - -void xe::kernel::xam::RegisterInfoExports( - ExportResolver* export_resolver, KernelState* state) { +void xe::kernel::xam::RegisterInfoExports(ExportResolver* export_resolver, + KernelState* state) { SHIM_SET_MAPPING("xam.xex", XamGetSystemVersion, state); SHIM_SET_MAPPING("xam.xex", XGetAVPack, state); SHIM_SET_MAPPING("xam.xex", XGetGameRegion, state); diff --git a/src/xenia/kernel/xam_input.cc b/src/xenia/kernel/xam_input.cc index 196d2dbde..d2808f874 100644 --- a/src/xenia/kernel/xam_input.cc +++ b/src/xenia/kernel/xam_input.cc @@ -16,53 +16,40 @@ #include #include - namespace xe { namespace kernel { using xe::hid::InputSystem; - -SHIM_CALL XamResetInactivity_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamResetInactivity_shim(PPCContext* ppc_state, KernelState* state) { uint32_t unk = SHIM_GET_ARG_32(0); - XELOGD( - "XamResetInactivity(%d)", - unk); + XELOGD("XamResetInactivity(%d)", unk); // Result ignored. SHIM_SET_RETURN_64(0); } - -SHIM_CALL XamEnableInactivityProcessing_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamEnableInactivityProcessing_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t zero = SHIM_GET_ARG_32(0); uint32_t unk = SHIM_GET_ARG_32(2); - XELOGD( - "XamEnableInactivityProcessing(%d, %d)", - zero, - unk); + XELOGD("XamEnableInactivityProcessing(%d, %d)", zero, unk); // Expects 0. SHIM_SET_RETURN_64(0); } - // http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinputgetcapabilities(v=vs.85).aspx -SHIM_CALL XamInputGetCapabilities_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamInputGetCapabilities_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t user_index = SHIM_GET_ARG_32(0); uint32_t flags = SHIM_GET_ARG_32(1); uint32_t caps_ptr = SHIM_GET_ARG_32(2); - XELOGD( - "XamInputGetCapabilities(%d, %.8X, %.8X)", - user_index, - flags, - caps_ptr); + XELOGD("XamInputGetCapabilities(%d, %.8X, %.8X)", user_index, flags, + caps_ptr); if (!caps_ptr) { SHIM_SET_RETURN_32(X_ERROR_BAD_ARGUMENTS); @@ -79,19 +66,13 @@ SHIM_CALL XamInputGetCapabilities_shim( SHIM_SET_RETURN_32(result); } - // http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinputgetstate(v=vs.85).aspx -SHIM_CALL XamInputGetState_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamInputGetState_shim(PPCContext* ppc_state, KernelState* state) { uint32_t user_index = SHIM_GET_ARG_32(0); uint32_t one = SHIM_GET_ARG_32(1); uint32_t state_ptr = SHIM_GET_ARG_32(2); - XELOGD( - "XamInputGetState(%d, %.8X, %.8X)", - user_index, - one, - state_ptr); + XELOGD("XamInputGetState(%d, %.8X, %.8X)", user_index, one, state_ptr); // Games call this with a NULL state ptr, probably as a query. @@ -107,19 +88,13 @@ SHIM_CALL XamInputGetState_shim( SHIM_SET_RETURN_32(result); } - // http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinputsetstate(v=vs.85).aspx -SHIM_CALL XamInputSetState_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamInputSetState_shim(PPCContext* ppc_state, KernelState* state) { uint32_t user_index = SHIM_GET_ARG_32(0); uint32_t unk = SHIM_GET_ARG_32(1); uint32_t vibration_ptr = SHIM_GET_ARG_32(2); - XELOGD( - "XamInputSetState(%d, %.8X, %.8X)", - user_index, - unk, - vibration_ptr); + XELOGD("XamInputSetState(%d, %.8X, %.8X)", user_index, unk, vibration_ptr); if (!vibration_ptr) { SHIM_SET_RETURN_32(X_ERROR_BAD_ARGUMENTS); @@ -133,10 +108,8 @@ SHIM_CALL XamInputSetState_shim( SHIM_SET_RETURN_32(result); } - // http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinputgetkeystroke(v=vs.85).aspx -SHIM_CALL XamInputGetKeystroke_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamInputGetKeystroke_shim(PPCContext* ppc_state, KernelState* state) { uint32_t user_index = SHIM_GET_ARG_32(0); uint32_t flags = SHIM_GET_ARG_32(1); uint32_t keystroke_ptr = SHIM_GET_ARG_32(2); @@ -145,11 +118,8 @@ SHIM_CALL XamInputGetKeystroke_shim( // user index = index or XUSER_INDEX_ANY // flags = XINPUT_FLAG_GAMEPAD (| _ANYUSER | _ANYDEVICE) - XELOGD( - "XamInputGetKeystroke(%d, %.8X, %.8X)", - user_index, - flags, - keystroke_ptr); + XELOGD("XamInputGetKeystroke(%d, %.8X, %.8X)", user_index, flags, + keystroke_ptr); if (!keystroke_ptr) { SHIM_SET_RETURN_32(X_ERROR_BAD_ARGUMENTS); @@ -166,21 +136,17 @@ SHIM_CALL XamInputGetKeystroke_shim( SHIM_SET_RETURN_32(result); } - // Same as non-ex, just takes a pointer to user index. -SHIM_CALL XamInputGetKeystrokeEx_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamInputGetKeystrokeEx_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t user_index_ptr = SHIM_GET_ARG_32(0); uint32_t flags = SHIM_GET_ARG_32(1); uint32_t keystroke_ptr = SHIM_GET_ARG_32(2); uint32_t user_index = SHIM_MEM_32(user_index_ptr); - XELOGD( - "XamInputGetKeystroke(%.8X(%.d), %.8X, %.8X)", - user_index_ptr, user_index, - flags, - keystroke_ptr); + XELOGD("XamInputGetKeystroke(%.8X(%.d), %.8X, %.8X)", user_index_ptr, + user_index, flags, keystroke_ptr); if (!keystroke_ptr) { SHIM_SET_RETURN_32(X_ERROR_BAD_ARGUMENTS); @@ -198,18 +164,13 @@ SHIM_CALL XamInputGetKeystrokeEx_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL XamUserGetDeviceContext_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamUserGetDeviceContext_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t user_index = SHIM_GET_ARG_32(0); uint32_t unk = SHIM_GET_ARG_32(1); uint32_t out_ptr = SHIM_GET_ARG_32(2); - XELOGD( - "XamUserGetDeviceContext(%d, %d, %.8X)", - user_index, - unk, - out_ptr); + XELOGD("XamUserGetDeviceContext(%d, %d, %.8X)", user_index, unk, out_ptr); // Games check the result - usually with some masking. // If this function fails they assume zero, so let's fail AND @@ -222,13 +183,11 @@ SHIM_CALL XamUserGetDeviceContext_shim( } } - } // namespace kernel } // namespace xe - -void xe::kernel::xam::RegisterInputExports( - ExportResolver* export_resolver, KernelState* state) { +void xe::kernel::xam::RegisterInputExports(ExportResolver* export_resolver, + KernelState* state) { SHIM_SET_MAPPING("xam.xex", XamResetInactivity, state); SHIM_SET_MAPPING("xam.xex", XamEnableInactivityProcessing, state); SHIM_SET_MAPPING("xam.xex", XamInputGetCapabilities, state); diff --git a/src/xenia/kernel/xam_module.cc b/src/xenia/kernel/xam_module.cc index 51649628e..8fa2edff0 100644 --- a/src/xenia/kernel/xam_module.cc +++ b/src/xenia/kernel/xam_module.cc @@ -14,21 +14,19 @@ #include #include - namespace xe { namespace kernel { - -XamModule::XamModule(Emulator* emulator, KernelState* kernel_state) : - XKernelModule(kernel_state, "xe:\\xam.xex") { - // Build the export table used for resolution. - #include +XamModule::XamModule(Emulator* emulator, KernelState* kernel_state) + : XKernelModule(kernel_state, "xe:\\xam.xex") { +// Build the export table used for resolution. +#include static KernelExport xam_export_table[] = { - #include +#include }; - #include - export_resolver_->RegisterTable( - "xam.xex", xam_export_table, poly::countof(xam_export_table)); +#include + export_resolver_->RegisterTable("xam.xex", xam_export_table, + poly::countof(xam_export_table)); // Register all exported functions. xam::RegisterContentExports(export_resolver_, kernel_state); @@ -43,8 +41,7 @@ XamModule::XamModule(Emulator* emulator, KernelState* kernel_state) : xam::RegisterVoiceExports(export_resolver_, kernel_state); } -XamModule::~XamModule() { -} +XamModule::~XamModule() {} } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/xam_module.h b/src/xenia/kernel/xam_module.h index 773ce1149..0adab60de 100644 --- a/src/xenia/kernel/xam_module.h +++ b/src/xenia/kernel/xam_module.h @@ -12,7 +12,6 @@ #include #include - #include #include #include @@ -20,18 +19,15 @@ namespace xe { namespace kernel { - class XamModule : public XKernelModule { -public: + public: XamModule(Emulator* emulator, KernelState* kernel_state); virtual ~XamModule(); -private: + private: }; - } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XAM_H_ diff --git a/src/xenia/kernel/xam_msg.cc b/src/xenia/kernel/xam_msg.cc index 54399c7a9..29d537956 100644 --- a/src/xenia/kernel/xam_msg.cc +++ b/src/xenia/kernel/xam_msg.cc @@ -15,68 +15,56 @@ #include #include - namespace xe { namespace kernel { - -SHIM_CALL XMsgInProcessCall_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XMsgInProcessCall_shim(PPCContext* ppc_state, KernelState* state) { uint32_t app = SHIM_GET_ARG_32(0); uint32_t message = SHIM_GET_ARG_32(1); uint32_t arg1 = SHIM_GET_ARG_32(2); uint32_t arg2 = SHIM_GET_ARG_32(3); - XELOGD( - "XMsgInProcessCall(%.8X, %.8X, %.8X, %.8X)", - app, message, arg1, arg2); + XELOGD("XMsgInProcessCall(%.8X, %.8X, %.8X, %.8X)", app, message, arg1, arg2); - auto result = state->app_manager()->DispatchMessageSync( - app, message, arg1, arg2); + auto result = + state->app_manager()->DispatchMessageSync(app, message, arg1, arg2); if (result == X_ERROR_NOT_FOUND) { XELOGE("XMsgInProcessCall: app %.8X undefined", app); } SHIM_SET_RETURN_32(result); } - -SHIM_CALL XMsgStartIORequest_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XMsgStartIORequest_shim(PPCContext* ppc_state, KernelState* state) { uint32_t app = SHIM_GET_ARG_32(0); uint32_t message = SHIM_GET_ARG_32(1); uint32_t overlapped_ptr = SHIM_GET_ARG_32(2); uint32_t buffer = SHIM_GET_ARG_32(3); uint32_t buffer_length = SHIM_GET_ARG_32(4); - XELOGD( - "XMsgStartIORequest(%.8X, %.8X, %.8X, %.8X, %d)", - app, message, overlapped_ptr, buffer, buffer_length); + XELOGD("XMsgStartIORequest(%.8X, %.8X, %.8X, %.8X, %d)", app, message, + overlapped_ptr, buffer, buffer_length); assert_zero(overlapped_ptr); - auto result = state->app_manager()->DispatchMessageAsync( - app, message, buffer, buffer_length); + auto result = state->app_manager()->DispatchMessageAsync(app, message, buffer, + buffer_length); if (result == X_ERROR_NOT_FOUND) { XELOGE("XMsgStartIORequest: app %.8X undefined", app); } SHIM_SET_RETURN_32(result); } - -SHIM_CALL XMsgCancelIORequest_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XMsgCancelIORequest_shim(PPCContext* ppc_state, KernelState* state) { uint32_t overlapped_ptr = SHIM_GET_ARG_32(0); uint32_t wait = SHIM_GET_ARG_32(1); - XELOGD( - "XMsgCancelIORequest(%.8X, %d)", - overlapped_ptr, wait); + XELOGD("XMsgCancelIORequest(%.8X, %d)", overlapped_ptr, wait); X_HANDLE event_handle = XOverlappedGetEvent(SHIM_MEM_ADDR(overlapped_ptr)); if (event_handle && wait) { XEvent* ev = nullptr; if (XSUCCEEDED(state->object_table()->GetObject( - event_handle, reinterpret_cast(&ev)))) { + event_handle, reinterpret_cast(&ev)))) { ev->Wait(0, 0, true, nullptr); ev->Release(); } @@ -85,13 +73,11 @@ SHIM_CALL XMsgCancelIORequest_shim( SHIM_SET_RETURN_32(0); } - } // namespace kernel } // namespace xe - -void xe::kernel::xam::RegisterMsgExports( - ExportResolver* export_resolver, KernelState* state) { +void xe::kernel::xam::RegisterMsgExports(ExportResolver* export_resolver, + KernelState* state) { SHIM_SET_MAPPING("xam.xex", XMsgInProcessCall, state); SHIM_SET_MAPPING("xam.xex", XMsgStartIORequest, state); SHIM_SET_MAPPING("xam.xex", XMsgCancelIORequest, state); diff --git a/src/xenia/kernel/xam_net.cc b/src/xenia/kernel/xam_net.cc index eacec8169..f141fe8b8 100644 --- a/src/xenia/kernel/xam_net.cc +++ b/src/xenia/kernel/xam_net.cc @@ -16,48 +16,33 @@ #include #include - namespace xe { namespace kernel { - -SHIM_CALL NetDll_XNetStartup_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NetDll_XNetStartup_shim(PPCContext* ppc_state, KernelState* state) { uint32_t arg0 = SHIM_GET_ARG_32(0); uint32_t params_ptr = SHIM_GET_ARG_32(1); - XELOGD( - "NetDll_XNetStartup(%d, %.8X)", - arg0, - params_ptr); + XELOGD("NetDll_XNetStartup(%d, %.8X)", arg0, params_ptr); SHIM_SET_RETURN_64(0); } -SHIM_CALL NetDll_XNetCleanup_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NetDll_XNetCleanup_shim(PPCContext* ppc_state, KernelState* state) { uint32_t arg0 = SHIM_GET_ARG_32(0); uint32_t params_ptr = SHIM_GET_ARG_32(1); - XELOGD( - "NetDll_XNetCleanup(%d, %.8X)", - arg0, - params_ptr); + XELOGD("NetDll_XNetCleanup(%d, %.8X)", arg0, params_ptr); SHIM_SET_RETURN_64(0); } -SHIM_CALL NetDll_XNetRandom_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NetDll_XNetRandom_shim(PPCContext* ppc_state, KernelState* state) { uint32_t arg0 = SHIM_GET_ARG_32(0); uint32_t buffer_ptr = SHIM_GET_ARG_32(1); uint32_t length = SHIM_GET_ARG_32(2); - XELOGD( - "NetDll_XNetRandom(%d, %.8X, %d)", - arg0, - buffer_ptr, - length); + XELOGD("NetDll_XNetRandom(%d, %.8X, %d)", arg0, buffer_ptr, length); // For now, constant values. // This makes replicating things easier. @@ -66,17 +51,12 @@ SHIM_CALL NetDll_XNetRandom_shim( SHIM_SET_RETURN_64(0); } -SHIM_CALL NetDll_WSAStartup_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NetDll_WSAStartup_shim(PPCContext* ppc_state, KernelState* state) { uint32_t arg0 = SHIM_GET_ARG_32(0); uint32_t version = SHIM_GET_ARG_16(1); uint32_t data_ptr = SHIM_GET_ARG_32(2); - XELOGD( - "NetDll_WSAStartup(%d, %.4X, %.8X)", - arg0, - version, - data_ptr); + XELOGD("NetDll_WSAStartup(%d, %.4X, %.8X)", arg0, version, data_ptr); if (data_ptr) { SHIM_SET_MEM_16(data_ptr + 0x000, version); @@ -94,109 +74,76 @@ SHIM_CALL NetDll_WSAStartup_shim( SHIM_SET_RETURN_64(0); } -SHIM_CALL NetDll_WSAGetLastError_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NetDll_WSAGetLastError_shim(PPCContext* ppc_state, + KernelState* state) { XELOGD("NetDll_WSAGetLastError()"); SHIM_SET_RETURN_32(10093L); // WSANOTINITIALISED } -SHIM_CALL NetDll_XNetGetTitleXnAddr_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NetDll_XNetGetTitleXnAddr_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t arg0 = SHIM_GET_ARG_32(0); uint32_t arg1 = SHIM_GET_ARG_32(1); - XELOGD( - "NetDll_XNetGetTitleXnAddr(%d, %.8X)", - arg0, - arg1); + XELOGD("NetDll_XNetGetTitleXnAddr(%d, %.8X)", arg0, arg1); SHIM_SET_RETURN_32(0x00000001); } -SHIM_CALL NetDll_XNetGetEthernetLinkStatus_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NetDll_XNetGetEthernetLinkStatus_shim(PPCContext* ppc_state, + KernelState* state) { // Games seem to call this before *Startup. If we return 0, they don't even // try. uint32_t arg0 = SHIM_GET_ARG_32(0); - XELOGD( - "NetDll_XNetGetEthernetLinkStatus(%d)", - arg0); + XELOGD("NetDll_XNetGetEthernetLinkStatus(%d)", arg0); SHIM_SET_RETURN_32(0); } -SHIM_CALL NetDll_inet_addr_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NetDll_inet_addr_shim(PPCContext* ppc_state, KernelState* state) { uint32_t cp_ptr = SHIM_GET_ARG_32(0); - XELOGD( - "NetDll_inet_addr(%.8X)", - cp_ptr); - SHIM_SET_RETURN_32(0xFFFFFFFF); // X_INADDR_NONE + XELOGD("NetDll_inet_addr(%.8X)", cp_ptr); + SHIM_SET_RETURN_32(0xFFFFFFFF); // X_INADDR_NONE } -SHIM_CALL NetDll_socket_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NetDll_socket_shim(PPCContext* ppc_state, KernelState* state) { uint32_t arg0 = SHIM_GET_ARG_32(0); uint32_t af = SHIM_GET_ARG_32(1); uint32_t type = SHIM_GET_ARG_32(2); uint32_t protocol = SHIM_GET_ARG_32(3); - XELOGD( - "NetDll_socket(%d, %d, %d, %d)", - arg0, - af, - type, - protocol); + XELOGD("NetDll_socket(%d, %d, %d, %d)", arg0, af, type, protocol); SHIM_SET_RETURN_32(X_SOCKET_ERROR); } -SHIM_CALL NetDll_setsockopt_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NetDll_setsockopt_shim(PPCContext* ppc_state, KernelState* state) { uint32_t arg0 = SHIM_GET_ARG_32(0); uint32_t socket_ptr = SHIM_GET_ARG_32(1); uint32_t level = SHIM_GET_ARG_32(2); uint32_t optname = SHIM_GET_ARG_32(3); uint32_t optval_ptr = SHIM_GET_ARG_32(4); uint32_t optlen = SHIM_GET_ARG_32(5); - XELOGD( - "NetDll_setsockopt(%d, %.8X, %d, %d, %.8X, %d)", - arg0, - socket_ptr, - level, - optname, - optval_ptr, - optlen); + XELOGD("NetDll_setsockopt(%d, %.8X, %d, %d, %.8X, %d)", arg0, socket_ptr, + level, optname, optval_ptr, optlen); SHIM_SET_RETURN_32(X_SOCKET_ERROR); } -SHIM_CALL NetDll_connect_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NetDll_connect_shim(PPCContext* ppc_state, KernelState* state) { uint32_t socket_ptr = SHIM_GET_ARG_32(0); uint32_t sockaddr_ptr = SHIM_GET_ARG_32(1); uint32_t namelen = SHIM_GET_ARG_32(2); - XELOGD( - "NetDll_connect(%.8X, %.8X, %d)", - socket_ptr, - sockaddr_ptr, - namelen); + XELOGD("NetDll_connect(%.8X, %.8X, %d)", socket_ptr, sockaddr_ptr, namelen); SHIM_SET_RETURN_32(X_SOCKET_ERROR); } -SHIM_CALL NetDll_recv_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NetDll_recv_shim(PPCContext* ppc_state, KernelState* state) { uint32_t arg0 = SHIM_GET_ARG_32(0); uint32_t socket_ptr = SHIM_GET_ARG_32(1); uint32_t buf_ptr = SHIM_GET_ARG_32(2); uint32_t len = SHIM_GET_ARG_32(3); uint32_t flags = SHIM_GET_ARG_32(4); - XELOGD( - "NetDll_recv(%d, %.8X, %.8X, %d, %d)", - arg0, - socket_ptr, - buf_ptr, - len, - flags); + XELOGD("NetDll_recv(%d, %.8X, %.8X, %d, %d)", arg0, socket_ptr, buf_ptr, len, + flags); SHIM_SET_RETURN_32(X_SOCKET_ERROR); } -SHIM_CALL NetDll_recvfrom_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NetDll_recvfrom_shim(PPCContext* ppc_state, KernelState* state) { uint32_t arg0 = SHIM_GET_ARG_32(0); uint32_t socket_ptr = SHIM_GET_ARG_32(1); uint32_t buf_ptr = SHIM_GET_ARG_32(2); @@ -204,42 +151,27 @@ SHIM_CALL NetDll_recvfrom_shim( uint32_t flags = SHIM_GET_ARG_32(4); uint32_t from_ptr = SHIM_GET_ARG_32(5); uint32_t fromlen_ptr = SHIM_GET_ARG_32(6); - XELOGD( - "NetDll_recvfrom(%d, %.8X, %.8X, %d, %d, %.8X, %.8X)", - arg0, - socket_ptr, - buf_ptr, - len, - flags, - from_ptr, - fromlen_ptr); + XELOGD("NetDll_recvfrom(%d, %.8X, %.8X, %d, %d, %.8X, %.8X)", arg0, + socket_ptr, buf_ptr, len, flags, from_ptr, fromlen_ptr); SHIM_SET_RETURN_32(X_SOCKET_ERROR); } -SHIM_CALL NetDll_send_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NetDll_send_shim(PPCContext* ppc_state, KernelState* state) { uint32_t arg0 = SHIM_GET_ARG_32(0); uint32_t socket_ptr = SHIM_GET_ARG_32(1); uint32_t buf_ptr = SHIM_GET_ARG_32(2); uint32_t len = SHIM_GET_ARG_32(3); uint32_t flags = SHIM_GET_ARG_32(4); - XELOGD( - "NetDll_send(%d,%.8X, %.8X, %d, %d)", - arg0, - socket_ptr, - buf_ptr, - len, - flags); + XELOGD("NetDll_send(%d,%.8X, %.8X, %d, %d)", arg0, socket_ptr, buf_ptr, len, + flags); SHIM_SET_RETURN_32(X_SOCKET_ERROR); } - } // namespace kernel } // namespace xe - -void xe::kernel::xam::RegisterNetExports( - ExportResolver* export_resolver, KernelState* state) { +void xe::kernel::xam::RegisterNetExports(ExportResolver* export_resolver, + KernelState* state) { SHIM_SET_MAPPING("xam.xex", NetDll_XNetStartup, state); SHIM_SET_MAPPING("xam.xex", NetDll_XNetCleanup, state); SHIM_SET_MAPPING("xam.xex", NetDll_XNetRandom, state); diff --git a/src/xenia/kernel/xam_notify.cc b/src/xenia/kernel/xam_notify.cc index 83e673ce5..dfd753ef8 100644 --- a/src/xenia/kernel/xam_notify.cc +++ b/src/xenia/kernel/xam_notify.cc @@ -15,20 +15,15 @@ #include #include - namespace xe { namespace kernel { - -SHIM_CALL XamNotifyCreateListener_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamNotifyCreateListener_shim(PPCContext* ppc_state, + KernelState* state) { uint64_t mask = SHIM_GET_ARG_64(0); uint32_t one = SHIM_GET_ARG_32(1); - XELOGD( - "XamNotifyCreateListener(%.8llX, %d)", - mask, - one); + XELOGD("XamNotifyCreateListener(%.8llX, %d)", mask, one); // r4=1 may indicate user process? @@ -42,21 +37,15 @@ SHIM_CALL XamNotifyCreateListener_shim( SHIM_SET_RETURN_64(handle); } - // http://ffplay360.googlecode.com/svn/Test/Common/AtgSignIn.cpp -SHIM_CALL XNotifyGetNext_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XNotifyGetNext_shim(PPCContext* ppc_state, KernelState* state) { uint32_t handle = SHIM_GET_ARG_32(0); uint32_t match_id = SHIM_GET_ARG_32(1); uint32_t id_ptr = SHIM_GET_ARG_32(2); uint32_t param_ptr = SHIM_GET_ARG_32(3); - XELOGD( - "XNotifyGetNext(%.8X, %.8X, %.8X, %.8X)", - handle, - match_id, - id_ptr, - param_ptr); + XELOGD("XNotifyGetNext(%.8X, %.8X, %.8X, %.8X)", handle, match_id, id_ptr, + param_ptr); if (!handle) { SHIM_SET_RETURN_64(0); @@ -65,8 +54,7 @@ SHIM_CALL XNotifyGetNext_shim( // Grab listener. XNotifyListener* listener = NULL; - if (XFAILED(state->object_table()->GetObject( - handle, (XObject**)&listener))) { + if (XFAILED(state->object_table()->GetObject(handle, (XObject**)&listener))) { SHIM_SET_RETURN_64(0); return; } @@ -95,25 +83,19 @@ SHIM_CALL XNotifyGetNext_shim( SHIM_SET_RETURN_64(dequeued ? 1 : 0); } - -SHIM_CALL XNotifyPositionUI_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XNotifyPositionUI_shim(PPCContext* ppc_state, KernelState* state) { uint32_t position = SHIM_GET_ARG_32(0); - XELOGD( - "XNotifyPositionUI(%.8X)", - position); + XELOGD("XNotifyPositionUI(%.8X)", position); // Ignored. } - } // namespace kernel } // namespace xe - -void xe::kernel::xam::RegisterNotifyExports( - ExportResolver* export_resolver, KernelState* state) { +void xe::kernel::xam::RegisterNotifyExports(ExportResolver* export_resolver, + KernelState* state) { SHIM_SET_MAPPING("xam.xex", XamNotifyCreateListener, state); SHIM_SET_MAPPING("xam.xex", XNotifyGetNext, state); SHIM_SET_MAPPING("xam.xex", XNotifyPositionUI, state); diff --git a/src/xenia/kernel/xam_ordinals.h b/src/xenia/kernel/xam_ordinals.h index 3c50ab2f7..4b85e613c 100644 --- a/src/xenia/kernel/xam_ordinals.h +++ b/src/xenia/kernel/xam_ordinals.h @@ -12,18 +12,15 @@ #include #include - #include - // Build an ordinal enum to make it easy to lookup ordinals. #include namespace ordinals { enum { - #include +#include }; } // namespace ordinals #include - #endif // XENIA_KERNEL_XAM_ORDINALS_H_ diff --git a/src/xenia/kernel/xam_private.h b/src/xenia/kernel/xam_private.h index 1884397e1..a79b2082b 100644 --- a/src/xenia/kernel/xam_private.h +++ b/src/xenia/kernel/xam_private.h @@ -12,10 +12,8 @@ #include #include - #include - namespace xe { namespace kernel { @@ -23,7 +21,8 @@ class KernelState; namespace xam { // Registration functions, one per file. -void RegisterContentExports(ExportResolver* export_resolver, KernelState* state); +void RegisterContentExports(ExportResolver* export_resolver, + KernelState* state); void RegisterInfoExports(ExportResolver* export_resolver, KernelState* state); void RegisterInputExports(ExportResolver* export_resolver, KernelState* state); void RegisterMsgExports(ExportResolver* export_resolver, KernelState* state); @@ -38,5 +37,4 @@ void RegisterVoiceExports(ExportResolver* export_resolver, KernelState* state); } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XAM_PRIVATE_H_ diff --git a/src/xenia/kernel/xam_ui.cc b/src/xenia/kernel/xam_ui.cc index fa477d877..4b7302b95 100644 --- a/src/xenia/kernel/xam_ui.cc +++ b/src/xenia/kernel/xam_ui.cc @@ -14,13 +14,11 @@ #include #include - namespace xe { namespace kernel { // http://www.se7ensins.com/forums/threads/working-xshowmessageboxui.844116/?jdfwkey=sb0vm -SHIM_CALL XamShowMessageBoxUI_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamShowMessageBoxUI_shim(PPCContext* ppc_state, KernelState* state) { uint32_t user_index = SHIM_GET_ARG_32(0); uint32_t title_ptr = SHIM_GET_ARG_32(1); uint32_t text_ptr = SHIM_GET_ARG_32(2); @@ -61,12 +59,10 @@ SHIM_CALL XamShowMessageBoxUI_shim( SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); } - } // namespace kernel } // namespace xe - -void xe::kernel::xam::RegisterUIExports( - ExportResolver* export_resolver, KernelState* state) { +void xe::kernel::xam::RegisterUIExports(ExportResolver* export_resolver, + KernelState* state) { SHIM_SET_MAPPING("xam.xex", XamShowMessageBoxUI, state); } diff --git a/src/xenia/kernel/xam_user.cc b/src/xenia/kernel/xam_user.cc index 300cbf07b..90844d873 100644 --- a/src/xenia/kernel/xam_user.cc +++ b/src/xenia/kernel/xam_user.cc @@ -16,22 +16,15 @@ #include #include - namespace xe { namespace kernel { - -SHIM_CALL XamUserGetXUID_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamUserGetXUID_shim(PPCContext* ppc_state, KernelState* state) { uint32_t user_index = SHIM_GET_ARG_32(0); uint32_t unk = SHIM_GET_ARG_32(1); uint32_t xuid_ptr = SHIM_GET_ARG_32(2); - XELOGD( - "XamUserGetXUID(%d, %.8X, %.8X)", - user_index, - unk, - xuid_ptr); + XELOGD("XamUserGetXUID(%d, %.8X, %.8X)", user_index, unk, xuid_ptr); if (user_index == 0) { const auto& user_profile = state->user_profile(); @@ -44,14 +37,11 @@ SHIM_CALL XamUserGetXUID_shim( } } - -SHIM_CALL XamUserGetSigninState_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamUserGetSigninState_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t user_index = SHIM_GET_ARG_32(0); - XELOGD( - "XamUserGetSigninState(%d)", - user_index); + XELOGD("XamUserGetSigninState(%d)", user_index); // Lie and say we are signed in, but local-only. // This should keep games from asking us to sign in and also keep them @@ -64,24 +54,20 @@ SHIM_CALL XamUserGetSigninState_shim( } } - -SHIM_CALL XamUserGetSigninInfo_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamUserGetSigninInfo_shim(PPCContext* ppc_state, KernelState* state) { uint32_t user_index = SHIM_GET_ARG_32(0); uint32_t flags = SHIM_GET_ARG_32(1); uint32_t info_ptr = SHIM_GET_ARG_32(2); - XELOGD( - "XamUserGetSigninInfo(%d, %.8X, %.8X)", - user_index, flags, info_ptr); + XELOGD("XamUserGetSigninInfo(%d, %.8X, %.8X)", user_index, flags, info_ptr); if (user_index == 0) { const auto& user_profile = state->user_profile(); SHIM_SET_MEM_64(info_ptr + 0, user_profile->xuid()); - SHIM_SET_MEM_32(info_ptr + 8, 0); // maybe zero? + SHIM_SET_MEM_32(info_ptr + 8, 0); // maybe zero? SHIM_SET_MEM_32(info_ptr + 12, user_profile->signin_state()); - SHIM_SET_MEM_32(info_ptr + 16, 0); // ? - SHIM_SET_MEM_32(info_ptr + 20, 0); // ? + SHIM_SET_MEM_32(info_ptr + 16, 0); // ? + SHIM_SET_MEM_32(info_ptr + 20, 0); // ? char* buffer = (char*)SHIM_MEM_ADDR(info_ptr + 24); strcpy(buffer, user_profile->name().data()); SHIM_SET_RETURN_32(0); @@ -90,16 +76,12 @@ SHIM_CALL XamUserGetSigninInfo_shim( } } - -SHIM_CALL XamUserGetName_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamUserGetName_shim(PPCContext* ppc_state, KernelState* state) { uint32_t user_index = SHIM_GET_ARG_32(0); uint32_t buffer_ptr = SHIM_GET_ARG_32(1); uint32_t buffer_len = SHIM_GET_ARG_32(2); - XELOGD( - "XamUserGetName(%d, %.8X, %d)", - user_index, buffer_ptr, buffer_len); + XELOGD("XamUserGetName(%d, %.8X, %d)", user_index, buffer_ptr, buffer_len); if (user_index == 0) { const auto& user_profile = state->user_profile(); @@ -111,10 +93,9 @@ SHIM_CALL XamUserGetName_shim( } } - // http://freestyledash.googlecode.com/svn/trunk/Freestyle/Tools/Generic/xboxtools.cpp -SHIM_CALL XamUserReadProfileSettings_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamUserReadProfileSettings_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t title_id = SHIM_GET_ARG_32(0); uint32_t user_index = SHIM_GET_ARG_32(1); uint32_t unk_0 = SHIM_GET_ARG_32(2); @@ -130,7 +111,8 @@ SHIM_CALL XamUserReadProfileSettings_shim( uint32_t buffer_size = SHIM_MEM_32(buffer_size_ptr); XELOGD( - "XamUserReadProfileSettings(%.8X, %d, %d, %d, %d, %.8X, %.8X(%d), %.8X, %.8X)", + "XamUserReadProfileSettings(%.8X, %d, %d, %d, %d, %.8X, %.8X(%d), %.8X, " + "%.8X)", title_id, user_index, unk_0, unk_1, setting_count, setting_ids_ptr, buffer_size_ptr, buffer_size, buffer_ptr, overlapped_ptr); @@ -171,14 +153,16 @@ SHIM_CALL XamUserReadProfileSettings_shim( uint32_t setting_id = SHIM_MEM_32(setting_ids_ptr + n * 4); auto setting = user_profile->GetSetting(setting_id); if (setting) { - auto extra_size = static_cast(setting->extra_size());; + auto extra_size = static_cast(setting->extra_size()); + ; size_needed += extra_size; } } SHIM_SET_MEM_32(buffer_size_ptr, size_needed); if (buffer_size < size_needed) { if (overlapped_ptr) { - state->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_INSUFFICIENT_BUFFER); + state->CompleteOverlappedImmediate(overlapped_ptr, + X_ERROR_INSUFFICIENT_BUFFER); } SHIM_SET_RETURN_32(X_ERROR_INSUFFICIENT_BUFFER); return; @@ -201,8 +185,7 @@ SHIM_CALL XamUserReadProfileSettings_shim( SHIM_SET_MEM_32(user_data_ptr + 16, setting_id); if (setting) { buffer_offset = setting->Append(SHIM_MEM_ADDR(user_data_ptr + 24), - SHIM_MEM_ADDR(buffer_ptr), - buffer_offset); + SHIM_MEM_ADDR(buffer_ptr), buffer_offset); } else { memset(SHIM_MEM_ADDR(user_data_ptr + 24), 0, 16); } @@ -217,18 +200,18 @@ SHIM_CALL XamUserReadProfileSettings_shim( } } - -SHIM_CALL XamUserWriteProfileSettings_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamUserWriteProfileSettings_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t user_index = SHIM_GET_ARG_32(0); uint32_t unknown = SHIM_GET_ARG_32(1); uint32_t setting_count = SHIM_GET_ARG_32(2); uint32_t settings_ptr = SHIM_GET_ARG_32(3); uint32_t overlapped_ptr = SHIM_GET_ARG_32(4); - + XELOGD( - "XamUserWriteProfileSettings(%.8X, %d, %d, %d, %d, %.8X, %.8X(%d), %.8X, %.8X)", - user_index, unknown, setting_count, settings_ptr, overlapped_ptr); + "XamUserWriteProfileSettings(%.8X, %d, %d, %d, %d, %.8X, %.8X(%d), %.8X, " + "%.8X)", + user_index, unknown, setting_count, settings_ptr, overlapped_ptr); if (!setting_count || !settings_ptr) { SHIM_SET_RETURN_32(X_ERROR_INVALID_PARAMETER); @@ -251,22 +234,19 @@ SHIM_CALL XamUserWriteProfileSettings_shim( if (overlapped_ptr) { state->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS); SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); - } - else { + } else { SHIM_SET_RETURN_32(X_ERROR_SUCCESS); } } - -SHIM_CALL XamUserCheckPrivilege_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamUserCheckPrivilege_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t user_index = SHIM_GET_ARG_32(0); uint32_t mask = SHIM_GET_ARG_32(1); uint32_t out_value_ptr = SHIM_GET_ARG_32(2); - XELOGD( - "XamUserCheckPrivilege(%d, %.8X, %.8X)", - user_index, mask, out_value_ptr); + XELOGD("XamUserCheckPrivilege(%d, %.8X, %.8X)", user_index, mask, + out_value_ptr); // If we deny everything, games should hopefully not try to do stuff. SHIM_SET_MEM_32(out_value_ptr, 0); @@ -274,15 +254,11 @@ SHIM_CALL XamUserCheckPrivilege_shim( SHIM_SET_RETURN_32(X_ERROR_SUCCESS); } - -SHIM_CALL XamShowSigninUI_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamShowSigninUI_shim(PPCContext* ppc_state, KernelState* state) { uint32_t unk_0 = SHIM_GET_ARG_32(0); uint32_t unk_mask = SHIM_GET_ARG_32(1); - XELOGD( - "XamShowSigninUI(%d, %.8X)", - unk_0, unk_mask); + XELOGD("XamShowSigninUI(%d, %.8X)", unk_0, unk_mask); // Mask values vary. Probably matching user types? Local/remote? // Games seem to sit and loop until we trigger this notification. @@ -291,9 +267,8 @@ SHIM_CALL XamShowSigninUI_shim( SHIM_SET_RETURN_32(X_ERROR_SUCCESS); } - -SHIM_CALL XamUserCreateAchievementEnumerator_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamUserCreateAchievementEnumerator_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t title_id = SHIM_GET_ARG_32(0); uint32_t user_index = SHIM_GET_ARG_32(1); uint32_t xuid = SHIM_GET_ARG_32(2); @@ -304,7 +279,8 @@ SHIM_CALL XamUserCreateAchievementEnumerator_shim( uint32_t handle_ptr = SHIM_GET_ARG_32(7); XELOGD( - "XamUserCreateAchievementEnumerator(%.8X, %d, %.8X, %.8X, %d, %d, %.8X, %.8X)", + "XamUserCreateAchievementEnumerator(%.8X, %d, %.8X, %.8X, %d, %d, %.8X, " + "%.8X)", title_id, user_index, xuid, flags, offset, count, buffer, handle_ptr); XEnumerator* e = new XEnumerator(state); @@ -315,9 +291,7 @@ SHIM_CALL XamUserCreateAchievementEnumerator_shim( SHIM_SET_RETURN_32(X_ERROR_SUCCESS); } - -SHIM_CALL XamWriteGamerTile_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamWriteGamerTile_shim(PPCContext* ppc_state, KernelState* state) { uint32_t arg0 = SHIM_GET_ARG_32(0); uint32_t arg1 = SHIM_GET_ARG_32(1); uint32_t arg2 = SHIM_GET_ARG_32(2); @@ -325,26 +299,22 @@ SHIM_CALL XamWriteGamerTile_shim( uint32_t arg4 = SHIM_GET_ARG_32(4); uint32_t overlapped_ptr = SHIM_GET_ARG_32(5); - XELOGD( - "XamWriteGamerTile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", - arg0, arg1, arg2, arg3, arg4, overlapped_ptr); + XELOGD("XamWriteGamerTile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", arg0, arg1, + arg2, arg3, arg4, overlapped_ptr); if (overlapped_ptr) { state->CompleteOverlappedImmediate(overlapped_ptr, X_ERROR_SUCCESS); SHIM_SET_RETURN_32(X_ERROR_IO_PENDING); - } - else { + } else { SHIM_SET_RETURN_32(X_ERROR_SUCCESS); } } - } // namespace kernel } // namespace xe - -void xe::kernel::xam::RegisterUserExports( - ExportResolver* export_resolver, KernelState* state) { +void xe::kernel::xam::RegisterUserExports(ExportResolver* export_resolver, + KernelState* state) { SHIM_SET_MAPPING("xam.xex", XamUserGetXUID, state); SHIM_SET_MAPPING("xam.xex", XamUserGetSigninState, state); SHIM_SET_MAPPING("xam.xex", XamUserGetSigninInfo, state); diff --git a/src/xenia/kernel/xam_video.cc b/src/xenia/kernel/xam_video.cc index b5f6f2693..d9fff40eb 100644 --- a/src/xenia/kernel/xam_video.cc +++ b/src/xenia/kernel/xam_video.cc @@ -14,11 +14,9 @@ #include #include - namespace xe { namespace kernel { - // TODO(benvanik): actually check to see if these are the same. void xeVdQueryVideoMode(X_VIDEO_MODE* video_mode); SHIM_CALL XGetVideoMode_shim(PPCContext* ppc_state, KernelState* state) { @@ -27,12 +25,10 @@ SHIM_CALL XGetVideoMode_shim(PPCContext* ppc_state, KernelState* state) { xeVdQueryVideoMode(video_mode); } - } // namespace kernel } // namespace xe - -void xe::kernel::xam::RegisterVideoExports( - ExportResolver* export_resolver, KernelState* state) { +void xe::kernel::xam::RegisterVideoExports(ExportResolver* export_resolver, + KernelState* state) { SHIM_SET_MAPPING("xam.xex", XGetVideoMode, state); } diff --git a/src/xenia/kernel/xam_voice.cc b/src/xenia/kernel/xam_voice.cc index f3c5e9f3a..decc55417 100644 --- a/src/xenia/kernel/xam_voice.cc +++ b/src/xenia/kernel/xam_voice.cc @@ -15,20 +15,15 @@ #include #include - namespace xe { namespace kernel { - -SHIM_CALL XamVoiceCreate_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t unk1 = SHIM_GET_ARG_32(0); // 0 - uint32_t unk2 = SHIM_GET_ARG_32(1); // 0xF +SHIM_CALL XamVoiceCreate_shim(PPCContext* ppc_state, KernelState* state) { + uint32_t unk1 = SHIM_GET_ARG_32(0); // 0 + uint32_t unk2 = SHIM_GET_ARG_32(1); // 0xF uint32_t out_voice_ptr = SHIM_GET_ARG_32(2); - XELOGD( - "XamVoiceCreate(%.8X, %.8X, %.8X)", - unk1, unk2, out_voice_ptr); + XELOGD("XamVoiceCreate(%.8X, %.8X, %.8X)", unk1, unk2, out_voice_ptr); // Null out the ptr. SHIM_SET_MEM_32(out_voice_ptr, 0); @@ -36,37 +31,28 @@ SHIM_CALL XamVoiceCreate_shim( SHIM_SET_RETURN_32(X_ERROR_ACCESS_DENIED); } - -SHIM_CALL XamVoiceClose_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamVoiceClose_shim(PPCContext* ppc_state, KernelState* state) { uint32_t voice_ptr = SHIM_GET_ARG_32(0); - XELOGD( - "XamVoiceClose(%.8X)", - voice_ptr); + XELOGD("XamVoiceClose(%.8X)", voice_ptr); SHIM_SET_RETURN_32(0); } - -SHIM_CALL XamVoiceHeadsetPresent_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XamVoiceHeadsetPresent_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t voice_ptr = SHIM_GET_ARG_32(0); - XELOGD( - "XamVoiceHeadsetPresent(%.8X)", - voice_ptr); + XELOGD("XamVoiceHeadsetPresent(%.8X)", voice_ptr); SHIM_SET_RETURN_32(0); } - } // namespace kernel } // namespace xe - -void xe::kernel::xam::RegisterVoiceExports( - ExportResolver* export_resolver, KernelState* state) { +void xe::kernel::xam::RegisterVoiceExports(ExportResolver* export_resolver, + KernelState* state) { SHIM_SET_MAPPING("xam.xex", XamVoiceCreate, state); SHIM_SET_MAPPING("xam.xex", XamVoiceClose, state); SHIM_SET_MAPPING("xam.xex", XamVoiceHeadsetPresent, state); diff --git a/src/xenia/kernel/xboxkrnl_audio.cc b/src/xenia/kernel/xboxkrnl_audio.cc index 1c04f25a1..c045a0b88 100644 --- a/src/xenia/kernel/xboxkrnl_audio.cc +++ b/src/xenia/kernel/xboxkrnl_audio.cc @@ -16,18 +16,13 @@ #include #include - namespace xe { namespace kernel { - -SHIM_CALL XMACreateContext_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XMACreateContext_shim(PPCContext* ppc_state, KernelState* state) { uint32_t context_ptr = SHIM_GET_ARG_32(0); - XELOGD( - "XMACreateContext(%.8X)", - context_ptr); + XELOGD("XMACreateContext(%.8X)", context_ptr); // TODO(benvanik): allocate and return -- see if size required or just dummy? // Games will call MmGetPhysicalAddress on the result. @@ -36,41 +31,32 @@ SHIM_CALL XMACreateContext_shim( SHIM_SET_RETURN_32(X_STATUS_SUCCESS); } - -SHIM_CALL XMAReleaseContext_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XMAReleaseContext_shim(PPCContext* ppc_state, KernelState* state) { uint32_t context_ptr = SHIM_GET_ARG_32(0); - XELOGD( - "XMAReleaseContext(%.8X)", - context_ptr); + XELOGD("XMAReleaseContext(%.8X)", context_ptr); // TODO(benvanik): free } - -SHIM_CALL XAudioGetSpeakerConfig_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XAudioGetSpeakerConfig_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t config_ptr = SHIM_GET_ARG_32(0); - XELOGD( - "XAudioGetSpeakerConfig(%.8X)", - config_ptr); + XELOGD("XAudioGetSpeakerConfig(%.8X)", config_ptr); SHIM_SET_MEM_32(config_ptr, 0x00010001); SHIM_SET_RETURN_32(X_ERROR_SUCCESS); } - -SHIM_CALL XAudioGetVoiceCategoryVolumeChangeMask_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XAudioGetVoiceCategoryVolumeChangeMask_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t driver_ptr = SHIM_GET_ARG_32(0); uint32_t out_ptr = SHIM_GET_ARG_32(1); - XELOGD( - "XAudioGetVoiceCategoryVolumeChangeMask(%.8X, %.8X)", - driver_ptr, out_ptr); + XELOGD("XAudioGetVoiceCategoryVolumeChangeMask(%.8X, %.8X)", driver_ptr, + out_ptr); assert_true((driver_ptr & 0xFFFF0000) == 0x41550000); @@ -83,15 +69,12 @@ SHIM_CALL XAudioGetVoiceCategoryVolumeChangeMask_shim( SHIM_SET_RETURN_32(X_ERROR_SUCCESS); } - -SHIM_CALL XAudioGetVoiceCategoryVolume_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XAudioGetVoiceCategoryVolume_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t unk = SHIM_GET_ARG_32(0); uint32_t out_ptr = SHIM_GET_ARG_32(1); - XELOGD( - "XAudioGetVoiceCategoryVolume(%.8X, %.8X)", - unk, out_ptr); + XELOGD("XAudioGetVoiceCategoryVolume(%.8X, %.8X)", unk, out_ptr); // Expects a floating point single. Volume %? SHIM_SET_MEM_F32(out_ptr, 1.0f); @@ -99,30 +82,24 @@ SHIM_CALL XAudioGetVoiceCategoryVolume_shim( SHIM_SET_RETURN_32(X_ERROR_SUCCESS); } - -SHIM_CALL XAudioEnableDucker_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XAudioEnableDucker_shim(PPCContext* ppc_state, KernelState* state) { uint32_t unk = SHIM_GET_ARG_32(0); - XELOGD( - "XAudioEnableDucker(%.8X)", - unk); + XELOGD("XAudioEnableDucker(%.8X)", unk); SHIM_SET_RETURN_32(X_ERROR_SUCCESS); } - -SHIM_CALL XAudioRegisterRenderDriverClient_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XAudioRegisterRenderDriverClient_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t callback_ptr = SHIM_GET_ARG_32(0); uint32_t driver_ptr = SHIM_GET_ARG_32(1); uint32_t callback = SHIM_MEM_32(callback_ptr + 0); uint32_t callback_arg = SHIM_MEM_32(callback_ptr + 4); - XELOGD( - "XAudioRegisterRenderDriverClient(%.8X(%.8X, %.8X), %.8X)", - callback_ptr, callback, callback_arg, driver_ptr); + XELOGD("XAudioRegisterRenderDriverClient(%.8X(%.8X, %.8X), %.8X)", + callback_ptr, callback, callback_arg, driver_ptr); auto audio_system = state->emulator()->audio_system(); @@ -134,18 +111,16 @@ SHIM_CALL XAudioRegisterRenderDriverClient_shim( } assert_true(!(index & ~0x0000FFFF)); - SHIM_SET_MEM_32(driver_ptr, 0x41550000 | (static_cast(index) & 0x0000FFFF)); + SHIM_SET_MEM_32(driver_ptr, + 0x41550000 | (static_cast(index) & 0x0000FFFF)); SHIM_SET_RETURN_32(X_ERROR_SUCCESS); } - -SHIM_CALL XAudioUnregisterRenderDriverClient_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XAudioUnregisterRenderDriverClient_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t driver_ptr = SHIM_GET_ARG_32(0); - XELOGD( - "XAudioUnregisterRenderDriverClient(%.8X)", - driver_ptr); + XELOGD("XAudioUnregisterRenderDriverClient(%.8X)", driver_ptr); assert_true((driver_ptr & 0xFFFF0000) == 0x41550000); @@ -154,15 +129,12 @@ SHIM_CALL XAudioUnregisterRenderDriverClient_shim( SHIM_SET_RETURN_32(X_ERROR_SUCCESS); } - -SHIM_CALL XAudioSubmitRenderDriverFrame_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XAudioSubmitRenderDriverFrame_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t driver_ptr = SHIM_GET_ARG_32(0); uint32_t samples_ptr = SHIM_GET_ARG_32(1); - XELOGD( - "XAudioSubmitRenderDriverFrame(%.8X, %.8X)", - driver_ptr, samples_ptr); + XELOGD("XAudioSubmitRenderDriverFrame(%.8X, %.8X)", driver_ptr, samples_ptr); assert_true((driver_ptr & 0xFFFF0000) == 0x41550000); @@ -172,13 +144,11 @@ SHIM_CALL XAudioSubmitRenderDriverFrame_shim( SHIM_SET_RETURN_32(X_ERROR_SUCCESS); } - } // namespace kernel } // namespace xe - -void xe::kernel::xboxkrnl::RegisterAudioExports( - ExportResolver* export_resolver, KernelState* state) { +void xe::kernel::xboxkrnl::RegisterAudioExports(ExportResolver* export_resolver, + KernelState* state) { SHIM_SET_MAPPING("xboxkrnl.exe", XMACreateContext, state); // SHIM_SET_MAPPING("xboxkrnl.exe", XMAInitializeContext, state); SHIM_SET_MAPPING("xboxkrnl.exe", XMAReleaseContext, state); @@ -202,7 +172,8 @@ void xe::kernel::xboxkrnl::RegisterAudioExports( // SHIM_SET_MAPPING("xboxkrnl.exe", XMAGetInputBufferReadOffset, state); SHIM_SET_MAPPING("xboxkrnl.exe", XAudioGetSpeakerConfig, state); - SHIM_SET_MAPPING("xboxkrnl.exe", XAudioGetVoiceCategoryVolumeChangeMask, state); + SHIM_SET_MAPPING("xboxkrnl.exe", XAudioGetVoiceCategoryVolumeChangeMask, + state); SHIM_SET_MAPPING("xboxkrnl.exe", XAudioGetVoiceCategoryVolume, state); SHIM_SET_MAPPING("xboxkrnl.exe", XAudioEnableDucker, state); diff --git a/src/xenia/kernel/xboxkrnl_debug.cc b/src/xenia/kernel/xboxkrnl_debug.cc index 7da596771..232ed4595 100644 --- a/src/xenia/kernel/xboxkrnl_debug.cc +++ b/src/xenia/kernel/xboxkrnl_debug.cc @@ -15,29 +15,26 @@ #include #include - namespace xe { namespace kernel { - // TODO: clean me up! -SHIM_CALL DbgPrint_shim( - PPCContext* ppc_state, KernelState* state) { - +SHIM_CALL DbgPrint_shim(PPCContext* ppc_state, KernelState* state) { uint32_t format_ptr = SHIM_GET_ARG_32(0); if (format_ptr == 0) { SHIM_SET_RETURN_64(-1); return; } - const char *format = (const char *)SHIM_MEM_ADDR(format_ptr); + const char* format = (const char*)SHIM_MEM_ADDR(format_ptr); int arg_index = 0; - char buffer[512]; // TODO: ensure it never writes past the end of the buffer... - char *b = buffer; + char buffer[512]; // TODO: ensure it never writes past the end of the + // buffer... + char* b = buffer; for (; *format != '\0'; ++format) { - const char *start = format; + const char* start = format; if (*format != '%') { *b++ = *format; @@ -54,14 +51,11 @@ SHIM_CALL DbgPrint_shim( continue; } - const char *end; + const char* end; end = format; // skip flags - while (*end == '-' || - *end == '+' || - *end == ' ' || - *end == '#' || + while (*end == '-' || *end == '+' || *end == ' ' || *end == '#' || *end == '0') { ++end; } @@ -76,8 +70,7 @@ SHIM_CALL DbgPrint_shim( if (*end == '*') { ++end; arg_extras++; - } - else { + } else { while (*end >= '0' && *end <= '9') { ++end; } @@ -94,8 +87,7 @@ SHIM_CALL DbgPrint_shim( if (*end == '*') { ++end; ++arg_extras; - } - else { + } else { while (*end >= '0' && *end <= '9') { ++end; } @@ -115,28 +107,23 @@ SHIM_CALL DbgPrint_shim( if (*end == 'h') { ++end; } - } - else if (*end == 'l') { + } else if (*end == 'l') { ++end; arg_size = 4; if (*end == 'l') { ++end; arg_size = 8; } - } - else if (*end == 'j') { + } else if (*end == 'j') { arg_size = 8; ++end; - } - else if (*end == 'z') { + } else if (*end == 'z') { arg_size = 4; ++end; - } - else if (*end == 't') { + } else if (*end == 't') { arg_size = 8; ++end; - } - else if (*end == 'L') { + } else if (*end == 'L') { arg_size = 8; ++end; } @@ -145,21 +132,10 @@ SHIM_CALL DbgPrint_shim( break; } - if (*end == 'd' || - *end == 'i' || - *end == 'u' || - *end == 'o' || - *end == 'x' || - *end == 'X' || - *end == 'f' || - *end == 'F' || - *end == 'e' || - *end == 'E' || - *end == 'g' || - *end == 'G' || - *end == 'a' || - *end == 'A' || - *end == 'c') { + if (*end == 'd' || *end == 'i' || *end == 'u' || *end == 'o' || + *end == 'x' || *end == 'X' || *end == 'f' || *end == 'F' || + *end == 'e' || *end == 'E' || *end == 'g' || *end == 'G' || + *end == 'a' || *end == 'A' || *end == 'c') { char local[512]; local[0] = '\0'; strncat(local, start, end + 1 - start); @@ -167,47 +143,42 @@ SHIM_CALL DbgPrint_shim( assert_true(arg_size == 8 || arg_size == 4); if (arg_size == 8) { if (arg_extras == 0) { - uint64_t value = arg_index < 7 - ? SHIM_GET_ARG_64(1 + arg_index) - : SHIM_MEM_32(SHIM_GPR_32(1) + 16 + ((1 + arg_index) * 8)); + uint64_t value = + arg_index < 7 + ? SHIM_GET_ARG_64(1 + arg_index) + : SHIM_MEM_32(SHIM_GPR_32(1) + 16 + ((1 + arg_index) * 8)); int result = sprintf(b, local, value); b += result; arg_index++; - } - else { + } else { assert_true(false); } - } - else if (arg_size == 4) { + } else if (arg_size == 4) { if (arg_extras == 0) { - uint64_t value = arg_index < 7 - ? SHIM_GET_ARG_64(1 + arg_index) - : SHIM_MEM_32(SHIM_GPR_32(1) + 16 + ((1 + arg_index) * 8)); + uint64_t value = + arg_index < 7 + ? SHIM_GET_ARG_64(1 + arg_index) + : SHIM_MEM_32(SHIM_GPR_32(1) + 16 + ((1 + arg_index) * 8)); int result = sprintf(b, local, (uint32_t)value); b += result; arg_index++; - } - else { + } else { assert_true(false); } } - } - else if (*end == 'n') - { + } else if (*end == 'n') { assert_true(arg_size == 4); if (arg_extras == 0) { uint32_t value = arg_index < 7 - ? SHIM_GET_ARG_32(1 + arg_index) - : (uint32_t)SHIM_MEM_64(SHIM_GPR_32(1) + 16 + ((1 + arg_index) * 8)); - SHIM_SET_MEM_32(value, (uint32_t)((b - buffer) / sizeof(char))); + ? SHIM_GET_ARG_32(1 + arg_index) + : (uint32_t)SHIM_MEM_64(SHIM_GPR_32(1) + 16 + + ((1 + arg_index) * 8)); + SHIM_SET_MEM_32(value, (uint32_t)((b - buffer) / sizeof(char))); arg_index++; - } - else { + } else { assert_true(false); } - } - else if (*end == 's' || - *end == 'p') { + } else if (*end == 's' || *end == 'p') { char local[512]; local[0] = '\0'; strncat(local, start, end + 1 - start); @@ -215,18 +186,17 @@ SHIM_CALL DbgPrint_shim( assert_true(arg_size == 4); if (arg_extras == 0) { uint32_t value = arg_index < 7 - ? SHIM_GET_ARG_32(1 + arg_index) - : (uint32_t)SHIM_MEM_64(SHIM_GPR_32(1) + 16 + ((1 + arg_index) * 8)); - const void *pointer = (const void *)SHIM_MEM_ADDR(value); + ? SHIM_GET_ARG_32(1 + arg_index) + : (uint32_t)SHIM_MEM_64(SHIM_GPR_32(1) + 16 + + ((1 + arg_index) * 8)); + const void* pointer = (const void*)SHIM_MEM_ADDR(value); int result = sprintf(b, local, pointer); b += result; arg_index++; - } - else { + } else { assert_true(false); } - } - else { + } else { assert_true(false); break; } @@ -238,16 +208,12 @@ SHIM_CALL DbgPrint_shim( XELOGD("(DbgPrint) %s", buffer); } - -SHIM_CALL DbgBreakPoint_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL DbgBreakPoint_shim(PPCContext* ppc_state, KernelState* state) { XELOGD("DbgBreakPoint()"); DebugBreak(); } - -SHIM_CALL RtlRaiseException_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL RtlRaiseException_shim(PPCContext* ppc_state, KernelState* state) { uint32_t record_ptr = SHIM_GET_ARG_32(0); uint32_t code = SHIM_MEM_32(record_ptr + 0); @@ -255,9 +221,7 @@ SHIM_CALL RtlRaiseException_shim( // ... uint32_t param_count = SHIM_MEM_32(record_ptr + 16); - XELOGD( - "RtlRaiseException(%.8X(%.8X))", - record_ptr, code); + XELOGD("RtlRaiseException(%.8X(%.8X))", record_ptr, code); if (code == 0x406D1388) { // SetThreadName. FFS. @@ -294,22 +258,21 @@ SHIM_CALL RtlRaiseException_shim( DebugBreak(); } - -void xeKeBugCheckEx(uint32_t code, uint32_t param1, uint32_t param2, uint32_t param3, uint32_t param4) { - XELOGD("*** STOP: 0x%.8X (0x%.8X, 0x%.8X, 0x%.8X, 0x%.8X)", code, param1, param2, param3, param4); +void xeKeBugCheckEx(uint32_t code, uint32_t param1, uint32_t param2, + uint32_t param3, uint32_t param4) { + XELOGD("*** STOP: 0x%.8X (0x%.8X, 0x%.8X, 0x%.8X, 0x%.8X)", code, param1, + param2, param3, param4); fflush(stdout); DebugBreak(); assert_always(); } -SHIM_CALL KeBugCheck_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeBugCheck_shim(PPCContext* ppc_state, KernelState* state) { uint32_t code = SHIM_GET_ARG_32(0); xeKeBugCheckEx(code, 0, 0, 0, 0); } -SHIM_CALL KeBugCheckEx_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeBugCheckEx_shim(PPCContext* ppc_state, KernelState* state) { uint32_t code = SHIM_GET_ARG_32(0); uint32_t param1 = SHIM_GET_ARG_32(1); uint32_t param2 = SHIM_GET_ARG_32(2); @@ -318,13 +281,11 @@ SHIM_CALL KeBugCheckEx_shim( xeKeBugCheckEx(code, param1, param2, param3, param4); } - } // namespace kernel } // namespace xe - -void xe::kernel::xboxkrnl::RegisterDebugExports( - ExportResolver* export_resolver, KernelState* state) { +void xe::kernel::xboxkrnl::RegisterDebugExports(ExportResolver* export_resolver, + KernelState* state) { SHIM_SET_MAPPING("xboxkrnl.exe", DbgPrint, state); SHIM_SET_MAPPING("xboxkrnl.exe", DbgBreakPoint, state); SHIM_SET_MAPPING("xboxkrnl.exe", RtlRaiseException, state); diff --git a/src/xenia/kernel/xboxkrnl_hal.cc b/src/xenia/kernel/xboxkrnl_hal.cc index 7e225077f..424744268 100644 --- a/src/xenia/kernel/xboxkrnl_hal.cc +++ b/src/xenia/kernel/xboxkrnl_hal.cc @@ -14,18 +14,13 @@ #include #include - namespace xe { namespace kernel { - -SHIM_CALL HalReturnToFirmware_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL HalReturnToFirmware_shim(PPCContext* ppc_state, KernelState* state) { uint32_t routine = SHIM_GET_ARG_32(0); - XELOGD( - "HalReturnToFirmware(%d)", - routine); + XELOGD("HalReturnToFirmware(%d)", routine); // void // IN FIRMWARE_REENTRY Routine @@ -39,12 +34,10 @@ SHIM_CALL HalReturnToFirmware_shim( exit(0); } - } // namespace kernel } // namespace xe - -void xe::kernel::xboxkrnl::RegisterHalExports( - ExportResolver* export_resolver, KernelState* state) { +void xe::kernel::xboxkrnl::RegisterHalExports(ExportResolver* export_resolver, + KernelState* state) { SHIM_SET_MAPPING("xboxkrnl.exe", HalReturnToFirmware, state); } diff --git a/src/xenia/kernel/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl_io.cc index 5054da354..aec999fe3 100644 --- a/src/xenia/kernel/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl_io.cc @@ -18,15 +18,12 @@ #include #include - namespace xe { namespace kernel { using namespace xe::kernel::fs; - -SHIM_CALL NtCreateFile_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtCreateFile_shim(PPCContext* ppc_state, KernelState* state) { uint32_t handle_ptr = SHIM_GET_ARG_32(0); uint32_t desired_access = SHIM_GET_ARG_32(1); uint32_t object_attributes_ptr = SHIM_GET_ARG_32(2); @@ -40,19 +37,13 @@ SHIM_CALL NtCreateFile_shim( char* object_name = attrs.object_name.Duplicate(); - XELOGD( - "NtCreateFile(%.8X, %.8X, %.8X(%s), %.8X, %.8X, %.8X, %d, %d)", - handle_ptr, - desired_access, - object_attributes_ptr, - !object_name ? "(null)" : object_name, - io_status_block_ptr, - allocation_size_ptr, - file_attributes, - share_access, - creation_disposition); + XELOGD("NtCreateFile(%.8X, %.8X, %.8X(%s), %.8X, %.8X, %.8X, %d, %d)", + handle_ptr, desired_access, object_attributes_ptr, + !object_name ? "(null)" : object_name, io_status_block_ptr, + allocation_size_ptr, file_attributes, share_access, + creation_disposition); - uint64_t allocation_size = 0; // is this correct??? + uint64_t allocation_size = 0; // is this correct??? if (allocation_size_ptr != 0) { allocation_size = SHIM_MEM_64(allocation_size_ptr); } @@ -65,18 +56,17 @@ SHIM_CALL NtCreateFile_shim( Entry* entry; XFile* root_file = NULL; - if (attrs.root_directory != 0xFFFFFFFD && // ObDosDevices + if (attrs.root_directory != 0xFFFFFFFD && // ObDosDevices attrs.root_directory != 0) { - result = state->object_table()->GetObject( - attrs.root_directory, (XObject**)&root_file); + result = state->object_table()->GetObject(attrs.root_directory, + (XObject**)&root_file); assert_true(XSUCCEEDED(result)); assert_true(root_file->type() == XObject::Type::kTypeFile); auto root_path = root_file->absolute_path(); auto target_path = root_path + object_name; entry = fs->ResolvePath(target_path); - } - else { + } else { // Resolve the file using the virtual file system. entry = fs->ResolvePath(object_name); } @@ -87,11 +77,9 @@ SHIM_CALL NtCreateFile_shim( XFile* file = NULL; if (entry && entry->type() == Entry::Type::FILE) { // Open the file. - result = entry->Open( - state, - mode, - false, // TODO(benvanik): pick async mode, if needed. - &file); + result = entry->Open(state, mode, + false, // TODO(benvanik): pick async mode, if needed. + &file); } else { result = X_STATUS_NO_SUCH_FILE; info = X_FILE_DOES_NOT_EXIST; @@ -101,13 +89,13 @@ SHIM_CALL NtCreateFile_shim( // Handle ref is incremented, so return that. handle = file->handle(); file->Release(); - result = X_STATUS_SUCCESS; - info = X_FILE_OPENED; + result = X_STATUS_SUCCESS; + info = X_FILE_OPENED; } if (io_status_block_ptr) { - SHIM_SET_MEM_32(io_status_block_ptr, result); // Status - SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information + SHIM_SET_MEM_32(io_status_block_ptr, result); // Status + SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information } if (XSUCCEEDED(result)) { if (handle_ptr) { @@ -119,8 +107,7 @@ SHIM_CALL NtCreateFile_shim( SHIM_SET_RETURN_32(result); } -SHIM_CALL NtOpenFile_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtOpenFile_shim(PPCContext* ppc_state, KernelState* state) { uint32_t handle_ptr = SHIM_GET_ARG_32(0); uint32_t desired_access = SHIM_GET_ARG_32(1); uint32_t object_attributes_ptr = SHIM_GET_ARG_32(2); @@ -131,23 +118,19 @@ SHIM_CALL NtOpenFile_shim( char* object_name = attrs.object_name.Duplicate(); - XELOGD( - "NtOpenFile(%.8X, %.8X, %.8X(%s), %.8X, %d)", - handle_ptr, - desired_access, - object_attributes_ptr, - !object_name ? "(null)" : object_name, - io_status_block_ptr, - open_options); + XELOGD("NtOpenFile(%.8X, %.8X, %.8X(%s), %.8X, %d)", handle_ptr, + desired_access, object_attributes_ptr, + !object_name ? "(null)" : object_name, io_status_block_ptr, + open_options); X_STATUS result = X_STATUS_NO_SUCH_FILE; uint32_t info = X_FILE_DOES_NOT_EXIST; uint32_t handle; XFile* root_file = NULL; - if (attrs.root_directory != 0xFFFFFFFD) { // ObDosDevices - result = state->object_table()->GetObject( - attrs.root_directory, (XObject**)&root_file); + if (attrs.root_directory != 0xFFFFFFFD) { // ObDosDevices + result = state->object_table()->GetObject(attrs.root_directory, + (XObject**)&root_file); assert_true(XSUCCEEDED(result)); assert_true(root_file->type() == XObject::Type::kTypeFile); assert_always(); @@ -162,13 +145,10 @@ SHIM_CALL NtOpenFile_shim( XFile* file = NULL; if (entry && entry->type() == Entry::Type::FILE) { // Open the file. - result = entry->Open( - state, - mode, - false, // TODO(benvanik): pick async mode, if needed. - &file); - } - else { + result = entry->Open(state, mode, + false, // TODO(benvanik): pick async mode, if needed. + &file); + } else { result = X_STATUS_NO_SUCH_FILE; info = X_FILE_DOES_NOT_EXIST; } @@ -182,8 +162,8 @@ SHIM_CALL NtOpenFile_shim( } if (io_status_block_ptr) { - SHIM_SET_MEM_32(io_status_block_ptr, result); // Status - SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information + SHIM_SET_MEM_32(io_status_block_ptr, result); // Status + SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information } if (XSUCCEEDED(result)) { if (handle_ptr) { @@ -196,7 +176,7 @@ SHIM_CALL NtOpenFile_shim( } class xeNtReadFileState { -public: + public: uint32_t x; }; void xeNtReadFileCompleted(XAsyncRequest* request, xeNtReadFileState* state) { @@ -205,8 +185,7 @@ void xeNtReadFileCompleted(XAsyncRequest* request, xeNtReadFileState* state) { delete state; } -SHIM_CALL NtReadFile_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtReadFile_shim(PPCContext* ppc_state, KernelState* state) { uint32_t file_handle = SHIM_GET_ARG_32(0); uint32_t event_handle = SHIM_GET_ARG_32(1); uint32_t apc_routine_ptr = SHIM_GET_ARG_32(2); @@ -217,17 +196,10 @@ SHIM_CALL NtReadFile_shim( uint32_t byte_offset_ptr = SHIM_GET_ARG_32(7); size_t byte_offset = byte_offset_ptr ? SHIM_MEM_64(byte_offset_ptr) : 0; - XELOGD( - "NtReadFile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %d, %.8X(%d))", - file_handle, - event_handle, - apc_routine_ptr, - apc_context, - io_status_block_ptr, - buffer, - buffer_length, - byte_offset_ptr, - byte_offset); + XELOGD("NtReadFile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %d, %.8X(%d))", + file_handle, event_handle, apc_routine_ptr, apc_context, + io_status_block_ptr, buffer, buffer_length, byte_offset_ptr, + byte_offset); // Async not supported yet. assert_zero(apc_routine_ptr); @@ -239,15 +211,13 @@ SHIM_CALL NtReadFile_shim( XEvent* ev = NULL; bool signal_event = false; if (event_handle) { - result = state->object_table()->GetObject( - event_handle, (XObject**)&ev); + result = state->object_table()->GetObject(event_handle, (XObject**)&ev); } // Grab file. XFile* file = NULL; if (XSUCCEEDED(result)) { - result = state->object_table()->GetObject( - file_handle, (XObject**)&file); + result = state->object_table()->GetObject(file_handle, (XObject**)&file); } // Execute read. @@ -260,17 +230,15 @@ SHIM_CALL NtReadFile_shim( // TODO(benvanik): async path. if (true) { // Synchronous request. - if (!byte_offset_ptr || - byte_offset == 0xFFFFFFFFfffffffe) { + if (!byte_offset_ptr || byte_offset == 0xFFFFFFFFfffffffe) { // FILE_USE_FILE_POINTER_POSITION byte_offset = -1; } // Read now. size_t bytes_read = 0; - result = file->Read( - SHIM_MEM_ADDR(buffer), buffer_length, byte_offset, - &bytes_read); + result = file->Read(SHIM_MEM_ADDR(buffer), buffer_length, byte_offset, + &bytes_read); if (XSUCCEEDED(result)) { info = (int32_t)bytes_read; } @@ -287,15 +255,15 @@ SHIM_CALL NtReadFile_shim( state, file, (XAsyncRequest::CompletionCallback)xeNtReadFileCompleted, call_state);*/ - //result = file->Read(buffer, buffer_length, byte_offset, request); + // result = file->Read(buffer, buffer_length, byte_offset, request); result = X_STATUS_PENDING; info = 0; } } if (io_status_block_ptr) { - SHIM_SET_MEM_32(io_status_block_ptr, result); // Status - SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information + SHIM_SET_MEM_32(io_status_block_ptr, result); // Status + SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information } if (file) { @@ -311,46 +279,39 @@ SHIM_CALL NtReadFile_shim( SHIM_SET_RETURN_32(result); } -SHIM_CALL NtSetInformationFile_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtSetInformationFile_shim(PPCContext* ppc_state, KernelState* state) { uint32_t file_handle = SHIM_GET_ARG_32(0); uint32_t io_status_block_ptr = SHIM_GET_ARG_32(1); uint32_t file_info_ptr = SHIM_GET_ARG_32(2); uint32_t length = SHIM_GET_ARG_32(3); uint32_t file_info_class = SHIM_GET_ARG_32(4); - XELOGD( - "NtSetInformationFile(%.8X, %.8X, %.8X, %.8X, %.8X)", - file_handle, - io_status_block_ptr, - file_info_ptr, - length, - file_info_class); + XELOGD("NtSetInformationFile(%.8X, %.8X, %.8X, %.8X, %.8X)", file_handle, + io_status_block_ptr, file_info_ptr, length, file_info_class); X_STATUS result = X_STATUS_SUCCESS; uint32_t info = 0; // Grab file. XFile* file = NULL; - result = state->object_table()->GetObject( - file_handle, (XObject**)&file); + result = state->object_table()->GetObject(file_handle, (XObject**)&file); if (XSUCCEEDED(result)) { result = X_STATUS_SUCCESS; switch (file_info_class) { - case XFilePositionInformation: - // struct FILE_POSITION_INFORMATION { - // LARGE_INTEGER CurrentByteOffset; - // }; - assert_true(length == 8); - info = 8; - file->set_position(SHIM_MEM_64(file_info_ptr)); - break; - default: - // Unsupported, for now. - assert_always(); - info = 0; - break; + case XFilePositionInformation: + // struct FILE_POSITION_INFORMATION { + // LARGE_INTEGER CurrentByteOffset; + // }; + assert_true(length == 8); + info = 8; + file->set_position(SHIM_MEM_64(file_info_ptr)); + break; + default: + // Unsupported, for now. + assert_always(); + info = 0; + break; } } @@ -358,8 +319,8 @@ SHIM_CALL NtSetInformationFile_shim( info = 0; } if (io_status_block_ptr) { - SHIM_SET_MEM_32(io_status_block_ptr, result); // Status - SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information + SHIM_SET_MEM_32(io_status_block_ptr, result); // Status + SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information } if (file) { @@ -369,91 +330,85 @@ SHIM_CALL NtSetInformationFile_shim( SHIM_SET_RETURN_32(result); } -SHIM_CALL NtQueryInformationFile_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtQueryInformationFile_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t file_handle = SHIM_GET_ARG_32(0); uint32_t io_status_block_ptr = SHIM_GET_ARG_32(1); uint32_t file_info_ptr = SHIM_GET_ARG_32(2); uint32_t length = SHIM_GET_ARG_32(3); uint32_t file_info_class = SHIM_GET_ARG_32(4); - XELOGD( - "NtQueryInformationFile(%.8X, %.8X, %.8X, %.8X, %.8X)", - file_handle, - io_status_block_ptr, - file_info_ptr, - length, - file_info_class); + XELOGD("NtQueryInformationFile(%.8X, %.8X, %.8X, %.8X, %.8X)", file_handle, + io_status_block_ptr, file_info_ptr, length, file_info_class); X_STATUS result = X_STATUS_SUCCESS; uint32_t info = 0; // Grab file. XFile* file = NULL; - result = state->object_table()->GetObject( - file_handle, (XObject**)&file); + result = state->object_table()->GetObject(file_handle, (XObject**)&file); if (XSUCCEEDED(result)) { result = X_STATUS_SUCCESS; switch (file_info_class) { - case XFileInternalInformation: - // Internal unique file pointer. Not sure why anyone would want this. - assert_true(length == 8); - info = 8; - // TODO(benvanik): use pointer to fs:: entry? - SHIM_SET_MEM_64(file_info_ptr, hash_combine(0, file->absolute_path())); - break; - case XFilePositionInformation: - // struct FILE_POSITION_INFORMATION { - // LARGE_INTEGER CurrentByteOffset; - // }; - assert_true(length == 8); - info = 8; - SHIM_SET_MEM_64(file_info_ptr, file->position()); - break; - case XFileNetworkOpenInformation: - // struct FILE_NETWORK_OPEN_INFORMATION { - // LARGE_INTEGER CreationTime; - // LARGE_INTEGER LastAccessTime; - // LARGE_INTEGER LastWriteTime; - // LARGE_INTEGER ChangeTime; - // LARGE_INTEGER AllocationSize; - // LARGE_INTEGER EndOfFile; - // ULONG FileAttributes; - // ULONG Unknown; - // }; - assert_true(length == 56); - XFileInfo file_info; - result = file->QueryInfo(&file_info); - if (XSUCCEEDED(result)) { - info = 56; - file_info.Write(SHIM_MEM_BASE, file_info_ptr); - } - break; - case XFileXctdCompressionInformation: - // Read timeout. - if (length == 4) { - uint32_t magic; - size_t bytes_read; - result = file->Read(&magic, sizeof(magic), 0, &bytes_read); + case XFileInternalInformation: + // Internal unique file pointer. Not sure why anyone would want this. + assert_true(length == 8); + info = 8; + // TODO(benvanik): use pointer to fs:: entry? + SHIM_SET_MEM_64(file_info_ptr, hash_combine(0, file->absolute_path())); + break; + case XFilePositionInformation: + // struct FILE_POSITION_INFORMATION { + // LARGE_INTEGER CurrentByteOffset; + // }; + assert_true(length == 8); + info = 8; + SHIM_SET_MEM_64(file_info_ptr, file->position()); + break; + case XFileNetworkOpenInformation: + // struct FILE_NETWORK_OPEN_INFORMATION { + // LARGE_INTEGER CreationTime; + // LARGE_INTEGER LastAccessTime; + // LARGE_INTEGER LastWriteTime; + // LARGE_INTEGER ChangeTime; + // LARGE_INTEGER AllocationSize; + // LARGE_INTEGER EndOfFile; + // ULONG FileAttributes; + // ULONG Unknown; + // }; + assert_true(length == 56); + XFileInfo file_info; + result = file->QueryInfo(&file_info); if (XSUCCEEDED(result)) { - if (bytes_read == sizeof(magic)) { - info = 4; - SHIM_SET_MEM_32(file_info_ptr, magic == poly::byte_swap(0x0FF512ED)); - } - else { - result = X_STATUS_UNSUCCESSFUL; - } + info = 56; + file_info.Write(SHIM_MEM_BASE, file_info_ptr); } - } else { - result = X_STATUS_INFO_LENGTH_MISMATCH; - } - break; - default: - // Unsupported, for now. - assert_always(); - info = 0; - break; + break; + case XFileXctdCompressionInformation: + // Read timeout. + if (length == 4) { + uint32_t magic; + size_t bytes_read; + result = file->Read(&magic, sizeof(magic), 0, &bytes_read); + if (XSUCCEEDED(result)) { + if (bytes_read == sizeof(magic)) { + info = 4; + SHIM_SET_MEM_32(file_info_ptr, + magic == poly::byte_swap(0x0FF512ED)); + } else { + result = X_STATUS_UNSUCCESSFUL; + } + } + } else { + result = X_STATUS_INFO_LENGTH_MISMATCH; + } + break; + default: + // Unsupported, for now. + assert_always(); + info = 0; + break; } } @@ -461,8 +416,8 @@ SHIM_CALL NtQueryInformationFile_shim( info = 0; } if (io_status_block_ptr) { - SHIM_SET_MEM_32(io_status_block_ptr, result); // Status - SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information + SHIM_SET_MEM_32(io_status_block_ptr, result); // Status + SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information } if (file) { @@ -472,8 +427,8 @@ SHIM_CALL NtQueryInformationFile_shim( SHIM_SET_RETURN_32(result); } -SHIM_CALL NtQueryFullAttributesFile_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtQueryFullAttributesFile_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t object_attributes_ptr = SHIM_GET_ARG_32(0); uint32_t file_info_ptr = SHIM_GET_ARG_32(1); @@ -481,18 +436,15 @@ SHIM_CALL NtQueryFullAttributesFile_shim( char* object_name = attrs.object_name.Duplicate(); - XELOGD( - "NtQueryFullAttributesFile(%.8X(%s), %.8X)", - object_attributes_ptr, - !object_name ? "(null)" : object_name, - file_info_ptr); + XELOGD("NtQueryFullAttributesFile(%.8X(%s), %.8X)", object_attributes_ptr, + !object_name ? "(null)" : object_name, file_info_ptr); X_STATUS result = X_STATUS_NO_SUCH_FILE; XFile* root_file = NULL; - if (attrs.root_directory != 0xFFFFFFFD) { // ObDosDevices - result = state->object_table()->GetObject( - attrs.root_directory, (XObject**)&root_file); + if (attrs.root_directory != 0xFFFFFFFD) { // ObDosDevices + result = state->object_table()->GetObject(attrs.root_directory, + (XObject**)&root_file); assert_true(XSUCCEEDED(result)); assert_true(root_file->type() == XObject::Type::kTypeFile); assert_always(); @@ -514,59 +466,52 @@ SHIM_CALL NtQueryFullAttributesFile_shim( SHIM_SET_RETURN_32(result); } -SHIM_CALL NtQueryVolumeInformationFile_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtQueryVolumeInformationFile_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t file_handle = SHIM_GET_ARG_32(0); uint32_t io_status_block_ptr = SHIM_GET_ARG_32(1); uint32_t fs_info_ptr = SHIM_GET_ARG_32(2); uint32_t length = SHIM_GET_ARG_32(3); uint32_t fs_info_class = SHIM_GET_ARG_32(4); - XELOGD( - "NtQueryVolumeInformationFile(%.8X, %.8X, %.8X, %.8X, %.8X)", - file_handle, - io_status_block_ptr, - fs_info_ptr, - length, - fs_info_class); - + XELOGD("NtQueryVolumeInformationFile(%.8X, %.8X, %.8X, %.8X, %.8X)", + file_handle, io_status_block_ptr, fs_info_ptr, length, fs_info_class); X_STATUS result = X_STATUS_SUCCESS; uint32_t info = 0; // Grab file. XFile* file = NULL; - result = state->object_table()->GetObject( - file_handle, (XObject**)&file); + result = state->object_table()->GetObject(file_handle, (XObject**)&file); if (XSUCCEEDED(result)) { result = X_STATUS_SUCCESS; switch (fs_info_class) { - case 1: { // FileFsVolumeInformation - auto volume_info = (XVolumeInfo*)xe_calloc(length); - result = file->QueryVolume(volume_info, length); - if (XSUCCEEDED(result)) { - volume_info->Write(SHIM_MEM_BASE, fs_info_ptr); - info = length; + case 1: { // FileFsVolumeInformation + auto volume_info = (XVolumeInfo*)xe_calloc(length); + result = file->QueryVolume(volume_info, length); + if (XSUCCEEDED(result)) { + volume_info->Write(SHIM_MEM_BASE, fs_info_ptr); + info = length; + } + xe_free(volume_info); + break; } - xe_free(volume_info); - break; - } - case 5: { // FileFsAttributeInformation - auto fs_attribute_info = (XFileSystemAttributeInfo*)xe_calloc(length); - result = file->QueryFileSystemAttributes(fs_attribute_info, length); - if (XSUCCEEDED(result)) { - fs_attribute_info->Write(SHIM_MEM_BASE, fs_info_ptr); - info = length; + case 5: { // FileFsAttributeInformation + auto fs_attribute_info = (XFileSystemAttributeInfo*)xe_calloc(length); + result = file->QueryFileSystemAttributes(fs_attribute_info, length); + if (XSUCCEEDED(result)) { + fs_attribute_info->Write(SHIM_MEM_BASE, fs_info_ptr); + info = length; + } + xe_free(fs_attribute_info); + break; } - xe_free(fs_attribute_info); - break; - } - default: - // Unsupported, for now. - assert_always(); - info = 0; - break; + default: + // Unsupported, for now. + assert_always(); + info = 0; + break; } } @@ -574,8 +519,8 @@ SHIM_CALL NtQueryVolumeInformationFile_shim( info = 0; } if (io_status_block_ptr) { - SHIM_SET_MEM_32(io_status_block_ptr, result); // Status - SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information + SHIM_SET_MEM_32(io_status_block_ptr, result); // Status + SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information } if (file) { @@ -585,8 +530,7 @@ SHIM_CALL NtQueryVolumeInformationFile_shim( SHIM_SET_RETURN_32(result); } -SHIM_CALL NtQueryDirectoryFile_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtQueryDirectoryFile_shim(PPCContext* ppc_state, KernelState* state) { uint32_t file_handle = SHIM_GET_ARG_32(0); uint32_t event_handle = SHIM_GET_ARG_32(1); uint32_t apc_routine = SHIM_GET_ARG_32(2); @@ -605,16 +549,10 @@ SHIM_CALL NtQueryDirectoryFile_shim( } XELOGD( - "NtQueryDirectoryFile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %d, %.8X(%s), %d)", - file_handle, - event_handle, - apc_routine, - apc_context, - io_status_block_ptr, - file_info_ptr, - length, - file_name_ptr, - !file_name ? "(null)" : file_name, + "NtQueryDirectoryFile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %d, %.8X(%s), " + "%d)", + file_handle, event_handle, apc_routine, apc_context, io_status_block_ptr, + file_info_ptr, length, file_name_ptr, !file_name ? "(null)" : file_name, restart_scan); if (length < 72) { @@ -627,11 +565,11 @@ SHIM_CALL NtQueryDirectoryFile_shim( uint32_t info = 0; XFile* file = NULL; - result = state->object_table()->GetObject( - file_handle, (XObject**)&file); + result = state->object_table()->GetObject(file_handle, (XObject**)&file); if (XSUCCEEDED(result)) { XDirectoryInfo* dir_info = (XDirectoryInfo*)xe_calloc(length); - result = file->QueryDirectory(dir_info, length, file_name, restart_scan != 0); + result = + file->QueryDirectory(dir_info, length, file_name, restart_scan != 0); if (XSUCCEEDED(result)) { dir_info->Write(SHIM_MEM_BASE, file_info_ptr); info = length; @@ -643,8 +581,8 @@ SHIM_CALL NtQueryDirectoryFile_shim( info = 0; } if (io_status_block_ptr) { - SHIM_SET_MEM_32(io_status_block_ptr, result); // Status - SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information + SHIM_SET_MEM_32(io_status_block_ptr, result); // Status + SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information } if (file) { @@ -655,27 +593,23 @@ SHIM_CALL NtQueryDirectoryFile_shim( SHIM_SET_RETURN_32(result); } -SHIM_CALL FscSetCacheElementCount_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL FscSetCacheElementCount_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t unk_0 = SHIM_GET_ARG_32(0); uint32_t unk_1 = SHIM_GET_ARG_32(1); // unk_0 = 0 // unk_1 looks like a count? in what units? 256 is a common value - XELOGD( - "FscSetCacheElementCount(%.8X, %.8X)", - unk_0, unk_1); + XELOGD("FscSetCacheElementCount(%.8X, %.8X)", unk_0, unk_1); SHIM_SET_RETURN_32(X_STATUS_SUCCESS); } - } // namespace kernel } // namespace xe - -void xe::kernel::xboxkrnl::RegisterIoExports( - ExportResolver* export_resolver, KernelState* state) { +void xe::kernel::xboxkrnl::RegisterIoExports(ExportResolver* export_resolver, + KernelState* state) { SHIM_SET_MAPPING("xboxkrnl.exe", NtCreateFile, state); SHIM_SET_MAPPING("xboxkrnl.exe", NtOpenFile, state); SHIM_SET_MAPPING("xboxkrnl.exe", NtReadFile, state); diff --git a/src/xenia/kernel/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl_memory.cc index 85a587946..fcc958094 100644 --- a/src/xenia/kernel/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl_memory.cc @@ -15,26 +15,22 @@ #include #include - namespace xe { namespace kernel { +SHIM_CALL NtAllocateVirtualMemory_shim(PPCContext* ppc_state, + KernelState* state) { + uint32_t base_addr_ptr = SHIM_GET_ARG_32(0); + uint32_t base_addr_value = SHIM_MEM_32(base_addr_ptr); + uint32_t region_size_ptr = SHIM_GET_ARG_32(1); + uint32_t region_size_value = SHIM_MEM_32(region_size_ptr); + uint32_t allocation_type = SHIM_GET_ARG_32(2); // X_MEM_* bitmask + uint32_t protect_bits = SHIM_GET_ARG_32(3); // X_PAGE_* bitmask + uint32_t unknown = SHIM_GET_ARG_32(4); -SHIM_CALL NtAllocateVirtualMemory_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t base_addr_ptr = SHIM_GET_ARG_32(0); - uint32_t base_addr_value = SHIM_MEM_32(base_addr_ptr); - uint32_t region_size_ptr = SHIM_GET_ARG_32(1); - uint32_t region_size_value = SHIM_MEM_32(region_size_ptr); - uint32_t allocation_type = SHIM_GET_ARG_32(2); // X_MEM_* bitmask - uint32_t protect_bits = SHIM_GET_ARG_32(3); // X_PAGE_* bitmask - uint32_t unknown = SHIM_GET_ARG_32(4); - - XELOGD( - "NtAllocateVirtualMemory(%.8X(%.8X), %.8X(%.8X), %.8X, %.8X, %.8X)", - base_addr_ptr, base_addr_value, - region_size_ptr, region_size_value, - allocation_type, protect_bits, unknown); + XELOGD("NtAllocateVirtualMemory(%.8X(%.8X), %.8X(%.8X), %.8X, %.8X, %.8X)", + base_addr_ptr, base_addr_value, region_size_ptr, region_size_value, + allocation_type, protect_bits, unknown); // NTSTATUS // _Inout_ PVOID *BaseAddress, @@ -68,7 +64,7 @@ SHIM_CALL NtAllocateVirtualMemory_shim( } // Don't allow games to set execute bits. if (protect_bits & (X_PAGE_EXECUTE | X_PAGE_EXECUTE_READ | - X_PAGE_EXECUTE_READWRITE | X_PAGE_EXECUTE_WRITECOPY)) { + X_PAGE_EXECUTE_READWRITE | X_PAGE_EXECUTE_WRITECOPY)) { SHIM_SET_RETURN_32(X_STATUS_ACCESS_DENIED); return; } @@ -83,7 +79,7 @@ SHIM_CALL NtAllocateVirtualMemory_shim( if (base_addr_value) { // Having a pointer already means that this is likely a follow-on COMMIT. assert_true(!(allocation_type & X_MEM_RESERVE) && - (allocation_type & X_MEM_COMMIT)); + (allocation_type & X_MEM_COMMIT)); SHIM_SET_MEM_32(base_addr_ptr, base_addr_value); SHIM_SET_MEM_32(region_size_ptr, adjusted_size); SHIM_SET_RETURN_32(X_STATUS_SUCCESS); @@ -92,8 +88,8 @@ SHIM_CALL NtAllocateVirtualMemory_shim( // Allocate. uint32_t flags = (allocation_type & X_MEM_NOZERO); - uint32_t addr = (uint32_t)state->memory()->HeapAlloc( - base_addr_value, adjusted_size, flags); + uint32_t addr = (uint32_t)state->memory()->HeapAlloc(base_addr_value, + adjusted_size, flags); if (!addr) { // Failed - assume no memory available. SHIM_SET_RETURN_32(X_STATUS_NO_MEMORY); @@ -107,22 +103,18 @@ SHIM_CALL NtAllocateVirtualMemory_shim( SHIM_SET_RETURN_32(X_STATUS_SUCCESS); } - -SHIM_CALL NtFreeVirtualMemory_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t base_addr_ptr = SHIM_GET_ARG_32(0); - uint32_t base_addr_value = SHIM_MEM_32(base_addr_ptr); - uint32_t region_size_ptr = SHIM_GET_ARG_32(1); - uint32_t region_size_value = SHIM_MEM_32(region_size_ptr); +SHIM_CALL NtFreeVirtualMemory_shim(PPCContext* ppc_state, KernelState* state) { + uint32_t base_addr_ptr = SHIM_GET_ARG_32(0); + uint32_t base_addr_value = SHIM_MEM_32(base_addr_ptr); + uint32_t region_size_ptr = SHIM_GET_ARG_32(1); + uint32_t region_size_value = SHIM_MEM_32(region_size_ptr); // X_MEM_DECOMMIT | X_MEM_RELEASE - uint32_t free_type = SHIM_GET_ARG_32(2); - uint32_t unknown = SHIM_GET_ARG_32(3); + uint32_t free_type = SHIM_GET_ARG_32(2); + uint32_t unknown = SHIM_GET_ARG_32(3); - XELOGD( - "NtFreeVirtualMemory(%.8X(%.8X), %.8X(%.8X), %.8X, %.8X)", - base_addr_ptr, base_addr_value, - region_size_ptr, region_size_value, - free_type, unknown); + XELOGD("NtFreeVirtualMemory(%.8X(%.8X), %.8X(%.8X), %.8X, %.8X)", + base_addr_ptr, base_addr_value, region_size_ptr, region_size_value, + free_type, unknown); // NTSTATUS // _Inout_ PVOID *BaseAddress, @@ -146,8 +138,7 @@ SHIM_CALL NtFreeVirtualMemory_shim( // Free. uint32_t flags = 0; - uint32_t freed_size = state->memory()->HeapFree( - base_addr_value, flags); + uint32_t freed_size = state->memory()->HeapFree(base_addr_value, flags); if (!freed_size) { SHIM_SET_RETURN_32(X_STATUS_UNSUCCESSFUL); return; @@ -158,15 +149,14 @@ SHIM_CALL NtFreeVirtualMemory_shim( SHIM_SET_RETURN_32(X_STATUS_SUCCESS); } -SHIM_CALL NtQueryVirtualMemory_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtQueryVirtualMemory_shim(PPCContext* ppc_state, KernelState* state) { uint32_t base_address = SHIM_GET_ARG_32(0); uint32_t memory_basic_information_ptr = SHIM_GET_ARG_32(1); - X_MEMORY_BASIC_INFORMATION *memory_basic_information = (X_MEMORY_BASIC_INFORMATION*)SHIM_MEM_ADDR(memory_basic_information_ptr); + X_MEMORY_BASIC_INFORMATION* memory_basic_information = + (X_MEMORY_BASIC_INFORMATION*)SHIM_MEM_ADDR(memory_basic_information_ptr); - XELOGD( - "NtQueryVirtualMemory(%.8X, %.8X)", - base_address, memory_basic_information_ptr); + XELOGD("NtQueryVirtualMemory(%.8X, %.8X)", base_address, + memory_basic_information_ptr); MEMORY_BASIC_INFORMATION mem_info; size_t result = state->memory()->QueryInformation(base_address, &mem_info); @@ -208,9 +198,8 @@ SHIM_CALL NtQueryVirtualMemory_shim( SHIM_SET_RETURN_32(X_STATUS_SUCCESS); } - -SHIM_CALL MmAllocatePhysicalMemoryEx_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL MmAllocatePhysicalMemoryEx_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t type = SHIM_GET_ARG_32(0); uint32_t region_size = SHIM_GET_ARG_32(1); uint32_t protect_bits = SHIM_GET_ARG_32(2); @@ -218,10 +207,8 @@ SHIM_CALL MmAllocatePhysicalMemoryEx_shim( uint32_t max_addr_range = SHIM_GET_ARG_32(4); uint32_t alignment = SHIM_GET_ARG_32(5); - XELOGD( - "MmAllocatePhysicalMemoryEx(%d, %.8X, %.8X, %.8X, %.8X, %.8X)", - type, region_size, protect_bits, - min_addr_range, max_addr_range, alignment); + XELOGD("MmAllocatePhysicalMemoryEx(%d, %.8X, %.8X, %.8X, %.8X, %.8X)", type, + region_size, protect_bits, min_addr_range, max_addr_range, alignment); // Type will usually be 0 (user request?), where 1 and 2 are sometimes made // by D3D/etc. @@ -273,7 +260,7 @@ SHIM_CALL MmAllocatePhysicalMemoryEx_shim( } // Move the address into the right range. - //if (protect_bits & X_MEM_LARGE_PAGES) { + // if (protect_bits & X_MEM_LARGE_PAGES) { // base_address += 0xA0000000; //} else if (protect_bits & X_MEM_16MB_PAGES) { // base_address += 0xC0000000; @@ -285,16 +272,12 @@ SHIM_CALL MmAllocatePhysicalMemoryEx_shim( SHIM_SET_RETURN_32(base_address); } - -SHIM_CALL MmFreePhysicalMemory_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL MmFreePhysicalMemory_shim(PPCContext* ppc_state, KernelState* state) { uint32_t type = SHIM_GET_ARG_32(0); uint32_t base_address = SHIM_GET_ARG_32(1); - XELOGD( - "MmFreePhysicalAddress(%d, %.8X)", - type, base_address); - + XELOGD("MmFreePhysicalAddress(%d, %.8X)", type, base_address); + // base_address = result of MmAllocatePhysicalMemory. // Strip off physical bits before passing down. @@ -302,47 +285,37 @@ SHIM_CALL MmFreePhysicalMemory_shim( // TODO(benvanik): free memory. XELOGE("xeMmFreePhysicalMemory NOT IMPLEMENTED"); - //uint32_t size = ?; - //xe_memory_heap_free( + // uint32_t size = ?; + // xe_memory_heap_free( // state->memory(), base_address, size); } - -SHIM_CALL MmQueryAddressProtect_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL MmQueryAddressProtect_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t base_address = SHIM_GET_ARG_32(0); - XELOGD( - "MmQueryAddressProtect(%.8X)", - base_address); + XELOGD("MmQueryAddressProtect(%.8X)", base_address); uint32_t access = state->memory()->QueryProtect(base_address); SHIM_SET_RETURN_32(access); } - -SHIM_CALL MmQueryAllocationSize_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL MmQueryAllocationSize_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t base_address = SHIM_GET_ARG_32(0); - XELOGD( - "MmQueryAllocationSize(%.8X)", - base_address); - + XELOGD("MmQueryAllocationSize(%.8X)", base_address); + size_t size = state->memory()->QuerySize(base_address); SHIM_SET_RETURN_32(static_cast(size)); } - -SHIM_CALL MmQueryStatistics_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL MmQueryStatistics_shim(PPCContext* ppc_state, KernelState* state) { uint32_t stats_ptr = SHIM_GET_ARG_32(0); - XELOGD( - "MmQueryStatistics(%.8X)", - stats_ptr); + XELOGD("MmQueryStatistics(%.8X)", stats_ptr); uint32_t size = SHIM_MEM_32(stats_ptr + 0); if (size != 104) { @@ -361,45 +334,45 @@ SHIM_CALL MmQueryStatistics_shim( // memory, this should satisfy it. If it's actually verifying things // this won't work :/ // https://code.google.com/p/vdash/source/browse/trunk/vdash/include/kernel.h - SHIM_SET_MEM_32(stats_ptr + 4 * 1, 0x00020000); // TotalPhysicalPages - SHIM_SET_MEM_32(stats_ptr + 4 * 2, 0x00000300); // KernelPages - SHIM_SET_MEM_32(stats_ptr + 4 * 3, 0x00020000); // TitleAvailablePages - SHIM_SET_MEM_32(stats_ptr + 4 * 4, 0x2FFF0000); // TitleTotalVirtualMemoryBytes - SHIM_SET_MEM_32(stats_ptr + 4 * 5, 0x00160000); // TitleReservedVirtualMemoryBytes - SHIM_SET_MEM_32(stats_ptr + 4 * 6, 0x00001000); // TitlePhysicalPages - SHIM_SET_MEM_32(stats_ptr + 4 * 7, 0x00000010); // TitlePoolPages - SHIM_SET_MEM_32(stats_ptr + 4 * 8, 0x00000100); // TitleStackPages - SHIM_SET_MEM_32(stats_ptr + 4 * 9, 0x00000100); // TitleImagePages - SHIM_SET_MEM_32(stats_ptr + 4 * 10, 0x00000100); // TitleHeapPages - SHIM_SET_MEM_32(stats_ptr + 4 * 11, 0x00000100); // TitleVirtualPages - SHIM_SET_MEM_32(stats_ptr + 4 * 12, 0x00000100); // TitlePageTablePages - SHIM_SET_MEM_32(stats_ptr + 4 * 13, 0x00000100); // TitleCachePages - SHIM_SET_MEM_32(stats_ptr + 4 * 14, 0x00000000); // SystemAvailablePages - SHIM_SET_MEM_32(stats_ptr + 4 * 15, 0x00000000); // SystemTotalVirtualMemoryBytes - SHIM_SET_MEM_32(stats_ptr + 4 * 16, 0x00000000); // SystemReservedVirtualMemoryBytes - SHIM_SET_MEM_32(stats_ptr + 4 * 17, 0x00000000); // SystemPhysicalPages - SHIM_SET_MEM_32(stats_ptr + 4 * 18, 0x00000000); // SystemPoolPages - SHIM_SET_MEM_32(stats_ptr + 4 * 19, 0x00000000); // SystemStackPages - SHIM_SET_MEM_32(stats_ptr + 4 * 20, 0x00000000); // SystemImagePages - SHIM_SET_MEM_32(stats_ptr + 4 * 21, 0x00000000); // SystemHeapPages - SHIM_SET_MEM_32(stats_ptr + 4 * 22, 0x00000000); // SystemVirtualPages - SHIM_SET_MEM_32(stats_ptr + 4 * 23, 0x00000000); // SystemPageTablePages - SHIM_SET_MEM_32(stats_ptr + 4 * 24, 0x00000000); // SystemCachePages - SHIM_SET_MEM_32(stats_ptr + 4 * 25, 0x0001FFFF); // HighestPhysicalPage + SHIM_SET_MEM_32(stats_ptr + 4 * 1, 0x00020000); // TotalPhysicalPages + SHIM_SET_MEM_32(stats_ptr + 4 * 2, 0x00000300); // KernelPages + SHIM_SET_MEM_32(stats_ptr + 4 * 3, 0x00020000); // TitleAvailablePages + SHIM_SET_MEM_32(stats_ptr + 4 * 4, + 0x2FFF0000); // TitleTotalVirtualMemoryBytes + SHIM_SET_MEM_32(stats_ptr + 4 * 5, + 0x00160000); // TitleReservedVirtualMemoryBytes + SHIM_SET_MEM_32(stats_ptr + 4 * 6, 0x00001000); // TitlePhysicalPages + SHIM_SET_MEM_32(stats_ptr + 4 * 7, 0x00000010); // TitlePoolPages + SHIM_SET_MEM_32(stats_ptr + 4 * 8, 0x00000100); // TitleStackPages + SHIM_SET_MEM_32(stats_ptr + 4 * 9, 0x00000100); // TitleImagePages + SHIM_SET_MEM_32(stats_ptr + 4 * 10, 0x00000100); // TitleHeapPages + SHIM_SET_MEM_32(stats_ptr + 4 * 11, 0x00000100); // TitleVirtualPages + SHIM_SET_MEM_32(stats_ptr + 4 * 12, 0x00000100); // TitlePageTablePages + SHIM_SET_MEM_32(stats_ptr + 4 * 13, 0x00000100); // TitleCachePages + SHIM_SET_MEM_32(stats_ptr + 4 * 14, 0x00000000); // SystemAvailablePages + SHIM_SET_MEM_32(stats_ptr + 4 * 15, + 0x00000000); // SystemTotalVirtualMemoryBytes + SHIM_SET_MEM_32(stats_ptr + 4 * 16, + 0x00000000); // SystemReservedVirtualMemoryBytes + SHIM_SET_MEM_32(stats_ptr + 4 * 17, 0x00000000); // SystemPhysicalPages + SHIM_SET_MEM_32(stats_ptr + 4 * 18, 0x00000000); // SystemPoolPages + SHIM_SET_MEM_32(stats_ptr + 4 * 19, 0x00000000); // SystemStackPages + SHIM_SET_MEM_32(stats_ptr + 4 * 20, 0x00000000); // SystemImagePages + SHIM_SET_MEM_32(stats_ptr + 4 * 21, 0x00000000); // SystemHeapPages + SHIM_SET_MEM_32(stats_ptr + 4 * 22, 0x00000000); // SystemVirtualPages + SHIM_SET_MEM_32(stats_ptr + 4 * 23, 0x00000000); // SystemPageTablePages + SHIM_SET_MEM_32(stats_ptr + 4 * 24, 0x00000000); // SystemCachePages + SHIM_SET_MEM_32(stats_ptr + 4 * 25, 0x0001FFFF); // HighestPhysicalPage SHIM_SET_RETURN_32(result); } - // http://msdn.microsoft.com/en-us/library/windows/hardware/ff554547(v=vs.85).aspx -SHIM_CALL MmGetPhysicalAddress_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL MmGetPhysicalAddress_shim(PPCContext* ppc_state, KernelState* state) { uint32_t base_address = SHIM_GET_ARG_32(0); - XELOGD( - "MmGetPhysicalAddress(%.8X)", - base_address); - + XELOGD("MmGetPhysicalAddress(%.8X)", base_address); + // PHYSICAL_ADDRESS MmGetPhysicalAddress( // _In_ PVOID BaseAddress // ); @@ -420,16 +393,13 @@ SHIM_CALL MmGetPhysicalAddress_shim( SHIM_SET_RETURN_32(base_address); } - -SHIM_CALL ExAllocatePoolTypeWithTag_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL ExAllocatePoolTypeWithTag_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t size = SHIM_GET_ARG_32(0); uint32_t tag = SHIM_GET_ARG_32(1); uint32_t zero = SHIM_GET_ARG_32(2); - XELOGD( - "ExAllocatePoolTypeWithTag(%d, %.8X, %d)", - size, tag, zero); + XELOGD("ExAllocatePoolTypeWithTag(%d, %.8X, %d)", size, tag, zero); uint32_t alignment = 8; uint32_t adjusted_size = size; @@ -445,48 +415,36 @@ SHIM_CALL ExAllocatePoolTypeWithTag_shim( SHIM_SET_RETURN_32(addr); } - -SHIM_CALL ExFreePool_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL ExFreePool_shim(PPCContext* ppc_state, KernelState* state) { uint32_t base_address = SHIM_GET_ARG_32(0); - XELOGD( - "ExFreePool(%.8X)", - base_address); + XELOGD("ExFreePool(%.8X)", base_address); state->memory()->HeapFree(base_address, 0); } - -SHIM_CALL KeLockL2_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeLockL2_shim(PPCContext* ppc_state, KernelState* state) { // Ignored for now. This is just a perf optimization, I think. // It may be useful as a hint for CPU-GPU transfer. - XELOGD( - "KeLockL2(?)"); + XELOGD("KeLockL2(?)"); SHIM_SET_RETURN_32(0); } - -SHIM_CALL KeUnlockL2_shim( - PPCContext* ppc_state, KernelState* state) { - XELOGD( - "KeUnlockL2(?)"); +SHIM_CALL KeUnlockL2_shim(PPCContext* ppc_state, KernelState* state) { + XELOGD("KeUnlockL2(?)"); } - } // namespace kernel } // namespace xe - void xe::kernel::xboxkrnl::RegisterMemoryExports( ExportResolver* export_resolver, KernelState* state) { SHIM_SET_MAPPING("xboxkrnl.exe", NtAllocateVirtualMemory, state); SHIM_SET_MAPPING("xboxkrnl.exe", NtFreeVirtualMemory, state); SHIM_SET_MAPPING("xboxkrnl.exe", NtQueryVirtualMemory, state); - //SHIM_SET_MAPPING("xboxkrnl.exe", MmAllocatePhysicalMemory, state); + // SHIM_SET_MAPPING("xboxkrnl.exe", MmAllocatePhysicalMemory, state); SHIM_SET_MAPPING("xboxkrnl.exe", MmAllocatePhysicalMemoryEx, state); SHIM_SET_MAPPING("xboxkrnl.exe", MmFreePhysicalMemory, state); SHIM_SET_MAPPING("xboxkrnl.exe", MmQueryAddressProtect, state); diff --git a/src/xenia/kernel/xboxkrnl_misc.cc b/src/xenia/kernel/xboxkrnl_misc.cc index 6a4b2db99..28cf77f87 100644 --- a/src/xenia/kernel/xboxkrnl_misc.cc +++ b/src/xenia/kernel/xboxkrnl_misc.cc @@ -15,24 +15,20 @@ #include #include - namespace xe { namespace kernel { - -SHIM_CALL KeEnableFpuExceptions_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeEnableFpuExceptions_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t enabled = SHIM_GET_ARG_32(0); XELOGD("KeEnableFpuExceptions(%d)", enabled); // TODO(benvanik): can we do anything about exceptions? } - } // namespace kernel } // namespace xe - -void xe::kernel::xboxkrnl::RegisterMiscExports( - ExportResolver* export_resolver, KernelState* state) { +void xe::kernel::xboxkrnl::RegisterMiscExports(ExportResolver* export_resolver, + KernelState* state) { SHIM_SET_MAPPING("xboxkrnl.exe", KeEnableFpuExceptions, state); } diff --git a/src/xenia/kernel/xboxkrnl_module.cc b/src/xenia/kernel/xboxkrnl_module.cc index f98e7a16d..04149eaf9 100644 --- a/src/xenia/kernel/xboxkrnl_module.cc +++ b/src/xenia/kernel/xboxkrnl_module.cc @@ -17,23 +17,20 @@ #include #include - DEFINE_bool(abort_before_entry, false, - "Abort execution right before launching the module."); - + "Abort execution right before launching the module."); namespace xe { namespace kernel { - -XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) : - XKernelModule(kernel_state, "xe:\\xboxkrnl.exe") { - // Build the export table used for resolution. - #include +XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) + : XKernelModule(kernel_state, "xe:\\xboxkrnl.exe") { +// Build the export table used for resolution. +#include static KernelExport xboxkrnl_export_table[] = { - #include +#include }; - #include +#include export_resolver_->RegisterTable("xboxkrnl.exe", xboxkrnl_export_table, poly::countof(xboxkrnl_export_table)); @@ -60,16 +57,14 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) : // arguments. If we wanted to see what would happen we could fake that. uint32_t pKeDebugMonitorData = (uint32_t)memory_->HeapAlloc(0, 256, 0); export_resolver_->SetVariableMapping( - "xboxkrnl.exe", ordinals::KeDebugMonitorData, - pKeDebugMonitorData); + "xboxkrnl.exe", ordinals::KeDebugMonitorData, pKeDebugMonitorData); poly::store_and_swap(mem + pKeDebugMonitorData, 0); // KeCertMonitorData (?*) // Always set to zero, ignored. uint32_t pKeCertMonitorData = (uint32_t)memory_->HeapAlloc(0, 4, 0); export_resolver_->SetVariableMapping( - "xboxkrnl.exe", ordinals::KeCertMonitorData, - pKeCertMonitorData); + "xboxkrnl.exe", ordinals::KeCertMonitorData, pKeCertMonitorData); poly::store_and_swap(mem + pKeCertMonitorData, 0); // XboxHardwareInfo (XboxHardwareInfo_t, 16b) @@ -79,10 +74,11 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) : // was whether an HDD was present. Not sure what the other flags are. uint32_t pXboxHardwareInfo = (uint32_t)memory_->HeapAlloc(0, 16, 0); export_resolver_->SetVariableMapping( - "xboxkrnl.exe", ordinals::XboxHardwareInfo, - pXboxHardwareInfo); - poly::store_and_swap(mem + pXboxHardwareInfo + 0, 0x00000000); // flags - poly::store_and_swap (mem + pXboxHardwareInfo + 4, 0x06); // cpu count + "xboxkrnl.exe", ordinals::XboxHardwareInfo, pXboxHardwareInfo); + poly::store_and_swap(mem + pXboxHardwareInfo + 0, + 0x00000000); // flags + poly::store_and_swap(mem + pXboxHardwareInfo + 4, + 0x06); // cpu count // Remaining 11b are zeroes? // XexExecutableModuleHandle (?**) @@ -95,13 +91,14 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) : // 0x80101058 <- pointer to xex header // 0x80101100 <- xex header base uint32_t ppXexExecutableModuleHandle = (uint32_t)memory_->HeapAlloc(0, 4, 0); - export_resolver_->SetVariableMapping( - "xboxkrnl.exe", ordinals::XexExecutableModuleHandle, - ppXexExecutableModuleHandle); - uint32_t pXexExecutableModuleHandle = - (uint32_t)memory_->HeapAlloc(0, 256, 0); - poly::store_and_swap(mem + ppXexExecutableModuleHandle, pXexExecutableModuleHandle); - poly::store_and_swap(mem + pXexExecutableModuleHandle + 0x58, 0x80101100); + export_resolver_->SetVariableMapping("xboxkrnl.exe", + ordinals::XexExecutableModuleHandle, + ppXexExecutableModuleHandle); + uint32_t pXexExecutableModuleHandle = (uint32_t)memory_->HeapAlloc(0, 256, 0); + poly::store_and_swap(mem + ppXexExecutableModuleHandle, + pXexExecutableModuleHandle); + poly::store_and_swap(mem + pXexExecutableModuleHandle + 0x58, + 0x80101100); // ExLoadedCommandLine (char*) // The name of the xex. Not sure this is ever really used on real devices. @@ -109,19 +106,17 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) : // Always set to "default.xex" (with quotes) for now. uint32_t pExLoadedCommandLine = (uint32_t)memory_->HeapAlloc(0, 1024, 0); export_resolver_->SetVariableMapping( - "xboxkrnl.exe", ordinals::ExLoadedCommandLine, - pExLoadedCommandLine); + "xboxkrnl.exe", ordinals::ExLoadedCommandLine, pExLoadedCommandLine); char command_line[] = "\"default.xex\""; - xe_copy_memory(mem + pExLoadedCommandLine, 1024, - command_line, poly::countof(command_line) + 1); + xe_copy_memory(mem + pExLoadedCommandLine, 1024, command_line, + poly::countof(command_line) + 1); // XboxKrnlVersion (8b) // Kernel version, looks like 2b.2b.2b.2b. // I've only seen games check >=, so we just fake something here. uint32_t pXboxKrnlVersion = (uint32_t)memory_->HeapAlloc(0, 8, 0); export_resolver_->SetVariableMapping( - "xboxkrnl.exe", ordinals::XboxKrnlVersion, - pXboxKrnlVersion); + "xboxkrnl.exe", ordinals::XboxKrnlVersion, pXboxKrnlVersion); poly::store_and_swap(mem + pXboxKrnlVersion + 0, 2); poly::store_and_swap(mem + pXboxKrnlVersion + 2, 0xFFFF); poly::store_and_swap(mem + pXboxKrnlVersion + 4, 0xFFFF); @@ -130,15 +125,13 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) : // KeTimeStampBundle (ad) uint32_t pKeTimeStampBundle = (uint32_t)memory_->HeapAlloc(0, 24, 0); export_resolver_->SetVariableMapping( - "xboxkrnl.exe", ordinals::KeTimeStampBundle, - pKeTimeStampBundle); - poly::store_and_swap(mem + pKeTimeStampBundle + 0, 0); - poly::store_and_swap(mem + pKeTimeStampBundle + 8, 0); + "xboxkrnl.exe", ordinals::KeTimeStampBundle, pKeTimeStampBundle); + poly::store_and_swap(mem + pKeTimeStampBundle + 0, 0); + poly::store_and_swap(mem + pKeTimeStampBundle + 8, 0); poly::store_and_swap(mem + pKeTimeStampBundle + 12, 0); } -XboxkrnlModule::~XboxkrnlModule() { -} +XboxkrnlModule::~XboxkrnlModule() {} int XboxkrnlModule::LaunchModule(const char* path) { // Create and register the module. We keep it local to this function and diff --git a/src/xenia/kernel/xboxkrnl_module.h b/src/xenia/kernel/xboxkrnl_module.h index 627cf850a..c5923bf57 100644 --- a/src/xenia/kernel/xboxkrnl_module.h +++ b/src/xenia/kernel/xboxkrnl_module.h @@ -12,7 +12,6 @@ #include #include - #include #include #include @@ -20,26 +19,22 @@ // All of the exported functions: #include - namespace xe { namespace kernel { class KernelState; - class XboxkrnlModule : public XKernelModule { -public: + public: XboxkrnlModule(Emulator* emulator, KernelState* kernel_state); virtual ~XboxkrnlModule(); int LaunchModule(const char* path); -private: + private: }; - } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_MODULE_H_ diff --git a/src/xenia/kernel/xboxkrnl_modules.cc b/src/xenia/kernel/xboxkrnl_modules.cc index ec7bf3fc6..03dd0f358 100644 --- a/src/xenia/kernel/xboxkrnl_modules.cc +++ b/src/xenia/kernel/xboxkrnl_modules.cc @@ -16,14 +16,12 @@ #include #include - namespace xe { namespace kernel { - -X_STATUS xeExGetXConfigSetting( - uint16_t category, uint16_t setting, void* buffer, uint16_t buffer_size, - uint16_t* required_size) { +X_STATUS xeExGetXConfigSetting(uint16_t category, uint16_t setting, + void* buffer, uint16_t buffer_size, + uint16_t* required_size) { uint16_t setting_size = 0; uint32_t value = 0; @@ -31,58 +29,58 @@ X_STATUS xeExGetXConfigSetting( // http://free60.org/XConfig // http://freestyledash.googlecode.com/svn/trunk/Freestyle/Tools/Generic/ExConfig.h switch (category) { - case 0x0002: - // XCONFIG_SECURED_CATEGORY - switch (setting) { - case 0x0002: // XCONFIG_SECURED_AV_REGION - setting_size = 4; - value = 0x00001000; // USA/Canada + case 0x0002: + // XCONFIG_SECURED_CATEGORY + switch (setting) { + case 0x0002: // XCONFIG_SECURED_AV_REGION + setting_size = 4; + value = 0x00001000; // USA/Canada + break; + default: + assert_unhandled_case(setting); + return X_STATUS_INVALID_PARAMETER_2; + } + break; + case 0x0003: + // XCONFIG_USER_CATEGORY + switch (setting) { + case 0x0001: // XCONFIG_USER_TIME_ZONE_BIAS + case 0x0002: // XCONFIG_USER_TIME_ZONE_STD_NAME + case 0x0003: // XCONFIG_USER_TIME_ZONE_DLT_NAME + case 0x0004: // XCONFIG_USER_TIME_ZONE_STD_DATE + case 0x0005: // XCONFIG_USER_TIME_ZONE_DLT_DATE + case 0x0006: // XCONFIG_USER_TIME_ZONE_STD_BIAS + case 0x0007: // XCONFIG_USER_TIME_ZONE_DLT_BIAS + setting_size = 4; + // TODO(benvanik): get this value. + value = 0; + break; + case 0x0009: // XCONFIG_USER_LANGUAGE + setting_size = 4; + value = 0x00000001; // English + break; + case 0x000A: // XCONFIG_USER_VIDEO_FLAGS + setting_size = 4; + value = 0x00040000; + break; + case 0x000C: // XCONFIG_USER_RETAIL_FLAGS + setting_size = 4; + // TODO(benvanik): get this value. + value = 0; + break; + case 0x000E: // XCONFIG_USER_COUNTRY + setting_size = 4; + // TODO(benvanik): get this value. + value = 0; + break; + default: + assert_unhandled_case(setting); + return X_STATUS_INVALID_PARAMETER_2; + } break; default: - assert_unhandled_case(setting); - return X_STATUS_INVALID_PARAMETER_2; - } - break; - case 0x0003: - // XCONFIG_USER_CATEGORY - switch (setting) { - case 0x0001: // XCONFIG_USER_TIME_ZONE_BIAS - case 0x0002: // XCONFIG_USER_TIME_ZONE_STD_NAME - case 0x0003: // XCONFIG_USER_TIME_ZONE_DLT_NAME - case 0x0004: // XCONFIG_USER_TIME_ZONE_STD_DATE - case 0x0005: // XCONFIG_USER_TIME_ZONE_DLT_DATE - case 0x0006: // XCONFIG_USER_TIME_ZONE_STD_BIAS - case 0x0007: // XCONFIG_USER_TIME_ZONE_DLT_BIAS - setting_size = 4; - // TODO(benvanik): get this value. - value = 0; - break; - case 0x0009: // XCONFIG_USER_LANGUAGE - setting_size = 4; - value = 0x00000001; // English - break; - case 0x000A: // XCONFIG_USER_VIDEO_FLAGS - setting_size = 4; - value = 0x00040000; - break; - case 0x000C: // XCONFIG_USER_RETAIL_FLAGS - setting_size = 4; - // TODO(benvanik): get this value. - value = 0; - break; - case 0x000E: // XCONFIG_USER_COUNTRY - setting_size = 4; - // TODO(benvanik): get this value. - value = 0; - break; - default: - assert_unhandled_case(setting); - return X_STATUS_INVALID_PARAMETER_2; - } - break; - default: - assert_unhandled_case(category); - return X_STATUS_INVALID_PARAMETER_1; + assert_unhandled_case(category); + return X_STATUS_INVALID_PARAMETER_1; } if (buffer_size < setting_size) { @@ -102,23 +100,20 @@ X_STATUS xeExGetXConfigSetting( return X_STATUS_SUCCESS; } - -SHIM_CALL ExGetXConfigSetting_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL ExGetXConfigSetting_shim(PPCContext* ppc_state, KernelState* state) { uint16_t category = SHIM_GET_ARG_16(0); uint16_t setting = SHIM_GET_ARG_16(1); uint32_t buffer_ptr = SHIM_GET_ARG_32(2); uint16_t buffer_size = SHIM_GET_ARG_16(3); uint32_t required_size_ptr = SHIM_GET_ARG_32(4); - XELOGD( - "ExGetXConfigSetting(%.4X, %.4X, %.8X, %.4X, %.8X)", - category, setting, buffer_ptr, buffer_size, required_size_ptr); + XELOGD("ExGetXConfigSetting(%.4X, %.4X, %.8X, %.4X, %.8X)", category, setting, + buffer_ptr, buffer_size, required_size_ptr); void* buffer = buffer_ptr ? SHIM_MEM_ADDR(buffer_ptr) : NULL; uint16_t required_size = 0; - X_STATUS result = xeExGetXConfigSetting( - category, setting, buffer, buffer_size, &required_size); + X_STATUS result = xeExGetXConfigSetting(category, setting, buffer, + buffer_size, &required_size); if (required_size_ptr) { SHIM_SET_MEM_16(required_size_ptr, required_size); @@ -127,14 +122,11 @@ SHIM_CALL ExGetXConfigSetting_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL XexCheckExecutablePrivilege_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XexCheckExecutablePrivilege_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t privilege = SHIM_GET_ARG_32(0); - XELOGD( - "XexCheckExecutablePrivilege(%.8X)", - privilege); + XELOGD("XexCheckExecutablePrivilege(%.8X)", privilege); // BOOL // DWORD Privilege @@ -159,16 +151,12 @@ SHIM_CALL XexCheckExecutablePrivilege_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL XexGetModuleHandle_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XexGetModuleHandle_shim(PPCContext* ppc_state, KernelState* state) { uint32_t module_name_ptr = SHIM_GET_ARG_32(0); const char* module_name = (const char*)SHIM_MEM_ADDR(module_name_ptr); uint32_t module_handle_ptr = SHIM_GET_ARG_32(1); - XELOGD( - "XexGetModuleHandle(%s, %.8X)", - module_name, module_handle_ptr); + XELOGD("XexGetModuleHandle(%s, %.8X)", module_name, module_handle_ptr); XModule* module = state->GetModule(module_name); if (!module) { @@ -184,18 +172,15 @@ SHIM_CALL XexGetModuleHandle_shim( SHIM_SET_RETURN_32(X_ERROR_SUCCESS); } - -SHIM_CALL XexGetModuleSection_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XexGetModuleSection_shim(PPCContext* ppc_state, KernelState* state) { uint32_t handle = SHIM_GET_ARG_32(0); uint32_t name_ptr = SHIM_GET_ARG_32(1); const char* name = (const char*)SHIM_MEM_ADDR(name_ptr); uint32_t data_ptr = SHIM_GET_ARG_32(2); uint32_t size_ptr = SHIM_GET_ARG_32(3); - XELOGD( - "XexGetModuleSection(%.8X, %s, %.8X, %.8X)", - handle, name, data_ptr, size_ptr); + XELOGD("XexGetModuleSection(%.8X, %s, %.8X, %.8X)", handle, name, data_ptr, + size_ptr); XModule* module = NULL; X_STATUS result = @@ -215,18 +200,15 @@ SHIM_CALL XexGetModuleSection_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL XexLoadImage_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XexLoadImage_shim(PPCContext* ppc_state, KernelState* state) { uint32_t module_name_ptr = SHIM_GET_ARG_32(0); const char* module_name = (const char*)SHIM_MEM_ADDR(module_name_ptr); uint32_t module_flags = SHIM_GET_ARG_32(1); uint32_t min_version = SHIM_GET_ARG_32(2); uint32_t handle_ptr = SHIM_GET_ARG_32(3); - XELOGD( - "XexLoadImage(%s, %.8X, %.8X, %.8X)", - module_name, module_flags, min_version, handle_ptr); + XELOGD("XexLoadImage(%s, %.8X, %.8X, %.8X)", module_name, module_flags, + min_version, handle_ptr); X_STATUS result = X_STATUS_NO_SUCH_FILE; @@ -244,14 +226,10 @@ SHIM_CALL XexLoadImage_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL XexUnloadImage_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XexUnloadImage_shim(PPCContext* ppc_state, KernelState* state) { uint32_t handle = SHIM_GET_ARG_32(0); - XELOGD( - "XexUnloadImage(%.8X)", - handle); + XELOGD("XexUnloadImage(%.8X)", handle); X_STATUS result = X_STATUS_INVALID_HANDLE; @@ -260,16 +238,14 @@ SHIM_CALL XexUnloadImage_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL XexGetProcedureAddress_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XexGetProcedureAddress_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t module_handle = SHIM_GET_ARG_32(0); uint32_t ordinal = SHIM_GET_ARG_32(1); uint32_t out_function_ptr = SHIM_GET_ARG_32(2); - XELOGD( - "XexGetProcedureAddress(%.8X, %.8X, %.8X)", - module_handle, ordinal, out_function_ptr); + XELOGD("XexGetProcedureAddress(%.8X, %.8X, %.8X)", module_handle, ordinal, + out_function_ptr); X_STATUS result = X_STATUS_INVALID_HANDLE; @@ -278,8 +254,8 @@ SHIM_CALL XexGetProcedureAddress_shim( if (!module_handle) { module = state->GetExecutableModule(); } else { - result = state->object_table()->GetObject( - module_handle, (XObject**)&module); + result = + state->object_table()->GetObject(module_handle, (XObject**)&module); } if (XSUCCEEDED(result)) { @@ -294,9 +270,8 @@ SHIM_CALL XexGetProcedureAddress_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL ExRegisterTitleTerminateNotification_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL ExRegisterTitleTerminateNotification_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t registration_ptr = SHIM_GET_ARG_32(0); uint32_t create = SHIM_GET_ARG_32(1); @@ -305,9 +280,8 @@ SHIM_CALL ExRegisterTitleTerminateNotification_shim( // list entry flink // list entry blink - XELOGD( - "ExRegisterTitleTerminateNotification(%.8X(%.8X), %.1X)", - registration_ptr, routine, create); + XELOGD("ExRegisterTitleTerminateNotification(%.8X(%.8X), %.1X)", + registration_ptr, routine, create); if (create) { // Adding. @@ -318,11 +292,9 @@ SHIM_CALL ExRegisterTitleTerminateNotification_shim( } } - } // namespace kernel } // namespace xe - void xe::kernel::xboxkrnl::RegisterModuleExports( ExportResolver* export_resolver, KernelState* state) { SHIM_SET_MAPPING("xboxkrnl.exe", ExGetXConfigSetting, state); diff --git a/src/xenia/kernel/xboxkrnl_ob.cc b/src/xenia/kernel/xboxkrnl_ob.cc index 7cb5a42d6..697a36fe2 100644 --- a/src/xenia/kernel/xboxkrnl_ob.cc +++ b/src/xenia/kernel/xboxkrnl_ob.cc @@ -16,22 +16,17 @@ #include #include - namespace xe { namespace kernel { - -SHIM_CALL ObReferenceObjectByHandle_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL ObReferenceObjectByHandle_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t handle = SHIM_GET_ARG_32(0); uint32_t object_type_ptr = SHIM_GET_ARG_32(1); uint32_t out_object_ptr = SHIM_GET_ARG_32(2); - XELOGD( - "ObReferenceObjectByHandle(%.8X, %.8X, %.8X)", - handle, - object_type_ptr, - out_object_ptr); + XELOGD("ObReferenceObjectByHandle(%.8X, %.8X, %.8X)", handle, object_type_ptr, + out_object_ptr); X_STATUS result = X_STATUS_INVALID_HANDLE; @@ -43,12 +38,11 @@ SHIM_CALL ObReferenceObjectByHandle_shim( // TODO(benvanik): get native value, if supported. uint32_t native_ptr = 0xDEADF00D; switch (object_type_ptr) { - case 0xD01BBEEF: // ExThreadObjectType + case 0xD01BBEEF: // ExThreadObjectType { XThread* thread = (XThread*)object; native_ptr = thread->thread_state(); - } - break; + } break; } if (out_object_ptr) { @@ -59,14 +53,10 @@ SHIM_CALL ObReferenceObjectByHandle_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL ObDereferenceObject_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL ObDereferenceObject_shim(PPCContext* ppc_state, KernelState* state) { uint32_t native_ptr = SHIM_GET_ARG_32(0); - XELOGD( - "ObDereferenceObject(%.8X)", - native_ptr); + XELOGD("ObDereferenceObject(%.8X)", native_ptr); // Check if a dummy value from ObReferenceObjectByHandle. if (native_ptr == 0xDEADF00D) { @@ -83,16 +73,13 @@ SHIM_CALL ObDereferenceObject_shim( SHIM_SET_RETURN_32(0); } - -SHIM_CALL NtDuplicateObject_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtDuplicateObject_shim(PPCContext* ppc_state, KernelState* state) { uint32_t handle = SHIM_GET_ARG_32(0); uint32_t new_handle_ptr = SHIM_GET_ARG_32(1); uint32_t options = SHIM_GET_ARG_32(2); - XELOGD( - "NtDuplicateObject(%.8X, %.8X, %.8X)", - handle, new_handle_ptr, options); + XELOGD("NtDuplicateObject(%.8X, %.8X, %.8X)", handle, new_handle_ptr, + options); // NOTE: new_handle_ptr can be zero to just close a handle. // NOTE: this function seems to be used to get the current thread handle @@ -123,14 +110,10 @@ SHIM_CALL NtDuplicateObject_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL NtClose_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtClose_shim(PPCContext* ppc_state, KernelState* state) { uint32_t handle = SHIM_GET_ARG_32(0); - XELOGD( - "NtClose(%.8X)", - handle); + XELOGD("NtClose(%.8X)", handle); X_STATUS result = X_STATUS_INVALID_HANDLE; @@ -139,13 +122,11 @@ SHIM_CALL NtClose_shim( SHIM_SET_RETURN_32(result); } - } // namespace kernel } // namespace xe - -void xe::kernel::xboxkrnl::RegisterObExports( - ExportResolver* export_resolver, KernelState* state) { +void xe::kernel::xboxkrnl::RegisterObExports(ExportResolver* export_resolver, + KernelState* state) { SHIM_SET_MAPPING("xboxkrnl.exe", ObReferenceObjectByHandle, state); SHIM_SET_MAPPING("xboxkrnl.exe", ObDereferenceObject, state); SHIM_SET_MAPPING("xboxkrnl.exe", NtDuplicateObject, state); diff --git a/src/xenia/kernel/xboxkrnl_ordinals.h b/src/xenia/kernel/xboxkrnl_ordinals.h index 6a0f9f08e..27b0f5033 100644 --- a/src/xenia/kernel/xboxkrnl_ordinals.h +++ b/src/xenia/kernel/xboxkrnl_ordinals.h @@ -12,18 +12,15 @@ #include #include - #include - // Build an ordinal enum to make it easy to lookup ordinals. #include namespace ordinals { enum { - #include +#include }; } // namespace ordinals #include - #endif // XENIA_KERNEL_XBOXKRNL_ORDINALS_H_ diff --git a/src/xenia/kernel/xboxkrnl_private.h b/src/xenia/kernel/xboxkrnl_private.h index c23d02d3f..4a67d2736 100644 --- a/src/xenia/kernel/xboxkrnl_private.h +++ b/src/xenia/kernel/xboxkrnl_private.h @@ -12,10 +12,8 @@ #include #include - #include - namespace xe { namespace kernel { @@ -42,5 +40,4 @@ void RegisterVideoExports(ExportResolver* export_resolver, KernelState* state); } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_PRIVATE_H_ diff --git a/src/xenia/kernel/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl_rtl.cc index d2f67949a..c15ff783c 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl_rtl.cc @@ -17,21 +17,16 @@ #include #include - namespace xe { namespace kernel { - // http://msdn.microsoft.com/en-us/library/ff561778 -SHIM_CALL RtlCompareMemory_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL RtlCompareMemory_shim(PPCContext* ppc_state, KernelState* state) { uint32_t source1_ptr = SHIM_GET_ARG_32(0); uint32_t source2_ptr = SHIM_GET_ARG_32(1); uint32_t length = SHIM_GET_ARG_32(2); - XELOGD( - "RtlCompareMemory(%.8X, %.8X, %d)", - source1_ptr, source2_ptr, length); + XELOGD("RtlCompareMemory(%.8X, %.8X, %d)", source1_ptr, source2_ptr, length); // SIZE_T // _In_ const VOID *Source1, @@ -55,17 +50,14 @@ SHIM_CALL RtlCompareMemory_shim( SHIM_SET_RETURN_64(c); } - // http://msdn.microsoft.com/en-us/library/ff552123 -SHIM_CALL RtlCompareMemoryUlong_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL RtlCompareMemoryUlong_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t source_ptr = SHIM_GET_ARG_32(0); uint32_t length = SHIM_GET_ARG_32(1); uint32_t pattern = SHIM_GET_ARG_32(2); - XELOGD( - "RtlCompareMemoryUlong(%.8X, %d, %.8X)", - source_ptr, length, pattern); + XELOGD("RtlCompareMemoryUlong(%.8X, %d, %.8X)", source_ptr, length, pattern); // SIZE_T // _In_ PVOID Source, @@ -96,17 +88,14 @@ SHIM_CALL RtlCompareMemoryUlong_shim( SHIM_SET_RETURN_64(c); } - // http://msdn.microsoft.com/en-us/library/ff552263 -SHIM_CALL RtlFillMemoryUlong_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL RtlFillMemoryUlong_shim(PPCContext* ppc_state, KernelState* state) { uint32_t destination_ptr = SHIM_GET_ARG_32(0); uint32_t length = SHIM_GET_ARG_32(1); uint32_t pattern = SHIM_GET_ARG_32(2); - XELOGD( - "RtlFillMemoryUlong(%.8X, %d, %.8X)", - destination_ptr, length, pattern); + XELOGD("RtlFillMemoryUlong(%.8X, %d, %.8X)", destination_ptr, length, + pattern); // VOID // _Out_ PVOID Destination, @@ -129,23 +118,20 @@ SHIM_CALL RtlFillMemoryUlong_shim( } } - // typedef struct _STRING { // USHORT Length; // USHORT MaximumLength; // PCHAR Buffer; // } ANSI_STRING, *PANSI_STRING; - // http://msdn.microsoft.com/en-us/library/ff561918 -SHIM_CALL RtlInitAnsiString_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL RtlInitAnsiString_shim(PPCContext* ppc_state, KernelState* state) { uint32_t destination_ptr = SHIM_GET_ARG_32(0); uint32_t source_ptr = SHIM_GET_ARG_32(1); const char* source = source_ptr ? (char*)SHIM_MEM_ADDR(source_ptr) : NULL; - XELOGD("RtlInitAnsiString(%.8X, %.8X = %s)", - destination_ptr, source_ptr, source ? source : ""); + XELOGD("RtlInitAnsiString(%.8X, %.8X = %s)", destination_ptr, source_ptr, + source ? source : ""); // VOID // _Out_ PANSI_STRING DestinationString, @@ -163,10 +149,8 @@ SHIM_CALL RtlInitAnsiString_shim( SHIM_SET_MEM_32(destination_ptr + 4, source_ptr); } - // http://msdn.microsoft.com/en-us/library/ff561899 -SHIM_CALL RtlFreeAnsiString_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL RtlFreeAnsiString_shim(PPCContext* ppc_state, KernelState* state) { uint32_t string_ptr = SHIM_GET_ARG_32(0); XELOGD("RtlFreeAnsiString(%.8X)", string_ptr); @@ -186,17 +170,14 @@ SHIM_CALL RtlFreeAnsiString_shim( SHIM_SET_MEM_32(string_ptr + 4, 0); } - // typedef struct _UNICODE_STRING { // USHORT Length; // USHORT MaximumLength; // PWSTR Buffer; // } UNICODE_STRING, *PUNICODE_STRING; - // http://msdn.microsoft.com/en-us/library/ff561934 -SHIM_CALL RtlInitUnicodeString_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL RtlInitUnicodeString_shim(PPCContext* ppc_state, KernelState* state) { uint32_t destination_ptr = SHIM_GET_ARG_32(0); uint32_t source_ptr = SHIM_GET_ARG_32(1); @@ -223,10 +204,8 @@ SHIM_CALL RtlInitUnicodeString_shim( } } - // http://msdn.microsoft.com/en-us/library/ff561903 -SHIM_CALL RtlFreeUnicodeString_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL RtlFreeUnicodeString_shim(PPCContext* ppc_state, KernelState* state) { uint32_t string_ptr = SHIM_GET_ARG_32(0); XELOGD("RtlFreeUnicodeString(%.8X)", string_ptr); @@ -246,16 +225,15 @@ SHIM_CALL RtlFreeUnicodeString_shim( SHIM_SET_MEM_32(string_ptr + 4, 0); } - // http://msdn.microsoft.com/en-us/library/ff562969 -SHIM_CALL RtlUnicodeStringToAnsiString_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL RtlUnicodeStringToAnsiString_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t destination_ptr = SHIM_GET_ARG_32(0); uint32_t source_ptr = SHIM_GET_ARG_32(1); uint32_t alloc_dest = SHIM_GET_ARG_32(2); - XELOGD("RtlUnicodeStringToAnsiString(%.8X, %.8X, %d)", - destination_ptr, source_ptr, alloc_dest); + XELOGD("RtlUnicodeStringToAnsiString(%.8X, %.8X, %d)", destination_ptr, + source_ptr, alloc_dest); // NTSTATUS // _Inout_ PANSI_STRING DestinationString, @@ -294,9 +272,8 @@ SHIM_CALL RtlUnicodeStringToAnsiString_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL RtlMultiByteToUnicodeN_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL RtlMultiByteToUnicodeN_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t destination_ptr = SHIM_GET_ARG_32(0); uint32_t destination_len = SHIM_GET_ARG_32(1); uint32_t written_ptr = SHIM_GET_ARG_32(2); @@ -310,22 +287,19 @@ SHIM_CALL RtlMultiByteToUnicodeN_shim( auto source = (uint8_t*)SHIM_MEM_ADDR(source_ptr); auto destination = (uint16_t*)SHIM_MEM_ADDR(destination_ptr); - for (uint32_t i = 0; i < copy_len; i++) - { + for (uint32_t i = 0; i < copy_len; i++) { *destination++ = poly::byte_swap(*source++); } - if (written_ptr != 0) - { + if (written_ptr != 0) { SHIM_SET_MEM_32(written_ptr, copy_len << 1); } SHIM_SET_RETURN_32(0); } - -SHIM_CALL RtlUnicodeToMultiByteN_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL RtlUnicodeToMultiByteN_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t destination_ptr = SHIM_GET_ARG_32(0); uint32_t destination_len = SHIM_GET_ARG_32(1); uint32_t written_ptr = SHIM_GET_ARG_32(2); @@ -339,28 +313,23 @@ SHIM_CALL RtlUnicodeToMultiByteN_shim( auto source = (uint16_t*)SHIM_MEM_ADDR(source_ptr); auto destination = (uint8_t*)SHIM_MEM_ADDR(destination_ptr); - for (uint32_t i = 0; i < copy_len; i++) - { + for (uint32_t i = 0; i < copy_len; i++) { uint16_t c = poly::byte_swap(*source++); *destination++ = c < 256 ? (uint8_t)c : '?'; } - if (written_ptr != 0) - { + if (written_ptr != 0) { SHIM_SET_MEM_32(written_ptr, copy_len); } SHIM_SET_RETURN_32(0); } - -SHIM_CALL RtlNtStatusToDosError_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL RtlNtStatusToDosError_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t status = SHIM_GET_ARG_32(0); - XELOGD( - "RtlNtStatusToDosError(%.4X)", - status); + XELOGD("RtlNtStatusToDosError(%.4X)", status); if (!status || (status & 0x20000000)) { // Success. @@ -374,16 +343,15 @@ SHIM_CALL RtlNtStatusToDosError_shim( // TODO(benvanik): implement lookup table. XELOGE("RtlNtStatusToDosError lookup NOT SHIMEMENTED"); - uint32_t result = 317; // ERROR_MR_MID_NOT_FOUND + uint32_t result = 317; // ERROR_MR_MID_NOT_FOUND SHIM_SET_RETURN_32(result); } - -SHIM_CALL RtlImageXexHeaderField_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t xex_header_base = SHIM_GET_ARG_32(0); - uint32_t image_field = SHIM_GET_ARG_32(1); +SHIM_CALL RtlImageXexHeaderField_shim(PPCContext* ppc_state, + KernelState* state) { + uint32_t xex_header_base = SHIM_GET_ARG_32(0); + uint32_t image_field = SHIM_GET_ARG_32(1); // NOTE: this is totally faked! // We set the XexExecutableModuleHandle pointer to a block that has at offset @@ -392,9 +360,7 @@ SHIM_CALL RtlImageXexHeaderField_shim( // The only ImageField I've seen in the wild is // 0x20401 (XEX_HEADER_DEFAULT_HEAP_SIZE), so that's all we'll support. - XELOGD( - "RtlImageXexHeaderField(%.8X, %.8X)", - xex_header_base, image_field); + XELOGD("RtlImageXexHeaderField(%.8X, %.8X)", xex_header_base, image_field); // PVOID // PVOID XexHeaderBase @@ -428,7 +394,6 @@ SHIM_CALL RtlImageXexHeaderField_shim( SHIM_SET_RETURN_64(0); } - // Unfortunately the Windows RTL_CRITICAL_SECTION object is bigger than the one // on the 360 (32b vs. 28b). This means that we can't do in-place splatting of // the critical sections. Also, the 360 never calls RtlDeleteCriticalSection @@ -440,23 +405,23 @@ SHIM_CALL RtlImageXexHeaderField_shim( // the user code will never know. // // Ref: http://msdn.microsoft.com/en-us/magazine/cc164040.aspx -// Ref: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/critical.c?view=markup - +// Ref: +// http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/critical.c?view=markup // This structure tries to match the one on the 360 as best I can figure out. // Unfortunately some games have the critical sections pre-initialized in // their embedded data and InitializeCriticalSection will never be called. #pragma pack(push, 1) struct X_RTL_CRITICAL_SECTION { - uint8_t unknown00; - uint8_t spin_count_div_256; // * 256 - uint8_t __padding[6]; - //uint32_t unknown04; // maybe the handle to the event? - uint32_t unknown08; // head of queue, pointing to this offset - uint32_t unknown0C; // tail of queue? - int32_t lock_count; // -1 -> 0 on first lock 0x10 - uint32_t recursion_count; // 0 -> 1 on first lock 0x14 - uint32_t owning_thread_id; // 0 unless locked 0x18 + uint8_t unknown00; + uint8_t spin_count_div_256; // * 256 + uint8_t __padding[6]; + // uint32_t unknown04; // maybe the handle to the event? + uint32_t unknown08; // head of queue, pointing to this offset + uint32_t unknown0C; // tail of queue? + int32_t lock_count; // -1 -> 0 on first lock 0x10 + uint32_t recursion_count; // 0 -> 1 on first lock 0x14 + uint32_t owning_thread_id; // 0 unless locked 0x18 }; #pragma pack(pop) static_assert_size(X_RTL_CRITICAL_SECTION, 28); @@ -465,16 +430,15 @@ void xeRtlInitializeCriticalSection(X_RTL_CRITICAL_SECTION* cs) { // VOID // _Out_ LPCRITICAL_SECTION lpCriticalSection - cs->unknown00 = 1; - cs->spin_count_div_256 = 0; - cs->lock_count = -1; - cs->recursion_count = 0; - cs->owning_thread_id = 0; + cs->unknown00 = 1; + cs->spin_count_div_256 = 0; + cs->lock_count = -1; + cs->recursion_count = 0; + cs->owning_thread_id = 0; } - -SHIM_CALL RtlInitializeCriticalSection_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL RtlInitializeCriticalSection_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t cs_ptr = SHIM_GET_ARG_32(0); XELOGD("RtlInitializeCriticalSection(%.8X)", cs_ptr); @@ -483,45 +447,41 @@ SHIM_CALL RtlInitializeCriticalSection_shim( xeRtlInitializeCriticalSection(cs); } - -X_STATUS xeRtlInitializeCriticalSectionAndSpinCount( - X_RTL_CRITICAL_SECTION* cs, uint32_t spin_count) { +X_STATUS xeRtlInitializeCriticalSectionAndSpinCount(X_RTL_CRITICAL_SECTION* cs, + uint32_t spin_count) { // NTSTATUS // _Out_ LPCRITICAL_SECTION lpCriticalSection, // _In_ DWORD dwSpinCount // Spin count is rouned up to 256 intervals then packed in. - //uint32_t spin_count_div_256 = (uint32_t)floor(spin_count / 256.0f + 0.5f); + // uint32_t spin_count_div_256 = (uint32_t)floor(spin_count / 256.0f + 0.5f); uint32_t spin_count_div_256 = (spin_count + 255) >> 8; if (spin_count_div_256 > 255) { spin_count_div_256 = 255; } - cs->unknown00 = 1; - cs->spin_count_div_256 = spin_count_div_256; - cs->lock_count = -1; - cs->recursion_count = 0; - cs->owning_thread_id = 0; + cs->unknown00 = 1; + cs->spin_count_div_256 = spin_count_div_256; + cs->lock_count = -1; + cs->recursion_count = 0; + cs->owning_thread_id = 0; return X_STATUS_SUCCESS; } - -SHIM_CALL RtlInitializeCriticalSectionAndSpinCount_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL RtlInitializeCriticalSectionAndSpinCount_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t cs_ptr = SHIM_GET_ARG_32(0); uint32_t spin_count = SHIM_GET_ARG_32(1); - XELOGD("RtlInitializeCriticalSectionAndSpinCount(%.8X, %d)", - cs_ptr, spin_count); + XELOGD("RtlInitializeCriticalSectionAndSpinCount(%.8X, %d)", cs_ptr, + spin_count); auto cs = (X_RTL_CRITICAL_SECTION*)SHIM_MEM_ADDR(cs_ptr); - X_STATUS result = xeRtlInitializeCriticalSectionAndSpinCount( - cs, spin_count); + X_STATUS result = xeRtlInitializeCriticalSectionAndSpinCount(cs, spin_count); SHIM_SET_RETURN_32(result); } - // TODO(benvanik): remove the need for passing in thread_id. void xeRtlEnterCriticalSection(X_RTL_CRITICAL_SECTION* cs, uint32_t thread_id) { // VOID @@ -545,19 +505,19 @@ spin: // All out of spin waits, create a full waiter. // TODO(benvanik): contention - do a real wait! - //XELOGE("RtlEnterCriticalSection tried to really lock!"); - spin_wait_remaining = 1; // HACK: spin forever + // XELOGE("RtlEnterCriticalSection tried to really lock!"); + spin_wait_remaining = 1; // HACK: spin forever Sleep(1); goto spin; } // Now own the lock. - cs->owning_thread_id = thread_id; - cs->recursion_count = 1; + cs->owning_thread_id = thread_id; + cs->recursion_count = 1; } -SHIM_CALL RtlEnterCriticalSection_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL RtlEnterCriticalSection_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t cs_ptr = SHIM_GET_ARG_32(0); // XELOGD("RtlEnterCriticalSection(%.8X)", cs_ptr); @@ -569,16 +529,16 @@ SHIM_CALL RtlEnterCriticalSection_shim( xeRtlEnterCriticalSection(cs, thread_id); } - // TODO(benvanik): remove the need for passing in thread_id. -uint32_t xeRtlTryEnterCriticalSection(X_RTL_CRITICAL_SECTION* cs, uint32_t thread_id) { +uint32_t xeRtlTryEnterCriticalSection(X_RTL_CRITICAL_SECTION* cs, + uint32_t thread_id) { // DWORD // _Inout_ LPCRITICAL_SECTION lpCriticalSection if (poly::atomic_cas(-1, 0, &cs->lock_count)) { // Able to steal the lock right away. - cs->owning_thread_id = thread_id; - cs->recursion_count = 1; + cs->owning_thread_id = thread_id; + cs->recursion_count = 1; return 1; } else if (cs->owning_thread_id == thread_id) { poly::atomic_inc(&cs->lock_count); @@ -589,9 +549,8 @@ uint32_t xeRtlTryEnterCriticalSection(X_RTL_CRITICAL_SECTION* cs, uint32_t threa return 0; } - -SHIM_CALL RtlTryEnterCriticalSection_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL RtlTryEnterCriticalSection_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t cs_ptr = SHIM_GET_ARG_32(0); // XELOGD("RtlTryEnterCriticalSection(%.8X)", cs_ptr); @@ -604,7 +563,6 @@ SHIM_CALL RtlTryEnterCriticalSection_shim( SHIM_SET_RETURN_64(result); } - void xeRtlLeaveCriticalSection(X_RTL_CRITICAL_SECTION* cs) { // VOID // _Inout_ LPCRITICAL_SECTION lpCriticalSection @@ -617,7 +575,7 @@ void xeRtlLeaveCriticalSection(X_RTL_CRITICAL_SECTION* cs) { } // Unlock! - cs->owning_thread_id = 0; + cs->owning_thread_id = 0; if (poly::atomic_dec(&cs->lock_count) != -1) { // There were waiters - wake one of them. // TODO(benvanik): wake a waiter. @@ -625,9 +583,8 @@ void xeRtlLeaveCriticalSection(X_RTL_CRITICAL_SECTION* cs) { } } - -SHIM_CALL RtlLeaveCriticalSection_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL RtlLeaveCriticalSection_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t cs_ptr = SHIM_GET_ARG_32(0); // XELOGD("RtlLeaveCriticalSection(%.8X)", cs_ptr); @@ -636,9 +593,7 @@ SHIM_CALL RtlLeaveCriticalSection_shim( xeRtlLeaveCriticalSection(cs); } - -SHIM_CALL RtlTimeToTimeFields_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL RtlTimeToTimeFields_shim(PPCContext* ppc_state, KernelState* state) { uint32_t time_ptr = SHIM_GET_ARG_32(0); uint32_t time_fields_ptr = SHIM_GET_ARG_32(1); @@ -661,22 +616,20 @@ SHIM_CALL RtlTimeToTimeFields_shim( SHIM_SET_MEM_16(time_fields_ptr + 12, st.wMilliseconds); } - -SHIM_CALL RtlTimeFieldsToTime_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL RtlTimeFieldsToTime_shim(PPCContext* ppc_state, KernelState* state) { uint32_t time_fields_ptr = SHIM_GET_ARG_32(0); uint32_t time_ptr = SHIM_GET_ARG_32(1); XELOGD("RtlTimeFieldsToTime(%.8X, %.8X)", time_fields_ptr, time_ptr); SYSTEMTIME st; - st.wYear = SHIM_MEM_16(time_fields_ptr + 0); - st.wMonth = SHIM_MEM_16(time_fields_ptr + 2); - st.wDay = SHIM_MEM_16(time_fields_ptr + 4); - st.wHour = SHIM_MEM_16(time_fields_ptr + 6); - st.wMinute = SHIM_MEM_16(time_fields_ptr + 8); - st.wSecond = SHIM_MEM_16(time_fields_ptr + 10); - st.wMilliseconds = SHIM_MEM_16(time_fields_ptr + 12); + st.wYear = SHIM_MEM_16(time_fields_ptr + 0); + st.wMonth = SHIM_MEM_16(time_fields_ptr + 2); + st.wDay = SHIM_MEM_16(time_fields_ptr + 4); + st.wHour = SHIM_MEM_16(time_fields_ptr + 6); + st.wMinute = SHIM_MEM_16(time_fields_ptr + 8); + st.wSecond = SHIM_MEM_16(time_fields_ptr + 10); + st.wMilliseconds = SHIM_MEM_16(time_fields_ptr + 12); FILETIME ft; if (!SystemTimeToFileTime(&st, &ft)) { @@ -690,13 +643,11 @@ SHIM_CALL RtlTimeFieldsToTime_shim( SHIM_SET_RETURN_64(1); } - } // namespace kernel } // namespace xe - -void xe::kernel::xboxkrnl::RegisterRtlExports( - ExportResolver* export_resolver, KernelState* state) { +void xe::kernel::xboxkrnl::RegisterRtlExports(ExportResolver* export_resolver, + KernelState* state) { SHIM_SET_MAPPING("xboxkrnl.exe", RtlCompareMemory, state); SHIM_SET_MAPPING("xboxkrnl.exe", RtlCompareMemoryUlong, state); SHIM_SET_MAPPING("xboxkrnl.exe", RtlFillMemoryUlong, state); @@ -717,7 +668,8 @@ void xe::kernel::xboxkrnl::RegisterRtlExports( SHIM_SET_MAPPING("xboxkrnl.exe", RtlImageXexHeaderField, state); SHIM_SET_MAPPING("xboxkrnl.exe", RtlInitializeCriticalSection, state); - SHIM_SET_MAPPING("xboxkrnl.exe", RtlInitializeCriticalSectionAndSpinCount, state); + SHIM_SET_MAPPING("xboxkrnl.exe", RtlInitializeCriticalSectionAndSpinCount, + state); SHIM_SET_MAPPING("xboxkrnl.exe", RtlEnterCriticalSection, state); SHIM_SET_MAPPING("xboxkrnl.exe", RtlTryEnterCriticalSection, state); SHIM_SET_MAPPING("xboxkrnl.exe", RtlLeaveCriticalSection, state); diff --git a/src/xenia/kernel/xboxkrnl_strings.cc b/src/xenia/kernel/xboxkrnl_strings.cc index bc5340a8d..986b2c741 100644 --- a/src/xenia/kernel/xboxkrnl_strings.cc +++ b/src/xenia/kernel/xboxkrnl_strings.cc @@ -17,15 +17,11 @@ #include #include - namespace xe { namespace kernel { - // TODO: clean me up! -SHIM_CALL vsprintf_shim( - PPCContext* ppc_state, KernelState* state) { - +SHIM_CALL vsprintf_shim(PPCContext* ppc_state, KernelState* state) { uint32_t buffer_ptr = SHIM_GET_ARG_32(0); uint32_t format_ptr = SHIM_GET_ARG_32(1); uint32_t arg_ptr = SHIM_GET_ARG_32(2); @@ -63,10 +59,7 @@ SHIM_CALL vsprintf_shim( end = format; // skip flags - while (*end == '-' || - *end == '+' || - *end == ' ' || - *end == '#' || + while (*end == '-' || *end == '+' || *end == ' ' || *end == '#' || *end == '0') { ++end; } @@ -81,8 +74,7 @@ SHIM_CALL vsprintf_shim( if (*end == '*') { ++end; arg_extras++; - } - else { + } else { while (*end >= '0' && *end <= '9') { ++end; } @@ -99,8 +91,7 @@ SHIM_CALL vsprintf_shim( if (*end == '*') { ++end; ++arg_extras; - } - else { + } else { while (*end >= '0' && *end <= '9') { ++end; } @@ -120,28 +111,23 @@ SHIM_CALL vsprintf_shim( if (*end == 'h') { ++end; } - } - else if (*end == 'l') { + } else if (*end == 'l') { ++end; arg_size = 4; if (*end == 'l') { ++end; arg_size = 8; } - } - else if (*end == 'j') { + } else if (*end == 'j') { arg_size = 8; ++end; - } - else if (*end == 'z') { + } else if (*end == 'z') { arg_size = 4; ++end; - } - else if (*end == 't') { + } else if (*end == 't') { arg_size = 8; ++end; - } - else if (*end == 'L') { + } else if (*end == 'L') { arg_size = 8; ++end; } @@ -150,21 +136,10 @@ SHIM_CALL vsprintf_shim( break; } - if (*end == 'd' || - *end == 'i' || - *end == 'u' || - *end == 'o' || - *end == 'x' || - *end == 'X' || - *end == 'f' || - *end == 'F' || - *end == 'e' || - *end == 'E' || - *end == 'g' || - *end == 'G' || - *end == 'a' || - *end == 'A' || - *end == 'c') { + if (*end == 'd' || *end == 'i' || *end == 'u' || *end == 'o' || + *end == 'x' || *end == 'X' || *end == 'f' || *end == 'F' || + *end == 'e' || *end == 'E' || *end == 'g' || *end == 'G' || + *end == 'a' || *end == 'A' || *end == 'c') { char local[512]; local[0] = '\0'; strncat(local, start, end + 1 - start); @@ -172,58 +147,52 @@ SHIM_CALL vsprintf_shim( assert_true(arg_size == 8 || arg_size == 4); if (arg_size == 8) { if (arg_extras == 0) { - uint64_t value = SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... + uint64_t value = SHIM_MEM_64( + arg_ptr + (arg_index * 8)); // TODO: check if this is correct... int result = sprintf(b, local, value); b += result; arg_index++; - } - else { + } else { assert_true(false); } - } - else if (arg_size == 4) { + } else if (arg_size == 4) { if (arg_extras == 0) { - uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... + uint32_t value = (uint32_t)SHIM_MEM_64( + arg_ptr + (arg_index * 8)); // TODO: check if this is correct... int result = sprintf(b, local, value); b += result; arg_index++; - } - else { + } else { assert_true(false); } } - } - else if (*end == 'n') - { + } else if (*end == 'n') { assert_true(arg_size == 4); if (arg_extras == 0) { - uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... - SHIM_SET_MEM_32(value, (uint32_t)((b - buffer) / sizeof(char))); + uint32_t value = (uint32_t)SHIM_MEM_64( + arg_ptr + (arg_index * 8)); // TODO: check if this is correct... + SHIM_SET_MEM_32(value, (uint32_t)((b - buffer) / sizeof(char))); arg_index++; - } - else { + } else { assert_true(false); } - } - else if (*end == 's' || - *end == 'p') { + } else if (*end == 's' || *end == 'p') { char local[512]; local[0] = '\0'; strncat(local, start, end + 1 - start); assert_true(arg_size == 4); if (arg_extras == 0) { - uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... + uint32_t value = (uint32_t)SHIM_MEM_64( + arg_ptr + (arg_index * 8)); // TODO: check if this is correct... const void* pointer = (const void*)SHIM_MEM_ADDR(value); int result = sprintf(b, local, pointer); b += result; arg_index++; - } - else { + } else { assert_true(false); } - } - else { + } else { assert_true(false); break; } @@ -233,11 +202,8 @@ SHIM_CALL vsprintf_shim( SHIM_SET_RETURN_32((uint32_t)(b - buffer)); } - // TODO: clean me up! -SHIM_CALL _vsnprintf_shim( - PPCContext* ppc_state, KernelState* state) { - +SHIM_CALL _vsnprintf_shim(PPCContext* ppc_state, KernelState* state) { uint32_t buffer_ptr = SHIM_GET_ARG_32(0); uint32_t count = SHIM_GET_ARG_32(1); uint32_t format_ptr = SHIM_GET_ARG_32(2); @@ -248,7 +214,9 @@ SHIM_CALL _vsnprintf_shim( return; } - char* buffer = (char*)SHIM_MEM_ADDR(buffer_ptr); // TODO: ensure it never writes past the end of the buffer (count)... + char* buffer = (char*)SHIM_MEM_ADDR(buffer_ptr); // TODO: ensure it never + // writes past the end of + // the buffer (count)... const char* format = (const char*)SHIM_MEM_ADDR(format_ptr); int arg_index = 0; @@ -276,10 +244,7 @@ SHIM_CALL _vsnprintf_shim( end = format; // skip flags - while (*end == '-' || - *end == '+' || - *end == ' ' || - *end == '#' || + while (*end == '-' || *end == '+' || *end == ' ' || *end == '#' || *end == '0') { ++end; } @@ -294,8 +259,7 @@ SHIM_CALL _vsnprintf_shim( if (*end == '*') { ++end; arg_extras++; - } - else { + } else { while (*end >= '0' && *end <= '9') { ++end; } @@ -312,8 +276,7 @@ SHIM_CALL _vsnprintf_shim( if (*end == '*') { ++end; ++arg_extras; - } - else { + } else { while (*end >= '0' && *end <= '9') { ++end; } @@ -333,28 +296,23 @@ SHIM_CALL _vsnprintf_shim( if (*end == 'h') { ++end; } - } - else if (*end == 'l') { + } else if (*end == 'l') { ++end; arg_size = 4; if (*end == 'l') { ++end; arg_size = 8; } - } - else if (*end == 'j') { + } else if (*end == 'j') { arg_size = 8; ++end; - } - else if (*end == 'z') { + } else if (*end == 'z') { arg_size = 4; ++end; - } - else if (*end == 't') { + } else if (*end == 't') { arg_size = 8; ++end; - } - else if (*end == 'L') { + } else if (*end == 'L') { arg_size = 8; ++end; } @@ -363,21 +321,10 @@ SHIM_CALL _vsnprintf_shim( break; } - if (*end == 'd' || - *end == 'i' || - *end == 'u' || - *end == 'o' || - *end == 'x' || - *end == 'X' || - *end == 'f' || - *end == 'F' || - *end == 'e' || - *end == 'E' || - *end == 'g' || - *end == 'G' || - *end == 'a' || - *end == 'A' || - *end == 'c') { + if (*end == 'd' || *end == 'i' || *end == 'u' || *end == 'o' || + *end == 'x' || *end == 'X' || *end == 'f' || *end == 'F' || + *end == 'e' || *end == 'E' || *end == 'g' || *end == 'G' || + *end == 'a' || *end == 'A' || *end == 'c') { char local[512]; local[0] = '\0'; strncat(local, start, end + 1 - start); @@ -385,58 +332,52 @@ SHIM_CALL _vsnprintf_shim( assert_true(arg_size == 8 || arg_size == 4); if (arg_size == 8) { if (arg_extras == 0) { - uint64_t value = SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... + uint64_t value = SHIM_MEM_64( + arg_ptr + (arg_index * 8)); // TODO: check if this is correct... int result = sprintf(b, local, value); b += result; arg_index++; - } - else { + } else { assert_true(false); } - } - else if (arg_size == 4) { + } else if (arg_size == 4) { if (arg_extras == 0) { - uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... + uint32_t value = (uint32_t)SHIM_MEM_64( + arg_ptr + (arg_index * 8)); // TODO: check if this is correct... int result = sprintf(b, local, value); b += result; arg_index++; - } - else { + } else { assert_true(false); } } - } - else if (*end == 'n') - { + } else if (*end == 'n') { assert_true(arg_size == 4); if (arg_extras == 0) { - uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... - SHIM_SET_MEM_32(value, (uint32_t)((b - buffer) / sizeof(char))); + uint32_t value = (uint32_t)SHIM_MEM_64( + arg_ptr + (arg_index * 8)); // TODO: check if this is correct... + SHIM_SET_MEM_32(value, (uint32_t)((b - buffer) / sizeof(char))); arg_index++; - } - else { + } else { assert_true(false); } - } - else if (*end == 's' || - *end == 'p') { + } else if (*end == 's' || *end == 'p') { char local[512]; local[0] = '\0'; strncat(local, start, end + 1 - start); assert_true(arg_size == 4); if (arg_extras == 0) { - uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... + uint32_t value = (uint32_t)SHIM_MEM_64( + arg_ptr + (arg_index * 8)); // TODO: check if this is correct... const void* pointer = (const void*)SHIM_MEM_ADDR(value); int result = sprintf(b, local, pointer); b += result; arg_index++; - } - else { + } else { assert_true(false); } - } - else { + } else { assert_true(false); break; } @@ -446,11 +387,8 @@ SHIM_CALL _vsnprintf_shim( SHIM_SET_RETURN_32((uint32_t)(b - buffer)); } - // TODO: clean me up! -SHIM_CALL _vswprintf_shim( - PPCContext* ppc_state, KernelState* state) { - +SHIM_CALL _vswprintf_shim(PPCContext* ppc_state, KernelState* state) { uint32_t buffer_ptr = SHIM_GET_ARG_32(0); uint32_t format_ptr = SHIM_GET_ARG_32(1); uint32_t arg_ptr = SHIM_GET_ARG_32(2); @@ -460,14 +398,17 @@ SHIM_CALL _vswprintf_shim( return; } - wchar_t*buffer = (wchar_t*)SHIM_MEM_ADDR(buffer_ptr); // TODO: ensure it never writes past the end of the buffer (count)... + wchar_t* buffer = + (wchar_t*)SHIM_MEM_ADDR(buffer_ptr); // TODO: ensure it never writes past + // the end of the buffer (count)... const wchar_t* format = (const wchar_t*)SHIM_MEM_ADDR(format_ptr); // this will work since a null is the same regardless of endianness size_t format_length = wcslen(format); // swap the format buffer - wchar_t* swapped_format = (wchar_t*)xe_malloc((format_length + 1) * sizeof(wchar_t)); + wchar_t* swapped_format = + (wchar_t*)xe_malloc((format_length + 1) * sizeof(wchar_t)); for (size_t i = 0; i < format_length; ++i) { swapped_format[i] = poly::byte_swap(format[i]); } @@ -480,7 +421,7 @@ SHIM_CALL _vswprintf_shim( wchar_t* b = buffer; for (; *format != '\0'; ++format) { - const wchar_t *start = format; + const wchar_t* start = format; if (*format != '%') { *b++ = *format; @@ -501,10 +442,7 @@ SHIM_CALL _vswprintf_shim( end = format; // skip flags - while (*end == '-' || - *end == '+' || - *end == ' ' || - *end == '#' || + while (*end == '-' || *end == '+' || *end == ' ' || *end == '#' || *end == '0') { ++end; } @@ -519,8 +457,7 @@ SHIM_CALL _vswprintf_shim( if (*end == '*') { ++end; arg_extras++; - } - else { + } else { while (*end >= '0' && *end <= '9') { ++end; } @@ -537,8 +474,7 @@ SHIM_CALL _vswprintf_shim( if (*end == '*') { ++end; ++arg_extras; - } - else { + } else { while (*end >= '0' && *end <= '9') { ++end; } @@ -558,28 +494,23 @@ SHIM_CALL _vswprintf_shim( if (*end == 'h') { ++end; } - } - else if (*end == 'l') { + } else if (*end == 'l') { ++end; arg_size = 4; if (*end == 'l') { ++end; arg_size = 8; } - } - else if (*end == 'j') { + } else if (*end == 'j') { arg_size = 8; ++end; - } - else if (*end == 'z') { + } else if (*end == 'z') { arg_size = 4; ++end; - } - else if (*end == 't') { + } else if (*end == 't') { arg_size = 8; ++end; - } - else if (*end == 'L') { + } else if (*end == 'L') { arg_size = 8; ++end; } @@ -588,21 +519,10 @@ SHIM_CALL _vswprintf_shim( break; } - if (*end == 'd' || - *end == 'i' || - *end == 'u' || - *end == 'o' || - *end == 'x' || - *end == 'X' || - *end == 'f' || - *end == 'F' || - *end == 'e' || - *end == 'E' || - *end == 'g' || - *end == 'G' || - *end == 'a' || - *end == 'A' || - *end == 'c') { + if (*end == 'd' || *end == 'i' || *end == 'u' || *end == 'o' || + *end == 'x' || *end == 'X' || *end == 'f' || *end == 'F' || + *end == 'e' || *end == 'E' || *end == 'g' || *end == 'G' || + *end == 'a' || *end == 'A' || *end == 'c') { wchar_t local[512]; local[0] = '\0'; wcsncat(local, start, end + 1 - start); @@ -610,67 +530,64 @@ SHIM_CALL _vswprintf_shim( assert_true(arg_size == 8 || arg_size == 4); if (arg_size == 8) { if (arg_extras == 0) { - uint64_t value = SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... + uint64_t value = SHIM_MEM_64( + arg_ptr + (arg_index * 8)); // TODO: check if this is correct... int result = wsprintf(b, local, value); b += result; arg_index++; - } - else { + } else { assert_true(false); } - } - else if (arg_size == 4) { + } else if (arg_size == 4) { if (arg_extras == 0) { - uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... + uint32_t value = (uint32_t)SHIM_MEM_64( + arg_ptr + (arg_index * 8)); // TODO: check if this is correct... int result = wsprintf(b, local, value); b += result; arg_index++; - } - else { + } else { assert_true(false); } } - } - else if (*end == 'n') - { + } else if (*end == 'n') { assert_true(arg_size == 4); if (arg_extras == 0) { - uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... - SHIM_SET_MEM_32(value, (uint32_t)((b - buffer) / sizeof(wchar_t))); + uint32_t value = (uint32_t)SHIM_MEM_64( + arg_ptr + (arg_index * 8)); // TODO: check if this is correct... + SHIM_SET_MEM_32(value, (uint32_t)((b - buffer) / sizeof(wchar_t))); arg_index++; - } - else { + } else { assert_true(false); } - } - else if (*end == 'p') { + } else if (*end == 'p') { wchar_t local[512]; local[0] = '\0'; wcsncat(local, start, end + 1 - start); assert_true(arg_size == 4); if (arg_extras == 0) { - uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... + uint32_t value = (uint32_t)SHIM_MEM_64( + arg_ptr + (arg_index * 8)); // TODO: check if this is correct... const void* pointer = (void*)SHIM_MEM_ADDR(value); int result = wsprintf(b, local, pointer); b += result; arg_index++; - } - else { + } else { assert_true(false); } - } - else if (*end == 's') { + } else if (*end == 's') { wchar_t local[512]; local[0] = '\0'; wcsncat(local, start, end + 1 - start); assert_true(arg_size == 4); if (arg_extras == 0) { - uint32_t value = (uint32_t)SHIM_MEM_64(arg_ptr + (arg_index * 8)); // TODO: check if this is correct... + uint32_t value = (uint32_t)SHIM_MEM_64( + arg_ptr + (arg_index * 8)); // TODO: check if this is correct... const wchar_t* data = (const wchar_t*)SHIM_MEM_ADDR(value); size_t data_length = wcslen(data); - wchar_t* swapped_data = (wchar_t*)xe_malloc((data_length + 1) * sizeof(wchar_t)); + wchar_t* swapped_data = + (wchar_t*)xe_malloc((data_length + 1) * sizeof(wchar_t)); for (size_t i = 0; i < data_length; ++i) { swapped_data[i] = poly::byte_swap(data[i]); } @@ -679,12 +596,10 @@ SHIM_CALL _vswprintf_shim( xe_free(swapped_data); b += result; arg_index++; - } - else { + } else { assert_true(false); } - } - else { + } else { assert_true(false); break; } @@ -695,19 +610,16 @@ SHIM_CALL _vswprintf_shim( xe_free(swapped_format); // swap the result buffer - for (wchar_t* swap = buffer; swap != b; ++swap) - { + for (wchar_t* swap = buffer; swap != b; ++swap) { *swap = poly::byte_swap(*swap); } SHIM_SET_RETURN_32((uint32_t)((b - buffer) / sizeof(wchar_t))); } - } // namespace kernel } // namespace xe - void xe::kernel::xboxkrnl::RegisterStringExports( ExportResolver* export_resolver, KernelState* state) { SHIM_SET_MAPPING("xboxkrnl.exe", vsprintf, state); diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index 7de07269f..56baa20e5 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -22,11 +22,9 @@ #include #include - namespace xe { namespace kernel { - // r13 + 0x100: pointer to thread local state // Thread local state: // 0x058: kernel time @@ -60,9 +58,7 @@ namespace kernel { // stw r3, 0x160(r11) // } - -SHIM_CALL ExCreateThread_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL ExCreateThread_shim(PPCContext* ppc_state, KernelState* state) { uint32_t handle_ptr = SHIM_GET_ARG_32(0); uint32_t stack_size = SHIM_GET_ARG_32(1); uint32_t thread_id_ptr = SHIM_GET_ARG_32(2); @@ -71,15 +67,9 @@ SHIM_CALL ExCreateThread_shim( uint32_t start_context = SHIM_GET_ARG_32(5); uint32_t creation_flags = SHIM_GET_ARG_32(6); - XELOGD( - "ExCreateThread(%.8X, %d, %.8X, %.8X, %.8X, %.8X, %.8X)", - handle_ptr, - stack_size, - thread_id_ptr, - xapi_thread_startup, - start_address, - start_context, - creation_flags); + XELOGD("ExCreateThread(%.8X, %d, %.8X, %.8X, %.8X, %.8X, %.8X)", handle_ptr, + stack_size, thread_id_ptr, xapi_thread_startup, start_address, + start_context, creation_flags); // DWORD // LPHANDLE Handle, @@ -90,9 +80,8 @@ SHIM_CALL ExCreateThread_shim( // LPVOID StartContext, // DWORD CreationFlags // 0x80? - XThread* thread = new XThread( - state, stack_size, xapi_thread_startup, start_address, start_context, - creation_flags); + XThread* thread = new XThread(state, stack_size, xapi_thread_startup, + start_address, start_context, creation_flags); X_STATUS result = thread->Create(); if (XFAILED(result)) { @@ -114,14 +103,10 @@ SHIM_CALL ExCreateThread_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL ExTerminateThread_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL ExTerminateThread_shim(PPCContext* ppc_state, KernelState* state) { uint32_t exit_code = SHIM_GET_ARG_32(0); - XELOGD( - "ExTerminateThread(%d)", - exit_code); + XELOGD("ExTerminateThread(%d)", exit_code); XThread* thread = XThread::GetCurrentThread(); @@ -130,20 +115,15 @@ SHIM_CALL ExTerminateThread_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL NtResumeThread_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtResumeThread_shim(PPCContext* ppc_state, KernelState* state) { uint32_t handle = SHIM_GET_ARG_32(0); uint32_t suspend_count_ptr = SHIM_GET_ARG_32(1); - XELOGD( - "NtResumeThread(%.8X, %.8X)", - handle, - suspend_count_ptr); + XELOGD("NtResumeThread(%.8X, %.8X)", handle, suspend_count_ptr); XThread* thread = NULL; - X_STATUS result = state->object_table()->GetObject( - handle, (XObject**)&thread); + X_STATUS result = + state->object_table()->GetObject(handle, (XObject**)&thread); uint32_t suspend_count; if (XSUCCEEDED(result)) { result = thread->Resume(&suspend_count); @@ -158,19 +138,15 @@ SHIM_CALL NtResumeThread_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL KeResumeThread_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeResumeThread_shim(PPCContext* ppc_state, KernelState* state) { uint32_t thread_ptr = SHIM_GET_ARG_32(0); uint32_t suspend_count_ptr = SHIM_GET_ARG_32(1); - XELOGD( - "KeResumeThread(%.8X, %.8X)", - thread_ptr, - suspend_count_ptr); + XELOGD("KeResumeThread(%.8X, %.8X)", thread_ptr, suspend_count_ptr); X_STATUS result; - XThread* thread = (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); + XThread* thread = + (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); uint32_t suspend_count; if (thread) { result = thread->Resume(&suspend_count); @@ -184,20 +160,15 @@ SHIM_CALL KeResumeThread_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL NtSuspendThread_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtSuspendThread_shim(PPCContext* ppc_state, KernelState* state) { uint32_t handle = SHIM_GET_ARG_32(0); uint32_t suspend_count_ptr = SHIM_GET_ARG_32(1); - XELOGD( - "NtSuspendThread(%.8X, %.8X)", - handle, - suspend_count_ptr); + XELOGD("NtSuspendThread(%.8X, %.8X)", handle, suspend_count_ptr); XThread* thread = NULL; - X_STATUS result = state->object_table()->GetObject( - handle, (XObject**)&thread); + X_STATUS result = + state->object_table()->GetObject(handle, (XObject**)&thread); uint32_t suspend_count; if (XSUCCEEDED(result)) { result = thread->Suspend(&suspend_count); @@ -213,18 +184,14 @@ SHIM_CALL NtSuspendThread_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL KeSetAffinityThread_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeSetAffinityThread_shim(PPCContext* ppc_state, KernelState* state) { uint32_t thread_ptr = SHIM_GET_ARG_32(0); uint32_t affinity = SHIM_GET_ARG_32(1); - XELOGD( - "KeSetAffinityThread(%.8X, %.8X)", - thread_ptr, - affinity); + XELOGD("KeSetAffinityThread(%.8X, %.8X)", thread_ptr, affinity); - XThread* thread = (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); + XThread* thread = + (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); if (thread) { thread->SetAffinity(affinity); } @@ -232,19 +199,16 @@ SHIM_CALL KeSetAffinityThread_shim( SHIM_SET_RETURN_32(affinity); } - -SHIM_CALL KeQueryBasePriorityThread_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeQueryBasePriorityThread_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t thread_ptr = SHIM_GET_ARG_32(0); - XELOGD( - "KeQueryBasePriorityThread(%.8X)", - thread_ptr); + XELOGD("KeQueryBasePriorityThread(%.8X)", thread_ptr); int32_t priority = 0; - XThread* thread = (XThread*)XObject::GetObject( - state, SHIM_MEM_ADDR(thread_ptr)); + XThread* thread = + (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); if (thread) { priority = thread->QueryPriority(); } @@ -252,16 +216,12 @@ SHIM_CALL KeQueryBasePriorityThread_shim( SHIM_SET_RETURN_32(priority); } - -SHIM_CALL KeSetBasePriorityThread_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeSetBasePriorityThread_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t thread_ptr = SHIM_GET_ARG_32(0); uint32_t increment = SHIM_GET_ARG_32(1); - XELOGD( - "KeSetBasePriorityThread(%.8X, %.8X)", - thread_ptr, - increment); + XELOGD("KeSetBasePriorityThread(%.8X, %.8X)", thread_ptr, increment); int32_t prev_priority = 0; @@ -275,9 +235,8 @@ SHIM_CALL KeSetBasePriorityThread_shim( SHIM_SET_RETURN_32(prev_priority); } - -SHIM_CALL KeGetCurrentProcessType_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeGetCurrentProcessType_shim(PPCContext* ppc_state, + KernelState* state) { // XELOGD( // "KeGetCurrentProcessType()"); @@ -287,9 +246,8 @@ SHIM_CALL KeGetCurrentProcessType_shim( SHIM_SET_RETURN_64(result); } - -SHIM_CALL KeQueryPerformanceFrequency_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeQueryPerformanceFrequency_shim(PPCContext* ppc_state, + KernelState* state) { // XELOGD( // "KeQueryPerformanceFrequency()"); @@ -301,9 +259,8 @@ SHIM_CALL KeQueryPerformanceFrequency_shim( SHIM_SET_RETURN_64(result); } - -SHIM_CALL KeDelayExecutionThread_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeDelayExecutionThread_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t processor_mode = SHIM_GET_ARG_32(0); uint32_t alertable = SHIM_GET_ARG_32(1); uint32_t interval_ptr = SHIM_GET_ARG_32(2); @@ -319,23 +276,17 @@ SHIM_CALL KeDelayExecutionThread_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL NtYieldExecution_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtYieldExecution_shim(PPCContext* ppc_state, KernelState* state) { XELOGD("NtYieldExecution()"); XThread* thread = XThread::GetCurrentThread(); X_STATUS result = thread->Delay(0, 0, 0); SHIM_SET_RETURN_64(0); } - -SHIM_CALL KeQuerySystemTime_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeQuerySystemTime_shim(PPCContext* ppc_state, KernelState* state) { uint32_t time_ptr = SHIM_GET_ARG_32(0); - XELOGD( - "KeQuerySystemTime(%.8X)", - time_ptr); + XELOGD("KeQuerySystemTime(%.8X)", time_ptr); FILETIME t; GetSystemTimeAsFileTime(&t); @@ -346,18 +297,14 @@ SHIM_CALL KeQuerySystemTime_shim( } } - // The TLS system used here is a bit hacky, but seems to work. // Both Win32 and pthreads use unsigned longs as TLS indices, so we can map // right into the system for these calls. We're just round tripping the IDs and // hoping for the best. - // http://msdn.microsoft.com/en-us/library/ms686801 -SHIM_CALL KeTlsAlloc_shim( - PPCContext* ppc_state, KernelState* state) { - XELOGD( - "KeTlsAlloc()"); +SHIM_CALL KeTlsAlloc_shim(PPCContext* ppc_state, KernelState* state) { + XELOGD("KeTlsAlloc()"); uint32_t tls_index; @@ -375,15 +322,11 @@ SHIM_CALL KeTlsAlloc_shim( SHIM_SET_RETURN_64(tls_index); } - // http://msdn.microsoft.com/en-us/library/ms686804 -SHIM_CALL KeTlsFree_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeTlsFree_shim(PPCContext* ppc_state, KernelState* state) { uint32_t tls_index = SHIM_GET_ARG_32(0); - XELOGD( - "KeTlsFree(%.8X)", - tls_index); + XELOGD("KeTlsFree(%.8X)", tls_index); if (tls_index == X_TLS_OUT_OF_INDEXES) { SHIM_SET_RETURN_64(0); @@ -401,14 +344,12 @@ SHIM_CALL KeTlsFree_shim( SHIM_SET_RETURN_64(result); } - // http://msdn.microsoft.com/en-us/library/ms686812 -SHIM_CALL KeTlsGetValue_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeTlsGetValue_shim(PPCContext* ppc_state, KernelState* state) { uint32_t tls_index = SHIM_GET_ARG_32(0); // Logging disabled, as some games spam this. - //XELOGD( + // XELOGD( // "KeTlsGetValue(%.8X)", // tls_index); @@ -428,16 +369,12 @@ SHIM_CALL KeTlsGetValue_shim( SHIM_SET_RETURN_64(value); } - // http://msdn.microsoft.com/en-us/library/ms686818 -SHIM_CALL KeTlsSetValue_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeTlsSetValue_shim(PPCContext* ppc_state, KernelState* state) { uint32_t tls_index = SHIM_GET_ARG_32(0); uint32_t tls_value = SHIM_GET_ARG_32(1); - XELOGD( - "KeTlsSetValue(%.8X, %.8X)", - tls_index, tls_value); + XELOGD("KeTlsSetValue(%.8X, %.8X)", tls_index, tls_value); int result = 0; @@ -450,17 +387,14 @@ SHIM_CALL KeTlsSetValue_shim( SHIM_SET_RETURN_64(result); } - -SHIM_CALL NtCreateEvent_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtCreateEvent_shim(PPCContext* ppc_state, KernelState* state) { uint32_t handle_ptr = SHIM_GET_ARG_32(0); uint32_t obj_attributes_ptr = SHIM_GET_ARG_32(1); uint32_t event_type = SHIM_GET_ARG_32(2); uint32_t initial_state = SHIM_GET_ARG_32(3); - XELOGD( - "NtCreateEvent(%.8X, %.8X, %d, %d)", - handle_ptr, obj_attributes_ptr, event_type, initial_state); + XELOGD("NtCreateEvent(%.8X, %.8X, %d, %d)", handle_ptr, obj_attributes_ptr, + event_type, initial_state); XEvent* ev = new XEvent(state); ev->Initialize(!event_type, !!initial_state); @@ -468,7 +402,7 @@ SHIM_CALL NtCreateEvent_shim( // obj_attributes may have a name inside of it, if != NULL. auto obj_attributes = SHIM_MEM_ADDR(obj_attributes_ptr); if (obj_attributes) { - //ev->SetName(...); + // ev->SetName(...); } if (handle_ptr) { @@ -477,16 +411,12 @@ SHIM_CALL NtCreateEvent_shim( SHIM_SET_RETURN_32(X_STATUS_SUCCESS); } - -SHIM_CALL KeSetEvent_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeSetEvent_shim(PPCContext* ppc_state, KernelState* state) { uint32_t event_ref = SHIM_GET_ARG_32(0); uint32_t increment = SHIM_GET_ARG_32(1); uint32_t wait = SHIM_GET_ARG_32(2); - XELOGD( - "KeSetEvent(%.8X, %.8X, %.8X)", - event_ref, increment, wait); + XELOGD("KeSetEvent(%.8X, %.8X, %.8X)", event_ref, increment, wait); void* event_ptr = SHIM_MEM_ADDR(event_ref); @@ -501,21 +431,16 @@ SHIM_CALL KeSetEvent_shim( SHIM_SET_RETURN_64(result); } - -SHIM_CALL NtSetEvent_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtSetEvent_shim(PPCContext* ppc_state, KernelState* state) { uint32_t event_handle = SHIM_GET_ARG_32(0); uint32_t previous_state_ptr = SHIM_GET_ARG_32(1); - XELOGD( - "NtSetEvent(%.8X, %.8X)", - event_handle, previous_state_ptr); + XELOGD("NtSetEvent(%.8X, %.8X)", event_handle, previous_state_ptr); X_STATUS result = X_STATUS_SUCCESS; XEvent* ev = NULL; - result = state->object_table()->GetObject( - event_handle, (XObject**)&ev); + result = state->object_table()->GetObject(event_handle, (XObject**)&ev); if (XSUCCEEDED(result)) { int32_t was_signalled = ev->Set(0, false); if (previous_state_ptr) { @@ -528,16 +453,12 @@ SHIM_CALL NtSetEvent_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL KePulseEvent_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KePulseEvent_shim(PPCContext* ppc_state, KernelState* state) { uint32_t event_ref = SHIM_GET_ARG_32(0); uint32_t increment = SHIM_GET_ARG_32(1); uint32_t wait = SHIM_GET_ARG_32(2); - XELOGD( - "KePulseEvent(%.8X, %.8X, %.8X)", - event_ref, increment, wait); + XELOGD("KePulseEvent(%.8X, %.8X, %.8X)", event_ref, increment, wait); int32_t result = 0; @@ -551,21 +472,16 @@ SHIM_CALL KePulseEvent_shim( SHIM_SET_RETURN_64(result); } - -SHIM_CALL NtPulseEvent_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtPulseEvent_shim(PPCContext* ppc_state, KernelState* state) { uint32_t event_handle = SHIM_GET_ARG_32(0); uint32_t previous_state_ptr = SHIM_GET_ARG_32(1); - XELOGD( - "NtPulseEvent(%.8X, %.8X)", - event_handle, previous_state_ptr); + XELOGD("NtPulseEvent(%.8X, %.8X)", event_handle, previous_state_ptr); X_STATUS result = X_STATUS_SUCCESS; XEvent* ev = NULL; - result = state->object_table()->GetObject( - event_handle, (XObject**)&ev); + result = state->object_table()->GetObject(event_handle, (XObject**)&ev); if (XSUCCEEDED(result)) { int32_t was_signalled = ev->Pulse(0, false); if (previous_state_ptr) { @@ -578,14 +494,10 @@ SHIM_CALL NtPulseEvent_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL KeResetEvent_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeResetEvent_shim(PPCContext* ppc_state, KernelState* state) { uint32_t event_ref = SHIM_GET_ARG_32(0); - XELOGD( - "KeResetEvent(%.8X)", - event_ref); + XELOGD("KeResetEvent(%.8X)", event_ref); void* event_ptr = SHIM_MEM_ADDR(event_ref); XEvent* ev = (XEvent*)XEvent::GetObject(state, event_ptr); @@ -599,20 +511,15 @@ SHIM_CALL KeResetEvent_shim( SHIM_SET_RETURN_64(result); } - -SHIM_CALL NtClearEvent_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtClearEvent_shim(PPCContext* ppc_state, KernelState* state) { uint32_t event_handle = SHIM_GET_ARG_32(0); - XELOGD( - "NtClearEvent(%.8X)", - event_handle); + XELOGD("NtClearEvent(%.8X)", event_handle); X_STATUS result = X_STATUS_SUCCESS; XEvent* ev = NULL; - result = state->object_table()->GetObject( - event_handle, (XObject**)&ev); + result = state->object_table()->GetObject(event_handle, (XObject**)&ev); if (XSUCCEEDED(result)) { ev->Reset(); ev->Release(); @@ -621,24 +528,21 @@ SHIM_CALL NtClearEvent_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL NtCreateSemaphore_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtCreateSemaphore_shim(PPCContext* ppc_state, KernelState* state) { uint32_t handle_ptr = SHIM_GET_ARG_32(0); uint32_t obj_attributes_ptr = SHIM_GET_ARG_32(1); int32_t count = SHIM_GET_ARG_32(2); int32_t limit = SHIM_GET_ARG_32(3); - XELOGD( - "NtCreateSemaphore(%.8X, %.8X, %d, %d)", - handle_ptr, obj_attributes_ptr, count, limit); + XELOGD("NtCreateSemaphore(%.8X, %.8X, %d, %d)", handle_ptr, + obj_attributes_ptr, count, limit); XSemaphore* sem = new XSemaphore(state); sem->Initialize(count, limit); // obj_attributes may have a name inside of it, if != NULL. if (obj_attributes_ptr) { - //sem->SetName(...); + // sem->SetName(...); } if (handle_ptr) { @@ -648,20 +552,17 @@ SHIM_CALL NtCreateSemaphore_shim( SHIM_SET_RETURN_32(X_STATUS_SUCCESS); } - -SHIM_CALL KeInitializeSemaphore_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeInitializeSemaphore_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t semaphore_ref = SHIM_GET_ARG_32(0); int32_t count = SHIM_GET_ARG_32(1); int32_t limit = SHIM_GET_ARG_32(2); - XELOGD( - "KeInitializeSemaphore(%.8X, %d, %d)", - semaphore_ref, count, limit); + XELOGD("KeInitializeSemaphore(%.8X, %d, %d)", semaphore_ref, count, limit); void* semaphore_ptr = SHIM_MEM_ADDR(semaphore_ref); - XSemaphore* sem = (XSemaphore*)XSemaphore::GetObject( - state, semaphore_ptr, 5 /* SemaphoreObject */); + XSemaphore* sem = (XSemaphore*)XSemaphore::GetObject(state, semaphore_ptr, + 5 /* SemaphoreObject */); assert_not_null(sem); if (!sem) { return; @@ -670,17 +571,14 @@ SHIM_CALL KeInitializeSemaphore_shim( sem->Initialize(count, limit); } - -SHIM_CALL KeReleaseSemaphore_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeReleaseSemaphore_shim(PPCContext* ppc_state, KernelState* state) { uint32_t semaphore_ref = SHIM_GET_ARG_32(0); int32_t increment = SHIM_GET_ARG_32(1); int32_t adjustment = SHIM_GET_ARG_32(2); int32_t wait = SHIM_GET_ARG_32(3); - XELOGD( - "KeReleaseSemaphore(%.8X, %d, %d, %d)", - semaphore_ref, increment, adjustment, wait); + XELOGD("KeReleaseSemaphore(%.8X, %d, %d, %d)", semaphore_ref, increment, + adjustment, wait); void* semaphore_ptr = SHIM_MEM_ADDR(semaphore_ref); XSemaphore* sem = (XSemaphore*)XSemaphore::GetObject(state, semaphore_ptr); @@ -697,22 +595,18 @@ SHIM_CALL KeReleaseSemaphore_shim( SHIM_SET_RETURN_64(result); } - -SHIM_CALL NtReleaseSemaphore_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtReleaseSemaphore_shim(PPCContext* ppc_state, KernelState* state) { uint32_t sem_handle = SHIM_GET_ARG_32(0); int32_t release_count = SHIM_GET_ARG_32(1); int32_t previous_count_ptr = SHIM_GET_ARG_32(2); - XELOGD( - "NtReleaseSemaphore(%.8X, %d, %.8X)", - sem_handle, release_count, previous_count_ptr); + XELOGD("NtReleaseSemaphore(%.8X, %d, %.8X)", sem_handle, release_count, + previous_count_ptr); X_STATUS result = X_STATUS_SUCCESS; XSemaphore* sem = NULL; - result = state->object_table()->GetObject( - sem_handle, (XObject**)&sem); + result = state->object_table()->GetObject(sem_handle, (XObject**)&sem); if (XSUCCEEDED(result)) { int32_t previous_count = sem->ReleaseSemaphore(release_count); sem->Release(); @@ -725,23 +619,20 @@ SHIM_CALL NtReleaseSemaphore_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL NtCreateMutant_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtCreateMutant_shim(PPCContext* ppc_state, KernelState* state) { uint32_t handle_ptr = SHIM_GET_ARG_32(0); uint32_t obj_attributes_ptr = SHIM_GET_ARG_32(1); uint32_t initial_owner = SHIM_GET_ARG_32(2); - XELOGD( - "NtCreateMutant(%.8X, %.8X, %.1X)", - handle_ptr, obj_attributes_ptr, initial_owner); + XELOGD("NtCreateMutant(%.8X, %.8X, %.1X)", handle_ptr, obj_attributes_ptr, + initial_owner); XMutant* mutant = new XMutant(state); mutant->Initialize(initial_owner ? true : false); // obj_attributes may have a name inside of it, if != NULL. if (obj_attributes_ptr) { - //mutant->SetName(...); + // mutant->SetName(...); } if (handle_ptr) { @@ -751,13 +642,11 @@ SHIM_CALL NtCreateMutant_shim( SHIM_SET_RETURN_32(X_STATUS_SUCCESS); } - -SHIM_CALL NtReleaseMutant_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtReleaseMutant_shim(PPCContext* ppc_state, KernelState* state) { uint32_t mutant_handle = SHIM_GET_ARG_32(0); int32_t unknown = SHIM_GET_ARG_32(1); // This doesn't seem to be supported. - //int32_t previous_count_ptr = SHIM_GET_ARG_32(2); + // int32_t previous_count_ptr = SHIM_GET_ARG_32(2); // Whatever arg 1 is all games seem to set it to 0, so whether it's // abandon or wait we just say false. Which is good, cause they are @@ -767,15 +656,12 @@ SHIM_CALL NtReleaseMutant_shim( bool abandon = false; bool wait = false; - XELOGD( - "NtReleaseMutant(%.8X, %.8X)", - mutant_handle, unknown); + XELOGD("NtReleaseMutant(%.8X, %.8X)", mutant_handle, unknown); X_STATUS result = X_STATUS_SUCCESS; XMutant* mutant = NULL; - result = state->object_table()->GetObject( - mutant_handle, (XObject**)&mutant); + result = state->object_table()->GetObject(mutant_handle, (XObject**)&mutant); if (XSUCCEEDED(result)) { result = mutant->ReleaseMutant(priority_increment, abandon, wait); mutant->Release(); @@ -784,25 +670,22 @@ SHIM_CALL NtReleaseMutant_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL NtCreateTimer_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtCreateTimer_shim(PPCContext* ppc_state, KernelState* state) { uint32_t handle_ptr = SHIM_GET_ARG_32(0); uint32_t obj_attributes_ptr = SHIM_GET_ARG_32(1); uint32_t timer_type = SHIM_GET_ARG_32(2); // timer_type = NotificationTimer (0) or SynchronizationTimer (1) - XELOGD( - "NtCreateTimer(%.8X, %.8X, %.1X)", - handle_ptr, obj_attributes_ptr, timer_type); + XELOGD("NtCreateTimer(%.8X, %.8X, %.1X)", handle_ptr, obj_attributes_ptr, + timer_type); XTimer* timer = new XTimer(state); timer->Initialize(timer_type); // obj_attributes may have a name inside of it, if != NULL. if (obj_attributes_ptr) { - //timer->SetName(...); + // timer->SetName(...); } if (handle_ptr) { @@ -812,12 +695,10 @@ SHIM_CALL NtCreateTimer_shim( SHIM_SET_RETURN_32(X_STATUS_SUCCESS); } - -SHIM_CALL NtSetTimerEx_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtSetTimerEx_shim(PPCContext* ppc_state, KernelState* state) { uint32_t timer_handle = SHIM_GET_ARG_32(0); uint32_t due_time_ptr = SHIM_GET_ARG_32(1); - uint32_t routine = SHIM_GET_ARG_32(2); // PTIMERAPCROUTINE + uint32_t routine = SHIM_GET_ARG_32(2); // PTIMERAPCROUTINE uint32_t unk_one = SHIM_GET_ARG_32(3); uint32_t routine_arg = SHIM_GET_ARG_32(4); uint32_t resume = SHIM_GET_ARG_32(5); @@ -829,43 +710,36 @@ SHIM_CALL NtSetTimerEx_shim( uint64_t due_time = SHIM_MEM_64(due_time_ptr); - XELOGD( - "NtSetTimerEx(%.8X, %.8X(%lld), %.8X, %.8X, %.8X, %.1X, %d, %.8X)", - timer_handle, due_time_ptr, due_time, routine, unk_one, - routine_arg, resume, period_ms, unk_zero); + XELOGD("NtSetTimerEx(%.8X, %.8X(%lld), %.8X, %.8X, %.8X, %.1X, %d, %.8X)", + timer_handle, due_time_ptr, due_time, routine, unk_one, routine_arg, + resume, period_ms, unk_zero); X_STATUS result = X_STATUS_SUCCESS; XTimer* timer = NULL; - result = state->object_table()->GetObject( - timer_handle, (XObject**)&timer); + result = state->object_table()->GetObject(timer_handle, (XObject**)&timer); if (XSUCCEEDED(result)) { - result = timer->SetTimer( - due_time, period_ms, routine, routine_arg, resume ? true : false); + result = timer->SetTimer(due_time, period_ms, routine, routine_arg, + resume ? true : false); timer->Release(); } SHIM_SET_RETURN_32(result); } - -SHIM_CALL NtCancelTimer_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtCancelTimer_shim(PPCContext* ppc_state, KernelState* state) { uint32_t timer_handle = SHIM_GET_ARG_32(0); uint32_t current_state_ptr = SHIM_GET_ARG_32(1); // UNVERIFIED DebugBreak(); - XELOGD( - "NtCancelTimer(%.8X, %.8X)", - timer_handle, current_state_ptr); + XELOGD("NtCancelTimer(%.8X, %.8X)", timer_handle, current_state_ptr); X_STATUS result = X_STATUS_SUCCESS; XTimer* timer = NULL; - result = state->object_table()->GetObject( - timer_handle, (XObject**)&timer); + result = state->object_table()->GetObject(timer_handle, (XObject**)&timer); if (XSUCCEEDED(result)) { result = timer->Cancel(); timer->Release(); @@ -878,18 +752,16 @@ SHIM_CALL NtCancelTimer_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL KeWaitForSingleObject_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeWaitForSingleObject_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t object_ptr = SHIM_GET_ARG_32(0); uint32_t wait_reason = SHIM_GET_ARG_32(1); uint32_t processor_mode = SHIM_GET_ARG_32(2); uint32_t alertable = SHIM_GET_ARG_32(3); uint32_t timeout_ptr = SHIM_GET_ARG_32(4); - XELOGD( - "KeWaitForSingleObject(%.8X, %.8X, %.8X, %.1X, %.8X)", - object_ptr, wait_reason, processor_mode, alertable, timeout_ptr); + XELOGD("KeWaitForSingleObject(%.8X, %.8X, %.8X, %.1X, %.8X)", object_ptr, + wait_reason, processor_mode, alertable, timeout_ptr); XObject* object = XObject::GetObject(state, SHIM_MEM_ADDR(object_ptr)); if (!object) { @@ -905,37 +777,32 @@ SHIM_CALL KeWaitForSingleObject_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL NtWaitForSingleObjectEx_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtWaitForSingleObjectEx_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t object_handle = SHIM_GET_ARG_32(0); uint8_t wait_mode = SHIM_GET_ARG_8(1); uint32_t alertable = SHIM_GET_ARG_32(2); uint32_t timeout_ptr = SHIM_GET_ARG_32(3); - XELOGD( - "NtWaitForSingleObjectEx(%.8X, %u, %.1X, %.8X)", - object_handle, (uint32_t)wait_mode, alertable, timeout_ptr); + XELOGD("NtWaitForSingleObjectEx(%.8X, %u, %.1X, %.8X)", object_handle, + (uint32_t)wait_mode, alertable, timeout_ptr); X_STATUS result = X_STATUS_SUCCESS; XObject* object = NULL; - result = state->object_table()->GetObject( - object_handle, &object); + result = state->object_table()->GetObject(object_handle, &object); if (XSUCCEEDED(result)) { uint64_t timeout = timeout_ptr ? SHIM_MEM_64(timeout_ptr) : 0; - result = object->Wait( - 3, wait_mode, alertable, - timeout_ptr ? &timeout : NULL); + result = + object->Wait(3, wait_mode, alertable, timeout_ptr ? &timeout : NULL); object->Release(); } SHIM_SET_RETURN_32(result); } - -SHIM_CALL KeWaitForMultipleObjects_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeWaitForMultipleObjects_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t count = SHIM_GET_ARG_32(0); uint32_t objects_ptr = SHIM_GET_ARG_32(1); uint32_t wait_type = SHIM_GET_ARG_32(2); @@ -947,8 +814,8 @@ SHIM_CALL KeWaitForMultipleObjects_shim( XELOGD( "KeWaitForMultipleObjects(%d, %.8X, %.8X, %.8X, %.8X, %.1X, %.8X, %.8X)", - count, objects_ptr, wait_type, wait_reason, processor_mode, - alertable, timeout_ptr, wait_block_array_ptr); + count, objects_ptr, wait_type, wait_reason, processor_mode, alertable, + timeout_ptr, wait_block_array_ptr); assert_true(wait_type >= 0 && wait_type <= 1); @@ -966,28 +833,24 @@ SHIM_CALL KeWaitForMultipleObjects_shim( } uint64_t timeout = timeout_ptr ? SHIM_MEM_64(timeout_ptr) : 0; - result = XObject::WaitMultiple( - count, objects, - wait_type, wait_reason, processor_mode, alertable, - timeout_ptr ? &timeout : NULL); + result = XObject::WaitMultiple(count, objects, wait_type, wait_reason, + processor_mode, alertable, + timeout_ptr ? &timeout : NULL); SHIM_SET_RETURN_32(result); } - -SHIM_CALL NtWaitForMultipleObjectsEx_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtWaitForMultipleObjectsEx_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t count = SHIM_GET_ARG_32(0); uint32_t handles_ptr = SHIM_GET_ARG_32(1); uint32_t wait_type = SHIM_GET_ARG_32(2); - uint8_t wait_mode = SHIM_GET_ARG_8(3); + uint8_t wait_mode = SHIM_GET_ARG_8(3); uint32_t alertable = SHIM_GET_ARG_32(4); uint32_t timeout_ptr = SHIM_GET_ARG_32(5); - XELOGD( - "NtWaitForMultipleObjectsEx(%d, %.8X, %.8X, %.8X, %.8X, %.8X)", - count, handles_ptr, wait_type, wait_mode, - alertable, timeout_ptr); + XELOGD("NtWaitForMultipleObjectsEx(%d, %.8X, %.8X, %.8X, %.8X, %.8X)", count, + handles_ptr, wait_type, wait_mode, alertable, timeout_ptr); assert_true(wait_type >= 0 && wait_type <= 1); @@ -1006,43 +869,35 @@ SHIM_CALL NtWaitForMultipleObjectsEx_shim( } uint64_t timeout = timeout_ptr ? SHIM_MEM_64(timeout_ptr) : 0; - result = XObject::WaitMultiple( - count, objects, - wait_type, 6, wait_mode, alertable, - timeout_ptr ? &timeout : NULL); + result = XObject::WaitMultiple(count, objects, wait_type, 6, wait_mode, + alertable, timeout_ptr ? &timeout : NULL); SHIM_SET_RETURN_32(result); } - -SHIM_CALL NtSignalAndWaitForSingleObjectEx_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtSignalAndWaitForSingleObjectEx_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t signal_handle = SHIM_GET_ARG_32(0); uint32_t wait_handle = SHIM_GET_ARG_32(1); uint32_t alertable = SHIM_GET_ARG_32(2); uint32_t unk_3 = SHIM_GET_ARG_32(3); uint32_t timeout_ptr = SHIM_GET_ARG_32(4); - XELOGD( - "NtSignalAndWaitForSingleObjectEx(%.8X, %.8X, %.1X, %.8X, %.8X)", - signal_handle, wait_handle, alertable, unk_3, - timeout_ptr); + XELOGD("NtSignalAndWaitForSingleObjectEx(%.8X, %.8X, %.1X, %.8X, %.8X)", + signal_handle, wait_handle, alertable, unk_3, timeout_ptr); X_STATUS result = X_STATUS_SUCCESS; XObject* signal_object = NULL; XObject* wait_object = NULL; - result = state->object_table()->GetObject( - signal_handle, &signal_object); + result = state->object_table()->GetObject(signal_handle, &signal_object); if (XSUCCEEDED(result)) { - result = state->object_table()->GetObject( - wait_handle, &wait_object); + result = state->object_table()->GetObject(wait_handle, &wait_object); } if (XSUCCEEDED(result)) { uint64_t timeout = timeout_ptr ? SHIM_MEM_64(timeout_ptr) : 0; - result = XObject::SignalAndWait( - signal_object, wait_object, 3, 1, alertable, - timeout_ptr ? &timeout : NULL); + result = XObject::SignalAndWait(signal_object, wait_object, 3, 1, alertable, + timeout_ptr ? &timeout : NULL); } if (signal_object) { signal_object->Release(); @@ -1054,9 +909,7 @@ SHIM_CALL NtSignalAndWaitForSingleObjectEx_shim( SHIM_SET_RETURN_32(result); } - -SHIM_CALL KfAcquireSpinLock_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KfAcquireSpinLock_shim(PPCContext* ppc_state, KernelState* state) { uint32_t lock_ptr = SHIM_GET_ARG_32(0); // XELOGD( @@ -1077,9 +930,7 @@ SHIM_CALL KfAcquireSpinLock_shim( SHIM_SET_RETURN_64(old_irql); } - -SHIM_CALL KfReleaseSpinLock_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KfReleaseSpinLock_shim(PPCContext* ppc_state, KernelState* state) { uint32_t lock_ptr = SHIM_GET_ARG_32(0); uint32_t old_irql = SHIM_GET_ARG_32(1); @@ -1097,9 +948,8 @@ SHIM_CALL KfReleaseSpinLock_shim( poly::atomic_dec(lock); } - -SHIM_CALL KeAcquireSpinLockAtRaisedIrql_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeAcquireSpinLockAtRaisedIrql_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t lock_ptr = SHIM_GET_ARG_32(0); // XELOGD( @@ -1114,9 +964,8 @@ SHIM_CALL KeAcquireSpinLockAtRaisedIrql_shim( } } - -SHIM_CALL KeReleaseSpinLockFromRaisedIrql_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeReleaseSpinLockFromRaisedIrql_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t lock_ptr = SHIM_GET_ARG_32(0); // XELOGD( @@ -1128,34 +977,29 @@ SHIM_CALL KeReleaseSpinLockFromRaisedIrql_shim( poly::atomic_dec(lock); } - -SHIM_CALL KeEnterCriticalRegion_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeEnterCriticalRegion_shim(PPCContext* ppc_state, + KernelState* state) { // XELOGD( // "KeEnterCriticalRegion()"); XThread::EnterCriticalRegion(); } - -SHIM_CALL KeLeaveCriticalRegion_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeLeaveCriticalRegion_shim(PPCContext* ppc_state, + KernelState* state) { // XELOGD( // "KeLeaveCriticalRegion()"); XThread::LeaveCriticalRegion(); } - -SHIM_CALL KeRaiseIrqlToDpcLevel_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeRaiseIrqlToDpcLevel_shim(PPCContext* ppc_state, + KernelState* state) { // XELOGD( // "KeRaiseIrqlToDpcLevel()"); auto old_value = state->processor()->RaiseIrql(cpu::Irql::DPC); SHIM_SET_RETURN_32(old_value); } - -SHIM_CALL KfLowerIrql_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KfLowerIrql_shim(PPCContext* ppc_state, KernelState* state) { uint32_t old_value = SHIM_GET_ARG_32(0); // XELOGD( // "KfLowerIrql(%d)", @@ -1163,24 +1007,19 @@ SHIM_CALL KfLowerIrql_shim( state->processor()->LowerIrql(static_cast(old_value)); } - -SHIM_CALL NtQueueApcThread_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL NtQueueApcThread_shim(PPCContext* ppc_state, KernelState* state) { uint32_t thread_handle = SHIM_GET_ARG_32(0); uint32_t apc_routine = SHIM_GET_ARG_32(1); uint32_t arg1 = SHIM_GET_ARG_32(2); uint32_t arg2 = SHIM_GET_ARG_32(3); - uint32_t arg3 = SHIM_GET_ARG_32(4); // ? - XELOGD( - "NtQueueApcThread(%.8X, %.8X, %.8X, %.8X, %.8X)", - thread_handle, apc_routine, arg1, arg2, arg3); + uint32_t arg3 = SHIM_GET_ARG_32(4); // ? + XELOGD("NtQueueApcThread(%.8X, %.8X, %.8X, %.8X, %.8X)", thread_handle, + apc_routine, arg1, arg2, arg3); // Alloc APC object (from somewhere) and insert. } - -SHIM_CALL KeInitializeApc_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeInitializeApc_shim(PPCContext* ppc_state, KernelState* state) { uint32_t apc_ptr = SHIM_GET_ARG_32(0); uint32_t thread = SHIM_GET_ARG_32(1); uint32_t kernel_routine = SHIM_GET_ARG_32(2); @@ -1189,49 +1028,45 @@ SHIM_CALL KeInitializeApc_shim( uint32_t processor_mode = SHIM_GET_ARG_32(5); uint32_t normal_context = SHIM_GET_ARG_32(6); - XELOGD( - "KeInitializeApc(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", - apc_ptr, thread, kernel_routine, rundown_routine, normal_routine, - processor_mode, normal_context); + XELOGD("KeInitializeApc(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", apc_ptr, + thread, kernel_routine, rundown_routine, normal_routine, + processor_mode, normal_context); // KAPC is 0x28(40) bytes? (what's passed to ExAllocatePoolWithTag) // This is 4b shorter than NT - looks like the reserved dword at +4 is gone - uint32_t type = 18; // ApcObject + uint32_t type = 18; // ApcObject uint32_t unk0 = 0; uint32_t size = 0x28; uint32_t unk1 = 0; SHIM_SET_MEM_32(apc_ptr + 0, - (type << 24) | (unk0 << 16) | (size << 8) | (unk1)); - SHIM_SET_MEM_32(apc_ptr + 4, thread); // known offset - derefed by games - SHIM_SET_MEM_32(apc_ptr + 8, 0); // flink - SHIM_SET_MEM_32(apc_ptr + 12, 0); // blink + (type << 24) | (unk0 << 16) | (size << 8) | (unk1)); + SHIM_SET_MEM_32(apc_ptr + 4, thread); // known offset - derefed by games + SHIM_SET_MEM_32(apc_ptr + 8, 0); // flink + SHIM_SET_MEM_32(apc_ptr + 12, 0); // blink SHIM_SET_MEM_32(apc_ptr + 16, kernel_routine); SHIM_SET_MEM_32(apc_ptr + 20, rundown_routine); SHIM_SET_MEM_32(apc_ptr + 24, normal_routine); SHIM_SET_MEM_32(apc_ptr + 28, normal_routine ? normal_context : 0); - SHIM_SET_MEM_32(apc_ptr + 32, 0); // arg1 - SHIM_SET_MEM_32(apc_ptr + 36, 0); // arg2 + SHIM_SET_MEM_32(apc_ptr + 32, 0); // arg1 + SHIM_SET_MEM_32(apc_ptr + 36, 0); // arg2 uint32_t state_index = 0; uint32_t inserted = 0; - SHIM_SET_MEM_32(apc_ptr + 40, - (state_index << 24) | (processor_mode << 16) | (inserted << 8)); + SHIM_SET_MEM_32(apc_ptr + 40, (state_index << 24) | (processor_mode << 16) | + (inserted << 8)); } - -SHIM_CALL KeInsertQueueApc_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeInsertQueueApc_shim(PPCContext* ppc_state, KernelState* state) { uint32_t apc_ptr = SHIM_GET_ARG_32(0); uint32_t arg1 = SHIM_GET_ARG_32(1); uint32_t arg2 = SHIM_GET_ARG_32(2); uint32_t priority_increment = SHIM_GET_ARG_32(3); - XELOGD( - "KeInsertQueueApc(%.8X, %.8X, %.8X, %.8X)", - apc_ptr, arg1, arg2, priority_increment); + XELOGD("KeInsertQueueApc(%.8X, %.8X, %.8X, %.8X)", apc_ptr, arg1, arg2, + priority_increment); uint32_t thread_ptr = SHIM_MEM_32(apc_ptr + 4); - XThread* thread = (XThread*)XObject::GetObject( - state, SHIM_MEM_ADDR(thread_ptr)); + XThread* thread = + (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); if (!thread) { SHIM_SET_RETURN_64(0); return; @@ -1251,7 +1086,7 @@ SHIM_CALL KeInsertQueueApc_shim( SHIM_SET_MEM_32(apc_ptr + 32, arg1); SHIM_SET_MEM_32(apc_ptr + 36, arg2); SHIM_SET_MEM_32(apc_ptr + 40, - (SHIM_MEM_32(apc_ptr + 40) & ~0xFF00) | (1 << 8)); + (SHIM_MEM_32(apc_ptr + 40) & ~0xFF00) | (1 << 8)); auto apc_list = thread->apc_list(); @@ -1264,20 +1099,16 @@ SHIM_CALL KeInsertQueueApc_shim( SHIM_SET_RETURN_64(1); } - -SHIM_CALL KeRemoveQueueApc_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeRemoveQueueApc_shim(PPCContext* ppc_state, KernelState* state) { uint32_t apc_ptr = SHIM_GET_ARG_32(0); - XELOGD( - "KeRemoveQueueApc(%.8X)", - apc_ptr); + XELOGD("KeRemoveQueueApc(%.8X)", apc_ptr); bool result = false; uint32_t thread_ptr = SHIM_MEM_32(apc_ptr + 4); - XThread* thread = (XThread*)XObject::GetObject( - state, SHIM_MEM_ADDR(thread_ptr)); + XThread* thread = + (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); if (!thread) { SHIM_SET_RETURN_64(0); return; @@ -1303,54 +1134,42 @@ SHIM_CALL KeRemoveQueueApc_shim( SHIM_SET_RETURN_64(result ? 1 : 0); } +SHIM_CALL KiApcNormalRoutineNop_shim(PPCContext* ppc_state, + KernelState* state) { + uint32_t unk0 = SHIM_GET_ARG_32(0); // output? + uint32_t unk1 = SHIM_GET_ARG_32(1); // 0x13 -SHIM_CALL KiApcNormalRoutineNop_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t unk0 = SHIM_GET_ARG_32(0); // output? - uint32_t unk1 = SHIM_GET_ARG_32(1); // 0x13 - - XELOGD( - "KiApcNormalRoutineNop(%.8X, %.8X)", - unk0, unk1); + XELOGD("KiApcNormalRoutineNop(%.8X, %.8X)", unk0, unk1); SHIM_SET_RETURN_64(0); } - -SHIM_CALL KeInitializeDpc_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeInitializeDpc_shim(PPCContext* ppc_state, KernelState* state) { uint32_t dpc_ptr = SHIM_GET_ARG_32(0); uint32_t routine = SHIM_GET_ARG_32(1); uint32_t context = SHIM_GET_ARG_32(2); - XELOGD( - "KeInitializeDpc(%.8X, %.8X, %.8X)", - dpc_ptr, routine, context); + XELOGD("KeInitializeDpc(%.8X, %.8X, %.8X)", dpc_ptr, routine, context); // KDPC (maybe) 0x18 bytes? - uint32_t type = 19; // DpcObject + uint32_t type = 19; // DpcObject uint32_t importance = 0; - uint32_t number = 0; // ? - SHIM_SET_MEM_32(dpc_ptr + 0, - (type << 24) | (importance << 16) | (number)); - SHIM_SET_MEM_32(dpc_ptr + 4, 0); // flink - SHIM_SET_MEM_32(dpc_ptr + 8, 0); // blink + uint32_t number = 0; // ? + SHIM_SET_MEM_32(dpc_ptr + 0, (type << 24) | (importance << 16) | (number)); + SHIM_SET_MEM_32(dpc_ptr + 4, 0); // flink + SHIM_SET_MEM_32(dpc_ptr + 8, 0); // blink SHIM_SET_MEM_32(dpc_ptr + 12, routine); SHIM_SET_MEM_32(dpc_ptr + 16, context); - SHIM_SET_MEM_32(dpc_ptr + 20, 0); // arg1 - SHIM_SET_MEM_32(dpc_ptr + 24, 0); // arg2 + SHIM_SET_MEM_32(dpc_ptr + 20, 0); // arg1 + SHIM_SET_MEM_32(dpc_ptr + 24, 0); // arg2 } - -SHIM_CALL KeInsertQueueDpc_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeInsertQueueDpc_shim(PPCContext* ppc_state, KernelState* state) { uint32_t dpc_ptr = SHIM_GET_ARG_32(0); uint32_t arg1 = SHIM_GET_ARG_32(1); uint32_t arg2 = SHIM_GET_ARG_32(2); - XELOGD( - "KeInsertQueueDpc(%.8X, %.8X, %.8X)", - dpc_ptr, arg1, arg2); + XELOGD("KeInsertQueueDpc(%.8X, %.8X, %.8X)", dpc_ptr, arg1, arg2); uint32_t list_entry_ptr = dpc_ptr + 4; @@ -1378,14 +1197,10 @@ SHIM_CALL KeInsertQueueDpc_shim( SHIM_SET_RETURN_64(1); } - -SHIM_CALL KeRemoveQueueDpc_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL KeRemoveQueueDpc_shim(PPCContext* ppc_state, KernelState* state) { uint32_t dpc_ptr = SHIM_GET_ARG_32(0); - XELOGD( - "KeRemoveQueueDpc(%.8X)", - dpc_ptr); + XELOGD("KeRemoveQueueDpc(%.8X)", dpc_ptr); bool result = false; @@ -1405,12 +1220,9 @@ SHIM_CALL KeRemoveQueueDpc_shim( SHIM_SET_RETURN_64(result ? 1 : 0); } - - } // namespace kernel } // namespace xe - void xe::kernel::xboxkrnl::RegisterThreadingExports( ExportResolver* export_resolver, KernelState* state) { SHIM_SET_MAPPING("xboxkrnl.exe", ExCreateThread, state); @@ -1472,7 +1284,7 @@ void xe::kernel::xboxkrnl::RegisterThreadingExports( SHIM_SET_MAPPING("xboxkrnl.exe", KeRaiseIrqlToDpcLevel, state); SHIM_SET_MAPPING("xboxkrnl.exe", KfLowerIrql, state); - //SHIM_SET_MAPPING("xboxkrnl.exe", NtQueueApcThread, state); + // SHIM_SET_MAPPING("xboxkrnl.exe", NtQueueApcThread, state); SHIM_SET_MAPPING("xboxkrnl.exe", KeInitializeApc, state); SHIM_SET_MAPPING("xboxkrnl.exe", KeInsertQueueApc, state); SHIM_SET_MAPPING("xboxkrnl.exe", KeRemoveQueueApc, state); diff --git a/src/xenia/kernel/xboxkrnl_usbcam.cc b/src/xenia/kernel/xboxkrnl_usbcam.cc index 5eb79cb28..f61fad285 100644 --- a/src/xenia/kernel/xboxkrnl_usbcam.cc +++ b/src/xenia/kernel/xboxkrnl_usbcam.cc @@ -14,27 +14,21 @@ #include #include - namespace xe { namespace kernel { -SHIM_CALL XUsbcamCreate_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL XUsbcamCreate_shim(PPCContext* ppc_state, KernelState* state) { uint32_t unk1 = SHIM_GET_ARG_32(0); uint32_t unk2 = SHIM_GET_ARG_32(1); - XELOGD( - "XUsbcamCreate(%.8X, %.8X)", - unk1, unk2); + XELOGD("XUsbcamCreate(%.8X, %.8X)", unk1, unk2); SHIM_SET_RETURN_32(-1); } - } // namespace kernel } // namespace xe - void xe::kernel::xboxkrnl::RegisterUsbcamExports( ExportResolver* export_resolver, KernelState* state) { SHIM_SET_MAPPING("xboxkrnl.exe", XUsbcamCreate, state); diff --git a/src/xenia/kernel/xboxkrnl_video.cc b/src/xenia/kernel/xboxkrnl_video.cc index 37bd71456..d1b319cde 100644 --- a/src/xenia/kernel/xboxkrnl_video.cc +++ b/src/xenia/kernel/xboxkrnl_video.cc @@ -19,13 +19,11 @@ #include #include - namespace xe { namespace kernel { using xe::gpu::GraphicsSystem; - // http://www.tweakoz.com/orkid/ // http://www.tweakoz.com/orkid/dox/d3/d52/xb360init_8cpp_source.html // https://github.com/Free60Project/xenosfb/ @@ -36,30 +34,25 @@ using xe::gpu::GraphicsSystem; // http://web.archive.org/web/20100423054747/http://msdn.microsoft.com/en-us/library/bb313878.aspx // http://web.archive.org/web/20090510235238/http://msdn.microsoft.com/en-us/library/bb313942.aspx // http://svn.dd-wrt.com/browser/src/linux/universal/linux-3.8/drivers/gpu/drm/radeon/radeon_ring.c -// http://www.microsoft.com/en-za/download/details.aspx?id=5313 -- "Stripped Down Direct3D: Xbox 360 Command Buffer and Resource Management" +// http://www.microsoft.com/en-za/download/details.aspx?id=5313 -- "Stripped +// Down Direct3D: Xbox 360 Command Buffer and Resource Management" - -SHIM_CALL VdGetCurrentDisplayGamma_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL VdGetCurrentDisplayGamma_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t arg0_ptr = SHIM_GET_ARG_32(0); uint32_t arg1_ptr = SHIM_GET_ARG_32(1); - XELOGD( - "VdGetCurrentDisplayGamma(%.8X, %.8X)", - arg0_ptr, arg1_ptr); + XELOGD("VdGetCurrentDisplayGamma(%.8X, %.8X)", arg0_ptr, arg1_ptr); SHIM_SET_MEM_32(arg0_ptr, 2); SHIM_SET_MEM_F32(arg1_ptr, 2.22222233f); } - -SHIM_CALL VdGetCurrentDisplayInformation_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL VdGetCurrentDisplayInformation_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t ptr = SHIM_GET_ARG_32(0); - XELOGD( - "VdGetCurrentDisplayInformation(%.8X)", - ptr); + XELOGD("VdGetCurrentDisplayInformation(%.8X)", ptr); // Expecting a length 0x58 struct of stuff. SHIM_SET_MEM_32(ptr + 0, (1280 << 16) | 720); @@ -67,7 +60,7 @@ SHIM_CALL VdGetCurrentDisplayInformation_shim( SHIM_SET_MEM_32(ptr + 8, 0); SHIM_SET_MEM_32(ptr + 12, 0); SHIM_SET_MEM_32(ptr + 16, 1280); // backbuffer width? - SHIM_SET_MEM_32(ptr + 20, 720); // backbuffer height? + SHIM_SET_MEM_32(ptr + 20, 720); // backbuffer height? SHIM_SET_MEM_32(ptr + 24, 1280); SHIM_SET_MEM_32(ptr + 28, 720); SHIM_SET_MEM_32(ptr + 32, 1); @@ -78,104 +71,87 @@ SHIM_CALL VdGetCurrentDisplayInformation_shim( SHIM_SET_MEM_32(ptr + 52, 0); SHIM_SET_MEM_32(ptr + 56, 0); SHIM_SET_MEM_32(ptr + 60, 0); - SHIM_SET_MEM_32(ptr + 64, 0x014000B4); // ? - SHIM_SET_MEM_32(ptr + 68, 0x014000B4); // ? + SHIM_SET_MEM_32(ptr + 64, 0x014000B4); // ? + SHIM_SET_MEM_32(ptr + 68, 0x014000B4); // ? SHIM_SET_MEM_32(ptr + 72, (1280 << 16) | 720); // actual display size? SHIM_SET_MEM_32(ptr + 76, 0x42700000); SHIM_SET_MEM_32(ptr + 80, 0); SHIM_SET_MEM_32(ptr + 84, 1280); // display width } - -SHIM_CALL VdQueryVideoFlags_shim( - PPCContext* ppc_state, KernelState* state) { - XELOGD( - "VdQueryVideoFlags()"); +SHIM_CALL VdQueryVideoFlags_shim(PPCContext* ppc_state, KernelState* state) { + XELOGD("VdQueryVideoFlags()"); SHIM_SET_RETURN_64(0x00000006); } - void xeVdQueryVideoMode(X_VIDEO_MODE* video_mode) { if (video_mode == NULL) { return; } // TODO: get info from actual display - video_mode->display_width = 1280; - video_mode->display_height = 720; - video_mode->is_interlaced = 0; - video_mode->is_widescreen = 1; - video_mode->is_hi_def = 1; - video_mode->refresh_rate = 60.0f; - video_mode->video_standard = 1; // NTSC - video_mode->unknown_0x8a = 0x8A; - video_mode->unknown_0x01 = 0x01; + video_mode->display_width = 1280; + video_mode->display_height = 720; + video_mode->is_interlaced = 0; + video_mode->is_widescreen = 1; + video_mode->is_hi_def = 1; + video_mode->refresh_rate = 60.0f; + video_mode->video_standard = 1; // NTSC + video_mode->unknown_0x8a = 0x8A; + video_mode->unknown_0x01 = 0x01; // TODO(benvanik): auto swap structure. - video_mode->display_width = poly::byte_swap(video_mode->display_width); - video_mode->display_height = poly::byte_swap(video_mode->display_height); - video_mode->is_interlaced = poly::byte_swap(video_mode->is_interlaced); - video_mode->is_widescreen = poly::byte_swap(video_mode->is_widescreen); - video_mode->is_hi_def = poly::byte_swap(video_mode->is_hi_def); - video_mode->refresh_rate = poly::byte_swap(video_mode->refresh_rate); - video_mode->video_standard = poly::byte_swap(video_mode->video_standard); - video_mode->unknown_0x8a = poly::byte_swap(video_mode->unknown_0x8a); - video_mode->unknown_0x01 = poly::byte_swap(video_mode->unknown_0x01); + video_mode->display_width = poly::byte_swap(video_mode->display_width); + video_mode->display_height = poly::byte_swap(video_mode->display_height); + video_mode->is_interlaced = poly::byte_swap(video_mode->is_interlaced); + video_mode->is_widescreen = poly::byte_swap(video_mode->is_widescreen); + video_mode->is_hi_def = poly::byte_swap(video_mode->is_hi_def); + video_mode->refresh_rate = poly::byte_swap(video_mode->refresh_rate); + video_mode->video_standard = poly::byte_swap(video_mode->video_standard); + video_mode->unknown_0x8a = poly::byte_swap(video_mode->unknown_0x8a); + video_mode->unknown_0x01 = poly::byte_swap(video_mode->unknown_0x01); } - -SHIM_CALL VdQueryVideoMode_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL VdQueryVideoMode_shim(PPCContext* ppc_state, KernelState* state) { uint32_t video_mode_ptr = SHIM_GET_ARG_32(0); - X_VIDEO_MODE *video_mode = (X_VIDEO_MODE*)SHIM_MEM_ADDR(video_mode_ptr); + X_VIDEO_MODE* video_mode = (X_VIDEO_MODE*)SHIM_MEM_ADDR(video_mode_ptr); - XELOGD( - "VdQueryVideoMode(%.8X)", - video_mode_ptr); + XELOGD("VdQueryVideoMode(%.8X)", video_mode_ptr); xeVdQueryVideoMode(video_mode); } - -SHIM_CALL VdInitializeEngines_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL VdInitializeEngines_shim(PPCContext* ppc_state, KernelState* state) { uint32_t unk0 = SHIM_GET_ARG_32(0); uint32_t callback = SHIM_GET_ARG_32(1); uint32_t unk1 = SHIM_GET_ARG_32(2); uint32_t unk2_ptr = SHIM_GET_ARG_32(3); uint32_t unk3_ptr = SHIM_GET_ARG_32(4); - XELOGD( - "VdInitializeEngines(%.8X, %.8X, %.8X, %.8X, %.8X)", - unk0, callback, unk1, unk2_ptr, unk3_ptr); - + XELOGD("VdInitializeEngines(%.8X, %.8X, %.8X, %.8X, %.8X)", unk0, callback, + unk1, unk2_ptr, unk3_ptr); + // r3 = 0x4F810000 // r4 = function ptr (cleanup callback?) // r5 = 0 // r6/r7 = some binary data in .data } - -SHIM_CALL VdShutdownEngines_shim( - PPCContext* ppc_state, KernelState* state) { - XELOGD( - "VdShutdownEngines()"); +SHIM_CALL VdShutdownEngines_shim(PPCContext* ppc_state, KernelState* state) { + XELOGD("VdShutdownEngines()"); // Ignored for now. // Games seem to call an Initialize/Shutdown pair to query info, then // re-initialize. } - -SHIM_CALL VdSetGraphicsInterruptCallback_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL VdSetGraphicsInterruptCallback_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t callback = SHIM_GET_ARG_32(0); uint32_t user_data = SHIM_GET_ARG_32(1); - XELOGD( - "VdSetGraphicsInterruptCallback(%.8X, %.8X)", - callback, user_data); + XELOGD("VdSetGraphicsInterruptCallback(%.8X, %.8X)", callback, user_data); GraphicsSystem* gs = state->emulator()->graphics_system(); if (!gs) { @@ -189,16 +165,13 @@ SHIM_CALL VdSetGraphicsInterruptCallback_shim( gs->SetInterruptCallback(callback, user_data); } - -SHIM_CALL VdInitializeRingBuffer_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL VdInitializeRingBuffer_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t ptr = SHIM_GET_ARG_32(0); uint32_t page_count = SHIM_GET_ARG_32(1); - XELOGD( - "VdInitializeRingBuffer(%.8X, %.8X)", - ptr, page_count); - + XELOGD("VdInitializeRingBuffer(%.8X, %.8X)", ptr, page_count); + GraphicsSystem* gs = state->emulator()->graphics_system(); if (!gs) { return; @@ -214,15 +187,12 @@ SHIM_CALL VdInitializeRingBuffer_shim( gs->InitializeRingBuffer(ptr, page_count); } - -SHIM_CALL VdEnableRingBufferRPtrWriteBack_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL VdEnableRingBufferRPtrWriteBack_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t ptr = SHIM_GET_ARG_32(0); uint32_t block_size = SHIM_GET_ARG_32(1); - XELOGD( - "VdEnableRingBufferRPtrWriteBack(%.8X, %.8X)", - ptr, block_size); + XELOGD("VdEnableRingBufferRPtrWriteBack(%.8X, %.8X)", ptr, block_size); GraphicsSystem* gs = state->emulator()->graphics_system(); if (!gs) { @@ -233,99 +203,83 @@ SHIM_CALL VdEnableRingBufferRPtrWriteBack_shim( gs->EnableReadPointerWriteBack(ptr, block_size); ptr += 0x20000000; - //printf("%.8X", ptr); + // printf("%.8X", ptr); // 0x0110343c // r3 = 0x2B10(d3d?) + 0x3C //((p + 0x3C) & 0x1FFFFFFF) + ((((p + 0x3C) >> 20) + 0x200) & 0x1000) - //also 0x3C offset into WriteBacks is PrimaryRingBufferReadIndex + // also 0x3C offset into WriteBacks is PrimaryRingBufferReadIndex //(1:17:38 AM) Rick: .text:8201B348 lwz r11, 0x2B10(r31) //(1:17:38 AM) Rick: .text:8201B34C addi r11, r11, 0x3C - //(1:17:38 AM) Rick: .text:8201B350 srwi r10, r11, 20 # r10 = r11 >> 20 - //(1:17:38 AM) Rick: .text:8201B354 clrlwi r11, r11, 3 # r11 = r11 & 0x1FFFFFFF + //(1:17:38 AM) Rick: .text:8201B350 srwi r10, r11, 20 # + //r10 = r11 >> 20 + //(1:17:38 AM) Rick: .text:8201B354 clrlwi r11, r11, 3 # + //r11 = r11 & 0x1FFFFFFF //(1:17:38 AM) Rick: .text:8201B358 addi r10, r10, 0x200 - //(1:17:39 AM) Rick: .text:8201B35C rlwinm r10, r10, 0,19,19 # r10 = r10 & 0x1000 + //(1:17:39 AM) Rick: .text:8201B35C rlwinm r10, r10, + //0,19,19 # r10 = r10 & 0x1000 //(1:17:39 AM) Rick: .text:8201B360 add r3, r10, r11 - //(1:17:39 AM) Rick: .text:8201B364 bl VdEnableRingBufferRPtrWriteBack + //(1:17:39 AM) Rick: .text:8201B364 bl + //VdEnableRingBufferRPtrWriteBack // TODO(benvanik): something? } - -SHIM_CALL VdGetSystemCommandBuffer_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL VdGetSystemCommandBuffer_shim(PPCContext* ppc_state, + KernelState* state) { uint32_t p0_ptr = SHIM_GET_ARG_32(0); uint32_t p1_ptr = SHIM_GET_ARG_32(1); - XELOGD( - "VdGetSystemCommandBuffer(%.8X, %.8X)", - p0_ptr, - p1_ptr); + XELOGD("VdGetSystemCommandBuffer(%.8X, %.8X)", p0_ptr, p1_ptr); SHIM_SET_MEM_32(p0_ptr, 0xBEEF0000); SHIM_SET_MEM_32(p1_ptr, 0xBEEF0001); } - SHIM_CALL VdSetSystemCommandBufferGpuIdentifierAddress_shim( PPCContext* ppc_state, KernelState* state) { uint32_t unk = SHIM_GET_ARG_32(0); - XELOGD( - "VdSetSystemCommandBufferGpuIdentifierAddress(%.8X)", - unk); - + XELOGD("VdSetSystemCommandBufferGpuIdentifierAddress(%.8X)", unk); + // r3 = 0x2B10(d3d?) + 8 } - // VdVerifyMEInitCommand // r3 // r4 = 19 // no op? - // VdCallGraphicsNotificationRoutines // r3 = 1 // r4 = ? // callbacks get 0, r3, r4 - -SHIM_CALL VdIsHSIOTrainingSucceeded_shim( - PPCContext* ppc_state, KernelState* state) { - XELOGD( - "VdIsHSIOTrainingSucceeded()"); +SHIM_CALL VdIsHSIOTrainingSucceeded_shim(PPCContext* ppc_state, + KernelState* state) { + XELOGD("VdIsHSIOTrainingSucceeded()"); // Not really sure what this should be - code does weird stuff here: // (cntlzw r11, r3 / extrwi r11, r11, 1, 26) SHIM_SET_RETURN_64(1); } - -SHIM_CALL VdPersistDisplay_shim( - PPCContext* ppc_state, KernelState* state) { - XELOGD( - "VdPersistDisplay(?)"); +SHIM_CALL VdPersistDisplay_shim(PPCContext* ppc_state, KernelState* state) { + XELOGD("VdPersistDisplay(?)"); // ? SHIM_SET_RETURN_64(1); } - -SHIM_CALL VdRetrainEDRAMWorker_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL VdRetrainEDRAMWorker_shim(PPCContext* ppc_state, KernelState* state) { uint32_t unk0 = SHIM_GET_ARG_32(0); - XELOGD( - "VdRetrainEDRAMWorker(%.8X)", - unk0); + XELOGD("VdRetrainEDRAMWorker(%.8X)", unk0); SHIM_SET_RETURN_64(0); } - -SHIM_CALL VdRetrainEDRAM_shim( - PPCContext* ppc_state, KernelState* state) { +SHIM_CALL VdRetrainEDRAM_shim(PPCContext* ppc_state, KernelState* state) { uint32_t unk0 = SHIM_GET_ARG_32(0); uint32_t unk1 = SHIM_GET_ARG_32(1); uint32_t unk2 = SHIM_GET_ARG_32(2); @@ -333,35 +287,24 @@ SHIM_CALL VdRetrainEDRAM_shim( uint32_t unk4 = SHIM_GET_ARG_32(4); uint32_t unk5 = SHIM_GET_ARG_32(5); - XELOGD( - "VdRetrainEDRAM(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", - unk0, unk1, unk2, unk3, unk4, unk5); + XELOGD("VdRetrainEDRAM(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", unk0, unk1, unk2, + unk3, unk4, unk5); SHIM_SET_RETURN_64(0); } - -SHIM_CALL VdSwap_shim( - PPCContext* ppc_state, KernelState* state) { - uint32_t unk0 = SHIM_GET_ARG_32(0); // ptr into primary ringbuffer +SHIM_CALL VdSwap_shim(PPCContext* ppc_state, KernelState* state) { + uint32_t unk0 = SHIM_GET_ARG_32(0); // ptr into primary ringbuffer uint32_t unk1 = SHIM_GET_ARG_32(1); uint32_t unk2 = SHIM_GET_ARG_32(2); - uint32_t unk3 = SHIM_GET_ARG_32(3); // ptr to 0xBEEF0000 - uint32_t unk4 = SHIM_GET_ARG_32(4); // 0xBEEF0001 + uint32_t unk3 = SHIM_GET_ARG_32(3); // ptr to 0xBEEF0000 + uint32_t unk4 = SHIM_GET_ARG_32(4); // 0xBEEF0001 uint32_t unk5 = SHIM_GET_ARG_32(5); uint32_t unk6 = SHIM_GET_ARG_32(6); uint32_t unk7 = SHIM_GET_ARG_32(7); - XELOGD( - "VdSwap(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", - unk0, - unk1, - unk2, - unk3, - unk4, - unk5, - unk6, - unk7); + XELOGD("VdSwap(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %.8X)", unk0, unk1, + unk2, unk3, unk4, unk5, unk6, unk7); // The caller seems to reserve 64 words (256b) in the primary ringbuffer // for this method to do what it needs. We just zero them out and send a @@ -370,20 +313,17 @@ SHIM_CALL VdSwap_shim( // use this method. xe_zero_struct(SHIM_MEM_ADDR(unk0), 64 * 4); auto dwords = reinterpret_cast(SHIM_MEM_ADDR(unk0)); - dwords[0] = poly::byte_swap((0x03 << 30) | - ((1 - 1) << 16) | + dwords[0] = poly::byte_swap((0x03 << 30) | ((1 - 1) << 16) | (xe::gpu::xenos::PM4_XE_SWAP << 8)); SHIM_SET_RETURN_64(0); } - } // namespace kernel } // namespace xe - -void xe::kernel::xboxkrnl::RegisterVideoExports( - ExportResolver* export_resolver, KernelState* state) { +void xe::kernel::xboxkrnl::RegisterVideoExports(ExportResolver* export_resolver, + KernelState* state) { SHIM_SET_MAPPING("xboxkrnl.exe", VdGetCurrentDisplayGamma, state); SHIM_SET_MAPPING("xboxkrnl.exe", VdGetCurrentDisplayInformation, state); SHIM_SET_MAPPING("xboxkrnl.exe", VdQueryVideoFlags, state); @@ -394,8 +334,8 @@ void xe::kernel::xboxkrnl::RegisterVideoExports( SHIM_SET_MAPPING("xboxkrnl.exe", VdInitializeRingBuffer, state); SHIM_SET_MAPPING("xboxkrnl.exe", VdEnableRingBufferRPtrWriteBack, state); SHIM_SET_MAPPING("xboxkrnl.exe", VdGetSystemCommandBuffer, state); - SHIM_SET_MAPPING("xboxkrnl.exe", - VdSetSystemCommandBufferGpuIdentifierAddress, state); + SHIM_SET_MAPPING("xboxkrnl.exe", VdSetSystemCommandBufferGpuIdentifierAddress, + state); SHIM_SET_MAPPING("xboxkrnl.exe", VdIsHSIOTrainingSucceeded, state); SHIM_SET_MAPPING("xboxkrnl.exe", VdPersistDisplay, state); SHIM_SET_MAPPING("xboxkrnl.exe", VdRetrainEDRAMWorker, state); diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index 555271832..2016fe815 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -14,16 +14,15 @@ #include #include - namespace xe { namespace kernel { - -XObject::XObject(KernelState* kernel_state, Type type) : - kernel_state_(kernel_state), - handle_ref_count_(0), - pointer_ref_count_(1), - type_(type), handle_(X_INVALID_HANDLE_VALUE) { +XObject::XObject(KernelState* kernel_state, Type type) + : kernel_state_(kernel_state), + handle_ref_count_(0), + pointer_ref_count_(1), + type_(type), + handle_(X_INVALID_HANDLE_VALUE) { kernel_state->object_table()->AddHandle(this, &handle_); } @@ -32,21 +31,13 @@ XObject::~XObject() { assert_zero(pointer_ref_count_); } -Memory* XObject::memory() const { - return kernel_state_->memory(); -} +Memory* XObject::memory() const { return kernel_state_->memory(); } -XObject::Type XObject::type() { - return type_; -} +XObject::Type XObject::type() { return type_; } -X_HANDLE XObject::handle() const { - return handle_; -} +X_HANDLE XObject::handle() const { return handle_; } -void XObject::RetainHandle() { - ++handle_ref_count_; -} +void XObject::RetainHandle() { ++handle_ref_count_; } bool XObject::ReleaseHandle() { if (--handle_ref_count_ == 0) { @@ -55,9 +46,7 @@ bool XObject::ReleaseHandle() { return false; } -void XObject::Retain() { - ++pointer_ref_count_; -} +void XObject::Retain() { ++pointer_ref_count_; } void XObject::Release() { if (--pointer_ref_count_ == 0) { @@ -78,7 +67,7 @@ uint32_t XObject::TimeoutTicksToMs(int64_t timeout_ticks) { return 0; } else if (timeout_ticks < 0) { // Relative time. - return (uint32_t)(-timeout_ticks / 10000); // Ticks -> MS + return (uint32_t)(-timeout_ticks / 10000); // Ticks -> MS } else { return 0; } @@ -92,57 +81,50 @@ X_STATUS XObject::Wait(uint32_t wait_reason, uint32_t processor_mode, return X_STATUS_SUCCESS; } - DWORD timeout_ms = opt_timeout ? - TimeoutTicksToMs(*opt_timeout) : INFINITE; + DWORD timeout_ms = opt_timeout ? TimeoutTicksToMs(*opt_timeout) : INFINITE; DWORD result = WaitForSingleObjectEx(wait_handle, timeout_ms, alertable); switch (result) { - case WAIT_OBJECT_0: - return X_STATUS_SUCCESS; - case WAIT_IO_COMPLETION: - // Or X_STATUS_ALERTED? - return X_STATUS_USER_APC; - case WAIT_TIMEOUT: - return X_STATUS_TIMEOUT; - default: - case WAIT_FAILED: - case WAIT_ABANDONED: - return X_STATUS_ABANDONED_WAIT_0; + case WAIT_OBJECT_0: + return X_STATUS_SUCCESS; + case WAIT_IO_COMPLETION: + // Or X_STATUS_ALERTED? + return X_STATUS_USER_APC; + case WAIT_TIMEOUT: + return X_STATUS_TIMEOUT; + default: + case WAIT_FAILED: + case WAIT_ABANDONED: + return X_STATUS_ABANDONED_WAIT_0; } } -X_STATUS XObject::SignalAndWait( - XObject* signal_object, XObject* wait_object, - uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable, - uint64_t* opt_timeout) { - DWORD timeout_ms = opt_timeout ? - TimeoutTicksToMs(*opt_timeout) : INFINITE; +X_STATUS XObject::SignalAndWait(XObject* signal_object, XObject* wait_object, + uint32_t wait_reason, uint32_t processor_mode, + uint32_t alertable, uint64_t* opt_timeout) { + DWORD timeout_ms = opt_timeout ? TimeoutTicksToMs(*opt_timeout) : INFINITE; - DWORD result = SignalObjectAndWait( - signal_object->GetWaitHandle(), - wait_object->GetWaitHandle(), - timeout_ms, - alertable ? TRUE : FALSE); + DWORD result = SignalObjectAndWait(signal_object->GetWaitHandle(), + wait_object->GetWaitHandle(), timeout_ms, + alertable ? TRUE : FALSE); return result; } -X_STATUS XObject::WaitMultiple( - uint32_t count, XObject** objects, - uint32_t wait_type, uint32_t wait_reason, uint32_t processor_mode, - uint32_t alertable, uint64_t* opt_timeout) { +X_STATUS XObject::WaitMultiple(uint32_t count, XObject** objects, + uint32_t wait_type, uint32_t wait_reason, + uint32_t processor_mode, uint32_t alertable, + uint64_t* opt_timeout) { void** wait_handles = (void**)alloca(sizeof(void*) * count); for (uint32_t n = 0; n < count; n++) { wait_handles[n] = objects[n]->GetWaitHandle(); assert_not_null(wait_handles[n]); } - DWORD timeout_ms = opt_timeout ? - TimeoutTicksToMs(*opt_timeout) : INFINITE; + DWORD timeout_ms = opt_timeout ? TimeoutTicksToMs(*opt_timeout) : INFINITE; DWORD result = WaitForMultipleObjectsEx( - count, wait_handles, - wait_type ? FALSE : TRUE, timeout_ms, alertable); + count, wait_handles, wait_type ? FALSE : TRUE, timeout_ms, alertable); return result; } @@ -164,7 +146,8 @@ void XObject::SetNativePointer(uint32_t native_ptr) { uint64_t object_ptr = reinterpret_cast(this); object_ptr |= 0x1; header_be->wait_list_flink = poly::byte_swap((uint32_t)(object_ptr >> 32)); - header_be->wait_list_blink = poly::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF)); + header_be->wait_list_blink = + poly::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF)); } XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr, @@ -193,9 +176,8 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr, if (header.wait_list_blink & 0x1) { // Already initialized. - uint64_t object_ptr = - ((uint64_t)header.wait_list_flink << 32) | - ((header.wait_list_blink) & ~0x1); + uint64_t object_ptr = ((uint64_t)header.wait_list_flink << 32) | + ((header.wait_list_blink) & ~0x1); XObject* object = reinterpret_cast(object_ptr); // TODO(benvanik): assert nothing has been changed in the struct. return object; @@ -204,51 +186,49 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr, // http://www.nirsoft.net/kernel_struct/vista/KOBJECTS.html XObject* object = NULL; switch (as_type) { - case 0: // EventNotificationObject - case 1: // EventSynchronizationObject + case 0: // EventNotificationObject + case 1: // EventSynchronizationObject { XEvent* ev = new XEvent(kernel_state); ev->InitializeNative(native_ptr, header); object = ev; - } - break; - case 2: // MutantObject + } break; + case 2: // MutantObject { XMutant* mutant = new XMutant(kernel_state); mutant->InitializeNative(native_ptr, header); object = mutant; - } - break; - case 5: // SemaphoreObject + } break; + case 5: // SemaphoreObject { XSemaphore* sem = new XSemaphore(kernel_state); sem->InitializeNative(native_ptr, header); object = sem; - } - break; - case 3: // ProcessObject - case 4: // QueueObject - case 6: // ThreadObject - case 7: // GateObject - case 8: // TimerNotificationObject - case 9: // TimerSynchronizationObject - case 18: // ApcObject - case 19: // DpcObject - case 20: // DeviceQueueObject - case 21: // EventPairObject - case 22: // InterruptObject - case 23: // ProfileObject - case 24: // ThreadedDpcObject - default: - assert_always(); - return NULL; + } break; + case 3: // ProcessObject + case 4: // QueueObject + case 6: // ThreadObject + case 7: // GateObject + case 8: // TimerNotificationObject + case 9: // TimerSynchronizationObject + case 18: // ApcObject + case 19: // DpcObject + case 20: // DeviceQueueObject + case 21: // EventPairObject + case 22: // InterruptObject + case 23: // ProfileObject + case 24: // ThreadedDpcObject + default: + assert_always(); + return NULL; } // Stash pointer in struct. uint64_t object_ptr = reinterpret_cast(object); object_ptr |= 0x1; header_be->wait_list_flink = poly::byte_swap((uint32_t)(object_ptr >> 32)); - header_be->wait_list_blink = poly::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF)); + header_be->wait_list_blink = + poly::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF)); return object; } diff --git a/src/xenia/kernel/xobject.h b/src/xenia/kernel/xobject.h index 3f267579a..021cc3e66 100644 --- a/src/xenia/kernel/xobject.h +++ b/src/xenia/kernel/xobject.h @@ -16,11 +16,9 @@ #include - namespace xe { namespace kernel { - // http://www.nirsoft.net/kernel_struct/vista/DISPATCHER_HEADER.html typedef struct { uint32_t type_flags; @@ -29,9 +27,8 @@ typedef struct { uint32_t wait_list_blink; } DISPATCH_HEADER; - class XObject { -public: + public: enum Type { kTypeModule, kTypeThread, @@ -62,42 +59,38 @@ public: // Reference() // Dereference() - X_STATUS Wait( - uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable, - uint64_t* opt_timeout); - static X_STATUS SignalAndWait( - XObject* signal_object, XObject* wait_object, - uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable, - uint64_t* opt_timeout); - static X_STATUS WaitMultiple( - uint32_t count, XObject** objects, - uint32_t wait_type, uint32_t wait_reason, uint32_t processor_mode, - uint32_t alertable, uint64_t* opt_timeout); + X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode, + uint32_t alertable, uint64_t* opt_timeout); + static X_STATUS SignalAndWait(XObject* signal_object, XObject* wait_object, + uint32_t wait_reason, uint32_t processor_mode, + uint32_t alertable, uint64_t* opt_timeout); + static X_STATUS WaitMultiple(uint32_t count, XObject** objects, + uint32_t wait_type, uint32_t wait_reason, + uint32_t processor_mode, uint32_t alertable, + uint64_t* opt_timeout); static XObject* GetObject(KernelState* kernel_state, void* native_ptr, int32_t as_type = -1); virtual void* GetWaitHandle() { return 0; } -protected: + protected: Memory* memory() const; void SetNativePointer(uint32_t native_ptr); static uint32_t TimeoutTicksToMs(int64_t timeout_ticks); - KernelState* kernel_state_; + KernelState* kernel_state_; -private: + private: std::atomic handle_ref_count_; std::atomic pointer_ref_count_; - Type type_; - X_HANDLE handle_; + Type type_; + X_HANDLE handle_; }; - } // namespace kernel } // namespace xe - #endif // XENIA_KERNEL_XBOXKRNL_XOBJECT_H_ From 23561645253f11545d1b145017418d41d5ac4e4a Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 1 Aug 2014 16:09:09 -0700 Subject: [PATCH 133/388] Fixing implicit narrow warning. --- src/alloy/backend/ivm/ivm_intcode.cc | 40 ++++++++++++++-------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index 6d38409ac..96043200d 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -2324,14 +2324,14 @@ int Translate_DID_SATURATE(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, IntCode_DID_SATURATE); } -#define VECTOR_COMPARER(type, value, dest_value, count, op) \ - const vec128_t& src1 = ics.rf[i->src1_reg].v128; \ - const vec128_t& src2 = ics.rf[i->src2_reg].v128; \ - vec128_t& dest = ics.rf[i->dest_reg].v128; \ - for (int n = 0; n < count; n++) { \ - dest.dest_value[n] = \ - ((type)src1.value[n] op(type) src2.value[n]) ? 0xFFFFFFFF : 0; \ - } \ +#define VECTOR_COMPARER(type, value, dest_value, count, op) \ + const vec128_t& src1 = ics.rf[i->src1_reg].v128; \ + const vec128_t& src2 = ics.rf[i->src2_reg].v128; \ + vec128_t& dest = ics.rf[i->dest_reg].v128; \ + for (int n = 0; n < count; n++) { \ + dest.dest_value[n] = \ + ((type)src1.value[n] op(type) src2.value[n]) ? (type)0xFFFFFFFF : 0; \ + } \ return IA_NEXT; uint32_t IntCode_VECTOR_COMPARE_EQ_I8(IntCodeState& ics, const IntCode* i){ @@ -2370,13 +2370,13 @@ int Translate_VECTOR_COMPARE_SGT(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, fns[i->flags]); } -uint32_t IntCode_VECTOR_COMPARE_SGE_I8(IntCodeState& ics, const IntCode* i){ +uint32_t IntCode_VECTOR_COMPARE_SGE_I8(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(int8_t, b16, b16, 16, >= )}; -uint32_t IntCode_VECTOR_COMPARE_SGE_I16(IntCodeState& ics, const IntCode* i){ +uint32_t IntCode_VECTOR_COMPARE_SGE_I16(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(int16_t, s8, s8, 8, >= )}; -uint32_t IntCode_VECTOR_COMPARE_SGE_I32(IntCodeState& ics, const IntCode* i){ +uint32_t IntCode_VECTOR_COMPARE_SGE_I32(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(int32_t, i4, i4, 4, >= )}; -uint32_t IntCode_VECTOR_COMPARE_SGE_F32(IntCodeState& ics, const IntCode* i){ +uint32_t IntCode_VECTOR_COMPARE_SGE_F32(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(float, f4, i4, 4, >= )}; int Translate_VECTOR_COMPARE_SGE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { @@ -2388,13 +2388,13 @@ int Translate_VECTOR_COMPARE_SGE(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, fns[i->flags]); } -uint32_t IntCode_VECTOR_COMPARE_UGT_I8(IntCodeState& ics, const IntCode* i){ +uint32_t IntCode_VECTOR_COMPARE_UGT_I8(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(uint8_t, b16, b16, 16, > )}; -uint32_t IntCode_VECTOR_COMPARE_UGT_I16(IntCodeState& ics, const IntCode* i){ +uint32_t IntCode_VECTOR_COMPARE_UGT_I16(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(uint16_t, s8, s8, 8, > )}; -uint32_t IntCode_VECTOR_COMPARE_UGT_I32(IntCodeState& ics, const IntCode* i){ +uint32_t IntCode_VECTOR_COMPARE_UGT_I32(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(uint32_t, i4, i4, 4, > )}; -uint32_t IntCode_VECTOR_COMPARE_UGT_F32(IntCodeState& ics, const IntCode* i){ +uint32_t IntCode_VECTOR_COMPARE_UGT_F32(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(float, f4, i4, 4, > )}; int Translate_VECTOR_COMPARE_UGT(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { @@ -2406,13 +2406,13 @@ int Translate_VECTOR_COMPARE_UGT(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, fns[i->flags]); } -uint32_t IntCode_VECTOR_COMPARE_UGE_I8(IntCodeState& ics, const IntCode* i){ +uint32_t IntCode_VECTOR_COMPARE_UGE_I8(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(uint8_t, b16, b16, 16, >= )}; -uint32_t IntCode_VECTOR_COMPARE_UGE_I16(IntCodeState& ics, const IntCode* i){ +uint32_t IntCode_VECTOR_COMPARE_UGE_I16(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(uint16_t, s8, s8, 8, >= )}; -uint32_t IntCode_VECTOR_COMPARE_UGE_I32(IntCodeState& ics, const IntCode* i){ +uint32_t IntCode_VECTOR_COMPARE_UGE_I32(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(uint32_t, i4, i4, 4, >= )}; -uint32_t IntCode_VECTOR_COMPARE_UGE_F32(IntCodeState& ics, const IntCode* i){ +uint32_t IntCode_VECTOR_COMPARE_UGE_F32(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(float, f4, i4, 4, >= )}; int Translate_VECTOR_COMPARE_UGE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { From d578f5d0f0aa448b78d23695caf9c6546fc1a475 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 18 Aug 2014 22:01:55 -0700 Subject: [PATCH 134/388] Mostly fixing up alloy clang build. --- src/alloy/backend/ivm/ivm_assembler.cc | 2 +- src/alloy/backend/ivm/ivm_intcode.cc | 21 ++++++++------- src/alloy/backend/x64/x64_code_cache_posix.cc | 7 ++--- src/alloy/backend/x64/x64_emitter.cc | 13 +++++----- src/alloy/backend/x64/x64_sequences.cc | 26 +++++++++---------- .../compiler/passes/context_promotion_pass.h | 1 + src/alloy/frontend/ppc/ppc_context.cc | 2 ++ src/alloy/string_buffer.cc | 2 +- src/poly/assert.h | 2 +- src/poly/atomic.h | 22 +++++++++------- src/poly/cxx_compat.h | 2 ++ src/poly/main_posix.cc | 8 +++--- src/poly/mapped_memory_posix.cc | 8 +++--- src/poly/math.h | 1 + src/poly/string.cc | 1 + xenia.gyp | 2 +- 16 files changed, 64 insertions(+), 56 deletions(-) diff --git a/src/alloy/backend/ivm/ivm_assembler.cc b/src/alloy/backend/ivm/ivm_assembler.cc index 6bdb846b8..c01eeb209 100644 --- a/src/alloy/backend/ivm/ivm_assembler.cc +++ b/src/alloy/backend/ivm/ivm_assembler.cc @@ -83,7 +83,7 @@ int IVMAssembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder, stack_offset += type_size; } // Ensure 16b alignment. - stack_offset = poly::align(stack_offset, 16ull); + stack_offset = poly::align(stack_offset, static_cast(16)); ctx.stack_size = stack_offset; auto block = builder->first_block(); diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index 96043200d..03a7e1690 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -102,7 +102,8 @@ uint32_t AllocConstant(TranslationContext& ctx, Value* value) { uint32_t AllocLabel(TranslationContext& ctx, Label* label) { // If it's a back-branch to an already tagged label avoid setting up // a reference. - uint32_t value = reinterpret_cast(label->tag); + uint32_t value = + static_cast(reinterpret_cast(label->tag)); if (value & 0x80000000) { // Already set. return AllocConstant(ctx, value & ~0x80000000); @@ -125,7 +126,7 @@ uint32_t AllocLabel(TranslationContext& ctx, Label* label) { uint32_t AllocDynamicRegister(TranslationContext& ctx, Value* value) { if (value->flags & VALUE_IS_ALLOCATED) { - return reinterpret_cast(value->tag); + return static_cast(reinterpret_cast(value->tag)); } else { value->flags |= VALUE_IS_ALLOCATED; auto reg = ctx.register_count++; @@ -2334,13 +2335,13 @@ int Translate_DID_SATURATE(TranslationContext& ctx, Instr* i) { } \ return IA_NEXT; -uint32_t IntCode_VECTOR_COMPARE_EQ_I8(IntCodeState& ics, const IntCode* i){ +uint32_t IntCode_VECTOR_COMPARE_EQ_I8(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(uint8_t, b16, b16, 16, == )}; -uint32_t IntCode_VECTOR_COMPARE_EQ_I16(IntCodeState& ics, const IntCode* i){ +uint32_t IntCode_VECTOR_COMPARE_EQ_I16(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(uint16_t, s8, s8, 8, == )}; -uint32_t IntCode_VECTOR_COMPARE_EQ_I32(IntCodeState& ics, const IntCode* i){ +uint32_t IntCode_VECTOR_COMPARE_EQ_I32(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(uint32_t, i4, i4, 4, == )}; -uint32_t IntCode_VECTOR_COMPARE_EQ_F32(IntCodeState& ics, const IntCode* i){ +uint32_t IntCode_VECTOR_COMPARE_EQ_F32(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(float, f4, i4, 4, == )}; int Translate_VECTOR_COMPARE_EQ(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { @@ -2352,13 +2353,13 @@ int Translate_VECTOR_COMPARE_EQ(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, fns[i->flags]); } -uint32_t IntCode_VECTOR_COMPARE_SGT_I8(IntCodeState& ics, const IntCode* i){ +uint32_t IntCode_VECTOR_COMPARE_SGT_I8(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(int8_t, b16, b16, 16, > )}; -uint32_t IntCode_VECTOR_COMPARE_SGT_I16(IntCodeState& ics, const IntCode* i){ +uint32_t IntCode_VECTOR_COMPARE_SGT_I16(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(int16_t, s8, s8, 8, > )}; -uint32_t IntCode_VECTOR_COMPARE_SGT_I32(IntCodeState& ics, const IntCode* i){ +uint32_t IntCode_VECTOR_COMPARE_SGT_I32(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(int32_t, i4, i4, 4, > )}; -uint32_t IntCode_VECTOR_COMPARE_SGT_F32(IntCodeState& ics, const IntCode* i){ +uint32_t IntCode_VECTOR_COMPARE_SGT_F32(IntCodeState& ics, const IntCode* i) { VECTOR_COMPARER(float, f4, i4, 4, > )}; int Translate_VECTOR_COMPARE_SGT(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { diff --git a/src/alloy/backend/x64/x64_code_cache_posix.cc b/src/alloy/backend/x64/x64_code_cache_posix.cc index 7570e119d..63a44e709 100644 --- a/src/alloy/backend/x64/x64_code_cache_posix.cc +++ b/src/alloy/backend/x64/x64_code_cache_posix.cc @@ -9,10 +9,11 @@ #include -#include - #include +#include +#include + namespace alloy { namespace backend { namespace x64 { @@ -51,7 +52,7 @@ void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size, // Always move the code to land on 16b alignment. We do this by rounding up // to 16b so that all offsets are aligned. - code_size = XEROUNDUP(code_size, 16); + code_size = poly::round_up(code_size, 16); lock_.lock(); diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index 00c84936e..7d387600e 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -127,7 +127,7 @@ int X64Emitter::Emit(HIRBuilder* builder, size_t& out_stack_size) { } // Ensure 16b alignment. stack_offset -= StackLayout::GUEST_STACK_SIZE; - stack_offset = poly::align(stack_offset, 16ull); + stack_offset = poly::align(stack_offset, static_cast(16)); // Function prolog. // Must be 16b aligned. @@ -242,7 +242,7 @@ void X64Emitter::EmitTraceSource(const Instr* instr) { uint8_t dest_reg_1 = instr->flags >> 8; xdb::protocol::EventType event_type; - size_t event_size; + size_t event_size = 0; if (dest_reg_0 == 100) { event_type = xdb::protocol::EventType::INSTR; event_size = sizeof(xdb::protocol::InstrEvent); @@ -269,6 +269,7 @@ void X64Emitter::EmitTraceSource(const Instr* instr) { event_size = sizeof(xdb::protocol::InstrEventR8R8); } } + assert_not_zero(event_size); mov(rax, trace_base); mov(r8d, static_cast(event_size)); @@ -289,6 +290,7 @@ void X64Emitter::EmitTraceSource(const Instr* instr) { mov(word[r8 + 2], ax); switch (event_type) { + default: case xdb::protocol::EventType::INSTR: break; case xdb::protocol::EventType::INSTR_R8: @@ -330,8 +332,7 @@ void X64Emitter::EmitTraceSourceAppendValue(const Value* value, void X64Emitter::EmitGetCurrentThreadId() { // rcx must point to context. We could fetch from the stack if needed. - mov(ax, - word[rcx + runtime_->frontend()->context_info()->thread_id_offset()]); + mov(ax, word[rcx + runtime_->frontend()->context_info()->thread_id_offset()]); } void X64Emitter::EmitTraceUserCallReturn() { @@ -345,7 +346,7 @@ void X64Emitter::EmitTraceUserCallReturn() { lock(); xadd(qword[rax], r8); mov(rax, static_cast(xdb::protocol::EventType::USER_CALL_RETURN) | - (static_cast(0) << 8) | (0ull << 32)); + (static_cast(0) << 8) | (0ull << 32)); mov(qword[r8], rax); EmitGetCurrentThreadId(); mov(word[r8 + 2], ax); @@ -645,8 +646,6 @@ void X64Emitter::CallExtern(const hir::Instr* instr, static_cast(sizeof(xdb::protocol::KernelCallReturnEvent))); lock(); xadd(qword[rax], r8); - uint32_t module_id = 0; - uint32_t ordinal = 0; mov(rax, static_cast(xdb::protocol::EventType::KERNEL_CALL_RETURN) | (static_cast(0) << 8) | (0)); diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index fed77e3a4..0de164066 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -4491,26 +4491,24 @@ EMITTER_OPCODE_TABLE( // TODO(benvanik): AVX512 has a native variable rotate (rolv). EMITTER(VECTOR_ROTATE_LEFT_V128, MATCH(I, V128<>, V128<>>)) { static __m128i EmulateVectorRotateLeftI8(__m128i src1, __m128i src2) { - alignas(16) __m128i value; - alignas(16) __m128i shamt; - _mm_store_si128(&value, src1); - _mm_store_si128(&shamt, src2); + alignas(16) uint8_t value[16]; + alignas(16) uint8_t shamt[16]; + _mm_store_si128(reinterpret_cast<__m128i*>(&value), src1); + _mm_store_si128(reinterpret_cast<__m128i*>(&shamt), src2); for (size_t i = 0; i < 16; ++i) { - value.m128i_u8[i] = poly::rotate_left( - value.m128i_u8[i], shamt.m128i_u8[i] & 0x3); + value[i] = poly::rotate_left(value[i], shamt[i] & 0x3); } - return _mm_load_si128(&value); + return _mm_load_si128(reinterpret_cast<__m128i*>(&value)); } static __m128i EmulateVectorRotateLeftI16(__m128i src1, __m128i src2) { - alignas(16) __m128i value; - alignas(16) __m128i shamt; - _mm_store_si128(&value, src1); - _mm_store_si128(&shamt, src2); + alignas(16) uint16_t value[8]; + alignas(16) uint16_t shamt[8]; + _mm_store_si128(reinterpret_cast<__m128i*>(&value), src1); + _mm_store_si128(reinterpret_cast<__m128i*>(&shamt), src2); for (size_t i = 0; i < 8; ++i) { - value.m128i_u16[i] = poly::rotate_left( - value.m128i_u16[i], shamt.m128i_u16[i] & 0xF); + value[i] = poly::rotate_left(value[i], shamt[i] & 0xF); } - return _mm_load_si128(&value); + return _mm_load_si128(reinterpret_cast<__m128i*>(&value)); } static void Emit(X64Emitter& e, const EmitArgType& i) { switch (i.instr->flags) { diff --git a/src/alloy/compiler/passes/context_promotion_pass.h b/src/alloy/compiler/passes/context_promotion_pass.h index 0f4758af1..db6480da7 100644 --- a/src/alloy/compiler/passes/context_promotion_pass.h +++ b/src/alloy/compiler/passes/context_promotion_pass.h @@ -19,6 +19,7 @@ #include #pragma warning(pop) #else +#include #include #endif // XE_COMPILER_MSVC diff --git a/src/alloy/frontend/ppc/ppc_context.cc b/src/alloy/frontend/ppc/ppc_context.cc index c7a070696..6bb9fea2b 100644 --- a/src/alloy/frontend/ppc/ppc_context.cc +++ b/src/alloy/frontend/ppc/ppc_context.cc @@ -9,6 +9,8 @@ #include +#include + namespace alloy { namespace frontend { namespace ppc { diff --git a/src/alloy/string_buffer.cc b/src/alloy/string_buffer.cc index aa9a0897e..b53601aa3 100644 --- a/src/alloy/string_buffer.cc +++ b/src/alloy/string_buffer.cc @@ -14,7 +14,7 @@ namespace alloy { StringBuffer::StringBuffer(size_t initial_capacity) { - buffer_.reserve(std::max(initial_capacity, 1024ull)); + buffer_.reserve(std::max(initial_capacity, static_cast(1024))); } StringBuffer::~StringBuffer() = default; diff --git a/src/poly/assert.h b/src/poly/assert.h index 80d1898c4..596dc2363 100644 --- a/src/poly/assert.h +++ b/src/poly/assert.h @@ -19,7 +19,7 @@ namespace poly { #define static_assert_size(type, size) \ static_assert(sizeof(type) == size, \ - "bad definition for "## #type##": must be "## #size##" bytes") + "bad definition for " #type ": must be " #size " bytes") // We rely on assert being compiled out in NDEBUG. #define poly_assert assert diff --git a/src/poly/atomic.h b/src/poly/atomic.h index 4d8473e23..6c11a4172 100644 --- a/src/poly/atomic.h +++ b/src/poly/atomic.h @@ -40,10 +40,12 @@ inline int64_t atomic_exchange(int64_t new_value, volatile int64_t* value) { return OSAtomicCompareAndSwap64Barrier(*value, new_value, value); } -//inline int32_t atomic_exchange_add(int32_t amount, volatile int32_t* value) { -//} -//inline int64_t atomic_exchange_add(int64_t amount, volatile int64_t* value) { -//} +inline int32_t atomic_exchange_add(int32_t amount, volatile int32_t* value) { + return OSAtomicAdd32Barrier(amount, value) - amount; +} +inline int64_t atomic_exchange_add(int64_t amount, volatile int64_t* value) { + return OSAtomicAdd64Barrier(amount, value) - amount; +} inline bool atomic_cas(int32_t old_value, int32_t new_value, volatile int32_t* value) { @@ -51,7 +53,7 @@ inline bool atomic_cas(int32_t old_value, int32_t new_value, old_value, new_value, reinterpret_cast(value)); } inline bool atomic_cas(int64_t old_value, int64_t new_value, - volatile int32_t* value) { + volatile int64_t* value) { return OSAtomicCompareAndSwap64Barrier( old_value, new_value, reinterpret_cast(value)); } @@ -110,10 +112,12 @@ inline int64_t atomic_exchange(int64_t new_value, volatile int64_t* value) { return __sync_val_compare_and_swap(*value, value, new_value); } -//inline int32_t atomic_exchange_add(int32_t amount, volatile int32_t* value) { -//} -//inline int64_t atomic_exchange_add(int64_t amount, volatile int64_t* value) { -//} +inline int32_t atomic_exchange_add(int32_t amount, volatile int32_t* value) { + return __sync_fetch_and_add(amount, value); +} +inline int64_t atomic_exchange_add(int64_t amount, volatile int64_t* value) { + return __sync_fetch_and_add(amount, value); +} inline bool atomic_cas(int32_t old_value, int32_t new_value, volatile int32_t* value) { diff --git a/src/poly/cxx_compat.h b/src/poly/cxx_compat.h index fd0f26d81..632be698e 100644 --- a/src/poly/cxx_compat.h +++ b/src/poly/cxx_compat.h @@ -36,12 +36,14 @@ // C++1y make_unique. // http://herbsutter.com/2013/05/29/gotw-89-solution-smart-pointers/ // This is present in clang with -std=c++1y, but not otherwise. +#if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 4) namespace std { template unique_ptr make_unique(Args&&... args) { return unique_ptr(new T(forward(args)...)); } } // namespace std +#endif // clang < 3.4 #endif // !XE_COMPILER_MSVC namespace poly {} // namespace poly diff --git a/src/poly/main_posix.cc b/src/poly/main_posix.cc index 5af8b2437..353a0d2be 100644 --- a/src/poly/main_posix.cc +++ b/src/poly/main_posix.cc @@ -9,22 +9,20 @@ #include +#include #include namespace poly { -bool has_console_attached() { - return true; -} +bool has_console_attached() { return true; } } // namespace poly - extern "C" int main(int argc, char** argv) { auto entry_info = poly::GetEntryInfo(); google::SetUsageMessage(std::string("usage: ") + - poly::to_string(entry_info.usage)); + poly::to_string(entry_info.usage)); google::SetVersionString("1.0"); google::ParseCommandLineFlags(&argc, &argv, true); diff --git a/src/poly/mapped_memory_posix.cc b/src/poly/mapped_memory_posix.cc index 825361983..c5358d582 100644 --- a/src/poly/mapped_memory_posix.cc +++ b/src/poly/mapped_memory_posix.cc @@ -36,22 +36,22 @@ class PosixMappedMemory : public MappedMemory { std::unique_ptr MappedMemory::Open(const std::wstring& path, Mode mode, size_t offset, size_t length) { - const char* mode; + const char* mode_str; int prot; switch (mode) { case Mode::READ: - mode = "rb"; + mode_str = "rb"; prot = PROT_READ; break; case Mode::READ_WRITE: - mode = "r+b"; + mode_str = "r+b"; prot = PROT_READ | PROT_WRITE; break; } auto mm = std::make_unique(path, mode); - mm->file_handle = fopen(poly::to_string(path).c_str(), mode); + mm->file_handle = fopen(poly::to_string(path).c_str(), mode_str); if (!mm->file_handle) { return nullptr; } diff --git a/src/poly/math.h b/src/poly/math.h index 1b059c53d..b8ab8c6de 100644 --- a/src/poly/math.h +++ b/src/poly/math.h @@ -14,6 +14,7 @@ #include #include +#include #include #include diff --git a/src/poly/string.cc b/src/poly/string.cc index 8c877ec0d..f2a822ce0 100644 --- a/src/poly/string.cc +++ b/src/poly/string.cc @@ -10,6 +10,7 @@ #include #include +#include namespace poly { diff --git a/xenia.gyp b/xenia.gyp index e98acf017..ebbd30f68 100644 --- a/xenia.gyp +++ b/xenia.gyp @@ -110,7 +110,7 @@ 'SYMROOT': '<(DEPTH)/build/xenia/', 'ALWAYS_SEARCH_USER_PATHS': 'NO', 'ARCHS': ['x86_64'], - 'CLANG_CXX_LANGUAGE_STANDARD': 'c++11', + 'CLANG_CXX_LANGUAGE_STANDARD': 'c++1y', 'COMBINE_HIDPI_IMAGES': 'YES', 'GCC_C_LANGUAGE_STANDARD': 'gnu99', 'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', From b870914795c685291c604ab988f897e178c8f9e2 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 18 Aug 2014 22:12:21 -0700 Subject: [PATCH 135/388] Removing use of MEMORY_BASIC_INFORMATION. --- src/alloy/memory.h | 15 +- src/xenia/cpu/xenon_memory.cc | 275 +++++++++++++++------------------- src/xenia/cpu/xenon_memory.h | 42 +++--- 3 files changed, 151 insertions(+), 181 deletions(-) diff --git a/src/alloy/memory.h b/src/alloy/memory.h index 0b2faf25e..05d13115b 100644 --- a/src/alloy/memory.h +++ b/src/alloy/memory.h @@ -20,6 +20,17 @@ enum { MEMORY_FLAG_PHYSICAL = (1 << 3), }; +// Equivalent to the Win32 MEMORY_BASIC_INFORMATION struct. +struct AllocationInfo { + uint64_t base_address; + uint64_t allocation_base; + uint32_t allocation_protect; // TBD + size_t region_size; + uint32_t state; // TBD + uint32_t protect; // TBD + uint32_t type; // TBD +}; + class Memory { public: Memory(); @@ -58,8 +69,8 @@ class Memory { uint32_t alignment = 0x20) = 0; virtual int HeapFree(uint64_t address, size_t size) = 0; - virtual size_t QueryInformation(uint64_t base_address, - MEMORY_BASIC_INFORMATION* mem_info) = 0; + virtual bool QueryInformation(uint64_t base_address, + AllocationInfo* mem_info) = 0; virtual size_t QuerySize(uint64_t base_address) = 0; virtual int Protect(uint64_t address, size_t size, uint32_t access) = 0; diff --git a/src/xenia/cpu/xenon_memory.cc b/src/xenia/cpu/xenon_memory.cc index 9c95609b5..8382ac922 100644 --- a/src/xenia/cpu/xenon_memory.cc +++ b/src/xenia/cpu/xenon_memory.cc @@ -25,32 +25,27 @@ using namespace xe::cpu; #include #endif // WIN32 -#define MSPACES 1 -#define USE_LOCKS 0 -#define USE_DL_PREFIX 1 -#define HAVE_MORECORE 0 -#define HAVE_MREMAP 0 -#define malloc_getpagesize 4096 -#define DEFAULT_GRANULARITY 64 * 1024 -#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T -#define MALLOC_ALIGNMENT 32 -#define MALLOC_INSPECT_ALL 1 +#define MSPACES 1 +#define USE_LOCKS 0 +#define USE_DL_PREFIX 1 +#define HAVE_MORECORE 0 +#define HAVE_MREMAP 0 +#define malloc_getpagesize 4096 +#define DEFAULT_GRANULARITY 64 * 1024 +#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T +#define MALLOC_ALIGNMENT 32 +#define MALLOC_INSPECT_ALL 1 #if XE_DEBUG -#define FOOTERS 0 +#define FOOTERS 0 #endif // XE_DEBUG #include - -DEFINE_bool( - log_heap, false, - "Log heap structure on alloc/free."); +DEFINE_bool(log_heap, false, "Log heap structure on alloc/free."); DEFINE_uint64( heap_guard_pages, 0, "Allocate the given number of guard pages around all heap chunks."); -DEFINE_bool( - scribble_heap, false, - "Scribble 0xCD into all allocated heap memory."); - +DEFINE_bool(scribble_heap, false, + "Scribble 0xCD into all allocated heap memory."); /** * Memory map: @@ -84,45 +79,43 @@ DEFINE_bool( * this. */ -#define XENON_MEMORY_PHYSICAL_HEAP_LOW 0x00010000 -#define XENON_MEMORY_PHYSICAL_HEAP_HIGH 0x20000000 -#define XENON_MEMORY_VIRTUAL_HEAP_LOW 0x20000000 -#define XENON_MEMORY_VIRTUAL_HEAP_HIGH 0x40000000 - +#define XENON_MEMORY_PHYSICAL_HEAP_LOW 0x00010000 +#define XENON_MEMORY_PHYSICAL_HEAP_HIGH 0x20000000 +#define XENON_MEMORY_VIRTUAL_HEAP_LOW 0x20000000 +#define XENON_MEMORY_VIRTUAL_HEAP_HIGH 0x40000000 class xe::cpu::XenonMemoryHeap { -public: + public: XenonMemoryHeap(XenonMemory* memory, bool is_physical); ~XenonMemoryHeap(); int Initialize(uint64_t low, uint64_t high); - uint64_t Alloc(uint64_t base_address, size_t size, - uint32_t flags, uint32_t alignment); + uint64_t Alloc(uint64_t base_address, size_t size, uint32_t flags, + uint32_t alignment); uint64_t Free(uint64_t address, size_t size); size_t QuerySize(uint64_t base_address); void Dump(); -private: + private: static uint32_t next_heap_id_; - static void DumpHandler( - void* start, void* end, size_t used_bytes, void* context); + static void DumpHandler(void* start, void* end, size_t used_bytes, + void* context); -private: - XenonMemory* memory_; - uint32_t heap_id_; - bool is_physical_; - std::mutex lock_; - size_t size_; - uint8_t* ptr_; - mspace space_; + private: + XenonMemory* memory_; + uint32_t heap_id_; + bool is_physical_; + std::mutex lock_; + size_t size_; + uint8_t* ptr_; + mspace space_; }; uint32_t XenonMemoryHeap::next_heap_id_ = 1; XenonMemory::XenonMemory() - : Memory(), - mapping_(0), mapping_base_(0), page_table_(0) { + : Memory(), mapping_(0), mapping_base_(0), page_table_(0) { virtual_heap_ = new XenonMemoryHeap(this, false); physical_heap_ = new XenonMemoryHeap(this, true); } @@ -134,9 +127,7 @@ XenonMemory::~XenonMemory() { if (mapping_base_) { // GPU writeback. - VirtualFree( - Translate(0xC0000000), 0x00100000, - MEM_DECOMMIT); + VirtualFree(Translate(0xC0000000), 0x00100000, MEM_DECOMMIT); } delete physical_heap_; @@ -158,15 +149,13 @@ int XenonMemory::Initialize() { } result = 1; - // Create main page file-backed mapping. This is all reserved but - // uncommitted (so it shouldn't expand page file). +// Create main page file-backed mapping. This is all reserved but +// uncommitted (so it shouldn't expand page file). #if XE_PLATFORM_WIN32 - mapping_ = CreateFileMapping( - INVALID_HANDLE_VALUE, - NULL, - PAGE_READWRITE | SEC_RESERVE, - 1, 0, // entire 4gb space - NULL); + mapping_ = + CreateFileMapping(INVALID_HANDLE_VALUE, NULL, + PAGE_READWRITE | SEC_RESERVE, 1, 0, // entire 4gb space + NULL); #else char mapping_path[] = "/xenia/mapping/XXXXXX"; mktemp(mapping_path); @@ -197,17 +186,14 @@ int XenonMemory::Initialize() { membase_ = mapping_base_; // Prepare heaps. - virtual_heap_->Initialize( - XENON_MEMORY_VIRTUAL_HEAP_LOW, XENON_MEMORY_VIRTUAL_HEAP_HIGH); - physical_heap_->Initialize( - XENON_MEMORY_PHYSICAL_HEAP_LOW, XENON_MEMORY_PHYSICAL_HEAP_HIGH - 0x1000); + virtual_heap_->Initialize(XENON_MEMORY_VIRTUAL_HEAP_LOW, + XENON_MEMORY_VIRTUAL_HEAP_HIGH); + physical_heap_->Initialize(XENON_MEMORY_PHYSICAL_HEAP_LOW, + XENON_MEMORY_PHYSICAL_HEAP_HIGH - 0x1000); // GPU writeback. // 0xC... is physical, 0x7F... is virtual. We may need to overlay these. - VirtualAlloc( - Translate(0xC0000000), - 0x00100000, - MEM_COMMIT, PAGE_READWRITE); + VirtualAlloc(Translate(0xC0000000), 0x00100000, MEM_COMMIT, PAGE_READWRITE); // Add handlers for MMIO. mmio_handler_ = MMIOHandler::Install(mapping_base_); @@ -220,9 +206,8 @@ int XenonMemory::Initialize() { // Allocate dirty page table. // This must live within our low heap. Ideally we'd hardcode the address but // this is more flexible. - page_table_ = physical_heap_->Alloc( - 0, (512 * 1024 * 1024) / (16 * 1024), - X_MEM_COMMIT, 16 * 1024); + page_table_ = physical_heap_->Alloc(0, (512 * 1024 * 1024) / (16 * 1024), + X_MEM_COMMIT, 16 * 1024); return 0; @@ -231,32 +216,32 @@ XECLEANUP: } const static struct { - uint64_t virtual_address_start; - uint64_t virtual_address_end; - uint64_t target_address; + uint64_t virtual_address_start; + uint64_t virtual_address_end; + uint64_t target_address; } map_info[] = { - 0x00000000, 0x3FFFFFFF, 0x00000000, // (1024mb) - virtual 4k pages - 0x40000000, 0x7FFFFFFF, 0x40000000, // (1024mb) - virtual 64k pages - 0x80000000, 0x9FFFFFFF, 0x80000000, // (512mb) - xex pages - 0xA0000000, 0xBFFFFFFF, 0x00000000, // (512mb) - physical 64k pages - 0xC0000000, 0xDFFFFFFF, 0x00000000, // - physical 16mb pages - 0xE0000000, 0xFFFFFFFF, 0x00000000, // - physical 4k pages + 0x00000000, 0x3FFFFFFF, 0x00000000, // (1024mb) - virtual 4k pages + 0x40000000, 0x7FFFFFFF, 0x40000000, // (1024mb) - virtual 64k pages + 0x80000000, 0x9FFFFFFF, 0x80000000, // (512mb) - xex pages + 0xA0000000, 0xBFFFFFFF, 0x00000000, // (512mb) - physical 64k pages + 0xC0000000, 0xDFFFFFFF, 0x00000000, // - physical 16mb pages + 0xE0000000, 0xFFFFFFFF, 0x00000000, // - physical 4k pages }; int XenonMemory::MapViews(uint8_t* mapping_base) { assert_true(poly::countof(map_info) == poly::countof(views_.all_views)); for (size_t n = 0; n < poly::countof(map_info); n++) { #if XE_PLATFORM_WIN32 views_.all_views[n] = reinterpret_cast(MapViewOfFileEx( - mapping_, - FILE_MAP_ALL_ACCESS, - 0x00000000, (DWORD)map_info[n].target_address, + mapping_, FILE_MAP_ALL_ACCESS, 0x00000000, + (DWORD)map_info[n].target_address, map_info[n].virtual_address_end - map_info[n].virtual_address_start + 1, mapping_base + map_info[n].virtual_address_start)); #else views_.all_views[n] = reinterpret_cast(mmap( map_info[n].virtual_address_start + mapping_base, map_info[n].virtual_address_end - map_info[n].virtual_address_start + 1, - PROT_NONE, MAP_SHARED | MAP_FIXED, mapping_, map_info[n].target_address)); + PROT_NONE, MAP_SHARED | MAP_FIXED, mapping_, + map_info[n].target_address)); #endif // XE_PLATFORM_WIN32 XEEXPECTNOTNULL(views_.all_views[n]); } @@ -273,25 +258,24 @@ void XenonMemory::UnmapViews() { #if XE_PLATFORM_WIN32 UnmapViewOfFile(views_.all_views[n]); #else - size_t length = map_info[n].virtual_address_end - map_info[n].virtual_address_start + 1; + size_t length = map_info[n].virtual_address_end - + map_info[n].virtual_address_start + 1; munmap(views_.all_views[n], length); #endif // XE_PLATFORM_WIN32 } } } -bool XenonMemory::AddMappedRange(uint64_t address, uint64_t mask, - uint64_t size, void* context, - MMIOReadCallback read_callback, +bool XenonMemory::AddMappedRange(uint64_t address, uint64_t mask, uint64_t size, + void* context, MMIOReadCallback read_callback, MMIOWriteCallback write_callback) { DWORD protect = PAGE_NOACCESS; - if (!VirtualAlloc(Translate(address), - size, - MEM_COMMIT, protect)) { + if (!VirtualAlloc(Translate(address), size, MEM_COMMIT, protect)) { XELOGE("Unable to map range; commit/protect failed"); return false; } - return mmio_handler_->RegisterRange(address, mask, size, context, read_callback, write_callback); + return mmio_handler_->RegisterRange(address, mask, size, context, + read_callback, write_callback); } uint8_t XenonMemory::LoadI8(uint64_t address) { @@ -350,20 +334,17 @@ void XenonMemory::StoreI64(uint64_t address, uint64_t value) { } } -uint64_t XenonMemory::HeapAlloc( - uint64_t base_address, size_t size, uint32_t flags, - uint32_t alignment) { +uint64_t XenonMemory::HeapAlloc(uint64_t base_address, size_t size, + uint32_t flags, uint32_t alignment) { // If we were given a base address we are outside of the normal heap and // will place wherever asked (so long as it doesn't overlap the heap). if (!base_address) { // Normal allocation from the managed heap. uint64_t result; if (flags & MEMORY_FLAG_PHYSICAL) { - result = physical_heap_->Alloc( - base_address, size, flags, alignment); + result = physical_heap_->Alloc(base_address, size, flags, alignment); } else { - result = virtual_heap_->Alloc( - base_address, size, flags, alignment); + result = virtual_heap_->Alloc(base_address, size, flags, alignment); } if (result) { if (flags & MEMORY_FLAG_ZERO) { @@ -417,11 +398,22 @@ int XenonMemory::HeapFree(uint64_t address, size_t size) { } } -size_t XenonMemory::QueryInformation(uint64_t base_address, - MEMORY_BASIC_INFORMATION* mem_info) { +bool XenonMemory::QueryInformation(uint64_t base_address, + AllocationInfo* mem_info) { uint8_t* p = Translate(base_address); - - return VirtualQuery(p, mem_info, sizeof(MEMORY_BASIC_INFORMATION)); + MEMORY_BASIC_INFORMATION mbi; + if (!VirtualQuery(p, &mbi, sizeof(mbi))) { + return false; + } + mem_info->base_address = base_address; + mem_info->allocation_base = + static_cast(mbi.AllocationBase - membase_); + mem_info->allocation_protect = mbi.AllocationProtect; + mem_info->region_size = mbi.RegionSize; + mem_info->state = mbi.State; + mem_info->protect = mbi.Protect; + mem_info->type = mbi.Type; + return true; } size_t XenonMemory::QuerySize(uint64_t base_address) { @@ -451,10 +443,10 @@ int XenonMemory::Protect(uint64_t address, size_t size, uint32_t access) { p += heap_guard_size; DWORD new_protect = access; - new_protect = new_protect & ( - X_PAGE_NOACCESS | X_PAGE_READONLY | X_PAGE_READWRITE | - X_PAGE_WRITECOPY | X_PAGE_GUARD | X_PAGE_NOCACHE | - X_PAGE_WRITECOMBINE); + new_protect = + new_protect & + (X_PAGE_NOACCESS | X_PAGE_READONLY | X_PAGE_READWRITE | X_PAGE_WRITECOPY | + X_PAGE_GUARD | X_PAGE_NOCACHE | X_PAGE_WRITECOMBINE); DWORD old_protect; return VirtualProtect(p, size, new_protect, &old_protect) == TRUE ? 0 : 1; @@ -470,9 +462,8 @@ uint32_t XenonMemory::QueryProtect(uint64_t address) { return info.Protect; } - -XenonMemoryHeap::XenonMemoryHeap(XenonMemory* memory, bool is_physical) : - memory_(memory), is_physical_(is_physical) { +XenonMemoryHeap::XenonMemoryHeap(XenonMemory* memory, bool is_physical) + : memory_(memory), is_physical_(is_physical) { heap_id_ = next_heap_id_++; } @@ -494,8 +485,7 @@ int XenonMemoryHeap::Initialize(uint64_t low, uint64_t high) { // as it goes. size_ = high - low; ptr_ = memory_->views_.v00000000 + low; - void* heap_result = VirtualAlloc( - ptr_, size_, MEM_COMMIT, PAGE_READWRITE); + void* heap_result = VirtualAlloc(ptr_, size_, MEM_COMMIT, PAGE_READWRITE); if (!heap_result) { return 1; } @@ -504,8 +494,8 @@ int XenonMemoryHeap::Initialize(uint64_t low, uint64_t high) { return 0; } -uint64_t XenonMemoryHeap::Alloc( - uint64_t base_address, size_t size, uint32_t flags, uint32_t alignment) { +uint64_t XenonMemoryHeap::Alloc(uint64_t base_address, size_t size, + uint32_t flags, uint32_t alignment) { lock_.lock(); size_t alloc_size = size; size_t heap_guard_size = FLAGS_heap_guard_pages * 4096; @@ -519,13 +509,10 @@ uint64_t XenonMemoryHeap::Alloc( if (FLAGS_heap_guard_pages) { size_t real_size = mspace_usable_size(p); DWORD old_protect; - VirtualProtect( - p, heap_guard_size, - PAGE_NOACCESS, &old_protect); + VirtualProtect(p, heap_guard_size, PAGE_NOACCESS, &old_protect); p += heap_guard_size; - VirtualProtect( - p + alloc_size, heap_guard_size, - PAGE_NOACCESS, &old_protect); + VirtualProtect(p + alloc_size, heap_guard_size, PAGE_NOACCESS, + &old_protect); } if (FLAGS_log_heap) { Dump(); @@ -538,25 +525,15 @@ uint64_t XenonMemoryHeap::Alloc( if (is_physical_) { // If physical, we need to commit the memory in the physical address ranges // so that it can be accessed. - VirtualAlloc( - memory_->views_.vA0000000 + (p - memory_->views_.v00000000), - size, - MEM_COMMIT, - PAGE_READWRITE); - VirtualAlloc( - memory_->views_.vC0000000 + (p - memory_->views_.v00000000), - size, - MEM_COMMIT, - PAGE_READWRITE); - VirtualAlloc( - memory_->views_.vE0000000 + (p - memory_->views_.v00000000), - size, - MEM_COMMIT, - PAGE_READWRITE); + VirtualAlloc(memory_->views_.vA0000000 + (p - memory_->views_.v00000000), + size, MEM_COMMIT, PAGE_READWRITE); + VirtualAlloc(memory_->views_.vC0000000 + (p - memory_->views_.v00000000), + size, MEM_COMMIT, PAGE_READWRITE); + VirtualAlloc(memory_->views_.vE0000000 + (p - memory_->views_.v00000000), + size, MEM_COMMIT, PAGE_READWRITE); } - if ((flags & X_MEM_NOZERO) && - FLAGS_scribble_heap) { + if ((flags & X_MEM_NOZERO) && FLAGS_scribble_heap) { // Trash the memory so that we can see bad read-before-write bugs easier. memset(p, 0xCD, alloc_size); } else { @@ -590,12 +567,9 @@ uint64_t XenonMemoryHeap::Free(uint64_t address, size_t size) { lock_.lock(); if (FLAGS_heap_guard_pages) { DWORD old_protect; - VirtualProtect( - p, heap_guard_size, - PAGE_READWRITE, &old_protect); - VirtualProtect( - p + heap_guard_size + real_size, heap_guard_size, - PAGE_READWRITE, &old_protect); + VirtualProtect(p, heap_guard_size, PAGE_READWRITE, &old_protect); + VirtualProtect(p + heap_guard_size + real_size, heap_guard_size, + PAGE_READWRITE, &old_protect); } mspace_free(space_, p); if (FLAGS_log_heap) { @@ -605,18 +579,12 @@ uint64_t XenonMemoryHeap::Free(uint64_t address, size_t size) { if (is_physical_) { // If physical, decommit from physical ranges too. - VirtualFree( - memory_->views_.vA0000000 + (p - memory_->views_.v00000000), - size, - MEM_DECOMMIT); - VirtualFree( - memory_->views_.vC0000000 + (p - memory_->views_.v00000000), - size, - MEM_DECOMMIT); - VirtualFree( - memory_->views_.vE0000000 + (p - memory_->views_.v00000000), - size, - MEM_DECOMMIT); + VirtualFree(memory_->views_.vA0000000 + (p - memory_->views_.v00000000), + size, MEM_DECOMMIT); + VirtualFree(memory_->views_.vC0000000 + (p - memory_->views_.v00000000), + size, MEM_DECOMMIT); + VirtualFree(memory_->views_.vE0000000 + (p - memory_->views_.v00000000), + size, MEM_DECOMMIT); } return (uint64_t)real_size; @@ -638,8 +606,7 @@ size_t XenonMemoryHeap::QuerySize(uint64_t base_address) { } void XenonMemoryHeap::Dump() { - XELOGI("XenonMemoryHeap::Dump - %s", - is_physical_ ? "physical" : "virtual"); + XELOGI("XenonMemoryHeap::Dump - %s", is_physical_ ? "physical" : "virtual"); if (FLAGS_heap_guard_pages) { XELOGI(" (heap guard pages enabled, stats will be wrong)"); } @@ -655,8 +622,8 @@ void XenonMemoryHeap::Dump() { mspace_inspect_all(space_, DumpHandler, this); } -void XenonMemoryHeap::DumpHandler( - void* start, void* end, size_t used_bytes, void* context) { +void XenonMemoryHeap::DumpHandler(void* start, void* end, size_t used_bytes, + void* context) { XenonMemoryHeap* heap = (XenonMemoryHeap*)context; XenonMemory* memory = heap->memory_; size_t heap_guard_size = FLAGS_heap_guard_pages * 4096; @@ -664,12 +631,10 @@ void XenonMemoryHeap::DumpHandler( uint64_t end_addr = (uint64_t)end - heap_guard_size; uint32_t guest_start = (uint32_t)(start_addr - (uintptr_t)memory->mapping_base_); - uint32_t guest_end = - (uint32_t)(end_addr - (uintptr_t)memory->mapping_base_); + uint32_t guest_end = (uint32_t)(end_addr - (uintptr_t)memory->mapping_base_); if (int32_t(end_addr - start_addr) > 0) { - XELOGI(" - %.8X-%.8X (%10db) %.16llX-%.16llX - %9db used", - guest_start, guest_end, (guest_end - guest_start), - start_addr, end_addr, + XELOGI(" - %.8X-%.8X (%10db) %.16llX-%.16llX - %9db used", guest_start, + guest_end, (guest_end - guest_start), start_addr, end_addr, used_bytes); } else { XELOGI(" - %.16llX-%.16llX - %9db used", diff --git a/src/xenia/cpu/xenon_memory.h b/src/xenia/cpu/xenon_memory.h index c71c6ccd9..f1dfe331f 100644 --- a/src/xenia/cpu/xenon_memory.h +++ b/src/xenia/cpu/xenon_memory.h @@ -17,7 +17,6 @@ #include #include - typedef struct xe_ppc_state xe_ppc_state_t; namespace xe { @@ -26,7 +25,7 @@ namespace cpu { class XenonMemoryHeap; class XenonMemory : public alloy::Memory { -public: + public: XenonMemory(); virtual ~XenonMemory(); @@ -34,10 +33,8 @@ public: uint64_t page_table() const override { return page_table_; } - bool AddMappedRange(uint64_t address, uint64_t mask, - uint64_t size, - void* context, - MMIOReadCallback read_callback, + bool AddMappedRange(uint64_t address, uint64_t mask, uint64_t size, + void* context, MMIOReadCallback read_callback, MMIOWriteCallback write_callback); uint8_t LoadI8(uint64_t address) override; @@ -49,35 +46,34 @@ public: void StoreI32(uint64_t address, uint32_t value) override; void StoreI64(uint64_t address, uint64_t value) override; - uint64_t HeapAlloc( - uint64_t base_address, size_t size, uint32_t flags, - uint32_t alignment = 0x20) override; + uint64_t HeapAlloc(uint64_t base_address, size_t size, uint32_t flags, + uint32_t alignment = 0x20) override; int HeapFree(uint64_t address, size_t size) override; - size_t QueryInformation(uint64_t base_address, - MEMORY_BASIC_INFORMATION* mem_info) override; + bool QueryInformation(uint64_t base_address, + alloy::AllocationInfo* mem_info) override; size_t QuerySize(uint64_t base_address) override; int Protect(uint64_t address, size_t size, uint32_t access) override; uint32_t QueryProtect(uint64_t address) override; -private: + private: int MapViews(uint8_t* mapping_base); void UnmapViews(); -private: - HANDLE mapping_; - uint8_t* mapping_base_; + private: + HANDLE mapping_; + uint8_t* mapping_base_; union { struct { - uint8_t* v00000000; - uint8_t* v40000000; - uint8_t* v80000000; - uint8_t* vA0000000; - uint8_t* vC0000000; - uint8_t* vE0000000; + uint8_t* v00000000; + uint8_t* v40000000; + uint8_t* v80000000; + uint8_t* vA0000000; + uint8_t* vC0000000; + uint8_t* vE0000000; }; - uint8_t* all_views[6]; + uint8_t* all_views[6]; } views_; std::unique_ptr mmio_handler_; @@ -90,9 +86,7 @@ private: friend class XenonMemoryHeap; }; - } // namespace cpu } // namespace xe - #endif // XENIA_CPU_XENON_MEMORY_H_ From 41f3c92c25e85222dcb62da59910eb0b9619b560 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 19 Aug 2014 19:41:29 -0700 Subject: [PATCH 136/388] Fixing build. --- src/xenia/cpu/xenon_memory.cc | 4 ++-- src/xenia/kernel/xboxkrnl_memory.cc | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/xenia/cpu/xenon_memory.cc b/src/xenia/cpu/xenon_memory.cc index 8382ac922..63f5cc6d7 100644 --- a/src/xenia/cpu/xenon_memory.cc +++ b/src/xenia/cpu/xenon_memory.cc @@ -406,8 +406,8 @@ bool XenonMemory::QueryInformation(uint64_t base_address, return false; } mem_info->base_address = base_address; - mem_info->allocation_base = - static_cast(mbi.AllocationBase - membase_); + mem_info->allocation_base = static_cast( + reinterpret_cast(mbi.AllocationBase) - membase_); mem_info->allocation_protect = mbi.AllocationProtect; mem_info->region_size = mbi.RegionSize; mem_info->state = mbi.State; diff --git a/src/xenia/kernel/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl_memory.cc index fcc958094..ffdc4c7b1 100644 --- a/src/xenia/kernel/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl_memory.cc @@ -158,7 +158,7 @@ SHIM_CALL NtQueryVirtualMemory_shim(PPCContext* ppc_state, KernelState* state) { XELOGD("NtQueryVirtualMemory(%.8X, %.8X)", base_address, memory_basic_information_ptr); - MEMORY_BASIC_INFORMATION mem_info; + alloy::AllocationInfo mem_info; size_t result = state->memory()->QueryInformation(base_address, &mem_info); if (!result) { SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER); @@ -166,16 +166,16 @@ SHIM_CALL NtQueryVirtualMemory_shim(PPCContext* ppc_state, KernelState* state) { } auto membase = state->memory()->membase(); - memory_basic_information->base_address = static_cast( - reinterpret_cast(mem_info.BaseAddress) - membase); - memory_basic_information->allocation_base = static_cast( - reinterpret_cast(mem_info.AllocationBase) - membase); - memory_basic_information->allocation_protect = mem_info.AllocationProtect; + memory_basic_information->base_address = + static_cast(mem_info.base_address); + memory_basic_information->allocation_base = + static_cast(mem_info.allocation_base); + memory_basic_information->allocation_protect = mem_info.allocation_protect; memory_basic_information->region_size = - static_cast(mem_info.RegionSize); - memory_basic_information->state = mem_info.State; - memory_basic_information->protect = mem_info.Protect; - memory_basic_information->type = mem_info.Type; + static_cast(mem_info.region_size); + memory_basic_information->state = mem_info.state; + memory_basic_information->protect = mem_info.protect; + memory_basic_information->type = mem_info.type; // TODO(benvanik): auto swap structure. memory_basic_information->base_address = From 76d524b6557123341d1f0641b2cc2e6c8ee6b5f8 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 19 Aug 2014 20:05:51 -0700 Subject: [PATCH 137/388] Removing dead file. --- src/xenia/gpu/draw_command.cc | 17 ----------------- src/xenia/gpu/sources.gypi | 1 - 2 files changed, 18 deletions(-) delete mode 100644 src/xenia/gpu/draw_command.cc diff --git a/src/xenia/gpu/draw_command.cc b/src/xenia/gpu/draw_command.cc deleted file mode 100644 index 468c4ed08..000000000 --- a/src/xenia/gpu/draw_command.cc +++ /dev/null @@ -1,17 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2014 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - - -using namespace std; -using namespace xe; -using namespace xe::gpu; -using namespace xe::gpu::xenos; - diff --git a/src/xenia/gpu/sources.gypi b/src/xenia/gpu/sources.gypi index b01f7a33b..e1e0a0b14 100644 --- a/src/xenia/gpu/sources.gypi +++ b/src/xenia/gpu/sources.gypi @@ -5,7 +5,6 @@ 'buffer_resource.h', 'command_processor.cc', 'command_processor.h', - 'draw_command.cc', 'draw_command.h', 'gpu-private.h', 'gpu.cc', From 48a0e5c6010f696c9b2359b97c755b4abfcb9395 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 19 Aug 2014 21:02:15 -0700 Subject: [PATCH 138/388] Shrinking alloy memory interface so that alloy-sandbox doesn't need xe. --- src/alloy/backend/ivm/ivm_intcode.cc | 4 +- src/alloy/backend/x64/x64_sequences.cc | 9 +- src/alloy/frontend/ppc/ppc_context.h | 2 +- src/alloy/memory.cc | 39 ++++++++ src/alloy/memory.h | 56 +++++------ src/alloy/runtime/raw_module.cc | 17 +--- src/xenia/apu/audio_system.cc | 2 +- src/xenia/core.h | 6 +- src/xenia/cpu/processor.cc | 1 - src/xenia/cpu/processor.h | 1 + src/xenia/cpu/sources.gypi | 2 - src/xenia/cpu/xenon_runtime.cc | 11 +-- src/xenia/cpu/xenon_thread_state.cc | 4 +- src/xenia/cpu/xenon_thread_state.h | 18 ++-- src/xenia/emulator.cc | 4 +- src/xenia/emulator.h | 27 +++--- src/xenia/kernel/objects/xthread.cc | 7 +- src/xenia/kernel/util/xex2.cc | 25 ++--- src/xenia/kernel/xboxkrnl_memory.cc | 6 +- src/xenia/{cpu/xenon_memory.cc => memory.cc} | 99 ++++++++++---------- src/xenia/{cpu/xenon_memory.h => memory.h} | 61 +++++++----- src/xenia/sources.gypi | 2 + tools/alloy-sandbox/alloy-sandbox.cc | 19 ++-- 23 files changed, 230 insertions(+), 192 deletions(-) rename src/xenia/{cpu/xenon_memory.cc => memory.cc} (87%) rename src/xenia/{cpu/xenon_memory.h => memory.h} (57%) diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index 03a7e1690..8533eda15 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -1499,7 +1499,9 @@ int Translate_LOAD(TranslationContext& ctx, Instr* i) { void MarkPageDirty(IntCodeState& ics, uint32_t address) { // 16KB pages. - ics.page_table[(address >> 14) & 0x7FFF] = 1; + if (ics.page_table) { + ics.page_table[(address >> 14) & 0x7FFF] = 1; + } } uint32_t IntCode_STORE_I8(IntCodeState& ics, const IntCode* i) { uint32_t address = ics.rf[i->src1_reg].u32; diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index 0de164066..e015fbd4b 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -1557,9 +1557,12 @@ EMITTER_OPCODE_TABLE( // Note: most *should* be aligned, but needs to be checked! void EmitMarkPageDirty(X64Emitter& e, RegExp& addr) { // 16KB pages. - e.shr(e.eax, 14); - e.and(e.eax, 0x7FFF); - e.mov(e.byte[e.rdx + e.rax + e.page_table_address()], 1); + auto page_table_address = e.page_table_address(); + if (page_table_address) { + e.shr(e.eax, 14); + e.and(e.eax, 0x7FFF); + e.mov(e.byte[e.rdx + e.rax + page_table_address], 1); + } } EMITTER(STORE_I8, MATCH(I, I8<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { diff --git a/src/alloy/frontend/ppc/ppc_context.h b/src/alloy/frontend/ppc/ppc_context.h index f3365e192..c0409e067 100644 --- a/src/alloy/frontend/ppc/ppc_context.h +++ b/src/alloy/frontend/ppc/ppc_context.h @@ -172,7 +172,7 @@ typedef struct alignas(64) PPCContext_s { uint32_t thread_id; // Reserve address for load acquire/store release. Shared. - uint32_t* reserve_address; + uint64_t* reserve_address; // Runtime-specific data pointer. Used on callbacks to get access to the // current runtime and its data. diff --git a/src/alloy/memory.cc b/src/alloy/memory.cc index abc0a8635..4154e9e43 100644 --- a/src/alloy/memory.cc +++ b/src/alloy/memory.cc @@ -61,4 +61,43 @@ uint64_t Memory::SearchAligned(uint64_t start, uint64_t end, return 0; } +SimpleMemory::SimpleMemory(size_t capacity) : memory_(capacity) { + membase_ = reinterpret_cast(memory_.data()); + reserve_address_ = capacity - 8; +} + +SimpleMemory::~SimpleMemory() = default; + +uint8_t SimpleMemory::LoadI8(uint64_t address) { + return poly::load(membase_ + address); +} + +uint16_t SimpleMemory::LoadI16(uint64_t address) { + return poly::load(membase_ + address); +} + +uint32_t SimpleMemory::LoadI32(uint64_t address) { + return poly::load(membase_ + address); +} + +uint64_t SimpleMemory::LoadI64(uint64_t address) { + return poly::load(membase_ + address); +} + +void SimpleMemory::StoreI8(uint64_t address, uint8_t value) { + poly::store(membase_ + address, value); +} + +void SimpleMemory::StoreI16(uint64_t address, uint16_t value) { + poly::store(membase_ + address, value); +} + +void SimpleMemory::StoreI32(uint64_t address, uint32_t value) { + poly::store(membase_ + address, value); +} + +void SimpleMemory::StoreI64(uint64_t address, uint64_t value) { + poly::store(membase_ + address, value); +} + } // namespace alloy diff --git a/src/alloy/memory.h b/src/alloy/memory.h index 05d13115b..869fc4eb7 100644 --- a/src/alloy/memory.h +++ b/src/alloy/memory.h @@ -14,23 +14,6 @@ namespace alloy { -enum { - MEMORY_FLAG_64KB_PAGES = (1 << 1), - MEMORY_FLAG_ZERO = (1 << 2), - MEMORY_FLAG_PHYSICAL = (1 << 3), -}; - -// Equivalent to the Win32 MEMORY_BASIC_INFORMATION struct. -struct AllocationInfo { - uint64_t base_address; - uint64_t allocation_base; - uint32_t allocation_protect; // TBD - size_t region_size; - uint32_t state; // TBD - uint32_t protect; // TBD - uint32_t type; // TBD -}; - class Memory { public: Memory(); @@ -40,8 +23,9 @@ class Memory { inline uint8_t* Translate(uint64_t guest_address) const { return membase_ + guest_address; }; - inline uint32_t* reserve_address() { return &reserve_address_; } + inline uint64_t* reserve_address() { return &reserve_address_; } + // TODO(benvanik): remove with GPU refactor. virtual uint64_t page_table() const = 0; uint64_t trace_base() const { return trace_base_; } @@ -49,6 +33,7 @@ class Memory { virtual int Initialize(); + // TODO(benvanik): make poly memory utils for these. void Zero(uint64_t address, size_t size); void Fill(uint64_t address, size_t size, uint8_t value); void Copy(uint64_t dest, uint64_t src, size_t size); @@ -56,6 +41,7 @@ class Memory { uint64_t SearchAligned(uint64_t start, uint64_t end, const uint32_t* values, size_t value_count); + // TODO(benvanik): remove with IVM. virtual uint8_t LoadI8(uint64_t address) = 0; virtual uint16_t LoadI16(uint64_t address) = 0; virtual uint32_t LoadI32(uint64_t address) = 0; @@ -65,24 +51,34 @@ class Memory { virtual void StoreI32(uint64_t address, uint32_t value) = 0; virtual void StoreI64(uint64_t address, uint64_t value) = 0; - virtual uint64_t HeapAlloc(uint64_t base_address, size_t size, uint32_t flags, - uint32_t alignment = 0x20) = 0; - virtual int HeapFree(uint64_t address, size_t size) = 0; - - virtual bool QueryInformation(uint64_t base_address, - AllocationInfo* mem_info) = 0; - virtual size_t QuerySize(uint64_t base_address) = 0; - - virtual int Protect(uint64_t address, size_t size, uint32_t access) = 0; - virtual uint32_t QueryProtect(uint64_t address) = 0; - protected: size_t system_page_size_; uint8_t* membase_; - uint32_t reserve_address_; + uint64_t reserve_address_; uint64_t trace_base_; }; +class SimpleMemory : public Memory { + public: + SimpleMemory(size_t capacity); + ~SimpleMemory() override; + + uint64_t page_table() const override { return 0; } + + // TODO(benvanik): remove with IVM. + uint8_t LoadI8(uint64_t address) override; + uint16_t LoadI16(uint64_t address) override; + uint32_t LoadI32(uint64_t address) override; + uint64_t LoadI64(uint64_t address) override; + void StoreI8(uint64_t address, uint8_t value) override; + void StoreI16(uint64_t address, uint16_t value) override; + void StoreI32(uint64_t address, uint32_t value) override; + void StoreI64(uint64_t address, uint64_t value) override; + + private: + std::vector memory_; +}; + } // namespace alloy #endif // ALLOY_MEMORY_H_ diff --git a/src/alloy/runtime/raw_module.cc b/src/alloy/runtime/raw_module.cc index 365d620ac..765d6a371 100644 --- a/src/alloy/runtime/raw_module.cc +++ b/src/alloy/runtime/raw_module.cc @@ -15,11 +15,7 @@ namespace runtime { RawModule::RawModule(Runtime* runtime) : Module(runtime), base_address_(0), low_address_(0), high_address_(0) {} -RawModule::~RawModule() { - if (base_address_) { - memory_->HeapFree(base_address_, high_address_ - low_address_); - } -} +RawModule::~RawModule() {} int RawModule::LoadFile(uint64_t base_address, const std::string& path) { FILE* file = fopen(path.c_str(), "rb"); @@ -28,15 +24,12 @@ int RawModule::LoadFile(uint64_t base_address, const std::string& path) { fseek(file, 0, SEEK_SET); // Allocate memory. - base_address_ = - memory_->HeapAlloc(base_address, file_length, MEMORY_FLAG_ZERO); - if (!base_address_) { - fclose(file); - return 1; - } + // Since we have no real heap just load it wherever. + base_address_ = base_address; + uint8_t* p = memory_->Translate(base_address_); + memset(p, 0, file_length); // Read into memory. - uint8_t* p = memory_->Translate(base_address_); fread(p, file_length, 1, file); fclose(file); diff --git a/src/xenia/apu/audio_system.cc b/src/xenia/apu/audio_system.cc index bf73c5d90..8a8e30fa7 100644 --- a/src/xenia/apu/audio_system.cc +++ b/src/xenia/apu/audio_system.cc @@ -48,7 +48,7 @@ X_STATUS AudioSystem::Setup() { new XenonThreadState(emulator_->processor()->runtime(), 0, 16 * 1024, 0); thread_state_->set_name("Audio Worker"); thread_block_ = - (uint32_t)memory_->HeapAlloc(0, 2048, alloy::MEMORY_FLAG_ZERO); + (uint32_t)memory_->HeapAlloc(0, 2048, MEMORY_FLAG_ZERO); thread_state_->context()->r[13] = thread_block_; // Create worker thread. diff --git a/src/xenia/core.h b/src/xenia/core.h index 8193aecff..6027d653d 100644 --- a/src/xenia/core.h +++ b/src/xenia/core.h @@ -12,13 +12,9 @@ #include -#include -namespace xe { - using Memory = alloy::Memory; -} // namespace xe - #include #include #include +#include #endif // XENIA_CORE_H_ diff --git a/src/xenia/cpu/processor.cc b/src/xenia/cpu/processor.cc index 220c9dd4a..92ac73572 100644 --- a/src/xenia/cpu/processor.cc +++ b/src/xenia/cpu/processor.cc @@ -12,7 +12,6 @@ #include #include #include -#include #include #include diff --git a/src/xenia/cpu/processor.h b/src/xenia/cpu/processor.h index 6dc1634bd..fc0b5bc2a 100644 --- a/src/xenia/cpu/processor.h +++ b/src/xenia/cpu/processor.h @@ -19,6 +19,7 @@ XEDECLARECLASS2(alloy, runtime, Breakpoint); XEDECLARECLASS1(xe, Emulator); XEDECLARECLASS1(xe, ExportResolver); +XEDECLARECLASS1(xe, Memory); XEDECLARECLASS2(xe, cpu, XenonMemory); XEDECLARECLASS2(xe, cpu, XenonRuntime); XEDECLARECLASS2(xe, cpu, XenonThreadState); diff --git a/src/xenia/cpu/sources.gypi b/src/xenia/cpu/sources.gypi index 46c524816..c519655de 100644 --- a/src/xenia/cpu/sources.gypi +++ b/src/xenia/cpu/sources.gypi @@ -8,8 +8,6 @@ 'mmio_handler.h', 'processor.cc', 'processor.h', - 'xenon_memory.cc', - 'xenon_memory.h', 'xenon_runtime.cc', 'xenon_runtime.h', 'xenon_thread_state.cc', diff --git a/src/xenia/cpu/xenon_runtime.cc b/src/xenia/cpu/xenon_runtime.cc index 1ae38b8c9..61ca8aabe 100644 --- a/src/xenia/cpu/xenon_runtime.cc +++ b/src/xenia/cpu/xenon_runtime.cc @@ -10,25 +10,20 @@ #include #include - #include -using namespace alloy; -using namespace alloy::frontend::ppc; -using namespace alloy::runtime; using namespace xe; using namespace xe::cpu; -XenonRuntime::XenonRuntime(alloy::Memory* memory, - ExportResolver* export_resolver, +XenonRuntime::XenonRuntime(Memory* memory, ExportResolver* export_resolver, uint32_t debug_info_flags, uint32_t trace_flags) : Runtime(memory, debug_info_flags, trace_flags), export_resolver_(export_resolver) {} XenonRuntime::~XenonRuntime() = default; -int XenonRuntime::Initialize(std::unique_ptr backend) { - std::unique_ptr frontend(new PPCFrontend(this)); +int XenonRuntime::Initialize(std::unique_ptr backend) { + auto frontend = std::make_unique(this); // TODO(benvanik): set options/etc. int result = Runtime::Initialize(std::move(frontend), std::move(backend)); diff --git a/src/xenia/cpu/xenon_thread_state.cc b/src/xenia/cpu/xenon_thread_state.cc index 0a4190573..e2abd64a1 100644 --- a/src/xenia/cpu/xenon_thread_state.cc +++ b/src/xenia/cpu/xenon_thread_state.cc @@ -24,7 +24,7 @@ XenonThreadState::XenonThreadState(XenonRuntime* runtime, uint32_t thread_id, : ThreadState(runtime, thread_id), stack_size_(stack_size), thread_state_address_(thread_state_address) { - stack_address_ = memory_->HeapAlloc(0, stack_size, MEMORY_FLAG_ZERO); + stack_address_ = xenon_memory()->HeapAlloc(0, stack_size, MEMORY_FLAG_ZERO); assert_not_zero(stack_address_); // Allocate with 64b alignment. @@ -56,7 +56,7 @@ XenonThreadState::~XenonThreadState() { runtime_->debugger()->OnThreadDestroyed(this); xe_free_aligned(context_); - memory_->HeapFree(stack_address_, stack_size_); + xenon_memory()->HeapFree(stack_address_, stack_size_); } void XenonThreadState::WriteRegisters(xdb::protocol::Registers* registers) { diff --git a/src/xenia/cpu/xenon_thread_state.h b/src/xenia/cpu/xenon_thread_state.h index 409d85a97..aedf39df0 100644 --- a/src/xenia/cpu/xenon_thread_state.h +++ b/src/xenia/cpu/xenon_thread_state.h @@ -27,13 +27,13 @@ class XenonRuntime; using PPCContext = alloy::frontend::ppc::PPCContext; - class XenonThreadState : public alloy::runtime::ThreadState { -public: - XenonThreadState(XenonRuntime* runtime, uint32_t thread_id, - size_t stack_size, uint64_t thread_state_address); + public: + XenonThreadState(XenonRuntime* runtime, uint32_t thread_id, size_t stack_size, + uint64_t thread_state_address); virtual ~XenonThreadState(); + Memory* xenon_memory() { return static_cast(memory_); } uint64_t stack_address() const { return stack_address_; } size_t stack_size() const { return stack_size_; } uint64_t thread_state_address() const { return thread_state_address_; } @@ -41,18 +41,16 @@ public: void WriteRegisters(xdb::protocol::Registers* registers); -private: - uint64_t stack_address_; - size_t stack_size_; - uint64_t thread_state_address_; + private: + uint64_t stack_address_; + size_t stack_size_; + uint64_t thread_state_address_; // NOTE: must be 64b aligned for SSE ops. PPCContext* context_; }; - } // namespace cpu } // namespace xe - #endif // XENIA_CPU_XENON_THREAD_STATE_H_ diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index ae6eeb75d..81467ad67 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -13,13 +13,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include namespace xe { @@ -87,7 +87,7 @@ X_STATUS Emulator::Setup() { XEEXPECTZERO(result); // Create memory system first, as it is required for other systems. - memory_ = new XenonMemory(); + memory_ = new Memory(); XEEXPECTNOTNULL(memory_); result = memory_->Initialize(); XEEXPECTZERO(result); diff --git a/src/xenia/emulator.h b/src/xenia/emulator.h index 77ffabd40..6da650108 100644 --- a/src/xenia/emulator.h +++ b/src/xenia/emulator.h @@ -14,7 +14,6 @@ #include #include -#include #include #include #include @@ -55,7 +54,7 @@ class Emulator { ui::Window* main_window() const { return main_window_; } void set_main_window(ui::Window* window); - cpu::XenonMemory* memory() const { return memory_; } + Memory* memory() const { return memory_; } DebugAgent* debug_agent() const { return debug_agent_.get(); } @@ -79,31 +78,29 @@ class Emulator { private: X_STATUS CompleteLaunch(const std::wstring& path, - const std::string& module_path); + const std::string& module_path); - std::wstring command_line_; + std::wstring command_line_; - ui::Window* main_window_; + ui::Window* main_window_; - cpu::XenonMemory* memory_; + Memory* memory_; std::unique_ptr debug_agent_; - cpu::Processor* processor_; - apu::AudioSystem* audio_system_; - gpu::GraphicsSystem* graphics_system_; - hid::InputSystem* input_system_; + cpu::Processor* processor_; + apu::AudioSystem* audio_system_; + gpu::GraphicsSystem* graphics_system_; + hid::InputSystem* input_system_; - ExportResolver* export_resolver_; + ExportResolver* export_resolver_; kernel::fs::FileSystem* file_system_; - kernel::KernelState* kernel_state_; - kernel::XamModule* xam_; + kernel::KernelState* kernel_state_; + kernel::XamModule* xam_; kernel::XboxkrnlModule* xboxkrnl_; }; - } // namespace xe - #endif // XENIA_EMULATOR_H_ diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index 8bef9479a..60c6086e3 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -152,7 +152,7 @@ X_STATUS XThread::Create() { // So, at offset 0x100 we have a 4b pointer to offset 200, then have the // structure. thread_state_address_ = - (uint32_t)memory()->HeapAlloc(0, 2048, alloy::MEMORY_FLAG_ZERO); + (uint32_t)memory()->HeapAlloc(0, 2048, MEMORY_FLAG_ZERO); if (!thread_state_address_) { XELOGW("Unable to allocate thread state block"); return X_STATUS_NO_MEMORY; @@ -167,13 +167,12 @@ X_STATUS XThread::Create() { // This is used by interrupts/APCs/etc so we can round-trip pointers through. scratch_size_ = 4 * 16; scratch_address_ = - (uint32_t)memory()->HeapAlloc(0, scratch_size_, alloy::MEMORY_FLAG_ZERO); + (uint32_t)memory()->HeapAlloc(0, scratch_size_, MEMORY_FLAG_ZERO); // Allocate TLS block. const xe_xex2_header_t* header = module->xex_header(); uint32_t tls_size = header->tls_info.slot_count * header->tls_info.data_size; - tls_address_ = - (uint32_t)memory()->HeapAlloc(0, tls_size, alloy::MEMORY_FLAG_ZERO); + tls_address_ = (uint32_t)memory()->HeapAlloc(0, tls_size, MEMORY_FLAG_ZERO); if (!tls_address_) { XELOGW("Unable to allocate thread local storage block"); module->Release(); diff --git a/src/xenia/kernel/util/xex2.cc b/src/xenia/kernel/util/xex2.cc index e9e8aeb31..1a7b48f41 100644 --- a/src/xenia/kernel/util/xex2.cc +++ b/src/xenia/kernel/util/xex2.cc @@ -21,14 +21,14 @@ #include #include -using namespace alloy; +// using namespace alloy; DEFINE_bool(xex_dev_key, false, "Use the devkit key."); typedef struct xe_xex2 { xe_ref_t ref; - Memory *memory; + xe::Memory *memory; xe_xex2_header_t header; @@ -44,13 +44,13 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, xe_xex2_header_t *header); int xe_xex2_decrypt_key(xe_xex2_header_t *header); int xe_xex2_read_image(xe_xex2_ref xex, const uint8_t *xex_addr, - const size_t xex_length, Memory *memory); + const size_t xex_length, xe::Memory *memory); int xe_xex2_load_pe(xe_xex2_ref xex); int xe_xex2_find_import_infos(xe_xex2_ref xex, const xe_xex2_import_library_t *library); -xe_xex2_ref xe_xex2_load(Memory *memory, const void *addr, const size_t length, - xe_xex2_options_t options) { +xe_xex2_ref xe_xex2_load(xe::Memory *memory, const void *addr, + const size_t length, xe_xex2_options_t options) { xe_xex2_ref xex = (xe_xex2_ref)xe_calloc(sizeof(xe_xex2)); xe_ref_init((xe_ref)xex); @@ -542,12 +542,13 @@ void xe_xex2_decrypt_buffer(const uint8_t *session_key, int xe_xex2_read_image_uncompressed(const xe_xex2_header_t *header, const uint8_t *xex_addr, - const size_t xex_length, Memory *memory) { + const size_t xex_length, + xe::Memory *memory) { // Allocate in-place the XEX memory. const size_t exe_length = xex_length - header->exe_offset; size_t uncompressed_size = exe_length; uint32_t alloc_result = (uint32_t)memory->HeapAlloc( - header->exe_address, uncompressed_size, MEMORY_FLAG_ZERO); + header->exe_address, uncompressed_size, xe::MEMORY_FLAG_ZERO); if (!alloc_result) { XELOGE("Unable to allocate XEX memory at %.8X-%.8X.", header->exe_address, uncompressed_size); @@ -575,7 +576,7 @@ int xe_xex2_read_image_uncompressed(const xe_xex2_header_t *header, int xe_xex2_read_image_basic_compressed(const xe_xex2_header_t *header, const uint8_t *xex_addr, const size_t xex_length, - Memory *memory) { + xe::Memory *memory) { const size_t exe_length = xex_length - header->exe_offset; const uint8_t *source_buffer = (const uint8_t *)xex_addr + header->exe_offset; const uint8_t *p = source_buffer; @@ -592,7 +593,7 @@ int xe_xex2_read_image_basic_compressed(const xe_xex2_header_t *header, // Allocate in-place the XEX memory. uint32_t alloc_result = (uint32_t)memory->HeapAlloc( - header->exe_address, uncompressed_size, MEMORY_FLAG_ZERO); + header->exe_address, uncompressed_size, xe::MEMORY_FLAG_ZERO); if (!alloc_result) { XELOGE("Unable to allocate XEX memory at %.8X-%.8X.", header->exe_address, uncompressed_size); @@ -645,7 +646,7 @@ XECLEANUP: int xe_xex2_read_image_compressed(const xe_xex2_header_t *header, const uint8_t *xex_addr, - const size_t xex_length, Memory *memory) { + const size_t xex_length, xe::Memory *memory) { const size_t exe_length = xex_length - header->exe_offset; const uint8_t *exe_buffer = (const uint8_t *)xex_addr + header->exe_offset; @@ -726,7 +727,7 @@ int xe_xex2_read_image_compressed(const xe_xex2_header_t *header, // Allocate in-place the XEX memory. uint32_t alloc_result = (uint32_t)memory->HeapAlloc( - header->exe_address, uncompressed_size, MEMORY_FLAG_ZERO); + header->exe_address, uncompressed_size, xe::MEMORY_FLAG_ZERO); if (!alloc_result) { XELOGE("Unable to allocate XEX memory at %.8X-%.8X.", header->exe_address, uncompressed_size); @@ -778,7 +779,7 @@ XECLEANUP: } int xe_xex2_read_image(xe_xex2_ref xex, const uint8_t *xex_addr, - const size_t xex_length, Memory *memory) { + const size_t xex_length, xe::Memory *memory) { const xe_xex2_header_t *header = &xex->header; switch (header->file_format_info.compression_type) { case XEX_COMPRESSION_NONE: diff --git a/src/xenia/kernel/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl_memory.cc index ffdc4c7b1..e3f80cd15 100644 --- a/src/xenia/kernel/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl_memory.cc @@ -158,7 +158,7 @@ SHIM_CALL NtQueryVirtualMemory_shim(PPCContext* ppc_state, KernelState* state) { XELOGD("NtQueryVirtualMemory(%.8X, %.8X)", base_address, memory_basic_information_ptr); - alloy::AllocationInfo mem_info; + AllocationInfo mem_info; size_t result = state->memory()->QueryInformation(base_address, &mem_info); if (!result) { SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER); @@ -250,7 +250,7 @@ SHIM_CALL MmAllocatePhysicalMemoryEx_shim(PPCContext* ppc_state, assert_true(max_addr_range == 0xFFFFFFFF); // Allocate. - uint32_t flags = alloy::MEMORY_FLAG_PHYSICAL; + uint32_t flags = MEMORY_FLAG_PHYSICAL; uint32_t base_address = (uint32_t)state->memory()->HeapAlloc( 0, adjusted_size, flags, adjusted_alignment); if (!base_address) { @@ -410,7 +410,7 @@ SHIM_CALL ExAllocatePoolTypeWithTag_shim(PPCContext* ppc_state, } uint32_t addr = (uint32_t)state->memory()->HeapAlloc( - 0, adjusted_size, alloy::MEMORY_FLAG_ZERO, alignment); + 0, adjusted_size, MEMORY_FLAG_ZERO, alignment); SHIM_SET_RETURN_32(addr); } diff --git a/src/xenia/cpu/xenon_memory.cc b/src/xenia/memory.cc similarity index 87% rename from src/xenia/cpu/xenon_memory.cc rename to src/xenia/memory.cc index 63f5cc6d7..596812317 100644 --- a/src/xenia/cpu/xenon_memory.cc +++ b/src/xenia/memory.cc @@ -7,16 +7,16 @@ ****************************************************************************** */ -#include +#include #include #include #include #include +#include -using namespace alloy; -using namespace xe::cpu; +using namespace xe; // TODO(benvanik): move xbox.h out #include @@ -84,10 +84,10 @@ DEFINE_bool(scribble_heap, false, #define XENON_MEMORY_VIRTUAL_HEAP_LOW 0x20000000 #define XENON_MEMORY_VIRTUAL_HEAP_HIGH 0x40000000 -class xe::cpu::XenonMemoryHeap { +class xe::MemoryHeap { public: - XenonMemoryHeap(XenonMemory* memory, bool is_physical); - ~XenonMemoryHeap(); + MemoryHeap(Memory* memory, bool is_physical); + ~MemoryHeap(); int Initialize(uint64_t low, uint64_t high); @@ -104,7 +104,7 @@ class xe::cpu::XenonMemoryHeap { void* context); private: - XenonMemory* memory_; + Memory* memory_; uint32_t heap_id_; bool is_physical_; std::mutex lock_; @@ -112,15 +112,15 @@ class xe::cpu::XenonMemoryHeap { uint8_t* ptr_; mspace space_; }; -uint32_t XenonMemoryHeap::next_heap_id_ = 1; +uint32_t MemoryHeap::next_heap_id_ = 1; -XenonMemory::XenonMemory() - : Memory(), mapping_(0), mapping_base_(0), page_table_(0) { - virtual_heap_ = new XenonMemoryHeap(this, false); - physical_heap_ = new XenonMemoryHeap(this, true); +Memory::Memory() + : alloy::Memory(), mapping_(0), mapping_base_(0), page_table_(0) { + virtual_heap_ = new MemoryHeap(this, false); + physical_heap_ = new MemoryHeap(this, true); } -XenonMemory::~XenonMemory() { +Memory::~Memory() { // Uninstall the MMIO handler, as we won't be able to service more // requests. mmio_handler_.reset(); @@ -142,8 +142,8 @@ XenonMemory::~XenonMemory() { } } -int XenonMemory::Initialize() { - int result = Memory::Initialize(); +int Memory::Initialize() { + int result = alloy::Memory::Initialize(); if (result) { return result; } @@ -196,7 +196,7 @@ int XenonMemory::Initialize() { VirtualAlloc(Translate(0xC0000000), 0x00100000, MEM_COMMIT, PAGE_READWRITE); // Add handlers for MMIO. - mmio_handler_ = MMIOHandler::Install(mapping_base_); + mmio_handler_ = cpu::MMIOHandler::Install(mapping_base_); if (!mmio_handler_) { XELOGE("Unable to install MMIO handlers"); assert_always(); @@ -227,7 +227,7 @@ const static struct { 0xC0000000, 0xDFFFFFFF, 0x00000000, // - physical 16mb pages 0xE0000000, 0xFFFFFFFF, 0x00000000, // - physical 4k pages }; -int XenonMemory::MapViews(uint8_t* mapping_base) { +int Memory::MapViews(uint8_t* mapping_base) { assert_true(poly::countof(map_info) == poly::countof(views_.all_views)); for (size_t n = 0; n < poly::countof(map_info); n++) { #if XE_PLATFORM_WIN32 @@ -252,7 +252,7 @@ XECLEANUP: return 1; } -void XenonMemory::UnmapViews() { +void Memory::UnmapViews() { for (size_t n = 0; n < poly::countof(views_.all_views); n++) { if (views_.all_views[n]) { #if XE_PLATFORM_WIN32 @@ -266,9 +266,9 @@ void XenonMemory::UnmapViews() { } } -bool XenonMemory::AddMappedRange(uint64_t address, uint64_t mask, uint64_t size, - void* context, MMIOReadCallback read_callback, - MMIOWriteCallback write_callback) { +bool Memory::AddMappedRange(uint64_t address, uint64_t mask, uint64_t size, + void* context, cpu::MMIOReadCallback read_callback, + cpu::MMIOWriteCallback write_callback) { DWORD protect = PAGE_NOACCESS; if (!VirtualAlloc(Translate(address), size, MEM_COMMIT, protect)) { XELOGE("Unable to map range; commit/protect failed"); @@ -278,7 +278,7 @@ bool XenonMemory::AddMappedRange(uint64_t address, uint64_t mask, uint64_t size, read_callback, write_callback); } -uint8_t XenonMemory::LoadI8(uint64_t address) { +uint8_t Memory::LoadI8(uint64_t address) { uint64_t value; if (!mmio_handler_->CheckLoad(address, &value)) { value = *reinterpret_cast(Translate(address)); @@ -286,7 +286,7 @@ uint8_t XenonMemory::LoadI8(uint64_t address) { return static_cast(value); } -uint16_t XenonMemory::LoadI16(uint64_t address) { +uint16_t Memory::LoadI16(uint64_t address) { uint64_t value; if (!mmio_handler_->CheckLoad(address, &value)) { value = *reinterpret_cast(Translate(address)); @@ -294,7 +294,7 @@ uint16_t XenonMemory::LoadI16(uint64_t address) { return static_cast(value); } -uint32_t XenonMemory::LoadI32(uint64_t address) { +uint32_t Memory::LoadI32(uint64_t address) { uint64_t value; if (!mmio_handler_->CheckLoad(address, &value)) { value = *reinterpret_cast(Translate(address)); @@ -302,7 +302,7 @@ uint32_t XenonMemory::LoadI32(uint64_t address) { return static_cast(value); } -uint64_t XenonMemory::LoadI64(uint64_t address) { +uint64_t Memory::LoadI64(uint64_t address) { uint64_t value; if (!mmio_handler_->CheckLoad(address, &value)) { value = *reinterpret_cast(Translate(address)); @@ -310,32 +310,32 @@ uint64_t XenonMemory::LoadI64(uint64_t address) { return static_cast(value); } -void XenonMemory::StoreI8(uint64_t address, uint8_t value) { +void Memory::StoreI8(uint64_t address, uint8_t value) { if (!mmio_handler_->CheckStore(address, value)) { *reinterpret_cast(Translate(address)) = value; } } -void XenonMemory::StoreI16(uint64_t address, uint16_t value) { +void Memory::StoreI16(uint64_t address, uint16_t value) { if (!mmio_handler_->CheckStore(address, value)) { *reinterpret_cast(Translate(address)) = value; } } -void XenonMemory::StoreI32(uint64_t address, uint32_t value) { +void Memory::StoreI32(uint64_t address, uint32_t value) { if (!mmio_handler_->CheckStore(address, value)) { *reinterpret_cast(Translate(address)) = value; } } -void XenonMemory::StoreI64(uint64_t address, uint64_t value) { +void Memory::StoreI64(uint64_t address, uint64_t value) { if (!mmio_handler_->CheckStore(address, value)) { *reinterpret_cast(Translate(address)) = value; } } -uint64_t XenonMemory::HeapAlloc(uint64_t base_address, size_t size, - uint32_t flags, uint32_t alignment) { +uint64_t Memory::HeapAlloc(uint64_t base_address, size_t size, uint32_t flags, + uint32_t alignment) { // If we were given a base address we are outside of the normal heap and // will place wherever asked (so long as it doesn't overlap the heap). if (!base_address) { @@ -384,7 +384,7 @@ uint64_t XenonMemory::HeapAlloc(uint64_t base_address, size_t size, } } -int XenonMemory::HeapFree(uint64_t address, size_t size) { +int Memory::HeapFree(uint64_t address, size_t size) { if (address >= XENON_MEMORY_VIRTUAL_HEAP_LOW && address < XENON_MEMORY_VIRTUAL_HEAP_HIGH) { return virtual_heap_->Free(address, size) ? 0 : 1; @@ -398,8 +398,7 @@ int XenonMemory::HeapFree(uint64_t address, size_t size) { } } -bool XenonMemory::QueryInformation(uint64_t base_address, - AllocationInfo* mem_info) { +bool Memory::QueryInformation(uint64_t base_address, AllocationInfo* mem_info) { uint8_t* p = Translate(base_address); MEMORY_BASIC_INFORMATION mbi; if (!VirtualQuery(p, &mbi, sizeof(mbi))) { @@ -416,7 +415,7 @@ bool XenonMemory::QueryInformation(uint64_t base_address, return true; } -size_t XenonMemory::QuerySize(uint64_t base_address) { +size_t Memory::QuerySize(uint64_t base_address) { if (base_address >= XENON_MEMORY_VIRTUAL_HEAP_LOW && base_address < XENON_MEMORY_VIRTUAL_HEAP_HIGH) { return virtual_heap_->QuerySize(base_address); @@ -436,7 +435,7 @@ size_t XenonMemory::QuerySize(uint64_t base_address) { } } -int XenonMemory::Protect(uint64_t address, size_t size, uint32_t access) { +int Memory::Protect(uint64_t address, size_t size, uint32_t access) { uint8_t* p = Translate(address); size_t heap_guard_size = FLAGS_heap_guard_pages * 4096; @@ -452,7 +451,7 @@ int XenonMemory::Protect(uint64_t address, size_t size, uint32_t access) { return VirtualProtect(p, size, new_protect, &old_protect) == TRUE ? 0 : 1; } -uint32_t XenonMemory::QueryProtect(uint64_t address) { +uint32_t Memory::QueryProtect(uint64_t address) { uint8_t* p = Translate(address); MEMORY_BASIC_INFORMATION info; size_t info_size = VirtualQuery((void*)p, &info, sizeof(info)); @@ -462,12 +461,12 @@ uint32_t XenonMemory::QueryProtect(uint64_t address) { return info.Protect; } -XenonMemoryHeap::XenonMemoryHeap(XenonMemory* memory, bool is_physical) +MemoryHeap::MemoryHeap(Memory* memory, bool is_physical) : memory_(memory), is_physical_(is_physical) { heap_id_ = next_heap_id_++; } -XenonMemoryHeap::~XenonMemoryHeap() { +MemoryHeap::~MemoryHeap() { if (space_) { std::lock_guard guard(lock_); destroy_mspace(space_); @@ -479,7 +478,7 @@ XenonMemoryHeap::~XenonMemoryHeap() { } } -int XenonMemoryHeap::Initialize(uint64_t low, uint64_t high) { +int MemoryHeap::Initialize(uint64_t low, uint64_t high) { // Commit the memory where our heap will live and allocate it. // TODO(benvanik): replace dlmalloc with an implementation that can commit // as it goes. @@ -494,8 +493,8 @@ int XenonMemoryHeap::Initialize(uint64_t low, uint64_t high) { return 0; } -uint64_t XenonMemoryHeap::Alloc(uint64_t base_address, size_t size, - uint32_t flags, uint32_t alignment) { +uint64_t MemoryHeap::Alloc(uint64_t base_address, size_t size, uint32_t flags, + uint32_t alignment) { lock_.lock(); size_t alloc_size = size; size_t heap_guard_size = FLAGS_heap_guard_pages * 4096; @@ -547,7 +546,7 @@ uint64_t XenonMemoryHeap::Alloc(uint64_t base_address, size_t size, return address; } -uint64_t XenonMemoryHeap::Free(uint64_t address, size_t size) { +uint64_t MemoryHeap::Free(uint64_t address, size_t size) { uint8_t* p = memory_->Translate(address); // Heap allocated address. @@ -590,7 +589,7 @@ uint64_t XenonMemoryHeap::Free(uint64_t address, size_t size) { return (uint64_t)real_size; } -size_t XenonMemoryHeap::QuerySize(uint64_t base_address) { +size_t MemoryHeap::QuerySize(uint64_t base_address) { uint8_t* p = memory_->Translate(base_address); // Heap allocated address. @@ -605,8 +604,8 @@ size_t XenonMemoryHeap::QuerySize(uint64_t base_address) { return real_size; } -void XenonMemoryHeap::Dump() { - XELOGI("XenonMemoryHeap::Dump - %s", is_physical_ ? "physical" : "virtual"); +void MemoryHeap::Dump() { + XELOGI("MemoryHeap::Dump - %s", is_physical_ ? "physical" : "virtual"); if (FLAGS_heap_guard_pages) { XELOGI(" (heap guard pages enabled, stats will be wrong)"); } @@ -622,10 +621,10 @@ void XenonMemoryHeap::Dump() { mspace_inspect_all(space_, DumpHandler, this); } -void XenonMemoryHeap::DumpHandler(void* start, void* end, size_t used_bytes, - void* context) { - XenonMemoryHeap* heap = (XenonMemoryHeap*)context; - XenonMemory* memory = heap->memory_; +void MemoryHeap::DumpHandler(void* start, void* end, size_t used_bytes, + void* context) { + MemoryHeap* heap = (MemoryHeap*)context; + Memory* memory = heap->memory_; size_t heap_guard_size = FLAGS_heap_guard_pages * 4096; uint64_t start_addr = (uint64_t)start + heap_guard_size; uint64_t end_addr = (uint64_t)end - heap_guard_size; diff --git a/src/xenia/cpu/xenon_memory.h b/src/xenia/memory.h similarity index 57% rename from src/xenia/cpu/xenon_memory.h rename to src/xenia/memory.h index f1dfe331f..91c87c6a9 100644 --- a/src/xenia/cpu/xenon_memory.h +++ b/src/xenia/memory.h @@ -7,8 +7,8 @@ ****************************************************************************** */ -#ifndef XENIA_CPU_XENON_MEMORY_H_ -#define XENIA_CPU_XENON_MEMORY_H_ +#ifndef XENIA_MEMORY_H_ +#define XENIA_MEMORY_H_ #include @@ -20,22 +20,41 @@ typedef struct xe_ppc_state xe_ppc_state_t; namespace xe { -namespace cpu { -class XenonMemoryHeap; +class MemoryHeap; -class XenonMemory : public alloy::Memory { +// TODO(benvanik): move to heap. +enum { + MEMORY_FLAG_64KB_PAGES = (1 << 1), + MEMORY_FLAG_ZERO = (1 << 2), + MEMORY_FLAG_PHYSICAL = (1 << 3), +}; + +// TODO(benvanik): move to heap. +// Equivalent to the Win32 MEMORY_BASIC_INFORMATION struct. +struct AllocationInfo { + uint64_t base_address; + uint64_t allocation_base; + uint32_t allocation_protect; // TBD + size_t region_size; + uint32_t state; // TBD + uint32_t protect; // TBD + uint32_t type; // TBD +}; + +class Memory : public alloy::Memory { public: - XenonMemory(); - virtual ~XenonMemory(); + Memory(); + ~Memory() override; int Initialize() override; + // TODO(benvanik): remove with GPU refactor. uint64_t page_table() const override { return page_table_; } bool AddMappedRange(uint64_t address, uint64_t mask, uint64_t size, - void* context, MMIOReadCallback read_callback, - MMIOWriteCallback write_callback); + void* context, cpu::MMIOReadCallback read_callback, + cpu::MMIOWriteCallback write_callback); uint8_t LoadI8(uint64_t address) override; uint16_t LoadI16(uint64_t address) override; @@ -47,15 +66,14 @@ class XenonMemory : public alloy::Memory { void StoreI64(uint64_t address, uint64_t value) override; uint64_t HeapAlloc(uint64_t base_address, size_t size, uint32_t flags, - uint32_t alignment = 0x20) override; - int HeapFree(uint64_t address, size_t size) override; + uint32_t alignment = 0x20); + int HeapFree(uint64_t address, size_t size); - bool QueryInformation(uint64_t base_address, - alloy::AllocationInfo* mem_info) override; - size_t QuerySize(uint64_t base_address) override; + bool QueryInformation(uint64_t base_address, AllocationInfo* mem_info); + size_t QuerySize(uint64_t base_address); - int Protect(uint64_t address, size_t size, uint32_t access) override; - uint32_t QueryProtect(uint64_t address) override; + int Protect(uint64_t address, size_t size, uint32_t access); + uint32_t QueryProtect(uint64_t address); private: int MapViews(uint8_t* mapping_base); @@ -76,17 +94,16 @@ class XenonMemory : public alloy::Memory { uint8_t* all_views[6]; } views_; - std::unique_ptr mmio_handler_; + std::unique_ptr mmio_handler_; - XenonMemoryHeap* virtual_heap_; - XenonMemoryHeap* physical_heap_; + MemoryHeap* virtual_heap_; + MemoryHeap* physical_heap_; uint64_t page_table_; - friend class XenonMemoryHeap; + friend class MemoryHeap; }; -} // namespace cpu } // namespace xe -#endif // XENIA_CPU_XENON_MEMORY_H_ +#endif // XENIA_MEMORY_H_ diff --git a/src/xenia/sources.gypi b/src/xenia/sources.gypi index cec755d15..26c0a909d 100644 --- a/src/xenia/sources.gypi +++ b/src/xenia/sources.gypi @@ -13,6 +13,8 @@ 'logging.h', 'malloc.cc', 'malloc.h', + 'memory.cc', + 'memory.h', 'profiling.cc', 'profiling.h', 'types.h', diff --git a/tools/alloy-sandbox/alloy-sandbox.cc b/tools/alloy-sandbox/alloy-sandbox.cc index 508ede3c9..393a1c6ac 100644 --- a/tools/alloy-sandbox/alloy-sandbox.cc +++ b/tools/alloy-sandbox/alloy-sandbox.cc @@ -15,7 +15,6 @@ #include #include #include -#include #include @@ -28,11 +27,12 @@ using alloy::runtime::Runtime; class ThreadState : public alloy::runtime::ThreadState { public: ThreadState(Runtime* runtime, uint32_t thread_id, size_t stack_size, - uint64_t thread_state_address) + uint64_t thread_state_address, uint64_t thread_stack_address) : alloy::runtime::ThreadState(runtime, thread_id), + stack_address_(thread_stack_address), stack_size_(stack_size), thread_state_address_(thread_state_address) { - stack_address_ = memory_->HeapAlloc(0, stack_size, MEMORY_FLAG_ZERO); + memset(memory_->Translate(stack_address_), 0, stack_size_); // Allocate with 64b alignment. context_ = (PPCContext*)xe_malloc_aligned(sizeof(PPCContext)); @@ -60,7 +60,6 @@ class ThreadState : public alloy::runtime::ThreadState { ~ThreadState() override { runtime_->debugger()->OnThreadDestroyed(this); xe_free_aligned(context_); - memory_->HeapFree(stack_address_, stack_size_); } PPCContext* context() const { return context_; } @@ -80,7 +79,8 @@ int main(std::vector& args) { xe::Profiler::Initialize(); xe::Profiler::ThreadEnter("main"); - auto memory = std::make_unique(); + size_t memory_size = 16 * 1024 * 1024; + auto memory = std::make_unique(memory_size); auto runtime = std::make_unique(memory.get()); auto frontend = @@ -97,11 +97,14 @@ int main(std::vector& args) { runtime->AddModule(std::move(module)); { - auto thread_state = - std::make_unique(runtime.get(), 100, 64 * 1024, 0); + uint64_t thread_state_address = 0; + uint64_t stack_address = memory_size - 1024; + uint64_t stack_size = 64 * 1024; + auto thread_state = std::make_unique( + runtime.get(), 100, stack_address, stack_size, thread_state_address); alloy::runtime::Function* fn; - runtime->ResolveFunction(0x82000000, &fn); + runtime->ResolveFunction(0x1000, &fn); auto ctx = thread_state->context(); ctx->lr = 0xBEBEBEBE; ctx->r[5] = 10; From fb98683ed34cdb94a866d82213209458812bb85a Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 19 Aug 2014 22:50:21 -0700 Subject: [PATCH 139/388] Converting HID API to use be<> auto swapping type. --- src/poly/byte_order.h | 2 + src/poly/memory.h | 13 ++ src/xenia/hid/input_driver.cc | 15 +- src/xenia/hid/input_driver.h | 24 +-- src/xenia/hid/input_system.cc | 37 ++-- src/xenia/hid/input_system.h | 25 +-- src/xenia/hid/nop/nop_hid-private.h | 7 +- src/xenia/hid/nop/nop_hid.cc | 38 ++-- src/xenia/hid/nop/nop_hid.h | 5 - src/xenia/hid/nop/nop_input_driver.cc | 40 ++-- src/xenia/hid/nop/nop_input_driver.h | 27 +-- src/xenia/hid/winkey/winkey_hid-private.h | 7 +- src/xenia/hid/winkey/winkey_hid.cc | 38 ++-- src/xenia/hid/winkey/winkey_hid.h | 5 - src/xenia/hid/winkey/winkey_input_driver.cc | 111 +++++----- src/xenia/hid/winkey/winkey_input_driver.h | 27 +-- src/xenia/hid/xinput/xinput_hid-private.h | 7 +- src/xenia/hid/xinput/xinput_hid.cc | 38 ++-- src/xenia/hid/xinput/xinput_hid.h | 5 - src/xenia/hid/xinput/xinput_input_driver.cc | 95 ++++----- src/xenia/hid/xinput/xinput_input_driver.h | 27 +-- src/xenia/kernel/util/shim_utils.h | 2 + src/xenia/kernel/xam_input.cc | 24 +-- src/xenia/xbox.h | 224 +++++--------------- 24 files changed, 325 insertions(+), 518 deletions(-) diff --git a/src/poly/byte_order.h b/src/poly/byte_order.h index ab6e4d0e4..8cb478a92 100644 --- a/src/poly/byte_order.h +++ b/src/poly/byte_order.h @@ -35,6 +35,8 @@ namespace poly { #define POLY_BYTE_SWAP_64 __bswap_64 #endif // XE_COMPILER_MSVC +inline int8_t byte_swap(int8_t value) { return value; } +inline uint8_t byte_swap(uint8_t value) { return value; } inline int16_t byte_swap(int16_t value) { return static_cast(POLY_BYTE_SWAP_16(static_cast(value))); } diff --git a/src/poly/memory.h b/src/poly/memory.h index e4d24a3f9..78336867a 100644 --- a/src/poly/memory.h +++ b/src/poly/memory.h @@ -245,6 +245,19 @@ inline void store_and_swap(void* mem, double value) { *reinterpret_cast(mem) = byte_swap(value); } +template +struct be { + be() = default; + be(const T& src) : value(poly::byte_swap(src)) {} + be(const be& other) { + value = other.value; + } + operator T() const { + return poly::byte_swap(value); + } + T value; +}; + } // namespace poly #endif // POLY_MEMORY_H_ diff --git a/src/xenia/hid/input_driver.cc b/src/xenia/hid/input_driver.cc index fb6474c6f..a7017b03b 100644 --- a/src/xenia/hid/input_driver.cc +++ b/src/xenia/hid/input_driver.cc @@ -9,14 +9,13 @@ #include +namespace xe { +namespace hid { -using namespace xe; -using namespace xe::hid; +InputDriver::InputDriver(InputSystem* input_system) + : input_system_(input_system) {} +InputDriver::~InputDriver() = default; -InputDriver::InputDriver(InputSystem* input_system) : - input_system_(input_system) { -} - -InputDriver::~InputDriver() { -} +} // namespace hid +} // namespace xe diff --git a/src/xenia/hid/input_driver.h b/src/xenia/hid/input_driver.h index e2b04daff..db8cb3725 100644 --- a/src/xenia/hid/input_driver.h +++ b/src/xenia/hid/input_driver.h @@ -13,38 +13,32 @@ #include #include - namespace xe { namespace hid { class InputSystem; - class InputDriver { -public: + public: virtual ~InputDriver(); virtual X_STATUS Setup() = 0; - virtual X_RESULT GetCapabilities( - uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps) = 0; - virtual X_RESULT GetState( - uint32_t user_index, X_INPUT_STATE& out_state) = 0; - virtual X_RESULT SetState( - uint32_t user_index, X_INPUT_VIBRATION& vibration) = 0; - virtual X_RESULT GetKeystroke( - uint32_t user_index, uint32_t flags, - X_INPUT_KEYSTROKE& out_keystroke) = 0; + virtual X_RESULT GetCapabilities(uint32_t user_index, uint32_t flags, + X_INPUT_CAPABILITIES* out_caps) = 0; + virtual X_RESULT GetState(uint32_t user_index, X_INPUT_STATE* out_state) = 0; + virtual X_RESULT SetState(uint32_t user_index, + X_INPUT_VIBRATION* vibration) = 0; + virtual X_RESULT GetKeystroke(uint32_t user_index, uint32_t flags, + X_INPUT_KEYSTROKE* out_keystroke) = 0; -protected: + protected: InputDriver(InputSystem* input_system); InputSystem* input_system_; }; - } // namespace hid } // namespace xe - #endif // XENIA_HID_INPUT_DRIVER_H_ diff --git a/src/xenia/hid/input_system.cc b/src/xenia/hid/input_system.cc index 6ad1ab177..1813e181e 100644 --- a/src/xenia/hid/input_system.cc +++ b/src/xenia/hid/input_system.cc @@ -13,18 +13,14 @@ #include #include +namespace xe { +namespace hid { -using namespace xe; -using namespace xe::hid; - - -InputSystem::InputSystem(Emulator* emulator) : - emulator_(emulator), memory_(emulator->memory()) { -} +InputSystem::InputSystem(Emulator* emulator) + : emulator_(emulator), memory_(emulator->memory()) {} InputSystem::~InputSystem() { - for (auto it = drivers_.begin(); - it != drivers_.end(); ++it) { + for (auto it = drivers_.begin(); it != drivers_.end(); ++it) { InputDriver* driver = *it; delete driver; } @@ -36,12 +32,10 @@ X_STATUS InputSystem::Setup() { return X_STATUS_SUCCESS; } -void InputSystem::AddDriver(InputDriver* driver) { - drivers_.push_back(driver); -} +void InputSystem::AddDriver(InputDriver* driver) { drivers_.push_back(driver); } -X_RESULT InputSystem::GetCapabilities( - uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps) { +X_RESULT InputSystem::GetCapabilities(uint32_t user_index, uint32_t flags, + X_INPUT_CAPABILITIES* out_caps) { SCOPE_profile_cpu_f("hid"); for (auto it = drivers_.begin(); it != drivers_.end(); ++it) { @@ -53,7 +47,7 @@ X_RESULT InputSystem::GetCapabilities( return X_ERROR_DEVICE_NOT_CONNECTED; } -X_RESULT InputSystem::GetState(uint32_t user_index, X_INPUT_STATE& out_state) { +X_RESULT InputSystem::GetState(uint32_t user_index, X_INPUT_STATE* out_state) { SCOPE_profile_cpu_f("hid"); for (auto it = drivers_.begin(); it != drivers_.end(); ++it) { @@ -65,8 +59,8 @@ X_RESULT InputSystem::GetState(uint32_t user_index, X_INPUT_STATE& out_state) { return X_ERROR_DEVICE_NOT_CONNECTED; } -X_RESULT InputSystem::SetState( - uint32_t user_index, X_INPUT_VIBRATION& vibration) { +X_RESULT InputSystem::SetState(uint32_t user_index, + X_INPUT_VIBRATION* vibration) { SCOPE_profile_cpu_f("hid"); for (auto it = drivers_.begin(); it != drivers_.end(); ++it) { @@ -78,8 +72,8 @@ X_RESULT InputSystem::SetState( return X_ERROR_DEVICE_NOT_CONNECTED; } -X_RESULT InputSystem::GetKeystroke( - uint32_t user_index, uint32_t flags, X_INPUT_KEYSTROKE& out_keystroke) { +X_RESULT InputSystem::GetKeystroke(uint32_t user_index, uint32_t flags, + X_INPUT_KEYSTROKE* out_keystroke) { SCOPE_profile_cpu_f("hid"); for (auto it = drivers_.begin(); it != drivers_.end(); ++it) { @@ -89,4 +83,7 @@ X_RESULT InputSystem::GetKeystroke( } } return X_ERROR_DEVICE_NOT_CONNECTED; -} \ No newline at end of file +} + +} // namespace hid +} // namespace xe diff --git a/src/xenia/hid/input_system.h b/src/xenia/hid/input_system.h index cb8d33019..f9f996469 100644 --- a/src/xenia/hid/input_system.h +++ b/src/xenia/hid/input_system.h @@ -15,19 +15,16 @@ #include #include - XEDECLARECLASS1(xe, Emulator); XEDECLARECLASS2(xe, cpu, Processor); - namespace xe { namespace hid { class InputDriver; - class InputSystem { -public: + public: InputSystem(Emulator* emulator); ~InputSystem(); @@ -39,24 +36,22 @@ public: void AddDriver(InputDriver* driver); - X_RESULT GetCapabilities( - uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps); - X_RESULT GetState(uint32_t user_index, X_INPUT_STATE& out_state); - X_RESULT SetState(uint32_t user_index, X_INPUT_VIBRATION& vibration); + X_RESULT GetCapabilities(uint32_t user_index, uint32_t flags, + X_INPUT_CAPABILITIES* out_caps); + X_RESULT GetState(uint32_t user_index, X_INPUT_STATE* out_state); + X_RESULT SetState(uint32_t user_index, X_INPUT_VIBRATION* vibration); X_RESULT GetKeystroke(uint32_t user_index, uint32_t flags, - X_INPUT_KEYSTROKE& out_keystroke); + X_INPUT_KEYSTROKE* out_keystroke); -private: - Emulator* emulator_; - Memory* memory_; - cpu::Processor* processor_; + private: + Emulator* emulator_; + Memory* memory_; + cpu::Processor* processor_; std::vector drivers_; }; - } // namespace hid } // namespace xe - #endif // XENIA_HID_INPUT_SYSTEM_H_ diff --git a/src/xenia/hid/nop/nop_hid-private.h b/src/xenia/hid/nop/nop_hid-private.h index 4fbb1b662..29bd21ebb 100644 --- a/src/xenia/hid/nop/nop_hid-private.h +++ b/src/xenia/hid/nop/nop_hid-private.h @@ -11,21 +11,16 @@ #define XENIA_HID_NOP_NOP_HID_PRIVATE_H_ #include - #include - namespace xe { namespace hid { namespace nop { - - - +// } // namespace nop } // namespace hid } // namespace xe - #endif // XENIA_HID_NOP_NOP_HID_PRIVATE_H_ diff --git a/src/xenia/hid/nop/nop_hid.cc b/src/xenia/hid/nop/nop_hid.cc index 1d17c23e5..520147285 100644 --- a/src/xenia/hid/nop/nop_hid.cc +++ b/src/xenia/hid/nop/nop_hid.cc @@ -11,34 +11,32 @@ #include +namespace xe { +namespace hid { +namespace nop { -using namespace xe; -using namespace xe::hid; -using namespace xe::hid::nop; +void InitializeIfNeeded(); +void CleanupOnShutdown(); - -namespace { - void InitializeIfNeeded(); - void CleanupOnShutdown(); - - void InitializeIfNeeded() { - static bool has_initialized = false; - if (has_initialized) { - return; - } - has_initialized = true; - - // - - atexit(CleanupOnShutdown); +void InitializeIfNeeded() { + static bool has_initialized = false; + if (has_initialized) { + return; } + has_initialized = true; - void CleanupOnShutdown() { - } + // + + atexit(CleanupOnShutdown); } +void CleanupOnShutdown() {} InputDriver* xe::hid::nop::Create(InputSystem* input_system) { InitializeIfNeeded(); return new NopInputDriver(input_system); } + +} // namespace nop +} // namespace hid +} // namespace xe diff --git a/src/xenia/hid/nop/nop_hid.h b/src/xenia/hid/nop/nop_hid.h index 79b461566..63fd1f3ac 100644 --- a/src/xenia/hid/nop/nop_hid.h +++ b/src/xenia/hid/nop/nop_hid.h @@ -12,22 +12,17 @@ #include - XEDECLARECLASS2(xe, hid, InputDriver); XEDECLARECLASS2(xe, hid, InputSystem); - namespace xe { namespace hid { namespace nop { - InputDriver* Create(InputSystem* input_system); - } // namespace nop } // namespace hid } // namespace xe - #endif // XENIA_HID_NOP_NOP_HID_H_ diff --git a/src/xenia/hid/nop/nop_input_driver.cc b/src/xenia/hid/nop/nop_input_driver.cc index d6a75c7fe..459391c77 100644 --- a/src/xenia/hid/nop/nop_input_driver.cc +++ b/src/xenia/hid/nop/nop_input_driver.cc @@ -11,42 +11,40 @@ #include +namespace xe { +namespace hid { +namespace nop { -using namespace xe; -using namespace xe::hid; -using namespace xe::hid::nop; +NopInputDriver::NopInputDriver(InputSystem* input_system) + : InputDriver(input_system) {} +NopInputDriver::~NopInputDriver() {} -NopInputDriver::NopInputDriver(InputSystem* input_system) : - InputDriver(input_system) { -} - -NopInputDriver::~NopInputDriver() { -} - -X_STATUS NopInputDriver::Setup() { - return X_STATUS_SUCCESS; -} +X_STATUS NopInputDriver::Setup() { return X_STATUS_SUCCESS; } // TODO(benvanik): spoof a device so that games don't stop waiting for // a controller to be plugged in. -X_RESULT NopInputDriver::GetCapabilities( - uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps) { +X_RESULT NopInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags, + X_INPUT_CAPABILITIES* out_caps) { return X_ERROR_DEVICE_NOT_CONNECTED; } -X_RESULT NopInputDriver::GetState( - uint32_t user_index, X_INPUT_STATE& out_state) { +X_RESULT NopInputDriver::GetState(uint32_t user_index, + X_INPUT_STATE* out_state) { return X_ERROR_DEVICE_NOT_CONNECTED; } -X_RESULT NopInputDriver::SetState( - uint32_t user_index, X_INPUT_VIBRATION& vibration) { +X_RESULT NopInputDriver::SetState(uint32_t user_index, + X_INPUT_VIBRATION* vibration) { return X_ERROR_DEVICE_NOT_CONNECTED; } -X_RESULT NopInputDriver::GetKeystroke( - uint32_t user_index, uint32_t flags, X_INPUT_KEYSTROKE& out_keystroke) { +X_RESULT NopInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags, + X_INPUT_KEYSTROKE* out_keystroke) { return X_ERROR_DEVICE_NOT_CONNECTED; } + +} // namespace nop +} // namespace hid +} // namespace xe diff --git a/src/xenia/hid/nop/nop_input_driver.h b/src/xenia/hid/nop/nop_input_driver.h index 58a205ec5..6faca0c0a 100644 --- a/src/xenia/hid/nop/nop_input_driver.h +++ b/src/xenia/hid/nop/nop_input_driver.h @@ -11,39 +11,30 @@ #define XENIA_HID_NOP_NOP_INPUT_DRIVER_H_ #include - #include #include - namespace xe { namespace hid { namespace nop { - class NopInputDriver : public InputDriver { -public: + public: NopInputDriver(InputSystem* input_system); - virtual ~NopInputDriver(); + ~NopInputDriver() override; - virtual X_STATUS Setup(); + X_STATUS Setup() override; - virtual X_RESULT GetCapabilities( - uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps); - virtual X_RESULT GetState( - uint32_t user_index, X_INPUT_STATE& out_state); - virtual X_RESULT SetState( - uint32_t user_index, X_INPUT_VIBRATION& vibration); - virtual X_RESULT GetKeystroke( - uint32_t user_index, uint32_t flags, X_INPUT_KEYSTROKE& out_keystroke); - -protected: + X_RESULT GetCapabilities(uint32_t user_index, uint32_t flags, + X_INPUT_CAPABILITIES* out_caps) override; + X_RESULT GetState(uint32_t user_index, X_INPUT_STATE* out_state) override; + X_RESULT SetState(uint32_t user_index, X_INPUT_VIBRATION* vibration) override; + X_RESULT GetKeystroke(uint32_t user_index, uint32_t flags, + X_INPUT_KEYSTROKE* out_keystroke) override; }; - } // namespace nop } // namespace hid } // namespace xe - #endif // XENIA_HID_NOP_NOP_INPUT_DRIVER_H_ diff --git a/src/xenia/hid/winkey/winkey_hid-private.h b/src/xenia/hid/winkey/winkey_hid-private.h index 2100f9185..8272462b5 100644 --- a/src/xenia/hid/winkey/winkey_hid-private.h +++ b/src/xenia/hid/winkey/winkey_hid-private.h @@ -11,21 +11,16 @@ #define XENIA_HID_WINKEY_WINKEY_HID_PRIVATE_H_ #include - #include - namespace xe { namespace hid { namespace winkey { - - - +// } // namespace winkey } // namespace hid } // namespace xe - #endif // XENIA_HID_WINKEY_WINKEY_HID_PRIVATE_H_ diff --git a/src/xenia/hid/winkey/winkey_hid.cc b/src/xenia/hid/winkey/winkey_hid.cc index 43d363271..f0fc06663 100644 --- a/src/xenia/hid/winkey/winkey_hid.cc +++ b/src/xenia/hid/winkey/winkey_hid.cc @@ -11,34 +11,32 @@ #include +namespace xe { +namespace hid { +namespace winkey { -using namespace xe; -using namespace xe::hid; -using namespace xe::hid::winkey; +void InitializeIfNeeded(); +void CleanupOnShutdown(); - -namespace { - void InitializeIfNeeded(); - void CleanupOnShutdown(); - - void InitializeIfNeeded() { - static bool has_initialized = false; - if (has_initialized) { - return; - } - has_initialized = true; - - // - - atexit(CleanupOnShutdown); +void InitializeIfNeeded() { + static bool has_initialized = false; + if (has_initialized) { + return; } + has_initialized = true; - void CleanupOnShutdown() { - } + // + + atexit(CleanupOnShutdown); } +void CleanupOnShutdown() {} InputDriver* xe::hid::winkey::Create(InputSystem* input_system) { InitializeIfNeeded(); return new WinKeyInputDriver(input_system); } + +} // namespace winkey +} // namespace hid +} // namespace xe diff --git a/src/xenia/hid/winkey/winkey_hid.h b/src/xenia/hid/winkey/winkey_hid.h index a5ed273bc..eac1fc9c5 100644 --- a/src/xenia/hid/winkey/winkey_hid.h +++ b/src/xenia/hid/winkey/winkey_hid.h @@ -12,22 +12,17 @@ #include - XEDECLARECLASS2(xe, hid, InputDriver); XEDECLARECLASS2(xe, hid, InputSystem); - namespace xe { namespace hid { namespace winkey { - InputDriver* Create(InputSystem* input_system); - } // namespace winkey } // namespace hid } // namespace xe - #endif // XENIA_HID_WINKEY_WINKEY_HID_H_ diff --git a/src/xenia/hid/winkey/winkey_input_driver.cc b/src/xenia/hid/winkey/winkey_input_driver.cc index d0e63d64b..9f2e83653 100644 --- a/src/xenia/hid/winkey/winkey_input_driver.cc +++ b/src/xenia/hid/winkey/winkey_input_driver.cc @@ -11,51 +11,44 @@ #include +namespace xe { +namespace hid { +namespace winkey { -using namespace xe; -using namespace xe::hid; -using namespace xe::hid::winkey; +WinKeyInputDriver::WinKeyInputDriver(InputSystem* input_system) + : packet_number_(1), InputDriver(input_system) {} +WinKeyInputDriver::~WinKeyInputDriver() {} -WinKeyInputDriver::WinKeyInputDriver(InputSystem* input_system) : - packet_number_(1), - InputDriver(input_system) { -} +X_STATUS WinKeyInputDriver::Setup() { return X_STATUS_SUCCESS; } -WinKeyInputDriver::~WinKeyInputDriver() { -} - -X_STATUS WinKeyInputDriver::Setup() { - return X_STATUS_SUCCESS; -} - -X_RESULT WinKeyInputDriver::GetCapabilities( - uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps) { +X_RESULT WinKeyInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags, + X_INPUT_CAPABILITIES* out_caps) { if (user_index != 0) { return X_ERROR_DEVICE_NOT_CONNECTED; } // TODO(benvanik): confirm with a real XInput controller. - out_caps.type = 0x01; // XINPUT_DEVTYPE_GAMEPAD - out_caps.sub_type = 0x01; // XINPUT_DEVSUBTYPE_GAMEPAD - out_caps.flags = 0; - out_caps.gamepad.buttons = 0xFFFF; - out_caps.gamepad.left_trigger = 0xFF; - out_caps.gamepad.right_trigger = 0xFF; - out_caps.gamepad.thumb_lx = (int16_t)0xFFFF; - out_caps.gamepad.thumb_ly = (int16_t)0xFFFF; - out_caps.gamepad.thumb_rx = (int16_t)0xFFFF; - out_caps.gamepad.thumb_ry = (int16_t)0xFFFF; - out_caps.vibration.left_motor_speed = 0; - out_caps.vibration.right_motor_speed = 0; + out_caps->type = 0x01; // XINPUT_DEVTYPE_GAMEPAD + out_caps->sub_type = 0x01; // XINPUT_DEVSUBTYPE_GAMEPAD + out_caps->flags = 0; + out_caps->gamepad.buttons = 0xFFFF; + out_caps->gamepad.left_trigger = 0xFF; + out_caps->gamepad.right_trigger = 0xFF; + out_caps->gamepad.thumb_lx = (int16_t)0xFFFF; + out_caps->gamepad.thumb_ly = (int16_t)0xFFFF; + out_caps->gamepad.thumb_rx = (int16_t)0xFFFF; + out_caps->gamepad.thumb_ry = (int16_t)0xFFFF; + out_caps->vibration.left_motor_speed = 0; + out_caps->vibration.right_motor_speed = 0; return X_ERROR_SUCCESS; } #define IS_KEY_TOGGLED(key) ((GetKeyState(key) & 0x1) == 0x1) #define IS_KEY_DOWN(key) ((GetAsyncKeyState(key) & 0x8000) == 0x8000) -X_RESULT WinKeyInputDriver::GetState( - uint32_t user_index, X_INPUT_STATE& out_state) { +X_RESULT WinKeyInputDriver::GetState(uint32_t user_index, + X_INPUT_STATE* out_state) { if (user_index != 0) { return X_ERROR_DEVICE_NOT_CONNECTED; } @@ -74,19 +67,19 @@ X_RESULT WinKeyInputDriver::GetState( // dpad toggled if (IS_KEY_DOWN(0x41)) { // A - buttons |= 0x0004; // XINPUT_GAMEPAD_DPAD_LEFT + buttons |= 0x0004; // XINPUT_GAMEPAD_DPAD_LEFT } if (IS_KEY_DOWN(0x44)) { // D - buttons |= 0x0008; // XINPUT_GAMEPAD_DPAD_RIGHT + buttons |= 0x0008; // XINPUT_GAMEPAD_DPAD_RIGHT } if (IS_KEY_DOWN(0x53)) { // S - buttons |= 0x0002; // XINPUT_GAMEPAD_DPAD_DOWN + buttons |= 0x0002; // XINPUT_GAMEPAD_DPAD_DOWN } if (IS_KEY_DOWN(0x57)) { // W - buttons |= 0x0001; // XINPUT_GAMEPAD_DPAD_UP + buttons |= 0x0001; // XINPUT_GAMEPAD_DPAD_UP } } else { // left stick @@ -110,44 +103,44 @@ X_RESULT WinKeyInputDriver::GetState( if (IS_KEY_DOWN(0x4C)) { // L - buttons |= 0x4000; // XINPUT_GAMEPAD_X + buttons |= 0x4000; // XINPUT_GAMEPAD_X } if (IS_KEY_DOWN(VK_OEM_7)) { // ' - buttons |= 0x2000; // XINPUT_GAMEPAD_B + buttons |= 0x2000; // XINPUT_GAMEPAD_B } if (IS_KEY_DOWN(VK_OEM_1)) { // ; - buttons |= 0x1000; // XINPUT_GAMEPAD_A + buttons |= 0x1000; // XINPUT_GAMEPAD_A } if (IS_KEY_DOWN(0x50)) { // P - buttons |= 0x8000; // XINPUT_GAMEPAD_Y + buttons |= 0x8000; // XINPUT_GAMEPAD_Y } if (IS_KEY_DOWN(0x5A)) { // Z - buttons |= 0x0020; // XINPUT_GAMEPAD_BACK + buttons |= 0x0020; // XINPUT_GAMEPAD_BACK } if (IS_KEY_DOWN(0x58)) { // X - buttons |= 0x0010; // XINPUT_GAMEPAD_START + buttons |= 0x0010; // XINPUT_GAMEPAD_START } - out_state.packet_number = packet_number_; - out_state.gamepad.buttons = buttons; - out_state.gamepad.left_trigger = left_trigger; - out_state.gamepad.right_trigger = right_trigger; - out_state.gamepad.thumb_lx = thumb_lx; - out_state.gamepad.thumb_ly = thumb_ly; - out_state.gamepad.thumb_rx = thumb_rx; - out_state.gamepad.thumb_ry = thumb_ry; + out_state->packet_number = packet_number_; + out_state->gamepad.buttons = buttons; + out_state->gamepad.left_trigger = left_trigger; + out_state->gamepad.right_trigger = right_trigger; + out_state->gamepad.thumb_lx = thumb_lx; + out_state->gamepad.thumb_ly = thumb_ly; + out_state->gamepad.thumb_rx = thumb_rx; + out_state->gamepad.thumb_ry = thumb_ry; return X_ERROR_SUCCESS; } -X_RESULT WinKeyInputDriver::SetState( - uint32_t user_index, X_INPUT_VIBRATION& vibration) { +X_RESULT WinKeyInputDriver::SetState(uint32_t user_index, + X_INPUT_VIBRATION* vibration) { if (user_index != 0) { return X_ERROR_DEVICE_NOT_CONNECTED; } @@ -155,8 +148,8 @@ X_RESULT WinKeyInputDriver::SetState( return X_ERROR_SUCCESS; } -X_RESULT WinKeyInputDriver::GetKeystroke( - uint32_t user_index, uint32_t flags, X_INPUT_KEYSTROKE& out_keystroke) { +X_RESULT WinKeyInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags, + X_INPUT_KEYSTROKE* out_keystroke) { if (user_index != 0) { return X_ERROR_DEVICE_NOT_CONNECTED; } @@ -168,14 +161,18 @@ X_RESULT WinKeyInputDriver::GetKeystroke( uint16_t keystroke_flags = 0; uint8_t hid_code = 0; - out_keystroke.virtual_key = virtual_key; - out_keystroke.unicode = unicode; - out_keystroke.flags = keystroke_flags; - out_keystroke.user_index = 0; - out_keystroke.hid_code = hid_code; + out_keystroke->virtual_key = virtual_key; + out_keystroke->unicode = unicode; + out_keystroke->flags = keystroke_flags; + out_keystroke->user_index = 0; + out_keystroke->hid_code = hid_code; // X_ERROR_EMPTY if no new keys // X_ERROR_DEVICE_NOT_CONNECTED if no device // X_ERROR_SUCCESS if key return result; } + +} // namespace winkey +} // namespace hid +} // namespace xe diff --git a/src/xenia/hid/winkey/winkey_input_driver.h b/src/xenia/hid/winkey/winkey_input_driver.h index b1d00fd10..9a547cb8f 100644 --- a/src/xenia/hid/winkey/winkey_input_driver.h +++ b/src/xenia/hid/winkey/winkey_input_driver.h @@ -11,40 +11,33 @@ #define XENIA_HID_WINKEY_WINKEY_DRIVER_H_ #include - #include #include - namespace xe { namespace hid { namespace winkey { - class WinKeyInputDriver : public InputDriver { -public: + public: WinKeyInputDriver(InputSystem* input_system); - virtual ~WinKeyInputDriver(); + ~WinKeyInputDriver() override; - virtual X_STATUS Setup(); + X_STATUS Setup() override; - virtual X_RESULT GetCapabilities( - uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps); - virtual X_RESULT GetState( - uint32_t user_index, X_INPUT_STATE& out_state); - virtual X_RESULT SetState( - uint32_t user_index, X_INPUT_VIBRATION& vibration); - virtual X_RESULT GetKeystroke( - uint32_t user_index, uint32_t flags, X_INPUT_KEYSTROKE& out_keystroke); + X_RESULT GetCapabilities(uint32_t user_index, uint32_t flags, + X_INPUT_CAPABILITIES* out_caps) override; + X_RESULT GetState(uint32_t user_index, X_INPUT_STATE* out_state) override; + X_RESULT SetState(uint32_t user_index, X_INPUT_VIBRATION* vibration) override; + X_RESULT GetKeystroke(uint32_t user_index, uint32_t flags, + X_INPUT_KEYSTROKE* out_keystroke) override; -protected: + protected: uint32_t packet_number_; }; - } // namespace winkey } // namespace hid } // namespace xe - #endif // XENIA_HID_WINKEY_WINKEY_DRIVER_H_ diff --git a/src/xenia/hid/xinput/xinput_hid-private.h b/src/xenia/hid/xinput/xinput_hid-private.h index 264fbfd37..cc83fd0b3 100644 --- a/src/xenia/hid/xinput/xinput_hid-private.h +++ b/src/xenia/hid/xinput/xinput_hid-private.h @@ -11,21 +11,16 @@ #define XENIA_HID_XINPUT_XINPUT_HID_PRIVATE_H_ #include - #include - namespace xe { namespace hid { namespace xinput { - - - +// } // namespace xinput } // namespace hid } // namespace xe - #endif // XENIA_HID_XINPUT_XINPUT_HID_PRIVATE_H_ diff --git a/src/xenia/hid/xinput/xinput_hid.cc b/src/xenia/hid/xinput/xinput_hid.cc index 960242765..7850cf258 100644 --- a/src/xenia/hid/xinput/xinput_hid.cc +++ b/src/xenia/hid/xinput/xinput_hid.cc @@ -11,34 +11,32 @@ #include +namespace xe { +namespace hid { +namespace xinput { -using namespace xe; -using namespace xe::hid; -using namespace xe::hid::xinput; +void InitializeIfNeeded(); +void CleanupOnShutdown(); - -namespace { - void InitializeIfNeeded(); - void CleanupOnShutdown(); - - void InitializeIfNeeded() { - static bool has_initialized = false; - if (has_initialized) { - return; - } - has_initialized = true; - - // - - atexit(CleanupOnShutdown); +void InitializeIfNeeded() { + static bool has_initialized = false; + if (has_initialized) { + return; } + has_initialized = true; - void CleanupOnShutdown() { - } + // + + atexit(CleanupOnShutdown); } +void CleanupOnShutdown() {} InputDriver* xe::hid::xinput::Create(InputSystem* input_system) { InitializeIfNeeded(); return new XInputInputDriver(input_system); } + +} // namespace xinput +} // namespace hid +} // namespace xe diff --git a/src/xenia/hid/xinput/xinput_hid.h b/src/xenia/hid/xinput/xinput_hid.h index a1522d830..9e1194a7a 100644 --- a/src/xenia/hid/xinput/xinput_hid.h +++ b/src/xenia/hid/xinput/xinput_hid.h @@ -12,22 +12,17 @@ #include - XEDECLARECLASS2(xe, hid, InputDriver); XEDECLARECLASS2(xe, hid, InputSystem); - namespace xe { namespace hid { namespace xinput { - InputDriver* Create(InputSystem* input_system); - } // namespace xinput } // namespace hid } // namespace xe - #endif // XENIA_HID_XINPUT_XINPUT_HID_H_ diff --git a/src/xenia/hid/xinput/xinput_input_driver.cc b/src/xenia/hid/xinput/xinput_input_driver.cc index cf1097196..cad5edadb 100644 --- a/src/xenia/hid/xinput/xinput_input_driver.cc +++ b/src/xenia/hid/xinput/xinput_input_driver.cc @@ -13,95 +13,92 @@ #include +namespace xe { +namespace hid { +namespace xinput { -using namespace xe; -using namespace xe::hid; -using namespace xe::hid::xinput; - - -XInputInputDriver::XInputInputDriver(InputSystem* input_system) : - InputDriver(input_system) { +XInputInputDriver::XInputInputDriver(InputSystem* input_system) + : InputDriver(input_system) { XInputEnable(TRUE); } -XInputInputDriver::~XInputInputDriver() { - XInputEnable(FALSE); -} +XInputInputDriver::~XInputInputDriver() { XInputEnable(FALSE); } -X_STATUS XInputInputDriver::Setup() { - return X_STATUS_SUCCESS; -} +X_STATUS XInputInputDriver::Setup() { return X_STATUS_SUCCESS; } -X_RESULT XInputInputDriver::GetCapabilities( - uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps) { +X_RESULT XInputInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags, + X_INPUT_CAPABILITIES* out_caps) { XINPUT_CAPABILITIES native_caps; DWORD result = XInputGetCapabilities(user_index, flags, &native_caps); if (result) { return result; } - out_caps.type = native_caps.Type; - out_caps.sub_type = native_caps.SubType; - out_caps.flags = native_caps.Flags; - out_caps.gamepad.buttons = native_caps.Gamepad.wButtons; - out_caps.gamepad.left_trigger = native_caps.Gamepad.bLeftTrigger; - out_caps.gamepad.right_trigger = native_caps.Gamepad.bRightTrigger; - out_caps.gamepad.thumb_lx = native_caps.Gamepad.sThumbLX; - out_caps.gamepad.thumb_ly = native_caps.Gamepad.sThumbLY; - out_caps.gamepad.thumb_rx = native_caps.Gamepad.sThumbRX; - out_caps.gamepad.thumb_ry = native_caps.Gamepad.sThumbRY; - out_caps.vibration.left_motor_speed = - native_caps.Vibration.wLeftMotorSpeed; - out_caps.vibration.right_motor_speed = + out_caps->type = native_caps.Type; + out_caps->sub_type = native_caps.SubType; + out_caps->flags = native_caps.Flags; + out_caps->gamepad.buttons = native_caps.Gamepad.wButtons; + out_caps->gamepad.left_trigger = native_caps.Gamepad.bLeftTrigger; + out_caps->gamepad.right_trigger = native_caps.Gamepad.bRightTrigger; + out_caps->gamepad.thumb_lx = native_caps.Gamepad.sThumbLX; + out_caps->gamepad.thumb_ly = native_caps.Gamepad.sThumbLY; + out_caps->gamepad.thumb_rx = native_caps.Gamepad.sThumbRX; + out_caps->gamepad.thumb_ry = native_caps.Gamepad.sThumbRY; + out_caps->vibration.left_motor_speed = native_caps.Vibration.wLeftMotorSpeed; + out_caps->vibration.right_motor_speed = native_caps.Vibration.wRightMotorSpeed; return result; } -X_RESULT XInputInputDriver::GetState( - uint32_t user_index, X_INPUT_STATE& out_state) { +X_RESULT XInputInputDriver::GetState(uint32_t user_index, + X_INPUT_STATE* out_state) { XINPUT_STATE native_state; DWORD result = XInputGetState(user_index, &native_state); if (result) { return result; } - out_state.packet_number = native_state.dwPacketNumber; - out_state.gamepad.buttons = native_state.Gamepad.wButtons; - out_state.gamepad.left_trigger = native_state.Gamepad.bLeftTrigger; - out_state.gamepad.right_trigger = native_state.Gamepad.bRightTrigger; - out_state.gamepad.thumb_lx = native_state.Gamepad.sThumbLX; - out_state.gamepad.thumb_ly = native_state.Gamepad.sThumbLY; - out_state.gamepad.thumb_rx = native_state.Gamepad.sThumbRX; - out_state.gamepad.thumb_ry = native_state.Gamepad.sThumbRY; + out_state->packet_number = native_state.dwPacketNumber; + out_state->gamepad.buttons = native_state.Gamepad.wButtons; + out_state->gamepad.left_trigger = native_state.Gamepad.bLeftTrigger; + out_state->gamepad.right_trigger = native_state.Gamepad.bRightTrigger; + out_state->gamepad.thumb_lx = native_state.Gamepad.sThumbLX; + out_state->gamepad.thumb_ly = native_state.Gamepad.sThumbLY; + out_state->gamepad.thumb_rx = native_state.Gamepad.sThumbRX; + out_state->gamepad.thumb_ry = native_state.Gamepad.sThumbRY; return result; } -X_RESULT XInputInputDriver::SetState( - uint32_t user_index, X_INPUT_VIBRATION& vibration) { +X_RESULT XInputInputDriver::SetState(uint32_t user_index, + X_INPUT_VIBRATION* vibration) { XINPUT_VIBRATION native_vibration; - native_vibration.wLeftMotorSpeed = vibration.left_motor_speed; - native_vibration.wRightMotorSpeed= vibration.right_motor_speed; + native_vibration.wLeftMotorSpeed = vibration->left_motor_speed; + native_vibration.wRightMotorSpeed = vibration->right_motor_speed; DWORD result = XInputSetState(user_index, &native_vibration); return result; } -X_RESULT XInputInputDriver::GetKeystroke( - uint32_t user_index, uint32_t flags, X_INPUT_KEYSTROKE& out_keystroke) { +X_RESULT XInputInputDriver::GetKeystroke(uint32_t user_index, uint32_t flags, + X_INPUT_KEYSTROKE* out_keystroke) { // We may want to filter flags/user_index before sending to native. // flags is reserved on desktop. XINPUT_KEYSTROKE native_keystroke; DWORD result = XInputGetKeystroke(user_index, flags, &native_keystroke); if (result == ERROR_SUCCESS) { - out_keystroke.virtual_key = native_keystroke.VirtualKey; - out_keystroke.unicode = native_keystroke.Unicode; - out_keystroke.flags = native_keystroke.Flags; - out_keystroke.user_index = native_keystroke.UserIndex; - out_keystroke.hid_code = native_keystroke.HidCode; + out_keystroke->virtual_key = native_keystroke.VirtualKey; + out_keystroke->unicode = native_keystroke.Unicode; + out_keystroke->flags = native_keystroke.Flags; + out_keystroke->user_index = native_keystroke.UserIndex; + out_keystroke->hid_code = native_keystroke.HidCode; } // X_ERROR_EMPTY if no new keys // X_ERROR_DEVICE_NOT_CONNECTED if no device // X_ERROR_SUCCESS if key return result; } + +} // namespace xinput +} // namespace hid +} // namespace xe diff --git a/src/xenia/hid/xinput/xinput_input_driver.h b/src/xenia/hid/xinput/xinput_input_driver.h index dc9118c1d..c020f59a7 100644 --- a/src/xenia/hid/xinput/xinput_input_driver.h +++ b/src/xenia/hid/xinput/xinput_input_driver.h @@ -11,39 +11,32 @@ #define XENIA_HID_XINPUT_XINPUT_DRIVER_H_ #include - #include #include - namespace xe { namespace hid { namespace xinput { - class XInputInputDriver : public InputDriver { -public: + public: XInputInputDriver(InputSystem* input_system); - virtual ~XInputInputDriver(); + ~XInputInputDriver() override; - virtual X_STATUS Setup(); + X_STATUS Setup() override; - virtual X_RESULT GetCapabilities( - uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES& out_caps); - virtual X_RESULT GetState( - uint32_t user_index, X_INPUT_STATE& out_state); - virtual X_RESULT SetState( - uint32_t user_index, X_INPUT_VIBRATION& vibration); - virtual X_RESULT GetKeystroke( - uint32_t user_index, uint32_t flags, X_INPUT_KEYSTROKE& out_keystroke); + X_RESULT GetCapabilities(uint32_t user_index, uint32_t flags, + X_INPUT_CAPABILITIES* out_caps) override; + X_RESULT GetState(uint32_t user_index, X_INPUT_STATE* out_state) override; + X_RESULT SetState(uint32_t user_index, X_INPUT_VIBRATION* vibration) override; + X_RESULT GetKeystroke(uint32_t user_index, uint32_t flags, + X_INPUT_KEYSTROKE* out_keystroke) override; -protected: + protected: }; - } // namespace xinput } // namespace hid } // namespace xe - #endif // XENIA_HID_XINPUT_XINPUT_DRIVER_H_ diff --git a/src/xenia/kernel/util/shim_utils.h b/src/xenia/kernel/util/shim_utils.h index d68ea4da8..8adeb86de 100644 --- a/src/xenia/kernel/util/shim_utils.h +++ b/src/xenia/kernel/util/shim_utils.h @@ -58,6 +58,8 @@ using PPCContext = alloy::frontend::ppc::PPCContext; #define SHIM_SET_RETURN_32(v) SHIM_SET_GPR_64(3, (uint64_t)(int32_t)v) #define SHIM_SET_RETURN_64(v) SHIM_SET_GPR_64(3, v) +#define SHIM_STRUCT(type, address) \ + reinterpret_cast(SHIM_MEM_ADDR(address)) } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/xam_input.cc b/src/xenia/kernel/xam_input.cc index d2808f874..6d0138336 100644 --- a/src/xenia/kernel/xam_input.cc +++ b/src/xenia/kernel/xam_input.cc @@ -58,11 +58,8 @@ SHIM_CALL XamInputGetCapabilities_shim(PPCContext* ppc_state, InputSystem* input_system = state->emulator()->input_system(); - X_INPUT_CAPABILITIES caps; + auto caps = SHIM_STRUCT(X_INPUT_CAPABILITIES, caps_ptr); X_RESULT result = input_system->GetCapabilities(user_index, flags, caps); - if (XSUCCEEDED(result)) { - caps.Write(SHIM_MEM_BASE, caps_ptr); - } SHIM_SET_RETURN_32(result); } @@ -78,13 +75,8 @@ SHIM_CALL XamInputGetState_shim(PPCContext* ppc_state, KernelState* state) { InputSystem* input_system = state->emulator()->input_system(); - X_INPUT_STATE input_state; + auto input_state = SHIM_STRUCT(X_INPUT_STATE, state_ptr); X_RESULT result = input_system->GetState(user_index, input_state); - if (XSUCCEEDED(result)) { - if (state_ptr) { - input_state.Write(SHIM_MEM_BASE, state_ptr); - } - } SHIM_SET_RETURN_32(result); } @@ -103,7 +95,7 @@ SHIM_CALL XamInputSetState_shim(PPCContext* ppc_state, KernelState* state) { InputSystem* input_system = state->emulator()->input_system(); - X_INPUT_VIBRATION vibration(SHIM_MEM_BASE, vibration_ptr); + auto vibration = SHIM_STRUCT(X_INPUT_VIBRATION, vibration_ptr); X_RESULT result = input_system->SetState(user_index, vibration); SHIM_SET_RETURN_32(result); } @@ -128,11 +120,8 @@ SHIM_CALL XamInputGetKeystroke_shim(PPCContext* ppc_state, KernelState* state) { InputSystem* input_system = state->emulator()->input_system(); - X_INPUT_KEYSTROKE keystroke; + auto keystroke = SHIM_STRUCT(X_INPUT_KEYSTROKE, keystroke_ptr); X_RESULT result = input_system->GetKeystroke(user_index, flags, keystroke); - if (XSUCCEEDED(result)) { - keystroke.Write(SHIM_MEM_BASE, keystroke_ptr); - } SHIM_SET_RETURN_32(result); } @@ -155,11 +144,10 @@ SHIM_CALL XamInputGetKeystrokeEx_shim(PPCContext* ppc_state, InputSystem* input_system = state->emulator()->input_system(); - X_INPUT_KEYSTROKE keystroke; + auto keystroke = SHIM_STRUCT(X_INPUT_KEYSTROKE, keystroke_ptr); X_RESULT result = input_system->GetKeystroke(user_index, flags, keystroke); if (XSUCCEEDED(result)) { - SHIM_SET_MEM_32(user_index_ptr, keystroke.user_index); - keystroke.Write(SHIM_MEM_BASE, keystroke_ptr); + SHIM_SET_MEM_32(user_index_ptr, keystroke->user_index); } SHIM_SET_RETURN_32(result); } diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index 8bb0c600c..39cce8f8c 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -10,12 +10,16 @@ #ifndef XENIA_XBOX_H_ #define XENIA_XBOX_H_ +#include #include #include namespace xe { +template +using be = poly::be; + #pragma pack(push, 4) @@ -277,6 +281,7 @@ public: return copy; } }; +//static_assert_size(X_ANSI_STRING, 8); class X_OBJECT_ATTRIBUTES { @@ -309,6 +314,7 @@ public: attributes = 0; } }; +static_assert_size(X_OBJECT_ATTRIBUTES, 12 + sizeof(X_ANSI_STRING)); // Values seem to be all over the place - GUIDs? @@ -330,194 +336,72 @@ struct X_VIDEO_MODE { }; static_assert_size(X_VIDEO_MODE, 48); - typedef enum _X_INPUT_FLAG { - X_INPUT_FLAG_GAMEPAD = 0x00000001, + X_INPUT_FLAG_GAMEPAD = 0x00000001, } X_INPUT_FLAG; typedef enum _X_INPUT_GAMEPAD_BUTTON { - X_INPUT_GAMEPAD_DPAD_UP = 0x0001, - X_INPUT_GAMEPAD_DPAD_DOWN = 0x0002, - X_INPUT_GAMEPAD_DPAD_LEFT = 0x0004, - X_INPUT_GAMEPAD_DPAD_RIGHT = 0x0008, - X_INPUT_GAMEPAD_START = 0x0010, - X_INPUT_GAMEPAD_BACK = 0x0020, - X_INPUT_GAMEPAD_LEFT_THUMB = 0x0040, - X_INPUT_GAMEPAD_RIGHT_THUMB = 0x0080, - X_INPUT_GAMEPAD_LEFT_SHOULDER = 0x0100, - X_INPUT_GAMEPAD_RIGHT_SHOULDER = 0x0200, - X_INPUT_GAMEPAD_A = 0x1000, - X_INPUT_GAMEPAD_B = 0x2000, - X_INPUT_GAMEPAD_X = 0x4000, - X_INPUT_GAMEPAD_Y = 0x8000, + X_INPUT_GAMEPAD_DPAD_UP = 0x0001, + X_INPUT_GAMEPAD_DPAD_DOWN = 0x0002, + X_INPUT_GAMEPAD_DPAD_LEFT = 0x0004, + X_INPUT_GAMEPAD_DPAD_RIGHT = 0x0008, + X_INPUT_GAMEPAD_START = 0x0010, + X_INPUT_GAMEPAD_BACK = 0x0020, + X_INPUT_GAMEPAD_LEFT_THUMB = 0x0040, + X_INPUT_GAMEPAD_RIGHT_THUMB = 0x0080, + X_INPUT_GAMEPAD_LEFT_SHOULDER = 0x0100, + X_INPUT_GAMEPAD_RIGHT_SHOULDER = 0x0200, + X_INPUT_GAMEPAD_A = 0x1000, + X_INPUT_GAMEPAD_B = 0x2000, + X_INPUT_GAMEPAD_X = 0x4000, + X_INPUT_GAMEPAD_Y = 0x8000, } X_INPUT_GAMEPAD_BUTTON; -class X_INPUT_GAMEPAD { -public: - uint16_t buttons; - uint8_t left_trigger; - uint8_t right_trigger; - int16_t thumb_lx; - int16_t thumb_ly; - int16_t thumb_rx; - int16_t thumb_ry; - - X_INPUT_GAMEPAD() { - Zero(); - } - X_INPUT_GAMEPAD(const uint8_t* base, uint32_t p) { - Read(base, p); - } - void Read(const uint8_t* base, uint32_t p) { - buttons = poly::load_and_swap(base + p); - left_trigger = poly::load_and_swap(base + p + 2); - right_trigger = poly::load_and_swap(base + p + 3); - thumb_lx = poly::load_and_swap(base + p + 4); - thumb_ly = poly::load_and_swap(base + p + 6); - thumb_rx = poly::load_and_swap(base + p + 8); - thumb_ry = poly::load_and_swap(base + p + 10); - } - void Write(uint8_t* base, uint32_t p) { - poly::store_and_swap(base + p, buttons); - poly::store_and_swap(base + p + 2, left_trigger); - poly::store_and_swap(base + p + 3, right_trigger); - poly::store_and_swap(base + p + 4, thumb_lx); - poly::store_and_swap(base + p + 6, thumb_ly); - poly::store_and_swap(base + p + 8, thumb_rx); - poly::store_and_swap(base + p + 10, thumb_ry); - } - void Zero() { - buttons = 0; - left_trigger = right_trigger = 0; - thumb_lx = thumb_ly = thumb_rx = thumb_ry = 0; - } +struct X_INPUT_GAMEPAD { + be buttons; + be left_trigger; + be right_trigger; + be thumb_lx; + be thumb_ly; + be thumb_rx; + be thumb_ry; }; -class X_INPUT_STATE { -public: - uint32_t packet_number; - X_INPUT_GAMEPAD gamepad; +static_assert_size(X_INPUT_GAMEPAD, 12); - X_INPUT_STATE() { - Zero(); - } - X_INPUT_STATE(const uint8_t* base, uint32_t p) { - Read(base, p); - } - void Read(const uint8_t* base, uint32_t p) { - packet_number = poly::load_and_swap(base + p); - gamepad.Read(base, p + 4); - } - void Write(uint8_t* base, uint32_t p) { - poly::store_and_swap(base + p, packet_number); - gamepad.Write(base, p + 4); - } - void Zero() { - packet_number = 0; - gamepad.Zero(); - } +struct X_INPUT_STATE { + be packet_number; + X_INPUT_GAMEPAD gamepad; }; -class X_INPUT_VIBRATION { -public: - uint16_t left_motor_speed; - uint16_t right_motor_speed; +static_assert_size(X_INPUT_STATE, sizeof(X_INPUT_GAMEPAD) + 4); - X_INPUT_VIBRATION() { - Zero(); - } - X_INPUT_VIBRATION(const uint8_t* base, uint32_t p) { - Read(base, p); - } - void Read(const uint8_t* base, uint32_t p) { - left_motor_speed = poly::load_and_swap(base + p); - right_motor_speed = poly::load_and_swap(base + p + 2); - } - void Write(uint8_t* base, uint32_t p) { - poly::store_and_swap(base + p, left_motor_speed); - poly::store_and_swap(base + p + 2, right_motor_speed); - } - void Zero() { - left_motor_speed = right_motor_speed = 0; - } +struct X_INPUT_VIBRATION { + be left_motor_speed; + be right_motor_speed; }; -class X_INPUT_CAPABILITIES { -public: - uint8_t type; - uint8_t sub_type; - uint16_t flags; - X_INPUT_GAMEPAD gamepad; +static_assert_size(X_INPUT_VIBRATION, 4); + +struct X_INPUT_CAPABILITIES { + be type; + be sub_type; + be flags; + X_INPUT_GAMEPAD gamepad; X_INPUT_VIBRATION vibration; - - X_INPUT_CAPABILITIES() { - Zero(); - } - X_INPUT_CAPABILITIES(const uint8_t* base, uint32_t p) { - Read(base, p); - } - void Read(const uint8_t* base, uint32_t p) { - type = poly::load_and_swap(base + p); - sub_type = poly::load_and_swap(base + p + 1); - flags = poly::load_and_swap(base + p + 2); - gamepad.Read(base, p + 4); - vibration.Read(base, p + 4 + 12); - } - void Write(uint8_t* base, uint32_t p) { - poly::store_and_swap(base + p, type); - poly::store_and_swap(base + p + 1, sub_type); - poly::store_and_swap(base + p + 2, flags); - gamepad.Write(base, p + 4); - vibration.Write(base, p + 4 + 12); - } - void Zero() { - type = 0; - sub_type = 0; - flags = 0; - gamepad.Zero(); - vibration.Zero(); - } }; +static_assert_size(X_INPUT_CAPABILITIES, + sizeof(X_INPUT_GAMEPAD) + sizeof(X_INPUT_VIBRATION) + 4); + // http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinput_keystroke(v=vs.85).aspx -class X_INPUT_KEYSTROKE { -public: - uint16_t virtual_key; - uint16_t unicode; - uint16_t flags; - uint8_t user_index; - uint8_t hid_code; - - X_INPUT_KEYSTROKE() { - Zero(); - } - X_INPUT_KEYSTROKE(const uint8_t* base, uint32_t p) { - Read(base, p); - } - void Read(const uint8_t* base, uint32_t p) { - virtual_key = poly::load_and_swap(base + p + 0); - unicode = poly::load_and_swap(base + p + 2); - flags = poly::load_and_swap(base + p + 4); - user_index = poly::load_and_swap(base + p + 6); - hid_code = poly::load_and_swap(base + p + 7); - } - void Write(uint8_t* base, uint32_t p) { - poly::store_and_swap(base + p + 0, virtual_key); - poly::store_and_swap(base + p + 2, unicode); - poly::store_and_swap(base + p + 4, flags); - poly::store_and_swap(base + p + 6, user_index); - poly::store_and_swap(base + p + 7, hid_code); - } - void Zero() { - virtual_key = 0; - unicode = 0; - flags = 0; - user_index = 0; - hid_code = 0; - } +struct X_INPUT_KEYSTROKE { + be virtual_key; + be unicode; + be flags; + be user_index; + be hid_code; }; - +static_assert_size(X_INPUT_KEYSTROKE, 8); #pragma pack(pop) - } // namespace xe - #endif // XENIA_XBOX_H_ From d33cae1bafc6f7af182057e10f3c7aa7f3eda788 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 19 Aug 2014 22:55:09 -0700 Subject: [PATCH 140/388] Auto swap for a few structs and shifting code around. --- src/xenia/kernel/xboxkrnl_io.cc | 32 ++++++++++++ src/xenia/kernel/xboxkrnl_memory.cc | 49 ++++++++--------- src/xenia/kernel/xboxkrnl_video.cc | 11 ---- src/xenia/xbox.h | 81 +++++++---------------------- 4 files changed, 72 insertions(+), 101 deletions(-) diff --git a/src/xenia/kernel/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl_io.cc index aec999fe3..11a32e000 100644 --- a/src/xenia/kernel/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl_io.cc @@ -23,6 +23,38 @@ namespace kernel { using namespace xe::kernel::fs; +class X_OBJECT_ATTRIBUTES { +public: + uint32_t root_directory; + uint32_t object_name_ptr; + X_ANSI_STRING object_name; + uint32_t attributes; + + X_OBJECT_ATTRIBUTES() { + Zero(); + } + X_OBJECT_ATTRIBUTES(const uint8_t* base, uint32_t p) { + Read(base, p); + } + void Read(const uint8_t* base, uint32_t p) { + root_directory = poly::load_and_swap(base + p); + object_name_ptr = poly::load_and_swap(base + p + 4); + if (object_name_ptr) { + object_name.Read(base, object_name_ptr); + } else { + object_name.Zero(); + } + attributes = poly::load_and_swap(base + p + 8); + } + void Zero() { + root_directory = 0; + object_name_ptr = 0; + object_name.Zero(); + attributes = 0; + } +}; +static_assert_size(X_OBJECT_ATTRIBUTES, 12 + sizeof(X_ANSI_STRING)); + SHIM_CALL NtCreateFile_shim(PPCContext* ppc_state, KernelState* state) { uint32_t handle_ptr = SHIM_GET_ARG_32(0); uint32_t desired_access = SHIM_GET_ARG_32(1); diff --git a/src/xenia/kernel/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl_memory.cc index e3f80cd15..b6a7124e0 100644 --- a/src/xenia/kernel/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl_memory.cc @@ -149,49 +149,42 @@ SHIM_CALL NtFreeVirtualMemory_shim(PPCContext* ppc_state, KernelState* state) { SHIM_SET_RETURN_32(X_STATUS_SUCCESS); } +struct X_MEMORY_BASIC_INFORMATION { + be base_address; + be allocation_base; + be allocation_protect; + be region_size; + be state; + be protect; + be type; +}; + SHIM_CALL NtQueryVirtualMemory_shim(PPCContext* ppc_state, KernelState* state) { uint32_t base_address = SHIM_GET_ARG_32(0); uint32_t memory_basic_information_ptr = SHIM_GET_ARG_32(1); - X_MEMORY_BASIC_INFORMATION* memory_basic_information = - (X_MEMORY_BASIC_INFORMATION*)SHIM_MEM_ADDR(memory_basic_information_ptr); + auto memory_basic_information = + SHIM_STRUCT(X_MEMORY_BASIC_INFORMATION, memory_basic_information_ptr); XELOGD("NtQueryVirtualMemory(%.8X, %.8X)", base_address, memory_basic_information_ptr); - AllocationInfo mem_info; - size_t result = state->memory()->QueryInformation(base_address, &mem_info); + AllocationInfo alloc_info; + size_t result = state->memory()->QueryInformation(base_address, &alloc_info); if (!result) { SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER); return; } - auto membase = state->memory()->membase(); memory_basic_information->base_address = - static_cast(mem_info.base_address); + static_cast(alloc_info.base_address); memory_basic_information->allocation_base = - static_cast(mem_info.allocation_base); - memory_basic_information->allocation_protect = mem_info.allocation_protect; + static_cast(alloc_info.allocation_base); + memory_basic_information->allocation_protect = alloc_info.allocation_protect; memory_basic_information->region_size = - static_cast(mem_info.region_size); - memory_basic_information->state = mem_info.state; - memory_basic_information->protect = mem_info.protect; - memory_basic_information->type = mem_info.type; - - // TODO(benvanik): auto swap structure. - memory_basic_information->base_address = - poly::byte_swap(memory_basic_information->base_address); - memory_basic_information->allocation_base = - poly::byte_swap(memory_basic_information->allocation_base); - memory_basic_information->allocation_protect = - poly::byte_swap(memory_basic_information->allocation_protect); - memory_basic_information->region_size = - poly::byte_swap(memory_basic_information->region_size); - memory_basic_information->state = - poly::byte_swap(memory_basic_information->state); - memory_basic_information->protect = - poly::byte_swap(memory_basic_information->protect); - memory_basic_information->type = - poly::byte_swap(memory_basic_information->type); + static_cast(alloc_info.region_size); + memory_basic_information->state = alloc_info.state; + memory_basic_information->protect = alloc_info.protect; + memory_basic_information->type = alloc_info.type; XELOGE("NtQueryVirtualMemory NOT IMPLEMENTED"); diff --git a/src/xenia/kernel/xboxkrnl_video.cc b/src/xenia/kernel/xboxkrnl_video.cc index d1b319cde..419393a70 100644 --- a/src/xenia/kernel/xboxkrnl_video.cc +++ b/src/xenia/kernel/xboxkrnl_video.cc @@ -100,17 +100,6 @@ void xeVdQueryVideoMode(X_VIDEO_MODE* video_mode) { video_mode->video_standard = 1; // NTSC video_mode->unknown_0x8a = 0x8A; video_mode->unknown_0x01 = 0x01; - - // TODO(benvanik): auto swap structure. - video_mode->display_width = poly::byte_swap(video_mode->display_width); - video_mode->display_height = poly::byte_swap(video_mode->display_height); - video_mode->is_interlaced = poly::byte_swap(video_mode->is_interlaced); - video_mode->is_widescreen = poly::byte_swap(video_mode->is_widescreen); - video_mode->is_hi_def = poly::byte_swap(video_mode->is_hi_def); - video_mode->refresh_rate = poly::byte_swap(video_mode->refresh_rate); - video_mode->video_standard = poly::byte_swap(video_mode->video_standard); - video_mode->unknown_0x8a = poly::byte_swap(video_mode->unknown_0x8a); - video_mode->unknown_0x01 = poly::byte_swap(video_mode->unknown_0x01); } SHIM_CALL VdQueryVideoMode_shim(PPCContext* ppc_state, KernelState* state) { diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index 39cce8f8c..fb0431eaa 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -28,6 +28,8 @@ typedef uint32_t X_HANDLE; #define X_INVALID_HANDLE_VALUE ((X_HANDLE)-1) +// TODO(benvanik): type all of this so we get some safety. + // NT_STATUS (STATUS_*) // http://msdn.microsoft.com/en-us/library/cc704588.aspx // Adding as needed. @@ -145,7 +147,7 @@ typedef uint32_t X_RESULT; #define X_LANGUAGE_JAPANESE 2 -typedef enum _X_FILE_ATTRIBUTES { +enum X_FILE_ATTRIBUTES { X_FILE_ATTRIBUTE_NONE = 0x0000, X_FILE_ATTRIBUTE_READONLY = 0x0001, X_FILE_ATTRIBUTE_HIDDEN = 0x0002, @@ -157,11 +159,11 @@ typedef enum _X_FILE_ATTRIBUTES { X_FILE_ATTRIBUTE_TEMPORARY = 0x0100, X_FILE_ATTRIBUTE_COMPRESSED = 0x0800, X_FILE_ATTRIBUTE_ENCRYPTED = 0x4000, -} X_FILE_ATTRIBUTES; +}; // http://code.google.com/p/vdash/source/browse/trunk/vdash/include/kernel.h -typedef enum _X_FILE_INFORMATION_CLASS { +enum X_FILE_INFORMATION_CLASS { XFileDirectoryInformation = 1, XFileFullDirectoryInformation, XFileBothDirectoryInformation, @@ -199,20 +201,8 @@ typedef enum _X_FILE_INFORMATION_CLASS { XFileAttributeTagInformation, XFileTrackingInformation, XFileMaximumInformation -} X_FILE_INFORMATION_CLASS; - - -struct X_MEMORY_BASIC_INFORMATION { - uint32_t base_address; - uint32_t allocation_base; - uint32_t allocation_protect; - uint32_t region_size; - uint32_t state; - uint32_t protect; - uint32_t type; }; - inline void XOverlappedSetResult(void* ptr, uint32_t value) { auto p = reinterpret_cast(ptr); poly::store_and_swap(&p[0], value); @@ -284,63 +274,30 @@ public: //static_assert_size(X_ANSI_STRING, 8); -class X_OBJECT_ATTRIBUTES { -public: - uint32_t root_directory; - uint32_t object_name_ptr; - X_ANSI_STRING object_name; - uint32_t attributes; - - X_OBJECT_ATTRIBUTES() { - Zero(); - } - X_OBJECT_ATTRIBUTES(const uint8_t* base, uint32_t p) { - Read(base, p); - } - void Read(const uint8_t* base, uint32_t p) { - root_directory = poly::load_and_swap(base + p); - object_name_ptr = poly::load_and_swap(base + p + 4); - if (object_name_ptr) { - object_name.Read(base, object_name_ptr); - } else { - object_name.Zero(); - } - attributes = poly::load_and_swap(base + p + 8); - } - void Zero() { - root_directory = 0; - object_name_ptr = 0; - object_name.Zero(); - attributes = 0; - } -}; -static_assert_size(X_OBJECT_ATTRIBUTES, 12 + sizeof(X_ANSI_STRING)); - - // Values seem to be all over the place - GUIDs? typedef uint32_t XNotificationID; // http://ffplay360.googlecode.com/svn/trunk/Common/XTLOnPC.h struct X_VIDEO_MODE { - uint32_t display_width; - uint32_t display_height; - uint32_t is_interlaced; - uint32_t is_widescreen; - uint32_t is_hi_def; - float refresh_rate; - uint32_t video_standard; - uint32_t unknown_0x8a; - uint32_t unknown_0x01; - uint32_t reserved[3]; + be display_width; + be display_height; + be is_interlaced; + be is_widescreen; + be is_hi_def; + be refresh_rate; + be video_standard; + be unknown_0x8a; + be unknown_0x01; + be reserved[3]; }; static_assert_size(X_VIDEO_MODE, 48); -typedef enum _X_INPUT_FLAG { +enum X_INPUT_FLAG { X_INPUT_FLAG_GAMEPAD = 0x00000001, -} X_INPUT_FLAG; +}; -typedef enum _X_INPUT_GAMEPAD_BUTTON { +enum X_INPUT_GAMEPAD_BUTTON { X_INPUT_GAMEPAD_DPAD_UP = 0x0001, X_INPUT_GAMEPAD_DPAD_DOWN = 0x0002, X_INPUT_GAMEPAD_DPAD_LEFT = 0x0004, @@ -355,7 +312,7 @@ typedef enum _X_INPUT_GAMEPAD_BUTTON { X_INPUT_GAMEPAD_B = 0x2000, X_INPUT_GAMEPAD_X = 0x4000, X_INPUT_GAMEPAD_Y = 0x8000, -} X_INPUT_GAMEPAD_BUTTON; +}; struct X_INPUT_GAMEPAD { be buttons; From 29dd4b948356df965d3d6f5e35a6054b09d3f1f4 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 20 Aug 2014 11:17:05 -0700 Subject: [PATCH 141/388] Create README.md --- src/xenia/core/README.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/xenia/core/README.md diff --git a/src/xenia/core/README.md b/src/xenia/core/README.md new file mode 100644 index 000000000..8fa35ec20 --- /dev/null +++ b/src/xenia/core/README.md @@ -0,0 +1,6 @@ +TODO(benvanik): remove all of this code. + +* hash can be moved to util/ +* ref can be removed when run_loop is rewritten +* run_loop should be moved to ui/ (perhaps) +* socket can be moved to poly From 7fc87730e2b8259d592bc81a05060634a166293b Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 20 Aug 2014 11:19:31 -0700 Subject: [PATCH 142/388] Create README.md --- src/README.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/README.md diff --git a/src/README.md b/src/README.md new file mode 100644 index 000000000..47240caca --- /dev/null +++ b/src/README.md @@ -0,0 +1,6 @@ +All code (headers and sources) lives under this path, excluding third_party code. + +* alloy: the dynamic recompiler that parses PPC and generates code. +* poly: a lightweight cross-platform/compiler compatibility library. +* xdb: xenia debugger library and UI. +* xenia: emulator code. From c38cf294f597dd84f305c00c555e439311fdc072 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 20 Aug 2014 11:27:05 -0700 Subject: [PATCH 143/388] Create README.md --- src/poly/README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/poly/README.md diff --git a/src/poly/README.md b/src/poly/README.md new file mode 100644 index 000000000..a221bae4a --- /dev/null +++ b/src/poly/README.md @@ -0,0 +1,25 @@ +poly is a lightweight cross-platform/compiler compatibility library. + +This library presupposes C++11/14 support. As more compilers get C++14 it will +assume that. + +Other parts of the project use this to avoid creating spaghetti linkage. Code +specific to the emulator should be kept out, as not all of the projects that +depend on this need it. + +Where possible, C++11/14 STL should be used instead of adding any code in here, and +the code should be kept as small as possible (by reusing STL/etc). Third party +dependencies should be kept to a minimum. + +Target compilers: +* MSVC++ 2013+ +* Clang 3.4+ +* GCC 4.8+. + +Target platforms: +* Windows 8+ (`_win.cc` suffix) +* Mac OSX 10.9+ (`_mac.cc` suffix, falling back to `_posix.cc`) +* Linux ? (`_posix.cc` suffix) + +Avoid the use of platform-specific #ifdefs and instead try to put all +platform-specific code in the appropriately suffixed cc files. From 609d7c755f260e86a865703dc1dcd6df064b1fa0 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 20 Aug 2014 11:35:22 -0700 Subject: [PATCH 144/388] Create README.md --- src/alloy/README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/alloy/README.md diff --git a/src/alloy/README.md b/src/alloy/README.md new file mode 100644 index 000000000..f3b64bcc8 --- /dev/null +++ b/src/alloy/README.md @@ -0,0 +1,30 @@ +alloy: small dynamic recompiler engine +=== + +Alloy is a transpiler framework that allows for pluggable frontends for decoding +guest machine instructions (such as PPC) and pluggable backends for generating +host code (such as x64). It features an SSA IR designed to model machine +instructions and vector operations and compilation passes that seek to efficiently +optimize previously-optimized code. + +Future versions will cache generated code across runs and enable offline +precompilation. + +Frontends +--- + +Frontends are responsible for translating guest machine instructions into IR. +Information about the guest machine and ABI is used to support efficient CPU +state accesses and debug information. + +* PPC64 with Altivec extenions + +Backends +--- + +A backend takes optimized IR and assembles an implementation-specific result. +The backend is also responsible for executing the code it generates and supporting +debugging features (such as breakpoints). + +* IVM: bytecode interpreter +* x64: IA-64 with AVX2 code generator From cecf83b7b754bc48dee63722cb11feb5eb3d9457 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 20 Aug 2014 22:22:47 -0700 Subject: [PATCH 145/388] Removing xenia/malloc.* Using standard memory functions now. --- src/alloy/arena.cc | 8 +- src/alloy/backend/ivm/ivm_function.cc | 8 +- src/alloy/backend/ivm/ivm_stack.cc | 4 +- src/alloy/backend/x64/x64_assembler.cc | 3 +- src/alloy/backend/x64/x64_code_cache_posix.cc | 2 +- .../passes/register_allocation_pass.cc | 2 +- src/alloy/core.h | 1 - src/alloy/frontend/ppc/ppc_hir_builder.cc | 6 +- src/alloy/frontend/ppc/ppc_instr_tables.h | 4 +- src/alloy/hir/hir_builder.cc | 2 +- src/alloy/runtime/debug_info.cc | 10 +- src/xenia/common.h | 1 - src/xenia/core/ref.cc | 11 +- src/xenia/core/socket_posix.cc | 65 ++++--- src/xenia/cpu/xenon_thread_state.cc | 5 +- src/xenia/gpu/register_file.cc | 9 +- src/xenia/gpu/shader_resource.cc | 163 +++++++++--------- .../kernel/fs/devices/disc_image_file.cc | 5 +- .../kernel/fs/devices/stfs_container_file.cc | 2 +- src/xenia/kernel/fs/gdfx.cc | 11 +- src/xenia/kernel/fs/stfs.cc | 16 +- src/xenia/kernel/object_table.cc | 16 +- src/xenia/kernel/objects/xfile.h | 9 +- src/xenia/kernel/objects/xuser_module.cc | 7 +- src/xenia/kernel/util/xex2.cc | 125 ++++++-------- src/xenia/kernel/xboxkrnl_io.cc | 42 ++--- src/xenia/kernel/xboxkrnl_memory.cc | 2 +- src/xenia/kernel/xboxkrnl_module.cc | 4 +- src/xenia/kernel/xboxkrnl_strings.cc | 8 +- src/xenia/kernel/xboxkrnl_video.cc | 10 +- src/xenia/malloc.cc | 137 --------------- src/xenia/malloc.h | 36 ---- src/xenia/memory.cc | 4 +- src/xenia/sources.gypi | 2 - src/xenia/xbox.h | 2 +- tools/alloy-sandbox/alloy-sandbox.cc | 5 +- 36 files changed, 266 insertions(+), 481 deletions(-) delete mode 100644 src/xenia/malloc.cc delete mode 100644 src/xenia/malloc.h diff --git a/src/alloy/arena.cc b/src/alloy/arena.cc index 66632e57d..081467e72 100644 --- a/src/alloy/arena.cc +++ b/src/alloy/arena.cc @@ -73,11 +73,11 @@ void* Arena::CloneContents() { } chunk = chunk->next; } - void* result = xe_malloc(total_length); + void* result = malloc(total_length); uint8_t* p = (uint8_t*)result; chunk = head_chunk_; while (chunk) { - xe_copy_struct(p, chunk->buffer, chunk->offset); + memcpy(p, chunk->buffer, chunk->offset); p += chunk->offset; if (chunk == active_chunk_) { break; @@ -89,12 +89,12 @@ void* Arena::CloneContents() { Arena::Chunk::Chunk(size_t chunk_size) : next(nullptr), capacity(chunk_size), buffer(0), offset(0) { - buffer = (uint8_t*)xe_malloc(capacity); + buffer = reinterpret_cast(malloc(capacity)); } Arena::Chunk::~Chunk() { if (buffer) { - xe_free(buffer); + free(buffer); } } diff --git a/src/alloy/backend/ivm/ivm_function.cc b/src/alloy/backend/ivm/ivm_function.cc index 2dba04264..aab30ce7b 100644 --- a/src/alloy/backend/ivm/ivm_function.cc +++ b/src/alloy/backend/ivm/ivm_function.cc @@ -25,13 +25,13 @@ IVMFunction::IVMFunction(FunctionInfo* symbol_info) : Function(symbol_info), register_count_(0), intcode_count_(0), - intcodes_(0), + intcodes_(nullptr), source_map_count_(0), - source_map_(0) {} + source_map_(nullptr) {} IVMFunction::~IVMFunction() { - xe_free(intcodes_); - xe_free(source_map_); + free(intcodes_); + free(source_map_); } void IVMFunction::Setup(TranslationContext& ctx) { diff --git a/src/alloy/backend/ivm/ivm_stack.cc b/src/alloy/backend/ivm/ivm_stack.cc index 5177ed351..1e80e4073 100644 --- a/src/alloy/backend/ivm/ivm_stack.cc +++ b/src/alloy/backend/ivm/ivm_stack.cc @@ -65,12 +65,12 @@ void IVMStack::Free(size_t register_count) { IVMStack::Chunk::Chunk(size_t chunk_size) : prev(NULL), next(NULL), capacity(chunk_size), buffer(0), offset(0) { - buffer = (uint8_t*)xe_malloc(capacity); + buffer = reinterpret_cast(malloc(capacity)); } IVMStack::Chunk::~Chunk() { if (buffer) { - xe_free(buffer); + free(buffer); } } diff --git a/src/alloy/backend/x64/x64_assembler.cc b/src/alloy/backend/x64/x64_assembler.cc index 34b8928b2..2b4075df2 100644 --- a/src/alloy/backend/x64/x64_assembler.cc +++ b/src/alloy/backend/x64/x64_assembler.cc @@ -93,8 +93,7 @@ int X64Assembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder, void X64Assembler::DumpMachineCode(DebugInfo* debug_info, void* machine_code, size_t code_size, StringBuffer* str) { - BE::DISASM disasm; - xe_zero_struct(&disasm, sizeof(disasm)); + BE::DISASM disasm = {0}; disasm.Archi = 64; disasm.Options = BE::Tabulation + BE::MasmSyntax + BE::PrefixedNumeral; disasm.EIP = (BE::UIntPtr)machine_code; diff --git a/src/alloy/backend/x64/x64_code_cache_posix.cc b/src/alloy/backend/x64/x64_code_cache_posix.cc index 63a44e709..0fa023ab5 100644 --- a/src/alloy/backend/x64/x64_code_cache_posix.cc +++ b/src/alloy/backend/x64/x64_code_cache_posix.cc @@ -76,7 +76,7 @@ void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size, lock_.unlock(); // Copy code. - xe_copy_struct(final_address, machine_code, code_size); + memcpy(final_address, machine_code, code_size); return final_address; } diff --git a/src/alloy/compiler/passes/register_allocation_pass.cc b/src/alloy/compiler/passes/register_allocation_pass.cc index cdfe910ad..2e4f6fc21 100644 --- a/src/alloy/compiler/passes/register_allocation_pass.cc +++ b/src/alloy/compiler/passes/register_allocation_pass.cc @@ -33,7 +33,7 @@ RegisterAllocationPass::RegisterAllocationPass(const MachineInfo* machine_info) // Initialize register sets. // TODO(benvanik): rewrite in a way that makes sense - this is terrible. auto mi_sets = machine_info->register_sets; - xe_zero_struct(&usage_sets_, sizeof(usage_sets_)); + memset(&usage_sets_, 0, sizeof(usage_sets_)); uint32_t n = 0; while (mi_sets[n].count) { auto& mi_set = mi_sets[n]; diff --git a/src/alloy/core.h b/src/alloy/core.h index e8a2c6637..08c6e2645 100644 --- a/src/alloy/core.h +++ b/src/alloy/core.h @@ -12,7 +12,6 @@ // TODO(benvanik): move the common stuff into here? #include -#include #include #endif // ALLOY_CORE_H_ diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index 627c4cac8..9078bfa3f 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -69,8 +69,8 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) { size_t list_size = instr_count_ * sizeof(void*); instr_offset_list_ = (Instr**)arena_->Alloc(list_size); label_list_ = (Label**)arena_->Alloc(list_size); - xe_zero_struct(instr_offset_list_, list_size); - xe_zero_struct(label_list_, list_size); + memset(instr_offset_list_, 0, list_size); + memset(label_list_, 0, list_size); // Always mark entry with label. label_list_[0] = NewLabel(); @@ -171,7 +171,7 @@ void PPCHIRBuilder::AnnotateLabel(uint64_t address, Label* label) { snprintf(name_buffer, poly::countof(name_buffer), "loc_%.8X", (uint32_t)address); label->name = (char*)arena_->Alloc(sizeof(name_buffer)); - xe_copy_struct(label->name, name_buffer, sizeof(name_buffer)); + memcpy(label->name, name_buffer, sizeof(name_buffer)); } FunctionInfo* PPCHIRBuilder::LookupFunction(uint64_t address) { diff --git a/src/alloy/frontend/ppc/ppc_instr_tables.h b/src/alloy/frontend/ppc/ppc_instr_tables.h index ccab23c49..bab5e48f1 100644 --- a/src/alloy/frontend/ppc/ppc_instr_tables.h +++ b/src/alloy/frontend/ppc/ppc_instr_tables.h @@ -95,7 +95,7 @@ namespace tables { static InstrType** instr_table_prep(InstrType* unprep, size_t unprep_count, int a, int b) { int prep_count = (int)pow(2.0, b - a + 1); - InstrType** prep = (InstrType**)xe_calloc(prep_count * sizeof(void*)); + InstrType** prep = (InstrType**)calloc(prep_count, sizeof(void*)); for (int n = 0; n < unprep_count; n++) { int ordinal = select_bits(unprep[n].opcode, a, b); prep[ordinal] = &unprep[n]; @@ -107,7 +107,7 @@ static InstrType** instr_table_prep_63(InstrType* unprep, size_t unprep_count, int a, int b) { // Special handling for A format instructions. int prep_count = (int)pow(2.0, b - a + 1); - InstrType** prep = (InstrType**)xe_calloc(prep_count * sizeof(void*)); + InstrType** prep = (InstrType**)calloc(prep_count, sizeof(void*)); for (int n = 0; n < unprep_count; n++) { int ordinal = select_bits(unprep[n].opcode, a, b); if (unprep[n].format == kXEPPCInstrFormatA) { diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index 2a0bec6f3..72871413f 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -632,7 +632,7 @@ void HIRBuilder::Comment(const char* format, ...) { return; } void* p = arena_->Alloc(len + 1); - xe_copy_struct(p, buffer, len + 1); + memcpy(p, buffer, len + 1); Instr* i = AppendInstr(OPCODE_COMMENT_info, 0); i->src1.offset = (uint64_t)p; i->src2.value = i->src3.value = NULL; diff --git a/src/alloy/runtime/debug_info.cc b/src/alloy/runtime/debug_info.cc index 64022868c..0eac0b795 100644 --- a/src/alloy/runtime/debug_info.cc +++ b/src/alloy/runtime/debug_info.cc @@ -21,11 +21,11 @@ DebugInfo::DebugInfo() source_map_(nullptr) {} DebugInfo::~DebugInfo() { - xe_free(source_map_); - xe_free(source_disasm_); - xe_free(raw_hir_disasm_); - xe_free(hir_disasm_); - xe_free(machine_code_disasm_); + free(source_map_); + free(source_disasm_); + free(raw_hir_disasm_); + free(hir_disasm_); + free(machine_code_disasm_); } void DebugInfo::InitializeSourceMap(size_t source_map_count, diff --git a/src/xenia/common.h b/src/xenia/common.h index 3b911ea0f..821b83cc7 100644 --- a/src/xenia/common.h +++ b/src/xenia/common.h @@ -17,7 +17,6 @@ #include #include -#include #include #include diff --git a/src/xenia/core/ref.cc b/src/xenia/core/ref.cc index c09c613eb..de0347ca5 100644 --- a/src/xenia/core/ref.cc +++ b/src/xenia/core/ref.cc @@ -9,14 +9,9 @@ #include +void xe_ref_init(xe_ref_t* ref) { ref->count = 1; } -void xe_ref_init(xe_ref_t* ref) { - ref->count = 1; -} - -void xe_ref_retain(xe_ref_t* ref) { - poly::atomic_inc(&ref->count); -} +void xe_ref_retain(xe_ref_t* ref) { poly::atomic_inc(&ref->count); } void xe_ref_release(xe_ref_t* ref, xe_ref_dealloc_t dealloc) { if (!ref) { @@ -26,6 +21,6 @@ void xe_ref_release(xe_ref_t* ref, xe_ref_dealloc_t dealloc) { if (dealloc) { dealloc(ref); } - xe_free(ref); + free(ref); } } diff --git a/src/xenia/core/socket_posix.cc b/src/xenia/core/socket_posix.cc index 1d9acbf5d..5b815e1c2 100644 --- a/src/xenia/core/socket_posix.cc +++ b/src/xenia/core/socket_posix.cc @@ -15,7 +15,6 @@ #include #include - void xe_socket_init() { // No-op. } @@ -35,31 +34,30 @@ void xe_socket_close(socket_t socket) { void xe_socket_set_keepalive(socket_t socket, bool value) { int opt_value = value ? 1 : 0; - setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, - &opt_value, sizeof(opt_value)); + setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &opt_value, sizeof(opt_value)); } void xe_socket_set_reuseaddr(socket_t socket, bool value) { int opt_value = value ? 1 : 0; - setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, - &opt_value, sizeof(opt_value)); + setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &opt_value, sizeof(opt_value)); } void xe_socket_set_nodelay(socket_t socket, bool value) { int opt_value = value ? 1 : 0; - setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, - &opt_value, sizeof(opt_value)); + setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, &opt_value, sizeof(opt_value)); } void xe_socket_set_nonblock(socket_t socket, bool value) { int flags; - while ((flags = fcntl(socket, F_GETFL, 0)) == -1 && errno == EINTR); + while ((flags = fcntl(socket, F_GETFL, 0)) == -1 && errno == EINTR) + ; if (flags == -1) { return; } int r; while ((r = fcntl(socket, F_SETFL, flags | O_NONBLOCK)) == -1 && - errno == EINTR); + errno == EINTR) + ; if (r == -1) { return; } @@ -67,9 +65,9 @@ void xe_socket_set_nonblock(socket_t socket, bool value) { int xe_socket_bind(socket_t socket, uint32_t port) { struct sockaddr_in socket_addr; - socket_addr.sin_family = AF_INET; + socket_addr.sin_family = AF_INET; socket_addr.sin_addr.s_addr = htonl(INADDR_ANY); - socket_addr.sin_port = htons(port); + socket_addr.sin_port = htons(port); int r = bind(socket, (struct sockaddr*)&socket_addr, sizeof(socket_addr)); if (r < 0) { return 1; @@ -79,9 +77,9 @@ int xe_socket_bind(socket_t socket, uint32_t port) { int xe_socket_bind_loopback(socket_t socket) { struct sockaddr_in socket_addr; - socket_addr.sin_family = AF_INET; + socket_addr.sin_family = AF_INET; socket_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - socket_addr.sin_port = htons(0); + socket_addr.sin_port = htons(0); int r = bind(socket, (struct sockaddr*)&socket_addr, sizeof(socket_addr)); if (r == SOCKET_ERROR) { return 1; @@ -100,8 +98,8 @@ int xe_socket_listen(socket_t socket) { int xe_socket_accept(socket_t socket, xe_socket_connection_t* out_client_info) { struct sockaddr_in client_addr; socklen_t client_count = sizeof(client_addr); - socket_t client_socket_id = accept( - socket, (struct sockaddr*)&client_addr, &client_count); + socket_t client_socket_id = + accept(socket, (struct sockaddr*)&client_addr, &client_count); if (client_socket_id < 0) { return 1; } @@ -109,8 +107,8 @@ int xe_socket_accept(socket_t socket, xe_socket_connection_t* out_client_info) { out_client_info->socket = client_socket_id; int client_ip = client_addr.sin_addr.s_addr; - inet_ntop(AF_INET, &client_ip, - out_client_info->addr, XECOUNT(out_client_info->addr)); + inet_ntop(AF_INET, &client_ip, out_client_info->addr, + XECOUNT(out_client_info->addr)); return 0; } @@ -130,21 +128,21 @@ int64_t xe_socket_recv(socket_t socket, uint8_t* data, size_t length, int flags, } struct xe_socket_loop { - socket_t socket; + socket_t socket; - int notify_rd_id; - int notify_wr_id; + int notify_rd_id; + int notify_wr_id; struct pollfd events[2]; - bool pending_queued_write; - bool pending_recv; - bool pending_send; + bool pending_queued_write; + bool pending_recv; + bool pending_send; }; xe_socket_loop_t* xe_socket_loop_create(socket_t socket) { - xe_socket_loop_t* loop = (xe_socket_loop_t*)xe_calloc( - sizeof(xe_socket_loop_t)); + xe_socket_loop_t* loop = + (xe_socket_loop_t*)calloc(1, sizeof(xe_socket_loop_t)); loop->socket = socket; @@ -153,10 +151,10 @@ xe_socket_loop_t* xe_socket_loop_create(socket_t socket) { loop->notify_rd_id = notify_ids[0]; loop->notify_wr_id = notify_ids[1]; - loop->events[0].fd = socket; - loop->events[0].events = POLLIN; - loop->events[1].fd = loop->notify_rd_id; - loop->events[1].events = POLLIN; + loop->events[0].fd = socket; + loop->events[0].events = POLLIN; + loop->events[1].fd = loop->notify_rd_id; + loop->events[1].events = POLLIN; return loop; } @@ -164,11 +162,11 @@ xe_socket_loop_t* xe_socket_loop_create(socket_t socket) { void xe_socket_loop_destroy(xe_socket_loop_t* loop) { close(loop->notify_rd_id); close(loop->notify_wr_id); - xe_free(loop); + free(loop); } -int xe_socket_loop_poll(xe_socket_loop_t* loop, - bool check_read, bool check_write) { +int xe_socket_loop_poll(xe_socket_loop_t* loop, bool check_read, + bool check_write) { // Prep events object. if (check_read) { loop->events[0].events |= POLLIN; @@ -180,7 +178,8 @@ int xe_socket_loop_poll(xe_socket_loop_t* loop, // Poll. int r; while ((r = poll(loop->events, XECOUNT(loop->events), -1)) == -1 && - errno == EINTR); + errno == EINTR) + ; if (r == -1) { return 1; } diff --git a/src/xenia/cpu/xenon_thread_state.cc b/src/xenia/cpu/xenon_thread_state.cc index e2abd64a1..0cdf90b38 100644 --- a/src/xenia/cpu/xenon_thread_state.cc +++ b/src/xenia/cpu/xenon_thread_state.cc @@ -28,9 +28,8 @@ XenonThreadState::XenonThreadState(XenonRuntime* runtime, uint32_t thread_id, assert_not_zero(stack_address_); // Allocate with 64b alignment. - context_ = (PPCContext*)xe_malloc_aligned(sizeof(PPCContext)); + context_ = (PPCContext*)calloc(1, sizeof(PPCContext)); assert_true(((uint64_t)context_ & 0xF) == 0); - xe_zero_struct(context_, sizeof(PPCContext)); // Stash pointers to common structures that callbacks may need. context_->reserve_address = memory_->reserve_address(); @@ -55,7 +54,7 @@ XenonThreadState::XenonThreadState(XenonRuntime* runtime, uint32_t thread_id, XenonThreadState::~XenonThreadState() { runtime_->debugger()->OnThreadDestroyed(this); - xe_free_aligned(context_); + free(context_); xenon_memory()->HeapFree(stack_address_, stack_size_); } diff --git a/src/xenia/gpu/register_file.cc b/src/xenia/gpu/register_file.cc index 288881d58..a2eec25fe 100644 --- a/src/xenia/gpu/register_file.cc +++ b/src/xenia/gpu/register_file.cc @@ -9,19 +9,16 @@ #include - using namespace xe; using namespace xe::gpu; - -RegisterFile::RegisterFile() { - xe_zero_struct(values, sizeof(values)); -} +RegisterFile::RegisterFile() { memset(values, 0, sizeof(values)); } const char* RegisterFile::GetRegisterName(uint32_t index) { switch (index) { #define XE_GPU_REGISTER(index, type, name) \ - case index: return #name; + case index: \ + return #name; #include #undef XE_GPU_REGISTER default: diff --git a/src/xenia/gpu/shader_resource.cc b/src/xenia/gpu/shader_resource.cc index 42986bf74..0d7447168 100644 --- a/src/xenia/gpu/shader_resource.cc +++ b/src/xenia/gpu/shader_resource.cc @@ -12,21 +12,21 @@ #include #include - using namespace std; using namespace xe; using namespace xe::gpu; using namespace xe::gpu::xenos; - ShaderResource::ShaderResource(const MemoryRange& memory_range, - const Info& info, - xenos::XE_GPU_SHADER_TYPE type) + const Info& info, xenos::XE_GPU_SHADER_TYPE type) : HashedResource(memory_range), - info_(info), type_(type), is_prepared_(false), disasm_src_(nullptr) { - xe_zero_struct(&alloc_counts_, sizeof(alloc_counts_)); - xe_zero_struct(&buffer_inputs_, sizeof(buffer_inputs_)); - xe_zero_struct(&sampler_inputs_, sizeof(sampler_inputs_)); + info_(info), + type_(type), + is_prepared_(false), + disasm_src_(nullptr) { + memset(&alloc_counts_, 0, sizeof(alloc_counts_)); + memset(&buffer_inputs_, 0, sizeof(buffer_inputs_)); + memset(&sampler_inputs_, 0, sizeof(sampler_inputs_)); // Verify. dword_count_ = memory_range.length / 4; @@ -34,7 +34,7 @@ ShaderResource::ShaderResource(const MemoryRange& memory_range, // Copy bytes and swap. size_t byte_size = dword_count_ * sizeof(uint32_t); - dwords_ = (uint32_t*)xe_malloc(byte_size); + dwords_ = (uint32_t*)malloc(byte_size); for (uint32_t n = 0; n < dword_count_; n++) { dwords_[n] = poly::load_and_swap(memory_range.host_base + n * 4); } @@ -47,8 +47,8 @@ ShaderResource::ShaderResource(const MemoryRange& memory_range, } ShaderResource::~ShaderResource() { - xe_free(disasm_src_); - xe_free(dwords_); + free(disasm_src_); + free(dwords_); } void ShaderResource::GatherIO() { @@ -83,18 +83,18 @@ void ShaderResource::GatherAlloc(const instr_cf_alloc_t* cf) { allocs_.push_back(*cf); switch (cf->buffer_select) { - case SQ_POSITION: - // Position (SV_POSITION). - alloc_counts_.positions += cf->size + 1; - break; - case SQ_PARAMETER_PIXEL: - // Output to PS (if VS), or frag output (if PS). - alloc_counts_.params += cf->size + 1; - break; - case SQ_MEMORY: - // MEMEXPORT? - alloc_counts_.memories += cf->size + 1; - break; + case SQ_POSITION: + // Position (SV_POSITION). + alloc_counts_.positions += cf->size + 1; + break; + case SQ_PARAMETER_PIXEL: + // Output to PS (if VS), or frag output (if PS). + alloc_counts_.params += cf->size + 1; + break; + case SQ_MEMORY: + // MEMEXPORT? + alloc_counts_.memories += cf->size + 1; + break; } } @@ -109,27 +109,26 @@ void ShaderResource::GatherExec(const instr_cf_exec_t* cf) { const instr_fetch_t* fetch = (const instr_fetch_t*)(dwords_ + alu_off * 3); switch (fetch->opc) { - case VTX_FETCH: - GatherVertexFetch(&fetch->vtx); - break; - case TEX_FETCH: - GatherTextureFetch(&fetch->tex); - break; - case TEX_GET_BORDER_COLOR_FRAC: - case TEX_GET_COMP_TEX_LOD: - case TEX_GET_GRADIENTS: - case TEX_GET_WEIGHTS: - case TEX_SET_TEX_LOD: - case TEX_SET_GRADIENTS_H: - case TEX_SET_GRADIENTS_V: - default: - assert_always(); - break; + case VTX_FETCH: + GatherVertexFetch(&fetch->vtx); + break; + case TEX_FETCH: + GatherTextureFetch(&fetch->tex); + break; + case TEX_GET_BORDER_COLOR_FRAC: + case TEX_GET_COMP_TEX_LOD: + case TEX_GET_GRADIENTS: + case TEX_GET_WEIGHTS: + case TEX_SET_TEX_LOD: + case TEX_SET_GRADIENTS_H: + case TEX_SET_GRADIENTS_V: + default: + assert_always(); + break; } } else { // TODO(benvanik): gather registers used, predicate bits used, etc. - const instr_alu_t* alu = - (const instr_alu_t*)(dwords_ + alu_off * 3); + const instr_alu_t* alu = (const instr_alu_t*)(dwords_ + alu_off * 3); if (alu->vector_write_mask) { if (alu->export_data && alu->vector_dest == 63) { alloc_counts_.point_size = true; @@ -213,39 +212,39 @@ void ShaderResource::GatherVertexFetch(const instr_fetch_vtx_t* vtx) { el->offset_words = vtx->offset; el->size_words = 0; switch (el->format) { - case FMT_8_8_8_8: - case FMT_2_10_10_10: - case FMT_10_11_11: - case FMT_11_11_10: - el->size_words = 1; - break; - case FMT_16_16: - case FMT_16_16_FLOAT: - el->size_words = 1; - break; - case FMT_16_16_16_16: - case FMT_16_16_16_16_FLOAT: - el->size_words = 2; - break; - case FMT_32: - case FMT_32_FLOAT: - el->size_words = 1; - break; - case FMT_32_32: - case FMT_32_32_FLOAT: - el->size_words = 2; - break; - case FMT_32_32_32_FLOAT: - el->size_words = 3; - break; - case FMT_32_32_32_32: - case FMT_32_32_32_32_FLOAT: - el->size_words = 4; - break; - default: - XELOGE("Unknown vertex format: %d", el->format); - assert_always(); - break; + case FMT_8_8_8_8: + case FMT_2_10_10_10: + case FMT_10_11_11: + case FMT_11_11_10: + el->size_words = 1; + break; + case FMT_16_16: + case FMT_16_16_FLOAT: + el->size_words = 1; + break; + case FMT_16_16_16_16: + case FMT_16_16_16_16_FLOAT: + el->size_words = 2; + break; + case FMT_32: + case FMT_32_FLOAT: + el->size_words = 1; + break; + case FMT_32_32: + case FMT_32_32_FLOAT: + el->size_words = 2; + break; + case FMT_32_32_32_FLOAT: + el->size_words = 3; + break; + case FMT_32_32_32_32: + case FMT_32_32_32_32_FLOAT: + el->size_words = 4; + break; + default: + XELOGE("Unknown vertex format: %d", el->format); + assert_always(); + break; } } @@ -255,22 +254,20 @@ void ShaderResource::GatherTextureFetch(const xenos::instr_fetch_tex_t* tex) { assert_true(sampler_inputs_.count + 1 < poly::countof(sampler_inputs_.descs)); auto& input = sampler_inputs_.descs[sampler_inputs_.count++]; input.input_index = sampler_inputs_.count - 1; - input.fetch_slot = tex->const_idx & 0xF; // ? + input.fetch_slot = tex->const_idx & 0xF; // ? input.tex_fetch = *tex; // Format mangling, size estimation, etc. } -VertexShaderResource::VertexShaderResource( - const MemoryRange& memory_range, const Info& info) - : ShaderResource(memory_range, info, XE_GPU_SHADER_TYPE_VERTEX) { -} +VertexShaderResource::VertexShaderResource(const MemoryRange& memory_range, + const Info& info) + : ShaderResource(memory_range, info, XE_GPU_SHADER_TYPE_VERTEX) {} VertexShaderResource::~VertexShaderResource() = default; -PixelShaderResource::PixelShaderResource( - const MemoryRange& memory_range, const Info& info) - : ShaderResource(memory_range, info, XE_GPU_SHADER_TYPE_PIXEL) { -} +PixelShaderResource::PixelShaderResource(const MemoryRange& memory_range, + const Info& info) + : ShaderResource(memory_range, info, XE_GPU_SHADER_TYPE_PIXEL) {} PixelShaderResource::~PixelShaderResource() = default; diff --git a/src/xenia/kernel/fs/devices/disc_image_file.cc b/src/xenia/kernel/fs/devices/disc_image_file.cc index 45db575f0..82afb41f1 100644 --- a/src/xenia/kernel/fs/devices/disc_image_file.cc +++ b/src/xenia/kernel/fs/devices/disc_image_file.cc @@ -21,7 +21,7 @@ namespace fs { DiscImageFile::DiscImageFile(KernelState* kernel_state, Mode mode, DiscImageEntry* entry) - : entry_(entry), XFile(kernel_state, mode) {} + : XFile(kernel_state, mode), entry_(entry) {} DiscImageFile::~DiscImageFile() {} @@ -59,8 +59,7 @@ X_STATUS DiscImageFile::ReadSync(void* buffer, size_t buffer_length, } size_t real_offset = gdfx_entry->offset + byte_offset; size_t real_length = std::min(buffer_length, gdfx_entry->size - byte_offset); - xe_copy_memory(buffer, buffer_length, entry_->mmap()->data() + real_offset, - real_length); + memcpy(buffer, entry_->mmap()->data() + real_offset, real_length); *out_bytes_read = real_length; return X_STATUS_SUCCESS; } diff --git a/src/xenia/kernel/fs/devices/stfs_container_file.cc b/src/xenia/kernel/fs/devices/stfs_container_file.cc index 32529fd95..fa7750c57 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_file.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_file.cc @@ -78,7 +78,7 @@ X_STATUS STFSContainerFile::ReadSync(void* buffer, size_t buffer_length, offset += byte_offset % 4096; read_length = std::min(read_length, record.length - (byte_offset % 4096)); } - xe_copy_struct(dest_ptr, entry_->mmap()->data() + offset, read_length); + memcpy(dest_ptr, entry_->mmap()->data() + offset, read_length); dest_ptr += read_length; remaining_length -= read_length; } diff --git a/src/xenia/kernel/fs/gdfx.cc b/src/xenia/kernel/fs/gdfx.cc index 1b722ad46..7eb8b43b2 100644 --- a/src/xenia/kernel/fs/gdfx.cc +++ b/src/xenia/kernel/fs/gdfx.cc @@ -50,19 +50,14 @@ void GDFXEntry::Dump(int indent) { } } -GDFX::GDFX(poly::MappedMemory* mmap) : mmap_(mmap) { - root_entry_ = nullptr; -} +GDFX::GDFX(poly::MappedMemory* mmap) : mmap_(mmap) { root_entry_ = nullptr; } -GDFX::~GDFX() { - delete root_entry_; -} +GDFX::~GDFX() { delete root_entry_; } GDFXEntry* GDFX::root_entry() { return root_entry_; } GDFX::Error GDFX::Load() { - ParseState state; - xe_zero_struct(&state, sizeof(state)); + ParseState state = {0}; state.ptr = mmap_->data(); state.size = mmap_->size(); diff --git a/src/xenia/kernel/fs/stfs.cc b/src/xenia/kernel/fs/stfs.cc index bf6ec0617..bc0483bff 100644 --- a/src/xenia/kernel/fs/stfs.cc +++ b/src/xenia/kernel/fs/stfs.cc @@ -37,15 +37,15 @@ bool STFSVolumeDescriptor::Read(const uint8_t* p) { block_separation = poly::load_and_swap(p + 0x02); file_table_block_count = poly::load_and_swap(p + 0x03); file_table_block_number = XEGETUINT24BE(p + 0x05); - xe_copy_struct(top_hash_table_hash, p + 0x08, 0x14); + memcpy(top_hash_table_hash, p + 0x08, 0x14); total_allocated_block_count = poly::load_and_swap(p + 0x1C); total_unallocated_block_count = poly::load_and_swap(p + 0x20); return true; }; bool STFSHeader::Read(const uint8_t* p) { - xe_copy_struct(license_entries, p + 0x22C, 0x100); - xe_copy_struct(header_hash, p + 0x32C, 0x14); + memcpy(license_entries, p + 0x22C, 0x100); + memcpy(header_hash, p + 0x32C, 0x14); header_size = poly::load_and_swap(p + 0x340); content_type = (STFSContentType)poly::load_and_swap(p + 0x344); metadata_version = poly::load_and_swap(p + 0x348); @@ -64,8 +64,8 @@ bool STFSHeader::Read(const uint8_t* p) { disc_number = poly::load_and_swap(p + 0x366); disc_in_set = poly::load_and_swap(p + 0x367); save_game_id = poly::load_and_swap(p + 0x368); - xe_copy_struct(console_id, p + 0x36C, 0x5); - xe_copy_struct(profile_id, p + 0x371, 0x8); + memcpy(console_id, p + 0x36C, 0x5); + memcpy(profile_id, p + 0x371, 0x8); data_file_count = poly::load_and_swap(p + 0x39D); data_file_combined_size = poly::load_and_swap(p + 0x3A1); descriptor_type = (STFSDescriptorType)poly::load_and_swap(p + 0x3A9); @@ -76,7 +76,7 @@ bool STFSHeader::Read(const uint8_t* p) { if (!volume_descriptor.Read(p + 0x379)) { return false; } - xe_copy_struct(device_id, p + 0x3FD, 0x14); + memcpy(device_id, p + 0x3FD, 0x14); for (size_t n = 0; n < 0x900 / 2; n++) { display_names[n] = poly::load_and_swap(p + 0x411 + n * 2); display_descs[n] = poly::load_and_swap(p + 0xD11 + n * 2); @@ -88,8 +88,8 @@ bool STFSHeader::Read(const uint8_t* p) { transfer_flags = poly::load_and_swap(p + 0x1711); thumbnail_image_size = poly::load_and_swap(p + 0x1712); title_thumbnail_image_size = poly::load_and_swap(p + 0x1716); - xe_copy_struct(thumbnail_image, p + 0x171A, 0x4000); - xe_copy_struct(title_thumbnail_image, p + 0x571A, 0x4000); + memcpy(thumbnail_image, p + 0x171A, 0x4000); + memcpy(title_thumbnail_image, p + 0x571A, 0x4000); return true; } diff --git a/src/xenia/kernel/object_table.cc b/src/xenia/kernel/object_table.cc index 2b2541daf..8745a3814 100644 --- a/src/xenia/kernel/object_table.cc +++ b/src/xenia/kernel/object_table.cc @@ -18,7 +18,7 @@ namespace xe { namespace kernel { ObjectTable::ObjectTable() - : table_capacity_(0), table_(NULL), last_free_entry_(0) {} + : table_capacity_(0), table_(nullptr), last_free_entry_(0) {} ObjectTable::~ObjectTable() { std::lock_guard lock(table_mutex_); @@ -34,7 +34,7 @@ ObjectTable::~ObjectTable() { table_capacity_ = 0; last_free_entry_ = 0; - xe_free(table_); + free(table_); table_ = NULL; } @@ -59,12 +59,18 @@ X_STATUS ObjectTable::FindFreeSlot(uint32_t* out_slot) { // Table out of slots, expand. uint32_t new_table_capacity = std::max(16 * 1024u, table_capacity_ * 2); - ObjectTableEntry* new_table = (ObjectTableEntry*)xe_recalloc( - table_, table_capacity_ * sizeof(ObjectTableEntry), - new_table_capacity * sizeof(ObjectTableEntry)); + size_t new_table_size = new_table_capacity * sizeof(ObjectTableEntry); + size_t old_table_size = table_capacity_ * sizeof(ObjectTableEntry); + ObjectTableEntry* new_table = + (ObjectTableEntry*)realloc(table_, new_table_size); if (!new_table) { return X_STATUS_NO_MEMORY; } + // Zero out new memory. + if (new_table_size > old_table_size) { + memset(reinterpret_cast(new_table) + old_table_size, 0, + new_table_size - old_table_size); + } last_free_entry_ = table_capacity_; table_capacity_ = new_table_capacity; table_ = new_table; diff --git a/src/xenia/kernel/objects/xfile.h b/src/xenia/kernel/objects/xfile.h index dfb2d7fe5..42057447a 100644 --- a/src/xenia/kernel/objects/xfile.h +++ b/src/xenia/kernel/objects/xfile.h @@ -74,8 +74,7 @@ class XDirectoryInfo { poly::store_and_swap(dst + 48, info->allocation_size); poly::store_and_swap(dst + 56, info->attributes); poly::store_and_swap(dst + 60, info->file_name_length); - xe_copy_memory(dst + 64, info->file_name_length, info->file_name, - info->file_name_length); + memcpy(dst + 64, info->file_name, info->file_name_length); dst += info->next_entry_offset; src += info->next_entry_offset; } while (info->next_entry_offset != 0); @@ -99,8 +98,7 @@ class XVolumeInfo { poly::store_and_swap(dst + 8, this->serial_number); poly::store_and_swap(dst + 12, this->label_length); poly::store_and_swap(dst + 16, this->supports_objects); - xe_copy_memory(dst + 20, this->label_length, this->label, - this->label_length); + memcpy(dst + 20, this->label, this->label_length); } }; static_assert_size(XVolumeInfo, 24); @@ -120,8 +118,7 @@ class XFileSystemAttributeInfo { poly::store_and_swap(dst + 4, this->maximum_component_name_length); poly::store_and_swap(dst + 8, this->fs_name_length); - xe_copy_memory(dst + 12, this->fs_name_length, this->fs_name, - this->fs_name_length); + memcpy(dst + 12, this->fs_name, this->fs_name_length); } }; static_assert_size(XFileSystemAttributeInfo, 16); diff --git a/src/xenia/kernel/objects/xuser_module.cc b/src/xenia/kernel/objects/xuser_module.cc index 65e82337c..634da5530 100644 --- a/src/xenia/kernel/objects/xuser_module.cc +++ b/src/xenia/kernel/objects/xuser_module.cc @@ -67,7 +67,7 @@ X_STATUS XUserModule::LoadFromFile(const char* path) { XEEXPECTZERO(result); size_t buffer_length = file_info.file_length; - buffer = (uint8_t*)xe_malloc(buffer_length); + buffer = (uint8_t*)malloc(buffer_length); // Open file for reading. result = fs_entry->Open(kernel_state(), fs::Mode::READ, false, &file); @@ -85,7 +85,7 @@ X_STATUS XUserModule::LoadFromFile(const char* path) { XECLEANUP: if (buffer) { - xe_free(buffer); + free(buffer); } if (file) { file->Release(); @@ -99,8 +99,7 @@ X_STATUS XUserModule::LoadFromMemory(const void* addr, const size_t length) { XenonRuntime* runtime = processor->runtime(); // Load the XEX into memory and decrypt. - xe_xex2_options_t xex_options; - xe_zero_struct(&xex_options, sizeof(xex_options)); + xe_xex2_options_t xex_options = {0}; xex_ = xe_xex2_load(kernel_state()->memory(), addr, length, xex_options); if (!xex_) { return X_STATUS_UNSUCCESSFUL; diff --git a/src/xenia/kernel/util/xex2.cc b/src/xenia/kernel/util/xex2.cc index 1a7b48f41..b0a2526db 100644 --- a/src/xenia/kernel/util/xex2.cc +++ b/src/xenia/kernel/util/xex2.cc @@ -51,7 +51,7 @@ int xe_xex2_find_import_infos(xe_xex2_ref xex, xe_xex2_ref xe_xex2_load(xe::Memory *memory, const void *addr, const size_t length, xe_xex2_options_t options) { - xe_xex2_ref xex = (xe_xex2_ref)xe_calloc(sizeof(xe_xex2)); + xe_xex2_ref xex = (xe_xex2_ref)calloc(1, sizeof(xe_xex2)); xe_ref_init((xe_ref)xex); xex->memory = memory; @@ -85,14 +85,14 @@ void xe_xex2_dealloc(xe_xex2_ref xex) { } xe_xex2_header_t *header = &xex->header; - xe_free(header->sections); - xe_free(header->resource_infos); + free(header->sections); + free(header->resource_infos); if (header->file_format_info.compression_type == XEX_COMPRESSION_BASIC) { - xe_free(header->file_format_info.compression_info.basic.blocks); + free(header->file_format_info.compression_info.basic.blocks); } for (size_t n = 0; n < header->import_library_count; n++) { xe_xex2_import_library_t *library = &header->import_libraries[n]; - xe_free(library->records); + free(library->records); } xex->memory = NULL; @@ -162,13 +162,12 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, break; case XEX_HEADER_RESOURCE_INFO: { header->resource_info_count = (opt_header->length - 4) / 16; - header->resource_infos = (xe_xex2_resource_info_t *)xe_calloc( - sizeof(xe_xex2_resource_info_t) * header->resource_info_count); + header->resource_infos = (xe_xex2_resource_info_t *)calloc( + header->resource_info_count, sizeof(xe_xex2_resource_info_t)); const uint8_t *ph = pp + 0x04; for (size_t n = 0; n < header->resource_info_count; n++) { auto &res = header->resource_infos[n]; - XEEXPECTZERO( - xe_copy_memory(res.name, sizeof(res.name), ph + 0x00, 8)); + memcpy(res.name, ph + 0x00, 8); res.address = poly::load_and_swap(ph + 0x08); res.size = poly::load_and_swap(ph + 0x0C); ph += 16; @@ -254,8 +253,7 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, pp += 12 + string_table_size; for (size_t m = 0; m < count; m++) { xe_xex2_import_library_t *library = &header->import_libraries[m]; - XEEXPECTZERO(xe_copy_memory(library->digest, sizeof(library->digest), - pp + 0x04, 20)); + memcpy(library->digest, pp + 0x04, 20); library->import_id = poly::load_and_swap(pp + 0x18); library->version.value = poly::load_and_swap(pp + 0x1C); library->min_version.value = poly::load_and_swap(pp + 0x20); @@ -282,7 +280,7 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, library->record_count = poly::load_and_swap(pp + 0x26); library->records = - (uint32_t *)xe_calloc(library->record_count * sizeof(uint32_t)); + (uint32_t *)calloc(library->record_count, sizeof(uint32_t)); XEEXPECTNOTNULL(library->records); pp += 0x28; for (size_t i = 0; i < library->record_count; i++) { @@ -304,8 +302,7 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, pp += 4; for (size_t m = 0; m < count; m++) { xe_xex2_static_library_t *library = &header->static_libraries[m]; - XEEXPECTZERO(xe_copy_memory(library->name, sizeof(library->name), - pp + 0x00, 8)); + memcpy(library->name, pp + 0x00, 8); library->name[8] = 0; library->major = poly::load_and_swap(pp + 0x08); library->minor = poly::load_and_swap(pp + 0x0A); @@ -333,8 +330,8 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, uint32_t info_size = poly::load_and_swap(pp + 0x00); comp_info->block_count = (info_size - 8) / 8; comp_info->blocks = - (xe_xex2_file_basic_compression_block_t *)xe_calloc( - comp_info->block_count * + (xe_xex2_file_basic_compression_block_t *)calloc( + comp_info->block_count, sizeof(xe_xex2_file_basic_compression_block_t)); XEEXPECTNOTNULL(comp_info->blocks); for (size_t m = 0; m < comp_info->block_count; m++) { @@ -360,9 +357,7 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, comp_info->window_size = poly::load_and_swap(pp + 0x08); comp_info->window_bits = window_bits; comp_info->block_size = poly::load_and_swap(pp + 0x0C); - XEEXPECTZERO(xe_copy_memory(comp_info->block_hash, - sizeof(comp_info->block_hash), - pp + 0x10, 20)); + memcpy(comp_info->block_hash, pp + 0x10, 20); } break; case XEX_COMPRESSION_DELTA: // TODO: XEX_COMPRESSION_DELTA @@ -378,25 +373,18 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, ldr = &header->loader_info; ldr->header_size = poly::load_and_swap(pc + 0x000); ldr->image_size = poly::load_and_swap(pc + 0x004); - XEEXPECTZERO(xe_copy_memory(ldr->rsa_signature, sizeof(ldr->rsa_signature), - pc + 0x008, 256)); + memcpy(ldr->rsa_signature, pc + 0x008, 256); ldr->unklength = poly::load_and_swap(pc + 0x108); ldr->image_flags = (xe_xex2_image_flags)poly::load_and_swap(pc + 0x10C); ldr->load_address = poly::load_and_swap(pc + 0x110); - XEEXPECTZERO(xe_copy_memory(ldr->section_digest, sizeof(ldr->section_digest), - pc + 0x114, 20)); + memcpy(ldr->section_digest, pc + 0x114, 20); ldr->import_table_count = poly::load_and_swap(pc + 0x128); - XEEXPECTZERO(xe_copy_memory(ldr->import_table_digest, - sizeof(ldr->import_table_digest), pc + 0x12C, - 20)); - XEEXPECTZERO( - xe_copy_memory(ldr->media_id, sizeof(ldr->media_id), pc + 0x140, 16)); - XEEXPECTZERO( - xe_copy_memory(ldr->file_key, sizeof(ldr->file_key), pc + 0x150, 16)); + memcpy(ldr->import_table_digest, pc + 0x12C, 20); + memcpy(ldr->media_id, pc + 0x140, 16); + memcpy(ldr->file_key, pc + 0x150, 16); ldr->export_table = poly::load_and_swap(pc + 0x160); - XEEXPECTZERO(xe_copy_memory(ldr->header_digest, sizeof(ldr->header_digest), - pc + 0x164, 20)); + memcpy(ldr->header_digest, pc + 0x164, 20); ldr->game_regions = (xe_xex2_region_flags)poly::load_and_swap(pc + 0x178); ldr->media_flags = @@ -406,15 +394,14 @@ int xe_xex2_read_header(const uint8_t *addr, const size_t length, ps = p + header->certificate_offset + 0x180; header->section_count = poly::load_and_swap(ps + 0x000); ps += 4; - header->sections = (xe_xex2_section_t *)xe_calloc(header->section_count * - sizeof(xe_xex2_section_t)); + header->sections = (xe_xex2_section_t *)calloc(header->section_count, + sizeof(xe_xex2_section_t)); XEEXPECTNOTNULL(header->sections); for (size_t n = 0; n < header->section_count; n++) { xe_xex2_section_t *section = &header->sections[n]; section->info.value = poly::load_and_swap(ps); ps += 4; - XEEXPECTZERO(xe_copy_memory(section->digest, sizeof(section->digest), ps, - sizeof(section->digest))); + memcpy(section->digest, ps, sizeof(section->digest)); ps += sizeof(section->digest); } @@ -462,7 +449,7 @@ mspack_memory_file *mspack_memory_open(struct mspack_system *sys, void *buffer, return NULL; } mspack_memory_file *memfile = - (mspack_memory_file *)xe_calloc(sizeof(mspack_memory_file)); + (mspack_memory_file *)calloc(1, sizeof(mspack_memory_file)); if (!memfile) { return NULL; } @@ -473,16 +460,13 @@ mspack_memory_file *mspack_memory_open(struct mspack_system *sys, void *buffer, } void mspack_memory_close(mspack_memory_file *file) { mspack_memory_file *memfile = (mspack_memory_file *)file; - xe_free(memfile); + free(memfile); } int mspack_memory_read(struct mspack_file *file, void *buffer, int chars) { mspack_memory_file *memfile = (mspack_memory_file *)file; const off_t remaining = memfile->buffer_size - memfile->offset; const off_t total = std::min(static_cast(chars), remaining); - if (xe_copy_memory(buffer, total, - (uint8_t *)memfile->buffer + memfile->offset, total)) { - return -1; - } + memcpy(buffer, (uint8_t *)memfile->buffer + memfile->offset, total); memfile->offset += total; return (int)total; } @@ -490,23 +474,20 @@ int mspack_memory_write(struct mspack_file *file, void *buffer, int chars) { mspack_memory_file *memfile = (mspack_memory_file *)file; const off_t remaining = memfile->buffer_size - memfile->offset; const off_t total = std::min(static_cast(chars), remaining); - if (xe_copy_memory((uint8_t *)memfile->buffer + memfile->offset, - memfile->buffer_size - memfile->offset, buffer, total)) { - return -1; - } + memcpy((uint8_t *)memfile->buffer + memfile->offset, buffer, total); memfile->offset += total; return (int)total; } void *mspack_memory_alloc(struct mspack_system *sys, size_t chars) { - return xe_calloc(chars); + return calloc(chars, 1); } -void mspack_memory_free(void *ptr) { xe_free(ptr); } +void mspack_memory_free(void *ptr) { free(ptr); } void mspack_memory_copy(void *src, void *dest, size_t chars) { - xe_copy_memory(dest, chars, src, chars); + memcpy(dest, src, chars); } struct mspack_system *mspack_memory_sys_create() { struct mspack_system *sys = - (struct mspack_system *)xe_calloc(sizeof(struct mspack_system)); + (struct mspack_system *)calloc(1, sizeof(struct mspack_system)); if (!sys) { return NULL; } @@ -517,7 +498,7 @@ struct mspack_system *mspack_memory_sys_create() { sys->copy = mspack_memory_copy; return sys; } -void mspack_memory_sys_destroy(struct mspack_system *sys) { xe_free(sys); } +void mspack_memory_sys_destroy(struct mspack_system *sys) { free(sys); } void xe_xex2_decrypt_buffer(const uint8_t *session_key, const uint8_t *input_buffer, @@ -560,7 +541,11 @@ int xe_xex2_read_image_uncompressed(const xe_xex2_header_t *header, switch (header->file_format_info.encryption_type) { case XEX_ENCRYPTION_NONE: - return xe_copy_memory(buffer, uncompressed_size, p, exe_length); + if (exe_length > uncompressed_size) { + return 1; + } + memcpy(buffer, p, exe_length); + return 0; case XEX_ENCRYPTION_NORMAL: xe_xex2_decrypt_buffer(header->session_key, p, exe_length, buffer, uncompressed_size); @@ -597,7 +582,7 @@ int xe_xex2_read_image_basic_compressed(const xe_xex2_header_t *header, if (!alloc_result) { XELOGE("Unable to allocate XEX memory at %.8X-%.8X.", header->exe_address, uncompressed_size); - XEFAIL(); + return 1; } uint8_t *buffer = memory->Translate(header->exe_address); uint8_t *d = buffer; @@ -612,8 +597,12 @@ int xe_xex2_read_image_basic_compressed(const xe_xex2_header_t *header, switch (header->file_format_info.encryption_type) { case XEX_ENCRYPTION_NONE: - XEEXPECTZERO(xe_copy_memory(d, uncompressed_size - (d - buffer), p, - exe_length - (p - source_buffer))); + if (exe_length - (p - source_buffer) > + uncompressed_size - (d - buffer)) { + // Overflow. + return 1; + } + memcpy(d, p, exe_length - (p - source_buffer)); break; case XEX_ENCRYPTION_NORMAL: { const uint8_t *ct = p; @@ -639,9 +628,6 @@ int xe_xex2_read_image_basic_compressed(const xe_xex2_header_t *header, } return 0; - -XECLEANUP: - return 1; } int xe_xex2_read_image_compressed(const xe_xex2_header_t *header, @@ -682,7 +668,7 @@ int xe_xex2_read_image_compressed(const xe_xex2_header_t *header, case XEX_ENCRYPTION_NORMAL: // TODO: a way to do without a copy/alloc? free_input = true; - input_buffer = (const uint8_t *)xe_calloc(input_size); + input_buffer = (const uint8_t *)calloc(1, input_size); XEEXPECTNOTNULL(input_buffer); xe_xex2_decrypt_buffer(header->session_key, exe_buffer, exe_length, (uint8_t *)input_buffer, input_size); @@ -692,14 +678,14 @@ int xe_xex2_read_image_compressed(const xe_xex2_header_t *header, return false; } - compress_buffer = (uint8_t *)xe_calloc(exe_length); + compress_buffer = (uint8_t *)calloc(1, exe_length); XEEXPECTNOTNULL(compress_buffer); p = input_buffer; d = compress_buffer; // De-block. - deblock_buffer = (uint8_t *)xe_calloc(input_size); + deblock_buffer = (uint8_t *)calloc(1, input_size); XEEXPECTNOTNULL(deblock_buffer); block_size = header->file_format_info.compression_info.normal.block_size; while (block_size) { @@ -714,7 +700,7 @@ int xe_xex2_read_image_compressed(const xe_xex2_header_t *header, if (!chunk_size) { break; } - xe_copy_memory(d, exe_length - (d - compress_buffer), p, chunk_size); + memcpy(d, p, chunk_size); p += chunk_size; d += chunk_size; @@ -770,10 +756,10 @@ XECLEANUP: mspack_memory_sys_destroy(sys); sys = NULL; } - xe_free(compress_buffer); - xe_free(deblock_buffer); + free(compress_buffer); + free(deblock_buffer); if (free_input) { - xe_free((void *)input_buffer); + free((void *)input_buffer); } return result_code; } @@ -865,9 +851,8 @@ int xe_xex2_load_pe(xe_xex2_ref xex) { // Setup/load sections. sechdr = IMAGE_FIRST_SECTION(nthdr); for (size_t n = 0; n < filehdr->NumberOfSections; n++, sechdr++) { - PESection *section = (PESection *)xe_calloc(sizeof(PESection)); - xe_copy_memory(section->name, sizeof(section->name), sechdr->Name, - sizeof(sechdr->Name)); + PESection *section = (PESection *)calloc(1, sizeof(PESection)); + memcpy(section->name, sechdr->Name, sizeof(sechdr->Name)); section->name[8] = 0; section->raw_address = sechdr->PointerToRawData; section->raw_size = sechdr->SizeOfRawData; @@ -928,8 +913,8 @@ int xe_xex2_find_import_infos(xe_xex2_ref xex, } // Allocate storage. - xe_xex2_import_info_t *infos = (xe_xex2_import_info_t *)xe_calloc( - info_count * sizeof(xe_xex2_import_info_t)); + xe_xex2_import_info_t *infos = (xe_xex2_import_info_t *)calloc( + info_count, sizeof(xe_xex2_import_info_t)); assert_not_null(infos); assert_not_zero(info_count); diff --git a/src/xenia/kernel/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl_io.cc index 11a32e000..06da957b9 100644 --- a/src/xenia/kernel/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl_io.cc @@ -24,27 +24,23 @@ namespace kernel { using namespace xe::kernel::fs; class X_OBJECT_ATTRIBUTES { -public: - uint32_t root_directory; - uint32_t object_name_ptr; + public: + uint32_t root_directory; + uint32_t object_name_ptr; X_ANSI_STRING object_name; - uint32_t attributes; + uint32_t attributes; - X_OBJECT_ATTRIBUTES() { - Zero(); - } - X_OBJECT_ATTRIBUTES(const uint8_t* base, uint32_t p) { - Read(base, p); - } + X_OBJECT_ATTRIBUTES() { Zero(); } + X_OBJECT_ATTRIBUTES(const uint8_t* base, uint32_t p) { Read(base, p); } void Read(const uint8_t* base, uint32_t p) { - root_directory = poly::load_and_swap(base + p); + root_directory = poly::load_and_swap(base + p); object_name_ptr = poly::load_and_swap(base + p + 4); if (object_name_ptr) { object_name.Read(base, object_name_ptr); } else { object_name.Zero(); } - attributes = poly::load_and_swap(base + p + 8); + attributes = poly::load_and_swap(base + p + 8); } void Zero() { root_directory = 0; @@ -135,7 +131,7 @@ SHIM_CALL NtCreateFile_shim(PPCContext* ppc_state, KernelState* state) { } } - xe_free(object_name); + free(object_name); SHIM_SET_RETURN_32(result); } @@ -203,7 +199,7 @@ SHIM_CALL NtOpenFile_shim(PPCContext* ppc_state, KernelState* state) { } } - xe_free(object_name); + free(object_name); SHIM_SET_RETURN_32(result); } @@ -494,7 +490,7 @@ SHIM_CALL NtQueryFullAttributesFile_shim(PPCContext* ppc_state, } } - xe_free(object_name); + free(object_name); SHIM_SET_RETURN_32(result); } @@ -520,23 +516,23 @@ SHIM_CALL NtQueryVolumeInformationFile_shim(PPCContext* ppc_state, result = X_STATUS_SUCCESS; switch (fs_info_class) { case 1: { // FileFsVolumeInformation - auto volume_info = (XVolumeInfo*)xe_calloc(length); + auto volume_info = (XVolumeInfo*)calloc(length, 1); result = file->QueryVolume(volume_info, length); if (XSUCCEEDED(result)) { volume_info->Write(SHIM_MEM_BASE, fs_info_ptr); info = length; } - xe_free(volume_info); + free(volume_info); break; } case 5: { // FileFsAttributeInformation - auto fs_attribute_info = (XFileSystemAttributeInfo*)xe_calloc(length); + auto fs_attribute_info = (XFileSystemAttributeInfo*)calloc(length, 1); result = file->QueryFileSystemAttributes(fs_attribute_info, length); if (XSUCCEEDED(result)) { fs_attribute_info->Write(SHIM_MEM_BASE, fs_info_ptr); info = length; } - xe_free(fs_attribute_info); + free(fs_attribute_info); break; } default: @@ -589,7 +585,7 @@ SHIM_CALL NtQueryDirectoryFile_shim(PPCContext* ppc_state, KernelState* state) { if (length < 72) { SHIM_SET_RETURN_32(X_STATUS_INFO_LENGTH_MISMATCH); - xe_free(file_name); + free(file_name); return; } @@ -599,14 +595,14 @@ SHIM_CALL NtQueryDirectoryFile_shim(PPCContext* ppc_state, KernelState* state) { XFile* file = NULL; result = state->object_table()->GetObject(file_handle, (XObject**)&file); if (XSUCCEEDED(result)) { - XDirectoryInfo* dir_info = (XDirectoryInfo*)xe_calloc(length); + XDirectoryInfo* dir_info = (XDirectoryInfo*)calloc(length, 1); result = file->QueryDirectory(dir_info, length, file_name, restart_scan != 0); if (XSUCCEEDED(result)) { dir_info->Write(SHIM_MEM_BASE, file_info_ptr); info = length; } - xe_free(dir_info); + free(dir_info); } if (XFAILED(result)) { @@ -621,7 +617,7 @@ SHIM_CALL NtQueryDirectoryFile_shim(PPCContext* ppc_state, KernelState* state) { file->Release(); } - xe_free(file_name); + free(file_name); SHIM_SET_RETURN_32(result); } diff --git a/src/xenia/kernel/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl_memory.cc index b6a7124e0..7cb6266dc 100644 --- a/src/xenia/kernel/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl_memory.cc @@ -319,7 +319,7 @@ SHIM_CALL MmQueryStatistics_shim(PPCContext* ppc_state, KernelState* state) { X_STATUS result = X_STATUS_SUCCESS; // Zero out the struct. - xe_zero_struct(SHIM_MEM_ADDR(stats_ptr), 104); + memset(SHIM_MEM_ADDR(stats_ptr), 0, 104); SHIM_SET_MEM_32(stats_ptr + 0, 104); // Set the constants the game is likely asking for. diff --git a/src/xenia/kernel/xboxkrnl_module.cc b/src/xenia/kernel/xboxkrnl_module.cc index 04149eaf9..08be07e73 100644 --- a/src/xenia/kernel/xboxkrnl_module.cc +++ b/src/xenia/kernel/xboxkrnl_module.cc @@ -108,8 +108,8 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) export_resolver_->SetVariableMapping( "xboxkrnl.exe", ordinals::ExLoadedCommandLine, pExLoadedCommandLine); char command_line[] = "\"default.xex\""; - xe_copy_memory(mem + pExLoadedCommandLine, 1024, command_line, - poly::countof(command_line) + 1); + memcpy(mem + pExLoadedCommandLine, command_line, + poly::countof(command_line) + 1); // XboxKrnlVersion (8b) // Kernel version, looks like 2b.2b.2b.2b. diff --git a/src/xenia/kernel/xboxkrnl_strings.cc b/src/xenia/kernel/xboxkrnl_strings.cc index 986b2c741..1498deb43 100644 --- a/src/xenia/kernel/xboxkrnl_strings.cc +++ b/src/xenia/kernel/xboxkrnl_strings.cc @@ -408,7 +408,7 @@ SHIM_CALL _vswprintf_shim(PPCContext* ppc_state, KernelState* state) { // swap the format buffer wchar_t* swapped_format = - (wchar_t*)xe_malloc((format_length + 1) * sizeof(wchar_t)); + (wchar_t*)malloc((format_length + 1) * sizeof(wchar_t)); for (size_t i = 0; i < format_length; ++i) { swapped_format[i] = poly::byte_swap(format[i]); } @@ -587,13 +587,13 @@ SHIM_CALL _vswprintf_shim(PPCContext* ppc_state, KernelState* state) { const wchar_t* data = (const wchar_t*)SHIM_MEM_ADDR(value); size_t data_length = wcslen(data); wchar_t* swapped_data = - (wchar_t*)xe_malloc((data_length + 1) * sizeof(wchar_t)); + (wchar_t*)malloc((data_length + 1) * sizeof(wchar_t)); for (size_t i = 0; i < data_length; ++i) { swapped_data[i] = poly::byte_swap(data[i]); } swapped_data[data_length] = '\0'; int result = wsprintf(b, local, swapped_data); - xe_free(swapped_data); + free(swapped_data); b += result; arg_index++; } else { @@ -607,7 +607,7 @@ SHIM_CALL _vswprintf_shim(PPCContext* ppc_state, KernelState* state) { } *b = '\0'; - xe_free(swapped_format); + free(swapped_format); // swap the result buffer for (wchar_t* swap = buffer; swap != b; ++swap) { diff --git a/src/xenia/kernel/xboxkrnl_video.cc b/src/xenia/kernel/xboxkrnl_video.cc index 419393a70..5a7f72de7 100644 --- a/src/xenia/kernel/xboxkrnl_video.cc +++ b/src/xenia/kernel/xboxkrnl_video.cc @@ -202,15 +202,15 @@ SHIM_CALL VdEnableRingBufferRPtrWriteBack_shim(PPCContext* ppc_state, //(1:17:38 AM) Rick: .text:8201B348 lwz r11, 0x2B10(r31) //(1:17:38 AM) Rick: .text:8201B34C addi r11, r11, 0x3C //(1:17:38 AM) Rick: .text:8201B350 srwi r10, r11, 20 # - //r10 = r11 >> 20 + // r10 = r11 >> 20 //(1:17:38 AM) Rick: .text:8201B354 clrlwi r11, r11, 3 # - //r11 = r11 & 0x1FFFFFFF + // r11 = r11 & 0x1FFFFFFF //(1:17:38 AM) Rick: .text:8201B358 addi r10, r10, 0x200 //(1:17:39 AM) Rick: .text:8201B35C rlwinm r10, r10, - //0,19,19 # r10 = r10 & 0x1000 + // 0,19,19 # r10 = r10 & 0x1000 //(1:17:39 AM) Rick: .text:8201B360 add r3, r10, r11 //(1:17:39 AM) Rick: .text:8201B364 bl - //VdEnableRingBufferRPtrWriteBack + // VdEnableRingBufferRPtrWriteBack // TODO(benvanik): something? } @@ -300,7 +300,7 @@ SHIM_CALL VdSwap_shim(PPCContext* ppc_state, KernelState* state) { // token value. It'd be nice to figure out what this is really doing so // that we could simulate it, though due to TCR I bet all games need to // use this method. - xe_zero_struct(SHIM_MEM_ADDR(unk0), 64 * 4); + memset(SHIM_MEM_ADDR(unk0), 0, 64 * 4); auto dwords = reinterpret_cast(SHIM_MEM_ADDR(unk0)); dwords[0] = poly::byte_swap((0x03 << 30) | ((1 - 1) << 16) | (xe::gpu::xenos::PM4_XE_SWAP << 8)); diff --git a/src/xenia/malloc.cc b/src/xenia/malloc.cc deleted file mode 100644 index 1c827d46f..000000000 --- a/src/xenia/malloc.cc +++ /dev/null @@ -1,137 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include - - -void *xe_malloc(const size_t size) { - // Some platforms return NULL from malloc with size zero. - if (!size) { - return malloc(1); - } - return malloc(size); -} - -void *xe_calloc(const size_t size) { - // Some platforms return NULL from malloc with size zero. - if (!size) { - return calloc(1, 1); - } - return calloc(1, size); -} - -void* xe_realloc(void *ptr, const size_t old_size, const size_t new_size) { - if (!ptr) { - // Support realloc as malloc. - return malloc(new_size); - } - if (old_size == new_size) { - // No-op. - return ptr; - } - if (!new_size) { - // Zero-size realloc, return a dummy buffer for platforms that don't support - // zero-size allocs. - void *dummy = malloc(1); - if (!dummy) { - return NULL; - } - xe_free(ptr); - return dummy; - } - - return realloc(ptr, new_size); -} - -void* xe_recalloc(void *ptr, const size_t old_size, const size_t new_size) { - if (!ptr) { - // Support realloc as malloc. - return calloc(1, new_size); - } - if (old_size == new_size) { - // No-op. - return ptr; - } - if (!new_size) { - // Zero-size realloc, return a dummy buffer for platforms that don't support - // zero-size allocs. - void *dummy = calloc(1, 1); - if (!dummy) { - return NULL; - } - xe_free(ptr); - return dummy; - } - - void *result = realloc(ptr, new_size); - if (!result) { - return NULL; - } - - // Zero out new memory. - if (new_size > old_size) { - xe_zero_memory(result, new_size, old_size, new_size - old_size); - } - - return result; -} - -void xe_free(void *ptr) { - if (ptr) { - free(ptr); - } -} - -xe_aligned_void_t *xe_malloc_aligned(const size_t size) { - // TODO(benvanik): validate every platform is aligned to XE_ALIGNMENT. - return xe_malloc(size); -} - -void xe_free_aligned(xe_aligned_void_t *ptr) { - xe_free((void*)ptr); -} - -int xe_zero_struct(void *ptr, const size_t size) { - return xe_zero_memory(ptr, size, 0, size); -} - -int xe_zero_memory(void *ptr, const size_t size, const size_t offset, - const size_t length) { - // TODO(benvanik): validate sizing/clamp. - if (!ptr || !length) { - return 0; - } - if (offset + length > size) { - return 1; - } - memset((uint8_t*)ptr + offset, 0, length); - return 0; -} - -int xe_copy_struct(void *dest, const void *source, const size_t size) { - return xe_copy_memory(dest, size, source, size); -} - -int xe_copy_memory(void *dest, const size_t dest_size, const void *source, - const size_t source_size) { - // TODO(benvanik): validate sizing. - if (!source_size) { - return 0; - } - if (!dest || !source) { - return 1; - } - if (dest_size < source_size) { - return 1; - } - memcpy(dest, source, source_size); - return 0; -} diff --git a/src/xenia/malloc.h b/src/xenia/malloc.h deleted file mode 100644 index cfe6304e5..000000000 --- a/src/xenia/malloc.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_MALLOC_H_ -#define XENIA_MALLOC_H_ - -#include - - -#define xe_alloca(size) alloca(size) - -void *xe_malloc(const size_t size); -void *xe_calloc(const size_t size); -void *xe_realloc(void *ptr, const size_t old_size, const size_t new_size); -void *xe_recalloc(void *ptr, const size_t old_size, const size_t new_size); -void xe_free(void *ptr); - -typedef __declspec(align(16)) volatile void xe_aligned_void_t; -xe_aligned_void_t *xe_malloc_aligned(const size_t size); -void xe_free_aligned(xe_aligned_void_t *ptr); - -int xe_zero_struct(void *ptr, const size_t size); -int xe_zero_memory(void *ptr, const size_t size, const size_t offset, - const size_t length); -int xe_copy_struct(void *dest, const void *source, const size_t size); -int xe_copy_memory(void *dest, const size_t dest_size, const void *source, - const size_t source_size); - - -#endif // XENIA_MALLOC_H_ diff --git a/src/xenia/memory.cc b/src/xenia/memory.cc index 596812317..4ee269353 100644 --- a/src/xenia/memory.cc +++ b/src/xenia/memory.cc @@ -348,7 +348,7 @@ uint64_t Memory::HeapAlloc(uint64_t base_address, size_t size, uint32_t flags, } if (result) { if (flags & MEMORY_FLAG_ZERO) { - xe_zero_struct(Translate(result), size); + memset(Translate(result), 0, size); } } return result; @@ -377,7 +377,7 @@ uint64_t Memory::HeapAlloc(uint64_t base_address, size_t size, uint32_t flags, } if (flags & MEMORY_FLAG_ZERO) { - xe_zero_struct(pv, size); + memset(pv, 0, size); } return base_address; diff --git a/src/xenia/sources.gypi b/src/xenia/sources.gypi index 26c0a909d..23345750f 100644 --- a/src/xenia/sources.gypi +++ b/src/xenia/sources.gypi @@ -11,8 +11,6 @@ 'export_resolver.h', 'logging.cc', 'logging.h', - 'malloc.cc', - 'malloc.h', 'memory.cc', 'memory.h', 'profiling.cc', diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index fb0431eaa..ce056362e 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -266,7 +266,7 @@ public: if (buffer == NULL || length == 0) { return NULL; } - auto copy = (char*)xe_calloc(length + 1); + auto copy = (char*)calloc(length + 1, sizeof(char)); std::strncpy(copy, buffer, length); return copy; } diff --git a/tools/alloy-sandbox/alloy-sandbox.cc b/tools/alloy-sandbox/alloy-sandbox.cc index 393a1c6ac..8ed74a8ac 100644 --- a/tools/alloy-sandbox/alloy-sandbox.cc +++ b/tools/alloy-sandbox/alloy-sandbox.cc @@ -35,9 +35,8 @@ class ThreadState : public alloy::runtime::ThreadState { memset(memory_->Translate(stack_address_), 0, stack_size_); // Allocate with 64b alignment. - context_ = (PPCContext*)xe_malloc_aligned(sizeof(PPCContext)); + context_ = (PPCContext*)calloc(1, sizeof(PPCContext)); assert_true((reinterpret_cast(context_) & 0xF) == 0); - memset(&context_, 0, sizeof(PPCContext)); // Stash pointers to common structures that callbacks may need. context_->reserve_address = memory_->reserve_address(); @@ -59,7 +58,7 @@ class ThreadState : public alloy::runtime::ThreadState { } ~ThreadState() override { runtime_->debugger()->OnThreadDestroyed(this); - xe_free_aligned(context_); + free(context_); } PPCContext* context() const { return context_; } From 06f5b8cbbf9020ca2a8d4e869e29c1ddcdeb2af6 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 20 Aug 2014 22:37:01 -0700 Subject: [PATCH 146/388] Removing dep on xenia/types.h from alloy. --- src/alloy/backend/x64/x64_emitter.h | 18 ++++++++++++------ src/alloy/backend/x64/x64_sequences.h | 6 +++++- src/alloy/hir/block.h | 4 +++- src/alloy/runtime/instrument.h | 4 +++- src/xenia/profiling.h | 3 ++- tools/alloy-sandbox/alloy-sandbox.cc | 4 ++++ 6 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/alloy/backend/x64/x64_emitter.h b/src/alloy/backend/x64/x64_emitter.h index 86ffba7db..d51f255ca 100644 --- a/src/alloy/backend/x64/x64_emitter.h +++ b/src/alloy/backend/x64/x64_emitter.h @@ -16,12 +16,18 @@ #include -XEDECLARECLASS2(alloy, hir, HIRBuilder); -XEDECLARECLASS2(alloy, hir, Instr); -XEDECLARECLASS2(alloy, runtime, DebugInfo); -XEDECLARECLASS2(alloy, runtime, FunctionInfo); -XEDECLARECLASS2(alloy, runtime, Runtime); -XEDECLARECLASS2(alloy, runtime, SymbolInfo); +namespace alloy { +namespace hir { +class HIRBuilder; +class Instr; +} // namespace hir +namespace runtime { +class DebugInfo; +class FunctionInfo; +class Runtime; +class SymbolInfo; +} // namespace runtime +} // namespace alloy namespace alloy { namespace backend { diff --git a/src/alloy/backend/x64/x64_sequences.h b/src/alloy/backend/x64/x64_sequences.h index 79053e31e..3bfe6d94b 100644 --- a/src/alloy/backend/x64/x64_sequences.h +++ b/src/alloy/backend/x64/x64_sequences.h @@ -12,7 +12,11 @@ #include -XEDECLARECLASS2(alloy, hir, Instr); +namespace alloy { +namespace hir { +class Instr; +} // namespace hir +} // namespace alloy namespace alloy { namespace backend { diff --git a/src/alloy/hir/block.h b/src/alloy/hir/block.h index f79147697..b62f70b58 100644 --- a/src/alloy/hir/block.h +++ b/src/alloy/hir/block.h @@ -13,7 +13,9 @@ #include #include -XEDECLARECLASS1(llvm, BitVector); +namespace llvm { +class BitVector; +} // namespace llvm namespace alloy { namespace hir { diff --git a/src/alloy/runtime/instrument.h b/src/alloy/runtime/instrument.h index c75d0ad09..631c72c55 100644 --- a/src/alloy/runtime/instrument.h +++ b/src/alloy/runtime/instrument.h @@ -12,7 +12,9 @@ #include -XEDECLARECLASS1(alloy, Memory); +namespace alloy { +class Memory; +} // namespace alloy namespace alloy { namespace runtime { diff --git a/src/xenia/profiling.h b/src/xenia/profiling.h index d3102e980..aa570ac91 100644 --- a/src/xenia/profiling.h +++ b/src/xenia/profiling.h @@ -13,9 +13,10 @@ #include #include -#include +#if XE_LIKE_WIN32 #define XE_OPTION_PROFILING 1 +#endif // XE_LIKE_WIN32 #if XE_OPTION_PROFILING // Pollutes the global namespace. Yuck. diff --git a/tools/alloy-sandbox/alloy-sandbox.cc b/tools/alloy-sandbox/alloy-sandbox.cc index 8ed74a8ac..b8f7b4e3f 100644 --- a/tools/alloy-sandbox/alloy-sandbox.cc +++ b/tools/alloy-sandbox/alloy-sandbox.cc @@ -75,8 +75,10 @@ class ThreadState : public alloy::runtime::ThreadState { // TODO(benvanik): simple memory? move more into core? int main(std::vector& args) { +#if XE_OPTION_PROFILING xe::Profiler::Initialize(); xe::Profiler::ThreadEnter("main"); +#endif // XE_OPTION_PROFILING size_t memory_size = 16 * 1024 * 1024; auto memory = std::make_unique(memory_size); @@ -116,8 +118,10 @@ int main(std::vector& args) { runtime.reset(); memory.reset(); +#if XE_OPTION_PROFILING xe::Profiler::Dump(); xe::Profiler::ThreadExit(); +#endif // XE_OPTION_PROFILING return 0; } From 244e8a8745576fd04d35390f051008d316420ba9 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 20 Aug 2014 22:50:10 -0700 Subject: [PATCH 147/388] Removing the last of XEDECLARECLASS. --- src/xenia/apu/apu.h | 8 ++-- src/xenia/apu/audio_driver.h | 20 +++------ src/xenia/apu/audio_system.h | 35 +++++++--------- src/xenia/apu/nop/nop_apu.h | 11 ++--- src/xenia/cpu/processor.h | 51 +++++++++-------------- src/xenia/cpu/xenon_runtime.h | 3 +- src/xenia/gpu/gpu.h | 9 ++-- src/xenia/gpu/graphics_system.h | 35 +++++++--------- src/xenia/gpu/nop/nop_gpu.h | 11 ++--- src/xenia/hid/hid.h | 9 ++-- src/xenia/hid/input_system.h | 4 +- src/xenia/hid/nop/nop_hid.h | 5 +-- src/xenia/kernel/objects/xkernel_module.h | 4 +- src/xenia/kernel/objects/xthread.h | 3 +- src/xenia/types.h | 44 ++++++++++++------- 15 files changed, 108 insertions(+), 144 deletions(-) diff --git a/src/xenia/apu/apu.h b/src/xenia/apu/apu.h index 36861efae..9c39b5079 100644 --- a/src/xenia/apu/apu.h +++ b/src/xenia/apu/apu.h @@ -12,14 +12,13 @@ #include - -XEDECLARECLASS1(xe, Emulator); - +namespace xe { +class Emulator; +} // namespace xe namespace xe { namespace apu { - AudioSystem* Create(Emulator* emulator); AudioSystem* CreateNop(Emulator* emulator); @@ -31,5 +30,4 @@ AudioSystem* CreateXAudio2(Emulator* emulator); } // namespace apu } // namespace xe - #endif // XENIA_APU_APU_H_ diff --git a/src/xenia/apu/audio_driver.h b/src/xenia/apu/audio_driver.h index 3ec11bdca..55d80acb4 100644 --- a/src/xenia/apu/audio_driver.h +++ b/src/xenia/apu/audio_driver.h @@ -11,34 +11,26 @@ #define XENIA_APU_AUDIO_DRIVER_H_ #include +#include #include - -XEDECLARECLASS1(xe, Emulator); -XEDECLARECLASS2(xe, cpu, Processor); -XEDECLARECLASS2(xe, cpu, XenonThreadState); - - namespace xe { namespace apu { - class AudioDriver { -public: + public: AudioDriver(Emulator* emulator); virtual ~AudioDriver(); virtual void SubmitFrame(uint32_t samples_ptr) = 0; -protected: - Emulator* emulator_; - Memory* memory_; - cpu::Processor* processor_; + protected: + Emulator* emulator_; + Memory* memory_; + cpu::Processor* processor_; }; - } // namespace apu } // namespace xe - #endif // XENIA_APU_AUDIO_DRIVER_H_ diff --git a/src/xenia/apu/audio_system.h b/src/xenia/apu/audio_system.h index 25f871745..b0b9a0321 100644 --- a/src/xenia/apu/audio_system.h +++ b/src/xenia/apu/audio_system.h @@ -16,19 +16,16 @@ #include #include +#include #include -XEDECLARECLASS1(xe, Emulator); -XEDECLARECLASS2(xe, cpu, Processor); -XEDECLARECLASS2(xe, cpu, XenonThreadState); -XEDECLARECLASS2(xe, apu, AudioDriver); - namespace xe { namespace apu { +class AudioDriver; class AudioSystem { -public: + public: virtual ~AudioSystem(); Emulator* emulator() const { return emulator_; } @@ -38,20 +35,22 @@ public: virtual X_STATUS Setup(); virtual void Shutdown(); - X_STATUS RegisterClient(uint32_t callback, uint32_t callback_arg, size_t* out_index); + X_STATUS RegisterClient(uint32_t callback, uint32_t callback_arg, + size_t* out_index); void UnregisterClient(size_t index); void SubmitFrame(size_t index, uint32_t samples_ptr); - virtual X_STATUS CreateDriver(size_t index, HANDLE wait_handle, AudioDriver** out_driver) = 0; + virtual X_STATUS CreateDriver(size_t index, HANDLE wait_handle, + AudioDriver** out_driver) = 0; virtual void DestroyDriver(AudioDriver* driver) = 0; virtual uint64_t ReadRegister(uint64_t addr); virtual void WriteRegister(uint64_t addr, uint64_t value); -protected: + protected: virtual void Initialize(); -private: + private: void ThreadStart(); static uint64_t MMIOReadRegisterThunk(AudioSystem* as, uint64_t addr) { @@ -62,19 +61,19 @@ private: as->WriteRegister(addr, value); } -protected: + protected: AudioSystem(Emulator* emulator); - Emulator* emulator_; - Memory* memory_; - cpu::Processor* processor_; + Emulator* emulator_; + Memory* memory_; + cpu::Processor* processor_; - std::thread thread_; + std::thread thread_; cpu::XenonThreadState* thread_state_; - uint32_t thread_block_; + uint32_t thread_block_; std::atomic running_; - std::mutex lock_; + std::mutex lock_; static const size_t maximum_client_count_ = 8; @@ -88,9 +87,7 @@ protected: std::queue unused_clients_; }; - } // namespace apu } // namespace xe - #endif // XENIA_APU_AUDIO_SYSTEM_H_ diff --git a/src/xenia/apu/nop/nop_apu.h b/src/xenia/apu/nop/nop_apu.h index 2ff51b89f..d7df58711 100644 --- a/src/xenia/apu/nop/nop_apu.h +++ b/src/xenia/apu/nop/nop_apu.h @@ -12,22 +12,19 @@ #include - -XEDECLARECLASS1(xe, Emulator); -XEDECLARECLASS2(xe, apu, AudioSystem); - +namespace xe { +class Emulator; +} // namespace xe namespace xe { namespace apu { +class AudioSystem; namespace nop { - AudioSystem* Create(Emulator* emulator); - } // namespace nop } // namespace apu } // namespace xe - #endif // XENIA_APU_NOP_NOP_APU_H_ diff --git a/src/xenia/cpu/processor.h b/src/xenia/cpu/processor.h index fc0b5bc2a..ffcd65c9b 100644 --- a/src/xenia/cpu/processor.h +++ b/src/xenia/cpu/processor.h @@ -14,21 +14,15 @@ #include #include - - -XEDECLARECLASS2(alloy, runtime, Breakpoint); -XEDECLARECLASS1(xe, Emulator); -XEDECLARECLASS1(xe, ExportResolver); -XEDECLARECLASS1(xe, Memory); -XEDECLARECLASS2(xe, cpu, XenonMemory); -XEDECLARECLASS2(xe, cpu, XenonRuntime); -XEDECLARECLASS2(xe, cpu, XenonThreadState); -XEDECLARECLASS2(xe, cpu, XexModule); - +#include namespace xe { namespace cpu { +class XenonMemory; +class XenonRuntime; +class XenonThreadState; +class XexModule; enum class Irql : uint32_t { PASSIVE = 0, @@ -37,9 +31,8 @@ enum class Irql : uint32_t { DPC = 3, }; - class Processor { -public: + public: Processor(Emulator* emulator); ~Processor(); @@ -49,34 +42,30 @@ public: int Setup(); - int Execute( - XenonThreadState* thread_state, uint64_t address); - uint64_t Execute( - XenonThreadState* thread_state, uint64_t address, uint64_t args[], - size_t arg_count); + int Execute(XenonThreadState* thread_state, uint64_t address); + uint64_t Execute(XenonThreadState* thread_state, uint64_t address, + uint64_t args[], size_t arg_count); Irql RaiseIrql(Irql new_value); void LowerIrql(Irql old_value); - uint64_t ExecuteInterrupt( - uint32_t cpu, uint64_t address, uint64_t args[], size_t arg_count); + uint64_t ExecuteInterrupt(uint32_t cpu, uint64_t address, uint64_t args[], + size_t arg_count); -private: - Emulator* emulator_; - ExportResolver* export_resolver_; + private: + Emulator* emulator_; + ExportResolver* export_resolver_; - XenonRuntime* runtime_; - Memory* memory_; + XenonRuntime* runtime_; + Memory* memory_; - Irql irql_; - std::mutex interrupt_thread_lock_; - XenonThreadState* interrupt_thread_state_; - uint64_t interrupt_thread_block_; + Irql irql_; + std::mutex interrupt_thread_lock_; + XenonThreadState* interrupt_thread_state_; + uint64_t interrupt_thread_block_; }; - } // namespace cpu } // namespace xe - #endif // XENIA_CPU_PROCESSOR_H_ diff --git a/src/xenia/cpu/xenon_runtime.h b/src/xenia/cpu/xenon_runtime.h index de90e167d..2b53d0561 100644 --- a/src/xenia/cpu/xenon_runtime.h +++ b/src/xenia/cpu/xenon_runtime.h @@ -14,8 +14,7 @@ #include #include - -XEDECLARECLASS1(xe, ExportResolver); +#include namespace xe { namespace cpu { diff --git a/src/xenia/gpu/gpu.h b/src/xenia/gpu/gpu.h index 2861d7446..7015fef24 100644 --- a/src/xenia/gpu/gpu.h +++ b/src/xenia/gpu/gpu.h @@ -12,14 +12,13 @@ #include - -XEDECLARECLASS1(xe, Emulator); - +namespace xe { +class Emulator; +} // namespace xe namespace xe { namespace gpu { - GraphicsSystem* Create(Emulator* emulator); GraphicsSystem* CreateNop(Emulator* emulator); @@ -28,9 +27,7 @@ GraphicsSystem* CreateNop(Emulator* emulator); GraphicsSystem* CreateD3D11(Emulator* emulator); #endif // WIN32 - } // namespace gpu } // namespace xe - #endif // XENIA_GPU_GPU_H_ diff --git a/src/xenia/gpu/graphics_system.h b/src/xenia/gpu/graphics_system.h index 0a068ff71..4f5e8f4c3 100644 --- a/src/xenia/gpu/graphics_system.h +++ b/src/xenia/gpu/graphics_system.h @@ -14,22 +14,17 @@ #include #include +#include #include - -XEDECLARECLASS1(xe, Emulator); -XEDECLARECLASS2(xe, cpu, Processor); - - namespace xe { namespace gpu { class CommandProcessor; class GraphicsDriver; - class GraphicsSystem { -public: + public: virtual ~GraphicsSystem(); Emulator* emulator() const { return emulator_; } @@ -50,11 +45,11 @@ public: void DispatchInterruptCallback(uint32_t source, uint32_t cpu = 0xFFFFFFFF); virtual void Swap() = 0; -protected: + protected: virtual void Initialize(); virtual void Pump() = 0; -private: + private: void ThreadStart(); static uint64_t MMIOReadRegisterThunk(GraphicsSystem* gs, uint64_t addr) { @@ -65,28 +60,26 @@ private: gs->WriteRegister(addr, value); } -protected: + protected: GraphicsSystem(Emulator* emulator); - Emulator* emulator_; - Memory* memory_; - cpu::Processor* processor_; + Emulator* emulator_; + Memory* memory_; + cpu::Processor* processor_; - xe_run_loop_ref run_loop_; - std::thread thread_; + xe_run_loop_ref run_loop_; + std::thread thread_; std::atomic running_; - GraphicsDriver* driver_; + GraphicsDriver* driver_; CommandProcessor* command_processor_; - uint32_t interrupt_callback_; - uint32_t interrupt_callback_data_; - HANDLE thread_wait_; + uint32_t interrupt_callback_; + uint32_t interrupt_callback_data_; + HANDLE thread_wait_; }; - } // namespace gpu } // namespace xe - #endif // XENIA_GPU_GRAPHICS_SYSTEM_H_ diff --git a/src/xenia/gpu/nop/nop_gpu.h b/src/xenia/gpu/nop/nop_gpu.h index 7d3e03a34..c9dfd5ead 100644 --- a/src/xenia/gpu/nop/nop_gpu.h +++ b/src/xenia/gpu/nop/nop_gpu.h @@ -12,22 +12,19 @@ #include - -XEDECLARECLASS1(xe, Emulator); -XEDECLARECLASS2(xe, gpu, GraphicsSystem); - +namespace xe { +class Emulator; +} // namespace xe namespace xe { namespace gpu { +class GraphicsSystem; namespace nop { - GraphicsSystem* Create(Emulator* emulator); - } // namespace nop } // namespace gpu } // namespace xe - #endif // XENIA_GPU_NOP_NOP_GPU_H_ diff --git a/src/xenia/hid/hid.h b/src/xenia/hid/hid.h index cd3fe887a..095dcfd9a 100644 --- a/src/xenia/hid/hid.h +++ b/src/xenia/hid/hid.h @@ -12,19 +12,16 @@ #include - -XEDECLARECLASS1(xe, Emulator); - +namespace xe { +class Emulator; +} // namespace xe namespace xe { namespace hid { - InputSystem* Create(Emulator* emulator); - } // namespace hid } // namespace xe - #endif // XENIA_HID_HID_H_ diff --git a/src/xenia/hid/input_system.h b/src/xenia/hid/input_system.h index f9f996469..309b1da02 100644 --- a/src/xenia/hid/input_system.h +++ b/src/xenia/hid/input_system.h @@ -13,11 +13,9 @@ #include #include +#include #include -XEDECLARECLASS1(xe, Emulator); -XEDECLARECLASS2(xe, cpu, Processor); - namespace xe { namespace hid { diff --git a/src/xenia/hid/nop/nop_hid.h b/src/xenia/hid/nop/nop_hid.h index 63fd1f3ac..6080d159e 100644 --- a/src/xenia/hid/nop/nop_hid.h +++ b/src/xenia/hid/nop/nop_hid.h @@ -12,11 +12,10 @@ #include -XEDECLARECLASS2(xe, hid, InputDriver); -XEDECLARECLASS2(xe, hid, InputSystem); - namespace xe { namespace hid { +class InputDriver; +class InputSystem; namespace nop { InputDriver* Create(InputSystem* input_system); diff --git a/src/xenia/kernel/objects/xkernel_module.h b/src/xenia/kernel/objects/xkernel_module.h index 6b8c6980f..e2ff4c28b 100644 --- a/src/xenia/kernel/objects/xkernel_module.h +++ b/src/xenia/kernel/objects/xkernel_module.h @@ -10,11 +10,9 @@ #ifndef XENIA_KERNEL_XBOXKRNL_XKERNEL_MODULE_H_ #define XENIA_KERNEL_XBOXKRNL_XKERNEL_MODULE_H_ +#include #include -XEDECLARECLASS1(xe, Emulator); -XEDECLARECLASS1(xe, ExportResolver); - namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xthread.h b/src/xenia/kernel/objects/xthread.h index 3d7e9da22..1f676ecba 100644 --- a/src/xenia/kernel/objects/xthread.h +++ b/src/xenia/kernel/objects/xthread.h @@ -14,11 +14,10 @@ #include #include +#include #include #include -XEDECLARECLASS2(xe, cpu, XenonThreadState); - namespace xe { namespace kernel { diff --git a/src/xenia/types.h b/src/xenia/types.h index 0fe6f7661..ad208a60d 100644 --- a/src/xenia/types.h +++ b/src/xenia/types.h @@ -10,20 +10,34 @@ #ifndef XENIA_TYPES_H_ #define XENIA_TYPES_H_ -#define XEDECLARECLASS1(ns1, name) \ - namespace ns1 { class name; } -#define XEDECLARECLASS2(ns1, ns2, name) \ - namespace ns1 { namespace ns2 { \ - class name; \ - } } - -#define XEFAIL() goto XECLEANUP -#define XEEXPECT(expr) if (!(expr) ) { goto XECLEANUP; } -#define XEEXPECTTRUE(expr) if (!(expr) ) { goto XECLEANUP; } -#define XEEXPECTFALSE(expr) if ( (expr) ) { goto XECLEANUP; } -#define XEEXPECTZERO(expr) if ( (expr) != 0 ) { goto XECLEANUP; } -#define XEEXPECTNOTZERO(expr) if ( (expr) == 0 ) { goto XECLEANUP; } -#define XEEXPECTNULL(expr) if ( (expr) != NULL ) { goto XECLEANUP; } -#define XEEXPECTNOTNULL(expr) if ( (expr) == NULL ) { goto XECLEANUP; } +#define XEFAIL() goto XECLEANUP +#define XEEXPECT(expr) \ + if (!(expr)) { \ + goto XECLEANUP; \ + } +#define XEEXPECTTRUE(expr) \ + if (!(expr)) { \ + goto XECLEANUP; \ + } +#define XEEXPECTFALSE(expr) \ + if ((expr)) { \ + goto XECLEANUP; \ + } +#define XEEXPECTZERO(expr) \ + if ((expr) != 0) { \ + goto XECLEANUP; \ + } +#define XEEXPECTNOTZERO(expr) \ + if ((expr) == 0) { \ + goto XECLEANUP; \ + } +#define XEEXPECTNULL(expr) \ + if ((expr) != NULL) { \ + goto XECLEANUP; \ + } +#define XEEXPECTNOTNULL(expr) \ + if ((expr) == NULL) { \ + goto XECLEANUP; \ + } #endif // XENIA_TYPES_H_ From c59d053404bc795f951032a9e27cf6bdc70b42db Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 20 Aug 2014 23:26:46 -0700 Subject: [PATCH 148/388] unique_ptr'ing things and removing some XECLEANUP. --- src/xenia/apu/apu.cc | 17 +--- src/xenia/apu/apu.h | 8 +- src/xenia/apu/nop/nop_apu.cc | 32 +++--- src/xenia/apu/nop/nop_apu.h | 4 +- src/xenia/apu/xaudio2/xaudio2_apu.cc | 32 +++--- src/xenia/apu/xaudio2/xaudio2_apu.h | 15 ++- src/xenia/common.h | 1 - src/xenia/core.h | 11 +++ src/xenia/emulator.cc | 97 +++++++++---------- src/xenia/emulator.h | 41 ++++---- src/xenia/gpu/d3d11/d3d11_gpu.cc | 32 +++--- src/xenia/gpu/d3d11/d3d11_gpu.h | 15 ++- src/xenia/gpu/gpu.cc | 23 ++--- src/xenia/gpu/gpu.h | 8 +- src/xenia/gpu/nop/nop_gpu.cc | 32 +++--- src/xenia/gpu/nop/nop_gpu.h | 4 +- src/xenia/hid/hid.cc | 32 +++--- src/xenia/hid/hid.h | 4 +- src/xenia/hid/nop/nop_hid.cc | 4 +- src/xenia/hid/nop/nop_hid.h | 4 +- src/xenia/hid/winkey/winkey_hid.cc | 4 +- src/xenia/hid/winkey/winkey_hid.h | 9 +- src/xenia/hid/xinput/xinput_hid.cc | 4 +- src/xenia/hid/xinput/xinput_hid.h | 9 +- src/xenia/kernel/fs/device.h | 3 +- .../kernel/fs/devices/disc_image_device.cc | 5 +- .../kernel/fs/devices/disc_image_device.h | 2 +- .../kernel/fs/devices/disc_image_entry.cc | 15 ++- .../kernel/fs/devices/disc_image_entry.h | 8 +- .../kernel/fs/devices/host_path_device.cc | 5 +- .../kernel/fs/devices/host_path_device.h | 2 +- .../kernel/fs/devices/host_path_entry.cc | 13 +-- src/xenia/kernel/fs/devices/host_path_entry.h | 4 +- .../fs/devices/stfs_container_device.cc | 5 +- .../kernel/fs/devices/stfs_container_device.h | 2 +- src/xenia/kernel/fs/entry.h | 5 +- src/xenia/kernel/fs/filesystem.cc | 4 +- src/xenia/kernel/fs/filesystem.h | 3 +- src/xenia/kernel/objects/xuser_module.cc | 26 ++--- src/xenia/kernel/xboxkrnl_io.cc | 10 +- src/xenia/memory.cc | 20 ++-- src/xenia/sources.gypi | 1 - src/xenia/types.h | 43 -------- 43 files changed, 271 insertions(+), 347 deletions(-) delete mode 100644 src/xenia/types.h diff --git a/src/xenia/apu/apu.cc b/src/xenia/apu/apu.cc index 7c9b84adf..4bac1f732 100644 --- a/src/xenia/apu/apu.cc +++ b/src/xenia/apu/apu.cc @@ -10,22 +10,16 @@ #include #include - - using namespace xe; using namespace xe::apu; - -DEFINE_string(apu, "any", - "Audio system. Use: [any, nop, xaudio2]"); - +DEFINE_string(apu, "any", "Audio system. Use: [any, nop, xaudio2]"); #include -AudioSystem* xe::apu::CreateNop(Emulator* emulator) { +std::unique_ptr xe::apu::CreateNop(Emulator* emulator) { return xe::apu::nop::Create(emulator); } - #if XE_PLATFORM_WIN32 #include AudioSystem* xe::apu::CreateXAudio2(Emulator* emulator) { @@ -33,17 +27,16 @@ AudioSystem* xe::apu::CreateXAudio2(Emulator* emulator) { } #endif // WIN32 -AudioSystem* xe::apu::Create(Emulator* emulator) { +std::unique_ptr xe::apu::Create(Emulator* emulator) { if (FLAGS_apu.compare("nop") == 0) { return CreateNop(emulator); #if XE_PLATFORM_WIN32 - } - else if (FLAGS_apu.compare("xaudio2") == 0) { + } else if (FLAGS_apu.compare("xaudio2") == 0) { return CreateXAudio2(emulator); #endif // WIN32 } else { // Create best available. - AudioSystem* best = NULL; + std::unique_ptr best; #if XE_PLATFORM_WIN32 best = CreateXAudio2(emulator); diff --git a/src/xenia/apu/apu.h b/src/xenia/apu/apu.h index 9c39b5079..2a5178a3a 100644 --- a/src/xenia/apu/apu.h +++ b/src/xenia/apu/apu.h @@ -10,6 +10,8 @@ #ifndef XENIA_APU_APU_H_ #define XENIA_APU_APU_H_ +#include + #include namespace xe { @@ -19,12 +21,12 @@ class Emulator; namespace xe { namespace apu { -AudioSystem* Create(Emulator* emulator); +std::unique_ptr Create(Emulator* emulator); -AudioSystem* CreateNop(Emulator* emulator); +std::unique_ptr CreateNop(Emulator* emulator); #if XE_PLATFORM_WIN32 -AudioSystem* CreateXAudio2(Emulator* emulator); +std::unique_ptr CreateXAudio2(Emulator* emulator); #endif // WIN32 } // namespace apu diff --git a/src/xenia/apu/nop/nop_apu.cc b/src/xenia/apu/nop/nop_apu.cc index ecd2b4a67..1ab673338 100644 --- a/src/xenia/apu/nop/nop_apu.cc +++ b/src/xenia/apu/nop/nop_apu.cc @@ -11,34 +11,30 @@ #include - using namespace xe; using namespace xe::apu; using namespace xe::apu::nop; - namespace { - void InitializeIfNeeded(); - void CleanupOnShutdown(); +void InitializeIfNeeded(); +void CleanupOnShutdown(); - void InitializeIfNeeded() { - static bool has_initialized = false; - if (has_initialized) { - return; - } - has_initialized = true; - - // - - atexit(CleanupOnShutdown); +void InitializeIfNeeded() { + static bool has_initialized = false; + if (has_initialized) { + return; } + has_initialized = true; - void CleanupOnShutdown() { - } + // + + atexit(CleanupOnShutdown); } +void CleanupOnShutdown() {} +} -AudioSystem* xe::apu::nop::Create(Emulator* emulator) { +std::unique_ptr xe::apu::nop::Create(Emulator* emulator) { InitializeIfNeeded(); - return new NopAudioSystem(emulator); + return std::make_unique(emulator); } diff --git a/src/xenia/apu/nop/nop_apu.h b/src/xenia/apu/nop/nop_apu.h index d7df58711..2cc6e771b 100644 --- a/src/xenia/apu/nop/nop_apu.h +++ b/src/xenia/apu/nop/nop_apu.h @@ -10,6 +10,8 @@ #ifndef XENIA_APU_NOP_NOP_APU_H_ #define XENIA_APU_NOP_NOP_APU_H_ +#include + #include namespace xe { @@ -21,7 +23,7 @@ namespace apu { class AudioSystem; namespace nop { -AudioSystem* Create(Emulator* emulator); +std::unique_ptr Create(Emulator* emulator); } // namespace nop } // namespace apu diff --git a/src/xenia/apu/xaudio2/xaudio2_apu.cc b/src/xenia/apu/xaudio2/xaudio2_apu.cc index 06d10e43b..2c02ccb5f 100644 --- a/src/xenia/apu/xaudio2/xaudio2_apu.cc +++ b/src/xenia/apu/xaudio2/xaudio2_apu.cc @@ -11,34 +11,30 @@ #include - using namespace xe; using namespace xe::apu; using namespace xe::apu::xaudio2; - namespace { - void InitializeIfNeeded(); - void CleanupOnShutdown(); +void InitializeIfNeeded(); +void CleanupOnShutdown(); - void InitializeIfNeeded() { - static bool has_initialized = false; - if (has_initialized) { - return; - } - has_initialized = true; - - // - - atexit(CleanupOnShutdown); +void InitializeIfNeeded() { + static bool has_initialized = false; + if (has_initialized) { + return; } + has_initialized = true; - void CleanupOnShutdown() { - } + // + + atexit(CleanupOnShutdown); } +void CleanupOnShutdown() {} +} -AudioSystem* xe::apu::xaudio2::Create(Emulator* emulator) { +std::unique_ptr xe::apu::xaudio2::Create(Emulator* emulator) { InitializeIfNeeded(); - return new XAudio2AudioSystem(emulator); + return std::make_unique(emulator); } diff --git a/src/xenia/apu/xaudio2/xaudio2_apu.h b/src/xenia/apu/xaudio2/xaudio2_apu.h index 4b5a97bf7..565f93d01 100644 --- a/src/xenia/apu/xaudio2/xaudio2_apu.h +++ b/src/xenia/apu/xaudio2/xaudio2_apu.h @@ -10,24 +10,23 @@ #ifndef XENIA_APU_XAUDIO2_XAUDIO2_APU_H_ #define XENIA_APU_XAUDIO2_XAUDIO2_APU_H_ +#include + #include - -XEDECLARECLASS1(xe, Emulator); -XEDECLARECLASS2(xe, apu, AudioSystem); - +namespace xe { +class Emulator; +} // namespace xe namespace xe { namespace apu { +class AudioSystem; namespace xaudio2 { - -AudioSystem* Create(Emulator* emulator); - +std::unique_ptr Create(Emulator* emulator); } // namespace xaudio2 } // namespace apu } // namespace xe - #endif // XENIA_APU_XAUDIO2_XAUDIO2_APU_H_ diff --git a/src/xenia/common.h b/src/xenia/common.h index 821b83cc7..f20beaa90 100644 --- a/src/xenia/common.h +++ b/src/xenia/common.h @@ -18,6 +18,5 @@ #include #include -#include #endif // XENIA_COMMON_H_ diff --git a/src/xenia/core.h b/src/xenia/core.h index 6027d653d..5bf4ebbbe 100644 --- a/src/xenia/core.h +++ b/src/xenia/core.h @@ -17,4 +17,15 @@ #include #include +// TODO(benvanik): remove. +#define XEFAIL() goto XECLEANUP +#define XEEXPECTZERO(expr) \ + if ((expr) != 0) { \ + goto XECLEANUP; \ + } +#define XEEXPECTNOTNULL(expr) \ + if ((expr) == NULL) { \ + goto XECLEANUP; \ + } + #endif // XENIA_CORE_H_ diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index 81467ad67..484571271 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -33,18 +33,7 @@ using namespace xe::kernel::fs; using namespace xe::ui; Emulator::Emulator(const std::wstring& command_line) - : command_line_(command_line), - main_window_(0), - memory_(0), - processor_(0), - audio_system_(0), - graphics_system_(0), - input_system_(0), - export_resolver_(0), - file_system_(0), - kernel_state_(0), - xam_(0), - xboxkrnl_(0) {} + : command_line_(command_line) {} Emulator::~Emulator() { // Note that we delete things in the reverse order they were initialized. @@ -60,23 +49,23 @@ Emulator::~Emulator() { debug_agent_.reset(); - delete xam_; - delete xboxkrnl_; - delete kernel_state_; + xam_.reset(); + xboxkrnl_.reset(); + kernel_state_.reset(); - delete file_system_; + file_system_.reset(); - delete input_system_; + input_system_.reset(); // Give the systems time to shutdown before we delete them. graphics_system_->Shutdown(); audio_system_->Shutdown(); - delete graphics_system_; - delete audio_system_; + graphics_system_.reset(); + audio_system_.reset(); - delete processor_; + processor_.reset(); - delete export_resolver_; + export_resolver_.reset(); } X_STATUS Emulator::Setup() { @@ -84,63 +73,71 @@ X_STATUS Emulator::Setup() { debug_agent_.reset(new DebugAgent(this)); result = debug_agent_->Initialize(); - XEEXPECTZERO(result); + if (result) { + return result; + } // Create memory system first, as it is required for other systems. - memory_ = new Memory(); - XEEXPECTNOTNULL(memory_); + memory_ = std::make_unique(); result = memory_->Initialize(); - XEEXPECTZERO(result); + if (result) { + return result; + } memory_->set_trace_base(debug_agent_->trace_base()); // Shared export resolver used to attach and query for HLE exports. - export_resolver_ = new ExportResolver(); - XEEXPECTNOTNULL(export_resolver_); + export_resolver_ = std::make_unique(); // Initialize the CPU. - processor_ = new Processor(this); - XEEXPECTNOTNULL(processor_); + processor_ = std::make_unique(this); // Initialize the APU. - audio_system_ = xe::apu::Create(this); - XEEXPECTNOTNULL(audio_system_); + audio_system_ = std::move(xe::apu::Create(this)); + if (!audio_system_) { + return X_STATUS_NOT_IMPLEMENTED; + } // Initialize the GPU. - graphics_system_ = xe::gpu::Create(this); - XEEXPECTNOTNULL(graphics_system_); + graphics_system_ = std::move(xe::gpu::Create(this)); + if (!graphics_system_) { + return X_STATUS_NOT_IMPLEMENTED; + } // Initialize the HID. - input_system_ = xe::hid::Create(this); - XEEXPECTNOTNULL(input_system_); + input_system_ = std::move(xe::hid::Create(this)); + if (!input_system_) { + return X_STATUS_NOT_IMPLEMENTED; + } // Setup the core components. result = processor_->Setup(); - XEEXPECTZERO(result); + if (result) { + return result; + } result = audio_system_->Setup(); - XEEXPECTZERO(result); + if (result) { + return result; + } result = graphics_system_->Setup(); - XEEXPECTZERO(result); + if (result) { + return result; + } result = input_system_->Setup(); - XEEXPECTZERO(result); + if (result) { + return result; + } // Bring up the virtual filesystem used by the kernel. - file_system_ = new FileSystem(); - XEEXPECTNOTNULL(file_system_); + file_system_ = std::make_unique(); // Shared kernel state. - kernel_state_ = new KernelState(this); - XEEXPECTNOTNULL(kernel_state_); + kernel_state_ = std::make_unique(this); // HLE kernel modules. - xboxkrnl_ = new XboxkrnlModule(this, kernel_state_); - XEEXPECTNOTNULL(xboxkrnl_); - xam_ = new XamModule(this, kernel_state_); - XEEXPECTNOTNULL(xam_); + xboxkrnl_ = std::make_unique(this, kernel_state_); + xam_ = std::make_unique(this, kernel_state_); return result; - -XECLEANUP: - return result; } void Emulator::set_main_window(Window* window) { diff --git a/src/xenia/emulator.h b/src/xenia/emulator.h index 6da650108..dd07a2be3 100644 --- a/src/xenia/emulator.h +++ b/src/xenia/emulator.h @@ -54,20 +54,22 @@ class Emulator { ui::Window* main_window() const { return main_window_; } void set_main_window(ui::Window* window); - Memory* memory() const { return memory_; } + Memory* memory() const { return memory_.get(); } DebugAgent* debug_agent() const { return debug_agent_.get(); } - cpu::Processor* processor() const { return processor_; } - apu::AudioSystem* audio_system() const { return audio_system_; } - gpu::GraphicsSystem* graphics_system() const { return graphics_system_; } - hid::InputSystem* input_system() const { return input_system_; } + cpu::Processor* processor() const { return processor_.get(); } + apu::AudioSystem* audio_system() const { return audio_system_.get(); } + gpu::GraphicsSystem* graphics_system() const { + return graphics_system_.get(); + } + hid::InputSystem* input_system() const { return input_system_.get(); } - ExportResolver* export_resolver() const { return export_resolver_; } - kernel::fs::FileSystem* file_system() const { return file_system_; } + ExportResolver* export_resolver() const { return export_resolver_.get(); } + kernel::fs::FileSystem* file_system() const { return file_system_.get(); } - kernel::XboxkrnlModule* xboxkrnl() const { return xboxkrnl_; } - kernel::XamModule* xam() const { return xam_; } + kernel::XboxkrnlModule* xboxkrnl() const { return xboxkrnl_.get(); } + kernel::XamModule* xam() const { return xam_.get(); } X_STATUS Setup(); @@ -82,23 +84,24 @@ class Emulator { std::wstring command_line_; + // TODO(benvanik): remove from here? ui::Window* main_window_; - Memory* memory_; + std::unique_ptr memory_; std::unique_ptr debug_agent_; - cpu::Processor* processor_; - apu::AudioSystem* audio_system_; - gpu::GraphicsSystem* graphics_system_; - hid::InputSystem* input_system_; + std::unique_ptr processor_; + std::unique_ptr audio_system_; + std::unique_ptr graphics_system_; + std::unique_ptr input_system_; - ExportResolver* export_resolver_; - kernel::fs::FileSystem* file_system_; + std::unique_ptr export_resolver_; + std::unique_ptr file_system_; - kernel::KernelState* kernel_state_; - kernel::XamModule* xam_; - kernel::XboxkrnlModule* xboxkrnl_; + std::unique_ptr kernel_state_; + std::unique_ptr xam_; + std::unique_ptr xboxkrnl_; }; } // namespace xe diff --git a/src/xenia/gpu/d3d11/d3d11_gpu.cc b/src/xenia/gpu/d3d11/d3d11_gpu.cc index 52dd9a7b6..dbd5bc4c8 100644 --- a/src/xenia/gpu/d3d11/d3d11_gpu.cc +++ b/src/xenia/gpu/d3d11/d3d11_gpu.cc @@ -11,34 +11,30 @@ #include - using namespace xe; using namespace xe::gpu; using namespace xe::gpu::d3d11; - namespace { - void InitializeIfNeeded(); - void CleanupOnShutdown(); +void InitializeIfNeeded(); +void CleanupOnShutdown(); - void InitializeIfNeeded() { - static bool has_initialized = false; - if (has_initialized) { - return; - } - has_initialized = true; - - // - - atexit(CleanupOnShutdown); +void InitializeIfNeeded() { + static bool has_initialized = false; + if (has_initialized) { + return; } + has_initialized = true; - void CleanupOnShutdown() { - } + // + + atexit(CleanupOnShutdown); } +void CleanupOnShutdown() {} +} -GraphicsSystem* xe::gpu::d3d11::Create(Emulator* emulator) { +std::unique_ptr xe::gpu::d3d11::Create(Emulator* emulator) { InitializeIfNeeded(); - return new D3D11GraphicsSystem(emulator); + return std::make_unique(emulator); } diff --git a/src/xenia/gpu/d3d11/d3d11_gpu.h b/src/xenia/gpu/d3d11/d3d11_gpu.h index 5003c7afd..3ab0265e1 100644 --- a/src/xenia/gpu/d3d11/d3d11_gpu.h +++ b/src/xenia/gpu/d3d11/d3d11_gpu.h @@ -10,24 +10,23 @@ #ifndef XENIA_GPU_D3D11_D3D11_GPU_H_ #define XENIA_GPU_D3D11_D3D11_GPU_H_ +#include + #include - -XEDECLARECLASS1(xe, Emulator); -XEDECLARECLASS2(xe, gpu, GraphicsSystem); - +namespace xe { +class Emulator; +} // namespace xe namespace xe { namespace gpu { +class GraphicsSystem; namespace d3d11 { - -GraphicsSystem* Create(Emulator* emulator); - +std::unique_ptr Create(Emulator* emulator); } // namespace d3d11 } // namespace gpu } // namespace xe - #endif // XENIA_GPU_D3D11_D3D11_GPU_H_ diff --git a/src/xenia/gpu/gpu.cc b/src/xenia/gpu/gpu.cc index 102f2a488..11af8022e 100644 --- a/src/xenia/gpu/gpu.cc +++ b/src/xenia/gpu/gpu.cc @@ -10,37 +10,28 @@ #include #include - - using namespace xe; using namespace xe::gpu; +DEFINE_string(gpu, "any", "Graphics system. Use: [any, nop, d3d11]"); -DEFINE_string(gpu, "any", - "Graphics system. Use: [any, nop, d3d11]"); - - -DEFINE_bool(trace_ring_buffer, false, - "Trace GPU ring buffer packets."); +DEFINE_bool(trace_ring_buffer, false, "Trace GPU ring buffer packets."); DEFINE_string(dump_shaders, "", - "Path to write GPU shaders to as they are compiled."); - + "Path to write GPU shaders to as they are compiled."); #include -GraphicsSystem* xe::gpu::CreateNop(Emulator* emulator) { +std::unique_ptr xe::gpu::CreateNop(Emulator* emulator) { return xe::gpu::nop::Create(emulator); } - #if XE_PLATFORM_WIN32 #include -GraphicsSystem* xe::gpu::CreateD3D11(Emulator* emulator) { +std::unique_ptr xe::gpu::CreateD3D11(Emulator* emulator) { return xe::gpu::d3d11::Create(emulator); } #endif // WIN32 - -GraphicsSystem* xe::gpu::Create(Emulator* emulator) { +std::unique_ptr xe::gpu::Create(Emulator* emulator) { if (FLAGS_gpu.compare("nop") == 0) { return CreateNop(emulator); #if XE_PLATFORM_WIN32 @@ -49,7 +40,7 @@ GraphicsSystem* xe::gpu::Create(Emulator* emulator) { #endif // WIN32 } else { // Create best available. - GraphicsSystem* best = NULL; + std::unique_ptr best; #if XE_PLATFORM_WIN32 best = CreateD3D11(emulator); diff --git a/src/xenia/gpu/gpu.h b/src/xenia/gpu/gpu.h index 7015fef24..43690f1e2 100644 --- a/src/xenia/gpu/gpu.h +++ b/src/xenia/gpu/gpu.h @@ -10,6 +10,8 @@ #ifndef XENIA_GPU_GPU_H_ #define XENIA_GPU_GPU_H_ +#include + #include namespace xe { @@ -19,12 +21,12 @@ class Emulator; namespace xe { namespace gpu { -GraphicsSystem* Create(Emulator* emulator); +std::unique_ptr Create(Emulator* emulator); -GraphicsSystem* CreateNop(Emulator* emulator); +std::unique_ptr CreateNop(Emulator* emulator); #if XE_PLATFORM_WIN32 -GraphicsSystem* CreateD3D11(Emulator* emulator); +std::unique_ptr CreateD3D11(Emulator* emulator); #endif // WIN32 } // namespace gpu diff --git a/src/xenia/gpu/nop/nop_gpu.cc b/src/xenia/gpu/nop/nop_gpu.cc index d976f5fa4..e9281f404 100644 --- a/src/xenia/gpu/nop/nop_gpu.cc +++ b/src/xenia/gpu/nop/nop_gpu.cc @@ -11,34 +11,30 @@ #include - using namespace xe; using namespace xe::gpu; using namespace xe::gpu::nop; - namespace { - void InitializeIfNeeded(); - void CleanupOnShutdown(); +void InitializeIfNeeded(); +void CleanupOnShutdown(); - void InitializeIfNeeded() { - static bool has_initialized = false; - if (has_initialized) { - return; - } - has_initialized = true; - - // - - atexit(CleanupOnShutdown); +void InitializeIfNeeded() { + static bool has_initialized = false; + if (has_initialized) { + return; } + has_initialized = true; - void CleanupOnShutdown() { - } + // + + atexit(CleanupOnShutdown); } +void CleanupOnShutdown() {} +} -GraphicsSystem* xe::gpu::nop::Create(Emulator* emulator) { +std::unique_ptr xe::gpu::nop::Create(Emulator* emulator) { InitializeIfNeeded(); - return new NopGraphicsSystem(emulator); + return std::make_unique(emulator); } diff --git a/src/xenia/gpu/nop/nop_gpu.h b/src/xenia/gpu/nop/nop_gpu.h index c9dfd5ead..54de9d619 100644 --- a/src/xenia/gpu/nop/nop_gpu.h +++ b/src/xenia/gpu/nop/nop_gpu.h @@ -10,6 +10,8 @@ #ifndef XENIA_GPU_NOP_NOP_GPU_H_ #define XENIA_GPU_NOP_NOP_GPU_H_ +#include + #include namespace xe { @@ -21,7 +23,7 @@ namespace gpu { class GraphicsSystem; namespace nop { -GraphicsSystem* Create(Emulator* emulator); +std::unique_ptr Create(Emulator* emulator); } // namespace nop } // namespace gpu diff --git a/src/xenia/hid/hid.cc b/src/xenia/hid/hid.cc index fbd66630d..50fed497c 100644 --- a/src/xenia/hid/hid.cc +++ b/src/xenia/hid/hid.cc @@ -10,15 +10,10 @@ #include #include - - using namespace xe; using namespace xe::hid; - -DEFINE_string(hid, "any", - "Input system. Use: [any, nop, winkey, xinput]"); - +DEFINE_string(hid, "any", "Input system. Use: [any, nop, winkey, xinput]"); #include #if XE_PLATFORM_WIN32 @@ -26,41 +21,40 @@ DEFINE_string(hid, "any", #include #endif // WIN32 - -InputSystem* xe::hid::Create(Emulator* emulator) { - //return xe::hid::nop::Create(emulator); - InputSystem* input_system = new InputSystem(emulator); +std::unique_ptr xe::hid::Create(Emulator* emulator) { + std::unique_ptr input_system = + std::make_unique(emulator); if (FLAGS_hid.compare("nop") == 0) { - input_system->AddDriver(xe::hid::nop::Create(input_system)); + input_system->AddDriver(xe::hid::nop::Create(input_system.get())); #if XE_PLATFORM_WIN32 } else if (FLAGS_hid.compare("winkey") == 0) { - input_system->AddDriver(xe::hid::winkey::Create(input_system)); + input_system->AddDriver(xe::hid::winkey::Create(input_system.get())); } else if (FLAGS_hid.compare("xinput") == 0) { - input_system->AddDriver(xe::hid::xinput::Create(input_system)); + input_system->AddDriver(xe::hid::xinput::Create(input_system.get())); #endif // WIN32 } else { // Create all available. bool any_created = false; - // NOTE: in any mode we create as many as we can, falling back to nop. +// NOTE: in any mode we create as many as we can, falling back to nop. #if XE_PLATFORM_WIN32 - InputDriver* xinput_driver = xe::hid::xinput::Create(input_system); + auto xinput_driver = xe::hid::xinput::Create(input_system.get()); if (xinput_driver) { - input_system->AddDriver(xinput_driver); + input_system->AddDriver(std::move(xinput_driver)); any_created = true; } - InputDriver* winkey_driver = xe::hid::winkey::Create(input_system); + auto winkey_driver = xe::hid::winkey::Create(input_system.get()); if (winkey_driver) { - input_system->AddDriver(winkey_driver); + input_system->AddDriver(std::move(winkey_driver)); any_created = true; } #endif // WIN32 // Fallback to nop if none created. if (!any_created) { - input_system->AddDriver(xe::hid::nop::Create(input_system)); + input_system->AddDriver(xe::hid::nop::Create(input_system.get())); } } diff --git a/src/xenia/hid/hid.h b/src/xenia/hid/hid.h index 095dcfd9a..ca589e150 100644 --- a/src/xenia/hid/hid.h +++ b/src/xenia/hid/hid.h @@ -10,6 +10,8 @@ #ifndef XENIA_HID_HID_H_ #define XENIA_HID_HID_H_ +#include + #include namespace xe { @@ -19,7 +21,7 @@ class Emulator; namespace xe { namespace hid { -InputSystem* Create(Emulator* emulator); +std::unique_ptr Create(Emulator* emulator); } // namespace hid } // namespace xe diff --git a/src/xenia/hid/nop/nop_hid.cc b/src/xenia/hid/nop/nop_hid.cc index 520147285..86240e9ae 100644 --- a/src/xenia/hid/nop/nop_hid.cc +++ b/src/xenia/hid/nop/nop_hid.cc @@ -32,9 +32,9 @@ void InitializeIfNeeded() { void CleanupOnShutdown() {} -InputDriver* xe::hid::nop::Create(InputSystem* input_system) { +std::unique_ptr Create(InputSystem* input_system) { InitializeIfNeeded(); - return new NopInputDriver(input_system); + return std::make_unique(input_system); } } // namespace nop diff --git a/src/xenia/hid/nop/nop_hid.h b/src/xenia/hid/nop/nop_hid.h index 6080d159e..79c29aecd 100644 --- a/src/xenia/hid/nop/nop_hid.h +++ b/src/xenia/hid/nop/nop_hid.h @@ -10,6 +10,8 @@ #ifndef XENIA_HID_NOP_NOP_HID_H_ #define XENIA_HID_NOP_NOP_HID_H_ +#include + #include namespace xe { @@ -18,7 +20,7 @@ class InputDriver; class InputSystem; namespace nop { -InputDriver* Create(InputSystem* input_system); +std::unique_ptr Create(InputSystem* input_system); } // namespace nop } // namespace hid diff --git a/src/xenia/hid/winkey/winkey_hid.cc b/src/xenia/hid/winkey/winkey_hid.cc index f0fc06663..d837a6548 100644 --- a/src/xenia/hid/winkey/winkey_hid.cc +++ b/src/xenia/hid/winkey/winkey_hid.cc @@ -32,9 +32,9 @@ void InitializeIfNeeded() { void CleanupOnShutdown() {} -InputDriver* xe::hid::winkey::Create(InputSystem* input_system) { +std::unique_ptr Create(InputSystem* input_system) { InitializeIfNeeded(); - return new WinKeyInputDriver(input_system); + return std::make_unique(input_system); } } // namespace winkey diff --git a/src/xenia/hid/winkey/winkey_hid.h b/src/xenia/hid/winkey/winkey_hid.h index eac1fc9c5..b249d8b30 100644 --- a/src/xenia/hid/winkey/winkey_hid.h +++ b/src/xenia/hid/winkey/winkey_hid.h @@ -10,16 +10,17 @@ #ifndef XENIA_HID_WINKEY_WINKEY_HID_H_ #define XENIA_HID_WINKEY_WINKEY_HID_H_ -#include +#include -XEDECLARECLASS2(xe, hid, InputDriver); -XEDECLARECLASS2(xe, hid, InputSystem); +#include namespace xe { namespace hid { +class InputDriver; +class InputSystem; namespace winkey { -InputDriver* Create(InputSystem* input_system); +std::unique_ptr Create(InputSystem* input_system); } // namespace winkey } // namespace hid diff --git a/src/xenia/hid/xinput/xinput_hid.cc b/src/xenia/hid/xinput/xinput_hid.cc index 7850cf258..1535d9a19 100644 --- a/src/xenia/hid/xinput/xinput_hid.cc +++ b/src/xenia/hid/xinput/xinput_hid.cc @@ -32,9 +32,9 @@ void InitializeIfNeeded() { void CleanupOnShutdown() {} -InputDriver* xe::hid::xinput::Create(InputSystem* input_system) { +std::unique_ptr Create(InputSystem* input_system) { InitializeIfNeeded(); - return new XInputInputDriver(input_system); + return std::make_unique(input_system); } } // namespace xinput diff --git a/src/xenia/hid/xinput/xinput_hid.h b/src/xenia/hid/xinput/xinput_hid.h index 9e1194a7a..d6c8d78c9 100644 --- a/src/xenia/hid/xinput/xinput_hid.h +++ b/src/xenia/hid/xinput/xinput_hid.h @@ -10,16 +10,17 @@ #ifndef XENIA_HID_XINPUT_XINPUT_HID_H_ #define XENIA_HID_XINPUT_XINPUT_HID_H_ -#include +#include -XEDECLARECLASS2(xe, hid, InputDriver); -XEDECLARECLASS2(xe, hid, InputSystem); +#include namespace xe { namespace hid { +class InputDriver; +class InputSystem; namespace xinput { -InputDriver* Create(InputSystem* input_system); +std::unique_ptr Create(InputSystem* input_system); } // namespace xinput } // namespace hid diff --git a/src/xenia/kernel/fs/device.h b/src/xenia/kernel/fs/device.h index af24004da..eff460bf5 100644 --- a/src/xenia/kernel/fs/device.h +++ b/src/xenia/kernel/fs/device.h @@ -10,6 +10,7 @@ #ifndef XENIA_KERNEL_FS_DEVICE_H_ #define XENIA_KERNEL_FS_DEVICE_H_ +#include #include #include @@ -26,7 +27,7 @@ class Device { const std::string& path() const { return path_; } - virtual Entry* ResolvePath(const char* path) = 0; + virtual std::unique_ptr ResolvePath(const char* path) = 0; virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) = 0; virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, diff --git a/src/xenia/kernel/fs/devices/disc_image_device.cc b/src/xenia/kernel/fs/devices/disc_image_device.cc index 9e9ab7efe..320e1332f 100644 --- a/src/xenia/kernel/fs/devices/disc_image_device.cc +++ b/src/xenia/kernel/fs/devices/disc_image_device.cc @@ -42,7 +42,7 @@ int DiscImageDevice::Init() { return 0; } -Entry* DiscImageDevice::ResolvePath(const char* path) { +std::unique_ptr DiscImageDevice::ResolvePath(const char* path) { // The filesystem will have stripped our prefix off already, so the path will // be in the form: // some\PATH.foo @@ -64,7 +64,8 @@ Entry* DiscImageDevice::ResolvePath(const char* path) { Entry::Type type = gdfx_entry->attributes & X_FILE_ATTRIBUTE_DIRECTORY ? Entry::Type::DIRECTORY : Entry::Type::FILE; - return new DiscImageEntry(type, this, path, mmap_.get(), gdfx_entry); + return std::make_unique(type, this, path, mmap_.get(), + gdfx_entry); } X_STATUS DiscImageDevice::QueryVolume(XVolumeInfo* out_info, size_t length) { diff --git a/src/xenia/kernel/fs/devices/disc_image_device.h b/src/xenia/kernel/fs/devices/disc_image_device.h index f1fb3fb4d..97b6feb41 100644 --- a/src/xenia/kernel/fs/devices/disc_image_device.h +++ b/src/xenia/kernel/fs/devices/disc_image_device.h @@ -31,7 +31,7 @@ class DiscImageDevice : public Device { int Init(); - Entry* ResolvePath(const char* path) override; + std::unique_ptr ResolvePath(const char* path) override; X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) override; X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, diff --git a/src/xenia/kernel/fs/devices/disc_image_entry.cc b/src/xenia/kernel/fs/devices/disc_image_entry.cc index fb74c2842..cc1110355 100644 --- a/src/xenia/kernel/fs/devices/disc_image_entry.cc +++ b/src/xenia/kernel/fs/devices/disc_image_entry.cc @@ -96,23 +96,22 @@ X_STATUS DiscImageEntry::QueryDirectory(XDirectoryInfo* out_info, size_t length, return X_STATUS_SUCCESS; } -MemoryMapping* DiscImageEntry::CreateMemoryMapping(Mode map_mode, - const size_t offset, - const size_t length) { +std::unique_ptr DiscImageEntry::CreateMemoryMapping( + Mode map_mode, const size_t offset, const size_t length) { if (map_mode != Mode::READ) { // Only allow reads. - return NULL; + return nullptr; } size_t real_offset = gdfx_entry_->offset + offset; size_t real_length = length ? std::min(length, gdfx_entry_->size) : gdfx_entry_->size; - return new DiscImageMemoryMapping(mmap_->data() + real_offset, real_length, - mmap_); + return std::make_unique(mmap_->data() + real_offset, + real_length, mmap_); } -X_STATUS DiscImageEntry::Open(KernelState* kernel_state, Mode mode, - bool async, XFile** out_file) { +X_STATUS DiscImageEntry::Open(KernelState* kernel_state, Mode mode, bool async, + XFile** out_file) { *out_file = new DiscImageFile(kernel_state, mode, this); return X_STATUS_SUCCESS; } diff --git a/src/xenia/kernel/fs/devices/disc_image_entry.h b/src/xenia/kernel/fs/devices/disc_image_entry.h index 76c971d02..b1a076698 100644 --- a/src/xenia/kernel/fs/devices/disc_image_entry.h +++ b/src/xenia/kernel/fs/devices/disc_image_entry.h @@ -37,11 +37,11 @@ class DiscImageEntry : public Entry { const char* file_name, bool restart); virtual bool can_map() { return true; } - virtual MemoryMapping* CreateMemoryMapping(Mode map_mode, const size_t offset, - const size_t length); + virtual std::unique_ptr CreateMemoryMapping( + Mode map_mode, const size_t offset, const size_t length); - virtual X_STATUS Open(KernelState* kernel_state, Mode mode, - bool async, XFile** out_file); + virtual X_STATUS Open(KernelState* kernel_state, Mode mode, bool async, + XFile** out_file); private: poly::MappedMemory* mmap_; diff --git a/src/xenia/kernel/fs/devices/host_path_device.cc b/src/xenia/kernel/fs/devices/host_path_device.cc index 88d88ba12..d14852a91 100644 --- a/src/xenia/kernel/fs/devices/host_path_device.cc +++ b/src/xenia/kernel/fs/devices/host_path_device.cc @@ -22,7 +22,7 @@ HostPathDevice::HostPathDevice(const std::string& path, HostPathDevice::~HostPathDevice() {} -Entry* HostPathDevice::ResolvePath(const char* path) { +std::unique_ptr HostPathDevice::ResolvePath(const char* path) { // The filesystem will have stripped our prefix off already, so the path will // be in the form: // some\PATH.foo @@ -38,8 +38,7 @@ Entry* HostPathDevice::ResolvePath(const char* path) { // TODO(benvanik): switch based on type auto type = Entry::Type::FILE; - HostPathEntry* entry = new HostPathEntry(type, this, path, full_path); - return entry; + return std::make_unique(type, this, path, full_path); } // TODO(gibbed): call into HostPathDevice? diff --git a/src/xenia/kernel/fs/devices/host_path_device.h b/src/xenia/kernel/fs/devices/host_path_device.h index 0380508b2..bc662ada6 100644 --- a/src/xenia/kernel/fs/devices/host_path_device.h +++ b/src/xenia/kernel/fs/devices/host_path_device.h @@ -25,7 +25,7 @@ class HostPathDevice : public Device { HostPathDevice(const std::string& path, const std::wstring& local_path); ~HostPathDevice() override; - Entry* ResolvePath(const char* path) override; + std::unique_ptr ResolvePath(const char* path) override; X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) override; X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, diff --git a/src/xenia/kernel/fs/devices/host_path_entry.cc b/src/xenia/kernel/fs/devices/host_path_entry.cc index 783c12119..037bb4f2d 100644 --- a/src/xenia/kernel/fs/devices/host_path_entry.cc +++ b/src/xenia/kernel/fs/devices/host_path_entry.cc @@ -121,9 +121,8 @@ X_STATUS HostPathEntry::QueryDirectory(XDirectoryInfo* out_info, size_t length, return X_STATUS_SUCCESS; } -MemoryMapping* HostPathEntry::CreateMemoryMapping(Mode map_mode, - const size_t offset, - const size_t length) { +std::unique_ptr HostPathEntry::CreateMemoryMapping( + Mode map_mode, const size_t offset, const size_t length) { auto mmap = poly::MappedMemory::Open( local_path_, map_mode == Mode::READ ? poly::MappedMemory::Mode::READ @@ -133,13 +132,11 @@ MemoryMapping* HostPathEntry::CreateMemoryMapping(Mode map_mode, return nullptr; } - HostPathMemoryMapping* lfmm = new HostPathMemoryMapping(std::move(mmap)); - - return lfmm; + return std::make_unique(std::move(mmap)); } -X_STATUS HostPathEntry::Open(KernelState* kernel_state, Mode mode, - bool async, XFile** out_file) { +X_STATUS HostPathEntry::Open(KernelState* kernel_state, Mode mode, bool async, + XFile** out_file) { DWORD desired_access = mode == Mode::READ ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE); DWORD share_mode = FILE_SHARE_READ; diff --git a/src/xenia/kernel/fs/devices/host_path_entry.h b/src/xenia/kernel/fs/devices/host_path_entry.h index b7624ffdf..913ece216 100644 --- a/src/xenia/kernel/fs/devices/host_path_entry.h +++ b/src/xenia/kernel/fs/devices/host_path_entry.h @@ -31,8 +31,8 @@ class HostPathEntry : public Entry { const char* file_name, bool restart); virtual bool can_map() { return true; } - virtual MemoryMapping* CreateMemoryMapping(Mode map_mode, const size_t offset, - const size_t length); + virtual std::unique_ptr CreateMemoryMapping( + Mode map_mode, const size_t offset, const size_t length); virtual X_STATUS Open(KernelState* kernel_state, Mode mode, bool async, XFile** out_file); diff --git a/src/xenia/kernel/fs/devices/stfs_container_device.cc b/src/xenia/kernel/fs/devices/stfs_container_device.cc index 98cab9dc8..c562ea1fa 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_device.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_device.cc @@ -42,7 +42,7 @@ int STFSContainerDevice::Init() { return 0; } -Entry* STFSContainerDevice::ResolvePath(const char* path) { +std::unique_ptr STFSContainerDevice::ResolvePath(const char* path) { // The filesystem will have stripped our prefix off already, so the path will // be in the form: // some\PATH.foo @@ -64,7 +64,8 @@ Entry* STFSContainerDevice::ResolvePath(const char* path) { Entry::Type type = stfs_entry->attributes & X_FILE_ATTRIBUTE_DIRECTORY ? Entry::Type::DIRECTORY : Entry::Type::FILE; - return new STFSContainerEntry(type, this, path, mmap_.get(), stfs_entry); + return std::make_unique(type, this, path, mmap_.get(), + stfs_entry); } X_STATUS STFSContainerDevice::QueryVolume(XVolumeInfo* out_info, diff --git a/src/xenia/kernel/fs/devices/stfs_container_device.h b/src/xenia/kernel/fs/devices/stfs_container_device.h index b5368bf97..0022e6545 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_device.h +++ b/src/xenia/kernel/fs/devices/stfs_container_device.h @@ -31,7 +31,7 @@ class STFSContainerDevice : public Device { int Init(); - Entry* ResolvePath(const char* path) override; + std::unique_ptr ResolvePath(const char* path) override; X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) override; X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, diff --git a/src/xenia/kernel/fs/entry.h b/src/xenia/kernel/fs/entry.h index 1e3c9e0e7..e9082d6b4 100644 --- a/src/xenia/kernel/fs/entry.h +++ b/src/xenia/kernel/fs/entry.h @@ -10,6 +10,7 @@ #ifndef XENIA_KERNEL_FS_ENTRY_H_ #define XENIA_KERNEL_FS_ENTRY_H_ +#include #include #include @@ -72,8 +73,8 @@ class Entry { virtual bool can_map() { return false; } - virtual MemoryMapping* CreateMemoryMapping(Mode map_mode, const size_t offset, - const size_t length) { + virtual std::unique_ptr CreateMemoryMapping( + Mode map_mode, const size_t offset, const size_t length) { return NULL; } diff --git a/src/xenia/kernel/fs/filesystem.cc b/src/xenia/kernel/fs/filesystem.cc index 0b9054359..8499c3185 100644 --- a/src/xenia/kernel/fs/filesystem.cc +++ b/src/xenia/kernel/fs/filesystem.cc @@ -142,7 +142,7 @@ int FileSystem::DeleteSymbolicLink(const std::string& path) { return 0; } -Entry* FileSystem::ResolvePath(const std::string& path) { +std::unique_ptr FileSystem::ResolvePath(const std::string& path) { // Strip off prefix and pass to device. // e.g., d:\some\PATH.foo -> some\PATH.foo // Support both symlinks and device specifiers, like: @@ -173,7 +173,7 @@ Entry* FileSystem::ResolvePath(const std::string& path) { } XELOGE("ResolvePath(%s) failed - no root found", path.c_str()); - return NULL; + return nullptr; } } // namespace fs diff --git a/src/xenia/kernel/fs/filesystem.h b/src/xenia/kernel/fs/filesystem.h index de0107fac..c785966be 100644 --- a/src/xenia/kernel/fs/filesystem.h +++ b/src/xenia/kernel/fs/filesystem.h @@ -10,6 +10,7 @@ #ifndef XENIA_KERNEL_FS_FILESYSTEM_H_ #define XENIA_KERNEL_FS_FILESYSTEM_H_ +#include #include #include #include @@ -50,7 +51,7 @@ class FileSystem { int CreateSymbolicLink(const std::string& path, const std::string& target); int DeleteSymbolicLink(const std::string& path); - Entry* ResolvePath(const std::string& path); + std::unique_ptr ResolvePath(const std::string& path); private: std::vector devices_; diff --git a/src/xenia/kernel/objects/xuser_module.cc b/src/xenia/kernel/objects/xuser_module.cc index 634da5530..164f407ad 100644 --- a/src/xenia/kernel/objects/xuser_module.cc +++ b/src/xenia/kernel/objects/xuser_module.cc @@ -33,41 +33,33 @@ const xe_xex2_header_t* XUserModule::xex_header() { X_STATUS XUserModule::LoadFromFile(const char* path) { X_STATUS result = X_STATUS_UNSUCCESSFUL; XFile* file = NULL; - uint8_t* buffer = 0; // Resolve the file to open. // TODO(benvanik): make this code shared? - fs::Entry* fs_entry = kernel_state()->file_system()->ResolvePath(path); + auto fs_entry = kernel_state()->file_system()->ResolvePath(path); if (!fs_entry) { XELOGE("File not found: %s", path); - result = X_STATUS_NO_SUCH_FILE; - XEFAIL(); + return X_STATUS_NO_SUCH_FILE; } if (fs_entry->type() != fs::Entry::Type::FILE) { XELOGE("Invalid file type: %s", path); - result = X_STATUS_NO_SUCH_FILE; - XEFAIL(); + return X_STATUS_NO_SUCH_FILE; } // If the FS supports mapping, map the file in and load from that. if (fs_entry->can_map()) { // Map. - fs::MemoryMapping* mmap = - fs_entry->CreateMemoryMapping(fs::Mode::READ, 0, 0); + auto mmap = fs_entry->CreateMemoryMapping(fs::Mode::READ, 0, 0); XEEXPECTNOTNULL(mmap); // Load the module. result = LoadFromMemory(mmap->address(), mmap->length()); - - // Unmap memory and cleanup. - delete mmap; } else { XFileInfo file_info; result = fs_entry->QueryInfo(&file_info); XEEXPECTZERO(result); - size_t buffer_length = file_info.file_length; - buffer = (uint8_t*)malloc(buffer_length); + std::vector buffer(file_info.file_length); // Open file for reading. result = fs_entry->Open(kernel_state(), fs::Mode::READ, false, &file); @@ -76,21 +68,17 @@ X_STATUS XUserModule::LoadFromFile(const char* path) { // Read entire file into memory. // Ugh. size_t bytes_read = 0; - result = file->Read(buffer, buffer_length, 0, &bytes_read); + result = file->Read(buffer.data(), buffer.size(), 0, &bytes_read); XEEXPECTZERO(result); // Load the module. - result = LoadFromMemory(buffer, bytes_read); + result = LoadFromMemory(buffer.data(), bytes_read); } XECLEANUP: - if (buffer) { - free(buffer); - } if (file) { file->Release(); } - delete fs_entry; return result; } diff --git a/src/xenia/kernel/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl_io.cc index 06da957b9..7b8dfcab3 100644 --- a/src/xenia/kernel/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl_io.cc @@ -81,7 +81,7 @@ SHIM_CALL NtCreateFile_shim(PPCContext* ppc_state, KernelState* state) { uint32_t handle; FileSystem* fs = state->file_system(); - Entry* entry; + std::unique_ptr entry; XFile* root_file = NULL; if (attrs.root_directory != 0xFFFFFFFD && // ObDosDevices @@ -93,10 +93,10 @@ SHIM_CALL NtCreateFile_shim(PPCContext* ppc_state, KernelState* state) { auto root_path = root_file->absolute_path(); auto target_path = root_path + object_name; - entry = fs->ResolvePath(target_path); + entry = std::move(fs->ResolvePath(target_path)); } else { // Resolve the file using the virtual file system. - entry = fs->ResolvePath(object_name); + entry = std::move(fs->ResolvePath(object_name)); } auto mode = @@ -169,7 +169,7 @@ SHIM_CALL NtOpenFile_shim(PPCContext* ppc_state, KernelState* state) { // Resolve the file using the virtual file system. FileSystem* fs = state->file_system(); - Entry* entry = fs->ResolvePath(object_name); + auto entry = fs->ResolvePath(object_name); XFile* file = NULL; if (entry && entry->type() == Entry::Type::FILE) { // Open the file. @@ -480,7 +480,7 @@ SHIM_CALL NtQueryFullAttributesFile_shim(PPCContext* ppc_state, // Resolve the file using the virtual file system. FileSystem* fs = state->file_system(); - Entry* entry = fs->ResolvePath(object_name); + auto entry = fs->ResolvePath(object_name); if (entry && entry->type() == Entry::Type::FILE) { // Found. XFileInfo file_info; diff --git a/src/xenia/memory.cc b/src/xenia/memory.cc index 4ee269353..bd216231a 100644 --- a/src/xenia/memory.cc +++ b/src/xenia/memory.cc @@ -147,7 +147,6 @@ int Memory::Initialize() { if (result) { return result; } - result = 1; // Create main page file-backed mapping. This is all reserved but // uncommitted (so it shouldn't expand page file). @@ -165,7 +164,7 @@ int Memory::Initialize() { if (!mapping_) { XELOGE("Unable to reserve the 4gb guest address space."); assert_not_null(mapping_); - XEFAIL(); + return 1; } // Attempt to create our views. This may fail at the first address @@ -181,7 +180,7 @@ int Memory::Initialize() { if (!mapping_base_) { XELOGE("Unable to find a continuous block in the 64bit address space."); assert_always(); - XEFAIL(); + return 1; } membase_ = mapping_base_; @@ -200,7 +199,7 @@ int Memory::Initialize() { if (!mmio_handler_) { XELOGE("Unable to install MMIO handlers"); assert_always(); - XEFAIL(); + return 1; } // Allocate dirty page table. @@ -210,9 +209,6 @@ int Memory::Initialize() { X_MEM_COMMIT, 16 * 1024); return 0; - -XECLEANUP: - return result; } const static struct { @@ -243,13 +239,13 @@ int Memory::MapViews(uint8_t* mapping_base) { PROT_NONE, MAP_SHARED | MAP_FIXED, mapping_, map_info[n].target_address)); #endif // XE_PLATFORM_WIN32 - XEEXPECTNOTNULL(views_.all_views[n]); + if (!views_.all_views[n]) { + // Failed, so bail and try again. + UnmapViews(); + return 1; + } } return 0; - -XECLEANUP: - UnmapViews(); - return 1; } void Memory::UnmapViews() { diff --git a/src/xenia/sources.gypi b/src/xenia/sources.gypi index 23345750f..5f85ac199 100644 --- a/src/xenia/sources.gypi +++ b/src/xenia/sources.gypi @@ -15,7 +15,6 @@ 'memory.h', 'profiling.cc', 'profiling.h', - 'types.h', 'xbox.h', ], diff --git a/src/xenia/types.h b/src/xenia/types.h deleted file mode 100644 index ad208a60d..000000000 --- a/src/xenia/types.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef XENIA_TYPES_H_ -#define XENIA_TYPES_H_ - -#define XEFAIL() goto XECLEANUP -#define XEEXPECT(expr) \ - if (!(expr)) { \ - goto XECLEANUP; \ - } -#define XEEXPECTTRUE(expr) \ - if (!(expr)) { \ - goto XECLEANUP; \ - } -#define XEEXPECTFALSE(expr) \ - if ((expr)) { \ - goto XECLEANUP; \ - } -#define XEEXPECTZERO(expr) \ - if ((expr) != 0) { \ - goto XECLEANUP; \ - } -#define XEEXPECTNOTZERO(expr) \ - if ((expr) == 0) { \ - goto XECLEANUP; \ - } -#define XEEXPECTNULL(expr) \ - if ((expr) != NULL) { \ - goto XECLEANUP; \ - } -#define XEEXPECTNOTNULL(expr) \ - if ((expr) == NULL) { \ - goto XECLEANUP; \ - } - -#endif // XENIA_TYPES_H_ From 08b0226a1681adef38778b8278cd73ea53cdaa78 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 21 Aug 2014 07:54:19 -0700 Subject: [PATCH 149/388] Finishing unique_ptr'ing and fixing file memory management (for now). --- src/alloy/backend/x64/x64_code_cache_win.cc | 7 +- src/alloy/runtime/debugger.h | 3 + src/xenia/apu/apu.cc | 2 +- src/xenia/core/run_loop_win.cc | 56 ++++++------- src/xenia/core/socket_win.cc | 78 +++++++++---------- src/xenia/emulator.cc | 6 +- src/xenia/emulator.h | 1 + src/xenia/gpu/d3d11/d3d11_buffer_resource.cc | 4 +- src/xenia/gpu/d3d11/d3d11_geometry_shader.cc | 7 +- src/xenia/gpu/d3d11/d3d11_graphics_driver.cc | 36 ++++----- src/xenia/gpu/d3d11/d3d11_graphics_system.h | 2 +- src/xenia/gpu/d3d11/d3d11_profiler_display.cc | 12 +-- .../gpu/d3d11/d3d11_sampler_state_resource.cc | 3 +- src/xenia/gpu/d3d11/d3d11_shader_resource.cc | 33 ++++---- src/xenia/gpu/d3d11/d3d11_texture_resource.cc | 9 +-- src/xenia/gpu/d3d11/d3d11_window.cc | 3 +- src/xenia/hid/hid.cc | 1 + src/xenia/hid/input_system.cc | 23 ++---- src/xenia/hid/input_system.h | 5 +- .../kernel/fs/devices/disc_image_file.cc | 2 +- src/xenia/kernel/fs/devices/host_path_file.cc | 5 +- .../kernel/fs/devices/stfs_container_file.cc | 2 +- src/xenia/kernel/fs/filesystem.cc | 10 +++ src/xenia/kernel/fs/filesystem.h | 2 + src/xenia/kernel/objects/xuser_module.cc | 3 +- src/xenia/kernel/xboxkrnl_io.cc | 12 +-- 26 files changed, 152 insertions(+), 175 deletions(-) diff --git a/src/alloy/backend/x64/x64_code_cache_win.cc b/src/alloy/backend/x64/x64_code_cache_win.cc index 1084b0508..50cac069f 100644 --- a/src/alloy/backend/x64/x64_code_cache_win.cc +++ b/src/alloy/backend/x64/x64_code_cache_win.cc @@ -94,7 +94,7 @@ void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size, lock_.unlock(); // Copy code. - xe_copy_struct(final_address, machine_code, code_size); + memcpy(final_address, machine_code, code_size); // This isn't needed on x64 (probably), but is convention. FlushInstructionCache(GetCurrentProcess(), final_address, alloc_size); @@ -109,7 +109,7 @@ X64CodeChunk::X64CodeChunk(size_t chunk_size) fn_table_capacity = static_cast(poly::round_up(capacity / ESTIMATED_FN_SIZE, 16)); size_t table_size = fn_table_capacity * sizeof(RUNTIME_FUNCTION); - fn_table = (RUNTIME_FUNCTION*)xe_malloc(table_size); + fn_table = (RUNTIME_FUNCTION*)malloc(table_size); fn_table_count = 0; fn_table_handle = 0; RtlAddGrowableFunctionTable(&fn_table_handle, fn_table, fn_table_count, @@ -198,8 +198,7 @@ void X64CodeChunk::AddTableEntry(uint8_t* code, size_t code_size, RtlDeleteGrowableFunctionTable(fn_table_handle); size_t old_size = fn_table_capacity * sizeof(RUNTIME_FUNCTION); size_t new_size = old_size * 2; - auto new_table = - (RUNTIME_FUNCTION*)xe_realloc(fn_table, old_size, new_size); + auto new_table = (RUNTIME_FUNCTION*)realloc(fn_table, new_size); assert_not_null(new_table); if (!new_table) { return; diff --git a/src/alloy/runtime/debugger.h b/src/alloy/runtime/debugger.h index 971443605..789e894a8 100644 --- a/src/alloy/runtime/debugger.h +++ b/src/alloy/runtime/debugger.h @@ -95,6 +95,9 @@ class Debugger { void FindBreakpoints(uint64_t address, std::vector& out_breakpoints); + // TODO(benvanik): utility functions for modification (make function ignored, + // etc). + void OnThreadCreated(ThreadState* thread_state); void OnThreadDestroyed(ThreadState* thread_state); void OnFunctionDefined(FunctionInfo* symbol_info, Function* function); diff --git a/src/xenia/apu/apu.cc b/src/xenia/apu/apu.cc index 4bac1f732..e7ed8c292 100644 --- a/src/xenia/apu/apu.cc +++ b/src/xenia/apu/apu.cc @@ -22,7 +22,7 @@ std::unique_ptr xe::apu::CreateNop(Emulator* emulator) { #if XE_PLATFORM_WIN32 #include -AudioSystem* xe::apu::CreateXAudio2(Emulator* emulator) { +std::unique_ptr xe::apu::CreateXAudio2(Emulator* emulator) { return xe::apu::xaudio2::Create(emulator); } #endif // WIN32 diff --git a/src/xenia/core/run_loop_win.cc b/src/xenia/core/run_loop_win.cc index 164932f1b..43fdaaa8d 100644 --- a/src/xenia/core/run_loop_win.cc +++ b/src/xenia/core/run_loop_win.cc @@ -9,29 +9,23 @@ #include +typedef struct xe_run_loop { xe_ref_t ref; } xe_run_loop_t; -typedef struct xe_run_loop { - xe_ref_t ref; -} xe_run_loop_t; - - -#define WM_XE_RUN_LOOP_QUIT (WM_APP + 0x100) -#define WM_XE_RUN_LOOP_CALL (WM_APP + 0x101) +#define WM_XE_RUN_LOOP_QUIT (WM_APP + 0x100) +#define WM_XE_RUN_LOOP_CALL (WM_APP + 0x101) typedef struct xe_run_loop_call { - xe_run_loop_callback callback; - void* data; + xe_run_loop_callback callback; + void* data; } xe_run_loop_call_t; - xe_run_loop_ref xe_run_loop_create() { - xe_run_loop_ref run_loop = (xe_run_loop_ref)xe_calloc(sizeof(xe_run_loop_t)); + xe_run_loop_ref run_loop = (xe_run_loop_ref)calloc(1, sizeof(xe_run_loop_t)); xe_ref_init((xe_ref)run_loop); return run_loop; } -void xe_run_loop_dealloc(xe_run_loop_ref run_loop) { -} +void xe_run_loop_dealloc(xe_run_loop_ref run_loop) {} xe_run_loop_ref xe_run_loop_retain(xe_run_loop_ref run_loop) { xe_ref_retain((xe_ref)run_loop); @@ -48,19 +42,19 @@ int xe_run_loop_pump(xe_run_loop_ref run_loop) { TranslateMessage(&msg); DispatchMessage(&msg); switch (msg.message) { - case WM_XE_RUN_LOOP_CALL: - if (msg.wParam == (WPARAM)run_loop) { - xe_run_loop_call_t* call = (xe_run_loop_call_t*)msg.lParam; - call->callback(call->data); - xe_free(call); - } - break; - case WM_XE_RUN_LOOP_QUIT: - if (msg.wParam == (WPARAM)run_loop) { - // Done! - return 1; - } - break; + case WM_XE_RUN_LOOP_CALL: + if (msg.wParam == (WPARAM)run_loop) { + xe_run_loop_call_t* call = (xe_run_loop_call_t*)msg.lParam; + call->callback(call->data); + free(call); + } + break; + case WM_XE_RUN_LOOP_QUIT: + if (msg.wParam == (WPARAM)run_loop) { + // Done! + return 1; + } + break; } } return 0; @@ -70,11 +64,11 @@ void xe_run_loop_quit(xe_run_loop_ref run_loop) { PostMessage(NULL, WM_XE_RUN_LOOP_QUIT, (WPARAM)run_loop, 0); } -void xe_run_loop_call(xe_run_loop_ref run_loop, - xe_run_loop_callback callback, void* data) { +void xe_run_loop_call(xe_run_loop_ref run_loop, xe_run_loop_callback callback, + void* data) { xe_run_loop_call_t* call = - (xe_run_loop_call_t*)xe_calloc(sizeof(xe_run_loop_call_t)); - call->callback = callback; - call->data = data; + (xe_run_loop_call_t*)calloc(1, sizeof(xe_run_loop_call_t)); + call->callback = callback; + call->data = data; PostMessage(NULL, WM_XE_RUN_LOOP_CALL, (WPARAM)run_loop, (LPARAM)call); } diff --git a/src/xenia/core/socket_win.cc b/src/xenia/core/socket_win.cc index c95b231d8..7579ff5ad 100644 --- a/src/xenia/core/socket_win.cc +++ b/src/xenia/core/socket_win.cc @@ -16,10 +16,8 @@ #include #include - // TODO(benvanik): win32 calls - void xe_socket_init() { WSADATA wsa_data; int result = WSAStartup(MAKEWORD(2, 2), &wsa_data); @@ -41,12 +39,8 @@ void xe_socket_close(socket_t socket) { struct linger so_linger; so_linger.l_onoff = TRUE; so_linger.l_linger = 30; - setsockopt( - socket, - SOL_SOCKET, - SO_LINGER, - (const char*)&so_linger, - sizeof so_linger); + setsockopt(socket, SOL_SOCKET, SO_LINGER, (const char*)&so_linger, + sizeof so_linger); shutdown(socket, SD_SEND); closesocket(socket); } @@ -57,32 +51,32 @@ void xe_socket_set_keepalive(socket_t socket, bool value) { alive.keepalivetime = 7200000; alive.keepaliveinterval = 6000; DWORD bytes_returned; - WSAIoctl(socket, SIO_KEEPALIVE_VALS, &alive, sizeof(alive), - NULL, 0, &bytes_returned, NULL, NULL); + WSAIoctl(socket, SIO_KEEPALIVE_VALS, &alive, sizeof(alive), NULL, 0, + &bytes_returned, NULL, NULL); } void xe_socket_set_reuseaddr(socket_t socket, bool value) { int opt_value = value ? 1 : 0; - setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, - (const char*)&opt_value, sizeof(opt_value)); + setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt_value, + sizeof(opt_value)); } void xe_socket_set_nodelay(socket_t socket, bool value) { int opt_value = value ? 1 : 0; - setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, - (const char*)&opt_value, sizeof(opt_value)); + setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&opt_value, + sizeof(opt_value)); } void xe_socket_set_nonblock(socket_t socket, bool value) { u_long mode = value ? 1 : 0; - ioctlsocket(socket, FIONBIO, &mode); + ioctlsocket(socket, FIONBIO, &mode); } int xe_socket_bind(socket_t socket, uint32_t port) { struct sockaddr_in socket_addr; - socket_addr.sin_family = AF_INET; + socket_addr.sin_family = AF_INET; socket_addr.sin_addr.s_addr = htonl(INADDR_ANY); - socket_addr.sin_port = htons(port); + socket_addr.sin_port = htons(port); int r = bind(socket, (struct sockaddr*)&socket_addr, sizeof(socket_addr)); if (r == SOCKET_ERROR) { return 1; @@ -92,9 +86,9 @@ int xe_socket_bind(socket_t socket, uint32_t port) { int xe_socket_bind_loopback(socket_t socket) { struct sockaddr_in socket_addr; - socket_addr.sin_family = AF_INET; + socket_addr.sin_family = AF_INET; socket_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - socket_addr.sin_port = htons(0); + socket_addr.sin_port = htons(0); int r = bind(socket, (struct sockaddr*)&socket_addr, sizeof(socket_addr)); if (r == SOCKET_ERROR) { return 1; @@ -113,8 +107,8 @@ int xe_socket_listen(socket_t socket) { int xe_socket_accept(socket_t socket, xe_socket_connection_t* out_client_info) { struct sockaddr_in client_addr; int client_count = sizeof(client_addr); - socket_t client_socket_id = accept( - socket, (struct sockaddr*)&client_addr, &client_count); + socket_t client_socket_id = + accept(socket, (struct sockaddr*)&client_addr, &client_count); if (client_socket_id == INVALID_SOCKET) { return 1; } @@ -122,8 +116,8 @@ int xe_socket_accept(socket_t socket, xe_socket_connection_t* out_client_info) { out_client_info->socket = client_socket_id; int client_ip = client_addr.sin_addr.s_addr; - inet_ntop(AF_INET, &client_ip, - out_client_info->addr, poly::countof(out_client_info->addr)); + inet_ntop(AF_INET, &client_ip, out_client_info->addr, + poly::countof(out_client_info->addr)); return 0; } @@ -153,16 +147,16 @@ int64_t xe_socket_recv(socket_t socket, uint8_t* data, size_t length, int flags, } struct xe_socket_loop { - socket_t socket; + socket_t socket; - socket_t notify_rd_id; - socket_t notify_wr_id; + socket_t notify_rd_id; + socket_t notify_wr_id; WSAPOLLFD events[2]; - bool pending_queued_write; - bool pending_recv; - bool pending_send; + bool pending_queued_write; + bool pending_recv; + bool pending_send; }; namespace { @@ -188,8 +182,8 @@ int Win32SocketPair(socket_t sockets[2]) { sockaddr client_name; int client_name_len = sizeof(client_name); r = getsockname(client, &client_name, &client_name_len); - const char *pc = (const char*)&client_name; - const char *pn = (const char*)&listener_name; + const char* pc = (const char*)&client_name; + const char* pn = (const char*)&listener_name; for (size_t n = 0; n < sizeof(client_name); n++) { if (pc[n] != pn[n]) { closesocket(listener); @@ -208,28 +202,28 @@ int Win32SocketPair(socket_t sockets[2]) { } xe_socket_loop_t* xe_socket_loop_create(socket_t socket) { - xe_socket_loop_t* loop = (xe_socket_loop_t*)xe_calloc( - sizeof(xe_socket_loop_t)); + xe_socket_loop_t* loop = + (xe_socket_loop_t*)calloc(1, sizeof(xe_socket_loop_t)); loop->socket = socket; - socket_t notify_ids[2] = { 0, 0 }; + socket_t notify_ids[2] = {0, 0}; for (int retry = 0; retry < 5; retry++) { if (!Win32SocketPair(notify_ids)) { break; } } if (!notify_ids[0]) { - xe_free(loop); + free(loop); return NULL; } loop->notify_rd_id = notify_ids[0]; loop->notify_wr_id = notify_ids[1]; - loop->events[0].fd = socket; - loop->events[0].events = POLLIN; - loop->events[1].fd = loop->notify_rd_id; - loop->events[1].events = POLLIN; + loop->events[0].fd = socket; + loop->events[0].events = POLLIN; + loop->events[1].fd = loop->notify_rd_id; + loop->events[1].events = POLLIN; return loop; } @@ -237,11 +231,11 @@ xe_socket_loop_t* xe_socket_loop_create(socket_t socket) { void xe_socket_loop_destroy(xe_socket_loop_t* loop) { closesocket(loop->notify_rd_id); closesocket(loop->notify_wr_id); - xe_free(loop); + free(loop); } -int xe_socket_loop_poll(xe_socket_loop_t* loop, - bool check_read, bool check_write) { +int xe_socket_loop_poll(xe_socket_loop_t* loop, bool check_read, + bool check_write) { // Prep events object. loop->events[0].events = 0; if (check_read) { diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index 484571271..1ba106486 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -33,7 +33,7 @@ using namespace xe::kernel::fs; using namespace xe::ui; Emulator::Emulator(const std::wstring& command_line) - : command_line_(command_line) {} + : command_line_(command_line), main_window_(nullptr) {} Emulator::~Emulator() { // Note that we delete things in the reverse order they were initialized. @@ -134,8 +134,8 @@ X_STATUS Emulator::Setup() { kernel_state_ = std::make_unique(this); // HLE kernel modules. - xboxkrnl_ = std::make_unique(this, kernel_state_); - xam_ = std::make_unique(this, kernel_state_); + xboxkrnl_ = std::make_unique(this, kernel_state_.get()); + xam_ = std::make_unique(this, kernel_state_.get()); return result; } diff --git a/src/xenia/emulator.h b/src/xenia/emulator.h index dd07a2be3..8b82e09fa 100644 --- a/src/xenia/emulator.h +++ b/src/xenia/emulator.h @@ -24,6 +24,7 @@ class AudioSystem; } // namespace apu namespace cpu { class Processor; +class XenonThreadState; } // namespace cpu namespace gpu { class GraphicsSystem; diff --git a/src/xenia/gpu/d3d11/d3d11_buffer_resource.cc b/src/xenia/gpu/d3d11/d3d11_buffer_resource.cc index 9f05c7ec9..72282923f 100644 --- a/src/xenia/gpu/d3d11/d3d11_buffer_resource.cc +++ b/src/xenia/gpu/d3d11/d3d11_buffer_resource.cc @@ -34,7 +34,7 @@ D3D11IndexBufferResource::~D3D11IndexBufferResource() { int D3D11IndexBufferResource::CreateHandle() { D3D11_BUFFER_DESC buffer_desc; - xe_zero_struct(&buffer_desc, sizeof(buffer_desc)); + memset(&buffer_desc, 0, sizeof(buffer_desc)); buffer_desc.ByteWidth = static_cast(memory_range_.length); buffer_desc.Usage = D3D11_USAGE_DYNAMIC; buffer_desc.BindFlags = D3D11_BIND_INDEX_BUFFER; @@ -100,7 +100,7 @@ D3D11VertexBufferResource::~D3D11VertexBufferResource() { int D3D11VertexBufferResource::CreateHandle() { D3D11_BUFFER_DESC buffer_desc; - xe_zero_struct(&buffer_desc, sizeof(buffer_desc)); + memset(&buffer_desc, 0, sizeof(buffer_desc)); buffer_desc.ByteWidth = static_cast(memory_range_.length); buffer_desc.Usage = D3D11_USAGE_DYNAMIC; buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; diff --git a/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc b/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc index 64214e31a..161b716f1 100644 --- a/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc +++ b/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc @@ -59,9 +59,8 @@ int D3D11GeometryShader::Prepare(D3D11VertexShaderResource* vertex_shader) { return 1; } byte_code_length = shader_blob->GetBufferSize(); - byte_code = xe_malloc(byte_code_length); - xe_copy_struct( - byte_code, shader_blob->GetBufferPointer(), byte_code_length); + byte_code = malloc(byte_code_length); + memcpy(byte_code, shader_blob->GetBufferPointer(), byte_code_length); SafeRelease(shader_blob); // Create shader. @@ -71,7 +70,7 @@ int D3D11GeometryShader::Prepare(D3D11VertexShaderResource* vertex_shader) { &handle_); if (FAILED(hr)) { XELOGE("D3D11: failed to create geometry shader"); - xe_free(byte_code); + free(byte_code); return 1; } diff --git a/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc b/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc index 1bdccf3ec..4a5bf6385 100644 --- a/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc +++ b/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc @@ -39,13 +39,12 @@ D3D11GraphicsDriver::D3D11GraphicsDriver( resource_cache_ = new D3D11ResourceCache(memory, device_, context_); - xe_zero_struct(&state_, sizeof(state_)); + memset(&state_, 0, sizeof(state_)); - xe_zero_struct(&render_targets_, sizeof(render_targets_)); + memset(&render_targets_, 0, sizeof(render_targets_)); HRESULT hr; - D3D11_BUFFER_DESC buffer_desc; - xe_zero_struct(&buffer_desc, sizeof(buffer_desc)); + D3D11_BUFFER_DESC buffer_desc = {0}; buffer_desc.Usage = D3D11_USAGE_DYNAMIC; buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; @@ -100,8 +99,7 @@ int D3D11GraphicsDriver::Initialize() { void D3D11GraphicsDriver::InitializeInvalidTexture() { // TODO(benvanik): pattern? - D3D11_TEXTURE2D_DESC texture_desc; - xe_zero_struct(&texture_desc, sizeof(texture_desc)); + D3D11_TEXTURE2D_DESC texture_desc = {0}; texture_desc.Width = 4; texture_desc.Height = 4; texture_desc.MipLevels = 1; @@ -131,8 +129,7 @@ void D3D11GraphicsDriver::InitializeInvalidTexture() { return; } - D3D11_SHADER_RESOURCE_VIEW_DESC texture_view_desc; - xe_zero_struct(&texture_view_desc, sizeof(texture_view_desc)); + D3D11_SHADER_RESOURCE_VIEW_DESC texture_view_desc = {}; texture_view_desc.Format = texture_desc.Format; texture_view_desc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D; texture_view_desc.Texture2D.MipLevels = 1; @@ -141,8 +138,7 @@ void D3D11GraphicsDriver::InitializeInvalidTexture() { texture, &texture_view_desc, &invalid_texture_view_); SafeRelease(texture); - D3D11_SAMPLER_DESC sampler_desc; - xe_zero_struct(&sampler_desc, sizeof(sampler_desc)); + D3D11_SAMPLER_DESC sampler_desc = {}; sampler_desc.Filter; sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; @@ -396,8 +392,7 @@ int D3D11GraphicsDriver::SetupRasterizerState(const DrawCommand& command) { ID3D11RasterizerState* rasterizer_state = nullptr; auto it = rasterizer_state_cache_.find(key); if (it == rasterizer_state_cache_.end()) { - D3D11_RASTERIZER_DESC rasterizer_desc; - xe_zero_struct(&rasterizer_desc, sizeof(rasterizer_desc)); + D3D11_RASTERIZER_DESC rasterizer_desc = {}; rasterizer_desc.FillMode = D3D11_FILL_SOLID; // D3D11_FILL_WIREFRAME; switch (mode_control & 0x3) { case 0: @@ -480,8 +475,7 @@ int D3D11GraphicsDriver::SetupBlendState(const DrawCommand& command) { ID3D11BlendState* blend_state = nullptr; auto it = blend_state_cache_.find(key); if (it == blend_state_cache_.end()) { - D3D11_BLEND_DESC blend_desc; - xe_zero_struct(&blend_desc, sizeof(blend_desc)); + D3D11_BLEND_DESC blend_desc = {0}; //blend_desc.AlphaToCoverageEnable = false; // ? blend_desc.IndependentBlendEnable = true; @@ -557,8 +551,7 @@ int D3D11GraphicsDriver::SetupDepthStencilState(const DrawCommand& command) { ID3D11DepthStencilState* depth_stencil_state = nullptr; auto it = depth_stencil_state_cache_.find(key); if (it == depth_stencil_state_cache_.end()) { - D3D11_DEPTH_STENCIL_DESC depth_stencil_desc; - xe_zero_struct(&depth_stencil_desc, sizeof(depth_stencil_desc)); + D3D11_DEPTH_STENCIL_DESC depth_stencil_desc = {0}; // A2XX_RB_DEPTHCONTROL_BACKFACE_ENABLE // ? // A2XX_RB_DEPTHCONTROL_Z_ENABLE @@ -846,8 +839,7 @@ int D3D11GraphicsDriver::RebuildRenderTargets(uint32_t width, for (int n = 0; n < poly::countof(render_targets_.color_buffers); n++) { auto& cb = render_targets_.color_buffers[n]; - D3D11_TEXTURE2D_DESC color_buffer_desc; - xe_zero_struct(&color_buffer_desc, sizeof(color_buffer_desc)); + D3D11_TEXTURE2D_DESC color_buffer_desc = {}; color_buffer_desc.Width = width; color_buffer_desc.Height = height; color_buffer_desc.MipLevels = 1; @@ -865,7 +857,7 @@ int D3D11GraphicsDriver::RebuildRenderTargets(uint32_t width, &color_buffer_desc, NULL, &cb.buffer); D3D11_RENDER_TARGET_VIEW_DESC render_target_view_desc; - xe_zero_struct(&render_target_view_desc, sizeof(render_target_view_desc)); + memset(&render_target_view_desc, 0, sizeof(render_target_view_desc)); render_target_view_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; render_target_view_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; // render_target_view_desc.Buffer ? @@ -875,8 +867,7 @@ int D3D11GraphicsDriver::RebuildRenderTargets(uint32_t width, &cb.color_view_8888); } - D3D11_TEXTURE2D_DESC depth_stencil_desc; - xe_zero_struct(&depth_stencil_desc, sizeof(depth_stencil_desc)); + D3D11_TEXTURE2D_DESC depth_stencil_desc = {}; depth_stencil_desc.Width = width; depth_stencil_desc.Height = height; depth_stencil_desc.MipLevels = 1; @@ -891,8 +882,7 @@ int D3D11GraphicsDriver::RebuildRenderTargets(uint32_t width, device_->CreateTexture2D( &depth_stencil_desc, NULL, &render_targets_.depth_buffer); - D3D11_DEPTH_STENCIL_VIEW_DESC depth_stencil_view_desc; - xe_zero_struct(&depth_stencil_view_desc, sizeof(depth_stencil_view_desc)); + D3D11_DEPTH_STENCIL_VIEW_DESC depth_stencil_view_desc = {}; depth_stencil_view_desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depth_stencil_view_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depth_stencil_view_desc.Flags = 0; diff --git a/src/xenia/gpu/d3d11/d3d11_graphics_system.h b/src/xenia/gpu/d3d11/d3d11_graphics_system.h index bdefc2c21..02d83328d 100644 --- a/src/xenia/gpu/d3d11/d3d11_graphics_system.h +++ b/src/xenia/gpu/d3d11/d3d11_graphics_system.h @@ -23,7 +23,7 @@ namespace d3d11 { class D3D11Window; -GraphicsSystem* Create(Emulator* emulator); +std::unique_ptr Create(Emulator* emulator); class D3D11GraphicsSystem : public GraphicsSystem { diff --git a/src/xenia/gpu/d3d11/d3d11_profiler_display.cc b/src/xenia/gpu/d3d11/d3d11_profiler_display.cc index 5b23ea3ec..6bc31ea15 100644 --- a/src/xenia/gpu/d3d11/d3d11_profiler_display.cc +++ b/src/xenia/gpu/d3d11/d3d11_profiler_display.cc @@ -175,8 +175,7 @@ bool D3D11ProfilerDisplay::SetupState() { HRESULT hr; auto device = window_->device(); - D3D11_BLEND_DESC blend_desc; - xe_zero_struct(&blend_desc, sizeof(blend_desc)); + D3D11_BLEND_DESC blend_desc = {0}; blend_desc.RenderTarget[0].BlendEnable = true; blend_desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; blend_desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; @@ -188,8 +187,7 @@ bool D3D11ProfilerDisplay::SetupState() { hr = device->CreateBlendState(&blend_desc, &blend_state_); assert_true(SUCCEEDED(hr)); - D3D11_DEPTH_STENCIL_DESC depth_stencil_desc; - xe_zero_struct(&depth_stencil_desc, sizeof(depth_stencil_desc)); + D3D11_DEPTH_STENCIL_DESC depth_stencil_desc = {0}; depth_stencil_desc.DepthEnable = false; depth_stencil_desc.StencilEnable = false; depth_stencil_desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; @@ -371,8 +369,7 @@ bool D3D11ProfilerDisplay::SetupFont() { return false; } - D3D11_SHADER_RESOURCE_VIEW_DESC texture_view_desc; - xe_zero_struct(&texture_view_desc, sizeof(texture_view_desc)); + D3D11_SHADER_RESOURCE_VIEW_DESC texture_view_desc = {}; texture_view_desc.Format = texture_desc.Format; texture_view_desc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D; texture_view_desc.Texture2D.MipLevels = 1; @@ -385,8 +382,7 @@ bool D3D11ProfilerDisplay::SetupFont() { return false; } - D3D11_SAMPLER_DESC sampler_desc; - xe_zero_struct(&sampler_desc, sizeof(sampler_desc)); + D3D11_SAMPLER_DESC sampler_desc = {}; sampler_desc.Filter = D3D11_ENCODE_BASIC_FILTER( D3D11_FILTER_TYPE_POINT, D3D11_FILTER_TYPE_POINT, D3D11_FILTER_TYPE_POINT, false); diff --git a/src/xenia/gpu/d3d11/d3d11_sampler_state_resource.cc b/src/xenia/gpu/d3d11/d3d11_sampler_state_resource.cc index 1f9971ae4..3572f5718 100644 --- a/src/xenia/gpu/d3d11/d3d11_sampler_state_resource.cc +++ b/src/xenia/gpu/d3d11/d3d11_sampler_state_resource.cc @@ -35,8 +35,7 @@ int D3D11SamplerStateResource::Prepare() { return 0; } - D3D11_SAMPLER_DESC sampler_desc; - xe_zero_struct(&sampler_desc, sizeof(sampler_desc)); + D3D11_SAMPLER_DESC sampler_desc = {}; // MIN, MAG, MIP static const D3D11_FILTER filter_matrix[2][2][3] = { { diff --git a/src/xenia/gpu/d3d11/d3d11_shader_resource.cc b/src/xenia/gpu/d3d11/d3d11_shader_resource.cc index 8e749ce47..e352936a7 100644 --- a/src/xenia/gpu/d3d11/d3d11_shader_resource.cc +++ b/src/xenia/gpu/d3d11/d3d11_shader_resource.cc @@ -97,7 +97,7 @@ D3D11VertexShaderResource::D3D11VertexShaderResource( handle_(nullptr), input_layout_(nullptr), translated_src_(nullptr) { - xe_zero_struct(geometry_shaders_, sizeof(geometry_shaders_)); + memset(geometry_shaders_, 0, sizeof(geometry_shaders_)); } D3D11VertexShaderResource::~D3D11VertexShaderResource() { @@ -106,7 +106,7 @@ D3D11VertexShaderResource::~D3D11VertexShaderResource() { for (int i = 0; i < poly::countof(geometry_shaders_); ++i) { delete geometry_shaders_[i]; } - xe_free(translated_src_); + free(translated_src_); } int D3D11VertexShaderResource::Prepare( @@ -135,25 +135,22 @@ int D3D11VertexShaderResource::Prepare( return 1; } byte_code_length = shader_blob->GetBufferSize(); - byte_code = xe_malloc(byte_code_length); - xe_copy_struct( - byte_code, shader_blob->GetBufferPointer(), byte_code_length); + byte_code = malloc(byte_code_length); + memcpy(byte_code, shader_blob->GetBufferPointer(), byte_code_length); SafeRelease(shader_blob); // Create shader. HRESULT hr = resource_cache_->device()->CreateVertexShader( - byte_code, byte_code_length, - nullptr, - &handle_); + byte_code, byte_code_length, nullptr, &handle_); if (FAILED(hr)) { XELOGE("D3D11: failed to create vertex shader"); - xe_free(byte_code); + free(byte_code); return 1; } // Create input layout. ret = CreateInputLayout(byte_code, byte_code_length); - xe_free(byte_code); + free(byte_code); if (ret) { return 1; } @@ -174,9 +171,8 @@ int D3D11VertexShaderResource::CreateInputLayout(const void* byte_code, return 0; } - D3D11_INPUT_ELEMENT_DESC* element_descs = - (D3D11_INPUT_ELEMENT_DESC*)xe_alloca( - sizeof(D3D11_INPUT_ELEMENT_DESC) * element_count); + D3D11_INPUT_ELEMENT_DESC* element_descs = (D3D11_INPUT_ELEMENT_DESC*)alloca( + sizeof(D3D11_INPUT_ELEMENT_DESC) * element_count); uint32_t el_index = 0; for (uint32_t n = 0; n < inputs.count; n++) { const auto& input = inputs.descs[n]; @@ -327,7 +323,7 @@ D3D11PixelShaderResource::D3D11PixelShaderResource( D3D11PixelShaderResource::~D3D11PixelShaderResource() { SafeRelease(handle_); - xe_free(translated_src_); + free(translated_src_); } int D3D11PixelShaderResource::Prepare(const xe_gpu_program_cntl_t& program_cntl, @@ -358,9 +354,8 @@ int D3D11PixelShaderResource::Prepare(const xe_gpu_program_cntl_t& program_cntl, return 1; } byte_code_length = shader_blob->GetBufferSize(); - byte_code = xe_malloc(byte_code_length); - xe_copy_struct( - byte_code, shader_blob->GetBufferPointer(), byte_code_length); + byte_code = malloc(byte_code_length); + memcpy(byte_code, shader_blob->GetBufferPointer(), byte_code_length); SafeRelease(shader_blob); // Create shader. @@ -370,11 +365,11 @@ int D3D11PixelShaderResource::Prepare(const xe_gpu_program_cntl_t& program_cntl, &handle_); if (FAILED(hr)) { XELOGE("D3D11: failed to create pixel shader"); - xe_free(byte_code); + free(byte_code); return 1; } - xe_free(byte_code); + free(byte_code); is_prepared_ = true; return 0; } diff --git a/src/xenia/gpu/d3d11/d3d11_texture_resource.cc b/src/xenia/gpu/d3d11/d3d11_texture_resource.cc index 201d86f56..ebe57fdb1 100644 --- a/src/xenia/gpu/d3d11/d3d11_texture_resource.cc +++ b/src/xenia/gpu/d3d11/d3d11_texture_resource.cc @@ -37,8 +37,7 @@ D3D11TextureResource::~D3D11TextureResource() { int D3D11TextureResource::CreateHandle() { SCOPE_profile_cpu_f("gpu"); - D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc; - xe_zero_struct(&srv_desc, sizeof(srv_desc)); + D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc = {}; // TODO(benvanik): this may need to be typed on the fetch instruction (float/int/etc?) srv_desc.Format = info_.format; @@ -94,8 +93,7 @@ int D3D11TextureResource::CreateHandle() { int D3D11TextureResource::CreateHandle1D() { uint32_t width = 1 + info_.size_1d.width; - D3D11_TEXTURE1D_DESC texture_desc; - xe_zero_struct(&texture_desc, sizeof(texture_desc)); + D3D11_TEXTURE1D_DESC texture_desc = {}; texture_desc.Width = width; texture_desc.MipLevels = 1; texture_desc.ArraySize = 1; @@ -113,8 +111,7 @@ int D3D11TextureResource::CreateHandle1D() { } int D3D11TextureResource::CreateHandle2D() { - D3D11_TEXTURE2D_DESC texture_desc; - xe_zero_struct(&texture_desc, sizeof(texture_desc)); + D3D11_TEXTURE2D_DESC texture_desc = {}; texture_desc.Width = info_.size_2d.output_width; texture_desc.Height = info_.size_2d.output_height; texture_desc.MipLevels = 1; diff --git a/src/xenia/gpu/d3d11/d3d11_window.cc b/src/xenia/gpu/d3d11/d3d11_window.cc index 192e87225..eb1e50d5b 100644 --- a/src/xenia/gpu/d3d11/d3d11_window.cc +++ b/src/xenia/gpu/d3d11/d3d11_window.cc @@ -57,8 +57,7 @@ int D3D11Window::Initialize(const std::wstring& title, uint32_t width, } // Setup swap chain. - DXGI_SWAP_CHAIN_DESC desc; - xe_zero_struct(&desc, sizeof(desc)); + DXGI_SWAP_CHAIN_DESC desc = {}; desc.OutputWindow = handle(); desc.Windowed = TRUE; desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; diff --git a/src/xenia/hid/hid.cc b/src/xenia/hid/hid.cc index 50fed497c..a31e40fd8 100644 --- a/src/xenia/hid/hid.cc +++ b/src/xenia/hid/hid.cc @@ -9,6 +9,7 @@ #include #include +#include using namespace xe; using namespace xe::hid; diff --git a/src/xenia/hid/input_system.cc b/src/xenia/hid/input_system.cc index 1813e181e..0c0431118 100644 --- a/src/xenia/hid/input_system.cc +++ b/src/xenia/hid/input_system.cc @@ -19,12 +19,7 @@ namespace hid { InputSystem::InputSystem(Emulator* emulator) : emulator_(emulator), memory_(emulator->memory()) {} -InputSystem::~InputSystem() { - for (auto it = drivers_.begin(); it != drivers_.end(); ++it) { - InputDriver* driver = *it; - delete driver; - } -} +InputSystem::~InputSystem() = default; X_STATUS InputSystem::Setup() { processor_ = emulator_->processor(); @@ -32,14 +27,15 @@ X_STATUS InputSystem::Setup() { return X_STATUS_SUCCESS; } -void InputSystem::AddDriver(InputDriver* driver) { drivers_.push_back(driver); } +void InputSystem::AddDriver(std::unique_ptr driver) { + drivers_.push_back(std::move(driver)); +} X_RESULT InputSystem::GetCapabilities(uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES* out_caps) { SCOPE_profile_cpu_f("hid"); - for (auto it = drivers_.begin(); it != drivers_.end(); ++it) { - InputDriver* driver = *it; + for (auto& driver : drivers_) { if (XSUCCEEDED(driver->GetCapabilities(user_index, flags, out_caps))) { return X_ERROR_SUCCESS; } @@ -50,8 +46,7 @@ X_RESULT InputSystem::GetCapabilities(uint32_t user_index, uint32_t flags, X_RESULT InputSystem::GetState(uint32_t user_index, X_INPUT_STATE* out_state) { SCOPE_profile_cpu_f("hid"); - for (auto it = drivers_.begin(); it != drivers_.end(); ++it) { - InputDriver* driver = *it; + for (auto& driver : drivers_) { if (driver->GetState(user_index, out_state) == X_ERROR_SUCCESS) { return X_ERROR_SUCCESS; } @@ -63,8 +58,7 @@ X_RESULT InputSystem::SetState(uint32_t user_index, X_INPUT_VIBRATION* vibration) { SCOPE_profile_cpu_f("hid"); - for (auto it = drivers_.begin(); it != drivers_.end(); ++it) { - InputDriver* driver = *it; + for (auto& driver : drivers_) { if (XSUCCEEDED(driver->SetState(user_index, vibration))) { return X_ERROR_SUCCESS; } @@ -76,8 +70,7 @@ X_RESULT InputSystem::GetKeystroke(uint32_t user_index, uint32_t flags, X_INPUT_KEYSTROKE* out_keystroke) { SCOPE_profile_cpu_f("hid"); - for (auto it = drivers_.begin(); it != drivers_.end(); ++it) { - InputDriver* driver = *it; + for (auto& driver : drivers_) { if (XSUCCEEDED(driver->GetKeystroke(user_index, flags, out_keystroke))) { return X_ERROR_SUCCESS; } diff --git a/src/xenia/hid/input_system.h b/src/xenia/hid/input_system.h index 309b1da02..98ff0e23a 100644 --- a/src/xenia/hid/input_system.h +++ b/src/xenia/hid/input_system.h @@ -10,6 +10,7 @@ #ifndef XENIA_HID_INPUT_SYSTEM_H_ #define XENIA_HID_INPUT_SYSTEM_H_ +#include #include #include @@ -32,7 +33,7 @@ class InputSystem { X_STATUS Setup(); - void AddDriver(InputDriver* driver); + void AddDriver(std::unique_ptr driver); X_RESULT GetCapabilities(uint32_t user_index, uint32_t flags, X_INPUT_CAPABILITIES* out_caps); @@ -46,7 +47,7 @@ class InputSystem { Memory* memory_; cpu::Processor* processor_; - std::vector drivers_; + std::vector> drivers_; }; } // namespace hid diff --git a/src/xenia/kernel/fs/devices/disc_image_file.cc b/src/xenia/kernel/fs/devices/disc_image_file.cc index 82afb41f1..1efb68b3f 100644 --- a/src/xenia/kernel/fs/devices/disc_image_file.cc +++ b/src/xenia/kernel/fs/devices/disc_image_file.cc @@ -23,7 +23,7 @@ DiscImageFile::DiscImageFile(KernelState* kernel_state, Mode mode, DiscImageEntry* entry) : XFile(kernel_state, mode), entry_(entry) {} -DiscImageFile::~DiscImageFile() {} +DiscImageFile::~DiscImageFile() { delete entry_; } const std::string& DiscImageFile::path() const { return entry_->path(); } diff --git a/src/xenia/kernel/fs/devices/host_path_file.cc b/src/xenia/kernel/fs/devices/host_path_file.cc index 0a81b8fed..eafd2cd1f 100644 --- a/src/xenia/kernel/fs/devices/host_path_file.cc +++ b/src/xenia/kernel/fs/devices/host_path_file.cc @@ -22,7 +22,10 @@ HostPathFile::HostPathFile(KernelState* kernel_state, Mode mode, file_handle_(file_handle), XFile(kernel_state, mode) {} -HostPathFile::~HostPathFile() { CloseHandle(file_handle_); } +HostPathFile::~HostPathFile() { + CloseHandle(file_handle_); + delete entry_; +} const std::string& HostPathFile::path() const { return entry_->path(); } diff --git a/src/xenia/kernel/fs/devices/stfs_container_file.cc b/src/xenia/kernel/fs/devices/stfs_container_file.cc index fa7750c57..b52c6e7ce 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_file.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_file.cc @@ -23,7 +23,7 @@ STFSContainerFile::STFSContainerFile(KernelState* kernel_state, Mode mode, STFSContainerEntry* entry) : entry_(entry), XFile(kernel_state, mode) {} -STFSContainerFile::~STFSContainerFile() {} +STFSContainerFile::~STFSContainerFile() { delete entry_; } const std::string& STFSContainerFile::path() const { return entry_->path(); } diff --git a/src/xenia/kernel/fs/filesystem.cc b/src/xenia/kernel/fs/filesystem.cc index 8499c3185..e3b37bb89 100644 --- a/src/xenia/kernel/fs/filesystem.cc +++ b/src/xenia/kernel/fs/filesystem.cc @@ -176,6 +176,16 @@ std::unique_ptr FileSystem::ResolvePath(const std::string& path) { return nullptr; } +X_STATUS FileSystem::Open(std::unique_ptr entry, + KernelState* kernel_state, Mode mode, bool async, + XFile** out_file) { + auto result = entry->Open(kernel_state, mode, async, out_file); + if (XSUCCEEDED(result)) { + entry.release(); + } + return result; +} + } // namespace fs } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/fs/filesystem.h b/src/xenia/kernel/fs/filesystem.h index c785966be..708f89343 100644 --- a/src/xenia/kernel/fs/filesystem.h +++ b/src/xenia/kernel/fs/filesystem.h @@ -52,6 +52,8 @@ class FileSystem { int DeleteSymbolicLink(const std::string& path); std::unique_ptr ResolvePath(const std::string& path); + X_STATUS Open(std::unique_ptr entry, KernelState* kernel_state, + Mode mode, bool async, XFile** out_file); private: std::vector devices_; diff --git a/src/xenia/kernel/objects/xuser_module.cc b/src/xenia/kernel/objects/xuser_module.cc index 164f407ad..4f59c205d 100644 --- a/src/xenia/kernel/objects/xuser_module.cc +++ b/src/xenia/kernel/objects/xuser_module.cc @@ -62,7 +62,8 @@ X_STATUS XUserModule::LoadFromFile(const char* path) { std::vector buffer(file_info.file_length); // Open file for reading. - result = fs_entry->Open(kernel_state(), fs::Mode::READ, false, &file); + result = kernel_state()->file_system()->Open( + std::move(fs_entry), kernel_state(), fs::Mode::READ, false, &file); XEEXPECTZERO(result); // Read entire file into memory. diff --git a/src/xenia/kernel/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl_io.cc index 7b8dfcab3..a74a77549 100644 --- a/src/xenia/kernel/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl_io.cc @@ -105,9 +105,9 @@ SHIM_CALL NtCreateFile_shim(PPCContext* ppc_state, KernelState* state) { XFile* file = NULL; if (entry && entry->type() == Entry::Type::FILE) { // Open the file. - result = entry->Open(state, mode, - false, // TODO(benvanik): pick async mode, if needed. - &file); + result = fs->Open(std::move(entry), state, mode, + false, // TODO(benvanik): pick async mode, if needed. + &file); } else { result = X_STATUS_NO_SUCH_FILE; info = X_FILE_DOES_NOT_EXIST; @@ -173,9 +173,9 @@ SHIM_CALL NtOpenFile_shim(PPCContext* ppc_state, KernelState* state) { XFile* file = NULL; if (entry && entry->type() == Entry::Type::FILE) { // Open the file. - result = entry->Open(state, mode, - false, // TODO(benvanik): pick async mode, if needed. - &file); + result = fs->Open(std::move(entry), state, mode, + false, // TODO(benvanik): pick async mode, if needed. + &file); } else { result = X_STATUS_NO_SUCH_FILE; info = X_FILE_DOES_NOT_EXIST; From e1b0388faf64cba32253ba369df66025d968fc6f Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 21 Aug 2014 20:26:55 -0700 Subject: [PATCH 150/388] Splitting logging core into poly. --- src/alloy/backend/x64/x64_code_cache_win.cc | 2 +- src/alloy/backend/x64/x64_emitter.cc | 8 +- src/alloy/backend/x64/x64_sequences.cc | 2 +- .../passes/register_allocation_pass.cc | 4 +- src/alloy/core.h | 1 - src/alloy/frontend/ppc/ppc_hir_builder.cc | 6 +- src/alloy/frontend/ppc/ppc_scanner.cc | 58 +++++++------- src/alloy/runtime/function.cc | 6 +- src/{xenia => poly}/logging.cc | 75 +++++++++--------- src/poly/logging.h | 77 +++++++++++++++++++ src/poly/poly.h | 1 + src/poly/sources.gypi | 2 + src/xenia/gpu/d3d11/d3d11_graphics_driver.cc | 4 +- src/xenia/gpu/d3d11/d3d11_profiler_display.cc | 2 +- src/xenia/logging.h | 72 +++++------------ src/xenia/sources.gypi | 1 - tools/xenia-compare/xenia-compare.cc | 7 +- tools/xenia-debug/xenia-debug.cc | 8 +- tools/xenia-run/xenia-run.cc | 2 +- 19 files changed, 194 insertions(+), 144 deletions(-) rename src/{xenia => poly}/logging.cc (52%) create mode 100644 src/poly/logging.h diff --git a/src/alloy/backend/x64/x64_code_cache_win.cc b/src/alloy/backend/x64/x64_code_cache_win.cc index 50cac069f..75ed4ee37 100644 --- a/src/alloy/backend/x64/x64_code_cache_win.cc +++ b/src/alloy/backend/x64/x64_code_cache_win.cc @@ -194,7 +194,7 @@ void X64CodeChunk::AddTableEntry(uint8_t* code, size_t code_size, if (fn_table_count + 1 > fn_table_capacity) { // Table exhausted, need to realloc. If this happens a lot we should tune // the table size to prevent this. - XELOGW("X64CodeCache growing FunctionTable - adjust ESTIMATED_FN_SIZE"); + PLOGW("X64CodeCache growing FunctionTable - adjust ESTIMATED_FN_SIZE"); RtlDeleteGrowableFunctionTable(fn_table_handle); size_t old_size = fn_table_capacity * sizeof(RUNTIME_FUNCTION); size_t new_size = old_size * 2; diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index 7d387600e..f90d1b0bf 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -193,7 +193,7 @@ int X64Emitter::Emit(HIRBuilder* builder, size_t& out_stack_size) { if (!SelectSequence(*this, instr, &new_tail)) { // No sequence found! assert_always(); - XELOGE("Unable to process HIR opcode %s", instr->opcode->name); + PLOGE("Unable to process HIR opcode %s", instr->opcode->name); break; } instr = new_tail; @@ -372,7 +372,7 @@ void X64Emitter::Trap(uint16_t trap_type) { db(0xCC); break; default: - XELOGW("Unknown trap type %d", trap_type); + PLOGW("Unknown trap type %d", trap_type); db(0xCC); break; } @@ -598,8 +598,8 @@ void X64Emitter::CallIndirect(const hir::Instr* instr, const Reg64& reg) { uint64_t UndefinedCallExtern(void* raw_context, uint64_t symbol_info_ptr) { auto symbol_info = reinterpret_cast(symbol_info_ptr); - XELOGW("undefined extern call to %.8llX %s", symbol_info->address(), - symbol_info->name().c_str()); + PLOGW("undefined extern call to %.8llX %s", symbol_info->address(), + symbol_info->name().c_str()); return 0; } void X64Emitter::CallExtern(const hir::Instr* instr, diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index e015fbd4b..d09fa7304 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -5392,7 +5392,7 @@ bool SelectSequence(X64Emitter& e, const Instr* i, const Instr** new_tail) { return true; } } - XELOGE("No sequence match for variant %s", i->opcode->name); + PLOGE("No sequence match for variant %s", i->opcode->name); return false; } diff --git a/src/alloy/compiler/passes/register_allocation_pass.cc b/src/alloy/compiler/passes/register_allocation_pass.cc index 2e4f6fc21..4db4cd1ef 100644 --- a/src/alloy/compiler/passes/register_allocation_pass.cc +++ b/src/alloy/compiler/passes/register_allocation_pass.cc @@ -145,7 +145,7 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) { // We spill only those registers we aren't using. if (!SpillOneRegister(builder, block, instr->dest->type)) { // Unable to spill anything - this shouldn't happen. - XELOGE("Unable to spill any registers"); + PLOGE("Unable to spill any registers"); assert_always(); return 1; } @@ -153,7 +153,7 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) { // Demand allocation. if (!TryAllocateRegister(instr->dest)) { // Boned. - XELOGE("Register allocation failed"); + PLOGE("Register allocation failed"); assert_always(); return 1; } diff --git a/src/alloy/core.h b/src/alloy/core.h index 08c6e2645..eedae6ac1 100644 --- a/src/alloy/core.h +++ b/src/alloy/core.h @@ -11,7 +11,6 @@ #define ALLOY_CORE_H_ // TODO(benvanik): move the common stuff into here? -#include #include #endif // ALLOY_CORE_H_ diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index 9078bfa3f..d0b6581e6 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -116,7 +116,7 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) { instr_offset_list_[offset] = first_instr; if (!i.type) { - XELOGCPU("Invalid instruction %.8llX %.8X", i.address, i.code); + PLOGE("Invalid instruction %.8llX %.8X", i.address, i.code); Comment("INVALID!"); // TraceInvalidInstruction(i); continue; @@ -131,8 +131,8 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) { } if (!i.type->emit || emit(*this, i)) { - XELOGCPU("Unimplemented instr %.8llX %.8X %s", i.address, i.code, - i.type->name); + PLOGE("Unimplemented instr %.8llX %.8X %s", i.address, i.code, + i.type->name); Comment("UNIMPLEMENTED!"); // DebugBreak(); // TraceInvalidInstruction(i); diff --git a/src/alloy/frontend/ppc/ppc_scanner.cc b/src/alloy/frontend/ppc/ppc_scanner.cc index 882b920b4..ba255ab07 100644 --- a/src/alloy/frontend/ppc/ppc_scanner.cc +++ b/src/alloy/frontend/ppc/ppc_scanner.cc @@ -15,8 +15,15 @@ #include #include #include +#include #include +#if 0 +#define LOGPPC(fmt, ...) PLOGCORE('p', fmt, ##__VA_ARGS__) +#else +#define LOGPPC(fmt, ...) POLY_EMPTY_MACRO +#endif + namespace alloy { namespace frontend { namespace ppc { @@ -48,7 +55,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { Memory* memory = frontend_->memory(); const uint8_t* p = memory->membase(); - XELOGSDB("Analyzing function %.8X...", symbol_info->address()); + LOGPPC("Analyzing function %.8X...", symbol_info->address()); uint32_t start_address = static_cast(symbol_info->address()); uint32_t end_address = static_cast(symbol_info->end_address()); @@ -65,7 +72,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { // If we fetched 0 assume that we somehow hit one of the awesome // 'no really we meant to end after that bl' functions. if (!i.code) { - XELOGSDB("function end %.8X (0x00000000 read)", address); + LOGPPC("function end %.8X (0x00000000 read)", address); // Don't include the 0's. address -= 4; break; @@ -94,17 +101,16 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { // Invalid instruction. // We can just ignore it because there's (very little)/no chance it'll // affect flow control. - XELOGSDB("Invalid instruction at %.8X: %.8X", address, i.code); + LOGPPC("Invalid instruction at %.8X: %.8X", address, i.code); } else if (i.code == 0x4E800020) { // blr -- unconditional branch to LR. // This is generally a return. if (furthest_target > address) { // Remaining targets within function, not end. - XELOGSDB("ignoring blr %.8X (branch to %.8X)", address, - furthest_target); + LOGPPC("ignoring blr %.8X (branch to %.8X)", address, furthest_target); } else { // Function end point. - XELOGSDB("function end %.8X", address); + LOGPPC("function end %.8X", address); ends_fn = true; } ends_block = true; @@ -115,11 +121,10 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { // TODO(benvanik): decode jump tables. if (furthest_target > address) { // Remaining targets within function, not end. - XELOGSDB("ignoring bctr %.8X (branch to %.8X)", address, - furthest_target); + LOGPPC("ignoring bctr %.8X (branch to %.8X)", address, furthest_target); } else { // Function end point. - XELOGSDB("function end %.8X", address); + LOGPPC("function end %.8X", address); ends_fn = true; } ends_block = true; @@ -129,25 +134,25 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { (uint32_t)XEEXTS26(i.I.LI << 2) + (i.I.AA ? 0 : (int32_t)address); if (i.I.LK) { - XELOGSDB("bl %.8X -> %.8X", address, target); + LOGPPC("bl %.8X -> %.8X", address, target); // Queue call target if needed. // GetOrInsertFunction(target); } else { - XELOGSDB("b %.8X -> %.8X", address, target); + LOGPPC("b %.8X -> %.8X", address, target); // If the target is back into the function and there's no further target // we are at the end of a function. // (Indirect branches may still go beyond, but no way of knowing). if (target >= start_address && target < address && furthest_target <= address) { - XELOGSDB("function end %.8X (back b)", address); + LOGPPC("function end %.8X (back b)", address); ends_fn = true; } // If the target is not a branch and it goes to before the current // address it's definitely a tail call. if (!ends_fn && target < start_address && furthest_target <= address) { - XELOGSDB("function end %.8X (back b before addr)", address); + LOGPPC("function end %.8X (back b before addr)", address); ends_fn = true; } @@ -156,7 +161,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { // of the function somewhere, so ensure we don't have any branches over // it. if (!ends_fn && furthest_target <= address && IsRestGprLr(target)) { - XELOGSDB("function end %.8X (__restgprlr_*)", address); + LOGPPC("function end %.8X (__restgprlr_*)", address); ends_fn = true; } @@ -168,7 +173,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { // This check may hit on functions that jump over data code, so only // trigger this check in leaf functions (no mfspr lr/prolog). if (!ends_fn && !starts_with_mfspr_lr && blocks_found == 1) { - XELOGSDB("HEURISTIC: ending at simple leaf thunk %.8X", address); + LOGPPC("HEURISTIC: ending at simple leaf thunk %.8X", address); ends_fn = true; } @@ -186,7 +191,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { if (!ends_fn && target > addr && furthest_target < addr) { - XELOGSDB("HEURISTIC: ending at tail call branch %.8X", addr); + LOGPPC("HEURISTIC: ending at tail call branch %.8X", addr); ends_fn = true; } */ @@ -206,14 +211,14 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { uint32_t target = (uint32_t)XEEXTS16(i.B.BD << 2) + (i.B.AA ? 0 : (int32_t)address); if (i.B.LK) { - XELOGSDB("bcl %.8X -> %.8X", address, target); + LOGPPC("bcl %.8X -> %.8X", address, target); // Queue call target if needed. // TODO(benvanik): see if this is correct - not sure anyone makes // function calls with bcl. // GetOrInsertFunction(target); } else { - XELOGSDB("bc %.8X -> %.8X", address, target); + LOGPPC("bc %.8X -> %.8X", address, target); // TODO(benvanik): GetOrInsertFunction? it's likely a BB @@ -225,17 +230,17 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { } else if (i.type->opcode == 0x4C000020) { // bclr/bclrl if (i.XL.LK) { - XELOGSDB("bclrl %.8X", address); + LOGPPC("bclrl %.8X", address); } else { - XELOGSDB("bclr %.8X", address); + LOGPPC("bclr %.8X", address); } ends_block = true; } else if (i.type->opcode == 0x4C000420) { // bcctr/bcctrl if (i.XL.LK) { - XELOGSDB("bcctrl %.8X", address); + LOGPPC("bcctrl %.8X", address); } else { - XELOGSDB("bcctr %.8X", address); + LOGPPC("bcctr %.8X", address); } ends_block = true; } @@ -250,8 +255,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { address += 4; if (end_address && address > end_address) { // Hmm.... - XELOGSDB("Ran over function bounds! %.8X-%.8X", start_address, - end_address); + LOGPPC("Ran over function bounds! %.8X-%.8X", start_address, end_address); break; } } @@ -261,8 +265,8 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { // from someplace valid (like method hints) this may indicate an error. // It's also possible that we guessed in hole-filling and there's another // function below this one. - XELOGSDB("Function ran under: %.8X-%.8X ended at %.8X", start_address, - end_address, address + 4); + LOGPPC("Function ran under: %.8X-%.8X ended at %.8X", start_address, + end_address, address + 4); } symbol_info->set_end_address(address); @@ -274,7 +278,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) { // - if present, flag function as needing a stack // - record prolog/epilog lengths/stack size/etc - XELOGSDB("Finished analyzing %.8X", start_address); + LOGPPC("Finished analyzing %.8X", start_address); return 0; } diff --git a/src/alloy/runtime/function.cc b/src/alloy/runtime/function.cc index 6f7f2762a..7f863ed29 100644 --- a/src/alloy/runtime/function.cc +++ b/src/alloy/runtime/function.cc @@ -65,7 +65,7 @@ Breakpoint* Function::FindBreakpoint(uint64_t address) { } int Function::Call(ThreadState* thread_state, uint64_t return_address) { - SCOPE_profile_cpu_f("alloy"); + //SCOPE_profile_cpu_f("alloy"); ThreadState* original_thread_state = ThreadState::Get(); if (original_thread_state != thread_state) { @@ -90,8 +90,8 @@ int Function::Call(ThreadState* thread_state, uint64_t return_address) { handler(thread_state->raw_context(), symbol_info_->extern_arg0(), symbol_info_->extern_arg1()); } else { - XELOGW("undefined extern call to %.8llX %s", symbol_info_->address(), - symbol_info_->name().c_str()); + PLOGW("undefined extern call to %.8llX %s", symbol_info_->address(), + symbol_info_->name().c_str()); result = 1; } diff --git a/src/xenia/logging.cc b/src/poly/logging.cc similarity index 52% rename from src/xenia/logging.cc rename to src/poly/logging.cc index dbabd593a..dcd3aa32a 100644 --- a/src/xenia/logging.cc +++ b/src/poly/logging.cc @@ -7,44 +7,49 @@ ****************************************************************************** */ -#include +#include #include #include #include #include -#include DEFINE_bool(fast_stdout, false, - "Don't lock around stdout/stderr. May introduce weirdness."); + "Don't lock around stdout/stderr. May introduce weirdness."); +DEFINE_bool(log_filenames, false, + "Log filenames/line numbers in log statements."); +namespace poly { -namespace { std::mutex log_lock; -} // namespace +void format_log_line(char* buffer, size_t buffer_count, const char* file_path, + const uint32_t line_number, const char level_char, + const char* fmt, va_list args) { + char* buffer_ptr; + if (FLAGS_log_filenames) { + // Strip out just the filename from the path. + const char* filename = strrchr(file_path, poly::path_separator); + if (filename) { + // Slash - skip over it. + filename++; + } else { + // No slash, entire thing is filename. + filename = file_path; + } -void xe_format_log_line( - char* buffer, size_t buffer_count, - const char* file_path, const uint32_t line_number, - const char* function_name, const char level_char, - const char* fmt, va_list args) { - // Strip out just the filename from the path. - const char* filename = strrchr(file_path, poly::path_separator); - if (filename) { - // Slash - skip over it. - filename++; + // Format string - add a trailing newline if required. + const char* outfmt = "%c> %s:%d: "; + buffer_ptr = buffer + snprintf(buffer, buffer_count - 1, outfmt, level_char, + filename, line_number); } else { - // No slash, entire thing is filename. - filename = file_path; + buffer_ptr = buffer; + *(buffer_ptr++) = level_char; + *(buffer_ptr++) = '>'; + *(buffer_ptr++) = ' '; } - // Format string - add a trailing newline if required. - const char* outfmt = "XE[%c] %s:%d: "; - char* buffer_ptr = buffer + snprintf(buffer, buffer_count - 1, outfmt, - level_char, filename, line_number); - // Scribble args into the print buffer. buffer_ptr = buffer_ptr + vsnprintf(buffer_ptr, buffer_count - (buffer_ptr - buffer) - 1, @@ -57,23 +62,21 @@ void xe_format_log_line( } } -void xe_log_line(const char* file_path, const uint32_t line_number, - const char* function_name, const char level_char, - const char* fmt, ...) { - SCOPE_profile_cpu_i("emu", "log_line"); +void log_line(const char* file_path, const uint32_t line_number, + const char level_char, const char* fmt, ...) { + // SCOPE_profile_cpu_i("emu", "log_line"); char buffer[2048]; va_list args; va_start(args, fmt); - xe_format_log_line(buffer, poly::countof(buffer), - file_path, line_number, function_name, level_char, - fmt, args); + format_log_line(buffer, poly::countof(buffer), file_path, line_number, + level_char, fmt, args); va_end(args); if (!FLAGS_fast_stdout) { log_lock.lock(); } -#if 0// defined(OutputDebugString) +#if 0 // defined(OutputDebugString) OutputDebugStringA(buffer); #else fprintf(stdout, buffer); @@ -84,15 +87,13 @@ void xe_log_line(const char* file_path, const uint32_t line_number, } } -void xe_handle_fatal( - const char* file_path, const uint32_t line_number, - const char* function_name, const char* fmt, ...) { +void handle_fatal(const char* file_path, const uint32_t line_number, + const char* fmt, ...) { char buffer[2048]; va_list args; va_start(args, fmt); - xe_format_log_line(buffer, poly::countof(buffer), - file_path, line_number, function_name, 'X', - fmt, args); + format_log_line(buffer, poly::countof(buffer), file_path, line_number, 'X', + fmt, args); va_end(args); if (!FLAGS_fast_stdout) { @@ -117,3 +118,5 @@ void xe_handle_fatal( exit(1); } + +} // namespace poly diff --git a/src/poly/logging.h b/src/poly/logging.h new file mode 100644 index 000000000..6ac8e0b75 --- /dev/null +++ b/src/poly/logging.h @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef POLY_LOGGING_H_ +#define POLY_LOGGING_H_ + +#include + +#include + +namespace poly { + +#define POLY_OPTION_ENABLE_LOGGING 1 +#define POLY_OPTION_LOG_ERROR 1 +#define POLY_OPTION_LOG_WARNING 1 +#define POLY_OPTION_LOG_INFO 1 +#define POLY_OPTION_LOG_DEBUG 1 + +#define POLY_EMPTY_MACRO \ + do { \ + } while (false) + +#if XE_COMPILER_GNUC +#define POLY_LOG_LINE_ATTRIBUTE __attribute__((format(printf, 5, 6))) +#else +#define POLY_LOG_LINE_ATTRIBUTE +#endif // GNUC +void log_line(const char* file_path, const uint32_t line_number, + const char level_char, const char* fmt, + ...) POLY_LOG_LINE_ATTRIBUTE; +#undef POLY_LOG_LINE_ATTRIBUTE + +void handle_fatal(const char* file_path, const uint32_t line_number, + const char* fmt, ...); + +#if POLY_OPTION_ENABLE_LOGGING +#define PLOGCORE(level, fmt, ...) \ + poly::log_line(__FILE__, __LINE__, level, fmt, ##__VA_ARGS__) +#else +#define PLOGCORE(level, fmt, ...) POLY_EMPTY_MACRO +#endif // ENABLE_LOGGING + +#define PFATAL(fmt, ...) \ + do { \ + poly::handle_fatal(__FILE__, __LINE__, fmt, ##__VA_ARGS__); \ + } while (false) + +#if POLY_OPTION_LOG_ERROR +#define PLOGE(fmt, ...) PLOGCORE('!', fmt, ##__VA_ARGS__) +#else +#define PLOGE(fmt, ...) POLY_EMPTY_MACRO +#endif +#if POLY_OPTION_LOG_WARNING +#define PLOGW(fmt, ...) PLOGCORE('w', fmt, ##__VA_ARGS__) +#else +#define PLOGW(fmt, ...) POLY_EMPTY_MACRO +#endif +#if POLY_OPTION_LOG_INFO +#define PLOGI(fmt, ...) PLOGCORE('i', fmt, ##__VA_ARGS__) +#else +#define PLOGI(fmt, ...) POLY_EMPTY_MACRO +#endif +#if POLY_OPTION_LOG_DEBUG +#define PLOGD(fmt, ...) PLOGCORE('d', fmt, ##__VA_ARGS__) +#else +#define PLOGD(fmt, ...) POLY_EMPTY_MACRO +#endif + +} // namespace poly + +#endif // POLY_LOGGING_H_ diff --git a/src/poly/poly.h b/src/poly/poly.h index 95cc10ec1..db4a1796c 100644 --- a/src/poly/poly.h +++ b/src/poly/poly.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/src/poly/sources.gypi b/src/poly/sources.gypi index b052dd85a..a0fe765f3 100644 --- a/src/poly/sources.gypi +++ b/src/poly/sources.gypi @@ -7,6 +7,8 @@ 'debugging.h', 'config.h', 'cxx_compat.h', + 'logging.cc', + 'logging.h', 'main.h', 'mapped_memory.h', 'math.cc', diff --git a/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc b/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc index 4a5bf6385..88caebe17 100644 --- a/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc +++ b/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc @@ -125,7 +125,7 @@ void D3D11GraphicsDriver::InitializeInvalidTexture() { HRESULT hr = device_->CreateTexture2D( &texture_desc, &initial_data, (ID3D11Texture2D**)&texture); if (FAILED(hr)) { - XEFATAL("D3D11: unable to create invalid texture"); + PFATAL("D3D11: unable to create invalid texture"); return; } @@ -155,7 +155,7 @@ void D3D11GraphicsDriver::InitializeInvalidTexture() { hr = device_->CreateSamplerState( &sampler_desc, &invalid_texture_sampler_state_); if (FAILED(hr)) { - XEFATAL("D3D11: unable to create invalid sampler state"); + PFATAL("D3D11: unable to create invalid sampler state"); return; } } diff --git a/src/xenia/gpu/d3d11/d3d11_profiler_display.cc b/src/xenia/gpu/d3d11/d3d11_profiler_display.cc index 6bc31ea15..4c1672808 100644 --- a/src/xenia/gpu/d3d11/d3d11_profiler_display.cc +++ b/src/xenia/gpu/d3d11/d3d11_profiler_display.cc @@ -401,7 +401,7 @@ bool D3D11ProfilerDisplay::SetupFont() { hr = device->CreateSamplerState( &sampler_desc, &font_sampler_state_); if (FAILED(hr)) { - XEFATAL("D3D11: unable to create invalid sampler state"); + PFATAL("D3D11: unable to create invalid sampler state"); return false; } diff --git a/src/xenia/logging.h b/src/xenia/logging.h index 2f55b5b3f..ebf988513 100644 --- a/src/xenia/logging.h +++ b/src/xenia/logging.h @@ -12,7 +12,7 @@ #include -#include +#include #define XE_OPTION_ENABLE_LOGGING 1 #define XE_OPTION_LOG_ERROR 1 @@ -20,89 +20,55 @@ #define XE_OPTION_LOG_INFO 1 #define XE_OPTION_LOG_DEBUG 1 #define XE_OPTION_LOG_CPU 1 -#define XE_OPTION_LOG_SDB 0 #define XE_OPTION_LOG_APU 1 #define XE_OPTION_LOG_GPU 1 #define XE_OPTION_LOG_KERNEL 1 #define XE_OPTION_LOG_FS 1 -#define XE_EMPTY_MACRO do { } while(0) - -#if XE_COMPILER_GNUC -#define XE_LOG_LINE_ATTRIBUTE __attribute__ ((format (printf, 5, 6))) -#else -#define XE_LOG_LINE_ATTRIBUTE -#endif // GNUC -void xe_log_line(const char* file_path, const uint32_t line_number, - const char* function_name, const char level_char, - const char* fmt, ...) XE_LOG_LINE_ATTRIBUTE; -#undef XE_LOG_LINE_ATTRIBUTE -void xe_handle_fatal( - const char* file_path, const uint32_t line_number, - const char* function_name, const char* fmt, ...); - -#if XE_OPTION_ENABLE_LOGGING -#define XELOGCORE(level, fmt, ...) xe_log_line( \ - __FILE__, __LINE__, __FUNCTION__, level, \ - fmt, ##__VA_ARGS__) -#else -#define XELOGCORE(level, fmt, ...) XE_EMPTY_MACRO -#endif // ENABLE_LOGGING - -#define XEFATAL(fmt, ...) do { \ - xe_handle_fatal(__FILE__, __LINE__, __FUNCTION__, \ - fmt, ##__VA_ARGS__); \ - } while (false); - #if XE_OPTION_LOG_ERROR -#define XELOGE(fmt, ...) XELOGCORE('!', fmt, ##__VA_ARGS__) +#define XELOGE PLOGE #else -#define XELOGE(fmt, ...) XE_EMPTY_MACRO +#define XELOGE(fmt, ...) POLY_EMPTY_MACRO #endif #if XE_OPTION_LOG_WARNING -#define XELOGW(fmt, ...) XELOGCORE('w', fmt, ##__VA_ARGS__) +#define XELOGW PLOGW #else -#define XELOGW(fmt, ...) XE_EMPTY_MACRO +#define XELOGW(fmt, ...) POLY_EMPTY_MACRO #endif #if XE_OPTION_LOG_INFO -#define XELOGI(fmt, ...) XELOGCORE('i', fmt, ##__VA_ARGS__) +#define XELOGI PLOGI #else -#define XELOGI(fmt, ...) XE_EMPTY_MACRO +#define XELOGI(fmt, ...) POLY_EMPTY_MACRO #endif #if XE_OPTION_LOG_DEBUG -#define XELOGD(fmt, ...) XELOGCORE('d', fmt, ##__VA_ARGS__) +#define XELOGD PLOGD #else -#define XELOGD(fmt, ...) XE_EMPTY_MACRO +#define XELOGD(fmt, ...) POLY_EMPTY_MACRO #endif #if XE_OPTION_LOG_CPU -#define XELOGCPU(fmt, ...) XELOGCORE('C', fmt, ##__VA_ARGS__) +#define XELOGCPU(fmt, ...) PLOGCORE('C', fmt, ##__VA_ARGS__) #else -#define XELOGCPU(fmt, ...) XE_EMPTY_MACRO -#endif -#if XE_OPTION_LOG_SDB -#define XELOGSDB(fmt, ...) XELOGCORE('S', fmt, ##__VA_ARGS__) -#else -#define XELOGSDB(fmt, ...) XE_EMPTY_MACRO +#define XELOGCPU(fmt, ...) POLY_EMPTY_MACRO #endif #if XE_OPTION_LOG_APU -#define XELOGAPU(fmt, ...) XELOGCORE('A', fmt, ##__VA_ARGS__) +#define XELOGAPU(fmt, ...) PLOGCORE('A', fmt, ##__VA_ARGS__) #else -#define XELOGAPU(fmt, ...) XE_EMPTY_MACRO +#define XELOGAPU(fmt, ...) POLY_EMPTY_MACRO #endif #if XE_OPTION_LOG_GPU -#define XELOGGPU(fmt, ...) XELOGCORE('G', fmt, ##__VA_ARGS__) +#define XELOGGPU(fmt, ...) PLOGCORE('G', fmt, ##__VA_ARGS__) #else -#define XELOGGPU(fmt, ...) XE_EMPTY_MACRO +#define XELOGGPU(fmt, ...) POLY_EMPTY_MACRO #endif #if XE_OPTION_LOG_KERNEL -#define XELOGKERNEL(fmt, ...) XELOGCORE('K', fmt, ##__VA_ARGS__) +#define XELOGKERNEL(fmt, ...) PLOGCORE('K', fmt, ##__VA_ARGS__) #else -#define XELOGKERNEL(fmt, ...) XE_EMPTY_MACRO +#define XELOGKERNEL(fmt, ...) POLY_EMPTY_MACRO #endif #if XE_OPTION_LOG_FS -#define XELOGFS(fmt, ...) XELOGCORE('F', fmt, ##__VA_ARGS__) +#define XELOGFS(fmt, ...) PLOGCORE('F', fmt, ##__VA_ARGS__) #else -#define XELOGFS(fmt, ...) XE_EMPTY_MACRO +#define XELOGFS(fmt, ...) POLY_EMPTY_MACRO #endif diff --git a/src/xenia/sources.gypi b/src/xenia/sources.gypi index 5f85ac199..d600a3025 100644 --- a/src/xenia/sources.gypi +++ b/src/xenia/sources.gypi @@ -9,7 +9,6 @@ 'emulator.h', 'export_resolver.cc', 'export_resolver.h', - 'logging.cc', 'logging.h', 'memory.cc', 'memory.h', diff --git a/tools/xenia-compare/xenia-compare.cc b/tools/xenia-compare/xenia-compare.cc index 16200cb21..e6cc1fd85 100644 --- a/tools/xenia-compare/xenia-compare.cc +++ b/tools/xenia-compare/xenia-compare.cc @@ -25,13 +25,12 @@ using xdb::PostmortemDebugTarget; int main(std::vector& args) { auto left_target = std::make_unique(); if (!left_target->LoadTrace(poly::to_wstring(FLAGS_trace_file_left))) { - XEFATAL("Unable to load left trace file: %s", - FLAGS_trace_file_left.c_str()); + PFATAL("Unable to load left trace file: %s", FLAGS_trace_file_left.c_str()); } auto right_target = std::make_unique(); if (!right_target->LoadTrace(poly::to_wstring(FLAGS_trace_file_right))) { - XEFATAL("Unable to load right trace file: %s", - FLAGS_trace_file_right.c_str()); + PFATAL("Unable to load right trace file: %s", + FLAGS_trace_file_right.c_str()); } return 0; diff --git a/tools/xenia-debug/xenia-debug.cc b/tools/xenia-debug/xenia-debug.cc index ce8450d50..27863f72b 100644 --- a/tools/xenia-debug/xenia-debug.cc +++ b/tools/xenia-debug/xenia-debug.cc @@ -26,7 +26,7 @@ namespace xdb { int main(std::vector& args) { wxInitializer init; if (!init.IsOk()) { - XEFATAL("Failed to initialize wxWidgets"); + PFATAL("Failed to initialize wxWidgets"); return 1; } @@ -34,18 +34,18 @@ int main(std::vector& args) { auto app = new ui::XdbApp(); wxApp::SetInstance(app); if (!wxEntryStart(0, nullptr)) { - XEFATAL("Failed to enter wxWidgets app"); + PFATAL("Failed to enter wxWidgets app"); return 1; } if (!app->OnInit()) { - XEFATAL("Failed to init app"); + PFATAL("Failed to init app"); return 1; } if (!FLAGS_trace_file.empty()) { // Trace file specified on command line. if (!app->OpenTraceFile(FLAGS_trace_file, FLAGS_content_file)) { - XEFATAL("Failed to open trace file"); + PFATAL("Failed to open trace file"); return 1; } } else { diff --git a/tools/xenia-run/xenia-run.cc b/tools/xenia-run/xenia-run.cc index a238824df..55dc11e64 100644 --- a/tools/xenia-run/xenia-run.cc +++ b/tools/xenia-run/xenia-run.cc @@ -23,7 +23,7 @@ int xenia_run(std::vector& args) { // Grab path from the flag or unnamed argument. if (!FLAGS_target.size() && args.size() < 2) { google::ShowUsageWithFlags("xenia-run"); - XEFATAL("Pass a file to launch."); + PFATAL("Pass a file to launch."); return 1; } std::wstring path; From 82b9841b5a6e967c017efb217d927a1a4b3642e1 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 21 Aug 2014 20:49:47 -0700 Subject: [PATCH 151/388] Removing alloy/core.h. --- src/alloy/alloy-private.h | 2 -- src/alloy/alloy.h | 2 -- src/alloy/arena.h | 2 +- src/alloy/backend/assembler.h | 2 -- src/alloy/backend/backend.h | 1 - src/alloy/backend/ivm/ivm_assembler.cc | 1 + src/alloy/backend/ivm/ivm_assembler.h | 2 -- src/alloy/backend/ivm/ivm_backend.h | 2 -- src/alloy/backend/ivm/ivm_function.h | 23 ++++++++----------- src/alloy/backend/ivm/ivm_intcode.h | 6 ++--- src/alloy/backend/ivm/ivm_stack.h | 2 -- src/alloy/backend/machine_info.h | 2 +- src/alloy/backend/x64/x64_assembler.cc | 1 + src/alloy/backend/x64/x64_assembler.h | 4 +--- src/alloy/backend/x64/x64_backend.h | 2 -- src/alloy/backend/x64/x64_code_cache.h | 2 -- src/alloy/backend/x64/x64_code_cache_win.cc | 1 + src/alloy/backend/x64/x64_emitter.cc | 1 + src/alloy/backend/x64/x64_emitter.h | 3 --- src/alloy/backend/x64/x64_function.h | 1 - src/alloy/backend/x64/x64_sequences.h | 2 -- src/alloy/backend/x64/x64_thunk_emitter.h | 1 - src/alloy/backend/x64/x64_tracers.h | 3 +-- src/alloy/compiler/compiler.cc | 1 + src/alloy/compiler/compiler.h | 1 - src/alloy/compiler/compiler_pass.h | 2 -- .../passes/constant_propagation_pass.cc | 1 + .../compiler/passes/context_promotion_pass.cc | 1 + .../passes/control_flow_analysis_pass.cc | 1 + .../control_flow_simplification_pass.cc | 1 + .../passes/data_flow_analysis_pass.cc | 1 + .../passes/dead_code_elimination_pass.cc | 2 ++ .../compiler/passes/finalization_pass.cc | 1 + .../passes/register_allocation_pass.cc | 2 ++ .../compiler/passes/simplification_pass.cc | 2 ++ src/alloy/compiler/passes/validation_pass.cc | 1 + .../compiler/passes/value_reduction_pass.cc | 1 + src/alloy/core.h | 16 ------------- src/alloy/delegate.h | 2 -- src/alloy/frontend/context_info.h | 2 +- src/alloy/frontend/frontend.h | 3 +-- src/alloy/frontend/ppc/ppc_context.h | 1 - src/alloy/frontend/ppc/ppc_frontend.h | 4 +--- src/alloy/frontend/ppc/ppc_hir_builder.cc | 1 + src/alloy/frontend/ppc/ppc_hir_builder.h | 3 +-- src/alloy/frontend/ppc/ppc_instr.h | 3 +-- src/alloy/frontend/ppc/ppc_scanner.cc | 1 + src/alloy/frontend/ppc/ppc_scanner.h | 1 - src/alloy/frontend/ppc/ppc_translator.cc | 1 + src/alloy/frontend/ppc/ppc_translator.h | 3 +-- src/alloy/hir/block.h | 1 - src/alloy/hir/hir_builder.cc | 3 ++- src/alloy/hir/hir_builder.h | 1 - src/alloy/hir/instr.h | 1 - src/alloy/hir/label.h | 2 -- src/alloy/hir/opcodes.h | 2 +- src/alloy/hir/value.h | 3 +-- src/alloy/memory.h | 3 ++- src/alloy/reset_scope.h | 2 -- src/alloy/runtime/debug_info.cc | 2 ++ src/alloy/runtime/debug_info.h | 2 +- src/alloy/runtime/debugger.h | 1 - src/alloy/runtime/entry_table.cc | 1 + src/alloy/runtime/entry_table.h | 2 -- src/alloy/runtime/function.h | 1 - src/alloy/runtime/instrument.h | 2 +- src/alloy/runtime/module.cc | 1 + src/alloy/runtime/module.h | 2 +- src/alloy/runtime/raw_module.cc | 2 ++ src/alloy/runtime/runtime.cc | 1 + src/alloy/runtime/runtime.h | 3 +-- src/alloy/runtime/symbol_info.h | 3 +-- src/alloy/runtime/thread_state.h | 2 -- src/alloy/sources.gypi | 1 - src/alloy/string_buffer.cc | 1 + src/alloy/string_buffer.h | 3 +-- src/alloy/type_pool.h | 2 -- src/alloy/vec128.h | 1 - xenia.gyp | 1 + 79 files changed, 64 insertions(+), 115 deletions(-) delete mode 100644 src/alloy/core.h diff --git a/src/alloy/alloy-private.h b/src/alloy/alloy-private.h index 8888e7b1c..3efde3d21 100644 --- a/src/alloy/alloy-private.h +++ b/src/alloy/alloy-private.h @@ -10,8 +10,6 @@ #ifndef ALLOY_ALLOY_PRIVATE_H_ #define ALLOY_ALLOY_PRIVATE_H_ -#include - #include DECLARE_bool(debug); diff --git a/src/alloy/alloy.h b/src/alloy/alloy.h index 2a72b6125..2b2d9f318 100644 --- a/src/alloy/alloy.h +++ b/src/alloy/alloy.h @@ -10,8 +10,6 @@ #ifndef ALLOY_ALLOY_H_ #define ALLOY_ALLOY_H_ -#include - #include #include #include diff --git a/src/alloy/arena.h b/src/alloy/arena.h index 3dae80b8d..d7b956001 100644 --- a/src/alloy/arena.h +++ b/src/alloy/arena.h @@ -10,7 +10,7 @@ #ifndef ALLOY_ARENA_H_ #define ALLOY_ARENA_H_ -#include +#include namespace alloy { diff --git a/src/alloy/backend/assembler.h b/src/alloy/backend/assembler.h index 5e721dbd9..e671b6f38 100644 --- a/src/alloy/backend/assembler.h +++ b/src/alloy/backend/assembler.h @@ -12,8 +12,6 @@ #include -#include - namespace alloy { namespace hir { class HIRBuilder; diff --git a/src/alloy/backend/backend.h b/src/alloy/backend/backend.h index e4dea7832..efa8371c1 100644 --- a/src/alloy/backend/backend.h +++ b/src/alloy/backend/backend.h @@ -12,7 +12,6 @@ #include -#include #include namespace alloy { diff --git a/src/alloy/backend/ivm/ivm_assembler.cc b/src/alloy/backend/ivm/ivm_assembler.cc index c01eeb209..a79db653e 100644 --- a/src/alloy/backend/ivm/ivm_assembler.cc +++ b/src/alloy/backend/ivm/ivm_assembler.cc @@ -16,6 +16,7 @@ #include #include #include +#include namespace alloy { namespace backend { diff --git a/src/alloy/backend/ivm/ivm_assembler.h b/src/alloy/backend/ivm/ivm_assembler.h index 4fe079b37..118ef69d5 100644 --- a/src/alloy/backend/ivm/ivm_assembler.h +++ b/src/alloy/backend/ivm/ivm_assembler.h @@ -10,8 +10,6 @@ #ifndef ALLOY_BACKEND_IVM_IVM_ASSEMBLER_H_ #define ALLOY_BACKEND_IVM_IVM_ASSEMBLER_H_ -#include - #include #include diff --git a/src/alloy/backend/ivm/ivm_backend.h b/src/alloy/backend/ivm/ivm_backend.h index b01536b6b..46814353b 100644 --- a/src/alloy/backend/ivm/ivm_backend.h +++ b/src/alloy/backend/ivm/ivm_backend.h @@ -10,8 +10,6 @@ #ifndef ALLOY_BACKEND_IVM_IVM_BACKEND_H_ #define ALLOY_BACKEND_IVM_IVM_BACKEND_H_ -#include - #include namespace alloy { diff --git a/src/alloy/backend/ivm/ivm_function.h b/src/alloy/backend/ivm/ivm_function.h index 0169ee5b1..31eb07084 100644 --- a/src/alloy/backend/ivm/ivm_function.h +++ b/src/alloy/backend/ivm/ivm_function.h @@ -10,47 +10,42 @@ #ifndef ALLOY_BACKEND_IVM_IVM_FUNCTION_H_ #define ALLOY_BACKEND_IVM_IVM_FUNCTION_H_ -#include #include #include #include - namespace alloy { namespace backend { namespace ivm { - class IVMFunction : public runtime::Function { -public: + public: IVMFunction(runtime::FunctionInfo* symbol_info); virtual ~IVMFunction(); void Setup(TranslationContext& ctx); -protected: + protected: virtual int AddBreakpointImpl(runtime::Breakpoint* breakpoint); virtual int RemoveBreakpointImpl(runtime::Breakpoint* breakpoint); virtual int CallImpl(runtime::ThreadState* thread_state, uint64_t return_address); -private: + private: IntCode* GetIntCodeAtSourceOffset(uint64_t offset); void OnBreakpointHit(runtime::ThreadState* thread_state, IntCode* i); -private: - size_t register_count_; - size_t stack_size_; - size_t intcode_count_; - IntCode* intcodes_; - size_t source_map_count_; + private: + size_t register_count_; + size_t stack_size_; + size_t intcode_count_; + IntCode* intcodes_; + size_t source_map_count_; SourceMapEntry* source_map_; }; - } // namespace ivm } // namespace backend } // namespace alloy - #endif // ALLOY_BACKEND_IVM_IVM_FUNCTION_H_ diff --git a/src/alloy/backend/ivm/ivm_intcode.h b/src/alloy/backend/ivm/ivm_intcode.h index bd982eef1..025f533bc 100644 --- a/src/alloy/backend/ivm/ivm_intcode.h +++ b/src/alloy/backend/ivm/ivm_intcode.h @@ -10,16 +10,14 @@ #ifndef ALLOY_BACKEND_IVM_INTCODE_H_ #define ALLOY_BACKEND_IVM_INTCODE_H_ -#include - #include #include namespace alloy { namespace runtime { class ThreadState; -} -} +} // namespace runtime +} // namespace alloy namespace alloy { namespace backend { diff --git a/src/alloy/backend/ivm/ivm_stack.h b/src/alloy/backend/ivm/ivm_stack.h index 1d447ffc7..f02a169f4 100644 --- a/src/alloy/backend/ivm/ivm_stack.h +++ b/src/alloy/backend/ivm/ivm_stack.h @@ -10,8 +10,6 @@ #ifndef ALLOY_BACKEND_IVM_IVM_STACK_H_ #define ALLOY_BACKEND_IVM_IVM_STACK_H_ -#include - #include namespace alloy { diff --git a/src/alloy/backend/machine_info.h b/src/alloy/backend/machine_info.h index d041489e4..709156624 100644 --- a/src/alloy/backend/machine_info.h +++ b/src/alloy/backend/machine_info.h @@ -10,7 +10,7 @@ #ifndef ALLOY_BACKEND_MACHINE_INFO_H_ #define ALLOY_BACKEND_MACHINE_INFO_H_ -#include +#include namespace alloy { namespace backend { diff --git a/src/alloy/backend/x64/x64_assembler.cc b/src/alloy/backend/x64/x64_assembler.cc index 2b4075df2..17e36025a 100644 --- a/src/alloy/backend/x64/x64_assembler.cc +++ b/src/alloy/backend/x64/x64_assembler.cc @@ -16,6 +16,7 @@ #include #include #include +#include namespace BE { #include diff --git a/src/alloy/backend/x64/x64_assembler.h b/src/alloy/backend/x64/x64_assembler.h index a1b81e198..03714e680 100644 --- a/src/alloy/backend/x64/x64_assembler.h +++ b/src/alloy/backend/x64/x64_assembler.h @@ -12,10 +12,8 @@ #include -#include - -#include #include +#include namespace alloy { namespace backend { diff --git a/src/alloy/backend/x64/x64_backend.h b/src/alloy/backend/x64/x64_backend.h index e8322ee1a..d285417f1 100644 --- a/src/alloy/backend/x64/x64_backend.h +++ b/src/alloy/backend/x64/x64_backend.h @@ -10,8 +10,6 @@ #ifndef ALLOY_BACKEND_X64_X64_BACKEND_H_ #define ALLOY_BACKEND_X64_X64_BACKEND_H_ -#include - #include namespace alloy { diff --git a/src/alloy/backend/x64/x64_code_cache.h b/src/alloy/backend/x64/x64_code_cache.h index 8a0953f15..014fb8510 100644 --- a/src/alloy/backend/x64/x64_code_cache.h +++ b/src/alloy/backend/x64/x64_code_cache.h @@ -12,8 +12,6 @@ #include -#include - namespace alloy { namespace backend { namespace x64 { diff --git a/src/alloy/backend/x64/x64_code_cache_win.cc b/src/alloy/backend/x64/x64_code_cache_win.cc index 75ed4ee37..0b4a04c63 100644 --- a/src/alloy/backend/x64/x64_code_cache_win.cc +++ b/src/alloy/backend/x64/x64_code_cache_win.cc @@ -10,6 +10,7 @@ #include #include +#include namespace alloy { namespace backend { diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index f90d1b0bf..fc06a63ac 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -20,6 +20,7 @@ #include #include #include +#include namespace alloy { namespace backend { diff --git a/src/alloy/backend/x64/x64_emitter.h b/src/alloy/backend/x64/x64_emitter.h index d51f255ca..e63b72b7f 100644 --- a/src/alloy/backend/x64/x64_emitter.h +++ b/src/alloy/backend/x64/x64_emitter.h @@ -10,10 +10,7 @@ #ifndef ALLOY_BACKEND_X64_X64_EMITTER_H_ #define ALLOY_BACKEND_X64_X64_EMITTER_H_ -#include - #include - #include namespace alloy { diff --git a/src/alloy/backend/x64/x64_function.h b/src/alloy/backend/x64/x64_function.h index 6e5812362..24d4af098 100644 --- a/src/alloy/backend/x64/x64_function.h +++ b/src/alloy/backend/x64/x64_function.h @@ -10,7 +10,6 @@ #ifndef ALLOY_BACKEND_X64_X64_FUNCTION_H_ #define ALLOY_BACKEND_X64_X64_FUNCTION_H_ -#include #include #include diff --git a/src/alloy/backend/x64/x64_sequences.h b/src/alloy/backend/x64/x64_sequences.h index 3bfe6d94b..2e77112fa 100644 --- a/src/alloy/backend/x64/x64_sequences.h +++ b/src/alloy/backend/x64/x64_sequences.h @@ -10,8 +10,6 @@ #ifndef ALLOY_BACKEND_X64_X64_SEQUENCES_H_ #define ALLOY_BACKEND_X64_X64_SEQUENCES_H_ -#include - namespace alloy { namespace hir { class Instr; diff --git a/src/alloy/backend/x64/x64_thunk_emitter.h b/src/alloy/backend/x64/x64_thunk_emitter.h index 6e6b8d428..a07b6f0c8 100644 --- a/src/alloy/backend/x64/x64_thunk_emitter.h +++ b/src/alloy/backend/x64/x64_thunk_emitter.h @@ -10,7 +10,6 @@ #ifndef ALLOY_BACKEND_X64_X64_THUNK_EMITTER_H_ #define ALLOY_BACKEND_X64_X64_THUNK_EMITTER_H_ -#include #include #include diff --git a/src/alloy/backend/x64/x64_tracers.h b/src/alloy/backend/x64/x64_tracers.h index 9b50ce610..8015f8a69 100644 --- a/src/alloy/backend/x64/x64_tracers.h +++ b/src/alloy/backend/x64/x64_tracers.h @@ -10,9 +10,8 @@ #ifndef ALLOY_BACKEND_X64_X64_TRACERS_H_ #define ALLOY_BACKEND_X64_X64_TRACERS_H_ -#include - #include +#include namespace alloy { namespace backend { diff --git a/src/alloy/compiler/compiler.cc b/src/alloy/compiler/compiler.cc index b74ada3cf..50b295803 100644 --- a/src/alloy/compiler/compiler.cc +++ b/src/alloy/compiler/compiler.cc @@ -10,6 +10,7 @@ #include #include +#include namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/compiler.h b/src/alloy/compiler/compiler.h index ed592bdb8..1f1c911f9 100644 --- a/src/alloy/compiler/compiler.h +++ b/src/alloy/compiler/compiler.h @@ -13,7 +13,6 @@ #include #include -#include #include namespace alloy { diff --git a/src/alloy/compiler/compiler_pass.h b/src/alloy/compiler/compiler_pass.h index 281d578f5..f00aa42ab 100644 --- a/src/alloy/compiler/compiler_pass.h +++ b/src/alloy/compiler/compiler_pass.h @@ -10,8 +10,6 @@ #ifndef ALLOY_COMPILER_COMPILER_PASS_H_ #define ALLOY_COMPILER_COMPILER_PASS_H_ -#include - #include namespace alloy { diff --git a/src/alloy/compiler/passes/constant_propagation_pass.cc b/src/alloy/compiler/passes/constant_propagation_pass.cc index 64eeb5f1d..471bc2633 100644 --- a/src/alloy/compiler/passes/constant_propagation_pass.cc +++ b/src/alloy/compiler/passes/constant_propagation_pass.cc @@ -11,6 +11,7 @@ #include #include +#include namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/passes/context_promotion_pass.cc b/src/alloy/compiler/passes/context_promotion_pass.cc index f00d605b5..1b47246c0 100644 --- a/src/alloy/compiler/passes/context_promotion_pass.cc +++ b/src/alloy/compiler/passes/context_promotion_pass.cc @@ -13,6 +13,7 @@ #include #include +#include DEFINE_bool(store_all_context_values, false, "Don't strip dead context stores to aid in debugging."); diff --git a/src/alloy/compiler/passes/control_flow_analysis_pass.cc b/src/alloy/compiler/passes/control_flow_analysis_pass.cc index 85b2bcfe4..ce379cee6 100644 --- a/src/alloy/compiler/passes/control_flow_analysis_pass.cc +++ b/src/alloy/compiler/passes/control_flow_analysis_pass.cc @@ -12,6 +12,7 @@ #include #include #include +#include namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/passes/control_flow_simplification_pass.cc b/src/alloy/compiler/passes/control_flow_simplification_pass.cc index 1891f2d7b..1e404dbe1 100644 --- a/src/alloy/compiler/passes/control_flow_simplification_pass.cc +++ b/src/alloy/compiler/passes/control_flow_simplification_pass.cc @@ -12,6 +12,7 @@ #include #include #include +#include namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/passes/data_flow_analysis_pass.cc b/src/alloy/compiler/passes/data_flow_analysis_pass.cc index 28b0a6d5a..7f0737028 100644 --- a/src/alloy/compiler/passes/data_flow_analysis_pass.cc +++ b/src/alloy/compiler/passes/data_flow_analysis_pass.cc @@ -12,6 +12,7 @@ #include #include #include +#include #if XE_COMPILER_MSVC #pragma warning(push) diff --git a/src/alloy/compiler/passes/dead_code_elimination_pass.cc b/src/alloy/compiler/passes/dead_code_elimination_pass.cc index 40f83bb3d..6ff73609e 100644 --- a/src/alloy/compiler/passes/dead_code_elimination_pass.cc +++ b/src/alloy/compiler/passes/dead_code_elimination_pass.cc @@ -9,6 +9,8 @@ #include +#include + namespace alloy { namespace compiler { namespace passes { diff --git a/src/alloy/compiler/passes/finalization_pass.cc b/src/alloy/compiler/passes/finalization_pass.cc index fcd827d1f..12e4254d7 100644 --- a/src/alloy/compiler/passes/finalization_pass.cc +++ b/src/alloy/compiler/passes/finalization_pass.cc @@ -12,6 +12,7 @@ #include #include #include +#include namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/passes/register_allocation_pass.cc b/src/alloy/compiler/passes/register_allocation_pass.cc index 4db4cd1ef..f388f90c1 100644 --- a/src/alloy/compiler/passes/register_allocation_pass.cc +++ b/src/alloy/compiler/passes/register_allocation_pass.cc @@ -11,6 +11,8 @@ #include +#include + namespace alloy { namespace compiler { namespace passes { diff --git a/src/alloy/compiler/passes/simplification_pass.cc b/src/alloy/compiler/passes/simplification_pass.cc index 22ec69820..c1d73db6b 100644 --- a/src/alloy/compiler/passes/simplification_pass.cc +++ b/src/alloy/compiler/passes/simplification_pass.cc @@ -9,6 +9,8 @@ #include +#include + namespace alloy { namespace compiler { namespace passes { diff --git a/src/alloy/compiler/passes/validation_pass.cc b/src/alloy/compiler/passes/validation_pass.cc index bc6c8d536..9b6d209fb 100644 --- a/src/alloy/compiler/passes/validation_pass.cc +++ b/src/alloy/compiler/passes/validation_pass.cc @@ -12,6 +12,7 @@ #include #include #include +#include namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/passes/value_reduction_pass.cc b/src/alloy/compiler/passes/value_reduction_pass.cc index 1d51de912..d46037fe0 100644 --- a/src/alloy/compiler/passes/value_reduction_pass.cc +++ b/src/alloy/compiler/passes/value_reduction_pass.cc @@ -12,6 +12,7 @@ #include #include #include +#include #if XE_COMPILER_MSVC #pragma warning(push) diff --git a/src/alloy/core.h b/src/alloy/core.h deleted file mode 100644 index eedae6ac1..000000000 --- a/src/alloy/core.h +++ /dev/null @@ -1,16 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_CORE_H_ -#define ALLOY_CORE_H_ - -// TODO(benvanik): move the common stuff into here? -#include - -#endif // ALLOY_CORE_H_ diff --git a/src/alloy/delegate.h b/src/alloy/delegate.h index 1c6ca5f42..137773ab6 100644 --- a/src/alloy/delegate.h +++ b/src/alloy/delegate.h @@ -14,8 +14,6 @@ #include #include -#include - namespace alloy { // TODO(benvanik): go lockfree, and don't hold the lock while emitting. diff --git a/src/alloy/frontend/context_info.h b/src/alloy/frontend/context_info.h index f9bf530d4..506b3572c 100644 --- a/src/alloy/frontend/context_info.h +++ b/src/alloy/frontend/context_info.h @@ -10,7 +10,7 @@ #ifndef ALLOY_FRONTEND_CONTEXT_INFO_H_ #define ALLOY_FRONTEND_CONTEXT_INFO_H_ -#include +#include namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/frontend.h b/src/alloy/frontend/frontend.h index 7555324b3..83d0f9839 100644 --- a/src/alloy/frontend/frontend.h +++ b/src/alloy/frontend/frontend.h @@ -12,9 +12,8 @@ #include -#include -#include #include +#include #include #include diff --git a/src/alloy/frontend/ppc/ppc_context.h b/src/alloy/frontend/ppc/ppc_context.h index c0409e067..44d0ec080 100644 --- a/src/alloy/frontend/ppc/ppc_context.h +++ b/src/alloy/frontend/ppc/ppc_context.h @@ -10,7 +10,6 @@ #ifndef ALLOY_FRONTEND_PPC_PPC_CONTEXT_H_ #define ALLOY_FRONTEND_PPC_PPC_CONTEXT_H_ -#include #include #include diff --git a/src/alloy/frontend/ppc/ppc_frontend.h b/src/alloy/frontend/ppc/ppc_frontend.h index 50608f934..9b524fc00 100644 --- a/src/alloy/frontend/ppc/ppc_frontend.h +++ b/src/alloy/frontend/ppc/ppc_frontend.h @@ -10,10 +10,8 @@ #ifndef ALLOY_FRONTEND_PPC_PPC_FRONTEND_H_ #define ALLOY_FRONTEND_PPC_PPC_FRONTEND_H_ -#include -#include - #include +#include namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index d0b6581e6..12431412e 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -16,6 +16,7 @@ #include #include #include +#include namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.h b/src/alloy/frontend/ppc/ppc_hir_builder.h index afbece4e3..ffe1a1a7b 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.h +++ b/src/alloy/frontend/ppc/ppc_hir_builder.h @@ -10,11 +10,10 @@ #ifndef ALLOY_FRONTEND_PPC_PPC_HIR_BUILDER_H_ #define ALLOY_FRONTEND_PPC_PPC_HIR_BUILDER_H_ -#include -#include #include #include #include +#include namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_instr.h b/src/alloy/frontend/ppc/ppc_instr.h index c080f82b1..f6052078b 100644 --- a/src/alloy/frontend/ppc/ppc_instr.h +++ b/src/alloy/frontend/ppc/ppc_instr.h @@ -10,11 +10,10 @@ #ifndef ALLOY_FRONTEND_PPC_PPC_INSTR_H_ #define ALLOY_FRONTEND_PPC_PPC_INSTR_H_ +#include #include #include -#include - namespace alloy { class StringBuffer; } // namespace alloy diff --git a/src/alloy/frontend/ppc/ppc_scanner.cc b/src/alloy/frontend/ppc/ppc_scanner.cc index ba255ab07..2ff120ea7 100644 --- a/src/alloy/frontend/ppc/ppc_scanner.cc +++ b/src/alloy/frontend/ppc/ppc_scanner.cc @@ -17,6 +17,7 @@ #include #include #include +#include #if 0 #define LOGPPC(fmt, ...) PLOGCORE('p', fmt, ##__VA_ARGS__) diff --git a/src/alloy/frontend/ppc/ppc_scanner.h b/src/alloy/frontend/ppc/ppc_scanner.h index 769b879d6..1eddcfd35 100644 --- a/src/alloy/frontend/ppc/ppc_scanner.h +++ b/src/alloy/frontend/ppc/ppc_scanner.h @@ -12,7 +12,6 @@ #include -#include #include namespace alloy { diff --git a/src/alloy/frontend/ppc/ppc_translator.cc b/src/alloy/frontend/ppc/ppc_translator.cc index a6059459d..b89497885 100644 --- a/src/alloy/frontend/ppc/ppc_translator.cc +++ b/src/alloy/frontend/ppc/ppc_translator.cc @@ -18,6 +18,7 @@ #include #include #include +#include namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_translator.h b/src/alloy/frontend/ppc/ppc_translator.h index 4c95e94b4..a24ddbb46 100644 --- a/src/alloy/frontend/ppc/ppc_translator.h +++ b/src/alloy/frontend/ppc/ppc_translator.h @@ -12,11 +12,10 @@ #include -#include -#include #include #include #include +#include namespace alloy { namespace frontend { diff --git a/src/alloy/hir/block.h b/src/alloy/hir/block.h index b62f70b58..70f11cac2 100644 --- a/src/alloy/hir/block.h +++ b/src/alloy/hir/block.h @@ -11,7 +11,6 @@ #define ALLOY_HIR_BLOCK_H_ #include -#include namespace llvm { class BitVector; diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index 72871413f..ccc089eb8 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -9,11 +9,12 @@ #include -#include #include #include #include #include +#include +#include namespace alloy { namespace hir { diff --git a/src/alloy/hir/hir_builder.h b/src/alloy/hir/hir_builder.h index ae0b23e55..ccbd3b339 100644 --- a/src/alloy/hir/hir_builder.h +++ b/src/alloy/hir/hir_builder.h @@ -12,7 +12,6 @@ #include -#include #include #include #include diff --git a/src/alloy/hir/instr.h b/src/alloy/hir/instr.h index c72c7d9e2..259ef843b 100644 --- a/src/alloy/hir/instr.h +++ b/src/alloy/hir/instr.h @@ -10,7 +10,6 @@ #ifndef ALLOY_HIR_INSTR_H_ #define ALLOY_HIR_INSTR_H_ -#include #include #include diff --git a/src/alloy/hir/label.h b/src/alloy/hir/label.h index 74beaa92d..bea95e7fc 100644 --- a/src/alloy/hir/label.h +++ b/src/alloy/hir/label.h @@ -10,8 +10,6 @@ #ifndef ALLOY_HIR_LABEL_H_ #define ALLOY_HIR_LABEL_H_ -#include - namespace alloy { namespace hir { diff --git a/src/alloy/hir/opcodes.h b/src/alloy/hir/opcodes.h index cfca101a0..cf84944cc 100644 --- a/src/alloy/hir/opcodes.h +++ b/src/alloy/hir/opcodes.h @@ -10,7 +10,7 @@ #ifndef ALLOY_HIR_OPCODES_H_ #define ALLOY_HIR_OPCODES_H_ -#include +#include namespace alloy { namespace hir { diff --git a/src/alloy/hir/value.h b/src/alloy/hir/value.h index 1a3097480..0b1fc38ad 100644 --- a/src/alloy/hir/value.h +++ b/src/alloy/hir/value.h @@ -10,11 +10,10 @@ #ifndef ALLOY_HIR_VALUE_H_ #define ALLOY_HIR_VALUE_H_ -#include #include -#include #include #include +#include #include namespace alloy { diff --git a/src/alloy/memory.h b/src/alloy/memory.h index 869fc4eb7..e0e42d116 100644 --- a/src/alloy/memory.h +++ b/src/alloy/memory.h @@ -10,7 +10,8 @@ #ifndef ALLOY_MEMORY_H_ #define ALLOY_MEMORY_H_ -#include +#include +#include namespace alloy { diff --git a/src/alloy/reset_scope.h b/src/alloy/reset_scope.h index d10c2561d..1007b1e25 100644 --- a/src/alloy/reset_scope.h +++ b/src/alloy/reset_scope.h @@ -12,8 +12,6 @@ #include -#include - namespace alloy { template diff --git a/src/alloy/runtime/debug_info.cc b/src/alloy/runtime/debug_info.cc index 0eac0b795..5abe39257 100644 --- a/src/alloy/runtime/debug_info.cc +++ b/src/alloy/runtime/debug_info.cc @@ -9,6 +9,8 @@ #include +#include + namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/debug_info.h b/src/alloy/runtime/debug_info.h index fa4ee4f3a..6df923a69 100644 --- a/src/alloy/runtime/debug_info.h +++ b/src/alloy/runtime/debug_info.h @@ -10,7 +10,7 @@ #ifndef ALLOY_RUNTIME_DEBUG_INFO_H_ #define ALLOY_RUNTIME_DEBUG_INFO_H_ -#include +#include namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/debugger.h b/src/alloy/runtime/debugger.h index 789e894a8..1ab802f40 100644 --- a/src/alloy/runtime/debugger.h +++ b/src/alloy/runtime/debugger.h @@ -15,7 +15,6 @@ #include #include -#include #include namespace alloy { diff --git a/src/alloy/runtime/entry_table.cc b/src/alloy/runtime/entry_table.cc index 17c737bb9..b309bbc15 100644 --- a/src/alloy/runtime/entry_table.cc +++ b/src/alloy/runtime/entry_table.cc @@ -10,6 +10,7 @@ #include #include +#include namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/entry_table.h b/src/alloy/runtime/entry_table.h index 1fe466a8a..fb70c4847 100644 --- a/src/alloy/runtime/entry_table.h +++ b/src/alloy/runtime/entry_table.h @@ -14,8 +14,6 @@ #include #include -#include - namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/function.h b/src/alloy/runtime/function.h index 68366ba8f..c244813a9 100644 --- a/src/alloy/runtime/function.h +++ b/src/alloy/runtime/function.h @@ -14,7 +14,6 @@ #include #include -#include #include namespace alloy { diff --git a/src/alloy/runtime/instrument.h b/src/alloy/runtime/instrument.h index 631c72c55..6ef8ce3a6 100644 --- a/src/alloy/runtime/instrument.h +++ b/src/alloy/runtime/instrument.h @@ -10,7 +10,7 @@ #ifndef ALLOY_RUNTIME_INSTRUMENT_H_ #define ALLOY_RUNTIME_INSTRUMENT_H_ -#include +#include namespace alloy { class Memory; diff --git a/src/alloy/runtime/module.cc b/src/alloy/runtime/module.cc index 8184e2d53..7278b9c1b 100644 --- a/src/alloy/runtime/module.cc +++ b/src/alloy/runtime/module.cc @@ -14,6 +14,7 @@ #include #include +#include namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/module.h b/src/alloy/runtime/module.h index 0c46c0418..88a1c4b94 100644 --- a/src/alloy/runtime/module.h +++ b/src/alloy/runtime/module.h @@ -11,11 +11,11 @@ #define ALLOY_RUNTIME_MODULE_H_ #include +#include #include #include #include -#include #include #include diff --git a/src/alloy/runtime/raw_module.cc b/src/alloy/runtime/raw_module.cc index 765d6a371..86eda6c2e 100644 --- a/src/alloy/runtime/raw_module.cc +++ b/src/alloy/runtime/raw_module.cc @@ -9,6 +9,8 @@ #include +#include + namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/runtime.cc b/src/alloy/runtime/runtime.cc index 9189cc299..8cf99d4a1 100644 --- a/src/alloy/runtime/runtime.cc +++ b/src/alloy/runtime/runtime.cc @@ -14,6 +14,7 @@ #include #include #include +#include // TODO(benvanik): based on compiler support #include diff --git a/src/alloy/runtime/runtime.h b/src/alloy/runtime/runtime.h index a9fe9c374..279edaf7c 100644 --- a/src/alloy/runtime/runtime.h +++ b/src/alloy/runtime/runtime.h @@ -14,10 +14,9 @@ #include #include -#include -#include #include #include +#include #include #include #include diff --git a/src/alloy/runtime/symbol_info.h b/src/alloy/runtime/symbol_info.h index 50f97e322..0f71323c1 100644 --- a/src/alloy/runtime/symbol_info.h +++ b/src/alloy/runtime/symbol_info.h @@ -10,10 +10,9 @@ #ifndef ALLOY_RUNTIME_SYMBOL_INFO_H_ #define ALLOY_RUNTIME_SYMBOL_INFO_H_ +#include #include -#include - namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/thread_state.h b/src/alloy/runtime/thread_state.h index 9cb2f7e96..012f0bf6f 100644 --- a/src/alloy/runtime/thread_state.h +++ b/src/alloy/runtime/thread_state.h @@ -12,8 +12,6 @@ #include -#include - #include namespace alloy { diff --git a/src/alloy/sources.gypi b/src/alloy/sources.gypi index 0854a8bc1..44a87a7d2 100644 --- a/src/alloy/sources.gypi +++ b/src/alloy/sources.gypi @@ -6,7 +6,6 @@ 'alloy.h', 'arena.cc', 'arena.h', - 'core.h', 'delegate.h', 'memory.cc', 'memory.h', diff --git a/src/alloy/string_buffer.cc b/src/alloy/string_buffer.cc index b53601aa3..bb9270def 100644 --- a/src/alloy/string_buffer.cc +++ b/src/alloy/string_buffer.cc @@ -10,6 +10,7 @@ #include #include +#include namespace alloy { diff --git a/src/alloy/string_buffer.h b/src/alloy/string_buffer.h index d6c2fcd0d..e2b294d64 100644 --- a/src/alloy/string_buffer.h +++ b/src/alloy/string_buffer.h @@ -10,11 +10,10 @@ #ifndef ALLOY_STRING_BUFFER_H_ #define ALLOY_STRING_BUFFER_H_ +#include #include #include -#include - namespace alloy { class StringBuffer { diff --git a/src/alloy/type_pool.h b/src/alloy/type_pool.h index 6483c9514..3ba2bd754 100644 --- a/src/alloy/type_pool.h +++ b/src/alloy/type_pool.h @@ -13,8 +13,6 @@ #include #include -#include - namespace alloy { template diff --git a/src/alloy/vec128.h b/src/alloy/vec128.h index 35caef5d1..c5b7bc81f 100644 --- a/src/alloy/vec128.h +++ b/src/alloy/vec128.h @@ -10,7 +10,6 @@ #ifndef ALLOY_VEC128_H_ #define ALLOY_VEC128_H_ -#include #include namespace alloy { diff --git a/xenia.gyp b/xenia.gyp index ebbd30f68..0fddef162 100644 --- a/xenia.gyp +++ b/xenia.gyp @@ -45,6 +45,7 @@ '__STDC_LIMIT_MACROS=1', '__STDC_CONSTANT_MACROS=1', '_ISOC99_SOURCE=1', + '_CRT_NONSTDC_NO_DEPRECATE=1', ], 'conditions': [ From c9d71486b02e759748104e727a4f457b09d4abaf Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 21 Aug 2014 21:23:35 -0700 Subject: [PATCH 152/388] alloy-sandbox can now (almost) build without libxenia. --- tools/alloy-sandbox/alloy-sandbox.cc | 2 +- xenia.gyp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/alloy-sandbox/alloy-sandbox.cc b/tools/alloy-sandbox/alloy-sandbox.cc index b8f7b4e3f..66afdfdcb 100644 --- a/tools/alloy-sandbox/alloy-sandbox.cc +++ b/tools/alloy-sandbox/alloy-sandbox.cc @@ -94,7 +94,7 @@ int main(std::vector& args) { runtime->Initialize(std::move(frontend), std::move(backend)); auto module = std::make_unique(runtime.get()); - module->LoadFile(0x82000000, "test\\codegen\\instr_add.bin"); + module->LoadFile(0x00001000, "test\\codegen\\instr_add.bin"); runtime->AddModule(std::move(module)); { diff --git a/xenia.gyp b/xenia.gyp index 0fddef162..a5f8bb215 100644 --- a/xenia.gyp +++ b/xenia.gyp @@ -242,6 +242,7 @@ 'ole32', 'ntdll', 'advapi32', + 'Shell32', ], }], ['OS == "mac"', { From 9b76d02f264d20e758483da26fefd0037766c669 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 21 Aug 2014 21:36:34 -0700 Subject: [PATCH 153/388] Fixing alloy-sandbox. --- src/alloy/backend/x64/x64_assembler.cc | 6 +++++- tools/alloy-sandbox/alloy-sandbox.cc | 18 +++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/alloy/backend/x64/x64_assembler.cc b/src/alloy/backend/x64/x64_assembler.cc index 17e36025a..a963b39e5 100644 --- a/src/alloy/backend/x64/x64_assembler.cc +++ b/src/alloy/backend/x64/x64_assembler.cc @@ -37,7 +37,11 @@ using alloy::runtime::FunctionInfo; X64Assembler::X64Assembler(X64Backend* backend) : Assembler(backend), x64_backend_(backend) {} -X64Assembler::~X64Assembler() = default; +X64Assembler::~X64Assembler() { + // Emitter must be freed before the allocator. + emitter_.reset(); + allocator_.reset(); +} int X64Assembler::Initialize() { int result = Assembler::Initialize(); diff --git a/tools/alloy-sandbox/alloy-sandbox.cc b/tools/alloy-sandbox/alloy-sandbox.cc index 66afdfdcb..e09030db1 100644 --- a/tools/alloy-sandbox/alloy-sandbox.cc +++ b/tools/alloy-sandbox/alloy-sandbox.cc @@ -26,10 +26,10 @@ using alloy::runtime::Runtime; class ThreadState : public alloy::runtime::ThreadState { public: - ThreadState(Runtime* runtime, uint32_t thread_id, size_t stack_size, - uint64_t thread_state_address, uint64_t thread_stack_address) + ThreadState(Runtime* runtime, uint32_t thread_id, uint64_t stack_address, + size_t stack_size, uint64_t thread_state_address) : alloy::runtime::ThreadState(runtime, thread_id), - stack_address_(thread_stack_address), + stack_address_(stack_address), stack_size_(stack_size), thread_state_address_(thread_state_address) { memset(memory_->Translate(stack_address_), 0, stack_size_); @@ -87,10 +87,10 @@ int main(std::vector& args) { auto frontend = std::make_unique(runtime.get()); std::unique_ptr backend; - // auto backend = - // std::make_unique(runtime.get()); - // auto backend = - // std::make_unique(runtime.get()); + // backend = + // std::make_unique(runtime.get()); + // backend = + // std::make_unique(runtime.get()); runtime->Initialize(std::move(frontend), std::move(backend)); auto module = std::make_unique(runtime.get()); @@ -98,9 +98,9 @@ int main(std::vector& args) { runtime->AddModule(std::move(module)); { - uint64_t thread_state_address = 0; - uint64_t stack_address = memory_size - 1024; uint64_t stack_size = 64 * 1024; + uint64_t stack_address = memory_size - stack_size; + uint64_t thread_state_address = stack_address - 0x1000; auto thread_state = std::make_unique( runtime.get(), 100, stack_address, stack_size, thread_state_address); From 52678ed1ef1ac42b90935c498ddab1b25ab3e466 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 21 Aug 2014 21:53:06 -0700 Subject: [PATCH 154/388] Removing dead ExportResolver code. --- src/xenia/export_resolver.cc | 30 ------------------------------ src/xenia/export_resolver.h | 6 ------ 2 files changed, 36 deletions(-) diff --git a/src/xenia/export_resolver.cc b/src/xenia/export_resolver.cc index 3cfa87710..9de2a9515 100644 --- a/src/xenia/export_resolver.cc +++ b/src/xenia/export_resolver.cc @@ -29,29 +29,6 @@ void ExportResolver::RegisterTable(const std::string& library_name, } } -uint16_t ExportResolver::GetLibraryOrdinal(const std::string& library_name) { - uint16_t n = 0; - for (const auto& table : tables_) { - if (table.name != library_name) { - return n; - } - ++n; - } - return -1; -} - -KernelExport* ExportResolver::GetExportByOrdinal(const uint16_t library_ordinal, - const uint32_t ordinal) { - const auto& table = tables_[library_ordinal]; - // TODO(benvanik): binary search? - for (size_t n = 0; n < table.count; n++) { - if (table.exports[n].ordinal == ordinal) { - return &table.exports[n]; - } - } - return nullptr; -} - KernelExport* ExportResolver::GetExportByOrdinal( const std::string& library_name, const uint32_t ordinal) { for (const auto& table : tables_) { @@ -68,13 +45,6 @@ KernelExport* ExportResolver::GetExportByOrdinal( return nullptr; } -KernelExport* ExportResolver::GetExportByName(const std::string& library_name, - const std::string& name) { - // TODO(benvanik): lookup by name. - assert_always(); - return nullptr; -} - void ExportResolver::SetVariableMapping(const std::string& library_name, const uint32_t ordinal, uint32_t value) { diff --git a/src/xenia/export_resolver.h b/src/xenia/export_resolver.h index 057c80f37..cf93f7ae4 100644 --- a/src/xenia/export_resolver.h +++ b/src/xenia/export_resolver.h @@ -61,14 +61,8 @@ class ExportResolver { void RegisterTable(const std::string& library_name, KernelExport* exports, const size_t count); - uint16_t GetLibraryOrdinal(const std::string& library_name); - - KernelExport* GetExportByOrdinal(const uint16_t library_ordinal, - const uint32_t ordinal); KernelExport* GetExportByOrdinal(const std::string& library_name, const uint32_t ordinal); - KernelExport* GetExportByName(const std::string& library_name, - const std::string& name); void SetVariableMapping(const std::string& library_name, const uint32_t ordinal, uint32_t value); From f65d860640b832e0a28121c68e0228090476b439 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 21 Aug 2014 22:27:33 -0700 Subject: [PATCH 155/388] Cleaning up some clang issues. --- src/alloy/arena.h | 1 + src/alloy/backend/x64/x64_code_cache_posix.cc | 1 + src/alloy/frontend/context_info.h | 1 + src/alloy/runtime/debug_info.cc | 2 +- src/alloy/runtime/debug_info.h | 1 + src/poly/logging.cc | 4 ++-- 6 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/alloy/arena.h b/src/alloy/arena.h index d7b956001..764dd31bf 100644 --- a/src/alloy/arena.h +++ b/src/alloy/arena.h @@ -10,6 +10,7 @@ #ifndef ALLOY_ARENA_H_ #define ALLOY_ARENA_H_ +#include #include namespace alloy { diff --git a/src/alloy/backend/x64/x64_code_cache_posix.cc b/src/alloy/backend/x64/x64_code_cache_posix.cc index 0fa023ab5..c32990cd6 100644 --- a/src/alloy/backend/x64/x64_code_cache_posix.cc +++ b/src/alloy/backend/x64/x64_code_cache_posix.cc @@ -13,6 +13,7 @@ #include #include +#include namespace alloy { namespace backend { diff --git a/src/alloy/frontend/context_info.h b/src/alloy/frontend/context_info.h index 506b3572c..68cf52e18 100644 --- a/src/alloy/frontend/context_info.h +++ b/src/alloy/frontend/context_info.h @@ -10,6 +10,7 @@ #ifndef ALLOY_FRONTEND_CONTEXT_INFO_H_ #define ALLOY_FRONTEND_CONTEXT_INFO_H_ +#include #include namespace alloy { diff --git a/src/alloy/runtime/debug_info.cc b/src/alloy/runtime/debug_info.cc index 5abe39257..6a34e4238 100644 --- a/src/alloy/runtime/debug_info.cc +++ b/src/alloy/runtime/debug_info.cc @@ -9,7 +9,7 @@ #include -#include +#include namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/debug_info.h b/src/alloy/runtime/debug_info.h index 6df923a69..4540deecf 100644 --- a/src/alloy/runtime/debug_info.h +++ b/src/alloy/runtime/debug_info.h @@ -10,6 +10,7 @@ #ifndef ALLOY_RUNTIME_DEBUG_INFO_H_ #define ALLOY_RUNTIME_DEBUG_INFO_H_ +#include #include namespace alloy { diff --git a/src/poly/logging.cc b/src/poly/logging.cc index dcd3aa32a..d7095d43c 100644 --- a/src/poly/logging.cc +++ b/src/poly/logging.cc @@ -79,7 +79,7 @@ void log_line(const char* file_path, const uint32_t line_number, #if 0 // defined(OutputDebugString) OutputDebugStringA(buffer); #else - fprintf(stdout, buffer); + fprintf(stdout, "%s", buffer); fflush(stdout); #endif // OutputDebugString if (!FLAGS_fast_stdout) { @@ -102,7 +102,7 @@ void handle_fatal(const char* file_path, const uint32_t line_number, #if defined(OutputDebugString) OutputDebugStringA(buffer); #else - fprintf(stderr, buffer); + fprintf(stderr, "%s", buffer); fflush(stderr); #endif // OutputDebugString if (!FLAGS_fast_stdout) { From 93285acf7b2cd25df284f2242d6f79447835cb0e Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 21 Aug 2014 22:30:02 -0700 Subject: [PATCH 156/388] Fixing link errors on clang (probably breaks mdvc...) --- src/alloy/backend/x64/x64_sequence.inl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/alloy/backend/x64/x64_sequence.inl b/src/alloy/backend/x64/x64_sequence.inl index d0f9e539d..c9451fdfe 100644 --- a/src/alloy/backend/x64/x64_sequence.inl +++ b/src/alloy/backend/x64/x64_sequence.inl @@ -528,7 +528,7 @@ template struct SingleSequence : public Sequence, T> { typedef Sequence, T> BASE; typedef T EmitArgType; - static const uint32_t head_key = T::key; + static constexpr uint32_t head_key() { return T::key; } static void Emit(X64Emitter& e, const typename BASE::EmitArgs& _) { SEQ::Emit(e, _.i1); } @@ -734,7 +734,7 @@ static const tag_t TAG7 = 7; template void Register() { - sequence_table.insert({ T::head_key, T::Select }); + sequence_table.insert({ T::head_key(), T::Select }); } template void Register() { From 7ae303dfa29d3d63b1ce7f7cf3a8beebfd5478a8 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 21 Aug 2014 22:46:12 -0700 Subject: [PATCH 157/388] alloy-sandbox running on osx (ivm only). --- docs/building.md | 11 +++++++++++ src/alloy/runtime/raw_module.cc | 12 +++++++----- src/alloy/runtime/raw_module.h | 2 +- tools/alloy-sandbox/alloy-sandbox.cc | 2 +- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/docs/building.md b/docs/building.md index 6e797a74e..eaeec0100 100644 --- a/docs/building.md +++ b/docs/building.md @@ -22,6 +22,17 @@ and set the 'Command' to `$(SolutionDir)$(TargetPath)` and the 'Working Directory' to `$(SolutionDir)..\..`. You can specify flags and the file to run in the 'Command Arguments' field (or use `--flagfile=flags.txt`). +### OSX + +* Mac OSX 10.9+ +* Xcode 5.1+ + +#### Debugging + +Choose `Product > Scheme > Edit Scheme`. For xenia-run, alloy-sandbox, and the +other executables select the Run action on the left and set +`Options > Working Directory` to your root xenia/ git path. + ## xenia-build A simple build script is included to manage basic tasks such as building diff --git a/src/alloy/runtime/raw_module.cc b/src/alloy/runtime/raw_module.cc index 86eda6c2e..2750a724e 100644 --- a/src/alloy/runtime/raw_module.cc +++ b/src/alloy/runtime/raw_module.cc @@ -10,6 +10,7 @@ #include #include +#include namespace alloy { namespace runtime { @@ -19,8 +20,9 @@ RawModule::RawModule(Runtime* runtime) RawModule::~RawModule() {} -int RawModule::LoadFile(uint64_t base_address, const std::string& path) { - FILE* file = fopen(path.c_str(), "rb"); +int RawModule::LoadFile(uint64_t base_address, const std::wstring& path) { + auto fixed_path = poly::to_string(poly::fix_path_separators(path)); + FILE* file = fopen(fixed_path.c_str(), "rb"); fseek(file, 0, SEEK_END); size_t file_length = ftell(file); fseek(file, 0, SEEK_SET); @@ -37,11 +39,11 @@ int RawModule::LoadFile(uint64_t base_address, const std::string& path) { fclose(file); // Setup debug info. - auto last_slash = path.find_last_of(poly::path_separator); + auto last_slash = fixed_path.find_last_of(poly::path_separator); if (last_slash != std::string::npos) { - name_ = path.substr(last_slash + 1); + name_ = fixed_path.substr(last_slash + 1); } else { - name_ = path; + name_ = fixed_path; } // TODO(benvanik): debug info diff --git a/src/alloy/runtime/raw_module.h b/src/alloy/runtime/raw_module.h index 37723119b..c40359f1e 100644 --- a/src/alloy/runtime/raw_module.h +++ b/src/alloy/runtime/raw_module.h @@ -22,7 +22,7 @@ class RawModule : public Module { RawModule(Runtime* runtime); ~RawModule() override; - int LoadFile(uint64_t base_address, const std::string& path); + int LoadFile(uint64_t base_address, const std::wstring& path); const std::string& name() const override { return name_; } diff --git a/tools/alloy-sandbox/alloy-sandbox.cc b/tools/alloy-sandbox/alloy-sandbox.cc index e09030db1..69ffa4d0a 100644 --- a/tools/alloy-sandbox/alloy-sandbox.cc +++ b/tools/alloy-sandbox/alloy-sandbox.cc @@ -94,7 +94,7 @@ int main(std::vector& args) { runtime->Initialize(std::move(frontend), std::move(backend)); auto module = std::make_unique(runtime.get()); - module->LoadFile(0x00001000, "test\\codegen\\instr_add.bin"); + module->LoadFile(0x00001000, L"test\\codegen\\instr_add.bin"); runtime->AddModule(std::move(module)); { From 6f802c243242f1bc66585ae02cd25e48cc4da142 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 21 Aug 2014 23:10:08 -0700 Subject: [PATCH 158/388] Fixing many clang warnings. --- src/xenia/core/hash.cc | 138 +------ src/xenia/core/socket_posix.cc | 16 +- src/xenia/cpu/processor.cc | 62 ++-- src/xenia/cpu/processor.h | 1 - src/xenia/gpu/xenos/ucode.h | 342 +++++++++--------- .../kernel/fs/devices/disc_image_entry.cc | 18 +- .../kernel/fs/devices/disc_image_entry.h | 18 +- src/xenia/kernel/fs/devices/host_path_entry.h | 18 +- .../kernel/fs/devices/stfs_container_entry.cc | 8 +- .../kernel/fs/devices/stfs_container_entry.h | 12 +- .../kernel/fs/devices/stfs_container_file.cc | 2 +- src/xenia/kernel/objects/xthread.cc | 4 +- src/xenia/kernel/objects/xuser_module.cc | 4 +- src/xenia/ui/ui_event.h | 44 +-- 14 files changed, 260 insertions(+), 427 deletions(-) diff --git a/src/xenia/core/hash.cc b/src/xenia/core/hash.cc index d2b9afb06..ee6560e84 100644 --- a/src/xenia/core/hash.cc +++ b/src/xenia/core/hash.cc @@ -89,142 +89,6 @@ static const uint64_t k0 = 0xc3a5c85c97cb3127ULL; static const uint64_t k1 = 0xb492b66fbe98f273ULL; static const uint64_t k2 = 0x9ae16a3b2f90404fULL; -// Magic numbers for 32-bit hashing. Copied from Murmur3. -static const uint32_t c1 = 0xcc9e2d51; -static const uint32_t c2 = 0x1b873593; - -// A 32-bit to 32-bit integer hash copied from Murmur3. -static uint32_t fmix(uint32_t h) { - h ^= h >> 16; - h *= 0x85ebca6b; - h ^= h >> 13; - h *= 0xc2b2ae35; - h ^= h >> 16; - return h; -} - -static uint32_t Rotate32(uint32_t val, int shift) { - // Avoid shifting by 32: doing so yields an undefined result. - return shift == 0 ? val : ((val >> shift) | (val << (32 - shift))); -} - -#undef PERMUTE3 -#define PERMUTE3(a, b, c) \ - do { \ - std::swap(a, b); \ - std::swap(a, c); \ - } while (0) - -static uint32_t Mur(uint32_t a, uint32_t h) { - // Helper from Murmur3 for combining two 32-bit values. - a *= c1; - a = Rotate32(a, 17); - a *= c2; - h ^= a; - h = Rotate32(h, 19); - return h * 5 + 0xe6546b64; -} - -static uint32_t Hash32Len13to24(const char *s, size_t len) { - uint32_t a = Fetch32(s - 4 + (len >> 1)); - uint32_t b = Fetch32(s + 4); - uint32_t c = Fetch32(s + len - 8); - uint32_t d = Fetch32(s + (len >> 1)); - uint32_t e = Fetch32(s); - uint32_t f = Fetch32(s + len - 4); - uint32_t h = (uint32_t)len; - - return fmix(Mur(f, Mur(e, Mur(d, Mur(c, Mur(b, Mur(a, h))))))); -} - -static uint32_t Hash32Len0to4(const char *s, size_t len) { - uint32_t b = 0; - uint32_t c = 9; - for (size_t i = 0; i < len; i++) { - signed char v = s[i]; - b = b * c1 + v; - c ^= b; - } - return fmix(Mur(b, Mur((uint32_t)len, c))); -} - -static uint32_t Hash32Len5to12(const char *s, size_t len) { - uint32_t a = (uint32_t)len, b = (uint32_t)len * 5, c = 9, d = b; - a += Fetch32(s); - b += Fetch32(s + len - 4); - c += Fetch32(s + ((len >> 1) & 4)); - return fmix(Mur(c, Mur(b, Mur(a, d)))); -} - -uint32_t CityHash32(const char *s, size_t len) { - if (len <= 24) { - return len <= 12 - ? (len <= 4 ? Hash32Len0to4(s, len) : Hash32Len5to12(s, len)) - : Hash32Len13to24(s, len); - } - - // len > 24 - uint32_t h = (uint32_t)len, g = c1 * (uint32_t)len, f = g; - uint32_t a0 = Rotate32(Fetch32(s + len - 4) * c1, 17) * c2; - uint32_t a1 = Rotate32(Fetch32(s + len - 8) * c1, 17) * c2; - uint32_t a2 = Rotate32(Fetch32(s + len - 16) * c1, 17) * c2; - uint32_t a3 = Rotate32(Fetch32(s + len - 12) * c1, 17) * c2; - uint32_t a4 = Rotate32(Fetch32(s + len - 20) * c1, 17) * c2; - h ^= a0; - h = Rotate32(h, 19); - h = h * 5 + 0xe6546b64; - h ^= a2; - h = Rotate32(h, 19); - h = h * 5 + 0xe6546b64; - g ^= a1; - g = Rotate32(g, 19); - g = g * 5 + 0xe6546b64; - g ^= a3; - g = Rotate32(g, 19); - g = g * 5 + 0xe6546b64; - f += a4; - f = Rotate32(f, 19); - f = f * 5 + 0xe6546b64; - size_t iters = (len - 1) / 20; - do { - uint32_t a0 = Rotate32(Fetch32(s) * c1, 17) * c2; - uint32_t a1 = Fetch32(s + 4); - uint32_t a2 = Rotate32(Fetch32(s + 8) * c1, 17) * c2; - uint32_t a3 = Rotate32(Fetch32(s + 12) * c1, 17) * c2; - uint32_t a4 = Fetch32(s + 16); - h ^= a0; - h = Rotate32(h, 18); - h = h * 5 + 0xe6546b64; - f += a1; - f = Rotate32(f, 19); - f = f * c1; - g += a2; - g = Rotate32(g, 18); - g = g * 5 + 0xe6546b64; - h ^= a3 + a1; - h = Rotate32(h, 19); - h = h * 5 + 0xe6546b64; - g ^= a4; - g = poly::byte_swap(g) * 5; - h += a4 * 5; - h = poly::byte_swap(h); - f += a0; - PERMUTE3(f, h, g); - s += 20; - } while (--iters != 0); - g = Rotate32(g, 11) * c1; - g = Rotate32(g, 17) * c1; - f = Rotate32(f, 11) * c1; - f = Rotate32(f, 17) * c1; - h = Rotate32(h + g, 19); - h = h * 5 + 0xe6546b64; - h = Rotate32(h, 17) * c1; - h = Rotate32(h + f, 19); - h = h * 5 + 0xe6546b64; - h = Rotate32(h, 17) * c1; - return h; -} - // Bitwise right rotate. Normally this will compile to a single // instruction, especially if the shift is a manifest constant. static uint64_t Rotate(uint64_t val, int shift) { @@ -374,4 +238,4 @@ uint64_t hash64(const void *data, size_t length, uint64_t seed) { return HashLen16(CityHash64((const char *)data, length) - k2, seed); } -} // namespace xe \ No newline at end of file +} // namespace xe diff --git a/src/xenia/core/socket_posix.cc b/src/xenia/core/socket_posix.cc index 5b815e1c2..4672faaa7 100644 --- a/src/xenia/core/socket_posix.cc +++ b/src/xenia/core/socket_posix.cc @@ -9,11 +9,15 @@ #include -#include -#include #include +#include +#include #include +#include #include +#include + +#include void xe_socket_init() { // No-op. @@ -81,7 +85,7 @@ int xe_socket_bind_loopback(socket_t socket) { socket_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); socket_addr.sin_port = htons(0); int r = bind(socket, (struct sockaddr*)&socket_addr, sizeof(socket_addr)); - if (r == SOCKET_ERROR) { + if (r == -1) { return 1; } return 0; @@ -108,7 +112,7 @@ int xe_socket_accept(socket_t socket, xe_socket_connection_t* out_client_info) { int client_ip = client_addr.sin_addr.s_addr; inet_ntop(AF_INET, &client_ip, out_client_info->addr, - XECOUNT(out_client_info->addr)); + poly::countof(out_client_info->addr)); return 0; } @@ -177,7 +181,7 @@ int xe_socket_loop_poll(xe_socket_loop_t* loop, bool check_read, // Poll. int r; - while ((r = poll(loop->events, XECOUNT(loop->events), -1)) == -1 && + while ((r = poll(loop->events, poly::countof(loop->events), -1)) == -1 && errno == EINTR) ; if (r == -1) { @@ -193,7 +197,7 @@ int xe_socket_loop_poll(xe_socket_loop_t* loop, bool check_read, loop->pending_queued_write = loop->events[1].revents != 0; if (loop->pending_queued_write) { uint8_t dummy; - XEIGNORE(recv(loop->notify_rd_id, &dummy, 1, 0)); + recv(loop->notify_rd_id, &dummy, 1, 0); } loop->events[1].revents = 0; loop->events[1].events = POLLIN; diff --git a/src/xenia/cpu/processor.cc b/src/xenia/cpu/processor.cc index 92ac73572..f397b3916 100644 --- a/src/xenia/cpu/processor.cc +++ b/src/xenia/cpu/processor.cc @@ -15,7 +15,6 @@ #include #include - using namespace alloy; using namespace alloy::backend; using namespace alloy::frontend::ppc; @@ -23,37 +22,35 @@ using namespace alloy::runtime; using namespace xe; using namespace xe::cpu; - namespace { - void InitializeIfNeeded(); - void CleanupOnShutdown(); +void InitializeIfNeeded(); +void CleanupOnShutdown(); - void InitializeIfNeeded() { - static bool has_initialized = false; - if (has_initialized) { - return; - } - has_initialized = true; - - //ppc::RegisterDisasmCategoryAltivec(); - //ppc::RegisterDisasmCategoryALU(); - //ppc::RegisterDisasmCategoryControl(); - //ppc::RegisterDisasmCategoryFPU(); - //ppc::RegisterDisasmCategoryMemory(); - - atexit(CleanupOnShutdown); +void InitializeIfNeeded() { + static bool has_initialized = false; + if (has_initialized) { + return; } + has_initialized = true; - void CleanupOnShutdown() { - } + // ppc::RegisterDisasmCategoryAltivec(); + // ppc::RegisterDisasmCategoryALU(); + // ppc::RegisterDisasmCategoryControl(); + // ppc::RegisterDisasmCategoryFPU(); + // ppc::RegisterDisasmCategoryMemory(); + + atexit(CleanupOnShutdown); } +void CleanupOnShutdown() {} +} -Processor::Processor(Emulator* emulator) : - emulator_(emulator), export_resolver_(emulator->export_resolver()), - runtime_(0), memory_(emulator->memory()), - interrupt_thread_state_(NULL), - interrupt_thread_block_(0) { +Processor::Processor(Emulator* emulator) + : export_resolver_(emulator->export_resolver()), + runtime_(0), + memory_(emulator->memory()), + interrupt_thread_state_(NULL), + interrupt_thread_block_(0) { InitializeIfNeeded(); } @@ -101,11 +98,9 @@ int Processor::Setup() { return result; } - interrupt_thread_state_ = new XenonThreadState( - runtime_, 0, 16 * 1024, 0); + interrupt_thread_state_ = new XenonThreadState(runtime_, 0, 16 * 1024, 0); interrupt_thread_state_->set_name("Interrupt"); - interrupt_thread_block_ = memory_->HeapAlloc( - 0, 2048, MEMORY_FLAG_ZERO); + interrupt_thread_block_ = memory_->HeapAlloc(0, 2048, MEMORY_FLAG_ZERO); interrupt_thread_state_->context()->r[13] = interrupt_thread_block_; return 0; @@ -136,9 +131,8 @@ int Processor::Execute(XenonThreadState* thread_state, uint64_t address) { return 0; } -uint64_t Processor::Execute( - XenonThreadState* thread_state, uint64_t address, uint64_t args[], - size_t arg_count) { +uint64_t Processor::Execute(XenonThreadState* thread_state, uint64_t address, + uint64_t args[], size_t arg_count) { SCOPE_profile_cpu_f("cpu"); PPCContext* context = thread_state->context(); @@ -163,8 +157,8 @@ void Processor::LowerIrql(Irql old_value) { reinterpret_cast(&irql_)); } -uint64_t Processor::ExecuteInterrupt( - uint32_t cpu, uint64_t address, uint64_t args[], size_t arg_count) { +uint64_t Processor::ExecuteInterrupt(uint32_t cpu, uint64_t address, + uint64_t args[], size_t arg_count) { SCOPE_profile_cpu_f("cpu"); // Acquire lock on interrupt thread (we can only dispatch one at a time). diff --git a/src/xenia/cpu/processor.h b/src/xenia/cpu/processor.h index ffcd65c9b..bf38bbf4b 100644 --- a/src/xenia/cpu/processor.h +++ b/src/xenia/cpu/processor.h @@ -53,7 +53,6 @@ class Processor { size_t arg_count); private: - Emulator* emulator_; ExportResolver* export_resolver_; XenonRuntime* runtime_; diff --git a/src/xenia/gpu/xenos/ucode.h b/src/xenia/gpu/xenos/ucode.h index f6130bcd3..eee9d58d0 100644 --- a/src/xenia/gpu/xenos/ucode.h +++ b/src/xenia/gpu/xenos/ucode.h @@ -12,31 +12,25 @@ #include - namespace xe { namespace gpu { namespace xenos { - #if XE_COMPILER_MSVC -#define XEPACKEDSTRUCT(name, value) \ - __pragma(pack(push, 1)) struct name##_s value __pragma(pack(pop)); \ - typedef struct name##_s name; +#define XEPACKEDSTRUCT(name, value) \ + __pragma(pack(push, 1)) struct name##_s value __pragma(pack(pop)); \ + typedef struct name##_s name; #define XEPACKEDSTRUCTANONYMOUS(value) \ - __pragma(pack(push, 1)) struct value __pragma(pack(pop)); -#define XEPACKEDUNION(name, value) \ - __pragma(pack(push, 1)) union name##_s value __pragma(pack(pop)); \ - typedef union name##_s name; -#elif XE_COMPILER_GNUC -#define XEPACKEDSTRUCT(name, value) \ - struct __attribute__((packed)) name -#define XEPACKEDSTRUCTANONYMOUS(value) \ - struct __attribute__((packed)) -#define XEPACKEDUNION(name, value) \ - union __attribute__((packed)) name + __pragma(pack(push, 1)) struct value __pragma(pack(pop)); +#define XEPACKEDUNION(name, value) \ + __pragma(pack(push, 1)) union name##_s value __pragma(pack(pop)); \ + typedef union name##_s name; +#else +#define XEPACKEDSTRUCT(name, value) struct __attribute__((packed)) name +#define XEPACKEDSTRUCTANONYMOUS(value) struct __attribute__((packed)) +#define XEPACKEDUNION(name, value) union __attribute__((packed)) name #endif // MSVC - // This code comes from the freedreno project: // https://github.com/freedreno/freedreno/blob/master/includes/instr-a2xx.h /* @@ -62,7 +56,6 @@ namespace xenos { * SOFTWARE. */ - enum a2xx_sq_surfaceformat { FMT_1_REVERSE = 0, FMT_1 = 1, @@ -127,7 +120,6 @@ enum a2xx_sq_surfaceformat { FMT_DXT3A_AS_1_1_1_1 = 61, }; - /* * ALU instructions: */ @@ -221,51 +213,49 @@ typedef enum { XEPACKEDSTRUCT(instr_alu_t, { /* dword0: */ XEPACKEDSTRUCTANONYMOUS({ - uint32_t vector_dest : 6; - uint32_t vector_dest_rel : 1; - uint32_t low_precision_16b_fp : 1; - uint32_t scalar_dest : 6; - uint32_t scalar_dest_rel : 1; - uint32_t export_data : 1; - uint32_t vector_write_mask : 4; - uint32_t scalar_write_mask : 4; - uint32_t vector_clamp : 1; - uint32_t scalar_clamp : 1; - uint32_t scalar_opc : 6; // instr_scalar_opc_t + uint32_t vector_dest : 6; + uint32_t vector_dest_rel : 1; + uint32_t low_precision_16b_fp : 1; + uint32_t scalar_dest : 6; + uint32_t scalar_dest_rel : 1; + uint32_t export_data : 1; + uint32_t vector_write_mask : 4; + uint32_t scalar_write_mask : 4; + uint32_t vector_clamp : 1; + uint32_t scalar_clamp : 1; + uint32_t scalar_opc : 6; // instr_scalar_opc_t }); /* dword1: */ XEPACKEDSTRUCTANONYMOUS({ - uint32_t src3_swiz : 8; - uint32_t src2_swiz : 8; - uint32_t src1_swiz : 8; - uint32_t src3_reg_negate : 1; - uint32_t src2_reg_negate : 1; - uint32_t src1_reg_negate : 1; - uint32_t pred_select : 2; - uint32_t relative_addr : 1; - uint32_t const_1_rel_abs : 1; - uint32_t const_0_rel_abs : 1; + uint32_t src3_swiz : 8; + uint32_t src2_swiz : 8; + uint32_t src1_swiz : 8; + uint32_t src3_reg_negate : 1; + uint32_t src2_reg_negate : 1; + uint32_t src1_reg_negate : 1; + uint32_t pred_select : 2; + uint32_t relative_addr : 1; + uint32_t const_1_rel_abs : 1; + uint32_t const_0_rel_abs : 1; }); /* dword2: */ XEPACKEDSTRUCTANONYMOUS({ - uint32_t src3_reg : 6; - uint32_t src3_reg_select : 1; - uint32_t src3_reg_abs : 1; - uint32_t src2_reg : 6; - uint32_t src2_reg_select : 1; - uint32_t src2_reg_abs : 1; - uint32_t src1_reg : 6; - uint32_t src1_reg_select : 1; - uint32_t src1_reg_abs : 1; - uint32_t vector_opc : 5; // instr_vector_opc_t - uint32_t src3_sel : 1; - uint32_t src2_sel : 1; - uint32_t src1_sel : 1; + uint32_t src3_reg : 6; + uint32_t src3_reg_select : 1; + uint32_t src3_reg_abs : 1; + uint32_t src2_reg : 6; + uint32_t src2_reg_select : 1; + uint32_t src2_reg_abs : 1; + uint32_t src1_reg : 6; + uint32_t src1_reg_select : 1; + uint32_t src1_reg_abs : 1; + uint32_t vector_opc : 5; // instr_vector_opc_t + uint32_t src3_sel : 1; + uint32_t src2_sel : 1; + uint32_t src1_sel : 1; }); }); - - /* * CF instructions: */ @@ -303,24 +293,22 @@ typedef enum { XEPACKEDSTRUCT(instr_cf_exec_t, { XEPACKEDSTRUCTANONYMOUS({ - uint32_t address : 12; - uint32_t count : 3; - uint32_t yeild : 1; - uint32_t serialize : 12; - uint32_t vc_hi : 4; + uint32_t address : 12; + uint32_t count : 3; + uint32_t yeild : 1; + uint32_t serialize : 12; + uint32_t vc_hi : 4; }); XEPACKEDSTRUCTANONYMOUS({ - uint32_t vc_lo : 2; /* vertex cache? */ - uint32_t bool_addr : 8; - uint32_t condition : 1; - uint32_t address_mode : 1; // instr_addr_mode_t - uint32_t opc : 4; // instr_cf_opc_t + uint32_t vc_lo : 2; /* vertex cache? */ + uint32_t bool_addr : 8; + uint32_t condition : 1; + uint32_t address_mode : 1; // instr_addr_mode_t + uint32_t opc : 4; // instr_cf_opc_t }); bool is_cond_exec() const { - return (this->opc == COND_EXEC) || - (this->opc == COND_EXEC_END) || - (this->opc == COND_PRED_EXEC) || - (this->opc == COND_PRED_EXEC_END) || + return (this->opc == COND_EXEC) || (this->opc == COND_EXEC_END) || + (this->opc == COND_PRED_EXEC) || (this->opc == COND_PRED_EXEC_END) || (this->opc == COND_EXEC_PRED_CLEAN) || (this->opc == COND_EXEC_PRED_CLEAN_END); } @@ -328,89 +316,84 @@ XEPACKEDSTRUCT(instr_cf_exec_t, { XEPACKEDSTRUCT(instr_cf_loop_t, { XEPACKEDSTRUCTANONYMOUS({ - uint32_t address : 13; - uint32_t repeat : 1; - uint32_t reserved0 : 2; - uint32_t loop_id : 5; - uint32_t pred_break : 1; - uint32_t reserved1_hi : 10; + uint32_t address : 13; + uint32_t repeat : 1; + uint32_t reserved0 : 2; + uint32_t loop_id : 5; + uint32_t pred_break : 1; + uint32_t reserved1_hi : 10; }); XEPACKEDSTRUCTANONYMOUS({ - uint32_t reserved1_lo : 10; - uint32_t condition : 1; - uint32_t address_mode : 1; // instr_addr_mode_t - uint32_t opc : 4; // instr_cf_opc_t + uint32_t reserved1_lo : 10; + uint32_t condition : 1; + uint32_t address_mode : 1; // instr_addr_mode_t + uint32_t opc : 4; // instr_cf_opc_t }); }); XEPACKEDSTRUCT(instr_cf_jmp_call_t, { XEPACKEDSTRUCTANONYMOUS({ - uint32_t address : 13; - uint32_t force_call : 1; - uint32_t predicated_jmp : 1; - uint32_t reserved1_hi : 17; + uint32_t address : 13; + uint32_t force_call : 1; + uint32_t predicated_jmp : 1; + uint32_t reserved1_hi : 17; }); XEPACKEDSTRUCTANONYMOUS({ - uint32_t reserved1_lo : 1; - uint32_t direction : 1; - uint32_t bool_addr : 8; - uint32_t condition : 1; - uint32_t address_mode : 1; // instr_addr_mode_t - uint32_t opc : 4; // instr_cf_opc_t + uint32_t reserved1_lo : 1; + uint32_t direction : 1; + uint32_t bool_addr : 8; + uint32_t condition : 1; + uint32_t address_mode : 1; // instr_addr_mode_t + uint32_t opc : 4; // instr_cf_opc_t }); }); XEPACKEDSTRUCT(instr_cf_alloc_t, { XEPACKEDSTRUCTANONYMOUS({ - uint32_t size : 3; - uint32_t reserved0_hi : 29; + uint32_t size : 3; + uint32_t reserved0_hi : 29; }); XEPACKEDSTRUCTANONYMOUS({ - uint32_t reserved0_lo : 8; - uint32_t no_serial : 1; - uint32_t buffer_select : 2; // instr_alloc_type_t - uint32_t alloc_mode : 1; - uint32_t opc : 4; // instr_cf_opc_t + uint32_t reserved0_lo : 8; + uint32_t no_serial : 1; + uint32_t buffer_select : 2; // instr_alloc_type_t + uint32_t alloc_mode : 1; + uint32_t opc : 4; // instr_cf_opc_t }); }); XEPACKEDUNION(instr_cf_t, { - instr_cf_exec_t exec; - instr_cf_loop_t loop; - instr_cf_jmp_call_t jmp_call; - instr_cf_alloc_t alloc; + instr_cf_exec_t exec; + instr_cf_loop_t loop; + instr_cf_jmp_call_t jmp_call; + instr_cf_alloc_t alloc; XEPACKEDSTRUCTANONYMOUS({ - uint32_t : 32; - uint32_t : 12; - uint32_t opc : 4; // instr_cf_opc_t + uint32_t: + 32; + uint32_t: + 12; + uint32_t opc : 4; // instr_cf_opc_t }); XEPACKEDSTRUCTANONYMOUS({ - uint32_t dword_0; - uint32_t dword_1; + uint32_t dword_0; + uint32_t dword_1; }); bool is_exec() const { - return (this->opc == EXEC) || - (this->opc == EXEC_END) || - (this->opc == COND_EXEC) || - (this->opc == COND_EXEC_END) || - (this->opc == COND_PRED_EXEC) || - (this->opc == COND_PRED_EXEC_END) || + return (this->opc == EXEC) || (this->opc == EXEC_END) || + (this->opc == COND_EXEC) || (this->opc == COND_EXEC_END) || + (this->opc == COND_PRED_EXEC) || (this->opc == COND_PRED_EXEC_END) || (this->opc == COND_EXEC_PRED_CLEAN) || (this->opc == COND_EXEC_PRED_CLEAN_END); } bool is_cond_exec() const { - return (this->opc == COND_EXEC) || - (this->opc == COND_EXEC_END) || - (this->opc == COND_PRED_EXEC) || - (this->opc == COND_PRED_EXEC_END) || + return (this->opc == COND_EXEC) || (this->opc == COND_EXEC_END) || + (this->opc == COND_PRED_EXEC) || (this->opc == COND_PRED_EXEC_END) || (this->opc == COND_EXEC_PRED_CLEAN) || (this->opc == COND_EXEC_PRED_CLEAN_END); } }); - - /* * FETCH instructions: */ @@ -431,7 +414,7 @@ typedef enum { typedef enum { TEX_FILTER_POINT = 0, TEX_FILTER_LINEAR = 1, - TEX_FILTER_BASEMAP = 2, /* only applicable for mip-filter */ + TEX_FILTER_BASEMAP = 2, /* only applicable for mip-filter */ TEX_FILTER_USE_FETCH_CONST = 3, } instr_tex_filter_t; @@ -472,104 +455,105 @@ typedef enum a2xx_sq_surfaceformat instr_surf_fmt_t; XEPACKEDSTRUCT(instr_fetch_tex_t, { /* dword0: */ XEPACKEDSTRUCTANONYMOUS({ - uint32_t opc : 5; // instr_fetch_opc_t - uint32_t src_reg : 6; - uint32_t src_reg_am : 1; - uint32_t dst_reg : 6; - uint32_t dst_reg_am : 1; - uint32_t fetch_valid_only : 1; - uint32_t const_idx : 5; - uint32_t tx_coord_denorm : 1; - uint32_t src_swiz : 6; // xyz + uint32_t opc : 5; // instr_fetch_opc_t + uint32_t src_reg : 6; + uint32_t src_reg_am : 1; + uint32_t dst_reg : 6; + uint32_t dst_reg_am : 1; + uint32_t fetch_valid_only : 1; + uint32_t const_idx : 5; + uint32_t tx_coord_denorm : 1; + uint32_t src_swiz : 6; // xyz }); /* dword1: */ XEPACKEDSTRUCTANONYMOUS({ - uint32_t dst_swiz : 12; // xyzw - uint32_t mag_filter : 2; // instr_tex_filter_t - uint32_t min_filter : 2; // instr_tex_filter_t - uint32_t mip_filter : 2; // instr_tex_filter_t - uint32_t aniso_filter : 3; // instr_aniso_filter_t - uint32_t arbitrary_filter : 3; // instr_arbitrary_filter_t - uint32_t vol_mag_filter : 2; // instr_tex_filter_t - uint32_t vol_min_filter : 2; // instr_tex_filter_t - uint32_t use_comp_lod : 1; - uint32_t use_reg_lod : 1; - uint32_t unk : 1; - uint32_t pred_select : 1; + uint32_t dst_swiz : 12; // xyzw + uint32_t mag_filter : 2; // instr_tex_filter_t + uint32_t min_filter : 2; // instr_tex_filter_t + uint32_t mip_filter : 2; // instr_tex_filter_t + uint32_t aniso_filter : 3; // instr_aniso_filter_t + uint32_t arbitrary_filter : 3; // instr_arbitrary_filter_t + uint32_t vol_mag_filter : 2; // instr_tex_filter_t + uint32_t vol_min_filter : 2; // instr_tex_filter_t + uint32_t use_comp_lod : 1; + uint32_t use_reg_lod : 1; + uint32_t unk : 1; + uint32_t pred_select : 1; }); /* dword2: */ XEPACKEDSTRUCTANONYMOUS({ - uint32_t use_reg_gradients : 1; - uint32_t sample_location : 1; // instr_sample_loc_t - uint32_t lod_bias : 7; - uint32_t unused : 5; - uint32_t dimension : 2; // instr_dimension_t - uint32_t offset_x : 5; - uint32_t offset_y : 5; - uint32_t offset_z : 5; - uint32_t pred_condition : 1; + uint32_t use_reg_gradients : 1; + uint32_t sample_location : 1; // instr_sample_loc_t + uint32_t lod_bias : 7; + uint32_t unused : 5; + uint32_t dimension : 2; // instr_dimension_t + uint32_t offset_x : 5; + uint32_t offset_y : 5; + uint32_t offset_z : 5; + uint32_t pred_condition : 1; }); }); XEPACKEDSTRUCT(instr_fetch_vtx_t, { /* dword0: */ XEPACKEDSTRUCTANONYMOUS({ - uint32_t opc : 5; // instr_fetch_opc_t - uint32_t src_reg : 6; - uint32_t src_reg_am : 1; - uint32_t dst_reg : 6; - uint32_t dst_reg_am : 1; - uint32_t must_be_one : 1; - uint32_t const_index : 5; - uint32_t const_index_sel : 2; - uint32_t reserved0 : 3; - uint32_t src_swiz : 2; + uint32_t opc : 5; // instr_fetch_opc_t + uint32_t src_reg : 6; + uint32_t src_reg_am : 1; + uint32_t dst_reg : 6; + uint32_t dst_reg_am : 1; + uint32_t must_be_one : 1; + uint32_t const_index : 5; + uint32_t const_index_sel : 2; + uint32_t reserved0 : 3; + uint32_t src_swiz : 2; }); /* dword1: */ XEPACKEDSTRUCTANONYMOUS({ - uint32_t dst_swiz : 12; - uint32_t format_comp_all : 1; /* '1' for signed, '0' for unsigned? */ - uint32_t num_format_all : 1; /* '0' for normalized, '1' for unnormalized */ - uint32_t signed_rf_mode_all : 1; - uint32_t reserved1 : 1; - uint32_t format : 6; // instr_surf_fmt_t - uint32_t reserved2 : 1; - uint32_t exp_adjust_all : 7; - uint32_t reserved3 : 1; - uint32_t pred_select : 1; + uint32_t dst_swiz : 12; + uint32_t format_comp_all : 1; /* '1' for signed, '0' for unsigned? */ + uint32_t num_format_all : 1; /* '0' for normalized, '1' for unnormalized */ + uint32_t signed_rf_mode_all : 1; + uint32_t reserved1 : 1; + uint32_t format : 6; // instr_surf_fmt_t + uint32_t reserved2 : 1; + uint32_t exp_adjust_all : 7; + uint32_t reserved3 : 1; + uint32_t pred_select : 1; }); /* dword2: */ XEPACKEDSTRUCTANONYMOUS({ - uint32_t stride : 8; - uint32_t offset : 23; - uint32_t pred_condition : 1; + uint32_t stride : 8; + uint32_t offset : 23; + uint32_t pred_condition : 1; }); }); XEPACKEDUNION(instr_fetch_t, { - instr_fetch_tex_t tex; - instr_fetch_vtx_t vtx; + instr_fetch_tex_t tex; + instr_fetch_vtx_t vtx; XEPACKEDSTRUCTANONYMOUS({ /* dword0: */ XEPACKEDSTRUCTANONYMOUS({ - uint32_t opc : 5; // instr_fetch_opc_t - uint32_t : 27; + uint32_t opc : 5; // instr_fetch_opc_t + uint32_t: + 27; }); /* dword1: */ XEPACKEDSTRUCTANONYMOUS({ - uint32_t : 32; + uint32_t: + 32; }); /* dword2: */ XEPACKEDSTRUCTANONYMOUS({ - uint32_t : 32; + uint32_t: + 32; }); }); }); - } // namespace xenos } // namespace gpu } // namespace xe - #endif // XENIA_GPU_XENOS_UCODE_H_ diff --git a/src/xenia/kernel/fs/devices/disc_image_entry.cc b/src/xenia/kernel/fs/devices/disc_image_entry.cc index cc1110355..141d4bf89 100644 --- a/src/xenia/kernel/fs/devices/disc_image_entry.cc +++ b/src/xenia/kernel/fs/devices/disc_image_entry.cc @@ -20,22 +20,18 @@ namespace fs { class DiscImageMemoryMapping : public MemoryMapping { public: - DiscImageMemoryMapping(uint8_t* address, size_t length, - poly::MappedMemory* mmap) - : MemoryMapping(address, length), mmap_(mmap) {} + DiscImageMemoryMapping(uint8_t* address, size_t length) + : MemoryMapping(address, length) {} - virtual ~DiscImageMemoryMapping() {} - - private: - poly::MappedMemory* mmap_; + ~DiscImageMemoryMapping() override = default; }; DiscImageEntry::DiscImageEntry(Type type, Device* device, const char* path, poly::MappedMemory* mmap, GDFXEntry* gdfx_entry) - : gdfx_entry_(gdfx_entry), - gdfx_entry_iterator_(gdfx_entry->children.end()), + : Entry(type, device, path), mmap_(mmap), - Entry(type, device, path) {} + gdfx_entry_(gdfx_entry), + gdfx_entry_iterator_(gdfx_entry->children.end()) {} DiscImageEntry::~DiscImageEntry() {} @@ -107,7 +103,7 @@ std::unique_ptr DiscImageEntry::CreateMemoryMapping( size_t real_length = length ? std::min(length, gdfx_entry_->size) : gdfx_entry_->size; return std::make_unique(mmap_->data() + real_offset, - real_length, mmap_); + real_length); } X_STATUS DiscImageEntry::Open(KernelState* kernel_state, Mode mode, bool async, diff --git a/src/xenia/kernel/fs/devices/disc_image_entry.h b/src/xenia/kernel/fs/devices/disc_image_entry.h index b1a076698..4ba6c79cc 100644 --- a/src/xenia/kernel/fs/devices/disc_image_entry.h +++ b/src/xenia/kernel/fs/devices/disc_image_entry.h @@ -27,21 +27,21 @@ class DiscImageEntry : public Entry { public: DiscImageEntry(Type type, Device* device, const char* path, poly::MappedMemory* mmap, GDFXEntry* gdfx_entry); - virtual ~DiscImageEntry(); + ~DiscImageEntry() override; poly::MappedMemory* mmap() const { return mmap_; } GDFXEntry* gdfx_entry() const { return gdfx_entry_; } - virtual X_STATUS QueryInfo(XFileInfo* out_info); - virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info, size_t length, - const char* file_name, bool restart); + X_STATUS QueryInfo(XFileInfo* out_info) override; + X_STATUS QueryDirectory(XDirectoryInfo* out_info, size_t length, + const char* file_name, bool restart) override; - virtual bool can_map() { return true; } - virtual std::unique_ptr CreateMemoryMapping( - Mode map_mode, const size_t offset, const size_t length); + bool can_map() override { return true; } + std::unique_ptr CreateMemoryMapping( + Mode map_mode, const size_t offset, const size_t length) override; - virtual X_STATUS Open(KernelState* kernel_state, Mode mode, bool async, - XFile** out_file); + X_STATUS Open(KernelState* kernel_state, Mode mode, bool async, + XFile** out_file) override; private: poly::MappedMemory* mmap_; diff --git a/src/xenia/kernel/fs/devices/host_path_entry.h b/src/xenia/kernel/fs/devices/host_path_entry.h index 913ece216..b72b0460a 100644 --- a/src/xenia/kernel/fs/devices/host_path_entry.h +++ b/src/xenia/kernel/fs/devices/host_path_entry.h @@ -22,20 +22,20 @@ class HostPathEntry : public Entry { public: HostPathEntry(Type type, Device* device, const char* path, const std::wstring& local_path); - virtual ~HostPathEntry(); + ~HostPathEntry() override; const std::wstring& local_path() { return local_path_; } - virtual X_STATUS QueryInfo(XFileInfo* out_info); - virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info, size_t length, - const char* file_name, bool restart); + X_STATUS QueryInfo(XFileInfo* out_info) override; + X_STATUS QueryDirectory(XDirectoryInfo* out_info, size_t length, + const char* file_name, bool restart) override; - virtual bool can_map() { return true; } - virtual std::unique_ptr CreateMemoryMapping( - Mode map_mode, const size_t offset, const size_t length); + bool can_map() override { return true; } + std::unique_ptr CreateMemoryMapping( + Mode map_mode, const size_t offset, const size_t length) override; - virtual X_STATUS Open(KernelState* kernel_state, Mode mode, bool async, - XFile** out_file); + X_STATUS Open(KernelState* kernel_state, Mode mode, bool async, + XFile** out_file) override; private: std::wstring local_path_; diff --git a/src/xenia/kernel/fs/devices/stfs_container_entry.cc b/src/xenia/kernel/fs/devices/stfs_container_entry.cc index 5012b7e3d..db6d5ff75 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_entry.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_entry.cc @@ -20,12 +20,12 @@ STFSContainerEntry::STFSContainerEntry(Type type, Device* device, const char* path, poly::MappedMemory* mmap, STFSEntry* stfs_entry) - : stfs_entry_(stfs_entry), - stfs_entry_iterator_(stfs_entry->children.end()), + : Entry(type, device, path), mmap_(mmap), - Entry(type, device, path) {} + stfs_entry_(stfs_entry), + stfs_entry_iterator_(stfs_entry->children.end()) {} -STFSContainerEntry::~STFSContainerEntry() {} +STFSContainerEntry::~STFSContainerEntry() = default; X_STATUS STFSContainerEntry::QueryInfo(XFileInfo* out_info) { assert_not_null(out_info); diff --git a/src/xenia/kernel/fs/devices/stfs_container_entry.h b/src/xenia/kernel/fs/devices/stfs_container_entry.h index db91161e6..65e416c0e 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_entry.h +++ b/src/xenia/kernel/fs/devices/stfs_container_entry.h @@ -27,17 +27,17 @@ class STFSContainerEntry : public Entry { public: STFSContainerEntry(Type type, Device* device, const char* path, poly::MappedMemory* mmap, STFSEntry* stfs_entry); - virtual ~STFSContainerEntry(); + ~STFSContainerEntry() override; poly::MappedMemory* mmap() const { return mmap_; } STFSEntry* stfs_entry() const { return stfs_entry_; } - virtual X_STATUS QueryInfo(XFileInfo* out_info); - virtual X_STATUS QueryDirectory(XDirectoryInfo* out_info, size_t length, - const char* file_name, bool restart); + X_STATUS QueryInfo(XFileInfo* out_info) override; + X_STATUS QueryDirectory(XDirectoryInfo* out_info, size_t length, + const char* file_name, bool restart) override; - virtual X_STATUS Open(KernelState* kernel_state, Mode desired_access, - bool async, XFile** out_file); + X_STATUS Open(KernelState* kernel_state, Mode desired_access, bool async, + XFile** out_file) override; private: poly::MappedMemory* mmap_; diff --git a/src/xenia/kernel/fs/devices/stfs_container_file.cc b/src/xenia/kernel/fs/devices/stfs_container_file.cc index b52c6e7ce..2baffba9c 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_file.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_file.cc @@ -21,7 +21,7 @@ namespace fs { STFSContainerFile::STFSContainerFile(KernelState* kernel_state, Mode mode, STFSContainerEntry* entry) - : entry_(entry), XFile(kernel_state, mode) {} + : XFile(kernel_state, mode), entry_(entry) {} STFSContainerFile::~STFSContainerFile() { delete entry_; } diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index 60c6086e3..d1b31f3f7 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -283,7 +283,7 @@ X_STATUS XThread::PlatformExit(int exit_code) { static void* XThreadStartCallbackPthreads(void* param) { XThread* thread = reinterpret_cast(param); - xe::Profiler::ThreadEnter(thread->name()); + xe::Profiler::ThreadEnter(thread->name().c_str()); current_thread_tls = thread; thread->Execute(); current_thread_tls = nullptr; @@ -334,7 +334,7 @@ void XThread::PlatformDestroy() { X_STATUS XThread::PlatformExit(int exit_code) { // NOTE: does not return. - pthread_exit((void*)exit_code); + pthread_exit(reinterpret_cast(exit_code)); return X_STATUS_SUCCESS; } diff --git a/src/xenia/kernel/objects/xuser_module.cc b/src/xenia/kernel/objects/xuser_module.cc index 4f59c205d..ad6b9aa41 100644 --- a/src/xenia/kernel/objects/xuser_module.cc +++ b/src/xenia/kernel/objects/xuser_module.cc @@ -161,7 +161,7 @@ void XUserModule::Dump() { const xe_xex2_header_t* header = xe_xex2_get_header(xex_); // XEX info. - printf("Module %s:\n\n", path_); + printf("Module %s:\n\n", path_.c_str()); printf(" Module Flags: %.8X\n", header->module_flags); printf(" System Flags: %.8X\n", header->system_flags); printf("\n"); @@ -292,7 +292,7 @@ void XUserModule::Dump() { unimpl_count++; } } - printf(" Total: %4u\n", import_info_count); + printf(" Total: %4zu\n", import_info_count); printf(" Known: %3d%% (%d known, %d unknown)\n", (int)(known_count / (float)import_info_count * 100.0f), known_count, unknown_count); diff --git a/src/xenia/ui/ui_event.h b/src/xenia/ui/ui_event.h index 07fae340e..95c313d19 100644 --- a/src/xenia/ui/ui_event.h +++ b/src/xenia/ui/ui_event.h @@ -12,41 +12,37 @@ #include - namespace xe { namespace ui { class App; class Window; - class UIEvent { -public: - UIEvent(Window* window = NULL) : - window_(window) {} - virtual ~UIEvent() {} + public: + UIEvent(Window* window = NULL) : window_(window) {} + virtual ~UIEvent() = default; Window* window() const { return window_; } -private: - Window* window_; + private: + Window* window_; }; class KeyEvent : public UIEvent { -public: - KeyEvent(Window* window, int key_code) : - key_code_(key_code), - UIEvent(window) {} - virtual ~KeyEvent() {} + public: + KeyEvent(Window* window, int key_code) + : UIEvent(window), key_code_(key_code) {} + ~KeyEvent() override = default; int key_code() const { return key_code_; } -private: + private: int key_code_; }; class MouseEvent : public UIEvent { -public: + public: enum Button { MOUSE_BUTTON_NONE = 0, MOUSE_BUTTON_LEFT, @@ -56,13 +52,11 @@ public: MOUSE_BUTTON_X2, }; -public: - MouseEvent(Window* window, - Button button, int32_t x, int32_t y, - int32_t dx = 0, int32_t dy = 0) : - button_(button), x_(x), y_(y), dx_(dx), dy_(dy), - UIEvent(window) {} - virtual ~MouseEvent() {} + public: + MouseEvent(Window* window, Button button, int32_t x, int32_t y, + int32_t dx = 0, int32_t dy = 0) + : UIEvent(window), button_(button), x_(x), y_(y), dx_(dx), dy_(dy) {} + ~MouseEvent() override = default; Button button() const { return button_; } int32_t x() const { return x_; } @@ -70,17 +64,15 @@ public: int32_t dx() const { return dx_; } int32_t dy() const { return dy_; } -private: - Button button_; + private: + Button button_; int32_t x_; int32_t y_; int32_t dx_; int32_t dy_; }; - } // namespace ui } // namespace xe - #endif // XENIA_UI_UI_EVENT_H_ From ba5b626cdf3d9b5f52e189d3f8090a85cbfd7304 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 22 Aug 2014 18:44:52 -0700 Subject: [PATCH 159/388] Fixing win32 build. Silly VC. --- src/alloy/backend/x64/x64_sequence.inl | 5 +++++ src/poly/platform.h | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/alloy/backend/x64/x64_sequence.inl b/src/alloy/backend/x64/x64_sequence.inl index c9451fdfe..5013ba4a6 100644 --- a/src/alloy/backend/x64/x64_sequence.inl +++ b/src/alloy/backend/x64/x64_sequence.inl @@ -528,7 +528,12 @@ template struct SingleSequence : public Sequence, T> { typedef Sequence, T> BASE; typedef T EmitArgType; + // TODO(benvanik): find a way to do this cross-compiler. +#if XE_COMPILER_MSVC + static uint32_t head_key() { return T::key; } +#else static constexpr uint32_t head_key() { return T::key; } +#endif // XE_COMPILER_MSVC static void Emit(X64Emitter& e, const typename BASE::EmitArgs& _) { SEQ::Emit(e, _.i1); } diff --git a/src/poly/platform.h b/src/poly/platform.h index 05be89e48..c576e6066 100644 --- a/src/poly/platform.h +++ b/src/poly/platform.h @@ -144,13 +144,13 @@ XE_CPU: 32BIT | 64BIT | BIGENDIAN | LITTLEENDIAN #if XE_COMPILER_MSVC // Disable warning C4068: unknown pragma #pragma warning(disable : 4068) -#endif // MSVC +#endif // XE_COMPILER_MSVC #if XE_COMPILER_MSVC #include #else #include -#endif // MSVC +#endif // XE_COMPILER_MSVC namespace poly { @@ -160,7 +160,7 @@ const size_t max_path = _MAX_PATH; #else const char path_separator = '/'; const size_t max_path = 1024; // PATH_MAX -#endif // WIN32 +#endif // XE_LIKE_WIN32 } // namespace poly From f6c73819a3fc47a21e1a7aa5bd1b9946baca421d Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 22 Aug 2014 21:58:28 -0700 Subject: [PATCH 160/388] Fixing add_carry (+typos). --- src/alloy/compiler/passes/constant_propagation_pass.cc | 9 +++++++-- src/alloy/frontend/ppc/ppc_emit_alu.cc | 2 +- src/xenia/gpu/d3d11/d3d11_window.cc | 1 - src/xenia/kernel/xboxkrnl_rtl.cc | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/alloy/compiler/passes/constant_propagation_pass.cc b/src/alloy/compiler/passes/constant_propagation_pass.cc index 471bc2633..072530db9 100644 --- a/src/alloy/compiler/passes/constant_propagation_pass.cc +++ b/src/alloy/compiler/passes/constant_propagation_pass.cc @@ -317,8 +317,13 @@ int ConstantPropagationPass::Run(HIRBuilder* builder) { } } } - i->Replace(&OPCODE_ASSIGN_info, 0); - i->set_src1(ca); + if (i->dest->type == ca->type) { + i->Replace(&OPCODE_ASSIGN_info, 0); + i->set_src1(ca); + } else { + i->Replace(&OPCODE_ZERO_EXTEND_info, 0); + i->set_src1(ca); + } } break; case OPCODE_SUB: diff --git a/src/alloy/frontend/ppc/ppc_emit_alu.cc b/src/alloy/frontend/ppc/ppc_emit_alu.cc index da8bf65a6..8638a0216 100644 --- a/src/alloy/frontend/ppc/ppc_emit_alu.cc +++ b/src/alloy/frontend/ppc/ppc_emit_alu.cc @@ -478,7 +478,7 @@ XEEMITTER(subfmex, 0x7C0001D0, XO)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(subfzex, 0x7C000190, XO)(PPCHIRBuilder& f, InstrData& i) { // RT <- ¬(RA) + CA Value* v = f.AddWithCarry(f.Not(f.LoadGPR(i.XO.RA)), f.LoadZero(INT64_TYPE), - f.LoadCA()); + f.LoadCA(), ARITHMETIC_SET_CARRY); if (i.XO.OE) { assert_always(); // e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1)); diff --git a/src/xenia/gpu/d3d11/d3d11_window.cc b/src/xenia/gpu/d3d11/d3d11_window.cc index eb1e50d5b..c99cdc421 100644 --- a/src/xenia/gpu/d3d11/d3d11_window.cc +++ b/src/xenia/gpu/d3d11/d3d11_window.cc @@ -138,4 +138,3 @@ bool D3D11Window::OnResize(uint32_t width, uint32_t height) { return true; } - diff --git a/src/xenia/kernel/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl_rtl.cc index c15ff783c..8616c5474 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl_rtl.cc @@ -341,7 +341,7 @@ SHIM_CALL RtlNtStatusToDosError_shim(PPCContext* ppc_state, } // TODO(benvanik): implement lookup table. - XELOGE("RtlNtStatusToDosError lookup NOT SHIMEMENTED"); + XELOGE("RtlNtStatusToDosError lookup NOT IMPLEMENTED"); uint32_t result = 317; // ERROR_MR_MID_NOT_FOUND From 540b192b1a3f64f3e206842dc6ab1339de979f8d Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 22 Aug 2014 21:58:46 -0700 Subject: [PATCH 161/388] Emulating vector sub signed sat i32. --- src/alloy/backend/x64/x64_sequences.cc | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index d09fa7304..d316af9c5 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -2871,6 +2871,18 @@ EMITTER_OPCODE_TABLE( // OPCODE_VECTOR_SUB // ============================================================================ EMITTER(VECTOR_SUB, MATCH(I, V128<>, V128<>>)) { + static __m128i EmulateVectorSubSignedSatI32(__m128i src1, __m128i src2) { + alignas(16) int32_t src1v[4]; + alignas(16) int32_t src2v[4]; + alignas(16) int32_t value[4]; + _mm_store_si128(reinterpret_cast<__m128i*>(&src1v), src1); + _mm_store_si128(reinterpret_cast<__m128i*>(&src2v), src2); + for (size_t i = 0; i < 4; ++i) { + auto t = int64_t(src1v[i]) + int64_t(src2v[i]); + value[i] = t < INT_MIN ? INT_MIN : (t > INT_MAX ? INT_MAX : int32_t(t)); + } + return _mm_load_si128(reinterpret_cast<__m128i*>(&value)); + } static void Emit(X64Emitter& e, const EmitArgType& i) { EmitCommutativeBinaryXmmOp(e, i, [&i](X64Emitter& e, const Xmm& dest, const Xmm& src1, const Xmm& src2) { @@ -2908,7 +2920,11 @@ EMITTER(VECTOR_SUB, MATCH(I, V128<>, V128<>>)) { if (is_unsigned) { assert_always(); } else { - assert_always(); + e.lea(e.r8, e.StashXmm(i.src1)); + e.lea(e.r9, e.StashXmm(i.src2)); + e.CallNativeSafe( + reinterpret_cast(EmulateVectorSubSignedSatI32)); + e.vmovaps(i.dest, e.xmm0); } } else { e.vpsubd(dest, src1, src2); From 168239b469de7b0b999a90ada7310625a526e6a7 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 22 Aug 2014 21:58:57 -0700 Subject: [PATCH 162/388] Optimizing eflags access (I think). --- src/alloy/backend/x64/x64_emitter.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index fc06a63ac..3762fdd4e 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -732,8 +732,7 @@ void X64Emitter::nop(size_t length) { void X64Emitter::LoadEflags() { #if STORE_EFLAGS mov(eax, dword[rsp + STASH_OFFSET]); - push(rax); - popf(); + btr(eax, 0); #else // EFLAGS already present. #endif // STORE_EFLAGS @@ -742,7 +741,7 @@ void X64Emitter::LoadEflags() { void X64Emitter::StoreEflags() { #if STORE_EFLAGS pushf(); - pop(qword[rsp + STASH_OFFSET]); + pop(dword[rsp + STASH_OFFSET]); #else // EFLAGS should have CA set? // (so long as we don't fuck with it) From 389de8b107e8e40dad754f036b6e2adc5b5a0936 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 23 Aug 2014 09:55:49 -0700 Subject: [PATCH 163/388] Subtract should subtract. Thanks hlide! --- src/alloy/backend/x64/x64_sequences.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index d316af9c5..a6fbd75af 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -2878,7 +2878,7 @@ EMITTER(VECTOR_SUB, MATCH(I, V128<>, V128<>>)) { _mm_store_si128(reinterpret_cast<__m128i*>(&src1v), src1); _mm_store_si128(reinterpret_cast<__m128i*>(&src2v), src2); for (size_t i = 0; i < 4; ++i) { - auto t = int64_t(src1v[i]) + int64_t(src2v[i]); + auto t = int64_t(src1v[i]) - int64_t(src2v[i]); value[i] = t < INT_MIN ? INT_MIN : (t > INT_MAX ? INT_MAX : int32_t(t)); } return _mm_load_si128(reinterpret_cast<__m128i*>(&value)); From 2a9f164f8e247647e6efe3cc7948bcc0550a235e Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 23 Aug 2014 14:53:36 -0700 Subject: [PATCH 164/388] Alloy test shim. --- .gitmodules | 3 + src/alloy/frontend/ppc/ppc_translator.cc | 2 +- src/alloy/runtime/module.h | 8 +- src/alloy/runtime/sources.gypi | 2 + src/alloy/runtime/test_module.cc | 103 ++++++++++++++++ src/alloy/runtime/test_module.h | 52 ++++++++ third_party/catch | 1 + tools/alloy-test/alloy-test.cc | 47 +++++++ tools/alloy-test/alloy-test.gypi | 29 +++++ tools/alloy-test/test_util.h | 148 +++++++++++++++++++++++ tools/tools.gypi | 1 + 11 files changed, 391 insertions(+), 5 deletions(-) create mode 100644 src/alloy/runtime/test_module.cc create mode 100644 src/alloy/runtime/test_module.h create mode 160000 third_party/catch create mode 100644 tools/alloy-test/alloy-test.cc create mode 100644 tools/alloy-test/alloy-test.gypi create mode 100644 tools/alloy-test/test_util.h diff --git a/.gitmodules b/.gitmodules index 31ad04ace..edfd14ccb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,6 @@ [submodule "third_party/wxWidgets"] path = third_party/wxWidgets url = https://github.com/wxWidgets/wxWidgets.git +[submodule "third_party/catch"] + path = third_party/catch + url = https://github.com/philsquared/Catch.git diff --git a/src/alloy/frontend/ppc/ppc_translator.cc b/src/alloy/frontend/ppc/ppc_translator.cc index b89497885..008ba8948 100644 --- a/src/alloy/frontend/ppc/ppc_translator.cc +++ b/src/alloy/frontend/ppc/ppc_translator.cc @@ -10,13 +10,13 @@ #include #include -#include #include #include #include #include #include #include +#include #include #include diff --git a/src/alloy/runtime/module.h b/src/alloy/runtime/module.h index 88a1c4b94..6bd50b6f0 100644 --- a/src/alloy/runtime/module.h +++ b/src/alloy/runtime/module.h @@ -37,10 +37,10 @@ class Module { virtual bool ContainsAddress(uint64_t address); SymbolInfo* LookupSymbol(uint64_t address, bool wait = true); - SymbolInfo::Status DeclareFunction(uint64_t address, - FunctionInfo** out_symbol_info); - SymbolInfo::Status DeclareVariable(uint64_t address, - VariableInfo** out_symbol_info); + virtual SymbolInfo::Status DeclareFunction(uint64_t address, + FunctionInfo** out_symbol_info); + virtual SymbolInfo::Status DeclareVariable(uint64_t address, + VariableInfo** out_symbol_info); SymbolInfo::Status DefineFunction(FunctionInfo* symbol_info); SymbolInfo::Status DefineVariable(VariableInfo* symbol_info); diff --git a/src/alloy/runtime/sources.gypi b/src/alloy/runtime/sources.gypi index d1d7648b5..283b16c79 100644 --- a/src/alloy/runtime/sources.gypi +++ b/src/alloy/runtime/sources.gypi @@ -19,6 +19,8 @@ 'runtime.h', 'symbol_info.cc', 'symbol_info.h', + 'test_module.cc', + 'test_module.h', 'thread_state.cc', 'thread_state.h', ], diff --git a/src/alloy/runtime/test_module.cc b/src/alloy/runtime/test_module.cc new file mode 100644 index 000000000..8ed766217 --- /dev/null +++ b/src/alloy/runtime/test_module.cc @@ -0,0 +1,103 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include +#include +#include +#include +#include + +namespace alloy { +namespace runtime { + +using alloy::backend::Backend; +using alloy::compiler::Compiler; +using alloy::hir::HIRBuilder; +using alloy::runtime::Function; +using alloy::runtime::FunctionInfo; +namespace passes = alloy::compiler::passes; + +TestModule::TestModule(Runtime* runtime, const std::string& name, + std::function contains_address, + std::function generate) + : Module(runtime), + name_(name), + contains_address_(contains_address), + generate_(generate) { + builder_.reset(new HIRBuilder()); + compiler_.reset(new Compiler(runtime)); + assembler_ = std::move(runtime->backend()->CreateAssembler()); + assembler_->Initialize(); + + // Merge blocks early. This will let us use more context in other passes. + // The CFG is required for simplification and dirtied by it. + compiler_->AddPass(std::make_unique()); + compiler_->AddPass(std::make_unique()); + compiler_->AddPass(std::make_unique()); + + // Passes are executed in the order they are added. Multiple of the same + // pass type may be used. + compiler_->AddPass(std::make_unique()); + compiler_->AddPass(std::make_unique()); + compiler_->AddPass(std::make_unique()); + compiler_->AddPass(std::make_unique()); + // compiler_->AddPass(std::make_unique()); + compiler_->AddPass(std::make_unique()); + + //// Removes all unneeded variables. Try not to add new ones after this. + // compiler_->AddPass(new passes::ValueReductionPass()); + + // Register allocation for the target backend. + // Will modify the HIR to add loads/stores. + // This should be the last pass before finalization, as after this all + // registers are assigned and ready to be emitted. + compiler_->AddPass(std::make_unique( + runtime->backend()->machine_info())); + + // Must come last. The HIR is not really HIR after this. + compiler_->AddPass(std::make_unique()); +} + +TestModule::~TestModule() = default; + +bool TestModule::ContainsAddress(uint64_t address) { + return contains_address_(address); +} + +SymbolInfo::Status TestModule::DeclareFunction(uint64_t address, + FunctionInfo** out_symbol_info) { + SymbolInfo::Status status = Module::DeclareFunction(address, out_symbol_info); + if (status == SymbolInfo::STATUS_NEW) { + auto symbol_info = *out_symbol_info; + + // Reset() all caching when we leave. + make_reset_scope(compiler_); + make_reset_scope(assembler_); + + if (!generate_(*builder_.get())) { + symbol_info->set_status(SymbolInfo::STATUS_FAILED); + return SymbolInfo::STATUS_FAILED; + } + + compiler_->Compile(builder_.get()); + + Function* fn = nullptr; + assembler_->Assemble(symbol_info, builder_.get(), 0, nullptr, 0, &fn); + + symbol_info->set_function(fn); + status = SymbolInfo::STATUS_DEFINED; + symbol_info->set_status(status); + } + return status; +} + +} // namespace runtime +} // namespace alloy diff --git a/src/alloy/runtime/test_module.h b/src/alloy/runtime/test_module.h new file mode 100644 index 000000000..822509e40 --- /dev/null +++ b/src/alloy/runtime/test_module.h @@ -0,0 +1,52 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef ALLOY_RUNTIME_TEST_MODULE_H_ +#define ALLOY_RUNTIME_TEST_MODULE_H_ + +#include +#include +#include + +#include +#include +#include +#include + +namespace alloy { +namespace runtime { + +class TestModule : public Module { + public: + TestModule(Runtime* runtime, const std::string& name, + std::function contains_address, + std::function generate); + ~TestModule() override; + + const std::string& name() const override { return name_; } + + bool ContainsAddress(uint64_t address) override; + + SymbolInfo::Status DeclareFunction(uint64_t address, + FunctionInfo** out_symbol_info) override; + + private: + std::string name_; + std::function contains_address_; + std::function generate_; + + std::unique_ptr builder_; + std::unique_ptr compiler_; + std::unique_ptr assembler_; +}; + +} // namespace runtime +} // namespace alloy + +#endif // ALLOY_RUNTIME_TEST_MODULE_H_ diff --git a/third_party/catch b/third_party/catch new file mode 160000 index 000000000..85d33e2cb --- /dev/null +++ b/third_party/catch @@ -0,0 +1 @@ +Subproject commit 85d33e2cbd5354c36000424f823fc87707a24c3c diff --git a/tools/alloy-test/alloy-test.cc b/tools/alloy-test/alloy-test.cc new file mode 100644 index 000000000..da558735a --- /dev/null +++ b/tools/alloy-test/alloy-test.cc @@ -0,0 +1,47 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#define CATCH_CONFIG_RUNNER +#include + +#include + +using namespace alloy; +using namespace alloy::hir; +using namespace alloy::runtime; +using alloy::frontend::ppc::PPCContext; + +TEST_CASE("Meta test", "[test]") { + alloy::test::TestFunction test([](hir::HIRBuilder& b) { + auto r = b.Add(b.LoadContext(offsetof(PPCContext, r) + 5 * 8, INT64_TYPE), + b.LoadContext(offsetof(PPCContext, r) + 25 * 8, INT64_TYPE)); + b.StoreContext(offsetof(PPCContext, r) + 11 * 8, r); + b.Return(); + return true; + }); + + test.Run([](PPCContext* ctx) { + ctx->r[5] = 10; + ctx->r[25] = 25; + }, + [](PPCContext* ctx) { + auto result = ctx->r[11]; + REQUIRE(result == 0x23); + }); + test.Run([](PPCContext* ctx) { + ctx->r[5] = 10; + ctx->r[25] = 25; + }, + [](PPCContext* ctx) { + auto result = ctx->r[11]; + REQUIRE(result == 0x24); + }); +} + +DEFINE_ENTRY_POINT(L"alloy-test", L"?", alloy::test::main); diff --git a/tools/alloy-test/alloy-test.gypi b/tools/alloy-test/alloy-test.gypi new file mode 100644 index 000000000..36de70cd8 --- /dev/null +++ b/tools/alloy-test/alloy-test.gypi @@ -0,0 +1,29 @@ +# Copyright 2014 Ben Vanik. All Rights Reserved. +{ + 'targets': [ + { + 'target_name': 'alloy-test', + 'type': 'executable', + + 'msvs_settings': { + 'VCLinkerTool': { + 'SubSystem': '1' + }, + }, + + 'dependencies': [ + 'alloy', + 'xenia', + ], + + 'include_dirs': [ + '.', + ], + + 'sources': [ + 'alloy-test.cc', + 'test_util.h', + ], + }, + ], +} diff --git a/tools/alloy-test/test_util.h b/tools/alloy-test/test_util.h new file mode 100644 index 000000000..34f4964b4 --- /dev/null +++ b/tools/alloy-test/test_util.h @@ -0,0 +1,148 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef ALLOY_TEST_TEST_UTIL_H_ +#define ALLOY_TEST_TEST_UTIL_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace alloy { +namespace test { + +using alloy::frontend::ppc::PPCContext; +using alloy::runtime::Runtime; + +int main(std::vector& args) { + std::vector narrow_args; + auto narrow_argv = new char* [args.size()]; + for (size_t i = 0; i < args.size(); ++i) { + auto narrow_arg = poly::to_string(args[i]); + narrow_argv[i] = const_cast(narrow_arg.data()); + narrow_args.push_back(std::move(narrow_arg)); + } + return Catch::Session().run(int(args.size()), narrow_argv); +} + +class ThreadState : public alloy::runtime::ThreadState { + public: + ThreadState(Runtime* runtime, uint32_t thread_id, uint64_t stack_address, + size_t stack_size, uint64_t thread_state_address) + : alloy::runtime::ThreadState(runtime, thread_id), + stack_address_(stack_address), + stack_size_(stack_size), + thread_state_address_(thread_state_address) { + memset(memory_->Translate(stack_address_), 0, stack_size_); + + // Allocate with 64b alignment. + context_ = (PPCContext*)calloc(1, sizeof(PPCContext)); + assert_true((reinterpret_cast(context_) & 0xF) == 0); + + // Stash pointers to common structures that callbacks may need. + context_->reserve_address = memory_->reserve_address(); + context_->membase = memory_->membase(); + context_->runtime = runtime; + context_->thread_state = this; + + // Set initial registers. + context_->r[1] = stack_address_ + stack_size; + context_->r[13] = thread_state_address_; + + // Pad out stack a bit, as some games seem to overwrite the caller by about + // 16 to 32b. + context_->r[1] -= 64; + + raw_context_ = context_; + + runtime_->debugger()->OnThreadCreated(this); + } + ~ThreadState() override { + runtime_->debugger()->OnThreadDestroyed(this); + free(context_); + } + + PPCContext* context() const { return context_; } + + private: + uint64_t stack_address_; + size_t stack_size_; + uint64_t thread_state_address_; + + // NOTE: must be 64b aligned for SSE ops. + PPCContext* context_; +}; + +class TestFunction { + public: + TestFunction(std::function generator) { + memory_size = 16 * 1024 * 1024; + memory.reset(new SimpleMemory(memory_size)); + runtime.reset(new Runtime(memory.get())); + + auto frontend = + std::make_unique(runtime.get()); + std::unique_ptr backend; + // backend = + // std::make_unique(runtime.get()); + // backend = + // std::make_unique(runtime.get()); + runtime->Initialize(std::move(frontend), std::move(backend)); + + auto module = std::make_unique( + runtime.get(), "Test", + [](uint64_t address) { return address == 0x1000; }, + [generator](hir::HIRBuilder& b) { return generator(b); }); + runtime->AddModule(std::move(module)); + + runtime->ResolveFunction(0x1000, &fn); + } + + ~TestFunction() { + runtime.reset(); + memory.reset(); + } + + void Run(std::function pre_call, + std::function post_call) { + memory->Zero(0, memory_size); + + uint64_t stack_size = 64 * 1024; + uint64_t stack_address = memory_size - stack_size; + uint64_t thread_state_address = stack_address - 0x1000; + auto thread_state = std::make_unique( + runtime.get(), 100, stack_address, stack_size, thread_state_address); + auto ctx = thread_state->context(); + ctx->lr = 0xBEBEBEBE; + + pre_call(ctx); + + fn->Call(thread_state.get(), ctx->lr); + + post_call(ctx); + } + + size_t memory_size; + std::unique_ptr memory; + std::unique_ptr runtime; + alloy::runtime::Function* fn; +}; + +} // namespace test +} // namespace alloy + +#endif // ALLOY_TEST_TEST_UTIL_H_ diff --git a/tools/tools.gypi b/tools/tools.gypi index 3e6a56ffd..26b5fba73 100644 --- a/tools/tools.gypi +++ b/tools/tools.gypi @@ -2,6 +2,7 @@ { 'includes': [ 'alloy-sandbox/alloy-sandbox.gypi', + 'alloy-test/alloy-test.gypi', 'xenia-compare/xenia-compare.gypi', 'xenia-debug/xenia-debug.gypi', 'xenia-run/xenia-run.gypi', From 7ebba018ada2c0239c8a6d421da3569c355beea8 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 23 Aug 2014 15:46:01 -0700 Subject: [PATCH 165/388] Run tests on both IVM and x64. --- tools/alloy-test/alloy-test.cc | 28 +++++++----- tools/alloy-test/test_util.h | 81 ++++++++++++++++++++-------------- 2 files changed, 66 insertions(+), 43 deletions(-) diff --git a/tools/alloy-test/alloy-test.cc b/tools/alloy-test/alloy-test.cc index da558735a..295f8a1bf 100644 --- a/tools/alloy-test/alloy-test.cc +++ b/tools/alloy-test/alloy-test.cc @@ -17,29 +17,35 @@ using namespace alloy::hir; using namespace alloy::runtime; using alloy::frontend::ppc::PPCContext; -TEST_CASE("Meta test", "[test]") { +Value* LoadGPR(hir::HIRBuilder& b, int reg) { + return b.LoadContext(offsetof(PPCContext, r) + reg * 8, INT64_TYPE); +} + +void StoreGPR(hir::HIRBuilder& b, int reg, Value* value) { + b.StoreContext(offsetof(PPCContext, r) + reg * 8, value); +} + +TEST_CASE("ADD", "[instr]") { alloy::test::TestFunction test([](hir::HIRBuilder& b) { - auto r = b.Add(b.LoadContext(offsetof(PPCContext, r) + 5 * 8, INT64_TYPE), - b.LoadContext(offsetof(PPCContext, r) + 25 * 8, INT64_TYPE)); - b.StoreContext(offsetof(PPCContext, r) + 11 * 8, r); + auto v = b.Add(LoadGPR(b, 4), LoadGPR(b, 5)); + StoreGPR(b, 3, v); b.Return(); - return true; }); test.Run([](PPCContext* ctx) { - ctx->r[5] = 10; - ctx->r[25] = 25; + ctx->r[4] = 10; + ctx->r[5] = 25; }, [](PPCContext* ctx) { - auto result = ctx->r[11]; + auto result = ctx->r[3]; REQUIRE(result == 0x23); }); test.Run([](PPCContext* ctx) { - ctx->r[5] = 10; - ctx->r[25] = 25; + ctx->r[4] = 10; + ctx->r[5] = 25; }, [](PPCContext* ctx) { - auto result = ctx->r[11]; + auto result = ctx->r[3]; REQUIRE(result == 0x24); }); } diff --git a/tools/alloy-test/test_util.h b/tools/alloy-test/test_util.h index 34f4964b4..c2406a925 100644 --- a/tools/alloy-test/test_util.h +++ b/tools/alloy-test/test_util.h @@ -36,7 +36,8 @@ int main(std::vector& args) { narrow_argv[i] = const_cast(narrow_arg.data()); narrow_args.push_back(std::move(narrow_arg)); } - return Catch::Session().run(int(args.size()), narrow_argv); + int ret = Catch::Session().run(int(args.size()), narrow_argv); + return ret; } class ThreadState : public alloy::runtime::ThreadState { @@ -89,57 +90,73 @@ class ThreadState : public alloy::runtime::ThreadState { class TestFunction { public: - TestFunction(std::function generator) { + TestFunction(std::function generator) { memory_size = 16 * 1024 * 1024; memory.reset(new SimpleMemory(memory_size)); - runtime.reset(new Runtime(memory.get())); - auto frontend = - std::make_unique(runtime.get()); - std::unique_ptr backend; - // backend = - // std::make_unique(runtime.get()); - // backend = - // std::make_unique(runtime.get()); - runtime->Initialize(std::move(frontend), std::move(backend)); + { + auto runtime = std::make_unique(memory.get()); + auto frontend = + std::make_unique(runtime.get()); + auto backend = + std::make_unique(runtime.get()); + runtime->Initialize(std::move(frontend), std::move(backend)); + runtimes.emplace_back(std::move(runtime)); + } + { + auto runtime = std::make_unique(memory.get()); + auto frontend = + std::make_unique(runtime.get()); + auto backend = + std::make_unique(runtime.get()); + runtime->Initialize(std::move(frontend), std::move(backend)); + runtimes.emplace_back(std::move(runtime)); + } - auto module = std::make_unique( - runtime.get(), "Test", - [](uint64_t address) { return address == 0x1000; }, - [generator](hir::HIRBuilder& b) { return generator(b); }); - runtime->AddModule(std::move(module)); - - runtime->ResolveFunction(0x1000, &fn); + for (auto& runtime : runtimes) { + auto module = std::make_unique( + runtime.get(), "Test", + [](uint64_t address) { return address == 0x1000; }, + [generator](hir::HIRBuilder& b) { + generator(b); + return true; + }); + runtime->AddModule(std::move(module)); + } } ~TestFunction() { - runtime.reset(); + runtimes.clear(); memory.reset(); } void Run(std::function pre_call, std::function post_call) { - memory->Zero(0, memory_size); + for (auto& runtime : runtimes) { + memory->Zero(0, memory_size); - uint64_t stack_size = 64 * 1024; - uint64_t stack_address = memory_size - stack_size; - uint64_t thread_state_address = stack_address - 0x1000; - auto thread_state = std::make_unique( - runtime.get(), 100, stack_address, stack_size, thread_state_address); - auto ctx = thread_state->context(); - ctx->lr = 0xBEBEBEBE; + alloy::runtime::Function* fn; + runtime->ResolveFunction(0x1000, &fn); - pre_call(ctx); + uint64_t stack_size = 64 * 1024; + uint64_t stack_address = memory_size - stack_size; + uint64_t thread_state_address = stack_address - 0x1000; + auto thread_state = std::make_unique( + runtime.get(), 100, stack_address, stack_size, thread_state_address); + auto ctx = thread_state->context(); + ctx->lr = 0xBEBEBEBE; - fn->Call(thread_state.get(), ctx->lr); + pre_call(ctx); - post_call(ctx); + fn->Call(thread_state.get(), ctx->lr); + + post_call(ctx); + } } size_t memory_size; std::unique_ptr memory; - std::unique_ptr runtime; - alloy::runtime::Function* fn; + std::vector> runtimes; }; } // namespace test From 423790209b25c47f4b12a0ff618b527ce17070fc Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 23 Aug 2014 16:32:40 -0700 Subject: [PATCH 166/388] Removing implicit vector add/sub. --- src/alloy/backend/ivm/ivm_intcode.cc | 23 ++-------------------- src/alloy/backend/x64/x64_sequences.cc | 23 ++-------------------- src/alloy/frontend/ppc/ppc_emit_altivec.cc | 4 ++-- 3 files changed, 6 insertions(+), 44 deletions(-) diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index 8533eda15..2327458f3 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -2475,21 +2475,11 @@ uint32_t IntCode_ADD_F64_F64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].f64 = ics.rf[i->src1_reg].f64 + ics.rf[i->src2_reg].f64; return IA_NEXT; } -uint32_t IntCode_ADD_V128_V128(IntCodeState& ics, const IntCode* i) { - assert_true(!i->flags); - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.f4[n] = src1.f4[n] + src2.f4[n]; - } - return IA_NEXT; -} int Translate_ADD(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { IntCode_ADD_I8_I8, IntCode_ADD_I16_I16, IntCode_ADD_I32_I32, IntCode_ADD_I64_I64, IntCode_ADD_F32_F32, IntCode_ADD_F64_F64, - IntCode_ADD_V128_V128, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->dest->type]); } @@ -2736,20 +2726,11 @@ uint32_t IntCode_SUB_F64_F64(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].f64 = ics.rf[i->src1_reg].f64 - ics.rf[i->src2_reg].f64; return IA_NEXT; } -uint32_t IntCode_SUB_V128_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.f4[n] = src1.f4[n] - src2.f4[n]; - } - return IA_NEXT; -} int Translate_SUB(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { IntCode_SUB_I8_I8, IntCode_SUB_I16_I16, IntCode_SUB_I32_I32, IntCode_SUB_I64_I64, IntCode_SUB_F32_F32, IntCode_SUB_F64_F64, - IntCode_SUB_V128_V128, + IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->dest->type]); } diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index a6fbd75af..a97c58782 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -2590,14 +2590,6 @@ EMITTER(ADD_F64, MATCH(I, F64<>, F64<>>)) { }); } }; -EMITTER(ADD_V128, MATCH(I, V128<>, V128<>>)) { - static void Emit(X64Emitter& e, const EmitArgType& i) { - EmitCommutativeBinaryXmmOp(e, i, - [](X64Emitter& e, Xmm dest, Xmm src1, Xmm src2) { - e.vaddps(dest, src1, src2); - }); - } -}; EMITTER_OPCODE_TABLE( OPCODE_ADD, ADD_I8, @@ -2605,8 +2597,7 @@ EMITTER_OPCODE_TABLE( ADD_I32, ADD_I64, ADD_F32, - ADD_F64, - ADD_V128); + ADD_F64); // ============================================================================ @@ -2847,15 +2838,6 @@ EMITTER(SUB_F64, MATCH(I, F64<>, F64<>>)) { }); } }; -EMITTER(SUB_V128, MATCH(I, V128<>, V128<>>)) { - static void Emit(X64Emitter& e, const EmitArgType& i) { - assert_true(!i.instr->flags); - EmitAssociativeBinaryXmmOp(e, i, - [](X64Emitter& e, Xmm dest, Xmm src1, Xmm src2) { - e.vsubps(dest, src1, src2); - }); - } -}; EMITTER_OPCODE_TABLE( OPCODE_SUB, SUB_I8, @@ -2863,8 +2845,7 @@ EMITTER_OPCODE_TABLE( SUB_I32, SUB_I64, SUB_F32, - SUB_F64, - SUB_V128); + SUB_F64); // ============================================================================ diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index a75c20026..b99c003b8 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -344,7 +344,7 @@ XEEMITTER(vaddcuw, 0x10000180, VX)(PPCHIRBuilder& f, InstrData& i) { int InstrEmit_vaddfp_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { // (VD) <- (VA) + (VB) (4 x fp) - Value* v = f.Add(f.LoadVR(va), f.LoadVR(vb)); + Value* v = f.VectorAdd(f.LoadVR(va), f.LoadVR(vb), FLOAT32_TYPE); f.StoreVR(vd, v); return 0; } @@ -1568,7 +1568,7 @@ XEEMITTER(vsubcuw, 0x10000580, VX)(PPCHIRBuilder& f, InstrData& i) { int InstrEmit_vsubfp_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { // (VD) <- (VA) - (VB) (4 x fp) - Value* v = f.Sub(f.LoadVR(va), f.LoadVR(vb)); + Value* v = f.VectorSub(f.LoadVR(va), f.LoadVR(vb), FLOAT32_TYPE); f.StoreVR(vd, v); return 0; } From 96007049d29ba3d93564b71aa7a113c5036a4913 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 23 Aug 2014 17:09:19 -0700 Subject: [PATCH 167/388] Starting tests. This is going to take some time. --- src/alloy/vec128.h | 28 ++ tools/alloy-test/alloy-test.cc | 56 +-- tools/alloy-test/alloy-test.gypi | 4 +- tools/alloy-test/test_add.cc | 550 +++++++++++++++++++++++ tools/alloy-test/{test_util.h => util.h} | 39 +- 5 files changed, 627 insertions(+), 50 deletions(-) create mode 100644 tools/alloy-test/test_add.cc rename tools/alloy-test/{test_util.h => util.h} (84%) diff --git a/src/alloy/vec128.h b/src/alloy/vec128.h index c5b7bc81f..a77a5aa79 100644 --- a/src/alloy/vec128.h +++ b/src/alloy/vec128.h @@ -58,6 +58,34 @@ static inline vec128_t vec128f(float x, float y, float z, float w) { v.f4[3] = w; return v; } +static inline vec128_t vec128s(uint16_t src) { + vec128_t v; + for (auto i = 0; i < 8; ++i) { + v.s8[i] = src; + } + return v; +} +static inline vec128_t vec128s(uint16_t x0, uint16_t x1, uint16_t y0, + uint16_t y1, uint16_t z0, uint16_t z1, + uint16_t w0, uint16_t w1) { + vec128_t v; + v.s8[0] = x0; + v.s8[1] = x1; + v.s8[2] = y0; + v.s8[3] = y1; + v.s8[4] = z0; + v.s8[5] = z1; + v.s8[6] = w0; + v.s8[7] = w1; + return v; +} +static inline vec128_t vec128b(uint8_t src) { + vec128_t v; + for (auto i = 0; i < 16; ++i) { + v.b16[i] = src; + } + return v; +} static inline vec128_t vec128b(uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t y0, uint8_t y1, uint8_t y2, uint8_t y3, uint8_t z0, uint8_t z1, uint8_t z2, uint8_t z3, diff --git a/tools/alloy-test/alloy-test.cc b/tools/alloy-test/alloy-test.cc index 295f8a1bf..4c530cf16 100644 --- a/tools/alloy-test/alloy-test.cc +++ b/tools/alloy-test/alloy-test.cc @@ -10,44 +10,32 @@ #define CATCH_CONFIG_RUNNER #include -#include +#include + +namespace alloy { +namespace test { -using namespace alloy; -using namespace alloy::hir; -using namespace alloy::runtime; using alloy::frontend::ppc::PPCContext; +using alloy::runtime::Runtime; -Value* LoadGPR(hir::HIRBuilder& b, int reg) { - return b.LoadContext(offsetof(PPCContext, r) + reg * 8, INT64_TYPE); +int main(std::vector& args) { + std::vector narrow_args; + auto narrow_argv = new char* [args.size()]; + for (size_t i = 0; i < args.size(); ++i) { + auto narrow_arg = poly::to_string(args[i]); + narrow_argv[i] = const_cast(narrow_arg.data()); + narrow_args.push_back(std::move(narrow_arg)); + } + int ret = Catch::Session().run(int(args.size()), narrow_argv); + if (ret) { + if (poly::debugging::IsDebuggerAttached()) { + poly::debugging::Break(); + } + } + return ret; } -void StoreGPR(hir::HIRBuilder& b, int reg, Value* value) { - b.StoreContext(offsetof(PPCContext, r) + reg * 8, value); -} - -TEST_CASE("ADD", "[instr]") { - alloy::test::TestFunction test([](hir::HIRBuilder& b) { - auto v = b.Add(LoadGPR(b, 4), LoadGPR(b, 5)); - StoreGPR(b, 3, v); - b.Return(); - }); - - test.Run([](PPCContext* ctx) { - ctx->r[4] = 10; - ctx->r[5] = 25; - }, - [](PPCContext* ctx) { - auto result = ctx->r[3]; - REQUIRE(result == 0x23); - }); - test.Run([](PPCContext* ctx) { - ctx->r[4] = 10; - ctx->r[5] = 25; - }, - [](PPCContext* ctx) { - auto result = ctx->r[3]; - REQUIRE(result == 0x24); - }); -} +} // namespace test +} // namespace alloy DEFINE_ENTRY_POINT(L"alloy-test", L"?", alloy::test::main); diff --git a/tools/alloy-test/alloy-test.gypi b/tools/alloy-test/alloy-test.gypi index 36de70cd8..122f5b430 100644 --- a/tools/alloy-test/alloy-test.gypi +++ b/tools/alloy-test/alloy-test.gypi @@ -22,7 +22,9 @@ 'sources': [ 'alloy-test.cc', - 'test_util.h', + 'test_add.cc', + 'test_vector_add.cc', + 'util.h', ], }, ], diff --git a/tools/alloy-test/test_add.cc b/tools/alloy-test/test_add.cc new file mode 100644 index 000000000..6805cbfc6 --- /dev/null +++ b/tools/alloy-test/test_add.cc @@ -0,0 +1,550 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +using namespace alloy; +using namespace alloy::hir; +using namespace alloy::runtime; +using namespace alloy::test; +using alloy::frontend::ppc::PPCContext; + +TEST_CASE("ADD_I8", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreGPR(b, 3, b.ZeroExtend(b.Add(b.Truncate(LoadGPR(b, 4), INT8_TYPE), + b.Truncate(LoadGPR(b, 5), INT8_TYPE)), + INT64_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 10; + ctx->r[5] = 25; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x23); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = -10; + ctx->r[5] = -5; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == -15); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = INT8_MIN; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == INT8_MIN); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = UINT8_MAX; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == UINT8_MAX); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = INT8_MIN; + ctx->r[5] = -1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == INT8_MAX); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = UINT8_MAX; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); +} + +TEST_CASE("ADD_I8_CARRY", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + auto v = b.Add(b.Truncate(LoadGPR(b, 4), INT8_TYPE), + b.Truncate(LoadGPR(b, 5), INT8_TYPE), ARITHMETIC_SET_CARRY); + StoreGPR(b, 3, b.ZeroExtend(b.DidCarry(v), INT64_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == 0); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = UINT8_MAX; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == 1); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = UINT8_MAX; + ctx->r[5] = UINT8_MAX; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == 1); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = INT8_MIN; + ctx->r[5] = -1; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == 1); + }); +} + +TEST_CASE("ADD_I16", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreGPR(b, 3, b.ZeroExtend(b.Add(b.Truncate(LoadGPR(b, 4), INT16_TYPE), + b.Truncate(LoadGPR(b, 5), INT16_TYPE)), + INT64_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 10; + ctx->r[5] = 25; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x23); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = -10; + ctx->r[5] = -5; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == -15); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = INT16_MIN; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == INT16_MIN); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = UINT16_MAX; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == UINT16_MAX); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = INT16_MIN; + ctx->r[5] = -1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == INT16_MAX); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = UINT16_MAX; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); +} + +TEST_CASE("ADD_I16_CARRY", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + auto v = b.Add(b.Truncate(LoadGPR(b, 4), INT16_TYPE), + b.Truncate(LoadGPR(b, 5), INT16_TYPE), ARITHMETIC_SET_CARRY); + StoreGPR(b, 3, b.ZeroExtend(b.DidCarry(v), INT64_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == 0); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = UINT16_MAX; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == 1); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = UINT16_MAX; + ctx->r[5] = UINT16_MAX; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == 1); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = INT16_MIN; + ctx->r[5] = -1; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == 1); + }); +} + +TEST_CASE("ADD_I32", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreGPR(b, 3, b.ZeroExtend(b.Add(b.Truncate(LoadGPR(b, 4), INT32_TYPE), + b.Truncate(LoadGPR(b, 5), INT32_TYPE)), + INT64_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 10; + ctx->r[5] = 25; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x23); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = -10; + ctx->r[5] = -5; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == -15); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = INT32_MIN; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == INT32_MIN); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = UINT32_MAX; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == UINT32_MAX); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = INT32_MIN; + ctx->r[5] = -1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == INT32_MAX); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = UINT32_MAX; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); +} + +TEST_CASE("ADD_I32_CARRY", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + auto v = b.Add(b.Truncate(LoadGPR(b, 4), INT32_TYPE), + b.Truncate(LoadGPR(b, 5), INT32_TYPE), ARITHMETIC_SET_CARRY); + StoreGPR(b, 3, b.ZeroExtend(b.DidCarry(v), INT64_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == 0); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = UINT32_MAX; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == 1); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = UINT32_MAX; + ctx->r[5] = UINT32_MAX; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == 1); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = INT32_MIN; + ctx->r[5] = -1; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == 1); + }); +} + +TEST_CASE("ADD_I64", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreGPR(b, 3, b.Add(LoadGPR(b, 4), LoadGPR(b, 5))); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == 0); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 10; + ctx->r[5] = 25; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == 0x23); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = -10; + ctx->r[5] = -5; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == -15); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = INT64_MIN; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == INT64_MIN); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = UINT64_MAX; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == UINT64_MAX); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = INT64_MIN; + ctx->r[5] = -1; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == INT64_MAX); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = UINT64_MAX; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == 0); + }); +} + +TEST_CASE("ADD_I64_CARRY", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + auto v = b.Add(b.Truncate(LoadGPR(b, 4), INT64_TYPE), + b.Truncate(LoadGPR(b, 5), INT64_TYPE), ARITHMETIC_SET_CARRY); + StoreGPR(b, 3, b.ZeroExtend(b.DidCarry(v), INT64_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == 0); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = UINT64_MAX; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == 1); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = UINT64_MAX; + ctx->r[5] = UINT64_MAX; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == 1); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = INT64_MIN; + ctx->r[5] = -1; + }, + [](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == 1); + }); +} + +TEST_CASE("ADD_F32", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreFPR(b, 3, b.Convert(b.Add(b.Convert(LoadFPR(b, 4), FLOAT32_TYPE), + b.Convert(LoadFPR(b, 5), FLOAT32_TYPE)), + FLOAT64_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->f[4] = 0.0; + ctx->f[5] = 0.0; + }, + [](PPCContext* ctx) { + auto result = ctx->f[3]; + REQUIRE(result == 0.0); + }); + test.Run([](PPCContext* ctx) { + ctx->f[4] = 5.0; + ctx->f[5] = 7.0; + }, + [](PPCContext* ctx) { + auto result = ctx->f[3]; + REQUIRE(result == 12.0); + }); + test.Run([](PPCContext* ctx) { + ctx->f[4] = FLT_MAX / 2.0; + ctx->f[5] = FLT_MAX / 2.0; + }, + [](PPCContext* ctx) { + auto result = ctx->f[3]; + REQUIRE(result == FLT_MAX); + }); + test.Run([](PPCContext* ctx) { + ctx->f[4] = -100.0; + ctx->f[5] = -150.0; + }, + [](PPCContext* ctx) { + auto result = ctx->f[3]; + REQUIRE(result == -250.0); + }); + test.Run([](PPCContext* ctx) { + ctx->f[4] = FLT_MIN; + ctx->f[5] = 0.0; + }, + [](PPCContext* ctx) { + auto result = ctx->f[3]; + REQUIRE(result == FLT_MIN); + }); + test.Run([](PPCContext* ctx) { + ctx->f[4] = FLT_MAX; + ctx->f[5] = 0.0; + }, + [](PPCContext* ctx) { + auto result = ctx->f[3]; + REQUIRE(result == FLT_MAX); + }); +} + +TEST_CASE("ADD_F64", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreFPR(b, 3, b.Add(LoadFPR(b, 4), LoadFPR(b, 5))); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->f[4] = 0.0; + ctx->f[5] = 0.0; + }, + [](PPCContext* ctx) { + auto result = ctx->f[3]; + REQUIRE(result == 0.0); + }); + test.Run([](PPCContext* ctx) { + ctx->f[4] = 5.0; + ctx->f[5] = 7.0; + }, + [](PPCContext* ctx) { + auto result = ctx->f[3]; + REQUIRE(result == 12.0); + }); + test.Run([](PPCContext* ctx) { + ctx->f[4] = DBL_MAX / 2.0; + ctx->f[5] = DBL_MAX / 2.0; + }, + [](PPCContext* ctx) { + auto result = ctx->f[3]; + REQUIRE(result == DBL_MAX); + }); + test.Run([](PPCContext* ctx) { + ctx->f[4] = -100.0; + ctx->f[5] = -150.0; + }, + [](PPCContext* ctx) { + auto result = ctx->f[3]; + REQUIRE(result == -250.0); + }); + test.Run([](PPCContext* ctx) { + ctx->f[4] = DBL_MIN; + ctx->f[5] = 0.0; + }, + [](PPCContext* ctx) { + auto result = ctx->f[3]; + REQUIRE(result == DBL_MIN); + }); + test.Run([](PPCContext* ctx) { + ctx->f[4] = DBL_MAX; + ctx->f[5] = 0.0; + }, + [](PPCContext* ctx) { + auto result = ctx->f[3]; + REQUIRE(result == DBL_MAX); + }); +} diff --git a/tools/alloy-test/test_util.h b/tools/alloy-test/util.h similarity index 84% rename from tools/alloy-test/test_util.h rename to tools/alloy-test/util.h index c2406a925..175140f37 100644 --- a/tools/alloy-test/test_util.h +++ b/tools/alloy-test/util.h @@ -7,8 +7,8 @@ ****************************************************************************** */ -#ifndef ALLOY_TEST_TEST_UTIL_H_ -#define ALLOY_TEST_TEST_UTIL_H_ +#ifndef ALLOY_TEST_UTIL_H_ +#define ALLOY_TEST_UTIL_H_ #include #include @@ -28,18 +28,6 @@ namespace test { using alloy::frontend::ppc::PPCContext; using alloy::runtime::Runtime; -int main(std::vector& args) { - std::vector narrow_args; - auto narrow_argv = new char* [args.size()]; - for (size_t i = 0; i < args.size(); ++i) { - auto narrow_arg = poly::to_string(args[i]); - narrow_argv[i] = const_cast(narrow_arg.data()); - narrow_args.push_back(std::move(narrow_arg)); - } - int ret = Catch::Session().run(int(args.size()), narrow_argv); - return ret; -} - class ThreadState : public alloy::runtime::ThreadState { public: ThreadState(Runtime* runtime, uint32_t thread_id, uint64_t stack_address, @@ -159,7 +147,28 @@ class TestFunction { std::vector> runtimes; }; +inline hir::Value* LoadGPR(hir::HIRBuilder& b, int reg) { + return b.LoadContext(offsetof(PPCContext, r) + reg * 8, hir::INT64_TYPE); +} +inline void StoreGPR(hir::HIRBuilder& b, int reg, hir::Value* value) { + b.StoreContext(offsetof(PPCContext, r) + reg * 8, value); +} + +inline hir::Value* LoadFPR(hir::HIRBuilder& b, int reg) { + return b.LoadContext(offsetof(PPCContext, f) + reg * 8, hir::FLOAT64_TYPE); +} +inline void StoreFPR(hir::HIRBuilder& b, int reg, hir::Value* value) { + b.StoreContext(offsetof(PPCContext, f) + reg * 8, value); +} + +inline hir::Value* LoadVR(hir::HIRBuilder& b, int reg) { + return b.LoadContext(offsetof(PPCContext, v) + reg * 16, hir::VEC128_TYPE); +} +inline void StoreVR(hir::HIRBuilder& b, int reg, hir::Value* value) { + b.StoreContext(offsetof(PPCContext, v) + reg * 16, value); +} + } // namespace test } // namespace alloy -#endif // ALLOY_TEST_TEST_UTIL_H_ +#endif // ALLOY_TEST_UTIL_H_ From 28bae464c27469daa43d16f1e0ef4fca06287dfa Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 23 Aug 2014 22:09:30 -0700 Subject: [PATCH 168/388] Adding vector add tests and fixing bugs found (still broken). --- src/alloy/backend/ivm/ivm_intcode.cc | 4 +- src/alloy/backend/x64/x64_sequences.cc | 2 +- src/alloy/vec128.h | 14 ++ tools/alloy-test/test_vector_add.cc | 280 +++++++++++++++++++++++++ 4 files changed, 297 insertions(+), 3 deletions(-) create mode 100644 tools/alloy-test/test_vector_add.cc diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index 2327458f3..09da2add0 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -2630,7 +2630,7 @@ uint32_t Translate_VECTOR_ADD_I32(IntCodeState& ics, const IntCode* i) { if (arithmetic_flags & ARITHMETIC_SATURATE) { if (arithmetic_flags & ARITHMETIC_UNSIGNED) { for (int n = 0; n < 4; n++) { - uint64_t v = VECI4(src1, n) + VECI4(src2, n); + uint64_t v = (uint64_t)VECI4(src1, n) + (uint64_t)VECI4(src2, n); if (v > 0xFFFFFFFF) { VECI4(dest, n) = 0xFFFFFFFF; ics.did_saturate = 1; @@ -2640,7 +2640,7 @@ uint32_t Translate_VECTOR_ADD_I32(IntCodeState& ics, const IntCode* i) { } } else { for (int n = 0; n < 4; n++) { - int64_t v = (int32_t)VECI4(src1, n) + (int32_t)VECI4(src2, n); + int64_t v = (int64_t)(int32_t)VECI4(src1, n) + (int64_t)(int32_t)VECI4(src2, n); if (v > 0x7FFFFFFF) { VECI4(dest, n) = 0x7FFFFFFF; ics.did_saturate = 1; diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index a97c58782..2edda3870 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -2749,7 +2749,7 @@ EMITTER(VECTOR_ADD, MATCH(I, V128<>, V128<>>)) { e.vblendvps(e.xmm2, e.xmm0, e.GetXmmConstPtr(XMMSignMaskPS), e.xmm2); e.vpor(e.xmm1, src1, src2); // sign_or e.vpandn(e.xmm1, e.xmm0); // max_sat_mask - e.vblendvps(e.xmm2, e.GetXmmConstPtr(XMMAbsMaskPS), e.xmm1); + e.vblendvps(dest, e.GetXmmConstPtr(XMMAbsMaskPS), e.xmm1); } } else { e.vpaddd(dest, src1, src2); diff --git a/src/alloy/vec128.h b/src/alloy/vec128.h index a77a5aa79..9a7b8f728 100644 --- a/src/alloy/vec128.h +++ b/src/alloy/vec128.h @@ -42,6 +42,13 @@ typedef struct alignas(16) vec128_s { return low == b.low && high == b.high; } } vec128_t; +static inline vec128_t vec128i(uint32_t src) { + vec128_t v; + for (auto i = 0; i < 4; ++i) { + v.i4[i] = src; + } + return v; +} static inline vec128_t vec128i(uint32_t x, uint32_t y, uint32_t z, uint32_t w) { vec128_t v; v.i4[0] = x; @@ -50,6 +57,13 @@ static inline vec128_t vec128i(uint32_t x, uint32_t y, uint32_t z, uint32_t w) { v.i4[3] = w; return v; } +static inline vec128_t vec128f(float src) { + vec128_t v; + for (auto i = 0; i < 4; ++i) { + v.f4[i] = src; + } + return v; +} static inline vec128_t vec128f(float x, float y, float z, float w) { vec128_t v; v.f4[0] = x; diff --git a/tools/alloy-test/test_vector_add.cc b/tools/alloy-test/test_vector_add.cc new file mode 100644 index 000000000..08a60715d --- /dev/null +++ b/tools/alloy-test/test_vector_add.cc @@ -0,0 +1,280 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +using namespace alloy; +using namespace alloy::hir; +using namespace alloy::runtime; +using namespace alloy::test; +using alloy::frontend::ppc::PPCContext; + +TEST_CASE("VECTOR_ADD_I8", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorAdd(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + ctx->v[5] = vec128b(100, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(100, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, + 22, 24, 26, 28, 30)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128b(UINT8_MAX); + ctx->v[5] = vec128b(1); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(0)); + }); +} + +TEST_CASE("VECTOR_ADD_I8_SAT_SIGNED", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorAdd(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE, + ARITHMETIC_SATURATE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128b(INT8_MAX); + ctx->v[5] = vec128b(1); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(INT8_MAX)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128b(INT8_MIN); + ctx->v[5] = vec128b(-1); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(INT8_MIN)); + }); +} + +TEST_CASE("VECTOR_ADD_I8_SAT_UNSIGNED", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorAdd(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE, + ARITHMETIC_SATURATE | ARITHMETIC_UNSIGNED)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128b(UINT8_MAX); + ctx->v[5] = vec128b(1); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(UINT8_MAX)); + }); +} + +TEST_CASE("VECTOR_ADD_I16", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorAdd(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128s(0, 1, 2, 3, 4, 5, 6, 7); + ctx->v[5] = vec128s(100, 1, 2, 3, 4, 5, 6, 7); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128s(100, 2, 4, 6, 8, 10, 12, 14)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128s(UINT16_MAX); + ctx->v[5] = vec128s(1); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128s(0)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128s(0); + ctx->v[5] = vec128s(-1); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128s(UINT16_MAX)); + }); +} + +TEST_CASE("VECTOR_ADD_I16_SAT_SIGNED", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorAdd(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE, + ARITHMETIC_SATURATE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128s(INT16_MAX); + ctx->v[5] = vec128s(1); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128s(INT16_MAX)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128s(INT16_MIN); + ctx->v[5] = vec128s(-1); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128s(INT16_MIN)); + }); +} + +TEST_CASE("VECTOR_ADD_I16_SAT_UNSIGNED", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorAdd(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE, + ARITHMETIC_SATURATE | ARITHMETIC_UNSIGNED)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128s(UINT16_MAX); + ctx->v[5] = vec128s(1); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128s(UINT16_MAX)); + }); +} + +TEST_CASE("VECTOR_ADD_I32", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorAdd(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128i(0, 1, 2, 3); + ctx->v[5] = vec128i(100, 1, 2, 3); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(100, 2, 4, 6)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128i(UINT32_MAX); + ctx->v[5] = vec128i(1); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(0)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128i(0); + ctx->v[5] = vec128i(-1); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(UINT32_MAX)); + }); +} + +TEST_CASE("VECTOR_ADD_I32_SAT_SIGNED", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorAdd(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE, + ARITHMETIC_SATURATE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128i(5); + ctx->v[5] = vec128i(5); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(10)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128i(INT32_MAX); + ctx->v[5] = vec128i(1); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(INT32_MAX)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128i(INT32_MIN); + ctx->v[5] = vec128i(-1); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(INT32_MIN)); + }); +} + +TEST_CASE("VECTOR_ADD_I32_SAT_UNSIGNED", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorAdd(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE, + ARITHMETIC_SATURATE | ARITHMETIC_UNSIGNED)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128i(5); + ctx->v[5] = vec128i(5); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(10)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128i(UINT32_MAX); + ctx->v[5] = vec128i(1); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(UINT32_MAX)); + }); +} + +TEST_CASE("VECTOR_ADD_F32", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorAdd(LoadVR(b, 4), LoadVR(b, 5), FLOAT32_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128f(0.12f, 0.34f, 0.56f, 0.78f); + ctx->v[5] = vec128f(0.12f, 0.34f, 0.56f, 0.78f); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == + vec128i(0x3E75C28F, 0x3F2E147B, 0x3F8F5C29, 0x3FC7AE14)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128f(FLT_MAX); + ctx->v[5] = vec128f(FLT_MAX); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(0x7F800000)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128f(FLT_MIN); + ctx->v[5] = vec128f(-1.0f); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(0xBF800000)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128f(FLT_MAX); + ctx->v[5] = vec128f(1.0f); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(0x7F7FFFFF)); + }); +} From d242e37d84572aa1fddc9017c205cafa99e3f2e8 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 23 Aug 2014 22:35:08 -0700 Subject: [PATCH 169/388] Running (IVM) tests on osx. --- tools/alloy-test/test_add.cc | 2 ++ tools/alloy-test/test_vector_add.cc | 4 +++- tools/alloy-test/util.h | 7 +++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/tools/alloy-test/test_add.cc b/tools/alloy-test/test_add.cc index 6805cbfc6..3a6f6146a 100644 --- a/tools/alloy-test/test_add.cc +++ b/tools/alloy-test/test_add.cc @@ -9,6 +9,8 @@ #include +#include + using namespace alloy; using namespace alloy::hir; using namespace alloy::runtime; diff --git a/tools/alloy-test/test_vector_add.cc b/tools/alloy-test/test_vector_add.cc index 08a60715d..ed236743a 100644 --- a/tools/alloy-test/test_vector_add.cc +++ b/tools/alloy-test/test_vector_add.cc @@ -9,6 +9,8 @@ #include +#include + using namespace alloy; using namespace alloy::hir; using namespace alloy::runtime; @@ -262,7 +264,7 @@ TEST_CASE("VECTOR_ADD_F32", "[instr]") { REQUIRE(result == vec128i(0x7F800000)); }); test.Run([](PPCContext* ctx) { - ctx->v[4] = vec128f(FLT_MIN); + ctx->v[4] = vec128f(-FLT_MIN); ctx->v[5] = vec128f(-1.0f); }, [](PPCContext* ctx) { diff --git a/tools/alloy-test/util.h b/tools/alloy-test/util.h index 175140f37..e6673dfe5 100644 --- a/tools/alloy-test/util.h +++ b/tools/alloy-test/util.h @@ -22,6 +22,9 @@ #include +#define ALLOY_TEST_IVM 1 +//#define ALLOY_TEST_X64 1 + namespace alloy { namespace test { @@ -82,6 +85,7 @@ class TestFunction { memory_size = 16 * 1024 * 1024; memory.reset(new SimpleMemory(memory_size)); +#if ALLOY_TEST_IVM { auto runtime = std::make_unique(memory.get()); auto frontend = @@ -91,6 +95,8 @@ class TestFunction { runtime->Initialize(std::move(frontend), std::move(backend)); runtimes.emplace_back(std::move(runtime)); } +#endif // ALLOY_TEST_IVM +#ifdef ALLOY_TEST_X64 { auto runtime = std::make_unique(memory.get()); auto frontend = @@ -100,6 +106,7 @@ class TestFunction { runtime->Initialize(std::move(frontend), std::move(backend)); runtimes.emplace_back(std::move(runtime)); } +#endif // ALLOY_TEST_X64 for (auto& runtime : runtimes) { auto module = std::make_unique( From 33ff2744ce23066039f9931111bfbf20d2b532f8 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 23 Aug 2014 22:44:49 -0700 Subject: [PATCH 170/388] Making alloy-test run on travis (in theory). --- .travis.yml | 7 +++++-- test/run-tests.sh | 0 tools/alloy-sandbox/alloy-sandbox.gypi | 1 - tools/alloy-test/alloy-test.gypi | 1 - 4 files changed, 5 insertions(+), 4 deletions(-) mode change 100644 => 100755 test/run-tests.sh diff --git a/.travis.yml b/.travis.yml index 5bc48c98d..109710b3f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,10 @@ os: # Run setup to build ninja/gyp/etc and actually build xenia. before_script: - travis_retry ./xenia-build.py setup - - ./xenia-build.py build --debug + #- ./xenia-build.py build --debug + - ./third_party/ninja/ninja -C build/xenia/Debug alloy-test # Run test suite. -script: ./test/run-tests.sh +script: + - ./build/xenia/Debug/alloy-test + #- ./test/run-tests.sh diff --git a/test/run-tests.sh b/test/run-tests.sh old mode 100644 new mode 100755 diff --git a/tools/alloy-sandbox/alloy-sandbox.gypi b/tools/alloy-sandbox/alloy-sandbox.gypi index 7988e708f..e5b947eac 100644 --- a/tools/alloy-sandbox/alloy-sandbox.gypi +++ b/tools/alloy-sandbox/alloy-sandbox.gypi @@ -13,7 +13,6 @@ 'dependencies': [ 'alloy', - 'xenia', ], 'include_dirs': [ diff --git a/tools/alloy-test/alloy-test.gypi b/tools/alloy-test/alloy-test.gypi index 122f5b430..560886289 100644 --- a/tools/alloy-test/alloy-test.gypi +++ b/tools/alloy-test/alloy-test.gypi @@ -13,7 +13,6 @@ 'dependencies': [ 'alloy', - 'xenia', ], 'include_dirs': [ From 6b0f49454d9e939eea6e0a482c2a6f8dc8214e77 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 23 Aug 2014 23:26:03 -0700 Subject: [PATCH 171/388] Disabling break on failure when not in VS. --- tools/alloy-test/alloy-test.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/alloy-test/alloy-test.cc b/tools/alloy-test/alloy-test.cc index 4c530cf16..0f3e6ce19 100644 --- a/tools/alloy-test/alloy-test.cc +++ b/tools/alloy-test/alloy-test.cc @@ -28,9 +28,12 @@ int main(std::vector& args) { } int ret = Catch::Session().run(int(args.size()), narrow_argv); if (ret) { +#if XE_LIKE_WIN32 + // Visual Studio kills the console on shutdown, so prevent that. if (poly::debugging::IsDebuggerAttached()) { poly::debugging::Break(); } +#endif // XE_LIKE_WIN32 } return ret; } From 0a1546c3e4db8e35abc635734ab868c0a4c2b526 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 23 Aug 2014 23:26:46 -0700 Subject: [PATCH 172/388] Adding vector min/max tests. --- tools/alloy-test/alloy-test.gypi | 2 + tools/alloy-test/test_vector_max.cc | 118 ++++++++++++++++++++++++++++ tools/alloy-test/test_vector_min.cc | 117 +++++++++++++++++++++++++++ 3 files changed, 237 insertions(+) create mode 100644 tools/alloy-test/test_vector_max.cc create mode 100644 tools/alloy-test/test_vector_min.cc diff --git a/tools/alloy-test/alloy-test.gypi b/tools/alloy-test/alloy-test.gypi index 560886289..ce7df1e44 100644 --- a/tools/alloy-test/alloy-test.gypi +++ b/tools/alloy-test/alloy-test.gypi @@ -23,6 +23,8 @@ 'alloy-test.cc', 'test_add.cc', 'test_vector_add.cc', + 'test_vector_max.cc', + 'test_vector_min.cc', 'util.h', ], }, diff --git a/tools/alloy-test/test_vector_max.cc b/tools/alloy-test/test_vector_max.cc new file mode 100644 index 000000000..0225c6823 --- /dev/null +++ b/tools/alloy-test/test_vector_max.cc @@ -0,0 +1,118 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include + +using namespace alloy; +using namespace alloy::hir; +using namespace alloy::runtime; +using namespace alloy::test; +using alloy::frontend::ppc::PPCContext; + +TEST_CASE("VECTOR_MAX_I8_SIGNED", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorMax(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + ctx->v[5] = vec128b(-100, 1, 100, -3, 4, -5, 60, 7, -80, 9, 10, + INT8_MIN, INT8_MAX, 13, 2, 0); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(0, 1, 100, 3, 4, 5, 60, 7, 8, 9, 10, 11, + INT8_MAX, 13, 14, 15)); + }); +} + +TEST_CASE("VECTOR_MAX_I8_UNSIGNED", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorMax(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE, + ARITHMETIC_UNSIGNED)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + ctx->v[5] = vec128b(-100, 1, 100, -3, 4, -5, 60, 7, -80, 9, 10, + INT8_MIN, INT8_MAX, 13, 2, 0); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(-100, 1, 100, -3, 4, -5, 60, 7, -80, 9, + 10, INT8_MIN, INT8_MAX, 13, 14, 15)); + }); +} + +TEST_CASE("VECTOR_MAX_I16_SIGNED", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorMax(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128s(0, 1, 2, 3, 4, 5, -6000, 7); + ctx->v[5] = vec128s(-1000, 1, -2000, 3, 4, SHRT_MAX, 6, 0); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128s(0, 1, 2, 3, 4, SHRT_MAX, 6, 7)); + }); +} + +TEST_CASE("VECTOR_MAX_I16_UNSIGNED", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorMax(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE, + ARITHMETIC_UNSIGNED)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128s(0, 1, 2, 3, 4, 5, -6000, 7); + ctx->v[5] = vec128s(-1000, 1, -2000, 3, 4, USHRT_MAX, 6, 0); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == + vec128s(-1000, 1, -2000, 3, 4, USHRT_MAX, -6000, 7)); + }); +} + +TEST_CASE("VECTOR_MAX_I32_SIGNED", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorMax(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128i(0, 1, 123, 3); + ctx->v[5] = vec128i(-1000000, 0, INT_MAX, 0); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(0, 1, INT_MAX, 3)); + }); +} + +TEST_CASE("VECTOR_MAX_I32_UNSIGNED", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorMax(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE, + ARITHMETIC_UNSIGNED)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128i(0, 1, 123, 3); + ctx->v[5] = vec128i(-1000000, 0, UINT_MAX, 0); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(-1000000, 1, UINT_MAX, 3)); + }); +} diff --git a/tools/alloy-test/test_vector_min.cc b/tools/alloy-test/test_vector_min.cc new file mode 100644 index 000000000..e82441189 --- /dev/null +++ b/tools/alloy-test/test_vector_min.cc @@ -0,0 +1,117 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include + +using namespace alloy; +using namespace alloy::hir; +using namespace alloy::runtime; +using namespace alloy::test; +using alloy::frontend::ppc::PPCContext; + +TEST_CASE("VECTOR_MIN_I8_SIGNED", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorMin(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + ctx->v[5] = vec128b(-100, 1, 100, -3, 4, -5, 60, 7, -80, 9, 10, + INT8_MIN, INT8_MAX, 13, 2, 0); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(-100, 1, 2, -3, 4, -5, 6, 7, -80, 9, 10, + INT8_MIN, 12, 13, 2, 0)); + }); +} + +TEST_CASE("VECTOR_MIN_I8_UNSIGNED", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorMin(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE, + ARITHMETIC_UNSIGNED)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + ctx->v[5] = vec128b(255, 1, 200, -3, 4, -5, 60, 7, -80, 9, 10, 11, + 12, 13, 2, 0); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 2, 0)); + }); +} + +TEST_CASE("VECTOR_MIN_I16_SIGNED", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorMin(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128s(0, 1, 2, 3, 4, 5, -6000, 7); + ctx->v[5] = vec128s(-1000, 1, -2000, 3, 4, SHRT_MAX, 6, 0); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128s(-1000, 1, -2000, 3, 4, 5, -6000, 0)); + }); +} + +TEST_CASE("VECTOR_MIN_I16_UNSIGNED", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorMin(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE, + ARITHMETIC_UNSIGNED)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128s(0, 1, 2, 3, 4, 5, -6000, 7); + ctx->v[5] = vec128s(-1000, 1, -2000, 3, 4, USHRT_MAX, 6, 0); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128s(0, 1, 2, 3, 4, 5, 6, 0)); + }); +} + +TEST_CASE("VECTOR_MIN_I32_SIGNED", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorMin(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128i(0, 1, 123, 3); + ctx->v[5] = vec128i(-1000000, 0, INT_MAX, 0); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(-1000000, 0, 123, 0)); + }); +} + +TEST_CASE("VECTOR_MIN_I32_UNSIGNED", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorMin(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE, + ARITHMETIC_UNSIGNED)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128i(0, 1, 123, 3); + ctx->v[5] = vec128i(-1000000, 0, UINT_MAX, 0); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(0, 0, 123, 0)); + }); +} From 2ffa1d3bd1e0b84fed4d598db5a80adc473b37ea Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 23 Aug 2014 23:35:42 -0700 Subject: [PATCH 173/388] Setting up test filenames as TODOs. --- tools/alloy-test/alloy-test.gypi | 59 ++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/tools/alloy-test/alloy-test.gypi b/tools/alloy-test/alloy-test.gypi index ce7df1e44..103ce7f8d 100644 --- a/tools/alloy-test/alloy-test.gypi +++ b/tools/alloy-test/alloy-test.gypi @@ -21,10 +21,69 @@ 'sources': [ 'alloy-test.cc', + #'test_abs.cc', 'test_add.cc', + #'test_add_carry.cc', + #'test_and.cc', + #'test_assign.cc', + #'test_atomic_add.cc', + #'test_atomic_exchange.cc', + #'test_atomic_sub.cc', + #'test_branch.cc', + #'test_byte_swap.cc', + #'test_cast.cc', + #'test_cntlz.cc', + #'test_compare.cc', + #'test_compare_exchange.cc', + #'test_convert.cc', + #'test_did_carry.cc', + #'test_div.cc', + #'test_dot_product_3.cc', + #'test_dot_product_4.cc', + #'test_extract.cc', + #'test_insert.cc', + #'test_is_true_false.cc', + #'test_load_clock.cc', + #'test_load_vector.cc', + #'test_log2.cc', + #'test_max.cc', + #'test_min.cc', + #'test_mul.cc', + #'test_mul_add.cc', + #'test_mul_hi.cc', + #'test_mul_sub.cc', + #'test_neg.cc', + #'test_not.cc', + #'test_or.cc', + #'test_pack.cc', + #'test_permute.cc', + #'test_pow2.cc', + #'test_rotate_left.cc', + #'test_round.cc', + #'test_rsqrt.cc', + #'test_select.cc', + #'test_sha.cc', + #'test_shl.cc', + #'test_shr.cc', + #'test_sign_extend.cc', + #'test_splat.cc', + #'test_sqrt.cc', + #'test_sub.cc', + #'test_swizzle.cc', + #'test_truncate.cc', + #'test_unpack.cc', 'test_vector_add.cc', + #'test_vector_compare.cc', + #'test_vector_convert.cc', 'test_vector_max.cc', 'test_vector_min.cc', + #'test_vector_rotate_left.cc', + #'test_vector_sha.cc', + #'test_vector_shl.cc', + #'test_vector_shr.cc', + #'test_vector_sub.cc', + #'test_xor.cc', + #'test_zero_extend.cc', 'util.h', ], }, From 9d7c916c674d37601635bff6126d8b7c0c170bdd Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 24 Aug 2014 12:27:13 -0700 Subject: [PATCH 174/388] Trying multiprocessor builds again - I remember there being issues. --- xenia.gyp | 1 + 1 file changed, 1 insertion(+) diff --git a/xenia.gyp b/xenia.gyp index a5f8bb215..000fb369c 100644 --- a/xenia.gyp +++ b/xenia.gyp @@ -90,6 +90,7 @@ 'AdditionalOptions': [ #'/TP', # Compile as C++ '/EHsc', # C++ exception handling, + '/MP', ], }, 'VCLinkerTool': { From 8ca76422268dfb48cd5ae1c74a5a0e7a49876ca2 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 24 Aug 2014 21:41:16 -0700 Subject: [PATCH 175/388] VectorSubF32 in IVM -- how did this not exist already? --- src/alloy/backend/ivm/ivm_intcode.cc | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index 09da2add0..10dcea2de 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -2735,10 +2735,23 @@ int Translate_SUB(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, fns[i->dest->type]); } +uint32_t Translate_VECTOR_SUB_F32(IntCodeState& ics, const IntCode* i) { + const vec128_t& src1 = ics.rf[i->src1_reg].v128; + const vec128_t& src2 = ics.rf[i->src2_reg].v128; + vec128_t& dest = ics.rf[i->dest_reg].v128; + for (int n = 0; n < 4; n++) { + dest.f4[n] = src1.f4[n] - src2.f4[n]; + } + return IA_NEXT; +} int Translate_VECTOR_SUB(TranslationContext& ctx, Instr* i) { - // TODO(benvanik): VECTOR_SUB in IVM. - assert_always(); - return 1; + TypeName part_type = (TypeName)(i->flags & 0xFF); + static IntCodeFn fns[] = { + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, Translate_VECTOR_SUB_F32, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, + }; + return DispatchToC(ctx, i, fns[part_type]); } uint32_t IntCode_MUL_I8_I8(IntCodeState& ics, const IntCode* i) { From f74aafeb8a010297397ac89a9e63f99645f5db26 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 29 Aug 2014 20:39:26 -0700 Subject: [PATCH 176/388] Swapping around vec128 to match AVX order. Was really hoping all this would fix some bugs, but no luck :( --- src/alloy/backend/ivm/ivm_intcode.cc | 693 +++++++++-------- src/alloy/backend/x64/x64_emitter.cc | 40 +- src/alloy/backend/x64/x64_emitter.h | 11 +- src/alloy/backend/x64/x64_sequences.cc | 760 +++++++++---------- src/alloy/frontend/ppc/ppc_emit_altivec.cc | 58 +- src/alloy/frontend/ppc/ppc_emit_alu.cc | 7 +- src/alloy/hir/opcodes.h | 7 +- src/alloy/hir/value.cc | 2 +- src/alloy/vec128.h | 152 ++-- src/poly/math.h | 5 + tools/alloy-sandbox/alloy-sandbox.gypi | 1 + tools/alloy-test/alloy-test.gypi | 29 +- tools/alloy-test/test_extract.cc | 141 ++++ tools/alloy-test/test_insert.cc | 83 ++ tools/alloy-test/test_load_vector_shl_shr.cc | 78 ++ tools/alloy-test/test_pack.cc | 111 +++ tools/alloy-test/test_permute.cc | 139 ++++ tools/alloy-test/test_sha.cc | 211 +++++ tools/alloy-test/test_shl.cc | 211 +++++ tools/alloy-test/test_shr.cc | 211 +++++ tools/alloy-test/test_swizzle.cc | 46 ++ tools/alloy-test/test_unpack.cc | 162 ++++ tools/alloy-test/test_vector_rotate_left.cc | 71 ++ tools/alloy-test/test_vector_sha.cc | 145 ++++ tools/alloy-test/test_vector_shl.cc | 145 ++++ tools/alloy-test/test_vector_shr.cc | 145 ++++ tools/alloy-test/util.h | 2 +- 27 files changed, 2845 insertions(+), 821 deletions(-) create mode 100644 tools/alloy-test/test_extract.cc create mode 100644 tools/alloy-test/test_insert.cc create mode 100644 tools/alloy-test/test_load_vector_shl_shr.cc create mode 100644 tools/alloy-test/test_pack.cc create mode 100644 tools/alloy-test/test_permute.cc create mode 100644 tools/alloy-test/test_sha.cc create mode 100644 tools/alloy-test/test_shl.cc create mode 100644 tools/alloy-test/test_shr.cc create mode 100644 tools/alloy-test/test_swizzle.cc create mode 100644 tools/alloy-test/test_unpack.cc create mode 100644 tools/alloy-test/test_vector_rotate_left.cc create mode 100644 tools/alloy-test/test_vector_sha.cc create mode 100644 tools/alloy-test/test_vector_shl.cc create mode 100644 tools/alloy-test/test_vector_shr.cc diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index 10dcea2de..141d6790f 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -44,29 +44,13 @@ using alloy::runtime::FunctionInfo; #define DPRINT(...) (void()) #define DFLUSH() (void()) -//#define IPRINT if (ics.thread_state->thread_id() == 1) printf +//#define IPRINT \ +// if (ics.thread_state->thread_id() == 1) printf //#define IFLUSH() fflush(stdout) -//#define DPRINT if (ics.thread_state->thread_id() == 1) printf +//#define DPRINT \ +// if (ics.thread_state->thread_id() == 1) printf //#define DFLUSH() fflush(stdout) -#if XE_CPU_BIGENDIAN -#define VECB16(v, n) (v.b16[n]) -#define VECS8(v, n) (v.s8[n]) -#define VECI4(v, n) (v.i4[n]) -#define VECF4(v, n) (v.f4[n]) -#else -static const uint8_t __vector_b16_table[16] = { - 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12, -}; -static const uint8_t __vector_s8_table[8] = { - 1, 0, 3, 2, 5, 4, 7, 6, -}; -#define VECB16(v, n) (v.b16[__vector_b16_table[(n)]]) -#define VECS8(v, n) (v.s8[__vector_s8_table[(n)]]) -#define VECI4(v, n) (v.i4[(n)]) -#define VECF4(v, n) (v.f4[(n)]) -#endif - uint32_t IntCode_INT_LOAD_CONSTANT(IntCodeState& ics, const IntCode* i) { // TODO(benvanik): optimize on type to avoid 16b copy per load. ics.rf[i->dest_reg].v128 = i->constant.v128; @@ -1011,7 +995,7 @@ uint32_t IntCode_ROUND_V128_ZERO(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (size_t n = 0; n < 4; n++) { - dest.f4[n] = truncf(src1.f4[n]); + dest.f32[n] = truncf(src1.f32[n]); } return IA_NEXT; } @@ -1019,7 +1003,7 @@ uint32_t IntCode_ROUND_V128_NEAREST(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (size_t n = 0; n < 4; n++) { - dest.f4[n] = roundf(src1.f4[n]); + dest.f32[n] = roundf(src1.f32[n]); } return IA_NEXT; } @@ -1027,8 +1011,8 @@ uint32_t IntCode_ROUND_V128_MINUS_INFINITY(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; - for (size_t n = 0; n < 4; n++) { - dest.f4[n] = floorf(src1.f4[n]); + for (int n = 0; n < 4; ++n) { + dest.f32[n] = floorf(src1.f32[n]); } return IA_NEXT; } @@ -1036,8 +1020,8 @@ uint32_t IntCode_ROUND_V128_POSITIVE_INFINTIY(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; - for (size_t n = 0; n < 4; n++) { - dest.f4[n] = ceilf(src1.f4[n]); + for (int n = 0; n < 4; ++n) { + dest.f32[n] = ceilf(src1.f32[n]); } return IA_NEXT; } @@ -1061,19 +1045,17 @@ int Translate_ROUND(TranslationContext& ctx, Instr* i) { uint32_t IntCode_VECTOR_CONVERT_I2F_S(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; - VECF4(dest, 0) = (float)(int32_t)VECI4(src1, 0); - VECF4(dest, 1) = (float)(int32_t)VECI4(src1, 1); - VECF4(dest, 2) = (float)(int32_t)VECI4(src1, 2); - VECF4(dest, 3) = (float)(int32_t)VECI4(src1, 3); + for (int n = 0; n < 4; ++n) { + dest.f32[n] = (float)(int32_t)src1.u32[n]; + } return IA_NEXT; } uint32_t IntCode_VECTOR_CONVERT_I2F_U(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; - VECF4(dest, 0) = (float)(uint32_t)VECI4(src1, 0); - VECF4(dest, 1) = (float)(uint32_t)VECI4(src1, 1); - VECF4(dest, 2) = (float)(uint32_t)VECI4(src1, 2); - VECF4(dest, 3) = (float)(uint32_t)VECI4(src1, 3); + for (int n = 0; n < 4; ++n) { + dest.f32[n] = (float)(uint32_t)src1.u32[n]; + } return IA_NEXT; } int Translate_VECTOR_CONVERT_I2F(TranslationContext& ctx, Instr* i) { @@ -1088,15 +1070,13 @@ uint32_t IntCode_VECTOR_CONVERT_F2I(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; if (i->flags & ARITHMETIC_UNSIGNED) { - VECI4(dest, 0) = (uint32_t)VECF4(src1, 0); - VECI4(dest, 1) = (uint32_t)VECF4(src1, 1); - VECI4(dest, 2) = (uint32_t)VECF4(src1, 2); - VECI4(dest, 3) = (uint32_t)VECF4(src1, 3); + for (int n = 0; n < 4; ++n) { + dest.u32[n] = (uint32_t)src1.f32[n]; + } } else { - VECI4(dest, 0) = (int32_t)VECF4(src1, 0); - VECI4(dest, 1) = (int32_t)VECF4(src1, 1); - VECI4(dest, 2) = (int32_t)VECF4(src1, 2); - VECI4(dest, 3) = (int32_t)VECF4(src1, 3); + for (int n = 0; n < 4; ++n) { + dest.u32[n] = (int32_t)src1.f32[n]; + } } return IA_NEXT; } @@ -1105,28 +1085,28 @@ uint32_t IntCode_VECTOR_CONVERT_F2I_SAT(IntCodeState& ics, const IntCode* i) { vec128_t& dest = ics.rf[i->dest_reg].v128; if (i->flags & ARITHMETIC_UNSIGNED) { for (int n = 0; n < 4; n++) { - float src = src1.f4[n]; + float src = src1.f32[n]; if (src < 0) { - VECI4(dest, n) = 0; + dest.u32[n] = 0; ics.did_saturate = 1; } else if (src > UINT_MAX) { - VECI4(dest, n) = UINT_MAX; + dest.u32[n] = UINT_MAX; ics.did_saturate = 1; } else { - VECI4(dest, n) = (uint32_t)src; + dest.u32[n] = (uint32_t)src; } } } else { for (int n = 0; n < 4; n++) { - float src = src1.f4[n]; + float src = src1.f32[n]; if (src < INT_MIN) { - VECI4(dest, n) = INT_MIN; + dest.u32[n] = INT_MIN; ics.did_saturate = 1; } else if (src > INT_MAX) { - VECI4(dest, n) = INT_MAX; + dest.u32[n] = INT_MAX; ics.did_saturate = 1; } else { - VECI4(dest, n) = (int32_t)src; + dest.u32[n] = (int32_t)src; } } } @@ -1140,51 +1120,46 @@ int Translate_VECTOR_CONVERT_F2I(TranslationContext& ctx, Instr* i) { } } -static uint8_t __lvsl_table[17][16] = { - {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, - {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, - {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, - {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}, - {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}, - {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, - {6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}, - {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}, - {8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}, - {9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}, - {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}, - {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}, - {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27}, - {13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28}, - {14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}, - {15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}, - {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, +static const vec128_t lvsl_table[16] = { + vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), + vec128b(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), + vec128b(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17), + vec128b(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18), + vec128b(4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19), + vec128b(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20), + vec128b(6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21), + vec128b(7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22), + vec128b(8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23), + vec128b(9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24), + vec128b(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25), + vec128b(11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26), + vec128b(12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27), + vec128b(13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28), + vec128b(14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29), + vec128b(15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30), }; -static uint8_t __lvsr_table[17][16] = { - {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, - {15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}, - {14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}, - {13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28}, - {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27}, - {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}, - {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}, - {9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}, - {8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}, - {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}, - {6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}, - {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, - {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}, - {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}, - {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, - {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, - {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, +static const vec128_t lvsr_table[16] = { + vec128b(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31), + vec128b(15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30), + vec128b(14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29), + vec128b(13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28), + vec128b(12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27), + vec128b(11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26), + vec128b(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25), + vec128b(9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24), + vec128b(8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23), + vec128b(7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22), + vec128b(6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21), + vec128b(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20), + vec128b(4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19), + vec128b(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18), + vec128b(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17), + vec128b(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), }; uint32_t IntCode_LOAD_VECTOR_SHL(IntCodeState& ics, const IntCode* i) { - int8_t sh = std::min(16, ics.rf[i->src1_reg].i8); - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 16; n++) { - VECB16(dest, n) = __lvsl_table[sh][n]; - } + int8_t sh = ics.rf[i->src1_reg].i8 & 0xF; + ics.rf[i->dest_reg].v128 = lvsl_table[sh]; return IA_NEXT; } int Translate_LOAD_VECTOR_SHL(TranslationContext& ctx, Instr* i) { @@ -1192,11 +1167,8 @@ int Translate_LOAD_VECTOR_SHL(TranslationContext& ctx, Instr* i) { } uint32_t IntCode_LOAD_VECTOR_SHR(IntCodeState& ics, const IntCode* i) { - int8_t sh = std::min(16, ics.rf[i->src1_reg].i8); - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 16; n++) { - VECB16(dest, n) = __lvsr_table[sh][n]; - } + int8_t sh = ics.rf[i->src1_reg].i8 & 0xF; + ics.rf[i->dest_reg].v128 = lvsr_table[sh]; return IA_NEXT; } int Translate_LOAD_VECTOR_SHR(TranslationContext& ctx, Instr* i) { @@ -1331,10 +1303,10 @@ uint32_t IntCode_LOAD_CONTEXT_V128(IntCodeState& ics, const IntCode* i) { ics.rf[i->dest_reg].v128 = *((vec128_t*)(ics.context + ics.rf[i->src1_reg].u64)); DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = ctx v128 +%d\n", - VECF4(ics.rf[i->dest_reg].v128, 0), VECF4(ics.rf[i->dest_reg].v128, 1), - VECF4(ics.rf[i->dest_reg].v128, 2), VECF4(ics.rf[i->dest_reg].v128, 3), - VECI4(ics.rf[i->dest_reg].v128, 0), VECI4(ics.rf[i->dest_reg].v128, 1), - VECI4(ics.rf[i->dest_reg].v128, 2), VECI4(ics.rf[i->dest_reg].v128, 3), + ics.rf[i->dest_reg].v128.x, ics.rf[i->dest_reg].v128.y, + ics.rf[i->dest_reg].v128.z, ics.rf[i->dest_reg].v128.w, + ics.rf[i->dest_reg].v128.ux, ics.rf[i->dest_reg].v128.uy, + ics.rf[i->dest_reg].v128.uz, ics.rf[i->dest_reg].v128.uw, ics.rf[i->src1_reg].u64); return IA_NEXT; } @@ -1391,11 +1363,11 @@ uint32_t IntCode_STORE_CONTEXT_V128(IntCodeState& ics, const IntCode* i) { *((vec128_t*)(ics.context + ics.rf[i->src1_reg].u64)) = ics.rf[i->src2_reg].v128; DPRINT("ctx v128 +%d = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", - ics.rf[i->src1_reg].u64, VECF4(ics.rf[i->src2_reg].v128, 0), - VECF4(ics.rf[i->src2_reg].v128, 1), VECF4(ics.rf[i->src2_reg].v128, 2), - VECF4(ics.rf[i->src2_reg].v128, 3), VECI4(ics.rf[i->src2_reg].v128, 0), - VECI4(ics.rf[i->src2_reg].v128, 1), VECI4(ics.rf[i->src2_reg].v128, 2), - VECI4(ics.rf[i->src2_reg].v128, 3)); + ics.rf[i->src1_reg].u64, ics.rf[i->src2_reg].v128.x, + ics.rf[i->src2_reg].v128.y, ics.rf[i->src2_reg].v128.z, + ics.rf[i->src2_reg].v128.w, ics.rf[i->src2_reg].v128.ux, + ics.rf[i->src2_reg].v128.uy, ics.rf[i->src2_reg].v128.uz, + ics.rf[i->src2_reg].v128.uw); return IA_NEXT; } int Translate_STORE_CONTEXT(TranslationContext& ctx, Instr* i) { @@ -1480,12 +1452,10 @@ uint32_t IntCode_LOAD_V128(IntCodeState& ics, const IntCode* i) { uint32_t address = ics.rf[i->src1_reg].u32; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - VECI4(dest, n) = *((uint32_t*)(ics.membase + address + n * 4)); + dest.u32[n] = *((uint32_t*)(ics.membase + address + n * 4)); } - DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = load.v128 %.8X\n", - VECF4(dest, 0), VECF4(dest, 1), VECF4(dest, 2), VECF4(dest, 3), - VECI4(dest, 0), VECI4(dest, 1), VECI4(dest, 2), VECI4(dest, 3), - address); + DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = load.v128 %.8X\n", dest.x, + dest.y, dest.z, dest.w, dest.ux, dest.uy, dest.uz, dest.uw, address); DFLUSH(); return IA_NEXT; } @@ -1579,11 +1549,10 @@ uint32_t IntCode_STORE_F64(IntCodeState& ics, const IntCode* i) { uint32_t IntCode_STORE_V128(IntCodeState& ics, const IntCode* i) { uint32_t address = ics.rf[i->src1_reg].u32; DPRINT("store.v128 %.8X = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", - address, VECF4(ics.rf[i->src2_reg].v128, 0), - VECF4(ics.rf[i->src2_reg].v128, 1), VECF4(ics.rf[i->src2_reg].v128, 2), - VECF4(ics.rf[i->src2_reg].v128, 3), VECI4(ics.rf[i->src2_reg].v128, 0), - VECI4(ics.rf[i->src2_reg].v128, 1), VECI4(ics.rf[i->src2_reg].v128, 2), - VECI4(ics.rf[i->src2_reg].v128, 3)); + address, ics.rf[i->src2_reg].v128.x, ics.rf[i->src2_reg].v128.y, + ics.rf[i->src2_reg].v128.z, ics.rf[i->src2_reg].v128.w, + ics.rf[i->src2_reg].v128.ux, ics.rf[i->src2_reg].v128.uy, + ics.rf[i->src2_reg].v128.uz, ics.rf[i->src2_reg].v128.uw); DFLUSH(); *((vec128_t*)(ics.membase + address)) = ics.rf[i->src2_reg].v128; MarkPageDirty(ics, address); @@ -1644,7 +1613,7 @@ uint32_t IntCode_MAX_V128_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - dest.f4[n] = std::max(src1.f4[n], src2.f4[n]); + dest.f32[n] = std::max(src1.f32[n], src2.f32[n]); } return IA_NEXT; } @@ -1662,7 +1631,7 @@ uint32_t IntCode_VECTOR_MAX_I8_UNSIGNED(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 16; n++) { - dest.b16[n] = std::max(src1.b16[n], src2.b16[n]); + dest.u8[n] = std::max(src1.u8[n], src2.u8[n]); } return IA_NEXT; } @@ -1671,7 +1640,7 @@ uint32_t IntCode_VECTOR_MAX_I16_UNSIGNED(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 8; n++) { - dest.s8[n] = std::max(src1.s8[n], src2.s8[n]); + dest.u16[n] = std::max(src1.u16[n], src2.u16[n]); } return IA_NEXT; } @@ -1680,7 +1649,7 @@ uint32_t IntCode_VECTOR_MAX_I32_UNSIGNED(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - dest.i4[n] = std::max(src1.i4[n], src2.i4[n]); + dest.u32[n] = std::max(src1.u32[n], src2.u32[n]); } return IA_NEXT; } @@ -1689,7 +1658,7 @@ uint32_t IntCode_VECTOR_MAX_I8_SIGNED(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 16; n++) { - dest.b16[n] = std::max((int8_t)src1.b16[n], (int8_t)src2.b16[n]); + dest.u8[n] = std::max((int8_t)src1.u8[n], (int8_t)src2.u8[n]); } return IA_NEXT; } @@ -1698,7 +1667,7 @@ uint32_t IntCode_VECTOR_MAX_I16_SIGNED(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 8; n++) { - dest.s8[n] = std::max((int16_t)src1.s8[n], (int16_t)src2.s8[n]); + dest.u16[n] = std::max((int16_t)src1.u16[n], (int16_t)src2.u16[n]); } return IA_NEXT; } @@ -1707,7 +1676,7 @@ uint32_t IntCode_VECTOR_MAX_I32_SIGNED(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - dest.i4[n] = std::max((int32_t)src1.i4[n], (int32_t)src2.i4[n]); + dest.u32[n] = std::max((int32_t)src1.u32[n], (int32_t)src2.u32[n]); } return IA_NEXT; } @@ -1767,7 +1736,7 @@ uint32_t IntCode_MIN_V128_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - dest.f4[n] = std::min(src1.f4[n], src2.f4[n]); + dest.f32[n] = std::min(src1.f32[n], src2.f32[n]); } return IA_NEXT; } @@ -1785,7 +1754,7 @@ uint32_t IntCode_VECTOR_MIN_I8_UNSIGNED(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 16; n++) { - dest.b16[n] = std::min(src1.b16[n], src2.b16[n]); + dest.u8[n] = std::min(src1.u8[n], src2.u8[n]); } return IA_NEXT; } @@ -1794,7 +1763,7 @@ uint32_t IntCode_VECTOR_MIN_I16_UNSIGNED(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 8; n++) { - dest.s8[n] = std::min(src1.s8[n], src2.s8[n]); + dest.u16[n] = std::min(src1.u16[n], src2.u16[n]); } return IA_NEXT; } @@ -1803,7 +1772,7 @@ uint32_t IntCode_VECTOR_MIN_I32_UNSIGNED(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - dest.i4[n] = std::min(src1.i4[n], src2.i4[n]); + dest.u32[n] = std::min(src1.u32[n], src2.u32[n]); } return IA_NEXT; } @@ -1812,7 +1781,7 @@ uint32_t IntCode_VECTOR_MIN_I8_SIGNED(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 16; n++) { - dest.b16[n] = std::min((int8_t)src1.b16[n], (int8_t)src2.b16[n]); + dest.u8[n] = std::min((int8_t)src1.u8[n], (int8_t)src2.u8[n]); } return IA_NEXT; } @@ -1821,7 +1790,7 @@ uint32_t IntCode_VECTOR_MIN_I16_SIGNED(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 8; n++) { - dest.s8[n] = std::min((int16_t)src1.s8[n], (int16_t)src2.s8[n]); + dest.u16[n] = std::min((int16_t)src1.u16[n], (int16_t)src2.u16[n]); } return IA_NEXT; } @@ -1830,7 +1799,7 @@ uint32_t IntCode_VECTOR_MIN_I32_SIGNED(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - dest.i4[n] = std::min((int32_t)src1.i4[n], (int32_t)src2.i4[n]); + dest.u32[n] = std::min((int32_t)src1.u32[n], (int32_t)src2.u32[n]); } return IA_NEXT; } @@ -2337,14 +2306,14 @@ int Translate_DID_SATURATE(TranslationContext& ctx, Instr* i) { } \ return IA_NEXT; -uint32_t IntCode_VECTOR_COMPARE_EQ_I8(IntCodeState& ics, const IntCode* i) { - VECTOR_COMPARER(uint8_t, b16, b16, 16, == )}; -uint32_t IntCode_VECTOR_COMPARE_EQ_I16(IntCodeState& ics, const IntCode* i) { - VECTOR_COMPARER(uint16_t, s8, s8, 8, == )}; -uint32_t IntCode_VECTOR_COMPARE_EQ_I32(IntCodeState& ics, const IntCode* i) { - VECTOR_COMPARER(uint32_t, i4, i4, 4, == )}; -uint32_t IntCode_VECTOR_COMPARE_EQ_F32(IntCodeState& ics, const IntCode* i) { - VECTOR_COMPARER(float, f4, i4, 4, == )}; +uint32_t IntCode_VECTOR_COMPARE_EQ_I8(IntCodeState& ics, const IntCode* i){ + VECTOR_COMPARER(uint8_t, u8, u8, 16, == )}; +uint32_t IntCode_VECTOR_COMPARE_EQ_I16(IntCodeState& ics, const IntCode* i){ + VECTOR_COMPARER(uint16_t, u16, u16, 8, == )}; +uint32_t IntCode_VECTOR_COMPARE_EQ_I32(IntCodeState& ics, const IntCode* i){ + VECTOR_COMPARER(uint32_t, u32, u32, 4, == )}; +uint32_t IntCode_VECTOR_COMPARE_EQ_F32(IntCodeState& ics, const IntCode* i){ + VECTOR_COMPARER(float, f32, u32, 4, == )}; int Translate_VECTOR_COMPARE_EQ(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { IntCode_VECTOR_COMPARE_EQ_I8, IntCode_VECTOR_COMPARE_EQ_I16, @@ -2355,14 +2324,14 @@ int Translate_VECTOR_COMPARE_EQ(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, fns[i->flags]); } -uint32_t IntCode_VECTOR_COMPARE_SGT_I8(IntCodeState& ics, const IntCode* i) { - VECTOR_COMPARER(int8_t, b16, b16, 16, > )}; -uint32_t IntCode_VECTOR_COMPARE_SGT_I16(IntCodeState& ics, const IntCode* i) { - VECTOR_COMPARER(int16_t, s8, s8, 8, > )}; -uint32_t IntCode_VECTOR_COMPARE_SGT_I32(IntCodeState& ics, const IntCode* i) { - VECTOR_COMPARER(int32_t, i4, i4, 4, > )}; -uint32_t IntCode_VECTOR_COMPARE_SGT_F32(IntCodeState& ics, const IntCode* i) { - VECTOR_COMPARER(float, f4, i4, 4, > )}; +uint32_t IntCode_VECTOR_COMPARE_SGT_I8(IntCodeState& ics, const IntCode* i){ + VECTOR_COMPARER(int8_t, i8, i8, 16, > )}; +uint32_t IntCode_VECTOR_COMPARE_SGT_I16(IntCodeState& ics, const IntCode* i){ + VECTOR_COMPARER(int16_t, i16, i16, 8, > )}; +uint32_t IntCode_VECTOR_COMPARE_SGT_I32(IntCodeState& ics, const IntCode* i){ + VECTOR_COMPARER(int32_t, i32, i32, 4, > )}; +uint32_t IntCode_VECTOR_COMPARE_SGT_F32(IntCodeState& ics, const IntCode* i){ + VECTOR_COMPARER(float, f32, u32, 4, > )}; int Translate_VECTOR_COMPARE_SGT(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { IntCode_VECTOR_COMPARE_SGT_I8, IntCode_VECTOR_COMPARE_SGT_I16, @@ -2373,14 +2342,14 @@ int Translate_VECTOR_COMPARE_SGT(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, fns[i->flags]); } -uint32_t IntCode_VECTOR_COMPARE_SGE_I8(IntCodeState& ics, const IntCode* i) { - VECTOR_COMPARER(int8_t, b16, b16, 16, >= )}; -uint32_t IntCode_VECTOR_COMPARE_SGE_I16(IntCodeState& ics, const IntCode* i) { - VECTOR_COMPARER(int16_t, s8, s8, 8, >= )}; -uint32_t IntCode_VECTOR_COMPARE_SGE_I32(IntCodeState& ics, const IntCode* i) { - VECTOR_COMPARER(int32_t, i4, i4, 4, >= )}; -uint32_t IntCode_VECTOR_COMPARE_SGE_F32(IntCodeState& ics, const IntCode* i) { - VECTOR_COMPARER(float, f4, i4, 4, >= )}; +uint32_t IntCode_VECTOR_COMPARE_SGE_I8(IntCodeState& ics, const IntCode* i){ + VECTOR_COMPARER(int8_t, i8, i8, 16, >= )}; +uint32_t IntCode_VECTOR_COMPARE_SGE_I16(IntCodeState& ics, const IntCode* i){ + VECTOR_COMPARER(int16_t, i16, i16, 8, >= )}; +uint32_t IntCode_VECTOR_COMPARE_SGE_I32(IntCodeState& ics, const IntCode* i){ + VECTOR_COMPARER(int32_t, i32, i32, 4, >= )}; +uint32_t IntCode_VECTOR_COMPARE_SGE_F32(IntCodeState& ics, const IntCode* i){ + VECTOR_COMPARER(float, f32, u32, 4, >= )}; int Translate_VECTOR_COMPARE_SGE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { IntCode_VECTOR_COMPARE_SGE_I8, IntCode_VECTOR_COMPARE_SGE_I16, @@ -2391,14 +2360,14 @@ int Translate_VECTOR_COMPARE_SGE(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, fns[i->flags]); } -uint32_t IntCode_VECTOR_COMPARE_UGT_I8(IntCodeState& ics, const IntCode* i) { - VECTOR_COMPARER(uint8_t, b16, b16, 16, > )}; -uint32_t IntCode_VECTOR_COMPARE_UGT_I16(IntCodeState& ics, const IntCode* i) { - VECTOR_COMPARER(uint16_t, s8, s8, 8, > )}; -uint32_t IntCode_VECTOR_COMPARE_UGT_I32(IntCodeState& ics, const IntCode* i) { - VECTOR_COMPARER(uint32_t, i4, i4, 4, > )}; -uint32_t IntCode_VECTOR_COMPARE_UGT_F32(IntCodeState& ics, const IntCode* i) { - VECTOR_COMPARER(float, f4, i4, 4, > )}; +uint32_t IntCode_VECTOR_COMPARE_UGT_I8(IntCodeState& ics, const IntCode* i){ + VECTOR_COMPARER(uint8_t, u8, u8, 16, > )}; +uint32_t IntCode_VECTOR_COMPARE_UGT_I16(IntCodeState& ics, const IntCode* i){ + VECTOR_COMPARER(uint16_t, u16, u16, 8, > )}; +uint32_t IntCode_VECTOR_COMPARE_UGT_I32(IntCodeState& ics, const IntCode* i){ + VECTOR_COMPARER(uint32_t, u32, u32, 4, > )}; +uint32_t IntCode_VECTOR_COMPARE_UGT_F32(IntCodeState& ics, const IntCode* i){ + VECTOR_COMPARER(float, f32, u32, 4, > )}; int Translate_VECTOR_COMPARE_UGT(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { IntCode_VECTOR_COMPARE_UGT_I8, IntCode_VECTOR_COMPARE_UGT_I16, @@ -2409,14 +2378,14 @@ int Translate_VECTOR_COMPARE_UGT(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, fns[i->flags]); } -uint32_t IntCode_VECTOR_COMPARE_UGE_I8(IntCodeState& ics, const IntCode* i) { - VECTOR_COMPARER(uint8_t, b16, b16, 16, >= )}; -uint32_t IntCode_VECTOR_COMPARE_UGE_I16(IntCodeState& ics, const IntCode* i) { - VECTOR_COMPARER(uint16_t, s8, s8, 8, >= )}; -uint32_t IntCode_VECTOR_COMPARE_UGE_I32(IntCodeState& ics, const IntCode* i) { - VECTOR_COMPARER(uint32_t, i4, i4, 4, >= )}; -uint32_t IntCode_VECTOR_COMPARE_UGE_F32(IntCodeState& ics, const IntCode* i) { - VECTOR_COMPARER(float, f4, i4, 4, >= )}; +uint32_t IntCode_VECTOR_COMPARE_UGE_I8(IntCodeState& ics, const IntCode* i){ + VECTOR_COMPARER(uint8_t, u8, u8, 16, >= )}; +uint32_t IntCode_VECTOR_COMPARE_UGE_I16(IntCodeState& ics, const IntCode* i){ + VECTOR_COMPARER(uint16_t, u16, u16, 8, >= )}; +uint32_t IntCode_VECTOR_COMPARE_UGE_I32(IntCodeState& ics, const IntCode* i){ + VECTOR_COMPARER(uint32_t, u32, u32, 4, >= )}; +uint32_t IntCode_VECTOR_COMPARE_UGE_F32(IntCodeState& ics, const IntCode* i){ + VECTOR_COMPARER(float, f32, u32, 4, >= )}; int Translate_VECTOR_COMPARE_UGE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { IntCode_VECTOR_COMPARE_UGE_I8, IntCode_VECTOR_COMPARE_UGE_I16, @@ -2477,8 +2446,8 @@ uint32_t IntCode_ADD_F64_F64(IntCodeState& ics, const IntCode* i) { } int Translate_ADD(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_ADD_I8_I8, IntCode_ADD_I16_I16, IntCode_ADD_I32_I32, - IntCode_ADD_I64_I64, IntCode_ADD_F32_F32, IntCode_ADD_F64_F64, + IntCode_ADD_I8_I8, IntCode_ADD_I16_I16, IntCode_ADD_I32_I32, + IntCode_ADD_I64_I64, IntCode_ADD_F32_F32, IntCode_ADD_F64_F64, IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->dest->type]); @@ -2556,31 +2525,31 @@ uint32_t Translate_VECTOR_ADD_I8(IntCodeState& ics, const IntCode* i) { if (arithmetic_flags & ARITHMETIC_SATURATE) { if (arithmetic_flags & ARITHMETIC_UNSIGNED) { for (int n = 0; n < 16; n++) { - uint16_t v = VECB16(src1, n) + VECB16(src2, n); + uint16_t v = src1.u8[n] + src2.u8[n]; if (v > 0xFF) { - VECB16(dest, n) = 0xFF; + dest.u8[n] = 0xFF; ics.did_saturate = 1; } else { - VECB16(dest, n) = (uint8_t)v; + dest.u8[n] = (uint8_t)v; } } } else { for (int n = 0; n < 16; n++) { - int16_t v = (int8_t)VECB16(src1, n) + (int8_t)VECB16(src2, n); + int16_t v = (int8_t)src1.u8[n] + (int8_t)src2.u8[n]; if (v > 0x7F) { - VECB16(dest, n) = 0x7F; + dest.u8[n] = 0x7F; ics.did_saturate = 1; } else if (v < -0x80) { - VECB16(dest, n) = -0x80; + dest.u8[n] = -0x80; ics.did_saturate = 1; } else { - VECB16(dest, n) = (uint8_t)v; + dest.u8[n] = (uint8_t)v; } } } } else { for (int n = 0; n < 16; n++) { - VECB16(dest, n) = VECB16(src1, n) + VECB16(src2, n); + dest.u8[n] = src1.u8[n] + src2.u8[n]; } } return IA_NEXT; @@ -2593,31 +2562,31 @@ uint32_t Translate_VECTOR_ADD_I16(IntCodeState& ics, const IntCode* i) { if (arithmetic_flags & ARITHMETIC_SATURATE) { if (arithmetic_flags & ARITHMETIC_UNSIGNED) { for (int n = 0; n < 8; n++) { - uint32_t v = VECS8(src1, n) + VECS8(src2, n); + uint32_t v = src1.u16[n] + src2.u16[n]; if (v > 0xFFFF) { - VECS8(dest, n) = 0xFFFF; + dest.u16[n] = 0xFFFF; ics.did_saturate = 1; } else { - VECS8(dest, n) = (uint16_t)v; + dest.u16[n] = (uint16_t)v; } } } else { for (int n = 0; n < 8; n++) { - int32_t v = (int16_t)VECS8(src1, n) + (int16_t)VECS8(src2, n); + int32_t v = (int16_t)src1.u16[n] + (int16_t)src2.u16[n]; if (v > 0x7FFF) { - VECS8(dest, n) = 0x7FFF; + dest.u16[n] = 0x7FFF; ics.did_saturate = 1; } else if (v < -0x8000) { - VECS8(dest, n) = -0x8000; + dest.u16[n] = -0x8000; ics.did_saturate = 1; } else { - VECS8(dest, n) = (uint16_t)v; + dest.u16[n] = (uint16_t)v; } } } } else { for (int n = 0; n < 8; n++) { - VECS8(dest, n) = VECS8(src1, n) + VECS8(src2, n); + dest.u16[n] = src1.u16[n] + src2.u16[n]; } } return IA_NEXT; @@ -2630,31 +2599,32 @@ uint32_t Translate_VECTOR_ADD_I32(IntCodeState& ics, const IntCode* i) { if (arithmetic_flags & ARITHMETIC_SATURATE) { if (arithmetic_flags & ARITHMETIC_UNSIGNED) { for (int n = 0; n < 4; n++) { - uint64_t v = (uint64_t)VECI4(src1, n) + (uint64_t)VECI4(src2, n); + uint64_t v = (uint64_t)src1.u32[n] + (uint64_t)src2.u32[n]; if (v > 0xFFFFFFFF) { - VECI4(dest, n) = 0xFFFFFFFF; + dest.u32[n] = 0xFFFFFFFF; ics.did_saturate = 1; } else { - VECI4(dest, n) = (uint32_t)v; + dest.u32[n] = (uint32_t)v; } } } else { for (int n = 0; n < 4; n++) { - int64_t v = (int64_t)(int32_t)VECI4(src1, n) + (int64_t)(int32_t)VECI4(src2, n); + int64_t v = + (int64_t)(int32_t)src1.u32[n] + (int64_t)(int32_t)src2.u32[n]; if (v > 0x7FFFFFFF) { - VECI4(dest, n) = 0x7FFFFFFF; + dest.u32[n] = 0x7FFFFFFF; ics.did_saturate = 1; } else if (v < -0x80000000ll) { - VECI4(dest, n) = 0x80000000; + dest.u32[n] = 0x80000000; ics.did_saturate = 1; } else { - VECI4(dest, n) = (uint32_t)v; + dest.u32[n] = (uint32_t)v; } } } } else { for (int n = 0; n < 4; n++) { - VECI4(dest, n) = VECI4(src1, n) + VECI4(src2, n); + dest.u32[n] = src1.u32[n] + src2.u32[n]; } } return IA_NEXT; @@ -2664,7 +2634,7 @@ uint32_t Translate_VECTOR_ADD_F32(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - dest.f4[n] = src1.f4[n] + src2.f4[n]; + dest.f32[n] = src1.f32[n] + src2.f32[n]; } return IA_NEXT; } @@ -2728,27 +2698,80 @@ uint32_t IntCode_SUB_F64_F64(IntCodeState& ics, const IntCode* i) { } int Translate_SUB(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { - IntCode_SUB_I8_I8, IntCode_SUB_I16_I16, IntCode_SUB_I32_I32, - IntCode_SUB_I64_I64, IntCode_SUB_F32_F32, IntCode_SUB_F64_F64, + IntCode_SUB_I8_I8, IntCode_SUB_I16_I16, IntCode_SUB_I32_I32, + IntCode_SUB_I64_I64, IntCode_SUB_F32_F32, IntCode_SUB_F64_F64, IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[i->dest->type]); } +uint32_t Translate_VECTOR_SUB_I8(IntCodeState& ics, const IntCode* i) { + const vec128_t& src1 = ics.rf[i->src1_reg].v128; + const vec128_t& src2 = ics.rf[i->src2_reg].v128; + vec128_t& dest = ics.rf[i->dest_reg].v128; + uint32_t flags = i->flags >> 8; + // assert_zero(flags & ARITHMETIC_SATURATE); + if (flags & ARITHMETIC_UNSIGNED) { + for (int n = 0; n < 16; n++) { + dest.u8[n] = src1.u8[n] - src2.u8[n]; + } + } else { + for (int n = 0; n < 16; n++) { + dest.i8[n] = src1.i8[n] - src2.i8[n]; + } + } + return IA_NEXT; +} +uint32_t Translate_VECTOR_SUB_I16(IntCodeState& ics, const IntCode* i) { + const vec128_t& src1 = ics.rf[i->src1_reg].v128; + const vec128_t& src2 = ics.rf[i->src2_reg].v128; + vec128_t& dest = ics.rf[i->dest_reg].v128; + uint32_t flags = i->flags >> 8; + // assert_zero(flags & ARITHMETIC_SATURATE); + if (flags & ARITHMETIC_UNSIGNED) { + for (int n = 0; n < 8; n++) { + dest.u16[n] = src1.u16[n] - src2.u16[n]; + } + } else { + for (int n = 0; n < 8; n++) { + dest.i16[n] = src1.i16[n] - src2.i16[n]; + } + } + return IA_NEXT; +} +uint32_t Translate_VECTOR_SUB_I32(IntCodeState& ics, const IntCode* i) { + const vec128_t& src1 = ics.rf[i->src1_reg].v128; + const vec128_t& src2 = ics.rf[i->src2_reg].v128; + vec128_t& dest = ics.rf[i->dest_reg].v128; + uint32_t flags = i->flags >> 8; + // assert_zero(flags & ARITHMETIC_SATURATE); + if (flags & ARITHMETIC_UNSIGNED) { + for (int n = 0; n < 4; n++) { + dest.u32[n] = src1.u32[n] - src2.u32[n]; + } + } else { + for (int n = 0; n < 4; n++) { + dest.i32[n] = src1.i32[n] - src2.i32[n]; + } + } + return IA_NEXT; +} uint32_t Translate_VECTOR_SUB_F32(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; + uint32_t flags = i->flags >> 8; for (int n = 0; n < 4; n++) { - dest.f4[n] = src1.f4[n] - src2.f4[n]; + dest.f32[n] = src1.f32[n] - src2.f32[n]; } return IA_NEXT; } int Translate_VECTOR_SUB(TranslationContext& ctx, Instr* i) { TypeName part_type = (TypeName)(i->flags & 0xFF); static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, Translate_VECTOR_SUB_F32, IntCode_INVALID_TYPE, + Translate_VECTOR_SUB_I8, Translate_VECTOR_SUB_I16, + Translate_VECTOR_SUB_I32, IntCode_INVALID_TYPE, + Translate_VECTOR_SUB_F32, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, }; return DispatchToC(ctx, i, fns[part_type]); @@ -2783,7 +2806,7 @@ uint32_t IntCode_MUL_V128_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - dest.f4[n] = src1.f4[n] * src2.f4[n]; + dest.f32[n] = src1.f32[n] * src2.f32[n]; } return IA_NEXT; } @@ -2993,7 +3016,7 @@ uint32_t IntCode_DIV_V128_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - dest.f4[n] = src1.f4[n] / src2.f4[n]; + dest.f32[n] = src1.f32[n] / src2.f32[n]; } return IA_NEXT; } @@ -3068,7 +3091,7 @@ uint32_t IntCode_MUL_ADD_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src3 = ics.rf[i->src3_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - dest.f4[n] = src1.f4[n] * src2.f4[n] + src3.f4[n]; + dest.f32[n] = src1.f32[n] * src2.f32[n] + src3.f32[n]; } return IA_NEXT; } @@ -3118,7 +3141,7 @@ uint32_t IntCode_MUL_SUB_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src3 = ics.rf[i->src3_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - dest.f4[n] = src1.f4[n] * src2.f4[n] - src3.f4[n]; + dest.f32[n] = src1.f32[n] * src2.f32[n] - src3.f32[n]; } return IA_NEXT; } @@ -3159,7 +3182,7 @@ uint32_t IntCode_NEG_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (size_t i = 0; i < 4; i++) { - dest.f4[i] = -src1.f4[i]; + dest.f32[i] = -src1.f32[i]; } return IA_NEXT; } @@ -3199,7 +3222,7 @@ uint32_t IntCode_ABS_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (size_t i = 0; i < 4; i++) { - dest.f4[i] = abs(src1.f4[i]); + dest.f32[i] = abs(src1.f32[i]); } return IA_NEXT; } @@ -3255,7 +3278,7 @@ uint32_t IntCode_SQRT_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (size_t i = 0; i < 4; i++) { - dest.f4[i] = sqrt(src1.f4[i]); + dest.f32[i] = sqrt(src1.f32[i]); } return IA_NEXT; } @@ -3272,7 +3295,7 @@ uint32_t IntCode_RSQRT_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - dest.f4[n] = 1 / sqrtf(src1.f4[n]); + dest.f32[n] = 1 / sqrtf(src1.f32[n]); } return IA_NEXT; } @@ -3297,7 +3320,7 @@ uint32_t IntCode_POW2_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (size_t i = 0; i < 4; i++) { - dest.f4[i] = (float)pow(2, src1.f4[i]); + dest.f32[i] = (float)pow(2, src1.f32[i]); } return IA_NEXT; } @@ -3322,7 +3345,7 @@ uint32_t IntCode_LOG2_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (size_t i = 0; i < 4; i++) { - dest.f4[i] = log2(src1.f4[i]); + dest.f32[i] = log2(src1.f32[i]); } return IA_NEXT; } @@ -3356,7 +3379,7 @@ uint32_t IntCode_AND_V128_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - VECI4(dest, n) = VECI4(src1, n) & VECI4(src2, n); + dest.u32[n] = src1.u32[n] & src2.u32[n]; } return IA_NEXT; } @@ -3390,7 +3413,7 @@ uint32_t IntCode_OR_V128_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - VECI4(dest, n) = VECI4(src1, n) | VECI4(src2, n); + dest.u32[n] = src1.u32[n] | src2.u32[n]; } return IA_NEXT; } @@ -3424,7 +3447,7 @@ uint32_t IntCode_XOR_V128_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - VECI4(dest, n) = VECI4(src1, n) ^ VECI4(src2, n); + dest.u32[n] = src1.u32[n] ^ src2.u32[n]; } return IA_NEXT; } @@ -3457,7 +3480,7 @@ uint32_t IntCode_NOT_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - VECI4(dest, n) = ~VECI4(src1, n); + dest.u32[n] = ~src1.u32[n]; } return IA_NEXT; } @@ -3500,7 +3523,7 @@ uint32_t IntCode_VECTOR_SHL_I8(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 16; n++) { - VECB16(dest, n) = VECB16(src1, n) << (VECB16(src2, n) & 0x7); + dest.u8[n] = src1.u8[n] << (src2.u8[n] & 0x7); } return IA_NEXT; } @@ -3509,7 +3532,7 @@ uint32_t IntCode_VECTOR_SHL_I16(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 8; n++) { - VECS8(dest, n) = VECS8(src1, n) << (VECS8(src2, n) & 0xF); + dest.u16[n] = src1.u16[n] << (src2.u16[n] & 0xF); } return IA_NEXT; } @@ -3518,7 +3541,7 @@ uint32_t IntCode_VECTOR_SHL_I32(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - VECI4(dest, n) = VECI4(src1, n) << (VECI4(src2, n) & 0x1F); + dest.u32[n] = src1.u32[n] << (src2.u32[n] & 0x1F); } return IA_NEXT; } @@ -3561,7 +3584,7 @@ uint32_t IntCode_VECTOR_SHR_I8(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 16; n++) { - VECB16(dest, n) = VECB16(src1, n) >> (VECB16(src2, n) & 0x7); + dest.u8[n] = src1.u8[n] >> (src2.u8[n] & 0x7); } return IA_NEXT; } @@ -3570,7 +3593,7 @@ uint32_t IntCode_VECTOR_SHR_I16(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 8; n++) { - VECS8(dest, n) = VECS8(src1, n) >> (VECS8(src2, n) & 0xF); + dest.u16[n] = src1.u16[n] >> (src2.u16[n] & 0xF); } return IA_NEXT; } @@ -3579,7 +3602,7 @@ uint32_t IntCode_VECTOR_SHR_I32(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - VECI4(dest, n) = VECI4(src1, n) >> (VECI4(src2, n) & 0x1F); + dest.u32[n] = src1.u32[n] >> (src2.u32[n] & 0x1F); } return IA_NEXT; } @@ -3622,7 +3645,7 @@ uint32_t IntCode_VECTOR_SHA_I8(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 16; n++) { - VECB16(dest, n) = int8_t(VECB16(src1, n)) >> (VECB16(src2, n) & 0x7); + dest.u8[n] = int8_t(src1.u8[n]) >> (src2.u8[n] & 0x7); } return IA_NEXT; } @@ -3631,7 +3654,7 @@ uint32_t IntCode_VECTOR_SHA_I16(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 8; n++) { - VECS8(dest, n) = int16_t(VECS8(src1, n)) >> (VECS8(src2, n) & 0xF); + dest.u16[n] = int16_t(src1.u16[n]) >> (src2.u16[n] & 0xF); } return IA_NEXT; } @@ -3640,7 +3663,7 @@ uint32_t IntCode_VECTOR_SHA_I32(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - VECI4(dest, n) = int32_t(VECI4(src1, n)) >> (VECI4(src2, n) & 0x1F); + dest.u32[n] = int32_t(src1.u32[n]) >> (src2.u32[n] & 0x1F); } return IA_NEXT; } @@ -3684,9 +3707,41 @@ int Translate_ROTATE_LEFT(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, fns[i->dest->type]); } +uint32_t IntCode_VECTOR_ROTATE_LEFT_I8(IntCodeState& ics, const IntCode* i) { + const vec128_t& src1 = ics.rf[i->src1_reg].v128; + const vec128_t& src2 = ics.rf[i->src2_reg].v128; + vec128_t& dest = ics.rf[i->dest_reg].v128; + for (int n = 0; n < 16; n++) { + dest.u8[n] = poly::rotate_left(src1.u8[n], src2.u8[n] & 0x7); + } + return IA_NEXT; +} +uint32_t IntCode_VECTOR_ROTATE_LEFT_I16(IntCodeState& ics, const IntCode* i) { + const vec128_t& src1 = ics.rf[i->src1_reg].v128; + const vec128_t& src2 = ics.rf[i->src2_reg].v128; + vec128_t& dest = ics.rf[i->dest_reg].v128; + for (int n = 0; n < 8; n++) { + dest.u16[n] = poly::rotate_left(src1.u16[n], src2.u16[n] & 0xF); + } + return IA_NEXT; +} +uint32_t IntCode_VECTOR_ROTATE_LEFT_I32(IntCodeState& ics, const IntCode* i) { + const vec128_t& src1 = ics.rf[i->src1_reg].v128; + const vec128_t& src2 = ics.rf[i->src2_reg].v128; + vec128_t& dest = ics.rf[i->dest_reg].v128; + for (int n = 0; n < 4; n++) { + dest.u32[n] = poly::rotate_left(src1.u32[n], src2.u32[n] & 0x1F); + } + return IA_NEXT; +} int Translate_VECTOR_ROTATE_LEFT(TranslationContext& ctx, Instr* i) { - assert_always(); - return 1; + static IntCodeFn fns[] = { + IntCode_VECTOR_ROTATE_LEFT_I8, IntCode_VECTOR_ROTATE_LEFT_I16, + IntCode_VECTOR_ROTATE_LEFT_I32, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, + IntCode_INVALID_TYPE, + }; + return DispatchToC(ctx, i, fns[i->flags]); } uint32_t IntCode_BYTE_SWAP_I16(IntCodeState& ics, const IntCode* i) { @@ -3705,7 +3760,7 @@ uint32_t IntCode_BYTE_SWAP_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; for (int n = 0; n < 4; n++) { - VECI4(dest, n) = poly::byte_swap(VECI4(src1, n)); + dest.u32[n] = poly::byte_swap(src1.u32[n]); } return IA_NEXT; } @@ -3749,17 +3804,17 @@ int Translate_CNTLZ(TranslationContext& ctx, Instr* i) { uint32_t IntCode_EXTRACT_INT8_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; - ics.rf[i->dest_reg].i8 = VECB16(src1, ics.rf[i->src2_reg].i8); + ics.rf[i->dest_reg].i8 = src1.i8[ics.rf[i->src2_reg].i8 ^ 0x3]; return IA_NEXT; } uint32_t IntCode_EXTRACT_INT16_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; - ics.rf[i->dest_reg].i16 = VECS8(src1, ics.rf[i->src2_reg].i8); + ics.rf[i->dest_reg].i16 = src1.i16[ics.rf[i->src2_reg].i8 ^ 0x1]; return IA_NEXT; } uint32_t IntCode_EXTRACT_INT32_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; - ics.rf[i->dest_reg].i32 = VECI4(src1, ics.rf[i->src2_reg].i8); + ics.rf[i->dest_reg].i32 = src1.i32[ics.rf[i->src2_reg].i8]; return IA_NEXT; } int Translate_EXTRACT(TranslationContext& ctx, Instr* i) { @@ -3800,9 +3855,8 @@ uint32_t IntCode_INSERT_INT8_V128(IntCodeState& ics, const IntCode* i) { const size_t offset = ics.rf[i->src2_reg].i64; const uint8_t part = ics.rf[i->src3_reg].i8; vec128_t& dest = ics.rf[i->dest_reg].v128; - for (size_t n = 0; n < 16; n++) { - VECB16(dest, n) = (n == offset) ? part : VECB16(src1, n); - } + dest = src1; + dest.u8[offset ^ 0x3] = part; return IA_NEXT; } uint32_t IntCode_INSERT_INT16_V128(IntCodeState& ics, const IntCode* i) { @@ -3810,9 +3864,8 @@ uint32_t IntCode_INSERT_INT16_V128(IntCodeState& ics, const IntCode* i) { const size_t offset = ics.rf[i->src2_reg].i64; const uint16_t part = ics.rf[i->src3_reg].i16; vec128_t& dest = ics.rf[i->dest_reg].v128; - for (size_t n = 0; n < 8; n++) { - VECS8(dest, n) = (n == offset) ? part : VECS8(src1, n); - } + dest = src1; + dest.u16[offset ^ 0x1] = part; return IA_NEXT; } uint32_t IntCode_INSERT_INT32_V128(IntCodeState& ics, const IntCode* i) { @@ -3820,9 +3873,8 @@ uint32_t IntCode_INSERT_INT32_V128(IntCodeState& ics, const IntCode* i) { const size_t offset = ics.rf[i->src2_reg].i64; const uint32_t part = ics.rf[i->src3_reg].i32; vec128_t& dest = ics.rf[i->dest_reg].v128; - for (size_t n = 0; n < 4; n++) { - VECI4(dest, n) = (n == offset) ? part : VECI4(src1, n); - } + dest = src1; + dest.u32[offset] = part; return IA_NEXT; } int Translate_INSERT(TranslationContext& ctx, Instr* i) { @@ -3862,7 +3914,7 @@ uint32_t IntCode_SPLAT_V128_INT8(IntCodeState& ics, const IntCode* i) { int8_t src1 = ics.rf[i->src1_reg].i8; vec128_t& dest = ics.rf[i->dest_reg].v128; for (size_t i = 0; i < 16; i++) { - VECB16(dest, i) = src1; + dest.u8[i] = src1; } return IA_NEXT; } @@ -3870,7 +3922,7 @@ uint32_t IntCode_SPLAT_V128_INT16(IntCodeState& ics, const IntCode* i) { int16_t src1 = ics.rf[i->src1_reg].i16; vec128_t& dest = ics.rf[i->dest_reg].v128; for (size_t i = 0; i < 8; i++) { - VECS8(dest, i) = src1; + dest.u16[i] = src1; } return IA_NEXT; } @@ -3878,7 +3930,7 @@ uint32_t IntCode_SPLAT_V128_INT32(IntCodeState& ics, const IntCode* i) { int32_t src1 = ics.rf[i->src1_reg].i32; vec128_t& dest = ics.rf[i->dest_reg].v128; for (size_t i = 0; i < 4; i++) { - VECI4(dest, i) = src1; + dest.u32[i] = src1; } return IA_NEXT; } @@ -3886,7 +3938,7 @@ uint32_t IntCode_SPLAT_V128_FLOAT32(IntCodeState& ics, const IntCode* i) { float src1 = ics.rf[i->src1_reg].f32; vec128_t& dest = ics.rf[i->dest_reg].v128; for (size_t i = 0; i < 4; i++) { - dest.f4[i] = src1; + dest.f32[i] = src1; } return IA_NEXT; } @@ -3928,10 +3980,14 @@ uint32_t IntCode_PERMUTE_V128_BY_INT32(IntCodeState& ics, const IntCode* i) { const vec128_t& src2 = ics.rf[i->src2_reg].v128; const vec128_t& src3 = ics.rf[i->src3_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; - for (size_t i = 0; i < 4; i++) { - size_t b = (table >> ((3 - i) * 8)) & 0x7; - VECI4(dest, i) = b < 4 ? VECI4(src2, b) : VECI4(src3, b - 4); - } + dest.i32[0] = + (table & 0x00000004) ? src3.i32[table & 0x3] : src2.i32[table & 0x3]; + dest.i32[1] = (table & 0x00000400) ? src3.i32[(table >> 8) & 0x3] + : src2.i32[(table >> 8) & 0x3]; + dest.i32[2] = (table & 0x00040000) ? src3.i32[(table >> 16) & 0x3] + : src2.i32[(table >> 16) & 0x3]; + dest.i32[3] = (table & 0x04000000) ? src3.i32[(table >> 24) & 0x3] + : src2.i32[(table >> 24) & 0x3]; return IA_NEXT; } uint32_t IntCode_PERMUTE_V128_BY_V128(IntCodeState& ics, const IntCode* i) { @@ -3941,9 +3997,8 @@ uint32_t IntCode_PERMUTE_V128_BY_V128(IntCodeState& ics, const IntCode* i) { vec128_t& dest = ics.rf[i->dest_reg].v128; dest.low = dest.high = 0; for (size_t n = 0; n < 16; n++) { - uint8_t index = VECB16(table, n) & 0x1F; - VECB16(dest, n) = - index < 16 ? VECB16(src2, index) : VECB16(src3, index - 16); + uint8_t index = (table.u8[n] & 0x1F) ^ 0x3; + dest.u8[n] = index < 16 ? src2.u8[index] : src3.u8[index - 16]; } return IA_NEXT; } @@ -3984,10 +4039,10 @@ uint32_t IntCode_SWIZZLE_V128(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; uint32_t swizzle_mask = ics.rf[i->src2_reg].u32; vec128_t& dest = ics.rf[i->dest_reg].v128; - VECI4(dest, 0) = VECI4(src1, (swizzle_mask >> 6) & 0x3); - VECI4(dest, 1) = VECI4(src1, (swizzle_mask >> 4) & 0x3); - VECI4(dest, 2) = VECI4(src1, (swizzle_mask >> 2) & 0x3); - VECI4(dest, 3) = VECI4(src1, (swizzle_mask)&0x3); + dest.i32[0] = src1.i32[(swizzle_mask >> 0) & 0x3]; + dest.i32[1] = src1.i32[(swizzle_mask >> 2) & 0x3]; + dest.i32[2] = src1.i32[(swizzle_mask >> 4) & 0x3]; + dest.i32[3] = src1.i32[(swizzle_mask >> 6) & 0x3]; return IA_NEXT; } int Translate_SWIZZLE(TranslationContext& ctx, Instr* i) { @@ -4003,48 +4058,36 @@ uint32_t IntCode_PACK_D3DCOLOR(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; // RGBA (XYZW) -> ARGB (WXYZ) - dest.ix = dest.iy = dest.iz = 0; - float r = roundf(((src1.x < 0) ? 0 : ((1 < src1.x) ? 1 : src1.x)) * 255); - float g = roundf(((src1.y < 0) ? 0 : ((1 < src1.y) ? 1 : src1.y)) * 255); - float b = roundf(((src1.z < 0) ? 0 : ((1 < src1.z) ? 1 : src1.z)) * 255); - float a = roundf(((src1.w < 0) ? 0 : ((1 < src1.w) ? 1 : src1.w)) * 255); - dest.iw = ((uint32_t)a << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | - ((uint32_t)b); + dest.ux = dest.uy = dest.uz = 0; + dest.uw = ((src1.uw & 0xFF) << 24) | ((src1.ux & 0xFF) << 16) | + ((src1.uy & 0xFF) << 8) | (src1.uz & 0xFF); return IA_NEXT; } uint32_t IntCode_PACK_FLOAT16_2(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; - dest.ix = dest.iy = dest.iz = 0; - dest.iw = (uint32_t(poly::float_to_half(src1.x)) << 16) | + dest.ux = dest.uy = dest.uz = 0; + dest.uw = (uint32_t(poly::float_to_half(src1.x)) << 16) | poly::float_to_half(src1.y); return IA_NEXT; } uint32_t IntCode_PACK_FLOAT16_4(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; - dest.ix = dest.iy = 0; - dest.iz = (uint32_t(poly::float_to_half(src1.x)) << 16) | + dest.ux = dest.uy = 0; + dest.uz = (uint32_t(poly::float_to_half(src1.x)) << 16) | poly::float_to_half(src1.y); - dest.iw = (uint32_t(poly::float_to_half(src1.z)) << 16) | + dest.uw = (uint32_t(poly::float_to_half(src1.z)) << 16) | poly::float_to_half(src1.w); return IA_NEXT; } uint32_t IntCode_PACK_SHORT_2(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; - // sx = 3 + (x / 1<<22) - // x = (sx - 3) * 1<<22 - float sx = src1.x; - float sy = src1.y; - union { - int16_t dx; - int16_t dy; - }; - dx = (int16_t)((sx - 3.0f) * (float)(1 << 22)); - dy = (int16_t)((sy - 3.0f) * (float)(1 << 22)); - dest.ix = dest.iy = dest.iz = 0; - dest.iw = ((uint32_t)dx << 16) | dy; + int16_t dx = int16_t(poly::saturate(src1.x) * 32767.0f); + int16_t dy = int16_t(poly::saturate(src1.y) * 32767.0f); + dest.ux = dest.uy = dest.uz = 0; + dest.uw = (uint32_t(uint16_t(dx)) << 16) | uint32_t(uint16_t(dy)); return IA_NEXT; } int Translate_PACK(TranslationContext& ctx, Instr* i) { @@ -4061,93 +4104,85 @@ uint32_t IntCode_UNPACK_D3DCOLOR(IntCodeState& ics, const IntCode* i) { vec128_t& dest = ics.rf[i->dest_reg].v128; // ARGB (WXYZ) -> RGBA (XYZW) // XMLoadColor - int32_t src = (int32_t)src1.iw; - dest.f4[0] = (float)((src >> 16) & 0xFF) * (1.0f / 255.0f); - dest.f4[1] = (float)((src >> 8) & 0xFF) * (1.0f / 255.0f); - dest.f4[2] = (float)(src & 0xFF) * (1.0f / 255.0f); - dest.f4[3] = (float)((src >> 24) & 0xFF) * (1.0f / 255.0f); + int32_t src = (int32_t)src1.uw; + dest.u32[0] = 0x3F800000 | ((src >> 16) & 0xFF); + dest.u32[1] = 0x3F800000 | ((src >> 8) & 0xFF); + dest.u32[2] = 0x3F800000 | (src & 0xFF); + dest.u32[3] = 0x3F800000 | ((src >> 24) & 0xFF); return IA_NEXT; } uint32_t IntCode_UNPACK_FLOAT16_2(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; - uint32_t src = src1.iw; - for (int n = 0; n < 2; n++) { - dest.f4[n] = poly::half_to_float(uint16_t(src)); - src >>= 16; - } - dest.f4[2] = 0.0f; - dest.f4[3] = 1.0f; + dest.f32[0] = poly::half_to_float(uint16_t(src1.uw >> 16)); + dest.f32[1] = poly::half_to_float(uint16_t(src1.uw)); + dest.f32[2] = 0.0f; + dest.f32[3] = 1.0f; return IA_NEXT; } uint32_t IntCode_UNPACK_FLOAT16_4(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; - uint64_t src = src1.iz | ((uint64_t)src1.iw << 32); - for (int n = 0; n < 4; n++) { - dest.f4[n] = poly::half_to_float(uint16_t(src)); - src >>= 16; - } + dest.f32[0] = poly::half_to_float(src1.u16[5]); + dest.f32[1] = poly::half_to_float(src1.u16[4]); + dest.f32[2] = poly::half_to_float(src1.u16[7]); + dest.f32[3] = poly::half_to_float(src1.u16[6]); return IA_NEXT; } uint32_t IntCode_UNPACK_SHORT_2(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; // XMLoadShortN2 - union { - int16_t sx; - int16_t sy; - }; - sx = (int16_t)(src1.iw >> 16); - sy = (int16_t)src1.iw; - dest.f4[0] = 3.0f + ((float)sx / (float)(1 << 22)); - dest.f4[1] = 3.0f + ((float)sy / (float)(1 << 22)); - dest.f4[2] = 0.0f; - dest.f4[3] = 1.0f; // 3? + uint16_t sx = src1.uw >> 16; + uint16_t sy = src1.uw & 0xFFFF; + dest.u32[0] = sx & 0x8000 ? (0x403F0000 | sx) : (0x40400000 | sx); + dest.u32[1] = sy & 0x8000 ? (0x403F0000 | sy) : (0x40400000 | sy); + dest.u32[2] = 0; + dest.u32[3] = 0x3F800000; return IA_NEXT; } uint32_t IntCode_UNPACK_S8_IN_16_LO(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; - VECS8(dest, 0) = (int16_t)(int8_t)VECB16(src1, 8 + 0); - VECS8(dest, 1) = (int16_t)(int8_t)VECB16(src1, 8 + 1); - VECS8(dest, 2) = (int16_t)(int8_t)VECB16(src1, 8 + 2); - VECS8(dest, 3) = (int16_t)(int8_t)VECB16(src1, 8 + 3); - VECS8(dest, 4) = (int16_t)(int8_t)VECB16(src1, 8 + 4); - VECS8(dest, 5) = (int16_t)(int8_t)VECB16(src1, 8 + 5); - VECS8(dest, 6) = (int16_t)(int8_t)VECB16(src1, 8 + 6); - VECS8(dest, 7) = (int16_t)(int8_t)VECB16(src1, 8 + 7); + dest.i16[0] = (int16_t)src1.i8[8 + 0]; + dest.i16[1] = (int16_t)src1.i8[8 + 1]; + dest.i16[2] = (int16_t)src1.i8[8 + 2]; + dest.i16[3] = (int16_t)src1.i8[8 + 3]; + dest.i16[4] = (int16_t)src1.i8[8 + 4]; + dest.i16[5] = (int16_t)src1.i8[8 + 5]; + dest.i16[6] = (int16_t)src1.i8[8 + 6]; + dest.i16[7] = (int16_t)src1.i8[8 + 7]; return IA_NEXT; } uint32_t IntCode_UNPACK_S8_IN_16_HI(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; - VECS8(dest, 0) = (int16_t)(int8_t)VECB16(src1, 0); - VECS8(dest, 1) = (int16_t)(int8_t)VECB16(src1, 1); - VECS8(dest, 2) = (int16_t)(int8_t)VECB16(src1, 2); - VECS8(dest, 3) = (int16_t)(int8_t)VECB16(src1, 3); - VECS8(dest, 4) = (int16_t)(int8_t)VECB16(src1, 4); - VECS8(dest, 5) = (int16_t)(int8_t)VECB16(src1, 5); - VECS8(dest, 6) = (int16_t)(int8_t)VECB16(src1, 6); - VECS8(dest, 7) = (int16_t)(int8_t)VECB16(src1, 7); + dest.i16[0] = (int16_t)src1.i8[0]; + dest.i16[1] = (int16_t)src1.i8[1]; + dest.i16[2] = (int16_t)src1.i8[2]; + dest.i16[3] = (int16_t)src1.i8[3]; + dest.i16[4] = (int16_t)src1.i8[4]; + dest.i16[5] = (int16_t)src1.i8[5]; + dest.i16[6] = (int16_t)src1.i8[6]; + dest.i16[7] = (int16_t)src1.i8[7]; return IA_NEXT; } uint32_t IntCode_UNPACK_S16_IN_32_LO(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; - VECI4(dest, 0) = (int32_t)(int16_t)VECS8(src1, 4 + 0); - VECI4(dest, 1) = (int32_t)(int16_t)VECS8(src1, 4 + 1); - VECI4(dest, 2) = (int32_t)(int16_t)VECS8(src1, 4 + 2); - VECI4(dest, 3) = (int32_t)(int16_t)VECS8(src1, 4 + 3); + dest.i32[0] = (int32_t)src1.i16[4 + 0]; + dest.i32[1] = (int32_t)src1.i16[4 + 1]; + dest.i32[2] = (int32_t)src1.i16[4 + 2]; + dest.i32[3] = (int32_t)src1.i16[4 + 3]; return IA_NEXT; } uint32_t IntCode_UNPACK_S16_IN_32_HI(IntCodeState& ics, const IntCode* i) { const vec128_t& src1 = ics.rf[i->src1_reg].v128; vec128_t& dest = ics.rf[i->dest_reg].v128; - VECI4(dest, 0) = (int32_t)(int16_t)VECS8(src1, 0); - VECI4(dest, 1) = (int32_t)(int16_t)VECS8(src1, 1); - VECI4(dest, 2) = (int32_t)(int16_t)VECS8(src1, 2); - VECI4(dest, 3) = (int32_t)(int16_t)VECS8(src1, 3); + dest.i32[0] = (int32_t)src1.i16[0]; + dest.i32[1] = (int32_t)src1.i16[1]; + dest.i32[2] = (int32_t)src1.i16[2]; + dest.i32[3] = (int32_t)src1.i16[3]; return IA_NEXT; } int Translate_UNPACK(TranslationContext& ctx, Instr* i) { diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index 3762fdd4e..0dac2fb36 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -41,6 +41,7 @@ using alloy::runtime::ThreadState; static const size_t MAX_CODE_SIZE = 1 * 1024 * 1024; static const size_t STASH_OFFSET = 32; +static const size_t STASH_OFFSET_HIGH = 32 + 16; // If we are running with tracing on we have to store the EFLAGS in the stack, // otherwise our calls out to C to print will clear it before DID_CARRY/etc @@ -786,8 +787,8 @@ void X64Emitter::MovMem64(const RegExp& addr, uint64_t v) { Address X64Emitter::GetXmmConstPtr(XmmConst id) { static const vec128_t xmm_consts[] = { - /* XMMZero */ vec128f(0.0f, 0.0f, 0.0f, 0.0f), - /* XMMOne */ vec128f(1.0f, 1.0f, 1.0f, 1.0f), + /* XMMZero */ vec128f(0.0f), + /* XMMOne */ vec128f(1.0f), /* XMMNegativeOne */ vec128f(-1.0f, -1.0f, -1.0f, -1.0f), /* XMMMaskX16Y16 */ vec128i(0x0000FFFFu, 0xFFFF0000u, 0x00000000u, 0x00000000u), @@ -808,14 +809,24 @@ Address X64Emitter::GetXmmConstPtr(XmmConst id) { 0xFFFFFFFFu, 0x7FFFFFFFu), /* XMMByteSwapMask */ vec128i(0x00010203u, 0x04050607u, 0x08090A0Bu, 0x0C0D0E0Fu), - /* XMMPermuteControl15 */ vec128b(15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15), + /* XMMPermuteControl15 */ vec128b(15), /* XMMPackD3DCOLOR */ vec128i(0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x0C000408u), /* XMMUnpackD3DCOLOR */ vec128i(0xFFFFFF0Eu, 0xFFFFFF0Du, 0xFFFFFF0Cu, 0xFFFFFF0Fu), - /* XMMOneOver255 */ vec128f(1.0f / 255.0f, 1.0f / 255.0f, - 1.0f / 255.0f, 1.0f / 255.0f), + /* XMMPackFLOAT16_2 */ vec128i(0xFFFFFFFFu, 0xFFFFFFFFu, + 0xFFFFFFFFu, 0x01000302u), + /* XMMUnpackFLOAT16_2 */ vec128i(0x0D0C0F0Eu, 0xFFFFFFFFu, + 0xFFFFFFFFu, 0xFFFFFFFFu), + /* XMMPackFLOAT16_4 */ vec128i(0xFFFFFFFFu, 0xFFFFFFFFu, + 0x05040706u, 0x01000302u), + /* XMMUnpackFLOAT16_4 */ vec128i(0x09080B0Au, 0x0D0C0F0Eu, + 0xFFFFFFFFu, 0xFFFFFFFFu), + /* XMMPackSHORT_2 */ vec128i(0xFFFFFFFFu, 0xFFFFFFFFu, + 0xFFFFFFFFu, 0x01000504u), + /* XMMUnpackSHORT_2 */ vec128i(0xFFFF0F0Eu, 0xFFFF0D0Cu, + 0xFFFFFFFFu, 0xFFFFFFFFu), + /* XMMOneOver255 */ vec128f(1.0f / 255.0f), /* XMMMaskEvenPI16 */ vec128i(0x0000FFFFu, 0x0000FFFFu, 0x0000FFFFu, 0x0000FFFFu), /* XMMShiftMaskEvenPI16 */ vec128i(0x0000000Fu, 0x0000000Fu, @@ -826,8 +837,8 @@ Address X64Emitter::GetXmmConstPtr(XmmConst id) { 0x000000FFu, 0x000000FFu), /* XMMUnsignedDwordMax */ vec128i(0xFFFFFFFFu, 0x00000000u, 0xFFFFFFFFu, 0x00000000u), - /* XMM255 */ vec128f(255.0f, 255.0f, 255.0f, 255.0f), - /* XMMPI32 */ vec128i(32, 32, 32, 32), + /* XMM255 */ vec128f(255.0f), + /* XMMPI32 */ vec128i(32), /* XMMSignMaskI8 */ vec128i(0x80808080u, 0x80808080u, 0x80808080u, 0x80808080u), /* XMMSignMaskI16 */ vec128i(0x80008000u, 0x80008000u, @@ -836,6 +847,8 @@ Address X64Emitter::GetXmmConstPtr(XmmConst id) { 0x80000000u, 0x80000000u), /* XMMSignMaskF32 */ vec128i(0x80000000u, 0x80000000u, 0x80000000u, 0x80000000u), + /* XMMShortMinPS */ vec128f(SHRT_MIN), + /* XMMShortMaxPS */ vec128f(SHRT_MAX), }; // TODO(benvanik): cache base pointer somewhere? stack? It'd be nice to // prevent this move. @@ -901,19 +914,12 @@ void X64Emitter::LoadConstantXmm(Xbyak::Xmm dest, double v) { } } -Address X64Emitter::StashXmm(const Xmm& r) { - auto addr = ptr[rsp + STASH_OFFSET]; +Address X64Emitter::StashXmm(int index, const Xmm& r) { + auto addr = ptr[rsp + STASH_OFFSET + (index * 16)]; vmovups(addr, r); return addr; } -Address X64Emitter::StashXmm(const vec128_t& v) { - auto addr = ptr[rsp + STASH_OFFSET]; - LoadConstantXmm(xmm0, v); - vmovups(addr, xmm0); - return addr; -} - } // namespace x64 } // namespace backend } // namespace alloy diff --git a/src/alloy/backend/x64/x64_emitter.h b/src/alloy/backend/x64/x64_emitter.h index e63b72b7f..7755c8cdb 100644 --- a/src/alloy/backend/x64/x64_emitter.h +++ b/src/alloy/backend/x64/x64_emitter.h @@ -56,6 +56,12 @@ enum XmmConst { XMMPermuteControl15, XMMPackD3DCOLOR, XMMUnpackD3DCOLOR, + XMMPackFLOAT16_2, + XMMUnpackFLOAT16_2, + XMMPackFLOAT16_4, + XMMUnpackFLOAT16_4, + XMMPackSHORT_2, + XMMUnpackSHORT_2, XMMOneOver255, XMMMaskEvenPI16, XMMShiftMaskEvenPI16, @@ -68,6 +74,8 @@ enum XmmConst { XMMSignMaskI16, XMMSignMaskI32, XMMSignMaskF32, + XMMShortMinPS, + XMMShortMaxPS, }; // Unfortunately due to the design of xbyak we have to pass this to the ctor. @@ -158,8 +166,7 @@ class X64Emitter : public Xbyak::CodeGenerator { void LoadConstantXmm(Xbyak::Xmm dest, float v); void LoadConstantXmm(Xbyak::Xmm dest, double v); void LoadConstantXmm(Xbyak::Xmm dest, const vec128_t& v); - Xbyak::Address StashXmm(const Xbyak::Xmm& r); - Xbyak::Address StashXmm(const vec128_t& v); + Xbyak::Address StashXmm(int index, const Xbyak::Xmm& r); size_t stack_size() const { return stack_size_; } diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index 2edda3870..f992b9949 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -994,24 +994,23 @@ EMITTER_OPCODE_TABLE( // ============================================================================ // OPCODE_LOAD_VECTOR_SHL // ============================================================================ -static vec128_t lvsl_table[17] = { - vec128b( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), - vec128b( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), - vec128b( 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17), - vec128b( 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18), - vec128b( 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19), - vec128b( 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20), - vec128b( 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21), - vec128b( 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22), - vec128b( 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23), - vec128b( 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24), - vec128b(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25), - vec128b(11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26), - vec128b(12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27), - vec128b(13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28), - vec128b(14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29), - vec128b(15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30), - vec128b(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31), +static const vec128_t lvsl_table[16] = { + vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), + vec128b(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), + vec128b(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17), + vec128b(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18), + vec128b(4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19), + vec128b(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20), + vec128b(6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21), + vec128b(7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22), + vec128b(8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23), + vec128b(9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24), + vec128b(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25), + vec128b(11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26), + vec128b(12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27), + vec128b(13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28), + vec128b(14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29), + vec128b(15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30), }; EMITTER(LOAD_VECTOR_SHL_I8, MATCH(I, I8<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { @@ -1021,17 +1020,10 @@ EMITTER(LOAD_VECTOR_SHL_I8, MATCH(I, I8<>>)) { e.mov(e.rax, (uintptr_t)&lvsl_table[sh]); e.vmovaps(i.dest, e.ptr[e.rax]); } else { -#if XE_DEBUG - // We should only ever be getting values in [0,16]. Assert that. - Xbyak::Label skip; - e.cmp(i.src1, 17); - e.jb(skip); - e.Trap(); - e.L(skip); -#endif // XE_DEBUG // TODO(benvanik): find a cheaper way of doing this. e.movzx(e.rdx, i.src1); - e.shl(e.rdx, 4); + e.and(e.dx, 0xF); + e.shl(e.dx, 4); e.mov(e.rax, (uintptr_t)lvsl_table); e.vmovaps(i.dest, e.ptr[e.rax + e.rdx]); e.ReloadEDX(); @@ -1046,24 +1038,23 @@ EMITTER_OPCODE_TABLE( // ============================================================================ // OPCODE_LOAD_VECTOR_SHR // ============================================================================ -static vec128_t lvsr_table[17] = { - vec128b(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31), - vec128b(15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30), - vec128b(14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29), - vec128b(13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28), - vec128b(12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27), - vec128b(11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26), - vec128b(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25), - vec128b( 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24), - vec128b( 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23), - vec128b( 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22), - vec128b( 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21), - vec128b( 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20), - vec128b( 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19), - vec128b( 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18), - vec128b( 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17), - vec128b( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), - vec128b( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), +static const vec128_t lvsr_table[16] = { + vec128b(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31), + vec128b(15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30), + vec128b(14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29), + vec128b(13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28), + vec128b(12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27), + vec128b(11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26), + vec128b(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25), + vec128b(9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24), + vec128b(8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23), + vec128b(7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22), + vec128b(6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21), + vec128b(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20), + vec128b(4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19), + vec128b(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18), + vec128b(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17), + vec128b(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), }; EMITTER(LOAD_VECTOR_SHR_I8, MATCH(I, I8<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { @@ -1073,17 +1064,10 @@ EMITTER(LOAD_VECTOR_SHR_I8, MATCH(I, I8<>>)) { e.mov(e.rax, (uintptr_t)&lvsr_table[sh]); e.vmovaps(i.dest, e.ptr[e.rax]); } else { -#if XE_DEBUG - // We should only ever be getting values in [0,16]. Assert that. - Xbyak::Label skip; - e.cmp(i.src1, 17); - e.jb(skip); - e.Trap(); - e.L(skip); -#endif // XE_DEBUG // TODO(benvanik): find a cheaper way of doing this. e.movzx(e.rdx, i.src1); - e.shl(e.rdx, 4); + e.and(e.dx, 0xF); + e.shl(e.dx, 4); e.mov(e.rax, (uintptr_t)lvsr_table); e.vmovaps(i.dest, e.ptr[e.rax + e.rdx]); e.ReloadEDX(); @@ -2676,7 +2660,41 @@ EMITTER_OPCODE_TABLE( // ============================================================================ // OPCODE_VECTOR_ADD // ============================================================================ -EMITTER(VECTOR_ADD, MATCH(I, V128<>, V128<>>)) { +EMITTER(VECTOR_ADD, MATCH(I, V128<>, V128<>>)){ + static __m128i EmulateVectorAddUnsignedSatI32(void*, __m128i src1, + __m128i src2){ + alignas(16) uint32_t a[4]; + alignas(16) uint32_t b[4]; + _mm_store_si128(reinterpret_cast<__m128i*>(a), src1); + _mm_store_si128(reinterpret_cast<__m128i*>(b), src2); + for (size_t i = 0; i < 4; ++i) { + uint64_t v = (uint64_t)a[i] + (uint64_t)b[i]; + if (v > 0xFFFFFFFF) { + a[i] = 0xFFFFFFFF; + } else { + a[i] = (uint32_t)v; + } + } + return _mm_load_si128(reinterpret_cast<__m128i*>(a)); + } + static __m128i EmulateVectorAddSignedSatI32(void*, __m128i src1, + __m128i src2){ + alignas(16) int32_t a[4]; + alignas(16) int32_t b[4]; + _mm_store_si128(reinterpret_cast<__m128i*>(a), src1); + _mm_store_si128(reinterpret_cast<__m128i*>(b), src2); + for (size_t i = 0; i < 4; ++i) { + int64_t v = (int64_t)a[i] + (int64_t)b[i]; + if (v > 0x7FFFFFFF) { + a[i] = 0x7FFFFFFF; + } else if (v < -0x80000000ll) { + a[i] = 0x80000000; + } else { + a[i] = (uint32_t)v; + } + } + return _mm_load_si128(reinterpret_cast<__m128i*>(a)); + } static void Emit(X64Emitter& e, const EmitArgType& i) { EmitCommutativeBinaryXmmOp(e, i, [&i](X64Emitter& e, const Xmm& dest, const Xmm& src1, const Xmm& src2) { @@ -2712,44 +2730,66 @@ EMITTER(VECTOR_ADD, MATCH(I, V128<>, V128<>>)) { case INT32_TYPE: if (saturate) { if (is_unsigned) { - // We reuse all these temps... - assert_true(src1 != e.xmm0 && src1 != e.xmm1 && src1 != e.xmm2); - assert_true(src2 != e.xmm0 && src2 != e.xmm1 && src2 != e.xmm2); - // Clamp to 0xFFFFFFFF. - // Wish there was a vpaddusd... - // | A | B | C | D | - // | B | D | - e.vpsllq(e.xmm0, src1, 32); - e.vpsllq(e.xmm1, src2, 32); - e.vpsrlq(e.xmm0, 32); - e.vpsrlq(e.xmm1, 32); - e.vpaddq(e.xmm0, e.xmm1); - e.vpcmpgtq(e.xmm0, e.GetXmmConstPtr(XMMUnsignedDwordMax)); - e.vpsllq(e.xmm0, 32); - e.vpsrlq(e.xmm0, 32); - // | A | C | - e.vpsrlq(e.xmm1, src1, 32); - e.vpsrlq(e.xmm2, src2, 32); - e.vpaddq(e.xmm1, e.xmm2); - e.vpcmpgtq(e.xmm1, e.GetXmmConstPtr(XMMUnsignedDwordMax)); - e.vpsllq(e.xmm1, 32); - // xmm0 = mask for with saturated dwords == 111... - e.vpor(e.xmm0, e.xmm1); - e.vpaddd(dest, src1, src2); - // dest.f[n] = xmm1.f[n] ? xmm1.f[n] : dest.f[n]; - e.vblendvps(dest, dest, e.xmm1, e.xmm1); + // TODO(benvanik): broken with UINT32MAX+1 + //// We reuse all these temps... + //assert_true(src1 != e.xmm0 && src1 != e.xmm1 && src1 != e.xmm2); + //assert_true(src2 != e.xmm0 && src2 != e.xmm1 && src2 != e.xmm2); + //// Clamp to 0xFFFFFFFF. + //// Wish there was a vpaddusd... + //// | A | B | C | D | + //// | B | D | + //e.vpsllq(e.xmm0, src1, 32); + //e.vpsllq(e.xmm1, src2, 32); + //e.vpsrlq(e.xmm0, 32); + //e.vpsrlq(e.xmm1, 32); + //e.vpaddq(e.xmm0, e.xmm1); + //e.vpcmpgtq(e.xmm0, e.GetXmmConstPtr(XMMUnsignedDwordMax)); + //e.vpsllq(e.xmm0, 32); + //e.vpsrlq(e.xmm0, 32); + //// | A | C | + //e.vpsrlq(e.xmm1, src1, 32); + //e.vpsrlq(e.xmm2, src2, 32); + //e.vpaddq(e.xmm1, e.xmm2); + //e.vpcmpgtq(e.xmm1, e.GetXmmConstPtr(XMMUnsignedDwordMax)); + //e.vpsllq(e.xmm1, 32); + //// xmm0 = mask for with saturated dwords == 111... + //e.vpor(e.xmm0, e.xmm1); + //e.vpaddd(dest, src1, src2); + //// dest.f[n] = xmm1.f[n] ? xmm1.f[n] : dest.f[n]; + //e.vblendvps(dest, dest, e.xmm1, e.xmm1); + if (i.src2.is_constant) { + e.LoadConstantXmm(e.xmm0, i.src2.constant()); + e.lea(e.r9, e.StashXmm(1, e.xmm0)); + } else { + e.lea(e.r9, e.StashXmm(1, i.src2)); + } + e.lea(e.r8, e.StashXmm(0, i.src1)); + e.CallNativeSafe( + reinterpret_cast(EmulateVectorAddUnsignedSatI32)); + e.vmovaps(i.dest, e.xmm0); } else { // https://software.intel.com/en-us/forums/topic/285219 + // TODO(benvanik): this is broken with INTMAX+1. // We reuse all these temps... - assert_true(src1 != e.xmm0 && src1 != e.xmm1 && src1 != e.xmm2); - assert_true(src2 != e.xmm0 && src2 != e.xmm1 && src2 != e.xmm2); - e.vpaddd(e.xmm0, src1, src2); // res - e.vpand(e.xmm1, src1, src2); // sign_and - e.vpandn(e.xmm2, e.xmm0, e.xmm1); // min_sat_mask - e.vblendvps(e.xmm2, e.xmm0, e.GetXmmConstPtr(XMMSignMaskPS), e.xmm2); - e.vpor(e.xmm1, src1, src2); // sign_or - e.vpandn(e.xmm1, e.xmm0); // max_sat_mask - e.vblendvps(dest, e.GetXmmConstPtr(XMMAbsMaskPS), e.xmm1); + //assert_true(src1 != e.xmm0 && src1 != e.xmm1 && src1 != e.xmm2); + //assert_true(src2 != e.xmm0 && src2 != e.xmm1 && src2 != e.xmm2); + //e.vpaddd(e.xmm0, src1, src2); // res + //e.vpand(e.xmm1, src1, src2); // sign_and + //e.vpandn(e.xmm2, e.xmm0, e.xmm1); // min_sat_mask + //e.vblendvps(dest, e.xmm0, e.GetXmmConstPtr(XMMSignMaskPS), e.xmm2); + //e.vpor(e.xmm1, src1, src2); // sign_or + //e.vpandn(e.xmm1, e.xmm0); // max_sat_mask + //e.vblendvps(dest, e.GetXmmConstPtr(XMMAbsMaskPS), e.xmm1); + if (i.src2.is_constant) { + e.LoadConstantXmm(e.xmm0, i.src2.constant()); + e.lea(e.r9, e.StashXmm(1, e.xmm0)); + } else { + e.lea(e.r9, e.StashXmm(1, i.src2)); + } + e.lea(e.r8, e.StashXmm(0, i.src1)); + e.CallNativeSafe( + reinterpret_cast(EmulateVectorAddSignedSatI32)); + e.vmovaps(i.dest, e.xmm0); } } else { e.vpaddd(dest, src1, src2); @@ -2852,17 +2892,17 @@ EMITTER_OPCODE_TABLE( // OPCODE_VECTOR_SUB // ============================================================================ EMITTER(VECTOR_SUB, MATCH(I, V128<>, V128<>>)) { - static __m128i EmulateVectorSubSignedSatI32(__m128i src1, __m128i src2) { + static __m128i EmulateVectorSubSignedSatI32(void*, __m128i src1, __m128i src2) { alignas(16) int32_t src1v[4]; alignas(16) int32_t src2v[4]; alignas(16) int32_t value[4]; - _mm_store_si128(reinterpret_cast<__m128i*>(&src1v), src1); - _mm_store_si128(reinterpret_cast<__m128i*>(&src2v), src2); + _mm_store_si128(reinterpret_cast<__m128i*>(src1v), src1); + _mm_store_si128(reinterpret_cast<__m128i*>(src2v), src2); for (size_t i = 0; i < 4; ++i) { auto t = int64_t(src1v[i]) - int64_t(src2v[i]); value[i] = t < INT_MIN ? INT_MIN : (t > INT_MAX ? INT_MAX : int32_t(t)); } - return _mm_load_si128(reinterpret_cast<__m128i*>(&value)); + return _mm_load_si128(reinterpret_cast<__m128i*>(value)); } static void Emit(X64Emitter& e, const EmitArgType& i) { EmitCommutativeBinaryXmmOp(e, i, @@ -2901,8 +2941,8 @@ EMITTER(VECTOR_SUB, MATCH(I, V128<>, V128<>>)) { if (is_unsigned) { assert_always(); } else { - e.lea(e.r8, e.StashXmm(i.src1)); - e.lea(e.r9, e.StashXmm(i.src2)); + e.lea(e.r8, e.StashXmm(0, i.src1)); + e.lea(e.r9, e.StashXmm(1, i.src2)); e.CallNativeSafe( reinterpret_cast(EmulateVectorSubSignedSatI32)); e.vmovaps(i.dest, e.xmm0); @@ -3638,7 +3678,7 @@ EMITTER_OPCODE_TABLE( // TODO(benvanik): use approx here: // http://jrfonseca.blogspot.com/2008/09/fast-sse2-pow-tables-or-polynomials.html EMITTER(POW2_F32, MATCH(I, F32<>>)) { - static __m128 EmulatePow2(__m128 src) { + static __m128 EmulatePow2(void*, __m128 src) { float src_value; _mm_store_ss(&src_value, src); float result = std::pow(2.0f, src_value); @@ -3646,13 +3686,13 @@ EMITTER(POW2_F32, MATCH(I, F32<>>)) { } static void Emit(X64Emitter& e, const EmitArgType& i) { assert_always(); - e.lea(e.r8, e.StashXmm(i.src1)); + e.lea(e.r8, e.StashXmm(0, i.src1)); e.CallNativeSafe(reinterpret_cast(EmulatePow2)); e.vmovaps(i.dest, e.xmm0); } }; EMITTER(POW2_F64, MATCH(I, F64<>>)) { - static __m128d EmulatePow2(__m128d src) { + static __m128d EmulatePow2(void*, __m128d src) { double src_value; _mm_store_sd(&src_value, src); double result = std::pow(2, src_value); @@ -3660,13 +3700,13 @@ EMITTER(POW2_F64, MATCH(I, F64<>>)) { } static void Emit(X64Emitter& e, const EmitArgType& i) { assert_always(); - e.lea(e.r8, e.StashXmm(i.src1)); + e.lea(e.r8, e.StashXmm(0, i.src1)); e.CallNativeSafe(reinterpret_cast(EmulatePow2)); e.vmovaps(i.dest, e.xmm0); } }; EMITTER(POW2_V128, MATCH(I, V128<>>)) { - static __m128 EmulatePow2(__m128 src) { + static __m128 EmulatePow2(void*, __m128 src) { alignas(16) float values[4]; _mm_store_ps(values, src); for (size_t i = 0; i < 4; ++i) { @@ -3675,7 +3715,7 @@ EMITTER(POW2_V128, MATCH(I, V128<>>)) { return _mm_load_ps(values); } static void Emit(X64Emitter& e, const EmitArgType& i) { - e.lea(e.r8, e.StashXmm(i.src1)); + e.lea(e.r8, e.StashXmm(0, i.src1)); e.CallNativeSafe(reinterpret_cast(EmulatePow2)); e.vmovaps(i.dest, e.xmm0); } @@ -3694,7 +3734,7 @@ EMITTER_OPCODE_TABLE( // http://jrfonseca.blogspot.com/2008/09/fast-sse2-pow-tables-or-polynomials.html // TODO(benvanik): this emulated fn destroys all xmm registers! don't do it! EMITTER(LOG2_F32, MATCH(I, F32<>>)) { - static __m128 EmulateLog2(__m128 src) { + static __m128 EmulateLog2(void*, __m128 src) { float src_value; _mm_store_ss(&src_value, src); float result = std::log2(src_value); @@ -3702,13 +3742,13 @@ EMITTER(LOG2_F32, MATCH(I, F32<>>)) { } static void Emit(X64Emitter& e, const EmitArgType& i) { assert_always(); - e.lea(e.r8, e.StashXmm(i.src1)); + e.lea(e.r8, e.StashXmm(0, i.src1)); e.CallNativeSafe(reinterpret_cast(EmulateLog2)); e.vmovaps(i.dest, e.xmm0); } }; EMITTER(LOG2_F64, MATCH(I, F64<>>)) { - static __m128d EmulateLog2(__m128d src) { + static __m128d EmulateLog2(void*, __m128d src) { double src_value; _mm_store_sd(&src_value, src); double result = std::log2(src_value); @@ -3716,13 +3756,13 @@ EMITTER(LOG2_F64, MATCH(I, F64<>>)) { } static void Emit(X64Emitter& e, const EmitArgType& i) { assert_always(); - e.lea(e.r8, e.StashXmm(i.src1)); + e.lea(e.r8, e.StashXmm(0, i.src1)); e.CallNativeSafe(reinterpret_cast(EmulateLog2)); e.vmovaps(i.dest, e.xmm0); } }; EMITTER(LOG2_V128, MATCH(I, V128<>>)) { - static __m128 EmulateLog2(__m128 src) { + static __m128 EmulateLog2(void*, __m128 src) { alignas(16) float values[4]; _mm_store_ps(values, src); for (size_t i = 0; i < 4; ++i) { @@ -3731,7 +3771,7 @@ EMITTER(LOG2_V128, MATCH(I, V128<>>)) { return _mm_load_ps(values); } static void Emit(X64Emitter& e, const EmitArgType& i) { - e.lea(e.r8, e.StashXmm(i.src1)); + e.lea(e.r8, e.StashXmm(0, i.src1)); e.CallNativeSafe(reinterpret_cast(EmulateLog2)); e.vmovaps(i.dest, e.xmm0); } @@ -4132,131 +4172,83 @@ EMITTER(VECTOR_SHL_V128, MATCH(I, V128<>, V128<>>)) { break; } } - static void EmitInt8(X64Emitter& e, const EmitArgType& i) { - if (i.src2.is_constant) { - const auto& shamt = i.src2.constant(); - bool all_same = true; - for (size_t n = 0; n < 16 - n; ++n) { - if (shamt.b16[n] != shamt.b16[n + 1]) { - all_same = false; - break; - } - } - if (all_same) { - // Every count is the same. - uint8_t sh = shamt.b16[0] & 0x7; - if (!sh) { - // No shift? - e.vmovaps(i.dest, i.src1); - } else { - // Even bytes. - e.vpsrlw(e.xmm0, i.src1, 8); - e.vpsllw(e.xmm0, sh + 8); - // Odd bytes. - e.vpsllw(i.dest, i.src1, 8); - e.vpsrlw(i.dest, 8 - sh); - // Mix. - e.vpor(i.dest, e.xmm0); - } - } else { - // Counts differ, so pre-mask and load constant. - assert_always(); - } - } else { - // Fully variable shift. - // TODO(benvanik): find a better sequence. - Xmm temp = i.dest; - if (i.dest == i.src1 || i.dest == i.src2) { - temp = e.xmm2; - } - auto byte_mask = e.GetXmmConstPtr(XMMShiftByteMask); - // AABBCCDD|EEFFGGHH|IIJJKKLL|MMNNOOPP - // DD| HH| LL| PP - e.vpand(e.xmm0, i.src1, byte_mask); - e.vpand(e.xmm1, i.src2, byte_mask); - e.vpsllvd(temp, e.xmm0, e.xmm1); - // CC | GG | KK | OO - e.vpsrld(e.xmm0, i.src1, 8); - e.vpand(e.xmm0, byte_mask); - e.vpsrld(e.xmm1, i.src2, 8); - e.vpand(e.xmm1, byte_mask); - e.vpsllvd(e.xmm0, e.xmm0, e.xmm1); - e.vpslld(e.xmm0, 8); - e.vpor(temp, e.xmm0); - // BB | FF | JJ | NN - e.vpsrld(e.xmm0, i.src1, 16); - e.vpand(e.xmm0, byte_mask); - e.vpsrld(e.xmm1, i.src2, 16); - e.vpand(e.xmm1, byte_mask); - e.vpsllvd(e.xmm0, e.xmm0, e.xmm1); - e.vpslld(e.xmm0, 16); - e.vpor(temp, e.xmm0); - // AA |EE |II |MM - e.vpsrld(e.xmm0, i.src1, 24); - e.vpand(e.xmm0, byte_mask); - e.vpsrld(e.xmm1, i.src2, 24); - e.vpand(e.xmm1, byte_mask); - e.vpsllvd(e.xmm0, e.xmm0, e.xmm1); - e.vpslld(e.xmm0, 24); - e.vpor(i.dest, temp, e.xmm0); + static __m128i EmulateVectorShlI8(void*, __m128i src1, __m128i src2) { + alignas(16) uint8_t value[16]; + alignas(16) uint8_t shamt[16]; + _mm_store_si128(reinterpret_cast<__m128i*>(value), src1); + _mm_store_si128(reinterpret_cast<__m128i*>(shamt), src2); + for (size_t i = 0; i < 16; ++i) { + value[i] = value[i] << (shamt[i] & 0x7); } + return _mm_load_si128(reinterpret_cast<__m128i*>(value)); + } + static void EmitInt8(X64Emitter& e, const EmitArgType& i) { + // TODO(benvanik): native version (with shift magic). + if (i.src2.is_constant) { + e.LoadConstantXmm(e.xmm0, i.src2.constant()); + e.lea(e.r9, e.StashXmm(1, e.xmm0)); + } else { + e.lea(e.r9, e.StashXmm(1, i.src2)); + } + e.lea(e.r8, e.StashXmm(0, i.src1)); + e.CallNativeSafe(reinterpret_cast(EmulateVectorShlI8)); + e.vmovaps(i.dest, e.xmm0); + } + static __m128i EmulateVectorShlI16(void*, __m128i src1, __m128i src2) { + alignas(16) uint16_t value[8]; + alignas(16) uint16_t shamt[8]; + _mm_store_si128(reinterpret_cast<__m128i*>(value), src1); + _mm_store_si128(reinterpret_cast<__m128i*>(shamt), src2); + for (size_t i = 0; i < 8; ++i) { + value[i] = value[i] << (shamt[i] & 0xF); + } + return _mm_load_si128(reinterpret_cast<__m128i*>(value)); } static void EmitInt16(X64Emitter& e, const EmitArgType& i) { if (i.src2.is_constant) { const auto& shamt = i.src2.constant(); bool all_same = true; for (size_t n = 0; n < 8 - n; ++n) { - if (shamt.s8[n] != shamt.s8[n + 1]) { + if (shamt.u16[n] != shamt.u16[n + 1]) { all_same = false; break; } } if (all_same) { // Every count is the same, so we can use vpsllw. - e.vpsllw(i.dest, i.src1, shamt.s8[0] & 0xF); - } else { - // Counts differ, so pre-mask and load constant. - assert_always(); + e.vpsllw(i.dest, i.src1, shamt.u16[0] & 0xF); + return; } - } else { - // Fully variable shift. - // TODO(benvanik): find a better sequence. - Xmm src1 = !i.src1.is_constant ? i.src1 : e.xmm2; - if (i.src1.is_constant) { - e.LoadConstantXmm(src1, i.src1.constant()); - } - // Even: - e.vpand(e.xmm0, i.src2, e.GetXmmConstPtr(XMMShiftMaskEvenPI16)); - e.vpsllvd(e.xmm1, src1, e.xmm0); - e.vpand(e.xmm1, e.GetXmmConstPtr(XMMMaskEvenPI16)); - // Odd: - e.vpsrld(e.xmm0, i.src2, 16); - e.vpand(e.xmm0, e.GetXmmConstPtr(XMMShiftMaskEvenPI16)); - e.vpsrld(i.dest, src1, 16); - e.vpsllvd(i.dest, i.dest, e.xmm0); - e.vpslld(i.dest, 8); - // Merge: - e.vpor(i.dest, e.xmm1); } + // TODO(benvanik): native version (with shift magic). + if (i.src2.is_constant) { + e.LoadConstantXmm(e.xmm0, i.src2.constant()); + e.lea(e.r9, e.StashXmm(1, e.xmm0)); + } else { + e.lea(e.r9, e.StashXmm(1, i.src2)); + } + e.lea(e.r8, e.StashXmm(0, i.src1)); + e.CallNativeSafe(reinterpret_cast(EmulateVectorShlI16)); + e.vmovaps(i.dest, e.xmm0); } static void EmitInt32(X64Emitter& e, const EmitArgType& i) { if (i.src2.is_constant) { const auto& shamt = i.src2.constant(); bool all_same = true; for (size_t n = 0; n < 4 - n; ++n) { - if (shamt.i4[n] != shamt.i4[n + 1]) { + if (shamt.u32[n] != shamt.u32[n + 1]) { all_same = false; break; } } if (all_same) { // Every count is the same, so we can use vpslld. - e.vpslld(i.dest, i.src1, shamt.b16[0] & 0x1F); + e.vpslld(i.dest, i.src1, shamt.u8[0] & 0x1F); } else { // Counts differ, so pre-mask and load constant. vec128_t masked = i.src2.constant(); for (size_t n = 0; n < 4; ++n) { - masked.i4[n] &= 0x1F; + masked.u32[n] &= 0x1F; } e.LoadConstantXmm(e.xmm0, masked); e.vpsllvd(i.dest, i.src1, e.xmm0); @@ -4295,81 +4287,83 @@ EMITTER(VECTOR_SHR_V128, MATCH(I, V128<>, V128<>>)) { break; } } - static void EmitInt8(X64Emitter& e, const EmitArgType& i) { - if (i.src2.is_constant) { - const auto& shamt = i.src2.constant(); - bool all_same = true; - for (size_t n = 0; n < 16 - n; ++n) { - if (shamt.b16[n] != shamt.b16[n + 1]) { - all_same = false; - break; - } - } - if (all_same) { - // Every count is the same. - uint8_t sh = shamt.b16[0] & 0x7; - if (!sh) { - // No shift? - e.vmovaps(i.dest, i.src1); - } else { - // Even bytes. - e.vpsllw(e.xmm0, i.src1, 8); - e.vpsrlw(e.xmm0, sh + 8); - // Odd bytes. - e.vpsrlw(i.dest, i.src1, 8); - e.vpsllw(i.dest, 8 - sh); - // Mix. - e.vpor(i.dest, e.xmm0); - } - } else { - // Counts differ, so pre-mask and load constant. - assert_always(); - } - } else { - // Fully variable shift. - assert_always(); + static __m128i EmulateVectorShrI8(void*, __m128i src1, __m128i src2) { + alignas(16) uint8_t value[16]; + alignas(16) uint8_t shamt[16]; + _mm_store_si128(reinterpret_cast<__m128i*>(value), src1); + _mm_store_si128(reinterpret_cast<__m128i*>(shamt), src2); + for (size_t i = 0; i < 16; ++i) { + value[i] = value[i] >> (shamt[i] & 0x7); } + return _mm_load_si128(reinterpret_cast<__m128i*>(value)); + } + static void EmitInt8(X64Emitter& e, const EmitArgType& i) { + // TODO(benvanik): native version (with shift magic). + if (i.src2.is_constant) { + e.LoadConstantXmm(e.xmm0, i.src2.constant()); + e.lea(e.r9, e.StashXmm(1, e.xmm0)); + } else { + e.lea(e.r9, e.StashXmm(1, i.src2)); + } + e.lea(e.r8, e.StashXmm(0, i.src1)); + e.CallNativeSafe(reinterpret_cast(EmulateVectorShrI8)); + e.vmovaps(i.dest, e.xmm0); + } + static __m128i EmulateVectorShrI16(void*, __m128i src1, __m128i src2) { + alignas(16) uint16_t value[8]; + alignas(16) uint16_t shamt[8]; + _mm_store_si128(reinterpret_cast<__m128i*>(value), src1); + _mm_store_si128(reinterpret_cast<__m128i*>(shamt), src2); + for (size_t i = 0; i < 8; ++i) { + value[i] = value[i] >> (shamt[i] & 0xF); + } + return _mm_load_si128(reinterpret_cast<__m128i*>(value)); } static void EmitInt16(X64Emitter& e, const EmitArgType& i) { if (i.src2.is_constant) { const auto& shamt = i.src2.constant(); bool all_same = true; for (size_t n = 0; n < 8 - n; ++n) { - if (shamt.s8[n] != shamt.s8[n + 1]) { + if (shamt.u16[n] != shamt.u16[n + 1]) { all_same = false; break; } } if (all_same) { // Every count is the same, so we can use vpsllw. - e.vpsrlw(i.dest, i.src1, shamt.s8[0] & 0xF); - } else { - // Counts differ, so pre-mask and load constant. - assert_always(); + e.vpsrlw(i.dest, i.src1, shamt.u16[0] & 0xF); + return; } - } else { - // Fully variable shift. - assert_always(); } + // TODO(benvanik): native version (with shift magic). + if (i.src2.is_constant) { + e.LoadConstantXmm(e.xmm0, i.src2.constant()); + e.lea(e.r9, e.StashXmm(1, e.xmm0)); + } else { + e.lea(e.r9, e.StashXmm(1, i.src2)); + } + e.lea(e.r8, e.StashXmm(0, i.src1)); + e.CallNativeSafe(reinterpret_cast(EmulateVectorShrI16)); + e.vmovaps(i.dest, e.xmm0); } static void EmitInt32(X64Emitter& e, const EmitArgType& i) { if (i.src2.is_constant) { const auto& shamt = i.src2.constant(); bool all_same = true; for (size_t n = 0; n < 4 - n; ++n) { - if (shamt.i4[n] != shamt.i4[n + 1]) { + if (shamt.u32[n] != shamt.u32[n + 1]) { all_same = false; break; } } if (all_same) { // Every count is the same, so we can use vpslld. - e.vpsrld(i.dest, i.src1, shamt.b16[0] & 0x1F); + e.vpsrld(i.dest, i.src1, shamt.u8[0] & 0x1F); } else { // Counts differ, so pre-mask and load constant. vec128_t masked = i.src2.constant(); for (size_t n = 0; n < 4; ++n) { - masked.i4[n] &= 0x1F; + masked.u32[n] &= 0x1F; } e.LoadConstantXmm(e.xmm0, masked); e.vpsrlvd(i.dest, i.src1, e.xmm0); @@ -4392,26 +4386,61 @@ EMITTER_OPCODE_TABLE( // OPCODE_VECTOR_SHA // ============================================================================ EMITTER(VECTOR_SHA_V128, MATCH(I, V128<>, V128<>>)) { + static __m128i EmulateVectorShaI8(void*, __m128i src1, __m128i src2) { + alignas(16) int8_t value[16]; + alignas(16) int8_t shamt[16]; + _mm_store_si128(reinterpret_cast<__m128i*>(value), src1); + _mm_store_si128(reinterpret_cast<__m128i*>(shamt), src2); + for (size_t i = 0; i < 16; ++i) { + value[i] = value[i] >> (shamt[i] & 0x7); + } + return _mm_load_si128(reinterpret_cast<__m128i*>(value)); + } + static __m128i EmulateVectorShaI16(void*, __m128i src1, __m128i src2) { + alignas(16) int16_t value[8]; + alignas(16) int16_t shamt[8]; + _mm_store_si128(reinterpret_cast<__m128i*>(value), src1); + _mm_store_si128(reinterpret_cast<__m128i*>(shamt), src2); + for (size_t i = 0; i < 8; ++i) { + value[i] = value[i] >> (shamt[i] & 0xF); + } + return _mm_load_si128(reinterpret_cast<__m128i*>(value)); + } static void Emit(X64Emitter& e, const EmitArgType& i) { switch (i.instr->flags) { + case INT8_TYPE: + // TODO(benvanik): native version (with shift magic). + if (i.src2.is_constant) { + e.LoadConstantXmm(e.xmm0, i.src2.constant()); + e.lea(e.r9, e.StashXmm(1, e.xmm0)); + } else { + e.lea(e.r9, e.StashXmm(1, i.src2)); + } + e.lea(e.r8, e.StashXmm(0, i.src1)); + e.CallNativeSafe(reinterpret_cast(EmulateVectorShaI8)); + e.vmovaps(i.dest, e.xmm0); + break; case INT16_TYPE: - // Even halfwords: - e.vpand(e.xmm0, i.src2, e.GetXmmConstPtr(XMMShiftMaskEvenPI16)); - e.vpslld(e.xmm1, i.src1, 16); - e.vpsrad(e.xmm1, 8); - e.vpsravd(e.xmm1, e.xmm1, e.xmm0); - // Odd halfwords: - e.vpsrld(e.xmm0, i.src2, 16); - e.vpand(e.xmm0, e.GetXmmConstPtr(XMMShiftMaskEvenPI16)); - e.vpslld(i.dest, i.src1, 16); - e.vpsravd(i.dest, i.dest, e.xmm0); - // Merge: - e.vpor(i.dest, e.xmm1); + // TODO(benvanik): native version (with shift magic). + if (i.src2.is_constant) { + e.LoadConstantXmm(e.xmm0, i.src2.constant()); + e.lea(e.r9, e.StashXmm(1, e.xmm0)); + } else { + e.lea(e.r9, e.StashXmm(1, i.src2)); + } + e.lea(e.r8, e.StashXmm(0, i.src1)); + e.CallNativeSafe(reinterpret_cast(EmulateVectorShaI16)); + e.vmovaps(i.dest, e.xmm0); break; case INT32_TYPE: // src shift mask may have values >31, and x86 sets to zero when // that happens so we mask. - e.vandps(e.xmm0, i.src2, e.GetXmmConstPtr(XMMShiftMaskPS)); + if (i.src2.is_constant) { + e.LoadConstantXmm(e.xmm0, i.src2.constant()); + e.vandps(e.xmm0, e.GetXmmConstPtr(XMMShiftMaskPS)); + } else { + e.vandps(e.xmm0, i.src2, e.GetXmmConstPtr(XMMShiftMaskPS)); + } e.vpsravd(i.dest, i.src1, e.xmm0); break; default: @@ -4490,39 +4519,39 @@ EMITTER_OPCODE_TABLE( // ============================================================================ // TODO(benvanik): AVX512 has a native variable rotate (rolv). EMITTER(VECTOR_ROTATE_LEFT_V128, MATCH(I, V128<>, V128<>>)) { - static __m128i EmulateVectorRotateLeftI8(__m128i src1, __m128i src2) { + static __m128i EmulateVectorRotateLeftI8(void*, __m128i src1, __m128i src2) { alignas(16) uint8_t value[16]; alignas(16) uint8_t shamt[16]; - _mm_store_si128(reinterpret_cast<__m128i*>(&value), src1); - _mm_store_si128(reinterpret_cast<__m128i*>(&shamt), src2); + _mm_store_si128(reinterpret_cast<__m128i*>(value), src1); + _mm_store_si128(reinterpret_cast<__m128i*>(shamt), src2); for (size_t i = 0; i < 16; ++i) { - value[i] = poly::rotate_left(value[i], shamt[i] & 0x3); + value[i] = poly::rotate_left(value[i], shamt[i] & 0x7); } - return _mm_load_si128(reinterpret_cast<__m128i*>(&value)); + return _mm_load_si128(reinterpret_cast<__m128i*>(value)); } - static __m128i EmulateVectorRotateLeftI16(__m128i src1, __m128i src2) { + static __m128i EmulateVectorRotateLeftI16(void*, __m128i src1, __m128i src2) { alignas(16) uint16_t value[8]; alignas(16) uint16_t shamt[8]; - _mm_store_si128(reinterpret_cast<__m128i*>(&value), src1); - _mm_store_si128(reinterpret_cast<__m128i*>(&shamt), src2); + _mm_store_si128(reinterpret_cast<__m128i*>(value), src1); + _mm_store_si128(reinterpret_cast<__m128i*>(shamt), src2); for (size_t i = 0; i < 8; ++i) { value[i] = poly::rotate_left(value[i], shamt[i] & 0xF); } - return _mm_load_si128(reinterpret_cast<__m128i*>(&value)); + return _mm_load_si128(reinterpret_cast<__m128i*>(value)); } static void Emit(X64Emitter& e, const EmitArgType& i) { switch (i.instr->flags) { case INT8_TYPE: // TODO(benvanik): native version (with shift magic). - e.lea(e.r8, e.StashXmm(i.src1)); - e.lea(e.r9, e.StashXmm(i.src2)); + e.lea(e.r8, e.StashXmm(0, i.src1)); + e.lea(e.r9, e.StashXmm(1, i.src2)); e.CallNativeSafe(reinterpret_cast(EmulateVectorRotateLeftI8)); e.vmovaps(i.dest, e.xmm0); break; case INT16_TYPE: // TODO(benvanik): native version (with shift magic). - e.lea(e.r8, e.StashXmm(i.src1)); - e.lea(e.r9, e.StashXmm(i.src2)); + e.lea(e.r8, e.StashXmm(0, i.src1)); + e.lea(e.r9, e.StashXmm(1, i.src2)); e.CallNativeSafe(reinterpret_cast(EmulateVectorRotateLeftI16)); e.vmovaps(i.dest, e.xmm0); break; @@ -4537,7 +4566,7 @@ EMITTER(VECTOR_ROTATE_LEFT_V128, MATCH(I, V128 // Shift right (to get low bits): e.vmovaps(temp, e.GetXmmConstPtr(XMMPI32)); e.vpsubd(temp, e.xmm0); - e.vpsrlvd(i.dest, i.src1, e.xmm0); + e.vpsrlvd(i.dest, i.src1, temp); // Merge: e.vpor(i.dest, e.xmm1); break; @@ -4629,6 +4658,23 @@ EMITTER_OPCODE_TABLE( // ============================================================================ // OPCODE_INSERT // ============================================================================ +EMITTER(INSERT_I8, MATCH(I, V128<>, I64<>, I8<>>)) { + static void Emit(X64Emitter& e, const EmitArgType& i) { + } +}; +EMITTER(INSERT_I16, MATCH(I, V128<>, I64<>, I16<>>)) { + static void Emit(X64Emitter& e, const EmitArgType& i) { + } +}; +EMITTER(INSERT_I32, MATCH(I, V128<>, I64<>, I32<>>)) { + static void Emit(X64Emitter& e, const EmitArgType& i) { + } +}; +EMITTER_OPCODE_TABLE( + OPCODE_INSERT, + INSERT_I8, + INSERT_I16, + INSERT_I32); // ============================================================================ @@ -4643,14 +4689,13 @@ EMITTER(EXTRACT_I8, MATCH(I, V128<>, I8<>>)) { if (i.src2.is_constant) { e.vpextrb(i.dest.reg().cvt32(), i.src1, VEC128_B(i.src2.constant())); } else { - assert_always(); - // TODO(benvanik): try out hlide's version: - // e.mov(e.eax, 0x80808003); - // e.xor(e.al, i.src2); - // e.and(e.al, 15); - // e.vmovd(e.xmm0, e.eax); - // e.vpshufb(e.xmm0, i.src1, e.xmm0); - // e.vmovd(i.dest.reg().cvt32(), e.xmm0); + e.mov(e.eax, 0x00000003); + e.xor(e.al, i.src2); + e.and(e.al, 0x1F); + e.vmovd(e.xmm0, e.eax); + e.vpshufb(e.xmm0, i.src1, e.xmm0); + e.vmovd(i.dest.reg().cvt32(), e.xmm0); + e.and(i.dest, uint8_t(0xFF)); } } }; @@ -4659,20 +4704,21 @@ EMITTER(EXTRACT_I16, MATCH(I, V128<>, I8<>>)) { if (i.src2.is_constant) { e.vpextrw(i.dest.reg().cvt32(), i.src1, VEC128_W(i.src2.constant())); } else { - // TODO(benvanik): try out hlide's version: e.mov(e.al, i.src2); - e.xor(e.al, 0x1); + e.xor(e.al, 0x01); + e.shl(e.al, 1); e.mov(e.ah, e.al); e.add(e.ah, 1); e.vmovd(e.xmm0, e.eax); e.vpshufb(e.xmm0, i.src1, e.xmm0); e.vmovd(i.dest.reg().cvt32(), e.xmm0); + e.and(i.dest.reg().cvt32(), 0xFFFFu); } } }; EMITTER(EXTRACT_I32, MATCH(I, V128<>, I8<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { - static vec128_t extract_table_32[4] = { + static const vec128_t extract_table_32[4] = { vec128b( 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), vec128b( 7, 6, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), vec128b(11, 10, 9, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), @@ -4706,29 +4752,11 @@ EMITTER(EXTRACT_I32, MATCH(I, V128<>, I8<>>)) { } } }; -EMITTER(EXTRACT_F32, MATCH(I, V128<>, I8<>>)) { - static void Emit(X64Emitter& e, const EmitArgType& i) { - if (i.src2.is_constant) { - e.vextractps(i.dest, i.src1, VEC128_F(i.src2.constant())); - } else { - assert_always(); - // TODO(benvanik): try out hlide's version: - // e.mov(e.eax, 3); - // e.and(e.al, i.src2); // eax = [(i&3), 0, 0, 0] - // e.imul(e.eax, 0x04040404); // [(i&3)*4, (i&3)*4, (i&3)*4, (i&3)*4] - // e.add(e.eax, 0x00010203); // [((i&3)*4)+3, ((i&3)*4)+2, ((i&3)*4)+1, ((i&3)*4)+0] - // e.vmovd(e.xmm0, e.eax); - // e.vpshufb(e.xmm0, i.src1, e.xmm0); - // e.vmovd(i.dest, e.xmm0); - } - } -}; EMITTER_OPCODE_TABLE( OPCODE_EXTRACT, EXTRACT_I8, EXTRACT_I16, - EXTRACT_I32, - EXTRACT_F32); + EXTRACT_I32); // ============================================================================ @@ -4805,15 +4833,15 @@ EMITTER(PERMUTE_I32, MATCH(I, I32<>, V128<>, V128<>>)) { // Shuffle things into the right places in dest & xmm0, // then we blend them together. uint32_t src_control = - (((control >> 24) & 0x3) << 0) | - (((control >> 16) & 0x3) << 2) | - (((control >> 8) & 0x3) << 4) | - (((control >> 0) & 0x3) << 6); + (((control >> 24) & 0x3) << 6) | + (((control >> 16) & 0x3) << 4) | + (((control >> 8) & 0x3) << 2) | + (((control >> 0) & 0x3) << 0); uint32_t blend_control = - (((control >> 26) & 0x1) << 0) | - (((control >> 18) & 0x1) << 1) | - (((control >> 10) & 0x1) << 2) | - (((control >> 2) & 0x1) << 3); + (((control >> 26) & 0x1) << 3) | + (((control >> 18) & 0x1) << 2) | + (((control >> 10) & 0x1) << 1) | + (((control >> 2) & 0x1) << 0); // TODO(benvanik): if src2/src3 are constants, shuffle now! Xmm src2; if (i.src2.is_constant) { @@ -4923,11 +4951,6 @@ EMITTER(SWIZZLE, MATCH(I, V128<>, OffsetOp>)) { assert_always(); } else if (element_type == INT32_TYPE || element_type == FLOAT32_TYPE) { uint8_t swizzle_mask = static_cast(i.src2.value); - swizzle_mask = - (((swizzle_mask >> 6) & 0x3) << 0) | - (((swizzle_mask >> 4) & 0x3) << 2) | - (((swizzle_mask >> 2) & 0x3) << 4) | - (((swizzle_mask >> 0) & 0x3) << 6); e.vpshufd(i.dest, i.src1, swizzle_mask); } else if (element_type == INT64_TYPE || element_type == FLOAT64_TYPE) { assert_always(); @@ -4976,54 +4999,40 @@ EMITTER(PACK, MATCH(I, V128<>>)) { } static void EmitD3DCOLOR(X64Emitter& e, const EmitArgType& i) { // RGBA (XYZW) -> ARGB (WXYZ) - // float r = roundf(((src1.x < 0) ? 0 : ((1 < src1.x) ? 1 : src1.x)) * 255); - // float g = roundf(((src1.y < 0) ? 0 : ((1 < src1.y) ? 1 : src1.y)) * 255); - // float b = roundf(((src1.z < 0) ? 0 : ((1 < src1.z) ? 1 : src1.z)) * 255); - // float a = roundf(((src1.w < 0) ? 0 : ((1 < src1.w) ? 1 : src1.w)) * 255); - // dest.iw = ((uint32_t)a << 24) | - // ((uint32_t)r << 16) | - // ((uint32_t)g << 8) | - // ((uint32_t)b); - // f2i(clamp(src, 0, 1) * 255) - e.vpxor(e.xmm0, e.xmm0); + // w = ((src1.uw & 0xFF) << 24) | ((src1.ux & 0xFF) << 16) | + // ((src1.uy & 0xFF) << 8) | (src1.uz & 0xFF) if (i.src1.is_constant) { - e.LoadConstantXmm(e.xmm1, i.src1.constant()); - e.vmaxps(e.xmm0, e.xmm1); + e.LoadConstantXmm(i.dest, i.src1.constant()); + e.vpshufb(i.dest, i.dest, e.GetXmmConstPtr(XMMPackD3DCOLOR)); } else { - e.vmaxps(e.xmm0, i.src1); + e.vpshufb(i.dest, i.src1, e.GetXmmConstPtr(XMMPackD3DCOLOR)); } - e.vminps(e.xmm0, e.GetXmmConstPtr(XMMOne)); - e.vmulps(e.xmm0, e.GetXmmConstPtr(XMM255)); - e.vcvttps2dq(e.xmm0, e.xmm0); - e.vpshufb(i.dest, e.xmm0, e.GetXmmConstPtr(XMMPackD3DCOLOR)); } static void EmitFLOAT16_2(X64Emitter& e, const EmitArgType& i) { // http://blogs.msdn.com/b/chuckw/archive/2012/09/11/directxmath-f16c-and-fma.aspx // dest = [(src1.x | src1.y), 0, 0, 0] // 0|0|0|0|W|Z|Y|X - e.vcvtps2ph(e.xmm0, i.src1, B00000011); - // Y|X|W|Z|0|0|0|0 - e.vpshufd(e.xmm0, e.xmm0, B00011011); - // Shuffle to X|Y|Z|W|0|0|0|0 - e.vpshufhw(e.xmm0, e.xmm0, B10110001); - // Select just X|Y - e.vxorps(i.dest, i.dest); - e.vpblendw(i.dest, e.xmm0, B11000000); + e.vcvtps2ph(i.dest, i.dest, B00000011); + // Shuffle to X|Y|0|0|0|0|0|0 + e.vpshufb(i.dest, i.dest, e.GetXmmConstPtr(XMMPackFLOAT16_2)); } static void EmitFLOAT16_4(X64Emitter& e, const EmitArgType& i) { // dest = [(src1.x | src1.y), (src1.z | src1.w), 0, 0] // 0|0|0|0|W|Z|Y|X e.vcvtps2ph(e.xmm0, i.src1, B00000011); - // Y|X|W|Z|0|0|0|0 - e.vpshufd(e.xmm0, e.xmm0, B00011011); // Shuffle to X|Y|Z|W|0|0|0|0 - e.vpshufhw(e.xmm0, e.xmm0, B10110001); - // Select just X|Y|Z|W - e.vxorps(i.dest, i.dest); - e.vpblendw(i.dest, e.xmm0, B11110000); + e.vpshufb(i.dest, i.dest, e.GetXmmConstPtr(XMMPackFLOAT16_4)); } static void EmitSHORT_2(X64Emitter& e, const EmitArgType& i) { - assert_always(); + // Saturate. + e.vmaxps(i.dest, i.src1, e.GetXmmConstPtr(XMMNegativeOne)); + e.vminps(i.dest, i.dest, e.GetXmmConstPtr(XMMOne)); + // Multiply by SHRT_MAX. + e.vmulps(i.dest, i.dest, e.GetXmmConstPtr(XMMShortMaxPS)); + // Convert to int32. + e.vcvtps2dq(i.dest, i.dest); + // Pack. + e.vpshufb(i.dest, i.dest, e.GetXmmConstPtr(XMMPackSHORT_2)); } static void EmitS8_IN_16_LO(X64Emitter& e, const EmitArgType& i) { assert_always(); @@ -5079,23 +5088,14 @@ EMITTER(UNPACK, MATCH(I, V128<>>)) { static void EmitD3DCOLOR(X64Emitter& e, const EmitArgType& i) { // ARGB (WXYZ) -> RGBA (XYZW) // XMLoadColor - // int32_t src = (int32_t)src1.iw; - // dest.f4[0] = (float)((src >> 16) & 0xFF) * (1.0f / 255.0f); - // dest.f4[1] = (float)((src >> 8) & 0xFF) * (1.0f / 255.0f); - // dest.f4[2] = (float)(src & 0xFF) * (1.0f / 255.0f); - // dest.f4[3] = (float)((src >> 24) & 0xFF) * (1.0f / 255.0f); if (i.src1.is_constant) { - e.vpxor(i.dest, i.dest); - return; + assert_always(); } - // src = ZZYYXXWW - // unpack to 000000ZZ,000000YY,000000XX,000000WW + // Unpack to 000000ZZ,000000YY,000000XX,000000WW e.vpshufb(i.dest, i.src1, e.GetXmmConstPtr(XMMUnpackD3DCOLOR)); - // int -> float - e.vcvtdq2ps(i.dest, i.dest); - // mult by 1/255 - e.vmulps(i.dest, e.GetXmmConstPtr(XMMOneOver255)); + // Add 1.0f to each. + e.vpor(i.dest, e.GetXmmConstPtr(XMMOne)); } static void EmitFLOAT16_2(X64Emitter& e, const EmitArgType& i) { // 1 bit sign, 5 bit exponent, 10 bit mantissa @@ -5114,13 +5114,17 @@ EMITTER(UNPACK, MATCH(I, V128<>>)) { // XMConvertHalfToFloat(sy), // 0.0, // 1.0 }; - e.vcvtph2ps(i.dest, i.src1); + // Shuffle to 0|0|0|0|0|0|Y|X + e.vpshufb(i.dest, i.src1, e.GetXmmConstPtr(XMMUnpackFLOAT16_2)); + e.vcvtph2ps(i.dest, i.dest); e.vpshufd(i.dest, i.dest, B10100100); e.vpor(i.dest, e.GetXmmConstPtr(XMM0001)); } static void EmitFLOAT16_4(X64Emitter& e, const EmitArgType& i) { // src = [(dest.x | dest.y), (dest.z | dest.w), 0, 0] - e.vcvtph2ps(i.dest, i.src1); + // Shuffle to 0|0|0|0|W|Z|Y|X + e.vpshufb(i.dest, i.src1, e.GetXmmConstPtr(XMMUnpackFLOAT16_4)); + e.vcvtph2ps(i.dest, i.dest); } static void EmitSHORT_2(X64Emitter& e, const EmitArgType& i) { // (VD.x) = 3.0 + (VB.x>>16)*2^-22 @@ -5131,31 +5135,23 @@ EMITTER(UNPACK, MATCH(I, V128<>>)) { // XMLoadShortN2 plus 3,3,0,3 (for some reason) // src is (xx,xx,xx,VALUE) // (VALUE,VALUE,VALUE,VALUE) + Xmm src; if (i.src1.is_constant) { if (i.src1.value->IsConstantZero()) { - e.vpxor(i.dest, i.dest); + e.vmovdqa(i.dest, e.GetXmmConstPtr(XMM3301)); + return; } else { - // TODO(benvanik): check other common constants. - e.LoadConstantXmm(i.dest, i.src1.constant()); - e.vbroadcastss(i.dest, i.src1); + // TODO(benvanik): check other common constants/perform shuffle/or here. + src = e.xmm0; + e.LoadConstantXmm(src, i.src1.constant()); } } else { - e.vbroadcastss(i.dest, i.src1); + src = i.src1; } - // (VALUE&0xFFFF,VALUE&0xFFFF0000,0,0) - e.vandps(i.dest, e.GetXmmConstPtr(XMMMaskX16Y16)); - // Sign extend. - e.vxorps(i.dest, e.GetXmmConstPtr(XMMFlipX16Y16)); - // Convert int->float. - e.cvtpi2ps(i.dest, e.StashXmm(i.dest)); - // 0x8000 to undo sign. - e.vaddps(i.dest, e.GetXmmConstPtr(XMMFixX16Y16)); - // Normalize. - e.vmulps(i.dest, e.GetXmmConstPtr(XMMNormalizeX16Y16)); - // Clamp. - e.vmaxps(i.dest, e.GetXmmConstPtr(XMMNegativeOne)); + // Shuffle bytes. + e.vpshufb(i.dest, src, e.GetXmmConstPtr(XMMUnpackSHORT_2)); // Add 3,3,0,1. - e.vaddps(i.dest, e.GetXmmConstPtr(XMM3301)); + e.vpor(i.dest, e.GetXmmConstPtr(XMM3301)); } static void EmitS8_IN_16_LO(X64Emitter& e, const EmitArgType& i) { e.vpunpckhbw(i.dest, i.src1, i.src1); @@ -5368,7 +5364,7 @@ void RegisterSequences() { REGISTER_EMITTER_OPCODE_TABLE(OPCODE_VECTOR_ROTATE_LEFT); REGISTER_EMITTER_OPCODE_TABLE(OPCODE_BYTE_SWAP); REGISTER_EMITTER_OPCODE_TABLE(OPCODE_CNTLZ); - //REGISTER_EMITTER_OPCODE_TABLE(OPCODE_INSERT); + REGISTER_EMITTER_OPCODE_TABLE(OPCODE_INSERT); REGISTER_EMITTER_OPCODE_TABLE(OPCODE_EXTRACT); REGISTER_EMITTER_OPCODE_TABLE(OPCODE_SPLAT); REGISTER_EMITTER_OPCODE_TABLE(OPCODE_PERMUTE); diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index b99c003b8..479c94f79 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -28,6 +28,7 @@ Value* CalculateEA_0(PPCHIRBuilder& f, uint32_t ra, uint32_t rb); // Most of this file comes from: // http://biallas.net/doc/vmx128/vmx128.txt // https://github.com/kakaroto/ps3ida/blob/master/plugins/PPCAltivec/src/main.cpp +// http://sannybuilder.com/forums/viewtopic.php?id=190 #define OP(x) ((((uint32_t)(x)) & 0x3f) << 26) #define VX128(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x3d0)) @@ -154,7 +155,7 @@ XEEMITTER(lvxl128, VX128_1(4, 707), VX128_1)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(stvebx, 0x7C00010E, X)(PPCHIRBuilder& f, InstrData& i) { Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB); - Value* el = f.And(ea, f.LoadConstant(0xFull)); + Value* el = f.And(f.Truncate(ea, INT8_TYPE), f.LoadConstant(uint8_t(0xF))); Value* v = f.Extract(f.LoadVR(i.X.RT), el, INT8_TYPE); f.Store(ea, v); return 0; @@ -163,7 +164,8 @@ XEEMITTER(stvebx, 0x7C00010E, X)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(stvehx, 0x7C00014E, X)(PPCHIRBuilder& f, InstrData& i) { Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB); ea = f.And(ea, f.LoadConstant(~0x1ull)); - Value* el = f.Shr(f.And(ea, f.LoadConstant(0xFull)), 1); + Value* el = + f.Shr(f.And(f.Truncate(ea, INT8_TYPE), f.LoadConstant(uint8_t(0xF))), 1); Value* v = f.Extract(f.LoadVR(i.X.RT), el, INT16_TYPE); f.Store(ea, f.ByteSwap(v)); return 0; @@ -173,7 +175,8 @@ int InstrEmit_stvewx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { Value* ea = CalculateEA_0(f, ra, rb); ea = f.And(ea, f.LoadConstant(~0x3ull)); - Value* el = f.Shr(f.And(ea, f.LoadConstant(0xFull)), 2); + Value* el = + f.Shr(f.And(f.Truncate(ea, INT8_TYPE), f.LoadConstant(uint8_t(0xF))), 2); Value* v = f.Extract(f.LoadVR(vd), el, INT32_TYPE); f.Store(ea, f.ByteSwap(v)); return 0; @@ -239,8 +242,8 @@ int InstrEmit_lvrx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, ea = f.And(ea, f.LoadConstant(~0xFull)); // v = (new >> (16 - eb)) Value* v = f.Permute(f.LoadVectorShr(f.Sub(f.LoadConstant((int8_t)16), eb)), - f.LoadZero(VEC128_TYPE), - f.ByteSwap(f.Load(ea, VEC128_TYPE)), INT8_TYPE); + f.ByteSwap(f.Load(ea, VEC128_TYPE)), + f.LoadZero(VEC128_TYPE), INT8_TYPE); f.StoreVR(vd, v); return 0; } @@ -935,8 +938,8 @@ int InstrEmit_vmrghw_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { // (VD.y) = (VB.x) // (VD.z) = (VA.y) // (VD.w) = (VB.y) - Value* v = f.Permute(f.LoadConstant(0x00040105), f.LoadVR(va), f.LoadVR(vb), - INT32_TYPE); + Value* v = f.Permute(f.LoadConstant(PERMUTE_MASK(0, 0, 1, 0, 0, 1, 1, 1)), + f.LoadVR(va), f.LoadVR(vb), INT32_TYPE); f.StoreVR(vd, v); return 0; } @@ -962,8 +965,8 @@ int InstrEmit_vmrglw_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { // (VD.y) = (VB.z) // (VD.z) = (VA.w) // (VD.w) = (VB.w) - Value* v = f.Permute(f.LoadConstant(0x02060307), f.LoadVR(va), f.LoadVR(vb), - INT32_TYPE); + Value* v = f.Permute(f.LoadConstant(PERMUTE_MASK(0, 2, 1, 2, 0, 3, 1, 3)), + f.LoadVR(va), f.LoadVR(vb), INT32_TYPE); f.StoreVR(vd, v); return 0; } @@ -1140,7 +1143,8 @@ XEEMITTER(vpermwi128, VX128_P(6, 528), VX128_P)(PPCHIRBuilder& f, const uint32_t vd = i.VX128_P.VD128l | (i.VX128_P.VD128h << 5); const uint32_t vb = i.VX128_P.VB128l | (i.VX128_P.VB128h << 5); uint32_t uimm = i.VX128_P.PERMl | (i.VX128_P.PERMh << 5); - Value* v = f.Swizzle(f.LoadVR(vb), INT32_TYPE, uimm); + uint32_t mask = SWIZZLE_MASK(uimm >> 6, uimm >> 4, uimm >> 2, uimm >> 0); + Value* v = f.Swizzle(f.LoadVR(vb), INT32_TYPE, mask); f.StoreVR(vd, v); return 0; } @@ -1213,14 +1217,16 @@ XEEMITTER(vrfiz128, VX128_3(6, 1008), VX128_3)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vrlb, 0x10000004, VX)(PPCHIRBuilder& f, InstrData& i) { // (VD) <- ROTL((VA), (VB)&0x3) - Value* v = f.VectorRotateLeft(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT8_TYPE); + Value* v = + f.VectorRotateLeft(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT8_TYPE); f.StoreVR(i.VX.VD, v); return 0; } XEEMITTER(vrlh, 0x10000044, VX)(PPCHIRBuilder& f, InstrData& i) { // (VD) <- ROTL((VA), (VB)&0xF) - Value* v = f.VectorRotateLeft(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT16_TYPE); + Value* v = + f.VectorRotateLeft(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT16_TYPE); f.StoreVR(i.VX.VD, v); return 0; } @@ -1244,10 +1250,10 @@ XEEMITTER(vrlimi128, VX128_4(6, 1808), VX128_4)(PPCHIRBuilder& f, const uint32_t vb = i.VX128_4.VB128l | (i.VX128_4.VB128h << 5); uint32_t blend_mask_src = i.VX128_4.IMM; uint32_t blend_mask = 0; - for (int n = 3; n >= 0; n--) { - blend_mask |= ((blend_mask_src & 0x1) ? n : (4 + n)) << ((3 - n) * 8); - blend_mask_src >>= 1; - } + blend_mask |= (((blend_mask_src >> 3) & 0x1) ? 0 : 4) << 0; + blend_mask |= (((blend_mask_src >> 2) & 0x1) ? 1 : 5) << 8; + blend_mask |= (((blend_mask_src >> 1) & 0x1) ? 2 : 6) << 16; + blend_mask |= (((blend_mask_src >> 0) & 0x1) ? 3 : 7) << 24; uint32_t rotate = i.VX128_4.z; // This is just a fancy permute. // X Y Z W, rotated left by 2 = Z W X Y @@ -1278,7 +1284,7 @@ XEEMITTER(vrlimi128, VX128_4(6, 1808), VX128_4)(PPCHIRBuilder& f, } else { v = f.LoadVR(vb); } - if (blend_mask != 0x00010203) { + if (blend_mask != PERMUTE_IDENTITY) { v = f.Permute(f.LoadConstant(blend_mask), v, f.LoadVR(vd), INT32_TYPE); } f.StoreVR(vd, v); @@ -1382,7 +1388,7 @@ int InstrEmit_vsldoi_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, // (VA << SH) OR (VB >> (16 - SH)) vec128_t shift = *((vec128_t*)(__vsldoi_table[sh])); for (int i = 0; i < 4; ++i) { - shift.i4[i] = poly::byte_swap(shift.i4[i]); + shift.u32[i] = poly::byte_swap(shift.u32[i]); } Value* control = f.LoadConstant(shift); Value* v = f.Permute(control, f.LoadVR(va), f.LoadVR(vb), INT8_TYPE); @@ -1410,7 +1416,7 @@ XEEMITTER(vspltb, 0x1000020C, VX)(PPCHIRBuilder& f, InstrData& i) { // b <- UIMM*8 // do i = 0 to 127 by 8 // (VD)[i:i+7] <- (VB)[b:b+7] - Value* b = f.Extract(f.LoadVR(i.VX.VB), (i.VX.VA & 0xF), INT8_TYPE); + Value* b = f.Extract(f.LoadVR(i.VX.VB), i.VX.VA & 0xF, INT8_TYPE); Value* v = f.Splat(b, VEC128_TYPE); f.StoreVR(i.VX.VD, v); return 0; @@ -1418,7 +1424,7 @@ XEEMITTER(vspltb, 0x1000020C, VX)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vsplth, 0x1000024C, VX)(PPCHIRBuilder& f, InstrData& i) { // (VD.xyzw) <- (VB.uimm) - Value* h = f.Extract(f.LoadVR(i.VX.VB), (i.VX.VA & 0x7), INT16_TYPE); + Value* h = f.Extract(f.LoadVR(i.VX.VB), i.VX.VA & 0x7, INT16_TYPE); Value* v = f.Splat(h, VEC128_TYPE); f.StoreVR(i.VX.VD, v); return 0; @@ -1427,7 +1433,7 @@ XEEMITTER(vsplth, 0x1000024C, VX)(PPCHIRBuilder& f, InstrData& i) { int InstrEmit_vspltw_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm) { // (VD.xyzw) <- (VB.uimm) - Value* w = f.Extract(f.LoadVR(vb), (uimm & 0x3), INT32_TYPE); + Value* w = f.Extract(f.LoadVR(vb), uimm & 0x3, INT32_TYPE); Value* v = f.Splat(w, VEC128_TYPE); f.StoreVR(vd, v); return 0; @@ -1856,8 +1862,8 @@ XEEMITTER(vpkd3d128, VX128_4(6, 1552), VX128_4)(PPCHIRBuilder& f, } // http://hlssmod.net/he_code/public/pixelwriter.h // control = prev:0123 | new:4567 - uint32_t control = 0x00010203; // original - uint32_t src = xerotl(0x04050607, shift * 8); + uint32_t control = PERMUTE_IDENTITY; // original + uint32_t src = xerotl(0x07060504, shift * 8); uint32_t mask = 0; switch (pack) { case 1: // VPACK_32 @@ -1870,8 +1876,8 @@ XEEMITTER(vpkd3d128, VX128_4(6, 1552), VX128_4)(PPCHIRBuilder& f, mask = 0x0000FFFF << (shift * 8); } else { // w - src = 0x00000007; - mask = 0x000000FF; + src = 0x07000000; + mask = 0xFF000000; } control = (control & ~mask) | (src & mask); break; @@ -1880,7 +1886,7 @@ XEEMITTER(vpkd3d128, VX128_4(6, 1552), VX128_4)(PPCHIRBuilder& f, mask = 0x0000FFFF << (shift * 8); } else { // z - src = 0x00000006; + src = 0x00000004; mask = 0x000000FF; } control = (control & ~mask) | (src & mask); diff --git a/src/alloy/frontend/ppc/ppc_emit_alu.cc b/src/alloy/frontend/ppc/ppc_emit_alu.cc index 8638a0216..acfa78e47 100644 --- a/src/alloy/frontend/ppc/ppc_emit_alu.cc +++ b/src/alloy/frontend/ppc/ppc_emit_alu.cc @@ -1072,7 +1072,7 @@ XEEMITTER(sradx, 0x7C000634, X)(PPCHIRBuilder& f, InstrData& i) { Value* v = f.LoadGPR(i.X.RT); Value* sh = f.And(f.Truncate(f.LoadGPR(i.X.RB), INT8_TYPE), - f.LoadConstant((int8_t)0x7F)); + f.LoadConstant((int8_t)0x3F)); // CA is set if any bits are shifted out of the right and if the result // is negative. Start tracking that here. @@ -1137,14 +1137,15 @@ XEEMITTER(srawx, 0x7C000630, X)(PPCHIRBuilder& f, InstrData& i) { // if n >= 32: rA <- 64 sign bits of rS, XER[CA] = sign bit of lo_32(rS) Value* v = f.Truncate(f.LoadGPR(i.X.RT), INT32_TYPE); Value* sh = - f.And(f.Truncate(f.LoadGPR(i.X.RB), INT32_TYPE), f.LoadConstant(0x7F)); + f.And(f.Truncate(f.LoadGPR(i.X.RB), INT32_TYPE), f.LoadConstant(0x1F)); // CA is set if any bits are shifted out of the right and if the result // is negative. Value* mask = f.Not(f.Shl(f.LoadConstant(-1), sh)); Value* ca = f.And(f.Truncate(f.Shr(v, 31), INT8_TYPE), f.IsTrue(f.And(v, mask))); f.StoreCA(ca); - v = f.Sha(v, sh), v = f.SignExtend(v, INT64_TYPE); + v = f.Sha(v, sh); + v = f.SignExtend(v, INT64_TYPE); f.StoreGPR(i.X.RA, v); if (i.X.Rc) { f.UpdateCR(0, v); diff --git a/src/alloy/hir/opcodes.h b/src/alloy/hir/opcodes.h index cf84944cc..ae3b9ca33 100644 --- a/src/alloy/hir/opcodes.h +++ b/src/alloy/hir/opcodes.h @@ -51,11 +51,14 @@ enum ArithmeticFlags { ARITHMETIC_UNSIGNED = (1 << 2), ARITHMETIC_SATURATE = (1 << 3), }; +#define PERMUTE_MASK(sel_x, x, sel_y, y, sel_z, z, sel_w, w) \ + ((((x)&0x3) << 0) | (sel_x << 2) | (((y)&0x3) << 8) | (sel_y << 10) | \ + (((z)&0x3) << 16) | (sel_z << 18) | (((w)&0x3) << 24) | (sel_w << 26)) enum Permutes { - PERMUTE_XY_ZW = 0x00010405, + PERMUTE_IDENTITY = PERMUTE_MASK(0, 0, 0, 1, 0, 2, 0, 3), }; #define SWIZZLE_MASK(x, y, z, w) \ - ((((x)&0x3) << 6) | (((y)&0x3) << 4) | (((z)&0x3) << 2) | (((w)&0x3))) + ((((x)&0x3) << 0) | (((y)&0x3) << 2) | (((z)&0x3) << 4) | (((w)&0x3) << 6)) enum Swizzles { SWIZZLE_XYZW_TO_XYZW = SWIZZLE_MASK(0, 1, 2, 3), SWIZZLE_XYZW_TO_YZWX = SWIZZLE_MASK(1, 2, 3, 0), diff --git a/src/alloy/hir/value.cc b/src/alloy/hir/value.cc index 211481c93..ae90900d4 100644 --- a/src/alloy/hir/value.cc +++ b/src/alloy/hir/value.cc @@ -582,7 +582,7 @@ void Value::ByteSwap() { break; case VEC128_TYPE: for (int n = 0; n < 4; n++) { - constant.v128.i4[n] = poly::byte_swap(constant.v128.i4[n]); + constant.v128.u32[n] = poly::byte_swap(constant.v128.u32[n]); } break; default: diff --git a/src/alloy/vec128.h b/src/alloy/vec128.h index 9a7b8f728..8a4a9a039 100644 --- a/src/alloy/vec128.h +++ b/src/alloy/vec128.h @@ -14,6 +14,58 @@ namespace alloy { +// The first rule of vector programming is to only rely on exact positions +// when absolutely required - prefer dumb loops to exact offsets. +// Vectors in memory are laid out as in AVX registers on little endian +// machines. Note that little endian is dumb, so the byte at index 0 in +// the vector is is really byte 15 (or the high byte of short 7 or int 3). +// Because of this, all byte access should be via the accessors instead of +// the direct array. + +// Altivec big endian layout: AVX little endian layout: +// +---------+---------+---------+ +---------+---------+---------+ +// | int32 0 | int16 0 | int8 0 | | int32 3 | int16 7 | int8 15 | +// | | +---------+ | | +---------+ +// | | | int8 1 | | | | int8 14 | +// | +---------+---------+ | +---------+---------+ +// | | int16 1 | int8 2 | | | int16 6 | int8 13 | +// | | +---------+ | | +---------+ +// | | | int8 3 | | | | int8 12 | +// +---------+---------+---------+ +---------+---------+---------+ +// | int32 1 | int16 2 | int8 4 | | int32 2 | int16 5 | int8 11 | +// | | +---------+ | | +---------+ +// | | | int8 5 | | | | int8 10 | +// | +---------+---------+ | +---------+---------+ +// | | int16 3 | int8 6 | | | int16 4 | int8 9 | +// | | +---------+ | | +---------+ +// | | | int8 7 | | | | int8 8 | +// +---------+---------+---------+ +---------+---------+---------+ +// | int32 2 | int16 4 | int8 8 | | int32 1 | int16 3 | int8 7 | +// | | +---------+ | | +---------+ +// | | | int8 9 | | | | int8 6 | +// | +---------+---------+ | +---------+---------+ +// | | int16 5 | int8 10 | | | int16 2 | int8 5 | +// | | +---------+ | | +---------+ +// | | | int8 11 | | | | int8 4 | +// +---------+---------+---------+ +---------+---------+---------+ +// | int32 3 | int16 6 | int8 12 | | int32 0 | int16 1 | int8 3 | +// | | +---------+ | | +---------+ +// | | | int8 13 | | | | int8 2 | +// | +---------+---------+ | +---------+---------+ +// | | int16 7 | int8 14 | | | int16 0 | int8 1 | +// | | +---------+ | | +---------+ +// | | | int8 15 | | | | int8 0 | +// +---------+---------+---------+ +---------+---------+---------+ +// +// Logical order: +// +-----+-----+-----+-----+ +-----+-----+-----+-----+ +// | X | Y | Z | W | | W | Z | Y | X | +// +-----+-----+-----+-----+ +-----+-----+-----+-----+ +// +// Mapping indices is easy: +// int32[i ^ 0x3] +// int16[i ^ 0x7] +// int8[i ^ 0xF] typedef struct alignas(16) vec128_s { union { struct { @@ -23,15 +75,26 @@ typedef struct alignas(16) vec128_s { float w; }; struct { - uint32_t ix; - uint32_t iy; - uint32_t iz; - uint32_t iw; + int32_t ix; + int32_t iy; + int32_t iz; + int32_t iw; }; - float f4[4]; - uint32_t i4[4]; - uint16_t s8[8]; - uint8_t b16[16]; + struct { + uint32_t ux; + uint32_t uy; + uint32_t uz; + uint32_t uw; + }; + float f32[4]; + int8_t i8[16]; + uint8_t u8[16]; + int16_t i16[8]; + uint16_t u16[8]; + int32_t i32[4]; + uint32_t u32[4]; + int64_t i64[2]; + uint64_t u64[2]; struct { uint64_t low; uint64_t high; @@ -42,40 +105,41 @@ typedef struct alignas(16) vec128_s { return low == b.low && high == b.high; } } vec128_t; + static inline vec128_t vec128i(uint32_t src) { vec128_t v; for (auto i = 0; i < 4; ++i) { - v.i4[i] = src; + v.u32[i] = src; } return v; } static inline vec128_t vec128i(uint32_t x, uint32_t y, uint32_t z, uint32_t w) { vec128_t v; - v.i4[0] = x; - v.i4[1] = y; - v.i4[2] = z; - v.i4[3] = w; + v.u32[0] = x; + v.u32[1] = y; + v.u32[2] = z; + v.u32[3] = w; return v; } static inline vec128_t vec128f(float src) { vec128_t v; for (auto i = 0; i < 4; ++i) { - v.f4[i] = src; + v.f32[i] = src; } return v; } static inline vec128_t vec128f(float x, float y, float z, float w) { vec128_t v; - v.f4[0] = x; - v.f4[1] = y; - v.f4[2] = z; - v.f4[3] = w; + v.f32[0] = x; + v.f32[1] = y; + v.f32[2] = z; + v.f32[3] = w; return v; } static inline vec128_t vec128s(uint16_t src) { vec128_t v; for (auto i = 0; i < 8; ++i) { - v.s8[i] = src; + v.u16[i] = src; } return v; } @@ -83,20 +147,20 @@ static inline vec128_t vec128s(uint16_t x0, uint16_t x1, uint16_t y0, uint16_t y1, uint16_t z0, uint16_t z1, uint16_t w0, uint16_t w1) { vec128_t v; - v.s8[0] = x0; - v.s8[1] = x1; - v.s8[2] = y0; - v.s8[3] = y1; - v.s8[4] = z0; - v.s8[5] = z1; - v.s8[6] = w0; - v.s8[7] = w1; + v.u16[0] = x1; + v.u16[1] = x0; + v.u16[2] = y1; + v.u16[3] = y0; + v.u16[4] = z1; + v.u16[5] = z0; + v.u16[6] = w1; + v.u16[7] = w0; return v; } static inline vec128_t vec128b(uint8_t src) { vec128_t v; for (auto i = 0; i < 16; ++i) { - v.b16[i] = src; + v.u8[i] = src; } return v; } @@ -105,22 +169,22 @@ static inline vec128_t vec128b(uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t z0, uint8_t z1, uint8_t z2, uint8_t z3, uint8_t w0, uint8_t w1, uint8_t w2, uint8_t w3) { vec128_t v; - v.b16[0] = x3; - v.b16[1] = x2; - v.b16[2] = x1; - v.b16[3] = x0; - v.b16[4] = y3; - v.b16[5] = y2; - v.b16[6] = y1; - v.b16[7] = y0; - v.b16[8] = z3; - v.b16[9] = z2; - v.b16[10] = z1; - v.b16[11] = z0; - v.b16[12] = w3; - v.b16[13] = w2; - v.b16[14] = w1; - v.b16[15] = w0; + v.u8[0] = x3; + v.u8[1] = x2; + v.u8[2] = x1; + v.u8[3] = x0; + v.u8[4] = y3; + v.u8[5] = y2; + v.u8[6] = y1; + v.u8[7] = y0; + v.u8[8] = z3; + v.u8[9] = z2; + v.u8[10] = z1; + v.u8[11] = z0; + v.u8[12] = w3; + v.u8[13] = w2; + v.u8[14] = w1; + v.u8[15] = w0; return v; } diff --git a/src/poly/math.h b/src/poly/math.h index b8ab8c6de..2bd43619c 100644 --- a/src/poly/math.h +++ b/src/poly/math.h @@ -12,6 +12,7 @@ #include +#include #include #include #include @@ -38,6 +39,10 @@ T round_up(T value, V multiple) { return value + multiple - 1 - (value - 1) % multiple; } +inline float saturate(float value) { + return std::max(std::min(1.0f, value), -1.0f); +} + // Gets the next power of two value that is greater than or equal to the given // value. template diff --git a/tools/alloy-sandbox/alloy-sandbox.gypi b/tools/alloy-sandbox/alloy-sandbox.gypi index e5b947eac..7988e708f 100644 --- a/tools/alloy-sandbox/alloy-sandbox.gypi +++ b/tools/alloy-sandbox/alloy-sandbox.gypi @@ -13,6 +13,7 @@ 'dependencies': [ 'alloy', + 'xenia', ], 'include_dirs': [ diff --git a/tools/alloy-test/alloy-test.gypi b/tools/alloy-test/alloy-test.gypi index 103ce7f8d..85cc9bc5c 100644 --- a/tools/alloy-test/alloy-test.gypi +++ b/tools/alloy-test/alloy-test.gypi @@ -13,6 +13,7 @@ 'dependencies': [ 'alloy', + 'xenia', ], 'include_dirs': [ @@ -40,11 +41,11 @@ #'test_div.cc', #'test_dot_product_3.cc', #'test_dot_product_4.cc', - #'test_extract.cc', - #'test_insert.cc', + 'test_extract.cc', + 'test_insert.cc', #'test_is_true_false.cc', #'test_load_clock.cc', - #'test_load_vector.cc', + 'test_load_vector_shl_shr.cc', #'test_log2.cc', #'test_max.cc', #'test_min.cc', @@ -55,32 +56,32 @@ #'test_neg.cc', #'test_not.cc', #'test_or.cc', - #'test_pack.cc', - #'test_permute.cc', + 'test_pack.cc', + 'test_permute.cc', #'test_pow2.cc', #'test_rotate_left.cc', #'test_round.cc', #'test_rsqrt.cc', #'test_select.cc', - #'test_sha.cc', - #'test_shl.cc', - #'test_shr.cc', + 'test_sha.cc', + 'test_shl.cc', + 'test_shr.cc', #'test_sign_extend.cc', #'test_splat.cc', #'test_sqrt.cc', #'test_sub.cc', - #'test_swizzle.cc', + 'test_swizzle.cc', #'test_truncate.cc', - #'test_unpack.cc', + 'test_unpack.cc', 'test_vector_add.cc', #'test_vector_compare.cc', #'test_vector_convert.cc', 'test_vector_max.cc', 'test_vector_min.cc', - #'test_vector_rotate_left.cc', - #'test_vector_sha.cc', - #'test_vector_shl.cc', - #'test_vector_shr.cc', + 'test_vector_rotate_left.cc', + 'test_vector_sha.cc', + 'test_vector_shl.cc', + 'test_vector_shr.cc', #'test_vector_sub.cc', #'test_xor.cc', #'test_zero_extend.cc', diff --git a/tools/alloy-test/test_extract.cc b/tools/alloy-test/test_extract.cc new file mode 100644 index 000000000..9e8935399 --- /dev/null +++ b/tools/alloy-test/test_extract.cc @@ -0,0 +1,141 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include + +using namespace alloy; +using namespace alloy::hir; +using namespace alloy::runtime; +using namespace alloy::test; +using alloy::frontend::ppc::PPCContext; + +TEST_CASE("EXTRACT_INT8", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreGPR(b, 3, b.ZeroExtend(b.Extract(LoadVR(b, 4), + b.Truncate(LoadGPR(b, 4), INT8_TYPE), + INT8_TYPE), + INT64_TYPE)); + b.Return(); + }); + for (int i = 0; i < 16; ++i) { + test.Run([i](PPCContext* ctx) { + ctx->r[4] = i; + ctx->v[4] = vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15); + }, + [i](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == i); + }); + } +} + +TEST_CASE("EXTRACT_INT8_CONSTANT", "[instr]") { + for (int i = 0; i < 16; ++i) { + TestFunction([i](hir::HIRBuilder& b) { + StoreGPR(b, 3, + b.ZeroExtend( + b.Extract(LoadVR(b, 4), + b.LoadConstant(int8_t(i)), INT8_TYPE), + INT64_TYPE)); + b.Return(); + }).Run([i](PPCContext* ctx) { + ctx->r[4] = i; + ctx->v[4] = vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15); + }, + [i](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == i); + }); + } +} + +TEST_CASE("EXTRACT_INT16", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreGPR(b, 3, b.ZeroExtend(b.Extract(LoadVR(b, 4), + b.Truncate(LoadGPR(b, 4), INT8_TYPE), + INT16_TYPE), + INT64_TYPE)); + b.Return(); + }); + for (int i = 0; i < 8; ++i) { + test.Run([i](PPCContext* ctx) { + ctx->r[4] = i; + ctx->v[4] = vec128s(0x0000, 0x1001, 0x2002, 0x3003, 0x4004, + 0x5005, 0x6006, 0x7007); + }, + [i](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == (i | (i << 12))); + }); + } +} + +TEST_CASE("EXTRACT_INT16_CONSTANT", "[instr]") { + for (int i = 0; i < 8; ++i) { + TestFunction([i](hir::HIRBuilder& b) { + StoreGPR(b, 3, + b.ZeroExtend(b.Extract(LoadVR(b, 4), + b.LoadConstant(int8_t(i)), + INT16_TYPE), + INT64_TYPE)); + b.Return(); + }).Run([i](PPCContext* ctx) { + ctx->r[4] = i; + ctx->v[4] = vec128s(0, 1, 2, 3, 4, 5, 6, 7); + }, + [i](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == i); + }); + } +} + +TEST_CASE("EXTRACT_INT32", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreGPR(b, 3, b.ZeroExtend(b.Extract(LoadVR(b, 4), + b.Truncate(LoadGPR(b, 4), INT8_TYPE), + INT32_TYPE), + INT64_TYPE)); + b.Return(); + }); + for (int i = 0; i < 4; ++i) { + test.Run([i](PPCContext* ctx) { + ctx->r[4] = i; + ctx->v[4] = vec128i(0, 1, 2, 3); + }, + [i](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == i); + }); + } +} + +TEST_CASE("EXTRACT_INT32_CONSTANT", "[instr]") { + for (int i = 0; i < 4; ++i) { + TestFunction([i](hir::HIRBuilder& b) { + StoreGPR(b, 3, + b.ZeroExtend(b.Extract(LoadVR(b, 4), + b.LoadConstant(int8_t(i)), + INT32_TYPE), + INT64_TYPE)); + b.Return(); + }).Run([i](PPCContext* ctx) { + ctx->r[4] = i; + ctx->v[4] = vec128i(0, 1, 2, 3); + }, + [i](PPCContext* ctx) { + auto result = ctx->r[3]; + REQUIRE(result == i); + }); + } +} diff --git a/tools/alloy-test/test_insert.cc b/tools/alloy-test/test_insert.cc new file mode 100644 index 000000000..c14e57051 --- /dev/null +++ b/tools/alloy-test/test_insert.cc @@ -0,0 +1,83 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include + +using namespace alloy; +using namespace alloy::hir; +using namespace alloy::runtime; +using namespace alloy::test; +using alloy::frontend::ppc::PPCContext; + +TEST_CASE("INSERT_INT8", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Insert(LoadVR(b, 4), LoadGPR(b, 4), + b.Truncate(LoadGPR(b, 5), INT8_TYPE))); + b.Return(); + }); + for (int i = 0; i < 16; ++i) { + test.Run([i](PPCContext* ctx) { + ctx->v[4] = vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15); + ctx->r[4] = i; + ctx->r[5] = 100 + i; + }, + [i](PPCContext* ctx) { + auto result = ctx->v[3]; + auto expected = vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15); + expected.i8[i ^ 0x3] = 100 + i; + REQUIRE(result == expected); + }); + } +} + +TEST_CASE("INSERT_INT16", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Insert(LoadVR(b, 4), LoadGPR(b, 4), + b.Truncate(LoadGPR(b, 5), INT16_TYPE))); + b.Return(); + }); + for (int i = 0; i < 8; ++i) { + test.Run([i](PPCContext* ctx) { + ctx->v[4] = vec128s(0, 1, 2, 3, 4, 5, 6, 7); + ctx->r[4] = i; + ctx->r[5] = 100 + i; + }, + [i](PPCContext* ctx) { + auto result = ctx->v[3]; + auto expected = vec128s(0, 1, 2, 3, 4, 5, 6, 7); + expected.i16[i ^ 0x1] = 100 + i; + REQUIRE(result == expected); + }); + } +} + +TEST_CASE("INSERT_INT32", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Insert(LoadVR(b, 4), LoadGPR(b, 4), + b.Truncate(LoadGPR(b, 5), INT32_TYPE))); + b.Return(); + }); + for (int i = 0; i < 4; ++i) { + test.Run([i](PPCContext* ctx) { + ctx->v[4] = vec128i(0, 1, 2, 3); + ctx->r[4] = i; + ctx->r[5] = 100 + i; + }, + [i](PPCContext* ctx) { + auto result = ctx->v[3]; + auto expected = vec128i(0, 1, 2, 3); + expected.i32[i] = 100 + i; + REQUIRE(result == expected); + }); + } +} diff --git a/tools/alloy-test/test_load_vector_shl_shr.cc b/tools/alloy-test/test_load_vector_shl_shr.cc new file mode 100644 index 000000000..dee8f07d2 --- /dev/null +++ b/tools/alloy-test/test_load_vector_shl_shr.cc @@ -0,0 +1,78 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +using namespace alloy; +using namespace alloy::hir; +using namespace alloy::runtime; +using namespace alloy::test; +using alloy::frontend::ppc::PPCContext; + +TEST_CASE("LOAD_VECTOR_SHL", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.LoadVectorShl(b.Truncate(LoadGPR(b, 4), INT8_TYPE))); + b.Return(); + }); + test.Run([](PPCContext* ctx) { ctx->r[4] = 0; }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15)); + }); + test.Run([](PPCContext* ctx) { ctx->r[4] = 7; }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22)); + }); + test.Run([](PPCContext* ctx) { ctx->r[4] = 15; }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30)); + }); + test.Run([](PPCContext* ctx) { ctx->r[4] = 16; }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15)); + }); +} + +TEST_CASE("LOAD_VECTOR_SHR", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.LoadVectorShr(b.Truncate(LoadGPR(b, 4), INT8_TYPE))); + b.Return(); + }); + test.Run([](PPCContext* ctx) { ctx->r[4] = 0; }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31)); + }); + test.Run([](PPCContext* ctx) { ctx->r[4] = 7; }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24)); + }); + test.Run([](PPCContext* ctx) { ctx->r[4] = 15; }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16)); + }); + test.Run([](PPCContext* ctx) { ctx->r[4] = 16; }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31)); + }); +} diff --git a/tools/alloy-test/test_pack.cc b/tools/alloy-test/test_pack.cc new file mode 100644 index 000000000..4c693e729 --- /dev/null +++ b/tools/alloy-test/test_pack.cc @@ -0,0 +1,111 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +using namespace alloy; +using namespace alloy::hir; +using namespace alloy::runtime; +using namespace alloy::test; +using alloy::frontend::ppc::PPCContext; + +TEST_CASE("PACK_D3DCOLOR", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Pack(LoadVR(b, 4), PACK_TYPE_D3DCOLOR)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { ctx->v[4] = vec128f(1.0f); }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(0)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128i(0x3F800050, 0x3F800060, 0x3F800070, 0x3F800080); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(0, 0, 0, 0x80506070)); + }); +} + +TEST_CASE("PACK_FLOAT16_2", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Pack(LoadVR(b, 4), PACK_TYPE_FLOAT16_2)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0, 0, 0, 0x3F800000); }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(0)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128i(0x47FFE000, 0xC7FFE000, 0x00000000, 0x3F800000); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(0, 0, 0, 0x7FFFFFFF)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128i(0x42AAA000, 0x44CCC000, 0x00000000, 0x3F800000); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(0, 0, 0, 0x55556666)); + }); +} + +TEST_CASE("PACK_FLOAT16_4", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Pack(LoadVR(b, 4), PACK_TYPE_FLOAT16_4)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0, 0, 0, 0); }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(0)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128i(0x449A4000, 0x45B17000, 0x41103261, 0x40922B6B); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == + vec128i(0x00000000, 0x00000000, 0x64D26D8C, 0x48824491)); + }); +} + +TEST_CASE("PACK_SHORT_2", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Pack(LoadVR(b, 4), PACK_TYPE_SHORT_2)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0); }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(0)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128i(0x43817E00, 0xC37CFC00, 0, 0); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(0, 0, 0, 0x7FFF8001)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128i(0xC0D47D97, 0xC2256E9D, 0, 0); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(0, 0, 0, 0x80018001)); + }); +} diff --git a/tools/alloy-test/test_permute.cc b/tools/alloy-test/test_permute.cc new file mode 100644 index 000000000..ab16ebc68 --- /dev/null +++ b/tools/alloy-test/test_permute.cc @@ -0,0 +1,139 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +using namespace alloy; +using namespace alloy::hir; +using namespace alloy::runtime; +using namespace alloy::test; +using alloy::frontend::ppc::PPCContext; + +TEST_CASE("PERMUTE_V128_BY_INT32_CONSTANT", "[instr]") { + { + uint32_t mask = PERMUTE_MASK(0, 0, 0, 1, 0, 2, 0, 3); + TestFunction([mask](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Permute(b.LoadConstant(mask), LoadVR(b, 4), + LoadVR(b, 5), INT32_TYPE)); + b.Return(); + }).Run([](PPCContext* ctx) { + ctx->v[4] = vec128i(0, 1, 2, 3); + ctx->v[5] = vec128i(4, 5, 6, 7); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(0, 1, 2, 3)); + }); + } + { + uint32_t mask = PERMUTE_MASK(1, 0, 1, 1, 1, 2, 1, 3); + TestFunction([mask](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Permute(b.LoadConstant(mask), LoadVR(b, 4), + LoadVR(b, 5), INT32_TYPE)); + b.Return(); + }).Run([](PPCContext* ctx) { + ctx->v[4] = vec128i(0, 1, 2, 3); + ctx->v[5] = vec128i(4, 5, 6, 7); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(4, 5, 6, 7)); + }); + } + { + uint32_t mask = PERMUTE_MASK(0, 3, 0, 2, 0, 1, 0, 0); + TestFunction([mask](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Permute(b.LoadConstant(mask), LoadVR(b, 4), + LoadVR(b, 5), INT32_TYPE)); + b.Return(); + }).Run([](PPCContext* ctx) { + ctx->v[4] = vec128i(0, 1, 2, 3); + ctx->v[5] = vec128i(4, 5, 6, 7); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(3, 2, 1, 0)); + }); + } + { + uint32_t mask = PERMUTE_MASK(1, 3, 1, 2, 1, 1, 1, 0); + TestFunction([mask](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Permute(b.LoadConstant(mask), LoadVR(b, 4), + LoadVR(b, 5), INT32_TYPE)); + b.Return(); + }).Run([](PPCContext* ctx) { + ctx->v[4] = vec128i(0, 1, 2, 3); + ctx->v[5] = vec128i(4, 5, 6, 7); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(7, 6, 5, 4)); + }); + } +} + +TEST_CASE("PERMUTE_V128_BY_V128", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, + b.Permute(LoadVR(b, 3), LoadVR(b, 4), LoadVR(b, 5), VEC128_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[3] = + vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + ctx->v[4] = vec128b(100, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15); + ctx->v[5] = vec128b(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(100, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[3] = vec128b(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31); + ctx->v[4] = + vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + ctx->v[5] = vec128b(116, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(116, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[3] = + vec128b(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); + ctx->v[4] = vec128b(100, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15); + ctx->v[5] = vec128b(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, + 3, 2, 1, 100)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[3] = vec128b(31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, + 19, 18, 17, 16); + ctx->v[4] = + vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + ctx->v[5] = vec128b(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 131); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(131, 30, 29, 28, 27, 26, 25, 24, 23, 22, + 21, 20, 19, 18, 17, 16)); + }); +} diff --git a/tools/alloy-test/test_sha.cc b/tools/alloy-test/test_sha.cc new file mode 100644 index 000000000..61e4b0007 --- /dev/null +++ b/tools/alloy-test/test_sha.cc @@ -0,0 +1,211 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +using namespace alloy; +using namespace alloy::hir; +using namespace alloy::runtime; +using namespace alloy::test; +using alloy::frontend::ppc::PPCContext; + +TEST_CASE("SHA_I8", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreGPR(b, 3, b.ZeroExtend(b.Sha(b.Truncate(LoadGPR(b, 4), INT8_TYPE), + b.Truncate(LoadGPR(b, 5), INT8_TYPE)), + INT64_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xF0; + ctx->r[5] = 4; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFF); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFF; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFF); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFF; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFF); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x80; + ctx->r[5] = 8; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFF); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x7F; + ctx->r[5] = 7; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); +} + +TEST_CASE("SHA_I16", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreGPR(b, 3, b.ZeroExtend(b.Sha(b.Truncate(LoadGPR(b, 4), INT16_TYPE), + b.Truncate(LoadGPR(b, 5), INT8_TYPE)), + INT64_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFF00; + ctx->r[5] = 8; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFF); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFFFF; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFF); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFFFE; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFF); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x8000; + ctx->r[5] = 16; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFF); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x7FFF; + ctx->r[5] = 15; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); +} + +TEST_CASE("SHA_I32", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreGPR(b, 3, b.ZeroExtend(b.Sha(b.Truncate(LoadGPR(b, 4), INT32_TYPE), + b.Truncate(LoadGPR(b, 5), INT8_TYPE)), + INT64_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFFFF0000; + ctx->r[5] = 16; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFFFFFF); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFFFFFFFF; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFFFFFF); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFFFFFFFE; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFFFFFF); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x80000000; + ctx->r[5] = 32; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x80000000); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x7FFFFFFF; + ctx->r[5] = 31; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); +} + +TEST_CASE("SHA_I64", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreGPR(b, 3, b.Sha(b.Truncate(LoadGPR(b, 4), INT64_TYPE), + b.Truncate(LoadGPR(b, 5), INT8_TYPE))); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFFFFFFFF00000000ull; + ctx->r[5] = 32; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFFFFFFFFFFFFFFull); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFFFFFFFFFFFFFFFFull; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFFFFFFFFFFFFFFull); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFFFFFFFFFFFFFFFEull; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFFFFFFFFFFFFFFull); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x8000000000000000ull; + ctx->r[5] = 64; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x8000000000000000ull); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x7FFFFFFFFFFFFFFFull; + ctx->r[5] = 63; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); +} diff --git a/tools/alloy-test/test_shl.cc b/tools/alloy-test/test_shl.cc new file mode 100644 index 000000000..c05bb7071 --- /dev/null +++ b/tools/alloy-test/test_shl.cc @@ -0,0 +1,211 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +using namespace alloy; +using namespace alloy::hir; +using namespace alloy::runtime; +using namespace alloy::test; +using alloy::frontend::ppc::PPCContext; + +TEST_CASE("SHL_I8", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreGPR(b, 3, b.ZeroExtend(b.Shl(b.Truncate(LoadGPR(b, 4), INT8_TYPE), + b.Truncate(LoadGPR(b, 5), INT8_TYPE)), + INT64_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x0F; + ctx->r[5] = 4; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xF0); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFF; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFF); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFF; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFE); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x80; + ctx->r[5] = 8; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x7F; + ctx->r[5] = 7; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x80); + }); +} + +TEST_CASE("SHL_I16", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreGPR(b, 3, b.ZeroExtend(b.Shl(b.Truncate(LoadGPR(b, 4), INT16_TYPE), + b.Truncate(LoadGPR(b, 5), INT8_TYPE)), + INT64_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x00FF; + ctx->r[5] = 8; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFF00); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFFFF; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFF); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x7FFF; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFE); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x8000; + ctx->r[5] = 16; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x7FFF; + ctx->r[5] = 15; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x8000); + }); +} + +TEST_CASE("SHL_I32", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreGPR(b, 3, b.ZeroExtend(b.Shl(b.Truncate(LoadGPR(b, 4), INT32_TYPE), + b.Truncate(LoadGPR(b, 5), INT8_TYPE)), + INT64_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x0000FFFF; + ctx->r[5] = 16; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFF0000); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFFFFFFFF; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFFFFFF); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x7FFFFFFF; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFFFFFE); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x80000000; + ctx->r[5] = 32; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x80000000); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x7FFFFFFF; + ctx->r[5] = 31; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x80000000); + }); +} + +TEST_CASE("SHL_I64", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreGPR(b, 3, b.Shl(b.Truncate(LoadGPR(b, 4), INT64_TYPE), + b.Truncate(LoadGPR(b, 5), INT8_TYPE))); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x00000000FFFFFFFFull; + ctx->r[5] = 32; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFFFFFF00000000ull); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFFFFFFFFFFFFFFFFull; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFFFFFFFFFFFFFFull); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x7FFFFFFFFFFFFFFFull; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFFFFFFFFFFFFFEull); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x8000000000000000ull; + ctx->r[5] = 64; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x8000000000000000ull); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x7FFFFFFFFFFFFFFFull; + ctx->r[5] = 63; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x8000000000000000ull); + }); +} diff --git a/tools/alloy-test/test_shr.cc b/tools/alloy-test/test_shr.cc new file mode 100644 index 000000000..3ddfc6dd7 --- /dev/null +++ b/tools/alloy-test/test_shr.cc @@ -0,0 +1,211 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +using namespace alloy; +using namespace alloy::hir; +using namespace alloy::runtime; +using namespace alloy::test; +using alloy::frontend::ppc::PPCContext; + +TEST_CASE("SHR_I8", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreGPR(b, 3, b.ZeroExtend(b.Shr(b.Truncate(LoadGPR(b, 4), INT8_TYPE), + b.Truncate(LoadGPR(b, 5), INT8_TYPE)), + INT64_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xF0; + ctx->r[5] = 4; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x0F); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFF; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFF); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFF; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x7F); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x80; + ctx->r[5] = 8; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x7F; + ctx->r[5] = 7; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); +} + +TEST_CASE("SHR_I16", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreGPR(b, 3, b.ZeroExtend(b.Shr(b.Truncate(LoadGPR(b, 4), INT16_TYPE), + b.Truncate(LoadGPR(b, 5), INT8_TYPE)), + INT64_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFF00; + ctx->r[5] = 8; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x00FF); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFFFF; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFF); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFFFE; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x7FFF); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x8000; + ctx->r[5] = 16; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x7FFF; + ctx->r[5] = 15; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); +} + +TEST_CASE("SHR_I32", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreGPR(b, 3, b.ZeroExtend(b.Shr(b.Truncate(LoadGPR(b, 4), INT32_TYPE), + b.Truncate(LoadGPR(b, 5), INT8_TYPE)), + INT64_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFFFF0000; + ctx->r[5] = 16; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x0000FFFF); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFFFFFFFF; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFFFFFF); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFFFFFFFE; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x7FFFFFFF); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x80000000; + ctx->r[5] = 32; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x80000000); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x7FFFFFFF; + ctx->r[5] = 31; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); +} + +TEST_CASE("SHR_I64", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreGPR(b, 3, b.Shr(b.Truncate(LoadGPR(b, 4), INT64_TYPE), + b.Truncate(LoadGPR(b, 5), INT8_TYPE))); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFFFFFFFF00000000ull; + ctx->r[5] = 32; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x00000000FFFFFFFFull); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFFFFFFFFFFFFFFFFull; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFFFFFFFFFFFFFFull); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0xFFFFFFFFFFFFFFFEull; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x7FFFFFFFFFFFFFFFull); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x8000000000000000ull; + ctx->r[5] = 64; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x8000000000000000ull); + }); + test.Run([](PPCContext* ctx) { + ctx->r[4] = 0x7FFFFFFFFFFFFFFFull; + ctx->r[5] = 63; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); +} diff --git a/tools/alloy-test/test_swizzle.cc b/tools/alloy-test/test_swizzle.cc new file mode 100644 index 000000000..270d6fb84 --- /dev/null +++ b/tools/alloy-test/test_swizzle.cc @@ -0,0 +1,46 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +using namespace alloy; +using namespace alloy::hir; +using namespace alloy::runtime; +using namespace alloy::test; +using alloy::frontend::ppc::PPCContext; + +TEST_CASE("SWIZZLE_V128", "[instr]") { + TestFunction([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Swizzle(LoadVR(b, 4), INT32_TYPE, + SWIZZLE_MASK(0, 1, 2, 3))); + b.Return(); + }).Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0, 1, 2, 3); }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(0, 1, 2, 3)); + }); + TestFunction([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Swizzle(LoadVR(b, 4), INT32_TYPE, + SWIZZLE_MASK(3, 2, 1, 0))); + b.Return(); + }).Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0, 1, 2, 3); }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(3, 2, 1, 0)); + }); + TestFunction([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Swizzle(LoadVR(b, 4), INT32_TYPE, + SWIZZLE_MASK(1, 1, 2, 2))); + b.Return(); + }).Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0, 1, 2, 3); }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(1, 1, 2, 2)); + }); +} diff --git a/tools/alloy-test/test_unpack.cc b/tools/alloy-test/test_unpack.cc new file mode 100644 index 000000000..2af4b0ef0 --- /dev/null +++ b/tools/alloy-test/test_unpack.cc @@ -0,0 +1,162 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +using namespace alloy; +using namespace alloy::hir; +using namespace alloy::runtime; +using namespace alloy::test; +using alloy::frontend::ppc::PPCContext; + +TEST_CASE("UNPACK_D3DCOLOR", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Unpack(LoadVR(b, 4), PACK_TYPE_D3DCOLOR)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + uint32_t value = 0; + ctx->v[4] = vec128i(0, 0, 0, value); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128f(1.0f, 1.0f, 1.0f, 1.0f)); + }); + test.Run([](PPCContext* ctx) { + uint32_t value = 0x80506070; + ctx->v[4] = vec128i(0, 0, 0, value); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == + vec128i(0x3F800050, 0x3F800060, 0x3F800070, 0x3F800080)); + }); +} + +TEST_CASE("UNPACK_FLOAT16_2", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Unpack(LoadVR(b, 4), PACK_TYPE_FLOAT16_2)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0); }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(0, 0, 0, 0x3F800000)); + }); + test.Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0, 0, 0, 0x7FFFFFFF); }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == + vec128i(0x47FFE000, 0xC7FFE000, 0x00000000, 0x3F800000)); + }); + test.Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0, 0, 0, 0x55556666); }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == + vec128i(0x42AAA000, 0x44CCC000, 0x00000000, 0x3F800000)); + }); +} + +TEST_CASE("UNPACK_FLOAT16_4", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Unpack(LoadVR(b, 4), PACK_TYPE_FLOAT16_4)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0); }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128i(0)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128s(0, 0, 0, 0, 0x64D2, 0x6D8B, 0x4881, 0x4491); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == + vec128i(0x449A4000, 0x45B16000, 0x41102000, 0x40922000)); + }); +} + +TEST_CASE("UNPACK_SHORT_2", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Unpack(LoadVR(b, 4), PACK_TYPE_SHORT_2)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { ctx->v[4] = vec128i(0); }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == + vec128i(0x40400000, 0x40400000, 0x00000000, 0x3F800000)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128i(0x7004FD60, 0x8201C990, 0x00000000, 0x7FFF8001); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == + vec128i(0x40407FFF, 0x403F8001, 0x00000000, 0x3F800000)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128i(0, 0, 0, (0x1234u << 16) | 0x5678u); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == + vec128i(0x40401234, 0x40405678, 0x00000000, 0x3F800000)); + }); +} + +// TEST_CASE("UNPACK_S8_IN_16_LO", "[instr]") { +// TestFunction test([](hir::HIRBuilder& b) { +// StoreVR(b, 3, b.Unpack(LoadVR(b, 4), PACK_TYPE_S8_IN_16_LO)); +// b.Return(); +// }); +// test.Run([](PPCContext* ctx) { ctx->v[4] = vec128b(0); }, +// [](PPCContext* ctx) { +// auto result = ctx->v[3]; +// REQUIRE(result == vec128b(0)); +// }); +//} +// +// TEST_CASE("UNPACK_S8_IN_16_HI", "[instr]") { +// TestFunction test([](hir::HIRBuilder& b) { +// StoreVR(b, 3, b.Unpack(LoadVR(b, 4), PACK_TYPE_S8_IN_16_HI)); +// b.Return(); +// }); +// test.Run([](PPCContext* ctx) { ctx->v[4] = vec128b(0); }, +// [](PPCContext* ctx) { +// auto result = ctx->v[3]; +// REQUIRE(result == vec128b(0)); +// }); +//} +// +// TEST_CASE("UNPACK_S16_IN_32_LO", "[instr]") { +// TestFunction test([](hir::HIRBuilder& b) { +// StoreVR(b, 3, b.Unpack(LoadVR(b, 4), PACK_TYPE_S16_IN_32_LO)); +// b.Return(); +// }); +// test.Run([](PPCContext* ctx) { ctx->v[4] = vec128b(0); }, +// [](PPCContext* ctx) { +// auto result = ctx->v[3]; +// REQUIRE(result == vec128b(0)); +// }); +//} +// +// TEST_CASE("UNPACK_S16_IN_32_HI", "[instr]") { +// TestFunction test([](hir::HIRBuilder& b) { +// StoreVR(b, 3, b.Unpack(LoadVR(b, 4), PACK_TYPE_S16_IN_32_HI)); +// b.Return(); +// }); +// test.Run([](PPCContext* ctx) { ctx->v[4] = vec128b(0); }, +// [](PPCContext* ctx) { +// auto result = ctx->v[3]; +// REQUIRE(result == vec128b(0)); +// }); +//} diff --git a/tools/alloy-test/test_vector_rotate_left.cc b/tools/alloy-test/test_vector_rotate_left.cc new file mode 100644 index 000000000..4f96c237c --- /dev/null +++ b/tools/alloy-test/test_vector_rotate_left.cc @@ -0,0 +1,71 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include +#include + +using namespace alloy; +using namespace alloy::hir; +using namespace alloy::runtime; +using namespace alloy::test; +using alloy::frontend::ppc::PPCContext; + +TEST_CASE("VECTOR_ROTATE_LEFT_I8", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorRotateLeft(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128b(B00000001); + ctx->v[5] = + vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == + vec128b(B00000001, B00000010, B00000100, B00001000, + B00010000, B00100000, B01000000, B10000000, + B00000001, B00000010, B00000100, B00001000, + B00010000, B00100000, B01000000, B10000000)); + }); +} + +TEST_CASE("VECTOR_ROTATE_LEFT_I16", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorRotateLeft(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128s(0x0001, 0x0001, 0x0001, 0x0001, 0x1000, 0x1000, + 0x1000, 0x1000); + ctx->v[5] = vec128s(0, 1, 2, 3, 14, 15, 16, 17); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128s(0x0001, 0x0002, 0x0004, 0x0008, 0x0400, + 0x0800, 0x1000, 0x2000)); + }); +} + +TEST_CASE("VECTOR_ROTATE_LEFT_I32", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorRotateLeft(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128i(0x00000001, 0x00000001, 0x80000000, 0x80000000); + ctx->v[5] = vec128i(0, 1, 1, 2); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == + vec128i(0x00000001, 0x00000002, 0x00000001, 0x00000002)); + }); +} diff --git a/tools/alloy-test/test_vector_sha.cc b/tools/alloy-test/test_vector_sha.cc new file mode 100644 index 000000000..6c9cdc16a --- /dev/null +++ b/tools/alloy-test/test_vector_sha.cc @@ -0,0 +1,145 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +using namespace alloy; +using namespace alloy::hir; +using namespace alloy::runtime; +using namespace alloy::test; +using alloy::frontend::ppc::PPCContext; + +TEST_CASE("VECTOR_SHA_I8", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorSha(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128b(0x7E, 0x7E, 0x7E, 0x7F, 0x80, 0xFF, 0x01, 0x12, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + ctx->v[5] = + vec128b(0, 1, 2, 8, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(0x7E, 0x3F, 0x1F, 0x7F, 0xF8, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00)); + }); +} + +TEST_CASE("VECTOR_SHA_I8_CONSTANT", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorSha(LoadVR(b, 4), b.LoadConstant(vec128b( + 0, 1, 2, 8, 4, 4, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15)), + INT8_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128b(0x7E, 0x7E, 0x7E, 0x7F, 0x80, 0xFF, 0x01, 0x12, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(0x7E, 0x3F, 0x1F, 0x7F, 0xF8, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00)); + }); +} + +TEST_CASE("VECTOR_SHA_I16", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorSha(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128s(0x7FFE, 0x7FFE, 0x7FFE, 0x7FFF, 0x8000, 0xFFFF, + 0x0001, 0x1234); + ctx->v[5] = vec128s(0, 1, 8, 15, 15, 8, 1, 16); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128s(0x7FFE, 0x3FFF, 0x007F, 0x0000, 0xFFFF, + 0xFFFF, 0x0000, 0x1234)); + }); +} + +TEST_CASE("VECTOR_SHA_I16_CONSTANT", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorSha(LoadVR(b, 4), b.LoadConstant(vec128s( + 0, 1, 8, 15, 15, 8, 1, 16)), + INT16_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128s(0x7FFE, 0x7FFE, 0x7FFE, 0x7FFF, 0x8000, 0xFFFF, + 0x0001, 0x1234); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128s(0x7FFE, 0x3FFF, 0x007F, 0x0000, 0xFFFF, + 0xFFFF, 0x0000, 0x1234)); + }); +} + +TEST_CASE("VECTOR_SHA_I32", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorSha(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128i(0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFF); + ctx->v[5] = vec128i(0, 1, 16, 31); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == + vec128i(0x7FFFFFFE, 0x3FFFFFFF, 0x00007FFF, 0x00000000)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128i(0x80000000, 0xFFFFFFFF, 0x00000001, 0x12345678); + ctx->v[5] = vec128i(31, 16, 1, 32); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == + vec128i(0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x12345678)); + }); +} + +TEST_CASE("VECTOR_SHA_I32_CONSTANT", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, + b.VectorSha(LoadVR(b, 4), b.LoadConstant(vec128i(0, 1, 16, 31)), + INT32_TYPE)); + StoreVR(b, 4, + b.VectorSha(LoadVR(b, 5), b.LoadConstant(vec128i(31, 16, 1, 32)), + INT32_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128i(0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFF); + ctx->v[5] = + vec128i(0x80000000, 0xFFFFFFFF, 0x00000001, 0x12345678); + }, + [](PPCContext* ctx) { + auto result1 = ctx->v[3]; + REQUIRE(result1 == + vec128i(0x7FFFFFFE, 0x3FFFFFFF, 0x00007FFF, 0x00000000)); + auto result2 = ctx->v[4]; + REQUIRE(result2 == + vec128i(0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x12345678)); + }); +} diff --git a/tools/alloy-test/test_vector_shl.cc b/tools/alloy-test/test_vector_shl.cc new file mode 100644 index 000000000..50228d310 --- /dev/null +++ b/tools/alloy-test/test_vector_shl.cc @@ -0,0 +1,145 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +using namespace alloy; +using namespace alloy::hir; +using namespace alloy::runtime; +using namespace alloy::test; +using alloy::frontend::ppc::PPCContext; + +TEST_CASE("VECTOR_SHL_I8", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorShl(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128b(0x7E, 0x7E, 0x7E, 0x7F, 0x80, 0xFF, 0x01, 0x12, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + ctx->v[5] = + vec128b(0, 1, 2, 8, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(0x7E, 0xFC, 0xF8, 0x7F, 0x00, 0xF0, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00)); + }); +} + +TEST_CASE("VECTOR_SHL_I8_CONSTANT", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorShl(LoadVR(b, 4), b.LoadConstant(vec128b( + 0, 1, 2, 8, 4, 4, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15)), + INT8_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128b(0x7E, 0x7E, 0x7E, 0x7F, 0x80, 0xFF, 0x01, 0x12, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(0x7E, 0xFC, 0xF8, 0x7F, 0x00, 0xF0, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00)); + }); +} + +TEST_CASE("VECTOR_SHL_I16", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorShl(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128s(0x7FFE, 0x7FFE, 0x7FFE, 0x7FFF, 0x8000, 0xFFFF, + 0x0001, 0x1234); + ctx->v[5] = vec128s(0, 1, 8, 15, 15, 8, 1, 16); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128s(0x7FFE, 0xFFFC, 0xFE00, 0x8000, 0x0000, + 0xFF00, 0x0002, 0x1234)); + }); +} + +TEST_CASE("VECTOR_SHL_I16_CONSTANT", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorShl(LoadVR(b, 4), b.LoadConstant(vec128s( + 0, 1, 8, 15, 15, 8, 1, 16)), + INT16_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128s(0x7FFE, 0x7FFE, 0x7FFE, 0x7FFF, 0x8000, 0xFFFF, + 0x0001, 0x1234); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128s(0x7FFE, 0xFFFC, 0xFE00, 0x8000, 0x0000, + 0xFF00, 0x0002, 0x1234)); + }); +} + +TEST_CASE("VECTOR_SHL_I32", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorShl(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128i(0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFF); + ctx->v[5] = vec128i(0, 1, 16, 31); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == + vec128i(0x7FFFFFFE, 0xFFFFFFFC, 0xFFFE0000, 0x80000000)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128i(0x80000000, 0xFFFFFFFF, 0x00000001, 0x12345678); + ctx->v[5] = vec128i(31, 16, 1, 32); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == + vec128i(0x00000000, 0xFFFF0000, 0x00000002, 0x12345678)); + }); +} + +TEST_CASE("VECTOR_SHL_I32_CONSTANT", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, + b.VectorShl(LoadVR(b, 4), b.LoadConstant(vec128i(0, 1, 16, 31)), + INT32_TYPE)); + StoreVR(b, 4, + b.VectorShl(LoadVR(b, 5), b.LoadConstant(vec128i(31, 16, 1, 32)), + INT32_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128i(0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFF); + ctx->v[5] = + vec128i(0x80000000, 0xFFFFFFFF, 0x00000001, 0x12345678); + }, + [](PPCContext* ctx) { + auto result1 = ctx->v[3]; + REQUIRE(result1 == + vec128i(0x7FFFFFFE, 0xFFFFFFFC, 0xFFFE0000, 0x80000000)); + auto result2 = ctx->v[4]; + REQUIRE(result2 == + vec128i(0x00000000, 0xFFFF0000, 0x00000002, 0x12345678)); + }); +} diff --git a/tools/alloy-test/test_vector_shr.cc b/tools/alloy-test/test_vector_shr.cc new file mode 100644 index 000000000..25ae6c91d --- /dev/null +++ b/tools/alloy-test/test_vector_shr.cc @@ -0,0 +1,145 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +using namespace alloy; +using namespace alloy::hir; +using namespace alloy::runtime; +using namespace alloy::test; +using alloy::frontend::ppc::PPCContext; + +TEST_CASE("VECTOR_SHR_I8", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorShr(LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128b(0x7E, 0x7E, 0x7E, 0x7F, 0x80, 0xFF, 0x01, 0x12, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + ctx->v[5] = + vec128b(0, 1, 2, 8, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(0x7E, 0x3F, 0x1F, 0x7F, 0x08, 0x0F, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00)); + }); +} + +TEST_CASE("VECTOR_SHR_I8_CONSTANT", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorShr(LoadVR(b, 4), b.LoadConstant(vec128b( + 0, 1, 2, 8, 4, 4, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15)), + INT8_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128b(0x7E, 0x7E, 0x7E, 0x7F, 0x80, 0xFF, 0x01, 0x12, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128b(0x7E, 0x3F, 0x1F, 0x7F, 0x08, 0x0F, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00)); + }); +} + +TEST_CASE("VECTOR_SHR_I16", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorShr(LoadVR(b, 4), LoadVR(b, 5), INT16_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128s(0x7FFE, 0x7FFE, 0x7FFE, 0x7FFF, 0x8000, 0xFFFF, + 0x0001, 0x1234); + ctx->v[5] = vec128s(0, 1, 8, 15, 15, 8, 1, 16); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128s(0x7FFE, 0x3FFF, 0x007F, 0x0000, 0x0001, + 0x00FF, 0x0000, 0x1234)); + }); +} + +TEST_CASE("VECTOR_SHR_I16_CONSTANT", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorShr(LoadVR(b, 4), b.LoadConstant(vec128s( + 0, 1, 8, 15, 15, 8, 1, 16)), + INT16_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = vec128s(0x7FFE, 0x7FFE, 0x7FFE, 0x7FFF, 0x8000, 0xFFFF, + 0x0001, 0x1234); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == vec128s(0x7FFE, 0x3FFF, 0x007F, 0x0000, 0x0001, + 0x00FF, 0x0000, 0x1234)); + }); +} + +TEST_CASE("VECTOR_SHR_I32", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.VectorShr(LoadVR(b, 4), LoadVR(b, 5), INT32_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128i(0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFF); + ctx->v[5] = vec128i(0, 1, 16, 31); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == + vec128i(0x7FFFFFFE, 0x3FFFFFFF, 0x00007FFF, 0x00000000)); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128i(0x80000000, 0xFFFFFFFF, 0x00000001, 0x12345678); + ctx->v[5] = vec128i(31, 16, 1, 32); + }, + [](PPCContext* ctx) { + auto result = ctx->v[3]; + REQUIRE(result == + vec128i(0x00000001, 0x0000FFFF, 0x00000000, 0x12345678)); + }); +} + +TEST_CASE("VECTOR_SHR_I32_CONSTANT", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, + b.VectorShr(LoadVR(b, 4), b.LoadConstant(vec128i(0, 1, 16, 31)), + INT32_TYPE)); + StoreVR(b, 4, + b.VectorShr(LoadVR(b, 5), b.LoadConstant(vec128i(31, 16, 1, 32)), + INT32_TYPE)); + b.Return(); + }); + test.Run([](PPCContext* ctx) { + ctx->v[4] = + vec128i(0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFE, 0x7FFFFFFF); + ctx->v[5] = + vec128i(0x80000000, 0xFFFFFFFF, 0x00000001, 0x12345678); + }, + [](PPCContext* ctx) { + auto result1 = ctx->v[3]; + REQUIRE(result1 == + vec128i(0x7FFFFFFE, 0x3FFFFFFF, 0x00007FFF, 0x00000000)); + auto result2 = ctx->v[4]; + REQUIRE(result2 == + vec128i(0x00000001, 0x0000FFFF, 0x00000000, 0x12345678)); + }); +} diff --git a/tools/alloy-test/util.h b/tools/alloy-test/util.h index e6673dfe5..56924dd82 100644 --- a/tools/alloy-test/util.h +++ b/tools/alloy-test/util.h @@ -23,7 +23,7 @@ #include #define ALLOY_TEST_IVM 1 -//#define ALLOY_TEST_X64 1 +#define ALLOY_TEST_X64 1 namespace alloy { namespace test { From 9c2cf49755a9df0e56f6c7277a4e3109dc668e5f Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 29 Aug 2014 21:49:26 -0700 Subject: [PATCH 177/388] Tweaking some instructions. --- src/alloy/backend/x64/x64_sequences.cc | 6 ++-- src/alloy/frontend/ppc/ppc_emit_altivec.cc | 40 +++++++++++++--------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index f992b9949..c11016f03 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -3681,7 +3681,7 @@ EMITTER(POW2_F32, MATCH(I, F32<>>)) { static __m128 EmulatePow2(void*, __m128 src) { float src_value; _mm_store_ss(&src_value, src); - float result = std::pow(2.0f, src_value); + float result = std::exp2(src_value); return _mm_load_ss(&result); } static void Emit(X64Emitter& e, const EmitArgType& i) { @@ -3695,7 +3695,7 @@ EMITTER(POW2_F64, MATCH(I, F64<>>)) { static __m128d EmulatePow2(void*, __m128d src) { double src_value; _mm_store_sd(&src_value, src); - double result = std::pow(2, src_value); + double result = std::exp2(src_value); return _mm_load_sd(&result); } static void Emit(X64Emitter& e, const EmitArgType& i) { @@ -3710,7 +3710,7 @@ EMITTER(POW2_V128, MATCH(I, V128<>>)) { alignas(16) float values[4]; _mm_store_ps(values, src); for (size_t i = 0; i < 4; ++i) { - values[i] = std::pow(2.0f, values[i]); + values[i] = std::exp2(values[i]); } return _mm_load_ps(values); } diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index 479c94f79..cfbb58ecd 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -489,9 +489,9 @@ XEEMITTER(vavguw, 0x10000482, VX)(PPCHIRBuilder& f, InstrData& i) { int InstrEmit_vcfsx_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm) { // (VD) <- float(VB as signed) / 2^uimm - uimm = uimm ? (2 << (uimm - 1)) : 1; + float fuimm = std::exp2(uimm); Value* v = f.Div(f.VectorConvertI2F(f.LoadVR(vb)), - f.Splat(f.LoadConstant((float)uimm), VEC128_TYPE)); + f.Splat(f.LoadConstant(fuimm), VEC128_TYPE)); f.StoreVR(vd, v); return 0; } @@ -506,9 +506,9 @@ XEEMITTER(vcsxwfp128, VX128_3(6, 688), VX128_3)(PPCHIRBuilder& f, int InstrEmit_vcfux_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm) { // (VD) <- float(VB as unsigned) / 2^uimm - uimm = uimm ? (2 << (uimm - 1)) : 1; + float fuimm = std::exp2(uimm); Value* v = f.Div(f.VectorConvertI2F(f.LoadVR(vb), ARITHMETIC_UNSIGNED), - f.Splat(f.LoadConstant((float)uimm), VEC128_TYPE)); + f.Splat(f.LoadConstant(fuimm), VEC128_TYPE)); f.StoreVR(vd, v); return 0; } @@ -523,9 +523,8 @@ XEEMITTER(vcuxwfp128, VX128_3(6, 752), VX128_3)(PPCHIRBuilder& f, int InstrEmit_vctsxs_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm) { // (VD) <- int_sat(VB as signed * 2^uimm) - uimm = uimm ? (2 << (uimm - 1)) : 1; - Value* v = - f.Mul(f.LoadVR(vb), f.Splat(f.LoadConstant((float)uimm), VEC128_TYPE)); + float fuimm = std::exp2(uimm); + Value* v = f.Mul(f.LoadVR(vb), f.Splat(f.LoadConstant(fuimm), VEC128_TYPE)); v = f.VectorConvertF2I(v, ARITHMETIC_SATURATE); f.StoreVR(vd, v); return 0; @@ -541,9 +540,8 @@ XEEMITTER(vcfpsxws128, VX128_3(6, 560), VX128_3)(PPCHIRBuilder& f, int InstrEmit_vctuxs_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm) { // (VD) <- int_sat(VB as unsigned * 2^uimm) - uimm = uimm ? (2 << (uimm - 1)) : 1; - Value* v = - f.Mul(f.LoadVR(vb), f.Splat(f.LoadConstant((float)uimm), VEC128_TYPE)); + float fuimm = std::exp2(uimm); + Value* v = f.Mul(f.LoadVR(vb), f.Splat(f.LoadConstant(fuimm), VEC128_TYPE)); v = f.VectorConvertF2I(v, ARITHMETIC_UNSIGNED | ARITHMETIC_SATURATE); f.StoreVR(vd, v); return 0; @@ -556,6 +554,8 @@ XEEMITTER(vcfpuxws128, VX128_3(6, 624), VX128_3)(PPCHIRBuilder& f, return InstrEmit_vctuxs_(f, VX128_3_VD128, VX128_3_VB128, VX128_3_IMM); } +// vcmpbfp128 VT, VA, VB VT.u0 = ((VA.x < VB.x) << 31)| ((VA.x > -VB.x) << 30); ...; VT.u0 = ((VA.x > VB.x) << 31)| ((VA.x < -VB.x) << 30); +// vcmpbfp128. VT, VA, VB VT.u0 = ((VA.x < VB.x) << 31)| ((VA.x > -VB.x) << 30); ...; VT.u0 = ((VA.x > VB.x) << 31)| ((VA.x < -VB.x) << 30); CR0:4 = 0; CR0:5 = VT == 0; CR0:6 = CR0:7 = 0; int InstrEmit_vcmpbfp_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t va, uint32_t vb, uint32_t rc) { XEINSTRNOTIMPLEMENTED(); @@ -1151,7 +1151,7 @@ XEEMITTER(vpermwi128, VX128_P(6, 528), VX128_P)(PPCHIRBuilder& f, int InstrEmit_vrefp_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { // (VD) <- 1/(VB) - vec128_t one = {{{1, 1, 1, 1}}}; + vec128_t one = vec128f(1.0f); Value* v = f.Div(f.LoadConstant(one), f.LoadVR(vb)); f.StoreVR(vd, v); return 0; @@ -1310,8 +1310,8 @@ XEEMITTER(vrsqrtefp128, VX128_3(6, 1648), VX128_3)(PPCHIRBuilder& f, int InstrEmit_vsel_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, uint32_t vc) { - Value* a = f.LoadVR(va); - Value* v = f.Xor(f.And(f.Xor(a, f.LoadVR(vb)), f.LoadVR(vc)), a); + Value* c = f.LoadVR(vc); + Value* v = f.Or(f.And(f.LoadVR(va), f.Not(c)), f.And(f.LoadVR(vb), c)); f.StoreVR(vd, v); return 0; } @@ -1323,8 +1323,11 @@ XEEMITTER(vsel128, VX128(5, 848), VX128)(PPCHIRBuilder& f, InstrData& i) { } XEEMITTER(vsl, 0x100001C4, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + Value* v = f.Shl(f.LoadVR(i.VX.VA), + f.And(f.Extract(f.LoadVR(i.VX.VB), 15, INT8_TYPE), + f.LoadConstant(int8_t(0x7F)))); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vslb, 0x10000104, VX)(PPCHIRBuilder& f, InstrData& i) { @@ -1499,8 +1502,11 @@ XEEMITTER(vspltisw128, VX128_3(6, 1904), VX128_3)(PPCHIRBuilder& f, } XEEMITTER(vsr, 0x100002C4, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + Value* v = f.Shr(f.LoadVR(i.VX.VA), + f.And(f.Extract(f.LoadVR(i.VX.VB), 15, INT8_TYPE), + f.LoadConstant(int8_t(0x7F)))); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vsrab, 0x10000304, VX)(PPCHIRBuilder& f, InstrData& i) { From 8dcfe94d81db294bbf2d57bb604ef714b1655caa Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 1 Sep 2014 10:03:52 -0700 Subject: [PATCH 178/388] Fix cleanup of object table (double NtClose crash). --- src/xenia/kernel/object_table.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/xenia/kernel/object_table.cc b/src/xenia/kernel/object_table.cc index 8745a3814..6240280bb 100644 --- a/src/xenia/kernel/object_table.cc +++ b/src/xenia/kernel/object_table.cc @@ -138,6 +138,7 @@ X_STATUS ObjectTable::RemoveHandle(X_HANDLE handle) { } else { result = X_STATUS_INVALID_HANDLE; } + entry.object = nullptr; } } From c00e162b88e931f0d4b37e7e102c6eb77d83a11c Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 1 Sep 2014 10:47:37 -0700 Subject: [PATCH 179/388] Unpack d3dcolor const. --- src/alloy/backend/x64/x64_sequences.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index c11016f03..0a9de3fbc 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -5089,7 +5089,12 @@ EMITTER(UNPACK, MATCH(I, V128<>>)) { // ARGB (WXYZ) -> RGBA (XYZW) // XMLoadColor if (i.src1.is_constant) { - assert_always(); + if (i.src1.value->IsConstantZero()) { + e.vmovaps(i.dest, e.GetXmmConstPtr(XMMOne)); + return; + } else { + assert_always(); + } } // src = ZZYYXXWW // Unpack to 000000ZZ,000000YY,000000XX,000000WW From 1bd789de56631479c5b4f148dbda85078b57817c Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 1 Sep 2014 10:50:47 -0700 Subject: [PATCH 180/388] A few more altivec instructions. --- src/alloy/frontend/ppc/ppc_emit_altivec.cc | 103 ++++++++++++++------- 1 file changed, 68 insertions(+), 35 deletions(-) diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index cfbb58ecd..d62886946 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -924,13 +924,24 @@ XEEMITTER(vmladduhm, 0x10000022, VXA)(PPCHIRBuilder& f, InstrData& i) { } XEEMITTER(vmrghb, 0x1000000C, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD.b[i]) = (VA.b[i]) + // (VD.b[i+1]) = (VB.b[i+1]) + // ... + Value* v = f.Permute(f.LoadConstant(vec128b(0, 16, 1, 17, 2, 18, 3, 19, 4, 20, + 5, 21, 6, 22, 7, 23)), + f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT8_TYPE); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vmrghh, 0x1000004C, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD.w[i]) = (VA.w[i]) + // (VD.w[i+1]) = (VB.w[i+1]) + // ... + Value* v = f.Permute(f.LoadConstant(vec128s(0, 8, 1, 9, 2, 10, 3, 11)), + f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT16_TYPE); + f.StoreVR(i.VX.VD, v); + return 0; } int InstrEmit_vmrghw_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { @@ -951,13 +962,24 @@ XEEMITTER(vmrghw128, VX128(6, 768), VX128)(PPCHIRBuilder& f, InstrData& i) { } XEEMITTER(vmrglb, 0x1000010C, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD.b[i]) = (VA.b[i]) + // (VD.b[i+1]) = (VB.b[i+1]) + // ... + Value* v = f.Permute(f.LoadConstant(vec128b(8, 24, 9, 25, 10, 26, 11, 27, 12, + 28, 13, 29, 14, 30, 15, 31)), + f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT8_TYPE); + f.StoreVR(i.VX.VD, v); + return 0; } XEEMITTER(vmrglh, 0x1000014C, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // (VD.w[i]) = (VA.w[i]) + // (VD.w[i+1]) = (VB.w[i+1]) + // ... + Value* v = f.Permute(f.LoadConstant(vec128s(4, 12, 5, 13, 6, 14, 7, 15)), + f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT16_TYPE); + f.StoreVR(i.VX.VD, v); + return 0; } int InstrEmit_vmrglw_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { @@ -1357,23 +1379,23 @@ XEEMITTER(vslw128, VX128(6, 208), VX128)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vslw_(f, VX128_VD128, VX128_VA128, VX128_VB128); } -static uint8_t __vsldoi_table[16][16] = { - {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, - {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, - {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, - {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}, - {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}, - {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, - {6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}, - {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}, - {8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}, - {9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}, - {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}, - {11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}, - {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27}, - {13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28}, - {14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}, - {15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}, +static const vec128_t __vsldoi_table[16] = { + vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), + vec128b(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), + vec128b(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17), + vec128b(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18), + vec128b(4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19), + vec128b(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20), + vec128b(6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21), + vec128b(7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22), + vec128b(8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23), + vec128b(9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24), + vec128b(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25), + vec128b(11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26), + vec128b(12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27), + vec128b(13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28), + vec128b(14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29), + vec128b(15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30), }; int InstrEmit_vsldoi_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, uint32_t sh) { @@ -1389,11 +1411,7 @@ int InstrEmit_vsldoi_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, // vsldoi128 vr63,vr63,vr63,4 // (ABCD ABCD) << 4b = (BCDA) // (VA << SH) OR (VB >> (16 - SH)) - vec128_t shift = *((vec128_t*)(__vsldoi_table[sh])); - for (int i = 0; i < 4; ++i) { - shift.u32[i] = poly::byte_swap(shift.u32[i]); - } - Value* control = f.LoadConstant(shift); + Value* control = f.LoadConstant(__vsldoi_table[sh]); Value* v = f.Permute(control, f.LoadVR(va), f.LoadVR(vb), INT8_TYPE); f.StoreVR(vd, v); return 0; @@ -1406,13 +1424,21 @@ XEEMITTER(vsldoi128, VX128_5(4, 16), VX128_5)(PPCHIRBuilder& f, InstrData& i) { VX128_5_SH); } +int InstrEmit_vslo_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { + // (VD) <- (VA) << (VB.b[F] & 0x78) (by octet) + // TODO(benvanik): flag for shift-by-octet as optimization. + Value* sh = + f.And(f.Extract(f.LoadVR(vb), 15, INT8_TYPE), f.LoadConstant(int8_t(0x78))); + Value* v = f.Permute(f.LoadVectorShl(sh), f.LoadVR(va), + f.LoadZero(VEC128_TYPE), INT8_TYPE); + f.StoreVR(vd, v); + return 0; +} XEEMITTER(vslo, 0x1000040C, VX)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + return InstrEmit_vslo_(f, i.VX.VD, i.VX.VA, i.VX.VB); } XEEMITTER(vslo128, VX128(5, 912), VX128)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + return InstrEmit_vslo_(f, VX128_VD128, VX128_VA128, VX128_VB128); } XEEMITTER(vspltb, 0x1000020C, VX)(PPCHIRBuilder& f, InstrData& i) { @@ -1551,7 +1577,14 @@ XEEMITTER(vsrh, 0x10000244, VX)(PPCHIRBuilder& f, InstrData& i) { } int InstrEmit_vsro_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { - return 1; + // (VD) <- (VA) >> (VB.b[F] & 0x78) (by octet) + // TODO(benvanik): flag for shift-by-octet as optimization. + Value* sh = + f.And(f.Extract(f.LoadVR(vb), 15, INT8_TYPE), f.LoadConstant(0x78)); + Value* v = f.Permute(f.LoadVectorShr(sh), f.LoadVR(va), + f.LoadZero(VEC128_TYPE), INT8_TYPE); + f.StoreVR(vd, v); + return 0; } XEEMITTER(vsro, 0x1000044C, VX)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vsro_(f, i.VX.VD, i.VX.VA, i.VX.VB); From d30483bf530b416dedc101071bd1ea8b6519c69e Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 1 Sep 2014 12:24:53 -0700 Subject: [PATCH 181/388] Fixing IVM vector compare. --- src/alloy/backend/ivm/ivm_intcode.cc | 57 ++++++++++++++-------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc index 141d6790f..52654fd9c 100644 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ b/src/alloy/backend/ivm/ivm_intcode.cc @@ -2296,24 +2296,25 @@ int Translate_DID_SATURATE(TranslationContext& ctx, Instr* i) { return DispatchToC(ctx, i, IntCode_DID_SATURATE); } -#define VECTOR_COMPARER(type, value, dest_value, count, op) \ - const vec128_t& src1 = ics.rf[i->src1_reg].v128; \ - const vec128_t& src2 = ics.rf[i->src2_reg].v128; \ - vec128_t& dest = ics.rf[i->dest_reg].v128; \ - for (int n = 0; n < count; n++) { \ - dest.dest_value[n] = \ - ((type)src1.value[n] op(type) src2.value[n]) ? (type)0xFFFFFFFF : 0; \ - } \ +#define VECTOR_COMPARER(type, value, dest_type, dest_value, count, op) \ + const vec128_t& src1 = ics.rf[i->src1_reg].v128; \ + const vec128_t& src2 = ics.rf[i->src2_reg].v128; \ + vec128_t& dest = ics.rf[i->dest_reg].v128; \ + for (int n = 0; n < count; n++) { \ + dest.dest_value[n] = ((type)src1.value[n] op(type) src2.value[n]) \ + ? (dest_type)0xFFFFFFFF \ + : 0; \ + } \ return IA_NEXT; uint32_t IntCode_VECTOR_COMPARE_EQ_I8(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(uint8_t, u8, u8, 16, == )}; + VECTOR_COMPARER(uint8_t, u8, uint8_t, u8, 16, == )}; uint32_t IntCode_VECTOR_COMPARE_EQ_I16(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(uint16_t, u16, u16, 8, == )}; + VECTOR_COMPARER(uint16_t, u16, uint16_t, u16, 8, == )}; uint32_t IntCode_VECTOR_COMPARE_EQ_I32(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(uint32_t, u32, u32, 4, == )}; + VECTOR_COMPARER(uint32_t, u32, uint32_t, u32, 4, == )}; uint32_t IntCode_VECTOR_COMPARE_EQ_F32(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(float, f32, u32, 4, == )}; + VECTOR_COMPARER(float, f32, uint32_t, u32, 4, == )}; int Translate_VECTOR_COMPARE_EQ(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { IntCode_VECTOR_COMPARE_EQ_I8, IntCode_VECTOR_COMPARE_EQ_I16, @@ -2325,13 +2326,13 @@ int Translate_VECTOR_COMPARE_EQ(TranslationContext& ctx, Instr* i) { } uint32_t IntCode_VECTOR_COMPARE_SGT_I8(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(int8_t, i8, i8, 16, > )}; + VECTOR_COMPARER(int8_t, i8, int8_t, i8, 16, > )}; uint32_t IntCode_VECTOR_COMPARE_SGT_I16(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(int16_t, i16, i16, 8, > )}; + VECTOR_COMPARER(int16_t, i16, int16_t, i16, 8, > )}; uint32_t IntCode_VECTOR_COMPARE_SGT_I32(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(int32_t, i32, i32, 4, > )}; + VECTOR_COMPARER(int32_t, i32, int32_t, i32, 4, > )}; uint32_t IntCode_VECTOR_COMPARE_SGT_F32(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(float, f32, u32, 4, > )}; + VECTOR_COMPARER(float, f32, uint32_t, u32, 4, > )}; int Translate_VECTOR_COMPARE_SGT(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { IntCode_VECTOR_COMPARE_SGT_I8, IntCode_VECTOR_COMPARE_SGT_I16, @@ -2343,13 +2344,13 @@ int Translate_VECTOR_COMPARE_SGT(TranslationContext& ctx, Instr* i) { } uint32_t IntCode_VECTOR_COMPARE_SGE_I8(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(int8_t, i8, i8, 16, >= )}; + VECTOR_COMPARER(int8_t, i8, int8_t, i8, 16, >= )}; uint32_t IntCode_VECTOR_COMPARE_SGE_I16(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(int16_t, i16, i16, 8, >= )}; + VECTOR_COMPARER(int16_t, i16, int16_t, i16, 8, >= )}; uint32_t IntCode_VECTOR_COMPARE_SGE_I32(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(int32_t, i32, i32, 4, >= )}; + VECTOR_COMPARER(int32_t, i32, int32_t, i32, 4, >= )}; uint32_t IntCode_VECTOR_COMPARE_SGE_F32(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(float, f32, u32, 4, >= )}; + VECTOR_COMPARER(float, f32, uint32_t, u32, 4, >= )}; int Translate_VECTOR_COMPARE_SGE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { IntCode_VECTOR_COMPARE_SGE_I8, IntCode_VECTOR_COMPARE_SGE_I16, @@ -2361,13 +2362,13 @@ int Translate_VECTOR_COMPARE_SGE(TranslationContext& ctx, Instr* i) { } uint32_t IntCode_VECTOR_COMPARE_UGT_I8(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(uint8_t, u8, u8, 16, > )}; + VECTOR_COMPARER(uint8_t, u8, uint8_t, u8, 16, > )}; uint32_t IntCode_VECTOR_COMPARE_UGT_I16(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(uint16_t, u16, u16, 8, > )}; + VECTOR_COMPARER(uint16_t, u16, uint16_t, u16, 8, > )}; uint32_t IntCode_VECTOR_COMPARE_UGT_I32(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(uint32_t, u32, u32, 4, > )}; + VECTOR_COMPARER(uint32_t, u32, uint32_t, u32, 4, > )}; uint32_t IntCode_VECTOR_COMPARE_UGT_F32(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(float, f32, u32, 4, > )}; + VECTOR_COMPARER(float, f32, uint32_t, u32, 4, > )}; int Translate_VECTOR_COMPARE_UGT(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { IntCode_VECTOR_COMPARE_UGT_I8, IntCode_VECTOR_COMPARE_UGT_I16, @@ -2379,13 +2380,13 @@ int Translate_VECTOR_COMPARE_UGT(TranslationContext& ctx, Instr* i) { } uint32_t IntCode_VECTOR_COMPARE_UGE_I8(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(uint8_t, u8, u8, 16, >= )}; + VECTOR_COMPARER(uint8_t, u8, uint8_t, u8, 16, >= )}; uint32_t IntCode_VECTOR_COMPARE_UGE_I16(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(uint16_t, u16, u16, 8, >= )}; + VECTOR_COMPARER(uint16_t, u16, uint16_t, u16, 8, >= )}; uint32_t IntCode_VECTOR_COMPARE_UGE_I32(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(uint32_t, u32, u32, 4, >= )}; + VECTOR_COMPARER(uint32_t, u32, uint32_t, u32, 4, >= )}; uint32_t IntCode_VECTOR_COMPARE_UGE_F32(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(float, f32, u32, 4, >= )}; + VECTOR_COMPARER(float, f32, uint32_t, u32, 4, >= )}; int Translate_VECTOR_COMPARE_UGE(TranslationContext& ctx, Instr* i) { static IntCodeFn fns[] = { IntCode_VECTOR_COMPARE_UGE_I8, IntCode_VECTOR_COMPARE_UGE_I16, From 080a0f8026951913ca87c277db29e561e87b7820 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 1 Sep 2014 13:00:00 -0700 Subject: [PATCH 182/388] Fixing vsel. --- src/alloy/backend/x64/x64_sequences.cc | 29 ++++++++++++++++++++-- src/alloy/frontend/ppc/ppc_emit_altivec.cc | 3 +-- src/alloy/hir/hir_builder.cc | 2 +- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index 0a9de3fbc..2bbb56190 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -1913,7 +1913,7 @@ EMITTER(SELECT_F64, MATCH(I, I8<>, F64<>, F64<>>)) { e.vpor(i.dest, e.xmm1); } }; -EMITTER(SELECT_V128, MATCH(I, I8<>, V128<>, V128<>>)) { +EMITTER(SELECT_V128_I8, MATCH(I, I8<>, V128<>, V128<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { // TODO(benvanik): find a shorter sequence. // xmm0 = src1 != 0 ? 1111... : 0000.... @@ -1927,6 +1927,30 @@ EMITTER(SELECT_V128, MATCH(I, I8<>, V128<>, V128<>>)) { e.vpor(i.dest, e.xmm1); } }; +EMITTER(SELECT_V128_V128, MATCH(I, V128<>, V128<>, V128<>>)) { + static void Emit(X64Emitter& e, const EmitArgType& i) { + // TODO(benvanik): could be made shorter when consts involved. + if (i.src2.is_constant) { + if (i.src2.value->IsConstantZero()) { + e.vpxor(e.xmm1, e.xmm1); + } else { + assert_always(); + } + } else { + e.vpandn(e.xmm1, i.src1, i.src2); + } + if (i.src3.is_constant) { + if (i.src3.value->IsConstantZero()) { + e.vpxor(i.dest, i.dest); + } else { + assert_always(); + } + } else { + e.vpand(i.dest, i.src1, i.src3); + } + e.vpor(i.dest, e.xmm1); + } +}; EMITTER_OPCODE_TABLE( OPCODE_SELECT, SELECT_I8, @@ -1935,7 +1959,8 @@ EMITTER_OPCODE_TABLE( SELECT_I64, SELECT_F32, SELECT_F64, - SELECT_V128); + SELECT_V128_I8, + SELECT_V128_V128); // ============================================================================ diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index d62886946..453fd1ec0 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -1332,8 +1332,7 @@ XEEMITTER(vrsqrtefp128, VX128_3(6, 1648), VX128_3)(PPCHIRBuilder& f, int InstrEmit_vsel_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, uint32_t vc) { - Value* c = f.LoadVR(vc); - Value* v = f.Or(f.And(f.LoadVR(va), f.Not(c)), f.And(f.LoadVR(vb), c)); + Value* v = f.Select(f.LoadVR(vc), f.LoadVR(va), f.LoadVR(vb)); f.StoreVR(vd, v); return 0; } diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index ccc089eb8..58929fd2d 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -1182,7 +1182,7 @@ Value* HIRBuilder::VectorMin(Value* value1, Value* value2, TypeName part_type, } Value* HIRBuilder::Select(Value* cond, Value* value1, Value* value2) { - assert_true(cond->type == INT8_TYPE); // for now + assert_true(cond->type == INT8_TYPE || cond->type == VEC128_TYPE); // for now ASSERT_TYPES_EQUAL(value1, value2); if (cond->IsConstant()) { From c9229670db637f7a944051cb908693c7fc7e7414 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 1 Sep 2014 14:14:55 -0700 Subject: [PATCH 183/388] Fixing warnings. --- src/alloy/frontend/ppc/ppc_emit_altivec.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index 453fd1ec0..bf3698fe5 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -489,7 +489,7 @@ XEEMITTER(vavguw, 0x10000482, VX)(PPCHIRBuilder& f, InstrData& i) { int InstrEmit_vcfsx_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm) { // (VD) <- float(VB as signed) / 2^uimm - float fuimm = std::exp2(uimm); + float fuimm = static_cast(std::exp2(uimm)); Value* v = f.Div(f.VectorConvertI2F(f.LoadVR(vb)), f.Splat(f.LoadConstant(fuimm), VEC128_TYPE)); f.StoreVR(vd, v); @@ -506,7 +506,7 @@ XEEMITTER(vcsxwfp128, VX128_3(6, 688), VX128_3)(PPCHIRBuilder& f, int InstrEmit_vcfux_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm) { // (VD) <- float(VB as unsigned) / 2^uimm - float fuimm = std::exp2(uimm); + float fuimm = static_cast(std::exp2(uimm)); Value* v = f.Div(f.VectorConvertI2F(f.LoadVR(vb), ARITHMETIC_UNSIGNED), f.Splat(f.LoadConstant(fuimm), VEC128_TYPE)); f.StoreVR(vd, v); @@ -523,7 +523,7 @@ XEEMITTER(vcuxwfp128, VX128_3(6, 752), VX128_3)(PPCHIRBuilder& f, int InstrEmit_vctsxs_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm) { // (VD) <- int_sat(VB as signed * 2^uimm) - float fuimm = std::exp2(uimm); + float fuimm = static_cast(std::exp2(uimm)); Value* v = f.Mul(f.LoadVR(vb), f.Splat(f.LoadConstant(fuimm), VEC128_TYPE)); v = f.VectorConvertF2I(v, ARITHMETIC_SATURATE); f.StoreVR(vd, v); @@ -540,7 +540,7 @@ XEEMITTER(vcfpsxws128, VX128_3(6, 560), VX128_3)(PPCHIRBuilder& f, int InstrEmit_vctuxs_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm) { // (VD) <- int_sat(VB as unsigned * 2^uimm) - float fuimm = std::exp2(uimm); + float fuimm = static_cast(std::exp2(uimm)); Value* v = f.Mul(f.LoadVR(vb), f.Splat(f.LoadConstant(fuimm), VEC128_TYPE)); v = f.VectorConvertF2I(v, ARITHMETIC_UNSIGNED | ARITHMETIC_SATURATE); f.StoreVR(vd, v); From ed61d025c1cd2815a75faa5eac232358acbd34ce Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 1 Sep 2014 14:18:41 -0700 Subject: [PATCH 184/388] vcmpbfp --- src/alloy/frontend/ppc/ppc_emit_altivec.cc | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index bf3698fe5..e5de7e4cf 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -554,12 +554,23 @@ XEEMITTER(vcfpuxws128, VX128_3(6, 624), VX128_3)(PPCHIRBuilder& f, return InstrEmit_vctuxs_(f, VX128_3_VD128, VX128_3_VB128, VX128_3_IMM); } -// vcmpbfp128 VT, VA, VB VT.u0 = ((VA.x < VB.x) << 31)| ((VA.x > -VB.x) << 30); ...; VT.u0 = ((VA.x > VB.x) << 31)| ((VA.x < -VB.x) << 30); -// vcmpbfp128. VT, VA, VB VT.u0 = ((VA.x < VB.x) << 31)| ((VA.x > -VB.x) << 30); ...; VT.u0 = ((VA.x > VB.x) << 31)| ((VA.x < -VB.x) << 30); CR0:4 = 0; CR0:5 = VT == 0; CR0:6 = CR0:7 = 0; int InstrEmit_vcmpbfp_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t va, uint32_t vb, uint32_t rc) { - XEINSTRNOTIMPLEMENTED(); - return 1; + Value* va_value = f.LoadVR(va); + Value* vb_value = f.LoadVR(vb); + Value* gt = f.VectorCompareSGT(va_value, vb_value, FLOAT32_TYPE); + Value* lt = + f.Not(f.VectorCompareSGE(va_value, f.Neg(vb_value), FLOAT32_TYPE)); + Value* v = f.Or(f.And(gt, f.LoadConstant(vec128i(0x80000000, 0x80000000, + 0x80000000, 0x80000000))), + f.And(lt, f.LoadConstant(vec128i(0x40000000, 0x40000000, + 0x40000000, 0x40000000)))); + f.StoreVR(vd, v); + if (rc) { + // CR0:4 = 0; CR0:5 = VT == 0; CR0:6 = CR0:7 = 0; + assert_always(); + } + return 0; } XEEMITTER(vcmpbfp, 0x100003C6, VXR)(PPCHIRBuilder& f, InstrData& i) { return InstrEmit_vcmpbfp_(f, i, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); From 437ec45d6612fb2a21b5a74e5b47562e8799e7cd Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 9 Sep 2014 20:15:49 -0700 Subject: [PATCH 185/388] Binutils with patch (brought forward a decade) for vmx128. --- .gitignore | 7 + Vagrantfile | 46 ++ third_party/binutils/README.md | 6 + .../binutils/binutils-2.24-vmx128.patch | 396 ++++++++++++++++++ third_party/binutils/build.sh | 65 +++ xenia-build.py | 54 +-- 6 files changed, 543 insertions(+), 31 deletions(-) create mode 100644 Vagrantfile create mode 100644 third_party/binutils/README.md create mode 100644 third_party/binutils/binutils-2.24-vmx128.patch create mode 100644 third_party/binutils/build.sh diff --git a/.gitignore b/.gitignore index 1a83a9bd8..c976ca4a3 100644 --- a/.gitignore +++ b/.gitignore @@ -75,5 +75,12 @@ build-test/ # ============================================================================== # Local-only paths # ============================================================================== + +.vagrant attic/ +third_party/binutils/binutils-2.24.tar.gz +third_party/binutils/bin/ +third_party/binutils/powerpc-none-elf/ +third_party/binutils/share/ +third_party/binutils/binutils* third_party/vasm/ diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 000000000..c659c6438 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,46 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +VAGRANTFILE_API_VERSION = "2" + +$script = <\n" +"\n" +" "; + +const size_t g_MicroProfileHtml_end_size = sizeof(g_MicroProfileHtml_end); +#endif //MICROPROFILE_EMBED_HTML + + +///end embedded file from microprofile.html diff --git a/third_party/microprofile/microprofileui.h b/third_party/microprofile/microprofileui.h new file mode 100644 index 000000000..bce3904dd --- /dev/null +++ b/third_party/microprofile/microprofileui.h @@ -0,0 +1,2760 @@ +#pragma once +// This is free and unencumbered software released into the public domain. +// Anyone is free to copy, modify, publish, use, compile, sell, or +// distribute this software, either in source code form or as a compiled +// binary, for any purpose, commercial or non-commercial, and by any +// means. +// In jurisdictions that recognize copyright laws, the author or authors +// of this software dedicate any and all copyright interest in the +// software to the public domain. We make this dedication for the benefit +// of the public at large and to the detriment of our heirs and +// successors. We intend this dedication to be an overt act of +// relinquishment in perpetuity of all present and future rights to this +// software under copyright law. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// For more information, please refer to +// +// *********************************************************************** +// +// +// + + +#ifndef MICROPROFILE_ENABLED +#error "microprofile.h must be included before including microprofileui.h" +#endif + +#ifndef MICROPROFILEUI_ENABLED +#define MICROPROFILEUI_ENABLED MICROPROFILE_ENABLED +#endif + +#ifndef MICROPROFILEUI_API +#define MICROPROFILEUI_API +#endif + + +#if 0 == MICROPROFILEUI_ENABLED +#define MicroProfileMouseButton(foo, bar) do{}while(0) +#define MicroProfileMousePosition(foo, bar, z) do{}while(0) +#define MicroProfileModKey(key) do{}while(0) +#define MicroProfileDraw(foo, bar) do{}while(0) +#define MicroProfileIsDrawing() 0 +#define MicroProfileToggleDisplayMode() do{}while(0) +#define MicroProfileSetDisplayMode(f) do{}while(0) +#else + +#ifndef MICROPROFILE_DRAWCURSOR +#define MICROPROFILE_DRAWCURSOR 0 +#endif + +#ifndef MICROPROFILE_DETAILED_BAR_NAMES +#define MICROPROFILE_DETAILED_BAR_NAMES 1 +#endif + +#ifndef MICROPROFILE_TEXT_WIDTH +#define MICROPROFILE_TEXT_WIDTH 5 +#endif + +#ifndef MICROPROFILE_TEXT_HEIGHT +#define MICROPROFILE_TEXT_HEIGHT 8 +#endif + +#ifndef MICROPROFILE_DETAILED_BAR_HEIGHT +#define MICROPROFILE_DETAILED_BAR_HEIGHT 12 +#endif + +#ifndef MICROPROFILE_DETAILED_CONTEXT_SWITCH_HEIGHT +#define MICROPROFILE_DETAILED_CONTEXT_SWITCH_HEIGHT 7 +#endif + +#ifndef MICROPROFILE_GRAPH_WIDTH +#define MICROPROFILE_GRAPH_WIDTH 256 +#endif + +#ifndef MICROPROFILE_GRAPH_HEIGHT +#define MICROPROFILE_GRAPH_HEIGHT 256 +#endif + +#ifndef MICROPROFILE_BORDER_SIZE +#define MICROPROFILE_BORDER_SIZE 1 +#endif + +#ifndef MICROPROFILE_HELP_LEFT +#define MICROPROFILE_HELP_LEFT "Left-Click" +#endif + +#ifndef MICROPROFILE_HELP_ALT +#define MICROPROFILE_HELP_ALT "Alt-Click" +#endif + +#ifndef MICROPROFILE_HELP_MOD +#define MICROPROFILE_HELP_MOD "Mod" +#endif + +#ifndef MICROPROFILE_BAR_WIDTH +#define MICROPROFILE_BAR_WIDTH 100 +#endif + +#define MICROPROFILE_FRAME_HISTORY_HEIGHT 50 +#define MICROPROFILE_FRAME_HISTORY_WIDTH 7 +#define MICROPROFILE_FRAME_HISTORY_COLOR_CPU 0xffff7f27 //255 127 39 +#define MICROPROFILE_FRAME_HISTORY_COLOR_GPU 0xff37a0ee //55 160 238 +#define MICROPROFILE_FRAME_HISTORY_COLOR_HIGHTLIGHT 0x7733bb44 +#define MICROPROFILE_FRAME_COLOR_HIGHTLIGHT 0x20009900 +#define MICROPROFILE_FRAME_COLOR_HIGHTLIGHT_GPU 0x20996600 +#define MICROPROFILE_NUM_FRAMES (MICROPROFILE_MAX_FRAME_HISTORY - (MICROPROFILE_GPU_FRAME_DELAY+1)) + +#define MICROPROFILE_TOOLTIP_MAX_STRINGS (32 + MICROPROFILE_MAX_GROUPS*2) +#define MICROPROFILE_TOOLTIP_STRING_BUFFER_SIZE (4*1024) +#define MICROPROFILE_TOOLTIP_MAX_LOCKED 3 + + +MICROPROFILEUI_API void MicroProfileUIInit(); +MICROPROFILEUI_API void MicroProfileDraw(uint32_t nWidth, uint32_t nHeight); //! call if drawing microprofilers +MICROPROFILEUI_API bool MicroProfileIsDrawing(); +MICROPROFILEUI_API void MicroProfileToggleGraph(MicroProfileToken nToken); +MICROPROFILEUI_API bool MicroProfileDrawGraph(uint32_t nScreenWidth, uint32_t nScreenHeight); +MICROPROFILEUI_API void MicroProfileToggleDisplayMode(); //switch between off, bars, detailed +MICROPROFILEUI_API void MicroProfileSetDisplayMode(int); //switch between off, bars, detailed +MICROPROFILEUI_API void MicroProfileClearGraph(); +MICROPROFILEUI_API void MicroProfileMousePosition(uint32_t nX, uint32_t nY, int nWheelDelta); +MICROPROFILEUI_API void MicroProfileModKey(uint32_t nKeyState); +MICROPROFILEUI_API void MicroProfileMouseButton(uint32_t nLeft, uint32_t nRight); +MICROPROFILEUI_API void MicroProfileDrawLineVertical(int nX, int nTop, int nBottom, uint32_t nColor); +MICROPROFILEUI_API void MicroProfileDrawLineHorizontal(int nLeft, int nRight, int nY, uint32_t nColor); +MICROPROFILEUI_API void MicroProfileLoadPreset(const char* pSuffix); +MICROPROFILEUI_API void MicroProfileSavePreset(const char* pSuffix); + +MICROPROFILEUI_API void MicroProfileDrawText(int nX, int nY, uint32_t nColor, const char* pText, uint32_t nNumCharacters); +MICROPROFILEUI_API void MicroProfileDrawBox(int nX, int nY, int nX1, int nY1, uint32_t nColor, MicroProfileBoxType = MicroProfileBoxTypeFlat); +MICROPROFILEUI_API void MicroProfileDrawLine2D(uint32_t nVertices, float* pVertices, uint32_t nColor); +MICROPROFILEUI_API void MicroProfileDumpTimers(); + +#ifdef MICROPROFILEUI_IMPL +#ifdef _WIN32 +#define snprintf _snprintf +#endif +#include +#include +#include + +MICROPROFILE_DEFINE(g_MicroProfileDetailed, "MicroProfile", "Detailed View", 0x8888000); +MICROPROFILE_DEFINE(g_MicroProfileDrawGraph, "MicroProfile", "Draw Graph", 0xff44ee00); +MICROPROFILE_DEFINE(g_MicroProfileContextSwitchSearch,"MicroProfile", "ContextSwitchSearch", 0xDD7300); +MICROPROFILE_DEFINE(g_MicroProfileDrawBarView, "MicroProfile", "DrawBarView", 0x00dd77); +MICROPROFILE_DEFINE(g_MicroProfileDraw,"MicroProfile", "Draw", 0x737373); + + +struct MicroProfileStringArray +{ + const char* ppStrings[MICROPROFILE_TOOLTIP_MAX_STRINGS]; + char Buffer[MICROPROFILE_TOOLTIP_STRING_BUFFER_SIZE]; + char* pBufferPos; + uint32_t nNumStrings; +}; + +struct MicroProfileUI +{ + //menu/mouse over stuff + uint64_t nHoverToken; + int64_t nHoverTime; + int nHoverFrame; +#if MICROPROFILE_DEBUG + uint64_t nHoverAddressEnter; + uint64_t nHoverAddressLeave; +#endif + + uint32_t nWidth; + uint32_t nHeight; + + + int nOffsetY; + float fDetailedOffset; //display offset relative to start of latest displayable frame. + float fDetailedRange; //no. of ms to display + float fDetailedOffsetTarget; + float fDetailedRangeTarget; + uint32_t nOpacityBackground; + uint32_t nOpacityForeground; + bool bShowSpikes; + + + + uint32_t nMouseX; + uint32_t nMouseY; + int nMouseWheelDelta; + uint32_t nMouseDownLeft; + uint32_t nMouseDownRight; + uint32_t nMouseLeft; + uint32_t nMouseRight; + uint32_t nMouseLeftMod; + uint32_t nMouseRightMod; + uint32_t nModDown; + uint32_t nActiveMenu; + + MicroProfileLogEntry* pDisplayMouseOver; + + int64_t nRangeBegin; + int64_t nRangeEnd; + int64_t nRangeBeginGpu; + int64_t nRangeEndGpu; + uint32_t nRangeBeginIndex; + uint32_t nRangeEndIndex; + MicroProfileThreadLog* pRangeLog; + uint32_t nHoverColor; + uint32_t nHoverColorShared; + + MicroProfileStringArray LockedToolTips[MICROPROFILE_TOOLTIP_MAX_LOCKED]; + uint32_t nLockedToolTipColor[MICROPROFILE_TOOLTIP_MAX_LOCKED]; + int LockedToolTipFront; + +}; + +MicroProfileUI g_MicroProfileUI; +#define UI g_MicroProfileUI +static uint32_t g_nMicroProfileBackColors[2] = { 0x474747, 0x313131 }; +#define MICROPROFILE_NUM_CONTEXT_SWITCH_COLORS 16 +static uint32_t g_nMicroProfileContextSwitchThreadColors[MICROPROFILE_NUM_CONTEXT_SWITCH_COLORS] = //palette generated by http://tools.medialab.sciences-po.fr/iwanthue/index.php +{ + 0x63607B, + 0x755E2B, + 0x326A55, + 0x523135, + 0x904F42, + 0x87536B, + 0x346875, + 0x5E6046, + 0x35404C, + 0x224038, + 0x413D1E, + 0x5E3A26, + 0x5D6161, + 0x4C6234, + 0x7D564F, + 0x5C4352, +}; + +static uint32_t g_MicroProfileAggregatePresets[] = {0, 10, 20, 30, 60, 120}; +static float g_MicroProfileReferenceTimePresets[] = {5.f, 10.f, 15.f,20.f, 33.33f, 66.66f, 100.f}; +static uint32_t g_MicroProfileOpacityPresets[] = {0x40, 0x80, 0xc0, 0xff}; +static const char* g_MicroProfilePresetNames[] = +{ + MICROPROFILE_DEFAULT_PRESET, + "Render", + "GPU", + "Lighting", + "AI", + "Visibility", + "Sound", +}; + +void MicroProfileInitUI() +{ + static bool bInitialized = false; + if(!bInitialized) + { + bInitialized = true; + memset(&g_MicroProfileUI, 0, sizeof(g_MicroProfileUI)); + UI.nActiveMenu = (uint32_t)-1; + UI.fDetailedOffsetTarget = UI.fDetailedOffset = 0.f; + UI.fDetailedRangeTarget = UI.fDetailedRange = 50.f; + + UI.nOpacityBackground = 0xff<<24; + UI.nOpacityForeground = 0xff<<24; + + UI.bShowSpikes = false; + + UI.nWidth = 100; + UI.nHeight = 100; + + + } +} + +void MicroProfileSetDisplayMode(int nValue) +{ + MicroProfile& S = *MicroProfileGet(); + nValue = nValue >= 0 && nValue < 4 ? nValue : S.nDisplay; + S.nDisplay = nValue; + UI.nOffsetY = 0; +} + +void MicroProfileToggleDisplayMode() +{ + MicroProfile& S = *MicroProfileGet(); + S.nDisplay = (S.nDisplay + 1) % 4; + UI.nOffsetY = 0; +} + + +void MicroProfileStringArrayClear(MicroProfileStringArray* pArray) +{ + pArray->nNumStrings = 0; + pArray->pBufferPos = &pArray->Buffer[0]; +} + +void MicroProfileStringArrayAddLiteral(MicroProfileStringArray* pArray, const char* pLiteral) +{ + MP_ASSERT(pArray->nNumStrings < MICROPROFILE_TOOLTIP_MAX_STRINGS); + pArray->ppStrings[pArray->nNumStrings++] = pLiteral; +} + +void MicroProfileStringArrayFormat(MicroProfileStringArray* pArray, const char* fmt, ...) +{ + MP_ASSERT(pArray->nNumStrings < MICROPROFILE_TOOLTIP_MAX_STRINGS); + pArray->ppStrings[pArray->nNumStrings++] = pArray->pBufferPos; + va_list args; + va_start (args, fmt); + pArray->pBufferPos += 1 + vsprintf(pArray->pBufferPos, fmt, args); + va_end(args); + MP_ASSERT(pArray->pBufferPos < pArray->Buffer + MICROPROFILE_TOOLTIP_STRING_BUFFER_SIZE); +} +void MicroProfileStringArrayCopy(MicroProfileStringArray* pDest, MicroProfileStringArray* pSrc) +{ + memcpy(&pDest->ppStrings[0], &pSrc->ppStrings[0], sizeof(pDest->ppStrings)); + memcpy(&pDest->Buffer[0], &pSrc->Buffer[0], sizeof(pDest->Buffer)); + for(uint32_t i = 0; i < MICROPROFILE_TOOLTIP_MAX_STRINGS; ++i) + { + if(i < pSrc->nNumStrings) + { + if(pSrc->ppStrings[i] >= &pSrc->Buffer[0] && pSrc->ppStrings[i] < &pSrc->Buffer[0] + MICROPROFILE_TOOLTIP_STRING_BUFFER_SIZE) + { + pDest->ppStrings[i] += &pDest->Buffer[0] - &pSrc->Buffer[0]; + } + } + } + pDest->nNumStrings = pSrc->nNumStrings; +} + +void MicroProfileFloatWindowSize(const char** ppStrings, uint32_t nNumStrings, uint32_t* pColors, uint32_t& nWidth, uint32_t& nHeight, uint32_t* pStringLengths = 0) +{ + uint32_t* nStringLengths = pStringLengths ? pStringLengths : (uint32_t*)alloca(nNumStrings * sizeof(uint32_t)); + uint32_t nTextCount = nNumStrings/2; + for(uint32_t i = 0; i < nTextCount; ++i) + { + uint32_t i0 = i * 2; + uint32_t s0, s1; + nStringLengths[i0] = s0 = (uint32_t)strlen(ppStrings[i0]); + nStringLengths[i0+1] = s1 = (uint32_t)strlen(ppStrings[i0+1]); + nWidth = MicroProfileMax(s0+s1, nWidth); + } + nWidth = (MICROPROFILE_TEXT_WIDTH+1) * (2+nWidth) + 2 * MICROPROFILE_BORDER_SIZE; + if(pColors) + nWidth += MICROPROFILE_TEXT_WIDTH + 1; + nHeight = (MICROPROFILE_TEXT_HEIGHT+1) * nTextCount + 2 * MICROPROFILE_BORDER_SIZE; +} + +void MicroProfileDrawFloatWindow(uint32_t nX, uint32_t nY, const char** ppStrings, uint32_t nNumStrings, uint32_t nColor, uint32_t* pColors = 0) +{ + uint32_t nWidth = 0, nHeight = 0; + uint32_t* nStringLengths = (uint32_t*)alloca(nNumStrings * sizeof(uint32_t)); + MicroProfileFloatWindowSize(ppStrings, nNumStrings, pColors, nWidth, nHeight, nStringLengths); + uint32_t nTextCount = nNumStrings/2; + if(nX + nWidth > UI.nWidth) + nX = UI.nWidth - nWidth; + if(nY + nHeight > UI.nHeight) + nY = UI.nHeight - nHeight; + MicroProfileDrawBox(nX-1, nY-1, nX + nWidth+1, nY + nHeight+1, 0xff000000|nColor); + MicroProfileDrawBox(nX, nY, nX + nWidth, nY + nHeight, 0xff000000); + if(pColors) + { + nX += MICROPROFILE_TEXT_WIDTH+1; + nWidth -= MICROPROFILE_TEXT_WIDTH+1; + } + for(uint32_t i = 0; i < nTextCount; ++i) + { + int i0 = i * 2; + if(pColors) + { + MicroProfileDrawBox(nX-MICROPROFILE_TEXT_WIDTH, nY, nX, nY + MICROPROFILE_TEXT_WIDTH, pColors[i]|0xff000000); + } + MicroProfileDrawText(nX + 1, nY + 1, (uint32_t)-1, ppStrings[i0], (uint32_t)strlen(ppStrings[i0])); + MicroProfileDrawText(nX + nWidth - nStringLengths[i0+1] * (MICROPROFILE_TEXT_WIDTH+1), nY + 1, (uint32_t)-1, ppStrings[i0+1], (uint32_t)strlen(ppStrings[i0+1])); + nY += (MICROPROFILE_TEXT_HEIGHT+1); + } +} +void MicroProfileDrawTextBox(uint32_t nX, uint32_t nY, const char** ppStrings, uint32_t nNumStrings, uint32_t nColor, uint32_t* pColors = 0) +{ + uint32_t nWidth = 0, nHeight = 0; + uint32_t* nStringLengths = (uint32_t*)alloca(nNumStrings * sizeof(uint32_t)); + for(uint32_t i = 0; i < nNumStrings; ++i) + { + nStringLengths[i] = (uint32_t)strlen(ppStrings[i]); + nWidth = MicroProfileMax(nWidth, nStringLengths[i]); + nHeight++; + } + nWidth = (MICROPROFILE_TEXT_WIDTH+1) * (2+nWidth) + 2 * MICROPROFILE_BORDER_SIZE; + nHeight = (MICROPROFILE_TEXT_HEIGHT+1) * nHeight + 2 * MICROPROFILE_BORDER_SIZE; + if(nX + nWidth > UI.nWidth) + nX = UI.nWidth - nWidth; + if(nY + nHeight > UI.nHeight) + nY = UI.nHeight - nHeight; + MicroProfileDrawBox(nX, nY, nX + nWidth, nY + nHeight, 0xff000000); + for(uint32_t i = 0; i < nNumStrings; ++i) + { + MicroProfileDrawText(nX + 1, nY + 1, (uint32_t)-1, ppStrings[i], (uint32_t)strlen(ppStrings[i])); + nY += (MICROPROFILE_TEXT_HEIGHT+1); + } +} + + + +void MicroProfileToolTipMeta(MicroProfileStringArray* pToolTip) +{ + MicroProfile& S = *MicroProfileGet(); + if(UI.nRangeBeginIndex != UI.nRangeEndIndex && UI.pRangeLog) + { + uint64_t nMetaSum[MICROPROFILE_META_MAX] = {0}; + uint64_t nMetaSumInclusive[MICROPROFILE_META_MAX] = {0}; + int nStackDepth = 0; + uint32_t nRange[2][2]; + MicroProfileThreadLog* pLog = UI.pRangeLog; + + + MicroProfileGetRange(UI.nRangeEndIndex, UI.nRangeBeginIndex, nRange); + for(uint32_t i = 0; i < 2; ++i) + { + uint32_t nStart = nRange[i][0]; + uint32_t nEnd = nRange[i][1]; + for(uint32_t j = nStart; j < nEnd; ++j) + { + MicroProfileLogEntry LE = pLog->Log[j]; + int nType = MicroProfileLogType(LE); + switch(nType) + { + case MP_LOG_META: + { + int64_t nMetaIndex = MicroProfileLogTimerIndex(LE); + int64_t nMetaCount = MicroProfileLogGetTick(LE); + MP_ASSERT(nMetaIndex < MICROPROFILE_META_MAX); + if(nStackDepth>1) + { + nMetaSumInclusive[nMetaIndex] += nMetaCount; + } + else + { + nMetaSum[nMetaIndex] += nMetaCount; + } + } + break; + case MP_LOG_LEAVE: + if(nStackDepth) + { + nStackDepth--; + } + else + { + for(int i = 0; i < MICROPROFILE_META_MAX; ++i) + { + nMetaSumInclusive[i] += nMetaSum[i]; + nMetaSum[i] = 0; + } + } + break; + case MP_LOG_ENTER: + nStackDepth++; + break; + } + + } + } + bool bSpaced = false; + for(int i = 0; i < MICROPROFILE_META_MAX; ++i) + { + if(S.MetaCounters[i].pName && (nMetaSum[i]||nMetaSumInclusive[i])) + { + if(!bSpaced) + { + bSpaced = true; + MicroProfileStringArrayAddLiteral(pToolTip, ""); + MicroProfileStringArrayAddLiteral(pToolTip, ""); + } + MicroProfileStringArrayFormat(pToolTip, "%s excl", S.MetaCounters[i].pName); + MicroProfileStringArrayFormat(pToolTip, "%5d", nMetaSum[i]); + MicroProfileStringArrayFormat(pToolTip, "%s incl", S.MetaCounters[i].pName); + MicroProfileStringArrayFormat(pToolTip, "%5d", nMetaSum[i] + nMetaSumInclusive[i]); + } + } + } +} + +void MicroProfileDrawFloatTooltip(uint32_t nX, uint32_t nY, uint32_t nToken, uint64_t nTime) +{ + MicroProfile& S = *MicroProfileGet(); + + uint32_t nIndex = MicroProfileGetTimerIndex(nToken); + uint32_t nAggregateFrames = S.nAggregateFrames ? S.nAggregateFrames : 1; + uint32_t nAggregateCount = S.Aggregate[nIndex].nCount ? S.Aggregate[nIndex].nCount : 1; + + uint32_t nGroupId = MicroProfileGetGroupIndex(nToken); + uint32_t nTimerId = MicroProfileGetTimerIndex(nToken); + bool bGpu = S.GroupInfo[nGroupId].Type == MicroProfileTokenTypeGpu; + + float fToMs = MicroProfileTickToMsMultiplier(bGpu ? MicroProfileTicksPerSecondGpu() : MicroProfileTicksPerSecondCpu()); + + float fMs = fToMs * (nTime); + float fFrameMs = fToMs * (S.Frame[nIndex].nTicks); + float fAverage = fToMs * (S.Aggregate[nIndex].nTicks/nAggregateFrames); + float fCallAverage = fToMs * (S.Aggregate[nIndex].nTicks / nAggregateCount); + float fMax = fToMs * (S.AggregateMax[nIndex]); + + float fFrameMsExclusive = fToMs * (S.FrameExclusive[nIndex]); + float fAverageExclusive = fToMs * (S.AggregateExclusive[nIndex]/nAggregateFrames); + float fMaxExclusive = fToMs * (S.AggregateMaxExclusive[nIndex]); + + + MicroProfileStringArray ToolTip; + MicroProfileStringArrayClear(&ToolTip); + const char* pGroupName = S.GroupInfo[nGroupId].pName; + const char* pTimerName = S.TimerInfo[nTimerId].pName; + MicroProfileStringArrayFormat(&ToolTip, "%s", pGroupName); + MicroProfileStringArrayFormat(&ToolTip,"%s", pTimerName); + +#if MICROPROFILE_DEBUG + MicroProfileStringArrayFormat(&ToolTip,"0x%p", UI.nHoverAddressEnter); + MicroProfileStringArrayFormat(&ToolTip,"0x%p", UI.nHoverAddressLeave); +#endif + + if(nTime != (uint64_t)0) + { + MicroProfileStringArrayAddLiteral(&ToolTip, "Time:"); + MicroProfileStringArrayFormat(&ToolTip,"%6.3fms", fMs); + MicroProfileStringArrayAddLiteral(&ToolTip, ""); + MicroProfileStringArrayAddLiteral(&ToolTip, ""); + } + + MicroProfileStringArrayAddLiteral(&ToolTip, "Frame Time:"); + MicroProfileStringArrayFormat(&ToolTip,"%6.3fms", fFrameMs); + + MicroProfileStringArrayAddLiteral(&ToolTip, "Average:"); + MicroProfileStringArrayFormat(&ToolTip,"%6.3fms", fAverage); + + MicroProfileStringArrayAddLiteral(&ToolTip, "Max:"); + MicroProfileStringArrayFormat(&ToolTip,"%6.3fms", fMax); + + MicroProfileStringArrayAddLiteral(&ToolTip, ""); + MicroProfileStringArrayAddLiteral(&ToolTip, ""); + + MicroProfileStringArrayAddLiteral(&ToolTip, "Frame Call Average:"); + MicroProfileStringArrayFormat(&ToolTip,"%6.3fms", fCallAverage); + + MicroProfileStringArrayAddLiteral(&ToolTip, "Frame Call Count:"); + MicroProfileStringArrayFormat(&ToolTip, "%6d", nAggregateCount / nAggregateFrames); + + MicroProfileStringArrayAddLiteral(&ToolTip, ""); + MicroProfileStringArrayAddLiteral(&ToolTip, ""); + + MicroProfileStringArrayAddLiteral(&ToolTip, "Exclusive Frame Time:"); + MicroProfileStringArrayFormat(&ToolTip, "%6.3fms", fFrameMsExclusive); + + MicroProfileStringArrayAddLiteral(&ToolTip, "Exclusive Average:"); + MicroProfileStringArrayFormat(&ToolTip, "%6.3fms", fAverageExclusive); + + MicroProfileStringArrayAddLiteral(&ToolTip, "Exclusive Max:"); + MicroProfileStringArrayFormat(&ToolTip, "%6.3fms", fMaxExclusive); + + MicroProfileToolTipMeta(&ToolTip); + + + MicroProfileDrawFloatWindow(nX, nY+20, &ToolTip.ppStrings[0], ToolTip.nNumStrings, S.TimerInfo[nTimerId].nColor); + + if(UI.nMouseLeftMod) + { + int nIndex = (g_MicroProfileUI.LockedToolTipFront + MICROPROFILE_TOOLTIP_MAX_LOCKED - 1) % MICROPROFILE_TOOLTIP_MAX_LOCKED; + g_MicroProfileUI.nLockedToolTipColor[nIndex] = S.TimerInfo[nTimerId].nColor; + MicroProfileStringArrayCopy(&g_MicroProfileUI.LockedToolTips[nIndex], &ToolTip); + g_MicroProfileUI.LockedToolTipFront = nIndex; + + } +} + + +void MicroProfileZoomTo(int64_t nTickStart, int64_t nTickEnd) +{ + MicroProfile& S = *MicroProfileGet(); + + int64_t nStart = S.Frames[S.nFrameCurrent].nFrameStartCpu; + float fToMs = MicroProfileTickToMsMultiplier(MicroProfileTicksPerSecondCpu()); + UI.fDetailedOffsetTarget = MicroProfileLogTickDifference(nStart, nTickStart) * fToMs; + UI.fDetailedRangeTarget = MicroProfileLogTickDifference(nTickStart, nTickEnd) * fToMs; +} + +void MicroProfileCenter(int64_t nTickCenter) +{ + MicroProfile& S = *MicroProfileGet(); + int64_t nStart = S.Frames[S.nFrameCurrent].nFrameStartCpu; + float fToMs = MicroProfileTickToMsMultiplier(MicroProfileTicksPerSecondCpu()); + float fCenter = MicroProfileLogTickDifference(nStart, nTickCenter) * fToMs; + UI.fDetailedOffsetTarget = UI.fDetailedOffset = fCenter - 0.5f * UI.fDetailedRange; +} +#ifdef MICROPROFILE_DEBUG +uint64_t* g_pMicroProfileDumpStart = 0; +uint64_t* g_pMicroProfileDumpEnd = 0; +void MicroProfileDebugDumpRange() +{ + MicroProfile& S = *MicroProfileGet(); + if(g_pMicroProfileDumpStart != g_pMicroProfileDumpEnd) + { + uint64_t* pStart = g_pMicroProfileDumpStart; + uint64_t* pEnd = g_pMicroProfileDumpEnd; + while(pStart != pEnd) + { + uint64_t nTick = MicroProfileLogGetTick(*pStart); + uint64_t nToken = MicroProfileLogTimerIndex(*pStart); + uint32_t nTimerId = MicroProfileGetTimerIndex(nToken); + + const char* pTimerName = S.TimerInfo[nTimerId].pName; + char buffer[256]; + int type = MicroProfileLogType(*pStart); + + const char* pBegin = type == MP_LOG_LEAVE ? "END" : + (type == MP_LOG_ENTER ? "BEGIN" : "META"); + snprintf(buffer, 255, "DUMP 0x%p: %s :: %llx: %s\n", pStart, pBegin, nTick, pTimerName); +#ifdef _WIN32 + OutputDebugString(buffer); +#else + printf("%s", buffer); +#endif + pStart++; + } + + g_pMicroProfileDumpStart = g_pMicroProfileDumpEnd; + } +} +#define MP_DEBUG_DUMP_RANGE() MicroProfileDebugDumpRange(); +#else +#define MP_DEBUG_DUMP_RANGE() do{} while(0) +#endif + +#define MICROPROFILE_HOVER_DIST 0.5f + +void MicroProfileDrawDetailedContextSwitchBars(uint32_t nY, uint32_t nThreadId, uint32_t nContextSwitchStart, uint32_t nContextSwitchEnd, int64_t nBaseTicks, uint32_t nBaseY) +{ + MicroProfile& S = *MicroProfileGet(); + int64_t nTickIn = -1; + uint32_t nThreadBefore = -1; + float fToMs = MicroProfileTickToMsMultiplier(MicroProfileTicksPerSecondCpu()); + float fMsToScreen = UI.nWidth / UI.fDetailedRange; + float fMouseX = (float)UI.nMouseX; + float fMouseY = (float)UI.nMouseY; + + + for(uint32_t j = nContextSwitchStart; j != nContextSwitchEnd; j = (j+1) % MICROPROFILE_CONTEXT_SWITCH_BUFFER_SIZE) + { + MP_ASSERT(j < MICROPROFILE_CONTEXT_SWITCH_BUFFER_SIZE); + MicroProfileContextSwitch CS = S.ContextSwitch[j]; + + if(nTickIn == -1) + { + if(CS.nThreadIn == nThreadId) + { + nTickIn = CS.nTicks; + nThreadBefore = CS.nThreadOut; + } + } + else + { + if(CS.nThreadOut == nThreadId) + { + int64_t nTickOut = CS.nTicks; + float fMsStart = fToMs * MicroProfileLogTickDifference(nBaseTicks, nTickIn); + float fMsEnd = fToMs * MicroProfileLogTickDifference(nBaseTicks, nTickOut); + if(fMsStart <= fMsEnd) + { + float fXStart = fMsStart * fMsToScreen; + float fXEnd = fMsEnd * fMsToScreen; + float fYStart = (float)nY; + float fYEnd = fYStart + (MICROPROFILE_DETAILED_CONTEXT_SWITCH_HEIGHT); + uint32_t nColor = g_nMicroProfileContextSwitchThreadColors[CS.nCpu%MICROPROFILE_NUM_CONTEXT_SWITCH_COLORS]; + float fXDist = MicroProfileMax(fXStart - fMouseX, fMouseX - fXEnd); + bool bHover = fXDist < MICROPROFILE_HOVER_DIST && fYStart <= fMouseY && fMouseY <= fYEnd && nBaseY < fMouseY; + if(bHover) + { + UI.nRangeBegin = nTickIn; + UI.nRangeEnd = nTickOut; + S.nContextSwitchHoverTickIn = nTickIn; + S.nContextSwitchHoverTickOut = nTickOut; + S.nContextSwitchHoverThread = CS.nThreadOut; + S.nContextSwitchHoverThreadBefore = nThreadBefore; + S.nContextSwitchHoverThreadAfter = CS.nThreadIn; + S.nContextSwitchHoverCpuNext = CS.nCpu; + nColor = UI.nHoverColor; + } + if(CS.nCpu == S.nContextSwitchHoverCpu) + { + nColor = UI.nHoverColorShared; + } + MicroProfileDrawBox(fXStart, fYStart, fXEnd, fYEnd, nColor|UI.nOpacityForeground, MicroProfileBoxTypeFlat); + } + nTickIn = -1; + } + } + } +} + +void MicroProfileDrawDetailedBars(uint32_t nWidth, uint32_t nHeight, int nBaseY, int nSelectedFrame) +{ + MicroProfile& S = *MicroProfileGet(); + MP_DEBUG_DUMP_RANGE(); + int nY = nBaseY - UI.nOffsetY; + int64_t nNumBoxes = 0; + int64_t nNumLines = 0; + + uint32_t nFrameNext = (S.nFrameCurrent+1) % MICROPROFILE_MAX_FRAME_HISTORY; + MicroProfileFrameState* pFrameCurrent = &S.Frames[S.nFrameCurrent]; + MicroProfileFrameState* pFrameNext = &S.Frames[nFrameNext]; + + UI.nRangeBegin = 0; + UI.nRangeEnd = 0; + UI.nRangeBeginGpu = 0; + UI.nRangeEndGpu = 0; + UI.nRangeBeginIndex = UI.nRangeEndIndex = 0; + UI.pRangeLog = 0; + uint64_t nFrameStartCpu = pFrameCurrent->nFrameStartCpu; + uint64_t nFrameStartGpu = pFrameCurrent->nFrameStartGpu; + float fToMsCpu = MicroProfileTickToMsMultiplier(MicroProfileTicksPerSecondCpu()); + float fToMsGpu = MicroProfileTickToMsMultiplier(MicroProfileTicksPerSecondGpu()); + + float fDetailedOffset = UI.fDetailedOffset; + float fDetailedRange = UI.fDetailedRange; + int64_t nDetailedOffsetTicksCpu = MicroProfileMsToTick(fDetailedOffset, MicroProfileTicksPerSecondCpu()); + int64_t nDetailedOffsetTicksGpu = MicroProfileMsToTick(fDetailedOffset, MicroProfileTicksPerSecondGpu()); + int64_t nBaseTicksCpu = nDetailedOffsetTicksCpu + nFrameStartCpu; + int64_t nBaseTicksGpu = nDetailedOffsetTicksGpu + nFrameStartGpu; + int64_t nBaseTicksEndCpu = nBaseTicksCpu + MicroProfileMsToTick(fDetailedRange, MicroProfileTicksPerSecondCpu()); + + MicroProfileFrameState* pFrameFirst = pFrameCurrent; + int64_t nGapTime = MicroProfileTicksPerSecondCpu() * MICROPROFILE_GAP_TIME / 1000; + for(uint32_t i = 0; i < MICROPROFILE_MAX_FRAME_HISTORY - MICROPROFILE_GPU_FRAME_DELAY; ++i) + { + uint32_t nNextIndex = (S.nFrameCurrent + MICROPROFILE_MAX_FRAME_HISTORY - i) % MICROPROFILE_MAX_FRAME_HISTORY; + pFrameFirst = &S.Frames[nNextIndex]; + if(pFrameFirst->nFrameStartCpu <= nBaseTicksCpu-nGapTime) + break; + } + + float fMsBase = fToMsCpu * nDetailedOffsetTicksCpu; + float fMs = fDetailedRange; + float fMsEnd = fMs + fMsBase; + float fWidth = (float)nWidth; + float fMsToScreen = fWidth / fMs; + + { + float fRate = floor(2*(log10(fMs)-1))/2; + float fStep = powf(10.f, fRate); + float fRcpStep = 1.f / fStep; + int nColorIndex = (int)(floor(fMsBase*fRcpStep)); + float fStart = floor(fMsBase*fRcpStep) * fStep; + for(float f = fStart; f < fMsEnd; ) + { + float fStart = f; + float fNext = f + fStep; + MicroProfileDrawBox(((fStart-fMsBase) * fMsToScreen), nBaseY, (fNext-fMsBase) * fMsToScreen+1, nBaseY + nHeight, UI.nOpacityBackground | g_nMicroProfileBackColors[nColorIndex++ & 1]); + f = fNext; + } + } + + nY += MICROPROFILE_TEXT_HEIGHT+1; + MicroProfileLogEntry* pMouseOver = UI.pDisplayMouseOver; + MicroProfileLogEntry* pMouseOverNext = 0; + uint64_t nMouseOverToken = pMouseOver ? MicroProfileLogTimerIndex(*pMouseOver) : MICROPROFILE_INVALID_TOKEN; + float fMouseX = (float)UI.nMouseX; + float fMouseY = (float)UI.nMouseY; + uint64_t nHoverToken = MICROPROFILE_INVALID_TOKEN; + int64_t nHoverTime = 0; + + static int nHoverCounter = 155; + static int nHoverCounterDelta = 10; + nHoverCounter += nHoverCounterDelta; + if(nHoverCounter >= 245) + nHoverCounterDelta = -10; + else if(nHoverCounter < 100) + nHoverCounterDelta = 10; + UI.nHoverColor = (nHoverCounter<<24)|(nHoverCounter<<16)|(nHoverCounter<<8)|nHoverCounter; + uint32_t nHoverCounterShared = nHoverCounter>>2; + UI.nHoverColorShared = (nHoverCounterShared<<24)|(nHoverCounterShared<<16)|(nHoverCounterShared<<8)|nHoverCounterShared; + + uint32_t nLinesDrawn[MICROPROFILE_STACK_MAX]={0}; + + uint32_t nContextSwitchHoverThreadAfter = S.nContextSwitchHoverThreadAfter; + uint32_t nContextSwitchHoverThreadBefore = S.nContextSwitchHoverThreadBefore; + S.nContextSwitchHoverThread = S.nContextSwitchHoverThreadAfter = S.nContextSwitchHoverThreadBefore = -1; + + uint32_t nContextSwitchStart = -1; + uint32_t nContextSwitchEnd = -1; + S.nContextSwitchHoverCpuNext = 0xff; + S.nContextSwitchHoverTickIn = -1; + S.nContextSwitchHoverTickOut = -1; + if(S.bContextSwitchRunning) + { + MICROPROFILE_SCOPE(g_MicroProfileContextSwitchSearch); + uint32_t nContextSwitchPut = S.nContextSwitchPut; + nContextSwitchStart = nContextSwitchEnd = (nContextSwitchPut + MICROPROFILE_CONTEXT_SWITCH_BUFFER_SIZE - 1) % MICROPROFILE_CONTEXT_SWITCH_BUFFER_SIZE; + int64_t nSearchEnd = nBaseTicksEndCpu + MicroProfileMsToTick(30.f, MicroProfileTicksPerSecondCpu()); + int64_t nSearchBegin = nBaseTicksCpu - MicroProfileMsToTick(30.f, MicroProfileTicksPerSecondCpu()); + for(uint32_t i = 0; i < MICROPROFILE_CONTEXT_SWITCH_BUFFER_SIZE; ++i) + { + uint32_t nIndex = (nContextSwitchPut + MICROPROFILE_CONTEXT_SWITCH_BUFFER_SIZE - (i+1)) % MICROPROFILE_CONTEXT_SWITCH_BUFFER_SIZE; + MicroProfileContextSwitch& CS = S.ContextSwitch[nIndex]; + if(CS.nTicks > nSearchEnd) + { + nContextSwitchEnd = nIndex; + } + if(CS.nTicks > nSearchBegin) + { + nContextSwitchStart = nIndex; + } + } + } + + bool bSkipBarView = S.bContextSwitchRunning && S.bContextSwitchNoBars; + + if(!bSkipBarView) + { + for(uint32_t i = 0; i < MICROPROFILE_MAX_THREADS; ++i) + { + MicroProfileThreadLog* pLog = S.Pool[i]; + if(!pLog) + continue; + + uint32_t nPut = pFrameNext->nLogStart[i]; + ///note: this may display new samples as old data, but this will only happen when + // unpaused, where the detailed view is hardly perceptible + uint32_t nFront = S.Pool[i]->nPut.load(std::memory_order_relaxed); + MicroProfileFrameState* pFrameLogFirst = pFrameCurrent; + MicroProfileFrameState* pFrameLogLast = pFrameNext; + uint32_t nGet = pFrameLogFirst->nLogStart[i]; + do + { + MP_ASSERT(pFrameLogFirst >= &S.Frames[0] && pFrameLogFirst < &S.Frames[MICROPROFILE_MAX_FRAME_HISTORY]); + uint32_t nNewGet = pFrameLogFirst->nLogStart[i]; + bool bIsValid = false; + if(nPut < nFront) + { + bIsValid = nNewGet <= nPut || nNewGet >= nFront; + } + else + { + bIsValid = nNewGet <= nPut && nNewGet >= nFront; + } + if(bIsValid) + { + nGet = nNewGet; + if(pFrameLogFirst->nFrameStartCpu > nBaseTicksEndCpu) + { + pFrameLogLast = pFrameLogFirst;//pick the last frame that ends after + } + + + pFrameLogFirst--; + if(pFrameLogFirst < &S.Frames[0]) + pFrameLogFirst = &S.Frames[MICROPROFILE_MAX_FRAME_HISTORY-1]; + } + else + { + break; + } + }while(pFrameLogFirst != pFrameFirst); + + + if(nGet == (uint32_t)-1) + continue; + MP_ASSERT(nGet != (uint32_t)-1); + + nPut = pFrameLogLast->nLogStart[i]; + + uint32_t nRange[2][2] = { {0, 0}, {0, 0}, }; + + MicroProfileGetRange(nPut, nGet, nRange); + if(nPut == nGet) + continue; + uint32_t nMaxStackDepth = 0; + + bool bGpu = pLog->nGpu != 0; + float fToMs = bGpu ? fToMsGpu : fToMsCpu; + int64_t nBaseTicks = bGpu ? nBaseTicksGpu : nBaseTicksCpu; + char ThreadName[MicroProfileThreadLog::THREAD_MAX_LEN + 16]; + uint64_t nThreadId = pLog->nThreadId; + snprintf(ThreadName, sizeof(ThreadName)-1, "%04llx: %s", nThreadId, &pLog->ThreadName[0] ); + nY += 3; + uint32_t nThreadColor = -1; + if(pLog->nThreadId == nContextSwitchHoverThreadAfter || pLog->nThreadId == nContextSwitchHoverThreadBefore) + nThreadColor = UI.nHoverColorShared|0x906060; + MicroProfileDrawText(0, nY, nThreadColor, &ThreadName[0], (uint32_t)strlen(&ThreadName[0])); + nY += 3; + nY += MICROPROFILE_TEXT_HEIGHT + 1; + + if(S.bContextSwitchRunning) + { + MicroProfileDrawDetailedContextSwitchBars(nY, pLog->nThreadId, nContextSwitchStart, nContextSwitchEnd, nBaseTicks, nBaseY); + nY -= MICROPROFILE_DETAILED_BAR_HEIGHT; + nY += MICROPROFILE_DETAILED_CONTEXT_SWITCH_HEIGHT+1; + } + + uint32_t nYDelta = MICROPROFILE_DETAILED_BAR_HEIGHT; + uint32_t nStack[MICROPROFILE_STACK_MAX]; + uint32_t nStackPos = 0; + for(uint32_t j = 0; j < 2; ++j) + { + uint32_t nStart = nRange[j][0]; + uint32_t nEnd = nRange[j][1]; + for(uint32_t k = nStart; k < nEnd; ++k) + { + MicroProfileLogEntry* pEntry = pLog->Log + k; + int nType = MicroProfileLogType(*pEntry); + if(MP_LOG_ENTER == nType) + { + MP_ASSERT(nStackPos < MICROPROFILE_STACK_MAX); + nStack[nStackPos++] = k; + } + else if(MP_LOG_META == nType) + { + + } + else if(MP_LOG_LEAVE == nType) + { + if(0 == nStackPos) + { + continue; + } + + MicroProfileLogEntry* pEntryEnter = pLog->Log + nStack[nStackPos-1]; + if(MicroProfileLogTimerIndex(*pEntryEnter) != MicroProfileLogTimerIndex(*pEntry)) + { + //uprintf("mismatch %llx %llx\n", pEntryEnter->nToken, pEntry->nToken); + continue; + } + int64_t nTickStart = MicroProfileLogGetTick(*pEntryEnter); + int64_t nTickEnd = MicroProfileLogGetTick(*pEntry); + uint64_t nTimerIndex = MicroProfileLogTimerIndex(*pEntry); + uint32_t nColor = S.TimerInfo[nTimerIndex].nColor; + if(nMouseOverToken == nTimerIndex) + { + if(pEntry == pMouseOver) + { + nColor = UI.nHoverColor; + if(bGpu) + { + UI.nRangeBeginGpu = *pEntryEnter; + UI.nRangeEndGpu = *pEntry; + UI.nRangeBeginIndex = nStack[nStackPos-1]; + UI.nRangeEndIndex = k; + UI.pRangeLog = pLog; + } + else + { + UI.nRangeBegin = *pEntryEnter; + UI.nRangeEnd = *pEntry; + UI.nRangeBeginIndex = nStack[nStackPos-1]; + UI.nRangeEndIndex = k; + UI.pRangeLog = pLog; + + } + } + else + { + nColor = UI.nHoverColorShared; + } + } + + nMaxStackDepth = MicroProfileMax(nMaxStackDepth, nStackPos); + float fMsStart = fToMs * MicroProfileLogTickDifference(nBaseTicks, nTickStart); + float fMsEnd = fToMs * MicroProfileLogTickDifference(nBaseTicks, nTickEnd); + float fXStart = fMsStart * fMsToScreen; + float fXEnd = fMsEnd * fMsToScreen; + float fYStart = (float)(nY + nStackPos * nYDelta); + float fYEnd = fYStart + (MICROPROFILE_DETAILED_BAR_HEIGHT); + float fXDist = MicroProfileMax(fXStart - fMouseX, fMouseX - fXEnd); + bool bHover = fXDist < MICROPROFILE_HOVER_DIST && fYStart <= fMouseY && fMouseY <= fYEnd && nBaseY < fMouseY; + uint32_t nIntegerWidth = (uint32_t)(fXEnd - fXStart); + if(nIntegerWidth) + { + if(bHover && UI.nActiveMenu == -1) + { + nHoverToken = MicroProfileLogTimerIndex(*pEntry); + #if MICROPROFILE_DEBUG + UI.nHoverAddressEnter = (uint64_t)pEntryEnter; + UI.nHoverAddressLeave = (uint64_t)pEntry; + #endif + nHoverTime = MicroProfileLogTickDifference(nTickStart, nTickEnd); + pMouseOverNext = pEntry; + } + + MicroProfileDrawBox(fXStart, fYStart, fXEnd, fYEnd, nColor|UI.nOpacityForeground, MicroProfileBoxTypeBar); +#if MICROPROFILE_DETAILED_BAR_NAMES + if(nIntegerWidth>3*MICROPROFILE_TEXT_WIDTH) + { + float fXStartText = MicroProfileMax(fXStart, 0.f); + int nTextWidth = (int)(fXEnd - fXStartText); + int nCharacters = (nTextWidth - 2*MICROPROFILE_TEXT_WIDTH) / MICROPROFILE_TEXT_WIDTH; + if(nCharacters>0) + { + MicroProfileDrawText(fXStartText+1, fYStart+1, -1, S.TimerInfo[nTimerIndex].pName, MicroProfileMin(S.TimerInfo[nTimerIndex].nNameLen, nCharacters)); + } + } +#endif + ++nNumBoxes; + } + else + { + float fXAvg = 0.5f * (fXStart + fXEnd); + int nLineX = (int)floor(fXAvg+0.5f); + if(nLineX != (int)nLinesDrawn[nStackPos]) + { + if(bHover && UI.nActiveMenu == -1) + { + nHoverToken = (uint32_t)MicroProfileLogTimerIndex(*pEntry); + nHoverTime = MicroProfileLogTickDifference(nTickStart, nTickEnd); + pMouseOverNext = pEntry; + } + nLinesDrawn[nStackPos] = nLineX; + MicroProfileDrawLineVertical(nLineX, fYStart + 0.5f, fYEnd + 0.5f, nColor|UI.nOpacityForeground); + ++nNumLines; + } + } + nStackPos--; + } + } + } + nY += nMaxStackDepth * nYDelta + MICROPROFILE_DETAILED_BAR_HEIGHT+1; + } + } + if(S.bContextSwitchRunning && (S.bContextSwitchAllThreads||S.bContextSwitchNoBars)) + { + uint32_t nNumThreads = 0; + uint32_t nThreads[MICROPROFILE_MAX_CONTEXT_SWITCH_THREADS]; + for(uint32_t i = 0; i < MICROPROFILE_MAX_THREADS && S.Pool[i]; ++i) + nThreads[nNumThreads++] = S.Pool[i]->nThreadId; + uint32_t nNumThreadsBase = nNumThreads; + if(S.bContextSwitchAllThreads) + { + for(uint32_t i = nContextSwitchStart; i != nContextSwitchEnd; i = (i+1) % MICROPROFILE_CONTEXT_SWITCH_BUFFER_SIZE) + { + MicroProfileContextSwitch CS = S.ContextSwitch[i]; + uint32_t nThreadId = CS.nThreadIn; + if(nThreadId) + { + bool bSeen = false; + for(uint32_t j = 0; j < nNumThreads; ++j) + { + if(nThreads[j] == nThreadId) + { + bSeen = true; + break; + } + } + if(!bSeen) + { + nThreads[nNumThreads++] = nThreadId; + } + } + if(nNumThreads == MICROPROFILE_MAX_CONTEXT_SWITCH_THREADS) + { + S.nOverflow = 10; + break; + } + } + std::sort(&nThreads[nNumThreadsBase], &nThreads[nNumThreads]); + } + uint32_t nStart = nNumThreadsBase; + if(S.bContextSwitchNoBars) + nStart = 0; + for(uint32_t i = nStart; i < nNumThreads; ++i) + { + uint32_t nThreadId = nThreads[i]; + if(nThreadId) + { + char ThreadName[MicroProfileThreadLog::THREAD_MAX_LEN + 16]; + const char* cLocal = MicroProfileIsLocalThread(nThreadId) ? "*": " "; + int nStrLen = snprintf(ThreadName, sizeof(ThreadName)-1, "%04x: %s", nThreadId, i < nNumThreadsBase ? &S.Pool[i]->ThreadName[0] : cLocal ); + uint32_t nThreadColor = -1; + if(nThreadId == nContextSwitchHoverThreadAfter || nThreadId == nContextSwitchHoverThreadBefore) + nThreadColor = UI.nHoverColorShared|0x906060; + MicroProfileDrawDetailedContextSwitchBars(nY+2, nThreadId, nContextSwitchStart, nContextSwitchEnd, nBaseTicksCpu, nBaseY); + MicroProfileDrawText(0, nY, nThreadColor, &ThreadName[0], nStrLen); + nY += MICROPROFILE_TEXT_HEIGHT+1; + } + } + } + + S.nContextSwitchHoverCpu = S.nContextSwitchHoverCpuNext; + + + + + UI.pDisplayMouseOver = pMouseOverNext; + + if(!S.nRunning) + { + if(nHoverToken != MICROPROFILE_INVALID_TOKEN && nHoverTime) + { + UI.nHoverToken = nHoverToken; + UI.nHoverTime = nHoverTime; + } + + if(nSelectedFrame != -1) + { + UI.nRangeBegin = S.Frames[nSelectedFrame].nFrameStartCpu; + UI.nRangeEnd = S.Frames[(nSelectedFrame+1)%MICROPROFILE_MAX_FRAME_HISTORY].nFrameStartCpu; + UI.nRangeBeginGpu = S.Frames[nSelectedFrame].nFrameStartGpu; + UI.nRangeEndGpu = S.Frames[(nSelectedFrame+1)%MICROPROFILE_MAX_FRAME_HISTORY].nFrameStartGpu; + } + if(UI.nRangeBegin != UI.nRangeEnd) + { + float fMsStart = fToMsCpu * MicroProfileLogTickDifference(nBaseTicksCpu, UI.nRangeBegin); + float fMsEnd = fToMsCpu * MicroProfileLogTickDifference(nBaseTicksCpu, UI.nRangeEnd); + float fXStart = fMsStart * fMsToScreen; + float fXEnd = fMsEnd * fMsToScreen; + MicroProfileDrawBox(fXStart, nBaseY, fXEnd, nHeight, MICROPROFILE_FRAME_COLOR_HIGHTLIGHT, MicroProfileBoxTypeFlat); + MicroProfileDrawLineVertical(fXStart, nBaseY, nHeight, MICROPROFILE_FRAME_COLOR_HIGHTLIGHT | 0x44000000); + MicroProfileDrawLineVertical(fXEnd, nBaseY, nHeight, MICROPROFILE_FRAME_COLOR_HIGHTLIGHT | 0x44000000); + + fMsStart += fDetailedOffset; + fMsEnd += fDetailedOffset; + char sBuffer[32]; + uint32_t nLenStart = snprintf(sBuffer, sizeof(sBuffer)-1, "%.2fms", fMsStart); + float fStartTextWidth = (float)((1+MICROPROFILE_TEXT_WIDTH) * nLenStart); + float fStartTextX = fXStart - fStartTextWidth - 2; + MicroProfileDrawBox(fStartTextX, nBaseY, fStartTextX + fStartTextWidth + 2, MICROPROFILE_TEXT_HEIGHT + 2 + nBaseY, 0x33000000, MicroProfileBoxTypeFlat); + MicroProfileDrawText(fStartTextX+1, nBaseY, (uint32_t)-1, sBuffer, nLenStart); + uint32_t nLenEnd = snprintf(sBuffer, sizeof(sBuffer)-1, "%.2fms", fMsEnd); + MicroProfileDrawBox(fXEnd+1, nBaseY, fXEnd+1+(1+MICROPROFILE_TEXT_WIDTH) * nLenEnd + 3, MICROPROFILE_TEXT_HEIGHT + 2 + nBaseY, 0x33000000, MicroProfileBoxTypeFlat); + MicroProfileDrawText(fXEnd+2, nBaseY+1, (uint32_t)-1, sBuffer, nLenEnd); + + if(UI.nMouseRight) + { + MicroProfileZoomTo(UI.nRangeBegin, UI.nRangeEnd); + } + } + + if(UI.nRangeBeginGpu != UI.nRangeEndGpu) + { + float fMsStart = fToMsGpu * MicroProfileLogTickDifference(nBaseTicksGpu, UI.nRangeBeginGpu); + float fMsEnd = fToMsGpu * MicroProfileLogTickDifference(nBaseTicksGpu, UI.nRangeEndGpu); + float fXStart = fMsStart * fMsToScreen; + float fXEnd = fMsEnd * fMsToScreen; + MicroProfileDrawBox(fXStart, nBaseY, fXEnd, nHeight, MICROPROFILE_FRAME_COLOR_HIGHTLIGHT_GPU, MicroProfileBoxTypeFlat); + MicroProfileDrawLineVertical(fXStart, nBaseY, nHeight, MICROPROFILE_FRAME_COLOR_HIGHTLIGHT_GPU | 0x44000000); + MicroProfileDrawLineVertical(fXEnd, nBaseY, nHeight, MICROPROFILE_FRAME_COLOR_HIGHTLIGHT_GPU | 0x44000000); + + nBaseY += MICROPROFILE_TEXT_HEIGHT+1; + + fMsStart += fDetailedOffset; + fMsEnd += fDetailedOffset; + char sBuffer[32]; + uint32_t nLenStart = snprintf(sBuffer, sizeof(sBuffer)-1, "%.2fms", fMsStart); + float fStartTextWidth = (float)((1+MICROPROFILE_TEXT_WIDTH) * nLenStart); + float fStartTextX = fXStart - fStartTextWidth - 2; + MicroProfileDrawBox(fStartTextX, nBaseY, fStartTextX + fStartTextWidth + 2, MICROPROFILE_TEXT_HEIGHT + 2 + nBaseY, 0x33000000, MicroProfileBoxTypeFlat); + MicroProfileDrawText(fStartTextX+1, nBaseY, (uint32_t)-1, sBuffer, nLenStart); + uint32_t nLenEnd = snprintf(sBuffer, sizeof(sBuffer)-1, "%.2fms", fMsEnd); + MicroProfileDrawBox(fXEnd+1, nBaseY, fXEnd+1+(1+MICROPROFILE_TEXT_WIDTH) * nLenEnd + 3, MICROPROFILE_TEXT_HEIGHT + 2 + nBaseY, 0x33000000, MicroProfileBoxTypeFlat); + MicroProfileDrawText(fXEnd+2, nBaseY+1, (uint32_t)-1, sBuffer, nLenEnd); + } + } +} + + +void MicroProfileDrawDetailedFrameHistory(uint32_t nWidth, uint32_t nHeight, uint32_t nBaseY, uint32_t nSelectedFrame) +{ + MicroProfile& S = *MicroProfileGet(); + + const uint32_t nBarHeight = MICROPROFILE_FRAME_HISTORY_HEIGHT; + float fBaseX = (float)nWidth; + float fDx = fBaseX / MICROPROFILE_NUM_FRAMES; + + uint32_t nLastIndex = (S.nFrameCurrent+1) % MICROPROFILE_MAX_FRAME_HISTORY; + MicroProfileDrawBox(0, nBaseY, nWidth, nBaseY+MICROPROFILE_FRAME_HISTORY_HEIGHT, 0xff000000 | g_nMicroProfileBackColors[0], MicroProfileBoxTypeFlat); + float fToMs = MicroProfileTickToMsMultiplier(MicroProfileTicksPerSecondCpu()) * S.fRcpReferenceTime; + float fToMsGpu = MicroProfileTickToMsMultiplier(MicroProfileTicksPerSecondGpu()) * S.fRcpReferenceTime; + + + MicroProfileFrameState* pFrameCurrent = &S.Frames[S.nFrameCurrent]; + uint64_t nFrameStartCpu = pFrameCurrent->nFrameStartCpu; + int64_t nDetailedOffsetTicksCpu = MicroProfileMsToTick(UI.fDetailedOffset, MicroProfileTicksPerSecondCpu()); + int64_t nCpuStart = nDetailedOffsetTicksCpu + nFrameStartCpu; + int64_t nCpuEnd = nCpuStart + MicroProfileMsToTick(UI.fDetailedRange, MicroProfileTicksPerSecondCpu());; + + + float fSelectionStart = (float)nWidth; + float fSelectionEnd = 0.f; + for(uint32_t i = 0; i < MICROPROFILE_NUM_FRAMES; ++i) + { + uint32_t nIndex = (S.nFrameCurrent + MICROPROFILE_MAX_FRAME_HISTORY - i) % MICROPROFILE_MAX_FRAME_HISTORY; + MicroProfileFrameState* pCurrent = &S.Frames[nIndex]; + MicroProfileFrameState* pNext = &S.Frames[nLastIndex]; + + int64_t nTicks = pNext->nFrameStartCpu - pCurrent->nFrameStartCpu; + int64_t nTicksGpu = pNext->nFrameStartGpu - pCurrent->nFrameStartGpu; + float fScale = fToMs * nTicks; + float fScaleGpu = fToMsGpu * nTicksGpu; + fScale = fScale > 1.f ? 0.f : 1.f - fScale; + fScaleGpu = fScaleGpu > 1.f ? 0.f : 1.f - fScaleGpu; + float fXEnd = fBaseX; + float fXStart = fBaseX - fDx; + fBaseX = fXStart; + uint32_t nColor = MICROPROFILE_FRAME_HISTORY_COLOR_CPU; + if(nIndex == nSelectedFrame) + nColor = (uint32_t)-1; + MicroProfileDrawBox(fXStart, nBaseY + fScale * nBarHeight, fXEnd, nBaseY+MICROPROFILE_FRAME_HISTORY_HEIGHT, nColor, MicroProfileBoxTypeBar); + if(pNext->nFrameStartCpu > nCpuStart) + { + fSelectionStart = fXStart; + } + if(pCurrent->nFrameStartCpu < nCpuEnd && fSelectionEnd == 0.f) + { + fSelectionEnd = fXEnd; + } + nLastIndex = nIndex; + } + MicroProfileDrawBox(fSelectionStart, nBaseY, fSelectionEnd, nBaseY+MICROPROFILE_FRAME_HISTORY_HEIGHT, MICROPROFILE_FRAME_HISTORY_COLOR_HIGHTLIGHT, MicroProfileBoxTypeFlat); +} +void MicroProfileDrawDetailedView(uint32_t nWidth, uint32_t nHeight) +{ + MicroProfile& S = *MicroProfileGet(); + + MICROPROFILE_SCOPE(g_MicroProfileDetailed); + uint32_t nBaseY = MICROPROFILE_TEXT_HEIGHT + 1; + + int nSelectedFrame = -1; + if(UI.nMouseY > nBaseY && UI.nMouseY <= nBaseY + MICROPROFILE_FRAME_HISTORY_HEIGHT && UI.nActiveMenu == -1) + { + + nSelectedFrame = ((MICROPROFILE_NUM_FRAMES) * (UI.nWidth-UI.nMouseX) / UI.nWidth); + nSelectedFrame = (S.nFrameCurrent + MICROPROFILE_MAX_FRAME_HISTORY - nSelectedFrame) % MICROPROFILE_MAX_FRAME_HISTORY; + UI.nHoverFrame = nSelectedFrame; + if(UI.nMouseRight) + { + int64_t nRangeBegin = S.Frames[nSelectedFrame].nFrameStartCpu; + int64_t nRangeEnd = S.Frames[(nSelectedFrame+1)%MICROPROFILE_MAX_FRAME_HISTORY].nFrameStartCpu; + MicroProfileZoomTo(nRangeBegin, nRangeEnd); + } + if(UI.nMouseDownLeft) + { + uint64_t nFrac = (1024 * (MICROPROFILE_NUM_FRAMES) * (UI.nMouseX) / UI.nWidth) % 1024; + int64_t nRangeBegin = S.Frames[nSelectedFrame].nFrameStartCpu; + int64_t nRangeEnd = S.Frames[(nSelectedFrame+1)%MICROPROFILE_MAX_FRAME_HISTORY].nFrameStartCpu; + MicroProfileCenter(nRangeBegin + (nRangeEnd-nRangeBegin) * nFrac / 1024); + } + } + else + { + UI.nHoverFrame = -1; + } + + MicroProfileDrawDetailedBars(nWidth, nHeight, nBaseY + MICROPROFILE_FRAME_HISTORY_HEIGHT, nSelectedFrame); + MicroProfileDrawDetailedFrameHistory(nWidth, nHeight, nBaseY, nSelectedFrame); +} + +template +void MicroProfileLoopActiveGroupsDraw(int32_t nX, int32_t nY, const char* pName, T CB) +{ + MicroProfile& S = *MicroProfileGet(); + + if(pName) + MicroProfileDrawText(nX, nY, (uint32_t)-1, pName, (uint32_t)strlen(pName)); + + nY += MICROPROFILE_TEXT_HEIGHT + 2; + uint64_t nGroup = S.nAllGroupsWanted ? S.nGroupMask : S.nActiveGroupWanted; + uint32_t nCount = 0; + for(uint32_t j = 0; j < MICROPROFILE_MAX_GROUPS; ++j) + { + uint64_t nMask = 1ll << j; + if(nMask & nGroup) + { + nY += MICROPROFILE_TEXT_HEIGHT + 1; + for(uint32_t i = 0; i < S.nTotalTimers;++i) + { + uint64_t nTokenMask = MicroProfileGetGroupMask(S.TimerInfo[i].nToken); + if(nTokenMask & nMask) + { + if(nY >= 0) + CB(i, nCount, nMask, nX, nY); + + nCount += 2; + nY += MICROPROFILE_TEXT_HEIGHT + 1; + + if(nY > (int)UI.nHeight) + return; + } + } + + } + } +} + + +void MicroProfileCalcTimers(float* pTimers, float* pAverage, float* pMax, float* pCallAverage, float* pExclusive, float* pAverageExclusive, float* pMaxExclusive, uint64_t nGroup, uint32_t nSize) +{ + MicroProfile& S = *MicroProfileGet(); + + uint32_t nCount = 0; + uint64_t nMask = 1; + + for(uint32_t j = 0; j < MICROPROFILE_MAX_GROUPS; ++j) + { + if(nMask & nGroup) + { + const float fToMs = MicroProfileTickToMsMultiplier(S.GroupInfo[j].Type == MicroProfileTokenTypeGpu ? MicroProfileTicksPerSecondGpu() : MicroProfileTicksPerSecondCpu()); + for(uint32_t i = 0; i < S.nTotalTimers;++i) + { + uint64_t nTokenMask = MicroProfileGetGroupMask(S.TimerInfo[i].nToken); + if(nTokenMask & nMask) + { + { + uint32_t nTimer = i; + uint32_t nIdx = nCount; + uint32_t nAggregateFrames = S.nAggregateFrames ? S.nAggregateFrames : 1; + uint32_t nAggregateCount = S.Aggregate[nTimer].nCount ? S.Aggregate[nTimer].nCount : 1; + float fToPrc = S.fRcpReferenceTime; + float fMs = fToMs * (S.Frame[nTimer].nTicks); + float fPrc = MicroProfileMin(fMs * fToPrc, 1.f); + float fAverageMs = fToMs * (S.Aggregate[nTimer].nTicks / nAggregateFrames); + float fAveragePrc = MicroProfileMin(fAverageMs * fToPrc, 1.f); + float fMaxMs = fToMs * (S.AggregateMax[nTimer]); + float fMaxPrc = MicroProfileMin(fMaxMs * fToPrc, 1.f); + float fCallAverageMs = fToMs * (S.Aggregate[nTimer].nTicks / nAggregateCount); + float fCallAveragePrc = MicroProfileMin(fCallAverageMs * fToPrc, 1.f); + float fMsExclusive = fToMs * (S.FrameExclusive[nTimer]); + float fPrcExclusive = MicroProfileMin(fMsExclusive * fToPrc, 1.f); + float fAverageMsExclusive = fToMs * (S.AggregateExclusive[nTimer] / nAggregateFrames); + float fAveragePrcExclusive = MicroProfileMin(fAverageMsExclusive * fToPrc, 1.f); + float fMaxMsExclusive = fToMs * (S.AggregateMaxExclusive[nTimer]); + float fMaxPrcExclusive = MicroProfileMin(fMaxMsExclusive * fToPrc, 1.f); + pTimers[nIdx] = fMs; + pTimers[nIdx+1] = fPrc; + pAverage[nIdx] = fAverageMs; + pAverage[nIdx+1] = fAveragePrc; + pMax[nIdx] = fMaxMs; + pMax[nIdx+1] = fMaxPrc; + pCallAverage[nIdx] = fCallAverageMs; + pCallAverage[nIdx+1] = fCallAveragePrc; + pExclusive[nIdx] = fMsExclusive; + pExclusive[nIdx+1] = fPrcExclusive; + pAverageExclusive[nIdx] = fAverageMsExclusive; + pAverageExclusive[nIdx+1] = fAveragePrcExclusive; + pMaxExclusive[nIdx] = fMaxMsExclusive; + pMaxExclusive[nIdx+1] = fMaxPrcExclusive; + } + nCount += 2; + } + } + } + nMask <<= 1ll; + } +} + +#define SBUF_MAX 32 + +uint32_t MicroProfileDrawBarArray(int32_t nX, int32_t nY, float* pTimers, const char* pName, uint32_t nTotalHeight, float* pTimers2 = NULL) +{ + MicroProfile* pState = MicroProfileGet(); + + const uint32_t nHeight = MICROPROFILE_TEXT_HEIGHT; + const uint32_t nWidth = MICROPROFILE_BAR_WIDTH; + const uint32_t nTextWidth = 6 * (1+MICROPROFILE_TEXT_WIDTH); + const float fWidth = (float)MICROPROFILE_BAR_WIDTH; + + MicroProfileDrawLineVertical(nX-5, nY, nTotalHeight, UI.nOpacityBackground|g_nMicroProfileBackColors[0]|g_nMicroProfileBackColors[1]); + + MicroProfileLoopActiveGroupsDraw(nX, nY, pName, + [=](uint32_t nTimer, uint32_t nIdx, uint64_t nGroupMask, uint32_t nX, uint32_t nY){ + MicroProfile& S = *pState; + char sBuffer[SBUF_MAX]; + if (pTimers2 && pTimers2[nIdx] > 0.1f) + snprintf(sBuffer, SBUF_MAX-1, "%5.2f %3.1fx", pTimers[nIdx], pTimers[nIdx] / pTimers2[nIdx]); + else + snprintf(sBuffer, SBUF_MAX-1, "%5.2f", pTimers[nIdx]); + if (!pTimers2) + MicroProfileDrawBox(nX + nTextWidth, nY, nX + nTextWidth + fWidth * pTimers[nIdx+1], nY + nHeight, UI.nOpacityForeground|S.TimerInfo[nTimer].nColor, MicroProfileBoxTypeBar); + MicroProfileDrawText(nX, nY, (uint32_t)-1, sBuffer, (uint32_t)strlen(sBuffer)); + }); + return nWidth + 5 + nTextWidth; + +} + +uint32_t MicroProfileDrawBarCallCount(int32_t nX, int32_t nY, const char* pName) +{ + + MicroProfileLoopActiveGroupsDraw(nX, nY, pName, + [](uint32_t nTimer, uint32_t nIdx, uint64_t nGroupMask, uint32_t nX, uint32_t nY){ + MicroProfile& S = *MicroProfileGet(); + char sBuffer[SBUF_MAX]; + int nLen = snprintf(sBuffer, SBUF_MAX-1, "%5d", S.Frame[nTimer].nCount);//fix + MicroProfileDrawText(nX, nY, (uint32_t)-1, sBuffer, nLen); + }); + uint32_t nTextWidth = 6 * MICROPROFILE_TEXT_WIDTH; + return 5 + nTextWidth; +} + +uint32_t MicroProfileDrawBarMetaCount(int32_t nX, int32_t nY, uint64_t* pCounters, const char* pName, uint32_t nTotalHeight) +{ + if(!pName) + return 0; + + MicroProfileDrawLineVertical(nX-5, nY, nTotalHeight, UI.nOpacityBackground|g_nMicroProfileBackColors[0]|g_nMicroProfileBackColors[1]); + uint32_t nTextWidth = (1+MICROPROFILE_TEXT_WIDTH) * MicroProfileMax(6, (uint32_t)strlen(pName)); + + + MicroProfileLoopActiveGroupsDraw(nX, nY, pName, + [=](uint32_t nTimer, uint32_t nIdx, uint64_t nGroupMask, uint32_t nX, uint32_t nY){ + char sBuffer[SBUF_MAX]; + int nLen = snprintf(sBuffer, SBUF_MAX-1, "%5llu", pCounters[nTimer]); + MicroProfileDrawText(nX + nTextWidth - nLen * (MICROPROFILE_TEXT_WIDTH+1), nY, (uint32_t)-1, sBuffer, nLen); + }); + return 5 + nTextWidth; +} + +uint32_t MicroProfileDrawBarLegend(int32_t nX, int32_t nY, uint32_t nTotalHeight) +{ + MicroProfileDrawLineVertical(nX-5, nY, nTotalHeight, UI.nOpacityBackground | g_nMicroProfileBackColors[0]|g_nMicroProfileBackColors[1]); + MicroProfileLoopActiveGroupsDraw(nX, nY, 0, + [](uint32_t nTimer, uint32_t nIdx, uint64_t nGroupMask, uint32_t nX, uint32_t nY){ + MicroProfile& S = *MicroProfileGet(); + if (S.TimerInfo[nTimer].bGraph) + { + MicroProfileDrawText(nX, nY, S.TimerInfo[nTimer].nColor, ">", 1); + } + MicroProfileDrawText(nX + (MICROPROFILE_TEXT_WIDTH+1), nY, S.TimerInfo[nTimer].nColor, S.TimerInfo[nTimer].pName, (uint32_t)strlen(S.TimerInfo[nTimer].pName)); + if(UI.nMouseY >= nY && UI.nMouseY < nY + MICROPROFILE_TEXT_HEIGHT+1 && UI.nMouseX < nX + 20 * (MICROPROFILE_TEXT_WIDTH+1)) + { + UI.nHoverToken = nTimer; + UI.nHoverTime = 0; + } + }); + return nX; +} + +bool MicroProfileDrawGraph(uint32_t nScreenWidth, uint32_t nScreenHeight) +{ + MicroProfile& S = *MicroProfileGet(); + + MICROPROFILE_SCOPE(g_MicroProfileDrawGraph); + bool bEnabled = false; + for(uint32_t i = 0; i < MICROPROFILE_MAX_GRAPHS; ++i) + if(S.Graph[i].nToken != MICROPROFILE_INVALID_TOKEN) + bEnabled = true; + if(!bEnabled) + return false; + + uint32_t nX = nScreenWidth - MICROPROFILE_GRAPH_WIDTH; + uint32_t nY = nScreenHeight - MICROPROFILE_GRAPH_HEIGHT; + MicroProfileDrawBox(nX, nY, nX + MICROPROFILE_GRAPH_WIDTH, nY + MICROPROFILE_GRAPH_HEIGHT, UI.nOpacityBackground | g_nMicroProfileBackColors[0]|g_nMicroProfileBackColors[1]); + bool bMouseOver = UI.nMouseX >= nX && UI.nMouseY >= nY; + float fMouseXPrc =(float(UI.nMouseX - nX)) / MICROPROFILE_GRAPH_WIDTH; + if(bMouseOver) + { + float fXAvg = fMouseXPrc * MICROPROFILE_GRAPH_WIDTH + nX; + MicroProfileDrawLineVertical(fXAvg, nY, nY + MICROPROFILE_GRAPH_HEIGHT, (uint32_t)-1); + } + + + float fY = (float)nScreenHeight; + float fDX = MICROPROFILE_GRAPH_WIDTH * 1.f / MICROPROFILE_GRAPH_HISTORY; + float fDY = MICROPROFILE_GRAPH_HEIGHT; + uint32_t nPut = S.nGraphPut; + float* pGraphData = (float*)alloca(sizeof(float)* MICROPROFILE_GRAPH_HISTORY*2); + for(uint32_t i = 0; i < MICROPROFILE_MAX_GRAPHS; ++i) + { + if(S.Graph[i].nToken != MICROPROFILE_INVALID_TOKEN) + { + uint32_t nGroupId = MicroProfileGetGroupIndex(S.Graph[i].nToken); + bool bGpu = S.GroupInfo[nGroupId].Type == MicroProfileTokenTypeGpu; + float fToMs = MicroProfileTickToMsMultiplier(bGpu ? MicroProfileTicksPerSecondGpu() : MicroProfileTicksPerSecondCpu()); + float fToPrc = fToMs * S.fRcpReferenceTime * 3 / 4; + + float fX = (float)nX; + for(uint32_t j = 0; j < MICROPROFILE_GRAPH_HISTORY; ++j) + { + float fWeigth = MicroProfileMin(fToPrc * (S.Graph[i].nHistory[(j+nPut)%MICROPROFILE_GRAPH_HISTORY]), 1.f); + pGraphData[(j*2)] = fX; + pGraphData[(j*2)+1] = fY - fDY * fWeigth; + fX += fDX; + } + MicroProfileDrawLine2D(MICROPROFILE_GRAPH_HISTORY, pGraphData, S.TimerInfo[MicroProfileGetTimerIndex(S.Graph[i].nToken)].nColor); + } + } + { + float fY1 = 0.25f * MICROPROFILE_GRAPH_HEIGHT + nY; + float fY2 = 0.50f * MICROPROFILE_GRAPH_HEIGHT + nY; + float fY3 = 0.75f * MICROPROFILE_GRAPH_HEIGHT + nY; + MicroProfileDrawLineHorizontal(nX, nX + MICROPROFILE_GRAPH_WIDTH, fY1, 0xffdd4444); + MicroProfileDrawLineHorizontal(nX, nX + MICROPROFILE_GRAPH_WIDTH, fY2, 0xff000000| g_nMicroProfileBackColors[0]); + MicroProfileDrawLineHorizontal(nX, nX + MICROPROFILE_GRAPH_WIDTH, fY3, 0xff000000|g_nMicroProfileBackColors[0]); + + char buf[32]; + int nLen = snprintf(buf, sizeof(buf)-1, "%5.2fms", S.fReferenceTime); + MicroProfileDrawText(nX+1, fY1 - (2+MICROPROFILE_TEXT_HEIGHT), (uint32_t)-1, buf, nLen); + } + + + + if(bMouseOver) + { + uint32_t pColors[MICROPROFILE_MAX_GRAPHS]; + MicroProfileStringArray Strings; + MicroProfileStringArrayClear(&Strings); + uint32_t nTextCount = 0; + uint32_t nGraphIndex = (S.nGraphPut + MICROPROFILE_GRAPH_HISTORY - int(MICROPROFILE_GRAPH_HISTORY*(1.f - fMouseXPrc))) % MICROPROFILE_GRAPH_HISTORY; + + uint32_t nX = UI.nMouseX; + uint32_t nY = UI.nMouseY + 20; + + for(uint32_t i = 0; i < MICROPROFILE_MAX_GRAPHS; ++i) + { + if(S.Graph[i].nToken != MICROPROFILE_INVALID_TOKEN) + { + uint32_t nGroupId = MicroProfileGetGroupIndex(S.Graph[i].nToken); + bool bGpu = S.GroupInfo[nGroupId].Type == MicroProfileTokenTypeGpu; + float fToMs = MicroProfileTickToMsMultiplier(bGpu ? MicroProfileTicksPerSecondGpu() : MicroProfileTicksPerSecondCpu()); + uint32_t nIndex = MicroProfileGetTimerIndex(S.Graph[i].nToken); + uint32_t nColor = S.TimerInfo[nIndex].nColor; + const char* pName = S.TimerInfo[nIndex].pName; + pColors[nTextCount++] = nColor; + MicroProfileStringArrayAddLiteral(&Strings, pName); + MicroProfileStringArrayFormat(&Strings, "%5.2fms", fToMs * (S.Graph[i].nHistory[nGraphIndex])); + } + } + if(nTextCount) + { + MicroProfileDrawFloatWindow(nX, nY, Strings.ppStrings, Strings.nNumStrings, 0, pColors); + } + + if(UI.nMouseRight) + { + for(uint32_t i = 0; i < MICROPROFILE_MAX_GRAPHS; ++i) + { + S.Graph[i].nToken = MICROPROFILE_INVALID_TOKEN; + } + } + } + + return bMouseOver; +} + +void MicroProfileDumpTimers() +{ + MicroProfile& S = *MicroProfileGet(); + + uint64_t nActiveGroup = S.nGroupMask; + + uint32_t nNumTimers = S.nTotalTimers; + uint32_t nBlockSize = 2 * nNumTimers; + float* pTimers = (float*)alloca(nBlockSize * 7 * sizeof(float)); + float* pAverage = pTimers + nBlockSize; + float* pMax = pTimers + 2 * nBlockSize; + float* pCallAverage = pTimers + 3 * nBlockSize; + float* pTimersExclusive = pTimers + 4 * nBlockSize; + float* pAverageExclusive = pTimers + 5 * nBlockSize; + float* pMaxExclusive = pTimers + 6 * nBlockSize; + MicroProfileCalcTimers(pTimers, pAverage, pMax, pCallAverage, pTimersExclusive, pAverageExclusive, pMaxExclusive, nActiveGroup, nNumTimers); + + MICROPROFILE_PRINTF("%11s, ", "Time"); + MICROPROFILE_PRINTF("%11s, ", "Average"); + MICROPROFILE_PRINTF("%11s, ", "Max"); + MICROPROFILE_PRINTF("%11s, ", "Call Avg"); + MICROPROFILE_PRINTF("%9s, ", "Count"); + MICROPROFILE_PRINTF("%11s, ", "Excl"); + MICROPROFILE_PRINTF("%11s, ", "Avg Excl"); + MICROPROFILE_PRINTF("%11s, \n", "Max Excl"); + + for(uint32_t j = 0; j < MICROPROFILE_MAX_GROUPS; ++j) + { + uint64_t nMask = 1ll << j; + if(nMask & nActiveGroup) + { + MICROPROFILE_PRINTF("%s\n", S.GroupInfo[j].pName); + for(uint32_t i = 0; i < S.nTotalTimers;++i) + { + uint64_t nTokenMask = MicroProfileGetGroupMask(S.TimerInfo[i].nToken); + if(nTokenMask & nMask) + { + uint32_t nIdx = i * 2; + MICROPROFILE_PRINTF("%9.2fms, ", pTimers[nIdx]); + MICROPROFILE_PRINTF("%9.2fms, ", pAverage[nIdx]); + MICROPROFILE_PRINTF("%9.2fms, ", pMax[nIdx]); + MICROPROFILE_PRINTF("%9.2fms, ", pCallAverage[nIdx]); + MICROPROFILE_PRINTF("%9d, ", S.Frame[i].nCount); + MICROPROFILE_PRINTF("%9.2fms, ", pTimersExclusive[nIdx]); + MICROPROFILE_PRINTF("%9.2fms, ", pAverageExclusive[nIdx]); + MICROPROFILE_PRINTF("%9.2fms, ", pMaxExclusive[nIdx]); + MICROPROFILE_PRINTF("%s\n", S.TimerInfo[i].pName); + } + } + } + } +} + +void MicroProfileDrawBarView(uint32_t nScreenWidth, uint32_t nScreenHeight) +{ + MicroProfile& S = *MicroProfileGet(); + + uint64_t nActiveGroup = S.nAllGroupsWanted ? S.nGroupMask : S.nActiveGroupWanted; + if(!nActiveGroup) + return; + MICROPROFILE_SCOPE(g_MicroProfileDrawBarView); + + const uint32_t nHeight = MICROPROFILE_TEXT_HEIGHT; + int nColorIndex = 0; + uint32_t nX = 0; + uint32_t nY = nHeight + 1 - UI.nOffsetY; + uint32_t nNumTimers = 0; + uint32_t nNumGroups = 0; + uint32_t nMaxTimerNameLen = 1; + for(uint32_t j = 0; j < MICROPROFILE_MAX_GROUPS; ++j) + { + if(nActiveGroup & (1ll << j)) + { + nNumTimers += S.GroupInfo[j].nNumTimers; + nNumGroups += 1; + nMaxTimerNameLen = MicroProfileMax(nMaxTimerNameLen, S.GroupInfo[j].nMaxTimerNameLen); + } + } + uint32_t nBlockSize = 2 * nNumTimers; + float* pTimers = (float*)alloca(nBlockSize * 7 * sizeof(float)); + float* pAverage = pTimers + nBlockSize; + float* pMax = pTimers + 2 * nBlockSize; + float* pCallAverage = pTimers + 3 * nBlockSize; + float* pTimersExclusive = pTimers + 4 * nBlockSize; + float* pAverageExclusive = pTimers + 5 * nBlockSize; + float* pMaxExclusive = pTimers + 6 * nBlockSize; + MicroProfileCalcTimers(pTimers, pAverage, pMax, pCallAverage, pTimersExclusive, pAverageExclusive, pMaxExclusive, nActiveGroup, nNumTimers); + { + uint32_t nWidth = 0; + for(uint32_t i = 1; i ; i <<= 1) + { + if(S.nBars & i) + { + nWidth += MICROPROFILE_BAR_WIDTH + 5 + 6 * (1+MICROPROFILE_TEXT_WIDTH); + if(i & MP_DRAW_CALL_COUNT) + nWidth += 5 + 6 * MICROPROFILE_TEXT_WIDTH; + } + } + nWidth += (1+nMaxTimerNameLen) * (MICROPROFILE_TEXT_WIDTH+1); + for(uint32_t i = 0; i < nNumTimers+nNumGroups+1; ++i) + { + uint32_t nY0 = nY + i * (nHeight + 1); + bool bInside = (UI.nActiveMenu == -1) && ((UI.nMouseY >= nY0) && (UI.nMouseY < (nY0 + nHeight + 1))); + MicroProfileDrawBox(nX, nY0, nWidth, nY0 + (nHeight+1)+1, UI.nOpacityBackground | (g_nMicroProfileBackColors[nColorIndex++ & 1] + ((bInside) ? 0x002c2c2c : 0))); + } + } + int nTotalHeight = (nNumTimers+nNumGroups+2) * (nHeight+1); + uint32_t nLegendOffset = 1; + for(uint32_t j = 0; j < MICROPROFILE_MAX_GROUPS; ++j) + { + if(nActiveGroup & (1ll << j)) + { + MicroProfileDrawText(nX, nY + (1+nHeight) * nLegendOffset, (uint32_t)-1, S.GroupInfo[j].pName, S.GroupInfo[j].nNameLen); + nLegendOffset += S.GroupInfo[j].nNumTimers+1; + } + } + if(S.nBars & MP_DRAW_TIMERS) + nX += MicroProfileDrawBarArray(nX, nY, pTimers, "Time", nTotalHeight) + 1; + if(S.nBars & MP_DRAW_AVERAGE) + nX += MicroProfileDrawBarArray(nX, nY, pAverage, "Average", nTotalHeight) + 1; + if(S.nBars & MP_DRAW_MAX) + nX += MicroProfileDrawBarArray(nX, nY, pMax, (!UI.bShowSpikes) ? "Max Time" : "Max Time, Spike", nTotalHeight, UI.bShowSpikes ? pAverage : NULL) + 1; + if(S.nBars & MP_DRAW_CALL_COUNT) + { + nX += MicroProfileDrawBarArray(nX, nY, pCallAverage, "Call Average", nTotalHeight) + 1; + nX += MicroProfileDrawBarCallCount(nX, nY, "Count") + 1; + } + if(S.nBars & MP_DRAW_TIMERS_EXCLUSIVE) + nX += MicroProfileDrawBarArray(nX, nY, pTimersExclusive, "Exclusive Time", nTotalHeight) + 1; + if(S.nBars & MP_DRAW_AVERAGE_EXCLUSIVE) + nX += MicroProfileDrawBarArray(nX, nY, pAverageExclusive, "Exclusive Average", nTotalHeight) + 1; + if(S.nBars & MP_DRAW_MAX_EXCLUSIVE) + nX += MicroProfileDrawBarArray(nX, nY, pMaxExclusive, (!UI.bShowSpikes) ? "Exclusive Max Time" :"Excl Max Time, Spike", nTotalHeight, UI.bShowSpikes ? pAverageExclusive : NULL) + 1; + + for(int i = 0; i < MICROPROFILE_META_MAX; ++i) + { + if(S.nBars & (MP_DRAW_META_FIRST< SubmenuCallback; + typedef std::function ClickCallback; + SubmenuCallback GroupCallback[] = + { [] (int index, bool& bSelected) -> const char*{ + MicroProfile& S = *MicroProfileGet(); + switch(index) + { + case 0: + bSelected = S.nDisplay == MP_DRAW_DETAILED; + return "Detailed"; + case 1: + bSelected = S.nDisplay == MP_DRAW_BARS; + return "Timers"; + case 2: + bSelected = S.nDisplay == MP_DRAW_HIDDEN; + return "Hidden"; + case 3: + bSelected = false; + return "Off"; + case 4: + bSelected = false; + return "------"; + case 5: + bSelected = S.nForceEnable != 0; + return "Force Enable"; + + default: return 0; + } + }, + [] (int index, bool& bSelected) -> const char*{ + MicroProfile& S = *MicroProfileGet(); + + if(index == 0) + { + bSelected = S.nAllGroupsWanted != 0; + return "ALL"; + } + else + { + index = index-1; + bSelected = 0 != (S.nActiveGroupWanted & (1ll << index)); + if(index < MICROPROFILE_MAX_GROUPS && S.GroupInfo[index].pName[0] != '\0') + return S.GroupInfo[index].pName; + else + return 0; + } + }, + [] (int index, bool& bSelected) -> const char*{ + MicroProfile& S = *MicroProfileGet(); + if(index < sizeof(g_MicroProfileAggregatePresets)/sizeof(g_MicroProfileAggregatePresets[0])) + { + int val = g_MicroProfileAggregatePresets[index]; + bSelected = (int)S.nAggregateFlip == val; + if(0 == val) + return "Infinite"; + else + { + static char buf[128]; + snprintf(buf, sizeof(buf)-1, "%7d", val); + return buf; + } + } + return 0; + }, + [] (int index, bool& bSelected) -> const char*{ + MicroProfile& S = *MicroProfileGet(); + bSelected = 0 != (S.nBars & (1 << index)); + switch(index) + { + case 0: return "Time"; + case 1: return "Average"; + case 2: return "Max"; + case 3: return "Call Count"; + case 4: return "Exclusive Timers"; + case 5: return "Exclusive Average"; + case 6: return "Exclusive Max"; + } + int nMetaIndex = index - 7; + if(nMetaIndex < MICROPROFILE_META_MAX) + { + return S.MetaCounters[nMetaIndex].pName; + } + return 0; + }, + [] (int index, bool& bSelected) -> const char*{ + MicroProfile& S = *MicroProfileGet(); + if(index >= nOptionSize) return 0; + switch(Options[index].nSubType) + { + case 0: + bSelected = S.fReferenceTime == g_MicroProfileReferenceTimePresets[Options[index].nIndex]; + break; + case 1: + bSelected = UI.nOpacityBackground>>24 == g_MicroProfileOpacityPresets[Options[index].nIndex]; + break; + case 2: + bSelected = UI.nOpacityForeground>>24 == g_MicroProfileOpacityPresets[Options[index].nIndex]; + break; + case 3: + bSelected = UI.bShowSpikes; + break; +#if MICROPROFILE_CONTEXT_SWITCH_TRACE + case 4: + { + switch(Options[index].nIndex) + { + case 0: + bSelected = S.bContextSwitchRunning; + break; + case 1: + bSelected = S.bContextSwitchAllThreads; + break; + case 2: + bSelected = S.bContextSwitchNoBars; + break; + } + } + break; +#endif + } + return Options[index].Text; + }, + + [] (int index, bool& bSelected) -> const char*{ + static char buf[128]; + bSelected = false; + int nNumPresets = sizeof(g_MicroProfilePresetNames) / sizeof(g_MicroProfilePresetNames[0]); + int nIndexSave = index - nNumPresets - 1; + if(index == nNumPresets) + return "--"; + else if(nIndexSave >=0 && nIndexSave const char*{ + return 0; + }, + [] (int index, bool& bSelected) -> const char*{ + return 0; + }, + [] (int index, bool& bSelected) -> const char*{ + return 0; + }, + + + }; + ClickCallback CBClick[] = + { + [](int nIndex) + { + MicroProfile& S = *MicroProfileGet(); + switch(nIndex) + { + case 0: + S.nDisplay = MP_DRAW_DETAILED; + break; + case 1: + S.nDisplay = MP_DRAW_BARS; + break; + case 2: + S.nDisplay = MP_DRAW_HIDDEN; + break; + case 3: + S.nDisplay = 0; + break; + case 4: + break; + case 5: + S.nForceEnable = !S.nForceEnable; + break; + } + }, + [](int nIndex) + { + MicroProfile& S = *MicroProfileGet(); + if(nIndex == 0) + S.nAllGroupsWanted = 1-S.nAllGroupsWanted; + else + S.nActiveGroupWanted ^= (1ll << (nIndex-1)); + }, + [](int nIndex) + { + MicroProfile& S = *MicroProfileGet(); + S.nAggregateFlip = g_MicroProfileAggregatePresets[nIndex]; + if(0 == S.nAggregateFlip) + { + S.nAggregateClear = 1; + } + }, + [](int nIndex) + { + MicroProfile& S = *MicroProfileGet(); + S.nBars ^= (1 << nIndex); + }, + [](int nIndex) + { + MicroProfile& S = *MicroProfileGet(); + switch(Options[nIndex].nSubType) + { + case 0: + S.fReferenceTime = g_MicroProfileReferenceTimePresets[Options[nIndex].nIndex]; + S.fRcpReferenceTime = 1.f / S.fReferenceTime; + break; + case 1: + UI.nOpacityBackground = g_MicroProfileOpacityPresets[Options[nIndex].nIndex]<<24; + break; + case 2: + UI.nOpacityForeground = g_MicroProfileOpacityPresets[Options[nIndex].nIndex]<<24; + break; + case 3: + UI.bShowSpikes = !UI.bShowSpikes; + break; +#if MICROPROFILE_CONTEXT_SWITCH_TRACE + case 4: + { + switch(Options[nIndex].nIndex) + { + case 0: + if(S.bContextSwitchRunning) + { + MicroProfileStopContextSwitchTrace(); + } + else + { + MicroProfileStartContextSwitchTrace(); + } + break; + case 1: + S.bContextSwitchAllThreads = !S.bContextSwitchAllThreads; + break; + case 2: + S.bContextSwitchNoBars= !S.bContextSwitchNoBars; + break; + + } + } + break; +#endif + } + }, + [](int nIndex) + { + int nNumPresets = sizeof(g_MicroProfilePresetNames) / sizeof(g_MicroProfilePresetNames[0]); + int nIndexSave = nIndex - nNumPresets - 1; + if(nIndexSave >= 0 && nIndexSave < nNumPresets) + { + MicroProfileSavePreset(g_MicroProfilePresetNames[nIndexSave]); + } + else if(nIndex >= 0 && nIndex < nNumPresets) + { + MicroProfileLoadPreset(g_MicroProfilePresetNames[nIndex]); + } + }, + [](int nIndex) + { + }, + [](int nIndex) + { + }, + [](int nIndex) + { + }, + }; + + uint32_t nSelectMenu = (uint32_t)-1; + for(uint32_t i = 0; i < nNumMenuItems; ++i) + { + nMenuX[i] = nX; + uint32_t nLen = (uint32_t)strlen(pMenuText[i]); + uint32_t nEnd = nX + nLen * (MICROPROFILE_TEXT_WIDTH+1); + if(UI.nMouseY <= MICROPROFILE_TEXT_HEIGHT && UI.nMouseX <= nEnd && UI.nMouseX >= nX) + { + MicroProfileDrawBox(nX-1, nY, nX + nLen * (MICROPROFILE_TEXT_WIDTH+1), nY +(MICROPROFILE_TEXT_HEIGHT+1)+1, 0xff888888); + nSelectMenu = i; + if((UI.nMouseLeft || UI.nMouseRight) && i == (int)nPauseIndex) + { + S.nToggleRunning = 1; + } + } + MicroProfileDrawText(nX, nY, (uint32_t)-1, pMenuText[i], (uint32_t)strlen(pMenuText[i])); + nX += (nLen+1) * (MICROPROFILE_TEXT_WIDTH+1); + } + uint32_t nMenu = nSelectMenu != (uint32_t)-1 ? nSelectMenu : UI.nActiveMenu; + UI.nActiveMenu = nMenu; + if((uint32_t)-1 != nMenu) + { + nX = nMenuX[nMenu]; + nY += MICROPROFILE_TEXT_HEIGHT+1; + SubmenuCallback CB = GroupCallback[nMenu]; + int nNumLines = 0; + bool bSelected = false; + const char* pString = CB(nNumLines, bSelected); + uint32_t nWidth = 0, nHeight = 0; + while(pString) + { + nWidth = MicroProfileMax(nWidth, (int)strlen(pString)); + nNumLines++; + pString = CB(nNumLines, bSelected); + } + nWidth = (2+nWidth) * (MICROPROFILE_TEXT_WIDTH+1); + nHeight = nNumLines * (MICROPROFILE_TEXT_HEIGHT+1); + if(UI.nMouseY <= nY + nHeight+0 && UI.nMouseY >= nY-0 && UI.nMouseX <= nX + nWidth + 0 && UI.nMouseX >= nX - 0) + { + UI.nActiveMenu = nMenu; + } + else if(nSelectMenu == (uint32_t)-1) + { + UI.nActiveMenu = (uint32_t)-1; + } + MicroProfileDrawBox(nX, nY, nX + nWidth, nY + nHeight, 0xff000000|g_nMicroProfileBackColors[1]); + for(int i = 0; i < nNumLines; ++i) + { + bool bSelected = false; + const char* pString = CB(i, bSelected); + if(UI.nMouseY >= nY && UI.nMouseY < nY + MICROPROFILE_TEXT_HEIGHT + 1) + { + bMouseOver = true; + if(UI.nMouseLeft || UI.nMouseRight) + { + CBClick[nMenu](i); + } + MicroProfileDrawBox(nX, nY, nX + nWidth, nY + MICROPROFILE_TEXT_HEIGHT + 1, 0xff888888); + } + int nLen = snprintf(buffer, SBUF_SIZE-1, "%c %s", bSelected ? '*' : ' ' ,pString); + MicroProfileDrawText(nX, nY, (uint32_t)-1, buffer, nLen); + nY += MICROPROFILE_TEXT_HEIGHT+1; + } + } + + + { + static char FrameTimeMessage[64]; + float fToMs = MicroProfileTickToMsMultiplier(MicroProfileTicksPerSecondCpu()); + uint32_t nAggregateFrames = S.nAggregateFrames ? S.nAggregateFrames : 1; + float fMs = fToMs * (S.nFlipTicks); + float fAverageMs = fToMs * (S.nFlipAggregateDisplay / nAggregateFrames); + float fMaxMs = fToMs * S.nFlipMaxDisplay; + int nLen = snprintf(FrameTimeMessage, sizeof(FrameTimeMessage)-1, "Time[%6.2f] Avg[%6.2f] Max[%6.2f]", fMs, fAverageMs, fMaxMs); + pMenuText[nNumMenuItems++] = &FrameTimeMessage[0]; + MicroProfileDrawText(nWidth - nLen * (MICROPROFILE_TEXT_WIDTH+1), 0, -1, FrameTimeMessage, nLen); + } +} + + +void MicroProfileMoveGraph() +{ + + int nZoom = UI.nMouseWheelDelta; + int nPanX = 0; + int nPanY = 0; + static int X = 0, Y = 0; + if(UI.nMouseDownLeft && !UI.nModDown) + { + nPanX = UI.nMouseX - X; + nPanY = UI.nMouseY - Y; + } + X = UI.nMouseX; + Y = UI.nMouseY; + + if(nZoom) + { + float fOldRange = UI.fDetailedRange; + if(nZoom>0) + { + UI.fDetailedRangeTarget = UI.fDetailedRange *= UI.nModDown ? 1.40f : 1.05f; + } + else + { + float fNewDetailedRange = UI.fDetailedRange / (UI.nModDown ? 1.40f : 1.05f); + if(fNewDetailedRange < 1e-4f) //100ns + fNewDetailedRange = 1e-4f; + UI.fDetailedRangeTarget = UI.fDetailedRange = fNewDetailedRange; + } + + float fDiff = fOldRange - UI.fDetailedRange; + float fMousePrc = MicroProfileMax((float)UI.nMouseX / UI.nWidth ,0.f); + UI.fDetailedOffsetTarget = UI.fDetailedOffset += fDiff * fMousePrc; + + } + if(nPanX) + { + UI.fDetailedOffsetTarget = UI.fDetailedOffset += -nPanX * UI.fDetailedRange / UI.nWidth; + } + UI.nOffsetY -= nPanY; + if(UI.nOffsetY<0) + UI.nOffsetY = 0; +} + +void MicroProfileDraw(uint32_t nWidth, uint32_t nHeight) +{ + MICROPROFILE_SCOPE(g_MicroProfileDraw); + MicroProfile& S = *MicroProfileGet(); + + + { + static int once = 0; + if(0 == once) + { + std::recursive_mutex& m = MicroProfileGetMutex(); + m.lock(); + MicroProfileInitUI(); + + + + uint32_t nDisplay = S.nDisplay; + MicroProfileLoadPreset(MICROPROFILE_DEFAULT_PRESET); + once++; + S.nDisplay = nDisplay;// dont load display, just state + m.unlock(); + + } + } + + + if(S.nDisplay) + { + std::recursive_mutex& m = MicroProfileGetMutex(); + m.lock(); + UI.nWidth = nWidth; + UI.nHeight = nHeight; + UI.nHoverToken = MICROPROFILE_INVALID_TOKEN; + UI.nHoverTime = 0; + UI.nHoverFrame = -1; + if(S.nDisplay != MP_DRAW_DETAILED) + S.nContextSwitchHoverThread = S.nContextSwitchHoverThreadAfter = S.nContextSwitchHoverThreadBefore = -1; + MicroProfileMoveGraph(); + + + if(S.nDisplay == MP_DRAW_DETAILED) + { + MicroProfileDrawDetailedView(nWidth, nHeight); + } + else if(S.nDisplay == MP_DRAW_BARS && S.nBars) + { + MicroProfileDrawBarView(nWidth, nHeight); + } + + MicroProfileDrawMenu(nWidth, nHeight); + bool bMouseOverGraph = MicroProfileDrawGraph(nWidth, nHeight); + bool bHidden = S.nDisplay == MP_DRAW_HIDDEN; + if(!bHidden) + { + uint32_t nLockedToolTipX = 3; + bool bDeleted = false; + for(int i = 0; i < MICROPROFILE_TOOLTIP_MAX_LOCKED; ++i) + { + int nIndex = (g_MicroProfileUI.LockedToolTipFront + i) % MICROPROFILE_TOOLTIP_MAX_LOCKED; + if(g_MicroProfileUI.LockedToolTips[nIndex].ppStrings[0]) + { + uint32_t nToolTipWidth = 0, nToolTipHeight = 0; + MicroProfileFloatWindowSize(g_MicroProfileUI.LockedToolTips[nIndex].ppStrings, g_MicroProfileUI.LockedToolTips[nIndex].nNumStrings, 0, nToolTipWidth, nToolTipHeight, 0); + uint32_t nStartY = nHeight - nToolTipHeight - 2; + if(!bDeleted && UI.nMouseY > nStartY && UI.nMouseX > nLockedToolTipX && UI.nMouseX <= nLockedToolTipX + nToolTipWidth && (UI.nMouseLeft || UI.nMouseRight) ) + { + bDeleted = true; + int j = i; + for(; j < MICROPROFILE_TOOLTIP_MAX_LOCKED-1; ++j) + { + int nIndex0 = (g_MicroProfileUI.LockedToolTipFront + j) % MICROPROFILE_TOOLTIP_MAX_LOCKED; + int nIndex1 = (g_MicroProfileUI.LockedToolTipFront + j+1) % MICROPROFILE_TOOLTIP_MAX_LOCKED; + MicroProfileStringArrayCopy(&g_MicroProfileUI.LockedToolTips[nIndex0], &g_MicroProfileUI.LockedToolTips[nIndex1]); + } + MicroProfileStringArrayClear(&g_MicroProfileUI.LockedToolTips[(g_MicroProfileUI.LockedToolTipFront + j) % MICROPROFILE_TOOLTIP_MAX_LOCKED]); + } + else + { + MicroProfileDrawFloatWindow(nLockedToolTipX, nHeight-nToolTipHeight-2, &g_MicroProfileUI.LockedToolTips[nIndex].ppStrings[0], g_MicroProfileUI.LockedToolTips[nIndex].nNumStrings, g_MicroProfileUI.nLockedToolTipColor[nIndex]); + nLockedToolTipX += nToolTipWidth + 4; + } + } + } + + if(UI.nActiveMenu == 7) + { + if(S.nDisplay & MP_DRAW_DETAILED) + { + MicroProfileStringArray DetailedHelp; + MicroProfileStringArrayClear(&DetailedHelp); + MicroProfileStringArrayFormat(&DetailedHelp, "%s", MICROPROFILE_HELP_LEFT); + MicroProfileStringArrayAddLiteral(&DetailedHelp, "Toggle Graph"); + MicroProfileStringArrayFormat(&DetailedHelp, "%s", MICROPROFILE_HELP_ALT); + MicroProfileStringArrayAddLiteral(&DetailedHelp, "Zoom"); + MicroProfileStringArrayFormat(&DetailedHelp, "%s + %s", MICROPROFILE_HELP_MOD, MICROPROFILE_HELP_LEFT); + MicroProfileStringArrayAddLiteral(&DetailedHelp, "Lock Tooltip"); + MicroProfileStringArrayAddLiteral(&DetailedHelp, "Drag"); + MicroProfileStringArrayAddLiteral(&DetailedHelp, "Pan View"); + MicroProfileStringArrayAddLiteral(&DetailedHelp, "Mouse Wheel"); + MicroProfileStringArrayAddLiteral(&DetailedHelp, "Zoom"); + MicroProfileDrawFloatWindow(nWidth, MICROPROFILE_FRAME_HISTORY_HEIGHT+20, DetailedHelp.ppStrings, DetailedHelp.nNumStrings, 0xff777777); + + MicroProfileStringArray DetailedHistoryHelp; + MicroProfileStringArrayClear(&DetailedHistoryHelp); + MicroProfileStringArrayFormat(&DetailedHistoryHelp, "%s", MICROPROFILE_HELP_LEFT); + MicroProfileStringArrayAddLiteral(&DetailedHistoryHelp, "Center View"); + MicroProfileStringArrayFormat(&DetailedHistoryHelp, "%s", MICROPROFILE_HELP_ALT); + MicroProfileStringArrayAddLiteral(&DetailedHistoryHelp, "Zoom to frame"); + MicroProfileDrawFloatWindow(nWidth, 20, DetailedHistoryHelp.ppStrings, DetailedHistoryHelp.nNumStrings, 0xff777777); + + + + } + else if(0 != (S.nDisplay & MP_DRAW_BARS) && S.nBars) + { + MicroProfileStringArray BarHelp; + MicroProfileStringArrayClear(&BarHelp); + MicroProfileStringArrayFormat(&BarHelp, "%s", MICROPROFILE_HELP_LEFT); + MicroProfileStringArrayAddLiteral(&BarHelp, "Toggle Graph"); + MicroProfileStringArrayFormat(&BarHelp, "%s + %s", MICROPROFILE_HELP_MOD, MICROPROFILE_HELP_LEFT); + MicroProfileStringArrayAddLiteral(&BarHelp, "Lock Tooltip"); + MicroProfileStringArrayAddLiteral(&BarHelp, "Drag"); + MicroProfileStringArrayAddLiteral(&BarHelp, "Pan View"); + MicroProfileDrawFloatWindow(nWidth, MICROPROFILE_FRAME_HISTORY_HEIGHT+20, BarHelp.ppStrings, BarHelp.nNumStrings, 0xff777777); + + } + MicroProfileStringArray Debug; + MicroProfileStringArrayClear(&Debug); + MicroProfileStringArrayAddLiteral(&Debug, "Memory Usage"); + MicroProfileStringArrayFormat(&Debug, "%4.2fmb", S.nMemUsage / (1024.f * 1024.f)); + uint32_t nFrameNext = (S.nFrameCurrent+1) % MICROPROFILE_MAX_FRAME_HISTORY; + MicroProfileFrameState* pFrameCurrent = &S.Frames[S.nFrameCurrent]; + MicroProfileFrameState* pFrameNext = &S.Frames[nFrameNext]; + + + MicroProfileStringArrayAddLiteral(&Debug, ""); + MicroProfileStringArrayAddLiteral(&Debug, ""); + MicroProfileStringArrayAddLiteral(&Debug, "Usage"); + MicroProfileStringArrayAddLiteral(&Debug, "markers [frames] "); + +#if MICROPROFILE_CONTEXT_SWITCH_TRACE + MicroProfileStringArrayAddLiteral(&Debug, "Context Switch"); + MicroProfileStringArrayFormat(&Debug, "%9d [%7d]", S.nContextSwitchUsage, MICROPROFILE_CONTEXT_SWITCH_BUFFER_SIZE / S.nContextSwitchUsage ); +#endif + + for(int i = 0; i < MICROPROFILE_MAX_THREADS; ++i) + { + if(pFrameCurrent->nLogStart[i] && S.Pool[i]) + { + uint32_t nEnd = pFrameNext->nLogStart[i]; + uint32_t nStart = pFrameCurrent->nLogStart[i]; + uint32_t nUsage = nStart < nEnd ? (nEnd - nStart) : (nEnd + MICROPROFILE_BUFFER_SIZE - nStart); + uint32_t nFrameSupport = MICROPROFILE_BUFFER_SIZE / nUsage; + MicroProfileStringArrayFormat(&Debug, "%s", &S.Pool[i]->ThreadName[0]); + MicroProfileStringArrayFormat(&Debug, "%9d [%7d]", nUsage, nFrameSupport); + } + } + + MicroProfileDrawFloatWindow(0, nHeight-10, Debug.ppStrings, Debug.nNumStrings, 0xff777777); + } + + + + if(UI.nActiveMenu == -1 && !bMouseOverGraph) + { + if(UI.nHoverToken != MICROPROFILE_INVALID_TOKEN) + { + MicroProfileDrawFloatTooltip(UI.nMouseX, UI.nMouseY, UI.nHoverToken, UI.nHoverTime); + } + else if(S.nContextSwitchHoverThreadAfter != -1 && S.nContextSwitchHoverThreadBefore != -1) + { + float fToMs = MicroProfileTickToMsMultiplier(MicroProfileTicksPerSecondCpu()); + MicroProfileStringArray ToolTip; + MicroProfileStringArrayClear(&ToolTip); + MicroProfileStringArrayAddLiteral(&ToolTip, "Context Switch"); + MicroProfileStringArrayFormat(&ToolTip, "%04x", S.nContextSwitchHoverThread); + MicroProfileStringArrayAddLiteral(&ToolTip, "Before"); + MicroProfileStringArrayFormat(&ToolTip, "%04x", S.nContextSwitchHoverThreadBefore); + MicroProfileStringArrayAddLiteral(&ToolTip, "After"); + MicroProfileStringArrayFormat(&ToolTip, "%04x", S.nContextSwitchHoverThreadAfter); + MicroProfileStringArrayAddLiteral(&ToolTip, "Duration"); + int64_t nDifference = MicroProfileLogTickDifference(S.nContextSwitchHoverTickIn, S.nContextSwitchHoverTickOut); + MicroProfileStringArrayFormat(&ToolTip, "%6.2fms", fToMs * nDifference ); + MicroProfileStringArrayAddLiteral(&ToolTip, "CPU"); + MicroProfileStringArrayFormat(&ToolTip, "%d", S.nContextSwitchHoverCpu); + MicroProfileDrawFloatWindow(UI.nMouseX, UI.nMouseY+20, &ToolTip.ppStrings[0], ToolTip.nNumStrings, -1); + + + } + else if(UI.nHoverFrame != -1) + { + uint32_t nNextFrame = (UI.nHoverFrame+1)%MICROPROFILE_MAX_FRAME_HISTORY; + int64_t nTick = S.Frames[UI.nHoverFrame].nFrameStartCpu; + int64_t nTickNext = S.Frames[nNextFrame].nFrameStartCpu; + int64_t nTickGpu = S.Frames[UI.nHoverFrame].nFrameStartGpu; + int64_t nTickNextGpu = S.Frames[nNextFrame].nFrameStartGpu; + + float fToMs = MicroProfileTickToMsMultiplier(MicroProfileTicksPerSecondCpu()); + float fToMsGpu = MicroProfileTickToMsMultiplier(MicroProfileTicksPerSecondGpu()); + float fMs = fToMs * (nTickNext - nTick); + float fMsGpu = fToMsGpu * (nTickNextGpu - nTickGpu); + MicroProfileStringArray ToolTip; + MicroProfileStringArrayClear(&ToolTip); + MicroProfileStringArrayFormat(&ToolTip, "Frame %d", UI.nHoverFrame); + #if MICROPROFILE_DEBUG + MicroProfileStringArrayFormat(&ToolTip, "%p", &S.Frames[UI.nHoverFrame]); + #else + MicroProfileStringArrayAddLiteral(&ToolTip, ""); + #endif + MicroProfileStringArrayAddLiteral(&ToolTip, "CPU Time"); + MicroProfileStringArrayFormat(&ToolTip, "%6.2fms", fMs); + MicroProfileStringArrayAddLiteral(&ToolTip, "GPU Time"); + MicroProfileStringArrayFormat(&ToolTip, "%6.2fms", fMsGpu); + #if MICROPROFILE_DEBUG + for(int i = 0; i < MICROPROFILE_MAX_THREADS; ++i) + { + if(S.Frames[UI.nHoverFrame].nLogStart[i]) + { + MicroProfileStringArrayFormat(&ToolTip, "%d", i); + MicroProfileStringArrayFormat(&ToolTip, "%d", S.Frames[UI.nHoverFrame].nLogStart[i]); + } + } + #endif + MicroProfileDrawFloatWindow(UI.nMouseX, UI.nMouseY+20, &ToolTip.ppStrings[0], ToolTip.nNumStrings, -1); + } + if(UI.nMouseLeft) + { + if(UI.nHoverToken != MICROPROFILE_INVALID_TOKEN) + MicroProfileToggleGraph(UI.nHoverToken); + } + } + } +#if MICROPROFILE_DRAWCURSOR + { + float fCursor[8] = + { + MicroProfileMax(0, (int)UI.nMouseX-3), UI.nMouseY, + MicroProfileMin(nWidth, UI.nMouseX+3), UI.nMouseY, + UI.nMouseX, MicroProfileMax((int)UI.nMouseY-3, 0), + UI.nMouseX, MicroProfileMin(nHeight, UI.nMouseY+3), + }; + MicroProfileDrawLine2D(2, &fCursor[0], 0xff00ff00); + MicroProfileDrawLine2D(2, &fCursor[4], 0xff00ff00); + } +#endif + m.unlock(); + } + UI.nMouseLeft = UI.nMouseRight = 0; + UI.nMouseLeftMod = UI.nMouseRightMod = 0; + UI.nMouseWheelDelta = 0; + if(S.nOverflow) + S.nOverflow--; + + UI.fDetailedOffset = UI.fDetailedOffset + (UI.fDetailedOffsetTarget - UI.fDetailedOffset) * MICROPROFILE_ANIM_DELAY_PRC; + UI.fDetailedRange = UI.fDetailedRange + (UI.fDetailedRangeTarget - UI.fDetailedRange) * MICROPROFILE_ANIM_DELAY_PRC; + + +} + +bool MicroProfileIsDrawing() +{ + MicroProfile& S = *MicroProfileGet(); + return S.nDisplay != 0; +} + +void MicroProfileToggleGraph(MicroProfileToken nToken) +{ + MicroProfile& S = *MicroProfileGet(); + uint32_t nTimerId = MicroProfileGetTimerIndex(nToken); + nToken &= 0xffff; + int32_t nMinSort = 0x7fffffff; + int32_t nFreeIndex = -1; + int32_t nMinIndex = 0; + int32_t nMaxSort = 0x80000000; + for(uint32_t i = 0; i < MICROPROFILE_MAX_GRAPHS; ++i) + { + if(S.Graph[i].nToken == MICROPROFILE_INVALID_TOKEN) + nFreeIndex = i; + if(S.Graph[i].nToken == nToken) + { + S.Graph[i].nToken = MICROPROFILE_INVALID_TOKEN; + S.TimerInfo[nTimerId].bGraph = false; + return; + } + if(S.Graph[i].nKey < nMinSort) + { + nMinSort = S.Graph[i].nKey; + nMinIndex = i; + } + if(S.Graph[i].nKey > nMaxSort) + { + nMaxSort = S.Graph[i].nKey; + } + } + int nIndex = nFreeIndex > -1 ? nFreeIndex : nMinIndex; + if (nFreeIndex == -1) + { + uint32_t idx = MicroProfileGetTimerIndex(S.Graph[nIndex].nToken); + S.TimerInfo[idx].bGraph = false; + } + S.Graph[nIndex].nToken = nToken; + S.Graph[nIndex].nKey = nMaxSort+1; + memset(&S.Graph[nIndex].nHistory[0], 0, sizeof(S.Graph[nIndex].nHistory)); + S.TimerInfo[nTimerId].bGraph = true; +} + + +void MicroProfileMousePosition(uint32_t nX, uint32_t nY, int nWheelDelta) +{ + UI.nMouseX = nX; + UI.nMouseY = nY; + UI.nMouseWheelDelta = nWheelDelta; +} + +void MicroProfileModKey(uint32_t nKeyState) +{ + UI.nModDown = nKeyState ? 1 : 0; +} + +void MicroProfileClearGraph() +{ + MicroProfile& S = *MicroProfileGet(); + for(uint32_t i = 0; i < MICROPROFILE_MAX_GRAPHS; ++i) + { + if(S.Graph[i].nToken != 0) + { + S.Graph[i].nToken = MICROPROFILE_INVALID_TOKEN; + } + } +} + +void MicroProfileMouseButton(uint32_t nLeft, uint32_t nRight) +{ + if(0 == nLeft && UI.nMouseDownLeft) + { + if(UI.nModDown) + UI.nMouseLeftMod = 1; + else + UI.nMouseLeft = 1; + } + + if(0 == nRight && UI.nMouseDownRight) + { + if(UI.nModDown) + UI.nMouseRightMod = 1; + else + UI.nMouseRight = 1; + } + + UI.nMouseDownLeft = nLeft; + UI.nMouseDownRight = nRight; + +} + +void MicroProfileDrawLineVertical(int nX, int nTop, int nBottom, uint32_t nColor) +{ + MicroProfileDrawBox(nX, nTop, nX + 1, nBottom, nColor); +} + +void MicroProfileDrawLineHorizontal(int nLeft, int nRight, int nY, uint32_t nColor) +{ + MicroProfileDrawBox(nLeft, nY, nRight, nY + 1, nColor); +} + + + +#include + +#define MICROPROFILE_PRESET_HEADER_MAGIC 0x28586813 +#define MICROPROFILE_PRESET_HEADER_VERSION 0x00000102 +struct MicroProfilePresetHeader +{ + uint32_t nMagic; + uint32_t nVersion; + //groups, threads, aggregate, reference frame, graphs timers + uint32_t nGroups[MICROPROFILE_MAX_GROUPS]; + uint32_t nThreads[MICROPROFILE_MAX_THREADS]; + uint32_t nGraphName[MICROPROFILE_MAX_GRAPHS]; + uint32_t nGraphGroupName[MICROPROFILE_MAX_GRAPHS]; + uint32_t nAllGroupsWanted; + uint32_t nAllThreadsWanted; + uint32_t nAggregateFlip; + float fReferenceTime; + uint32_t nBars; + uint32_t nDisplay; + uint32_t nOpacityBackground; + uint32_t nOpacityForeground; + uint32_t nShowSpikes; +}; + +#ifndef MICROPROFILE_PRESET_FILENAME_FUNC +#define MICROPROFILE_PRESET_FILENAME_FUNC MicroProfilePresetFilename +static const char* MicroProfilePresetFilename(const char* pSuffix) +{ + static char filename[512]; + snprintf(filename, sizeof(filename)-1, ".microprofilepreset.%s", pSuffix); + return filename; +} +#endif + +void MicroProfileSavePreset(const char* pPresetName) +{ + std::lock_guard Lock(MicroProfileGetMutex()); + FILE* F = fopen(MICROPROFILE_PRESET_FILENAME_FUNC(pPresetName), "wb"); + if(!F) return; + + MicroProfile& S = *MicroProfileGet(); + + MicroProfilePresetHeader Header; + memset(&Header, 0, sizeof(Header)); + Header.nAggregateFlip = S.nAggregateFlip; + Header.nBars = S.nBars; + Header.fReferenceTime = S.fReferenceTime; + Header.nAllGroupsWanted = S.nAllGroupsWanted; + Header.nAllThreadsWanted = S.nAllThreadsWanted; + Header.nMagic = MICROPROFILE_PRESET_HEADER_MAGIC; + Header.nVersion = MICROPROFILE_PRESET_HEADER_VERSION; + Header.nDisplay = S.nDisplay; + Header.nOpacityBackground = UI.nOpacityBackground; + Header.nOpacityForeground = UI.nOpacityForeground; + Header.nShowSpikes = UI.bShowSpikes ? 1 : 0; + fwrite(&Header, sizeof(Header), 1, F); + uint64_t nMask = 1; + for(uint32_t i = 0; i < MICROPROFILE_MAX_GROUPS; ++i) + { + if(S.nActiveGroupWanted & nMask) + { + uint32_t offset = ftell(F); + const char* pName = S.GroupInfo[i].pName; + int nLen = (int)strlen(pName)+1; + fwrite(pName, nLen, 1, F); + Header.nGroups[i] = offset; + } + nMask <<= 1; + } + for(uint32_t i = 0; i < MICROPROFILE_MAX_THREADS; ++i) + { + MicroProfileThreadLog* pLog = S.Pool[i]; + if(pLog && S.nThreadActive[i]) + { + uint32_t nOffset = ftell(F); + const char* pName = &pLog->ThreadName[0]; + int nLen = (int)strlen(pName)+1; + fwrite(pName, nLen, 1, F); + Header.nThreads[i] = nOffset; + } + } + for(uint32_t i = 0; i < MICROPROFILE_MAX_GRAPHS; ++i) + { + MicroProfileToken nToken = S.Graph[i].nToken; + if(nToken != MICROPROFILE_INVALID_TOKEN) + { + uint32_t nGroupIndex = MicroProfileGetGroupIndex(nToken); + uint32_t nTimerIndex = MicroProfileGetTimerIndex(nToken); + const char* pGroupName = S.GroupInfo[nGroupIndex].pName; + const char* pTimerName = S.TimerInfo[nTimerIndex].pName; + MP_ASSERT(pGroupName); + MP_ASSERT(pTimerName); + int nGroupLen = (int)strlen(pGroupName)+1; + int nTimerLen = (int)strlen(pTimerName)+1; + + uint32_t nOffsetGroup = ftell(F); + fwrite(pGroupName, nGroupLen, 1, F); + uint32_t nOffsetTimer = ftell(F); + fwrite(pTimerName, nTimerLen, 1, F); + Header.nGraphName[i] = nOffsetTimer; + Header.nGraphGroupName[i] = nOffsetGroup; + } + } + fseek(F, 0, SEEK_SET); + fwrite(&Header, sizeof(Header), 1, F); + + fclose(F); + +} + + + +void MicroProfileLoadPreset(const char* pSuffix) +{ + std::lock_guard Lock(MicroProfileGetMutex()); + FILE* F = fopen(MICROPROFILE_PRESET_FILENAME_FUNC(pSuffix), "rb"); + if(!F) + { + return; + } + fseek(F, 0, SEEK_END); + int nSize = ftell(F); + char* const pBuffer = (char*)alloca(nSize); + fseek(F, 0, SEEK_SET); + int nRead = (int)fread(pBuffer, nSize, 1, F); + fclose(F); + if(1 != nRead) + return; + + MicroProfile& S = *MicroProfileGet(); + + MicroProfilePresetHeader& Header = *(MicroProfilePresetHeader*)pBuffer; + + if(Header.nMagic != MICROPROFILE_PRESET_HEADER_MAGIC || Header.nVersion != MICROPROFILE_PRESET_HEADER_VERSION) + { + return; + } + + S.nAggregateFlip = Header.nAggregateFlip; + S.nBars = Header.nBars; + S.fReferenceTime = Header.fReferenceTime; + S.fRcpReferenceTime = 1.f / Header.fReferenceTime; + S.nAllGroupsWanted = Header.nAllGroupsWanted; + S.nAllThreadsWanted = Header.nAllThreadsWanted; + S.nDisplay = Header.nDisplay; + S.nActiveGroupWanted = 0; + UI.nOpacityBackground = Header.nOpacityBackground; + UI.nOpacityForeground = Header.nOpacityForeground; + UI.bShowSpikes = Header.nShowSpikes == 1; + + memset(&S.nThreadActive[0], 0, sizeof(S.nThreadActive)); + + for(uint32_t i = 0; i < MICROPROFILE_MAX_GROUPS; ++i) + { + if(Header.nGroups[i]) + { + const char* pGroupName = pBuffer + Header.nGroups[i]; + for(uint32_t j = 0; j < MICROPROFILE_MAX_GROUPS; ++j) + { + if(S.GroupInfo[j].pName && 0 == MP_STRCASECMP(pGroupName, S.GroupInfo[j].pName)) + { + S.nActiveGroupWanted |= (1ll << j); + } + } + } + } + for(uint32_t i = 0; i < MICROPROFILE_MAX_THREADS; ++i) + { + if(Header.nThreads[i]) + { + const char* pThreadName = pBuffer + Header.nThreads[i]; + for(uint32_t j = 0; j < MICROPROFILE_MAX_THREADS; ++j) + { + MicroProfileThreadLog* pLog = S.Pool[j]; + if(pLog && 0 == MP_STRCASECMP(pThreadName, &pLog->ThreadName[0])) + { + S.nThreadActive[j] = 1; + } + } + } + } + for(uint32_t i = 0; i < MICROPROFILE_MAX_GRAPHS; ++i) + { + MicroProfileToken nPrevToken = S.Graph[i].nToken; + S.Graph[i].nToken = MICROPROFILE_INVALID_TOKEN; + if(Header.nGraphName[i] && Header.nGraphGroupName[i]) + { + const char* pGraphName = pBuffer + Header.nGraphName[i]; + const char* pGraphGroupName = pBuffer + Header.nGraphGroupName[i]; + for(uint32_t j = 0; j < S.nTotalTimers; ++j) + { + uint64_t nGroupIndex = S.TimerInfo[j].nGroupIndex; + if(0 == MP_STRCASECMP(pGraphName, S.TimerInfo[j].pName) && 0 == MP_STRCASECMP(pGraphGroupName, S.GroupInfo[nGroupIndex].pName)) + { + MicroProfileToken nToken = MicroProfileMakeToken(1ll << nGroupIndex, (uint16_t)j); + S.Graph[i].nToken = nToken; // note: group index is stored here but is checked without in MicroProfileToggleGraph()! + S.TimerInfo[j].bGraph = true; + if(nToken != nPrevToken) + { + memset(&S.Graph[i].nHistory, 0, sizeof(S.Graph[i].nHistory)); + } + break; + } + } + } + } +} + + +#undef UI + +#endif +#endif From aa22d07caf4a36bd37a93e8411103ed4ebb905ba Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 2 Jan 2015 17:26:02 -0800 Subject: [PATCH 307/388] Super slow MicroProfile GL UI. --- src/poly/ui/ui_event.h | 18 +- src/poly/ui/win32/win32_control.cc | 9 +- src/xenia/gpu/gl4/circular_buffer.cc | 11 +- src/xenia/gpu/gl4/circular_buffer.h | 3 +- src/xenia/gpu/gl4/command_processor.cc | 19 +- src/xenia/gpu/gl4/gl4_graphics_system.cc | 12 +- src/xenia/gpu/gl4/gl4_profiler_display.cc | 560 ++++++++++++++++++++++ src/xenia/gpu/gl4/gl4_profiler_display.h | 84 ++++ src/xenia/gpu/gl4/gl_context.cc | 5 +- src/xenia/gpu/gl4/sources.gypi | 2 + src/xenia/gpu/gl4/wgl_control.cc | 10 +- src/xenia/profiling.cc | 59 ++- src/xenia/profiling.h | 14 +- third_party/microprofile/microprofileui.h | 2 +- 14 files changed, 748 insertions(+), 60 deletions(-) create mode 100644 src/xenia/gpu/gl4/gl4_profiler_display.cc create mode 100644 src/xenia/gpu/gl4/gl4_profiler_display.h diff --git a/src/poly/ui/ui_event.h b/src/poly/ui/ui_event.h index eb3dfe8bc..641eddf90 100644 --- a/src/poly/ui/ui_event.h +++ b/src/poly/ui/ui_event.h @@ -29,12 +29,16 @@ class UIEvent { class KeyEvent : public UIEvent { public: KeyEvent(Control* control, int key_code) - : UIEvent(control), key_code_(key_code) {} + : UIEvent(control), handled_(false), key_code_(key_code) {} ~KeyEvent() override = default; + bool is_handled() const { return handled_; } + void set_handled(bool value) { handled_ = value; } + int key_code() const { return key_code_; } private: + bool handled_; int key_code_; }; @@ -52,9 +56,18 @@ class MouseEvent : public UIEvent { public: MouseEvent(Control* control, Button button, int32_t x, int32_t y, int32_t dx = 0, int32_t dy = 0) - : UIEvent(control), button_(button), x_(x), y_(y), dx_(dx), dy_(dy) {} + : UIEvent(control), + handled_(false), + button_(button), + x_(x), + y_(y), + dx_(dx), + dy_(dy) {} ~MouseEvent() override = default; + bool is_handled() const { return handled_; } + void set_handled(bool value) { handled_ = value; } + Button button() const { return button_; } int32_t x() const { return x_; } int32_t y() const { return y_; } @@ -62,6 +75,7 @@ class MouseEvent : public UIEvent { int32_t dy() const { return dy_; } private: + bool handled_; Button button_; int32_t x_; int32_t y_; diff --git a/src/poly/ui/win32/win32_control.cc b/src/poly/ui/win32/win32_control.cc index c4f888cba..cc75558fc 100644 --- a/src/poly/ui/win32/win32_control.cc +++ b/src/poly/ui/win32/win32_control.cc @@ -342,7 +342,7 @@ bool Win32Control::HandleMouse(UINT message, WPARAM wParam, LPARAM lParam) { OnMouseWheel(e); break; } - return true; + return e.is_handled(); } bool Win32Control::HandleKeyboard(UINT message, WPARAM wParam, LPARAM lParam) { @@ -350,13 +350,12 @@ bool Win32Control::HandleKeyboard(UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_KEYDOWN: OnKeyDown(e); - return true; + break; case WM_KEYUP: OnKeyUp(e); - return true; - default: - return false; + break; } + return e.is_handled(); } } // namespace win32 diff --git a/src/xenia/gpu/gl4/circular_buffer.cc b/src/xenia/gpu/gl4/circular_buffer.cc index d2a342646..92ce0e643 100644 --- a/src/xenia/gpu/gl4/circular_buffer.cc +++ b/src/xenia/gpu/gl4/circular_buffer.cc @@ -20,8 +20,9 @@ namespace gl4 { extern "C" GLEWContext* glewGetContext(); extern "C" WGLEWContext* wglewGetContext(); -CircularBuffer::CircularBuffer(size_t capacity) +CircularBuffer::CircularBuffer(size_t capacity, size_t alignment) : capacity_(capacity), + alignment_(alignment), write_head_(0), buffer_(0), gpu_base_(0), @@ -64,11 +65,11 @@ void CircularBuffer::Shutdown() { CircularBuffer::Allocation CircularBuffer::Acquire(size_t length) { // Addresses must always be % 256. - length = poly::round_up(length, 256); + size_t aligned_length = poly::round_up(length, alignment_); - assert_true(length <= capacity_, "Request too large"); + assert_true(aligned_length <= capacity_, "Request too large"); - if (write_head_ + length > capacity_) { + if (write_head_ + aligned_length > capacity_) { // Flush and wait. WaitUntilClean(); } @@ -78,7 +79,7 @@ CircularBuffer::Allocation CircularBuffer::Acquire(size_t length) { allocation.gpu_ptr = gpu_base_ + write_head_; allocation.offset = write_head_; allocation.length = length; - write_head_ += length; + write_head_ += aligned_length; return allocation; } diff --git a/src/xenia/gpu/gl4/circular_buffer.h b/src/xenia/gpu/gl4/circular_buffer.h index 987ce746c..777f60274 100644 --- a/src/xenia/gpu/gl4/circular_buffer.h +++ b/src/xenia/gpu/gl4/circular_buffer.h @@ -20,7 +20,7 @@ namespace gl4 { // TODO(benvanik): fences to prevent this from ever flushing. class CircularBuffer { public: - CircularBuffer(size_t capacity); + CircularBuffer(size_t capacity, size_t alignment = 256); ~CircularBuffer(); struct Allocation { @@ -42,6 +42,7 @@ class CircularBuffer { private: size_t capacity_; + size_t alignment_; uintptr_t write_head_; GLuint buffer_; GLuint64 gpu_base_; diff --git a/src/xenia/gpu/gl4/command_processor.cc b/src/xenia/gpu/gl4/command_processor.cc index 6f2dd422c..64029c914 100644 --- a/src/xenia/gpu/gl4/command_processor.cc +++ b/src/xenia/gpu/gl4/command_processor.cc @@ -125,6 +125,7 @@ void CommandProcessor::WorkerMain() { uint32_t write_ptr_index = write_ptr_index_.load(); while (write_ptr_index == 0xBAADF00D || read_ptr_index_ == write_ptr_index) { + SCOPE_profile_cpu_i("gpu", "xe::gpu::gl4::CommandProcessor::Stall"); // Check if the pointer has moved. // We wait a short bit here to yield time. Since we are also running the // main window display we don't want to pause too long, though. @@ -781,6 +782,8 @@ bool CommandProcessor::ExecutePacketType3_INTERRUPT(RingbufferReader* reader, uint32_t packet_ptr, uint32_t packet, uint32_t count) { + SCOPE_profile_cpu_f("gpu"); + // generate interrupt from the command stream XETRACECP("[%.8X] Packet(%.8X): PM4_INTERRUPT", packet_ptr, packet); reader->TraceData(count); @@ -797,6 +800,8 @@ bool CommandProcessor::ExecutePacketType3_XE_SWAP(RingbufferReader* reader, uint32_t packet_ptr, uint32_t packet, uint32_t count) { + SCOPE_profile_cpu_f("gpu"); + auto& regs = *register_file_; PLOGI("XE_SWAP"); @@ -858,6 +863,8 @@ bool CommandProcessor::ExecutePacketType3_WAIT_REG_MEM(RingbufferReader* reader, uint32_t packet_ptr, uint32_t packet, uint32_t count) { + SCOPE_profile_cpu_f("gpu"); + // wait until a register or memory location is a specific value XETRACECP("[%.8X] Packet(%.8X): PM4_WAIT_REG_MEM", packet_ptr, packet); reader->TraceData(count); @@ -1315,6 +1322,7 @@ bool CommandProcessor::IssueDraw(DrawCommand* draw_command) { SCOPE_profile_cpu_f("gpu"); auto& regs = *register_file_; auto& cmd = *draw_command; + auto enable_mode = static_cast(regs[XE_GPU_REG_RB_MODECONTROL].u32 & 0x7); if (enable_mode == ModeControl::kIgnore) { @@ -1455,6 +1463,7 @@ bool CommandProcessor::IssueDraw(DrawCommand* draw_command) { } bool CommandProcessor::UpdateRenderTargets(DrawCommand* draw_command) { + SCOPE_profile_cpu_f("gpu"); auto& regs = *register_file_; auto enable_mode = @@ -1541,15 +1550,15 @@ bool CommandProcessor::UpdateRenderTargets(DrawCommand* draw_command) { } bool CommandProcessor::UpdateState(DrawCommand* draw_command) { + SCOPE_profile_cpu_f("gpu"); + auto& regs = *register_file_; + auto state_data = draw_command->state_data; + // Much of this state machine is extracted from: // https://github.com/freedreno/mesa/blob/master/src/mesa/drivers/dri/r200/r200_state.c // http://fossies.org/dox/MesaLib-10.3.5/fd2__gmem_8c_source.html // http://www.x.org/docs/AMD/old/evergreen_3D_registers_v2.pdf - auto& regs = *register_file_; - - auto state_data = draw_command->state_data; - uint32_t mode_control = regs[XE_GPU_REG_PA_SU_SC_MODE_CNTL].u32; // Window parameters. @@ -2115,7 +2124,6 @@ bool CommandProcessor::PopulateVertexBuffers(DrawCommand* draw_command) { bool CommandProcessor::PopulateSamplers(DrawCommand* draw_command) { SCOPE_profile_cpu_f("gpu"); - auto& regs = *register_file_; // VS and PS samplers are shared, but may be used exclusively. @@ -2201,6 +2209,7 @@ bool CommandProcessor::PopulateSampler(DrawCommand* draw_command, } bool CommandProcessor::IssueCopy(DrawCommand* draw_command) { + SCOPE_profile_cpu_f("gpu"); auto& regs = *register_file_; // This is used to resolve surfaces, taking them from EDRAM render targets diff --git a/src/xenia/gpu/gl4/gl4_graphics_system.cc b/src/xenia/gpu/gl4/gl4_graphics_system.cc index a977f2a6f..2edc4277d 100644 --- a/src/xenia/gpu/gl4/gl4_graphics_system.cc +++ b/src/xenia/gpu/gl4/gl4_graphics_system.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include namespace xe { @@ -43,17 +44,16 @@ X_STATUS GL4GraphicsSystem::Setup() { control_ = std::make_unique(loop); emulator_->main_window()->AddChild(control_.get()); - if (FLAGS_thread_safe_gl) { - control_->context()->MakeCurrent(); - } - // Setup the GL context the command processor will do all its drawing in. // It's shared with the control context so that we can resolve framebuffers // from it. processor_context = control_->context()->CreateShared(); - if (FLAGS_thread_safe_gl) { - control_->context()->ClearCurrent(); + { + GLContextLock context_lock(control_->context()); + auto profiler_display = + std::make_unique(control_.get()); + Profiler::set_display(std::move(profiler_display)); } control_ready_fence.Signal(); diff --git a/src/xenia/gpu/gl4/gl4_profiler_display.cc b/src/xenia/gpu/gl4/gl4_profiler_display.cc new file mode 100644 index 000000000..21929ab48 --- /dev/null +++ b/src/xenia/gpu/gl4/gl4_profiler_display.cc @@ -0,0 +1,560 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include + +#include +#include +#include + +namespace xe { +namespace gpu { +namespace gl4 { + +extern "C" GLEWContext* glewGetContext(); + +#define MICROPROFILE_MAX_VERTICES (16 << 10) +#define MICROPROFILE_NUM_QUERIES (8 << 10) +#define MAX_FONT_CHARS 256 +#define Q0(d, member, v) d[0].member = v +#define Q1(d, member, v) \ + d[1].member = v; \ + d[3].member = v +#define Q2(d, member, v) d[4].member = v +#define Q3(d, member, v) \ + d[2].member = v; \ + d[5].member = v + +const int FONT_TEX_X = 1024; +const int FONT_TEX_Y = 9; + +const uint8_t profiler_font[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x78, 0x38, 0x78, + 0x7c, 0x7c, 0x3c, 0x44, 0x38, 0x04, 0x44, 0x40, 0x44, 0x44, 0x38, 0x78, + 0x38, 0x78, 0x38, 0x7c, 0x44, 0x44, 0x44, 0x44, 0x44, 0x7c, 0x00, 0x00, + 0x40, 0x00, 0x04, 0x00, 0x18, 0x00, 0x40, 0x10, 0x08, 0x40, 0x30, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x10, 0x38, 0x7c, 0x08, 0x7c, 0x1c, 0x7c, 0x38, 0x38, + 0x10, 0x28, 0x28, 0x10, 0x00, 0x20, 0x10, 0x08, 0x10, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x20, 0x38, 0x38, 0x70, 0x00, + 0x1c, 0x10, 0x00, 0x1c, 0x10, 0x70, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x44, 0x44, 0x44, 0x40, 0x40, 0x40, 0x44, + 0x10, 0x04, 0x48, 0x40, 0x6c, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x10, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x04, 0x00, 0x00, 0x40, 0x00, 0x04, 0x00, + 0x24, 0x00, 0x40, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x30, + 0x44, 0x04, 0x18, 0x40, 0x20, 0x04, 0x44, 0x44, 0x10, 0x28, 0x28, 0x3c, + 0x44, 0x50, 0x10, 0x10, 0x08, 0x54, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x08, 0x00, 0x10, 0x44, 0x44, 0x40, 0x40, 0x04, 0x28, 0x00, 0x30, + 0x10, 0x18, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x44, 0x44, 0x40, 0x44, 0x40, 0x40, 0x40, 0x44, 0x10, 0x04, 0x50, 0x40, + 0x54, 0x64, 0x44, 0x44, 0x44, 0x44, 0x40, 0x10, 0x44, 0x44, 0x44, 0x28, + 0x28, 0x08, 0x00, 0x38, 0x78, 0x3c, 0x3c, 0x38, 0x20, 0x38, 0x78, 0x30, + 0x18, 0x44, 0x10, 0x6c, 0x78, 0x38, 0x78, 0x3c, 0x5c, 0x3c, 0x3c, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x7c, 0x00, 0x4c, 0x10, 0x04, 0x08, 0x28, 0x78, + 0x40, 0x08, 0x44, 0x44, 0x10, 0x00, 0x7c, 0x50, 0x08, 0x50, 0x00, 0x20, + 0x04, 0x38, 0x10, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x10, 0x7c, 0x08, + 0x08, 0x54, 0x40, 0x20, 0x04, 0x44, 0x00, 0x30, 0x10, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x78, 0x40, 0x44, + 0x78, 0x78, 0x40, 0x7c, 0x10, 0x04, 0x60, 0x40, 0x54, 0x54, 0x44, 0x78, + 0x44, 0x78, 0x38, 0x10, 0x44, 0x44, 0x54, 0x10, 0x10, 0x10, 0x00, 0x04, + 0x44, 0x40, 0x44, 0x44, 0x78, 0x44, 0x44, 0x10, 0x08, 0x48, 0x10, 0x54, + 0x44, 0x44, 0x44, 0x44, 0x60, 0x40, 0x10, 0x44, 0x44, 0x44, 0x28, 0x44, + 0x08, 0x00, 0x54, 0x10, 0x18, 0x18, 0x48, 0x04, 0x78, 0x10, 0x38, 0x3c, + 0x10, 0x00, 0x28, 0x38, 0x10, 0x20, 0x00, 0x20, 0x04, 0x10, 0x7c, 0x00, + 0x7c, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x04, 0x10, 0x5c, 0x40, 0x10, + 0x04, 0x00, 0x00, 0x60, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0x44, 0x40, 0x44, 0x40, 0x40, 0x4c, 0x44, + 0x10, 0x04, 0x50, 0x40, 0x44, 0x4c, 0x44, 0x40, 0x54, 0x50, 0x04, 0x10, + 0x44, 0x44, 0x54, 0x28, 0x10, 0x20, 0x00, 0x3c, 0x44, 0x40, 0x44, 0x7c, + 0x20, 0x44, 0x44, 0x10, 0x08, 0x70, 0x10, 0x54, 0x44, 0x44, 0x44, 0x44, + 0x40, 0x38, 0x10, 0x44, 0x44, 0x54, 0x10, 0x44, 0x10, 0x00, 0x64, 0x10, + 0x20, 0x04, 0x7c, 0x04, 0x44, 0x20, 0x44, 0x04, 0x10, 0x00, 0x7c, 0x14, + 0x20, 0x54, 0x00, 0x20, 0x04, 0x38, 0x10, 0x10, 0x00, 0x00, 0x20, 0x10, + 0x10, 0x10, 0x7c, 0x08, 0x10, 0x58, 0x40, 0x08, 0x04, 0x00, 0x00, 0x30, + 0x10, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x44, 0x44, 0x44, 0x44, 0x40, 0x40, 0x44, 0x44, 0x10, 0x44, 0x48, 0x40, + 0x44, 0x44, 0x44, 0x40, 0x48, 0x48, 0x44, 0x10, 0x44, 0x28, 0x6c, 0x44, + 0x10, 0x40, 0x00, 0x44, 0x44, 0x40, 0x44, 0x40, 0x20, 0x3c, 0x44, 0x10, + 0x08, 0x48, 0x10, 0x54, 0x44, 0x44, 0x44, 0x44, 0x40, 0x04, 0x12, 0x4c, + 0x28, 0x54, 0x28, 0x3c, 0x20, 0x00, 0x44, 0x10, 0x40, 0x44, 0x08, 0x44, + 0x44, 0x20, 0x44, 0x08, 0x00, 0x00, 0x28, 0x78, 0x44, 0x48, 0x00, 0x10, + 0x08, 0x54, 0x10, 0x10, 0x00, 0x00, 0x40, 0x00, 0x10, 0x08, 0x00, 0x10, + 0x00, 0x40, 0x40, 0x04, 0x04, 0x00, 0x00, 0x30, 0x10, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x78, 0x38, 0x78, + 0x7c, 0x40, 0x3c, 0x44, 0x38, 0x38, 0x44, 0x7c, 0x44, 0x44, 0x38, 0x40, + 0x34, 0x44, 0x38, 0x10, 0x38, 0x10, 0x44, 0x44, 0x10, 0x7c, 0x00, 0x3c, + 0x78, 0x3c, 0x3c, 0x3c, 0x20, 0x04, 0x44, 0x38, 0x48, 0x44, 0x38, 0x44, + 0x44, 0x38, 0x78, 0x3c, 0x40, 0x78, 0x0c, 0x34, 0x10, 0x6c, 0x44, 0x04, + 0x7c, 0x00, 0x38, 0x38, 0x7c, 0x38, 0x08, 0x38, 0x38, 0x20, 0x38, 0x70, + 0x10, 0x00, 0x28, 0x10, 0x00, 0x34, 0x00, 0x08, 0x10, 0x10, 0x00, 0x20, + 0x00, 0x10, 0x00, 0x00, 0x20, 0x04, 0x00, 0x20, 0x10, 0x3c, 0x70, 0x00, + 0x1c, 0x00, 0x7c, 0x1c, 0x10, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +GL4ProfilerDisplay::GL4ProfilerDisplay(WGLControl* control) + : control_(control), + program_(0), + vao_(0), + font_texture_(0), + font_handle_(0), + vertex_buffer_(MICROPROFILE_MAX_VERTICES * sizeof(Vertex) * 10, sizeof(Vertex)), + draw_command_count_(0) { + if (!SetupFont() || !SetupState() || !SetupShaders()) { + // Hrm. + assert_always(); + } + + // Pass through mouse events. + control->on_mouse_down.AddListener([](poly::ui::MouseEvent& e) { + Profiler::OnMouseDown(e.button() == poly::ui::MouseEvent::Button::kLeft, + e.button() == poly::ui::MouseEvent::Button::kRight); + e.set_handled(true); + }); + control->on_mouse_up.AddListener([](poly::ui::MouseEvent& e) { + Profiler::OnMouseUp(); + e.set_handled(true); + }); + control->on_mouse_move.AddListener([](poly::ui::MouseEvent& e) { + Profiler::OnMouseMove(e.x(), e.y()); + e.set_handled(true); + }); + control->on_mouse_wheel.AddListener([](poly::ui::MouseEvent& e) { + Profiler::OnMouseWheel(e.x(), e.y(), -e.dy()); + e.set_handled(true); + }); + + // Watch for toggle/mode keys and such. + control->on_key_down.AddListener([](poly::ui::KeyEvent& e) { + Profiler::OnKeyDown(e.key_code()); + e.set_handled(true); + }); + control->on_key_up.AddListener([](poly::ui::KeyEvent& e) { + Profiler::OnKeyUp(e.key_code()); + e.set_handled(true); + }); +} + +bool GL4ProfilerDisplay::SetupFont() { + // Setup font lookup table. + for (uint32_t i = 0; i < poly::countof(font_description_.char_offsets); ++i) { + font_description_.char_offsets[i] = 206; + } + for (uint32_t i = 'A'; i <= 'Z'; ++i) { + font_description_.char_offsets[i] = (i - 'A') * 8 + 1; + } + for (uint32_t i = 'a'; i <= 'z'; ++i) { + font_description_.char_offsets[i] = (i - 'a') * 8 + 217; + } + for (uint32_t i = '0'; i <= '9'; ++i) { + font_description_.char_offsets[i] = (i - '0') * 8 + 433; + } + for (uint32_t i = '!'; i <= '/'; ++i) { + font_description_.char_offsets[i] = (i - '!') * 8 + 513; + } + for (uint32_t i = ':'; i <= '@'; ++i) { + font_description_.char_offsets[i] = (i - ':') * 8 + 625 + 8; + } + for (uint32_t i = '['; i <= '_'; ++i) { + font_description_.char_offsets[i] = (i - '[') * 8 + 681 + 8; + } + for (uint32_t i = '{'; i <= '~'; ++i) { + font_description_.char_offsets[i] = (i - '{') * 8 + 721 + 8; + } + + // Unpack font bitmap into an RGBA texture. + const int UNPACKED_SIZE = FONT_TEX_X * FONT_TEX_Y * 4; + uint32_t unpacked[UNPACKED_SIZE]; + int idx = 0; + int end = FONT_TEX_X * FONT_TEX_Y / 8; + for (int i = 0; i < end; i++) { + uint8_t b = profiler_font[i]; + for (int j = 0; j < 8; ++j) { + unpacked[idx++] = b & 0x80 ? 0xFFFFFFFFu : 0; + b <<= 1; + } + } + + glCreateTextures(GL_TEXTURE_2D, 1, &font_texture_); + glTextureParameteri(font_texture_, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTextureParameteri(font_texture_, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTextureParameteri(font_texture_, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTextureParameteri(font_texture_, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTextureStorage2D(font_texture_, 1, GL_RGBA8, FONT_TEX_X, FONT_TEX_Y); + glTextureSubImage2D(font_texture_, 0, 0, 0, FONT_TEX_X, FONT_TEX_Y, GL_RGBA, + GL_UNSIGNED_BYTE, unpacked); + + font_handle_ = glGetTextureHandleARB(font_texture_); + glMakeTextureHandleResidentARB(font_handle_); + + return true; +} + +bool GL4ProfilerDisplay::SetupState() { + if (!vertex_buffer_.Initialize()) { + return false; + } + return true; +} + +bool GL4ProfilerDisplay::SetupShaders() { + const std::string header = + "\n\ +#version 450 \n\ +#extension GL_ARB_bindless_texture : require\n\ +#extension GL_ARB_explicit_uniform_location : require\n\ +#extension GL_ARB_shading_language_420pack : require\n\ +precision highp float; \n\ +precision highp int;\n\ +layout(std140, column_major) uniform;\n\ +layout(std430, column_major) buffer;\n\ +struct VertexData {\n\ + vec4 color; \n\ + vec2 uv; \n\ +};\n\ +"; + const std::string vertex_shader_source = header + + "\n\ +layout(location = 0) uniform mat4 projection_matrix; \n\ +struct VertexFetch { \n\ + vec2 pos; \n\ + vec4 color; \n\ + vec2 uv; \n\ +}; \n\ +layout(location = 0) in VertexFetch vfetch; \n\ +layout(location = 0) out VertexData vtx; \n\ +void main() { \n\ + gl_Position = projection_matrix * vec4(vfetch.pos.xy, 0.0, 1.0); \n\ + vtx.color = vfetch.color; \n\ + vtx.uv = vfetch.uv; \n\ +} \n\ +"; + const std::string fragment_shader_source = header + + "\n\ +layout(location = 1, bindless_sampler) uniform sampler2D font_texture; \n\ +layout(location = 2) uniform float font_height; \n\ +layout(location = 0) in VertexData vtx; \n\ +layout(location = 0) out vec4 oC; \n\ +void main() { \n\ + if (vtx.uv.x > 1.0) { \n\ + oC = vtx.color; \n\ + } else { \n\ + vec4 color = texture(font_texture, vtx.uv); \n\ + oC = color.rgba * vtx.color; \n\ + if (color.a < 0.5) { \n\ + vec4 c1 = texture(font_texture, vtx.uv + vec2(0.0, font_height)); \n\ + oC = vec4(0, 0, 0, c1.a); \n\ + } \n\ + } \n\ +} \n\ +"; + + GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); + const char* vertex_shader_source_ptr = vertex_shader_source.c_str(); + GLint vertex_shader_source_length = GLint(vertex_shader_source.size()); + glShaderSource(vertex_shader, 1, &vertex_shader_source_ptr, + &vertex_shader_source_length); + glCompileShader(vertex_shader); + + GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); + const char* fragment_shader_source_ptr = fragment_shader_source.c_str(); + GLint fragment_shader_source_length = GLint(fragment_shader_source.size()); + glShaderSource(fragment_shader, 1, &fragment_shader_source_ptr, + &fragment_shader_source_length); + glCompileShader(fragment_shader); + + program_ = glCreateProgram(); + glAttachShader(program_, vertex_shader); + glAttachShader(program_, fragment_shader); + glLinkProgram(program_); + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); + + glProgramUniformHandleui64ARB(program_, 1, font_handle_); + glProgramUniform1f(program_, 2, 1.0f / FONT_TEX_Y); + + glCreateVertexArrays(1, &vao_); + glEnableVertexArrayAttrib(vao_, 0); + glVertexArrayAttribBinding(vao_, 0, 0); + glVertexArrayAttribFormat(vao_, 0, 2, GL_FLOAT, GL_FALSE, + offsetof(Vertex, x)); + glEnableVertexArrayAttrib(vao_, 1); + glVertexArrayAttribBinding(vao_, 1, 0); + glVertexArrayAttribFormat(vao_, 1, 4, GL_UNSIGNED_BYTE, GL_TRUE, + offsetof(Vertex, color)); + glEnableVertexArrayAttrib(vao_, 2); + glVertexArrayAttribBinding(vao_, 2, 0); + glVertexArrayAttribFormat(vao_, 2, 2, GL_FLOAT, GL_FALSE, + offsetof(Vertex, u)); + glVertexArrayVertexBuffer(vao_, 0, vertex_buffer_.handle(), 0, + sizeof(Vertex)); + + return true; +} + +GL4ProfilerDisplay::~GL4ProfilerDisplay() { + vertex_buffer_.Shutdown(); + glMakeTextureHandleNonResidentARB(font_handle_); + glDeleteTextures(1, &font_texture_); + glDeleteVertexArrays(1, &vao_); + glDeleteProgram(program_); +} + +uint32_t GL4ProfilerDisplay::width() const { return control_->width(); } + +uint32_t GL4ProfilerDisplay::height() const { return control_->height(); } + +void GL4ProfilerDisplay::Begin() { + glEnablei(GL_BLEND, 0); + glBlendFunci(0, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_DEPTH_TEST); + + float left = 0.0f; + float right = float(width()); + float bottom = float(height()); + float top = 0.0f; + float z_near = -1.0f; + float z_far = 1.0f; + float projection[16] = {0}; + projection[0] = 2.0f / (right - left); + projection[5] = 2.0f / (top - bottom); + projection[10] = -2.0f / (z_far - z_near); + projection[12] = -(right + left) / (right - left); + projection[13] = -(top + bottom) / (top - bottom); + projection[14] = -(z_far + z_near) / (z_far - z_near); + projection[15] = 1.0f; + glProgramUniformMatrix4fv(program_, 0, 1, GL_FALSE, projection); + + glUseProgram(program_); + glBindVertexArray(vao_); +} + +void GL4ProfilerDisplay::End() { + Flush(); + glUseProgram(0); + glBindVertexArray(0); +} + +GL4ProfilerDisplay::Vertex* GL4ProfilerDisplay::BeginVertices(size_t count) { + if (draw_command_count_ + 1 > kMaxCommands) { + Flush(); + } + current_allocation_ = vertex_buffer_.Acquire(sizeof(Vertex) * count); + return reinterpret_cast(current_allocation_.host_ptr); +} + +void GL4ProfilerDisplay::EndVertices(GLenum prim_type) { + size_t vertex_count = current_allocation_.length / sizeof(Vertex); + + if (false&&draw_command_count_ && + draw_commands_[draw_command_count_ - 1].prim_type == prim_type) { + // Coalesce. + auto& prev_command = draw_commands_[draw_command_count_ - 1]; + prev_command.vertex_count += vertex_count; + } else { + auto& command = draw_commands_[draw_command_count_++]; + command.prim_type = prim_type; + command.vertex_offset = current_allocation_.offset / sizeof(Vertex); + command.vertex_count = vertex_count; + } + + vertex_buffer_.Commit(std::move(current_allocation_)); +} + +void GL4ProfilerDisplay::Flush() { + if (!draw_command_count_) { + return; + } + for (size_t i = 0; i < draw_command_count_; ++i) { + glDrawArrays(draw_commands_[i].prim_type, + GLint(draw_commands_[i].vertex_offset), + GLsizei(draw_commands_[i].vertex_count)); + } + draw_command_count_ = 0; + vertex_buffer_.WaitUntilClean(); +} + +void GL4ProfilerDisplay::DrawBox(int x0, int y0, int x1, int y1, uint32_t color, + BoxType type) { + if (type == BoxType::kFlat) { + color = + ((color & 0xff) << 16) | ((color >> 16) & 0xff) | (0xff00ff00 & color); + auto v = BeginVertices(6); + Q0(v, x, (float)x0); + Q0(v, y, (float)y0); + Q0(v, color, color); + Q0(v, u, 2.0f); + Q0(v, v, 2.0f); + Q1(v, x, (float)x1); + Q1(v, y, (float)y0); + Q1(v, color, color); + Q1(v, u, 2.0f); + Q1(v, v, 2.0f); + Q2(v, x, (float)x1); + Q2(v, y, (float)y1); + Q2(v, color, color); + Q2(v, u, 2.0f); + Q2(v, v, 2.0f); + Q3(v, x, (float)x0); + Q3(v, y, (float)y1); + Q3(v, color, color); + Q3(v, u, 2.0f); + Q3(v, v, 2.0f); + EndVertices(GL_TRIANGLES); + } else { + uint32_t r = 0xff & (color >> 16); + uint32_t g = 0xff & (color >> 8); + uint32_t b = 0xff & color; + uint32_t nMax = std::max(std::max(std::max(r, g), b), 30u); + uint32_t nMin = std::min(std::min(std::min(r, g), b), 180u); + + uint32_t r0 = 0xff & ((r + nMax) / 2); + uint32_t g0 = 0xff & ((g + nMax) / 2); + uint32_t b0 = 0xff & ((b + nMax) / 2); + + uint32_t r1 = 0xff & ((r + nMin) / 2); + uint32_t g1 = 0xff & ((g + nMin) / 2); + uint32_t b1 = 0xff & ((b + nMin) / 2); + uint32_t color0 = (r0 << 0) | (g0 << 8) | (b0 << 16) | (0xff000000 & color); + uint32_t color1 = (r1 << 0) | (g1 << 8) | (b1 << 16) | (0xff000000 & color); + auto v = BeginVertices(6); + Q0(v, x, (float)x0); + Q0(v, y, (float)y0); + Q0(v, color, color0); + Q0(v, u, 2.0f); + Q0(v, v, 2.0f); + Q1(v, x, (float)x1); + Q1(v, y, (float)y0); + Q1(v, color, color0); + Q1(v, u, 3.0f); + Q1(v, v, 2.0f); + Q2(v, x, (float)x1); + Q2(v, y, (float)y1); + Q2(v, color, color1); + Q2(v, u, 3.0f); + Q2(v, v, 3.0f); + Q3(v, x, (float)x0); + Q3(v, y, (float)y1); + Q3(v, color, color1); + Q3(v, u, 2.0f); + Q3(v, v, 3.0f); + EndVertices(GL_TRIANGLES); + } +} + +void GL4ProfilerDisplay::DrawLine2D(uint32_t count, float* vertices, + uint32_t color) { + if (!count || !vertices) { + return; + } + auto v = BeginVertices(2 * (count - 1)); + color = 0xff000000 | ((color & 0xff) << 16) | (color & 0xff00ff00) | + ((color >> 16) & 0xff); + for (uint32_t i = 0; i < count - 1; ++i) { + v[0].x = vertices[i * 2]; + v[0].y = vertices[i * 2 + 1]; + v[0].color = color; + v[0].u = 2.0f; + v[0].v = 2.0f; + v[1].x = vertices[(i + 1) * 2]; + v[1].y = vertices[(i + 1) * 2 + 1]; + v[1].color = color; + v[1].u = 2.0f; + v[1].v = 2.0f; + v += 2; + } + EndVertices(GL_LINES); +} + +void GL4ProfilerDisplay::DrawText(int x, int y, uint32_t color, + const char* text, size_t text_length) { + const float fOffsetU = 5.0f / 1024.0f; + float fX = (float)x; + float fY = (float)y; + float fY2 = fY + (MICROPROFILE_TEXT_HEIGHT + 1); + + auto v = BeginVertices(6 * text_length); + const char* pStr = text; + color = 0xff000000 | ((color & 0xff) << 16) | (color & 0xff00) | + ((color >> 16) & 0xff); + + for (size_t j = 0; j < text_length; ++j) { + int16_t char_offset = font_description_.char_offsets[(int)*pStr++]; + float fOffset = char_offset / 1024.0f; + Q0(v, x, fX); + Q0(v, y, fY); + Q0(v, color, color); + Q0(v, u, fOffset); + Q0(v, v, 0.0f); + + Q1(v, x, fX + MICROPROFILE_TEXT_WIDTH); + Q1(v, y, fY); + Q1(v, color, color); + Q1(v, u, fOffset + fOffsetU); + Q1(v, v, 0.0f); + + Q2(v, x, fX + MICROPROFILE_TEXT_WIDTH); + Q2(v, y, fY2); + Q2(v, color, color); + Q2(v, u, fOffset + fOffsetU); + Q2(v, v, 1.0f); + + Q3(v, x, fX); + Q3(v, y, fY2); + Q3(v, color, color); + Q3(v, u, fOffset); + Q3(v, v, 1.0f); + + fX += MICROPROFILE_TEXT_WIDTH + 1; + v += 6; + } + + EndVertices(GL_TRIANGLES); +} + +} // namespace gl4 +} // namespace gpu +} // namespace xe diff --git a/src/xenia/gpu/gl4/gl4_profiler_display.h b/src/xenia/gpu/gl4/gl4_profiler_display.h new file mode 100644 index 000000000..d5290d62f --- /dev/null +++ b/src/xenia/gpu/gl4/gl4_profiler_display.h @@ -0,0 +1,84 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_GPU_GL4_GL4_PROFILER_DISPLAY_H_ +#define XENIA_GPU_GL4_GL4_PROFILER_DISPLAY_H_ + +#include +#include +#include +#include +#include + +namespace xe { +namespace gpu { +namespace gl4 { + +class GL4ProfilerDisplay : public ProfilerDisplay { + public: + GL4ProfilerDisplay(WGLControl* control); + virtual ~GL4ProfilerDisplay(); + + uint32_t width() const override; + uint32_t height() const override; + + // TODO(benvanik): GPU timestamping. + + void Begin() override; + void End() override; + void DrawBox(int x0, int y0, int x1, int y1, uint32_t color, + BoxType type) override; + void DrawLine2D(uint32_t count, float* vertices, uint32_t color) override; + void DrawText(int x, int y, uint32_t color, const char* text, + size_t text_length) override; + + private: + struct Vertex { + float x; + float y; + uint32_t color; + float u; + float v; + }; + + bool SetupFont(); + bool SetupState(); + bool SetupShaders(); + + Vertex* BeginVertices(size_t count); + void EndVertices(GLenum prim_type); + void Flush(); + + WGLControl* control_; + GLuint program_; + GLuint vao_; + GLuint font_texture_; + GLuint64 font_handle_; + CircularBuffer vertex_buffer_; + + static const size_t kMaxCommands = 32; + struct { + GLenum prim_type; + size_t vertex_offset; + size_t vertex_count; + } draw_commands_[kMaxCommands]; + uint32_t draw_command_count_; + + CircularBuffer::Allocation current_allocation_; + + struct { + uint16_t char_offsets[256]; + } font_description_; +}; + +} // namespace gl4 +} // namespace gpu +} // namespace xe + +#endif // XENIA_GPU_GL4_GL4_PROFILER_DISPLAY_H_ diff --git a/src/xenia/gpu/gl4/gl_context.cc b/src/xenia/gpu/gl4/gl_context.cc index 76824f4d1..d5e39fa34 100644 --- a/src/xenia/gpu/gl4/gl_context.cc +++ b/src/xenia/gpu/gl4/gl_context.cc @@ -289,8 +289,8 @@ void GLContext::SetupDebugging() { // intended to be used as an offset into a buffer object? }; glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_OTHER, GL_DONT_CARE, - poly::countof(disable_message_ids), disable_message_ids, - GL_FALSE); + GLsizei(poly::countof(disable_message_ids)), + disable_message_ids, GL_FALSE); // Callback will be made from driver threads. glDebugMessageCallback(reinterpret_cast(&DebugMessageThunk), @@ -298,6 +298,7 @@ void GLContext::SetupDebugging() { } bool GLContext::MakeCurrent() { + SCOPE_profile_cpu_f("gpu"); if (FLAGS_thread_safe_gl) { global_gl_mutex_.lock(); } diff --git a/src/xenia/gpu/gl4/sources.gypi b/src/xenia/gpu/gl4/sources.gypi index bdeeae80a..efc52f2b6 100644 --- a/src/xenia/gpu/gl4/sources.gypi +++ b/src/xenia/gpu/gl4/sources.gypi @@ -10,6 +10,8 @@ 'gl4_gpu.h', 'gl4_graphics_system.cc', 'gl4_graphics_system.h', + 'gl4_profiler_display.cc', + 'gl4_profiler_display.h', 'gl4_shader.cc', 'gl4_shader.h', 'gl4_shader_translator.cc', diff --git a/src/xenia/gpu/gl4/wgl_control.cc b/src/xenia/gpu/gl4/wgl_control.cc index dacc22890..ce02f7b2f 100644 --- a/src/xenia/gpu/gl4/wgl_control.cc +++ b/src/xenia/gpu/gl4/wgl_control.cc @@ -48,7 +48,7 @@ bool WGLControl::Create() { } // Create window. - DWORD window_style = WS_CHILD | WS_VISIBLE; + DWORD window_style = WS_CHILD | WS_VISIBLE | SS_NOTIFY; DWORD window_ex_style = 0; hwnd_ = CreateWindowEx(window_ex_style, L"XeniaWglClass", L"Xenia", window_style, @@ -64,6 +64,8 @@ bool WGLControl::Create() { return false; } + SetFocus(hwnd_); + OnCreate(); return true; } @@ -74,6 +76,7 @@ LRESULT WGLControl::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_PAINT: { + SCOPE_profile_cpu_i("gpu", "xe::gpu::gl4::WGLControl::WM_PAINT"); { GLContextLock context_lock(&context_); wglSwapIntervalEXT(0); @@ -100,7 +103,10 @@ LRESULT WGLControl::WndProc(HWND hWnd, UINT message, WPARAM wParam, glClearNamedFramebufferfv(0, GL_COLOR, 0, red); glDisable(GL_SCISSOR_TEST); } - SwapBuffers(context_.dc()); + { + SCOPE_profile_cpu_i("gpu", "xe::gpu::gl4::WGLControl::SwapBuffers"); + SwapBuffers(context_.dc()); + } } break; } return Win32Control::WndProc(hWnd, message, wParam, lParam); diff --git a/src/xenia/profiling.cc b/src/xenia/profiling.cc index a8a47dcec..2267980cc 100644 --- a/src/xenia/profiling.cc +++ b/src/xenia/profiling.cc @@ -7,17 +7,21 @@ ****************************************************************************** */ -#define MICROPROFILE_IMPL +#include + +#define MICROPROFILE_ENABLED 1 +#define MICROPROFILEUI_ENABLED 1 +#define MICROPROFILE_IMPL 1 +#define MICROPROFILEUI_IMPL 1 #define MICROPROFILE_USE_THREAD_NAME_CALLBACK 1 #define MICROPROFILE_PRINTF PLOGI +#define MICROPROFILE_WEBSERVER 0 +#define MICROPROFILE_DEBUG 0 #include +#include #include -#if XE_OPTION_PROFILING_UI -#include -#endif // XE_OPTION_PROFILING_UI - namespace xe { std::unique_ptr Profiler::display_ = nullptr; @@ -25,16 +29,38 @@ std::unique_ptr Profiler::display_ = nullptr; #if XE_OPTION_PROFILING void Profiler::Initialize() { - MicroProfileSetForceEnable(true); - MicroProfileSetEnableAllGroups(true); - MicroProfileSetForceMetaCounters(true); + // Custom groups. + MicroProfileSetEnableAllGroups(false); + MicroProfileForceEnableGroup("alloy", MicroProfileTokenTypeCpu); + MicroProfileForceEnableGroup("apu", MicroProfileTokenTypeCpu); + MicroProfileForceEnableGroup("cpu", MicroProfileTokenTypeCpu); + MicroProfileForceEnableGroup("gpu", MicroProfileTokenTypeCpu); + MicroProfileForceEnableGroup("internal", MicroProfileTokenTypeCpu); + g_MicroProfile.nGroupMask = g_MicroProfile.nForceGroup; + g_MicroProfile.nActiveGroup = g_MicroProfile.nActiveGroupWanted = + g_MicroProfile.nGroupMask; + + // Custom timers: time, average. + g_MicroProfile.nBars |= 0x1 | 0x2; + g_MicroProfile.nActiveBars |= 0x1 | 0x2; + #if XE_OPTION_PROFILING_UI MicroProfileInitUI(); + g_MicroProfileUI.bShowSpikes = true; + g_MicroProfileUI.nOpacityBackground = 0x40 << 24; + g_MicroProfileUI.nOpacityForeground = 0xc0 << 24; MicroProfileSetDisplayMode(1); +#else + MicroProfileSetForceEnable(true); + MicroProfileSetEnableAllGroups(true); + MicroProfileSetForceMetaCounters(false); #endif // XE_OPTION_PROFILING_UI } void Profiler::Dump() { +#if XE_OPTION_PROFILING_UI + MicroProfileDumpTimers(); +#endif // XE_OPTION_PROFILING_UI MicroProfileDumpHtml("profile.html"); MicroProfileDumpHtmlToFile(); } @@ -116,29 +142,14 @@ void Profiler::set_display(std::unique_ptr display) { } void Profiler::Present() { + SCOPE_profile_cpu_f("internal"); MicroProfileFlip(); #if XE_OPTION_PROFILING_UI if (!display_) { return; } - float left = 0.f; - float right = display_->width(); - float bottom = display_->height(); - float top = 0.f; - float near = -1.f; - float far = 1.f; - float projection[16] = {0}; - projection[0] = 2.0f / (right - left); - projection[5] = 2.0f / (top - bottom); - projection[10] = -2.0f / (far - near); - projection[12] = -(right + left) / (right - left); - projection[13] = -(top + bottom) / (top - bottom); - projection[14] = -(far + near) / (far - near); - projection[15] = 1.f; display_->Begin(); - MicroProfileBeginDraw(display_->width(), display_->height(), projection); MicroProfileDraw(display_->width(), display_->height()); - MicroProfileEndDraw(); display_->End(); #endif // XE_OPTION_PROFILING_UI } diff --git a/src/xenia/profiling.h b/src/xenia/profiling.h index 4c18b4bac..2428c78d3 100644 --- a/src/xenia/profiling.h +++ b/src/xenia/profiling.h @@ -16,7 +16,7 @@ #define XE_OPTION_PROFILING 1 #if XE_LIKE_WIN32 -//#define XE_OPTION_PROFILING_UI 1 +#define XE_OPTION_PROFILING_UI 1 #endif // XE_LIKE_WIN32 #if XE_OPTION_PROFILING @@ -122,13 +122,13 @@ namespace xe { class ProfilerDisplay { public: - enum BoxType { + enum class BoxType { #if XE_OPTION_PROFILING - BOX_TYPE_BAR = MicroProfileBoxTypeBar, - BOX_TYPE_FLAT = MicroProfileBoxTypeFlat, + kBar = MicroProfileBoxTypeBar, + kFlat = MicroProfileBoxTypeFlat, #else - BOX_TYPE_BAR, - BOX_TYPE_FLAT, + kBar, + kFlat, #endif // XE_OPTION_PROFILING }; @@ -139,7 +139,7 @@ class ProfilerDisplay { virtual void Begin() = 0; virtual void End() = 0; - virtual void DrawBox(int x, int y, int x1, int y1, uint32_t color, + virtual void DrawBox(int x0, int y0, int x1, int y1, uint32_t color, BoxType type) = 0; virtual void DrawLine2D(uint32_t count, float* vertices, uint32_t color) = 0; virtual void DrawText(int x, int y, uint32_t color, const char* text, diff --git a/third_party/microprofile/microprofileui.h b/third_party/microprofile/microprofileui.h index bce3904dd..b84bf8c9c 100644 --- a/third_party/microprofile/microprofileui.h +++ b/third_party/microprofile/microprofileui.h @@ -592,7 +592,7 @@ void MicroProfileCenter(int64_t nTickCenter) float fCenter = MicroProfileLogTickDifference(nStart, nTickCenter) * fToMs; UI.fDetailedOffsetTarget = UI.fDetailedOffset = fCenter - 0.5f * UI.fDetailedRange; } -#ifdef MICROPROFILE_DEBUG +#if MICROPROFILE_DEBUG uint64_t* g_pMicroProfileDumpStart = 0; uint64_t* g_pMicroProfileDumpEnd = 0; void MicroProfileDebugDumpRange() From bb15d2f62ff6d5a9468f1a85d9640d9758263e94 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 2 Jan 2015 17:44:15 -0800 Subject: [PATCH 308/388] Faster profiler drawing. --- src/xenia/gpu/gl4/gl4_profiler_display.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/xenia/gpu/gl4/gl4_profiler_display.cc b/src/xenia/gpu/gl4/gl4_profiler_display.cc index 21929ab48..37d4b1f67 100644 --- a/src/xenia/gpu/gl4/gl4_profiler_display.cc +++ b/src/xenia/gpu/gl4/gl4_profiler_display.cc @@ -389,7 +389,7 @@ GL4ProfilerDisplay::Vertex* GL4ProfilerDisplay::BeginVertices(size_t count) { void GL4ProfilerDisplay::EndVertices(GLenum prim_type) { size_t vertex_count = current_allocation_.length / sizeof(Vertex); - if (false&&draw_command_count_ && + if (draw_command_count_ && draw_commands_[draw_command_count_ - 1].prim_type == prim_type) { // Coalesce. auto& prev_command = draw_commands_[draw_command_count_ - 1]; @@ -419,10 +419,10 @@ void GL4ProfilerDisplay::Flush() { void GL4ProfilerDisplay::DrawBox(int x0, int y0, int x1, int y1, uint32_t color, BoxType type) { + auto v = BeginVertices(6); if (type == BoxType::kFlat) { color = ((color & 0xff) << 16) | ((color >> 16) & 0xff) | (0xff00ff00 & color); - auto v = BeginVertices(6); Q0(v, x, (float)x0); Q0(v, y, (float)y0); Q0(v, color, color); @@ -443,7 +443,6 @@ void GL4ProfilerDisplay::DrawBox(int x0, int y0, int x1, int y1, uint32_t color, Q3(v, color, color); Q3(v, u, 2.0f); Q3(v, v, 2.0f); - EndVertices(GL_TRIANGLES); } else { uint32_t r = 0xff & (color >> 16); uint32_t g = 0xff & (color >> 8); @@ -460,7 +459,6 @@ void GL4ProfilerDisplay::DrawBox(int x0, int y0, int x1, int y1, uint32_t color, uint32_t b1 = 0xff & ((b + nMin) / 2); uint32_t color0 = (r0 << 0) | (g0 << 8) | (b0 << 16) | (0xff000000 & color); uint32_t color1 = (r1 << 0) | (g1 << 8) | (b1 << 16) | (0xff000000 & color); - auto v = BeginVertices(6); Q0(v, x, (float)x0); Q0(v, y, (float)y0); Q0(v, color, color0); @@ -481,8 +479,8 @@ void GL4ProfilerDisplay::DrawBox(int x0, int y0, int x1, int y1, uint32_t color, Q3(v, color, color1); Q3(v, u, 2.0f); Q3(v, v, 3.0f); - EndVertices(GL_TRIANGLES); } + EndVertices(GL_TRIANGLES); } void GL4ProfilerDisplay::DrawLine2D(uint32_t count, float* vertices, @@ -511,6 +509,10 @@ void GL4ProfilerDisplay::DrawLine2D(uint32_t count, float* vertices, void GL4ProfilerDisplay::DrawText(int x, int y, uint32_t color, const char* text, size_t text_length) { + if (!text_length) { + return; + } + const float fOffsetU = 5.0f / 1024.0f; float fX = (float)x; float fY = (float)y; From 5236477043feaeeb61c4f5a23d7db7b2b83452f2 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 2 Jan 2015 18:01:48 -0800 Subject: [PATCH 309/388] Batch flushing buffer. --- src/xenia/gpu/gl4/circular_buffer.cc | 27 +++++++++++++++++++---- src/xenia/gpu/gl4/circular_buffer.h | 5 +++++ src/xenia/gpu/gl4/command_processor.cc | 1 + src/xenia/gpu/gl4/gl4_profiler_display.cc | 8 ++++++- 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/xenia/gpu/gl4/circular_buffer.cc b/src/xenia/gpu/gl4/circular_buffer.cc index 92ce0e643..537cd5604 100644 --- a/src/xenia/gpu/gl4/circular_buffer.cc +++ b/src/xenia/gpu/gl4/circular_buffer.cc @@ -24,6 +24,8 @@ CircularBuffer::CircularBuffer(size_t capacity, size_t alignment) : capacity_(capacity), alignment_(alignment), write_head_(0), + dirty_start_(UINT64_MAX), + dirty_end_(0), buffer_(0), gpu_base_(0), host_base_(nullptr) {} @@ -63,12 +65,15 @@ void CircularBuffer::Shutdown() { buffer_ = 0; } +bool CircularBuffer::CanAcquire(size_t length) { + size_t aligned_length = poly::round_up(length, alignment_); + return write_head_ + aligned_length <= capacity_; +} + CircularBuffer::Allocation CircularBuffer::Acquire(size_t length) { // Addresses must always be % 256. size_t aligned_length = poly::round_up(length, alignment_); - assert_true(aligned_length <= capacity_, "Request too large"); - if (write_head_ + aligned_length > capacity_) { // Flush and wait. WaitUntilClean(); @@ -79,16 +84,30 @@ CircularBuffer::Allocation CircularBuffer::Acquire(size_t length) { allocation.gpu_ptr = gpu_base_ + write_head_; allocation.offset = write_head_; allocation.length = length; + allocation.aligned_length = aligned_length; write_head_ += aligned_length; return allocation; } void CircularBuffer::Commit(Allocation allocation) { - glFlushMappedNamedBufferRange(buffer_, allocation.gpu_ptr - gpu_base_, - allocation.length); + uintptr_t start = allocation.gpu_ptr - gpu_base_; + uintptr_t end = start + allocation.aligned_length; + dirty_start_ = std::min(dirty_start_, start); + dirty_end_ = std::max(dirty_end_, end); +} + +void CircularBuffer::Flush() { + if (dirty_start_ == dirty_end_ || dirty_start_ == UINT64_MAX) { + return; + } + glFlushMappedNamedBufferRange(buffer_, dirty_start_, + dirty_end_ - dirty_start_); + dirty_start_ = UINT64_MAX; + dirty_end_ = 0; } void CircularBuffer::WaitUntilClean() { + Flush(); glFinish(); write_head_ = 0; } diff --git a/src/xenia/gpu/gl4/circular_buffer.h b/src/xenia/gpu/gl4/circular_buffer.h index 777f60274..2db1d639c 100644 --- a/src/xenia/gpu/gl4/circular_buffer.h +++ b/src/xenia/gpu/gl4/circular_buffer.h @@ -28,6 +28,7 @@ class CircularBuffer { GLuint64 gpu_ptr; size_t offset; size_t length; + size_t aligned_length; }; bool Initialize(); @@ -35,8 +36,10 @@ class CircularBuffer { GLuint handle() const { return buffer_; } + bool CanAcquire(size_t length); Allocation Acquire(size_t length); void Commit(Allocation allocation); + void Flush(); void WaitUntilClean(); @@ -44,6 +47,8 @@ class CircularBuffer { size_t capacity_; size_t alignment_; uintptr_t write_head_; + uintptr_t dirty_start_; + uintptr_t dirty_end_; GLuint buffer_; GLuint64 gpu_base_; uint8_t* host_base_; diff --git a/src/xenia/gpu/gl4/command_processor.cc b/src/xenia/gpu/gl4/command_processor.cc index 64029c914..50b562051 100644 --- a/src/xenia/gpu/gl4/command_processor.cc +++ b/src/xenia/gpu/gl4/command_processor.cc @@ -1428,6 +1428,7 @@ bool CommandProcessor::IssueDraw(DrawCommand* draw_command) { glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, scratch_buffer_.handle(), allocation.offset, allocation.length); scratch_buffer_.Commit(std::move(allocation)); + scratch_buffer_.Flush(); if (cmd.index_buffer.address) { // Indexed draw. diff --git a/src/xenia/gpu/gl4/gl4_profiler_display.cc b/src/xenia/gpu/gl4/gl4_profiler_display.cc index 37d4b1f67..f60723cce 100644 --- a/src/xenia/gpu/gl4/gl4_profiler_display.cc +++ b/src/xenia/gpu/gl4/gl4_profiler_display.cc @@ -382,7 +382,11 @@ GL4ProfilerDisplay::Vertex* GL4ProfilerDisplay::BeginVertices(size_t count) { if (draw_command_count_ + 1 > kMaxCommands) { Flush(); } - current_allocation_ = vertex_buffer_.Acquire(sizeof(Vertex) * count); + size_t total_length = sizeof(Vertex) * count; + if (!vertex_buffer_.CanAcquire(total_length)) { + Flush(); + } + current_allocation_ = vertex_buffer_.Acquire(total_length); return reinterpret_cast(current_allocation_.host_ptr); } @@ -408,12 +412,14 @@ void GL4ProfilerDisplay::Flush() { if (!draw_command_count_) { return; } + vertex_buffer_.Flush(); for (size_t i = 0; i < draw_command_count_; ++i) { glDrawArrays(draw_commands_[i].prim_type, GLint(draw_commands_[i].vertex_offset), GLsizei(draw_commands_[i].vertex_count)); } draw_command_count_ = 0; + // TODO(benvanik): don't finish here. vertex_buffer_.WaitUntilClean(); } From 79179c28ef7758099cfccf5acce33d3eae3ffe1c Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 2 Jan 2015 18:21:39 -0800 Subject: [PATCH 310/388] Experimenting with index ranges. Look unused by d3d :( --- src/xenia/gpu/gl4/command_processor.cc | 9 ++++++++- src/xenia/gpu/gl4/command_processor.h | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/xenia/gpu/gl4/command_processor.cc b/src/xenia/gpu/gl4/command_processor.cc index 50b562051..d22c9527b 100644 --- a/src/xenia/gpu/gl4/command_processor.cc +++ b/src/xenia/gpu/gl4/command_processor.cc @@ -1311,8 +1311,15 @@ void CommandProcessor::PrepareDraw(DrawCommand* draw_command) { cmd.index_count = 0; cmd.index_buffer.address = nullptr; - // Generic stuff. + // Starting index when drawing indexed. cmd.start_index = regs[XE_GPU_REG_VGT_INDX_OFFSET].u32; + + // Min/max index ranges. This is often [0,FFFF|FFFFFF], but if it's not we + // can use it to do a glDrawRangeElements. + cmd.min_index = regs[XE_GPU_REG_VGT_MIN_VTX_INDX].u32; + cmd.max_index = regs[XE_GPU_REG_VGT_MAX_VTX_INDX].u32; + + // ? cmd.base_vertex = 0; cmd.state_data = nullptr; diff --git a/src/xenia/gpu/gl4/command_processor.h b/src/xenia/gpu/gl4/command_processor.h index 0d5a39c64..5a98fefaf 100644 --- a/src/xenia/gpu/gl4/command_processor.h +++ b/src/xenia/gpu/gl4/command_processor.h @@ -79,6 +79,8 @@ static_assert(sizeof(UniformDataBlock) <= 16 * 1024, struct DrawCommand { PrimitiveType prim_type; uint32_t start_index; + uint32_t min_index; + uint32_t max_index; uint32_t index_count; uint32_t base_vertex; From 718762746ae03ba976a3b1c5dbc8a321870d5cf9 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 3 Jan 2015 01:05:56 -0800 Subject: [PATCH 311/388] A texture cache that never invalidates. --- src/poly/ui/win32/win32_control.cc | 2 + src/xenia/gpu/gl4/command_processor.cc | 13 +- src/xenia/gpu/gl4/texture_cache.cc | 355 +++++++++++++++++-------- src/xenia/gpu/gl4/texture_cache.h | 46 ++-- src/xenia/gpu/sampler_info.cc | 8 + src/xenia/gpu/sampler_info.h | 1 + src/xenia/gpu/texture_info.cc | 11 +- src/xenia/gpu/texture_info.h | 8 +- 8 files changed, 303 insertions(+), 141 deletions(-) diff --git a/src/poly/ui/win32/win32_control.cc b/src/poly/ui/win32/win32_control.cc index cc75558fc..d26716a2d 100644 --- a/src/poly/ui/win32/win32_control.cc +++ b/src/poly/ui/win32/win32_control.cc @@ -198,12 +198,14 @@ LRESULT Win32Control::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { if (message >= WM_MOUSEFIRST && message <= WM_MOUSELAST) { if (HandleMouse(message, wParam, lParam)) { + SetFocus(hwnd_); return 0; } else { return DefWindowProc(hWnd, message, wParam, lParam); } } else if (message >= WM_KEYFIRST && message <= WM_KEYLAST) { if (HandleKeyboard(message, wParam, lParam)) { + SetFocus(hwnd_); return 0; } else { return DefWindowProc(hWnd, message, wParam, lParam); diff --git a/src/xenia/gpu/gl4/command_processor.cc b/src/xenia/gpu/gl4/command_processor.cc index d22c9527b..6c21affdc 100644 --- a/src/xenia/gpu/gl4/command_processor.cc +++ b/src/xenia/gpu/gl4/command_processor.cc @@ -169,7 +169,7 @@ bool CommandProcessor::SetupGL() { } // Texture cache that keeps track of any textures/samplers used. - if (!texture_cache_.Initialize(&scratch_buffer_)) { + if (!texture_cache_.Initialize(membase_, &scratch_buffer_)) { PLOGE("Unable to initialize texture cache"); return false; } @@ -843,6 +843,9 @@ bool CommandProcessor::ExecutePacketType3_XE_SWAP(RingbufferReader* reader, PrepareForWait(); swap_handler_(swap_params); ReturnFromWait(); + + // Remove any dead textures, etc. + texture_cache_.Scavenge(); } return true; } @@ -1340,9 +1343,6 @@ bool CommandProcessor::IssueDraw(DrawCommand* draw_command) { return IssueCopy(draw_command); } - // TODO(benvanik): actually cache things >_> - texture_cache_.Clear(); - // Allocate a state data block. // Everything the shaders access lives here. auto allocation = scratch_buffer_.Acquire(sizeof(UniformDataBlock)); @@ -2199,10 +2199,7 @@ bool CommandProcessor::PopulateSampler(DrawCommand* draw_command, return true; // invalid texture used } - uint32_t guest_base = fetch.address << 12; - void* host_base = membase_ + guest_base; - auto entry_view = texture_cache_.Demand(host_base, texture_info.input_length, - texture_info, sampler_info); + auto entry_view = texture_cache_.Demand(texture_info, sampler_info); if (!entry_view) { // Unable to create/fetch/etc. XELOGE("Failed to demand texture"); diff --git a/src/xenia/gpu/gl4/texture_cache.cc b/src/xenia/gpu/gl4/texture_cache.cc index e42f5b7fb..f6ed565da 100644 --- a/src/xenia/gpu/gl4/texture_cache.cc +++ b/src/xenia/gpu/gl4/texture_cache.cc @@ -22,138 +22,139 @@ using namespace xe::gpu::xenos; extern "C" GLEWContext* glewGetContext(); extern "C" WGLEWContext* wglewGetContext(); -TextureCache::TextureCache() { - // +TextureCache::TextureCache() : membase_(nullptr), scratch_buffer_(nullptr) { + invalidated_textures_sets_[0].reserve(64); + invalidated_textures_sets_[1].reserve(64); + invalidated_textures_ = &invalidated_textures_sets_[0]; } TextureCache::~TextureCache() { Shutdown(); } -bool TextureCache::Initialize(CircularBuffer* scratch_buffer) { +bool TextureCache::Initialize(uint8_t* membase, + CircularBuffer* scratch_buffer) { + membase_ = membase; scratch_buffer_ = scratch_buffer; return true; } -void TextureCache::Shutdown() { - Clear(); - // +void TextureCache::Shutdown() { Clear(); } + +void TextureCache::Scavenge() { + invalidated_textures_mutex_.lock(); + std::vector& invalidated_textures = *invalidated_textures_; + if (invalidated_textures_ == &invalidated_textures_sets_[0]) { + invalidated_textures_ = &invalidated_textures_sets_[1]; + } else { + invalidated_textures_ = &invalidated_textures_sets_[0]; + } + invalidated_textures_mutex_.unlock(); + if (invalidated_textures.empty()) { + return; + } + + for (auto& entry : invalidated_textures) { + EvictTexture(entry); + } + invalidated_textures.clear(); } void TextureCache::Clear() { - for (auto& entry : entries_) { - for (auto& view : entry.views) { - glMakeTextureHandleNonResidentARB(view.texture_sampler_handle); - glDeleteSamplers(1, &view.sampler); - } - glDeleteTextures(1, &entry.base_texture); + // Kill all textures - some may be in the eviction list, but that's fine + // as we will clear that below. + while (texture_entries_.size()) { + auto entry = texture_entries_.begin()->second; + EvictTexture(entry); + } + + // Samplers must go last, as textures depend on them. + while (sampler_entries_.size()) { + auto entry = sampler_entries_.begin()->second; + EvictSampler(entry); + } + + { + std::lock_guard lock(invalidated_textures_mutex_); + invalidated_textures_sets_[0].clear(); + invalidated_textures_sets_[1].clear(); } - entries_.clear(); } -TextureCache::EntryView* TextureCache::Demand(void* host_base, size_t length, - const TextureInfo& texture_info, - const SamplerInfo& sampler_info) { - entries_.emplace_back(Entry()); - auto& entry = entries_.back(); - entry.texture_info = texture_info; +//typedef void (*WriteWatchCallback)(void* context, void* data, void* address); +//uintptr_t AddWriteWatch(void* address, size_t length, +// WriteWatchCallback callback, void* callback_context, +// void* callback_data) { +// // +//} - GLenum target; - switch (texture_info.dimension) { - case Dimension::k1D: - target = GL_TEXTURE_1D; - break; - case Dimension::k2D: - target = GL_TEXTURE_2D; - break; - case Dimension::k3D: - target = GL_TEXTURE_3D; - break; - case Dimension::kCube: - target = GL_TEXTURE_CUBE_MAP; - break; +TextureCache::TextureEntryView* TextureCache::Demand( + const TextureInfo& texture_info, const SamplerInfo& sampler_info) { + uint64_t texture_hash = texture_info.hash(); + auto texture_entry = LookupOrInsertTexture(texture_info, texture_hash); + if (!texture_entry) { + PLOGE("Failed to setup texture"); + return nullptr; } - // Setup the base texture. - glCreateTextures(target, 1, &entry.base_texture); - if (!SetupTexture(entry.base_texture, texture_info)) { - PLOGE("Unable to setup texture parameters"); - return false; + // We likely have the sampler in the texture view listing, so scan for it. + uint64_t sampler_hash = sampler_info.hash(); + for (auto& it : texture_entry->views) { + if (it->sampler_hash == sampler_hash) { + // Found. + return it.get(); + } } - // Upload/convert. - bool uploaded = false; - switch (texture_info.dimension) { - case Dimension::k2D: - uploaded = UploadTexture2D(entry.base_texture, host_base, length, - texture_info, sampler_info); - break; - case Dimension::k1D: - case Dimension::k3D: - case Dimension::kCube: - assert_unhandled_case(texture_info.dimension); - return false; - } - if (!uploaded) { - PLOGE("Failed to convert/upload texture"); - return false; + // No existing view found - build it. + auto sampler_entry = LookupOrInsertSampler(sampler_info, sampler_hash); + if (!sampler_entry) { + PLOGE("Failed to setup texture sampler"); + return nullptr; } - entry.views.emplace_back(EntryView()); - auto& entry_view = entry.views.back(); - entry_view.sampler_info = sampler_info; - - // Setup the sampler. - glCreateSamplers(1, &entry_view.sampler); - if (!SetupSampler(entry_view.sampler, texture_info, sampler_info)) { - PLOGE("Unable to setup texture sampler parameters"); - return false; - } + auto view = std::make_unique(); + view->sampler = sampler_entry; + view->sampler_hash = sampler_hash; + view->texture_sampler_handle = 0; // Get the uvec2 handle to the texture/sampler pair and make it resident. // The handle can be passed directly to the shader. - entry_view.texture_sampler_handle = - glGetTextureSamplerHandleARB(entry.base_texture, entry_view.sampler); - if (!entry_view.texture_sampler_handle) { + view->texture_sampler_handle = glGetTextureSamplerHandleARB( + texture_entry->handle, sampler_entry->handle); + if (!view->texture_sampler_handle) { return nullptr; } - glMakeTextureHandleResidentARB(entry_view.texture_sampler_handle); + glMakeTextureHandleResidentARB(view->texture_sampler_handle); - return &entry_view; + // Entry takes ownership. + auto view_ptr = view.get(); + texture_entry->views.push_back(std::move(view)); + return view_ptr; } -bool TextureCache::SetupTexture(GLuint texture, - const TextureInfo& texture_info) { - // TODO(benvanik): texture mip levels. - glTextureParameteri(texture, GL_TEXTURE_BASE_LEVEL, 0); - glTextureParameteri(texture, GL_TEXTURE_MAX_LEVEL, 1); +TextureCache::SamplerEntry* TextureCache::LookupOrInsertSampler( + const SamplerInfo& sampler_info, uint64_t opt_hash) { + const uint64_t hash = opt_hash ? opt_hash : sampler_info.hash(); + for (auto it = sampler_entries_.find(hash); it != sampler_entries_.end(); + ++it) { + if (it->second->sampler_info == sampler_info) { + // Found in cache! + return it->second; + } + } - // Pre-shader swizzle. - // TODO(benvanik): can this be dynamic? Maybe per view? - // We may have to emulate this in the shader. - uint32_t swizzle_r = texture_info.swizzle & 0x7; - uint32_t swizzle_g = (texture_info.swizzle >> 3) & 0x7; - uint32_t swizzle_b = (texture_info.swizzle >> 6) & 0x7; - uint32_t swizzle_a = (texture_info.swizzle >> 9) & 0x7; - static const GLenum swizzle_map[] = { - GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_ZERO, GL_ONE, - }; - glTextureParameteri(texture, GL_TEXTURE_SWIZZLE_R, swizzle_map[swizzle_r]); - glTextureParameteri(texture, GL_TEXTURE_SWIZZLE_G, swizzle_map[swizzle_g]); - glTextureParameteri(texture, GL_TEXTURE_SWIZZLE_B, swizzle_map[swizzle_b]); - glTextureParameteri(texture, GL_TEXTURE_SWIZZLE_A, swizzle_map[swizzle_a]); + // Not found, create. + auto entry = std::make_unique(); + entry->sampler_info = sampler_info; + glCreateSamplers(1, &entry->handle); - return true; -} - -bool TextureCache::SetupSampler(GLuint sampler, const TextureInfo& texture_info, - const SamplerInfo& sampler_info) { // TODO(benvanik): border color from texture fetch. GLfloat border_color[4] = {0.0f}; - glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, border_color); + glSamplerParameterfv(entry->handle, GL_TEXTURE_BORDER_COLOR, border_color); // TODO(benvanik): setup LODs for mipmapping. - glSamplerParameterf(sampler, GL_TEXTURE_LOD_BIAS, 0.0f); - glSamplerParameterf(sampler, GL_TEXTURE_MIN_LOD, 0.0f); - glSamplerParameterf(sampler, GL_TEXTURE_MAX_LOD, 0.0f); + glSamplerParameterf(entry->handle, GL_TEXTURE_LOD_BIAS, 0.0f); + glSamplerParameterf(entry->handle, GL_TEXTURE_MIN_LOD, 0.0f); + glSamplerParameterf(entry->handle, GL_TEXTURE_MAX_LOD, 0.0f); // Texture wrapping modes. // TODO(benvanik): not sure if the middle ones are correct. @@ -167,11 +168,11 @@ bool TextureCache::SetupSampler(GLuint sampler, const TextureInfo& texture_info, GL_CLAMP_TO_BORDER, // GL_MIRROR_CLAMP_TO_BORDER_EXT, // }; - glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, + glSamplerParameteri(entry->handle, GL_TEXTURE_WRAP_S, wrap_map[sampler_info.clamp_u]); - glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, + glSamplerParameteri(entry->handle, GL_TEXTURE_WRAP_T, wrap_map[sampler_info.clamp_v]); - glSamplerParameteri(sampler, GL_TEXTURE_WRAP_R, + glSamplerParameteri(entry->handle, GL_TEXTURE_WRAP_R, wrap_map[sampler_info.clamp_w]); // Texture level filtering. @@ -192,7 +193,7 @@ bool TextureCache::SetupSampler(GLuint sampler, const TextureInfo& texture_info, break; default: assert_unhandled_case(sampler_info.mip_filter); - return false; + return nullptr; } break; case ucode::TEX_FILTER_LINEAR: @@ -210,12 +211,12 @@ bool TextureCache::SetupSampler(GLuint sampler, const TextureInfo& texture_info, break; default: assert_unhandled_case(sampler_info.mip_filter); - return false; + return nullptr; } break; default: assert_unhandled_case(sampler_info.min_filter); - return false; + return nullptr; } GLenum mag_filter; switch (sampler_info.mag_filter) { @@ -227,15 +228,140 @@ bool TextureCache::SetupSampler(GLuint sampler, const TextureInfo& texture_info, break; default: assert_unhandled_case(mag_filter); - return false; + return nullptr; } - glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, min_filter); - glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, mag_filter); + glSamplerParameteri(entry->handle, GL_TEXTURE_MIN_FILTER, min_filter); + glSamplerParameteri(entry->handle, GL_TEXTURE_MAG_FILTER, mag_filter); // TODO(benvanik): anisotropic filtering. // GL_TEXTURE_MAX_ANISOTROPY_EXT - return true; + // Add to map - map takes ownership. + auto entry_ptr = entry.get(); + sampler_entries_.insert({hash, entry.release()}); + return entry_ptr; +} + +void TextureCache::EvictSampler(SamplerEntry* entry) { + glDeleteSamplers(1, &entry->handle); + + for (auto it = sampler_entries_.find(entry->sampler_info.hash()); + it != sampler_entries_.end(); ++it) { + if (it->second == entry) { + sampler_entries_.erase(it); + break; + } + } + + delete entry; +} + +TextureCache::TextureEntry* TextureCache::LookupOrInsertTexture( + const TextureInfo& texture_info, uint64_t opt_hash) { + const uint64_t hash = opt_hash ? opt_hash : texture_info.hash(); + for (auto it = texture_entries_.find(hash); it != texture_entries_.end(); + ++it) { + if (it->second->texture_info == texture_info) { + // Found in cache! + return it->second; + } + } + + // Not found, create. + auto entry = std::make_unique(); + entry->texture_info = texture_info; + entry->handle = 0; + + GLenum target; + switch (texture_info.dimension) { + case Dimension::k1D: + target = GL_TEXTURE_1D; + break; + case Dimension::k2D: + target = GL_TEXTURE_2D; + break; + case Dimension::k3D: + target = GL_TEXTURE_3D; + break; + case Dimension::kCube: + target = GL_TEXTURE_CUBE_MAP; + break; + } + + // Setup the base texture. + glCreateTextures(target, 1, &entry->handle); + + // TODO(benvanik): texture mip levels. + glTextureParameteri(entry->handle, GL_TEXTURE_BASE_LEVEL, 0); + glTextureParameteri(entry->handle, GL_TEXTURE_MAX_LEVEL, 1); + + // Pre-shader swizzle. + // TODO(benvanik): can this be dynamic? Maybe per view? + // We may have to emulate this in the shader. + uint32_t swizzle_r = texture_info.swizzle & 0x7; + uint32_t swizzle_g = (texture_info.swizzle >> 3) & 0x7; + uint32_t swizzle_b = (texture_info.swizzle >> 6) & 0x7; + uint32_t swizzle_a = (texture_info.swizzle >> 9) & 0x7; + static const GLenum swizzle_map[] = { + GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_ZERO, GL_ONE, + }; + glTextureParameteri(entry->handle, GL_TEXTURE_SWIZZLE_R, + swizzle_map[swizzle_r]); + glTextureParameteri(entry->handle, GL_TEXTURE_SWIZZLE_G, + swizzle_map[swizzle_g]); + glTextureParameteri(entry->handle, GL_TEXTURE_SWIZZLE_B, + swizzle_map[swizzle_b]); + glTextureParameteri(entry->handle, GL_TEXTURE_SWIZZLE_A, + swizzle_map[swizzle_a]); + + // Upload/convert. + bool uploaded = false; + switch (texture_info.dimension) { + case Dimension::k2D: + uploaded = UploadTexture2D(entry->handle, texture_info); + break; + case Dimension::k1D: + case Dimension::k3D: + case Dimension::kCube: + assert_unhandled_case(texture_info.dimension); + return false; + } + if (!uploaded) { + PLOGE("Failed to convert/upload texture"); + return nullptr; + } + + // AddWriteWatch(host_base, length, [](void* context_ptr, void* data_ptr, + // void* address) { + // // + //}, this, &entry); + + // Add to map - map takes ownership. + auto entry_ptr = entry.get(); + texture_entries_.insert({hash, entry.release()}); + return entry_ptr; +} + +void TextureCache::EvictTexture(TextureEntry* entry) { + /*if (entry->write_watch_handle) { + // remove from watch list + }*/ + + for (auto& view : entry->views) { + glMakeTextureHandleNonResidentARB(view->texture_sampler_handle); + } + glDeleteTextures(1, &entry->handle); + + uint64_t texture_hash = entry->texture_info.hash(); + for (auto it = texture_entries_.find(texture_hash); + it != texture_entries_.end(); ++it) { + if (it->second == entry) { + texture_entries_.erase(it); + break; + } + } + + delete entry; } void TextureSwap(Endian endianness, void* dest, const void* src, @@ -266,11 +392,10 @@ void TextureSwap(Endian endianness, void* dest, const void* src, } } -bool TextureCache::UploadTexture2D(GLuint texture, void* host_base, - size_t length, - const TextureInfo& texture_info, - const SamplerInfo& sampler_info) { - assert_true(length == texture_info.input_length); +bool TextureCache::UploadTexture2D(GLuint texture, + const TextureInfo& texture_info) { + auto host_address = + reinterpret_cast(membase_ + texture_info.guest_address); GLenum internal_format = GL_RGBA8; GLenum format = GL_RGBA; @@ -433,13 +558,13 @@ bool TextureCache::UploadTexture2D(GLuint texture, void* host_base, if (texture_info.size_2d.input_pitch == texture_info.size_2d.logical_pitch) { // Fast path copy entire image. - TextureSwap(texture_info.endianness, allocation.host_ptr, host_base, + TextureSwap(texture_info.endianness, allocation.host_ptr, host_address, unpack_length); } else { // Slow path copy row-by-row because strides differ. // UNPACK_ROW_LENGTH only works for uncompressed images, and likely does // this exact thing under the covers, so we just always do it here. - const uint8_t* src = reinterpret_cast(host_base); + const uint8_t* src = host_address; uint8_t* dest = reinterpret_cast(allocation.host_ptr); for (uint32_t y = 0; y < texture_info.size_2d.block_height; y++) { TextureSwap(texture_info.endianness, dest, src, @@ -452,7 +577,7 @@ bool TextureCache::UploadTexture2D(GLuint texture, void* host_base, // Untile image. // We could do this in a shader to speed things up, as this is pretty slow. // TODO(benvanik): optimize this inner loop (or work by tiles). - uint8_t* src = reinterpret_cast(host_base); + const uint8_t* src = host_address; uint8_t* dest = reinterpret_cast(allocation.host_ptr); uint32_t output_pitch = (texture_info.size_2d.output_width / texture_info.block_size) * diff --git a/src/xenia/gpu/gl4/texture_cache.h b/src/xenia/gpu/gl4/texture_cache.h index f4816d981..05187ef28 100644 --- a/src/xenia/gpu/gl4/texture_cache.h +++ b/src/xenia/gpu/gl4/texture_cache.h @@ -10,6 +10,8 @@ #ifndef XENIA_GPU_GL4_TEXTURE_CACHE_H_ #define XENIA_GPU_GL4_TEXTURE_CACHE_H_ +#include +#include #include #include @@ -23,39 +25,51 @@ namespace gl4 { class TextureCache { public: - struct EntryView { + struct SamplerEntry { SamplerInfo sampler_info; - GLuint sampler; + GLuint handle; + }; + struct TextureEntryView { + SamplerEntry* sampler; + uint64_t sampler_hash; GLuint64 texture_sampler_handle; }; - struct Entry { + struct TextureEntry { TextureInfo texture_info; - GLuint base_texture; - std::vector views; + GLuint handle; + std::vector> views; }; TextureCache(); ~TextureCache(); - bool Initialize(CircularBuffer* scratch_buffer); + bool Initialize(uint8_t* membase, CircularBuffer* scratch_buffer); void Shutdown(); + + void Scavenge(); void Clear(); - EntryView* Demand(void* host_base, size_t length, - const TextureInfo& texture_info, - const SamplerInfo& sampler_info); + TextureEntryView* Demand(const TextureInfo& texture_info, + const SamplerInfo& sampler_info); private: - bool SetupTexture(GLuint texture, const TextureInfo& texture_info); - bool SetupSampler(GLuint sampler, const TextureInfo& texture_info, - const SamplerInfo& sampler_info); + SamplerEntry* LookupOrInsertSampler(const SamplerInfo& sampler_info, + uint64_t opt_hash = 0); + void EvictSampler(SamplerEntry* entry); + TextureEntry* LookupOrInsertTexture(const TextureInfo& texture_info, + uint64_t opt_hash = 0); + void EvictTexture(TextureEntry* entry); - bool UploadTexture2D(GLuint texture, void* host_base, size_t length, - const TextureInfo& texture_info, - const SamplerInfo& sampler_info); + bool UploadTexture2D(GLuint texture, const TextureInfo& texture_info); + uint8_t* membase_; CircularBuffer* scratch_buffer_; - std::vector entries_; + std::unordered_map sampler_entries_; + std::unordered_map texture_entries_; + + std::mutex invalidated_textures_mutex_; + std::vector* invalidated_textures_; + std::vector invalidated_textures_sets_[2]; }; } // namespace gl4 diff --git a/src/xenia/gpu/sampler_info.cc b/src/xenia/gpu/sampler_info.cc index f260f7bfc..78c023656 100644 --- a/src/xenia/gpu/sampler_info.cc +++ b/src/xenia/gpu/sampler_info.cc @@ -9,12 +9,16 @@ #include +#include + namespace xe { namespace gpu { bool SamplerInfo::Prepare(const xenos::xe_gpu_texture_fetch_t& fetch, const ucode::instr_fetch_tex_t& fetch_instr, SamplerInfo* out_info) { + std::memset(out_info, 0, sizeof(SamplerInfo)); + out_info->min_filter = static_cast( fetch_instr.min_filter == 3 ? fetch.min_filter : fetch_instr.min_filter); out_info->mag_filter = static_cast( @@ -27,5 +31,9 @@ bool SamplerInfo::Prepare(const xenos::xe_gpu_texture_fetch_t& fetch, return true; } +uint64_t SamplerInfo::hash() const { + return XXH64(this, sizeof(SamplerInfo), 0); +} + } // namespace gpu } // namespace xe diff --git a/src/xenia/gpu/sampler_info.h b/src/xenia/gpu/sampler_info.h index 9aa764117..57abfb4b9 100644 --- a/src/xenia/gpu/sampler_info.h +++ b/src/xenia/gpu/sampler_info.h @@ -28,6 +28,7 @@ struct SamplerInfo { const ucode::instr_fetch_tex_t& fetch_instr, SamplerInfo* out_info); + uint64_t hash() const; bool operator==(const SamplerInfo& other) const { return min_filter == other.min_filter && mag_filter == other.mag_filter && mip_filter == other.mip_filter && clamp_u == other.clamp_u && diff --git a/src/xenia/gpu/texture_info.cc b/src/xenia/gpu/texture_info.cc index d2beb2945..38eb711c8 100644 --- a/src/xenia/gpu/texture_info.cc +++ b/src/xenia/gpu/texture_info.cc @@ -9,6 +9,8 @@ #include +#include + #include namespace xe { @@ -19,13 +21,16 @@ using namespace xe::gpu::xenos; bool TextureInfo::Prepare(const xe_gpu_texture_fetch_t& fetch, TextureInfo* out_info) { + std::memset(out_info, 0, sizeof(TextureInfo)); + // http://msdn.microsoft.com/en-us/library/windows/desktop/cc308051(v=vs.85).aspx // a2xx_sq_surfaceformat - auto& info = *out_info; + info.guest_address = fetch.address << 12; info.swizzle = fetch.swizzle; info.dimension = static_cast(fetch.dimension); + info.width = info.height = info.depth = 0; switch (info.dimension) { case Dimension::k1D: info.width = fetch.size_1d.width; @@ -240,5 +245,9 @@ uint32_t TextureInfo::TiledOffset2DInner(uint32_t x, uint32_t y, uint32_t bpp, ((y & 16) << 7) + (((((y & 8) >> 2) + (x >> 3)) & 3) << 6); } +uint64_t TextureInfo::hash() const { + return XXH64(this, sizeof(TextureInfo), 0); +} + } // namespace gpu } // namespace xe diff --git a/src/xenia/gpu/texture_info.h b/src/xenia/gpu/texture_info.h index 2cda83426..1ebaee00e 100644 --- a/src/xenia/gpu/texture_info.h +++ b/src/xenia/gpu/texture_info.h @@ -85,6 +85,8 @@ enum class TextureFormat : uint32_t { }; struct TextureInfo { + uint32_t guest_address; + uint32_t input_length; uint32_t swizzle; Dimension dimension; uint32_t width; @@ -95,7 +97,6 @@ struct TextureInfo { xenos::Endian endianness; bool is_tiled; bool is_compressed; - uint32_t input_length; TextureFormat format; @@ -129,6 +130,11 @@ struct TextureInfo { static uint32_t TiledOffset2DInner(uint32_t x, uint32_t y, uint32_t bpp, uint32_t base_offset); + uint64_t hash() const; + bool operator==(const TextureInfo& other) const { + return std::memcmp(this, &other, sizeof(TextureInfo)) == 0; + } + private: void CalculateTextureSizes1D(const xenos::xe_gpu_texture_fetch_t& fetch); void CalculateTextureSizes2D(const xenos::xe_gpu_texture_fetch_t& fetch); From c6f0ce7a1e543fdef1fd5f5e3b55cc13e04af752 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 3 Jan 2015 01:06:19 -0800 Subject: [PATCH 312/388] Enabling microprofile webserver and adding a timeout. --- src/xenia/profiling.cc | 6 +++++- third_party/microprofile/microprofile.h | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/xenia/profiling.cc b/src/xenia/profiling.cc index 2267980cc..a143ff927 100644 --- a/src/xenia/profiling.cc +++ b/src/xenia/profiling.cc @@ -13,10 +13,14 @@ #define MICROPROFILEUI_ENABLED 1 #define MICROPROFILE_IMPL 1 #define MICROPROFILEUI_IMPL 1 +#define MICROPROFILE_PER_THREAD_BUFFER_SIZE (1024 * 1024 * 10) #define MICROPROFILE_USE_THREAD_NAME_CALLBACK 1 #define MICROPROFILE_PRINTF PLOGI -#define MICROPROFILE_WEBSERVER 0 +#define MICROPROFILE_WEBSERVER 1 #define MICROPROFILE_DEBUG 0 +#if MICROPROFILE_WEBSERVER +#include +#endif // MICROPROFILE_WEBSERVER #include #include diff --git a/third_party/microprofile/microprofile.h b/third_party/microprofile/microprofile.h index 01126528b..911593cdd 100644 --- a/third_party/microprofile/microprofile.h +++ b/third_party/microprofile/microprofile.h @@ -1985,7 +1985,11 @@ bool MicroProfileWebServerUpdate() bool bServed = false; if(!MP_INVALID_SOCKET(Connection)) { - std::lock_guard Lock(MicroProfileMutex()); + int timeout = 100; + setsockopt(Connection, SOL_SOCKET, SO_RCVTIMEO, + reinterpret_cast(&timeout), sizeof(timeout)); + + std::lock_guard Lock(MicroProfileMutex()); char Req[8192]; MicroProfileSetNonBlocking(Connection, 0); int nReceived = recv(Connection, Req, sizeof(Req)-1, 0); From 858f70549fde2f3dbd6d64ee61472c725dedd7a4 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 3 Jan 2015 01:32:59 -0800 Subject: [PATCH 313/388] Dangerous --vsync=false flag. --- src/xenia/gpu/gl4/command_processor.cc | 37 ++++++++++++++---------- src/xenia/gpu/gl4/gl4_graphics_system.cc | 12 ++++---- src/xenia/gpu/gpu-private.h | 2 ++ src/xenia/gpu/gpu.cc | 2 ++ src/xenia/profiling.cc | 1 + 5 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/xenia/gpu/gl4/command_processor.cc b/src/xenia/gpu/gl4/command_processor.cc index 6c21affdc..5444abcfc 100644 --- a/src/xenia/gpu/gl4/command_processor.cc +++ b/src/xenia/gpu/gl4/command_processor.cc @@ -123,22 +123,23 @@ void CommandProcessor::WorkerMain() { while (worker_running_) { uint32_t write_ptr_index = write_ptr_index_.load(); - while (write_ptr_index == 0xBAADF00D || - read_ptr_index_ == write_ptr_index) { + if (write_ptr_index == 0xBAADF00D || read_ptr_index_ == write_ptr_index) { SCOPE_profile_cpu_i("gpu", "xe::gpu::gl4::CommandProcessor::Stall"); - // Check if the pointer has moved. - // We wait a short bit here to yield time. Since we are also running the - // main window display we don't want to pause too long, though. - // YieldProcessor(); - PrepareForWait(); - const int wait_time_ms = 5; - if (WaitForSingleObject(write_ptr_index_event_, wait_time_ms) == - WAIT_TIMEOUT) { - ReturnFromWait(); + // We've run out of commands to execute. + // We spin here waiting for new ones, as the overhead of waiting on our + // event is too high. + //PrepareForWait(); + do { + // TODO(benvanik): if we go longer than Nms, switch to waiting? + // It'll keep us from burning power. + // const int wait_time_ms = 5; + // WaitForSingleObject(write_ptr_index_event_, wait_time_ms); + SwitchToThread(); + MemoryBarrier(); write_ptr_index = write_ptr_index_.load(); - continue; - } - ReturnFromWait(); + } while (write_ptr_index == 0xBAADF00D || + read_ptr_index_ == write_ptr_index); + //ReturnFromWait(); } assert_true(read_ptr_index_ != write_ptr_index); @@ -925,7 +926,13 @@ bool CommandProcessor::ExecutePacketType3_WAIT_REG_MEM(RingbufferReader* reader, // Wait. if (wait >= 0x100) { PrepareForWait(); - Sleep(wait / 0x100); + if (!FLAGS_vsync) { + // User wants it fast and dangerous. + SwitchToThread(); + } else { + Sleep(wait / 0x100); + } + MemoryBarrier(); ReturnFromWait(); } else { SwitchToThread(); diff --git a/src/xenia/gpu/gl4/gl4_graphics_system.cc b/src/xenia/gpu/gl4/gl4_graphics_system.cc index 2edc4277d..dde643ce3 100644 --- a/src/xenia/gpu/gl4/gl4_graphics_system.cc +++ b/src/xenia/gpu/gl4/gl4_graphics_system.cc @@ -77,10 +77,15 @@ X_STATUS GL4GraphicsSystem::Setup() { reinterpret_cast(MMIOWriteRegisterThunk)); // 60hz vsync timer. + DWORD timer_period = 16; + if (!FLAGS_vsync) { + // DANGER a value too low here will lead to starvation! + timer_period = 4; + } timer_queue_ = CreateTimerQueue(); CreateTimerQueueTimer(&vsync_timer_, timer_queue_, - (WAITORTIMERCALLBACK)VsyncCallbackThunk, this, 16, 16, - WT_EXECUTEINTIMERTHREAD); + (WAITORTIMERCALLBACK)VsyncCallbackThunk, this, 16, + timer_period, WT_EXECUTEINPERSISTENTTHREAD); return X_STATUS_SUCCESS; } @@ -138,9 +143,6 @@ void GL4GraphicsSystem::SwapHandler(const SwapParameters& swap_params) { control_->width(), control_->height(), GL_COLOR_BUFFER_BIT, GL_LINEAR); }); - - // Roll over vblank. - MarkVblank(); } uint64_t GL4GraphicsSystem::ReadRegister(uint64_t addr) { diff --git a/src/xenia/gpu/gpu-private.h b/src/xenia/gpu/gpu-private.h index aafa820fd..4b9024447 100644 --- a/src/xenia/gpu/gpu-private.h +++ b/src/xenia/gpu/gpu-private.h @@ -17,4 +17,6 @@ DECLARE_string(gpu); DECLARE_bool(trace_ring_buffer); DECLARE_string(dump_shaders); +DECLARE_bool(vsync); + #endif // XENIA_GPU_PRIVATE_H_ diff --git a/src/xenia/gpu/gpu.cc b/src/xenia/gpu/gpu.cc index 92d0a9b94..47d773362 100644 --- a/src/xenia/gpu/gpu.cc +++ b/src/xenia/gpu/gpu.cc @@ -19,6 +19,8 @@ DEFINE_bool(trace_ring_buffer, false, "Trace GPU ring buffer packets."); DEFINE_string(dump_shaders, "", "Path to write GPU shaders to as they are compiled."); +DEFINE_bool(vsync, true, "Enable VSYNC."); + namespace xe { namespace gpu { diff --git a/src/xenia/profiling.cc b/src/xenia/profiling.cc index a143ff927..2602a1491 100644 --- a/src/xenia/profiling.cc +++ b/src/xenia/profiling.cc @@ -15,6 +15,7 @@ #define MICROPROFILEUI_IMPL 1 #define MICROPROFILE_PER_THREAD_BUFFER_SIZE (1024 * 1024 * 10) #define MICROPROFILE_USE_THREAD_NAME_CALLBACK 1 +#define MICROPROFILE_WEBSERVER_MAXFRAMES 10 #define MICROPROFILE_PRINTF PLOGI #define MICROPROFILE_WEBSERVER 1 #define MICROPROFILE_DEBUG 0 From 07a82200f95c55d17b626fb2e853b2385732c517 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 3 Jan 2015 02:57:58 -0800 Subject: [PATCH 314/388] Shadow state to eliminate most redundant GL calls. --- src/xenia/gpu/gl4/command_processor.cc | 402 ++++++++++++++++--------- src/xenia/gpu/gl4/command_processor.h | 67 ++++- src/xenia/gpu/gl4/wgl_control.cc | 9 - src/xenia/profiling.cc | 2 +- 4 files changed, 320 insertions(+), 160 deletions(-) diff --git a/src/xenia/gpu/gl4/command_processor.cc b/src/xenia/gpu/gl4/command_processor.cc index 5444abcfc..2113dac23 100644 --- a/src/xenia/gpu/gl4/command_processor.cc +++ b/src/xenia/gpu/gl4/command_processor.cc @@ -128,7 +128,7 @@ void CommandProcessor::WorkerMain() { // We've run out of commands to execute. // We spin here waiting for new ones, as the overhead of waiting on our // event is too high. - //PrepareForWait(); + // PrepareForWait(); do { // TODO(benvanik): if we go longer than Nms, switch to waiting? // It'll keep us from burning power. @@ -139,7 +139,7 @@ void CommandProcessor::WorkerMain() { write_ptr_index = write_ptr_index_.load(); } while (write_ptr_index == 0xBAADF00D || read_ptr_index_ == write_ptr_index); - //ReturnFromWait(); + // ReturnFromWait(); } assert_true(read_ptr_index_ != write_ptr_index); @@ -163,6 +163,8 @@ void CommandProcessor::WorkerMain() { } bool CommandProcessor::SetupGL() { + glViewport(0, 0, 1280, 720); + // Circular buffer holding scratch vertex/index data. if (!scratch_buffer_.Initialize()) { PLOGE("Unable to initialize scratch buffer"); @@ -236,7 +238,8 @@ bool CommandProcessor::SetupGL() { "layout(triangle_strip, max_vertices = 4) out;\n" "void main() {\n" // Most games use the left-aligned form. - " bool left_aligned = gl_in[0].gl_Position.x == gl_in[2].gl_Position.x;\n" + " bool left_aligned = gl_in[0].gl_Position.x == \n" + " gl_in[2].gl_Position.x;\n" " if (left_aligned) {\n" // 0 ------ 1 // | - | @@ -1396,11 +1399,9 @@ bool CommandProcessor::IssueDraw(DrawCommand* draw_command) { } GLenum prim_type = 0; - GLuint pipeline = active_pipeline_->handles.default_pipeline; switch (cmd.prim_type) { case PrimitiveType::kPointList: prim_type = GL_POINTS; - pipeline = active_pipeline_->handles.point_list_pipeline; break; case PrimitiveType::kLineList: prim_type = GL_LINES; @@ -1422,11 +1423,9 @@ bool CommandProcessor::IssueDraw(DrawCommand* draw_command) { break; case PrimitiveType::kRectangleList: prim_type = GL_TRIANGLE_STRIP; - pipeline = active_pipeline_->handles.rect_list_pipeline; break; case PrimitiveType::kQuadList: prim_type = GL_LINES_ADJACENCY; - pipeline = active_pipeline_->handles.quad_list_pipeline; break; default: case PrimitiveType::kUnknown0x07: @@ -1436,8 +1435,6 @@ bool CommandProcessor::IssueDraw(DrawCommand* draw_command) { return false; } - glBindProgramPipeline(pipeline); - // Commit the state buffer - nothing can change after this. glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, scratch_buffer_.handle(), allocation.offset, allocation.length); @@ -1462,33 +1459,56 @@ bool CommandProcessor::IssueDraw(DrawCommand* draw_command) { glDrawArrays(prim_type, cmd.start_index, cmd.index_count); } - // Hacky draw counter. - if (false) { - static int draw_count = 0; - glEnable(GL_SCISSOR_TEST); - glScissor(20, 0, 20, 20); - float red[] = {0, draw_count / 100.0f, 0, 1.0f}; - draw_count = (draw_count + 1) % 100; - glClearNamedFramebufferfv(active_framebuffer_->framebuffer, GL_COLOR, 0, - red); - glDisable(GL_SCISSOR_TEST); - } + return true; +} +bool CommandProcessor::SetShadowRegister(uint32_t& dest, + uint32_t register_name) { + uint32_t value = register_file_->values[register_name].u32; + if (dest == value) { + return false; + } + dest = value; + return true; +} + +bool CommandProcessor::SetShadowRegister(float& dest, uint32_t register_name) { + float value = register_file_->values[register_name].f32; + if (dest == value) { + return false; + } + dest = value; return true; } bool CommandProcessor::UpdateRenderTargets(DrawCommand* draw_command) { - SCOPE_profile_cpu_f("gpu"); - auto& regs = *register_file_; + auto& regs = update_render_targets_regs_; - auto enable_mode = - static_cast(regs[XE_GPU_REG_RB_MODECONTROL].u32 & 0x7); + bool dirty = false; + dirty |= SetShadowRegister(regs.rb_modecontrol, XE_GPU_REG_RB_MODECONTROL); + dirty |= SetShadowRegister(regs.rb_surface_info, XE_GPU_REG_RB_SURFACE_INFO); + dirty |= SetShadowRegister(regs.rb_color_info, XE_GPU_REG_RB_COLOR_INFO); + dirty |= SetShadowRegister(regs.rb_color1_info, XE_GPU_REG_RB_COLOR1_INFO); + dirty |= SetShadowRegister(regs.rb_color2_info, XE_GPU_REG_RB_COLOR2_INFO); + dirty |= SetShadowRegister(regs.rb_color3_info, XE_GPU_REG_RB_COLOR3_INFO); + dirty |= SetShadowRegister(regs.rb_color_mask, XE_GPU_REG_RB_COLOR_MASK); + dirty |= SetShadowRegister(regs.rb_depthcontrol, XE_GPU_REG_RB_DEPTHCONTROL); + dirty |= + SetShadowRegister(regs.rb_stencilrefmask, XE_GPU_REG_RB_STENCILREFMASK); + dirty |= SetShadowRegister(regs.rb_depth_info, XE_GPU_REG_RB_DEPTH_INFO); + if (!dirty) { + return true; + } + + SCOPE_profile_cpu_f("gpu"); + + auto enable_mode = static_cast(regs.rb_modecontrol & 0x7); // RB_SURFACE_INFO // http://fossies.org/dox/MesaLib-10.3.5/fd2__gmem_8c_source.html - uint32_t surface_info = regs[XE_GPU_REG_RB_SURFACE_INFO].u32; - uint32_t surface_pitch = surface_info & 0x3FFF; - auto surface_msaa = static_cast((surface_info >> 16) & 0x3); + uint32_t surface_pitch = regs.rb_surface_info & 0x3FFF; + auto surface_msaa = + static_cast((regs.rb_surface_info >> 16) & 0x3); // Get/create all color render targets, if we are using them. // In depth-only mode we don't need them. @@ -1500,14 +1520,12 @@ bool CommandProcessor::UpdateRenderTargets(DrawCommand* draw_command) { GLuint color_targets[4] = {kAnyTarget, kAnyTarget, kAnyTarget, kAnyTarget}; if (enable_mode == ModeControl::kColorDepth) { uint32_t color_info[4] = { - regs[XE_GPU_REG_RB_COLOR_INFO].u32, regs[XE_GPU_REG_RB_COLOR1_INFO].u32, - regs[XE_GPU_REG_RB_COLOR2_INFO].u32, - regs[XE_GPU_REG_RB_COLOR3_INFO].u32, + regs.rb_color_info, regs.rb_color1_info, regs.rb_color2_info, + regs.rb_color3_info, }; // A2XX_RB_COLOR_MASK_WRITE_* == D3DRS_COLORWRITEENABLE - uint32_t color_mask = regs[XE_GPU_REG_RB_COLOR_MASK].u32; for (int n = 0; n < poly::countof(color_info); n++) { - uint32_t write_mask = (color_mask >> (n * 4)) & 0xF; + uint32_t write_mask = (regs.rb_color_mask >> (n * 4)) & 0xF; if (!write_mask || !shader_targets[n]) { // Unused, so keep disabled and set to wildcard so we'll take any // framebuffer that has it. @@ -1525,18 +1543,16 @@ bool CommandProcessor::UpdateRenderTargets(DrawCommand* draw_command) { } // Get/create depth buffer, but only if we are going to use it. - uint32_t depth_control = regs[XE_GPU_REG_RB_DEPTHCONTROL].u32; - uint32_t stencil_ref_mask = regs[XE_GPU_REG_RB_STENCILREFMASK].u32; - bool uses_depth = - (depth_control & 0x00000002) || (depth_control & 0x00000004); - uint32_t stencil_write_mask = (stencil_ref_mask & 0x00FF0000) >> 16; - bool uses_stencil = (depth_control & 0x00000001) || (stencil_write_mask != 0); + bool uses_depth = (regs.rb_depthcontrol & 0x00000002) || + (regs.rb_depthcontrol & 0x00000004); + uint32_t stencil_write_mask = (regs.rb_stencilrefmask & 0x00FF0000) >> 16; + bool uses_stencil = + (regs.rb_depthcontrol & 0x00000001) || (stencil_write_mask != 0); GLuint depth_target = kAnyTarget; if (uses_depth && uses_stencil) { - uint32_t depth_info = regs[XE_GPU_REG_RB_DEPTH_INFO].u32; - uint32_t depth_base = depth_info & 0xFFF; + uint32_t depth_base = regs.rb_depth_info & 0xFFF; auto depth_format = - static_cast((depth_info >> 16) & 0x1); + static_cast((regs.rb_depth_info >> 16) & 0x1); depth_target = GetDepthRenderTarget(surface_pitch, surface_msaa, depth_base, depth_format); // TODO(benvanik): when a game switches does it expect to keep the same @@ -1547,20 +1563,17 @@ bool CommandProcessor::UpdateRenderTargets(DrawCommand* draw_command) { // Note that none may be returned if we really don't need one. auto cached_framebuffer = GetFramebuffer(color_targets, depth_target); active_framebuffer_ = cached_framebuffer; - if (!active_framebuffer_) { - // Nothing to do. - return true; + if (active_framebuffer_) { + // Setup just the targets we want. + glNamedFramebufferDrawBuffers(cached_framebuffer->framebuffer, 4, + draw_buffers); + + // Make active. + // TODO(benvanik): can we do this all named? + // TODO(benvanik): do we want this on READ too? + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, cached_framebuffer->framebuffer); } - // Setup just the targets we want. - glNamedFramebufferDrawBuffers(cached_framebuffer->framebuffer, 4, - draw_buffers); - - // Make active. - // TODO(benvanik): can we do this all named? - // TODO(benvanik): do we want this on READ too? - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, cached_framebuffer->framebuffer); - return true; } @@ -1569,6 +1582,29 @@ bool CommandProcessor::UpdateState(DrawCommand* draw_command) { auto& regs = *register_file_; auto state_data = draw_command->state_data; + // Alpha testing -- ALPHAREF, ALPHAFUNC, ALPHATESTENABLE + // Deprecated in GL, implemented in shader. + // if(ALPHATESTENABLE && frag_out.a [<=/ALPHAFUNC] ALPHAREF) discard; + uint32_t color_control = regs[XE_GPU_REG_RB_COLORCONTROL].u32; + state_data->alpha_test.x = + (color_control & 0x4) ? 1.0f : 0.0f; // ALPAHTESTENABLE + state_data->alpha_test.y = float(color_control & 0x3); // ALPHAFUNC + state_data->alpha_test.z = regs[XE_GPU_REG_RB_ALPHA_REF].f32; + + UpdateViewportState(draw_command); + UpdateRasterizerState(draw_command); + UpdateBlendState(draw_command); + UpdateDepthStencilState(draw_command); + + return true; +} + +bool CommandProcessor::UpdateViewportState(DrawCommand* draw_command) { + auto& regs = *register_file_; + auto state_data = draw_command->state_data; + + SCOPE_profile_cpu_f("gpu"); + // Much of this state machine is extracted from: // https://github.com/freedreno/mesa/blob/master/src/mesa/drivers/dri/r200/r200_state.c // http://fossies.org/dox/MesaLib-10.3.5/fd2__gmem_8c_source.html @@ -1614,7 +1650,6 @@ bool CommandProcessor::UpdateState(DrawCommand* draw_command) { } state_data->window_offset.z = window_width_scalar; state_data->window_offset.w = window_height_scalar; - glViewport(0, 0, 1280, 720); // Whether each of the viewport settings is enabled. // http://www.x.org/docs/AMD/old/evergreen_3D_registers_v2.pdf @@ -1662,63 +1697,98 @@ bool CommandProcessor::UpdateState(DrawCommand* draw_command) { // https://github.com/freedreno/amd-gpu/blob/master/include/reg/yamato/14/yamato_genenum.h#L1587 uint32_t clip_control = regs[XE_GPU_REG_PA_CL_CLIP_CNTL].u32; bool clip_enabled = ((clip_control >> 17) & 0x1) == 0; - //assert_true(clip_enabled); + // assert_true(clip_enabled); bool dx_clip = ((clip_control >> 20) & 0x1) == 0x1; - //assert_true(dx_clip); + // assert_true(dx_clip); + + return true; +} + +bool CommandProcessor::UpdateRasterizerState(DrawCommand* draw_command) { + auto& regs = update_rasterizer_state_regs_; + + bool dirty = false; + dirty |= + SetShadowRegister(regs.pa_su_sc_mode_cntl, XE_GPU_REG_PA_SU_SC_MODE_CNTL); + dirty |= SetShadowRegister(regs.pa_sc_screen_scissor_tl, + XE_GPU_REG_PA_SC_SCREEN_SCISSOR_TL); + dirty |= SetShadowRegister(regs.pa_sc_screen_scissor_br, + XE_GPU_REG_PA_SC_SCREEN_SCISSOR_BR); + if (!dirty) { + return true; + } + + SCOPE_profile_cpu_f("gpu"); // Scissoring. - int32_t screen_scissor_tl = regs[XE_GPU_REG_PA_SC_SCREEN_SCISSOR_TL].u32; - int32_t screen_scissor_br = regs[XE_GPU_REG_PA_SC_SCREEN_SCISSOR_BR].u32; - if (screen_scissor_tl != 0 && screen_scissor_br != 0x20002000) { + if (regs.pa_sc_screen_scissor_tl != 0 && + regs.pa_sc_screen_scissor_br != 0x20002000) { glEnable(GL_SCISSOR_TEST); // TODO(benvanik): signed? - int32_t screen_scissor_x = screen_scissor_tl & 0x7FFF; - int32_t screen_scissor_y = (screen_scissor_tl >> 16) & 0x7FFF; - int32_t screen_scissor_w = screen_scissor_br & 0x7FFF - screen_scissor_x; + int32_t screen_scissor_x = regs.pa_sc_screen_scissor_tl & 0x7FFF; + int32_t screen_scissor_y = (regs.pa_sc_screen_scissor_tl >> 16) & 0x7FFF; + int32_t screen_scissor_w = + regs.pa_sc_screen_scissor_br & 0x7FFF - screen_scissor_x; int32_t screen_scissor_h = - (screen_scissor_br >> 16) & 0x7FFF - screen_scissor_y; + (regs.pa_sc_screen_scissor_br >> 16) & 0x7FFF - screen_scissor_y; glScissor(screen_scissor_x, screen_scissor_y, screen_scissor_w, screen_scissor_h); } else { glDisable(GL_SCISSOR_TEST); } - // Rasterizer state. - if (draw_command->prim_type == PrimitiveType::kRectangleList) { - // Rect lists aren't culled. There may be other things they skip too. - glDisable(GL_CULL_FACE); - } else { - switch (mode_control & 0x3) { - case 0: - glDisable(GL_CULL_FACE); - break; - case 1: - glEnable(GL_CULL_FACE); - glCullFace(GL_FRONT); - break; - case 2: - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - break; - } + // Rect lists aren't culled. There may be other things they skip too. + assert_true((regs.pa_su_sc_mode_cntl & 0x3) == 0 || + draw_command->prim_type != PrimitiveType::kRectangleList); + + switch (regs.pa_su_sc_mode_cntl & 0x3) { + case 0: + glDisable(GL_CULL_FACE); + break; + case 1: + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + break; + case 2: + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + break; } - if (mode_control & 0x4) { + + if (regs.pa_su_sc_mode_cntl & 0x4) { glFrontFace(GL_CW); } else { glFrontFace(GL_CCW); } + // TODO(benvanik): wireframe mode. // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - // Alpha testing -- ALPHAREF, ALPHAFUNC, ALPHATESTENABLE - // Deprecated in GL, implemented in shader. - // if(ALPHATESTENABLE && frag_out.a [<=/ALPHAFUNC] ALPHAREF) discard; - uint32_t color_control = regs[XE_GPU_REG_RB_COLORCONTROL].u32; - state_data->alpha_test.x = - (color_control & 0x4) ? 1.0f : 0.0f; // ALPAHTESTENABLE - state_data->alpha_test.y = float(color_control & 0x3); // ALPHAFUNC - state_data->alpha_test.z = regs[XE_GPU_REG_RB_ALPHA_REF].f32; + return true; +} + +bool CommandProcessor::UpdateBlendState(DrawCommand* draw_command) { + auto& regs = update_blend_state_regs_; + + bool dirty = false; + dirty |= + SetShadowRegister(regs.rb_blendcontrol[0], XE_GPU_REG_RB_BLENDCONTROL_0); + dirty |= + SetShadowRegister(regs.rb_blendcontrol[1], XE_GPU_REG_RB_BLENDCONTROL_1); + dirty |= + SetShadowRegister(regs.rb_blendcontrol[2], XE_GPU_REG_RB_BLENDCONTROL_2); + dirty |= + SetShadowRegister(regs.rb_blendcontrol[3], XE_GPU_REG_RB_BLENDCONTROL_3); + dirty |= SetShadowRegister(regs.rb_blend_rgba[0], XE_GPU_REG_RB_BLEND_RED); + dirty |= SetShadowRegister(regs.rb_blend_rgba[1], XE_GPU_REG_RB_BLEND_GREEN); + dirty |= SetShadowRegister(regs.rb_blend_rgba[2], XE_GPU_REG_RB_BLEND_BLUE); + dirty |= SetShadowRegister(regs.rb_blend_rgba[3], XE_GPU_REG_RB_BLEND_ALPHA); + if (!dirty) { + return true; + } + + SCOPE_profile_cpu_f("gpu"); static const GLenum blend_map[] = { /* 0 */ GL_ZERO, @@ -1746,25 +1816,20 @@ bool CommandProcessor::UpdateState(DrawCommand* draw_command) { /* 3 */ GL_MAX, /* 4 */ GL_FUNC_REVERSE_SUBTRACT, }; - uint32_t blend_control[4] = { - regs[XE_GPU_REG_RB_BLENDCONTROL_0].u32, - regs[XE_GPU_REG_RB_BLENDCONTROL_1].u32, - regs[XE_GPU_REG_RB_BLENDCONTROL_2].u32, - regs[XE_GPU_REG_RB_BLENDCONTROL_3].u32, - }; - for (int n = 0; n < poly::countof(blend_control); n++) { + for (int i = 0; i < poly::countof(regs.rb_blendcontrol); ++i) { + uint32_t blend_control = regs.rb_blendcontrol[i]; // A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND - auto src_blend = blend_map[(blend_control[n] & 0x0000001F) >> 0]; + auto src_blend = blend_map[(blend_control & 0x0000001F) >> 0]; // A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND - auto dest_blend = blend_map[(blend_control[n] & 0x00001F00) >> 8]; + auto dest_blend = blend_map[(blend_control & 0x00001F00) >> 8]; // A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN - auto blend_op = blend_op_map[(blend_control[n] & 0x000000E0) >> 5]; + auto blend_op = blend_op_map[(blend_control & 0x000000E0) >> 5]; // A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND - auto src_blend_alpha = blend_map[(blend_control[n] & 0x001F0000) >> 16]; + auto src_blend_alpha = blend_map[(blend_control & 0x001F0000) >> 16]; // A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND - auto dest_blend_alpha = blend_map[(blend_control[n] & 0x1F000000) >> 24]; + auto dest_blend_alpha = blend_map[(blend_control & 0x1F000000) >> 24]; // A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN - auto blend_op_alpha = blend_op_map[(blend_control[n] & 0x00E00000) >> 21]; + auto blend_op_alpha = blend_op_map[(blend_control & 0x00E00000) >> 21]; // A2XX_RB_COLORCONTROL_BLEND_DISABLE ?? Can't find this! // Just guess based on actions. bool blend_enable = @@ -1772,19 +1837,33 @@ bool CommandProcessor::UpdateState(DrawCommand* draw_command) { (blend_op == GL_FUNC_ADD) && (src_blend_alpha == GL_ONE) && (dest_blend_alpha == GL_ZERO) && (blend_op_alpha == GL_FUNC_ADD)); if (blend_enable) { - glEnablei(GL_BLEND, n); - glBlendEquationSeparatei(n, blend_op, blend_op_alpha); - glBlendFuncSeparatei(n, src_blend, dest_blend, src_blend_alpha, + glEnablei(GL_BLEND, i); + glBlendEquationSeparatei(i, blend_op, blend_op_alpha); + glBlendFuncSeparatei(i, src_blend, dest_blend, src_blend_alpha, dest_blend_alpha); } else { - glDisablei(GL_BLEND, n); + glDisablei(GL_BLEND, i); } } - float blend_color[4] = { - regs[XE_GPU_REG_RB_BLEND_RED].f32, regs[XE_GPU_REG_RB_BLEND_GREEN].f32, - regs[XE_GPU_REG_RB_BLEND_BLUE].f32, regs[XE_GPU_REG_RB_BLEND_ALPHA].f32, - }; - glBlendColor(blend_color[0], blend_color[1], blend_color[2], blend_color[3]); + + glBlendColor(regs.rb_blend_rgba[0], regs.rb_blend_rgba[1], + regs.rb_blend_rgba[2], regs.rb_blend_rgba[3]); + + return true; +} + +bool CommandProcessor::UpdateDepthStencilState(DrawCommand* draw_command) { + auto& regs = update_depth_stencil_state_regs_; + + bool dirty = false; + dirty |= SetShadowRegister(regs.rb_depthcontrol, XE_GPU_REG_RB_DEPTHCONTROL); + dirty |= + SetShadowRegister(regs.rb_stencilrefmask, XE_GPU_REG_RB_STENCILREFMASK); + if (!dirty) { + return true; + } + + SCOPE_profile_cpu_f("gpu"); static const GLenum compare_func_map[] = { /* 0 */ GL_NEVER, @@ -1806,64 +1885,62 @@ bool CommandProcessor::UpdateState(DrawCommand* draw_command) { /* 6 */ GL_INCR, /* 7 */ GL_DECR, }; - uint32_t depth_control = regs[XE_GPU_REG_RB_DEPTHCONTROL].u32; // A2XX_RB_DEPTHCONTROL_Z_ENABLE - if (depth_control & 0x00000002) { + if (regs.rb_depthcontrol & 0x00000002) { glEnable(GL_DEPTH_TEST); } else { glDisable(GL_DEPTH_TEST); } // A2XX_RB_DEPTHCONTROL_Z_WRITE_ENABLE - glDepthMask((depth_control & 0x00000004) ? GL_TRUE : GL_FALSE); + glDepthMask((regs.rb_depthcontrol & 0x00000004) ? GL_TRUE : GL_FALSE); // A2XX_RB_DEPTHCONTROL_EARLY_Z_ENABLE // ? // A2XX_RB_DEPTHCONTROL_ZFUNC - glDepthFunc(compare_func_map[(depth_control & 0x00000070) >> 4]); + glDepthFunc(compare_func_map[(regs.rb_depthcontrol & 0x00000070) >> 4]); // A2XX_RB_DEPTHCONTROL_STENCIL_ENABLE - if (depth_control & 0x00000001) { + if (regs.rb_depthcontrol & 0x00000001) { glEnable(GL_STENCIL_TEST); } else { glDisable(GL_STENCIL_TEST); } - uint32_t stencil_ref_mask = regs[XE_GPU_REG_RB_STENCILREFMASK].u32; // RB_STENCILREFMASK_STENCILREF - uint32_t stencil_ref = (stencil_ref_mask & 0x000000FF); + uint32_t stencil_ref = (regs.rb_stencilrefmask & 0x000000FF); // RB_STENCILREFMASK_STENCILMASK - uint32_t stencil_read_mask = (stencil_ref_mask & 0x0000FF00) >> 8; + uint32_t stencil_read_mask = (regs.rb_stencilrefmask & 0x0000FF00) >> 8; // RB_STENCILREFMASK_STENCILWRITEMASK - glStencilMask((stencil_ref_mask & 0x00FF0000) >> 16); + glStencilMask((regs.rb_stencilrefmask & 0x00FF0000) >> 16); // A2XX_RB_DEPTHCONTROL_BACKFACE_ENABLE - bool backface_enabled = (depth_control & 0x00000080) != 0; + bool backface_enabled = (regs.rb_depthcontrol & 0x00000080) != 0; if (backface_enabled) { // A2XX_RB_DEPTHCONTROL_STENCILFUNC - glStencilFuncSeparate(GL_FRONT, - compare_func_map[(depth_control & 0x00000700) >> 8], - stencil_ref, stencil_read_mask); + glStencilFuncSeparate( + GL_FRONT, compare_func_map[(regs.rb_depthcontrol & 0x00000700) >> 8], + stencil_ref, stencil_read_mask); // A2XX_RB_DEPTHCONTROL_STENCILFAIL // A2XX_RB_DEPTHCONTROL_STENCILZFAIL // A2XX_RB_DEPTHCONTROL_STENCILZPASS - glStencilOpSeparate(GL_FRONT, - stencil_op_map[(depth_control & 0x00003800) >> 11], - stencil_op_map[(depth_control & 0x000E0000) >> 17], - stencil_op_map[(depth_control & 0x0001C000) >> 14]); + glStencilOpSeparate( + GL_FRONT, stencil_op_map[(regs.rb_depthcontrol & 0x00003800) >> 11], + stencil_op_map[(regs.rb_depthcontrol & 0x000E0000) >> 17], + stencil_op_map[(regs.rb_depthcontrol & 0x0001C000) >> 14]); // A2XX_RB_DEPTHCONTROL_STENCILFUNC_BF - glStencilFuncSeparate(GL_BACK, - compare_func_map[(depth_control & 0x00700000) >> 20], - stencil_ref, stencil_read_mask); + glStencilFuncSeparate( + GL_BACK, compare_func_map[(regs.rb_depthcontrol & 0x00700000) >> 20], + stencil_ref, stencil_read_mask); // A2XX_RB_DEPTHCONTROL_STENCILFAIL_BF // A2XX_RB_DEPTHCONTROL_STENCILZFAIL_BF // A2XX_RB_DEPTHCONTROL_STENCILZPASS_BF - glStencilOpSeparate(GL_BACK, - stencil_op_map[(depth_control & 0x03800000) >> 23], - stencil_op_map[(depth_control & 0xE0000000) >> 29], - stencil_op_map[(depth_control & 0x1C000000) >> 26]); + glStencilOpSeparate( + GL_BACK, stencil_op_map[(regs.rb_depthcontrol & 0x03800000) >> 23], + stencil_op_map[(regs.rb_depthcontrol & 0xE0000000) >> 29], + stencil_op_map[(regs.rb_depthcontrol & 0x1C000000) >> 26]); } else { // Backfaces disabled - treat backfaces as frontfaces. - glStencilFunc(compare_func_map[(depth_control & 0x00000700) >> 8], + glStencilFunc(compare_func_map[(regs.rb_depthcontrol & 0x00000700) >> 8], stencil_ref, stencil_read_mask); - glStencilOp(stencil_op_map[(depth_control & 0x00003800) >> 11], - stencil_op_map[(depth_control & 0x000E0000) >> 17], - stencil_op_map[(depth_control & 0x0001C000) >> 14]); + glStencilOp(stencil_op_map[(regs.rb_depthcontrol & 0x00003800) >> 11], + stencil_op_map[(regs.rb_depthcontrol & 0x000E0000) >> 17], + stencil_op_map[(regs.rb_depthcontrol & 0x0001C000) >> 14]); } return true; @@ -1888,12 +1965,25 @@ bool CommandProcessor::UpdateConstants(DrawCommand* draw_command) { } bool CommandProcessor::UpdateShaders(DrawCommand* draw_command) { - SCOPE_profile_cpu_f("gpu"); - auto& regs = *register_file_; + auto& regs = update_shaders_regs_; auto& cmd = *draw_command; + bool dirty = false; + dirty |= SetShadowRegister(regs.sq_program_cntl, XE_GPU_REG_SQ_PROGRAM_CNTL); + dirty |= regs.vertex_shader != active_vertex_shader_; + dirty |= regs.pixel_shader != active_pixel_shader_; + dirty |= regs.prim_type != cmd.prim_type; + if (!dirty) { + return true; + } + regs.vertex_shader = active_vertex_shader_; + regs.pixel_shader = active_pixel_shader_; + regs.prim_type = cmd.prim_type; + + SCOPE_profile_cpu_f("gpu"); + xe_gpu_program_cntl_t program_cntl; - program_cntl.dword_0 = regs[XE_GPU_REG_SQ_PROGRAM_CNTL].u32; + program_cntl.dword_0 = regs.sq_program_cntl; if (!active_vertex_shader_->has_prepared()) { if (!active_vertex_shader_->PrepareVertexShader(program_cntl)) { XELOGE("Unable to prepare vertex shader"); @@ -1961,15 +2051,24 @@ bool CommandProcessor::UpdateShaders(DrawCommand* draw_command) { cached_pipeline->handles.quad_list_pipeline = pipelines[3]; } - // NOTE: we don't yet have our state data pointer - that comes at the end. - // We also don't know which configuration we want (based on prim type). - active_pipeline_ = cached_pipeline; + GLuint pipeline = cached_pipeline->handles.default_pipeline; + switch (regs.prim_type) { + case PrimitiveType::kPointList: + pipeline = cached_pipeline->handles.point_list_pipeline; + break; + case PrimitiveType::kRectangleList: + pipeline = cached_pipeline->handles.rect_list_pipeline; + break; + case PrimitiveType::kQuadList: + pipeline = cached_pipeline->handles.quad_list_pipeline; + break; + } + glBindProgramPipeline(pipeline); return true; } bool CommandProcessor::PopulateIndexBuffer(DrawCommand* draw_command) { - SCOPE_profile_cpu_f("gpu"); auto& cmd = *draw_command; auto& info = cmd.index_buffer; @@ -1978,6 +2077,8 @@ bool CommandProcessor::PopulateIndexBuffer(DrawCommand* draw_command) { return true; } + SCOPE_profile_cpu_f("gpu"); + assert_true(info.endianness == Endian::k8in16 || info.endianness == Endian::k8in32); @@ -2406,10 +2507,13 @@ bool CommandProcessor::IssueCopy(DrawCommand* draw_command) { GLint stencil = copy_depth_clear & 0xFF; // HACK: this should work, but throws INVALID_ENUM on nvidia drivers. // glClearNamedFramebufferfi(source_framebuffer->framebuffer, - // GL_DEPTH_STENCIL, - // depth, stencil); + // GL_DEPTH_STENCIL, + // depth, stencil); + GLint old_draw_framebuffer; + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &old_draw_framebuffer); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, source_framebuffer->framebuffer); glClearBufferfi(GL_DEPTH_STENCIL, 0, depth, stencil); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, old_draw_framebuffer); } return true; diff --git a/src/xenia/gpu/gl4/command_processor.h b/src/xenia/gpu/gl4/command_processor.h index 5a98fefaf..4f0fda8b8 100644 --- a/src/xenia/gpu/gl4/command_processor.h +++ b/src/xenia/gpu/gl4/command_processor.h @@ -237,6 +237,10 @@ class CommandProcessor { bool IssueDraw(DrawCommand* draw_command); bool UpdateRenderTargets(DrawCommand* draw_command); bool UpdateState(DrawCommand* draw_command); + bool UpdateViewportState(DrawCommand* draw_command); + bool UpdateRasterizerState(DrawCommand* draw_command); + bool UpdateBlendState(DrawCommand* draw_command); + bool UpdateDepthStencilState(DrawCommand* draw_command); bool UpdateConstants(DrawCommand* draw_command); bool UpdateShaders(DrawCommand* draw_command); bool PopulateIndexBuffer(DrawCommand* draw_command); @@ -287,7 +291,6 @@ class CommandProcessor { std::unordered_map shader_cache_; GL4Shader* active_vertex_shader_; GL4Shader* active_pixel_shader_; - CachedPipeline* active_pipeline_; CachedFramebuffer* active_framebuffer_; std::vector cached_framebuffers_; @@ -303,6 +306,68 @@ class CommandProcessor { CircularBuffer scratch_buffer_; DrawCommand draw_command_; + + private: + bool SetShadowRegister(uint32_t& dest, uint32_t register_name); + bool SetShadowRegister(float& dest, uint32_t register_name); + struct UpdateRenderTargetsRegisters { + uint32_t rb_modecontrol; + uint32_t rb_surface_info; + uint32_t rb_color_info; + uint32_t rb_color1_info; + uint32_t rb_color2_info; + uint32_t rb_color3_info; + uint32_t rb_color_mask; + uint32_t rb_depthcontrol; + uint32_t rb_stencilrefmask; + uint32_t rb_depth_info; + + UpdateRenderTargetsRegisters() { Reset(); } + void Reset() { std::memset(this, 0, sizeof(*this)); } + } update_render_targets_regs_; + struct UpdateViewportStateRegisters { + // + UpdateViewportStateRegisters() { Reset(); } + void Reset() { std::memset(this, 0, sizeof(*this)); } + } update_viewport_state_regs_; + struct UpdateRasterizerStateRegisters { + uint32_t pa_su_sc_mode_cntl; + uint32_t pa_sc_screen_scissor_tl; + uint32_t pa_sc_screen_scissor_br; + + UpdateRasterizerStateRegisters() { Reset(); } + void Reset() { std::memset(this, 0, sizeof(*this)); } + } update_rasterizer_state_regs_; + struct UpdateBlendStateRegisters { + uint32_t rb_blendcontrol[4]; + float rb_blend_rgba[4]; + + UpdateBlendStateRegisters() { Reset(); } + void Reset() { std::memset(this, 0, sizeof(*this)); } + } update_blend_state_regs_; + struct UpdateDepthStencilStateRegisters { + uint32_t rb_depthcontrol; + uint32_t rb_stencilrefmask; + + UpdateDepthStencilStateRegisters() { Reset(); } + void Reset() { std::memset(this, 0, sizeof(*this)); } + } update_depth_stencil_state_regs_; + // TODO(benvanik): constant bitmask? + struct UpdateShadersRegisters { + PrimitiveType prim_type; + uint32_t sq_program_cntl; + GL4Shader* vertex_shader; + GL4Shader* pixel_shader; + + UpdateShadersRegisters() { Reset(); } + void Reset() { + sq_program_cntl = 0; + vertex_shader = pixel_shader = nullptr; + } + } update_shaders_regs_; + // ib + // vb + // samplers }; } // namespace gl4 diff --git a/src/xenia/gpu/gl4/wgl_control.cc b/src/xenia/gpu/gl4/wgl_control.cc index ce02f7b2f..6a83c1b38 100644 --- a/src/xenia/gpu/gl4/wgl_control.cc +++ b/src/xenia/gpu/gl4/wgl_control.cc @@ -93,15 +93,6 @@ LRESULT WGLControl::WndProc(HWND hWnd, UINT message, WPARAM wParam, // TODO(benvanik): profiler present. Profiler::Present(); - - // Hacky swap timer. - static int swap_count = 0; - glEnable(GL_SCISSOR_TEST); - glScissor(0, 0, 20, 20); - float red[] = {swap_count / 60.0f, 0, 0, 1.0f}; - swap_count = (swap_count + 1) % 60; - glClearNamedFramebufferfv(0, GL_COLOR, 0, red); - glDisable(GL_SCISSOR_TEST); } { SCOPE_profile_cpu_i("gpu", "xe::gpu::gl4::WGLControl::SwapBuffers"); diff --git a/src/xenia/profiling.cc b/src/xenia/profiling.cc index 2602a1491..f60a2a6ce 100644 --- a/src/xenia/profiling.cc +++ b/src/xenia/profiling.cc @@ -15,7 +15,7 @@ #define MICROPROFILEUI_IMPL 1 #define MICROPROFILE_PER_THREAD_BUFFER_SIZE (1024 * 1024 * 10) #define MICROPROFILE_USE_THREAD_NAME_CALLBACK 1 -#define MICROPROFILE_WEBSERVER_MAXFRAMES 10 +#define MICROPROFILE_WEBSERVER_MAXFRAMES 3 #define MICROPROFILE_PRINTF PLOGI #define MICROPROFILE_WEBSERVER 1 #define MICROPROFILE_DEBUG 0 From 3e61cc95cd5c8cf6caeb0893d1ccbc20c5976b7f Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 3 Jan 2015 03:19:32 -0800 Subject: [PATCH 315/388] Tracking whether state changes are compatible for batching. --- src/xenia/gpu/gl4/command_processor.cc | 190 +++++++++++++++---------- src/xenia/gpu/gl4/command_processor.h | 32 +++-- 2 files changed, 132 insertions(+), 90 deletions(-) diff --git a/src/xenia/gpu/gl4/command_processor.cc b/src/xenia/gpu/gl4/command_processor.cc index 2113dac23..3b8730dab 100644 --- a/src/xenia/gpu/gl4/command_processor.cc +++ b/src/xenia/gpu/gl4/command_processor.cc @@ -1362,41 +1362,42 @@ bool CommandProcessor::IssueDraw(DrawCommand* draw_command) { return false; } - if (!UpdateShaders(draw_command)) { - PLOGE("Unable to prepare draw shaders"); - return false; - } - if (!UpdateRenderTargets(draw_command)) { - PLOGE("Unable to setup render targets"); - return false; +#define CHECK_ISSUE_UPDATE_STATUS(status, mismatch, error_message) \ + { \ + if (status == UpdateStatus::kError) { \ + PLOGE(error_message); \ + return false; \ + } else if (status == UpdateStatus::kMismatch) { \ + mismatch = true; \ + } \ } + + UpdateStatus status; + bool mismatch = false; + status = UpdateShaders(draw_command); + CHECK_ISSUE_UPDATE_STATUS(status, mismatch, "Unable to prepare draw shaders"); + status = UpdateRenderTargets(draw_command); + CHECK_ISSUE_UPDATE_STATUS(status, mismatch, "Unable to setup render targets"); if (!active_framebuffer_) { // No framebuffer, so nothing we do will actually have an effect. // Treat it as a no-op. XETRACECP("No-op draw (no framebuffer set)"); return true; } - if (!UpdateState(draw_command)) { - PLOGE("Unable to setup render state"); - return false; - } - if (!UpdateConstants(draw_command)) { - PLOGE("Unable to update shader constants"); - return false; - } - if (!PopulateIndexBuffer(draw_command)) { - PLOGE("Unable to setup index buffer"); - return false; - } - if (!PopulateVertexBuffers(draw_command)) { - PLOGE("Unable to setup vertex buffers"); - return false; - } - if (!PopulateSamplers(draw_command)) { - PLOGE("Unable to prepare draw samplers"); - return false; - } + status = UpdateState(draw_command); + CHECK_ISSUE_UPDATE_STATUS(status, mismatch, "Unable to setup render state"); + status = UpdateConstants(draw_command); + CHECK_ISSUE_UPDATE_STATUS(status, mismatch, + "Unable to update shader constants"); + status = PopulateSamplers(draw_command); + CHECK_ISSUE_UPDATE_STATUS(status, mismatch, + "Unable to prepare draw samplers"); + + status = PopulateIndexBuffer(draw_command); + CHECK_ISSUE_UPDATE_STATUS(status, mismatch, "Unable to setup index buffer"); + status = PopulateVertexBuffers(draw_command); + CHECK_ISSUE_UPDATE_STATUS(status, mismatch, "Unable to setup vertex buffers"); GLenum prim_type = 0; switch (cmd.prim_type) { @@ -1481,7 +1482,8 @@ bool CommandProcessor::SetShadowRegister(float& dest, uint32_t register_name) { return true; } -bool CommandProcessor::UpdateRenderTargets(DrawCommand* draw_command) { +CommandProcessor::UpdateStatus CommandProcessor::UpdateRenderTargets( + DrawCommand* draw_command) { auto& regs = update_render_targets_regs_; bool dirty = false; @@ -1497,7 +1499,7 @@ bool CommandProcessor::UpdateRenderTargets(DrawCommand* draw_command) { SetShadowRegister(regs.rb_stencilrefmask, XE_GPU_REG_RB_STENCILREFMASK); dirty |= SetShadowRegister(regs.rb_depth_info, XE_GPU_REG_RB_DEPTH_INFO); if (!dirty) { - return true; + return UpdateStatus::kCompatible; } SCOPE_profile_cpu_f("gpu"); @@ -1574,14 +1576,16 @@ bool CommandProcessor::UpdateRenderTargets(DrawCommand* draw_command) { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, cached_framebuffer->framebuffer); } - return true; + return UpdateStatus::kMismatch; } -bool CommandProcessor::UpdateState(DrawCommand* draw_command) { - SCOPE_profile_cpu_f("gpu"); +CommandProcessor::UpdateStatus CommandProcessor::UpdateState( + DrawCommand* draw_command) { auto& regs = *register_file_; auto state_data = draw_command->state_data; + bool mismatch = false; + // Alpha testing -- ALPHAREF, ALPHAFUNC, ALPHATESTENABLE // Deprecated in GL, implemented in shader. // if(ALPHATESTENABLE && frag_out.a [<=/ALPHAFUNC] ALPHAREF) discard; @@ -1591,19 +1595,35 @@ bool CommandProcessor::UpdateState(DrawCommand* draw_command) { state_data->alpha_test.y = float(color_control & 0x3); // ALPHAFUNC state_data->alpha_test.z = regs[XE_GPU_REG_RB_ALPHA_REF].f32; - UpdateViewportState(draw_command); - UpdateRasterizerState(draw_command); - UpdateBlendState(draw_command); - UpdateDepthStencilState(draw_command); +#define CHECK_UPDATE_STATUS(status, mismatch, error_message) \ + { \ + if (status == UpdateStatus::kError) { \ + PLOGE(error_message); \ + return status; \ + } else if (status == UpdateStatus::kMismatch) { \ + mismatch = true; \ + } \ + } - return true; + UpdateStatus status; + status = UpdateViewportState(draw_command); + CHECK_UPDATE_STATUS(status, mismatch, "Unable to update viewport state"); + status = UpdateRasterizerState(draw_command); + CHECK_UPDATE_STATUS(status, mismatch, "Unable to update rasterizer state"); + status = UpdateBlendState(draw_command); + CHECK_UPDATE_STATUS(status, mismatch, "Unable to update blend state"); + status = UpdateDepthStencilState(draw_command); + CHECK_UPDATE_STATUS(status, mismatch, "Unable to update depth/stencil state"); + + return mismatch ? UpdateStatus::kMismatch : UpdateStatus::kCompatible; } -bool CommandProcessor::UpdateViewportState(DrawCommand* draw_command) { +CommandProcessor::UpdateStatus CommandProcessor::UpdateViewportState( + DrawCommand* draw_command) { auto& regs = *register_file_; auto state_data = draw_command->state_data; - SCOPE_profile_cpu_f("gpu"); + // NOTE: we don't track state here as this is all cheap to update (ish). // Much of this state machine is extracted from: // https://github.com/freedreno/mesa/blob/master/src/mesa/drivers/dri/r200/r200_state.c @@ -1701,10 +1721,11 @@ bool CommandProcessor::UpdateViewportState(DrawCommand* draw_command) { bool dx_clip = ((clip_control >> 20) & 0x1) == 0x1; // assert_true(dx_clip); - return true; + return UpdateStatus::kCompatible; } -bool CommandProcessor::UpdateRasterizerState(DrawCommand* draw_command) { +CommandProcessor::UpdateStatus CommandProcessor::UpdateRasterizerState( + DrawCommand* draw_command) { auto& regs = update_rasterizer_state_regs_; bool dirty = false; @@ -1715,7 +1736,7 @@ bool CommandProcessor::UpdateRasterizerState(DrawCommand* draw_command) { dirty |= SetShadowRegister(regs.pa_sc_screen_scissor_br, XE_GPU_REG_PA_SC_SCREEN_SCISSOR_BR); if (!dirty) { - return true; + return UpdateStatus::kCompatible; } SCOPE_profile_cpu_f("gpu"); @@ -1765,10 +1786,11 @@ bool CommandProcessor::UpdateRasterizerState(DrawCommand* draw_command) { // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - return true; + return UpdateStatus::kMismatch; } -bool CommandProcessor::UpdateBlendState(DrawCommand* draw_command) { +CommandProcessor::UpdateStatus CommandProcessor::UpdateBlendState( + DrawCommand* draw_command) { auto& regs = update_blend_state_regs_; bool dirty = false; @@ -1785,7 +1807,7 @@ bool CommandProcessor::UpdateBlendState(DrawCommand* draw_command) { dirty |= SetShadowRegister(regs.rb_blend_rgba[2], XE_GPU_REG_RB_BLEND_BLUE); dirty |= SetShadowRegister(regs.rb_blend_rgba[3], XE_GPU_REG_RB_BLEND_ALPHA); if (!dirty) { - return true; + return UpdateStatus::kCompatible; } SCOPE_profile_cpu_f("gpu"); @@ -1849,10 +1871,11 @@ bool CommandProcessor::UpdateBlendState(DrawCommand* draw_command) { glBlendColor(regs.rb_blend_rgba[0], regs.rb_blend_rgba[1], regs.rb_blend_rgba[2], regs.rb_blend_rgba[3]); - return true; + return UpdateStatus::kMismatch; } -bool CommandProcessor::UpdateDepthStencilState(DrawCommand* draw_command) { +CommandProcessor::UpdateStatus CommandProcessor::UpdateDepthStencilState( + DrawCommand* draw_command) { auto& regs = update_depth_stencil_state_regs_; bool dirty = false; @@ -1860,7 +1883,7 @@ bool CommandProcessor::UpdateDepthStencilState(DrawCommand* draw_command) { dirty |= SetShadowRegister(regs.rb_stencilrefmask, XE_GPU_REG_RB_STENCILREFMASK); if (!dirty) { - return true; + return UpdateStatus::kCompatible; } SCOPE_profile_cpu_f("gpu"); @@ -1943,10 +1966,11 @@ bool CommandProcessor::UpdateDepthStencilState(DrawCommand* draw_command) { stencil_op_map[(regs.rb_depthcontrol & 0x0001C000) >> 14]); } - return true; + return UpdateStatus::kMismatch; } -bool CommandProcessor::UpdateConstants(DrawCommand* draw_command) { +CommandProcessor::UpdateStatus CommandProcessor::UpdateConstants( + DrawCommand* draw_command) { auto& regs = *register_file_; auto state_data = draw_command->state_data; @@ -1961,10 +1985,11 @@ bool CommandProcessor::UpdateConstants(DrawCommand* draw_command) { sizeof(state_data->float_consts) + sizeof(state_data->fetch_consts) + sizeof(state_data->loop_consts) + sizeof(state_data->bool_consts)); - return true; + return UpdateStatus::kCompatible; } -bool CommandProcessor::UpdateShaders(DrawCommand* draw_command) { +CommandProcessor::UpdateStatus CommandProcessor::UpdateShaders( + DrawCommand* draw_command) { auto& regs = update_shaders_regs_; auto& cmd = *draw_command; @@ -1974,7 +1999,7 @@ bool CommandProcessor::UpdateShaders(DrawCommand* draw_command) { dirty |= regs.pixel_shader != active_pixel_shader_; dirty |= regs.prim_type != cmd.prim_type; if (!dirty) { - return true; + return UpdateStatus::kCompatible; } regs.vertex_shader = active_vertex_shader_; regs.pixel_shader = active_pixel_shader_; @@ -1987,21 +2012,21 @@ bool CommandProcessor::UpdateShaders(DrawCommand* draw_command) { if (!active_vertex_shader_->has_prepared()) { if (!active_vertex_shader_->PrepareVertexShader(program_cntl)) { XELOGE("Unable to prepare vertex shader"); - return false; + return UpdateStatus::kError; } } else if (!active_vertex_shader_->is_valid()) { XELOGE("Vertex shader invalid"); - return false; + return UpdateStatus::kError; } if (!active_pixel_shader_->has_prepared()) { if (!active_pixel_shader_->PreparePixelShader(program_cntl)) { XELOGE("Unable to prepare pixel shader"); - return false; + return UpdateStatus::kError; } } else if (!active_pixel_shader_->is_valid()) { XELOGE("Pixel shader invalid"); - return false; + return UpdateStatus::kError; } GLuint vertex_program = active_vertex_shader_->program(); @@ -2065,16 +2090,17 @@ bool CommandProcessor::UpdateShaders(DrawCommand* draw_command) { } glBindProgramPipeline(pipeline); - return true; + return UpdateStatus::kMismatch; } -bool CommandProcessor::PopulateIndexBuffer(DrawCommand* draw_command) { +CommandProcessor::UpdateStatus CommandProcessor::PopulateIndexBuffer( + DrawCommand* draw_command) { auto& cmd = *draw_command; auto& info = cmd.index_buffer; if (!cmd.index_count || !info.address) { // No index buffer or auto draw. - return true; + return UpdateStatus::kMismatch; // ? } SCOPE_profile_cpu_f("gpu"); @@ -2109,10 +2135,11 @@ bool CommandProcessor::PopulateIndexBuffer(DrawCommand* draw_command) { } scratch_buffer_.Commit(std::move(allocation)); - return true; + return UpdateStatus::kMismatch; } -bool CommandProcessor::PopulateVertexBuffers(DrawCommand* draw_command) { +CommandProcessor::UpdateStatus CommandProcessor::PopulateVertexBuffers( + DrawCommand* draw_command) { SCOPE_profile_cpu_f("gpu"); auto& regs = *register_file_; auto& cmd = *draw_command; @@ -2235,13 +2262,16 @@ bool CommandProcessor::PopulateVertexBuffers(DrawCommand* draw_command) { scratch_buffer_.Commit(std::move(allocation)); } - return true; + return UpdateStatus::kMismatch; } -bool CommandProcessor::PopulateSamplers(DrawCommand* draw_command) { +CommandProcessor::UpdateStatus CommandProcessor::PopulateSamplers( + DrawCommand* draw_command) { SCOPE_profile_cpu_f("gpu"); auto& regs = *register_file_; + bool mismatch = false; + // VS and PS samplers are shared, but may be used exclusively. // We walk each and setup lazily. bool has_setup_sampler[32] = {false}; @@ -2254,8 +2284,11 @@ bool CommandProcessor::PopulateSamplers(DrawCommand* draw_command) { continue; } has_setup_sampler[desc.fetch_slot] = true; - if (!PopulateSampler(draw_command, desc)) { - return false; + auto status = PopulateSampler(draw_command, desc); + if (status == UpdateStatus::kError) { + return status; + } else if (status == UpdateStatus::kMismatch) { + mismatch = true; } } @@ -2267,16 +2300,19 @@ bool CommandProcessor::PopulateSamplers(DrawCommand* draw_command) { continue; } has_setup_sampler[desc.fetch_slot] = true; - if (!PopulateSampler(draw_command, desc)) { - return false; + auto status = PopulateSampler(draw_command, desc); + if (status == UpdateStatus::kError) { + return UpdateStatus::kError; + } else if (status == UpdateStatus::kMismatch) { + mismatch = true; } } - return true; + return mismatch ? UpdateStatus::kMismatch : UpdateStatus::kCompatible; } -bool CommandProcessor::PopulateSampler(DrawCommand* draw_command, - const Shader::SamplerDesc& desc) { +CommandProcessor::UpdateStatus CommandProcessor::PopulateSampler( + DrawCommand* draw_command, const Shader::SamplerDesc& desc) { auto& regs = *register_file_; int r = XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 + desc.fetch_slot * 6; auto group = reinterpret_cast(®s.values[r]); @@ -2287,38 +2323,38 @@ bool CommandProcessor::PopulateSampler(DrawCommand* draw_command, draw_command->state_data->texture_samplers[desc.fetch_slot] = 0; if (FLAGS_disable_textures) { - return true; + return UpdateStatus::kCompatible; } // ? if (!fetch.type) { - return true; + return UpdateStatus::kCompatible; } assert_true(fetch.type == 0x2); TextureInfo texture_info; if (!TextureInfo::Prepare(fetch, &texture_info)) { XELOGE("Unable to parse texture fetcher info"); - return true; // invalid texture used + return UpdateStatus::kCompatible; // invalid texture used } SamplerInfo sampler_info; if (!SamplerInfo::Prepare(fetch, desc.tex_fetch, &sampler_info)) { XELOGE("Unable to parse sampler info"); - return true; // invalid texture used + return UpdateStatus::kCompatible; // invalid texture used } auto entry_view = texture_cache_.Demand(texture_info, sampler_info); if (!entry_view) { // Unable to create/fetch/etc. XELOGE("Failed to demand texture"); - return true; + return UpdateStatus::kCompatible; } // Shaders will use bindless to fetch right from it. draw_command->state_data->texture_samplers[desc.fetch_slot] = entry_view->texture_sampler_handle; - return true; + return UpdateStatus::kCompatible; } bool CommandProcessor::IssueCopy(DrawCommand* draw_command) { diff --git a/src/xenia/gpu/gl4/command_processor.h b/src/xenia/gpu/gl4/command_processor.h index 4f0fda8b8..2433e964e 100644 --- a/src/xenia/gpu/gl4/command_processor.h +++ b/src/xenia/gpu/gl4/command_processor.h @@ -129,6 +129,12 @@ class CommandProcessor { private: class RingbufferReader; + enum class UpdateStatus { + kCompatible, + kMismatch, + kError, + }; + struct CachedFramebuffer { GLuint color_targets[4]; GLuint depth_target; @@ -235,19 +241,19 @@ class CommandProcessor { void PrepareDraw(DrawCommand* draw_command); bool IssueDraw(DrawCommand* draw_command); - bool UpdateRenderTargets(DrawCommand* draw_command); - bool UpdateState(DrawCommand* draw_command); - bool UpdateViewportState(DrawCommand* draw_command); - bool UpdateRasterizerState(DrawCommand* draw_command); - bool UpdateBlendState(DrawCommand* draw_command); - bool UpdateDepthStencilState(DrawCommand* draw_command); - bool UpdateConstants(DrawCommand* draw_command); - bool UpdateShaders(DrawCommand* draw_command); - bool PopulateIndexBuffer(DrawCommand* draw_command); - bool PopulateVertexBuffers(DrawCommand* draw_command); - bool PopulateSamplers(DrawCommand* draw_command); - bool PopulateSampler(DrawCommand* draw_command, - const Shader::SamplerDesc& desc); + UpdateStatus UpdateRenderTargets(DrawCommand* draw_command); + UpdateStatus UpdateState(DrawCommand* draw_command); + UpdateStatus UpdateViewportState(DrawCommand* draw_command); + UpdateStatus UpdateRasterizerState(DrawCommand* draw_command); + UpdateStatus UpdateBlendState(DrawCommand* draw_command); + UpdateStatus UpdateDepthStencilState(DrawCommand* draw_command); + UpdateStatus UpdateConstants(DrawCommand* draw_command); + UpdateStatus UpdateShaders(DrawCommand* draw_command); + UpdateStatus PopulateIndexBuffer(DrawCommand* draw_command); + UpdateStatus PopulateVertexBuffers(DrawCommand* draw_command); + UpdateStatus PopulateSamplers(DrawCommand* draw_command); + UpdateStatus PopulateSampler(DrawCommand* draw_command, + const Shader::SamplerDesc& desc); bool IssueCopy(DrawCommand* draw_command); CachedFramebuffer* GetFramebuffer(GLuint color_targets[4], From 76c41edfd68eb2c88e68d24673ee376ae5952855 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 3 Jan 2015 03:42:27 -0800 Subject: [PATCH 316/388] Thread names. --- src/xenia/apu/audio_system.cc | 4 ++-- src/xenia/gpu/xenos.h | 1 + src/xenia/ui/main_window.cc | 3 +++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/xenia/apu/audio_system.cc b/src/xenia/apu/audio_system.cc index 8a8e30fa7..f6e6c9ecf 100644 --- a/src/xenia/apu/audio_system.cc +++ b/src/xenia/apu/audio_system.cc @@ -62,8 +62,8 @@ X_STATUS AudioSystem::Setup() { } void AudioSystem::ThreadStart() { - poly::threading::set_name("AudioSystemThread"); - xe::Profiler::ThreadEnter("AudioSystemThread"); + poly::threading::set_name("Audio Worker"); + xe::Profiler::ThreadEnter("Audio Worker"); // Initialize driver and ringbuffer. Initialize(); diff --git a/src/xenia/gpu/xenos.h b/src/xenia/gpu/xenos.h index 0c3d75fca..77e9b766a 100644 --- a/src/xenia/gpu/xenos.h +++ b/src/xenia/gpu/xenos.h @@ -33,6 +33,7 @@ enum class PrimitiveType : uint32_t { kRectangleList = 0x08, kLineLoop = 0x0C, kQuadList = 0x0D, + kQuadStrip = 0x0E, }; enum class Dimension : uint32_t { diff --git a/src/xenia/ui/main_window.cc b/src/xenia/ui/main_window.cc index 381cdfd3d..059d5d9f7 100644 --- a/src/xenia/ui/main_window.cc +++ b/src/xenia/ui/main_window.cc @@ -25,6 +25,9 @@ void MainWindow::Start() { poly::threading::Fence fence; loop_.Post([&]() { + poly::threading::set_name("Win32 Loop"); + xe::Profiler::ThreadEnter("Win32 Loop"); + if (!Initialize()) { PFATAL("Failed to initialize main window"); exit(1); From 70c0c0fea12b658fd97dc4fb28acec705b1d53e4 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 3 Jan 2015 13:40:20 -0800 Subject: [PATCH 317/388] Adding --vendor_gl_extensions flag to disable NV stuff. --- src/xenia/gpu/gl4/circular_buffer.cc | 5 +++-- src/xenia/gpu/gl4/command_processor.cc | 8 ++++++-- src/xenia/gpu/gl4/gl4_gpu-private.h | 2 ++ src/xenia/gpu/gl4/gl4_gpu.cc | 3 +++ 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/xenia/gpu/gl4/circular_buffer.cc b/src/xenia/gpu/gl4/circular_buffer.cc index 537cd5604..e33677406 100644 --- a/src/xenia/gpu/gl4/circular_buffer.cc +++ b/src/xenia/gpu/gl4/circular_buffer.cc @@ -11,6 +11,7 @@ #include #include +#include #include namespace xe { @@ -44,7 +45,7 @@ bool CircularBuffer::Initialize() { return false; } - if (GLEW_NV_shader_buffer_load) { + if (FLAGS_vendor_gl_extensions && GLEW_NV_shader_buffer_load) { // To use this bindlessly we must make it resident. glMakeNamedBufferResidentNV(buffer_, GL_WRITE_ONLY); glGetNamedBufferParameterui64vNV(buffer_, GL_BUFFER_GPU_ADDRESS_NV, @@ -58,7 +59,7 @@ void CircularBuffer::Shutdown() { return; } glUnmapNamedBuffer(buffer_); - if (GLEW_NV_shader_buffer_load) { + if (FLAGS_vendor_gl_extensions && GLEW_NV_shader_buffer_load) { glMakeNamedBufferNonResidentNV(buffer_); } glDeleteBuffers(1, &buffer_); diff --git a/src/xenia/gpu/gl4/command_processor.cc b/src/xenia/gpu/gl4/command_processor.cc index 3b8730dab..61d3f283f 100644 --- a/src/xenia/gpu/gl4/command_processor.cc +++ b/src/xenia/gpu/gl4/command_processor.cc @@ -181,11 +181,16 @@ bool CommandProcessor::SetupGL() { glGenVertexArrays(1, &vertex_array_); glBindVertexArray(vertex_array_); - if (GLEW_NV_vertex_buffer_unified_memory) { + if (FLAGS_vendor_gl_extensions && GLEW_NV_vertex_buffer_unified_memory) { has_bindless_vbos_ = true; glEnableClientState(GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV); glEnableClientState(GL_ELEMENT_ARRAY_UNIFIED_NV); } + GLint max_vertex_attribs = 0; + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_vertex_attribs); + for (GLint i = 0; i < max_vertex_attribs; ++i) { + glEnableVertexAttribArray(i); + } const std::string geometry_header = "#version 450\n" @@ -2242,7 +2247,6 @@ CommandProcessor::UpdateStatus CommandProcessor::PopulateVertexBuffers( assert_unhandled_case(el.format); break; } - glEnableVertexAttribArray(el_index); if (has_bindless_vbos_) { glVertexAttribFormatNV(el_index, comp_count, comp_type, el.is_normalized, diff --git a/src/xenia/gpu/gl4/gl4_gpu-private.h b/src/xenia/gpu/gl4/gl4_gpu-private.h index 065e0e327..73937bee4 100644 --- a/src/xenia/gpu/gl4/gl4_gpu-private.h +++ b/src/xenia/gpu/gl4/gl4_gpu-private.h @@ -20,6 +20,8 @@ DECLARE_bool(thread_safe_gl); DECLARE_bool(gl_debug_output); DECLARE_bool(gl_debug_output_synchronous); +DECLARE_bool(vendor_gl_extensions); + DECLARE_bool(disable_textures); namespace xe { diff --git a/src/xenia/gpu/gl4/gl4_gpu.cc b/src/xenia/gpu/gl4/gl4_gpu.cc index d9f248d0f..3f9ef960d 100644 --- a/src/xenia/gpu/gl4/gl4_gpu.cc +++ b/src/xenia/gpu/gl4/gl4_gpu.cc @@ -19,6 +19,9 @@ DEFINE_bool(gl_debug_output, false, "Dump ARB_debug_output to stderr."); DEFINE_bool(gl_debug_output_synchronous, true, "ARB_debug_output will synchronize to be thread safe."); +DEFINE_bool(vendor_gl_extensions, true, + "Enable vendor-specific (NV, AMD, etc) GL extensions."); + DEFINE_bool(disable_textures, false, "Disable textures and use colors only."); namespace xe { From 2a082ff2425505eb965cd9ce6f7a1716a63f694c Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 3 Jan 2015 13:50:11 -0800 Subject: [PATCH 318/388] Tracking bytes used in the scratch buffer. --- src/xenia/gpu/gl4/command_processor.cc | 3 +++ src/xenia/gpu/gl4/command_processor.h | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/src/xenia/gpu/gl4/command_processor.cc b/src/xenia/gpu/gl4/command_processor.cc index 61d3f283f..92978df92 100644 --- a/src/xenia/gpu/gl4/command_processor.cc +++ b/src/xenia/gpu/gl4/command_processor.cc @@ -1361,6 +1361,7 @@ bool CommandProcessor::IssueDraw(DrawCommand* draw_command) { // Allocate a state data block. // Everything the shaders access lives here. auto allocation = scratch_buffer_.Acquire(sizeof(UniformDataBlock)); + scratch_buffer_stats_.total_state_data_size += sizeof(UniformDataBlock); cmd.state_data = reinterpret_cast(allocation.host_ptr); if (!cmd.state_data) { PLOGE("Unable to allocate uniform data buffer"); @@ -2117,6 +2118,7 @@ CommandProcessor::UpdateStatus CommandProcessor::PopulateIndexBuffer( cmd.index_count * (info.format == IndexFormat::kInt32 ? sizeof(uint32_t) : sizeof(uint16_t)); auto allocation = scratch_buffer_.Acquire(total_size); + scratch_buffer_stats_.total_indices_size += total_size; if (info.format == IndexFormat::kInt32) { poly::copy_and_swap_32_aligned( @@ -2177,6 +2179,7 @@ CommandProcessor::UpdateStatus CommandProcessor::PopulateVertexBuffers( assert_not_zero(fetch->size); auto allocation = scratch_buffer_.Acquire(fetch->size * sizeof(uint32_t)); + scratch_buffer_stats_.total_vertices_size += fetch->size * sizeof(uint32_t); // Copy and byte swap the entire buffer. // We could be smart about this to save GPU bandwidth by building a CRC diff --git a/src/xenia/gpu/gl4/command_processor.h b/src/xenia/gpu/gl4/command_processor.h index 2433e964e..5962fb212 100644 --- a/src/xenia/gpu/gl4/command_processor.h +++ b/src/xenia/gpu/gl4/command_processor.h @@ -308,8 +308,15 @@ class CommandProcessor { GLuint point_list_geometry_program_; GLuint rect_list_geometry_program_; GLuint quad_list_geometry_program_; + TextureCache texture_cache_; + CircularBuffer scratch_buffer_; + struct ScratchBufferStats { + size_t total_state_data_size = 0; + size_t total_indices_size = 0; + size_t total_vertices_size = 0; + } scratch_buffer_stats_; DrawCommand draw_command_; From 56a04592d58969694d966d5326cb592cf0d3040e Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 3 Jan 2015 13:59:31 -0800 Subject: [PATCH 319/388] Removing fetch consts from state data. --- src/xenia/gpu/gl4/command_processor.cc | 12 +++++++---- src/xenia/gpu/gl4/command_processor.h | 28 ++++++++++++++------------ 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/xenia/gpu/gl4/command_processor.cc b/src/xenia/gpu/gl4/command_processor.cc index 92978df92..460f6df29 100644 --- a/src/xenia/gpu/gl4/command_processor.cc +++ b/src/xenia/gpu/gl4/command_processor.cc @@ -1646,7 +1646,8 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateViewportState( state_data->window_offset.x = float(window_offset & 0x7FFF); state_data->window_offset.y = float((window_offset >> 16) & 0x7FFF); } else { - state_data->window_offset.x = state_data->window_offset.y = 0; + state_data->window_offset.x = 0; + state_data->window_offset.y = 0; } uint32_t window_scissor_tl = regs[XE_GPU_REG_PA_SC_WINDOW_SCISSOR_TL].u32; uint32_t window_scissor_br = regs[XE_GPU_REG_PA_SC_WINDOW_SCISSOR_BR].u32; @@ -1986,10 +1987,13 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateConstants( // down on state block sizes. // Copy over all constants. + std::memcpy(&state_data->float_consts, + ®s[XE_GPU_REG_SHADER_CONSTANT_000_X].f32, + sizeof(state_data->float_consts)); std::memcpy( - &state_data->float_consts, ®s[XE_GPU_REG_SHADER_CONSTANT_000_X].f32, - sizeof(state_data->float_consts) + sizeof(state_data->fetch_consts) + - sizeof(state_data->loop_consts) + sizeof(state_data->bool_consts)); + &state_data->bool_consts, + ®s[XE_GPU_REG_SHADER_CONSTANT_BOOL_000_031].f32, + sizeof(state_data->bool_consts) + sizeof(state_data->loop_consts)); return UpdateStatus::kCompatible; } diff --git a/src/xenia/gpu/gl4/command_processor.h b/src/xenia/gpu/gl4/command_processor.h index 5962fb212..d1cdcd141 100644 --- a/src/xenia/gpu/gl4/command_processor.h +++ b/src/xenia/gpu/gl4/command_processor.h @@ -50,8 +50,8 @@ struct UniformDataBlock { }; }; - float4 window_offset; // tx,ty,sx,sy - float4 window_scissor; // x0,y0,x1,y1 + float4 window_offset; // tx,ty,sx,sy + float4 window_scissor; // x0,y0,x1,y1 float4 vtx_fmt; float4 viewport_offset; // tx,ty,tz,? float4 viewport_scale; // sx,sy,sz,? @@ -59,21 +59,22 @@ struct UniformDataBlock { float4 alpha_test; // alpha test enable, func, ref, ? - // TODO(benvanik): overlay with fetch_consts below? + // TODO(benvanik): pack tightly uint64_t texture_samplers[32]; // Register data from 0x4000 to 0x4927. - // SHADER_CONSTANT_000_X... - float4 float_consts[512]; - // SHADER_CONSTANT_FETCH_00_0... - uint32_t fetch_consts[32 * 6]; - // SHADER_CONSTANT_BOOL_000_031... - int32_t bool_consts[8]; - // SHADER_CONSTANT_LOOP_00... - int32_t loop_consts[32]; + // UpdateConstants relies on the packing of these. + struct { + // SHADER_CONSTANT_000_X... + float4 float_consts[512]; + // SHADER_CONSTANT_FETCH_00_0 is omitted + // SHADER_CONSTANT_BOOL_000_031... + int32_t bool_consts[8]; + // SHADER_CONSTANT_LOOP_00... + int32_t loop_consts[32]; + }; }; -static_assert(sizeof(UniformDataBlock) <= 16 * 1024, - "Need <=16k uniform data"); +static_assert(sizeof(UniformDataBlock) <= 16 * 1024, "Need <=16k uniform data"); // TODO(benvanik): move more of the enums in here? struct DrawCommand { @@ -103,6 +104,7 @@ struct DrawCommand { SamplerInput vertex_shader_samplers[32]; SamplerInput pixel_shader_samplers[32]; + // NOTE: do not read from this - the mapped memory is likely write combined. UniformDataBlock* state_data; }; From 34fb0e4a8a59d29eab3fcb15f2af760ae81ee896 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 4 Jan 2015 04:57:40 -0800 Subject: [PATCH 320/388] Optionally track max value seen during copy. --- src/poly/memory.cc | 74 +++++++++++++++++++++++++++++++--------------- src/poly/memory.h | 21 +++++++------ 2 files changed, 62 insertions(+), 33 deletions(-) diff --git a/src/poly/memory.cc b/src/poly/memory.cc index d4360abe7..0f6e47f1c 100644 --- a/src/poly/memory.cc +++ b/src/poly/memory.cc @@ -9,6 +9,8 @@ #include +#include + #if !XE_LIKE_WIN32 #include #endif // !XE_LIKE_WIN32 @@ -34,45 +36,69 @@ size_t page_size() { // http://gnuradio.org/redmine/projects/gnuradio/repository/revisions/f2bc76cc65ffba51a141950f98e75364e49df874/entry/volk/kernels/volk/volk_32u_byteswap.h // http://gnuradio.org/redmine/projects/gnuradio/repository/revisions/2c4c371885c31222362f70a1cd714415d1398021/entry/volk/kernels/volk/volk_64u_byteswap.h -void copy_and_swap_16_aligned(uint16_t* dest, const uint16_t* src, - size_t count) { - for (size_t i = 0; i < count; ++i) { - dest[i] = byte_swap(src[i]); - } +void copy_and_swap_16_aligned(uint16_t* dest, const uint16_t* src, size_t count, + uint16_t* out_max_value) { + return copy_and_swap_16_unaligned(dest, src, count, out_max_value); } void copy_and_swap_16_unaligned(uint16_t* dest, const uint16_t* src, - size_t count) { - for (size_t i = 0; i < count; ++i) { - dest[i] = byte_swap(src[i]); + size_t count, uint16_t* out_max_value) { + if (out_max_value) { + uint16_t max_value = 0; + for (size_t i = 0; i < count; ++i) { + uint16_t value = byte_swap(src[i]); + max_value = std::max(max_value, value); + dest[i] = value; + } + *out_max_value = max_value; + } else { + for (size_t i = 0; i < count; ++i) { + dest[i] = byte_swap(src[i]); + } } } -void copy_and_swap_32_aligned(uint32_t* dest, const uint32_t* src, - size_t count) { - for (size_t i = 0; i < count; ++i) { - dest[i] = byte_swap(src[i]); - } +void copy_and_swap_32_aligned(uint32_t* dest, const uint32_t* src, size_t count, + uint32_t* out_max_value) { + return copy_and_swap_32_unaligned(dest, src, count, out_max_value); } void copy_and_swap_32_unaligned(uint32_t* dest, const uint32_t* src, - size_t count) { - for (size_t i = 0; i < count; ++i) { - dest[i] = byte_swap(src[i]); + size_t count, uint32_t* out_max_value) { + if (out_max_value) { + uint32_t max_value = 0; + for (size_t i = 0; i < count; ++i) { + uint32_t value = byte_swap(src[i]); + max_value = std::max(max_value, value); + dest[i] = value; + } + *out_max_value = max_value; + } else { + for (size_t i = 0; i < count; ++i) { + dest[i] = byte_swap(src[i]); + } } } -void copy_and_swap_64_aligned(uint64_t* dest, const uint64_t* src, - size_t count) { - for (size_t i = 0; i < count; ++i) { - dest[i] = byte_swap(src[i]); - } +void copy_and_swap_64_aligned(uint64_t* dest, const uint64_t* src, size_t count, + uint64_t* out_max_value) { + return copy_and_swap_64_unaligned(dest, src, count, out_max_value); } void copy_and_swap_64_unaligned(uint64_t* dest, const uint64_t* src, - size_t count) { - for (size_t i = 0; i < count; ++i) { - dest[i] = byte_swap(src[i]); + size_t count, uint64_t* out_max_value) { + if (out_max_value) { + uint64_t max_value = 0; + for (size_t i = 0; i < count; ++i) { + uint64_t value = byte_swap(src[i]); + max_value = std::max(max_value, value); + dest[i] = value; + } + *out_max_value = max_value; + } else { + for (size_t i = 0; i < count; ++i) { + dest[i] = byte_swap(src[i]); + } } } diff --git a/src/poly/memory.h b/src/poly/memory.h index e7443626a..66918a0eb 100644 --- a/src/poly/memory.h +++ b/src/poly/memory.h @@ -29,18 +29,21 @@ size_t hash_combine(size_t seed, const T& v, const Ts&... vs) { size_t page_size(); -void copy_and_swap_16_aligned(uint16_t* dest, const uint16_t* src, - size_t count); +void copy_and_swap_16_aligned(uint16_t* dest, const uint16_t* src, size_t count, + uint16_t* out_max_value = nullptr); void copy_and_swap_16_unaligned(uint16_t* dest, const uint16_t* src, - size_t count); -void copy_and_swap_32_aligned(uint32_t* dest, const uint32_t* src, - size_t count); + size_t count, + uint16_t* out_max_value = nullptr); +void copy_and_swap_32_aligned(uint32_t* dest, const uint32_t* src, size_t count, + uint32_t* out_max_value = nullptr); void copy_and_swap_32_unaligned(uint32_t* dest, const uint32_t* src, - size_t count); -void copy_and_swap_64_aligned(uint64_t* dest, const uint64_t* src, - size_t count); + size_t count, + uint32_t* out_max_value = nullptr); +void copy_and_swap_64_aligned(uint64_t* dest, const uint64_t* src, size_t count, + uint64_t* out_max_value = nullptr); void copy_and_swap_64_unaligned(uint64_t* dest, const uint64_t* src, - size_t count); + size_t count, + uint64_t* out_max_value = nullptr); template void copy_and_swap(T* dest, const T* src, size_t count) { From eda38a7428537b6448bac317b9b9f398c36284b6 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 4 Jan 2015 04:59:26 -0800 Subject: [PATCH 321/388] Misc tweaks. --- src/xenia/gpu/gl4/circular_buffer.cc | 7 ++++++- src/xenia/gpu/gl4/circular_buffer.h | 1 + src/xenia/gpu/gl4/command_processor.cc | 3 ++- src/xenia/gpu/gl4/gl4_shader_translator.cc | 6 +++--- src/xenia/gpu/shader.cc | 1 + src/xenia/gpu/shader.h | 1 + 6 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/xenia/gpu/gl4/circular_buffer.cc b/src/xenia/gpu/gl4/circular_buffer.cc index e33677406..a2554f9fb 100644 --- a/src/xenia/gpu/gl4/circular_buffer.cc +++ b/src/xenia/gpu/gl4/circular_buffer.cc @@ -47,7 +47,7 @@ bool CircularBuffer::Initialize() { if (FLAGS_vendor_gl_extensions && GLEW_NV_shader_buffer_load) { // To use this bindlessly we must make it resident. - glMakeNamedBufferResidentNV(buffer_, GL_WRITE_ONLY); + glMakeNamedBufferResidentNV(buffer_, GL_READ_ONLY); glGetNamedBufferParameterui64vNV(buffer_, GL_BUFFER_GPU_ADDRESS_NV, &gpu_base_); } @@ -90,11 +90,16 @@ CircularBuffer::Allocation CircularBuffer::Acquire(size_t length) { return allocation; } +void CircularBuffer::Discard(Allocation allocation) { + write_head_ -= allocation.aligned_length; +} + void CircularBuffer::Commit(Allocation allocation) { uintptr_t start = allocation.gpu_ptr - gpu_base_; uintptr_t end = start + allocation.aligned_length; dirty_start_ = std::min(dirty_start_, start); dirty_end_ = std::max(dirty_end_, end); + assert_true(dirty_end_ <= capacity_); } void CircularBuffer::Flush() { diff --git a/src/xenia/gpu/gl4/circular_buffer.h b/src/xenia/gpu/gl4/circular_buffer.h index 2db1d639c..d7288d5a8 100644 --- a/src/xenia/gpu/gl4/circular_buffer.h +++ b/src/xenia/gpu/gl4/circular_buffer.h @@ -38,6 +38,7 @@ class CircularBuffer { bool CanAcquire(size_t length); Allocation Acquire(size_t length); + void Discard(Allocation allocation); void Commit(Allocation allocation); void Flush(); diff --git a/src/xenia/gpu/gl4/command_processor.cc b/src/xenia/gpu/gl4/command_processor.cc index 460f6df29..750079ae5 100644 --- a/src/xenia/gpu/gl4/command_processor.cc +++ b/src/xenia/gpu/gl4/command_processor.cc @@ -163,7 +163,6 @@ void CommandProcessor::WorkerMain() { } bool CommandProcessor::SetupGL() { - glViewport(0, 0, 1280, 720); // Circular buffer holding scratch vertex/index data. if (!scratch_buffer_.Initialize()) { @@ -1580,6 +1579,8 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateRenderTargets( // TODO(benvanik): can we do this all named? // TODO(benvanik): do we want this on READ too? glBindFramebuffer(GL_DRAW_FRAMEBUFFER, cached_framebuffer->framebuffer); + + glViewport(0, 0, 1280, 720); } return UpdateStatus::kMismatch; diff --git a/src/xenia/gpu/gl4/gl4_shader_translator.cc b/src/xenia/gpu/gl4/gl4_shader_translator.cc index 8ceab5547..e314191ea 100644 --- a/src/xenia/gpu/gl4/gl4_shader_translator.cc +++ b/src/xenia/gpu/gl4/gl4_shader_translator.cc @@ -936,7 +936,8 @@ bool GL4ShaderTranslator::TranslateALU_RECIP_IEEE(const instr_alu_t& alu) { return true; } -bool GL4ShaderTranslator::TranslateALU_RECIPSQ_IEEE(const ucode::instr_alu_t& alu) { +bool GL4ShaderTranslator::TranslateALU_RECIPSQ_IEEE( + const ucode::instr_alu_t& alu) { AppendDestReg(alu.scalar_dest, alu.scalar_write_mask, alu.export_data); Append(" = "); if (alu.scalar_clamp) { @@ -1298,8 +1299,7 @@ bool GL4ShaderTranslator::TranslateALU(const instr_alu_t* alu, int sync) { } else { Append("\t \tOP(%u)\t", alu->scalar_opc); } - PrintDstReg(alu->scalar_dest, alu->scalar_write_mask, - alu->export_data); + PrintDstReg(alu->scalar_dest, alu->scalar_write_mask, alu->export_data); Append(" = "); if (is.num_srcs == 2) { // ADD_CONST_0 dest, [const], [reg] diff --git a/src/xenia/gpu/shader.cc b/src/xenia/gpu/shader.cc index a3812b814..c79d51727 100644 --- a/src/xenia/gpu/shader.cc +++ b/src/xenia/gpu/shader.cc @@ -215,6 +215,7 @@ void Shader::GatherVertexFetch(const instr_fetch_vtx_t* vtx) { desc.stride_words = vtx->stride; el = &desc.elements[desc.element_count++]; } + ++inputs.total_elements_count; el->vtx_fetch = *vtx; el->format = static_cast(vtx->format); diff --git a/src/xenia/gpu/shader.h b/src/xenia/gpu/shader.h index e5383b6dc..5983b851d 100644 --- a/src/xenia/gpu/shader.h +++ b/src/xenia/gpu/shader.h @@ -51,6 +51,7 @@ class Shader { }; struct BufferInputs { uint32_t count; + uint32_t total_elements_count; BufferDesc descs[32]; }; const BufferInputs& buffer_inputs() { return buffer_inputs_; } From 4fcf9c6229a1837d816c372b627ba8fe5f92def5 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 4 Jan 2015 11:20:42 -0800 Subject: [PATCH 322/388] MultiDrawIndirect draw batching - now down to <20us per draw. --- src/xenia/gpu/gl4/circular_buffer.h | 2 + src/xenia/gpu/gl4/command_processor.cc | 756 ++++++++------------- src/xenia/gpu/gl4/command_processor.h | 120 +--- src/xenia/gpu/gl4/draw_batcher.cc | 384 +++++++++++ src/xenia/gpu/gl4/draw_batcher.h | 230 +++++++ src/xenia/gpu/gl4/gl4_shader.cc | 206 ++++-- src/xenia/gpu/gl4/gl4_shader.h | 6 + src/xenia/gpu/gl4/gl4_shader_translator.cc | 4 +- src/xenia/gpu/gl4/gl_context.cc | 11 +- src/xenia/gpu/gl4/sources.gypi | 2 + 10 files changed, 1120 insertions(+), 601 deletions(-) create mode 100644 src/xenia/gpu/gl4/draw_batcher.cc create mode 100644 src/xenia/gpu/gl4/draw_batcher.h diff --git a/src/xenia/gpu/gl4/circular_buffer.h b/src/xenia/gpu/gl4/circular_buffer.h index d7288d5a8..aaa7ea7e8 100644 --- a/src/xenia/gpu/gl4/circular_buffer.h +++ b/src/xenia/gpu/gl4/circular_buffer.h @@ -35,6 +35,8 @@ class CircularBuffer { void Shutdown(); GLuint handle() const { return buffer_; } + GLuint64 gpu_handle() const { return gpu_base_; } + size_t capacity() const { return capacity_; } bool CanAcquire(size_t length); Allocation Acquire(size_t length); diff --git a/src/xenia/gpu/gl4/command_processor.cc b/src/xenia/gpu/gl4/command_processor.cc index 750079ae5..c686a94af 100644 --- a/src/xenia/gpu/gl4/command_processor.cc +++ b/src/xenia/gpu/gl4/command_processor.cc @@ -25,6 +25,8 @@ #define XETRACECP(fmt, ...) \ if (FLAGS_trace_ring_buffer) XELOGGPU(fmt, ##__VA_ARGS__) +#define FINE_GRAINED_DRAW_SCOPES 1 + namespace xe { namespace gpu { namespace gl4 { @@ -39,6 +41,7 @@ const GLuint kAnyTarget = UINT_MAX; // with the GPU, so this should be large enough to prevent that in a normal // frame. const size_t kScratchBufferCapacity = 256 * 1024 * 1024; +const size_t kScratchBufferAlignment = 256; CommandProcessor::CachedPipeline::CachedPipeline() : vertex_program(0), fragment_program(0), handles({0}) {} @@ -69,12 +72,12 @@ CommandProcessor::CommandProcessor(GL4GraphicsSystem* graphics_system) active_vertex_shader_(nullptr), active_pixel_shader_(nullptr), active_framebuffer_(nullptr), - vertex_array_(0), point_list_geometry_program_(0), rect_list_geometry_program_(0), quad_list_geometry_program_(0), - scratch_buffer_(kScratchBufferCapacity) { - std::memset(&draw_command_, 0, sizeof(draw_command_)); + draw_index_count_(0), + draw_batcher_(graphics_system_->register_file()), + scratch_buffer_(kScratchBufferCapacity, kScratchBufferAlignment) { LARGE_INTEGER perf_counter; QueryPerformanceCounter(&perf_counter); time_base_ = perf_counter.QuadPart; @@ -163,6 +166,9 @@ void CommandProcessor::WorkerMain() { } bool CommandProcessor::SetupGL() { + if (FLAGS_vendor_gl_extensions && GLEW_NV_vertex_buffer_unified_memory) { + has_bindless_vbos_ = true; + } // Circular buffer holding scratch vertex/index data. if (!scratch_buffer_.Initialize()) { @@ -170,27 +176,18 @@ bool CommandProcessor::SetupGL() { return false; } + // Command buffer. + if (!draw_batcher_.Initialize(&scratch_buffer_)) { + PLOGE("Unable to initialize command buffer"); + return false; + } + // Texture cache that keeps track of any textures/samplers used. if (!texture_cache_.Initialize(membase_, &scratch_buffer_)) { PLOGE("Unable to initialize texture cache"); return false; } - // TODO(benvanik): cache. - glGenVertexArrays(1, &vertex_array_); - glBindVertexArray(vertex_array_); - - if (FLAGS_vendor_gl_extensions && GLEW_NV_vertex_buffer_unified_memory) { - has_bindless_vbos_ = true; - glEnableClientState(GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV); - glEnableClientState(GL_ELEMENT_ARRAY_UNIFIED_NV); - } - GLint max_vertex_attribs = 0; - glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_vertex_attribs); - for (GLint i = 0; i < max_vertex_attribs; ++i) { - glEnableVertexAttribArray(i); - } - const std::string geometry_header = "#version 450\n" "#extension all : warn\n" @@ -346,8 +343,8 @@ void CommandProcessor::ShutdownGL() { glDeleteProgram(point_list_geometry_program_); glDeleteProgram(rect_list_geometry_program_); glDeleteProgram(quad_list_geometry_program_); - glDeleteVertexArrays(1, &vertex_array_); texture_cache_.Shutdown(); + draw_batcher_.Shutdown(); scratch_buffer_.Shutdown(); } @@ -437,7 +434,8 @@ void CommandProcessor::PrepareForWait() { // TODO(benvanik): fences and fancy stuff. We should figure out a way to // make interrupt callbacks from the GPU so that we don't have to do a full // synchronize here. - glFlush(); + //glFlush(); + glFinish(); if (FLAGS_thread_safe_gl) { context_->ClearCurrent(); @@ -1106,46 +1104,45 @@ bool CommandProcessor::ExecutePacketType3_DRAW_INDX(RingbufferReader* reader, uint32_t index_count = dword1 >> 16; auto prim_type = static_cast(dword1 & 0x3F); - uint32_t index_base = 0; - uint32_t index_size = 0; - Endian index_endianness = Endian::kUnspecified; - bool index_32bit = false; uint32_t src_sel = (dword1 >> 6) & 0x3; if (src_sel == 0x0) { // Indexed draw. - index_base = reader->Read(); - index_size = reader->Read(); - index_endianness = static_cast(index_size >> 30); + index_buffer_info_.guest_base = reader->Read(); + uint32_t index_size = reader->Read(); + index_buffer_info_.endianness = static_cast(index_size >> 30); index_size &= 0x00FFFFFF; - index_32bit = (dword1 >> 11) & 0x1; + bool index_32bit = (dword1 >> 11) & 0x1; + index_buffer_info_.format = + index_32bit ? IndexFormat::kInt32 : IndexFormat::kInt16; index_size *= index_32bit ? 4 : 2; + index_buffer_info_.length = index_size; + index_buffer_info_.count = index_count; } else if (src_sel == 0x2) { // Auto draw. + index_buffer_info_.guest_base = 0; + index_buffer_info_.length = 0; } else { // Unknown source select. assert_always(); } + draw_index_count_ = index_count; - PrepareDraw(&draw_command_); - draw_command_.prim_type = prim_type; - draw_command_.start_index = 0; - draw_command_.index_count = index_count; - draw_command_.base_vertex = 0; + bool draw_valid = false; if (src_sel == 0x0) { // Indexed draw. - draw_command_.index_buffer.address = membase_ + index_base; - draw_command_.index_buffer.size = index_size; - draw_command_.index_buffer.endianness = index_endianness; - draw_command_.index_buffer.format = - index_32bit ? IndexFormat::kInt32 : IndexFormat::kInt16; + draw_valid = draw_batcher_.BeginDrawElements(prim_type, index_count, + index_buffer_info_.format); } else if (src_sel == 0x2) { // Auto draw. - draw_command_.index_buffer.address = nullptr; + draw_valid = draw_batcher_.BeginDrawArrays(prim_type, index_count); } else { // Unknown source select. assert_always(); } - return IssueDraw(&draw_command_); + if (!draw_valid) { + return false; + } + return IssueDraw(); } bool CommandProcessor::ExecutePacketType3_DRAW_INDX_2(RingbufferReader* reader, @@ -1164,14 +1161,15 @@ bool CommandProcessor::ExecutePacketType3_DRAW_INDX_2(RingbufferReader* reader, uint32_t indices_size = index_count * (index_32bit ? 4 : 2); reader->CheckRead(indices_size / sizeof(uint32_t)); uint32_t index_ptr = reader->ptr(); + index_buffer_info_.guest_base = 0; + index_buffer_info_.length = 0; reader->Advance(count - 1); - PrepareDraw(&draw_command_); - draw_command_.prim_type = prim_type; - draw_command_.start_index = 0; - draw_command_.index_count = index_count; - draw_command_.base_vertex = 0; - draw_command_.index_buffer.address = nullptr; - return IssueDraw(&draw_command_); + draw_index_count_ = index_count; + bool draw_valid = draw_batcher_.BeginDrawArrays(prim_type, index_count); + if (!draw_valid) { + return false; + } + return IssueDraw(); } bool CommandProcessor::ExecutePacketType3_SET_CONSTANT(RingbufferReader* reader, @@ -1319,58 +1317,30 @@ bool CommandProcessor::LoadShader(ShaderType shader_type, return true; } -void CommandProcessor::PrepareDraw(DrawCommand* draw_command) { - auto& regs = *register_file_; - auto& cmd = *draw_command; - - // Reset the things we don't modify so that we have clean state. - cmd.prim_type = PrimitiveType::kPointList; - cmd.index_count = 0; - cmd.index_buffer.address = nullptr; - - // Starting index when drawing indexed. - cmd.start_index = regs[XE_GPU_REG_VGT_INDX_OFFSET].u32; - - // Min/max index ranges. This is often [0,FFFF|FFFFFF], but if it's not we - // can use it to do a glDrawRangeElements. - cmd.min_index = regs[XE_GPU_REG_VGT_MIN_VTX_INDX].u32; - cmd.max_index = regs[XE_GPU_REG_VGT_MAX_VTX_INDX].u32; - - // ? - cmd.base_vertex = 0; - - cmd.state_data = nullptr; -} - -bool CommandProcessor::IssueDraw(DrawCommand* draw_command) { +bool CommandProcessor::IssueDraw() { +#if FINE_GRAINED_DRAW_SCOPES SCOPE_profile_cpu_f("gpu"); +#endif // FINE_GRAINED_DRAW_SCOPES + auto& regs = *register_file_; - auto& cmd = *draw_command; auto enable_mode = static_cast(regs[XE_GPU_REG_RB_MODECONTROL].u32 & 0x7); if (enable_mode == ModeControl::kIgnore) { // Ignored. + draw_batcher_.DiscardDraw(); return true; } else if (enable_mode == ModeControl::kCopy) { // Special copy handling. - return IssueCopy(draw_command); - } - - // Allocate a state data block. - // Everything the shaders access lives here. - auto allocation = scratch_buffer_.Acquire(sizeof(UniformDataBlock)); - scratch_buffer_stats_.total_state_data_size += sizeof(UniformDataBlock); - cmd.state_data = reinterpret_cast(allocation.host_ptr); - if (!cmd.state_data) { - PLOGE("Unable to allocate uniform data buffer"); - return false; + draw_batcher_.DiscardDraw(); + return IssueCopy(); } #define CHECK_ISSUE_UPDATE_STATUS(status, mismatch, error_message) \ { \ if (status == UpdateStatus::kError) { \ PLOGE(error_message); \ + draw_batcher_.DiscardDraw(); \ return false; \ } else if (status == UpdateStatus::kMismatch) { \ mismatch = true; \ @@ -1379,93 +1349,31 @@ bool CommandProcessor::IssueDraw(DrawCommand* draw_command) { UpdateStatus status; bool mismatch = false; - status = UpdateShaders(draw_command); + status = UpdateShaders(draw_batcher_.prim_type()); CHECK_ISSUE_UPDATE_STATUS(status, mismatch, "Unable to prepare draw shaders"); - status = UpdateRenderTargets(draw_command); + status = UpdateRenderTargets(); CHECK_ISSUE_UPDATE_STATUS(status, mismatch, "Unable to setup render targets"); if (!active_framebuffer_) { // No framebuffer, so nothing we do will actually have an effect. // Treat it as a no-op. + // TODO(benvanik): if we have a vs export, still allow it to go. XETRACECP("No-op draw (no framebuffer set)"); + draw_batcher_.DiscardDraw(); return true; } - status = UpdateState(draw_command); + status = UpdateState(); CHECK_ISSUE_UPDATE_STATUS(status, mismatch, "Unable to setup render state"); - status = UpdateConstants(draw_command); - CHECK_ISSUE_UPDATE_STATUS(status, mismatch, - "Unable to update shader constants"); - status = PopulateSamplers(draw_command); + status = PopulateSamplers(); CHECK_ISSUE_UPDATE_STATUS(status, mismatch, "Unable to prepare draw samplers"); - status = PopulateIndexBuffer(draw_command); + status = PopulateIndexBuffer(); CHECK_ISSUE_UPDATE_STATUS(status, mismatch, "Unable to setup index buffer"); - status = PopulateVertexBuffers(draw_command); + status = PopulateVertexBuffers(); CHECK_ISSUE_UPDATE_STATUS(status, mismatch, "Unable to setup vertex buffers"); - GLenum prim_type = 0; - switch (cmd.prim_type) { - case PrimitiveType::kPointList: - prim_type = GL_POINTS; - break; - case PrimitiveType::kLineList: - prim_type = GL_LINES; - break; - case PrimitiveType::kLineStrip: - prim_type = GL_LINE_STRIP; - break; - case PrimitiveType::kLineLoop: - prim_type = GL_LINE_LOOP; - break; - case PrimitiveType::kTriangleList: - prim_type = GL_TRIANGLES; - break; - case PrimitiveType::kTriangleStrip: - prim_type = GL_TRIANGLE_STRIP; - break; - case PrimitiveType::kTriangleFan: - prim_type = GL_TRIANGLE_FAN; - break; - case PrimitiveType::kRectangleList: - prim_type = GL_TRIANGLE_STRIP; - break; - case PrimitiveType::kQuadList: - prim_type = GL_LINES_ADJACENCY; - break; - default: - case PrimitiveType::kUnknown0x07: - prim_type = GL_POINTS; - XELOGE("unsupported primitive type %d", cmd.prim_type); - assert_unhandled_case(cmd.prim_type); - return false; - } - - // Commit the state buffer - nothing can change after this. - glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, scratch_buffer_.handle(), - allocation.offset, allocation.length); - scratch_buffer_.Commit(std::move(allocation)); - scratch_buffer_.Flush(); - - if (cmd.index_buffer.address) { - // Indexed draw. - // PopulateIndexBuffer has our element array setup. - size_t element_size = cmd.index_buffer.format == IndexFormat::kInt32 - ? sizeof(uint32_t) - : sizeof(uint16_t); - glDrawElementsBaseVertex( - prim_type, cmd.index_count, - cmd.index_buffer.format == IndexFormat::kInt32 ? GL_UNSIGNED_INT - : GL_UNSIGNED_SHORT, - reinterpret_cast(cmd.index_buffer.buffer_offset + - cmd.start_index * element_size), - cmd.base_vertex); - } else { - // Auto draw. - glDrawArrays(prim_type, cmd.start_index, cmd.index_count); - } - - return true; + return draw_batcher_.CommitDraw(); } bool CommandProcessor::SetShadowRegister(uint32_t& dest, @@ -1487,8 +1395,129 @@ bool CommandProcessor::SetShadowRegister(float& dest, uint32_t register_name) { return true; } -CommandProcessor::UpdateStatus CommandProcessor::UpdateRenderTargets( - DrawCommand* draw_command) { +CommandProcessor::UpdateStatus CommandProcessor::UpdateShaders( + PrimitiveType prim_type) { + auto& regs = update_shaders_regs_; + + bool dirty = false; + dirty |= SetShadowRegister(regs.sq_program_cntl, XE_GPU_REG_SQ_PROGRAM_CNTL); + dirty |= regs.vertex_shader != active_vertex_shader_; + dirty |= regs.pixel_shader != active_pixel_shader_; + dirty |= regs.prim_type != prim_type; + if (!dirty) { + return UpdateStatus::kCompatible; + } + regs.vertex_shader = active_vertex_shader_; + regs.pixel_shader = active_pixel_shader_; + regs.prim_type = prim_type; + + SCOPE_profile_cpu_f("gpu"); + + draw_batcher_.Flush(DrawBatcher::FlushMode::kStateChange); + + xe_gpu_program_cntl_t program_cntl; + program_cntl.dword_0 = regs.sq_program_cntl; + if (!active_vertex_shader_->has_prepared()) { + if (!active_vertex_shader_->PrepareVertexShader(program_cntl)) { + XELOGE("Unable to prepare vertex shader"); + return UpdateStatus::kError; + } + } else if (!active_vertex_shader_->is_valid()) { + XELOGE("Vertex shader invalid"); + return UpdateStatus::kError; + } + + if (!active_pixel_shader_->has_prepared()) { + if (!active_pixel_shader_->PreparePixelShader(program_cntl)) { + XELOGE("Unable to prepare pixel shader"); + return UpdateStatus::kError; + } + } else if (!active_pixel_shader_->is_valid()) { + XELOGE("Pixel shader invalid"); + return UpdateStatus::kError; + } + + GLuint vertex_program = active_vertex_shader_->program(); + GLuint fragment_program = active_pixel_shader_->program(); + + uint64_t key = (uint64_t(vertex_program) << 32) | fragment_program; + CachedPipeline* cached_pipeline = nullptr; + auto it = cached_pipelines_.find(key); + if (it == cached_pipelines_.end()) { + // Existing pipeline for these programs not found - create it. + auto new_pipeline = std::make_unique(); + new_pipeline->vertex_program = vertex_program; + new_pipeline->fragment_program = fragment_program; + new_pipeline->handles.default_pipeline = 0; + cached_pipeline = new_pipeline.get(); + all_pipelines_.emplace_back(std::move(new_pipeline)); + cached_pipelines_.insert({key, cached_pipeline}); + } else { + // Found a pipeline container - it may or may not have what we want. + cached_pipeline = it->second; + } + if (!cached_pipeline->handles.default_pipeline) { + // Perhaps it's a bit wasteful to do all of these, but oh well. + GLuint pipelines[4]; + glCreateProgramPipelines(GLsizei(poly::countof(pipelines)), pipelines); + + glUseProgramStages(pipelines[0], GL_VERTEX_SHADER_BIT, vertex_program); + glUseProgramStages(pipelines[0], GL_FRAGMENT_SHADER_BIT, fragment_program); + cached_pipeline->handles.default_pipeline = pipelines[0]; + + glUseProgramStages(pipelines[1], GL_VERTEX_SHADER_BIT, vertex_program); + glUseProgramStages(pipelines[1], GL_GEOMETRY_SHADER_BIT, + point_list_geometry_program_); + glUseProgramStages(pipelines[1], GL_FRAGMENT_SHADER_BIT, fragment_program); + cached_pipeline->handles.point_list_pipeline = pipelines[1]; + + glUseProgramStages(pipelines[2], GL_VERTEX_SHADER_BIT, vertex_program); + glUseProgramStages(pipelines[2], GL_GEOMETRY_SHADER_BIT, + rect_list_geometry_program_); + glUseProgramStages(pipelines[2], GL_FRAGMENT_SHADER_BIT, fragment_program); + cached_pipeline->handles.rect_list_pipeline = pipelines[2]; + + glUseProgramStages(pipelines[3], GL_VERTEX_SHADER_BIT, vertex_program); + glUseProgramStages(pipelines[3], GL_GEOMETRY_SHADER_BIT, + quad_list_geometry_program_); + glUseProgramStages(pipelines[3], GL_FRAGMENT_SHADER_BIT, fragment_program); + cached_pipeline->handles.quad_list_pipeline = pipelines[3]; + + // This can be set once, as the buffer never changes. + if (has_bindless_vbos_) { + glBindVertexArray(active_vertex_shader_->vao()); + glBufferAddressRangeNV(GL_ELEMENT_ARRAY_ADDRESS_NV, 0, + scratch_buffer_.gpu_handle(), + scratch_buffer_.capacity()); + } else { + glVertexArrayElementBuffer(active_vertex_shader_->vao(), + scratch_buffer_.handle()); + } + } + + GLuint pipeline = cached_pipeline->handles.default_pipeline; + switch (regs.prim_type) { + case PrimitiveType::kPointList: + pipeline = cached_pipeline->handles.point_list_pipeline; + break; + case PrimitiveType::kRectangleList: + pipeline = cached_pipeline->handles.rect_list_pipeline; + break; + case PrimitiveType::kQuadList: + pipeline = cached_pipeline->handles.quad_list_pipeline; + break; + } + + draw_batcher_.ReconfigurePipeline(active_vertex_shader_, active_pixel_shader_, + pipeline); + + glBindProgramPipeline(pipeline); + glBindVertexArray(active_vertex_shader_->vao()); + + return UpdateStatus::kMismatch; +} + +CommandProcessor::UpdateStatus CommandProcessor::UpdateRenderTargets() { auto& regs = update_render_targets_regs_; bool dirty = false; @@ -1509,6 +1538,8 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateRenderTargets( SCOPE_profile_cpu_f("gpu"); + draw_batcher_.Flush(DrawBatcher::FlushMode::kStateChange); + auto enable_mode = static_cast(regs.rb_modecontrol & 0x7); // RB_SURFACE_INFO @@ -1586,10 +1617,8 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateRenderTargets( return UpdateStatus::kMismatch; } -CommandProcessor::UpdateStatus CommandProcessor::UpdateState( - DrawCommand* draw_command) { +CommandProcessor::UpdateStatus CommandProcessor::UpdateState() { auto& regs = *register_file_; - auto state_data = draw_command->state_data; bool mismatch = false; @@ -1597,10 +1626,9 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateState( // Deprecated in GL, implemented in shader. // if(ALPHATESTENABLE && frag_out.a [<=/ALPHAFUNC] ALPHAREF) discard; uint32_t color_control = regs[XE_GPU_REG_RB_COLORCONTROL].u32; - state_data->alpha_test.x = - (color_control & 0x4) ? 1.0f : 0.0f; // ALPAHTESTENABLE - state_data->alpha_test.y = float(color_control & 0x3); // ALPHAFUNC - state_data->alpha_test.z = regs[XE_GPU_REG_RB_ALPHA_REF].f32; + draw_batcher_.set_alpha_test((color_control & 0x4) != 0, // ALPAHTESTENABLE + color_control & 0x3, // ALPHAFUNC + regs[XE_GPU_REG_RB_ALPHA_REF].f32); #define CHECK_UPDATE_STATUS(status, mismatch, error_message) \ { \ @@ -1613,22 +1641,20 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateState( } UpdateStatus status; - status = UpdateViewportState(draw_command); + status = UpdateViewportState(); CHECK_UPDATE_STATUS(status, mismatch, "Unable to update viewport state"); - status = UpdateRasterizerState(draw_command); + status = UpdateRasterizerState(); CHECK_UPDATE_STATUS(status, mismatch, "Unable to update rasterizer state"); - status = UpdateBlendState(draw_command); + status = UpdateBlendState(); CHECK_UPDATE_STATUS(status, mismatch, "Unable to update blend state"); - status = UpdateDepthStencilState(draw_command); + status = UpdateDepthStencilState(); CHECK_UPDATE_STATUS(status, mismatch, "Unable to update depth/stencil state"); return mismatch ? UpdateStatus::kMismatch : UpdateStatus::kCompatible; } -CommandProcessor::UpdateStatus CommandProcessor::UpdateViewportState( - DrawCommand* draw_command) { +CommandProcessor::UpdateStatus CommandProcessor::UpdateViewportState() { auto& regs = *register_file_; - auto state_data = draw_command->state_data; // NOTE: we don't track state here as this is all cheap to update (ish). @@ -1644,18 +1670,16 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateViewportState( // https://github.com/freedreno/mesa/blob/master/src/mesa/drivers/dri/r200/r200_state.c if ((mode_control >> 17) & 1) { uint32_t window_offset = regs[XE_GPU_REG_PA_SC_WINDOW_OFFSET].u32; - state_data->window_offset.x = float(window_offset & 0x7FFF); - state_data->window_offset.y = float((window_offset >> 16) & 0x7FFF); + draw_batcher_.set_window_offset(window_offset & 0x7FFF, + (window_offset >> 16) & 0x7FFF); } else { - state_data->window_offset.x = 0; - state_data->window_offset.y = 0; + draw_batcher_.set_window_offset(0, 0); } uint32_t window_scissor_tl = regs[XE_GPU_REG_PA_SC_WINDOW_SCISSOR_TL].u32; uint32_t window_scissor_br = regs[XE_GPU_REG_PA_SC_WINDOW_SCISSOR_BR].u32; - state_data->window_scissor.x = float(window_scissor_tl & 0x7FFF); - state_data->window_scissor.y = float((window_scissor_tl >> 16) & 0x7FFF); - state_data->window_scissor.z = float(window_scissor_br & 0x7FFF); - state_data->window_scissor.w = float((window_scissor_br >> 16) & 0x7FFF); + draw_batcher_.set_window_scissor( + window_scissor_tl & 0x7FFF, (window_scissor_tl >> 16) & 0x7FFF, + window_scissor_br & 0x7FFF, (window_scissor_br >> 16) & 0x7FFF); // HACK: no clue where to get these values. // RB_SURFACE_INFO @@ -1676,8 +1700,7 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateViewportState( window_height_scalar = 2; break; } - state_data->window_offset.z = window_width_scalar; - state_data->window_offset.w = window_height_scalar; + draw_batcher_.set_window_scalar(window_width_scalar, window_height_scalar); // Whether each of the viewport settings is enabled. // http://www.x.org/docs/AMD/old/evergreen_3D_registers_v2.pdf @@ -1693,33 +1716,25 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateViewportState( vport_yoffset_enable == vport_zoffset_enable); // Viewport scaling. Only enabled if the flags are all set. - state_data->viewport_scale.x = - vport_xscale_enable ? regs[XE_GPU_REG_PA_CL_VPORT_XSCALE].f32 : 1; // 640 - state_data->viewport_offset.x = vport_xoffset_enable - ? regs[XE_GPU_REG_PA_CL_VPORT_XOFFSET].f32 - : 0; // 640 - state_data->viewport_scale.y = vport_yscale_enable - ? regs[XE_GPU_REG_PA_CL_VPORT_YSCALE].f32 - : 1; // -360 - state_data->viewport_offset.y = vport_yoffset_enable - ? regs[XE_GPU_REG_PA_CL_VPORT_YOFFSET].f32 - : 0; // 360 - state_data->viewport_scale.z = - vport_zscale_enable ? regs[XE_GPU_REG_PA_CL_VPORT_ZSCALE].f32 : 1; // 1 - state_data->viewport_offset.z = - vport_zoffset_enable ? regs[XE_GPU_REG_PA_CL_VPORT_ZOFFSET].f32 : 0; // 0 + draw_batcher_.set_viewport_offset( + vport_xoffset_enable ? regs[XE_GPU_REG_PA_CL_VPORT_XOFFSET].f32 : 0, + vport_yoffset_enable ? regs[XE_GPU_REG_PA_CL_VPORT_YOFFSET].f32 : 0, + vport_zoffset_enable ? regs[XE_GPU_REG_PA_CL_VPORT_ZOFFSET].f32 : 0); + draw_batcher_.set_viewport_scale( + vport_xscale_enable ? regs[XE_GPU_REG_PA_CL_VPORT_XSCALE].f32 : 1, + vport_yscale_enable ? regs[XE_GPU_REG_PA_CL_VPORT_YSCALE].f32 : 1, + vport_zscale_enable ? regs[XE_GPU_REG_PA_CL_VPORT_ZSCALE].f32 : 1); // http://www.x.org/docs/AMD/old/evergreen_3D_registers_v2.pdf // VTX_XY_FMT = true: the incoming X, Y have already been multiplied by 1/W0. // = false: multiply the X, Y coordinates by 1/W0. - state_data->vtx_fmt.x = state_data->vtx_fmt.y = - (vte_control >> 8) & 0x1 ? 1.0f : 0.0f; // VTX_Z_FMT = true: the incoming Z has already been multiplied by 1/W0. // = false: multiply the Z coordinate by 1/W0. - state_data->vtx_fmt.z = (vte_control >> 9) & 0x1 ? 1.0f : 0.0f; // VTX_W0_FMT = true: the incoming W0 is not 1/W0. Perform the reciprocal to // get 1/W0. - state_data->vtx_fmt.w = (vte_control >> 10) & 0x1 ? 1.0f : 0.0f; + draw_batcher_.set_vtx_fmt((vte_control >> 8) & 0x1 ? 1.0f : 0.0f, + (vte_control >> 9) & 0x1 ? 1.0f : 0.0f, + (vte_control >> 10) & 0x1 ? 1.0f : 0.0f); // Clipping. // https://github.com/freedreno/amd-gpu/blob/master/include/reg/yamato/14/yamato_genenum.h#L1587 @@ -1732,8 +1747,7 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateViewportState( return UpdateStatus::kCompatible; } -CommandProcessor::UpdateStatus CommandProcessor::UpdateRasterizerState( - DrawCommand* draw_command) { +CommandProcessor::UpdateStatus CommandProcessor::UpdateRasterizerState() { auto& regs = update_rasterizer_state_regs_; bool dirty = false; @@ -1749,6 +1763,8 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateRasterizerState( SCOPE_profile_cpu_f("gpu"); + draw_batcher_.Flush(DrawBatcher::FlushMode::kStateChange); + // Scissoring. if (regs.pa_sc_screen_scissor_tl != 0 && regs.pa_sc_screen_scissor_br != 0x20002000) { @@ -1766,10 +1782,6 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateRasterizerState( glDisable(GL_SCISSOR_TEST); } - // Rect lists aren't culled. There may be other things they skip too. - assert_true((regs.pa_su_sc_mode_cntl & 0x3) == 0 || - draw_command->prim_type != PrimitiveType::kRectangleList); - switch (regs.pa_su_sc_mode_cntl & 0x3) { case 0: glDisable(GL_CULL_FACE); @@ -1784,6 +1796,12 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateRasterizerState( break; } + if (regs.pa_su_sc_mode_cntl & (1 << 20)) { + glProvokingVertex(GL_LAST_VERTEX_CONVENTION); + } else { + glProvokingVertex(GL_FIRST_VERTEX_CONVENTION); + } + if (regs.pa_su_sc_mode_cntl & 0x4) { glFrontFace(GL_CW); } else { @@ -1797,8 +1815,7 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateRasterizerState( return UpdateStatus::kMismatch; } -CommandProcessor::UpdateStatus CommandProcessor::UpdateBlendState( - DrawCommand* draw_command) { +CommandProcessor::UpdateStatus CommandProcessor::UpdateBlendState() { auto& regs = update_blend_state_regs_; bool dirty = false; @@ -1820,6 +1837,8 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateBlendState( SCOPE_profile_cpu_f("gpu"); + draw_batcher_.Flush(DrawBatcher::FlushMode::kStateChange); + static const GLenum blend_map[] = { /* 0 */ GL_ZERO, /* 1 */ GL_ONE, @@ -1882,8 +1901,7 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateBlendState( return UpdateStatus::kMismatch; } -CommandProcessor::UpdateStatus CommandProcessor::UpdateDepthStencilState( - DrawCommand* draw_command) { +CommandProcessor::UpdateStatus CommandProcessor::UpdateDepthStencilState() { auto& regs = update_depth_stencil_state_regs_; bool dirty = false; @@ -1896,6 +1914,8 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateDepthStencilState( SCOPE_profile_cpu_f("gpu"); + draw_batcher_.Flush(DrawBatcher::FlushMode::kStateChange); + static const GLenum compare_func_map[] = { /* 0 */ GL_NEVER, /* 1 */ GL_LESS, @@ -1977,192 +1997,72 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateDepthStencilState( return UpdateStatus::kMismatch; } -CommandProcessor::UpdateStatus CommandProcessor::UpdateConstants( - DrawCommand* draw_command) { +CommandProcessor::UpdateStatus CommandProcessor::PopulateIndexBuffer() { auto& regs = *register_file_; - auto state_data = draw_command->state_data; - - // TODO(benvanik): partial updates, etc. We could use shader constant access - // knowledge that we get at compile time to only upload those constants - // required. If we did this as a variable length then we could really cut - // down on state block sizes. - - // Copy over all constants. - std::memcpy(&state_data->float_consts, - ®s[XE_GPU_REG_SHADER_CONSTANT_000_X].f32, - sizeof(state_data->float_consts)); - std::memcpy( - &state_data->bool_consts, - ®s[XE_GPU_REG_SHADER_CONSTANT_BOOL_000_031].f32, - sizeof(state_data->bool_consts) + sizeof(state_data->loop_consts)); - - return UpdateStatus::kCompatible; -} - -CommandProcessor::UpdateStatus CommandProcessor::UpdateShaders( - DrawCommand* draw_command) { - auto& regs = update_shaders_regs_; - auto& cmd = *draw_command; - - bool dirty = false; - dirty |= SetShadowRegister(regs.sq_program_cntl, XE_GPU_REG_SQ_PROGRAM_CNTL); - dirty |= regs.vertex_shader != active_vertex_shader_; - dirty |= regs.pixel_shader != active_pixel_shader_; - dirty |= regs.prim_type != cmd.prim_type; - if (!dirty) { + auto& info = index_buffer_info_; + if (!info.guest_base) { + // No index buffer or auto draw. return UpdateStatus::kCompatible; } - regs.vertex_shader = active_vertex_shader_; - regs.pixel_shader = active_pixel_shader_; - regs.prim_type = cmd.prim_type; +#if FINE_GRAINED_DRAW_SCOPES SCOPE_profile_cpu_f("gpu"); +#endif // FINE_GRAINED_DRAW_SCOPES - xe_gpu_program_cntl_t program_cntl; - program_cntl.dword_0 = regs.sq_program_cntl; - if (!active_vertex_shader_->has_prepared()) { - if (!active_vertex_shader_->PrepareVertexShader(program_cntl)) { - XELOGE("Unable to prepare vertex shader"); - return UpdateStatus::kError; - } - } else if (!active_vertex_shader_->is_valid()) { - XELOGE("Vertex shader invalid"); - return UpdateStatus::kError; - } - - if (!active_pixel_shader_->has_prepared()) { - if (!active_pixel_shader_->PreparePixelShader(program_cntl)) { - XELOGE("Unable to prepare pixel shader"); - return UpdateStatus::kError; - } - } else if (!active_pixel_shader_->is_valid()) { - XELOGE("Pixel shader invalid"); - return UpdateStatus::kError; - } - - GLuint vertex_program = active_vertex_shader_->program(); - GLuint fragment_program = active_pixel_shader_->program(); - - uint64_t key = (uint64_t(vertex_program) << 32) | fragment_program; - CachedPipeline* cached_pipeline = nullptr; - auto it = cached_pipelines_.find(key); - if (it == cached_pipelines_.end()) { - // Existing pipeline for these programs not found - create it. - auto new_pipeline = std::make_unique(); - new_pipeline->vertex_program = vertex_program; - new_pipeline->fragment_program = fragment_program; - new_pipeline->handles.default_pipeline = 0; - cached_pipeline = new_pipeline.get(); - all_pipelines_.emplace_back(std::move(new_pipeline)); - cached_pipelines_.insert({key, cached_pipeline}); - } else { - // Found a pipeline container - it may or may not have what we want. - cached_pipeline = it->second; - } - if (!cached_pipeline->handles.default_pipeline) { - // Perhaps it's a bit wasteful to do all of these, but oh well. - GLuint pipelines[4]; - glCreateProgramPipelines(GLsizei(poly::countof(pipelines)), pipelines); - - glUseProgramStages(pipelines[0], GL_VERTEX_SHADER_BIT, vertex_program); - glUseProgramStages(pipelines[0], GL_FRAGMENT_SHADER_BIT, fragment_program); - cached_pipeline->handles.default_pipeline = pipelines[0]; - - glUseProgramStages(pipelines[1], GL_VERTEX_SHADER_BIT, vertex_program); - glUseProgramStages(pipelines[1], GL_GEOMETRY_SHADER_BIT, - point_list_geometry_program_); - glUseProgramStages(pipelines[1], GL_FRAGMENT_SHADER_BIT, fragment_program); - cached_pipeline->handles.point_list_pipeline = pipelines[1]; - - glUseProgramStages(pipelines[2], GL_VERTEX_SHADER_BIT, vertex_program); - glUseProgramStages(pipelines[2], GL_GEOMETRY_SHADER_BIT, - rect_list_geometry_program_); - glUseProgramStages(pipelines[2], GL_FRAGMENT_SHADER_BIT, fragment_program); - cached_pipeline->handles.rect_list_pipeline = pipelines[2]; - - glUseProgramStages(pipelines[3], GL_VERTEX_SHADER_BIT, vertex_program); - glUseProgramStages(pipelines[3], GL_GEOMETRY_SHADER_BIT, - quad_list_geometry_program_); - glUseProgramStages(pipelines[3], GL_FRAGMENT_SHADER_BIT, fragment_program); - cached_pipeline->handles.quad_list_pipeline = pipelines[3]; - } - - GLuint pipeline = cached_pipeline->handles.default_pipeline; - switch (regs.prim_type) { - case PrimitiveType::kPointList: - pipeline = cached_pipeline->handles.point_list_pipeline; - break; - case PrimitiveType::kRectangleList: - pipeline = cached_pipeline->handles.rect_list_pipeline; - break; - case PrimitiveType::kQuadList: - pipeline = cached_pipeline->handles.quad_list_pipeline; - break; - } - glBindProgramPipeline(pipeline); - - return UpdateStatus::kMismatch; -} - -CommandProcessor::UpdateStatus CommandProcessor::PopulateIndexBuffer( - DrawCommand* draw_command) { - auto& cmd = *draw_command; - - auto& info = cmd.index_buffer; - if (!cmd.index_count || !info.address) { - // No index buffer or auto draw. - return UpdateStatus::kMismatch; // ? - } - - SCOPE_profile_cpu_f("gpu"); + // Min/max index ranges. This is often [0g,FFFF|FFFFFF], but if it's not we + // can use it to do a glDrawRangeElements. + uint32_t min_index = regs[XE_GPU_REG_VGT_MIN_VTX_INDX].u32; + uint32_t max_index = regs[XE_GPU_REG_VGT_MAX_VTX_INDX].u32; + assert_true(min_index == 0); + assert_true(max_index == 0xFFFF || max_index == 0xFFFFFF); assert_true(info.endianness == Endian::k8in16 || info.endianness == Endian::k8in32); size_t total_size = - cmd.index_count * (info.format == IndexFormat::kInt32 ? sizeof(uint32_t) - : sizeof(uint16_t)); + info.count * (info.format == IndexFormat::kInt32 ? sizeof(uint32_t) + : sizeof(uint16_t)); auto allocation = scratch_buffer_.Acquire(total_size); - scratch_buffer_stats_.total_indices_size += total_size; if (info.format == IndexFormat::kInt32) { - poly::copy_and_swap_32_aligned( - reinterpret_cast(allocation.host_ptr), - reinterpret_cast(cmd.index_buffer.address), - cmd.index_count); + auto dest = reinterpret_cast(allocation.host_ptr); + auto src = reinterpret_cast(membase_ + info.guest_base); + uint32_t max_index_found; + poly::copy_and_swap_32_aligned(dest, src, info.count, &max_index_found); + index_buffer_info_.max_index_found = max_index_found; } else { - poly::copy_and_swap_16_aligned( - reinterpret_cast(allocation.host_ptr), - reinterpret_cast(cmd.index_buffer.address), - cmd.index_count); + auto dest = reinterpret_cast(allocation.host_ptr); + auto src = reinterpret_cast(membase_ + info.guest_base); + uint16_t max_index_found; + poly::copy_and_swap_16_aligned(dest, src, info.count, &max_index_found); + index_buffer_info_.max_index_found = max_index_found; } - if (has_bindless_vbos_) { - glBufferAddressRangeNV(GL_ELEMENT_ARRAY_ADDRESS_NV, 0, allocation.gpu_ptr, - allocation.length); - } else { - // Offset is used in glDrawElements. - cmd.index_buffer.buffer_offset = allocation.offset; - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, scratch_buffer_.handle()); - } + draw_batcher_.set_index_buffer(allocation); + scratch_buffer_.Commit(std::move(allocation)); - return UpdateStatus::kMismatch; + return UpdateStatus::kCompatible; } -CommandProcessor::UpdateStatus CommandProcessor::PopulateVertexBuffers( - DrawCommand* draw_command) { +CommandProcessor::UpdateStatus CommandProcessor::PopulateVertexBuffers() { +#if FINE_GRAINED_DRAW_SCOPES SCOPE_profile_cpu_f("gpu"); +#endif // FINE_GRAINED_DRAW_SCOPES + auto& regs = *register_file_; - auto& cmd = *draw_command; assert_not_null(active_vertex_shader_); - const auto& buffer_inputs = active_vertex_shader_->buffer_inputs(); + if (!has_bindless_vbos_) { + // TODO(benvanik): find a way to get around glVertexArrayVertexBuffer below. + draw_batcher_.Flush(DrawBatcher::FlushMode::kMakeCoherent); + } uint32_t el_index = 0; - for (uint32_t n = 0; n < buffer_inputs.count; n++) { - const auto& desc = buffer_inputs.descs[n]; - + const auto& buffer_inputs = active_vertex_shader_->buffer_inputs(); + for (uint32_t buffer_index = 0; buffer_index < buffer_inputs.count; + ++buffer_index) { + const auto& desc = buffer_inputs.descs[buffer_index]; int r = XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 + (desc.fetch_slot / 3) * 6; auto group = reinterpret_cast(®s.values[r]); xe_gpu_vertex_fetch_t* fetch = nullptr; @@ -2177,14 +2077,16 @@ CommandProcessor::UpdateStatus CommandProcessor::PopulateVertexBuffers( fetch = &group->vertex_fetch_2; break; } - assert_not_null(fetch); - assert_true(fetch->type == 0x3); // must be of type vertex - // TODO(benvanik): some games have type 2, which is texture - maybe - // fetch_slot wrong? - assert_not_zero(fetch->size); - auto allocation = scratch_buffer_.Acquire(fetch->size * sizeof(uint32_t)); - scratch_buffer_stats_.total_vertices_size += fetch->size * sizeof(uint32_t); + // Constrain the vertex upload to just what we are interested in. + const size_t kRangeKludge = 5; // could pick index count based on prim. + uint32_t max_index = index_buffer_info_.guest_base + ? index_buffer_info_.max_index_found + : draw_index_count_; + size_t valid_range = (max_index + kRangeKludge) * desc.stride_words * 4; + valid_range = std::min(valid_range, size_t(fetch->size * 4)); + + auto allocation = scratch_buffer_.Acquire(valid_range); // Copy and byte swap the entire buffer. // We could be smart about this to save GPU bandwidth by building a CRC @@ -2193,93 +2095,35 @@ CommandProcessor::UpdateStatus CommandProcessor::PopulateVertexBuffers( poly::copy_and_swap_32_aligned( reinterpret_cast(allocation.host_ptr), reinterpret_cast(membase_ + (fetch->address << 2)), - fetch->size); + valid_range / 4); if (!has_bindless_vbos_) { - glBindVertexBuffer(n, scratch_buffer_.handle(), allocation.offset, - desc.stride_words * 4); + // TODO(benvanik): if we could find a way to avoid this, we could use + // multidraw without flushing. + glVertexArrayVertexBuffer(active_vertex_shader_->vao(), buffer_index, + scratch_buffer_.handle(), allocation.offset, + desc.stride_words * 4); } - for (uint32_t i = 0; i < desc.element_count; ++i) { - const auto& el = desc.elements[i]; - auto comp_count = GetVertexFormatComponentCount(el.format); - GLenum comp_type; - switch (el.format) { - case VertexFormat::k_8_8_8_8: - comp_type = el.is_signed ? GL_BYTE : GL_UNSIGNED_BYTE; - break; - case VertexFormat::k_2_10_10_10: - comp_type = el.is_signed ? GL_INT_2_10_10_10_REV - : GL_UNSIGNED_INT_2_10_10_10_REV; - break; - case VertexFormat::k_10_11_11: - assert_false(el.is_signed); - comp_type = GL_UNSIGNED_INT_10F_11F_11F_REV; - break; - /*case VertexFormat::k_11_11_10: - break;*/ - case VertexFormat::k_16_16: - comp_type = el.is_signed ? GL_SHORT : GL_UNSIGNED_SHORT; - break; - case VertexFormat::k_16_16_FLOAT: - comp_type = GL_HALF_FLOAT; - break; - case VertexFormat::k_16_16_16_16: - comp_type = el.is_signed ? GL_SHORT : GL_UNSIGNED_SHORT; - break; - case VertexFormat::k_16_16_16_16_FLOAT: - comp_type = GL_HALF_FLOAT; - break; - case VertexFormat::k_32: - comp_type = el.is_signed ? GL_INT : GL_UNSIGNED_INT; - break; - case VertexFormat::k_32_32: - comp_type = el.is_signed ? GL_INT : GL_UNSIGNED_INT; - break; - case VertexFormat::k_32_32_32_32: - comp_type = el.is_signed ? GL_INT : GL_UNSIGNED_INT; - break; - case VertexFormat::k_32_FLOAT: - comp_type = GL_FLOAT; - break; - case VertexFormat::k_32_32_FLOAT: - comp_type = GL_FLOAT; - break; - case VertexFormat::k_32_32_32_FLOAT: - comp_type = GL_FLOAT; - break; - case VertexFormat::k_32_32_32_32_FLOAT: - comp_type = GL_FLOAT; - break; - default: - assert_unhandled_case(el.format); - break; + if (has_bindless_vbos_) { + for (uint32_t i = 0; i < desc.element_count; ++i, ++el_index) { + const auto& el = desc.elements[i]; + draw_batcher_.set_vertex_buffer(el_index, 0, desc.stride_words * 4, + allocation); } - if (has_bindless_vbos_) { - glVertexAttribFormatNV(el_index, comp_count, comp_type, - el.is_normalized, - desc.stride_words * sizeof(uint32_t)); - glBufferAddressRangeNV(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, el_index, - allocation.gpu_ptr + (el.offset_words * 4), - allocation.length - (el.offset_words * 4)); - } else { - glVertexAttribBinding(el_index, n); - glVertexAttribFormat(el_index, comp_count, comp_type, el.is_normalized, - el.offset_words * 4); - } - ++el_index; } - // Flush buffer before we draw. scratch_buffer_.Commit(std::move(allocation)); } - return UpdateStatus::kMismatch; + return UpdateStatus::kCompatible; } -CommandProcessor::UpdateStatus CommandProcessor::PopulateSamplers( - DrawCommand* draw_command) { +CommandProcessor::UpdateStatus CommandProcessor::PopulateSamplers() { +#if FINE_GRAINED_DRAW_SCOPES SCOPE_profile_cpu_f("gpu"); +#endif // FINE_GRAINED_DRAW_SCOPES + auto& regs = *register_file_; bool mismatch = false; @@ -2296,7 +2140,7 @@ CommandProcessor::UpdateStatus CommandProcessor::PopulateSamplers( continue; } has_setup_sampler[desc.fetch_slot] = true; - auto status = PopulateSampler(draw_command, desc); + auto status = PopulateSampler(desc); if (status == UpdateStatus::kError) { return status; } else if (status == UpdateStatus::kMismatch) { @@ -2312,7 +2156,7 @@ CommandProcessor::UpdateStatus CommandProcessor::PopulateSamplers( continue; } has_setup_sampler[desc.fetch_slot] = true; - auto status = PopulateSampler(draw_command, desc); + auto status = PopulateSampler(desc); if (status == UpdateStatus::kError) { return UpdateStatus::kError; } else if (status == UpdateStatus::kMismatch) { @@ -2324,7 +2168,7 @@ CommandProcessor::UpdateStatus CommandProcessor::PopulateSamplers( } CommandProcessor::UpdateStatus CommandProcessor::PopulateSampler( - DrawCommand* draw_command, const Shader::SamplerDesc& desc) { + const Shader::SamplerDesc& desc) { auto& regs = *register_file_; int r = XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 + desc.fetch_slot * 6; auto group = reinterpret_cast(®s.values[r]); @@ -2332,7 +2176,7 @@ CommandProcessor::UpdateStatus CommandProcessor::PopulateSampler( // Reset slot. // If we fail, we still draw but with an invalid texture. - draw_command->state_data->texture_samplers[desc.fetch_slot] = 0; + draw_batcher_.set_texture_sampler(desc.fetch_slot, 0); if (FLAGS_disable_textures) { return UpdateStatus::kCompatible; @@ -2363,13 +2207,13 @@ CommandProcessor::UpdateStatus CommandProcessor::PopulateSampler( } // Shaders will use bindless to fetch right from it. - draw_command->state_data->texture_samplers[desc.fetch_slot] = - entry_view->texture_sampler_handle; + draw_batcher_.set_texture_sampler(desc.fetch_slot, + entry_view->texture_sampler_handle); return UpdateStatus::kCompatible; } -bool CommandProcessor::IssueCopy(DrawCommand* draw_command) { +bool CommandProcessor::IssueCopy() { SCOPE_profile_cpu_f("gpu"); auto& regs = *register_file_; diff --git a/src/xenia/gpu/gl4/command_processor.h b/src/xenia/gpu/gl4/command_processor.h index d1cdcd141..481bb98ff 100644 --- a/src/xenia/gpu/gl4/command_processor.h +++ b/src/xenia/gpu/gl4/command_processor.h @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -41,73 +42,6 @@ struct SwapParameters { GLenum attachment; }; -// This must match the layout in gl4_shader.cc. -struct UniformDataBlock { - union float4 { - float v[4]; - struct { - float x, y, z, w; - }; - }; - - float4 window_offset; // tx,ty,sx,sy - float4 window_scissor; // x0,y0,x1,y1 - float4 vtx_fmt; - float4 viewport_offset; // tx,ty,tz,? - float4 viewport_scale; // sx,sy,sz,? - // TODO(benvanik): vertex format xyzw? - - float4 alpha_test; // alpha test enable, func, ref, ? - - // TODO(benvanik): pack tightly - uint64_t texture_samplers[32]; - - // Register data from 0x4000 to 0x4927. - // UpdateConstants relies on the packing of these. - struct { - // SHADER_CONSTANT_000_X... - float4 float_consts[512]; - // SHADER_CONSTANT_FETCH_00_0 is omitted - // SHADER_CONSTANT_BOOL_000_031... - int32_t bool_consts[8]; - // SHADER_CONSTANT_LOOP_00... - int32_t loop_consts[32]; - }; -}; -static_assert(sizeof(UniformDataBlock) <= 16 * 1024, "Need <=16k uniform data"); - -// TODO(benvanik): move more of the enums in here? -struct DrawCommand { - PrimitiveType prim_type; - uint32_t start_index; - uint32_t min_index; - uint32_t max_index; - uint32_t index_count; - uint32_t base_vertex; - - // Index buffer, if present. - // If index_count > 0 but buffer is nullptr then auto draw. - struct { - const uint8_t* address; - size_t size; - xenos::Endian endianness; - xenos::IndexFormat format; - size_t buffer_offset; - } index_buffer; - - // Texture samplers. - struct SamplerInput { - uint32_t input_index; - // TextureResource* texture; - // SamplerStateResource* sampler_state; - }; - SamplerInput vertex_shader_samplers[32]; - SamplerInput pixel_shader_samplers[32]; - - // NOTE: do not read from this - the mapped memory is likely write combined. - UniformDataBlock* state_data; -}; - class CommandProcessor { public: CommandProcessor(GL4GraphicsSystem* graphics_system); @@ -241,22 +175,19 @@ class CommandProcessor { bool LoadShader(ShaderType shader_type, const uint32_t* address, uint32_t dword_count); - void PrepareDraw(DrawCommand* draw_command); - bool IssueDraw(DrawCommand* draw_command); - UpdateStatus UpdateRenderTargets(DrawCommand* draw_command); - UpdateStatus UpdateState(DrawCommand* draw_command); - UpdateStatus UpdateViewportState(DrawCommand* draw_command); - UpdateStatus UpdateRasterizerState(DrawCommand* draw_command); - UpdateStatus UpdateBlendState(DrawCommand* draw_command); - UpdateStatus UpdateDepthStencilState(DrawCommand* draw_command); - UpdateStatus UpdateConstants(DrawCommand* draw_command); - UpdateStatus UpdateShaders(DrawCommand* draw_command); - UpdateStatus PopulateIndexBuffer(DrawCommand* draw_command); - UpdateStatus PopulateVertexBuffers(DrawCommand* draw_command); - UpdateStatus PopulateSamplers(DrawCommand* draw_command); - UpdateStatus PopulateSampler(DrawCommand* draw_command, - const Shader::SamplerDesc& desc); - bool IssueCopy(DrawCommand* draw_command); + bool IssueDraw(); + UpdateStatus UpdateShaders(PrimitiveType prim_type); + UpdateStatus UpdateRenderTargets(); + UpdateStatus UpdateState(); + UpdateStatus UpdateViewportState(); + UpdateStatus UpdateRasterizerState(); + UpdateStatus UpdateBlendState(); + UpdateStatus UpdateDepthStencilState(); + UpdateStatus PopulateIndexBuffer(); + UpdateStatus PopulateVertexBuffers(); + UpdateStatus PopulateSamplers(); + UpdateStatus PopulateSampler(const Shader::SamplerDesc& desc); + bool IssueCopy(); CachedFramebuffer* GetFramebuffer(GLuint color_targets[4], GLuint depth_target); @@ -306,21 +237,23 @@ class CommandProcessor { std::vector cached_depth_render_targets_; std::vector> all_pipelines_; std::unordered_map cached_pipelines_; - GLuint vertex_array_; GLuint point_list_geometry_program_; GLuint rect_list_geometry_program_; GLuint quad_list_geometry_program_; + struct { + xenos::IndexFormat format; + xenos::Endian endianness; + uint32_t count; + uint32_t guest_base; + size_t length; + uint32_t max_index_found; + } index_buffer_info_; + uint32_t draw_index_count_; TextureCache texture_cache_; + DrawBatcher draw_batcher_; CircularBuffer scratch_buffer_; - struct ScratchBufferStats { - size_t total_state_data_size = 0; - size_t total_indices_size = 0; - size_t total_vertices_size = 0; - } scratch_buffer_stats_; - - DrawCommand draw_command_; private: bool SetShadowRegister(uint32_t& dest, uint32_t register_name); @@ -341,7 +274,6 @@ class CommandProcessor { void Reset() { std::memset(this, 0, sizeof(*this)); } } update_render_targets_regs_; struct UpdateViewportStateRegisters { - // UpdateViewportStateRegisters() { Reset(); } void Reset() { std::memset(this, 0, sizeof(*this)); } } update_viewport_state_regs_; @@ -367,7 +299,6 @@ class CommandProcessor { UpdateDepthStencilStateRegisters() { Reset(); } void Reset() { std::memset(this, 0, sizeof(*this)); } } update_depth_stencil_state_regs_; - // TODO(benvanik): constant bitmask? struct UpdateShadersRegisters { PrimitiveType prim_type; uint32_t sq_program_cntl; @@ -380,9 +311,6 @@ class CommandProcessor { vertex_shader = pixel_shader = nullptr; } } update_shaders_regs_; - // ib - // vb - // samplers }; } // namespace gl4 diff --git a/src/xenia/gpu/gl4/draw_batcher.cc b/src/xenia/gpu/gl4/draw_batcher.cc new file mode 100644 index 000000000..c5d0bdb39 --- /dev/null +++ b/src/xenia/gpu/gl4/draw_batcher.cc @@ -0,0 +1,384 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include +#include +#include +#include + +namespace xe { +namespace gpu { +namespace gl4 { + +using namespace xe::gpu::xenos; + +extern "C" GLEWContext* glewGetContext(); + +const size_t kCommandBufferCapacity = 16 * (1024 * 1024); +const size_t kCommandBufferAlignment = 4; +const size_t kStateBufferCapacity = 64 * (1024 * 1024); +const size_t kStateBufferAlignment = 256; + +DrawBatcher::DrawBatcher(RegisterFile* register_file) + : register_file_(register_file), + command_buffer_(kCommandBufferCapacity, kCommandBufferAlignment), + state_buffer_(kStateBufferCapacity, kStateBufferAlignment), + array_data_buffer_(nullptr), + has_bindless_mdi_(false), + draw_open_(false) { + std::memset(&batch_state_, 0, sizeof(batch_state_)); + batch_state_.needs_reconfigure = true; + batch_state_.command_range_start = batch_state_.state_range_start = + UINTPTR_MAX; + std::memset(&active_draw_, 0, sizeof(active_draw_)); +} + +bool DrawBatcher::Initialize(CircularBuffer* array_data_buffer) { + array_data_buffer_ = array_data_buffer; + if (!command_buffer_.Initialize()) { + return false; + } + if (!state_buffer_.Initialize()) { + return false; + } + glBindBuffer(GL_DRAW_INDIRECT_BUFFER, command_buffer_.handle()); + if (FLAGS_vendor_gl_extensions && GLEW_NV_bindless_multi_draw_indirect) { + has_bindless_mdi_ = true; + } + return true; +} + +void DrawBatcher::Shutdown() { + command_buffer_.Shutdown(); + state_buffer_.Shutdown(); +} + +bool DrawBatcher::ReconfigurePipeline(GL4Shader* vertex_shader, + GL4Shader* pixel_shader, + GLuint pipeline) { + if (batch_state_.pipeline == pipeline) { + // No-op. + return true; + } + if (!Flush(FlushMode::kReconfigure)) { + return false; + } + + batch_state_.vertex_shader = vertex_shader; + batch_state_.pixel_shader = pixel_shader; + batch_state_.pipeline = pipeline; + + return true; +} + +bool DrawBatcher::BeginDrawArrays(PrimitiveType prim_type, + uint32_t index_count) { + assert_false(draw_open_); + if (batch_state_.prim_type != prim_type || batch_state_.indexed) { + if (!Flush(FlushMode::kReconfigure)) { + return false; + } + } + batch_state_.prim_type = prim_type; + batch_state_.indexed = false; + + if (!BeginDraw()) { + return false; + } + + auto cmd = active_draw_.draw_arrays_cmd; + cmd->base_instance = 0; + cmd->instance_count = 1; + cmd->count = index_count; + cmd->first_index = 0; + + return true; +} + +bool DrawBatcher::BeginDrawElements(PrimitiveType prim_type, + uint32_t index_count, + IndexFormat index_format) { + assert_false(draw_open_); + GLenum index_type = + index_format == IndexFormat::kInt32 ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT; + if (batch_state_.prim_type != prim_type || !batch_state_.indexed || + batch_state_.index_type != index_type) { + if (!Flush(FlushMode::kReconfigure)) { + return false; + } + } + batch_state_.prim_type = prim_type; + batch_state_.indexed = true; + batch_state_.index_type = index_type; + + if (!BeginDraw()) { + return false; + } + + uint32_t start_index = register_file_->values[XE_GPU_REG_VGT_INDX_OFFSET].u32; + assert_zero(start_index); + + auto cmd = active_draw_.draw_elements_cmd; + cmd->base_instance = 0; + cmd->instance_count = 1; + cmd->count = index_count; + cmd->first_index = start_index; + cmd->base_vertex = 0; + + if (has_bindless_mdi_) { + auto bindless_cmd = active_draw_.draw_elements_bindless_cmd; + bindless_cmd->reserved_zero = 0; + } + return true; +} + +bool DrawBatcher::BeginDraw() { + draw_open_ = true; + + if (batch_state_.needs_reconfigure) { + batch_state_.needs_reconfigure = false; + // Have been reconfigured since last draw - need to compute state size. + // Layout: + // [draw command] + // [common header] + // [consts] + + // Padded to max. + GLsizei command_size = 0; + if (has_bindless_mdi_) { + if (batch_state_.indexed) { + command_size = sizeof(DrawElementsIndirectBindlessCommandNV); + } else { + command_size = sizeof(DrawArraysIndirectBindlessCommandNV); + } + } else { + if (batch_state_.indexed) { + command_size = sizeof(DrawElementsIndirectCommand); + } else { + command_size = sizeof(DrawArraysIndirectCommand); + } + } + batch_state_.command_stride = + poly::round_up(command_size, GLsizei(kCommandBufferAlignment)); + + GLsizei header_size = sizeof(CommonHeader); + + // TODO(benvanik); consts sizing. + // GLsizei float_consts_size = sizeof(float4) * 512; + // GLsizei bool_consts_size = sizeof(uint32_t) * 8; + // GLsizei loop_consts_size = sizeof(uint32_t) * 32; + // GLsizei consts_size = + // float_consts_size + bool_consts_size + loop_consts_size; + // batch_state_.float_consts_offset = batch_state_.header_offset + + // header_size; + // batch_state_.bool_consts_offset = + // batch_state_.float_consts_offset + float_consts_size; + // batch_state_.loop_consts_offset = + // batch_state_.bool_consts_offset + bool_consts_size; + GLsizei consts_size = 0; + + batch_state_.state_stride = header_size + consts_size; + } + + // Allocate a command data block. + // We should treat it as write-only. + if (!command_buffer_.CanAcquire(batch_state_.command_stride)) { + Flush(FlushMode::kMakeCoherent); + } + active_draw_.command_allocation = + command_buffer_.Acquire(batch_state_.command_stride); + assert_not_null(active_draw_.command_allocation.host_ptr); + + // Allocate a state data block. + // We should treat it as write-only. + if (!state_buffer_.CanAcquire(batch_state_.state_stride)) { + Flush(FlushMode::kMakeCoherent); + } + active_draw_.state_allocation = + state_buffer_.Acquire(batch_state_.state_stride); + assert_not_null(active_draw_.state_allocation.host_ptr); + + active_draw_.command_address = + reinterpret_cast(active_draw_.command_allocation.host_ptr); + auto state_host_ptr = + reinterpret_cast(active_draw_.state_allocation.host_ptr); + active_draw_.header = reinterpret_cast(state_host_ptr); + // active_draw_.float_consts = + // reinterpret_cast(state_host_ptr + + // batch_state_.float_consts_offset); + // active_draw_.bool_consts = + // reinterpret_cast(state_host_ptr + + // batch_state_.bool_consts_offset); + // active_draw_.loop_consts = + // reinterpret_cast(state_host_ptr + + // batch_state_.loop_consts_offset); + return true; +} + +void DrawBatcher::DiscardDraw() { + if (!draw_open_) { + // No-op. + return; + } + draw_open_ = false; + + command_buffer_.Discard(std::move(active_draw_.command_allocation)); + state_buffer_.Discard(std::move(active_draw_.state_allocation)); +} + +bool DrawBatcher::CommitDraw() { + assert_true(draw_open_); + draw_open_ = false; + + // Copy over required constants. + CopyConstants(); + + if (batch_state_.state_range_start == UINTPTR_MAX) { + batch_state_.command_range_start = active_draw_.command_allocation.offset; + batch_state_.state_range_start = active_draw_.state_allocation.offset; + } + batch_state_.command_range_length += + active_draw_.command_allocation.aligned_length; + batch_state_.state_range_length += + active_draw_.state_allocation.aligned_length; + + command_buffer_.Commit(std::move(active_draw_.command_allocation)); + state_buffer_.Commit(std::move(active_draw_.state_allocation)); + + ++batch_state_.draw_count; + return true; +} + +bool DrawBatcher::Flush(FlushMode mode) { + if (batch_state_.draw_count) { + SCOPE_profile_cpu_f("gpu"); + + assert_not_zero(batch_state_.command_stride); + assert_not_zero(batch_state_.state_stride); + + // Flush pending buffer changes. + command_buffer_.Flush(); + state_buffer_.Flush(); + array_data_buffer_->Flush(); + + // State data is indexed by draw ID. + glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, state_buffer_.handle(), + batch_state_.state_range_start, + batch_state_.state_range_length); + + GLenum prim_type = 0; + switch (batch_state_.prim_type) { + case PrimitiveType::kPointList: + prim_type = GL_POINTS; + break; + case PrimitiveType::kLineList: + prim_type = GL_LINES; + break; + case PrimitiveType::kLineStrip: + prim_type = GL_LINE_STRIP; + break; + case PrimitiveType::kLineLoop: + prim_type = GL_LINE_LOOP; + break; + case PrimitiveType::kTriangleList: + prim_type = GL_TRIANGLES; + break; + case PrimitiveType::kTriangleStrip: + prim_type = GL_TRIANGLE_STRIP; + break; + case PrimitiveType::kTriangleFan: + prim_type = GL_TRIANGLE_FAN; + break; + case PrimitiveType::kRectangleList: + prim_type = GL_TRIANGLE_STRIP; + // Rect lists aren't culled. There may be other things they skip too. + // assert_true((register_file_->values[XE_GPU_REG_PA_SU_SC_MODE_CNTL].u32 + // & + // 0x3) == 0); + break; + case PrimitiveType::kQuadList: + prim_type = GL_LINES_ADJACENCY; + break; + default: + case PrimitiveType::kUnknown0x07: + prim_type = GL_POINTS; + XELOGE("unsupported primitive type %d", batch_state_.prim_type); + assert_unhandled_case(batch_state_.prim_type); + DiscardDraw(); + return false; + } + + // Fast path for single draws. + void* indirect_offset = + reinterpret_cast(batch_state_.command_range_start); + + if (has_bindless_mdi_) { + int vertex_buffer_count = + batch_state_.vertex_shader->buffer_inputs().total_elements_count; + assert_true(vertex_buffer_count < 8); + if (batch_state_.indexed) { + glMultiDrawElementsIndirectBindlessNV( + prim_type, batch_state_.index_type, indirect_offset, + batch_state_.draw_count, batch_state_.command_stride, + vertex_buffer_count); + } else { + glMultiDrawArraysIndirectBindlessNV( + prim_type, indirect_offset, batch_state_.draw_count, + batch_state_.command_stride, vertex_buffer_count); + } + } else { + if (batch_state_.indexed) { + glMultiDrawElementsIndirect(prim_type, batch_state_.index_type, + indirect_offset, batch_state_.draw_count, + batch_state_.command_stride); + } else { + glMultiDrawArraysIndirect(prim_type, indirect_offset, + batch_state_.draw_count, + batch_state_.command_stride); + } + } + + batch_state_.command_range_start = UINTPTR_MAX; + batch_state_.command_range_length = 0; + batch_state_.state_range_start = UINTPTR_MAX; + batch_state_.state_range_length = 0; + batch_state_.draw_count = 0; + } + + if (mode == FlushMode::kReconfigure) { + // Reset - we'll update it as soon as we have all the information. + batch_state_.needs_reconfigure = true; + } + + return true; +} + +void DrawBatcher::CopyConstants() { + // TODO(benvanik): partial updates, etc. We could use shader constant access + // knowledge that we get at compile time to only upload those constants + // required. If we did this as a variable length then we could really cut + // down on state block sizes. + + std::memcpy(active_draw_.header->float_consts, + ®ister_file_->values[XE_GPU_REG_SHADER_CONSTANT_000_X].f32, + sizeof(active_draw_.header->float_consts)); + std::memcpy( + active_draw_.header->bool_consts, + ®ister_file_->values[XE_GPU_REG_SHADER_CONSTANT_BOOL_000_031].f32, + sizeof(active_draw_.header->bool_consts)); + std::memcpy(active_draw_.header->loop_consts, + ®ister_file_->values[XE_GPU_REG_SHADER_CONSTANT_LOOP_00].f32, + sizeof(active_draw_.header->loop_consts)); +} + +} // namespace gl4 +} // namespace gpu +} // namespace xe diff --git a/src/xenia/gpu/gl4/draw_batcher.h b/src/xenia/gpu/gl4/draw_batcher.h new file mode 100644 index 000000000..f930ba2a0 --- /dev/null +++ b/src/xenia/gpu/gl4/draw_batcher.h @@ -0,0 +1,230 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_GPU_GL4_GL4_STATE_DATA_BUILDER_H_ +#define XENIA_GPU_GL4_GL4_STATE_DATA_BUILDER_H_ + +#include +#include +#include +#include +#include +#include + +namespace xe { +namespace gpu { +namespace gl4 { + +union float4 { + float v[4]; + struct { + float x, y, z, w; + }; +}; + +#pragma pack(push, 4) +struct DrawArraysIndirectCommand { + GLuint count; + GLuint instance_count; + GLuint first_index; + GLuint base_instance; +}; +struct DrawElementsIndirectCommand { + GLuint count; + GLuint instance_count; + GLuint first_index; + GLint base_vertex; + GLuint base_instance; +}; +struct BindlessPtrNV { + GLuint index; + GLuint reserved_zero; + GLuint64 address; + GLuint64 length; +}; +struct DrawArraysIndirectBindlessCommandNV { + DrawArraysIndirectCommand cmd; + // NOTE: the spec is wrong here. For fucks sake. + // GLuint reserved_zero; + BindlessPtrNV vertex_buffers[8]; +}; +struct DrawElementsIndirectBindlessCommandNV { + DrawElementsIndirectCommand cmd; + GLuint reserved_zero; + BindlessPtrNV index_buffer; + BindlessPtrNV vertex_buffers[8]; +}; +#pragma pack(pop) + +class DrawBatcher { + public: + enum class FlushMode { + kMakeCoherent, + kStateChange, + kReconfigure, + }; + + DrawBatcher(RegisterFile* register_file); + + bool Initialize(CircularBuffer* array_data_buffer); + void Shutdown(); + + PrimitiveType prim_type() const { return batch_state_.prim_type; } + + void set_window_offset(uint32_t x, uint32_t y) { + active_draw_.header->window_offset.x = float(x); + active_draw_.header->window_offset.y = float(y); + } + void set_window_scissor(uint32_t left, uint32_t top, uint32_t right, + uint32_t bottom) { + active_draw_.header->window_scissor.x = float(left); + active_draw_.header->window_scissor.y = float(top); + active_draw_.header->window_scissor.z = float(right); + active_draw_.header->window_scissor.w = float(bottom); + } + void set_window_scalar(float width_scalar, float height_scalar) { + active_draw_.header->window_offset.z = width_scalar; + active_draw_.header->window_offset.w = height_scalar; + } + void set_viewport_offset(float offset_x, float offset_y, float offset_z) { + active_draw_.header->viewport_offset.x = offset_x; + active_draw_.header->viewport_offset.y = offset_y; + active_draw_.header->viewport_offset.z = offset_z; + } + void set_viewport_scale(float scale_x, float scale_y, float scale_z) { + active_draw_.header->viewport_scale.x = scale_x; + active_draw_.header->viewport_scale.y = scale_y; + active_draw_.header->viewport_scale.z = scale_z; + } + void set_vtx_fmt(float xy, float z, float w) { + active_draw_.header->vtx_fmt.x = xy; + active_draw_.header->vtx_fmt.y = xy; + active_draw_.header->vtx_fmt.z = z; + active_draw_.header->vtx_fmt.w = w; + } + void set_alpha_test(bool enabled, uint32_t func, float ref) { + active_draw_.header->alpha_test.x = enabled ? 1.0f : 0.0f; + active_draw_.header->alpha_test.y = float(func); + active_draw_.header->alpha_test.z = ref; + } + void set_texture_sampler(int index, GLuint64 handle) { + active_draw_.header->texture_samplers[index] = handle; + } + void set_index_buffer(const CircularBuffer::Allocation& allocation) { + if (has_bindless_mdi_) { + auto& ptr = active_draw_.draw_elements_bindless_cmd->index_buffer; + ptr.reserved_zero = 0; + ptr.index = 0; + ptr.address = allocation.gpu_ptr; + ptr.length = allocation.length; + } else { + // Offset is used in glDrawElements. + auto& cmd = active_draw_.draw_elements_cmd; + size_t index_size = batch_state_.index_type == GL_UNSIGNED_SHORT ? 2 : 4; + cmd->first_index = GLuint(allocation.offset / index_size); + } + } + void set_vertex_buffer(int index, GLsizei offset, GLsizei stride, + const CircularBuffer::Allocation& allocation) { + if (has_bindless_mdi_) { + BindlessPtrNV* ptr; + if (batch_state_.indexed) { + ptr = &active_draw_.draw_elements_bindless_cmd->vertex_buffers[index]; + } else { + ptr = &active_draw_.draw_arrays_bindless_cmd->vertex_buffers[index]; + } + ptr->reserved_zero = 0; + ptr->index = index; + ptr->address = allocation.gpu_ptr + offset; + ptr->length = allocation.length - offset; + } + } + + bool ReconfigurePipeline(GL4Shader* vertex_shader, GL4Shader* pixel_shader, + GLuint pipeline); + + bool BeginDrawArrays(PrimitiveType prim_type, uint32_t index_count); + bool BeginDrawElements(PrimitiveType prim_type, uint32_t index_count, + xenos::IndexFormat index_format); + void DiscardDraw(); + bool CommitDraw(); + bool Flush(FlushMode mode); + + private: + bool BeginDraw(); + void CopyConstants(); + + RegisterFile* register_file_; + CircularBuffer command_buffer_; + CircularBuffer state_buffer_; + CircularBuffer* array_data_buffer_; + + bool has_bindless_mdi_; + + struct BatchState { + bool needs_reconfigure; + PrimitiveType prim_type; + bool indexed; + GLenum index_type; + + GL4Shader* vertex_shader; + GL4Shader* pixel_shader; + GLuint pipeline; + + GLsizei command_stride; + GLsizei state_stride; + GLsizei float_consts_offset; + GLsizei bool_consts_offset; + GLsizei loop_consts_offset; + + uintptr_t command_range_start; + uintptr_t command_range_length; + uintptr_t state_range_start; + uintptr_t state_range_length; + GLsizei draw_count; + } batch_state_; + + // This must match GL4Shader's header. + struct CommonHeader { + float4 window_offset; // tx,ty,sx,sy + float4 window_scissor; // x0,y0,x1,y1 + float4 viewport_offset; // tx,ty,tz,? + float4 viewport_scale; // sx,sy,sz,? + float4 vtx_fmt; // + float4 alpha_test; // alpha test enable, func, ref, ? + + // TODO(benvanik): pack tightly + GLuint64 texture_samplers[32]; + + float4 float_consts[512]; + uint32_t bool_consts[8]; + uint32_t loop_consts[32]; + }; + struct { + CircularBuffer::Allocation command_allocation; + CircularBuffer::Allocation state_allocation; + + union { + DrawArraysIndirectCommand* draw_arrays_cmd; + DrawElementsIndirectCommand* draw_elements_cmd; + DrawArraysIndirectBindlessCommandNV* draw_arrays_bindless_cmd; + DrawElementsIndirectBindlessCommandNV* draw_elements_bindless_cmd; + uintptr_t command_address; + }; + + CommonHeader* header; + } active_draw_; + bool draw_open_; +}; + +} // namespace gl4 +} // namespace gpu +} // namespace xe + +#endif // XENIA_GPU_GL4_GL4_STATE_DATA_BUILDER_H_ diff --git a/src/xenia/gpu/gl4/gl4_shader.cc b/src/xenia/gpu/gl4/gl4_shader.cc index 3409824a2..2255be226 100644 --- a/src/xenia/gpu/gl4/gl4_shader.cc +++ b/src/xenia/gpu/gl4/gl4_shader.cc @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -18,6 +19,8 @@ namespace xe { namespace gpu { namespace gl4 { +using namespace xe::gpu::xenos; + extern "C" GLEWContext* glewGetContext(); // Stateful, but minimally. @@ -25,41 +28,147 @@ thread_local GL4ShaderTranslator shader_translator_; GL4Shader::GL4Shader(ShaderType shader_type, uint64_t data_hash, const uint32_t* dword_ptr, uint32_t dword_count) - : Shader(shader_type, data_hash, dword_ptr, dword_count), program_(0) {} + : Shader(shader_type, data_hash, dword_ptr, dword_count), + program_(0), + vao_(0) {} -GL4Shader::~GL4Shader() { glDeleteProgram(program_); } +GL4Shader::~GL4Shader() { + glDeleteProgram(program_); + glDeleteVertexArrays(1, &vao_); +} -const std::string header = - "#version 450\n" - "#extension all : warn\n" - "#extension GL_ARB_bindless_texture : require\n" - "#extension GL_ARB_explicit_uniform_location : require\n" - "#extension GL_ARB_shading_language_420pack : require\n" - "#extension GL_ARB_shader_storage_buffer_object : require\n" - "precision highp float;\n" - "precision highp int;\n" - "layout(std140, column_major) uniform;\n" - "layout(std430, column_major) buffer;\n" - "struct StateData {\n" - " vec4 window_offset;\n" - " vec4 window_scissor;\n" - " vec4 vtx_fmt;\n" - " vec4 viewport_offset;\n" - " vec4 viewport_scale;\n" - " vec4 alpha_test;\n" - " uvec2 texture_samplers[32];\n" - " vec4 float_consts[512];\n" - " uint fetch_consts[32 * 6];\n" - " int bool_consts[8];\n" - " int loop_consts[32];\n" - "};\n" - "struct VertexData {\n" - " vec4 o[16];\n" - "};\n" - "\n" - "layout(binding = 0) buffer State {\n" - " StateData state;\n" - "};\n"; +std::string GL4Shader::GetHeader() { + static const std::string header = + "#version 450\n" + "#extension all : warn\n" + "#extension GL_ARB_bindless_texture : require\n" + "#extension GL_ARB_explicit_uniform_location : require\n" + "#extension GL_ARB_shader_draw_parameters : require\n" + "#extension GL_ARB_shader_storage_buffer_object : require\n" + "#extension GL_ARB_shading_language_420pack : require\n" + "precision highp float;\n" + "precision highp int;\n" + "layout(std140, column_major) uniform;\n" + "layout(std430, column_major) buffer;\n" + "\n" + // This must match DrawBatcher::CommonHeader. + "struct StateData {\n" + " vec4 window_offset;\n" + " vec4 window_scissor;\n" + " vec4 viewport_offset;\n" + " vec4 viewport_scale;\n" + " vec4 vtx_fmt;\n" + " vec4 alpha_test;\n" + // TODO(benvanik): variable length. + " uvec2 texture_samplers[32];\n" + " vec4 float_consts[512];\n" + " int bool_consts[8];\n" + " int loop_consts[32];\n" + "};\n" + "layout(binding = 0) buffer State {\n" + " StateData states[];\n" + "};\n" + "\n" + "struct VertexData {\n" + " vec4 o[16];\n" + "};\n"; + return header; +} + +bool GL4Shader::PrepareVertexArrayObject() { + glCreateVertexArrays(1, &vao_); + + bool has_bindless_vbos = false; + if (FLAGS_vendor_gl_extensions && GLEW_NV_vertex_buffer_unified_memory) { + has_bindless_vbos = true; + // Nasty, but no DSA for this. + glBindVertexArray(vao_); + glEnableClientState(GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV); + glEnableClientState(GL_ELEMENT_ARRAY_UNIFIED_NV); + } + + uint32_t el_index = 0; + for (uint32_t buffer_index = 0; buffer_index < buffer_inputs_.count; + ++buffer_index) { + const auto& desc = buffer_inputs_.descs[buffer_index]; + + for (uint32_t i = 0; i < desc.element_count; ++i, ++el_index) { + const auto& el = desc.elements[i]; + auto comp_count = GetVertexFormatComponentCount(el.format); + GLenum comp_type; + switch (el.format) { + case VertexFormat::k_8_8_8_8: + comp_type = el.is_signed ? GL_BYTE : GL_UNSIGNED_BYTE; + break; + case VertexFormat::k_2_10_10_10: + comp_type = el.is_signed ? GL_INT_2_10_10_10_REV + : GL_UNSIGNED_INT_2_10_10_10_REV; + break; + case VertexFormat::k_10_11_11: + assert_false(el.is_signed); + comp_type = GL_UNSIGNED_INT_10F_11F_11F_REV; + break; + /*case VertexFormat::k_11_11_10: + break;*/ + case VertexFormat::k_16_16: + comp_type = el.is_signed ? GL_SHORT : GL_UNSIGNED_SHORT; + break; + case VertexFormat::k_16_16_FLOAT: + comp_type = GL_HALF_FLOAT; + break; + case VertexFormat::k_16_16_16_16: + comp_type = el.is_signed ? GL_SHORT : GL_UNSIGNED_SHORT; + break; + case VertexFormat::k_16_16_16_16_FLOAT: + comp_type = GL_HALF_FLOAT; + break; + case VertexFormat::k_32: + comp_type = el.is_signed ? GL_INT : GL_UNSIGNED_INT; + break; + case VertexFormat::k_32_32: + comp_type = el.is_signed ? GL_INT : GL_UNSIGNED_INT; + break; + case VertexFormat::k_32_32_32_32: + comp_type = el.is_signed ? GL_INT : GL_UNSIGNED_INT; + break; + case VertexFormat::k_32_FLOAT: + comp_type = GL_FLOAT; + break; + case VertexFormat::k_32_32_FLOAT: + comp_type = GL_FLOAT; + break; + case VertexFormat::k_32_32_32_FLOAT: + comp_type = GL_FLOAT; + break; + case VertexFormat::k_32_32_32_32_FLOAT: + comp_type = GL_FLOAT; + break; + default: + assert_unhandled_case(el.format); + return false; + } + + glEnableVertexArrayAttrib(vao_, el_index); + if (has_bindless_vbos) { + // NOTE: MultiDrawIndirectBindlessMumble doesn't handle separate + // vertex bindings/formats. + glVertexAttribFormat(el_index, comp_count, comp_type, el.is_normalized, + el.offset_words * 4); + glVertexArrayVertexBuffer(vao_, el_index, 0, 0, desc.stride_words * 4); + } else { + glVertexArrayAttribBinding(vao_, el_index, buffer_index); + glVertexArrayAttribFormat(vao_, el_index, comp_count, comp_type, + el.is_normalized, el.offset_words * 4); + } + } + } + + if (has_bindless_vbos) { + glBindVertexArray(0); + } + + return true; +} bool GL4Shader::PrepareVertexShader( const xenos::xe_gpu_program_cntl_t& program_cntl) { @@ -68,8 +177,14 @@ bool GL4Shader::PrepareVertexShader( } has_prepared_ = true; + // Build static vertex array descriptor. + if (!PrepareVertexArrayObject()) { + PLOGE("Unable to prepare vertex shader array object"); + return false; + } + std::string apply_transform = - "vec4 applyTransform(vec4 pos) {\n" + "vec4 applyTransform(const in StateData state, vec4 pos) {\n" " // Clip->NDC with perspective divide.\n" " // We do this here because it's programmable on the 360.\n" " float w = pos.w;\n" @@ -107,14 +222,15 @@ bool GL4Shader::PrepareVertexShader( " return pos;\n" "}\n"; std::string source = - header + apply_transform + + GetHeader() + apply_transform + "out gl_PerVertex {\n" " vec4 gl_Position;\n" " float gl_PointSize;\n" " float gl_ClipDistance[];\n" "};\n" - "layout(location = 0) out VertexData vtx;\n" - "void processVertex();\n" + "layout(location = 0) flat out uint draw_id;\n" + "layout(location = 1) out VertexData vtx;\n" + "void processVertex(const in StateData state);\n" "void main() {\n" + (alloc_counts().positions ? " gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n" : "") + @@ -122,8 +238,10 @@ bool GL4Shader::PrepareVertexShader( " for (int i = 0; i < vtx.o.length(); ++i) {\n" " vtx.o[i] = vec4(0.0, 0.0, 0.0, 0.0);\n" " }\n" - " processVertex();\n" - " gl_Position = applyTransform(gl_Position);\n" + " const StateData state = states[gl_DrawIDARB];\n" + " processVertex(state);\n" + " gl_Position = applyTransform(state, gl_Position);\n" + " draw_id = gl_DrawIDARB;\n" "}\n"; std::string translated_source = @@ -149,12 +267,14 @@ bool GL4Shader::PreparePixelShader( } has_prepared_ = true; - std::string source = header + - "layout(location = 0) in VertexData vtx;\n" + std::string source = GetHeader() + + "layout(location = 0) flat in uint draw_id;\n" + "layout(location = 1) in VertexData vtx;\n" "layout(location = 0) out vec4 oC[4];\n" - "void processFragment();\n" + "void processFragment(const in StateData state);\n" "void main() {\n" + - " processFragment();\n" + " const StateData state = states[draw_id];\n" + " processFragment(state);\n" "}\n"; std::string translated_source = diff --git a/src/xenia/gpu/gl4/gl4_shader.h b/src/xenia/gpu/gl4/gl4_shader.h index da3c3df78..1dac6b4c3 100644 --- a/src/xenia/gpu/gl4/gl4_shader.h +++ b/src/xenia/gpu/gl4/gl4_shader.h @@ -10,6 +10,8 @@ #ifndef XENIA_GPU_GL4_GL4_SHADER_H_ #define XENIA_GPU_GL4_GL4_SHADER_H_ +#include + #include #include #include @@ -25,14 +27,18 @@ class GL4Shader : public Shader { ~GL4Shader() override; GLuint program() const { return program_; } + GLuint vao() const { return vao_; } bool PrepareVertexShader(const xenos::xe_gpu_program_cntl_t& program_cntl); bool PreparePixelShader(const xenos::xe_gpu_program_cntl_t& program_cntl); protected: + std::string GetHeader(); + bool PrepareVertexArrayObject(); bool CompileProgram(std::string source); GLuint program_; + GLuint vao_; }; } // namespace gl4 diff --git a/src/xenia/gpu/gl4/gl4_shader_translator.cc b/src/xenia/gpu/gl4/gl4_shader_translator.cc index e314191ea..1b3aff02b 100644 --- a/src/xenia/gpu/gl4/gl4_shader_translator.cc +++ b/src/xenia/gpu/gl4/gl4_shader_translator.cc @@ -91,7 +91,7 @@ std::string GL4ShaderTranslator::TranslateVertexShader( const auto& alloc_counts = vertex_shader->alloc_counts(); // Vertex shader main() header. - Append("void processVertex() {\n"); + Append("void processVertex(const in StateData state) {\n"); // Add temporaries for any registers we may use. uint32_t temp_regs = program_cntl.vs_regs + program_cntl.ps_regs; @@ -126,7 +126,7 @@ std::string GL4ShaderTranslator::TranslatePixelShader( // (and less than the number of required registers), things may die. // Pixel shader main() header. - Append("void processFragment() {\n"); + Append("void processFragment(const in StateData state) {\n"); // Add temporary registers. uint32_t temp_regs = program_cntl.vs_regs + program_cntl.ps_regs; diff --git a/src/xenia/gpu/gl4/gl_context.cc b/src/xenia/gpu/gl4/gl_context.cc index d5e39fa34..3d4600514 100644 --- a/src/xenia/gpu/gl4/gl_context.cc +++ b/src/xenia/gpu/gl4/gl_context.cc @@ -132,12 +132,15 @@ std::unique_ptr GLContext::CreateShared() { GLContextLock context_lock(this); int context_flags = 0; + //int profile = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + int profile = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; #if DEBUG context_flags |= WGL_CONTEXT_DEBUG_BIT_ARB; -#endif // DEBUG - int attrib_list[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 4, // - WGL_CONTEXT_MINOR_VERSION_ARB, 5, // - WGL_CONTEXT_FLAGS_ARB, context_flags, // +#endif // DEBUG + int attrib_list[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 4, // + WGL_CONTEXT_MINOR_VERSION_ARB, 5, // + WGL_CONTEXT_FLAGS_ARB, context_flags, // + WGL_CONTEXT_PROFILE_MASK_ARB, profile, // 0}; new_glrc = wglCreateContextAttribsARB(dc_, glrc_, attrib_list); if (!new_glrc) { diff --git a/src/xenia/gpu/gl4/sources.gypi b/src/xenia/gpu/gl4/sources.gypi index efc52f2b6..2f5c0db72 100644 --- a/src/xenia/gpu/gl4/sources.gypi +++ b/src/xenia/gpu/gl4/sources.gypi @@ -5,6 +5,8 @@ 'circular_buffer.h', 'command_processor.cc', 'command_processor.h', + 'draw_batcher.cc', + 'draw_batcher.h', 'gl4_gpu-private.h', 'gl4_gpu.cc', 'gl4_gpu.h', From 55c4488ab2127adbc4a24e7e7753f79fc06d96aa Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 4 Jan 2015 14:23:28 -0800 Subject: [PATCH 323/388] Fast-pathing MDI's that have only one draw. --- src/xenia/gpu/gl4/draw_batcher.cc | 33 ++++++++++++++++++++------ src/xenia/kernel/xboxkrnl_threading.cc | 2 +- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/xenia/gpu/gl4/draw_batcher.cc b/src/xenia/gpu/gl4/draw_batcher.cc index c5d0bdb39..304992a80 100644 --- a/src/xenia/gpu/gl4/draw_batcher.cc +++ b/src/xenia/gpu/gl4/draw_batcher.cc @@ -335,14 +335,33 @@ bool DrawBatcher::Flush(FlushMode mode) { batch_state_.command_stride, vertex_buffer_count); } } else { - if (batch_state_.indexed) { - glMultiDrawElementsIndirect(prim_type, batch_state_.index_type, - indirect_offset, batch_state_.draw_count, - batch_state_.command_stride); + if (batch_state_.draw_count == 1) { + // Fast path for one draw. Removes MDI overhead when not required. + if (batch_state_.indexed) { + auto& cmd = active_draw_.draw_elements_cmd; + glDrawElementsInstancedBaseVertexBaseInstance( + prim_type, cmd->count, batch_state_.index_type, + reinterpret_cast( + uintptr_t(cmd->first_index) * + (batch_state_.index_type == GL_UNSIGNED_SHORT ? 2 : 4)), + cmd->instance_count, cmd->base_vertex, cmd->base_instance); + } else { + auto& cmd = active_draw_.draw_arrays_cmd; + glDrawArraysInstancedBaseInstance(prim_type, cmd->first_index, + cmd->count, cmd->instance_count, + cmd->base_instance); + } } else { - glMultiDrawArraysIndirect(prim_type, indirect_offset, - batch_state_.draw_count, - batch_state_.command_stride); + // Full multi-draw. + if (batch_state_.indexed) { + glMultiDrawElementsIndirect(prim_type, batch_state_.index_type, + indirect_offset, batch_state_.draw_count, + batch_state_.command_stride); + } else { + glMultiDrawArraysIndirect(prim_type, indirect_offset, + batch_state_.draw_count, + batch_state_.command_stride); + } } } diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index e63ca2ef0..4c404aa1b 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -287,7 +287,7 @@ SHIM_CALL KeDelayExecutionThread_shim(PPCContext* ppc_state, } SHIM_CALL NtYieldExecution_shim(PPCContext* ppc_state, KernelState* state) { - XELOGD("NtYieldExecution()"); + //XELOGD("NtYieldExecution()"); XThread* thread = XThread::GetCurrentThread(); X_STATUS result = thread->Delay(0, 0, 0); SHIM_SET_RETURN_64(0); From 0529fdb84d961a9287249858ca818ddb8dbbd9cb Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 4 Jan 2015 16:28:42 -0800 Subject: [PATCH 324/388] Basic hacky write watching for texture invalidation. Doesn't scale. --- src/xenia/cpu/mmio_handler.cc | 108 ++++++++++++++++++++++++- src/xenia/cpu/mmio_handler.h | 25 ++++++ src/xenia/gpu/gl4/command_processor.cc | 2 +- src/xenia/gpu/gl4/texture_cache.cc | 71 ++++++++++------ src/xenia/gpu/gl4/texture_cache.h | 8 +- src/xenia/memory.cc | 29 ++++--- src/xenia/memory.h | 5 ++ 7 files changed, 207 insertions(+), 41 deletions(-) diff --git a/src/xenia/cpu/mmio_handler.cc b/src/xenia/cpu/mmio_handler.cc index 299d2704e..eb6834b38 100644 --- a/src/xenia/cpu/mmio_handler.cc +++ b/src/xenia/cpu/mmio_handler.cc @@ -78,6 +78,109 @@ bool MMIOHandler::CheckStore(uint64_t address, uint64_t value) { return false; } +uintptr_t MMIOHandler::AddWriteWatch(uint32_t guest_address, size_t length, + WriteWatchCallback callback, + void* callback_context, + void* callback_data) { + uint32_t base_address = guest_address; + if (base_address > 0xA0000000) { + base_address -= 0xA0000000; + } + + // Add to table. The slot reservation may evict a previous watch, which + // could include our target, so we do it first. + auto entry = new WriteWatchEntry(); + entry->address = base_address; + entry->length = uint32_t(length); + entry->callback = callback; + entry->callback_context = callback_context; + entry->callback_data = callback_data; + write_watch_mutex_.lock(); + write_watches_.push_back(entry); + write_watch_mutex_.unlock(); + + // Make the desired range read only under all address spaces. + auto host_address = mapping_base_ + base_address; + DWORD old_protect; + VirtualProtect(host_address, length, PAGE_READONLY, &old_protect); + VirtualProtect(host_address + 0xA0000000, length, PAGE_READONLY, + &old_protect); + VirtualProtect(host_address + 0xC0000000, length, PAGE_READONLY, + &old_protect); + VirtualProtect(host_address + 0xE0000000, length, PAGE_READONLY, + &old_protect); + + return reinterpret_cast(entry); +} + +void MMIOHandler::ClearWriteWatch(WriteWatchEntry* entry) { + auto host_address = mapping_base_ + entry->address; + DWORD old_protect; + VirtualProtect(host_address, entry->length, PAGE_READWRITE, nullptr); + VirtualProtect(host_address + 0xA0000000, entry->length, PAGE_READWRITE, + &old_protect); + VirtualProtect(host_address + 0xC0000000, entry->length, PAGE_READWRITE, + &old_protect); + VirtualProtect(host_address + 0xE0000000, entry->length, PAGE_READWRITE, + &old_protect); +} + +void MMIOHandler::CancelWriteWatch(uintptr_t watch_handle) { + auto entry = reinterpret_cast(watch_handle); + + // Allow access to the range again. + ClearWriteWatch(entry); + + // Remove from table. + write_watch_mutex_.lock(); + auto it = std::find(write_watches_.begin(), write_watches_.end(), entry); + if (it != write_watches_.end()) { + write_watches_.erase(it); + } + write_watch_mutex_.unlock(); + + delete entry; +} + +bool MMIOHandler::CheckWriteWatch(void* thread_state, uint64_t fault_address) { + uint32_t guest_address = uint32_t(fault_address - uintptr_t(mapping_base_)); + uint32_t base_address = guest_address; + if (base_address > 0xA0000000) { + base_address -= 0xA0000000; + } + std::list pending_invalidates; + write_watch_mutex_.lock(); + for (auto it = write_watches_.begin(); it != write_watches_.end();) { + auto entry = *it; + if (entry->address <= base_address && + entry->address + entry->length > base_address) { + // Hit! + pending_invalidates.push_back(entry); + // TODO(benvanik): outside of lock? + ClearWriteWatch(entry); + auto erase_it = it; + ++it; + write_watches_.erase(erase_it); + continue; + } + ++it; + } + write_watch_mutex_.unlock(); + if (pending_invalidates.empty()) { + // Rethrow access violation - range was not being watched. + return false; + } + while (!pending_invalidates.empty()) { + auto entry = pending_invalidates.back(); + pending_invalidates.pop_back(); + entry->callback(entry->callback_context, entry->callback_data, + guest_address); + delete entry; + } + // Range was watched, so lets eat this access violation. + return true; +} + bool MMIOHandler::HandleAccessFault(void* thread_state, uint64_t fault_address) { // Access violations are pretty rare, so we can do a linear search here. @@ -92,7 +195,7 @@ bool MMIOHandler::HandleAccessFault(void* thread_state, if (!range) { // Access is not found within any range, so fail and let the caller handle // it (likely by aborting). - return false; + return CheckWriteWatch(thread_state, fault_address); } // TODO(benvanik): replace with simple check of mov (that's all @@ -175,8 +278,7 @@ bool MMIOHandler::HandleAccessFault(void* thread_state, } range->write(range->context, fault_address & 0xFFFFFFFF, value); } else { - // Unknown MMIO instruction type. - assert_always(); + assert_always("Unknown MMIO instruction type"); return false; } diff --git a/src/xenia/cpu/mmio_handler.h b/src/xenia/cpu/mmio_handler.h index 586c04840..b872a81cb 100644 --- a/src/xenia/cpu/mmio_handler.h +++ b/src/xenia/cpu/mmio_handler.h @@ -10,7 +10,9 @@ #ifndef XENIA_CPU_MMIO_HANDLER_H_ #define XENIA_CPU_MMIO_HANDLER_H_ +#include #include +#include #include namespace xe { @@ -19,6 +21,9 @@ namespace cpu { typedef uint64_t (*MMIOReadCallback)(void* context, uint64_t addr); typedef void (*MMIOWriteCallback)(void* context, uint64_t addr, uint64_t value); +typedef void (*WriteWatchCallback)(void* context_ptr, void* data_ptr, + uint32_t address); + // NOTE: only one can exist at a time! class MMIOHandler { public: @@ -34,14 +39,30 @@ class MMIOHandler { bool CheckLoad(uint64_t address, uint64_t* out_value); bool CheckStore(uint64_t address, uint64_t value); + uintptr_t AddWriteWatch(uint32_t guest_address, size_t length, + WriteWatchCallback callback, void* callback_context, + void* callback_data); + void CancelWriteWatch(uintptr_t watch_handle); + public: bool HandleAccessFault(void* thread_state, uint64_t fault_address); protected: + struct WriteWatchEntry { + uint32_t address; + uint32_t length; + WriteWatchCallback callback; + void* callback_context; + void* callback_data; + }; + MMIOHandler(uint8_t* mapping_base) : mapping_base_(mapping_base) {} virtual bool Initialize() = 0; + void ClearWriteWatch(WriteWatchEntry* entry); + bool CheckWriteWatch(void* thread_state, uint64_t fault_address); + virtual uint64_t GetThreadStateRip(void* thread_state_ptr) = 0; virtual void SetThreadStateRip(void* thread_state_ptr, uint64_t rip) = 0; virtual uint64_t* GetThreadStateRegPtr(void* thread_state_ptr, @@ -59,6 +80,10 @@ class MMIOHandler { }; std::vector mapped_ranges_; + // TODO(benvanik): data structure magic. + std::mutex write_watch_mutex_; + std::list write_watches_; + static MMIOHandler* global_handler_; }; diff --git a/src/xenia/gpu/gl4/command_processor.cc b/src/xenia/gpu/gl4/command_processor.cc index c686a94af..f499dc1ad 100644 --- a/src/xenia/gpu/gl4/command_processor.cc +++ b/src/xenia/gpu/gl4/command_processor.cc @@ -183,7 +183,7 @@ bool CommandProcessor::SetupGL() { } // Texture cache that keeps track of any textures/samplers used. - if (!texture_cache_.Initialize(membase_, &scratch_buffer_)) { + if (!texture_cache_.Initialize(memory_, &scratch_buffer_)) { PLOGE("Unable to initialize texture cache"); return false; } diff --git a/src/xenia/gpu/gl4/texture_cache.cc b/src/xenia/gpu/gl4/texture_cache.cc index f6ed565da..6193b19d2 100644 --- a/src/xenia/gpu/gl4/texture_cache.cc +++ b/src/xenia/gpu/gl4/texture_cache.cc @@ -22,7 +22,7 @@ using namespace xe::gpu::xenos; extern "C" GLEWContext* glewGetContext(); extern "C" WGLEWContext* wglewGetContext(); -TextureCache::TextureCache() : membase_(nullptr), scratch_buffer_(nullptr) { +TextureCache::TextureCache() : memory_(nullptr), scratch_buffer_(nullptr) { invalidated_textures_sets_[0].reserve(64); invalidated_textures_sets_[1].reserve(64); invalidated_textures_ = &invalidated_textures_sets_[0]; @@ -30,9 +30,8 @@ TextureCache::TextureCache() : membase_(nullptr), scratch_buffer_(nullptr) { TextureCache::~TextureCache() { Shutdown(); } -bool TextureCache::Initialize(uint8_t* membase, - CircularBuffer* scratch_buffer) { - membase_ = membase; +bool TextureCache::Initialize(Memory* memory, CircularBuffer* scratch_buffer) { + memory_ = memory; scratch_buffer_ = scratch_buffer; return true; } @@ -59,18 +58,22 @@ void TextureCache::Scavenge() { } void TextureCache::Clear() { - // Kill all textures - some may be in the eviction list, but that's fine - // as we will clear that below. - while (texture_entries_.size()) { - auto entry = texture_entries_.begin()->second; - EvictTexture(entry); - } + EvictAllTextures(); // Samplers must go last, as textures depend on them. while (sampler_entries_.size()) { auto entry = sampler_entries_.begin()->second; EvictSampler(entry); } +} + +void TextureCache::EvictAllTextures() { + // Kill all textures - some may be in the eviction list, but that's fine + // as we will clear that below. + while (texture_entries_.size()) { + auto entry = texture_entries_.begin()->second; + EvictTexture(entry); + } { std::lock_guard lock(invalidated_textures_mutex_); @@ -79,13 +82,6 @@ void TextureCache::Clear() { } } -//typedef void (*WriteWatchCallback)(void* context, void* data, void* address); -//uintptr_t AddWriteWatch(void* address, size_t length, -// WriteWatchCallback callback, void* callback_context, -// void* callback_data) { -// // -//} - TextureCache::TextureEntryView* TextureCache::Demand( const TextureInfo& texture_info, const SamplerInfo& sampler_info) { uint64_t texture_hash = texture_info.hash(); @@ -121,6 +117,7 @@ TextureCache::TextureEntryView* TextureCache::Demand( view->texture_sampler_handle = glGetTextureSamplerHandleARB( texture_entry->handle, sampler_entry->handle); if (!view->texture_sampler_handle) { + assert_always("Unable to get texture handle?"); return nullptr; } glMakeTextureHandleResidentARB(view->texture_sampler_handle); @@ -261,6 +258,12 @@ TextureCache::TextureEntry* TextureCache::LookupOrInsertTexture( const uint64_t hash = opt_hash ? opt_hash : texture_info.hash(); for (auto it = texture_entries_.find(hash); it != texture_entries_.end(); ++it) { + if (it->second->pending_invalidation) { + // Whoa, we've been invalidated! Let's scavenge to cleanup and try again. + // TODO(benvanik): reuse existing texture storage. + Scavenge(); + break; + } if (it->second->texture_info == texture_info) { // Found in cache! return it->second; @@ -270,6 +273,8 @@ TextureCache::TextureEntry* TextureCache::LookupOrInsertTexture( // Not found, create. auto entry = std::make_unique(); entry->texture_info = texture_info; + entry->write_watch_handle = 0; + entry->pending_invalidation = false; entry->handle = 0; GLenum target; @@ -331,10 +336,24 @@ TextureCache::TextureEntry* TextureCache::LookupOrInsertTexture( return nullptr; } - // AddWriteWatch(host_base, length, [](void* context_ptr, void* data_ptr, - // void* address) { - // // - //}, this, &entry); + // Add a write watch. If any data in the given range is touched we'll get a + // callback and evict the texture. We could reuse the storage, though the + // driver is likely in a better position to pool that kind of stuff. + entry->write_watch_handle = memory_->AddWriteWatch( + texture_info.guest_address, texture_info.input_length, + [](void* context_ptr, void* data_ptr, uint32_t address) { + auto self = reinterpret_cast(context_ptr); + auto touched_entry = reinterpret_cast(data_ptr); + // Clear watch handle first so we don't redundantly + // remove. + touched_entry->write_watch_handle = 0; + touched_entry->pending_invalidation = true; + // Add to pending list so Scavenge will clean it up. + self->invalidated_textures_mutex_.lock(); + self->invalidated_textures_->push_back(touched_entry); + self->invalidated_textures_mutex_.unlock(); + }, + this, entry.get()); // Add to map - map takes ownership. auto entry_ptr = entry.get(); @@ -343,9 +362,10 @@ TextureCache::TextureEntry* TextureCache::LookupOrInsertTexture( } void TextureCache::EvictTexture(TextureEntry* entry) { - /*if (entry->write_watch_handle) { - // remove from watch list - }*/ + if (entry->write_watch_handle) { + memory_->CancelWriteWatch(entry->write_watch_handle); + entry->write_watch_handle = 0; + } for (auto& view : entry->views) { glMakeTextureHandleNonResidentARB(view->texture_sampler_handle); @@ -394,8 +414,7 @@ void TextureSwap(Endian endianness, void* dest, const void* src, bool TextureCache::UploadTexture2D(GLuint texture, const TextureInfo& texture_info) { - auto host_address = - reinterpret_cast(membase_ + texture_info.guest_address); + const auto host_address = memory_->Translate(texture_info.guest_address); GLenum internal_format = GL_RGBA8; GLenum format = GL_RGBA; diff --git a/src/xenia/gpu/gl4/texture_cache.h b/src/xenia/gpu/gl4/texture_cache.h index 05187ef28..8eedfc476 100644 --- a/src/xenia/gpu/gl4/texture_cache.h +++ b/src/xenia/gpu/gl4/texture_cache.h @@ -18,6 +18,7 @@ #include #include #include +#include namespace xe { namespace gpu { @@ -36,18 +37,21 @@ class TextureCache { }; struct TextureEntry { TextureInfo texture_info; + uintptr_t write_watch_handle; GLuint handle; + bool pending_invalidation; std::vector> views; }; TextureCache(); ~TextureCache(); - bool Initialize(uint8_t* membase, CircularBuffer* scratch_buffer); + bool Initialize(Memory* memory, CircularBuffer* scratch_buffer); void Shutdown(); void Scavenge(); void Clear(); + void EvictAllTextures(); TextureEntryView* Demand(const TextureInfo& texture_info, const SamplerInfo& sampler_info); @@ -62,7 +66,7 @@ class TextureCache { bool UploadTexture2D(GLuint texture, const TextureInfo& texture_info); - uint8_t* membase_; + Memory* memory_; CircularBuffer* scratch_buffer_; std::unordered_map sampler_entries_; std::unordered_map texture_entries_; diff --git a/src/xenia/memory.cc b/src/xenia/memory.cc index a3d90a7ac..7f387e07a 100644 --- a/src/xenia/memory.cc +++ b/src/xenia/memory.cc @@ -209,15 +209,15 @@ const static struct { uint64_t virtual_address_end; uint64_t target_address; } map_info[] = { - 0x00000000, 0x3FFFFFFF, 0x00000000, // (1024mb) - virtual 4k pages - 0x40000000, 0x7EFFFFFF, 0x40000000, // (1024mb) - virtual 64k pages (cont) - 0x7F000000, 0x7F0FFFFF, 0x00000000, // (1mb) - GPU writeback - 0x7F100000, 0x7FFFFFFF, 0x00100000, // (15mb) - XPS? - 0x80000000, 0x8FFFFFFF, 0x80000000, // (256mb) - xex 64k pages - 0x90000000, 0x9FFFFFFF, 0x80000000, // (256mb) - xex 4k pages - 0xA0000000, 0xBFFFFFFF, 0x00000000, // (512mb) - physical 64k pages - 0xC0000000, 0xDFFFFFFF, 0x00000000, // - physical 16mb pages - 0xE0000000, 0xFFFFFFFF, 0x00000000, // - physical 4k pages + 0x00000000, 0x3FFFFFFF, 0x00000000, // (1024mb) - virtual 4k pages + 0x40000000, 0x7EFFFFFF, 0x40000000, // (1024mb) - virtual 64k pages (cont) + 0x7F000000, 0x7F0FFFFF, 0x00000000, // (1mb) - GPU writeback + 0x7F100000, 0x7FFFFFFF, 0x00100000, // (15mb) - XPS? + 0x80000000, 0x8FFFFFFF, 0x80000000, // (256mb) - xex 64k pages + 0x90000000, 0x9FFFFFFF, 0x80000000, // (256mb) - xex 4k pages + 0xA0000000, 0xBFFFFFFF, 0x00000000, // (512mb) - physical 64k pages + 0xC0000000, 0xDFFFFFFF, 0x00000000, // - physical 16mb pages + 0xE0000000, 0xFFFFFFFF, 0x00000000, // - physical 4k pages }; int Memory::MapViews(uint8_t* mapping_base) { assert_true(poly::countof(map_info) == poly::countof(views_.all_views)); @@ -270,6 +270,17 @@ bool Memory::AddMappedRange(uint64_t address, uint64_t mask, uint64_t size, read_callback, write_callback); } +uintptr_t Memory::AddWriteWatch(uint32_t guest_address, size_t length, + cpu::WriteWatchCallback callback, + void* callback_context, void* callback_data) { + return mmio_handler_->AddWriteWatch(guest_address, length, callback, + callback_context, callback_data); +} + +void Memory::CancelWriteWatch(uintptr_t watch_handle) { + mmio_handler_->CancelWriteWatch(watch_handle); +} + uint8_t Memory::LoadI8(uint64_t address) { uint64_t value; if (!mmio_handler_->CheckLoad(address, &value)) { diff --git a/src/xenia/memory.h b/src/xenia/memory.h index bcdc254d7..2258ee151 100644 --- a/src/xenia/memory.h +++ b/src/xenia/memory.h @@ -53,6 +53,11 @@ class Memory : public alloy::Memory { void* context, cpu::MMIOReadCallback read_callback, cpu::MMIOWriteCallback write_callback); + uintptr_t AddWriteWatch(uint32_t guest_address, size_t length, + cpu::WriteWatchCallback callback, + void* callback_context, void* callback_data); + void CancelWriteWatch(uintptr_t watch_handle); + uint8_t LoadI8(uint64_t address) override; uint16_t LoadI16(uint64_t address) override; uint32_t LoadI32(uint64_t address) override; From 0b6b6a41896af84f21a1ee6335d034faff2a21f1 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 4 Jan 2015 16:52:29 -0800 Subject: [PATCH 325/388] Fixing buffer flushes. --- src/xenia/gpu/gl4/command_processor.cc | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/xenia/gpu/gl4/command_processor.cc b/src/xenia/gpu/gl4/command_processor.cc index f499dc1ad..c2717bafe 100644 --- a/src/xenia/gpu/gl4/command_processor.cc +++ b/src/xenia/gpu/gl4/command_processor.cc @@ -434,8 +434,8 @@ void CommandProcessor::PrepareForWait() { // TODO(benvanik): fences and fancy stuff. We should figure out a way to // make interrupt callbacks from the GPU so that we don't have to do a full // synchronize here. - //glFlush(); - glFinish(); + glFlush(); + // glFinish(); if (FLAGS_thread_safe_gl) { context_->ClearCurrent(); @@ -820,6 +820,10 @@ bool CommandProcessor::ExecutePacketType3_XE_SWAP(RingbufferReader* reader, reader->TraceData(1); uint32_t frontbuffer_ptr = reader->Read(); reader->Advance(count - 1); + + // Ensure we issue any pending draws. + draw_batcher_.Flush(DrawBatcher::FlushMode::kMakeCoherent); + if (swap_handler_) { SwapParameters swap_params; @@ -1373,7 +1377,14 @@ bool CommandProcessor::IssueDraw() { status = PopulateVertexBuffers(); CHECK_ISSUE_UPDATE_STATUS(status, mismatch, "Unable to setup vertex buffers"); - return draw_batcher_.CommitDraw(); + if (!draw_batcher_.CommitDraw()) { + return false; + } + if (!has_bindless_vbos_) { + // TODO(benvanik): find a way to get around glVertexArrayVertexBuffer below. + draw_batcher_.Flush(DrawBatcher::FlushMode::kMakeCoherent); + } + return true; } bool CommandProcessor::SetShadowRegister(uint32_t& dest, @@ -2053,11 +2064,6 @@ CommandProcessor::UpdateStatus CommandProcessor::PopulateVertexBuffers() { auto& regs = *register_file_; assert_not_null(active_vertex_shader_); - if (!has_bindless_vbos_) { - // TODO(benvanik): find a way to get around glVertexArrayVertexBuffer below. - draw_batcher_.Flush(DrawBatcher::FlushMode::kMakeCoherent); - } - uint32_t el_index = 0; const auto& buffer_inputs = active_vertex_shader_->buffer_inputs(); for (uint32_t buffer_index = 0; buffer_index < buffer_inputs.count; From caad11b30bfd8332789b18c4edc515d0953db82a Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 4 Jan 2015 20:57:12 -0800 Subject: [PATCH 326/388] Support root-relative paths. --- src/xenia/kernel/fs/filesystem.cc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/xenia/kernel/fs/filesystem.cc b/src/xenia/kernel/fs/filesystem.cc index e3b37bb89..760c9329d 100644 --- a/src/xenia/kernel/fs/filesystem.cc +++ b/src/xenia/kernel/fs/filesystem.cc @@ -151,12 +151,19 @@ std::unique_ptr FileSystem::ResolvePath(const std::string& path) { // TODO(benvanik): normalize path/etc // e.g., remove ..'s and such + // If no path (starts with a slash) do it module-relative. + // Which for now, we just make game:. + std::string normalized_path = path; + if (path[0] == '\\') { + normalized_path = "game:" + normalized_path; + } + // Resolve symlinks. // TODO(benvanik): more robust symlink handling - right now we assume simple // drive path -> device mappings with nothing nested. - std::string full_path = path; + std::string full_path = normalized_path; for (const auto& it : symlinks_) { - if (poly::find_first_of_case(path, it.first) == 0) { + if (poly::find_first_of_case(normalized_path, it.first) == 0) { // Found symlink, fixup by replacing the prefix. full_path = it.second + full_path.substr(it.first.size()); break; From a82629efd51ba883a76b81c7ce2582111ab1a316 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 4 Jan 2015 21:08:47 -0800 Subject: [PATCH 327/388] Fix dots in path names. --- src/xenia/kernel/fs/filesystem.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/xenia/kernel/fs/filesystem.cc b/src/xenia/kernel/fs/filesystem.cc index 760c9329d..87be60c1e 100644 --- a/src/xenia/kernel/fs/filesystem.cc +++ b/src/xenia/kernel/fs/filesystem.cc @@ -32,7 +32,11 @@ FileSystem::~FileSystem() { } fs::FileSystemType FileSystem::InferType(const std::wstring& local_path) { + auto last_slash = local_path.find_last_of(poly::path_separator); auto last_dot = local_path.find_last_of('.'); + if (last_dot < last_slash) { + last_dot = std::wstring::npos; + } if (last_dot == std::wstring::npos) { // Likely an STFS container. return FileSystemType::STFS_TITLE; From 4aa98ae1e96ca72bc8d6690cf9bf3e5f0fef0862 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 5 Jan 2015 22:11:02 -0800 Subject: [PATCH 328/388] fnmadd(s)x --- src/alloy/frontend/ppc/ppc_emit_fpu.cc | 27 ++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/alloy/frontend/ppc/ppc_emit_fpu.cc b/src/alloy/frontend/ppc/ppc_emit_fpu.cc index 8a332bf68..43945f8af 100644 --- a/src/alloy/frontend/ppc/ppc_emit_fpu.cc +++ b/src/alloy/frontend/ppc/ppc_emit_fpu.cc @@ -255,13 +255,32 @@ XEEMITTER(fmsubsx, 0xEC000038, A)(PPCHIRBuilder& f, InstrData& i) { } XEEMITTER(fnmaddx, 0xFC00003E, A)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // frD <- -([frA x frC] + frB) + Value* v = f.Neg( + f.MulAdd(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB))); + f.StoreFPR(i.A.FRT, v); + // f.UpdateFPRF(v); + if (i.A.Rc) { + // e.update_cr_with_cond(1, v); + XEINSTRNOTIMPLEMENTED(); + return 1; + } + return 0; } XEEMITTER(fnmaddsx, 0xEC00003E, A)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; + // frD <- -([frA x frC] + frB) + Value* v = f.Neg( + f.MulAdd(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB))); + v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE); + f.StoreFPR(i.A.FRT, v); + // f.UpdateFPRF(v); + if (i.A.Rc) { + // e.update_cr_with_cond(1, v); + XEINSTRNOTIMPLEMENTED(); + return 1; + } + return 0; } XEEMITTER(fnmsubx, 0xFC00003C, A)(PPCHIRBuilder& f, InstrData& i) { From 9e65e35a09d387d1a0f1ad9eae950dca32ff9aea Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 5 Jan 2015 22:11:26 -0800 Subject: [PATCH 329/388] Some user profile settings. --- src/xenia/kernel/user_profile.cc | 8 +++++++- src/xenia/kernel/xam_user.cc | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/xenia/kernel/user_profile.cc b/src/xenia/kernel/user_profile.cc index 9397767e0..9c9a3cfd4 100644 --- a/src/xenia/kernel/user_profile.cc +++ b/src/xenia/kernel/user_profile.cc @@ -17,6 +17,7 @@ UserProfile::UserProfile() { name_ = "User"; // http://cs.rin.ru/forum/viewtopic.php?f=38&t=60668&hilit=gfwl+live&start=195 + // https://github.com/arkem/py360/blob/master/py360/constants.py // XPROFILE_GAMER_YAXIS_INVERSION AddSetting(std::make_unique(0x10040002, 0)); // XPROFILE_OPTION_CONTROLLER_VIBRATION @@ -45,6 +46,10 @@ UserProfile::UserProfile() { AddSetting(std::make_unique(0x10040015, 0)); // XPROFILE_GAMER_CONTROL_SENSITIVITY AddSetting(std::make_unique(0x10040018, 0)); + // Preferred color 1 + AddSetting(std::make_unique(0x1004001D, 0xFFFF0000u)); + // Preferred color 2 + AddSetting(std::make_unique(0x1004001E, 0xFF00FF00u)); // XPROFILE_GAMER_ACTION_AUTO_AIM AddSetting(std::make_unique(0x10040022, 1)); // XPROFILE_GAMER_ACTION_AUTO_CENTER @@ -66,7 +71,8 @@ UserProfile::UserProfile() { // If we set this, games will try to get it. // XPROFILE_GAMERCARD_PICTURE_KEY - AddSetting(std::make_unique(0x4064000F, L"gamercard_picture_key")); + AddSetting( + std::make_unique(0x4064000F, L"gamercard_picture_key")); std::vector zeros; zeros.resize(1000); diff --git a/src/xenia/kernel/xam_user.cc b/src/xenia/kernel/xam_user.cc index f77cdcd5b..4b34e5bad 100644 --- a/src/xenia/kernel/xam_user.cc +++ b/src/xenia/kernel/xam_user.cc @@ -130,6 +130,7 @@ SHIM_CALL XamUserReadProfileSettings_shim(PPCContext* ppc_state, } const auto& user_profile = state->user_profile(); + // First call asks for size (fill buffer_size_ptr). // Second call asks for buffer contents with that size. From 540740ca41d6555b30f3cd8a5b9c8e66db8266db Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 5 Jan 2015 22:32:15 -0800 Subject: [PATCH 330/388] NtCreateFile/NtOpenFile cleanup. Now opens directories, too. --- src/xenia/kernel/xboxkrnl_io.cc | 154 +++++++++++++++----------------- 1 file changed, 71 insertions(+), 83 deletions(-) diff --git a/src/xenia/kernel/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl_io.cc index 4ccc18f6f..ef4e1ffcd 100644 --- a/src/xenia/kernel/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl_io.cc @@ -50,26 +50,28 @@ class X_OBJECT_ATTRIBUTES { }; static_assert_size(X_OBJECT_ATTRIBUTES, 12 + sizeof(X_ANSI_STRING)); -SHIM_CALL NtCreateFile_shim(PPCContext* ppc_state, KernelState* state) { - uint32_t handle_ptr = SHIM_GET_ARG_32(0); - uint32_t desired_access = SHIM_GET_ARG_32(1); - uint32_t object_attributes_ptr = SHIM_GET_ARG_32(2); - uint32_t io_status_block_ptr = SHIM_GET_ARG_32(3); - uint32_t allocation_size_ptr = SHIM_GET_ARG_32(4); - uint32_t file_attributes = SHIM_GET_ARG_32(5); - uint32_t share_access = SHIM_GET_ARG_32(6); - uint32_t creation_disposition = SHIM_GET_ARG_32(7); +struct FileDisposition { + static const uint32_t X_FILE_SUPERSEDE = 0x00000000; + static const uint32_t X_FILE_OPEN = 0x00000001; + static const uint32_t X_FILE_CREATE = 0x00000002; + static const uint32_t X_FILE_OPEN_IF = 0x00000003; + static const uint32_t X_FILE_OVERWRITE = 0x00000004; + static const uint32_t X_FILE_OVERWRITE_IF = 0x00000005; +}; - X_OBJECT_ATTRIBUTES attrs(SHIM_MEM_BASE, object_attributes_ptr); - - char* object_name = attrs.object_name.Duplicate(); - - XELOGD("NtCreateFile(%.8X, %.8X, %.8X(%s), %.8X, %.8X, %.8X, %d, %d)", - handle_ptr, desired_access, object_attributes_ptr, - !object_name ? "(null)" : object_name, io_status_block_ptr, - allocation_size_ptr, file_attributes, share_access, - creation_disposition); +struct FileAccess { + static const uint32_t X_GENERIC_READ = 1 << 0; + static const uint32_t X_GENERIC_WRITE = 1 << 1; + static const uint32_t X_GENERIC_EXECUTE = 1 << 2; + static const uint32_t X_GENERIC_ALL = 1 << 3; +}; +X_STATUS NtCreateFile(PPCContext* ppc_state, KernelState* state, + uint32_t handle_ptr, uint32_t desired_access, + X_OBJECT_ATTRIBUTES* object_attrs, + const char* object_name, uint32_t io_status_block_ptr, + uint32_t allocation_size_ptr, uint32_t file_attributes, + uint32_t share_access, uint32_t creation_disposition) { uint64_t allocation_size = 0; // is this correct??? if (allocation_size_ptr != 0) { allocation_size = SHIM_MEM_64(allocation_size_ptr); @@ -83,33 +85,37 @@ SHIM_CALL NtCreateFile_shim(PPCContext* ppc_state, KernelState* state) { std::unique_ptr entry; XFile* root_file = NULL; - if (attrs.root_directory != 0xFFFFFFFD && // ObDosDevices - attrs.root_directory != 0) { - result = state->object_table()->GetObject(attrs.root_directory, + if (object_attrs->root_directory != 0xFFFFFFFD && // ObDosDevices + object_attrs->root_directory != 0) { + result = state->object_table()->GetObject(object_attrs->root_directory, (XObject**)&root_file); assert_true(XSUCCEEDED(result)); assert_true(root_file->type() == XObject::Type::kTypeFile); auto root_path = root_file->absolute_path(); auto target_path = root_path + object_name; - entry = std::move(fs->ResolvePath(target_path)); + entry = fs->ResolvePath(target_path); } else { // Resolve the file using the virtual file system. - entry = std::move(fs->ResolvePath(object_name)); + entry = fs->ResolvePath(object_name); } - auto mode = - desired_access & GENERIC_WRITE ? fs::Mode::READ_WRITE : fs::Mode::READ; - - XFile* file = NULL; - if (entry && entry->type() == Entry::Type::FILE) { - // Open the file. - result = fs->Open(std::move(entry), state, mode, - false, // TODO(benvanik): pick async mode, if needed. - &file); - } else { + XFile* file = nullptr; + if (!entry) { result = X_STATUS_NO_SUCH_FILE; info = X_FILE_DOES_NOT_EXIST; + } else if (creation_disposition != FileDisposition::X_FILE_OPEN || + desired_access & FileAccess::X_GENERIC_WRITE || + desired_access & FileAccess::X_GENERIC_ALL) { + // We don't support any write modes. + XELOGE("Attempted to open the file/dir for create/write"); + result = X_STATUS_ACCESS_DENIED; + info = entry ? X_FILE_EXISTS : X_FILE_DOES_NOT_EXIST; + } else { + // Open the file/directory. + result = fs->Open(std::move(entry), state, fs::Mode::READ, + false, // TODO(benvanik): pick async mode, if needed. + &file); } if (XSUCCEEDED(result)) { @@ -130,6 +136,33 @@ SHIM_CALL NtCreateFile_shim(PPCContext* ppc_state, KernelState* state) { } } + return result; +} + +SHIM_CALL NtCreateFile_shim(PPCContext* ppc_state, KernelState* state) { + uint32_t handle_ptr = SHIM_GET_ARG_32(0); + uint32_t desired_access = SHIM_GET_ARG_32(1); + uint32_t object_attributes_ptr = SHIM_GET_ARG_32(2); + uint32_t io_status_block_ptr = SHIM_GET_ARG_32(3); + uint32_t allocation_size_ptr = SHIM_GET_ARG_32(4); + uint32_t file_attributes = SHIM_GET_ARG_32(5); + uint32_t share_access = SHIM_GET_ARG_32(6); + uint32_t creation_disposition = SHIM_GET_ARG_32(7); + + X_OBJECT_ATTRIBUTES object_attrs(SHIM_MEM_BASE, object_attributes_ptr); + char* object_name = object_attrs.object_name.Duplicate(); + + XELOGD("NtCreateFile(%.8X, %.8X, %.8X(%s), %.8X, %.8X, %.8X, %d, %d)", + handle_ptr, desired_access, object_attributes_ptr, + !object_name ? "(null)" : object_name, io_status_block_ptr, + allocation_size_ptr, file_attributes, share_access, + creation_disposition); + + auto result = + NtCreateFile(ppc_state, state, handle_ptr, desired_access, &object_attrs, + object_name, io_status_block_ptr, allocation_size_ptr, + file_attributes, share_access, creation_disposition); + free(object_name); SHIM_SET_RETURN_32(result); } @@ -141,62 +174,17 @@ SHIM_CALL NtOpenFile_shim(PPCContext* ppc_state, KernelState* state) { uint32_t io_status_block_ptr = SHIM_GET_ARG_32(3); uint32_t open_options = SHIM_GET_ARG_32(4); - X_OBJECT_ATTRIBUTES attrs(SHIM_MEM_BASE, object_attributes_ptr); - - char* object_name = attrs.object_name.Duplicate(); + X_OBJECT_ATTRIBUTES object_attrs(SHIM_MEM_BASE, object_attributes_ptr); + char* object_name = object_attrs.object_name.Duplicate(); XELOGD("NtOpenFile(%.8X, %.8X, %.8X(%s), %.8X, %d)", handle_ptr, desired_access, object_attributes_ptr, !object_name ? "(null)" : object_name, io_status_block_ptr, open_options); - X_STATUS result = X_STATUS_NO_SUCH_FILE; - uint32_t info = X_FILE_DOES_NOT_EXIST; - uint32_t handle; - - XFile* root_file = NULL; - if (attrs.root_directory != 0xFFFFFFFD) { // ObDosDevices - result = state->object_table()->GetObject(attrs.root_directory, - (XObject**)&root_file); - assert_true(XSUCCEEDED(result)); - assert_true(root_file->type() == XObject::Type::kTypeFile); - assert_always(); - } - - auto mode = - desired_access & GENERIC_WRITE ? fs::Mode::READ_WRITE : fs::Mode::READ; - - // Resolve the file using the virtual file system. - FileSystem* fs = state->file_system(); - auto entry = fs->ResolvePath(object_name); - XFile* file = NULL; - if (entry && entry->type() == Entry::Type::FILE) { - // Open the file. - result = fs->Open(std::move(entry), state, mode, - false, // TODO(benvanik): pick async mode, if needed. - &file); - } else { - result = X_STATUS_NO_SUCH_FILE; - info = X_FILE_DOES_NOT_EXIST; - } - - if (XSUCCEEDED(result)) { - // Handle ref is incremented, so return that. - handle = file->handle(); - file->Release(); - result = X_STATUS_SUCCESS; - info = X_FILE_OPENED; - } - - if (io_status_block_ptr) { - SHIM_SET_MEM_32(io_status_block_ptr, result); // Status - SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information - } - if (XSUCCEEDED(result)) { - if (handle_ptr) { - SHIM_SET_MEM_32(handle_ptr, handle); - } - } + auto result = NtCreateFile(ppc_state, state, handle_ptr, desired_access, + &object_attrs, object_name, io_status_block_ptr, 0, + 0, 0, FileDisposition::X_FILE_OPEN); free(object_name); SHIM_SET_RETURN_32(result); From 58e71c7ff3ef06804446fdec3242d7ed394e3e79 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 5 Jan 2015 22:32:22 -0800 Subject: [PATCH 331/388] KeSetDisableBoostThread stub. --- src/xenia/kernel/xboxkrnl_threading.cc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index 4c404aa1b..89299a2d7 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -234,6 +234,22 @@ SHIM_CALL KeSetBasePriorityThread_shim(PPCContext* ppc_state, SHIM_SET_RETURN_32(prev_priority); } +SHIM_CALL KeSetDisableBoostThread_shim(PPCContext* ppc_state, + KernelState* state) { + uint32_t thread_ptr = SHIM_GET_ARG_32(0); + uint32_t disabled = SHIM_GET_ARG_32(1); + + XELOGD("KeSetDisableBoostThread(%.8X, %.8X)", thread_ptr, disabled); + + XThread* thread = + (XThread*)XObject::GetObject(state, SHIM_MEM_ADDR(thread_ptr)); + if (thread) { + // Uhm? + } + + SHIM_SET_RETURN_32(0); +} + SHIM_CALL KeGetCurrentProcessType_shim(PPCContext* ppc_state, KernelState* state) { // XELOGD( @@ -1243,6 +1259,7 @@ void xe::kernel::xboxkrnl::RegisterThreadingExports( SHIM_SET_MAPPING("xboxkrnl.exe", KeSetAffinityThread, state); SHIM_SET_MAPPING("xboxkrnl.exe", KeQueryBasePriorityThread, state); SHIM_SET_MAPPING("xboxkrnl.exe", KeSetBasePriorityThread, state); + SHIM_SET_MAPPING("xboxkrnl.exe", KeSetDisableBoostThread, state); SHIM_SET_MAPPING("xboxkrnl.exe", KeGetCurrentProcessType, state); SHIM_SET_MAPPING("xboxkrnl.exe", KeSetCurrentProcessType, state); From 1a706069049fe59a31ede847068023dc63285be9 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 5 Jan 2015 22:32:44 -0800 Subject: [PATCH 332/388] QueryFileSystemAttributes/QueryVolume for STFS/ISO. --- src/xenia/kernel/fs/device.cc | 40 ++++++++++++++ src/xenia/kernel/fs/device.h | 4 +- .../kernel/fs/devices/disc_image_device.cc | 11 ---- .../kernel/fs/devices/disc_image_device.h | 4 -- .../kernel/fs/devices/disc_image_entry.cc | 53 +++++++++++-------- .../kernel/fs/devices/host_path_device.cc | 38 ------------- .../kernel/fs/devices/host_path_device.h | 4 -- .../fs/devices/stfs_container_device.cc | 13 +---- .../kernel/fs/devices/stfs_container_device.h | 4 -- .../kernel/fs/devices/stfs_container_entry.cc | 51 ++++++++++-------- 10 files changed, 105 insertions(+), 117 deletions(-) diff --git a/src/xenia/kernel/fs/device.cc b/src/xenia/kernel/fs/device.cc index f4c32a000..bec6f33d1 100644 --- a/src/xenia/kernel/fs/device.cc +++ b/src/xenia/kernel/fs/device.cc @@ -9,6 +9,8 @@ #include +#include + namespace xe { namespace kernel { namespace fs { @@ -17,6 +19,44 @@ Device::Device(const std::string& path) : path_(path) {} Device::~Device() = default; +// TODO(gibbed): call into HostPathDevice? +X_STATUS Device::QueryVolume(XVolumeInfo* out_info, size_t length) { + assert_not_null(out_info); + const char* name = "test"; // TODO(gibbed): actual value + + auto end = (uint8_t*)out_info + length; + size_t name_length = strlen(name); + if (((uint8_t*)&out_info->label[0]) + name_length > end) { + return X_STATUS_BUFFER_OVERFLOW; + } + + out_info->creation_time = 0; + out_info->serial_number = 12345678; + out_info->supports_objects = 0; + out_info->label_length = (uint32_t)name_length; + memcpy(out_info->label, name, name_length); + return X_STATUS_SUCCESS; +} + +// TODO(gibbed): call into HostPathDevice? +X_STATUS Device::QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, + size_t length) { + assert_not_null(out_info); + const char* name = "test"; // TODO(gibbed): actual value + + auto end = (uint8_t*)out_info + length; + size_t name_length = strlen(name); + if (((uint8_t*)&out_info->fs_name[0]) + name_length > end) { + return X_STATUS_BUFFER_OVERFLOW; + } + + out_info->attributes = 0; + out_info->maximum_component_name_length = 255; // TODO(gibbed): actual value + out_info->fs_name_length = (uint32_t)name_length; + memcpy(out_info->fs_name, name, name_length); + return X_STATUS_SUCCESS; +} + } // namespace fs } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/fs/device.h b/src/xenia/kernel/fs/device.h index 0758aa2f1..f6aa4ab11 100644 --- a/src/xenia/kernel/fs/device.h +++ b/src/xenia/kernel/fs/device.h @@ -29,9 +29,9 @@ class Device { virtual std::unique_ptr ResolvePath(const char* path) = 0; - virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) = 0; + virtual X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length); virtual X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, - size_t length) = 0; + size_t length); protected: std::string path_; diff --git a/src/xenia/kernel/fs/devices/disc_image_device.cc b/src/xenia/kernel/fs/devices/disc_image_device.cc index 320e1332f..1bbb5a109 100644 --- a/src/xenia/kernel/fs/devices/disc_image_device.cc +++ b/src/xenia/kernel/fs/devices/disc_image_device.cc @@ -68,17 +68,6 @@ std::unique_ptr DiscImageDevice::ResolvePath(const char* path) { gdfx_entry); } -X_STATUS DiscImageDevice::QueryVolume(XVolumeInfo* out_info, size_t length) { - assert_always(); - return X_STATUS_NOT_IMPLEMENTED; -} - -X_STATUS DiscImageDevice::QueryFileSystemAttributes( - XFileSystemAttributeInfo* out_info, size_t length) { - assert_always(); - return X_STATUS_NOT_IMPLEMENTED; -} - } // namespace fs } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/fs/devices/disc_image_device.h b/src/xenia/kernel/fs/devices/disc_image_device.h index 352a089db..85af80883 100644 --- a/src/xenia/kernel/fs/devices/disc_image_device.h +++ b/src/xenia/kernel/fs/devices/disc_image_device.h @@ -32,10 +32,6 @@ class DiscImageDevice : public Device { std::unique_ptr ResolvePath(const char* path) override; - X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) override; - X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, - size_t length) override; - private: std::wstring local_path_; std::unique_ptr mmap_; diff --git a/src/xenia/kernel/fs/devices/disc_image_entry.cc b/src/xenia/kernel/fs/devices/disc_image_entry.cc index 141d4bf89..ea4c90555 100644 --- a/src/xenia/kernel/fs/devices/disc_image_entry.cc +++ b/src/xenia/kernel/fs/devices/disc_image_entry.cc @@ -51,30 +51,41 @@ X_STATUS DiscImageEntry::QueryDirectory(XDirectoryInfo* out_info, size_t length, const char* file_name, bool restart) { assert_not_null(out_info); - if (restart == true && gdfx_entry_iterator_ != gdfx_entry_->children.end()) { - gdfx_entry_iterator_ = gdfx_entry_->children.end(); - } - - if (gdfx_entry_iterator_ == gdfx_entry_->children.end()) { - gdfx_entry_iterator_ = gdfx_entry_->children.begin(); - if (gdfx_entry_iterator_ == gdfx_entry_->children.end()) { - return X_STATUS_UNSUCCESSFUL; + // TODO(benvanik): move to common code. + assert_null(file_name); + GDFXEntry* entry = nullptr; + if (file_name) { + // Specified filename, return just that info. + assert_true(std::strchr(file_name, '*') == nullptr); + entry = gdfx_entry_->GetChild(file_name); + if (!entry) { + return X_STATUS_NO_SUCH_FILE; } } else { - ++gdfx_entry_iterator_; - if (gdfx_entry_iterator_ == gdfx_entry_->children.end()) { - return X_STATUS_UNSUCCESSFUL; + if (restart == true && + gdfx_entry_iterator_ != gdfx_entry_->children.end()) { + gdfx_entry_iterator_ = gdfx_entry_->children.end(); } - } - auto end = (uint8_t*)out_info + length; + if (gdfx_entry_iterator_ == gdfx_entry_->children.end()) { + gdfx_entry_iterator_ = gdfx_entry_->children.begin(); + if (gdfx_entry_iterator_ == gdfx_entry_->children.end()) { + return X_STATUS_UNSUCCESSFUL; + } + } else { + ++gdfx_entry_iterator_; + if (gdfx_entry_iterator_ == gdfx_entry_->children.end()) { + return X_STATUS_UNSUCCESSFUL; + } + } - auto entry = *gdfx_entry_iterator_; - auto entry_name = entry->name; - - if (((uint8_t*)&out_info->file_name[0]) + entry_name.size() > end) { - gdfx_entry_iterator_ = gdfx_entry_->children.end(); - return X_STATUS_UNSUCCESSFUL; + auto end = (uint8_t*)out_info + length; + entry = *gdfx_entry_iterator_; + auto entry_name = entry->name; + if (((uint8_t*)&out_info->file_name[0]) + entry_name.size() > end) { + gdfx_entry_iterator_ = gdfx_entry_->children.end(); + return X_STATUS_NO_MORE_FILES; + } } out_info->next_entry_offset = 0; @@ -86,8 +97,8 @@ X_STATUS DiscImageEntry::QueryDirectory(XDirectoryInfo* out_info, size_t length, out_info->end_of_file = entry->size; out_info->allocation_size = 2048; out_info->attributes = (X_FILE_ATTRIBUTES)entry->attributes; - out_info->file_name_length = static_cast(entry_name.size()); - memcpy(out_info->file_name, entry_name.c_str(), entry_name.size()); + out_info->file_name_length = static_cast(entry->name.size()); + memcpy(out_info->file_name, entry->name.c_str(), entry->name.size()); return X_STATUS_SUCCESS; } diff --git a/src/xenia/kernel/fs/devices/host_path_device.cc b/src/xenia/kernel/fs/devices/host_path_device.cc index d14852a91..309a389a9 100644 --- a/src/xenia/kernel/fs/devices/host_path_device.cc +++ b/src/xenia/kernel/fs/devices/host_path_device.cc @@ -41,44 +41,6 @@ std::unique_ptr HostPathDevice::ResolvePath(const char* path) { return std::make_unique(type, this, path, full_path); } -// TODO(gibbed): call into HostPathDevice? -X_STATUS HostPathDevice::QueryVolume(XVolumeInfo* out_info, size_t length) { - assert_not_null(out_info); - const char* name = "test"; // TODO(gibbed): actual value - - auto end = (uint8_t*)out_info + length; - size_t name_length = strlen(name); - if (((uint8_t*)&out_info->label[0]) + name_length > end) { - return X_STATUS_BUFFER_OVERFLOW; - } - - out_info->creation_time = 0; - out_info->serial_number = 12345678; - out_info->supports_objects = 0; - out_info->label_length = (uint32_t)name_length; - memcpy(out_info->label, name, name_length); - return X_STATUS_SUCCESS; -} - -// TODO(gibbed): call into HostPathDevice? -X_STATUS HostPathDevice::QueryFileSystemAttributes( - XFileSystemAttributeInfo* out_info, size_t length) { - assert_not_null(out_info); - const char* name = "test"; // TODO(gibbed): actual value - - auto end = (uint8_t*)out_info + length; - size_t name_length = strlen(name); - if (((uint8_t*)&out_info->fs_name[0]) + name_length > end) { - return X_STATUS_BUFFER_OVERFLOW; - } - - out_info->attributes = 0; - out_info->maximum_component_name_length = 255; // TODO(gibbed): actual value - out_info->fs_name_length = (uint32_t)name_length; - memcpy(out_info->fs_name, name, name_length); - return X_STATUS_SUCCESS; -} - } // namespace fs } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/fs/devices/host_path_device.h b/src/xenia/kernel/fs/devices/host_path_device.h index 0af6d8b62..80f618e05 100644 --- a/src/xenia/kernel/fs/devices/host_path_device.h +++ b/src/xenia/kernel/fs/devices/host_path_device.h @@ -26,10 +26,6 @@ class HostPathDevice : public Device { std::unique_ptr ResolvePath(const char* path) override; - X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) override; - X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, - size_t length) override; - private: std::wstring local_path_; }; diff --git a/src/xenia/kernel/fs/devices/stfs_container_device.cc b/src/xenia/kernel/fs/devices/stfs_container_device.cc index c562ea1fa..0704f8b4a 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_device.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_device.cc @@ -12,6 +12,7 @@ #include #include #include +#include namespace xe { namespace kernel { @@ -68,18 +69,6 @@ std::unique_ptr STFSContainerDevice::ResolvePath(const char* path) { stfs_entry); } -X_STATUS STFSContainerDevice::QueryVolume(XVolumeInfo* out_info, - size_t length) { - assert_always(); - return X_STATUS_NOT_IMPLEMENTED; -} - -X_STATUS STFSContainerDevice::QueryFileSystemAttributes( - XFileSystemAttributeInfo* out_info, size_t length) { - assert_always(); - return X_STATUS_NOT_IMPLEMENTED; -} - } // namespace fs } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/fs/devices/stfs_container_device.h b/src/xenia/kernel/fs/devices/stfs_container_device.h index 34568bedd..1f5dd7607 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_device.h +++ b/src/xenia/kernel/fs/devices/stfs_container_device.h @@ -32,10 +32,6 @@ class STFSContainerDevice : public Device { std::unique_ptr ResolvePath(const char* path) override; - X_STATUS QueryVolume(XVolumeInfo* out_info, size_t length) override; - X_STATUS QueryFileSystemAttributes(XFileSystemAttributeInfo* out_info, - size_t length) override; - private: std::wstring local_path_; std::unique_ptr mmap_; diff --git a/src/xenia/kernel/fs/devices/stfs_container_entry.cc b/src/xenia/kernel/fs/devices/stfs_container_entry.cc index db6d5ff75..c28cff9e8 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_entry.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_entry.cc @@ -45,30 +45,39 @@ X_STATUS STFSContainerEntry::QueryDirectory(XDirectoryInfo* out_info, bool restart) { assert_not_null(out_info); - if (restart && stfs_entry_iterator_ != stfs_entry_->children.end()) { - stfs_entry_iterator_ = stfs_entry_->children.end(); - } - - if (stfs_entry_iterator_ == stfs_entry_->children.end()) { - stfs_entry_iterator_ = stfs_entry_->children.begin(); - if (stfs_entry_iterator_ == stfs_entry_->children.end()) { - return X_STATUS_UNSUCCESSFUL; + // TODO(benvanik): move to common code. + STFSEntry* entry = nullptr; + if (file_name) { + // Specified filename, return just that info. + assert_true(std::strchr(file_name, '*') == nullptr); + entry = stfs_entry_->GetChild(file_name); + if (!entry) { + return X_STATUS_NO_SUCH_FILE; } } else { - ++stfs_entry_iterator_; - if (stfs_entry_iterator_ == stfs_entry_->children.end()) { - return X_STATUS_UNSUCCESSFUL; + if (restart && stfs_entry_iterator_ != stfs_entry_->children.end()) { + stfs_entry_iterator_ = stfs_entry_->children.end(); } - } - auto end = (uint8_t*)out_info + length; + if (stfs_entry_iterator_ == stfs_entry_->children.end()) { + stfs_entry_iterator_ = stfs_entry_->children.begin(); + if (stfs_entry_iterator_ == stfs_entry_->children.end()) { + return X_STATUS_UNSUCCESSFUL; + } + } else { + ++stfs_entry_iterator_; + if (stfs_entry_iterator_ == stfs_entry_->children.end()) { + return X_STATUS_UNSUCCESSFUL; + } + } - auto entry = stfs_entry_iterator_->get(); - auto entry_name = entry->name; - - if (((uint8_t*)&out_info->file_name[0]) + entry_name.size() > end) { - stfs_entry_iterator_ = stfs_entry_->children.end(); - return X_STATUS_UNSUCCESSFUL; + auto end = (uint8_t*)out_info + length; + entry = stfs_entry_iterator_->get(); + auto entry_name = entry->name; + if (((uint8_t*)&out_info->file_name[0]) + entry_name.size() > end) { + stfs_entry_iterator_ = stfs_entry_->children.end(); + return X_STATUS_NO_MORE_FILES; + } } out_info->file_index = 0xCDCDCDCD; @@ -79,8 +88,8 @@ X_STATUS STFSContainerEntry::QueryDirectory(XDirectoryInfo* out_info, out_info->end_of_file = entry->size; out_info->allocation_size = 4096; out_info->attributes = entry->attributes; - out_info->file_name_length = static_cast(entry_name.size()); - memcpy(out_info->file_name, entry_name.c_str(), entry_name.size()); + out_info->file_name_length = static_cast(entry->name.size()); + memcpy(out_info->file_name, entry->name.c_str(), entry->name.size()); return X_STATUS_SUCCESS; } From 672ecdf25217654ec5bae4bbc9b8baaa34a1ce1f Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 5 Jan 2015 23:25:32 -0800 Subject: [PATCH 333/388] Some games open readonly paths for writes.. hmm --- src/alloy/frontend/ppc/ppc_emit_altivec.cc | 4 ++++ src/xenia/kernel/xboxkrnl_io.cc | 14 +++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index ac6e1ea45..75eb13a23 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -464,6 +464,10 @@ XEEMITTER(vavgsh, 0x10000542, VX)(PPCHIRBuilder& f, InstrData& i) { } XEEMITTER(vavgsw, 0x10000582, VX)(PPCHIRBuilder& f, InstrData& i) { + // do i = 0 to 127 by 32 + // aop = EXTS((VRA)i:i + 31) + // bop = EXTS((VRB)i:i + 31) + // VRTi:i + 31 = Chop((aop + int bop + int 1) >> 1, 32) XEINSTRNOTIMPLEMENTED(); return 1; } diff --git a/src/xenia/kernel/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl_io.cc index ef4e1ffcd..40dcacff7 100644 --- a/src/xenia/kernel/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl_io.cc @@ -100,17 +100,17 @@ X_STATUS NtCreateFile(PPCContext* ppc_state, KernelState* state, entry = fs->ResolvePath(object_name); } + if (creation_disposition != FileDisposition::X_FILE_OPEN || + desired_access & FileAccess::X_GENERIC_WRITE || + desired_access & FileAccess::X_GENERIC_ALL) { + // We don't support any write modes. + XELOGW("Attempted to open the file/dir for create/write"); + } + XFile* file = nullptr; if (!entry) { result = X_STATUS_NO_SUCH_FILE; info = X_FILE_DOES_NOT_EXIST; - } else if (creation_disposition != FileDisposition::X_FILE_OPEN || - desired_access & FileAccess::X_GENERIC_WRITE || - desired_access & FileAccess::X_GENERIC_ALL) { - // We don't support any write modes. - XELOGE("Attempted to open the file/dir for create/write"); - result = X_STATUS_ACCESS_DENIED; - info = entry ? X_FILE_EXISTS : X_FILE_DOES_NOT_EXIST; } else { // Open the file/directory. result = fs->Open(std::move(entry), state, fs::Mode::READ, From 3658e710d2e4de6c323b5b74dbac21925875e8f3 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Tue, 6 Jan 2015 00:13:27 -0800 Subject: [PATCH 334/388] Tweaks; timebase supports TBU. --- src/alloy/frontend/ppc/ppc_emit_control.cc | 17 +++++++++++++++-- src/xenia/kernel/apps/xmp_app.cc | 2 +- src/xenia/kernel/xboxkrnl_modules.cc | 1 + 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/alloy/frontend/ppc/ppc_emit_control.cc b/src/alloy/frontend/ppc/ppc_emit_control.cc index 7de4a02a4..49f1a62ff 100644 --- a/src/alloy/frontend/ppc/ppc_emit_control.cc +++ b/src/alloy/frontend/ppc/ppc_emit_control.cc @@ -555,7 +555,14 @@ XEEMITTER(mfspr, 0x7C0002A6, XFX)(PPCHIRBuilder& f, InstrData& i) { // CTR v = f.LoadCTR(); break; - // 268 + 269 = TB + TBU + case 268: + // TB + v = f.LoadClock(); + break; + case 269: + // TBU + v = f.Shr(f.LoadClock(), 32); + break; default: XEINSTRNOTIMPLEMENTED(); return 1; @@ -566,8 +573,14 @@ XEEMITTER(mfspr, 0x7C0002A6, XFX)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(mftb, 0x7C0002E6, XFX)(PPCHIRBuilder& f, InstrData& i) { Value* time = f.LoadClock(); + const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F); + if (n == 268) { + // TB - full bits. + } else { + // TBU - upper bits only. + time = f.Shr(time, 32); + } f.StoreGPR(i.XFX.RT, time); - return 0; } diff --git a/src/xenia/kernel/apps/xmp_app.cc b/src/xenia/kernel/apps/xmp_app.cc index 423a64506..e3ce93c27 100644 --- a/src/xenia/kernel/apps/xmp_app.cc +++ b/src/xenia/kernel/apps/xmp_app.cc @@ -30,7 +30,7 @@ X_RESULT XXMPApp::XMPGetStatusEx(uint32_t unk, uint32_t unk_ptr, uint32_t disabled_ptr) { // Some stupid games will hammer this on a thread - induce a delay // here to keep from starving real threads. - Sleep(1); + Sleep(10); XELOGD("XMPGetStatusEx(%.8X, %.8X, %.8X)", unk, unk_ptr, disabled_ptr); diff --git a/src/xenia/kernel/xboxkrnl_modules.cc b/src/xenia/kernel/xboxkrnl_modules.cc index 33f66aa26..1a57e4cdd 100644 --- a/src/xenia/kernel/xboxkrnl_modules.cc +++ b/src/xenia/kernel/xboxkrnl_modules.cc @@ -246,6 +246,7 @@ SHIM_CALL XexGetProcedureAddress_shim(PPCContext* ppc_state, out_function_ptr); X_STATUS result = X_STATUS_INVALID_HANDLE; + SHIM_SET_MEM_32(out_function_ptr, 0xDEADF00D); XModule* module = NULL; From 662bbb67299569b7875d66dde92d5e6f35ea1596 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 7 Jan 2015 21:47:46 -0800 Subject: [PATCH 335/388] Experimenting with video stuff. --- src/xenia/gpu/gl4/command_processor.cc | 1 + src/xenia/kernel/xboxkrnl_video.cc | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/xenia/gpu/gl4/command_processor.cc b/src/xenia/gpu/gl4/command_processor.cc index c2717bafe..2dd6b7b44 100644 --- a/src/xenia/gpu/gl4/command_processor.cc +++ b/src/xenia/gpu/gl4/command_processor.cc @@ -746,6 +746,7 @@ bool CommandProcessor::ExecutePacketType3(RingbufferReader* reader, // Ignored packets - useful if breaking on the default handler below. case 0x50: // 0xC0015000 usually 2 words, 0xFFFFFFFF / 0x00000000 + case 0x51: // 0xC0015100 usually 2 words, 0xFFFFFFFF / 0xFFFFFFFF XETRACECP("[%.8X] Packet(%.8X): unknown!", packet_ptr, packet); reader->TraceData(count); reader->Skip(count); diff --git a/src/xenia/kernel/xboxkrnl_video.cc b/src/xenia/kernel/xboxkrnl_video.cc index 36bc76069..e15489aa7 100644 --- a/src/xenia/kernel/xboxkrnl_video.cc +++ b/src/xenia/kernel/xboxkrnl_video.cc @@ -97,8 +97,10 @@ void xeVdQueryVideoMode(X_VIDEO_MODE* video_mode) { video_mode->is_hi_def = 1; video_mode->refresh_rate = 60.0f; video_mode->video_standard = 1; // NTSC - video_mode->unknown_0x8a = 0x8A; + video_mode->unknown_0x8a = 0x94; // 0x8A; video_mode->unknown_0x01 = 0x01; + video_mode->reserved[0] = video_mode->reserved[1] = video_mode->reserved[2] = + 0; } SHIM_CALL VdQueryVideoMode_shim(PPCContext* ppc_state, KernelState* state) { @@ -158,6 +160,13 @@ SHIM_CALL VdShutdownEngines_shim(PPCContext* ppc_state, KernelState* state) { // re-initialize. } +SHIM_CALL VdGetGraphicsAsicID_shim(PPCContext* ppc_state, KernelState* state) { + XELOGD("VdGetGraphicsAsicID()"); + + // Games compare for < 0x10 and do VdInitializeEDRAM, else other (retrain/etc). + SHIM_SET_RETURN_64(0x11); +} + SHIM_CALL VdEnableDisableClockGating_shim(PPCContext* ppc_state, KernelState* state) { uint32_t enabled = SHIM_GET_ARG_32(0); @@ -397,6 +406,7 @@ SHIM_CALL VdSwap_shim(PPCContext* ppc_state, KernelState* state) { } // namespace kernel } // namespace xe + void xe::kernel::xboxkrnl::RegisterVideoExports(ExportResolver* export_resolver, KernelState* state) { SHIM_SET_MAPPING("xboxkrnl.exe", VdGetCurrentDisplayGamma, state); @@ -407,6 +417,7 @@ void xe::kernel::xboxkrnl::RegisterVideoExports(ExportResolver* export_resolver, SHIM_SET_MAPPING("xboxkrnl.exe", VdSetDisplayModeOverride, state); SHIM_SET_MAPPING("xboxkrnl.exe", VdInitializeEngines, state); SHIM_SET_MAPPING("xboxkrnl.exe", VdShutdownEngines, state); + SHIM_SET_MAPPING("xboxkrnl.exe", VdGetGraphicsAsicID, state); SHIM_SET_MAPPING("xboxkrnl.exe", VdEnableDisableClockGating, state); SHIM_SET_MAPPING("xboxkrnl.exe", VdSetGraphicsInterruptCallback, state); SHIM_SET_MAPPING("xboxkrnl.exe", VdInitializeRingBuffer, state); From 6eb9c3c9e548138908cd3a4f8da755766daf2912 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 7 Jan 2015 21:51:03 -0800 Subject: [PATCH 336/388] Trying to find real register values. --- src/xenia/gpu/gl4/gl4_graphics_system.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/xenia/gpu/gl4/gl4_graphics_system.cc b/src/xenia/gpu/gl4/gl4_graphics_system.cc index dde643ce3..a92339bd6 100644 --- a/src/xenia/gpu/gl4/gl4_graphics_system.cc +++ b/src/xenia/gpu/gl4/gl4_graphics_system.cc @@ -152,12 +152,16 @@ uint64_t GL4GraphicsSystem::ReadRegister(uint64_t addr) { } switch (r) { - case 0x6530: // ???? - return 1; + case 0x3C00: // ? + return 0x08100748; + case 0x3C04: // ? + return 0x0000200E; + case 0x6530: // Scanline? + return 0x000002D0; case 0x6544: // ? vblank pending? return 1; - case 0x6584: // ???? - return 1; + case 0x6584: // Screen res - 1280x720 + return 0x050002D0; } assert_true(r >= 0 && r < RegisterFile::kRegisterCount); From 9e1c3e1dfc83446555deeaafdfb2057366f3d9bc Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 7 Jan 2015 22:24:59 -0800 Subject: [PATCH 337/388] Putting something at 0x40000000. --- src/xenia/memory.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/xenia/memory.cc b/src/xenia/memory.cc index 7f387e07a..ccbb8e85e 100644 --- a/src/xenia/memory.cc +++ b/src/xenia/memory.cc @@ -201,6 +201,11 @@ int Memory::Initialize() { return 1; } + // I have no idea what this is, but games try to read/write there. + VirtualAlloc(Translate(0x40000000), 0x00010000, MEM_COMMIT, PAGE_READWRITE); + StoreI32(0x40000000, 0x00C40000); + StoreI32(0x40000004, 0x00010000); + return 0; } From dfba5943dafa2df2db371156964c67469fcae75e Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 7 Jan 2015 22:54:50 -0800 Subject: [PATCH 338/388] Hide invalid interrupt dispatches. --- src/xenia/gpu/graphics_system.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/xenia/gpu/graphics_system.cc b/src/xenia/gpu/graphics_system.cc index f5476e518..89eca968e 100644 --- a/src/xenia/gpu/graphics_system.cc +++ b/src/xenia/gpu/graphics_system.cc @@ -41,6 +41,10 @@ void GraphicsSystem::SetInterruptCallback(uint32_t callback, } void GraphicsSystem::DispatchInterruptCallback(uint32_t source, uint32_t cpu) { + if (!interrupt_callback_) { + return; + } + // Pick a CPU, if needed. We're going to guess 2. Because. if (cpu == 0xFFFFFFFF) { cpu = 2; @@ -50,9 +54,6 @@ void GraphicsSystem::DispatchInterruptCallback(uint32_t source, uint32_t cpu) { interrupt_callback_, source, cpu); // NOTE: we may be executing in some random thread. - if (!interrupt_callback_) { - return; - } uint64_t args[] = {source, interrupt_callback_data_}; processor_->ExecuteInterrupt(cpu, interrupt_callback_, args, poly::countof(args)); From fde3904130c1528e7ff11c0acbd4b83d91cd08bb Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 8 Jan 2015 23:35:25 -0800 Subject: [PATCH 339/388] Emulated SHR_V128 implementation. --- src/alloy/backend/x64/x64_sequences.cc | 29 +- src/alloy/test/test_shr.cc | 387 +++++++++++++++---------- 2 files changed, 255 insertions(+), 161 deletions(-) diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index fcc4649d9..a3b207425 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -4192,12 +4192,39 @@ EMITTER(SHR_I64, MATCH(I, I64<>, I8<>>)) { EmitShrXX(e, i); } }; +EMITTER(SHR_V128, MATCH(I, V128<>, I8<>>)) { + static void Emit(X64Emitter& e, const EmitArgType& i) { + // TODO(benvanik): native version (with shift magic). + if (i.src2.is_constant) { + e.mov(e.r9, i.src2.constant()); + } else { + e.mov(e.r9, i.src2); + } + e.lea(e.r8, e.StashXmm(0, i.src1)); + e.CallNativeSafe(reinterpret_cast(EmulateShrV128)); + e.vmovaps(i.dest, e.xmm0); + } + static __m128i EmulateShrV128(void*, __m128i src1, uint8_t src2) { + // Almost all instances are shamt = 1, but non-constant. + // shamt is [0,7] + uint8_t shamt = src2 & 0x7; + alignas(16) vec128_t value; + _mm_store_si128(reinterpret_cast<__m128i*>(&value), src1); + value.u8[0 ^ 0x3] = value.u8[0 ^ 0x3] >> shamt; + for (int i = 15; i > 0; --i) { + value.u8[i ^ 0x3] = (value.u8[i ^ 0x3] >> shamt) | + (value.u8[(i - 1) ^ 0x3] << (8 - shamt)); + } + return _mm_load_si128(reinterpret_cast<__m128i*>(&value)); + } +}; EMITTER_OPCODE_TABLE( OPCODE_SHR, SHR_I8, SHR_I16, SHR_I32, - SHR_I64); + SHR_I64, + SHR_V128); // ============================================================================ diff --git a/src/alloy/test/test_shr.cc b/src/alloy/test/test_shr.cc index ff5b10634..d79237000 100644 --- a/src/alloy/test/test_shr.cc +++ b/src/alloy/test/test_shr.cc @@ -22,46 +22,51 @@ TEST_CASE("SHR_I8", "[instr]") { INT64_TYPE)); b.Return(); }); - test.Run([](PPCContext* ctx) { - ctx->r[4] = 0xF0; - ctx->r[5] = 4; - }, - [](PPCContext* ctx) { - auto result = static_cast(ctx->r[3]); - REQUIRE(result == 0x0F); - }); - test.Run([](PPCContext* ctx) { - ctx->r[4] = 0xFF; - ctx->r[5] = 0; - }, - [](PPCContext* ctx) { - auto result = static_cast(ctx->r[3]); - REQUIRE(result == 0xFF); - }); - test.Run([](PPCContext* ctx) { - ctx->r[4] = 0xFF; - ctx->r[5] = 1; - }, - [](PPCContext* ctx) { - auto result = static_cast(ctx->r[3]); - REQUIRE(result == 0x7F); - }); - test.Run([](PPCContext* ctx) { - ctx->r[4] = 0x80; - ctx->r[5] = 8; - }, - [](PPCContext* ctx) { - auto result = static_cast(ctx->r[3]); - REQUIRE(result == 0); - }); - test.Run([](PPCContext* ctx) { - ctx->r[4] = 0x7F; - ctx->r[5] = 7; - }, - [](PPCContext* ctx) { - auto result = static_cast(ctx->r[3]); - REQUIRE(result == 0); - }); + test.Run( + [](PPCContext* ctx) { + ctx->r[4] = 0xF0; + ctx->r[5] = 4; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x0F); + }); + test.Run( + [](PPCContext* ctx) { + ctx->r[4] = 0xFF; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFF); + }); + test.Run( + [](PPCContext* ctx) { + ctx->r[4] = 0xFF; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x7F); + }); + test.Run( + [](PPCContext* ctx) { + ctx->r[4] = 0x80; + ctx->r[5] = 8; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); + test.Run( + [](PPCContext* ctx) { + ctx->r[4] = 0x7F; + ctx->r[5] = 7; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); } TEST_CASE("SHR_I16", "[instr]") { @@ -71,46 +76,51 @@ TEST_CASE("SHR_I16", "[instr]") { INT64_TYPE)); b.Return(); }); - test.Run([](PPCContext* ctx) { - ctx->r[4] = 0xFF00; - ctx->r[5] = 8; - }, - [](PPCContext* ctx) { - auto result = static_cast(ctx->r[3]); - REQUIRE(result == 0x00FF); - }); - test.Run([](PPCContext* ctx) { - ctx->r[4] = 0xFFFF; - ctx->r[5] = 0; - }, - [](PPCContext* ctx) { - auto result = static_cast(ctx->r[3]); - REQUIRE(result == 0xFFFF); - }); - test.Run([](PPCContext* ctx) { - ctx->r[4] = 0xFFFE; - ctx->r[5] = 1; - }, - [](PPCContext* ctx) { - auto result = static_cast(ctx->r[3]); - REQUIRE(result == 0x7FFF); - }); - test.Run([](PPCContext* ctx) { - ctx->r[4] = 0x8000; - ctx->r[5] = 16; - }, - [](PPCContext* ctx) { - auto result = static_cast(ctx->r[3]); - REQUIRE(result == 0); - }); - test.Run([](PPCContext* ctx) { - ctx->r[4] = 0x7FFF; - ctx->r[5] = 15; - }, - [](PPCContext* ctx) { - auto result = static_cast(ctx->r[3]); - REQUIRE(result == 0); - }); + test.Run( + [](PPCContext* ctx) { + ctx->r[4] = 0xFF00; + ctx->r[5] = 8; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x00FF); + }); + test.Run( + [](PPCContext* ctx) { + ctx->r[4] = 0xFFFF; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFF); + }); + test.Run( + [](PPCContext* ctx) { + ctx->r[4] = 0xFFFE; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x7FFF); + }); + test.Run( + [](PPCContext* ctx) { + ctx->r[4] = 0x8000; + ctx->r[5] = 16; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); + test.Run( + [](PPCContext* ctx) { + ctx->r[4] = 0x7FFF; + ctx->r[5] = 15; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); } TEST_CASE("SHR_I32", "[instr]") { @@ -120,46 +130,51 @@ TEST_CASE("SHR_I32", "[instr]") { INT64_TYPE)); b.Return(); }); - test.Run([](PPCContext* ctx) { - ctx->r[4] = 0xFFFF0000; - ctx->r[5] = 16; - }, - [](PPCContext* ctx) { - auto result = static_cast(ctx->r[3]); - REQUIRE(result == 0x0000FFFF); - }); - test.Run([](PPCContext* ctx) { - ctx->r[4] = 0xFFFFFFFF; - ctx->r[5] = 0; - }, - [](PPCContext* ctx) { - auto result = static_cast(ctx->r[3]); - REQUIRE(result == 0xFFFFFFFF); - }); - test.Run([](PPCContext* ctx) { - ctx->r[4] = 0xFFFFFFFE; - ctx->r[5] = 1; - }, - [](PPCContext* ctx) { - auto result = static_cast(ctx->r[3]); - REQUIRE(result == 0x7FFFFFFF); - }); - test.Run([](PPCContext* ctx) { - ctx->r[4] = 0x80000000; - ctx->r[5] = 32; - }, - [](PPCContext* ctx) { - auto result = static_cast(ctx->r[3]); - REQUIRE(result == 0x80000000); - }); - test.Run([](PPCContext* ctx) { - ctx->r[4] = 0x7FFFFFFF; - ctx->r[5] = 31; - }, - [](PPCContext* ctx) { - auto result = static_cast(ctx->r[3]); - REQUIRE(result == 0); - }); + test.Run( + [](PPCContext* ctx) { + ctx->r[4] = 0xFFFF0000; + ctx->r[5] = 16; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x0000FFFF); + }); + test.Run( + [](PPCContext* ctx) { + ctx->r[4] = 0xFFFFFFFF; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFFFFFF); + }); + test.Run( + [](PPCContext* ctx) { + ctx->r[4] = 0xFFFFFFFE; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x7FFFFFFF); + }); + test.Run( + [](PPCContext* ctx) { + ctx->r[4] = 0x80000000; + ctx->r[5] = 32; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x80000000); + }); + test.Run( + [](PPCContext* ctx) { + ctx->r[4] = 0x7FFFFFFF; + ctx->r[5] = 31; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); } TEST_CASE("SHR_I64", "[instr]") { @@ -168,44 +183,96 @@ TEST_CASE("SHR_I64", "[instr]") { b.Truncate(LoadGPR(b, 5), INT8_TYPE))); b.Return(); }); - test.Run([](PPCContext* ctx) { - ctx->r[4] = 0xFFFFFFFF00000000ull; - ctx->r[5] = 32; - }, - [](PPCContext* ctx) { - auto result = static_cast(ctx->r[3]); - REQUIRE(result == 0x00000000FFFFFFFFull); - }); - test.Run([](PPCContext* ctx) { - ctx->r[4] = 0xFFFFFFFFFFFFFFFFull; - ctx->r[5] = 0; - }, - [](PPCContext* ctx) { - auto result = static_cast(ctx->r[3]); - REQUIRE(result == 0xFFFFFFFFFFFFFFFFull); - }); - test.Run([](PPCContext* ctx) { - ctx->r[4] = 0xFFFFFFFFFFFFFFFEull; - ctx->r[5] = 1; - }, - [](PPCContext* ctx) { - auto result = static_cast(ctx->r[3]); - REQUIRE(result == 0x7FFFFFFFFFFFFFFFull); - }); - test.Run([](PPCContext* ctx) { - ctx->r[4] = 0x8000000000000000ull; - ctx->r[5] = 64; - }, - [](PPCContext* ctx) { - auto result = static_cast(ctx->r[3]); - REQUIRE(result == 0x8000000000000000ull); - }); - test.Run([](PPCContext* ctx) { - ctx->r[4] = 0x7FFFFFFFFFFFFFFFull; - ctx->r[5] = 63; - }, - [](PPCContext* ctx) { - auto result = static_cast(ctx->r[3]); - REQUIRE(result == 0); - }); + test.Run( + [](PPCContext* ctx) { + ctx->r[4] = 0xFFFFFFFF00000000ull; + ctx->r[5] = 32; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x00000000FFFFFFFFull); + }); + test.Run( + [](PPCContext* ctx) { + ctx->r[4] = 0xFFFFFFFFFFFFFFFFull; + ctx->r[5] = 0; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0xFFFFFFFFFFFFFFFFull); + }); + test.Run( + [](PPCContext* ctx) { + ctx->r[4] = 0xFFFFFFFFFFFFFFFEull; + ctx->r[5] = 1; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x7FFFFFFFFFFFFFFFull); + }); + test.Run( + [](PPCContext* ctx) { + ctx->r[4] = 0x8000000000000000ull; + ctx->r[5] = 64; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0x8000000000000000ull); + }); + test.Run( + [](PPCContext* ctx) { + ctx->r[4] = 0x7FFFFFFFFFFFFFFFull; + ctx->r[5] = 63; + }, + [](PPCContext* ctx) { + auto result = static_cast(ctx->r[3]); + REQUIRE(result == 0); + }); } + +TEST_CASE("SHR_V128", "[instr]") { + TestFunction test([](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Shr(LoadVR(b, 4), b.Truncate(LoadGPR(b, 1), INT8_TYPE))); + b.Return(); + }); + test.Run( + [](PPCContext* ctx) { + ctx->r[1] = 0; + ctx->v[4] = vec128i(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); + }, + [](PPCContext* ctx) { + auto result1 = ctx->v[3]; + REQUIRE(result1 == + vec128i(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF)); + }); + test.Run( + [](PPCContext* ctx) { + ctx->r[1] = 1; + ctx->v[4] = vec128i(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); + }, + [](PPCContext* ctx) { + auto result1 = ctx->v[3]; + REQUIRE(result1 == + vec128i(0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF)); + }); + test.Run( + [](PPCContext* ctx) { + ctx->r[1] = 2; + ctx->v[4] = vec128i(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); + }, + [](PPCContext* ctx) { + auto result1 = ctx->v[3]; + REQUIRE(result1 == + vec128i(0x3FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF)); + }); + test.Run( + [](PPCContext* ctx) { + ctx->r[1] = 8; + ctx->v[4] = vec128i(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); + }, + [](PPCContext* ctx) { + auto result1 = ctx->v[3]; + REQUIRE(result1 == + vec128i(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF)); + }); +} \ No newline at end of file From 6437bbec96ab7701fb504e5dcf21c4761415d2e0 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 9 Jan 2015 00:12:11 -0800 Subject: [PATCH 340/388] OPCODE_INSERT --- src/alloy/backend/x64/x64_sequences.cc | 12 ++- src/alloy/hir/hir_builder.cc | 5 +- src/alloy/test/test_insert.cc | 103 +++++++++++++------------ 3 files changed, 66 insertions(+), 54 deletions(-) diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index a3b207425..8a1467a43 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -4782,16 +4782,22 @@ EMITTER_OPCODE_TABLE( // ============================================================================ // OPCODE_INSERT // ============================================================================ -EMITTER(INSERT_I8, MATCH(I, V128<>, I64<>, I8<>>)) { +EMITTER(INSERT_I8, MATCH(I, V128<>, I8<>, I8<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { + assert_true(i.src2.is_constant); + e.vpinsrb(i.dest, i.src3.reg().cvt32(), i.src2.constant() ^ 0x3); } }; -EMITTER(INSERT_I16, MATCH(I, V128<>, I64<>, I16<>>)) { +EMITTER(INSERT_I16, MATCH(I, V128<>, I8<>, I16<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { + assert_true(i.src2.is_constant); + e.vpinsrw(i.dest, i.src3.reg().cvt32(), i.src2.constant() ^ 0x1); } }; -EMITTER(INSERT_I32, MATCH(I, V128<>, I64<>, I32<>>)) { +EMITTER(INSERT_I32, MATCH(I, V128<>, I8<>, I32<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { + assert_true(i.src2.is_constant); + e.vpinsrd(i.dest, i.src3, i.src2.constant()); } }; EMITTER_OPCODE_TABLE( diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index f1d3f7883..62dbe16cf 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -1809,9 +1809,12 @@ Value* HIRBuilder::CountLeadingZeros(Value* value) { Value* HIRBuilder::Insert(Value* value, Value* index, Value* part) { // TODO(benvanik): could do some of this as constants. + Value* trunc_index = + index->type != INT8_TYPE ? Truncate(index, INT8_TYPE) : index; + Instr* i = AppendInstr(OPCODE_INSERT_info, 0, AllocValue(value->type)); i->set_src1(value); - i->set_src2(ZeroExtend(index, INT64_TYPE)); + i->set_src2(trunc_index); i->set_src3(part); return i->dest; } diff --git a/src/alloy/test/test_insert.cc b/src/alloy/test/test_insert.cc index a23d07896..5bd9a756b 100644 --- a/src/alloy/test/test_insert.cc +++ b/src/alloy/test/test_insert.cc @@ -18,66 +18,69 @@ using namespace alloy::test; using alloy::frontend::ppc::PPCContext; TEST_CASE("INSERT_INT8", "[instr]") { - TestFunction test([](hir::HIRBuilder& b) { - StoreVR(b, 3, b.Insert(LoadVR(b, 4), LoadGPR(b, 4), - b.Truncate(LoadGPR(b, 5), INT8_TYPE))); - b.Return(); - }); for (int i = 0; i < 16; ++i) { - test.Run([i](PPCContext* ctx) { - ctx->v[4] = vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15); - ctx->r[4] = i; - ctx->r[5] = 100 + i; - }, - [i](PPCContext* ctx) { - auto result = ctx->v[3]; - auto expected = vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15); - expected.i8[i ^ 0x3] = 100 + i; - REQUIRE(result == expected); - }); + TestFunction test([i](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Insert(LoadVR(b, 4), b.LoadConstant(i), + b.Truncate(LoadGPR(b, 5), INT8_TYPE))); + b.Return(); + }); + test.Run( + [i](PPCContext* ctx) { + ctx->v[4] = + vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + ctx->r[4] = i; + ctx->r[5] = 100 + i; + }, + [i](PPCContext* ctx) { + auto result = ctx->v[3]; + auto expected = + vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + expected.i8[i ^ 0x3] = 100 + i; + REQUIRE(result == expected); + }); } } TEST_CASE("INSERT_INT16", "[instr]") { - TestFunction test([](hir::HIRBuilder& b) { - StoreVR(b, 3, b.Insert(LoadVR(b, 4), LoadGPR(b, 4), - b.Truncate(LoadGPR(b, 5), INT16_TYPE))); - b.Return(); - }); for (int i = 0; i < 8; ++i) { - test.Run([i](PPCContext* ctx) { - ctx->v[4] = vec128s(0, 1, 2, 3, 4, 5, 6, 7); - ctx->r[4] = i; - ctx->r[5] = 100 + i; - }, - [i](PPCContext* ctx) { - auto result = ctx->v[3]; - auto expected = vec128s(0, 1, 2, 3, 4, 5, 6, 7); - expected.i16[i ^ 0x1] = 100 + i; - REQUIRE(result == expected); - }); + TestFunction test([i](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Insert(LoadVR(b, 4), b.LoadConstant(i), + b.Truncate(LoadGPR(b, 5), INT16_TYPE))); + b.Return(); + }); + test.Run( + [i](PPCContext* ctx) { + ctx->v[4] = vec128s(0, 1, 2, 3, 4, 5, 6, 7); + ctx->r[4] = i; + ctx->r[5] = 100 + i; + }, + [i](PPCContext* ctx) { + auto result = ctx->v[3]; + auto expected = vec128s(0, 1, 2, 3, 4, 5, 6, 7); + expected.i16[i ^ 0x1] = 100 + i; + REQUIRE(result == expected); + }); } } TEST_CASE("INSERT_INT32", "[instr]") { - TestFunction test([](hir::HIRBuilder& b) { - StoreVR(b, 3, b.Insert(LoadVR(b, 4), LoadGPR(b, 4), - b.Truncate(LoadGPR(b, 5), INT32_TYPE))); - b.Return(); - }); for (int i = 0; i < 4; ++i) { - test.Run([i](PPCContext* ctx) { - ctx->v[4] = vec128i(0, 1, 2, 3); - ctx->r[4] = i; - ctx->r[5] = 100 + i; - }, - [i](PPCContext* ctx) { - auto result = ctx->v[3]; - auto expected = vec128i(0, 1, 2, 3); - expected.i32[i] = 100 + i; - REQUIRE(result == expected); - }); + TestFunction test([i](hir::HIRBuilder& b) { + StoreVR(b, 3, b.Insert(LoadVR(b, 4), b.LoadConstant(i), + b.Truncate(LoadGPR(b, 5), INT32_TYPE))); + b.Return(); + }); + test.Run( + [i](PPCContext* ctx) { + ctx->v[4] = vec128i(0, 1, 2, 3); + ctx->r[4] = i; + ctx->r[5] = 100 + i; + }, + [i](PPCContext* ctx) { + auto result = ctx->v[3]; + auto expected = vec128i(0, 1, 2, 3); + expected.i32[i] = 100 + i; + REQUIRE(result == expected); + }); } } From 2bc951cd1ef54b99b60761e17005fabec0695823 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 9 Jan 2015 00:26:40 -0800 Subject: [PATCH 341/388] Stub for screen extent write event. --- src/xenia/gpu/gl4/command_processor.cc | 15 +++++++++++++++ src/xenia/gpu/gl4/command_processor.h | 3 +++ src/xenia/gpu/xenos.h | 1 + 3 files changed, 19 insertions(+) diff --git a/src/xenia/gpu/gl4/command_processor.cc b/src/xenia/gpu/gl4/command_processor.cc index 2dd6b7b44..907427790 100644 --- a/src/xenia/gpu/gl4/command_processor.cc +++ b/src/xenia/gpu/gl4/command_processor.cc @@ -686,6 +686,10 @@ bool CommandProcessor::ExecutePacketType3(RingbufferReader* reader, result = ExecutePacketType3_EVENT_WRITE_SHD(reader, packet_ptr, packet, count); break; + case PM4_EVENT_WRITE_EXT: + result = + ExecutePacketType3_EVENT_WRITE_EXT(reader, packet_ptr, packet, count); + break; case PM4_DRAW_INDX: result = ExecutePacketType3_DRAW_INDX(reader, packet_ptr, packet, count); break; @@ -1096,6 +1100,17 @@ bool CommandProcessor::ExecutePacketType3_EVENT_WRITE_SHD( return true; } +bool CommandProcessor::ExecutePacketType3_EVENT_WRITE_EXT( + RingbufferReader* reader, uint32_t packet_ptr, uint32_t packet, + uint32_t count) { + // generate a screen extent event + XETRACECP("[%.8X] Packet(%.8X): PM4_EVENT_WRITE_EXT", packet_ptr, packet); + reader->TraceData(count); + uint32_t unk0 = reader->Read(); + uint32_t unk1 = reader->Read(); + return true; +} + bool CommandProcessor::ExecutePacketType3_DRAW_INDX(RingbufferReader* reader, uint32_t packet_ptr, uint32_t packet, diff --git a/src/xenia/gpu/gl4/command_processor.h b/src/xenia/gpu/gl4/command_processor.h index 481bb98ff..6a21459dd 100644 --- a/src/xenia/gpu/gl4/command_processor.h +++ b/src/xenia/gpu/gl4/command_processor.h @@ -151,6 +151,9 @@ class CommandProcessor { bool ExecutePacketType3_EVENT_WRITE_SHD(RingbufferReader* reader, uint32_t packet_ptr, uint32_t packet, uint32_t count); + bool ExecutePacketType3_EVENT_WRITE_EXT(RingbufferReader* reader, + uint32_t packet_ptr, uint32_t packet, + uint32_t count); bool ExecutePacketType3_DRAW_INDX(RingbufferReader* reader, uint32_t packet_ptr, uint32_t packet, uint32_t count); diff --git a/src/xenia/gpu/xenos.h b/src/xenia/gpu/xenos.h index 77e9b766a..3b8446e27 100644 --- a/src/xenia/gpu/xenos.h +++ b/src/xenia/gpu/xenos.h @@ -398,6 +398,7 @@ enum Type3Opcode { PM4_EVENT_WRITE = 0x46, // generate an event that creates a write to memory when completed PM4_EVENT_WRITE_SHD = 0x58, // generate a VS|PS_done event PM4_EVENT_WRITE_CFL = 0x59, // generate a cache flush done event + PM4_EVENT_WRITE_EXT = 0x5a, // generate a screen extent event PM4_EVENT_WRITE_ZPD = 0x5b, // generate a z_pass done event PM4_DRAW_INDX = 0x22, // initiate fetch of index buffer and draw From 9f765e1291afe6de2da2f54c810ce6e9714210f1 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 9 Jan 2015 00:26:47 -0800 Subject: [PATCH 342/388] XMsgStartIORequestEx --- src/xenia/kernel/xam_msg.cc | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/xenia/kernel/xam_msg.cc b/src/xenia/kernel/xam_msg.cc index 9647c323a..fca069e67 100644 --- a/src/xenia/kernel/xam_msg.cc +++ b/src/xenia/kernel/xam_msg.cc @@ -53,6 +53,27 @@ SHIM_CALL XMsgStartIORequest_shim(PPCContext* ppc_state, KernelState* state) { SHIM_SET_RETURN_32(result); } +SHIM_CALL XMsgStartIORequestEx_shim(PPCContext* ppc_state, KernelState* state) { + uint32_t app = SHIM_GET_ARG_32(0); + uint32_t message = SHIM_GET_ARG_32(1); + uint32_t overlapped_ptr = SHIM_GET_ARG_32(2); + uint32_t buffer = SHIM_GET_ARG_32(3); + uint32_t buffer_length = SHIM_GET_ARG_32(4); + uint32_t unknown_ptr = SHIM_GET_ARG_32(5); + + XELOGD("XMsgStartIORequestEx(%.8X, %.8X, %.8X, %.8X, %d, %.8X)", app, message, + overlapped_ptr, buffer, buffer_length, unknown_ptr); + + assert_zero(overlapped_ptr); + + auto result = state->app_manager()->DispatchMessageAsync(app, message, buffer, + buffer_length); + if (result == X_ERROR_NOT_FOUND) { + XELOGE("XMsgStartIORequestEx: app %.8X undefined", app); + } + SHIM_SET_RETURN_32(result); +} + SHIM_CALL XMsgCancelIORequest_shim(PPCContext* ppc_state, KernelState* state) { uint32_t overlapped_ptr = SHIM_GET_ARG_32(0); uint32_t wait = SHIM_GET_ARG_32(1); @@ -79,5 +100,6 @@ void xe::kernel::xam::RegisterMsgExports(ExportResolver* export_resolver, KernelState* state) { SHIM_SET_MAPPING("xam.xex", XMsgInProcessCall, state); SHIM_SET_MAPPING("xam.xex", XMsgStartIORequest, state); + SHIM_SET_MAPPING("xam.xex", XMsgStartIORequestEx, state); SHIM_SET_MAPPING("xam.xex", XMsgCancelIORequest, state); } From e7ee2bf40d168fdaa228672b2b2bdf0e79e35c0e Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 9 Jan 2015 00:31:56 -0800 Subject: [PATCH 343/388] XamLoaderLaunchTitle --- src/xenia/kernel/xam_info.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/xenia/kernel/xam_info.cc b/src/xenia/kernel/xam_info.cc index b6a140c01..8109b086a 100644 --- a/src/xenia/kernel/xam_info.cc +++ b/src/xenia/kernel/xam_info.cc @@ -89,6 +89,11 @@ SHIM_CALL XamLoaderGetLaunchData_shim(PPCContext* ppc_state, SHIM_SET_RETURN_64(0); } +SHIM_CALL XamLoaderLaunchTitle_shim(PPCContext* ppc_state, KernelState* state) { + XELOGD("XamLoaderLaunchTitle(?)"); + assert_always(); +} + SHIM_CALL XamLoaderTerminateTitle_shim(PPCContext* ppc_state, KernelState* state) { XELOGD("XamLoaderTerminateTitle()"); @@ -142,6 +147,7 @@ void xe::kernel::xam::RegisterInfoExports(ExportResolver* export_resolver, SHIM_SET_MAPPING("xam.xex", XamLoaderGetLaunchDataSize, state); SHIM_SET_MAPPING("xam.xex", XamLoaderGetLaunchData, state); + SHIM_SET_MAPPING("xam.xex", XamLoaderLaunchTitle, state); SHIM_SET_MAPPING("xam.xex", XamLoaderTerminateTitle, state); SHIM_SET_MAPPING("xam.xex", XamEnumerate, state); From cf31969510d34f699ba87a5b6f6ce58d8c4e2c64 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 9 Jan 2015 00:33:11 -0800 Subject: [PATCH 344/388] Update comment on VGT_MIN/MAX_VTX_INDX. --- src/xenia/gpu/gl4/command_processor.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xenia/gpu/gl4/command_processor.cc b/src/xenia/gpu/gl4/command_processor.cc index 907427790..203c6a000 100644 --- a/src/xenia/gpu/gl4/command_processor.cc +++ b/src/xenia/gpu/gl4/command_processor.cc @@ -2036,8 +2036,8 @@ CommandProcessor::UpdateStatus CommandProcessor::PopulateIndexBuffer() { SCOPE_profile_cpu_f("gpu"); #endif // FINE_GRAINED_DRAW_SCOPES - // Min/max index ranges. This is often [0g,FFFF|FFFFFF], but if it's not we - // can use it to do a glDrawRangeElements. + // Min/max index ranges for clamping. This is often [0g,FFFF|FFFFFF]. + // All indices should be clamped to [min,max]. May be a way to do this in GL. uint32_t min_index = regs[XE_GPU_REG_VGT_MIN_VTX_INDX].u32; uint32_t max_index = regs[XE_GPU_REG_VGT_MAX_VTX_INDX].u32; assert_true(min_index == 0); From f5e12eba769c8dfcc96fd2c248d1fe278b450e05 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 10 Jan 2015 21:36:46 -0800 Subject: [PATCH 345/388] Digging into XMP stuff. Wish these were just normal functions. --- src/xenia/kernel/app.cc | 7 +- src/xenia/kernel/app.h | 10 +- src/xenia/kernel/apps/xmp_app.cc | 252 +++++++++++++++++++++++-------- src/xenia/kernel/apps/xmp_app.h | 38 ++++- 4 files changed, 228 insertions(+), 79 deletions(-) diff --git a/src/xenia/kernel/app.cc b/src/xenia/kernel/app.cc index 4541ade59..bb2e5a1bc 100644 --- a/src/xenia/kernel/app.cc +++ b/src/xenia/kernel/app.cc @@ -26,12 +26,13 @@ void XAppManager::RegisterApp(std::unique_ptr app) { } X_RESULT XAppManager::DispatchMessageSync(uint32_t app_id, uint32_t message, - uint32_t arg1, uint32_t arg2) { + uint32_t buffer_ptr, + uint32_t buffer_length) { const auto& it = app_lookup_.find(app_id); if (it == app_lookup_.end()) { return X_ERROR_NOT_FOUND; } - return it->second->DispatchMessageSync(message, arg1, arg2); + return it->second->DispatchMessageSync(message, buffer_ptr, buffer_length); } X_RESULT XAppManager::DispatchMessageAsync(uint32_t app_id, uint32_t message, @@ -41,7 +42,7 @@ X_RESULT XAppManager::DispatchMessageAsync(uint32_t app_id, uint32_t message, if (it == app_lookup_.end()) { return X_ERROR_NOT_FOUND; } - return it->second->DispatchMessageAsync(message, buffer_ptr, buffer_length); + return it->second->DispatchMessageSync(message, buffer_ptr, buffer_length); } } // namespace kernel diff --git a/src/xenia/kernel/app.h b/src/xenia/kernel/app.h index 4b4782a69..3ff461cc0 100644 --- a/src/xenia/kernel/app.h +++ b/src/xenia/kernel/app.h @@ -26,10 +26,8 @@ class XApp { public: uint32_t app_id() const { return app_id_; } - virtual X_RESULT DispatchMessageSync(uint32_t message, uint32_t arg1, - uint32_t arg2) = 0; - virtual X_RESULT DispatchMessageAsync(uint32_t message, uint32_t buffer_ptr, - size_t buffer_length) = 0; + virtual X_RESULT DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, + uint32_t buffer_length) = 0; protected: XApp(KernelState* kernel_state, uint32_t app_id); @@ -43,8 +41,8 @@ class XAppManager { public: void RegisterApp(std::unique_ptr app); - X_RESULT DispatchMessageSync(uint32_t app_id, uint32_t message, uint32_t arg1, - uint32_t arg2); + X_RESULT DispatchMessageSync(uint32_t app_id, uint32_t message, + uint32_t buffer_ptr, uint32_t buffer_length); X_RESULT DispatchMessageAsync(uint32_t app_id, uint32_t message, uint32_t buffer_ptr, size_t buffer_length); diff --git a/src/xenia/kernel/apps/xmp_app.cc b/src/xenia/kernel/apps/xmp_app.cc index e3ce93c27..68a906e4a 100644 --- a/src/xenia/kernel/apps/xmp_app.cc +++ b/src/xenia/kernel/apps/xmp_app.cc @@ -13,91 +13,219 @@ namespace xe { namespace kernel { namespace apps { -X_RESULT XXMPApp::XMPGetStatus(uint32_t unk, uint32_t status_ptr) { +XXMPApp::XXMPApp(KernelState* kernel_state) + : XApp(kernel_state, 0xFA), + status_(Status::kStopped), + disabled_(0), + unknown_state1_(0), + unknown_state2_(0), + unknown_flags_(0), + unknown_float_(0.0f) {} + +X_RESULT XXMPApp::XMPGetStatus(uint32_t status_ptr) { // Some stupid games will hammer this on a thread - induce a delay // here to keep from starving real threads. Sleep(1); - XELOGD("XMPGetStatus(%.8X, %.8X)", unk, status_ptr); - - assert_true(unk == 2); - poly::store_and_swap(membase_ + status_ptr, 0); - + XELOGD("XMPGetStatus(%.8X)", status_ptr); + poly::store_and_swap(membase_ + status_ptr, + static_cast(status_)); + OnStatusChanged(); return X_ERROR_SUCCESS; } -X_RESULT XXMPApp::XMPGetStatusEx(uint32_t unk, uint32_t unk_ptr, - uint32_t disabled_ptr) { - // Some stupid games will hammer this on a thread - induce a delay - // here to keep from starving real threads. - Sleep(10); - - XELOGD("XMPGetStatusEx(%.8X, %.8X, %.8X)", unk, unk_ptr, disabled_ptr); - - assert_true(unk == 2); - poly::store_and_swap(membase_ + unk_ptr, 0); - poly::store_and_swap(membase_ + disabled_ptr, 1); - +X_RESULT XXMPApp::XMPContinue() { + XELOGD("XMPContinue()"); + if (status_ == Status::kPaused) { + status_ = Status::kPlaying; + } + OnStatusChanged(); return X_ERROR_SUCCESS; } -X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t arg1, - uint32_t arg2) { +X_RESULT XXMPApp::XMPStop(uint32_t unk) { + assert_zero(unk); + XELOGD("XMPStop(%.8X)", unk); + status_ = Status::kStopped; + OnStatusChanged(); + return X_ERROR_SUCCESS; +} + +X_RESULT XXMPApp::XMPPause() { + XELOGD("XMPPause()"); + if (status_ == Status::kPlaying) { + status_ = Status::kPaused; + } + OnStatusChanged(); + return X_ERROR_SUCCESS; +} + +X_RESULT XXMPApp::XMPNext() { + XELOGD("XMPNext()"); + status_ = Status::kPlaying; + OnStatusChanged(); + return X_ERROR_SUCCESS; +} + +X_RESULT XXMPApp::XMPPrevious() { + XELOGD("XMPPrevious()"); + status_ = Status::kPlaying; + OnStatusChanged(); + return X_ERROR_SUCCESS; +} + +void XXMPApp::OnStatusChanged() { + kernel_state_->BroadcastNotification(kMsgStatusChanged, + static_cast(status_)); +} + +X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, + uint32_t buffer_length) { + // NOTE: buffer_length may be zero or valid. // http://freestyledash.googlecode.com/svn-history/r1/trunk/Freestyle/Scenes/Media/Music/ScnMusic.cpp switch (message) { + case 0x00070003: { + assert_true(!buffer_length || buffer_length == 4); + uint32_t xmp_client = + poly::load_and_swap(membase_ + buffer_ptr + 0); + assert_true(xmp_client == 0x00000002); + return XMPContinue(); + } + case 0x00070004: { + assert_true(!buffer_length || buffer_length == 8); + uint32_t xmp_client = + poly::load_and_swap(membase_ + buffer_ptr + 0); + uint32_t unk = poly::load_and_swap(membase_ + buffer_ptr + 4); + assert_true(xmp_client == 0x00000002); + return XMPStop(unk); + } + case 0x00070005: { + assert_true(!buffer_length || buffer_length == 4); + uint32_t xmp_client = + poly::load_and_swap(membase_ + buffer_ptr + 0); + assert_true(xmp_client == 0x00000002); + return XMPPause(); + } + case 0x00070006: { + assert_true(!buffer_length || buffer_length == 4); + uint32_t xmp_client = + poly::load_and_swap(membase_ + buffer_ptr + 0); + assert_true(xmp_client == 0x00000002); + return XMPNext(); + } + case 0x00070007: { + assert_true(!buffer_length || buffer_length == 4); + uint32_t xmp_client = + poly::load_and_swap(membase_ + buffer_ptr + 0); + assert_true(xmp_client == 0x00000002); + return XMPPrevious(); + } + case 0x00070008: { + assert_true(!buffer_length || buffer_length == 16); + uint32_t xmp_client = + poly::load_and_swap(membase_ + buffer_ptr + 0); + uint32_t unk1 = poly::load_and_swap(membase_ + buffer_ptr + 4); + uint32_t unk2 = poly::load_and_swap(membase_ + buffer_ptr + 8); + uint32_t flags = + poly::load_and_swap(membase_ + buffer_ptr + 12); + assert_true(xmp_client == 0x00000002); + XELOGD("XMPSetState?(%.8X, %.8X, %.8X)", unk1, unk2, flags); + unknown_state1_ = unk1; + unknown_state2_ = unk2; + unknown_flags_ = flags; + kernel_state_->BroadcastNotification(kMsgStateChanged, 0); + return X_ERROR_SUCCESS; + } case 0x00070009: { - uint32_t unk = - poly::load_and_swap(membase_ + arg1 + 0); // 0x00000002 - uint32_t status_ptr = poly::load_and_swap( - membase_ + arg1 + 4); // out ptr to 4b - expect 0 - assert_zero(arg2); - return XMPGetStatus(unk, status_ptr); - } - case 0x0007001A: { - // dcz - // arg1 = ? - // arg2 = 0 - break; - } - case 0x0007001B: { - uint32_t unk = - poly::load_and_swap(membase_ + arg1 + 0); // 0x00000002 - uint32_t unk_ptr = poly::load_and_swap( - membase_ + arg1 + 4); // out ptr to 4b - expect 0 - uint32_t disabled_ptr = poly::load_and_swap( - membase_ + arg1 + 8); // out ptr to 4b - expect 1 (to skip) - assert_zero(arg2); - return XMPGetStatusEx(unk, unk_ptr, disabled_ptr); - } - } - XELOGE("Unimplemented XMsg message app=%.8X, msg=%.8X, arg1=%.8X, arg2=%.8X", - app_id(), message, arg1, arg2); - return X_ERROR_NOT_FOUND; -} - -X_RESULT XXMPApp::DispatchMessageAsync(uint32_t message, uint32_t buffer_ptr, - size_t buffer_length) { - switch (message) { - case 0x00070009: { - uint32_t unk = poly::load_and_swap(membase_ + buffer_ptr + - 0); // 0x00000002 + assert_true(!buffer_length || buffer_length == 8); + uint32_t xmp_client = + poly::load_and_swap(membase_ + buffer_ptr + 0); uint32_t status_ptr = poly::load_and_swap( membase_ + buffer_ptr + 4); // out ptr to 4b - expect 0 - assert_true(buffer_length == 8); - return XMPGetStatus(unk, status_ptr); + assert_true(xmp_client == 0x00000002); + return XMPGetStatus(status_ptr); + } + case 0x0007000B: { + assert_true(!buffer_length || buffer_length == 8); + uint32_t xmp_client = + poly::load_and_swap(membase_ + buffer_ptr + 0); + uint32_t float_ptr = poly::load_and_swap( + membase_ + buffer_ptr + 4); // out ptr to 4b - floating point + assert_true(xmp_client == 0x00000002); + XELOGD("XMPGetFloat?(%.8X)", float_ptr); + poly::store_and_swap(membase_ + float_ptr, unknown_float_); + return X_ERROR_SUCCESS; + } + case 0x0007000C: { + assert_true(!buffer_length || buffer_length == 8); + uint32_t xmp_client = + poly::load_and_swap(membase_ + buffer_ptr + 0); + float float_value = poly::load_and_swap(membase_ + buffer_ptr + 4); + assert_true(xmp_client == 0x00000002); + XELOGD("XMPSetFloat?(%g)", float_value); + unknown_float_ = float_value; + return X_ERROR_SUCCESS; + } + case 0x0007001A: { + assert_true(!buffer_length || buffer_length == 12); + uint32_t xmp_client = + poly::load_and_swap(membase_ + buffer_ptr + 0); + uint32_t unk1 = poly::load_and_swap(membase_ + buffer_ptr + 4); + uint32_t disabled = + poly::load_and_swap(membase_ + buffer_ptr + 8); + assert_true(xmp_client == 0x00000002); + assert_zero(unk1); + XELOGD("XMPSetDisabled(%.8X, %.8X)", unk1, disabled); + disabled_ = disabled; + kernel_state_->BroadcastNotification(kMsgDisableChanged, disabled_); + return X_ERROR_SUCCESS; } case 0x0007001B: { - uint32_t unk = poly::load_and_swap(membase_ + buffer_ptr + - 0); // 0x00000002 + assert_true(!buffer_length || buffer_length == 12); + uint32_t xmp_client = + poly::load_and_swap(membase_ + buffer_ptr + 0); uint32_t unk_ptr = poly::load_and_swap( membase_ + buffer_ptr + 4); // out ptr to 4b - expect 0 uint32_t disabled_ptr = poly::load_and_swap( membase_ + buffer_ptr + 8); // out ptr to 4b - expect 1 (to skip) - assert_true(buffer_length == 0xC); - return XMPGetStatusEx(unk, unk_ptr, disabled_ptr); + assert_true(xmp_client == 0x00000002); + XELOGD("XMPGetDisabled(%.8X, %.8X)", unk_ptr, disabled_ptr); + poly::store_and_swap(membase_ + unk_ptr, 0); + poly::store_and_swap(membase_ + disabled_ptr, disabled_); + return X_ERROR_SUCCESS; + } + case 0x00070029: { + assert_true(!buffer_length || buffer_length == 16); + uint32_t xmp_client = + poly::load_and_swap(membase_ + buffer_ptr + 0); + uint32_t unk1_ptr = + poly::load_and_swap(membase_ + buffer_ptr + 4); + uint32_t unk2_ptr = + poly::load_and_swap(membase_ + buffer_ptr + 8); + uint32_t unk3_ptr = + poly::load_and_swap(membase_ + buffer_ptr + 12); + assert_true(xmp_client == 0x00000002); + XELOGD("XMPGetState?(%.8X, %.8X, %.8X)", unk1_ptr, unk2_ptr, unk3_ptr); + poly::store_and_swap(membase_ + unk1_ptr, unknown_state1_); + poly::store_and_swap(membase_ + unk2_ptr, unknown_state2_); + poly::store_and_swap(membase_ + unk3_ptr, unknown_flags_); + return X_ERROR_SUCCESS; + } + case 0x0007002E: { + assert_true(!buffer_length || buffer_length == 12); + // 00000002 00000003 20049ce0 + uint32_t xmp_client = poly::load_and_swap( + membase_ + buffer_ptr + 0); // 0x00000002 + uint32_t unk1 = poly::load_and_swap(membase_ + buffer_ptr + + 4); // 0x00000003 + uint32_t unk_ptr = + poly::load_and_swap(membase_ + buffer_ptr + 8); + assert_true(xmp_client == 0x00000002); + // + break; } } - XELOGE("Unimplemented XMsg message app=%.8X, msg=%.8X, buffer=%.8X, len=%d", + XELOGE("Unimplemented XMsg message app=%.8X, msg=%.8X, arg1=%.8X, arg2=%.8X", app_id(), message, buffer_ptr, buffer_length); return X_ERROR_NOT_FOUND; } diff --git a/src/xenia/kernel/apps/xmp_app.h b/src/xenia/kernel/apps/xmp_app.h index b851ea5c2..a9fbe76b7 100644 --- a/src/xenia/kernel/apps/xmp_app.h +++ b/src/xenia/kernel/apps/xmp_app.h @@ -20,16 +20,38 @@ namespace apps { class XXMPApp : public XApp { public: - XXMPApp(KernelState* kernel_state) : XApp(kernel_state, 0xFA) {} + enum class Status : uint32_t { + kStopped = 0, + kPlaying = 1, + kPaused = 2, + }; - X_RESULT XMPGetStatus(uint32_t unk, uint32_t status_ptr); - X_RESULT XMPGetStatusEx(uint32_t unk, uint32_t unk_ptr, - uint32_t disabled_ptr); + XXMPApp(KernelState* kernel_state); - X_RESULT DispatchMessageSync(uint32_t message, uint32_t arg1, - uint32_t arg2) override; - X_RESULT DispatchMessageAsync(uint32_t message, uint32_t buffer_ptr, - size_t buffer_length) override; + X_RESULT XMPGetStatus(uint32_t status_ptr); + + X_RESULT XMPContinue(); + X_RESULT XMPStop(uint32_t unk); + X_RESULT XMPPause(); + X_RESULT XMPNext(); + X_RESULT XMPPrevious(); + + X_RESULT DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, + uint32_t buffer_length) override; + + private: + static const uint32_t kMsgStatusChanged = 0xA000001; + static const uint32_t kMsgStateChanged = 0xA000002; + static const uint32_t kMsgDisableChanged = 0xA000003; + + void OnStatusChanged(); + + Status status_; + uint32_t disabled_; + uint32_t unknown_state1_; + uint32_t unknown_state2_; + uint32_t unknown_flags_; + float unknown_float_; }; } // namespace apps From b6b27e621a44dba43e57e94270370ca04514cdb9 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 11 Jan 2015 00:28:24 -0800 Subject: [PATCH 346/388] Enough XMP to play (fake) play media. --- src/poly/memory.h | 14 + src/xenia/kernel/app.cc | 2 +- src/xenia/kernel/app.h | 2 +- src/xenia/kernel/apps/xmp_app.cc | 316 +++++++++++++++---- src/xenia/kernel/apps/xmp_app.h | 74 ++++- src/xenia/kernel/objects/xnotify_listener.cc | 2 +- 6 files changed, 343 insertions(+), 67 deletions(-) diff --git a/src/poly/memory.h b/src/poly/memory.h index 66918a0eb..c4e5b4b90 100644 --- a/src/poly/memory.h +++ b/src/poly/memory.h @@ -305,6 +305,20 @@ template <> inline void store_and_swap(void* mem, double value) { *reinterpret_cast(mem) = byte_swap(value); } +template <> +inline void store_and_swap(void* mem, std::string value) { + for (auto i = 0; i < value.size(); ++i) { + poly::store_and_swap(reinterpret_cast(mem) + i, + value[i]); + } +} +template <> +inline void store_and_swap(void* mem, std::wstring value) { + for (auto i = 0; i < value.size(); ++i) { + poly::store_and_swap(reinterpret_cast(mem) + i, + value[i]); + } +} template struct be { diff --git a/src/xenia/kernel/app.cc b/src/xenia/kernel/app.cc index bb2e5a1bc..3216a32fc 100644 --- a/src/xenia/kernel/app.cc +++ b/src/xenia/kernel/app.cc @@ -37,7 +37,7 @@ X_RESULT XAppManager::DispatchMessageSync(uint32_t app_id, uint32_t message, X_RESULT XAppManager::DispatchMessageAsync(uint32_t app_id, uint32_t message, uint32_t buffer_ptr, - size_t buffer_length) { + uint32_t buffer_length) { const auto& it = app_lookup_.find(app_id); if (it == app_lookup_.end()) { return X_ERROR_NOT_FOUND; diff --git a/src/xenia/kernel/app.h b/src/xenia/kernel/app.h index 3ff461cc0..1608a4162 100644 --- a/src/xenia/kernel/app.h +++ b/src/xenia/kernel/app.h @@ -44,7 +44,7 @@ class XAppManager { X_RESULT DispatchMessageSync(uint32_t app_id, uint32_t message, uint32_t buffer_ptr, uint32_t buffer_length); X_RESULT DispatchMessageAsync(uint32_t app_id, uint32_t message, - uint32_t buffer_ptr, size_t buffer_length); + uint32_t buffer_ptr, uint32_t buffer_length); private: std::vector> apps_; diff --git a/src/xenia/kernel/apps/xmp_app.cc b/src/xenia/kernel/apps/xmp_app.cc index 68a906e4a..3d04be800 100644 --- a/src/xenia/kernel/apps/xmp_app.cc +++ b/src/xenia/kernel/apps/xmp_app.cc @@ -9,81 +9,204 @@ #include +#include + namespace xe { namespace kernel { namespace apps { XXMPApp::XXMPApp(KernelState* kernel_state) : XApp(kernel_state, 0xFA), - status_(Status::kStopped), + state_(State::kIdle), disabled_(0), - unknown_state1_(0), - unknown_state2_(0), + playback_mode_(PlaybackMode::kUnknown), + repeat_mode_(RepeatMode::kUnknown), unknown_flags_(0), - unknown_float_(0.0f) {} + volume_(0.0f), + active_playlist_(nullptr), + active_song_index_(0), + next_playlist_handle_(1), + next_song_handle_(1) {} -X_RESULT XXMPApp::XMPGetStatus(uint32_t status_ptr) { +X_RESULT XXMPApp::XMPGetStatus(uint32_t state_ptr) { // Some stupid games will hammer this on a thread - induce a delay // here to keep from starving real threads. Sleep(1); - XELOGD("XMPGetStatus(%.8X)", status_ptr); - poly::store_and_swap(membase_ + status_ptr, - static_cast(status_)); - OnStatusChanged(); + XELOGD("XMPGetStatus(%.8X)", state_ptr); + poly::store_and_swap(membase_ + state_ptr, + static_cast(state_)); + return X_ERROR_SUCCESS; +} + +X_RESULT XXMPApp::XMPCreateTitlePlaylist( + uint32_t songs_ptr, uint32_t song_count, uint32_t playlist_name_ptr, + std::wstring playlist_name, uint32_t flags, uint32_t out_song_handles, + uint32_t out_playlist_handle) { + XELOGD("XMPCreateTitlePlaylist(%.8X, %.8X, %.8X(%s), %.8X, %.8X, %.8X)", + songs_ptr, song_count, playlist_name_ptr, + poly::to_string(playlist_name).c_str(), flags, out_song_handles, + out_playlist_handle); + auto playlist = std::make_unique(); + playlist->handle = ++next_playlist_handle_; + playlist->name = std::move(playlist_name); + playlist->flags = flags; + for (uint32_t i = 0; i < song_count; ++i) { + auto song = std::make_unique(); + song->handle = ++next_song_handle_; + uint8_t* song_base = membase_ + songs_ptr + (i * 36); + song->file_path = poly::load_and_swap( + membase_ + poly::load_and_swap(song_base + 0)); + song->name = poly::load_and_swap( + membase_ + poly::load_and_swap(song_base + 4)); + song->artist = poly::load_and_swap( + membase_ + poly::load_and_swap(song_base + 8)); + song->album = poly::load_and_swap( + membase_ + poly::load_and_swap(song_base + 12)); + song->album_artist = poly::load_and_swap( + membase_ + poly::load_and_swap(song_base + 16)); + song->genre = poly::load_and_swap( + membase_ + poly::load_and_swap(song_base + 20)); + song->track_number = poly::load_and_swap(song_base + 24); + song->duration_ms = poly::load_and_swap(song_base + 28); + song->format = static_cast( + poly::load_and_swap(song_base + 32)); + if (out_song_handles) { + poly::store_and_swap(membase_ + out_song_handles + (i * 4), + song->handle); + } + playlist->songs.emplace_back(std::move(song)); + } + poly::store_and_swap(membase_ + out_playlist_handle, + playlist->handle); + + std::lock_guard lock(mutex_); + playlists_.insert({playlist->handle, playlist.get()}); + playlist.release(); + return X_ERROR_SUCCESS; +} + +X_RESULT XXMPApp::XMPDeleteTitlePlaylist(uint32_t playlist_handle) { + XELOGD("XMPDeleteTitlePlaylist(%.8X)", playlist_handle); + std::lock_guard lock(mutex_); + auto it = playlists_.find(playlist_handle); + if (it == playlists_.end()) { + XELOGE("Playlist %.8X not found", playlist_handle); + return X_ERROR_NOT_FOUND; + } + auto playlist = it->second; + if (playlist == active_playlist_) { + XMPStop(0); + } + playlists_.erase(it); + delete playlist; + return X_ERROR_SUCCESS; +} + +X_RESULT XXMPApp::XMPPlayTitlePlaylist(uint32_t playlist_handle, + uint32_t song_handle) { + XELOGD("XMPPlayTitlePlaylist(%.8X, %.8X)", playlist_handle, song_handle); + Playlist* playlist = nullptr; + { + std::lock_guard lock(mutex_); + auto it = playlists_.find(playlist_handle); + if (it == playlists_.end()) { + XELOGE("Playlist %.8X not found", playlist_handle); + return X_ERROR_NOT_FOUND; + } + playlist = it->second; + } + + if (disabled_) { + // Ignored because we aren't enabled? + XELOGW("Ignoring XMPPlayTitlePlaylist because disabled"); + return X_ERROR_SUCCESS; + } + + // Start playlist? + XELOGW("Playlist playback not supported"); + active_playlist_ = playlist; + active_song_index_ = 0; + state_ = State::kPlaying; + OnStateChanged(); return X_ERROR_SUCCESS; } X_RESULT XXMPApp::XMPContinue() { XELOGD("XMPContinue()"); - if (status_ == Status::kPaused) { - status_ = Status::kPlaying; + if (state_ == State::kPaused) { + state_ = State::kPlaying; } - OnStatusChanged(); + OnStateChanged(); return X_ERROR_SUCCESS; } X_RESULT XXMPApp::XMPStop(uint32_t unk) { assert_zero(unk); XELOGD("XMPStop(%.8X)", unk); - status_ = Status::kStopped; - OnStatusChanged(); + active_playlist_ = nullptr; // ? + active_song_index_ = 0; + state_ = State::kIdle; + OnStateChanged(); return X_ERROR_SUCCESS; } X_RESULT XXMPApp::XMPPause() { XELOGD("XMPPause()"); - if (status_ == Status::kPlaying) { - status_ = Status::kPaused; + if (state_ == State::kPlaying) { + state_ = State::kPaused; } - OnStatusChanged(); + OnStateChanged(); return X_ERROR_SUCCESS; } X_RESULT XXMPApp::XMPNext() { XELOGD("XMPNext()"); - status_ = Status::kPlaying; - OnStatusChanged(); + if (!active_playlist_) { + return X_ERROR_NOT_FOUND; + } + state_ = State::kPlaying; + active_song_index_ = + (active_song_index_ + 1) % active_playlist_->songs.size(); + OnStateChanged(); return X_ERROR_SUCCESS; } X_RESULT XXMPApp::XMPPrevious() { XELOGD("XMPPrevious()"); - status_ = Status::kPlaying; - OnStatusChanged(); + if (!active_playlist_) { + return X_ERROR_NOT_FOUND; + } + state_ = State::kPlaying; + if (!active_song_index_) { + active_song_index_ = static_cast(active_playlist_->songs.size()) - 1; + } else { + --active_song_index_; + } + OnStateChanged(); return X_ERROR_SUCCESS; } -void XXMPApp::OnStatusChanged() { - kernel_state_->BroadcastNotification(kMsgStatusChanged, - static_cast(status_)); +void XXMPApp::OnStateChanged() { + kernel_state_->BroadcastNotification(kMsgStateChanged, + static_cast(state_)); } X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, uint32_t buffer_length) { // NOTE: buffer_length may be zero or valid. - // http://freestyledash.googlecode.com/svn-history/r1/trunk/Freestyle/Scenes/Media/Music/ScnMusic.cpp switch (message) { + case 0x00070002: { + assert_true(!buffer_length || buffer_length == 12); + uint32_t xmp_client = + poly::load_and_swap(membase_ + buffer_ptr + 0); + uint32_t playlist_handle = + poly::load_and_swap(membase_ + buffer_ptr + 4); + uint32_t song_handle = + poly::load_and_swap(membase_ + buffer_ptr + 8); // 0? + assert_true(xmp_client == 0x00000002); + return XMPPlayTitlePlaylist(playlist_handle, song_handle); + } case 0x00070003: { assert_true(!buffer_length || buffer_length == 4); uint32_t xmp_client = @@ -124,26 +247,29 @@ X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, assert_true(!buffer_length || buffer_length == 16); uint32_t xmp_client = poly::load_and_swap(membase_ + buffer_ptr + 0); - uint32_t unk1 = poly::load_and_swap(membase_ + buffer_ptr + 4); - uint32_t unk2 = poly::load_and_swap(membase_ + buffer_ptr + 8); + uint32_t playback_mode = + poly::load_and_swap(membase_ + buffer_ptr + 4); + uint32_t repeat_mode = + poly::load_and_swap(membase_ + buffer_ptr + 8); uint32_t flags = poly::load_and_swap(membase_ + buffer_ptr + 12); assert_true(xmp_client == 0x00000002); - XELOGD("XMPSetState?(%.8X, %.8X, %.8X)", unk1, unk2, flags); - unknown_state1_ = unk1; - unknown_state2_ = unk2; + XELOGD("XMPSetPlaybackBehavior(%.8X, %.8X, %.8X)", playback_mode, + repeat_mode, flags); + playback_mode_ = static_cast(playback_mode); + repeat_mode_ = static_cast(repeat_mode); unknown_flags_ = flags; - kernel_state_->BroadcastNotification(kMsgStateChanged, 0); + kernel_state_->BroadcastNotification(kMsgPlaybackBehaviorChanged, 0); return X_ERROR_SUCCESS; } case 0x00070009: { assert_true(!buffer_length || buffer_length == 8); uint32_t xmp_client = poly::load_and_swap(membase_ + buffer_ptr + 0); - uint32_t status_ptr = poly::load_and_swap( + uint32_t state_ptr = poly::load_and_swap( membase_ + buffer_ptr + 4); // out ptr to 4b - expect 0 assert_true(xmp_client == 0x00000002); - return XMPGetStatus(status_ptr); + return XMPGetStatus(state_ptr); } case 0x0007000B: { assert_true(!buffer_length || buffer_length == 8); @@ -152,8 +278,8 @@ X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, uint32_t float_ptr = poly::load_and_swap( membase_ + buffer_ptr + 4); // out ptr to 4b - floating point assert_true(xmp_client == 0x00000002); - XELOGD("XMPGetFloat?(%.8X)", float_ptr); - poly::store_and_swap(membase_ + float_ptr, unknown_float_); + XELOGD("XMPGetVolume(%.8X)", float_ptr); + poly::store_and_swap(membase_ + float_ptr, volume_); return X_ERROR_SUCCESS; } case 0x0007000C: { @@ -162,21 +288,96 @@ X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, poly::load_and_swap(membase_ + buffer_ptr + 0); float float_value = poly::load_and_swap(membase_ + buffer_ptr + 4); assert_true(xmp_client == 0x00000002); - XELOGD("XMPSetFloat?(%g)", float_value); - unknown_float_ = float_value; + XELOGD("XMPSetVolume(%g)", float_value); + volume_ = float_value; return X_ERROR_SUCCESS; } + case 0x0007000D: { + assert_true(!buffer_length || buffer_length == 36); + uint32_t xmp_client = + poly::load_and_swap(membase_ + buffer_ptr + 0); + uint32_t dummy_alloc_ptr = + poly::load_and_swap(membase_ + buffer_ptr + 4); + uint32_t dummy_alloc_size = + poly::load_and_swap(membase_ + buffer_ptr + 8); + uint32_t songs_ptr = + poly::load_and_swap(membase_ + buffer_ptr + 12); + uint32_t song_count = + poly::load_and_swap(membase_ + buffer_ptr + 16); + uint32_t playlist_name_ptr = + poly::load_and_swap(membase_ + buffer_ptr + 20); + uint32_t flags = + poly::load_and_swap(membase_ + buffer_ptr + 24); + uint32_t song_handles_ptr = + poly::load_and_swap(membase_ + buffer_ptr + 28); // 0? + uint32_t playlist_handle_ptr = + poly::load_and_swap(membase_ + buffer_ptr + 32); + assert_true(xmp_client == 0x00000002); + auto playlist_name = + poly::load_and_swap(membase_ + playlist_name_ptr); + // dummy_alloc_ptr is the result of a XamAlloc of dummy_alloc_size. + assert_true(dummy_alloc_size == song_count * 128); + return XMPCreateTitlePlaylist(songs_ptr, song_count, playlist_name_ptr, + playlist_name, flags, song_handles_ptr, + playlist_handle_ptr); + } + case 0x0007000E: { + assert_true(!buffer_length || buffer_length == 12); + uint32_t xmp_client = + poly::load_and_swap(membase_ + buffer_ptr + 0); + uint32_t unk_ptr = + poly::load_and_swap(membase_ + buffer_ptr + 4); // 0 + uint32_t info_ptr = + poly::load_and_swap(membase_ + buffer_ptr + 8); + assert_true(xmp_client == 0x00000002); + assert_zero(unk_ptr); + XELOGE("XMPGetInfo?(%.8X, %.8X)", unk_ptr, info_ptr); + if (!active_playlist_) { + return X_ERROR_NOT_FOUND; + } + auto& song = active_playlist_->songs[active_song_index_]; + poly::store_and_swap(membase_ + info_ptr + 0, song->handle); + poly::store_and_swap(membase_ + info_ptr + 4 + 572 + 0, + song->name); + poly::store_and_swap(membase_ + info_ptr + 4 + 572 + 40, + song->artist); + poly::store_and_swap(membase_ + info_ptr + 4 + 572 + 80, + song->album); + poly::store_and_swap(membase_ + info_ptr + 4 + 572 + 120, + song->album_artist); + poly::store_and_swap(membase_ + info_ptr + 4 + 572 + 160, + song->genre); + poly::store_and_swap(membase_ + info_ptr + 4 + 572 + 200, + song->track_number); + poly::store_and_swap(membase_ + info_ptr + 4 + 572 + 204, + song->duration_ms); + poly::store_and_swap(membase_ + info_ptr + 4 + 572 + 208, + static_cast(song->format)); + return X_ERROR_SUCCESS; + } + case 0x00070013: { + assert_true(!buffer_length || buffer_length == 8); + uint32_t xmp_client = + poly::load_and_swap(membase_ + buffer_ptr + 0); + uint32_t playlist_handle = + poly::load_and_swap(membase_ + buffer_ptr + 4); + assert_true(xmp_client == 0x00000002); + return XMPDeleteTitlePlaylist(playlist_handle); + } case 0x0007001A: { assert_true(!buffer_length || buffer_length == 12); uint32_t xmp_client = poly::load_and_swap(membase_ + buffer_ptr + 0); uint32_t unk1 = poly::load_and_swap(membase_ + buffer_ptr + 4); - uint32_t disabled = + uint32_t enabled = poly::load_and_swap(membase_ + buffer_ptr + 8); assert_true(xmp_client == 0x00000002); assert_zero(unk1); - XELOGD("XMPSetDisabled(%.8X, %.8X)", unk1, disabled); - disabled_ = disabled; + XELOGD("XMPSetEnabled(%.8X, %.8X)", unk1, enabled); + disabled_ = enabled; + if (disabled_) { + XMPStop(0); + } kernel_state_->BroadcastNotification(kMsgDisableChanged, disabled_); return X_ERROR_SUCCESS; } @@ -189,40 +390,47 @@ X_RESULT XXMPApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, uint32_t disabled_ptr = poly::load_and_swap( membase_ + buffer_ptr + 8); // out ptr to 4b - expect 1 (to skip) assert_true(xmp_client == 0x00000002); - XELOGD("XMPGetDisabled(%.8X, %.8X)", unk_ptr, disabled_ptr); + XELOGD("XMPGetEnabled(%.8X, %.8X)", unk_ptr, disabled_ptr); poly::store_and_swap(membase_ + unk_ptr, 0); poly::store_and_swap(membase_ + disabled_ptr, disabled_); + // Atrain spawns a thread 82437FD0 to call this in a tight loop forever. + poly::threading::Sleep(std::chrono::milliseconds(10)); return X_ERROR_SUCCESS; } case 0x00070029: { assert_true(!buffer_length || buffer_length == 16); uint32_t xmp_client = poly::load_and_swap(membase_ + buffer_ptr + 0); - uint32_t unk1_ptr = + uint32_t playback_mode_ptr = poly::load_and_swap(membase_ + buffer_ptr + 4); - uint32_t unk2_ptr = + uint32_t repeat_mode_ptr = poly::load_and_swap(membase_ + buffer_ptr + 8); uint32_t unk3_ptr = poly::load_and_swap(membase_ + buffer_ptr + 12); assert_true(xmp_client == 0x00000002); - XELOGD("XMPGetState?(%.8X, %.8X, %.8X)", unk1_ptr, unk2_ptr, unk3_ptr); - poly::store_and_swap(membase_ + unk1_ptr, unknown_state1_); - poly::store_and_swap(membase_ + unk2_ptr, unknown_state2_); + XELOGD("XMPGetPlaybackBehavior(%.8X, %.8X, %.8X)", playback_mode_ptr, + repeat_mode_ptr, unk3_ptr); + poly::store_and_swap(membase_ + playback_mode_ptr, + static_cast(playback_mode_)); + poly::store_and_swap(membase_ + repeat_mode_ptr, + static_cast(repeat_mode_)); poly::store_and_swap(membase_ + unk3_ptr, unknown_flags_); return X_ERROR_SUCCESS; } case 0x0007002E: { assert_true(!buffer_length || buffer_length == 12); - // 00000002 00000003 20049ce0 - uint32_t xmp_client = poly::load_and_swap( - membase_ + buffer_ptr + 0); // 0x00000002 - uint32_t unk1 = poly::load_and_swap(membase_ + buffer_ptr + - 4); // 0x00000003 - uint32_t unk_ptr = + // Query of size for XamAlloc - the result of the alloc is passed to + // 0x0007000D. + uint32_t xmp_client = + poly::load_and_swap(membase_ + buffer_ptr + 0); + uint32_t song_count = + poly::load_and_swap(membase_ + buffer_ptr + 4); + uint32_t size_ptr = poly::load_and_swap(membase_ + buffer_ptr + 8); assert_true(xmp_client == 0x00000002); - // - break; + // We don't use the storage, so just fudge the number. + poly::store_and_swap(membase_ + size_ptr, song_count * 128); + return X_ERROR_SUCCESS; } } XELOGE("Unimplemented XMsg message app=%.8X, msg=%.8X, arg1=%.8X, arg2=%.8X", diff --git a/src/xenia/kernel/apps/xmp_app.h b/src/xenia/kernel/apps/xmp_app.h index a9fbe76b7..0b1658f17 100644 --- a/src/xenia/kernel/apps/xmp_app.h +++ b/src/xenia/kernel/apps/xmp_app.h @@ -10,6 +10,12 @@ #ifndef XENIA_KERNEL_XBOXKRNL_APPS_XMP_APP_H_ #define XENIA_KERNEL_XBOXKRNL_APPS_XMP_APP_H_ +#include +#include +#include +#include +#include + #include #include #include @@ -18,18 +24,59 @@ namespace xe { namespace kernel { namespace apps { +// Only source of docs for a lot of these functions: +// http://freestyledash.googlecode.com/svn-history/r1/trunk/Freestyle/Scenes/Media/Music/ScnMusic.cpp + class XXMPApp : public XApp { public: - enum class Status : uint32_t { - kStopped = 0, + enum class State : uint32_t { + kIdle = 0, kPlaying = 1, kPaused = 2, }; + enum class PlaybackMode : uint32_t { + // kInOrder = ?, + kUnknown = 0, + }; + enum class RepeatMode : uint32_t { + // kNoRepeat = ?, + kUnknown = 0, + }; + struct Song { + enum class Format : uint32_t { + kWma = 0, + kMp3 = 1, + }; + + uint32_t handle; + std::wstring file_path; + std::wstring name; + std::wstring artist; + std::wstring album; + std::wstring album_artist; + std::wstring genre; + uint32_t track_number; + uint32_t duration_ms; + Format format; + }; + struct Playlist { + uint32_t handle; + std::wstring name; + uint32_t flags; + std::vector> songs; + }; XXMPApp(KernelState* kernel_state); X_RESULT XMPGetStatus(uint32_t status_ptr); + X_RESULT XMPCreateTitlePlaylist(uint32_t songs_ptr, uint32_t song_count, + uint32_t playlist_name_ptr, + std::wstring playlist_name, uint32_t flags, + uint32_t out_song_handles, + uint32_t out_playlist_handle); + X_RESULT XMPDeleteTitlePlaylist(uint32_t playlist_handle); + X_RESULT XMPPlayTitlePlaylist(uint32_t playlist_handle, uint32_t song_handle); X_RESULT XMPContinue(); X_RESULT XMPStop(uint32_t unk); X_RESULT XMPPause(); @@ -40,18 +87,25 @@ class XXMPApp : public XApp { uint32_t buffer_length) override; private: - static const uint32_t kMsgStatusChanged = 0xA000001; - static const uint32_t kMsgStateChanged = 0xA000002; - static const uint32_t kMsgDisableChanged = 0xA000003; + static const uint32_t kMsgStateChanged = 0x0A000001; + static const uint32_t kMsgPlaybackBehaviorChanged = 0x0A000002; + static const uint32_t kMsgDisableChanged = 0x0A000003; - void OnStatusChanged(); + void OnStateChanged(); - Status status_; + State state_; uint32_t disabled_; - uint32_t unknown_state1_; - uint32_t unknown_state2_; + PlaybackMode playback_mode_; + RepeatMode repeat_mode_; uint32_t unknown_flags_; - float unknown_float_; + float volume_; + Playlist* active_playlist_; + int active_song_index_; + + std::mutex mutex_; + std::unordered_map playlists_; + uint32_t next_playlist_handle_; + uint32_t next_song_handle_; }; } // namespace apps diff --git a/src/xenia/kernel/objects/xnotify_listener.cc b/src/xenia/kernel/objects/xnotify_listener.cc index 738a5440d..8825de59d 100644 --- a/src/xenia/kernel/objects/xnotify_listener.cc +++ b/src/xenia/kernel/objects/xnotify_listener.cc @@ -36,7 +36,7 @@ void XNotifyListener::Initialize(uint64_t mask) { void XNotifyListener::EnqueueNotification(XNotificationID id, uint32_t data) { // Ignore if the notification doesn't match our mask. - if ((mask_ & uint64_t(1 << ((id >> 25) + 1))) == 0) { + if ((mask_ & uint64_t(1 << (id >> 25))) == 0) { return; } From 5827f5f5d82b321b6952e8203c2cc2e38bade055 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 11 Jan 2015 00:44:17 -0800 Subject: [PATCH 347/388] Utility to dump instruction translation counts. --- src/alloy/frontend/ppc/ppc_hir_builder.cc | 1 + src/alloy/frontend/ppc/ppc_instr.cc | 49 +++++++++++++---------- src/alloy/frontend/ppc/ppc_instr.h | 2 + src/alloy/frontend/ppc/ppc_instr_tables.h | 4 +- src/alloy/frontend/ppc/ppc_translator.cc | 4 ++ 5 files changed, 37 insertions(+), 23 deletions(-) diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index cdf6f0230..06294a54c 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -122,6 +122,7 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) { // TraceInvalidInstruction(i); continue; } + ++i.type->translation_count; typedef int (*InstrEmitter)(PPCHIRBuilder& f, InstrData& i); InstrEmitter emit = (InstrEmitter)i.type->emit; diff --git a/src/alloy/frontend/ppc/ppc_instr.cc b/src/alloy/frontend/ppc/ppc_instr.cc index c90c46a37..04da51c9a 100644 --- a/src/alloy/frontend/ppc/ppc_instr.cc +++ b/src/alloy/frontend/ppc/ppc_instr.cc @@ -10,14 +10,30 @@ #include #include +#include #include +#include #include namespace alloy { namespace frontend { namespace ppc { +std::vector all_instrs_; + +void DumpAllInstrCounts() { + StringBuffer sb; + sb.Append("Instruction translation counts:\n"); + for (auto instr_type : all_instrs_) { + if (instr_type->translation_count) { + sb.Append("%8d : %s\n", instr_type->translation_count, instr_type->name); + } + } + fprintf(stdout, sb.GetString()); + fflush(stdout); +} + void InstrOperand::Dump(std::string& out_str) { if (display) { out_str += display; @@ -322,48 +338,39 @@ InstrType* GetInstrType(uint32_t code) { switch (code >> 26) { case 4: // Opcode = 4, index = bits 10-0 (10) - slot = - alloy::frontend::ppc::tables::instr_table_4[select_bits(code, 0, 10)]; + slot = tables::instr_table_4[select_bits(code, 0, 10)]; break; case 19: // Opcode = 19, index = bits 10-1 (10) - slot = alloy::frontend::ppc::tables::instr_table_19[select_bits(code, 1, - 10)]; + slot = tables::instr_table_19[select_bits(code, 1, 10)]; break; case 30: // Opcode = 30, index = bits 4-1 (4) // Special cased to an uber instruction. - slot = - alloy::frontend::ppc::tables::instr_table_30[select_bits(code, 0, 0)]; + slot = tables::instr_table_30[select_bits(code, 0, 0)]; break; case 31: // Opcode = 31, index = bits 10-1 (10) - slot = alloy::frontend::ppc::tables::instr_table_31[select_bits(code, 1, - 10)]; + slot = tables::instr_table_31[select_bits(code, 1, 10)]; break; case 58: // Opcode = 58, index = bits 1-0 (2) - slot = - alloy::frontend::ppc::tables::instr_table_58[select_bits(code, 0, 1)]; + slot = tables::instr_table_58[select_bits(code, 0, 1)]; break; case 59: // Opcode = 59, index = bits 5-1 (5) - slot = - alloy::frontend::ppc::tables::instr_table_59[select_bits(code, 1, 5)]; + slot = tables::instr_table_59[select_bits(code, 1, 5)]; break; case 62: // Opcode = 62, index = bits 1-0 (2) - slot = - alloy::frontend::ppc::tables::instr_table_62[select_bits(code, 0, 1)]; + slot = tables::instr_table_62[select_bits(code, 0, 1)]; break; case 63: // Opcode = 63, index = bits 10-1 (10) - slot = alloy::frontend::ppc::tables::instr_table_63[select_bits(code, 1, - 10)]; + slot = tables::instr_table_63[select_bits(code, 1, 10)]; break; default: - slot = - alloy::frontend::ppc::tables::instr_table[select_bits(code, 26, 31)]; + slot = tables::instr_table[select_bits(code, 26, 31)]; break; } if (slot && slot->opcode) { @@ -372,9 +379,8 @@ InstrType* GetInstrType(uint32_t code) { // Slow lookup via linear scan. // This is primarily due to laziness. It could be made fast like the others. - for (size_t n = 0; - n < poly::countof(alloy::frontend::ppc::tables::instr_table_scan); n++) { - slot = &(alloy::frontend::ppc::tables::instr_table_scan[n]); + for (size_t n = 0; n < poly::countof(tables::instr_table_scan); n++) { + slot = &(tables::instr_table_scan[n]); if (slot->opcode == (code & slot->opcode_mask)) { return slot; } @@ -389,6 +395,7 @@ int RegisterInstrEmit(uint32_t code, InstrEmitFn emit) { if (!instr_type) { return 1; } + all_instrs_.push_back(instr_type); assert_null(instr_type->emit); instr_type->emit = emit; return 0; diff --git a/src/alloy/frontend/ppc/ppc_instr.h b/src/alloy/frontend/ppc/ppc_instr.h index 96575a2c4..709d552c1 100644 --- a/src/alloy/frontend/ppc/ppc_instr.h +++ b/src/alloy/frontend/ppc/ppc_instr.h @@ -561,10 +561,12 @@ class InstrType { uint32_t flags; // xe_ppc_instr_flag_e InstrDisasmFn disasm; char name[16]; + uint32_t translation_count; InstrEmitFn emit; }; +void DumpAllInstrCounts(); InstrType* GetInstrType(uint32_t code); int RegisterInstrEmit(uint32_t code, InstrEmitFn emit); diff --git a/src/alloy/frontend/ppc/ppc_instr_tables.h b/src/alloy/frontend/ppc/ppc_instr_tables.h index 15819efc2..dec760993 100644 --- a/src/alloy/frontend/ppc/ppc_instr_tables.h +++ b/src/alloy/frontend/ppc/ppc_instr_tables.h @@ -127,7 +127,7 @@ static InstrType** instr_table_prep_63(InstrType* unprep, size_t unprep_count, #define INSTRUCTION(name, opcode, format, type, disasm_fn, descr) \ { \ opcode, 0, kXEPPCInstrFormat##format, kXEPPCInstrType##type, 0, \ - Disasm_##disasm_fn, #name, \ + Disasm_##disasm_fn, #name, 0, \ } #define FLAG(t) kXEPPCInstrFlag##t @@ -844,7 +844,7 @@ static InstrType** instr_table = instr_table_prep( #define SCAN_INSTRUCTION(name, opcode, format, type, disasm_fn, descr) \ { \ opcode, kXEPPCInstrMask##format, kXEPPCInstrFormat##format, \ - kXEPPCInstrType##type, 0, Disasm_##disasm_fn, #name, \ + kXEPPCInstrType##type, 0, Disasm_##disasm_fn, #name, 0, \ } #define OP(x) ((((uint32_t)(x)) & 0x3f) << 26) #define VX128(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x3d0)) diff --git a/src/alloy/frontend/ppc/ppc_translator.cc b/src/alloy/frontend/ppc/ppc_translator.cc index 008ba8948..1b21c386d 100644 --- a/src/alloy/frontend/ppc/ppc_translator.cc +++ b/src/alloy/frontend/ppc/ppc_translator.cc @@ -124,6 +124,10 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info, string_buffer_.Reset(); } + if (false) { + alloy::frontend::ppc::DumpAllInstrCounts(); + } + // Emit function. uint32_t emit_flags = 0; if (debug_info) { From ffe9fad6857039b242c0387fccfaebedb73822e8 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 11 Jan 2015 13:11:13 -0800 Subject: [PATCH 348/388] Minor tweaks while reviewing instructions. --- src/alloy/backend/x64/x64_sequences.cc | 2 ++ src/alloy/frontend/ppc/ppc_emit_alu.cc | 9 ++++----- src/alloy/frontend/ppc/ppc_emit_fpu.cc | 3 +++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index 8a1467a43..81803d8c2 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -2893,6 +2893,8 @@ EMITTER(VECTOR_ADD, MATCH(I, V128<>, V128<>>)){ } break; case FLOAT32_TYPE: + assert_false(is_unsigned); + assert_false(saturate); e.vaddps(dest, src1, src2); break; default: assert_unhandled_case(part_type); break; diff --git a/src/alloy/frontend/ppc/ppc_emit_alu.cc b/src/alloy/frontend/ppc/ppc_emit_alu.cc index 93d1b4156..94af993ba 100644 --- a/src/alloy/frontend/ppc/ppc_emit_alu.cc +++ b/src/alloy/frontend/ppc/ppc_emit_alu.cc @@ -365,9 +365,9 @@ XEEMITTER(mullwx, 0x7C0001D6, XO)(PPCHIRBuilder& f, InstrData& i) { XEINSTRNOTIMPLEMENTED(); return 1; } - Value* v = f.Mul( - f.SignExtend(f.Truncate(f.LoadGPR(i.XO.RA), INT32_TYPE), INT64_TYPE), - f.SignExtend(f.Truncate(f.LoadGPR(i.XO.RB), INT32_TYPE), INT64_TYPE)); + Value* v = f.SignExtend(f.Mul(f.Truncate(f.LoadGPR(i.XO.RA), INT32_TYPE), + f.Truncate(f.LoadGPR(i.XO.RB), INT32_TYPE)), + INT64_TYPE); f.StoreGPR(i.XO.RT, v); if (i.XO.Rc) { f.UpdateCR(0, v); @@ -743,8 +743,7 @@ XEEMITTER(nandx, 0x7C0003B8, X)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(norx, 0x7C0000F8, X)(PPCHIRBuilder& f, InstrData& i) { // RA <- ¬((RS) | (RB)) - Value* ra = f.Or(f.LoadGPR(i.X.RT), f.LoadGPR(i.X.RB)); - ra = f.Not(ra); + Value* ra = f.Not(f.Or(f.LoadGPR(i.X.RT), f.LoadGPR(i.X.RB))); f.StoreGPR(i.X.RA, ra); if (i.X.Rc) { f.UpdateCR(0, ra); diff --git a/src/alloy/frontend/ppc/ppc_emit_fpu.cc b/src/alloy/frontend/ppc/ppc_emit_fpu.cc index 43945f8af..750054347 100644 --- a/src/alloy/frontend/ppc/ppc_emit_fpu.cc +++ b/src/alloy/frontend/ppc/ppc_emit_fpu.cc @@ -454,6 +454,9 @@ XEEMITTER(mtfsfx, 0xFC00058E, XFL)(PPCHIRBuilder& f, InstrData& i) { return 1; } else { // Directly store. + // TODO(benvanik): use w/field mask to select bits. + i.XFL.W; + i.XFL.FM; f.StoreFPSCR(f.Cast(f.LoadFPR(i.XFL.RB), INT64_TYPE)); } return 0; From f2100a78bca866c4082c97e08d59f492085c2eb0 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 11 Jan 2015 13:11:31 -0800 Subject: [PATCH 349/388] vrfin test. --- src/alloy/frontend/ppc/test/bin/instr_vrfin.bin | Bin 0 -> 16 bytes src/alloy/frontend/ppc/test/bin/instr_vrfin.dis | 13 +++++++++++++ src/alloy/frontend/ppc/test/bin/instr_vrfin.map | 2 ++ src/alloy/frontend/ppc/test/instr_vrfin.s | 13 +++++++++++++ 4 files changed, 28 insertions(+) create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vrfin.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vrfin.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vrfin.map create mode 100644 src/alloy/frontend/ppc/test/instr_vrfin.s diff --git a/src/alloy/frontend/ppc/test/bin/instr_vrfin.bin b/src/alloy/frontend/ppc/test/bin/instr_vrfin.bin new file mode 100644 index 0000000000000000000000000000000000000000..c236bb45d332c6fa4f9126ffd4a5b8cfeb9b5dcb GIT binary patch literal 16 RcmWegkmB-dU{DZ%(f}E(0|fv8 literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vrfin.dis b/src/alloy/frontend/ppc/test/bin/instr_vrfin.dis new file mode 100644 index 000000000..3d7f0a2cd --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vrfin.dis @@ -0,0 +1,13 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vrfin.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 60 1a 0a vrfin v3,v3 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 10 60 1a 0a vrfin v3,v3 + 10000c: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vrfin.map b/src/alloy/frontend/ppc/test/bin/instr_vrfin.map new file mode 100644 index 000000000..42705011b --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vrfin.map @@ -0,0 +1,2 @@ +0000000000000000 t test_vrfin_1 +0000000000000008 t test_vrfin_2 diff --git a/src/alloy/frontend/ppc/test/instr_vrfin.s b/src/alloy/frontend/ppc/test/instr_vrfin.s new file mode 100644 index 000000000..cf31be55e --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vrfin.s @@ -0,0 +1,13 @@ +test_vrfin_1: + #_ REGISTER_IN v3 [3f800000, 3fc00000, 3f8ccccd, 3ff33333] + # 1.0, 1.5, 1.1, 1.9 -> 1.0, 2.0, 1.0, 2.0 + vrfin v3, v3 + blr + #_ REGISTER_OUT v3 [3f800000, 40000000, 3f800000, 40000000] + +test_vrfin_2: + #_ REGISTER_IN v3 [bf800000, bfc00000, bf8ccccd, bff33333] + # -1.0, -1.5, -1.1, -1.9 -> -1.0, -2.0, -1.0, -2.0 + vrfin v3, v3 + blr + #_ REGISTER_OUT v3 [bf800000, c0000000, bf800000, c0000000] From 338b5809b4e16fd52a5e3d5a78aa869934889f81 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 11 Jan 2015 14:48:51 -0800 Subject: [PATCH 350/388] vsl[bhw] tests. --- .../frontend/ppc/test/bin/instr_vslb.bin | Bin 0 -> 40 bytes .../frontend/ppc/test/bin/instr_vslb.dis | 25 ++++++++++ .../frontend/ppc/test/bin/instr_vslb.map | 5 ++ .../frontend/ppc/test/bin/instr_vslh.bin | Bin 0 -> 48 bytes .../frontend/ppc/test/bin/instr_vslh.dis | 29 +++++++++++ .../frontend/ppc/test/bin/instr_vslh.map | 6 +++ .../frontend/ppc/test/bin/instr_vslw.bin | Bin 0 -> 48 bytes .../frontend/ppc/test/bin/instr_vslw.dis | 29 +++++++++++ .../frontend/ppc/test/bin/instr_vslw.map | 6 +++ src/alloy/frontend/ppc/test/instr_vslb.s | 39 +++++++++++++++ src/alloy/frontend/ppc/test/instr_vslh.s | 47 ++++++++++++++++++ src/alloy/frontend/ppc/test/instr_vslw.s | 47 ++++++++++++++++++ 12 files changed, 233 insertions(+) create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vslb.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vslb.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vslb.map create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vslh.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vslh.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vslh.map create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vslw.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vslw.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vslw.map create mode 100644 src/alloy/frontend/ppc/test/instr_vslb.s create mode 100644 src/alloy/frontend/ppc/test/instr_vslh.s create mode 100644 src/alloy/frontend/ppc/test/instr_vslw.s diff --git a/src/alloy/frontend/ppc/test/bin/instr_vslb.bin b/src/alloy/frontend/ppc/test/bin/instr_vslb.bin new file mode 100644 index 0000000000000000000000000000000000000000..f67219f0fa420ede645017c562cee174c0185759 GIT binary patch literal 40 ScmWegR%G#OU{DYsKm!1riwB: + 100000: 10 63 21 04 vslb v3,v3,v4 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 10 63 21 04 vslb v3,v3,v4 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: 10 63 21 04 vslb v3,v3,v4 + 100014: 4e 80 00 20 blr + +0000000000100018 : + 100018: 10 63 21 04 vslb v3,v3,v4 + 10001c: 4e 80 00 20 blr + +0000000000100020 : + 100020: 10 63 21 04 vslb v3,v3,v4 + 100024: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vslb.map b/src/alloy/frontend/ppc/test/bin/instr_vslb.map new file mode 100644 index 000000000..50b022f8a --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vslb.map @@ -0,0 +1,5 @@ +0000000000000000 t test_vslb_1 +0000000000000008 t test_vslb_2 +0000000000000010 t test_vslb_3 +0000000000000018 t test_vslb_4 +0000000000000020 t test_vslb_5 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vslh.bin b/src/alloy/frontend/ppc/test/bin/instr_vslh.bin new file mode 100644 index 0000000000000000000000000000000000000000..ea30d6291a4ab28de17d6c96e05c4460f27d340f GIT binary patch literal 48 ScmWegR&?=eU{DYsk_G?;`3j`~ literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vslh.dis b/src/alloy/frontend/ppc/test/bin/instr_vslh.dis new file mode 100644 index 000000000..45b8e7e75 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vslh.dis @@ -0,0 +1,29 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vslh.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 63 21 44 vslh v3,v3,v4 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 10 63 21 44 vslh v3,v3,v4 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: 10 63 21 44 vslh v3,v3,v4 + 100014: 4e 80 00 20 blr + +0000000000100018 : + 100018: 10 63 21 44 vslh v3,v3,v4 + 10001c: 4e 80 00 20 blr + +0000000000100020 : + 100020: 10 63 21 44 vslh v3,v3,v4 + 100024: 4e 80 00 20 blr + +0000000000100028 : + 100028: 10 63 21 44 vslh v3,v3,v4 + 10002c: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vslh.map b/src/alloy/frontend/ppc/test/bin/instr_vslh.map new file mode 100644 index 000000000..7d334c1ae --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vslh.map @@ -0,0 +1,6 @@ +0000000000000000 t test_vslh_1 +0000000000000008 t test_vslh_2 +0000000000000010 t test_vslh_3 +0000000000000018 t test_vslh_4 +0000000000000020 t test_vslh_5 +0000000000000028 t test_vslh_6 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vslw.bin b/src/alloy/frontend/ppc/test/bin/instr_vslw.bin new file mode 100644 index 0000000000000000000000000000000000000000..fc509af2ba866b05dce70e9168e310401165f850 GIT binary patch literal 48 ScmWegR&4QWU{DYsk_G@Pc?=~0 literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vslw.dis b/src/alloy/frontend/ppc/test/bin/instr_vslw.dis new file mode 100644 index 000000000..711653586 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vslw.dis @@ -0,0 +1,29 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vslw.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 63 21 84 vslw v3,v3,v4 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 10 63 21 84 vslw v3,v3,v4 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: 10 63 21 84 vslw v3,v3,v4 + 100014: 4e 80 00 20 blr + +0000000000100018 : + 100018: 10 63 21 84 vslw v3,v3,v4 + 10001c: 4e 80 00 20 blr + +0000000000100020 : + 100020: 10 63 21 84 vslw v3,v3,v4 + 100024: 4e 80 00 20 blr + +0000000000100028 : + 100028: 10 63 21 84 vslw v3,v3,v4 + 10002c: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vslw.map b/src/alloy/frontend/ppc/test/bin/instr_vslw.map new file mode 100644 index 000000000..39c2633d5 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vslw.map @@ -0,0 +1,6 @@ +0000000000000000 t test_vslw_1 +0000000000000008 t test_vslw_2 +0000000000000010 t test_vslw_3 +0000000000000018 t test_vslw_4 +0000000000000020 t test_vslw_5 +0000000000000028 t test_vslw_6 diff --git a/src/alloy/frontend/ppc/test/instr_vslb.s b/src/alloy/frontend/ppc/test/instr_vslb.s new file mode 100644 index 000000000..818f1d2de --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vslb.s @@ -0,0 +1,39 @@ +test_vslb_1: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00000000, 00000000, 00000000, 00000000] + vslb v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_OUT v4 [00000000, 00000000, 00000000, 00000000] + +test_vslb_2: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [01010101, 01010101, 01010101, 01010101] + vslb v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FEFEFEFE, FEFEFEFE, FEFEFEFE, FEFEFEFE] + #_ REGISTER_OUT v4 [01010101, 01010101, 01010101, 01010101] + +test_vslb_3: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [07070707, 07070707, 07070707, 07070707] + vslb v3, v3, v4 + blr + #_ REGISTER_OUT v3 [80808080, 80808080, 80808080, 80808080] + #_ REGISTER_OUT v4 [07070707, 07070707, 07070707, 07070707] + +test_vslb_4: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [08080808, 08080808, 08080808, 08080808] + vslb v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_OUT v4 [08080808, 08080808, 08080808, 08080808] + +test_vslb_5: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [09090909, 09090909, 09090909, 09090909] + vslb v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FEFEFEFE, FEFEFEFE, FEFEFEFE, FEFEFEFE] + #_ REGISTER_OUT v4 [09090909, 09090909, 09090909, 09090909] diff --git a/src/alloy/frontend/ppc/test/instr_vslh.s b/src/alloy/frontend/ppc/test/instr_vslh.s new file mode 100644 index 000000000..d29d66667 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vslh.s @@ -0,0 +1,47 @@ +test_vslh_1: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00000000, 00000000, 00000000, 00000000] + vslh v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_OUT v4 [00000000, 00000000, 00000000, 00000000] + +test_vslh_2: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00010001, 00010001, 00010001, 00010001] + vslh v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFEFFFE, FFFEFFFE, FFFEFFFE, FFFEFFFE] + #_ REGISTER_OUT v4 [00010001, 00010001, 00010001, 00010001] + +test_vslh_3: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [000F000F, 000F000F, 000F000F, 000F000F] + vslh v3, v3, v4 + blr + #_ REGISTER_OUT v3 [80008000, 80008000, 80008000, 80008000] + #_ REGISTER_OUT v4 [000F000F, 000F000F, 000F000F, 000F000F] + +test_vslh_4: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00100010, 00100010, 00100010, 00100010] + vslh v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_OUT v4 [00100010, 00100010, 00100010, 00100010] + +test_vslh_5: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00090009, 00090009, 00090009, 00090009] + vslh v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FE00FE00, FE00FE00, FE00FE00, FE00FE00] + #_ REGISTER_OUT v4 [00090009, 00090009, 00090009, 00090009] + +test_vslh_6: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00110011, 00110011, 00110011, 00110011] + vslh v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFEFFFE, FFFEFFFE, FFFEFFFE, FFFEFFFE] + #_ REGISTER_OUT v4 [00110011, 00110011, 00110011, 00110011] diff --git a/src/alloy/frontend/ppc/test/instr_vslw.s b/src/alloy/frontend/ppc/test/instr_vslw.s new file mode 100644 index 000000000..89013eee4 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vslw.s @@ -0,0 +1,47 @@ +test_vslw_1: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00000000, 00000000, 00000000, 00000000] + vslw v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_OUT v4 [00000000, 00000000, 00000000, 00000000] + +test_vslw_2: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00000001, 00000001, 00000001, 00000001] + vslw v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFE, FFFFFFFE, FFFFFFFE, FFFFFFFE] + #_ REGISTER_OUT v4 [00000001, 00000001, 00000001, 00000001] + +test_vslw_3: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [0000001F, 0000001F, 0000001F, 0000001F] + vslw v3, v3, v4 + blr + #_ REGISTER_OUT v3 [80000000, 80000000, 80000000, 80000000] + #_ REGISTER_OUT v4 [0000001F, 0000001F, 0000001F, 0000001F] + +test_vslw_4: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00000020, 00000020, 00000020, 00000020] + vslw v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_OUT v4 [00000020, 00000020, 00000020, 00000020] + +test_vslw_5: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00000009, 00000009, 00000009, 00000009] + vslw v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFE00, FFFFFE00, FFFFFE00, FFFFFE00] + #_ REGISTER_OUT v4 [00000009, 00000009, 00000009, 00000009] + +test_vslw_6: + #_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + #_ REGISTER_IN v4 [00000021, 00000021, 00000021, 00000021] + vslw v3, v3, v4 + blr + #_ REGISTER_OUT v3 [FFFFFFFE, FFFFFFFE, FFFFFFFE, FFFFFFFE] + #_ REGISTER_OUT v4 [00000021, 00000021, 00000021, 00000021] From aacb51503504982ee4da7b9255de6d34f9966dce Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 11 Jan 2015 14:58:05 -0800 Subject: [PATCH 351/388] vsplt[bhw] tests. --- .../frontend/ppc/test/bin/instr_vspltb.bin | Bin 0 -> 24 bytes .../frontend/ppc/test/bin/instr_vspltb.dis | 17 +++++++++++++++ .../frontend/ppc/test/bin/instr_vspltb.map | 3 +++ .../frontend/ppc/test/bin/instr_vsplth.bin | Bin 0 -> 24 bytes .../frontend/ppc/test/bin/instr_vsplth.dis | 17 +++++++++++++++ .../frontend/ppc/test/bin/instr_vsplth.map | 3 +++ .../frontend/ppc/test/bin/instr_vspltw.bin | Bin 0 -> 24 bytes .../frontend/ppc/test/bin/instr_vspltw.dis | 17 +++++++++++++++ .../frontend/ppc/test/bin/instr_vspltw.map | 3 +++ src/alloy/frontend/ppc/test/instr_vspltb.s | 20 ++++++++++++++++++ src/alloy/frontend/ppc/test/instr_vsplth.s | 20 ++++++++++++++++++ src/alloy/frontend/ppc/test/instr_vspltw.s | 20 ++++++++++++++++++ 12 files changed, 120 insertions(+) create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vspltb.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vspltb.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vspltb.map create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vsplth.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vsplth.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vsplth.map create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vspltw.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vspltw.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vspltw.map create mode 100644 src/alloy/frontend/ppc/test/instr_vspltb.s create mode 100644 src/alloy/frontend/ppc/test/instr_vsplth.s create mode 100644 src/alloy/frontend/ppc/test/instr_vspltw.s diff --git a/src/alloy/frontend/ppc/test/bin/instr_vspltb.bin b/src/alloy/frontend/ppc/test/bin/instr_vspltb.bin new file mode 100644 index 0000000000000000000000000000000000000000..2fa47981df55d2e4da7491cd9c84a2e19bc138e8 GIT binary patch literal 24 VcmWegP~!1xU{DZ9gwpvC8UQ-51hoJF literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vspltb.dis b/src/alloy/frontend/ppc/test/bin/instr_vspltb.dis new file mode 100644 index 000000000..600912aec --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vspltb.dis @@ -0,0 +1,17 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vspltb.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 60 22 0c vspltb v3,v4,0 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 10 61 22 0c vspltb v3,v4,1 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: 10 6f 22 0c vspltb v3,v4,15 + 100014: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vspltb.map b/src/alloy/frontend/ppc/test/bin/instr_vspltb.map new file mode 100644 index 000000000..1c99d3732 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vspltb.map @@ -0,0 +1,3 @@ +0000000000000000 t test_vspltb_1 +0000000000000008 t test_vspltb_2 +0000000000000010 t test_vspltb_3 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vsplth.bin b/src/alloy/frontend/ppc/test/bin/instr_vsplth.bin new file mode 100644 index 0000000000000000000000000000000000000000..81692954ace3a3c839d954c01eed2d7d915ba3f0 GIT binary patch literal 24 VcmWegQ1bC>U{DZ9gwp8{8URE%1#JKT literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vsplth.dis b/src/alloy/frontend/ppc/test/bin/instr_vsplth.dis new file mode 100644 index 000000000..4512df243 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vsplth.dis @@ -0,0 +1,17 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vsplth.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 60 22 4c vsplth v3,v4,0 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 10 61 22 4c vsplth v3,v4,1 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: 10 67 22 4c vsplth v3,v4,7 + 100014: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vsplth.map b/src/alloy/frontend/ppc/test/bin/instr_vsplth.map new file mode 100644 index 000000000..68f48827f --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vsplth.map @@ -0,0 +1,3 @@ +0000000000000000 t test_vsplth_1 +0000000000000008 t test_vsplth_2 +0000000000000010 t test_vsplth_3 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vspltw.bin b/src/alloy/frontend/ppc/test/bin/instr_vspltw.bin new file mode 100644 index 0000000000000000000000000000000000000000..d100e823d2fbf74c9cd33d7a8d55b20adc3c6819 GIT binary patch literal 24 VcmWegQ0nn(U{DZ9gwn|n8URh)1}Ojl literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vspltw.dis b/src/alloy/frontend/ppc/test/bin/instr_vspltw.dis new file mode 100644 index 000000000..147037bae --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vspltw.dis @@ -0,0 +1,17 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vspltw.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 60 22 8c vspltw v3,v4,0 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 10 61 22 8c vspltw v3,v4,1 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: 10 63 22 8c vspltw v3,v4,3 + 100014: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vspltw.map b/src/alloy/frontend/ppc/test/bin/instr_vspltw.map new file mode 100644 index 000000000..5fd932869 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vspltw.map @@ -0,0 +1,3 @@ +0000000000000000 t test_vspltw_1 +0000000000000008 t test_vspltw_2 +0000000000000010 t test_vspltw_3 diff --git a/src/alloy/frontend/ppc/test/instr_vspltb.s b/src/alloy/frontend/ppc/test/instr_vspltb.s new file mode 100644 index 000000000..71d2197b3 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vspltb.s @@ -0,0 +1,20 @@ +test_vspltb_1: + #_ REGISTER_IN v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vspltb v3, v4, 0 + blr + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vspltb_2: + #_ REGISTER_IN v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vspltb v3, v4, 1 + blr + #_ REGISTER_OUT v3 [01010101, 01010101, 01010101, 01010101] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vspltb_3: + #_ REGISTER_IN v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vspltb v3, v4, 0xF + blr + #_ REGISTER_OUT v3 [0F0F0F0F, 0F0F0F0F, 0F0F0F0F, 0F0F0F0F] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] diff --git a/src/alloy/frontend/ppc/test/instr_vsplth.s b/src/alloy/frontend/ppc/test/instr_vsplth.s new file mode 100644 index 000000000..a6a382d23 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vsplth.s @@ -0,0 +1,20 @@ +test_vsplth_1: + #_ REGISTER_IN v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vsplth v3, v4, 0 + blr + #_ REGISTER_OUT v3 [00010001, 00010001, 00010001, 00010001] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vsplth_2: + #_ REGISTER_IN v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vsplth v3, v4, 1 + blr + #_ REGISTER_OUT v3 [02030203, 02030203, 02030203, 02030203] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vsplth_3: + #_ REGISTER_IN v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vsplth v3, v4, 7 + blr + #_ REGISTER_OUT v3 [0E0F0E0F, 0E0F0E0F, 0E0F0E0F, 0E0F0E0F] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] diff --git a/src/alloy/frontend/ppc/test/instr_vspltw.s b/src/alloy/frontend/ppc/test/instr_vspltw.s new file mode 100644 index 000000000..d9f30e112 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vspltw.s @@ -0,0 +1,20 @@ +test_vspltw_1: + #_ REGISTER_IN v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vspltw v3, v4, 0 + blr + #_ REGISTER_OUT v3 [00010203, 00010203, 00010203, 00010203] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vspltw_2: + #_ REGISTER_IN v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vspltw v3, v4, 1 + blr + #_ REGISTER_OUT v3 [04050607, 04050607, 04050607, 04050607] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vspltw_3: + #_ REGISTER_IN v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vspltw v3, v4, 3 + blr + #_ REGISTER_OUT v3 [0C0D0E0F, 0C0D0E0F, 0C0D0E0F, 0C0D0E0F] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] From 229daab25bb25dd45f51b3768cfa4351738ceb78 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 11 Jan 2015 15:02:57 -0800 Subject: [PATCH 352/388] vspltis[bhw] tests. --- .../frontend/ppc/test/bin/instr_vspltisb.bin | Bin 0 -> 32 bytes .../frontend/ppc/test/bin/instr_vspltisb.dis | 21 ++++++++++++++++++ .../frontend/ppc/test/bin/instr_vspltisb.map | 4 ++++ .../frontend/ppc/test/bin/instr_vspltish.bin | Bin 0 -> 32 bytes .../frontend/ppc/test/bin/instr_vspltish.dis | 21 ++++++++++++++++++ .../frontend/ppc/test/bin/instr_vspltish.map | 4 ++++ .../frontend/ppc/test/bin/instr_vspltisw.bin | Bin 0 -> 32 bytes .../frontend/ppc/test/bin/instr_vspltisw.dis | 21 ++++++++++++++++++ .../frontend/ppc/test/bin/instr_vspltisw.map | 4 ++++ src/alloy/frontend/ppc/test/instr_vspltisb.s | 19 ++++++++++++++++ src/alloy/frontend/ppc/test/instr_vspltish.s | 19 ++++++++++++++++ src/alloy/frontend/ppc/test/instr_vspltisw.s | 19 ++++++++++++++++ 12 files changed, 132 insertions(+) create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vspltisb.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vspltisb.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vspltisb.map create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vspltish.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vspltish.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vspltish.map create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vspltisw.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vspltisw.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vspltisw.map create mode 100644 src/alloy/frontend/ppc/test/instr_vspltisb.s create mode 100644 src/alloy/frontend/ppc/test/instr_vspltish.s create mode 100644 src/alloy/frontend/ppc/test/instr_vspltisw.s diff --git a/src/alloy/frontend/ppc/test/bin/instr_vspltisb.bin b/src/alloy/frontend/ppc/test/bin/instr_vspltisb.bin new file mode 100644 index 0000000000000000000000000000000000000000..4d17de5ace9205911afb7dcc505f3769ec063f5a GIT binary patch literal 32 YcmWegVCL~_U{DZ9gwpj;x(-4E0AOMT^8f$< literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vspltisb.dis b/src/alloy/frontend/ppc/test/bin/instr_vspltisb.dis new file mode 100644 index 000000000..8378aca3e --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vspltisb.dis @@ -0,0 +1,21 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vspltisb.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 60 03 0c vspltisb v3,0 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 10 61 03 0c vspltisb v3,1 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: 10 7f 03 0c vspltisb v3,-1 + 100014: 4e 80 00 20 blr + +0000000000100018 : + 100018: 10 7e 03 0c vspltisb v3,-2 + 10001c: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vspltisb.map b/src/alloy/frontend/ppc/test/bin/instr_vspltisb.map new file mode 100644 index 000000000..93d21b9ed --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vspltisb.map @@ -0,0 +1,4 @@ +0000000000000000 t test_vspltisb_1 +0000000000000008 t test_vspltisb_2 +0000000000000010 t test_vspltisb_3 +0000000000000018 t test_vspltisb_4 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vspltish.bin b/src/alloy/frontend/ppc/test/bin/instr_vspltish.bin new file mode 100644 index 0000000000000000000000000000000000000000..f2db822f79879a3e2375d440fc05587bd509fbbe GIT binary patch literal 32 YcmWegVD|BAU{DZ9gwpj;x(-4E0C8dl^8f$< literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vspltish.dis b/src/alloy/frontend/ppc/test/bin/instr_vspltish.dis new file mode 100644 index 000000000..7eb39018e --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vspltish.dis @@ -0,0 +1,21 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vspltish.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 60 03 4c vspltish v3,0 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 10 61 03 4c vspltish v3,1 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: 10 7f 03 4c vspltish v3,-1 + 100014: 4e 80 00 20 blr + +0000000000100018 : + 100018: 10 7e 03 4c vspltish v3,-2 + 10001c: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vspltish.map b/src/alloy/frontend/ppc/test/bin/instr_vspltish.map new file mode 100644 index 000000000..9eb8c3160 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vspltish.map @@ -0,0 +1,4 @@ +0000000000000000 t test_vspltish_1 +0000000000000008 t test_vspltish_2 +0000000000000010 t test_vspltish_3 +0000000000000018 t test_vspltish_4 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vspltisw.bin b/src/alloy/frontend/ppc/test/bin/instr_vspltisw.bin new file mode 100644 index 0000000000000000000000000000000000000000..687d74ce1ebadc750b3c65383b2fc7b12e89c50f GIT binary patch literal 32 YcmWegVD9m2U{DZ9gwpj;x(-4E0D@u%^8f$< literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vspltisw.dis b/src/alloy/frontend/ppc/test/bin/instr_vspltisw.dis new file mode 100644 index 000000000..740a94ea9 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vspltisw.dis @@ -0,0 +1,21 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vspltisw.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 60 03 8c vspltisw v3,0 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 10 61 03 8c vspltisw v3,1 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: 10 7f 03 8c vspltisw v3,-1 + 100014: 4e 80 00 20 blr + +0000000000100018 : + 100018: 10 7e 03 8c vspltisw v3,-2 + 10001c: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vspltisw.map b/src/alloy/frontend/ppc/test/bin/instr_vspltisw.map new file mode 100644 index 000000000..46346e99c --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vspltisw.map @@ -0,0 +1,4 @@ +0000000000000000 t test_vspltisw_1 +0000000000000008 t test_vspltisw_2 +0000000000000010 t test_vspltisw_3 +0000000000000018 t test_vspltisw_4 diff --git a/src/alloy/frontend/ppc/test/instr_vspltisb.s b/src/alloy/frontend/ppc/test/instr_vspltisb.s new file mode 100644 index 000000000..83e48c09f --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vspltisb.s @@ -0,0 +1,19 @@ +test_vspltisb_1: + vspltisb v3, 0 + blr + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + +test_vspltisb_2: + vspltisb v3, 1 + blr + #_ REGISTER_OUT v3 [01010101, 01010101, 01010101, 01010101] + +test_vspltisb_3: + vspltisb v3, -1 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + +test_vspltisb_4: + vspltisb v3, -2 + blr + #_ REGISTER_OUT v3 [FEFEFEFE, FEFEFEFE, FEFEFEFE, FEFEFEFE] diff --git a/src/alloy/frontend/ppc/test/instr_vspltish.s b/src/alloy/frontend/ppc/test/instr_vspltish.s new file mode 100644 index 000000000..40ae3d61a --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vspltish.s @@ -0,0 +1,19 @@ +test_vspltish_1: + vspltish v3, 0 + blr + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + +test_vspltish_2: + vspltish v3, 1 + blr + #_ REGISTER_OUT v3 [00010001, 00010001, 00010001, 00010001] + +test_vspltish_3: + vspltish v3, -1 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + +test_vspltish_4: + vspltish v3, -2 + blr + #_ REGISTER_OUT v3 [FFFEFFFE, FFFEFFFE, FFFEFFFE, FFFEFFFE] diff --git a/src/alloy/frontend/ppc/test/instr_vspltisw.s b/src/alloy/frontend/ppc/test/instr_vspltisw.s new file mode 100644 index 000000000..696544cdc --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vspltisw.s @@ -0,0 +1,19 @@ +test_vspltisw_1: + vspltisw v3, 0 + blr + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + +test_vspltisw_2: + vspltisw v3, 1 + blr + #_ REGISTER_OUT v3 [00000001, 00000001, 00000001, 00000001] + +test_vspltisw_3: + vspltisw v3, -1 + blr + #_ REGISTER_OUT v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + +test_vspltisw_4: + vspltisw v3, -2 + blr + #_ REGISTER_OUT v3 [FFFFFFFE, FFFFFFFE, FFFFFFFE, FFFFFFFE] From d234f2bc47a9a808a3d8fd62f1ae6eae5f23e524 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 11 Jan 2015 15:17:16 -0800 Subject: [PATCH 353/388] vperm test + fix for % byte. --- src/alloy/backend/x64/x64_emitter.cc | 1 + src/alloy/backend/x64/x64_emitter.h | 1 + src/alloy/backend/x64/x64_sequences.cc | 4 ++ .../frontend/ppc/test/bin/instr_vperm.bin | Bin 0 -> 32 bytes .../frontend/ppc/test/bin/instr_vperm.dis | 21 +++++++++ .../frontend/ppc/test/bin/instr_vperm.map | 4 ++ src/alloy/frontend/ppc/test/instr_vperm.s | 44 ++++++++++++++++++ 7 files changed, 75 insertions(+) create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vperm.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vperm.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vperm.map create mode 100644 src/alloy/frontend/ppc/test/instr_vperm.s diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index c26aa59a1..00723703c 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -810,6 +810,7 @@ Address X64Emitter::GetXmmConstPtr(XmmConst id) { /* XMMByteOrderMask */ vec128i(0x01000302u, 0x05040706u, 0x09080B0Au, 0x0D0C0F0Eu), /* XMMPermuteControl15 */ vec128b(15), + /* XMMPermuteByteMask */ vec128b(0x1F), /* XMMPackD3DCOLORSat */ vec128i(0x404000FFu), /* XMMPackD3DCOLOR */ vec128i(0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x0C000408u), diff --git a/src/alloy/backend/x64/x64_emitter.h b/src/alloy/backend/x64/x64_emitter.h index b54bc8267..9245f408d 100644 --- a/src/alloy/backend/x64/x64_emitter.h +++ b/src/alloy/backend/x64/x64_emitter.h @@ -57,6 +57,7 @@ enum XmmConst { XMMByteSwapMask, XMMByteOrderMask, XMMPermuteControl15, + XMMPermuteByteMask, XMMPackD3DCOLORSat, XMMPackD3DCOLOR, XMMUnpackD3DCOLOR, diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index 81803d8c2..0d0c56270 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -5007,6 +5007,7 @@ EMITTER(PERMUTE_I32, MATCH(I, I32<>, V128<>, V128<>>)) { }; EMITTER(PERMUTE_V128, MATCH(I, V128<>, V128<>, V128<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { + assert_true(i.instr->flags == INT8_TYPE); // TODO(benvanik): find out how to do this with only one temp register! // Permute bytes between src2 and src3. if (i.src3.value->IsConstantZero()) { @@ -5022,6 +5023,7 @@ EMITTER(PERMUTE_V128, MATCH(I, V128<>, V128<>, V128<>>)) } else { e.vxorps(e.xmm0, i.src1, e.GetXmmConstPtr(XMMSwapWordMask)); } + e.vpand(e.xmm0, e.GetXmmConstPtr(XMMPermuteByteMask)); if (i.src2.is_constant) { e.LoadConstantXmm(i.dest, i.src2.constant()); e.vpshufb(i.dest, i.dest, e.xmm0); @@ -5035,12 +5037,14 @@ EMITTER(PERMUTE_V128, MATCH(I, V128<>, V128<>, V128<>>)) } else { // General permute. // Control mask needs to be shuffled. + // TODO(benvanik): do constants here instead of in generated code. if (i.src1.is_constant) { e.LoadConstantXmm(e.xmm2, i.src1.constant()); e.vxorps(e.xmm2, e.xmm2, e.GetXmmConstPtr(XMMSwapWordMask)); } else { e.vxorps(e.xmm2, i.src1, e.GetXmmConstPtr(XMMSwapWordMask)); } + e.vpand(e.xmm2, e.GetXmmConstPtr(XMMPermuteByteMask)); Xmm src2_shuf = e.xmm0; if (i.src2.value->IsConstantZero()) { e.vpxor(src2_shuf, src2_shuf); diff --git a/src/alloy/frontend/ppc/test/bin/instr_vperm.bin b/src/alloy/frontend/ppc/test/bin/instr_vperm.bin new file mode 100644 index 0000000000000000000000000000000000000000..25523ecae35522cbc10682b27e6db55dc4d198dc GIT binary patch literal 32 ScmWeQteEZBz@Q+2g9ZScxCu1? literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vperm.dis b/src/alloy/frontend/ppc/test/bin/instr_vperm.dis new file mode 100644 index 000000000..353683ccb --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vperm.dis @@ -0,0 +1,21 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vperm.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 c3 21 6b vperm v6,v3,v4,v5 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 10 c3 21 6b vperm v6,v3,v4,v5 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: 10 c3 21 6b vperm v6,v3,v4,v5 + 100014: 4e 80 00 20 blr + +0000000000100018 : + 100018: 10 c3 21 6b vperm v6,v3,v4,v5 + 10001c: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vperm.map b/src/alloy/frontend/ppc/test/bin/instr_vperm.map new file mode 100644 index 000000000..18e6711bc --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vperm.map @@ -0,0 +1,4 @@ +0000000000000000 t test_vperm_1 +0000000000000008 t test_vperm_2 +0000000000000010 t test_vperm_3 +0000000000000018 t test_vperm_4 diff --git a/src/alloy/frontend/ppc/test/instr_vperm.s b/src/alloy/frontend/ppc/test/instr_vperm.s new file mode 100644 index 000000000..d709b5ae0 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vperm.s @@ -0,0 +1,44 @@ +test_vperm_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_IN v5 [00000000, 00000000, 00000000, 00000000] + vperm v6, v3, v4, v5 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [00000000, 00000000, 00000000, 00000000] + #_ REGISTER_OUT v6 [00000000, 00000000, 00000000, 00000000] + +test_vperm_2: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_IN v5 [01010101, 01010101, 01010101, 01010101] + vperm v6, v3, v4, v5 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [01010101, 01010101, 01010101, 01010101] + #_ REGISTER_OUT v6 [01010101, 01010101, 01010101, 01010101] + +test_vperm_3: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_IN v5 [11111111, 11111111, 11111111, 11111111] + vperm v6, v3, v4, v5 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [11111111, 11111111, 11111111, 11111111] + #_ REGISTER_OUT v6 [11111111, 11111111, 11111111, 11111111] + +test_vperm_4: + # try with > 32b values (should mod) + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_IN v5 [21212121, 21212121, 21212121, 21212121] + vperm v6, v3, v4, v5 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [21212121, 21212121, 21212121, 21212121] + #_ REGISTER_OUT v6 [01010101, 01010101, 01010101, 01010101] From f6404a098264a39a257eb5ceb05c0b45b4637bb9 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 11 Jan 2015 15:38:01 -0800 Subject: [PATCH 354/388] vctsxs tests. --- .../frontend/ppc/test/bin/instr_vctsxs.bin | Bin 0 -> 40 bytes .../frontend/ppc/test/bin/instr_vctsxs.dis | 25 ++++++++++++++ .../frontend/ppc/test/bin/instr_vctsxs.map | 5 +++ src/alloy/frontend/ppc/test/instr_vctsxs.s | 32 ++++++++++++++++++ 4 files changed, 62 insertions(+) create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vctsxs.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vctsxs.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vctsxs.map create mode 100644 src/alloy/frontend/ppc/test/instr_vctsxs.s diff --git a/src/alloy/frontend/ppc/test/bin/instr_vctsxs.bin b/src/alloy/frontend/ppc/test/bin/instr_vctsxs.bin new file mode 100644 index 0000000000000000000000000000000000000000..5db997781e6633c5731ed1770174d5cf364ec7e0 GIT binary patch literal 40 XcmWegkUr(tz@Q+I2&I#tG@3X7>L?3T literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vctsxs.dis b/src/alloy/frontend/ppc/test/bin/instr_vctsxs.dis new file mode 100644 index 000000000..9416bbc42 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vctsxs.dis @@ -0,0 +1,25 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vctsxs.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 60 1b ca vctsxs v3,v3,0 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 10 61 1b ca vctsxs v3,v3,1 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: 10 62 1b ca vctsxs v3,v3,2 + 100014: 4e 80 00 20 blr + +0000000000100018 : + 100018: 10 60 1b ca vctsxs v3,v3,0 + 10001c: 4e 80 00 20 blr + +0000000000100020 : + 100020: 10 61 1b ca vctsxs v3,v3,1 + 100024: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vctsxs.map b/src/alloy/frontend/ppc/test/bin/instr_vctsxs.map new file mode 100644 index 000000000..d5b353670 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vctsxs.map @@ -0,0 +1,5 @@ +0000000000000000 t test_vctsxs_1 +0000000000000008 t test_vctsxs_2 +0000000000000010 t test_vctsxs_3 +0000000000000018 t test_vctsxs_4 +0000000000000020 t test_vctsxs_5 diff --git a/src/alloy/frontend/ppc/test/instr_vctsxs.s b/src/alloy/frontend/ppc/test/instr_vctsxs.s new file mode 100644 index 000000000..c3c35f444 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vctsxs.s @@ -0,0 +1,32 @@ +test_vctsxs_1: + #_ REGISTER_IN v3 [3f800000, 3fc00000, 3f8ccccd, 3ff33333] + # 1.0, 1.5, 1.1, 1.9 + vctsxs v3, v3, 0 + blr + #_ REGISTER_OUT v3 [00000001, 00000001, 00000001, 00000001] + +test_vctsxs_2: + #_ REGISTER_IN v3 [3f800000, 3fc00000, 3f8ccccd, 3ff33333] + # 1.0, 1.5, 1.1, 1.9 + vctsxs v3, v3, 1 + blr + #_ REGISTER_OUT v3 [00000002, 00000003, 00000002, 00000003] + +test_vctsxs_3: + #_ REGISTER_IN v3 [3f800000, 3fc00000, 3f8ccccd, 3ff33333] + # 1.0, 1.5, 1.1, 1.9 + vctsxs v3, v3, 2 + blr + #_ REGISTER_OUT v3 [00000004, 00000006, 00000004, 00000007] + +test_vctsxs_4: + #_ REGISTER_IN v3 [42c83333, 43480000, 449a4000, c49a4000] + vctsxs v3, v3, 0 + blr + #_ REGISTER_OUT v3 [00000064, 000000c8, 000004d2, fffffb2e] + +test_vctsxs_5: + #_ REGISTER_IN v3 [42c83333, 43480000, 449a4000, c49a4000] + vctsxs v3, v3, 1 + blr + #_ REGISTER_OUT v3 [000000c8, 00000190, 000009a4, fffff65c] From d66c6ec3d3d70d38fe3980c7b9f25f3b0a9de212 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 11 Jan 2015 15:45:17 -0800 Subject: [PATCH 355/388] fabs test. --- src/alloy/frontend/ppc/ppc_context.cc | 14 ++++++++++++++ src/alloy/frontend/ppc/test/bin/instr_fabs.bin | Bin 0 -> 24 bytes src/alloy/frontend/ppc/test/bin/instr_fabs.dis | 17 +++++++++++++++++ src/alloy/frontend/ppc/test/bin/instr_fabs.map | 3 +++ src/alloy/frontend/ppc/test/instr_fabs.s | 17 +++++++++++++++++ 5 files changed, 51 insertions(+) create mode 100644 src/alloy/frontend/ppc/test/bin/instr_fabs.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_fabs.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_fabs.map create mode 100644 src/alloy/frontend/ppc/test/instr_fabs.s diff --git a/src/alloy/frontend/ppc/ppc_context.cc b/src/alloy/frontend/ppc/ppc_context.cc index 9495cabf8..ad94c95f2 100644 --- a/src/alloy/frontend/ppc/ppc_context.cc +++ b/src/alloy/frontend/ppc/ppc_context.cc @@ -19,6 +19,10 @@ uint64_t ParseInt64(const char* value) { return std::strtoull(value, nullptr, 0); } +double ParseFloat64(const char* value) { + return std::strtod(value, nullptr); +} + vec128_t ParseVec128(const char* value) { vec128_t v; char* p = const_cast(value); @@ -37,6 +41,8 @@ void PPCContext::SetRegFromString(const char* name, const char* value) { int n; if (sscanf(name, "r%d", &n) == 1) { this->r[n] = ParseInt64(value); + } else if (sscanf(name, "f%d", &n) == 1) { + this->f[n] = ParseFloat64(value); } else if (sscanf(name, "v%d", &n) == 1) { this->v[n] = ParseVec128(value); } else { @@ -54,6 +60,14 @@ bool PPCContext::CompareRegWithString(const char* name, const char* value, return false; } return true; + } else if (sscanf(name, "f%d", &n) == 1) { + double expected = ParseFloat64(value); + // TODO(benvanik): epsilon + if (this->f[n] != expected) { + snprintf(out_value, out_value_size, "%f", this->f[n]); + return false; + } + return true; } else if (sscanf(name, "v%d", &n) == 1) { vec128_t expected = ParseVec128(value); if (this->v[n] != expected) { diff --git a/src/alloy/frontend/ppc/test/bin/instr_fabs.bin b/src/alloy/frontend/ppc/test/bin/instr_fabs.bin new file mode 100644 index 0000000000000000000000000000000000000000..c34adc217d25a34691ed77a53aaa9a6a6fa60680 GIT binary patch literal 24 ScmeyPz$M_: + 100000: fc 20 0a 10 fabs f1,f1 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: fc 20 0a 10 fabs f1,f1 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: fc 20 0a 10 fabs f1,f1 + 100014: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_fabs.map b/src/alloy/frontend/ppc/test/bin/instr_fabs.map new file mode 100644 index 000000000..dc13f6f64 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_fabs.map @@ -0,0 +1,3 @@ +0000000000000000 t test_fabs_1 +0000000000000008 t test_fabs_2 +0000000000000010 t test_fabs_3 diff --git a/src/alloy/frontend/ppc/test/instr_fabs.s b/src/alloy/frontend/ppc/test/instr_fabs.s new file mode 100644 index 000000000..5d3c35d90 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_fabs.s @@ -0,0 +1,17 @@ +test_fabs_1: + #_ REGISTER_IN f1 1.0 + fabs f1, f1 + blr + #_ REGISTER_OUT f1 1.0 + +test_fabs_2: + #_ REGISTER_IN f1 -1.0 + fabs f1, f1 + blr + #_ REGISTER_OUT f1 1.0 + +test_fabs_3: + #_ REGISTER_IN f1 -1234.0 + fabs f1, f1 + blr + #_ REGISTER_OUT f1 1234.0 From 18e458e99ab97011c3dad3057ab36730a6469e45 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 11 Jan 2015 15:49:56 -0800 Subject: [PATCH 356/388] addic tests. --- src/alloy/frontend/ppc/test/bin/instr_addic.bin | Bin 0 -> 24 bytes src/alloy/frontend/ppc/test/bin/instr_addic.dis | 15 +++++++++++++++ src/alloy/frontend/ppc/test/bin/instr_addic.map | 2 ++ src/alloy/frontend/ppc/test/instr_addic.s | 15 +++++++++++++++ 4 files changed, 32 insertions(+) create mode 100644 src/alloy/frontend/ppc/test/bin/instr_addic.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_addic.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_addic.map create mode 100644 src/alloy/frontend/ppc/test/instr_addic.s diff --git a/src/alloy/frontend/ppc/test/bin/instr_addic.bin b/src/alloy/frontend/ppc/test/bin/instr_addic.bin new file mode 100644 index 0000000000000000000000000000000000000000..b7154c4b9b9cb188cedccbba41618c2b5dacce82 GIT binary patch literal 24 WcmXqLVPLE|z$oI^z@T7�CINHU;Sb literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_addic.dis b/src/alloy/frontend/ppc/test/bin/instr_addic.dis new file mode 100644 index 000000000..62eb33ef7 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_addic.dis @@ -0,0 +1,15 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_addic.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 30 84 00 01 addic r4,r4,1 + 100004: 7c c0 01 14 adde r6,r0,r0 + 100008: 4e 80 00 20 blr + +000000000010000c : + 10000c: 30 84 00 01 addic r4,r4,1 + 100010: 7c c0 01 14 adde r6,r0,r0 + 100014: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_addic.map b/src/alloy/frontend/ppc/test/bin/instr_addic.map new file mode 100644 index 000000000..de7ccdb31 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_addic.map @@ -0,0 +1,2 @@ +0000000000000000 t test_addic_1 +000000000000000c t test_addic_2 diff --git a/src/alloy/frontend/ppc/test/instr_addic.s b/src/alloy/frontend/ppc/test/instr_addic.s new file mode 100644 index 000000000..13b96d6f7 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_addic.s @@ -0,0 +1,15 @@ +test_addic_1: + #_ REGISTER_IN r4 1 + addic r4, r4, 1 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r4 2 + #_ REGISTER_OUT r6 0 + +test_addic_2: + #_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF + addic r4, r4, 1 + adde r6, r0, r0 + blr + #_ REGISTER_OUT r4 0 + #_ REGISTER_OUT r6 1 From fc397456340ac35965d232d740b69f51eaac28ab Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 11 Jan 2015 16:00:16 -0800 Subject: [PATCH 357/388] lvsl/lvsr tests. --- .../frontend/ppc/test/bin/instr_lvsl.bin | Bin 0 -> 24 bytes .../frontend/ppc/test/bin/instr_lvsl.dis | 17 +++++++++++++++ .../frontend/ppc/test/bin/instr_lvsl.map | 3 +++ .../frontend/ppc/test/bin/instr_lvsr.bin | Bin 0 -> 24 bytes .../frontend/ppc/test/bin/instr_lvsr.dis | 17 +++++++++++++++ .../frontend/ppc/test/bin/instr_lvsr.map | 3 +++ src/alloy/frontend/ppc/test/instr_lvsl.s | 20 ++++++++++++++++++ src/alloy/frontend/ppc/test/instr_lvsr.s | 20 ++++++++++++++++++ 8 files changed, 80 insertions(+) create mode 100644 src/alloy/frontend/ppc/test/bin/instr_lvsl.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_lvsl.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_lvsl.map create mode 100644 src/alloy/frontend/ppc/test/bin/instr_lvsr.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_lvsr.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_lvsr.map create mode 100644 src/alloy/frontend/ppc/test/instr_lvsl.s create mode 100644 src/alloy/frontend/ppc/test/instr_lvsr.s diff --git a/src/alloy/frontend/ppc/test/bin/instr_lvsl.bin b/src/alloy/frontend/ppc/test/bin/instr_lvsl.bin new file mode 100644 index 0000000000000000000000000000000000000000..c8d11323ccb2782b6e9f926931c4993bf39d8122 GIT binary patch literal 24 Rcmb: + 100000: 7c 64 00 0c lvsl v3,r4,r0 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 7c 64 00 0c lvsl v3,r4,r0 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: 7c 64 00 0c lvsl v3,r4,r0 + 100014: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_lvsl.map b/src/alloy/frontend/ppc/test/bin/instr_lvsl.map new file mode 100644 index 000000000..9092d008f --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_lvsl.map @@ -0,0 +1,3 @@ +0000000000000000 t test_lvsl_1 +0000000000000008 t test_lvsl_2 +0000000000000010 t test_lvsl_3 diff --git a/src/alloy/frontend/ppc/test/bin/instr_lvsr.bin b/src/alloy/frontend/ppc/test/bin/instr_lvsr.bin new file mode 100644 index 0000000000000000000000000000000000000000..7ea145691725b6fe68e2c4f2728cd19a5d0d2e46 GIT binary patch literal 24 Rcmb: + 100000: 7c 64 00 4c lvsr v3,r4,r0 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 7c 64 00 4c lvsr v3,r4,r0 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: 7c 64 00 4c lvsr v3,r4,r0 + 100014: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_lvsr.map b/src/alloy/frontend/ppc/test/bin/instr_lvsr.map new file mode 100644 index 000000000..daf1ee1cc --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_lvsr.map @@ -0,0 +1,3 @@ +0000000000000000 t test_lvsr_1 +0000000000000008 t test_lvsr_2 +0000000000000010 t test_lvsr_3 diff --git a/src/alloy/frontend/ppc/test/instr_lvsl.s b/src/alloy/frontend/ppc/test/instr_lvsl.s new file mode 100644 index 000000000..31cd73194 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_lvsl.s @@ -0,0 +1,20 @@ +test_lvsl_1: + #_ REGISTER_IN r4 0x1070 + lvsl v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x1070 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_lvsl_2: + #_ REGISTER_IN r4 0x1071 + lvsl v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x1071 + #_ REGISTER_OUT v3 [01020304, 05060708, 090A0B0C, 0D0E0F10] + +test_lvsl_3: + #_ REGISTER_IN r4 0x107F + lvsl v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x107F + #_ REGISTER_OUT v3 [0F101112, 13141516, 1718191A, 1B1C1D1E] diff --git a/src/alloy/frontend/ppc/test/instr_lvsr.s b/src/alloy/frontend/ppc/test/instr_lvsr.s new file mode 100644 index 000000000..c3e29b963 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_lvsr.s @@ -0,0 +1,20 @@ +test_lvsr_1: + #_ REGISTER_IN r4 0x1070 + lvsr v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x1070 + #_ REGISTER_OUT v3 [10111213, 14151617, 18191A1B, 1C1D1E1F] + +test_lvsr_2: + #_ REGISTER_IN r4 0x1071 + lvsr v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x1071 + #_ REGISTER_OUT v3 [0F101112, 13141516, 1718191A, 1B1C1D1E] + +test_lvsr_3: + #_ REGISTER_IN r4 0x107F + lvsr v3, r4, r0 + blr + #_ REGISTER_OUT r4 0x107F + #_ REGISTER_OUT v3 [01020304, 05060708, 090A0B0C, 0D0E0F10] From 0dfe0602ad7d06273b658ebbaadf0e7846c86266 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 11 Jan 2015 16:39:36 -0800 Subject: [PATCH 358/388] stvew tests. --- .../frontend/ppc/test/bin/instr_stvew.bin | Bin 0 -> 32 bytes .../frontend/ppc/test/bin/instr_stvew.dis | 21 ++++++++++ .../frontend/ppc/test/bin/instr_stvew.map | 4 ++ src/alloy/frontend/ppc/test/instr_stvew.s | 39 ++++++++++++++++++ 4 files changed, 64 insertions(+) create mode 100644 src/alloy/frontend/ppc/test/bin/instr_stvew.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_stvew.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_stvew.map create mode 100644 src/alloy/frontend/ppc/test/instr_stvew.s diff --git a/src/alloy/frontend/ppc/test/bin/instr_stvew.bin b/src/alloy/frontend/ppc/test/bin/instr_stvew.bin new file mode 100644 index 0000000000000000000000000000000000000000..ceea4226bb3e0bd383cf67a7911af06c19c0a59d GIT binary patch literal 32 Scmb: + 100000: 7c 60 21 8e stvewx v3,0,r4 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 7c 60 21 8e stvewx v3,0,r4 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: 7c 60 21 8e stvewx v3,0,r4 + 100014: 4e 80 00 20 blr + +0000000000100018 : + 100018: 7c 60 21 8e stvewx v3,0,r4 + 10001c: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_stvew.map b/src/alloy/frontend/ppc/test/bin/instr_stvew.map new file mode 100644 index 000000000..7a317bfbf --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_stvew.map @@ -0,0 +1,4 @@ +0000000000000000 t test_stvew_1 +0000000000000008 t test_stvew_2 +0000000000000010 t test_stvew_3 +0000000000000018 t test_stvew_4 diff --git a/src/alloy/frontend/ppc/test/instr_stvew.s b/src/alloy/frontend/ppc/test/instr_stvew.s new file mode 100644 index 000000000..ec13b25e2 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_stvew.s @@ -0,0 +1,39 @@ +test_stvew_1: + #_ MEMORY_IN 00001050 CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC + #_ REGISTER_IN r4 0x1050 + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + stvewx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x1050 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ MEMORY_OUT 00001050 00010203 CCCCCCCC CCCCCCCC CCCCCCCC + +test_stvew_2: + #_ MEMORY_IN 00001050 CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC + #_ REGISTER_IN r4 0x1054 + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + stvewx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x1054 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ MEMORY_OUT 00001050 CCCCCCCC 04050607 CCCCCCCC CCCCCCCC + +test_stvew_3: + #_ MEMORY_IN 00001050 CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC + #_ REGISTER_IN r4 0x1058 + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + stvewx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x1058 + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ MEMORY_OUT 00001050 CCCCCCCC CCCCCCCC 08090A0B CCCCCCCC + +test_stvew_4: + #_ MEMORY_IN 00001050 CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC + #_ REGISTER_IN r4 0x105C + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + stvewx v3, r0, r4 + blr + #_ REGISTER_OUT r4 0x105C + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ MEMORY_OUT 00001050 CCCCCCCC CCCCCCCC CCCCCCCC 0C0D0E0F From 6a44cf96626d717767075286ae636e69e3f9f485 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 11 Jan 2015 16:39:44 -0800 Subject: [PATCH 359/388] vrlimi128 tests. --- .../frontend/ppc/test/bin/instr_vrlimi128.bin | Bin 0 -> 72 bytes .../frontend/ppc/test/bin/instr_vrlimi128.dis | 41 ++++++++++ .../frontend/ppc/test/bin/instr_vrlimi128.map | 9 +++ src/alloy/frontend/ppc/test/instr_vrlimi128.s | 75 ++++++++++++++++++ 4 files changed, 125 insertions(+) create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vrlimi128.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vrlimi128.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vrlimi128.map create mode 100644 src/alloy/frontend/ppc/test/instr_vrlimi128.s diff --git a/src/alloy/frontend/ppc/test/bin/instr_vrlimi128.bin b/src/alloy/frontend/ppc/test/bin/instr_vrlimi128.bin new file mode 100644 index 0000000000000000000000000000000000000000..954231d04756511295649dd96180f3bb21d070fe GIT binary patch literal 72 scmb1WkQeZ4U{H|ghtSgc*F&NF2_RbP{qd_{eg{-t3zTkx(v1)r0KT6Rm;e9( literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vrlimi128.dis b/src/alloy/frontend/ppc/test/bin/instr_vrlimi128.dis new file mode 100644 index 000000000..57e5c8c6a --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vrlimi128.dis @@ -0,0 +1,41 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vrlimi128.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 18 80 1f 10 vrlimi128 v4,v3,0,0 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 18 8f 1f 10 vrlimi128 v4,v3,15,0 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: 1b 2f d7 55 vrlimi128 v57,v58,15,0 + 100014: 4e 80 00 20 blr + +0000000000100018 : + 100018: 18 8f 1f 90 vrlimi128 v4,v3,15,2 + 10001c: 4e 80 00 20 blr + +0000000000100020 : + 100020: 1a ef c7 d5 vrlimi128 v55,v56,15,2 + 100024: 4e 80 00 20 blr + +0000000000100028 : + 100028: 18 88 1f 10 vrlimi128 v4,v3,8,0 + 10002c: 4e 80 00 20 blr + +0000000000100030 : + 100030: 18 84 1f 10 vrlimi128 v4,v3,4,0 + 100034: 4e 80 00 20 blr + +0000000000100038 : + 100038: 18 82 1f 10 vrlimi128 v4,v3,2,0 + 10003c: 4e 80 00 20 blr + +0000000000100040 : + 100040: 18 81 1f 10 vrlimi128 v4,v3,1,0 + 100044: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vrlimi128.map b/src/alloy/frontend/ppc/test/bin/instr_vrlimi128.map new file mode 100644 index 000000000..33c21f77c --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vrlimi128.map @@ -0,0 +1,9 @@ +0000000000000000 t test_vrlimi128_1 +0000000000000008 t test_vrlimi128_2 +0000000000000010 t test_vrlimi128_3 +0000000000000018 t test_vrlimi128_4 +0000000000000020 t test_vrlimi128_5 +0000000000000028 t test_vrlimi128_6 +0000000000000030 t test_vrlimi128_7 +0000000000000038 t test_vrlimi128_8 +0000000000000040 t test_vrlimi128_9 diff --git a/src/alloy/frontend/ppc/test/instr_vrlimi128.s b/src/alloy/frontend/ppc/test/instr_vrlimi128.s new file mode 100644 index 000000000..55a128d32 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vrlimi128.s @@ -0,0 +1,75 @@ +test_vrlimi128_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, CCCCCCCC] + vrlimi128 v4, v3, 0, 0 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, CCCCCCCC] + +test_vrlimi128_2: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, CCCCCCCC] + vrlimi128 v4, v3, 0xF, 0 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vrlimi128_3: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, CCCCCCCC] + # assember is busted here: + # vrlimi128 v4, v3, 0xF, 1 + .long 0x188f1f50 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [04050607, 08090A0B, 0C0D0E0F, 00010203] + +test_vrlimi128_4: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, CCCCCCCC] + vrlimi128 v4, v3, 0xF, 2 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [08090A0B, 0C0D0E0F, 00010203, 04050607] + +test_vrlimi128_5: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, CCCCCCCC] + # assember is busted here: + # vrlimi128 v4, v3, 0xF, 3 + .long 0x188f1fd0 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [0C0D0E0F, 00010203, 04050607, 08090A0B] + +test_vrlimi128_6: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, CCCCCCCC] + vrlimi128 v4, v3, 0x8, 0 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [00010203, CCCCCCCC, CCCCCCCC, CCCCCCCC] + +test_vrlimi128_7: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, CCCCCCCC] + vrlimi128 v4, v3, 0x4, 0 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [CCCCCCCC, 04050607, CCCCCCCC, CCCCCCCC] + +test_vrlimi128_8: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, CCCCCCCC] + vrlimi128 v4, v3, 0x2, 0 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [CCCCCCCC, CCCCCCCC, 08090A0B, CCCCCCCC] + +test_vrlimi128_9: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, CCCCCCCC] + vrlimi128 v4, v3, 0x1, 0 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [CCCCCCCC, CCCCCCCC, CCCCCCCC, 0C0D0E0F] From cd4e877ae1c37f419bf8d0c53399896bf8061a56 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 11 Jan 2015 21:01:25 -0800 Subject: [PATCH 360/388] fsel test. --- src/alloy/frontend/ppc/ppc_emit_alu.cc | 3 +- .../frontend/ppc/test/bin/instr_fsel.bin | Bin 0 -> 24 bytes .../frontend/ppc/test/bin/instr_fsel.dis | 17 ++++++++++ .../frontend/ppc/test/bin/instr_fsel.map | 3 ++ src/alloy/frontend/ppc/test/instr_fsel.s | 32 ++++++++++++++++++ 5 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 src/alloy/frontend/ppc/test/bin/instr_fsel.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_fsel.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_fsel.map create mode 100644 src/alloy/frontend/ppc/test/instr_fsel.s diff --git a/src/alloy/frontend/ppc/ppc_emit_alu.cc b/src/alloy/frontend/ppc/ppc_emit_alu.cc index 94af993ba..bf1b5ed44 100644 --- a/src/alloy/frontend/ppc/ppc_emit_alu.cc +++ b/src/alloy/frontend/ppc/ppc_emit_alu.cc @@ -732,8 +732,7 @@ XEEMITTER(extswx, 0x7C0007B4, X)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(nandx, 0x7C0003B8, X)(PPCHIRBuilder& f, InstrData& i) { // RA <- ¬((RS) & (RB)) - Value* ra = f.And(f.LoadGPR(i.X.RT), f.LoadGPR(i.X.RB)); - ra = f.Not(ra); + Value* ra = f.Not(f.And(f.LoadGPR(i.X.RT), f.LoadGPR(i.X.RB))); f.StoreGPR(i.X.RA, ra); if (i.X.Rc) { f.UpdateCR(0, ra); diff --git a/src/alloy/frontend/ppc/test/bin/instr_fsel.bin b/src/alloy/frontend/ppc/test/bin/instr_fsel.bin new file mode 100644 index 0000000000000000000000000000000000000000..ba21487fc427cfc6564874d466ee8628738d62bf GIT binary patch literal 24 ScmeyPr0~wKfkEL98Vvw_tO-v5 literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_fsel.dis b/src/alloy/frontend/ppc/test/bin/instr_fsel.dis new file mode 100644 index 000000000..b2ac1fd55 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_fsel.dis @@ -0,0 +1,17 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_fsel.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: fc 22 20 ee fsel f1,f2,f3,f4 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: fc 22 20 ee fsel f1,f2,f3,f4 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: fc 22 20 ee fsel f1,f2,f3,f4 + 100014: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_fsel.map b/src/alloy/frontend/ppc/test/bin/instr_fsel.map new file mode 100644 index 000000000..ccab66f5f --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_fsel.map @@ -0,0 +1,3 @@ +0000000000000000 t test_fsel_1 +0000000000000008 t test_fsel_2 +0000000000000010 t test_fsel_3 diff --git a/src/alloy/frontend/ppc/test/instr_fsel.s b/src/alloy/frontend/ppc/test/instr_fsel.s new file mode 100644 index 000000000..ca9e52b19 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_fsel.s @@ -0,0 +1,32 @@ +test_fsel_1: + #_ REGISTER_IN f2 2.0 + #_ REGISTER_IN f3 3.0 + #_ REGISTER_IN f4 4.0 + fsel f1, f2, f3, f4 + blr + #_ REGISTER_OUT f1 3.0 + #_ REGISTER_OUT f2 2.0 + #_ REGISTER_OUT f3 3.0 + #_ REGISTER_OUT f4 4.0 + +test_fsel_2: + #_ REGISTER_IN f2 -2.0 + #_ REGISTER_IN f3 3.0 + #_ REGISTER_IN f4 4.0 + fsel f1, f2, f3, f4 + blr + #_ REGISTER_OUT f1 4.0 + #_ REGISTER_OUT f2 -2.0 + #_ REGISTER_OUT f3 3.0 + #_ REGISTER_OUT f4 4.0 + +test_fsel_3: + #_ REGISTER_IN f2 0.0 + #_ REGISTER_IN f3 3.0 + #_ REGISTER_IN f4 4.0 + fsel f1, f2, f3, f4 + blr + #_ REGISTER_OUT f1 3.0 + #_ REGISTER_OUT f2 0.0 + #_ REGISTER_OUT f3 3.0 + #_ REGISTER_OUT f4 4.0 From 58107f34993da7434fca38f6f95f55db673a62bb Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 11 Jan 2015 21:16:04 -0800 Subject: [PATCH 361/388] vpermwi128 tests. --- .../ppc/test/bin/instr_vpermwi128.bin | Bin 0 -> 32 bytes .../ppc/test/bin/instr_vpermwi128.dis | 21 +++++++++++ .../ppc/test/bin/instr_vpermwi128.map | 4 ++ .../frontend/ppc/test/instr_vpermwi128.s | 35 ++++++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vpermwi128.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vpermwi128.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vpermwi128.map create mode 100644 src/alloy/frontend/ppc/test/instr_vpermwi128.s diff --git a/src/alloy/frontend/ppc/test/bin/instr_vpermwi128.bin b/src/alloy/frontend/ppc/test/bin/instr_vpermwi128.bin new file mode 100644 index 0000000000000000000000000000000000000000..db91ea4d3d202427baf6b4b8e25f79ec5a9f6650 GIT binary patch literal 32 acmb1`EhXUBz@Q+}B7Ff&H$eIGA$$OdMhJlb literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vpermwi128.dis b/src/alloy/frontend/ppc/test/bin/instr_vpermwi128.dis new file mode 100644 index 000000000..a805aa45d --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vpermwi128.dis @@ -0,0 +1,21 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vpermwi128.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 18 9b 1a 10 vpermwi128 v4,v3,27 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 18 84 1b d0 vpermwi128 v4,v3,228 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: 18 80 1a 10 vpermwi128 v4,v3,0 + 100014: 4e 80 00 20 blr + +0000000000100018 : + 100018: 18 9f 1b d0 vpermwi128 v4,v3,255 + 10001c: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vpermwi128.map b/src/alloy/frontend/ppc/test/bin/instr_vpermwi128.map new file mode 100644 index 000000000..c698db776 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vpermwi128.map @@ -0,0 +1,4 @@ +0000000000000000 t test_vpermwi128_1 +0000000000000008 t test_vpermwi128_2 +0000000000000010 t test_vpermwi128_3 +0000000000000018 t test_vpermwi128_4 diff --git a/src/alloy/frontend/ppc/test/instr_vpermwi128.s b/src/alloy/frontend/ppc/test/instr_vpermwi128.s new file mode 100644 index 000000000..158a0e608 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vpermwi128.s @@ -0,0 +1,35 @@ +test_vpermwi128_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + # to 0,1,2,3 + # vpermwi128 v4, v3, 0x1B + .long 0x189B1A10 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vpermwi128_2: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + # to 3,2,1,0 + # vpermwi128 v4, v3, 0xE4 + .long 0x18841BD0 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [0C0D0E0F, 08090A0B, 04050607, 00010203] + +test_vpermwi128_3: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + # to 0,0,0,0 + # vpermwi128 v4, v3, 0 + .long 0x18801A10 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [00010203, 00010203, 00010203, 00010203] + +test_vpermwi128_4: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + # to 3,3,3,3 + # vpermwi128 v4, v3, 0xFF + .long 0x189F1BD0 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [0C0D0E0F, 0C0D0E0F, 0C0D0E0F, 0C0D0E0F] From e48d9a44c702b7ef3c17c42140a5c877dac76d14 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 11 Jan 2015 21:21:51 -0800 Subject: [PATCH 362/388] vsldoi tests. --- .../frontend/ppc/test/bin/instr_vsldoi.bin | Bin 0 -> 24 bytes .../frontend/ppc/test/bin/instr_vsldoi.dis | 17 ++++++++++ .../frontend/ppc/test/bin/instr_vsldoi.map | 3 ++ src/alloy/frontend/ppc/test/instr_vsldoi.s | 29 ++++++++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vsldoi.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vsldoi.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vsldoi.map create mode 100644 src/alloy/frontend/ppc/test/instr_vsldoi.s diff --git a/src/alloy/frontend/ppc/test/bin/instr_vsldoi.bin b/src/alloy/frontend/ppc/test/bin/instr_vsldoi.bin new file mode 100644 index 0000000000000000000000000000000000000000..8fda0ff56806045f275d28780c905f31c02c6d7a GIT binary patch literal 24 YcmWewtf1r9z@Q+oSRn^OE58BJ08yO=%K!iX literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vsldoi.dis b/src/alloy/frontend/ppc/test/bin/instr_vsldoi.dis new file mode 100644 index 000000000..cc5a2b16a --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vsldoi.dis @@ -0,0 +1,17 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vsldoi.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 a3 20 2c vsldoi v5,v3,v4,0 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 10 a3 20 6c vsldoi v5,v3,v4,1 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: 10 a3 23 ec vsldoi v5,v3,v4,15 + 100014: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vsldoi.map b/src/alloy/frontend/ppc/test/bin/instr_vsldoi.map new file mode 100644 index 000000000..e9c64fe09 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vsldoi.map @@ -0,0 +1,3 @@ +0000000000000000 t test_vsldoi_1 +0000000000000008 t test_vsldoi_2 +0000000000000010 t test_vsldoi_3 diff --git a/src/alloy/frontend/ppc/test/instr_vsldoi.s b/src/alloy/frontend/ppc/test/instr_vsldoi.s new file mode 100644 index 000000000..7ab577c82 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vsldoi.s @@ -0,0 +1,29 @@ +test_vsldoi_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_IN v5 [00000000, 00000000, 00000000, 00000000] + vsldoi v5, v3, v4, 0 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vsldoi_2: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_IN v5 [00000000, 00000000, 00000000, 00000000] + vsldoi v5, v3, v4, 1 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [01020304, 05060708, 090A0B0C, 0D0E0F10] + +test_vsldoi_3: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_IN v5 [00000000, 00000000, 00000000, 00000000] + vsldoi v5, v3, v4, 0xF + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [0F101112, 13141516, 1718191A, 1B1C1D1E] From 9a666297259f5411b9523ebb2a9457088187b79a Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 11 Jan 2015 21:32:34 -0800 Subject: [PATCH 363/388] vsel tests. --- src/alloy/frontend/ppc/ppc_emit_altivec.cc | 2 ++ .../frontend/ppc/test/bin/instr_vsel.bin | Bin 0 -> 24 bytes .../frontend/ppc/test/bin/instr_vsel.dis | 17 ++++++++++ .../frontend/ppc/test/bin/instr_vsel.map | 3 ++ src/alloy/frontend/ppc/test/instr_vsel.s | 29 ++++++++++++++++++ 5 files changed, 51 insertions(+) create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vsel.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vsel.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vsel.map create mode 100644 src/alloy/frontend/ppc/test/instr_vsel.s diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index 75eb13a23..381634af0 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -1344,6 +1344,8 @@ XEEMITTER(vrsqrtefp128, VX128_3(6, 1648), VX128_3)(PPCHIRBuilder& f, int InstrEmit_vsel_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, uint32_t vc) { + // For each bit: + // VRTi <- ((VRC)i=0) ? (VRA)i : (VRB)i Value* v = f.Select(f.LoadVR(vc), f.LoadVR(va), f.LoadVR(vb)); f.StoreVR(vd, v); return 0; diff --git a/src/alloy/frontend/ppc/test/bin/instr_vsel.bin b/src/alloy/frontend/ppc/test/bin/instr_vsel.bin new file mode 100644 index 0000000000000000000000000000000000000000..c62e03541c6da4fca426fcf1fce3a17507b6156a GIT binary patch literal 24 ScmWewteEB3z@Q+2Mgss;CkBN8 literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vsel.dis b/src/alloy/frontend/ppc/test/bin/instr_vsel.dis new file mode 100644 index 000000000..60fb62fce --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vsel.dis @@ -0,0 +1,17 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vsel.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 a3 21 6a vsel v5,v3,v4,v5 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 10 a3 21 6a vsel v5,v3,v4,v5 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: 10 a3 21 6a vsel v5,v3,v4,v5 + 100014: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vsel.map b/src/alloy/frontend/ppc/test/bin/instr_vsel.map new file mode 100644 index 000000000..41f9acf96 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vsel.map @@ -0,0 +1,3 @@ +0000000000000000 t test_vsel_1 +0000000000000008 t test_vsel_2 +0000000000000010 t test_vsel_3 diff --git a/src/alloy/frontend/ppc/test/instr_vsel.s b/src/alloy/frontend/ppc/test/instr_vsel.s new file mode 100644 index 000000000..7a8863ca1 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vsel.s @@ -0,0 +1,29 @@ +test_vsel_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_IN v5 [00000000, 00000000, 00000000, 00000000] + vsel v5, v3, v4, v5 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [00010203, 04050607, 08090A0B, 0C0D0E0F] + +test_vsel_2: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_IN v5 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF] + vsel v5, v3, v4, v5 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [10111213, 14151617, 18191A1B, 1C1D1E1F] + +test_vsel_3: + #_ REGISTER_IN v3 [0C010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [1D111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_IN v5 [10101010, 10101010, 10101010, 10101010] + vsel v5, v3, v4, v5 + blr + #_ REGISTER_OUT v3 [0C010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [1D111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [1C111213, 14151617, 18191A1B, 1C1D1E1F] From d76db54feeb735ef4b5cdbc83722bae65972aff7 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 14 Jan 2015 17:47:54 -0800 Subject: [PATCH 364/388] Tests for vmrg* (broken! woo!) --- src/alloy/frontend/ppc/test/bin/instr_vmrghb.bin | Bin 0 -> 8 bytes src/alloy/frontend/ppc/test/bin/instr_vmrghb.dis | 9 +++++++++ src/alloy/frontend/ppc/test/bin/instr_vmrghb.map | 1 + src/alloy/frontend/ppc/test/bin/instr_vmrghh.bin | Bin 0 -> 8 bytes src/alloy/frontend/ppc/test/bin/instr_vmrghh.dis | 9 +++++++++ src/alloy/frontend/ppc/test/bin/instr_vmrghh.map | 1 + src/alloy/frontend/ppc/test/bin/instr_vmrghw.bin | Bin 0 -> 8 bytes src/alloy/frontend/ppc/test/bin/instr_vmrghw.dis | 9 +++++++++ src/alloy/frontend/ppc/test/bin/instr_vmrghw.map | 1 + src/alloy/frontend/ppc/test/bin/instr_vmrglb.bin | Bin 0 -> 8 bytes src/alloy/frontend/ppc/test/bin/instr_vmrglb.dis | 9 +++++++++ src/alloy/frontend/ppc/test/bin/instr_vmrglb.map | 1 + src/alloy/frontend/ppc/test/bin/instr_vmrglh.bin | Bin 0 -> 8 bytes src/alloy/frontend/ppc/test/bin/instr_vmrglh.dis | 9 +++++++++ src/alloy/frontend/ppc/test/bin/instr_vmrglh.map | 1 + src/alloy/frontend/ppc/test/bin/instr_vmrglw.bin | Bin 0 -> 8 bytes src/alloy/frontend/ppc/test/bin/instr_vmrglw.dis | 9 +++++++++ src/alloy/frontend/ppc/test/bin/instr_vmrglw.map | 1 + .../frontend/ppc/test/bin/instr_vrlimi128.bin | Bin 72 -> 72 bytes .../frontend/ppc/test/bin/instr_vrlimi128.dis | 4 ++-- src/alloy/frontend/ppc/test/instr_vmrghb.s | 8 ++++++++ src/alloy/frontend/ppc/test/instr_vmrghh.s | 8 ++++++++ src/alloy/frontend/ppc/test/instr_vmrghw.s | 8 ++++++++ src/alloy/frontend/ppc/test/instr_vmrglb.s | 8 ++++++++ src/alloy/frontend/ppc/test/instr_vmrglh.s | 8 ++++++++ src/alloy/frontend/ppc/test/instr_vmrglw.s | 8 ++++++++ 26 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vmrghb.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vmrghb.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vmrghb.map create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vmrghh.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vmrghh.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vmrghh.map create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vmrghw.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vmrghw.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vmrghw.map create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vmrglb.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vmrglb.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vmrglb.map create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vmrglh.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vmrglh.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vmrglh.map create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vmrglw.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vmrglw.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vmrglw.map create mode 100644 src/alloy/frontend/ppc/test/instr_vmrghb.s create mode 100644 src/alloy/frontend/ppc/test/instr_vmrghh.s create mode 100644 src/alloy/frontend/ppc/test/instr_vmrghw.s create mode 100644 src/alloy/frontend/ppc/test/instr_vmrglb.s create mode 100644 src/alloy/frontend/ppc/test/instr_vmrglh.s create mode 100644 src/alloy/frontend/ppc/test/instr_vmrglw.s diff --git a/src/alloy/frontend/ppc/test/bin/instr_vmrghb.bin b/src/alloy/frontend/ppc/test/bin/instr_vmrghb.bin new file mode 100644 index 0000000000000000000000000000000000000000..7d70f7c7897fd37fe557de451b473303fc46c4dd GIT binary patch literal 8 PcmWewtia>fz@PvC2+;w~ literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vmrghb.dis b/src/alloy/frontend/ppc/test/bin/instr_vmrghb.dis new file mode 100644 index 000000000..cad3a1fec --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vmrghb.dis @@ -0,0 +1,9 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vmrghb.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 a3 20 0c vmrghb v5,v3,v4 + 100004: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vmrghb.map b/src/alloy/frontend/ppc/test/bin/instr_vmrghb.map new file mode 100644 index 000000000..722579e07 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vmrghb.map @@ -0,0 +1 @@ +0000000000000000 t test_vmrghb_1 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vmrghh.bin b/src/alloy/frontend/ppc/test/bin/instr_vmrghh.bin new file mode 100644 index 0000000000000000000000000000000000000000..3db0e559377e8d03cfcb7f446a6650aac0f8cc90 GIT binary patch literal 8 PcmWewtl;C: + 100000: 10 a3 20 4c vmrghh v5,v3,v4 + 100004: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vmrghh.map b/src/alloy/frontend/ppc/test/bin/instr_vmrghh.map new file mode 100644 index 000000000..fa3154185 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vmrghh.map @@ -0,0 +1 @@ +0000000000000000 t test_vmrghh_1 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vmrghw.bin b/src/alloy/frontend/ppc/test/bin/instr_vmrghw.bin new file mode 100644 index 0000000000000000000000000000000000000000..49d6bd213c22217829eb23a16559a644abe9b6f1 GIT binary patch literal 8 PcmWewtkC1vz@PvC3sC}2 literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vmrghw.dis b/src/alloy/frontend/ppc/test/bin/instr_vmrghw.dis new file mode 100644 index 000000000..836fa3ecc --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vmrghw.dis @@ -0,0 +1,9 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vmrghw.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 a3 20 8c vmrghw v5,v3,v4 + 100004: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vmrghw.map b/src/alloy/frontend/ppc/test/bin/instr_vmrghw.map new file mode 100644 index 000000000..6e75d3e31 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vmrghw.map @@ -0,0 +1 @@ +0000000000000000 t test_vmrghw_1 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vmrglb.bin b/src/alloy/frontend/ppc/test/bin/instr_vmrglb.bin new file mode 100644 index 0000000000000000000000000000000000000000..3065726a5467e43bd00979e149c58a454602a532 GIT binary patch literal 8 PcmWewtjOcnz@PvC2-gA6 literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vmrglb.dis b/src/alloy/frontend/ppc/test/bin/instr_vmrglb.dis new file mode 100644 index 000000000..0f0eb6667 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vmrglb.dis @@ -0,0 +1,9 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vmrglb.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 a3 21 0c vmrglb v5,v3,v4 + 100004: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vmrglb.map b/src/alloy/frontend/ppc/test/bin/instr_vmrglb.map new file mode 100644 index 000000000..f453a6a09 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vmrglb.map @@ -0,0 +1 @@ +0000000000000000 t test_vmrglb_1 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vmrglh.bin b/src/alloy/frontend/ppc/test/bin/instr_vmrglh.bin new file mode 100644 index 0000000000000000000000000000000000000000..d057fde54a182bd81fcec28f01827dc040eeea85 GIT binary patch literal 8 PcmWewtmxy{z@PvC3Ks$o literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vmrglh.dis b/src/alloy/frontend/ppc/test/bin/instr_vmrglh.dis new file mode 100644 index 000000000..af22d8548 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vmrglh.dis @@ -0,0 +1,9 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vmrglh.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 a3 21 4c vmrglh v5,v3,v4 + 100004: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vmrglh.map b/src/alloy/frontend/ppc/test/bin/instr_vmrglh.map new file mode 100644 index 000000000..79e7d7303 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vmrglh.map @@ -0,0 +1 @@ +0000000000000000 t test_vmrglh_1 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vmrglw.bin b/src/alloy/frontend/ppc/test/bin/instr_vmrglw.bin new file mode 100644 index 0000000000000000000000000000000000000000..5bd3c388379ee0ba5c8ca05a1a986d690dff9e28 GIT binary patch literal 8 PcmWewtk~n%z@PvC3s(Y9 literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vmrglw.dis b/src/alloy/frontend/ppc/test/bin/instr_vmrglw.dis new file mode 100644 index 000000000..148d0d08a --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vmrglw.dis @@ -0,0 +1,9 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vmrglw.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 a3 21 8c vmrglw v5,v3,v4 + 100004: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vmrglw.map b/src/alloy/frontend/ppc/test/bin/instr_vmrglw.map new file mode 100644 index 000000000..4632cad96 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vmrglw.map @@ -0,0 +1 @@ +0000000000000000 t test_vmrglw_1 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vrlimi128.bin b/src/alloy/frontend/ppc/test/bin/instr_vrlimi128.bin index 954231d04756511295649dd96180f3bb21d070fe..4cddadaff087cc6e99b0c22022c3703ed4b66238 100644 GIT binary patch literal 72 lcmb1WkQeZ4U{H|ghtmO2{sbs}0Zey5: - 100010: 1b 2f d7 55 vrlimi128 v57,v58,15,0 + 100010: 18 8f 1f 50 vrlimi128 v4,v3,15,0 100014: 4e 80 00 20 blr 0000000000100018 : @@ -21,7 +21,7 @@ Disassembly of section .text: 10001c: 4e 80 00 20 blr 0000000000100020 : - 100020: 1a ef c7 d5 vrlimi128 v55,v56,15,2 + 100020: 18 8f 1f d0 vrlimi128 v4,v3,15,2 100024: 4e 80 00 20 blr 0000000000100028 : diff --git a/src/alloy/frontend/ppc/test/instr_vmrghb.s b/src/alloy/frontend/ppc/test/instr_vmrghb.s new file mode 100644 index 000000000..a24a98a86 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vmrghb.s @@ -0,0 +1,8 @@ +test_vmrghb_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + vmrghb v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [00100111, 02120313, 04140515, 06160717] diff --git a/src/alloy/frontend/ppc/test/instr_vmrghh.s b/src/alloy/frontend/ppc/test/instr_vmrghh.s new file mode 100644 index 000000000..826a11b3a --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vmrghh.s @@ -0,0 +1,8 @@ +test_vmrghh_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + vmrghh v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [00011011, 02031213, 04051415, 06071617] diff --git a/src/alloy/frontend/ppc/test/instr_vmrghw.s b/src/alloy/frontend/ppc/test/instr_vmrghw.s new file mode 100644 index 000000000..0aa8f1b08 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vmrghw.s @@ -0,0 +1,8 @@ +test_vmrghw_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + vmrghw v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [00010203, 10111213, 04050607, 14151617] diff --git a/src/alloy/frontend/ppc/test/instr_vmrglb.s b/src/alloy/frontend/ppc/test/instr_vmrglb.s new file mode 100644 index 000000000..c21b25283 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vmrglb.s @@ -0,0 +1,8 @@ +test_vmrglb_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + vmrglb v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [08180919, 0a1a0b1b, 0c1c0d1d, 0e1e0f1f] diff --git a/src/alloy/frontend/ppc/test/instr_vmrglh.s b/src/alloy/frontend/ppc/test/instr_vmrglh.s new file mode 100644 index 000000000..4f1c647df --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vmrglh.s @@ -0,0 +1,8 @@ +test_vmrglh_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + vmrglh v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [08091819, 0a0b1a1b, 0c0d1c1d, 0e0f1e1f] diff --git a/src/alloy/frontend/ppc/test/instr_vmrglw.s b/src/alloy/frontend/ppc/test/instr_vmrglw.s new file mode 100644 index 000000000..5567e9fe0 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vmrglw.s @@ -0,0 +1,8 @@ +test_vmrglw_1: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_IN v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + vmrglw v5, v3, v4 + blr + #_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + #_ REGISTER_OUT v4 [10111213, 14151617, 18191A1B, 1C1D1E1F] + #_ REGISTER_OUT v5 [08090a0b, 18191a1b, 0c0d0e0f, 1c1d1e1f] From 1d4ee3e6fb1dac4a399d97a9979fba5135c1685d Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 14 Jan 2015 17:59:14 -0800 Subject: [PATCH 365/388] vcfsx test --- .../frontend/ppc/test/bin/instr_vcfsx.bin | Bin 0 -> 24 bytes .../frontend/ppc/test/bin/instr_vcfsx.dis | 17 +++++++++++++++ .../frontend/ppc/test/bin/instr_vcfsx.map | 3 +++ src/alloy/frontend/ppc/test/instr_vcfsx.s | 20 ++++++++++++++++++ 4 files changed, 40 insertions(+) create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vcfsx.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vcfsx.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vcfsx.map create mode 100644 src/alloy/frontend/ppc/test/instr_vcfsx.s diff --git a/src/alloy/frontend/ppc/test/bin/instr_vcfsx.bin b/src/alloy/frontend/ppc/test/bin/instr_vcfsx.bin new file mode 100644 index 0000000000000000000000000000000000000000..37185319aa8b0fa034ce1c918c5e030774c7547d GIT binary patch literal 24 VcmWegkoNLxU{DZ9gwk0M8URAs1yuk5 literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vcfsx.dis b/src/alloy/frontend/ppc/test/bin/instr_vcfsx.dis new file mode 100644 index 000000000..4a48e6f4b --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vcfsx.dis @@ -0,0 +1,17 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vcfsx.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 60 1b 4a vcfsx v3,v3,0 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 10 61 1b 4a vcfsx v3,v3,1 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: 10 6a 1b 4a vcfsx v3,v3,10 + 100014: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vcfsx.map b/src/alloy/frontend/ppc/test/bin/instr_vcfsx.map new file mode 100644 index 000000000..73c00c6e1 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vcfsx.map @@ -0,0 +1,3 @@ +0000000000000000 t test_vcfsx_1 +0000000000000008 t test_vcfsx_2 +0000000000000010 t test_vcfsx_3 diff --git a/src/alloy/frontend/ppc/test/instr_vcfsx.s b/src/alloy/frontend/ppc/test/instr_vcfsx.s new file mode 100644 index 000000000..86986f309 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vcfsx.s @@ -0,0 +1,20 @@ +test_vcfsx_1: + #_ REGISTER_IN v3 [3f800000, 3fc00000, 3f8ccccd, 3ff33333] + # 1.0, 1.5, 1.1, 1.9 + vcfsx v3, v3, 0 + blr + #_ REGISTER_OUT v3 [4e7e0000, 4e7f0000, 4e7e3333, 4e7fcccd] + +test_vcfsx_2: + #_ REGISTER_IN v3 [3f800000, 3fc00000, 3f8ccccd, 3ff33333] + # 1.0, 1.5, 1.1, 1.9 + vcfsx v3, v3, 1 + blr + #_ REGISTER_OUT v3 [4dfe0000, 4dff0000, 4dfe3333, 4dffcccd] + +test_vcfsx_3: + #_ REGISTER_IN v3 [3f800000, 3fc00000, 3f8ccccd, 3ff33333] + # 1.0, 1.5, 1.1, 1.9 + vcfsx v3, v3, 10 + blr + #_ REGISTER_OUT v3 [497e0000, 497f0000, 497e3333, 497fcccd] From 9099f597fe9038c1570b38bfc66085a7b8b906ee Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 19 Jan 2015 11:46:14 -0800 Subject: [PATCH 366/388] Test vupkd3d128 and fix short2 unpacking. --- src/alloy/backend/x64/x64_sequences.cc | 5 +- .../ppc/test/bin/instr_vupkd3d128.bin | Bin 0 -> 48 bytes .../ppc/test/bin/instr_vupkd3d128.dis | 29 +++++++++++ .../ppc/test/bin/instr_vupkd3d128.map | 6 +++ .../frontend/ppc/test/instr_vupkd3d128.s | 48 ++++++++++++++++++ 5 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vupkd3d128.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vupkd3d128.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vupkd3d128.map create mode 100644 src/alloy/frontend/ppc/test/instr_vupkd3d128.s diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index 0d0c56270..53995f4c3 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -5364,8 +5364,11 @@ EMITTER(UNPACK, MATCH(I, V128<>>)) { } // Shuffle bytes. e.vpshufb(i.dest, src, e.GetXmmConstPtr(XMMUnpackSHORT_2)); + // Sign extend words. + e.vpslld(i.dest, 16); + e.vpsrad(i.dest, 16); // Add 3,3,0,1. - e.vpor(i.dest, e.GetXmmConstPtr(XMM3301)); + e.vpaddd(i.dest, e.GetXmmConstPtr(XMM3301)); } static void Emit8_IN_16(X64Emitter& e, const EmitArgType& i, uint32_t flags) { assert_false(IsPackOutSaturate(flags)); diff --git a/src/alloy/frontend/ppc/test/bin/instr_vupkd3d128.bin b/src/alloy/frontend/ppc/test/bin/instr_vupkd3d128.bin new file mode 100644 index 0000000000000000000000000000000000000000..a87c63968f6e75c74e0b664f974a301c72f271d3 GIT binary patch literal 48 Ycmb10kpJMi_@% literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vupkd3d128.dis b/src/alloy/frontend/ppc/test/bin/instr_vupkd3d128.dis new file mode 100644 index 000000000..8f6225d63 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vupkd3d128.dis @@ -0,0 +1,29 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vupkd3d128.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 18 60 1f f0 vupkd3d128 v3,v3,0 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 18 64 1f f0 vupkd3d128 v3,v3,4 + 10000c: 4e 80 00 20 blr + +0000000000100010 : + 100010: 18 64 1f f0 vupkd3d128 v3,v3,4 + 100014: 4e 80 00 20 blr + +0000000000100018 : + 100018: 18 64 1f f0 vupkd3d128 v3,v3,4 + 10001c: 4e 80 00 20 blr + +0000000000100020 : + 100020: 18 6c 1f f0 vupkd3d128 v3,v3,12 + 100024: 4e 80 00 20 blr + +0000000000100028 : + 100028: 18 74 1f f0 vupkd3d128 v3,v3,20 + 10002c: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vupkd3d128.map b/src/alloy/frontend/ppc/test/bin/instr_vupkd3d128.map new file mode 100644 index 000000000..1e52624e8 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vupkd3d128.map @@ -0,0 +1,6 @@ +0000000000000000 t test_vupkd3d128_d3dcolor +0000000000000008 t test_vupkd3d128_short2_0 +0000000000000010 t test_vupkd3d128_short2_1 +0000000000000018 t test_vupkd3d128_short2_2 +0000000000000020 t test_vupkd3d128_float16_2_0 +0000000000000028 t test_vupkd3d128_float16_4_0 diff --git a/src/alloy/frontend/ppc/test/instr_vupkd3d128.s b/src/alloy/frontend/ppc/test/instr_vupkd3d128.s new file mode 100644 index 000000000..31800b3a2 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vupkd3d128.s @@ -0,0 +1,48 @@ +# vupkd3d128 dest, src, type +# type: +# 0 = PACK_TYPE_D3DCOLOR +# 1 = PACK_TYPE_SHORT_2 +# 3 = PACK_TYPE_FLOAT16_2 +# 5 = PACK_TYPE_FLOAT16_4 + +# vupkd3d128 is broken in binutils, so these are hand coded + +test_vupkd3d128_d3dcolor: + #_ REGISTER_IN v3 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 04010203] + # vupkd3d128 v3, v3, 0 + .long 0x18601FF0 + blr + #_ REGISTER_OUT v3 [3f800001, 3f800002, 3f800003, 3f800004] + +test_vupkd3d128_short2_0: + #_ REGISTER_IN v3 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 7FFF8001] + # vupkd3d128 v3, v3, 1 + .long 0x18641FF0 + blr + #_ REGISTER_OUT v3 [40407fff, 403f8001, 00000000, 3f800000] +test_vupkd3d128_short2_1: + #_ REGISTER_IN v3 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 4000C000] + # vupkd3d128 v3, v3, 1 + .long 0x18641FF0 + blr + #_ REGISTER_OUT v3 [40404000, 403FC000, 00000000, 3f800000] +test_vupkd3d128_short2_2: + #_ REGISTER_IN v3 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 7FFFF333] + # vupkd3d128 v3, v3, 1 + .long 0x18641FF0 + blr + #_ REGISTER_OUT v3 [40407FFF, 403FF333, 00000000, 3f800000] + +test_vupkd3d128_float16_2_0: + #_ REGISTER_IN v3 [CDCDCDCD, CDCDCDCD, CDCDCDCD, 3800B800] + # vupkd3d128 v3, v3, 3 + .long 0x186C1FF0 + blr + #_ REGISTER_OUT v3 [3F000000, BF000000, 00000000, 3f800000] + +test_vupkd3d128_float16_4_0: + #_ REGISTER_IN v3 [CDCDCDCD, CDCDCDCD, 3800B801, 3802B803] + # vupkd3d128 v3, v3, 5 + .long 0x18741FF0 + blr + #_ REGISTER_OUT v3 [3F000000, bf002000, 3f004000, bf006000] From dd2f799380c28029d22997f770e9ebc63239efec Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 19 Jan 2015 11:52:51 -0800 Subject: [PATCH 367/388] Tests for vupklsh/vupkhsh. --- src/alloy/frontend/ppc/test/bin/instr_vupkhsh.bin | Bin 0 -> 16 bytes src/alloy/frontend/ppc/test/bin/instr_vupkhsh.dis | 13 +++++++++++++ src/alloy/frontend/ppc/test/bin/instr_vupkhsh.map | 2 ++ src/alloy/frontend/ppc/test/bin/instr_vupklsh.bin | Bin 0 -> 16 bytes src/alloy/frontend/ppc/test/bin/instr_vupklsh.dis | 13 +++++++++++++ src/alloy/frontend/ppc/test/bin/instr_vupklsh.map | 2 ++ src/alloy/frontend/ppc/test/instr_vupkhsh.s | 11 +++++++++++ src/alloy/frontend/ppc/test/instr_vupklsh.s | 11 +++++++++++ 8 files changed, 52 insertions(+) create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vupkhsh.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vupkhsh.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vupkhsh.map create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vupklsh.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vupklsh.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vupklsh.map create mode 100644 src/alloy/frontend/ppc/test/instr_vupkhsh.s create mode 100644 src/alloy/frontend/ppc/test/instr_vupklsh.s diff --git a/src/alloy/frontend/ppc/test/bin/instr_vupkhsh.bin b/src/alloy/frontend/ppc/test/bin/instr_vupkhsh.bin new file mode 100644 index 0000000000000000000000000000000000000000..b3873f9d0f6679b741f8c431190901316ccbe640 GIT binary patch literal 16 RcmWegkn;0uU{DZ%(f}TG1C0Ox literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vupkhsh.dis b/src/alloy/frontend/ppc/test/bin/instr_vupkhsh.dis new file mode 100644 index 000000000..045a34f5e --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vupkhsh.dis @@ -0,0 +1,13 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vupkhsh.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 60 1a 4e vupkhsh v3,v3 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 10 60 1a 4e vupkhsh v3,v3 + 10000c: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vupkhsh.map b/src/alloy/frontend/ppc/test/bin/instr_vupkhsh.map new file mode 100644 index 000000000..07205feca --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vupkhsh.map @@ -0,0 +1,2 @@ +0000000000000000 t test_vupkhsh_0 +0000000000000008 t test_vupkhsh_1 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vupklsh.bin b/src/alloy/frontend/ppc/test/bin/instr_vupklsh.bin new file mode 100644 index 0000000000000000000000000000000000000000..342b2dad6a80c8a0c1367f09743a5318939a9ee2 GIT binary patch literal 16 RcmWegkUHnrz@Q)ir2!{&1dRXy literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vupklsh.dis b/src/alloy/frontend/ppc/test/bin/instr_vupklsh.dis new file mode 100644 index 000000000..1d7f0a4c5 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vupklsh.dis @@ -0,0 +1,13 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vupklsh.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 60 1a ce vupklsh v3,v3 + 100004: 4e 80 00 20 blr + +0000000000100008 : + 100008: 10 60 1a ce vupklsh v3,v3 + 10000c: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vupklsh.map b/src/alloy/frontend/ppc/test/bin/instr_vupklsh.map new file mode 100644 index 000000000..fc4c3985c --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vupklsh.map @@ -0,0 +1,2 @@ +0000000000000000 t test_vupklsh_0 +0000000000000008 t test_vupklsh_1 diff --git a/src/alloy/frontend/ppc/test/instr_vupkhsh.s b/src/alloy/frontend/ppc/test/instr_vupkhsh.s new file mode 100644 index 000000000..e4ec3765c --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vupkhsh.s @@ -0,0 +1,11 @@ +test_vupkhsh_0: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vupkhsh v3, v3 + blr + #_ REGISTER_OUT v3 [00000001, 00000203, 00000405, 00000607] + +test_vupkhsh_1: + #_ REGISTER_IN v3 [7F800203, 04050607, 7F800A0B, 0C0D0E0F] + vupkhsh v3, v3 + blr + #_ REGISTER_OUT v3 [00007f80, 00000203, 00000405, 00000607] diff --git a/src/alloy/frontend/ppc/test/instr_vupklsh.s b/src/alloy/frontend/ppc/test/instr_vupklsh.s new file mode 100644 index 000000000..1a4529be8 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vupklsh.s @@ -0,0 +1,11 @@ +test_vupklsh_0: + #_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F] + vupklsh v3, v3 + blr + #_ REGISTER_OUT v3 [00000809, 00000a0b, 00000c0d, 00000e0f] + +test_vupklsh_1: + #_ REGISTER_IN v3 [7F800203, 04050607, 7F800A0B, 0C0D0E0F] + vupklsh v3, v3 + blr + #_ REGISTER_OUT v3 [00007f80, 00000a0b, 00000c0d, 00000e0f] From 88d0c2cfd31df0919ec0dec173d85aa320b8d85c Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 19 Jan 2015 12:13:26 -0800 Subject: [PATCH 368/388] Fixing vupklsh/vupkhsh. --- src/alloy/backend/x64/x64_sequences.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index 53995f4c3..e2e10d4f6 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -5457,6 +5457,7 @@ EMITTER(UNPACK, MATCH(I, V128<>>)) { } } } + e.vpshufd(i.dest, i.dest, 0xB1); } }; EMITTER_OPCODE_TABLE( From acc1286b72792479836065bf61e18881ee934752 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 19 Jan 2015 12:13:43 -0800 Subject: [PATCH 369/388] Disasm path diffs. --- src/alloy/frontend/ppc/test/bin/instr_add.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_addc.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_adde.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_addme.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_addze.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_cntlzd.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_cntlzw.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_divd.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_divdu.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_divw.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_divwu.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_eqv.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_mulhd.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_mulhdu.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_mulhw.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_mulhwu.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_mulld.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_mulli.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_mullw.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_ori.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_rldicl.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_rldicr.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_rlwimi.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_rlwinm.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_rlwnm.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_sld.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_slw.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_srad.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_sradi.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_sraw.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_srawi.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_srd.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_srw.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_subf.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_subfc.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_subfe.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_subfic.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_subfme.dis | 2 +- src/alloy/frontend/ppc/test/bin/instr_subfze.dis | 2 +- 39 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/alloy/frontend/ppc/test/bin/instr_add.dis b/src/alloy/frontend/ppc/test/bin/instr_add.dis index 73d045571..58963620a 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_add.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_add.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_add.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_add.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_addc.dis b/src/alloy/frontend/ppc/test/bin/instr_addc.dis index 035eaa01d..c113fd618 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_addc.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_addc.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_addc.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_addc.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_adde.dis b/src/alloy/frontend/ppc/test/bin/instr_adde.dis index e40f4b763..6df59b52f 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_adde.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_adde.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_adde.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_adde.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_addme.dis b/src/alloy/frontend/ppc/test/bin/instr_addme.dis index 58c8ef1dc..766dffc5e 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_addme.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_addme.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_addme.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_addme.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_addze.dis b/src/alloy/frontend/ppc/test/bin/instr_addze.dis index c7b64c89a..2209d366d 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_addze.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_addze.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_addze.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_addze.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_cntlzd.dis b/src/alloy/frontend/ppc/test/bin/instr_cntlzd.dis index 6a325968c..f8797e0b1 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_cntlzd.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_cntlzd.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_cntlzd.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_cntlzd.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_cntlzw.dis b/src/alloy/frontend/ppc/test/bin/instr_cntlzw.dis index a1ed5fcf9..842693b66 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_cntlzw.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_cntlzw.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_cntlzw.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_cntlzw.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_divd.dis b/src/alloy/frontend/ppc/test/bin/instr_divd.dis index cfe3fce1f..5b622f6c1 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_divd.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_divd.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_divd.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_divd.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_divdu.dis b/src/alloy/frontend/ppc/test/bin/instr_divdu.dis index bbac0f979..cf260bc48 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_divdu.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_divdu.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_divdu.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_divdu.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_divw.dis b/src/alloy/frontend/ppc/test/bin/instr_divw.dis index b0f0692ac..f4574cf52 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_divw.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_divw.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_divw.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_divw.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_divwu.dis b/src/alloy/frontend/ppc/test/bin/instr_divwu.dis index ec4ca77cb..3e5ca892b 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_divwu.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_divwu.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_divwu.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_divwu.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_eqv.dis b/src/alloy/frontend/ppc/test/bin/instr_eqv.dis index af9569cd1..4a30e0b5b 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_eqv.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_eqv.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_eqv.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_eqv.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_mulhd.dis b/src/alloy/frontend/ppc/test/bin/instr_mulhd.dis index 90857255f..8011360e9 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_mulhd.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_mulhd.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_mulhd.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_mulhd.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_mulhdu.dis b/src/alloy/frontend/ppc/test/bin/instr_mulhdu.dis index 119d18321..6f89b2ffb 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_mulhdu.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_mulhdu.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_mulhdu.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_mulhdu.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_mulhw.dis b/src/alloy/frontend/ppc/test/bin/instr_mulhw.dis index 8f68aaad6..451f1efe5 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_mulhw.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_mulhw.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_mulhw.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_mulhw.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_mulhwu.dis b/src/alloy/frontend/ppc/test/bin/instr_mulhwu.dis index 66f385528..1be6b924f 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_mulhwu.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_mulhwu.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_mulhwu.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_mulhwu.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_mulld.dis b/src/alloy/frontend/ppc/test/bin/instr_mulld.dis index f1df8455c..68c20c90b 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_mulld.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_mulld.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_mulld.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_mulld.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_mulli.dis b/src/alloy/frontend/ppc/test/bin/instr_mulli.dis index 716cefe73..bca53580e 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_mulli.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_mulli.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_mulli.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_mulli.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_mullw.dis b/src/alloy/frontend/ppc/test/bin/instr_mullw.dis index 9899025fa..4e295346c 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_mullw.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_mullw.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_mullw.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_mullw.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_ori.dis b/src/alloy/frontend/ppc/test/bin/instr_ori.dis index c34e05f06..c947e25ad 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_ori.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_ori.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_ori.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_ori.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_rldicl.dis b/src/alloy/frontend/ppc/test/bin/instr_rldicl.dis index 6aea8f574..226852357 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_rldicl.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_rldicl.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_rldicl.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_rldicl.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_rldicr.dis b/src/alloy/frontend/ppc/test/bin/instr_rldicr.dis index 7487f0ee5..5e5546a69 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_rldicr.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_rldicr.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_rldicr.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_rldicr.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_rlwimi.dis b/src/alloy/frontend/ppc/test/bin/instr_rlwimi.dis index 030025062..59c25b491 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_rlwimi.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_rlwimi.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_rlwimi.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_rlwimi.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_rlwinm.dis b/src/alloy/frontend/ppc/test/bin/instr_rlwinm.dis index 6434e67e9..f7214a092 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_rlwinm.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_rlwinm.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_rlwinm.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_rlwinm.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_rlwnm.dis b/src/alloy/frontend/ppc/test/bin/instr_rlwnm.dis index 9b4938e99..84eb6d939 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_rlwnm.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_rlwnm.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_rlwnm.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_rlwnm.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_sld.dis b/src/alloy/frontend/ppc/test/bin/instr_sld.dis index 440acdecb..602090951 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_sld.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_sld.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_sld.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_sld.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_slw.dis b/src/alloy/frontend/ppc/test/bin/instr_slw.dis index 195ab1f30..654fa9779 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_slw.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_slw.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_slw.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_slw.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_srad.dis b/src/alloy/frontend/ppc/test/bin/instr_srad.dis index 25fd4f8a9..ab9b64ac8 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_srad.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_srad.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_srad.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_srad.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_sradi.dis b/src/alloy/frontend/ppc/test/bin/instr_sradi.dis index c1a976709..65b0f03da 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_sradi.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_sradi.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_sradi.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_sradi.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_sraw.dis b/src/alloy/frontend/ppc/test/bin/instr_sraw.dis index 09e359e0f..fe1d65547 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_sraw.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_sraw.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_sraw.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_sraw.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_srawi.dis b/src/alloy/frontend/ppc/test/bin/instr_srawi.dis index f5aa1dbfa..13e05e784 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_srawi.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_srawi.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_srawi.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_srawi.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_srd.dis b/src/alloy/frontend/ppc/test/bin/instr_srd.dis index d1bf99b49..fc717de5a 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_srd.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_srd.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_srd.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_srd.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_srw.dis b/src/alloy/frontend/ppc/test/bin/instr_srw.dis index e328a5992..c2e8559c6 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_srw.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_srw.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_srw.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_srw.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_subf.dis b/src/alloy/frontend/ppc/test/bin/instr_subf.dis index 7af24bcd7..79d03d3c6 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_subf.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_subf.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_subf.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_subf.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_subfc.dis b/src/alloy/frontend/ppc/test/bin/instr_subfc.dis index e37ae2781..cf77ab4c8 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_subfc.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_subfc.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_subfc.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_subfc.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_subfe.dis b/src/alloy/frontend/ppc/test/bin/instr_subfe.dis index 62ffd2d83..fe4f2cbca 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_subfe.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_subfe.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_subfe.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_subfe.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_subfic.dis b/src/alloy/frontend/ppc/test/bin/instr_subfic.dis index 74b7bc6de..17920075a 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_subfic.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_subfic.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_subfic.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_subfic.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_subfme.dis b/src/alloy/frontend/ppc/test/bin/instr_subfme.dis index b5277b98c..f21dd43b5 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_subfme.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_subfme.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_subfme.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_subfme.o: file format elf64-powerpc Disassembly of section .text: diff --git a/src/alloy/frontend/ppc/test/bin/instr_subfze.dis b/src/alloy/frontend/ppc/test/bin/instr_subfze.dis index 4f98b44c2..df4aa687d 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_subfze.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_subfze.dis @@ -1,5 +1,5 @@ -/cygdrive/d/dev/xenia/src/alloy/frontend/ppc/test/bin//instr_subfze.o: file format elf64-powerpc +/vagrant/src/alloy/frontend/ppc/test/bin//instr_subfze.o: file format elf64-powerpc Disassembly of section .text: From b2e03fa628e125ab225e160371326b29f23f4c6a Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 19 Jan 2015 12:15:10 -0800 Subject: [PATCH 370/388] I don't like it, but fixing permute by int16. --- src/alloy/backend/x64/x64_emitter.cc | 2 +- src/alloy/backend/x64/x64_sequences.cc | 63 +++++++++++++++++++++- src/alloy/backend/x64/x64_thunk_emitter.cc | 1 + src/alloy/backend/x64/x64_thunk_emitter.h | 16 +++--- src/alloy/hir/hir_builder.cc | 1 + src/alloy/test/test_permute.cc | 2 +- 6 files changed, 73 insertions(+), 12 deletions(-) diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index 00723703c..79d904ea9 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -41,7 +41,7 @@ using alloy::runtime::ThreadState; static const size_t MAX_CODE_SIZE = 1 * 1024 * 1024; static const size_t STASH_OFFSET = 32; -static const size_t STASH_OFFSET_HIGH = 32 + 16; +static const size_t STASH_OFFSET_HIGH = 32 + 32; // If we are running with tracing on we have to store the EFLAGS in the stack, // otherwise our calls out to C to print will clear it before DID_CARRY/etc diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index e2e10d4f6..fe422d8f0 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -4958,6 +4958,7 @@ EMITTER_OPCODE_TABLE( // ============================================================================ EMITTER(PERMUTE_I32, MATCH(I, I32<>, V128<>, V128<>>)) { static void Emit(X64Emitter& e, const EmitArgType& i) { + assert_true(i.instr->flags == INT32_TYPE); // Permute words between src2 and src3. // TODO(benvanik): check src3 for zero. if 0, we can use pshufb. if (i.src1.is_constant) { @@ -5006,8 +5007,7 @@ EMITTER(PERMUTE_I32, MATCH(I, I32<>, V128<>, V128<>>)) { } }; EMITTER(PERMUTE_V128, MATCH(I, V128<>, V128<>, V128<>>)) { - static void Emit(X64Emitter& e, const EmitArgType& i) { - assert_true(i.instr->flags == INT8_TYPE); + static void EmitByInt8(X64Emitter& e, const EmitArgType& i) { // TODO(benvanik): find out how to do this with only one temp register! // Permute bytes between src2 and src3. if (i.src3.value->IsConstantZero()) { @@ -5068,6 +5068,65 @@ EMITTER(PERMUTE_V128, MATCH(I, V128<>, V128<>, V128<>>)) e.vpblendvb(i.dest, src2_shuf, src3_shuf, i.dest); } } + + static __m128i EmulateByInt16(void*, __m128i control, __m128i src1, __m128i src2) { + alignas(16) uint16_t c[8]; + alignas(16) uint16_t a[8]; + alignas(16) uint16_t b[8]; + _mm_store_si128(reinterpret_cast<__m128i*>(c), control); + _mm_store_si128(reinterpret_cast<__m128i*>(a), src1); + _mm_store_si128(reinterpret_cast<__m128i*>(b), src2); + for (size_t i = 0; i < 8; ++i) { + uint16_t si = (c[i] & 0xF) ^ 0x1; + c[i] = si >= 8 ? b[si - 8] : a[si]; + } + return _mm_load_si128(reinterpret_cast<__m128i*>(c)); + } + static void EmitByInt16(X64Emitter& e, const EmitArgType& i) { + // TODO(benvanik): replace with proper version. + assert_true(i.src1.is_constant); + if (i.src1.is_constant) { + e.LoadConstantXmm(e.xmm0, i.src1.constant()); + e.lea(e.r8, e.StashXmm(0, e.xmm0)); + } else { + e.lea(e.r8, e.StashXmm(0, i.src1)); + } + if (i.src2.is_constant) { + e.LoadConstantXmm(e.xmm0, i.src2.constant()); + e.lea(e.r9, e.StashXmm(1, e.xmm0)); + } else { + e.lea(e.r9, e.StashXmm(1, i.src2)); + } + if (i.src3.is_constant) { + e.LoadConstantXmm(e.xmm0, i.src3.constant()); + e.lea(e.r10, e.StashXmm(2, e.xmm0)); + } else { + e.lea(e.r10, e.StashXmm(2, i.src3)); + } + e.CallNativeSafe(reinterpret_cast(EmulateByInt16)); + e.vmovaps(i.dest, e.xmm0); + } + + static void EmitByInt32(X64Emitter& e, const EmitArgType& i) { + assert_always(); + } + + static void Emit(X64Emitter& e, const EmitArgType& i) { + switch (i.instr->flags) { + case INT8_TYPE: + EmitByInt8(e, i); + break; + case INT16_TYPE: + EmitByInt16(e, i); + break; + case INT32_TYPE: + EmitByInt32(e, i); + break; + default: + assert_unhandled_case(i.instr->flags); + return; + } + } }; EMITTER_OPCODE_TABLE( OPCODE_PERMUTE, diff --git a/src/alloy/backend/x64/x64_thunk_emitter.cc b/src/alloy/backend/x64/x64_thunk_emitter.cc index 049377417..999766662 100644 --- a/src/alloy/backend/x64/x64_thunk_emitter.cc +++ b/src/alloy/backend/x64/x64_thunk_emitter.cc @@ -118,6 +118,7 @@ GuestToHostThunk X64ThunkEmitter::EmitGuestToHostThunk() { mov(rax, rdx); mov(rdx, r8); mov(r8, r9); + mov(r9, r10); call(rax); mov(rbx, qword[rsp + 48]); diff --git a/src/alloy/backend/x64/x64_thunk_emitter.h b/src/alloy/backend/x64/x64_thunk_emitter.h index a07b6f0c8..b8b5c612d 100644 --- a/src/alloy/backend/x64/x64_thunk_emitter.h +++ b/src/alloy/backend/x64/x64_thunk_emitter.h @@ -96,14 +96,14 @@ namespace x64 { * | | * | | * +------------------+ - * | scratch, 32b | rsp + 32 + * | scratch, 48b | rsp + 32 * | | * +------------------+ - * | rcx / context | rsp + 64 + * | rcx / context | rsp + 80 * +------------------+ - * | guest ret addr | rsp + 72 + * | guest ret addr | rsp + 88 * +------------------+ - * | call ret addr | rsp + 80 + * | call ret addr | rsp + 96 * +------------------+ * ... locals ... * +------------------+ @@ -116,10 +116,10 @@ class StackLayout { public: const static size_t THUNK_STACK_SIZE = 120; - const static size_t GUEST_STACK_SIZE = 88; - const static size_t GUEST_RCX_HOME = 64; - const static size_t GUEST_RET_ADDR = 72; - const static size_t GUEST_CALL_RET_ADDR = 80; + const static size_t GUEST_STACK_SIZE = 104; + const static size_t GUEST_RCX_HOME = 80; + const static size_t GUEST_RET_ADDR = 88; + const static size_t GUEST_CALL_RET_ADDR = 96; }; class X64ThunkEmitter : public X64Emitter { diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index 62dbe16cf..c981d6915 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -1852,6 +1852,7 @@ Value* HIRBuilder::Splat(Value* value, TypeName target_type) { Value* HIRBuilder::Permute(Value* control, Value* value1, Value* value2, TypeName part_type) { ASSERT_TYPES_EQUAL(value1, value2); + assert_true(part_type >= INT8_TYPE && part_type <= INT32_TYPE); // TODO(benvanik): could do some of this as constants. diff --git a/src/alloy/test/test_permute.cc b/src/alloy/test/test_permute.cc index cacb8635b..8b2f7b6a8 100644 --- a/src/alloy/test/test_permute.cc +++ b/src/alloy/test/test_permute.cc @@ -81,7 +81,7 @@ TEST_CASE("PERMUTE_V128_BY_INT32_CONSTANT", "[instr]") { TEST_CASE("PERMUTE_V128_BY_V128", "[instr]") { TestFunction test([](hir::HIRBuilder& b) { StoreVR(b, 3, - b.Permute(LoadVR(b, 3), LoadVR(b, 4), LoadVR(b, 5), VEC128_TYPE)); + b.Permute(LoadVR(b, 3), LoadVR(b, 4), LoadVR(b, 5), INT8_TYPE)); b.Return(); }); test.Run([](PPCContext* ctx) { From 056d4ed9b0f959bee7817efbd6c493305a1edf94 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 19 Jan 2015 12:24:41 -0800 Subject: [PATCH 371/388] vaddshs/vadduhm/vsubshs/vsubuhm tests. --- src/alloy/frontend/ppc/test/bin/instr_vaddshs.bin | Bin 0 -> 8 bytes src/alloy/frontend/ppc/test/bin/instr_vaddshs.dis | 9 +++++++++ src/alloy/frontend/ppc/test/bin/instr_vaddshs.map | 1 + src/alloy/frontend/ppc/test/bin/instr_vadduhm.bin | Bin 0 -> 8 bytes src/alloy/frontend/ppc/test/bin/instr_vadduhm.dis | 9 +++++++++ src/alloy/frontend/ppc/test/bin/instr_vadduhm.map | 1 + src/alloy/frontend/ppc/test/bin/instr_vsubshs.bin | Bin 0 -> 8 bytes src/alloy/frontend/ppc/test/bin/instr_vsubshs.dis | 9 +++++++++ src/alloy/frontend/ppc/test/bin/instr_vsubshs.map | 1 + src/alloy/frontend/ppc/test/bin/instr_vsubuhm.bin | Bin 0 -> 8 bytes src/alloy/frontend/ppc/test/bin/instr_vsubuhm.dis | 9 +++++++++ src/alloy/frontend/ppc/test/bin/instr_vsubuhm.map | 1 + src/alloy/frontend/ppc/test/instr_vaddshs.s | 7 +++++++ src/alloy/frontend/ppc/test/instr_vadduhm.s | 7 +++++++ src/alloy/frontend/ppc/test/instr_vsubshs.s | 7 +++++++ src/alloy/frontend/ppc/test/instr_vsubuhm.s | 7 +++++++ 16 files changed, 68 insertions(+) create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vaddshs.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vaddshs.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vaddshs.map create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vadduhm.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vadduhm.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vadduhm.map create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vsubshs.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vsubshs.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vsubshs.map create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vsubuhm.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vsubuhm.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vsubuhm.map create mode 100644 src/alloy/frontend/ppc/test/instr_vaddshs.s create mode 100644 src/alloy/frontend/ppc/test/instr_vadduhm.s create mode 100644 src/alloy/frontend/ppc/test/instr_vsubshs.s create mode 100644 src/alloy/frontend/ppc/test/instr_vsubuhm.s diff --git a/src/alloy/frontend/ppc/test/bin/instr_vaddshs.bin b/src/alloy/frontend/ppc/test/bin/instr_vaddshs.bin new file mode 100644 index 0000000000000000000000000000000000000000..a17ec46ba1dd0dfad12efedf3aa234c3fb32835b GIT binary patch literal 8 PcmWegR(9}fU{C-62qyu> literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vaddshs.dis b/src/alloy/frontend/ppc/test/bin/instr_vaddshs.dis new file mode 100644 index 000000000..62ebbba4c --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vaddshs.dis @@ -0,0 +1,9 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vaddshs.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 63 23 40 vaddshs v3,v3,v4 + 100004: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vaddshs.map b/src/alloy/frontend/ppc/test/bin/instr_vaddshs.map new file mode 100644 index 000000000..811e5abb7 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vaddshs.map @@ -0,0 +1 @@ +0000000000000000 t test_vaddshs_1 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vadduhm.bin b/src/alloy/frontend/ppc/test/bin/instr_vadduhm.bin new file mode 100644 index 0000000000000000000000000000000000000000..53fe687b0829b02f33b3b6b69bd011839f5c9f54 GIT binary patch literal 8 PcmWegR&elZU{C-62o(Xs literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vadduhm.dis b/src/alloy/frontend/ppc/test/bin/instr_vadduhm.dis new file mode 100644 index 000000000..696588275 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vadduhm.dis @@ -0,0 +1,9 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vadduhm.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 63 20 40 vadduhm v3,v3,v4 + 100004: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vadduhm.map b/src/alloy/frontend/ppc/test/bin/instr_vadduhm.map new file mode 100644 index 000000000..30ec24c91 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vadduhm.map @@ -0,0 +1 @@ +0000000000000000 t test_vadduhm_1 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vsubshs.bin b/src/alloy/frontend/ppc/test/bin/instr_vsubshs.bin new file mode 100644 index 0000000000000000000000000000000000000000..87035a37fe743daca1bf224bd8e0501903cb6a67 GIT binary patch literal 8 PcmWegR(J4gU{C-62tNVI literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vsubshs.dis b/src/alloy/frontend/ppc/test/bin/instr_vsubshs.dis new file mode 100644 index 000000000..dc1333a0f --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vsubshs.dis @@ -0,0 +1,9 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vsubshs.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 63 27 40 .long 0x10632740 + 100004: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vsubshs.map b/src/alloy/frontend/ppc/test/bin/instr_vsubshs.map new file mode 100644 index 000000000..44c86bc4c --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vsubshs.map @@ -0,0 +1 @@ +0000000000000000 t test_vsubshs_1 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vsubuhm.bin b/src/alloy/frontend/ppc/test/bin/instr_vsubuhm.bin new file mode 100644 index 0000000000000000000000000000000000000000..74071d6837bbef33dc876ed230bd7693ef1c7c30 GIT binary patch literal 8 PcmWegR&nraU{C-62rU7| literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vsubuhm.dis b/src/alloy/frontend/ppc/test/bin/instr_vsubuhm.dis new file mode 100644 index 000000000..af6831d44 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vsubuhm.dis @@ -0,0 +1,9 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vsubuhm.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 63 24 40 vsubuhm v3,v3,v4 + 100004: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vsubuhm.map b/src/alloy/frontend/ppc/test/bin/instr_vsubuhm.map new file mode 100644 index 000000000..0eeae2b33 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vsubuhm.map @@ -0,0 +1 @@ +0000000000000000 t test_vsubuhm_1 diff --git a/src/alloy/frontend/ppc/test/instr_vaddshs.s b/src/alloy/frontend/ppc/test/instr_vaddshs.s new file mode 100644 index 000000000..033b9cf37 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vaddshs.s @@ -0,0 +1,7 @@ +test_vaddshs_1: + #_ REGISTER_IN v3 [7FFF8001, 7FFF8003, 7FFF8005, 80068007] + #_ REGISTER_IN v4 [00018001, 10000000, 42568124, 00000000] + vaddshs v3, v3, v4 + blr + #_ REGISTER_OUT v3 [7fff8000, 7fff8003, 7fff8000, 80068007] + #_ REGISTER_OUT v4 [00018001, 10000000, 42568124, 00000000] diff --git a/src/alloy/frontend/ppc/test/instr_vadduhm.s b/src/alloy/frontend/ppc/test/instr_vadduhm.s new file mode 100644 index 000000000..2d7126d2d --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vadduhm.s @@ -0,0 +1,7 @@ +test_vadduhm_1: + #_ REGISTER_IN v3 [7FFF8001, 7FFF8003, 7FFF8005, 80068007] + #_ REGISTER_IN v4 [00018001, 10000000, 42568124, 00000000] + vadduhm v3, v3, v4 + blr + #_ REGISTER_OUT v3 [80000002, 8fff8003, c2550129, 80068007] + #_ REGISTER_OUT v4 [00018001, 10000000, 42568124, 00000000] diff --git a/src/alloy/frontend/ppc/test/instr_vsubshs.s b/src/alloy/frontend/ppc/test/instr_vsubshs.s new file mode 100644 index 000000000..956f5e31d --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vsubshs.s @@ -0,0 +1,7 @@ +test_vsubshs_1: + #_ REGISTER_IN v3 [7FFF8001, 7FFF8003, 7FFF8005, 80068007] + #_ REGISTER_IN v4 [00018001, 10000000, 42568124, 00000000] + vsubshs v3, v3, v4 + blr + #_ REGISTER_OUT v3 [7ffe0000, 6fff8003, 3da9fee1, 80068007] + #_ REGISTER_OUT v4 [00018001, 10000000, 42568124, 00000000] diff --git a/src/alloy/frontend/ppc/test/instr_vsubuhm.s b/src/alloy/frontend/ppc/test/instr_vsubuhm.s new file mode 100644 index 000000000..7eb9b8a98 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vsubuhm.s @@ -0,0 +1,7 @@ +test_vsubuhm_1: + #_ REGISTER_IN v3 [7FFF8001, 7FFF8003, 7FFF8005, 80068007] + #_ REGISTER_IN v4 [00018001, 10000000, 42568124, 00000000] + vsubuhm v3, v3, v4 + blr + #_ REGISTER_OUT v3 [7ffe0000, 6fff8003, 3da9fee1, 80068007] + #_ REGISTER_OUT v4 [00018001, 10000000, 42568124, 00000000] From b8bb338564757cd1b04e323904bfe8e4c087515b Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Mon, 19 Jan 2015 12:35:43 -0800 Subject: [PATCH 372/388] Removing IVM. --- src/alloy/README.md | 1 - src/alloy/backend/ivm/ivm_assembler.cc | 124 - src/alloy/backend/ivm/ivm_assembler.h | 44 - src/alloy/backend/ivm/ivm_backend.cc | 56 - src/alloy/backend/ivm/ivm_backend.h | 38 - src/alloy/backend/ivm/ivm_function.cc | 176 - src/alloy/backend/ivm/ivm_function.h | 51 - src/alloy/backend/ivm/ivm_intcode.cc | 4287 ----------------- src/alloy/backend/ivm/ivm_intcode.h | 107 - src/alloy/backend/ivm/ivm_stack.cc | 79 - src/alloy/backend/ivm/ivm_stack.h | 51 - src/alloy/backend/ivm/sources.gypi | 15 - src/alloy/backend/sources.gypi | 1 - src/alloy/frontend/ppc/test/alloy-ppc-test.cc | 1 - src/alloy/memory.cc | 32 - src/alloy/memory.h | 20 - src/alloy/runtime/instrument.cc | 1 - src/alloy/runtime/runtime.cc | 13 +- src/alloy/test/alloy-sandbox.cc | 1 - src/alloy/test/util.h | 13 - src/xenia/cpu/processor.cc | 1 - src/xenia/memory.cc | 60 +- src/xenia/memory.h | 9 - 23 files changed, 3 insertions(+), 5178 deletions(-) delete mode 100644 src/alloy/backend/ivm/ivm_assembler.cc delete mode 100644 src/alloy/backend/ivm/ivm_assembler.h delete mode 100644 src/alloy/backend/ivm/ivm_backend.cc delete mode 100644 src/alloy/backend/ivm/ivm_backend.h delete mode 100644 src/alloy/backend/ivm/ivm_function.cc delete mode 100644 src/alloy/backend/ivm/ivm_function.h delete mode 100644 src/alloy/backend/ivm/ivm_intcode.cc delete mode 100644 src/alloy/backend/ivm/ivm_intcode.h delete mode 100644 src/alloy/backend/ivm/ivm_stack.cc delete mode 100644 src/alloy/backend/ivm/ivm_stack.h delete mode 100644 src/alloy/backend/ivm/sources.gypi diff --git a/src/alloy/README.md b/src/alloy/README.md index f3b64bcc8..2cbe29fc6 100644 --- a/src/alloy/README.md +++ b/src/alloy/README.md @@ -26,5 +26,4 @@ A backend takes optimized IR and assembles an implementation-specific result. The backend is also responsible for executing the code it generates and supporting debugging features (such as breakpoints). -* IVM: bytecode interpreter * x64: IA-64 with AVX2 code generator diff --git a/src/alloy/backend/ivm/ivm_assembler.cc b/src/alloy/backend/ivm/ivm_assembler.cc deleted file mode 100644 index a79db653e..000000000 --- a/src/alloy/backend/ivm/ivm_assembler.cc +++ /dev/null @@ -1,124 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace alloy { -namespace backend { -namespace ivm { - -using alloy::hir::HIRBuilder; -using alloy::runtime::DebugInfo; -using alloy::runtime::Function; -using alloy::runtime::FunctionInfo; - -IVMAssembler::IVMAssembler(Backend* backend) - : Assembler(backend), source_map_arena_(128 * 1024) {} - -IVMAssembler::~IVMAssembler() = default; - -int IVMAssembler::Initialize() { - int result = Assembler::Initialize(); - if (result) { - return result; - } - - return result; -} - -void IVMAssembler::Reset() { - intcode_arena_.Reset(); - source_map_arena_.Reset(); - scratch_arena_.Reset(); - Assembler::Reset(); -} - -int IVMAssembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder, - uint32_t debug_info_flags, - std::unique_ptr debug_info, - uint32_t trace_flags, Function** out_function) { - SCOPE_profile_cpu_f("alloy"); - - // Reset when we leave. - make_reset_scope(this); - - IVMFunction* fn = new IVMFunction(symbol_info); - fn->set_debug_info(std::move(debug_info)); - - TranslationContext ctx; - ctx.register_count = 0; - ctx.intcode_count = 0; - ctx.intcode_arena = &intcode_arena_; - ctx.source_map_count = 0; - ctx.source_map_arena = &source_map_arena_; - ctx.scratch_arena = &scratch_arena_; - ctx.label_ref_head = NULL; - - // Reset label tags as we use them. - builder->ResetLabelTags(); - - // Function prologue. - size_t stack_offset = 0; - auto locals = builder->locals(); - for (auto it = locals.begin(); it != locals.end(); ++it) { - auto slot = *it; - size_t type_size = GetTypeSize(slot->type); - // Align to natural size. - stack_offset = poly::align(stack_offset, type_size); - slot->set_constant((uint32_t)stack_offset); - stack_offset += type_size; - } - // Ensure 16b alignment. - stack_offset = poly::align(stack_offset, static_cast(16)); - ctx.stack_size = stack_offset; - - auto block = builder->first_block(); - while (block) { - auto label = block->label_head; - while (label) { - label->tag = (void*)(0x80000000 | ctx.intcode_count); - label = label->next; - } - - auto i = block->instr_head; - while (i) { - TranslateIntCodes(ctx, i); - i = i->next; - } - block = block->next; - } - - // Function epilogue. - - // Fixup label references. - LabelRef* label_ref = ctx.label_ref_head; - while (label_ref) { - label_ref->instr->src1_reg = - (uint32_t)(intptr_t)label_ref->label->tag & ~0x80000000; - label_ref = label_ref->next; - } - - fn->Setup(ctx); - - *out_function = fn; - return 0; -} - -} // namespace ivm -} // namespace backend -} // namespace alloy diff --git a/src/alloy/backend/ivm/ivm_assembler.h b/src/alloy/backend/ivm/ivm_assembler.h deleted file mode 100644 index 118ef69d5..000000000 --- a/src/alloy/backend/ivm/ivm_assembler.h +++ /dev/null @@ -1,44 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_BACKEND_IVM_IVM_ASSEMBLER_H_ -#define ALLOY_BACKEND_IVM_IVM_ASSEMBLER_H_ - -#include -#include - -namespace alloy { -namespace backend { -namespace ivm { - -class IVMAssembler : public Assembler { - public: - IVMAssembler(Backend* backend); - ~IVMAssembler() override; - - int Initialize() override; - - void Reset() override; - - int Assemble(runtime::FunctionInfo* symbol_info, hir::HIRBuilder* builder, - uint32_t debug_info_flags, - std::unique_ptr debug_info, - uint32_t trace_flags, runtime::Function** out_function) override; - - private: - Arena intcode_arena_; - Arena source_map_arena_; - Arena scratch_arena_; -}; - -} // namespace ivm -} // namespace backend -} // namespace alloy - -#endif // ALLOY_BACKEND_IVM_IVM_ASSEMBLER_H_ diff --git a/src/alloy/backend/ivm/ivm_backend.cc b/src/alloy/backend/ivm/ivm_backend.cc deleted file mode 100644 index 171765a36..000000000 --- a/src/alloy/backend/ivm/ivm_backend.cc +++ /dev/null @@ -1,56 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include -#include - -namespace alloy { -namespace backend { -namespace ivm { - -using alloy::runtime::Runtime; - -IVMBackend::IVMBackend(Runtime* runtime) : Backend(runtime) {} - -IVMBackend::~IVMBackend() = default; - -int IVMBackend::Initialize() { - int result = Backend::Initialize(); - if (result) { - return result; - } - - machine_info_.register_sets[0] = { - 0, "gpr", MachineInfo::RegisterSet::INT_TYPES, 16, - }; - machine_info_.register_sets[1] = { - 1, "vec", MachineInfo::RegisterSet::FLOAT_TYPES | - MachineInfo::RegisterSet::VEC_TYPES, - 16, - }; - - return result; -} - -void* IVMBackend::AllocThreadData() { return new IVMStack(); } - -void IVMBackend::FreeThreadData(void* thread_data) { - auto stack = (IVMStack*)thread_data; - delete stack; -} - -std::unique_ptr IVMBackend::CreateAssembler() { - return std::make_unique(this); -} - -} // namespace ivm -} // namespace backend -} // namespace alloy diff --git a/src/alloy/backend/ivm/ivm_backend.h b/src/alloy/backend/ivm/ivm_backend.h deleted file mode 100644 index 46814353b..000000000 --- a/src/alloy/backend/ivm/ivm_backend.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_BACKEND_IVM_IVM_BACKEND_H_ -#define ALLOY_BACKEND_IVM_IVM_BACKEND_H_ - -#include - -namespace alloy { -namespace backend { -namespace ivm { - -#define ALLOY_HAS_IVM_BACKEND 1 - -class IVMBackend : public Backend { - public: - IVMBackend(runtime::Runtime* runtime); - ~IVMBackend() override; - - int Initialize() override; - - void* AllocThreadData() override; - void FreeThreadData(void* thread_data) override; - - std::unique_ptr CreateAssembler() override; -}; - -} // namespace ivm -} // namespace backend -} // namespace alloy - -#endif // ALLOY_BACKEND_IVM_IVM_BACKEND_H_ diff --git a/src/alloy/backend/ivm/ivm_function.cc b/src/alloy/backend/ivm/ivm_function.cc deleted file mode 100644 index fa99c5a11..000000000 --- a/src/alloy/backend/ivm/ivm_function.cc +++ /dev/null @@ -1,176 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include -#include -#include - -namespace alloy { -namespace backend { -namespace ivm { - -using alloy::runtime::Breakpoint; -using alloy::runtime::FunctionInfo; -using alloy::runtime::ThreadState; - -IVMFunction::IVMFunction(FunctionInfo* symbol_info) - : Function(symbol_info), - register_count_(0), - intcode_count_(0), - intcodes_(nullptr), - source_map_count_(0), - source_map_(nullptr) {} - -IVMFunction::~IVMFunction() { - free(intcodes_); - free(source_map_); -} - -void IVMFunction::Setup(TranslationContext& ctx) { - register_count_ = ctx.register_count; - stack_size_ = ctx.stack_size; - intcode_count_ = ctx.intcode_count; - intcodes_ = (IntCode*)ctx.intcode_arena->CloneContents(); - source_map_count_ = ctx.source_map_count; - source_map_ = (SourceMapEntry*)ctx.source_map_arena->CloneContents(); -} - -IntCode* IVMFunction::GetIntCodeAtSourceOffset(uint64_t offset) { - for (size_t n = 0; n < source_map_count_; n++) { - auto entry = &source_map_[n]; - if (entry->source_offset == offset) { - return &intcodes_[entry->intcode_index]; - } - } - return NULL; -} - -int IVMFunction::AddBreakpointImpl(Breakpoint* breakpoint) { - auto i = GetIntCodeAtSourceOffset(breakpoint->address()); - if (!i) { - return 1; - } - - // TEMP breakpoints always overwrite normal ones. - if (!i->debug_flags || breakpoint->type() == Breakpoint::TEMP_TYPE) { - uint64_t breakpoint_ptr = (uint64_t)breakpoint; - i->src2_reg = (uint32_t)breakpoint_ptr; - i->src3_reg = (uint32_t)(breakpoint_ptr >> 32); - } - - // Increment breakpoint counter. - ++i->debug_flags; - - return 0; -} - -int IVMFunction::RemoveBreakpointImpl(Breakpoint* breakpoint) { - auto i = GetIntCodeAtSourceOffset(breakpoint->address()); - if (!i) { - return 1; - } - - // Decrement breakpoint counter. - --i->debug_flags; - i->src2_reg = i->src3_reg = 0; - - // If there were other breakpoints, see what they were. - if (i->debug_flags) { - auto old_breakpoint = FindBreakpoint(breakpoint->address()); - if (old_breakpoint) { - uint64_t breakpoint_ptr = (uint64_t)old_breakpoint; - i->src2_reg = (uint32_t)breakpoint_ptr; - i->src3_reg = (uint32_t)(breakpoint_ptr >> 32); - } - } - - return 0; -} - -void IVMFunction::OnBreakpointHit(ThreadState* thread_state, IntCode* i) { - uint64_t breakpoint_ptr = i->src2_reg | (uint64_t(i->src3_reg) << 32); - Breakpoint* breakpoint = (Breakpoint*)breakpoint_ptr; - - // Notify debugger. - // The debugger may choose to wait (blocking us). - auto debugger = thread_state->runtime()->debugger(); - debugger->OnBreakpointHit(thread_state, breakpoint); -} - -#undef TRACE_SOURCE_OFFSET - -int IVMFunction::CallImpl(ThreadState* thread_state, uint64_t return_address) { - // Setup register file on stack. - auto stack = (IVMStack*)thread_state->backend_data(); - auto register_file = (Register*)stack->Alloc(register_count_); - auto local_stack = (uint8_t*)alloca(stack_size_); - - Memory* memory = thread_state->memory(); - - IntCodeState ics; - ics.rf = register_file; - ics.locals = local_stack; - ics.context = (uint8_t*)thread_state->raw_context(); - ics.membase = memory->membase(); - ics.did_carry = 0; - ics.did_saturate = 0; - ics.thread_state = thread_state; - ics.return_address = return_address; - ics.call_return_address = 0; - -// TODO(benvanik): DID_CARRY -- need HIR to set a OPCODE_FLAG_SET_CARRY -// or something so the fns can set an ics flag. - -#ifdef TRACE_SOURCE_OFFSET - size_t source_index = 0; -#endif - - uint32_t ia = 0; - while (true) { -#ifdef TRACE_SOURCE_OFFSET - uint64_t source_offset = -1; - if (source_index < this->source_map_count_ && - this->source_map_[source_index].intcode_index <= ia) { - while (source_index + 1 < this->source_map_count_ && - this->source_map_[source_index + 1].intcode_index <= ia) { - source_index++; - } - source_offset = this->source_map_[source_index].source_offset; - } -#endif - - IntCode* i = &intcodes_[ia]; - - if (i->debug_flags) { - OnBreakpointHit(thread_state, i); - } - - uint32_t new_ia = i->intcode_fn(ics, i); - if (new_ia == IA_NEXT) { - ia++; - } else if (new_ia == IA_RETURN) { - break; - } else { - ia = new_ia; -#ifdef TRACE_SOURCE_OFFSET - source_index = 0; -#endif - } - } - - stack->Free(register_count_); - - return 0; -} - -} // namespace ivm -} // namespace backend -} // namespace alloy diff --git a/src/alloy/backend/ivm/ivm_function.h b/src/alloy/backend/ivm/ivm_function.h deleted file mode 100644 index 31eb07084..000000000 --- a/src/alloy/backend/ivm/ivm_function.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_BACKEND_IVM_IVM_FUNCTION_H_ -#define ALLOY_BACKEND_IVM_IVM_FUNCTION_H_ - -#include -#include -#include - -namespace alloy { -namespace backend { -namespace ivm { - -class IVMFunction : public runtime::Function { - public: - IVMFunction(runtime::FunctionInfo* symbol_info); - virtual ~IVMFunction(); - - void Setup(TranslationContext& ctx); - - protected: - virtual int AddBreakpointImpl(runtime::Breakpoint* breakpoint); - virtual int RemoveBreakpointImpl(runtime::Breakpoint* breakpoint); - virtual int CallImpl(runtime::ThreadState* thread_state, - uint64_t return_address); - - private: - IntCode* GetIntCodeAtSourceOffset(uint64_t offset); - void OnBreakpointHit(runtime::ThreadState* thread_state, IntCode* i); - - private: - size_t register_count_; - size_t stack_size_; - size_t intcode_count_; - IntCode* intcodes_; - size_t source_map_count_; - SourceMapEntry* source_map_; -}; - -} // namespace ivm -} // namespace backend -} // namespace alloy - -#endif // ALLOY_BACKEND_IVM_IVM_FUNCTION_H_ diff --git a/src/alloy/backend/ivm/ivm_intcode.cc b/src/alloy/backend/ivm/ivm_intcode.cc deleted file mode 100644 index 8c2b55d7d..000000000 --- a/src/alloy/backend/ivm/ivm_intcode.cc +++ /dev/null @@ -1,4287 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include - -#include -#include -#include -#include -#include -#include - -// TODO(benvanik): make a compile time flag? -//#define DYNAMIC_REGISTER_ACCESS_CHECK(address) false -#define DYNAMIC_REGISTER_ACCESS_CHECK(address) \ - ((address & 0xFF000000) == 0x7F000000) - -namespace alloy { -namespace backend { -namespace ivm { - -// TODO(benvanik): remove when enums redefined. -using namespace alloy::hir; - -using alloy::hir::Instr; -using alloy::hir::Label; -using alloy::hir::OpcodeInfo; -using alloy::hir::OpcodeSignatureType; -using alloy::hir::TypeName; -using alloy::hir::Value; -using alloy::runtime::Function; -using alloy::runtime::FunctionInfo; - -#define IPRINT(...) (void()) -#define IFLUSH() (void()) -#define DPRINT(...) (void()) -#define DFLUSH() (void()) - -//#define IPRINT \ -// if (ics.thread_state->thread_id() == 1) printf -//#define IFLUSH() fflush(stdout) -//#define DPRINT \ -// if (ics.thread_state->thread_id() == 1) printf -//#define DFLUSH() fflush(stdout) - -uint32_t IntCode_INT_LOAD_CONSTANT(IntCodeState& ics, const IntCode* i) { - // TODO(benvanik): optimize on type to avoid 16b copy per load. - ics.rf[i->dest_reg].v128 = i->constant.v128; - return IA_NEXT; -} - -uint32_t AllocConstant(TranslationContext& ctx, uint64_t value, - IntCode** out_ic = NULL) { - ctx.intcode_count++; - IntCode* ic = ctx.intcode_arena->Alloc(); - ic->intcode_fn = IntCode_INT_LOAD_CONSTANT; - ic->flags = 0; - ic->debug_flags = 0; - ic->dest_reg = ctx.register_count++; - ic->constant.u64 = value; - if (out_ic) { - *out_ic = ic; - } - return ic->dest_reg; -} - -uint32_t AllocConstant(TranslationContext& ctx, Value* value) { - ctx.intcode_count++; - IntCode* ic = ctx.intcode_arena->Alloc(); - ic->intcode_fn = IntCode_INT_LOAD_CONSTANT; - ic->flags = 0; - ic->debug_flags = 0; - ic->dest_reg = ctx.register_count++; - ic->constant.v128 = value->constant.v128; - return ic->dest_reg; -} - -uint32_t AllocLabel(TranslationContext& ctx, Label* label) { - // If it's a back-branch to an already tagged label avoid setting up - // a reference. - uint32_t value = - static_cast(reinterpret_cast(label->tag)); - if (value & 0x80000000) { - // Already set. - return AllocConstant(ctx, value & ~0x80000000); - } - - // Allocate a constant - it will be updated later. - IntCode* ic; - uint32_t reg = AllocConstant(ctx, 0, &ic); - - // Setup a label reference. After assembly is complete this will - // run through and fix up the constant with the IA. - LabelRef* label_ref = ctx.scratch_arena->Alloc(); - label_ref->next = ctx.label_ref_head; - ctx.label_ref_head = label_ref; - label_ref->label = label; - label_ref->instr = ic; - - return reg; -} - -uint32_t AllocDynamicRegister(TranslationContext& ctx, Value* value) { - if (value->flags & VALUE_IS_ALLOCATED) { - return static_cast(reinterpret_cast(value->tag)); - } else { - value->flags |= VALUE_IS_ALLOCATED; - auto reg = ctx.register_count++; - value->tag = reinterpret_cast(static_cast(reg)); - return (uint32_t)reg; - } -} - -uint32_t AllocOpRegister(TranslationContext& ctx, OpcodeSignatureType sig_type, - Instr::Op* op) { - switch (sig_type) { - case OPCODE_SIG_TYPE_X: - // Nothing. - return 0; - case OPCODE_SIG_TYPE_L: - return AllocLabel(ctx, op->label); - case OPCODE_SIG_TYPE_O: - return AllocConstant(ctx, (uint64_t)op->offset); - case OPCODE_SIG_TYPE_S: - return AllocConstant(ctx, (uint64_t)op->symbol_info); - case OPCODE_SIG_TYPE_V: - Value* value = op->value; - if (value->IsConstant()) { - return AllocConstant(ctx, value); - } else { - return AllocDynamicRegister(ctx, value); - } - } - return 0; -} - -uint32_t IntCode_INVALID(IntCodeState& ics, const IntCode* i); -uint32_t IntCode_INVALID_TYPE(IntCodeState& ics, const IntCode* i); -int DispatchToC(TranslationContext& ctx, Instr* i, IntCodeFn fn) { - assert_true(fn != IntCode_INVALID); - assert_true(fn != IntCode_INVALID_TYPE); - - const OpcodeInfo* op = i->opcode; - uint32_t sig = op->signature; - OpcodeSignatureType dest_type = GET_OPCODE_SIG_TYPE_DEST(sig); - OpcodeSignatureType src1_type = GET_OPCODE_SIG_TYPE_SRC1(sig); - OpcodeSignatureType src2_type = GET_OPCODE_SIG_TYPE_SRC2(sig); - OpcodeSignatureType src3_type = GET_OPCODE_SIG_TYPE_SRC3(sig); - - // Setup arguments. - uint32_t dest_reg = 0; - if (dest_type == OPCODE_SIG_TYPE_V) { - // Allocate dest register. - dest_reg = AllocDynamicRegister(ctx, i->dest); - } - uint32_t src1_reg = AllocOpRegister(ctx, src1_type, &i->src1); - uint32_t src2_reg = AllocOpRegister(ctx, src2_type, &i->src2); - uint32_t src3_reg = AllocOpRegister(ctx, src3_type, &i->src3); - - // Allocate last (in case we had any setup instructions for args). - ctx.intcode_count++; - IntCode* ic = ctx.intcode_arena->Alloc(); - ic->intcode_fn = fn; - ic->flags = i->flags; - ic->debug_flags = 0; - ic->dest_reg = dest_reg; - ic->src1_reg = src1_reg; - ic->src2_reg = src2_reg; - ic->src3_reg = src3_reg; - - return 0; -} - -uint32_t IntCode_INVALID(IntCodeState& ics, const IntCode* i) { - assert_always(); - return IA_NEXT; -} -uint32_t IntCode_INVALID_TYPE(IntCodeState& ics, const IntCode* i) { - assert_always(); - return IA_NEXT; -} -int TranslateInvalid(TranslationContext& ctx, Instr* i) { - return DispatchToC(ctx, i, IntCode_INVALID); -} - -uint32_t IntCode_COMMENT(IntCodeState& ics, const IntCode* i) { - char* value = (char*)(i->src1_reg | ((uint64_t)i->src2_reg << 32)); - (void)(value); - IPRINT("XE[t] :%d: %s\n", ics.thread_state->thread_id(), value); - IFLUSH(); - return IA_NEXT; -} -int Translate_COMMENT(TranslationContext& ctx, Instr* i) { - ctx.intcode_count++; - IntCode* ic = ctx.intcode_arena->Alloc(); - ic->intcode_fn = IntCode_COMMENT; - ic->flags = i->flags; - ic->debug_flags = 0; - // HACK HACK HACK - char* src = strdup(reinterpret_cast(i->src1.offset)); - uint64_t src_p = (uint64_t)src; - ic->src1_reg = (uint32_t)src_p; - ic->src2_reg = (uint32_t)(src_p >> 32); - return 0; -} - -uint32_t IntCode_NOP(IntCodeState& ics, const IntCode* i) { return IA_NEXT; } -int Translate_NOP(TranslationContext& ctx, Instr* i) { - return DispatchToC(ctx, i, IntCode_NOP); -} - -uint32_t IntCode_SOURCE_OFFSET(IntCodeState& ics, const IntCode* i) { - return IA_NEXT; -} -int Translate_SOURCE_OFFSET(TranslationContext& ctx, Instr* i) { - int result = DispatchToC(ctx, i, IntCode_SOURCE_OFFSET); - if (result) { - return result; - } - auto entry = ctx.source_map_arena->Alloc(); - entry->intcode_index = ctx.intcode_count - 1; - entry->source_offset = i->src1.offset; - ctx.source_map_count++; - return 0; -} - -// TODO(benvanik): dispatch of register forms. -uint32_t IntCode_TRACE_SOURCE(IntCodeState& ics, const IntCode* i) { - uint64_t trace_base = ics.thread_state->memory()->trace_base(); - if (trace_base) { - auto ev = xdb::protocol::InstrEvent::Append(trace_base); - ev->type = xdb::protocol::EventType::INSTR; - ev->thread_id = ics.thread_state->thread_id(); - ev->address = ics.rf[i->src1_reg].i32; - } - return IA_NEXT; -} -int Translate_TRACE_SOURCE(TranslationContext& ctx, Instr* i) { - return DispatchToC(ctx, i, IntCode_TRACE_SOURCE); -} - -uint32_t IntCode_DEBUG_BREAK(IntCodeState& ics, const IntCode* i) { - DFLUSH(); - __debugbreak(); - return IA_NEXT; -} -int Translate_DEBUG_BREAK(TranslationContext& ctx, Instr* i) { - return DispatchToC(ctx, i, IntCode_DEBUG_BREAK); -} - -uint32_t IntCode_DEBUG_BREAK_TRUE_I8(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u8) { - return IntCode_DEBUG_BREAK(ics, i); - } - return IA_NEXT; -} -uint32_t IntCode_DEBUG_BREAK_TRUE_I16(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u16) { - return IntCode_DEBUG_BREAK(ics, i); - } - return IA_NEXT; -} -uint32_t IntCode_DEBUG_BREAK_TRUE_I32(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u32) { - return IntCode_DEBUG_BREAK(ics, i); - } - return IA_NEXT; -} -uint32_t IntCode_DEBUG_BREAK_TRUE_I64(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u64) { - return IntCode_DEBUG_BREAK(ics, i); - } - return IA_NEXT; -} -uint32_t IntCode_DEBUG_BREAK_TRUE_F32(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].f32) { - return IntCode_DEBUG_BREAK(ics, i); - } - return IA_NEXT; -} -uint32_t IntCode_DEBUG_BREAK_TRUE_F64(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].f64) { - return IntCode_DEBUG_BREAK(ics, i); - } - return IA_NEXT; -} -int Translate_DEBUG_BREAK_TRUE(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_DEBUG_BREAK_TRUE_I8, IntCode_DEBUG_BREAK_TRUE_I16, - IntCode_DEBUG_BREAK_TRUE_I32, IntCode_DEBUG_BREAK_TRUE_I64, - IntCode_DEBUG_BREAK_TRUE_F32, IntCode_DEBUG_BREAK_TRUE_F64, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_TRAP(IntCodeState& ics, const IntCode* i) { - // TODO(benvanik): post software interrupt to debugger. - switch (i->flags) { - case 20: - // 0x0FE00014 is a 'debug print' where r3 = buffer r4 = length - return IA_NEXT; - case 22: - // Always trap? - break; - } - __debugbreak(); - return IA_NEXT; -} -int Translate_TRAP(TranslationContext& ctx, Instr* i) { - return DispatchToC(ctx, i, IntCode_TRAP); -} - -uint32_t IntCode_TRAP_TRUE_I8(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u8) { - return IntCode_TRAP(ics, i); - } - return IA_NEXT; -} -uint32_t IntCode_TRAP_TRUE_I16(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u16) { - return IntCode_TRAP(ics, i); - } - return IA_NEXT; -} -uint32_t IntCode_TRAP_TRUE_I32(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u32) { - return IntCode_TRAP(ics, i); - } - return IA_NEXT; -} -uint32_t IntCode_TRAP_TRUE_I64(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u64) { - return IntCode_TRAP(ics, i); - } - return IA_NEXT; -} -uint32_t IntCode_TRAP_TRUE_F32(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].f32) { - return IntCode_TRAP(ics, i); - } - return IA_NEXT; -} -uint32_t IntCode_TRAP_TRUE_F64(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].f64) { - return IntCode_TRAP(ics, i); - } - return IA_NEXT; -} -int Translate_TRAP_TRUE(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_TRAP_TRUE_I8, IntCode_TRAP_TRUE_I16, IntCode_TRAP_TRUE_I32, - IntCode_TRAP_TRUE_I64, IntCode_TRAP_TRUE_F32, IntCode_TRAP_TRUE_F64, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_CALL_XX(IntCodeState& ics, const IntCode* i, uint32_t reg) { - FunctionInfo* symbol_info = (FunctionInfo*)ics.rf[reg].u64; - Function* fn = symbol_info->function(); - if (!fn) { - ics.thread_state->runtime()->ResolveFunction(symbol_info->address(), &fn); - } - assert_not_null(fn); - // TODO(benvanik): proper tail call support, somehow. - uint64_t return_address = - (i->flags & CALL_TAIL) ? ics.return_address : ics.call_return_address; - fn->Call(ics.thread_state, return_address); - if (i->flags & CALL_TAIL) { - return IA_RETURN; - } - return IA_NEXT; -} -uint32_t IntCode_CALL(IntCodeState& ics, const IntCode* i) { - return IntCode_CALL_XX(ics, i, i->src1_reg); -} -int Translate_CALL(TranslationContext& ctx, Instr* i) { - return DispatchToC(ctx, i, IntCode_CALL); -} - -uint32_t IntCode_CALL_TRUE_I8(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u8) { - return IntCode_CALL_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -uint32_t IntCode_CALL_TRUE_I16(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u16) { - return IntCode_CALL_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -uint32_t IntCode_CALL_TRUE_I32(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u32) { - return IntCode_CALL_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -uint32_t IntCode_CALL_TRUE_I64(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u64) { - return IntCode_CALL_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -uint32_t IntCode_CALL_TRUE_F32(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].f32) { - return IntCode_CALL_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -uint32_t IntCode_CALL_TRUE_F64(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].f64) { - return IntCode_CALL_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -int Translate_CALL_TRUE(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_CALL_TRUE_I8, IntCode_CALL_TRUE_I16, IntCode_CALL_TRUE_I32, - IntCode_CALL_TRUE_I64, IntCode_CALL_TRUE_F32, IntCode_CALL_TRUE_F64, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_CALL_INDIRECT_XX(IntCodeState& ics, const IntCode* i, - uint32_t reg) { - uint64_t target = ics.rf[reg].u32; - - // Check if return address - if so, return. - if (i->flags & CALL_POSSIBLE_RETURN) { - if (target == ics.return_address) { - return IA_RETURN; - } - } - - // Real call. - Function* fn = NULL; - ics.thread_state->runtime()->ResolveFunction(target, &fn); - assert_not_null(fn); - // TODO(benvanik): proper tail call support, somehow. - uint64_t return_address = - (i->flags & CALL_TAIL) ? ics.return_address : ics.call_return_address; - fn->Call(ics.thread_state, return_address); - if (i->flags & CALL_TAIL) { - return IA_RETURN; - } - return IA_NEXT; -} -uint32_t IntCode_CALL_INDIRECT(IntCodeState& ics, const IntCode* i) { - return IntCode_CALL_INDIRECT_XX(ics, i, i->src1_reg); -} -int Translate_CALL_INDIRECT(TranslationContext& ctx, Instr* i) { - return DispatchToC(ctx, i, IntCode_CALL_INDIRECT); -} - -uint32_t IntCode_CALL_INDIRECT_TRUE_I8(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u8) { - return IntCode_CALL_INDIRECT_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -uint32_t IntCode_CALL_INDIRECT_TRUE_I16(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u16) { - return IntCode_CALL_INDIRECT_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -uint32_t IntCode_CALL_INDIRECT_TRUE_I32(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u32) { - return IntCode_CALL_INDIRECT_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -uint32_t IntCode_CALL_INDIRECT_TRUE_I64(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u64) { - return IntCode_CALL_INDIRECT_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -uint32_t IntCode_CALL_INDIRECT_TRUE_F32(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].f32) { - return IntCode_CALL_INDIRECT_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -uint32_t IntCode_CALL_INDIRECT_TRUE_F64(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].f64) { - return IntCode_CALL_INDIRECT_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -int Translate_CALL_INDIRECT_TRUE(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_CALL_INDIRECT_TRUE_I8, IntCode_CALL_INDIRECT_TRUE_I16, - IntCode_CALL_INDIRECT_TRUE_I32, IntCode_CALL_INDIRECT_TRUE_I64, - IntCode_CALL_INDIRECT_TRUE_F32, IntCode_CALL_INDIRECT_TRUE_F64, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_CALL_EXTERN(IntCodeState& ics, const IntCode* i) { - return IntCode_CALL_XX(ics, i, i->src1_reg); -} -int Translate_CALL_EXTERN(TranslationContext& ctx, Instr* i) { - return DispatchToC(ctx, i, IntCode_CALL_EXTERN); -} - -uint32_t IntCode_RETURN(IntCodeState& ics, const IntCode* i) { - return IA_RETURN; -} -int Translate_RETURN(TranslationContext& ctx, Instr* i) { - return DispatchToC(ctx, i, IntCode_RETURN); -} - -uint32_t IntCode_RETURN_TRUE_I8(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u8) { - return IA_RETURN; - } - return IA_NEXT; -} -uint32_t IntCode_RETURN_TRUE_I16(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u16) { - return IA_RETURN; - } - return IA_NEXT; -} -uint32_t IntCode_RETURN_TRUE_I32(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u32) { - return IA_RETURN; - } - return IA_NEXT; -} -uint32_t IntCode_RETURN_TRUE_I64(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u64) { - return IA_RETURN; - } - return IA_NEXT; -} -uint32_t IntCode_RETURN_TRUE_F32(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].f32) { - return IA_RETURN; - } - return IA_NEXT; -} -uint32_t IntCode_RETURN_TRUE_F64(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].f64) { - return IA_RETURN; - } - return IA_NEXT; -} -int Translate_RETURN_TRUE(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_RETURN_TRUE_I8, IntCode_RETURN_TRUE_I16, IntCode_RETURN_TRUE_I32, - IntCode_RETURN_TRUE_I64, IntCode_RETURN_TRUE_F32, IntCode_RETURN_TRUE_F64, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_SET_RETURN_ADDRESS(IntCodeState& ics, const IntCode* i) { - ics.call_return_address = ics.rf[i->src1_reg].u32; - return IA_NEXT; -} -int Translate_SET_RETURN_ADDRESS(TranslationContext& ctx, Instr* i) { - return DispatchToC(ctx, i, IntCode_SET_RETURN_ADDRESS); -} - -uint32_t IntCode_BRANCH_XX(IntCodeState& ics, const IntCode* i, uint32_t reg) { - return ics.rf[reg].u32; -} -uint32_t IntCode_BRANCH(IntCodeState& ics, const IntCode* i) { - return IntCode_BRANCH_XX(ics, i, i->src1_reg); -} -int Translate_BRANCH(TranslationContext& ctx, Instr* i) { - return DispatchToC(ctx, i, IntCode_BRANCH); -} - -uint32_t IntCode_BRANCH_TRUE_I8(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u8) { - return IntCode_BRANCH_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -uint32_t IntCode_BRANCH_TRUE_I16(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u16) { - return IntCode_BRANCH_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -uint32_t IntCode_BRANCH_TRUE_I32(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u32) { - return IntCode_BRANCH_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -uint32_t IntCode_BRANCH_TRUE_I64(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].u64) { - return IntCode_BRANCH_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -uint32_t IntCode_BRANCH_TRUE_F32(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].f32) { - return IntCode_BRANCH_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -uint32_t IntCode_BRANCH_TRUE_F64(IntCodeState& ics, const IntCode* i) { - if (ics.rf[i->src1_reg].f64) { - return IntCode_BRANCH_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -int Translate_BRANCH_TRUE(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_BRANCH_TRUE_I8, IntCode_BRANCH_TRUE_I16, IntCode_BRANCH_TRUE_I32, - IntCode_BRANCH_TRUE_I64, IntCode_BRANCH_TRUE_F32, IntCode_BRANCH_TRUE_F64, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_BRANCH_FALSE_I8(IntCodeState& ics, const IntCode* i) { - if (!ics.rf[i->src1_reg].u8) { - return IntCode_BRANCH_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -uint32_t IntCode_BRANCH_FALSE_I16(IntCodeState& ics, const IntCode* i) { - if (!ics.rf[i->src1_reg].u16) { - return IntCode_BRANCH_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -uint32_t IntCode_BRANCH_FALSE_I32(IntCodeState& ics, const IntCode* i) { - if (!ics.rf[i->src1_reg].u32) { - return IntCode_BRANCH_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -uint32_t IntCode_BRANCH_FALSE_I64(IntCodeState& ics, const IntCode* i) { - if (!ics.rf[i->src1_reg].u64) { - return IntCode_BRANCH_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -uint32_t IntCode_BRANCH_FALSE_F32(IntCodeState& ics, const IntCode* i) { - if (!ics.rf[i->src1_reg].f32) { - return IntCode_BRANCH_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -uint32_t IntCode_BRANCH_FALSE_F64(IntCodeState& ics, const IntCode* i) { - if (!ics.rf[i->src1_reg].f64) { - return IntCode_BRANCH_XX(ics, i, i->src2_reg); - } - return IA_NEXT; -} -int Translate_BRANCH_FALSE(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_BRANCH_FALSE_I8, IntCode_BRANCH_FALSE_I16, - IntCode_BRANCH_FALSE_I32, IntCode_BRANCH_FALSE_I64, - IntCode_BRANCH_FALSE_F32, IntCode_BRANCH_FALSE_F64, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_ASSIGN_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_ASSIGN_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = ics.rf[i->src1_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_ASSIGN_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = ics.rf[i->src1_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_ASSIGN_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = ics.rf[i->src1_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_ASSIGN_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f32 = ics.rf[i->src1_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_ASSIGN_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f64 = ics.rf[i->src1_reg].f64; - return IA_NEXT; -} -uint32_t IntCode_ASSIGN_V128(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].v128 = ics.rf[i->src1_reg].v128; - return IA_NEXT; -} -int Translate_ASSIGN(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_ASSIGN_I8, IntCode_ASSIGN_I16, IntCode_ASSIGN_I32, - IntCode_ASSIGN_I64, IntCode_ASSIGN_F32, IntCode_ASSIGN_F64, - IntCode_ASSIGN_V128, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_CAST(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].v128 = ics.rf[i->src1_reg].v128; - return IA_NEXT; -} -int Translate_CAST(TranslationContext& ctx, Instr* i) { - return DispatchToC(ctx, i, IntCode_CAST); -} - -uint32_t IntCode_ZERO_EXTEND_I8_TO_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = (uint8_t)ics.rf[i->src1_reg].u8; - return IA_NEXT; -} -uint32_t IntCode_ZERO_EXTEND_I8_TO_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = (uint16_t)ics.rf[i->src1_reg].u8; - return IA_NEXT; -} -uint32_t IntCode_ZERO_EXTEND_I8_TO_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = (uint64_t)ics.rf[i->src1_reg].u8; - return IA_NEXT; -} -uint32_t IntCode_ZERO_EXTEND_I16_TO_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = (uint32_t)ics.rf[i->src1_reg].u16; - return IA_NEXT; -} -uint32_t IntCode_ZERO_EXTEND_I16_TO_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = (uint64_t)ics.rf[i->src1_reg].u16; - return IA_NEXT; -} -uint32_t IntCode_ZERO_EXTEND_I32_TO_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = (uint64_t)ics.rf[i->src1_reg].u32; - return IA_NEXT; -} -int Translate_ZERO_EXTEND(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_ASSIGN_I8, IntCode_ZERO_EXTEND_I8_TO_I16, - IntCode_ZERO_EXTEND_I8_TO_I32, IntCode_ZERO_EXTEND_I8_TO_I64, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_ASSIGN_I16, IntCode_ZERO_EXTEND_I16_TO_I32, - IntCode_ZERO_EXTEND_I16_TO_I64, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_ASSIGN_I32, IntCode_ZERO_EXTEND_I32_TO_I64, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_ASSIGN_I64, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - IntCodeFn fn = fns[i->src1.value->type * MAX_TYPENAME + i->dest->type]; - return DispatchToC(ctx, i, fn); -} - -uint32_t IntCode_SIGN_EXTEND_I8_TO_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = (int8_t)ics.rf[i->src1_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_SIGN_EXTEND_I8_TO_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = (int16_t)ics.rf[i->src1_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_SIGN_EXTEND_I8_TO_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = (int64_t)ics.rf[i->src1_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_SIGN_EXTEND_I16_TO_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = (int32_t)ics.rf[i->src1_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_SIGN_EXTEND_I16_TO_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = (int64_t)ics.rf[i->src1_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_SIGN_EXTEND_I32_TO_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = (int64_t)ics.rf[i->src1_reg].i32; - return IA_NEXT; -} -int Translate_SIGN_EXTEND(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_ASSIGN_I8, IntCode_SIGN_EXTEND_I8_TO_I16, - IntCode_SIGN_EXTEND_I8_TO_I32, IntCode_SIGN_EXTEND_I8_TO_I64, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_ASSIGN_I16, IntCode_SIGN_EXTEND_I16_TO_I32, - IntCode_SIGN_EXTEND_I16_TO_I64, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_ASSIGN_I32, IntCode_SIGN_EXTEND_I32_TO_I64, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_ASSIGN_I64, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - IntCodeFn fn = fns[i->src1.value->type * MAX_TYPENAME + i->dest->type]; - return DispatchToC(ctx, i, fn); -} - -uint32_t IntCode_TRUNCATE_I16_TO_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = (int8_t)ics.rf[i->src1_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_TRUNCATE_I32_TO_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = (int8_t)ics.rf[i->src1_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_TRUNCATE_I32_TO_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = (int16_t)ics.rf[i->src1_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_TRUNCATE_I64_TO_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = (int8_t)ics.rf[i->src1_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_TRUNCATE_I64_TO_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = (int16_t)ics.rf[i->src1_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_TRUNCATE_I64_TO_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = (int32_t)ics.rf[i->src1_reg].i64; - return IA_NEXT; -} -int Translate_TRUNCATE(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_ASSIGN_I8, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_TRUNCATE_I16_TO_I8, - IntCode_ASSIGN_I16, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_TRUNCATE_I32_TO_I8, IntCode_TRUNCATE_I32_TO_I16, - IntCode_ASSIGN_I32, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_TRUNCATE_I64_TO_I8, - IntCode_TRUNCATE_I64_TO_I16, IntCode_TRUNCATE_I64_TO_I32, - IntCode_ASSIGN_I64, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - IntCodeFn fn = fns[i->src1.value->type * MAX_TYPENAME + i->dest->type]; - return DispatchToC(ctx, i, fn); -} - -uint32_t IntCode_CONVERT_I32_TO_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f32 = (float)ics.rf[i->src1_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_CONVERT_I64_TO_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f64 = (double)ics.rf[i->src1_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_CONVERT_F32_TO_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = (int32_t)ics.rf[i->src1_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_CONVERT_F32_TO_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f64 = (double)ics.rf[i->src1_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_CONVERT_F64_TO_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = (int32_t)ics.rf[i->src1_reg].f64; - return IA_NEXT; -} -uint32_t IntCode_CONVERT_F64_TO_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = (int64_t)ics.rf[i->src1_reg].f64; - return IA_NEXT; -} -uint32_t IntCode_CONVERT_F64_TO_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f32 = (float)ics.rf[i->src1_reg].f64; - return IA_NEXT; -} -int Translate_CONVERT(TranslationContext& ctx, Instr* i) { - // Can do more as needed. - static IntCodeFn fns[] = { - IntCode_ASSIGN_I8, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_ASSIGN_I16, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_ASSIGN_I32, IntCode_INVALID_TYPE, - IntCode_CONVERT_I32_TO_F32, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_ASSIGN_I64, IntCode_INVALID_TYPE, - IntCode_CONVERT_I64_TO_F64, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_CONVERT_F32_TO_I32, IntCode_INVALID_TYPE, - IntCode_ASSIGN_F32, IntCode_CONVERT_F32_TO_F64, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_CONVERT_F64_TO_I32, - IntCode_CONVERT_F64_TO_I64, IntCode_CONVERT_F64_TO_F32, - IntCode_ASSIGN_F64, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_ASSIGN_V128, - }; - IntCodeFn fn = fns[i->src1.value->type * MAX_TYPENAME + i->dest->type]; - return DispatchToC(ctx, i, fn); -} - -uint32_t IntCode_ROUND_F32(IntCodeState& ics, const IntCode* i) { - float src1 = ics.rf[i->src1_reg].f32; - float dest = src1; - switch (i->flags) { - case ROUND_TO_ZERO: - dest = truncf(src1); - break; - case ROUND_TO_NEAREST: - dest = roundf(src1); - break; - case ROUND_TO_MINUS_INFINITY: - dest = floorf(src1); - break; - case ROUND_TO_POSITIVE_INFINITY: - dest = ceilf(src1); - break; - } - ics.rf[i->dest_reg].f32 = dest; - return IA_NEXT; -} -uint32_t IntCode_ROUND_F64(IntCodeState& ics, const IntCode* i) { - double src1 = ics.rf[i->src1_reg].f64; - double dest = src1; - switch (i->flags) { - case ROUND_TO_ZERO: - dest = trunc(src1); - break; - case ROUND_TO_NEAREST: - dest = round(src1); - break; - case ROUND_TO_MINUS_INFINITY: - dest = floor(src1); - break; - case ROUND_TO_POSITIVE_INFINITY: - dest = ceil(src1); - break; - } - ics.rf[i->dest_reg].f64 = dest; - return IA_NEXT; -} -uint32_t IntCode_ROUND_V128_ZERO(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (size_t n = 0; n < 4; n++) { - dest.f32[n] = truncf(src1.f32[n]); - } - return IA_NEXT; -} -uint32_t IntCode_ROUND_V128_NEAREST(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (size_t n = 0; n < 4; n++) { - dest.f32[n] = roundf(src1.f32[n]); - } - return IA_NEXT; -} -uint32_t IntCode_ROUND_V128_MINUS_INFINITY(IntCodeState& ics, - const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; ++n) { - dest.f32[n] = floorf(src1.f32[n]); - } - return IA_NEXT; -} -uint32_t IntCode_ROUND_V128_POSITIVE_INFINTIY(IntCodeState& ics, - const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; ++n) { - dest.f32[n] = ceilf(src1.f32[n]); - } - return IA_NEXT; -} -int Translate_ROUND(TranslationContext& ctx, Instr* i) { - if (i->dest->type == VEC128_TYPE) { - static IntCodeFn fns[] = { - IntCode_ROUND_V128_ZERO, IntCode_ROUND_V128_NEAREST, - IntCode_ROUND_V128_MINUS_INFINITY, IntCode_ROUND_V128_POSITIVE_INFINTIY, - }; - return DispatchToC(ctx, i, fns[i->flags]); - } else { - static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_ROUND_F32, IntCode_ROUND_F64, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); - } -} - -uint32_t IntCode_VECTOR_CONVERT_I2F_S(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; ++n) { - dest.f32[n] = (float)(int32_t)src1.u32[n]; - } - return IA_NEXT; -} -uint32_t IntCode_VECTOR_CONVERT_I2F_U(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; ++n) { - dest.f32[n] = (float)(uint32_t)src1.u32[n]; - } - return IA_NEXT; -} -int Translate_VECTOR_CONVERT_I2F(TranslationContext& ctx, Instr* i) { - if (i->flags & ARITHMETIC_UNSIGNED) { - return DispatchToC(ctx, i, IntCode_VECTOR_CONVERT_I2F_U); - } else { - return DispatchToC(ctx, i, IntCode_VECTOR_CONVERT_I2F_S); - } -} - -uint32_t IntCode_VECTOR_CONVERT_F2I(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - if (i->flags & ARITHMETIC_UNSIGNED) { - for (int n = 0; n < 4; ++n) { - dest.u32[n] = (uint32_t)src1.f32[n]; - } - } else { - for (int n = 0; n < 4; ++n) { - dest.u32[n] = (int32_t)src1.f32[n]; - } - } - return IA_NEXT; -} -uint32_t IntCode_VECTOR_CONVERT_F2I_SAT(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - if (i->flags & ARITHMETIC_UNSIGNED) { - for (int n = 0; n < 4; n++) { - float src = src1.f32[n]; - if (src < 0) { - dest.u32[n] = 0; - ics.did_saturate = 1; - } else if (src > UINT_MAX) { - dest.u32[n] = UINT_MAX; - ics.did_saturate = 1; - } else { - dest.u32[n] = (uint32_t)src; - } - } - } else { - for (int n = 0; n < 4; n++) { - float src = src1.f32[n]; - if (src < INT_MIN) { - dest.u32[n] = INT_MIN; - ics.did_saturate = 1; - } else if (src > INT_MAX) { - dest.u32[n] = INT_MAX; - ics.did_saturate = 1; - } else { - dest.u32[n] = (int32_t)src; - } - } - } - return IA_NEXT; -} -int Translate_VECTOR_CONVERT_F2I(TranslationContext& ctx, Instr* i) { - if (i->flags & ARITHMETIC_SATURATE) { - return DispatchToC(ctx, i, IntCode_VECTOR_CONVERT_F2I_SAT); - } else { - return DispatchToC(ctx, i, IntCode_VECTOR_CONVERT_F2I); - } -} - -static const vec128_t lvsl_table[16] = { - vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), - vec128b(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), - vec128b(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17), - vec128b(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18), - vec128b(4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19), - vec128b(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20), - vec128b(6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21), - vec128b(7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22), - vec128b(8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23), - vec128b(9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24), - vec128b(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25), - vec128b(11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26), - vec128b(12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27), - vec128b(13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28), - vec128b(14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29), - vec128b(15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30), -}; -static const vec128_t lvsr_table[16] = { - vec128b(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31), - vec128b(15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30), - vec128b(14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29), - vec128b(13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28), - vec128b(12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27), - vec128b(11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26), - vec128b(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25), - vec128b(9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24), - vec128b(8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23), - vec128b(7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22), - vec128b(6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21), - vec128b(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20), - vec128b(4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19), - vec128b(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18), - vec128b(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17), - vec128b(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), -}; - -uint32_t IntCode_LOAD_VECTOR_SHL(IntCodeState& ics, const IntCode* i) { - int8_t sh = ics.rf[i->src1_reg].i8 & 0xF; - ics.rf[i->dest_reg].v128 = lvsl_table[sh]; - return IA_NEXT; -} -int Translate_LOAD_VECTOR_SHL(TranslationContext& ctx, Instr* i) { - return DispatchToC(ctx, i, IntCode_LOAD_VECTOR_SHL); -} - -uint32_t IntCode_LOAD_VECTOR_SHR(IntCodeState& ics, const IntCode* i) { - int8_t sh = ics.rf[i->src1_reg].i8 & 0xF; - ics.rf[i->dest_reg].v128 = lvsr_table[sh]; - return IA_NEXT; -} -int Translate_LOAD_VECTOR_SHR(TranslationContext& ctx, Instr* i) { - return DispatchToC(ctx, i, IntCode_LOAD_VECTOR_SHR); -} - -uint32_t IntCode_LOAD_CLOCK(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = poly::threading::ticks(); - return IA_NEXT; -} -int Translate_LOAD_CLOCK(TranslationContext& ctx, Instr* i) { - return DispatchToC(ctx, i, IntCode_LOAD_CLOCK); -} - -uint32_t IntCode_LOAD_LOCAL_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = *((int8_t*)(ics.locals + ics.rf[i->src1_reg].u32)); - return IA_NEXT; -} -uint32_t IntCode_LOAD_LOCAL_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = *((int16_t*)(ics.locals + ics.rf[i->src1_reg].u32)); - return IA_NEXT; -} -uint32_t IntCode_LOAD_LOCAL_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = *((int32_t*)(ics.locals + ics.rf[i->src1_reg].u32)); - return IA_NEXT; -} -uint32_t IntCode_LOAD_LOCAL_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = *((int64_t*)(ics.locals + ics.rf[i->src1_reg].u32)); - return IA_NEXT; -} -uint32_t IntCode_LOAD_LOCAL_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f32 = *((float*)(ics.locals + ics.rf[i->src1_reg].u32)); - return IA_NEXT; -} -uint32_t IntCode_LOAD_LOCAL_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f64 = *((double*)(ics.locals + ics.rf[i->src1_reg].u32)); - return IA_NEXT; -} -uint32_t IntCode_LOAD_LOCAL_V128(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].v128 = - *((vec128_t*)(ics.locals + ics.rf[i->src1_reg].u32)); - return IA_NEXT; -} -int Translate_LOAD_LOCAL(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_LOAD_LOCAL_I8, IntCode_LOAD_LOCAL_I16, IntCode_LOAD_LOCAL_I32, - IntCode_LOAD_LOCAL_I64, IntCode_LOAD_LOCAL_F32, IntCode_LOAD_LOCAL_F64, - IntCode_LOAD_LOCAL_V128, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_STORE_LOCAL_I8(IntCodeState& ics, const IntCode* i) { - *((int8_t*)(ics.locals + ics.rf[i->src1_reg].u32)) = ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_STORE_LOCAL_I16(IntCodeState& ics, const IntCode* i) { - *((int16_t*)(ics.locals + ics.rf[i->src1_reg].u32)) = ics.rf[i->src2_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_STORE_LOCAL_I32(IntCodeState& ics, const IntCode* i) { - *((int32_t*)(ics.locals + ics.rf[i->src1_reg].u32)) = ics.rf[i->src2_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_STORE_LOCAL_I64(IntCodeState& ics, const IntCode* i) { - *((int64_t*)(ics.locals + ics.rf[i->src1_reg].u32)) = ics.rf[i->src2_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_STORE_LOCAL_F32(IntCodeState& ics, const IntCode* i) { - *((float*)(ics.locals + ics.rf[i->src1_reg].u32)) = ics.rf[i->src2_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_STORE_LOCAL_F64(IntCodeState& ics, const IntCode* i) { - *((double*)(ics.locals + ics.rf[i->src1_reg].u32)) = ics.rf[i->src2_reg].f64; - return IA_NEXT; -} -uint32_t IntCode_STORE_LOCAL_V128(IntCodeState& ics, const IntCode* i) { - *((vec128_t*)(ics.locals + ics.rf[i->src1_reg].u32)) = - ics.rf[i->src2_reg].v128; - return IA_NEXT; -} -int Translate_STORE_LOCAL(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_STORE_LOCAL_I8, IntCode_STORE_LOCAL_I16, - IntCode_STORE_LOCAL_I32, IntCode_STORE_LOCAL_I64, - IntCode_STORE_LOCAL_F32, IntCode_STORE_LOCAL_F64, - IntCode_STORE_LOCAL_V128, - }; - return DispatchToC(ctx, i, fns[i->src2.value->type]); -} - -uint32_t IntCode_LOAD_CONTEXT_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = *((int8_t*)(ics.context + ics.rf[i->src1_reg].u64)); - DPRINT("%d (%X) = ctx i8 +%d\n", ics.rf[i->dest_reg].i8, - ics.rf[i->dest_reg].u8, ics.rf[i->src1_reg].u64); - return IA_NEXT; -} -uint32_t IntCode_LOAD_CONTEXT_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = - *((int16_t*)(ics.context + ics.rf[i->src1_reg].u64)); - DPRINT("%d (%X) = ctx i16 +%d\n", ics.rf[i->dest_reg].i16, - ics.rf[i->dest_reg].u16, ics.rf[i->src1_reg].u64); - return IA_NEXT; -} -uint32_t IntCode_LOAD_CONTEXT_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = - *((int32_t*)(ics.context + ics.rf[i->src1_reg].u64)); - DPRINT("%d (%X) = ctx i32 +%d\n", ics.rf[i->dest_reg].i32, - ics.rf[i->dest_reg].u32, ics.rf[i->src1_reg].u64); - return IA_NEXT; -} -uint32_t IntCode_LOAD_CONTEXT_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = - *((int64_t*)(ics.context + ics.rf[i->src1_reg].u64)); - DPRINT("%lld (%llX) = ctx i64 +%d\n", ics.rf[i->dest_reg].i64, - ics.rf[i->dest_reg].u64, ics.rf[i->src1_reg].u64); - return IA_NEXT; -} -uint32_t IntCode_LOAD_CONTEXT_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f32 = *((float*)(ics.context + ics.rf[i->src1_reg].u64)); - DPRINT("%e (%X) = ctx f32 +%d\n", ics.rf[i->dest_reg].f32, - ics.rf[i->dest_reg].u32, ics.rf[i->src1_reg].u64); - return IA_NEXT; -} -uint32_t IntCode_LOAD_CONTEXT_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f64 = *((double*)(ics.context + ics.rf[i->src1_reg].u64)); - DPRINT("%lle (%llX) = ctx f64 +%d\n", ics.rf[i->dest_reg].f64, - ics.rf[i->dest_reg].u64, ics.rf[i->src1_reg].u64); - return IA_NEXT; -} -uint32_t IntCode_LOAD_CONTEXT_V128(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].v128 = - *((vec128_t*)(ics.context + ics.rf[i->src1_reg].u64)); - DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = ctx v128 +%d\n", - ics.rf[i->dest_reg].v128.x, ics.rf[i->dest_reg].v128.y, - ics.rf[i->dest_reg].v128.z, ics.rf[i->dest_reg].v128.w, - ics.rf[i->dest_reg].v128.ux, ics.rf[i->dest_reg].v128.uy, - ics.rf[i->dest_reg].v128.uz, ics.rf[i->dest_reg].v128.uw, - ics.rf[i->src1_reg].u64); - return IA_NEXT; -} -int Translate_LOAD_CONTEXT(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_LOAD_CONTEXT_I8, IntCode_LOAD_CONTEXT_I16, - IntCode_LOAD_CONTEXT_I32, IntCode_LOAD_CONTEXT_I64, - IntCode_LOAD_CONTEXT_F32, IntCode_LOAD_CONTEXT_F64, - IntCode_LOAD_CONTEXT_V128, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_STORE_CONTEXT_I8(IntCodeState& ics, const IntCode* i) { - *((int8_t*)(ics.context + ics.rf[i->src1_reg].u64)) = ics.rf[i->src2_reg].i8; - DPRINT("ctx i8 +%d = %d (%X)\n", ics.rf[i->src1_reg].u64, - ics.rf[i->src2_reg].i8, ics.rf[i->src2_reg].u8); - return IA_NEXT; -} -uint32_t IntCode_STORE_CONTEXT_I16(IntCodeState& ics, const IntCode* i) { - *((int16_t*)(ics.context + ics.rf[i->src1_reg].u64)) = - ics.rf[i->src2_reg].i16; - DPRINT("ctx i16 +%d = %d (%X)\n", ics.rf[i->src1_reg].u64, - ics.rf[i->src2_reg].i16, ics.rf[i->src2_reg].u16); - return IA_NEXT; -} -uint32_t IntCode_STORE_CONTEXT_I32(IntCodeState& ics, const IntCode* i) { - *((int32_t*)(ics.context + ics.rf[i->src1_reg].u64)) = - ics.rf[i->src2_reg].i32; - DPRINT("ctx i32 +%d = %d (%X)\n", ics.rf[i->src1_reg].u64, - ics.rf[i->src2_reg].i32, ics.rf[i->src2_reg].u32); - return IA_NEXT; -} -uint32_t IntCode_STORE_CONTEXT_I64(IntCodeState& ics, const IntCode* i) { - *((int64_t*)(ics.context + ics.rf[i->src1_reg].u64)) = - ics.rf[i->src2_reg].i64; - DPRINT("ctx i64 +%d = %lld (%llX)\n", ics.rf[i->src1_reg].u64, - ics.rf[i->src2_reg].i64, ics.rf[i->src2_reg].u64); - return IA_NEXT; -} -uint32_t IntCode_STORE_CONTEXT_F32(IntCodeState& ics, const IntCode* i) { - *((float*)(ics.context + ics.rf[i->src1_reg].u64)) = ics.rf[i->src2_reg].f32; - DPRINT("ctx f32 +%d = %e (%X)\n", ics.rf[i->src1_reg].u64, - ics.rf[i->src2_reg].f32, ics.rf[i->src2_reg].u32); - return IA_NEXT; -} -uint32_t IntCode_STORE_CONTEXT_F64(IntCodeState& ics, const IntCode* i) { - *((double*)(ics.context + ics.rf[i->src1_reg].u64)) = ics.rf[i->src2_reg].f64; - DPRINT("ctx f64 +%d = %lle (%llX)\n", ics.rf[i->src1_reg].u64, - ics.rf[i->src2_reg].f64, ics.rf[i->src2_reg].u64); - return IA_NEXT; -} -uint32_t IntCode_STORE_CONTEXT_V128(IntCodeState& ics, const IntCode* i) { - *((vec128_t*)(ics.context + ics.rf[i->src1_reg].u64)) = - ics.rf[i->src2_reg].v128; - DPRINT("ctx v128 +%d = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", - ics.rf[i->src1_reg].u64, ics.rf[i->src2_reg].v128.x, - ics.rf[i->src2_reg].v128.y, ics.rf[i->src2_reg].v128.z, - ics.rf[i->src2_reg].v128.w, ics.rf[i->src2_reg].v128.ux, - ics.rf[i->src2_reg].v128.uy, ics.rf[i->src2_reg].v128.uz, - ics.rf[i->src2_reg].v128.uw); - return IA_NEXT; -} -int Translate_STORE_CONTEXT(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_STORE_CONTEXT_I8, IntCode_STORE_CONTEXT_I16, - IntCode_STORE_CONTEXT_I32, IntCode_STORE_CONTEXT_I64, - IntCode_STORE_CONTEXT_F32, IntCode_STORE_CONTEXT_F64, - IntCode_STORE_CONTEXT_V128, - }; - return DispatchToC(ctx, i, fns[i->src2.value->type]); -} - -uint32_t IntCode_LOAD_I8(IntCodeState& ics, const IntCode* i) { - uint32_t address = ics.rf[i->src1_reg].u32; - if (DYNAMIC_REGISTER_ACCESS_CHECK(address)) { - ics.rf[i->dest_reg].i8 = ics.thread_state->memory()->LoadI8(address); - return IA_NEXT; - } - DPRINT("%d (%X) = load.i8 %.8X\n", *((int8_t*)(ics.membase + address)), - *((uint8_t*)(ics.membase + address)), address); - DFLUSH(); - ics.rf[i->dest_reg].i8 = *((int8_t*)(ics.membase + address)); - return IA_NEXT; -} -uint32_t IntCode_LOAD_I16(IntCodeState& ics, const IntCode* i) { - uint32_t address = ics.rf[i->src1_reg].u32; - if (DYNAMIC_REGISTER_ACCESS_CHECK(address)) { - ics.rf[i->dest_reg].i16 = - poly::byte_swap(ics.thread_state->memory()->LoadI16(address)); - return IA_NEXT; - } - DPRINT("%d (%X) = load.i16 %.8X\n", *((int16_t*)(ics.membase + address)), - *((uint16_t*)(ics.membase + address)), address); - DFLUSH(); - ics.rf[i->dest_reg].i16 = *((int16_t*)(ics.membase + address)); - return IA_NEXT; -} -uint32_t IntCode_LOAD_I32(IntCodeState& ics, const IntCode* i) { - uint32_t address = ics.rf[i->src1_reg].u32; - if (DYNAMIC_REGISTER_ACCESS_CHECK(address)) { - ics.rf[i->dest_reg].i32 = - poly::byte_swap(ics.thread_state->memory()->LoadI32(address)); - return IA_NEXT; - } - DFLUSH(); - DPRINT("%d (%X) = load.i32 %.8X\n", *((int32_t*)(ics.membase + address)), - *((uint32_t*)(ics.membase + address)), address); - DFLUSH(); - ics.rf[i->dest_reg].i32 = *((int32_t*)(ics.membase + address)); - return IA_NEXT; -} -uint32_t IntCode_LOAD_I64(IntCodeState& ics, const IntCode* i) { - uint32_t address = ics.rf[i->src1_reg].u32; - if (DYNAMIC_REGISTER_ACCESS_CHECK(address)) { - ics.rf[i->dest_reg].i64 = - poly::byte_swap(ics.thread_state->memory()->LoadI64(address)); - return IA_NEXT; - } - DPRINT("%lld (%llX) = load.i64 %.8X\n", *((int64_t*)(ics.membase + address)), - *((uint64_t*)(ics.membase + address)), address); - DFLUSH(); - ics.rf[i->dest_reg].i64 = *((int64_t*)(ics.membase + address)); - return IA_NEXT; -} -uint32_t IntCode_LOAD_F32(IntCodeState& ics, const IntCode* i) { - uint32_t address = ics.rf[i->src1_reg].u32; - DPRINT("%e (%X) = load.f32 %.8X\n", *((float*)(ics.membase + address)), - *((uint64_t*)(ics.membase + address)), address); - DFLUSH(); - ics.rf[i->dest_reg].f32 = *((float*)(ics.membase + address)); - return IA_NEXT; -} -uint32_t IntCode_LOAD_F64(IntCodeState& ics, const IntCode* i) { - uint32_t address = ics.rf[i->src1_reg].u32; - DPRINT("%lle (%llX) = load.f64 %.8X\n", *((double*)(ics.membase + address)), - *((uint64_t*)(ics.membase + address)), address); - DFLUSH(); - ics.rf[i->dest_reg].f64 = *((double*)(ics.membase + address)); - return IA_NEXT; -} -uint32_t IntCode_LOAD_V128(IntCodeState& ics, const IntCode* i) { - uint32_t address = ics.rf[i->src1_reg].u32; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.u32[n] = *((uint32_t*)(ics.membase + address + n * 4)); - } - DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = load.v128 %.8X\n", dest.x, - dest.y, dest.z, dest.w, dest.ux, dest.uy, dest.uz, dest.uw, address); - DFLUSH(); - return IA_NEXT; -} -int Translate_LOAD(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_LOAD_I8, IntCode_LOAD_I16, IntCode_LOAD_I32, IntCode_LOAD_I64, - IntCode_LOAD_F32, IntCode_LOAD_F64, IntCode_LOAD_V128, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_STORE_I8(IntCodeState& ics, const IntCode* i) { - uint32_t address = ics.rf[i->src1_reg].u32; - if (DYNAMIC_REGISTER_ACCESS_CHECK(address)) { - ics.thread_state->memory()->StoreI8(address, ics.rf[i->src2_reg].i8); - return IA_NEXT; - } - DPRINT("store.i8 %.8X = %d (%X)\n", address, ics.rf[i->src2_reg].i8, - ics.rf[i->src2_reg].u8); - DFLUSH(); - *((int8_t*)(ics.membase + address)) = ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_STORE_I16(IntCodeState& ics, const IntCode* i) { - uint32_t address = ics.rf[i->src1_reg].u32; - if (DYNAMIC_REGISTER_ACCESS_CHECK(address)) { - ics.thread_state->memory()->StoreI16( - address, poly::byte_swap(ics.rf[i->src2_reg].i16)); - return IA_NEXT; - } - DPRINT("store.i16 %.8X = %d (%X)\n", address, ics.rf[i->src2_reg].i16, - ics.rf[i->src2_reg].u16); - DFLUSH(); - *((int16_t*)(ics.membase + address)) = ics.rf[i->src2_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_STORE_I32(IntCodeState& ics, const IntCode* i) { - uint32_t address = ics.rf[i->src1_reg].u32; - if (DYNAMIC_REGISTER_ACCESS_CHECK(address)) { - ics.thread_state->memory()->StoreI32( - address, poly::byte_swap(ics.rf[i->src2_reg].i32)); - return IA_NEXT; - } - DPRINT("store.i32 %.8X = %d (%X)\n", address, ics.rf[i->src2_reg].i32, - ics.rf[i->src2_reg].u32); - DFLUSH(); - *((int32_t*)(ics.membase + address)) = ics.rf[i->src2_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_STORE_I64(IntCodeState& ics, const IntCode* i) { - uint32_t address = ics.rf[i->src1_reg].u32; - if (DYNAMIC_REGISTER_ACCESS_CHECK(address)) { - ics.thread_state->memory()->StoreI64( - address, poly::byte_swap(ics.rf[i->src2_reg].i64)); - return IA_NEXT; - } - DPRINT("store.i64 %.8X = %lld (%llX)\n", address, ics.rf[i->src2_reg].i64, - ics.rf[i->src2_reg].u64); - DFLUSH(); - *((int64_t*)(ics.membase + address)) = ics.rf[i->src2_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_STORE_F32(IntCodeState& ics, const IntCode* i) { - uint32_t address = ics.rf[i->src1_reg].u32; - DPRINT("store.f32 %.8X = %e (%X)\n", address, ics.rf[i->src2_reg].f32, - ics.rf[i->src2_reg].u32); - DFLUSH(); - *((float*)(ics.membase + address)) = ics.rf[i->src2_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_STORE_F64(IntCodeState& ics, const IntCode* i) { - uint32_t address = ics.rf[i->src1_reg].u32; - DPRINT("store.f64 %.8X = %lle (%llX)\n", address, ics.rf[i->src2_reg].f64, - ics.rf[i->src2_reg].u64); - DFLUSH(); - *((double*)(ics.membase + address)) = ics.rf[i->src2_reg].f64; - return IA_NEXT; -} -uint32_t IntCode_STORE_V128(IntCodeState& ics, const IntCode* i) { - uint32_t address = ics.rf[i->src1_reg].u32; - DPRINT("store.v128 %.8X = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", - address, ics.rf[i->src2_reg].v128.x, ics.rf[i->src2_reg].v128.y, - ics.rf[i->src2_reg].v128.z, ics.rf[i->src2_reg].v128.w, - ics.rf[i->src2_reg].v128.ux, ics.rf[i->src2_reg].v128.uy, - ics.rf[i->src2_reg].v128.uz, ics.rf[i->src2_reg].v128.uw); - DFLUSH(); - *((vec128_t*)(ics.membase + address)) = ics.rf[i->src2_reg].v128; - return IA_NEXT; -} -int Translate_STORE(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_STORE_I8, IntCode_STORE_I16, IntCode_STORE_I32, - IntCode_STORE_I64, IntCode_STORE_F32, IntCode_STORE_F64, - IntCode_STORE_V128, - }; - return DispatchToC(ctx, i, fns[i->src2.value->type]); -} - -uint32_t IntCode_PREFETCH(IntCodeState& ics, const IntCode* i) { - return IA_NEXT; -} -int Translate_PREFETCH(TranslationContext& ctx, Instr* i) { - return DispatchToC(ctx, i, IntCode_PREFETCH); -} - -uint32_t IntCode_MAX_I8_I8(IntCodeState& ics, const IntCode* i) { - int8_t a = ics.rf[i->src1_reg].i8; - int8_t b = ics.rf[i->src2_reg].i8; - ics.rf[i->dest_reg].i8 = std::max(a, b); - return IA_NEXT; -} -uint32_t IntCode_MAX_I16_I16(IntCodeState& ics, const IntCode* i) { - int16_t a = ics.rf[i->src1_reg].i16; - int16_t b = ics.rf[i->src2_reg].i16; - ics.rf[i->dest_reg].i16 = std::max(a, b); - return IA_NEXT; -} -uint32_t IntCode_MAX_I32_I32(IntCodeState& ics, const IntCode* i) { - int32_t a = ics.rf[i->src1_reg].i32; - int32_t b = ics.rf[i->src2_reg].i32; - ics.rf[i->dest_reg].i32 = std::max(a, b); - return IA_NEXT; -} -uint32_t IntCode_MAX_I64_I64(IntCodeState& ics, const IntCode* i) { - int64_t a = ics.rf[i->src1_reg].i64; - int64_t b = ics.rf[i->src2_reg].i64; - ics.rf[i->dest_reg].i64 = std::max(a, b); - return IA_NEXT; -} -uint32_t IntCode_MAX_F32_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f32 = - std::max(ics.rf[i->src1_reg].f32, ics.rf[i->src2_reg].f32); - return IA_NEXT; -} -uint32_t IntCode_MAX_F64_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f64 = - std::max(ics.rf[i->src1_reg].f64, ics.rf[i->src2_reg].f64); - return IA_NEXT; -} -uint32_t IntCode_MAX_V128_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.f32[n] = std::max(src1.f32[n], src2.f32[n]); - } - return IA_NEXT; -} -int Translate_MAX(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_MAX_I8_I8, IntCode_MAX_I16_I16, IntCode_MAX_I32_I32, - IntCode_MAX_I64_I64, IntCode_MAX_F32_F32, IntCode_MAX_F64_F64, - IntCode_MAX_V128_V128, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_VECTOR_MAX_I8_UNSIGNED(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 16; n++) { - dest.u8[n] = std::max(src1.u8[n], src2.u8[n]); - } - return IA_NEXT; -} -uint32_t IntCode_VECTOR_MAX_I16_UNSIGNED(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 8; n++) { - dest.u16[n] = std::max(src1.u16[n], src2.u16[n]); - } - return IA_NEXT; -} -uint32_t IntCode_VECTOR_MAX_I32_UNSIGNED(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.u32[n] = std::max(src1.u32[n], src2.u32[n]); - } - return IA_NEXT; -} -uint32_t IntCode_VECTOR_MAX_I8_SIGNED(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 16; n++) { - dest.u8[n] = std::max((int8_t)src1.u8[n], (int8_t)src2.u8[n]); - } - return IA_NEXT; -} -uint32_t IntCode_VECTOR_MAX_I16_SIGNED(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 8; n++) { - dest.u16[n] = std::max((int16_t)src1.u16[n], (int16_t)src2.u16[n]); - } - return IA_NEXT; -} -uint32_t IntCode_VECTOR_MAX_I32_SIGNED(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.u32[n] = std::max((int32_t)src1.u32[n], (int32_t)src2.u32[n]); - } - return IA_NEXT; -} -int Translate_VECTOR_MAX(TranslationContext& ctx, Instr* i) { - static IntCodeFn unsigned_fns[] = { - IntCode_VECTOR_MAX_I8_UNSIGNED, IntCode_VECTOR_MAX_I16_UNSIGNED, - IntCode_VECTOR_MAX_I32_UNSIGNED, - }; - static IntCodeFn signed_fns[] = { - IntCode_VECTOR_MAX_I8_SIGNED, IntCode_VECTOR_MAX_I16_SIGNED, - IntCode_VECTOR_MAX_I32_SIGNED, - }; - uint32_t part_type = i->flags >> 8; - if (i->flags & ARITHMETIC_UNSIGNED) { - return DispatchToC(ctx, i, unsigned_fns[part_type]); - } else { - return DispatchToC(ctx, i, signed_fns[part_type]); - } -} - -uint32_t IntCode_MIN_I8_I8(IntCodeState& ics, const IntCode* i) { - int8_t a = ics.rf[i->src1_reg].i8; - int8_t b = ics.rf[i->src2_reg].i8; - ics.rf[i->dest_reg].i8 = std::min(a, b); - return IA_NEXT; -} -uint32_t IntCode_MIN_I16_I16(IntCodeState& ics, const IntCode* i) { - int16_t a = ics.rf[i->src1_reg].i16; - int16_t b = ics.rf[i->src2_reg].i16; - ics.rf[i->dest_reg].i16 = std::min(a, b); - return IA_NEXT; -} -uint32_t IntCode_MIN_I32_I32(IntCodeState& ics, const IntCode* i) { - int32_t a = ics.rf[i->src1_reg].i32; - int32_t b = ics.rf[i->src2_reg].i32; - ics.rf[i->dest_reg].i32 = std::min(a, b); - return IA_NEXT; -} -uint32_t IntCode_MIN_I64_I64(IntCodeState& ics, const IntCode* i) { - int64_t a = ics.rf[i->src1_reg].i64; - int64_t b = ics.rf[i->src2_reg].i64; - ics.rf[i->dest_reg].i64 = std::min(a, b); - return IA_NEXT; -} -uint32_t IntCode_MIN_F32_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f32 = - std::min(ics.rf[i->src1_reg].f32, ics.rf[i->src2_reg].f32); - return IA_NEXT; -} -uint32_t IntCode_MIN_F64_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f64 = - std::min(ics.rf[i->src1_reg].f64, ics.rf[i->src2_reg].f64); - return IA_NEXT; -} -uint32_t IntCode_MIN_V128_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.f32[n] = std::min(src1.f32[n], src2.f32[n]); - } - return IA_NEXT; -} -int Translate_MIN(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_MIN_I8_I8, IntCode_MIN_I16_I16, IntCode_MIN_I32_I32, - IntCode_MIN_I64_I64, IntCode_MIN_F32_F32, IntCode_MIN_F64_F64, - IntCode_MIN_V128_V128, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_VECTOR_MIN_I8_UNSIGNED(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 16; n++) { - dest.u8[n] = std::min(src1.u8[n], src2.u8[n]); - } - return IA_NEXT; -} -uint32_t IntCode_VECTOR_MIN_I16_UNSIGNED(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 8; n++) { - dest.u16[n] = std::min(src1.u16[n], src2.u16[n]); - } - return IA_NEXT; -} -uint32_t IntCode_VECTOR_MIN_I32_UNSIGNED(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.u32[n] = std::min(src1.u32[n], src2.u32[n]); - } - return IA_NEXT; -} -uint32_t IntCode_VECTOR_MIN_I8_SIGNED(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 16; n++) { - dest.u8[n] = std::min((int8_t)src1.u8[n], (int8_t)src2.u8[n]); - } - return IA_NEXT; -} -uint32_t IntCode_VECTOR_MIN_I16_SIGNED(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 8; n++) { - dest.u16[n] = std::min((int16_t)src1.u16[n], (int16_t)src2.u16[n]); - } - return IA_NEXT; -} -uint32_t IntCode_VECTOR_MIN_I32_SIGNED(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.u32[n] = std::min((int32_t)src1.u32[n], (int32_t)src2.u32[n]); - } - return IA_NEXT; -} -int Translate_VECTOR_MIN(TranslationContext& ctx, Instr* i) { - static IntCodeFn unsigned_fns[] = { - IntCode_VECTOR_MIN_I8_UNSIGNED, IntCode_VECTOR_MIN_I16_UNSIGNED, - IntCode_VECTOR_MIN_I32_UNSIGNED, - }; - static IntCodeFn signed_fns[] = { - IntCode_VECTOR_MIN_I8_SIGNED, IntCode_VECTOR_MIN_I16_SIGNED, - IntCode_VECTOR_MIN_I32_SIGNED, - }; - uint32_t part_type = i->flags >> 8; - if (i->flags & ARITHMETIC_UNSIGNED) { - return DispatchToC(ctx, i, unsigned_fns[part_type]); - } else { - return DispatchToC(ctx, i, signed_fns[part_type]); - } -} - -uint32_t IntCode_SELECT_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = - ics.rf[i->src1_reg].i8 ? ics.rf[i->src2_reg].i8 : ics.rf[i->src3_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_SELECT_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = ics.rf[i->src1_reg].i8 ? ics.rf[i->src2_reg].i16 - : ics.rf[i->src3_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_SELECT_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = ics.rf[i->src1_reg].i8 ? ics.rf[i->src2_reg].i32 - : ics.rf[i->src3_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_SELECT_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = ics.rf[i->src1_reg].i8 ? ics.rf[i->src2_reg].i64 - : ics.rf[i->src3_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_SELECT_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f32 = ics.rf[i->src1_reg].i8 ? ics.rf[i->src2_reg].f32 - : ics.rf[i->src3_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_SELECT_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f64 = ics.rf[i->src1_reg].i8 ? ics.rf[i->src2_reg].f64 - : ics.rf[i->src3_reg].f64; - return IA_NEXT; -} -uint32_t IntCode_SELECT_V128(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].v128 = ics.rf[i->src1_reg].i8 ? ics.rf[i->src2_reg].v128 - : ics.rf[i->src3_reg].v128; - return IA_NEXT; -} -int Translate_SELECT(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_SELECT_I8, IntCode_SELECT_I16, IntCode_SELECT_I32, - IntCode_SELECT_I64, IntCode_SELECT_F32, IntCode_SELECT_F64, - IntCode_SELECT_V128, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_IS_TRUE_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = !!ics.rf[i->src1_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_IS_TRUE_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = !!ics.rf[i->src1_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_IS_TRUE_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = !!ics.rf[i->src1_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_IS_TRUE_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = !!ics.rf[i->src1_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_IS_TRUE_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = !!ics.rf[i->src1_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_IS_TRUE_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = !!ics.rf[i->src1_reg].f64; - return IA_NEXT; -} -uint32_t IntCode_IS_TRUE_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - ics.rf[i->dest_reg].i8 = src1.high && src1.low; - return IA_NEXT; -} -int Translate_IS_TRUE(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_IS_TRUE_I8, IntCode_IS_TRUE_I16, IntCode_IS_TRUE_I32, - IntCode_IS_TRUE_I64, IntCode_IS_TRUE_F32, IntCode_IS_TRUE_F64, - IntCode_IS_TRUE_V128, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_IS_FALSE_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = !ics.rf[i->src1_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_IS_FALSE_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = !ics.rf[i->src1_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_IS_FALSE_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = !ics.rf[i->src1_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_IS_FALSE_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = !ics.rf[i->src1_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_IS_FALSE_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = !ics.rf[i->src1_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_IS_FALSE_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = !ics.rf[i->src1_reg].f64; - return IA_NEXT; -} -uint32_t IntCode_IS_FALSE_V128(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = - !(ics.rf[i->src1_reg].v128.high && ics.rf[i->src1_reg].v128.low); - return IA_NEXT; -} -int Translate_IS_FALSE(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_IS_FALSE_I8, IntCode_IS_FALSE_I16, IntCode_IS_FALSE_I32, - IntCode_IS_FALSE_I64, IntCode_IS_FALSE_F32, IntCode_IS_FALSE_F64, - IntCode_IS_FALSE_V128, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_COMPARE_EQ_I8_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 == ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_EQ_I16_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i16 == ics.rf[i->src2_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_EQ_I32_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i32 == ics.rf[i->src2_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_EQ_I64_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i64 == ics.rf[i->src2_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_EQ_F32_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 == ics.rf[i->src2_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_EQ_F64_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 == ics.rf[i->src2_reg].f64; - return IA_NEXT; -} -int Translate_COMPARE_EQ(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_COMPARE_EQ_I8_I8, IntCode_COMPARE_EQ_I16_I16, - IntCode_COMPARE_EQ_I32_I32, IntCode_COMPARE_EQ_I64_I64, - IntCode_COMPARE_EQ_F32_F32, IntCode_COMPARE_EQ_F64_F64, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_COMPARE_NE_I8_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 != ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_NE_I16_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i16 != ics.rf[i->src2_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_NE_I32_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i32 != ics.rf[i->src2_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_NE_I64_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i64 != ics.rf[i->src2_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_NE_F32_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 != ics.rf[i->src2_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_NE_F64_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 != ics.rf[i->src2_reg].f64; - return IA_NEXT; -} -int Translate_COMPARE_NE(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_COMPARE_NE_I8_I8, IntCode_COMPARE_NE_I16_I16, - IntCode_COMPARE_NE_I32_I32, IntCode_COMPARE_NE_I64_I64, - IntCode_COMPARE_NE_F32_F32, IntCode_COMPARE_NE_F64_F64, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_COMPARE_SLT_I8_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 < ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_SLT_I16_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i16 < ics.rf[i->src2_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_SLT_I32_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i32 < ics.rf[i->src2_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_SLT_I64_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i64 < ics.rf[i->src2_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_SLT_F32_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 < ics.rf[i->src2_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_SLT_F64_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 < ics.rf[i->src2_reg].f64; - return IA_NEXT; -} -int Translate_COMPARE_SLT(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_COMPARE_SLT_I8_I8, IntCode_COMPARE_SLT_I16_I16, - IntCode_COMPARE_SLT_I32_I32, IntCode_COMPARE_SLT_I64_I64, - IntCode_COMPARE_SLT_F32_F32, IntCode_COMPARE_SLT_F64_F64, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_COMPARE_SLE_I8_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 <= ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_SLE_I16_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i16 <= ics.rf[i->src2_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_SLE_I32_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i32 <= ics.rf[i->src2_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_SLE_I64_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i64 <= ics.rf[i->src2_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_SLE_F32_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 <= ics.rf[i->src2_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_SLE_F64_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 <= ics.rf[i->src2_reg].f64; - return IA_NEXT; -} -int Translate_COMPARE_SLE(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_COMPARE_SLE_I8_I8, IntCode_COMPARE_SLE_I16_I16, - IntCode_COMPARE_SLE_I32_I32, IntCode_COMPARE_SLE_I64_I64, - IntCode_COMPARE_SLE_F32_F32, IntCode_COMPARE_SLE_F64_F64, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_COMPARE_SGT_I8_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 > ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_SGT_I16_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i16 > ics.rf[i->src2_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_SGT_I32_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i32 > ics.rf[i->src2_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_SGT_I64_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i64 > ics.rf[i->src2_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_SGT_F32_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 > ics.rf[i->src2_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_SGT_F64_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 > ics.rf[i->src2_reg].f64; - return IA_NEXT; -} -int Translate_COMPARE_SGT(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_COMPARE_SGT_I8_I8, IntCode_COMPARE_SGT_I16_I16, - IntCode_COMPARE_SGT_I32_I32, IntCode_COMPARE_SGT_I64_I64, - IntCode_COMPARE_SGT_F32_F32, IntCode_COMPARE_SGT_F64_F64, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_COMPARE_SGE_I8_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 >= ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_SGE_I16_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i16 >= ics.rf[i->src2_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_SGE_I32_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i32 >= ics.rf[i->src2_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_SGE_I64_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i64 >= ics.rf[i->src2_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_SGE_F32_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 >= ics.rf[i->src2_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_SGE_F64_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 >= ics.rf[i->src2_reg].f64; - return IA_NEXT; -} -int Translate_COMPARE_SGE(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_COMPARE_SGE_I8_I8, IntCode_COMPARE_SGE_I16_I16, - IntCode_COMPARE_SGE_I32_I32, IntCode_COMPARE_SGE_I64_I64, - IntCode_COMPARE_SGE_F32_F32, IntCode_COMPARE_SGE_F64_F64, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_COMPARE_ULT_I8_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u8 < ics.rf[i->src2_reg].u8; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_ULT_I16_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u16 < ics.rf[i->src2_reg].u16; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_ULT_I32_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u32 < ics.rf[i->src2_reg].u32; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_ULT_I64_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u64 < ics.rf[i->src2_reg].u64; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_ULT_F32_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 < ics.rf[i->src2_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_ULT_F64_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 < ics.rf[i->src2_reg].f64; - return IA_NEXT; -} -int Translate_COMPARE_ULT(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_COMPARE_ULT_I8_I8, IntCode_COMPARE_ULT_I16_I16, - IntCode_COMPARE_ULT_I32_I32, IntCode_COMPARE_ULT_I64_I64, - IntCode_COMPARE_ULT_F32_F32, IntCode_COMPARE_ULT_F64_F64, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_COMPARE_ULE_I8_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u8 <= ics.rf[i->src2_reg].u8; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_ULE_I16_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u16 <= ics.rf[i->src2_reg].u16; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_ULE_I32_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u32 <= ics.rf[i->src2_reg].u32; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_ULE_I64_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u64 <= ics.rf[i->src2_reg].u64; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_ULE_F32_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 <= ics.rf[i->src2_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_ULE_F64_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 <= ics.rf[i->src2_reg].f64; - return IA_NEXT; -} -int Translate_COMPARE_ULE(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_COMPARE_ULE_I8_I8, IntCode_COMPARE_ULE_I16_I16, - IntCode_COMPARE_ULE_I32_I32, IntCode_COMPARE_ULE_I64_I64, - IntCode_COMPARE_ULE_F32_F32, IntCode_COMPARE_ULE_F64_F64, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_COMPARE_UGT_I8_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u8 > ics.rf[i->src2_reg].u8; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_UGT_I16_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u16 > ics.rf[i->src2_reg].u16; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_UGT_I32_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u32 > ics.rf[i->src2_reg].u32; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_UGT_I64_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u64 > ics.rf[i->src2_reg].u64; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_UGT_F32_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 > ics.rf[i->src2_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_UGT_F64_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 > ics.rf[i->src2_reg].f64; - return IA_NEXT; -} -int Translate_COMPARE_UGT(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_COMPARE_UGT_I8_I8, IntCode_COMPARE_UGT_I16_I16, - IntCode_COMPARE_UGT_I32_I32, IntCode_COMPARE_UGT_I64_I64, - IntCode_COMPARE_UGT_F32_F32, IntCode_COMPARE_UGT_F64_F64, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_COMPARE_UGE_I8_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u8 >= ics.rf[i->src2_reg].u8; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_UGE_I16_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u16 >= ics.rf[i->src2_reg].u16; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_UGE_I32_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u32 >= ics.rf[i->src2_reg].u32; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_UGE_I64_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u64 >= ics.rf[i->src2_reg].u64; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_UGE_F32_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f32 >= ics.rf[i->src2_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_COMPARE_UGE_F64_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].f64 >= ics.rf[i->src2_reg].f64; - return IA_NEXT; -} -int Translate_COMPARE_UGE(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_COMPARE_UGE_I8_I8, IntCode_COMPARE_UGE_I16_I16, - IntCode_COMPARE_UGE_I32_I32, IntCode_COMPARE_UGE_I64_I64, - IntCode_COMPARE_UGE_F32_F32, IntCode_COMPARE_UGE_F64_F64, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_DID_CARRY(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.did_carry; - return IA_NEXT; -} -int Translate_DID_CARRY(TranslationContext& ctx, Instr* i) { - return DispatchToC(ctx, i, IntCode_DID_CARRY); -} - -uint32_t IntCode_DID_SATURATE(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.did_saturate; - return IA_NEXT; -} -int Translate_DID_SATURATE(TranslationContext& ctx, Instr* i) { - return DispatchToC(ctx, i, IntCode_DID_SATURATE); -} - -#define VECTOR_COMPARER(type, value, dest_type, dest_value, count, op) \ - const vec128_t& src1 = ics.rf[i->src1_reg].v128; \ - const vec128_t& src2 = ics.rf[i->src2_reg].v128; \ - vec128_t& dest = ics.rf[i->dest_reg].v128; \ - for (int n = 0; n < count; n++) { \ - dest.dest_value[n] = ((type)src1.value[n] op(type) src2.value[n]) \ - ? (dest_type)0xFFFFFFFF \ - : 0; \ - } \ - return IA_NEXT; - -uint32_t IntCode_VECTOR_COMPARE_EQ_I8(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(uint8_t, u8, uint8_t, u8, 16, == )}; -uint32_t IntCode_VECTOR_COMPARE_EQ_I16(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(uint16_t, u16, uint16_t, u16, 8, == )}; -uint32_t IntCode_VECTOR_COMPARE_EQ_I32(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(uint32_t, u32, uint32_t, u32, 4, == )}; -uint32_t IntCode_VECTOR_COMPARE_EQ_F32(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(float, f32, uint32_t, u32, 4, == )}; -int Translate_VECTOR_COMPARE_EQ(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_VECTOR_COMPARE_EQ_I8, IntCode_VECTOR_COMPARE_EQ_I16, - IntCode_VECTOR_COMPARE_EQ_I32, IntCode_INVALID_TYPE, - IntCode_VECTOR_COMPARE_EQ_F32, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->flags]); -} - -uint32_t IntCode_VECTOR_COMPARE_SGT_I8(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(int8_t, i8, int8_t, i8, 16, > )}; -uint32_t IntCode_VECTOR_COMPARE_SGT_I16(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(int16_t, i16, int16_t, i16, 8, > )}; -uint32_t IntCode_VECTOR_COMPARE_SGT_I32(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(int32_t, i32, int32_t, i32, 4, > )}; -uint32_t IntCode_VECTOR_COMPARE_SGT_F32(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(float, f32, uint32_t, u32, 4, > )}; -int Translate_VECTOR_COMPARE_SGT(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_VECTOR_COMPARE_SGT_I8, IntCode_VECTOR_COMPARE_SGT_I16, - IntCode_VECTOR_COMPARE_SGT_I32, IntCode_INVALID_TYPE, - IntCode_VECTOR_COMPARE_SGT_F32, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->flags]); -} - -uint32_t IntCode_VECTOR_COMPARE_SGE_I8(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(int8_t, i8, int8_t, i8, 16, >= )}; -uint32_t IntCode_VECTOR_COMPARE_SGE_I16(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(int16_t, i16, int16_t, i16, 8, >= )}; -uint32_t IntCode_VECTOR_COMPARE_SGE_I32(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(int32_t, i32, int32_t, i32, 4, >= )}; -uint32_t IntCode_VECTOR_COMPARE_SGE_F32(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(float, f32, uint32_t, u32, 4, >= )}; -int Translate_VECTOR_COMPARE_SGE(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_VECTOR_COMPARE_SGE_I8, IntCode_VECTOR_COMPARE_SGE_I16, - IntCode_VECTOR_COMPARE_SGE_I32, IntCode_INVALID_TYPE, - IntCode_VECTOR_COMPARE_SGE_F32, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->flags]); -} - -uint32_t IntCode_VECTOR_COMPARE_UGT_I8(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(uint8_t, u8, uint8_t, u8, 16, > )}; -uint32_t IntCode_VECTOR_COMPARE_UGT_I16(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(uint16_t, u16, uint16_t, u16, 8, > )}; -uint32_t IntCode_VECTOR_COMPARE_UGT_I32(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(uint32_t, u32, uint32_t, u32, 4, > )}; -uint32_t IntCode_VECTOR_COMPARE_UGT_F32(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(float, f32, uint32_t, u32, 4, > )}; -int Translate_VECTOR_COMPARE_UGT(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_VECTOR_COMPARE_UGT_I8, IntCode_VECTOR_COMPARE_UGT_I16, - IntCode_VECTOR_COMPARE_UGT_I32, IntCode_INVALID_TYPE, - IntCode_VECTOR_COMPARE_UGT_F32, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->flags]); -} - -uint32_t IntCode_VECTOR_COMPARE_UGE_I8(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(uint8_t, u8, uint8_t, u8, 16, >= )}; -uint32_t IntCode_VECTOR_COMPARE_UGE_I16(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(uint16_t, u16, uint16_t, u16, 8, >= )}; -uint32_t IntCode_VECTOR_COMPARE_UGE_I32(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(uint32_t, u32, uint32_t, u32, 4, >= )}; -uint32_t IntCode_VECTOR_COMPARE_UGE_F32(IntCodeState& ics, const IntCode* i){ - VECTOR_COMPARER(float, f32, uint32_t, u32, 4, >= )}; -int Translate_VECTOR_COMPARE_UGE(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_VECTOR_COMPARE_UGE_I8, IntCode_VECTOR_COMPARE_UGE_I16, - IntCode_VECTOR_COMPARE_UGE_I32, IntCode_INVALID_TYPE, - IntCode_VECTOR_COMPARE_UGE_F32, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->flags]); -} - -#define CHECK_DID_CARRY(v1, v2) (((uint64_t)v2) > ~((uint64_t)v1)) -#define ADD_DID_CARRY(a, b) CHECK_DID_CARRY(a, b) -uint32_t IntCode_ADD_I8_I8(IntCodeState& ics, const IntCode* i) { - int8_t a = ics.rf[i->src1_reg].i8; - int8_t b = ics.rf[i->src2_reg].i8; - if (i->flags == ARITHMETIC_SET_CARRY) { - ics.did_carry = ADD_DID_CARRY(a, b); - } - ics.rf[i->dest_reg].i8 = a + b; - return IA_NEXT; -} -uint32_t IntCode_ADD_I16_I16(IntCodeState& ics, const IntCode* i) { - int16_t a = ics.rf[i->src1_reg].i16; - int16_t b = ics.rf[i->src2_reg].i16; - if (i->flags == ARITHMETIC_SET_CARRY) { - ics.did_carry = ADD_DID_CARRY(a, b); - } - ics.rf[i->dest_reg].i16 = a + b; - return IA_NEXT; -} -uint32_t IntCode_ADD_I32_I32(IntCodeState& ics, const IntCode* i) { - int32_t a = ics.rf[i->src1_reg].i32; - int32_t b = ics.rf[i->src2_reg].i32; - if (i->flags == ARITHMETIC_SET_CARRY) { - ics.did_carry = ADD_DID_CARRY(a, b); - } - ics.rf[i->dest_reg].i32 = a + b; - return IA_NEXT; -} -uint32_t IntCode_ADD_I64_I64(IntCodeState& ics, const IntCode* i) { - int64_t a = ics.rf[i->src1_reg].i64; - int64_t b = ics.rf[i->src2_reg].i64; - if (i->flags == ARITHMETIC_SET_CARRY) { - ics.did_carry = ADD_DID_CARRY(a, b); - } - ics.rf[i->dest_reg].i64 = a + b; - return IA_NEXT; -} -uint32_t IntCode_ADD_F32_F32(IntCodeState& ics, const IntCode* i) { - assert_true(!i->flags); - ics.rf[i->dest_reg].f32 = ics.rf[i->src1_reg].f32 + ics.rf[i->src2_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_ADD_F64_F64(IntCodeState& ics, const IntCode* i) { - assert_true(!i->flags); - ics.rf[i->dest_reg].f64 = ics.rf[i->src1_reg].f64 + ics.rf[i->src2_reg].f64; - return IA_NEXT; -} -int Translate_ADD(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_ADD_I8_I8, IntCode_ADD_I16_I16, IntCode_ADD_I32_I32, - IntCode_ADD_I64_I64, IntCode_ADD_F32_F32, IntCode_ADD_F64_F64, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -#define ADD_CARRY_DID_CARRY(a, b, c) \ - (CHECK_DID_CARRY(a, b) || ((c) != 0) && CHECK_DID_CARRY((a) + (b), c)) -uint32_t IntCode_ADD_CARRY_I8_I8(IntCodeState& ics, const IntCode* i) { - int8_t a = ics.rf[i->src1_reg].i8; - int8_t b = ics.rf[i->src2_reg].i8; - uint8_t c = ics.rf[i->src3_reg].u8; - if (i->flags == ARITHMETIC_SET_CARRY) { - ics.did_carry = ADD_CARRY_DID_CARRY(a, b, c); - } - ics.rf[i->dest_reg].i8 = a + b + c; - return IA_NEXT; -} -uint32_t IntCode_ADD_CARRY_I16_I16(IntCodeState& ics, const IntCode* i) { - int16_t a = ics.rf[i->src1_reg].i16; - int16_t b = ics.rf[i->src2_reg].i16; - uint8_t c = ics.rf[i->src3_reg].u8; - if (i->flags == ARITHMETIC_SET_CARRY) { - ics.did_carry = ADD_CARRY_DID_CARRY(a, b, c); - } - ics.rf[i->dest_reg].i16 = a + b + c; - return IA_NEXT; -} -uint32_t IntCode_ADD_CARRY_I32_I32(IntCodeState& ics, const IntCode* i) { - int32_t a = ics.rf[i->src1_reg].i32; - int32_t b = ics.rf[i->src2_reg].i32; - uint8_t c = ics.rf[i->src3_reg].u8; - if (i->flags == ARITHMETIC_SET_CARRY) { - ics.did_carry = ADD_CARRY_DID_CARRY(a, b, c); - } - ics.rf[i->dest_reg].i32 = a + b + c; - return IA_NEXT; -} -uint32_t IntCode_ADD_CARRY_I64_I64(IntCodeState& ics, const IntCode* i) { - int64_t a = ics.rf[i->src1_reg].i64; - int64_t b = ics.rf[i->src2_reg].i64; - uint8_t c = ics.rf[i->src3_reg].u8; - if (i->flags == ARITHMETIC_SET_CARRY) { - ics.did_carry = ADD_CARRY_DID_CARRY(a, b, c); - } - ics.rf[i->dest_reg].i64 = a + b + c; - return IA_NEXT; -} -uint32_t IntCode_ADD_CARRY_F32_F32(IntCodeState& ics, const IntCode* i) { - assert_true(!i->flags); - ics.rf[i->dest_reg].f32 = ics.rf[i->src1_reg].f32 + ics.rf[i->src2_reg].f32 + - ics.rf[i->src3_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_ADD_CARRY_F64_F64(IntCodeState& ics, const IntCode* i) { - assert_true(!i->flags); - ics.rf[i->dest_reg].f64 = ics.rf[i->src1_reg].f64 + ics.rf[i->src2_reg].f64 + - ics.rf[i->src3_reg].i8; - return IA_NEXT; -} -int Translate_ADD_CARRY(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_ADD_CARRY_I8_I8, IntCode_ADD_CARRY_I16_I16, - IntCode_ADD_CARRY_I32_I32, IntCode_ADD_CARRY_I64_I64, - IntCode_ADD_CARRY_F32_F32, IntCode_ADD_CARRY_F64_F64, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t Translate_VECTOR_ADD_I8(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - const uint32_t arithmetic_flags = i->flags >> 8; - if (arithmetic_flags & ARITHMETIC_SATURATE) { - if (arithmetic_flags & ARITHMETIC_UNSIGNED) { - for (int n = 0; n < 16; n++) { - uint16_t v = src1.u8[n] + src2.u8[n]; - if (v > 0xFF) { - dest.u8[n] = 0xFF; - ics.did_saturate = 1; - } else { - dest.u8[n] = (uint8_t)v; - } - } - } else { - for (int n = 0; n < 16; n++) { - int16_t v = (int8_t)src1.u8[n] + (int8_t)src2.u8[n]; - if (v > 0x7F) { - dest.u8[n] = 0x7F; - ics.did_saturate = 1; - } else if (v < -0x80) { - dest.u8[n] = -0x80; - ics.did_saturate = 1; - } else { - dest.u8[n] = (uint8_t)v; - } - } - } - } else { - for (int n = 0; n < 16; n++) { - dest.u8[n] = src1.u8[n] + src2.u8[n]; - } - } - return IA_NEXT; -} -uint32_t Translate_VECTOR_ADD_I16(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - const uint32_t arithmetic_flags = i->flags >> 8; - if (arithmetic_flags & ARITHMETIC_SATURATE) { - if (arithmetic_flags & ARITHMETIC_UNSIGNED) { - for (int n = 0; n < 8; n++) { - uint32_t v = src1.u16[n] + src2.u16[n]; - if (v > 0xFFFF) { - dest.u16[n] = 0xFFFF; - ics.did_saturate = 1; - } else { - dest.u16[n] = (uint16_t)v; - } - } - } else { - for (int n = 0; n < 8; n++) { - int32_t v = (int16_t)src1.u16[n] + (int16_t)src2.u16[n]; - if (v > 0x7FFF) { - dest.u16[n] = 0x7FFF; - ics.did_saturate = 1; - } else if (v < -0x8000) { - dest.u16[n] = -0x8000; - ics.did_saturate = 1; - } else { - dest.u16[n] = (uint16_t)v; - } - } - } - } else { - for (int n = 0; n < 8; n++) { - dest.u16[n] = src1.u16[n] + src2.u16[n]; - } - } - return IA_NEXT; -} -uint32_t Translate_VECTOR_ADD_I32(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - const uint32_t arithmetic_flags = i->flags >> 8; - if (arithmetic_flags & ARITHMETIC_SATURATE) { - if (arithmetic_flags & ARITHMETIC_UNSIGNED) { - for (int n = 0; n < 4; n++) { - uint64_t v = (uint64_t)src1.u32[n] + (uint64_t)src2.u32[n]; - if (v > 0xFFFFFFFF) { - dest.u32[n] = 0xFFFFFFFF; - ics.did_saturate = 1; - } else { - dest.u32[n] = (uint32_t)v; - } - } - } else { - for (int n = 0; n < 4; n++) { - int64_t v = - (int64_t)(int32_t)src1.u32[n] + (int64_t)(int32_t)src2.u32[n]; - if (v > 0x7FFFFFFF) { - dest.u32[n] = 0x7FFFFFFF; - ics.did_saturate = 1; - } else if (v < -0x80000000ll) { - dest.u32[n] = 0x80000000; - ics.did_saturate = 1; - } else { - dest.u32[n] = (uint32_t)v; - } - } - } - } else { - for (int n = 0; n < 4; n++) { - dest.u32[n] = src1.u32[n] + src2.u32[n]; - } - } - return IA_NEXT; -} -uint32_t Translate_VECTOR_ADD_F32(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.f32[n] = src1.f32[n] + src2.f32[n]; - } - return IA_NEXT; -} -int Translate_VECTOR_ADD(TranslationContext& ctx, Instr* i) { - TypeName part_type = (TypeName)(i->flags & 0xFF); - static IntCodeFn fns[] = { - Translate_VECTOR_ADD_I8, Translate_VECTOR_ADD_I16, - Translate_VECTOR_ADD_I32, IntCode_INVALID_TYPE, - Translate_VECTOR_ADD_F32, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[part_type]); -} - -#define SUB_DID_CARRY(a, b) ((b) == 0) || CHECK_DID_CARRY(a, 0 - b) -uint32_t IntCode_SUB_I8_I8(IntCodeState& ics, const IntCode* i) { - int8_t a = ics.rf[i->src1_reg].i8; - int8_t b = ics.rf[i->src2_reg].i8; - if (i->flags == ARITHMETIC_SET_CARRY) { - ics.did_carry = SUB_DID_CARRY(a, b); - } - ics.rf[i->dest_reg].i8 = a - b; - return IA_NEXT; -} -uint32_t IntCode_SUB_I16_I16(IntCodeState& ics, const IntCode* i) { - int16_t a = ics.rf[i->src1_reg].i16; - int16_t b = ics.rf[i->src2_reg].i16; - if (i->flags == ARITHMETIC_SET_CARRY) { - ics.did_carry = SUB_DID_CARRY(a, b); - } - ics.rf[i->dest_reg].i16 = a - b; - return IA_NEXT; -} -uint32_t IntCode_SUB_I32_I32(IntCodeState& ics, const IntCode* i) { - int32_t a = ics.rf[i->src1_reg].i32; - int32_t b = ics.rf[i->src2_reg].i32; - if (i->flags == ARITHMETIC_SET_CARRY) { - ics.did_carry = SUB_DID_CARRY(a, b); - } - ics.rf[i->dest_reg].i32 = a - b; - return IA_NEXT; -} -uint32_t IntCode_SUB_I64_I64(IntCodeState& ics, const IntCode* i) { - int64_t a = ics.rf[i->src1_reg].i64; - int64_t b = ics.rf[i->src2_reg].i64; - if (i->flags == ARITHMETIC_SET_CARRY) { - ics.did_carry = SUB_DID_CARRY(a, b); - } - ics.rf[i->dest_reg].i64 = a - b; - return IA_NEXT; -} -uint32_t IntCode_SUB_F32_F32(IntCodeState& ics, const IntCode* i) { - assert_true(!i->flags); - ics.rf[i->dest_reg].f32 = ics.rf[i->src1_reg].f32 - ics.rf[i->src2_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_SUB_F64_F64(IntCodeState& ics, const IntCode* i) { - assert_true(!i->flags); - ics.rf[i->dest_reg].f64 = ics.rf[i->src1_reg].f64 - ics.rf[i->src2_reg].f64; - return IA_NEXT; -} -int Translate_SUB(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_SUB_I8_I8, IntCode_SUB_I16_I16, IntCode_SUB_I32_I32, - IntCode_SUB_I64_I64, IntCode_SUB_F32_F32, IntCode_SUB_F64_F64, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t Translate_VECTOR_SUB_I8(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - uint32_t flags = i->flags >> 8; - // assert_zero(flags & ARITHMETIC_SATURATE); - if (flags & ARITHMETIC_UNSIGNED) { - for (int n = 0; n < 16; n++) { - dest.u8[n] = src1.u8[n] - src2.u8[n]; - } - } else { - for (int n = 0; n < 16; n++) { - dest.i8[n] = src1.i8[n] - src2.i8[n]; - } - } - return IA_NEXT; -} -uint32_t Translate_VECTOR_SUB_I16(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - uint32_t flags = i->flags >> 8; - // assert_zero(flags & ARITHMETIC_SATURATE); - if (flags & ARITHMETIC_UNSIGNED) { - for (int n = 0; n < 8; n++) { - dest.u16[n] = src1.u16[n] - src2.u16[n]; - } - } else { - for (int n = 0; n < 8; n++) { - dest.i16[n] = src1.i16[n] - src2.i16[n]; - } - } - return IA_NEXT; -} -uint32_t Translate_VECTOR_SUB_I32(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - uint32_t flags = i->flags >> 8; - // assert_zero(flags & ARITHMETIC_SATURATE); - if (flags & ARITHMETIC_UNSIGNED) { - for (int n = 0; n < 4; n++) { - dest.u32[n] = src1.u32[n] - src2.u32[n]; - } - } else { - for (int n = 0; n < 4; n++) { - dest.i32[n] = src1.i32[n] - src2.i32[n]; - } - } - return IA_NEXT; -} -uint32_t Translate_VECTOR_SUB_F32(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - uint32_t flags = i->flags >> 8; - for (int n = 0; n < 4; n++) { - dest.f32[n] = src1.f32[n] - src2.f32[n]; - } - return IA_NEXT; -} -int Translate_VECTOR_SUB(TranslationContext& ctx, Instr* i) { - TypeName part_type = (TypeName)(i->flags & 0xFF); - static IntCodeFn fns[] = { - Translate_VECTOR_SUB_I8, Translate_VECTOR_SUB_I16, - Translate_VECTOR_SUB_I32, IntCode_INVALID_TYPE, - Translate_VECTOR_SUB_F32, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[part_type]); -} - -uint32_t IntCode_MUL_I8_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 * ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_MUL_I16_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = ics.rf[i->src1_reg].i16 * ics.rf[i->src2_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_MUL_I32_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = ics.rf[i->src1_reg].i32 * ics.rf[i->src2_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_MUL_I64_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = ics.rf[i->src1_reg].i64 * ics.rf[i->src2_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_MUL_F32_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f32 = ics.rf[i->src1_reg].f32 * ics.rf[i->src2_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_MUL_F64_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f64 = ics.rf[i->src1_reg].f64 * ics.rf[i->src2_reg].f64; - return IA_NEXT; -} -uint32_t IntCode_MUL_V128_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.f32[n] = src1.f32[n] * src2.f32[n]; - } - return IA_NEXT; -} -uint32_t IntCode_MUL_I8_I8_U(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].u8 = ics.rf[i->src1_reg].u8 * ics.rf[i->src2_reg].u8; - return IA_NEXT; -} -uint32_t IntCode_MUL_I16_I16_U(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].u16 = ics.rf[i->src1_reg].u16 * ics.rf[i->src2_reg].u16; - return IA_NEXT; -} -uint32_t IntCode_MUL_I32_I32_U(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].u32 = ics.rf[i->src1_reg].u32 * ics.rf[i->src2_reg].u32; - return IA_NEXT; -} -uint32_t IntCode_MUL_I64_I64_U(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].u64 = ics.rf[i->src1_reg].u64 * ics.rf[i->src2_reg].u64; - return IA_NEXT; -} -int Translate_MUL(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_MUL_I8_I8, IntCode_MUL_I16_I16, IntCode_MUL_I32_I32, - IntCode_MUL_I64_I64, IntCode_MUL_F32_F32, IntCode_MUL_F64_F64, - IntCode_MUL_V128_V128, - }; - static IntCodeFn fns_unsigned[] = { - IntCode_MUL_I8_I8_U, IntCode_MUL_I16_I16_U, IntCode_MUL_I32_I32_U, - IntCode_MUL_I64_I64_U, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - if (i->flags & ARITHMETIC_UNSIGNED) { - return DispatchToC(ctx, i, fns_unsigned[i->dest->type]); - } else { - return DispatchToC(ctx, i, fns[i->dest->type]); - } -} - -#if XE_COMPILER_MSVC -uint64_t Mul128(uint64_t xi_low, uint64_t xi_high, uint64_t yi_low, - uint64_t yi_high) { -// 128bit multiply, simplified for two input 64bit integers. -// http://mrob.com/pub/math/int128.c.txt -#define HI_WORD 0xFFFFFFFF00000000LL -#define LO_WORD 0x00000000FFFFFFFFLL - uint64_t d = xi_low & LO_WORD; - uint64_t c = (xi_low & HI_WORD) >> 32LL; - uint64_t b = xi_high & LO_WORD; - uint64_t a = (xi_high & HI_WORD) >> 32LL; - uint64_t h = yi_low & LO_WORD; - uint64_t g = (yi_low & HI_WORD) >> 32LL; - uint64_t f = yi_high & LO_WORD; - uint64_t e = (yi_high & HI_WORD) >> 32LL; - uint64_t acc = d * h; - acc >>= 32LL; - uint64_t carry = 0; - - uint64_t ac2 = acc + c * h; - if (ac2 < acc) { - carry++; - } - acc = ac2 + d * g; - if (acc < ac2) { - carry++; - } - ac2 = (acc >> 32LL) | (carry << 32LL); - carry = 0; - - acc = ac2 + b * h; - if (acc < ac2) { - carry++; - } - ac2 = acc + c * g; - if (ac2 < acc) { - carry++; - } - acc = ac2 + d * f; - if (acc < ac2) { - carry++; - } - uint64_t o2 = acc & LO_WORD; - ac2 = (acc >> 32LL) | (carry << 32LL); - - acc = ac2 + a * h; - ac2 = acc + b * g; - acc = ac2 + c * f; - ac2 = acc + d * e; - uint64_t rv2_hi = (ac2 << 32LL) | o2; - - return rv2_hi; -} -#endif // !XE_COMPILER_MSVC - -uint32_t IntCode_MUL_HI_I8_I8(IntCodeState& ics, const IntCode* i) { - int16_t v = (int16_t)ics.rf[i->src1_reg].i8 * (int16_t)ics.rf[i->src2_reg].i8; - ics.rf[i->dest_reg].i8 = (v >> 8); - return IA_NEXT; -} -uint32_t IntCode_MUL_HI_I16_I16(IntCodeState& ics, const IntCode* i) { - int32_t v = - (int32_t)ics.rf[i->src1_reg].i16 * (int32_t)ics.rf[i->src2_reg].i16; - ics.rf[i->dest_reg].i16 = (v >> 16); - return IA_NEXT; -} -uint32_t IntCode_MUL_HI_I32_I32(IntCodeState& ics, const IntCode* i) { - int64_t v = - (int64_t)ics.rf[i->src1_reg].i32 * (int64_t)ics.rf[i->src2_reg].i32; - ics.rf[i->dest_reg].i32 = (v >> 32); - return IA_NEXT; -} -uint32_t IntCode_MUL_HI_I64_I64(IntCodeState& ics, const IntCode* i) { -#if !XE_COMPILER_MSVC - // GCC can, in theory, do this: - __int128 v = - (__int128)ics.rf[i->src1_reg].i64 * (__int128)ics.rf[i->src2_reg].i64; - ics.rf[i->dest_reg].i64 = (v >> 64); -#else - // 128bit multiply, simplified for two input 64bit integers. - // http://mrob.com/pub/math/int128.c.txt - int64_t xi_low = ics.rf[i->src1_reg].i64; - int64_t xi_high = xi_low < 0 ? -1 : 0; - int64_t yi_low = ics.rf[i->src2_reg].i64; - int64_t yi_high = yi_low < 0 ? -1 : 0; - ics.rf[i->dest_reg].i64 = Mul128(xi_low, xi_high, yi_low, yi_high); -#endif // !MSVC - return IA_NEXT; -} -uint32_t IntCode_MUL_HI_I8_I8_U(IntCodeState& ics, const IntCode* i) { - uint16_t v = - (uint16_t)ics.rf[i->src1_reg].u8 * (uint16_t)ics.rf[i->src2_reg].u8; - ics.rf[i->dest_reg].u8 = (v >> 8); - return IA_NEXT; -} -uint32_t IntCode_MUL_HI_I16_I16_U(IntCodeState& ics, const IntCode* i) { - uint32_t v = - (uint32_t)ics.rf[i->src1_reg].u16 * (uint32_t)ics.rf[i->src2_reg].u16; - ics.rf[i->dest_reg].u16 = (v >> 16); - return IA_NEXT; -} -uint32_t IntCode_MUL_HI_I32_I32_U(IntCodeState& ics, const IntCode* i) { - uint64_t v = - (uint64_t)ics.rf[i->src1_reg].u32 * (uint64_t)ics.rf[i->src2_reg].u32; - ics.rf[i->dest_reg].u32 = (v >> 32); - return IA_NEXT; -} -uint32_t IntCode_MUL_HI_I64_I64_U(IntCodeState& ics, const IntCode* i) { -#if !XE_COMPILER_MSVC - // GCC can, in theory, do this: - __int128 v = - (__int128)ics.rf[i->src1_reg].i64 * (__int128)ics.rf[i->src2_reg].i64; - ics.rf[i->dest_reg].i64 = (v >> 64); -#else - // 128bit multiply, simplified for two input 64bit integers. - // http://mrob.com/pub/math/int128.c.txt - int64_t xi_low = ics.rf[i->src1_reg].i64; - int64_t xi_high = 0; - int64_t yi_low = ics.rf[i->src2_reg].i64; - int64_t yi_high = 0; - ics.rf[i->dest_reg].i64 = Mul128(xi_low, xi_high, yi_low, yi_high); -#endif // !MSVC - return IA_NEXT; -} -int Translate_MUL_HI(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_MUL_HI_I8_I8, IntCode_MUL_HI_I16_I16, IntCode_MUL_HI_I32_I32, - IntCode_MUL_HI_I64_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - static IntCodeFn fns_unsigned[] = { - IntCode_MUL_HI_I8_I8_U, IntCode_MUL_HI_I16_I16_U, - IntCode_MUL_HI_I32_I32_U, IntCode_MUL_HI_I64_I64_U, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - if (i->flags & ARITHMETIC_UNSIGNED) { - return DispatchToC(ctx, i, fns_unsigned[i->dest->type]); - } else { - return DispatchToC(ctx, i, fns[i->dest->type]); - } -} - -uint32_t IntCode_DIV_I8_I8(IntCodeState& ics, const IntCode* i) { - auto divisor = ics.rf[i->src2_reg].i8; - ics.rf[i->dest_reg].i8 = divisor ? ics.rf[i->src1_reg].i8 / divisor : 0; - return IA_NEXT; -} -uint32_t IntCode_DIV_I16_I16(IntCodeState& ics, const IntCode* i) { - auto divisor = ics.rf[i->src2_reg].i16; - ics.rf[i->dest_reg].i16 = divisor ? ics.rf[i->src1_reg].i16 / divisor : 0; - return IA_NEXT; -} -uint32_t IntCode_DIV_I32_I32(IntCodeState& ics, const IntCode* i) { - auto divisor = ics.rf[i->src2_reg].i32; - ics.rf[i->dest_reg].i32 = divisor ? ics.rf[i->src1_reg].i32 / divisor : 0; - return IA_NEXT; -} -uint32_t IntCode_DIV_I64_I64(IntCodeState& ics, const IntCode* i) { - auto divisor = ics.rf[i->src2_reg].i64; - ics.rf[i->dest_reg].i64 = divisor ? ics.rf[i->src1_reg].i64 / divisor : 0; - return IA_NEXT; -} -uint32_t IntCode_DIV_F32_F32(IntCodeState& ics, const IntCode* i) { - auto divisor = ics.rf[i->src2_reg].f32; - ics.rf[i->dest_reg].f32 = divisor ? ics.rf[i->src1_reg].f32 / divisor : 0; - return IA_NEXT; -} -uint32_t IntCode_DIV_F64_F64(IntCodeState& ics, const IntCode* i) { - auto divisor = ics.rf[i->src2_reg].f64; - ics.rf[i->dest_reg].f64 = divisor ? ics.rf[i->src1_reg].f64 / divisor : 0; - return IA_NEXT; -} -uint32_t IntCode_DIV_V128_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.f32[n] = src1.f32[n] / src2.f32[n]; - } - return IA_NEXT; -} -uint32_t IntCode_DIV_I8_I8_U(IntCodeState& ics, const IntCode* i) { - auto divisor = ics.rf[i->src2_reg].u8; - ics.rf[i->dest_reg].u8 = divisor ? ics.rf[i->src1_reg].u8 / divisor : 0; - return IA_NEXT; -} -uint32_t IntCode_DIV_I16_I16_U(IntCodeState& ics, const IntCode* i) { - auto divisor = ics.rf[i->src2_reg].u16; - ics.rf[i->dest_reg].u16 = divisor ? ics.rf[i->src1_reg].u16 / divisor : 0; - return IA_NEXT; -} -uint32_t IntCode_DIV_I32_I32_U(IntCodeState& ics, const IntCode* i) { - auto divisor = ics.rf[i->src2_reg].u32; - ics.rf[i->dest_reg].u32 = divisor ? ics.rf[i->src1_reg].u32 / divisor : 0; - return IA_NEXT; -} -uint32_t IntCode_DIV_I64_I64_U(IntCodeState& ics, const IntCode* i) { - auto divisor = ics.rf[i->src2_reg].u64; - ics.rf[i->dest_reg].u64 = divisor ? ics.rf[i->src1_reg].u64 / divisor : 0; - return IA_NEXT; -} -int Translate_DIV(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_DIV_I8_I8, IntCode_DIV_I16_I16, IntCode_DIV_I32_I32, - IntCode_DIV_I64_I64, IntCode_DIV_F32_F32, IntCode_DIV_F64_F64, - IntCode_DIV_V128_V128, - }; - static IntCodeFn fns_unsigned[] = { - IntCode_DIV_I8_I8_U, IntCode_DIV_I16_I16_U, IntCode_DIV_I32_I32_U, - IntCode_DIV_I64_I64_U, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - if (i->flags & ARITHMETIC_UNSIGNED) { - return DispatchToC(ctx, i, fns_unsigned[i->dest->type]); - } else { - return DispatchToC(ctx, i, fns[i->dest->type]); - } -} - -// TODO(benvanik): use intrinsics or something -uint32_t IntCode_MUL_ADD_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = - ics.rf[i->src1_reg].i8 * ics.rf[i->src2_reg].i8 + ics.rf[i->src3_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_MUL_ADD_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = ics.rf[i->src1_reg].i16 * ics.rf[i->src2_reg].i16 + - ics.rf[i->src3_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_MUL_ADD_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = ics.rf[i->src1_reg].i32 * ics.rf[i->src2_reg].i32 + - ics.rf[i->src3_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_MUL_ADD_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = ics.rf[i->src1_reg].i64 * ics.rf[i->src2_reg].i64 + - ics.rf[i->src3_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_MUL_ADD_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f32 = ics.rf[i->src1_reg].f32 * ics.rf[i->src2_reg].f32 + - ics.rf[i->src3_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_MUL_ADD_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f64 = ics.rf[i->src1_reg].f64 * ics.rf[i->src2_reg].f64 + - ics.rf[i->src3_reg].f64; - return IA_NEXT; -} -uint32_t IntCode_MUL_ADD_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - const vec128_t& src3 = ics.rf[i->src3_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.f32[n] = src1.f32[n] * src2.f32[n] + src3.f32[n]; - } - return IA_NEXT; -} -int Translate_MUL_ADD(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_MUL_ADD_I8, IntCode_MUL_ADD_I16, IntCode_MUL_ADD_I32, - IntCode_MUL_ADD_I64, IntCode_MUL_ADD_F32, IntCode_MUL_ADD_F64, - IntCode_MUL_ADD_V128, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -// TODO(benvanik): use intrinsics or something -uint32_t IntCode_MUL_SUB_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = - ics.rf[i->src1_reg].i8 * ics.rf[i->src2_reg].i8 - ics.rf[i->src3_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_MUL_SUB_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = ics.rf[i->src1_reg].i16 * ics.rf[i->src2_reg].i16 - - ics.rf[i->src3_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_MUL_SUB_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = ics.rf[i->src1_reg].i32 * ics.rf[i->src2_reg].i32 - - ics.rf[i->src3_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_MUL_SUB_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = ics.rf[i->src1_reg].i64 * ics.rf[i->src2_reg].i64 - - ics.rf[i->src3_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_MUL_SUB_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f32 = ics.rf[i->src1_reg].f32 * ics.rf[i->src2_reg].f32 - - ics.rf[i->src3_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_MUL_SUB_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f64 = ics.rf[i->src1_reg].f64 * ics.rf[i->src2_reg].f64 - - ics.rf[i->src3_reg].f64; - return IA_NEXT; -} -uint32_t IntCode_MUL_SUB_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - const vec128_t& src3 = ics.rf[i->src3_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.f32[n] = src1.f32[n] * src2.f32[n] - src3.f32[n]; - } - return IA_NEXT; -} -int Translate_MUL_SUB(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_MUL_SUB_I8, IntCode_MUL_SUB_I16, IntCode_MUL_SUB_I32, - IntCode_MUL_SUB_I64, IntCode_MUL_SUB_F32, IntCode_MUL_SUB_F64, - IntCode_MUL_SUB_V128, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_NEG_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = -ics.rf[i->src1_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_NEG_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = -ics.rf[i->src1_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_NEG_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = -ics.rf[i->src1_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_NEG_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = -ics.rf[i->src1_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_NEG_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f32 = -ics.rf[i->src1_reg].f32; - return IA_NEXT; -} -uint32_t IntCode_NEG_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f64 = -ics.rf[i->src1_reg].f64; - return IA_NEXT; -} -uint32_t IntCode_NEG_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (size_t j = 0; j < 4; j++) { - dest.f32[j] = -src1.f32[j]; - } - return IA_NEXT; -} -int Translate_NEG(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_NEG_I8, IntCode_NEG_I16, IntCode_NEG_I32, IntCode_NEG_I64, - IntCode_NEG_F32, IntCode_NEG_F64, IntCode_NEG_V128, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_ABS_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = abs(ics.rf[i->src1_reg].i8); - return IA_NEXT; -} -uint32_t IntCode_ABS_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = abs(ics.rf[i->src1_reg].i16); - return IA_NEXT; -} -uint32_t IntCode_ABS_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = abs(ics.rf[i->src1_reg].i32); - return IA_NEXT; -} -uint32_t IntCode_ABS_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = abs(ics.rf[i->src1_reg].i64); - return IA_NEXT; -} -uint32_t IntCode_ABS_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f32 = abs(ics.rf[i->src1_reg].f32); - return IA_NEXT; -} -uint32_t IntCode_ABS_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f64 = abs(ics.rf[i->src1_reg].f64); - return IA_NEXT; -} -uint32_t IntCode_ABS_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (size_t j = 0; j < 4; j++) { - dest.f32[j] = abs(src1.f32[j]); - } - return IA_NEXT; -} -int Translate_ABS(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_ABS_I8, IntCode_ABS_I16, IntCode_ABS_I32, IntCode_ABS_I64, - IntCode_ABS_F32, IntCode_ABS_F64, IntCode_ABS_V128, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_DOT_PRODUCT_3_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - ics.rf[i->dest_reg].f32 = - (src1.x * src2.x) + (src1.y * src2.y) + (src1.z * src2.z); - return IA_NEXT; -} -int Translate_DOT_PRODUCT_3(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_DOT_PRODUCT_3_V128, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_DOT_PRODUCT_4_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - ics.rf[i->dest_reg].f32 = (src1.x * src2.x) + (src1.y * src2.y) + - (src1.z * src2.z) + (src1.w * src2.w); - return IA_NEXT; -} -int Translate_DOT_PRODUCT_4(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_DOT_PRODUCT_4_V128, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_SQRT_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f32 = sqrt(ics.rf[i->src1_reg].f32); - return IA_NEXT; -} -uint32_t IntCode_SQRT_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f64 = sqrt(ics.rf[i->src1_reg].f64); - return IA_NEXT; -} -uint32_t IntCode_SQRT_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (size_t j = 0; j < 4; j++) { - dest.f32[j] = sqrt(src1.f32[j]); - } - return IA_NEXT; -} -int Translate_SQRT(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_SQRT_F32, IntCode_SQRT_F64, - IntCode_SQRT_V128, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_RSQRT_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.f32[n] = 1 / sqrtf(src1.f32[n]); - } - return IA_NEXT; -} -int Translate_RSQRT(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_RSQRT_V128, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_POW2_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f32 = (float)pow(2, ics.rf[i->src1_reg].f32); - return IA_NEXT; -} -uint32_t IntCode_POW2_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f64 = pow(2, ics.rf[i->src1_reg].f64); - return IA_NEXT; -} -uint32_t IntCode_POW2_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (size_t j = 0; j < 4; j++) { - dest.f32[j] = (float)pow(2, src1.f32[j]); - } - return IA_NEXT; -} -int Translate_POW2(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_POW2_F32, IntCode_POW2_F64, - IntCode_POW2_V128, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_LOG2_F32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f32 = log2(ics.rf[i->src1_reg].f32); - return IA_NEXT; -} -uint32_t IntCode_LOG2_F64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].f64 = log2(ics.rf[i->src1_reg].f64); - return IA_NEXT; -} -uint32_t IntCode_LOG2_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (size_t j = 0; j < 4; j++) { - dest.f32[j] = log2(src1.f32[j]); - } - return IA_NEXT; -} -int Translate_LOG2(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_LOG2_F32, IntCode_LOG2_F64, - IntCode_LOG2_V128, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_AND_I8_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 & ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_AND_I16_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = ics.rf[i->src1_reg].i16 & ics.rf[i->src2_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_AND_I32_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = ics.rf[i->src1_reg].i32 & ics.rf[i->src2_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_AND_I64_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = ics.rf[i->src1_reg].i64 & ics.rf[i->src2_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_AND_V128_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.u32[n] = src1.u32[n] & src2.u32[n]; - } - return IA_NEXT; -} -int Translate_AND(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_AND_I8_I8, IntCode_AND_I16_I16, IntCode_AND_I32_I32, - IntCode_AND_I64_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_AND_V128_V128, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_OR_I8_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 | ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_OR_I16_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = ics.rf[i->src1_reg].i16 | ics.rf[i->src2_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_OR_I32_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = ics.rf[i->src1_reg].i32 | ics.rf[i->src2_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_OR_I64_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = ics.rf[i->src1_reg].i64 | ics.rf[i->src2_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_OR_V128_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.u32[n] = src1.u32[n] | src2.u32[n]; - } - return IA_NEXT; -} -int Translate_OR(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_OR_I8_I8, IntCode_OR_I16_I16, IntCode_OR_I32_I32, - IntCode_OR_I64_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_OR_V128_V128, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_XOR_I8_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 ^ ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_XOR_I16_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = ics.rf[i->src1_reg].i16 ^ ics.rf[i->src2_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_XOR_I32_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = ics.rf[i->src1_reg].i32 ^ ics.rf[i->src2_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_XOR_I64_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = ics.rf[i->src1_reg].i64 ^ ics.rf[i->src2_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_XOR_V128_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.u32[n] = src1.u32[n] ^ src2.u32[n]; - } - return IA_NEXT; -} -int Translate_XOR(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_XOR_I8_I8, IntCode_XOR_I16_I16, IntCode_XOR_I32_I32, - IntCode_XOR_I64_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_XOR_V128_V128, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_NOT_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ~ics.rf[i->src1_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_NOT_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = ~ics.rf[i->src1_reg].i16; - return IA_NEXT; -} -uint32_t IntCode_NOT_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = ~ics.rf[i->src1_reg].i32; - return IA_NEXT; -} -uint32_t IntCode_NOT_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = ~ics.rf[i->src1_reg].i64; - return IA_NEXT; -} -uint32_t IntCode_NOT_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.u32[n] = ~src1.u32[n]; - } - return IA_NEXT; -} -int Translate_NOT(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_NOT_I8, IntCode_NOT_I16, IntCode_NOT_I32, - IntCode_NOT_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_NOT_V128, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_SHL_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 << ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_SHL_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = ics.rf[i->src1_reg].i16 << ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_SHL_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = ics.rf[i->src1_reg].i32 << ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_SHL_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = ics.rf[i->src1_reg].i64 << ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -int Translate_SHL(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_SHL_I8, IntCode_SHL_I16, IntCode_SHL_I32, - IntCode_SHL_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_VECTOR_SHL_I8(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 16; n++) { - dest.u8[n] = src1.u8[n] << (src2.u8[n] & 0x7); - } - return IA_NEXT; -} -uint32_t IntCode_VECTOR_SHL_I16(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 8; n++) { - dest.u16[n] = src1.u16[n] << (src2.u16[n] & 0xF); - } - return IA_NEXT; -} -uint32_t IntCode_VECTOR_SHL_I32(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.u32[n] = src1.u32[n] << (src2.u32[n] & 0x1F); - } - return IA_NEXT; -} -int Translate_VECTOR_SHL(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_VECTOR_SHL_I8, IntCode_VECTOR_SHL_I16, IntCode_VECTOR_SHL_I32, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->flags]); -} - -uint32_t IntCode_SHR_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].u8 >> ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_SHR_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = ics.rf[i->src1_reg].u16 >> ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_SHR_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = ics.rf[i->src1_reg].u32 >> ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_SHR_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = ics.rf[i->src1_reg].u64 >> ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -int Translate_SHR(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_SHR_I8, IntCode_SHR_I16, IntCode_SHR_I32, - IntCode_SHR_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_VECTOR_SHR_I8(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 16; n++) { - dest.u8[n] = src1.u8[n] >> (src2.u8[n] & 0x7); - } - return IA_NEXT; -} -uint32_t IntCode_VECTOR_SHR_I16(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 8; n++) { - dest.u16[n] = src1.u16[n] >> (src2.u16[n] & 0xF); - } - return IA_NEXT; -} -uint32_t IntCode_VECTOR_SHR_I32(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.u32[n] = src1.u32[n] >> (src2.u32[n] & 0x1F); - } - return IA_NEXT; -} -int Translate_VECTOR_SHR(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_VECTOR_SHR_I8, IntCode_VECTOR_SHR_I16, IntCode_VECTOR_SHR_I32, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->flags]); -} - -uint32_t IntCode_SHA_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = ics.rf[i->src1_reg].i8 >> ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_SHA_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = ics.rf[i->src1_reg].i16 >> ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_SHA_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = ics.rf[i->src1_reg].i32 >> ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -uint32_t IntCode_SHA_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = ics.rf[i->src1_reg].i64 >> ics.rf[i->src2_reg].i8; - return IA_NEXT; -} -int Translate_SHA(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_SHA_I8, IntCode_SHA_I16, IntCode_SHA_I32, - IntCode_SHA_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_VECTOR_SHA_I8(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 16; n++) { - dest.u8[n] = int8_t(src1.u8[n]) >> (src2.u8[n] & 0x7); - } - return IA_NEXT; -} -uint32_t IntCode_VECTOR_SHA_I16(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 8; n++) { - dest.u16[n] = int16_t(src1.u16[n]) >> (src2.u16[n] & 0xF); - } - return IA_NEXT; -} -uint32_t IntCode_VECTOR_SHA_I32(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.u32[n] = int32_t(src1.u32[n]) >> (src2.u32[n] & 0x1F); - } - return IA_NEXT; -} -int Translate_VECTOR_SHA(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_VECTOR_SHA_I8, IntCode_VECTOR_SHA_I16, IntCode_VECTOR_SHA_I32, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->flags]); -} - -uint32_t IntCode_ROTATE_LEFT_I8(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = poly::rotate_left(ics.rf[i->src1_reg].i8, - ics.rf[i->src2_reg].i8); - return IA_NEXT; -} -uint32_t IntCode_ROTATE_LEFT_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = poly::rotate_left(ics.rf[i->src1_reg].i16, - ics.rf[i->src2_reg].i8); - return IA_NEXT; -} -uint32_t IntCode_ROTATE_LEFT_I32(IntCodeState& ics, const IntCode* i) { - // TODO(benvanik): use _rtol on vc++ - ics.rf[i->dest_reg].i32 = poly::rotate_left(ics.rf[i->src1_reg].i32, - ics.rf[i->src2_reg].i8); - return IA_NEXT; -} -uint32_t IntCode_ROTATE_LEFT_I64(IntCodeState& ics, const IntCode* i) { - // TODO(benvanik): use _rtol64 on vc++ - ics.rf[i->dest_reg].i64 = poly::rotate_left(ics.rf[i->src1_reg].i64, - ics.rf[i->src2_reg].i8); - return IA_NEXT; -} -int Translate_ROTATE_LEFT(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_ROTATE_LEFT_I8, IntCode_ROTATE_LEFT_I16, IntCode_ROTATE_LEFT_I32, - IntCode_ROTATE_LEFT_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_VECTOR_ROTATE_LEFT_I8(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 16; n++) { - dest.u8[n] = poly::rotate_left(src1.u8[n], src2.u8[n] & 0x7); - } - return IA_NEXT; -} -uint32_t IntCode_VECTOR_ROTATE_LEFT_I16(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 8; n++) { - dest.u16[n] = poly::rotate_left(src1.u16[n], src2.u16[n] & 0xF); - } - return IA_NEXT; -} -uint32_t IntCode_VECTOR_ROTATE_LEFT_I32(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.u32[n] = poly::rotate_left(src1.u32[n], src2.u32[n] & 0x1F); - } - return IA_NEXT; -} -int Translate_VECTOR_ROTATE_LEFT(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_VECTOR_ROTATE_LEFT_I8, IntCode_VECTOR_ROTATE_LEFT_I16, - IntCode_VECTOR_ROTATE_LEFT_I32, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->flags]); -} - -uint32_t IntCode_BYTE_SWAP_I16(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i16 = poly::byte_swap(ics.rf[i->src1_reg].i16); - return IA_NEXT; -} -uint32_t IntCode_BYTE_SWAP_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i32 = poly::byte_swap(ics.rf[i->src1_reg].i32); - return IA_NEXT; -} -uint32_t IntCode_BYTE_SWAP_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i64 = poly::byte_swap(ics.rf[i->src1_reg].i64); - return IA_NEXT; -} -uint32_t IntCode_BYTE_SWAP_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (int n = 0; n < 4; n++) { - dest.u32[n] = poly::byte_swap(src1.u32[n]); - } - return IA_NEXT; -} -int Translate_BYTE_SWAP(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, IntCode_BYTE_SWAP_I16, IntCode_BYTE_SWAP_I32, - IntCode_BYTE_SWAP_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_BYTE_SWAP_V128, - }; - return DispatchToC(ctx, i, fns[i->dest->type]); -} - -uint32_t IntCode_CNTLZ_I8(IntCodeState& ics, const IntCode* i) { - // CHECK - assert_always(); - ics.rf[i->dest_reg].i8 = poly::lzcnt(ics.rf[i->src1_reg].i8); - return IA_NEXT; -} -uint32_t IntCode_CNTLZ_I16(IntCodeState& ics, const IntCode* i) { - // CHECK - assert_always(); - ics.rf[i->dest_reg].i8 = poly::lzcnt(ics.rf[i->src1_reg].i16); - return IA_NEXT; -} -uint32_t IntCode_CNTLZ_I32(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = poly::lzcnt(ics.rf[i->src1_reg].i32); - return IA_NEXT; -} -uint32_t IntCode_CNTLZ_I64(IntCodeState& ics, const IntCode* i) { - ics.rf[i->dest_reg].i8 = poly::lzcnt(ics.rf[i->src1_reg].i64); - return IA_NEXT; -} -int Translate_CNTLZ(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_CNTLZ_I8, IntCode_CNTLZ_I16, IntCode_CNTLZ_I32, - IntCode_CNTLZ_I64, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_EXTRACT_INT8_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - ics.rf[i->dest_reg].i8 = src1.i8[ics.rf[i->src2_reg].i8 ^ 0x3]; - return IA_NEXT; -} -uint32_t IntCode_EXTRACT_INT16_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - ics.rf[i->dest_reg].i16 = src1.i16[ics.rf[i->src2_reg].i8 ^ 0x1]; - return IA_NEXT; -} -uint32_t IntCode_EXTRACT_INT32_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - ics.rf[i->dest_reg].i32 = src1.i32[ics.rf[i->src2_reg].i8]; - return IA_NEXT; -} -int Translate_EXTRACT(TranslationContext& ctx, Instr* i) { - // Can do more as needed. - static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_EXTRACT_INT8_V128, IntCode_EXTRACT_INT16_V128, - IntCode_EXTRACT_INT32_V128, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - IntCodeFn fn = fns[i->src1.value->type * MAX_TYPENAME + i->dest->type]; - return DispatchToC(ctx, i, fn); -} - -uint32_t IntCode_INSERT_INT8_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const size_t offset = ics.rf[i->src2_reg].i64; - const uint8_t part = ics.rf[i->src3_reg].i8; - vec128_t& dest = ics.rf[i->dest_reg].v128; - dest = src1; - dest.u8[offset ^ 0x3] = part; - return IA_NEXT; -} -uint32_t IntCode_INSERT_INT16_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const size_t offset = ics.rf[i->src2_reg].i64; - const uint16_t part = ics.rf[i->src3_reg].i16; - vec128_t& dest = ics.rf[i->dest_reg].v128; - dest = src1; - dest.u16[offset ^ 0x1] = part; - return IA_NEXT; -} -uint32_t IntCode_INSERT_INT32_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - const size_t offset = ics.rf[i->src2_reg].i64; - const uint32_t part = ics.rf[i->src3_reg].i32; - vec128_t& dest = ics.rf[i->dest_reg].v128; - dest = src1; - dest.u32[offset] = part; - return IA_NEXT; -} -int Translate_INSERT(TranslationContext& ctx, Instr* i) { - // Can do more as needed. - static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INSERT_INT8_V128, IntCode_INSERT_INT16_V128, - IntCode_INSERT_INT32_V128, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - IntCodeFn fn = fns[i->src1.value->type * MAX_TYPENAME + i->src3.value->type]; - return DispatchToC(ctx, i, fn); -} - -uint32_t IntCode_SPLAT_V128_INT8(IntCodeState& ics, const IntCode* i) { - int8_t src1 = ics.rf[i->src1_reg].i8; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (size_t j = 0; j < 16; j++) { - dest.u8[j] = src1; - } - return IA_NEXT; -} -uint32_t IntCode_SPLAT_V128_INT16(IntCodeState& ics, const IntCode* i) { - int16_t src1 = ics.rf[i->src1_reg].i16; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (size_t j = 0; j < 8; j++) { - dest.u16[j] = src1; - } - return IA_NEXT; -} -uint32_t IntCode_SPLAT_V128_INT32(IntCodeState& ics, const IntCode* i) { - int32_t src1 = ics.rf[i->src1_reg].i32; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (size_t j = 0; j < 4; j++) { - dest.u32[j] = src1; - } - return IA_NEXT; -} -uint32_t IntCode_SPLAT_V128_FLOAT32(IntCodeState& ics, const IntCode* i) { - float src1 = ics.rf[i->src1_reg].f32; - vec128_t& dest = ics.rf[i->dest_reg].v128; - for (size_t j = 0; j < 4; j++) { - dest.f32[j] = src1; - } - return IA_NEXT; -} -int Translate_SPLAT(TranslationContext& ctx, Instr* i) { - // Can do more as needed. - static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_SPLAT_V128_INT8, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_SPLAT_V128_INT16, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_SPLAT_V128_INT32, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_SPLAT_V128_FLOAT32, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - IntCodeFn fn = fns[i->src1.value->type * MAX_TYPENAME + i->dest->type]; - return DispatchToC(ctx, i, fn); -} - -uint32_t IntCode_PERMUTE_V128_BY_INT32(IntCodeState& ics, const IntCode* i) { - uint32_t table = ics.rf[i->src1_reg].i32; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - const vec128_t& src3 = ics.rf[i->src3_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - dest.i32[0] = - (table & 0x00000004) ? src3.i32[table & 0x3] : src2.i32[table & 0x3]; - dest.i32[1] = (table & 0x00000400) ? src3.i32[(table >> 8) & 0x3] - : src2.i32[(table >> 8) & 0x3]; - dest.i32[2] = (table & 0x00040000) ? src3.i32[(table >> 16) & 0x3] - : src2.i32[(table >> 16) & 0x3]; - dest.i32[3] = (table & 0x04000000) ? src3.i32[(table >> 24) & 0x3] - : src2.i32[(table >> 24) & 0x3]; - return IA_NEXT; -} -uint32_t IntCode_PERMUTE_V128_BY_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& table = ics.rf[i->src1_reg].v128; - const vec128_t& src2 = ics.rf[i->src2_reg].v128; - const vec128_t& src3 = ics.rf[i->src3_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - dest.low = dest.high = 0; - for (size_t n = 0; n < 16; n++) { - uint8_t index = (table.u8[n] & 0x1F) ^ 0x3; - dest.u8[n] = index < 16 ? src2.u8[index] : src3.u8[index - 16]; - } - return IA_NEXT; -} -int Translate_PERMUTE(TranslationContext& ctx, Instr* i) { - // Can do more as needed. - static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_PERMUTE_V128_BY_INT32, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_PERMUTE_V128_BY_V128, - }; - IntCodeFn fn = fns[i->src1.value->type * MAX_TYPENAME + i->dest->type]; - return DispatchToC(ctx, i, fn); -} - -uint32_t IntCode_SWIZZLE_V128(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - uint32_t swizzle_mask = ics.rf[i->src2_reg].u32; - vec128_t& dest = ics.rf[i->dest_reg].v128; - dest.i32[0] = src1.i32[(swizzle_mask >> 0) & 0x3]; - dest.i32[1] = src1.i32[(swizzle_mask >> 2) & 0x3]; - dest.i32[2] = src1.i32[(swizzle_mask >> 4) & 0x3]; - dest.i32[3] = src1.i32[(swizzle_mask >> 6) & 0x3]; - return IA_NEXT; -} -int Translate_SWIZZLE(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_SWIZZLE_V128, - }; - return DispatchToC(ctx, i, fns[i->src1.value->type]); -} - -uint32_t IntCode_PACK_D3DCOLOR(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - // RGBA (XYZW) -> ARGB (WXYZ) - dest.ux = dest.uy = dest.uz = 0; - dest.uw = ((src1.uw & 0xFF) << 24) | ((src1.ux & 0xFF) << 16) | - ((src1.uy & 0xFF) << 8) | (src1.uz & 0xFF); - return IA_NEXT; -} -uint32_t IntCode_PACK_FLOAT16_2(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - dest.ux = dest.uy = dest.uz = 0; - dest.uw = (uint32_t(poly::float_to_half(src1.x)) << 16) | - poly::float_to_half(src1.y); - return IA_NEXT; -} -uint32_t IntCode_PACK_FLOAT16_4(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - dest.ux = dest.uy = 0; - dest.uz = (uint32_t(poly::float_to_half(src1.x)) << 16) | - poly::float_to_half(src1.y); - dest.uw = (uint32_t(poly::float_to_half(src1.z)) << 16) | - poly::float_to_half(src1.w); - return IA_NEXT; -} -uint32_t IntCode_PACK_SHORT_2(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - int16_t dx = int16_t(poly::saturate(src1.x) * 32767.0f); - int16_t dy = int16_t(poly::saturate(src1.y) * 32767.0f); - dest.ux = dest.uy = dest.uz = 0; - dest.uw = (uint32_t(uint16_t(dx)) << 16) | uint32_t(uint16_t(dy)); - return IA_NEXT; -} -int Translate_PACK(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_PACK_D3DCOLOR, IntCode_PACK_FLOAT16_2, IntCode_PACK_FLOAT16_4, - IntCode_PACK_SHORT_2, IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->flags]); -} - -uint32_t IntCode_UNPACK_D3DCOLOR(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - // ARGB (WXYZ) -> RGBA (XYZW) - // XMLoadColor - int32_t src = (int32_t)src1.uw; - dest.u32[0] = 0x3F800000 | ((src >> 16) & 0xFF); - dest.u32[1] = 0x3F800000 | ((src >> 8) & 0xFF); - dest.u32[2] = 0x3F800000 | (src & 0xFF); - dest.u32[3] = 0x3F800000 | ((src >> 24) & 0xFF); - return IA_NEXT; -} -uint32_t IntCode_UNPACK_FLOAT16_2(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - dest.f32[0] = poly::half_to_float(uint16_t(src1.uw >> 16)); - dest.f32[1] = poly::half_to_float(uint16_t(src1.uw)); - dest.f32[2] = 0.0f; - dest.f32[3] = 1.0f; - return IA_NEXT; -} -uint32_t IntCode_UNPACK_FLOAT16_4(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - dest.f32[0] = poly::half_to_float(src1.u16[5]); - dest.f32[1] = poly::half_to_float(src1.u16[4]); - dest.f32[2] = poly::half_to_float(src1.u16[7]); - dest.f32[3] = poly::half_to_float(src1.u16[6]); - return IA_NEXT; -} -uint32_t IntCode_UNPACK_SHORT_2(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - // XMLoadShortN2 - uint16_t sx = src1.uw >> 16; - uint16_t sy = src1.uw & 0xFFFF; - dest.u32[0] = sx & 0x8000 ? (0x403F0000 | sx) : (0x40400000 | sx); - dest.u32[1] = sy & 0x8000 ? (0x403F0000 | sy) : (0x40400000 | sy); - dest.u32[2] = 0; - dest.u32[3] = 0x3F800000; - return IA_NEXT; -} -uint32_t IntCode_UNPACK_S8_IN_16_LO(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - dest.i16[0] = (int16_t)src1.i8[8 + 0]; - dest.i16[1] = (int16_t)src1.i8[8 + 1]; - dest.i16[2] = (int16_t)src1.i8[8 + 2]; - dest.i16[3] = (int16_t)src1.i8[8 + 3]; - dest.i16[4] = (int16_t)src1.i8[8 + 4]; - dest.i16[5] = (int16_t)src1.i8[8 + 5]; - dest.i16[6] = (int16_t)src1.i8[8 + 6]; - dest.i16[7] = (int16_t)src1.i8[8 + 7]; - return IA_NEXT; -} -uint32_t IntCode_UNPACK_S8_IN_16_HI(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - dest.i16[0] = (int16_t)src1.i8[0]; - dest.i16[1] = (int16_t)src1.i8[1]; - dest.i16[2] = (int16_t)src1.i8[2]; - dest.i16[3] = (int16_t)src1.i8[3]; - dest.i16[4] = (int16_t)src1.i8[4]; - dest.i16[5] = (int16_t)src1.i8[5]; - dest.i16[6] = (int16_t)src1.i8[6]; - dest.i16[7] = (int16_t)src1.i8[7]; - return IA_NEXT; -} -uint32_t IntCode_UNPACK_S16_IN_32_LO(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - dest.i32[0] = (int32_t)src1.i16[4 + 0]; - dest.i32[1] = (int32_t)src1.i16[4 + 1]; - dest.i32[2] = (int32_t)src1.i16[4 + 2]; - dest.i32[3] = (int32_t)src1.i16[4 + 3]; - return IA_NEXT; -} -uint32_t IntCode_UNPACK_S16_IN_32_HI(IntCodeState& ics, const IntCode* i) { - const vec128_t& src1 = ics.rf[i->src1_reg].v128; - vec128_t& dest = ics.rf[i->dest_reg].v128; - dest.i32[0] = (int32_t)src1.i16[0]; - dest.i32[1] = (int32_t)src1.i16[1]; - dest.i32[2] = (int32_t)src1.i16[2]; - dest.i32[3] = (int32_t)src1.i16[3]; - return IA_NEXT; -} -int Translate_UNPACK(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_UNPACK_D3DCOLOR, IntCode_UNPACK_FLOAT16_2, - IntCode_UNPACK_FLOAT16_4, IntCode_UNPACK_SHORT_2, - IntCode_UNPACK_S8_IN_16_LO, IntCode_UNPACK_S8_IN_16_HI, - IntCode_UNPACK_S16_IN_32_LO, IntCode_UNPACK_S16_IN_32_HI, - }; - return DispatchToC(ctx, i, fns[i->flags]); -} - -uint32_t IntCode_ATOMIC_EXCHANGE_I32(IntCodeState& ics, const IntCode* i) { - auto address = (uint32_t*)ics.rf[i->src1_reg].u64; - auto new_value = ics.rf[i->src2_reg].u32; - auto old_value = poly::atomic_exchange(new_value, address); - ics.rf[i->dest_reg].u32 = old_value; - return IA_NEXT; -} -uint32_t IntCode_ATOMIC_EXCHANGE_I64(IntCodeState& ics, const IntCode* i) { - auto address = (uint64_t*)ics.rf[i->src1_reg].u64; - auto new_value = ics.rf[i->src2_reg].u64; - auto old_value = poly::atomic_exchange(new_value, address); - ics.rf[i->dest_reg].u64 = old_value; - return IA_NEXT; -} -int Translate_ATOMIC_EXCHANGE(TranslationContext& ctx, Instr* i) { - static IntCodeFn fns[] = { - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_ATOMIC_EXCHANGE_I32, IntCode_ATOMIC_EXCHANGE_I64, - IntCode_INVALID_TYPE, IntCode_INVALID_TYPE, - IntCode_INVALID_TYPE, - }; - return DispatchToC(ctx, i, fns[i->src2.value->type]); -} - -typedef int (*TranslateFn)(TranslationContext& ctx, Instr* i); -static const TranslateFn dispatch_table[] = { - Translate_COMMENT, Translate_NOP, - Translate_SOURCE_OFFSET, Translate_TRACE_SOURCE, - Translate_DEBUG_BREAK, Translate_DEBUG_BREAK_TRUE, - Translate_TRAP, Translate_TRAP_TRUE, - Translate_CALL, Translate_CALL_TRUE, - Translate_CALL_INDIRECT, Translate_CALL_INDIRECT_TRUE, - Translate_CALL_EXTERN, Translate_RETURN, - Translate_RETURN_TRUE, Translate_SET_RETURN_ADDRESS, - Translate_BRANCH, Translate_BRANCH_TRUE, - Translate_BRANCH_FALSE, Translate_ASSIGN, - Translate_CAST, Translate_ZERO_EXTEND, - Translate_SIGN_EXTEND, Translate_TRUNCATE, - Translate_CONVERT, Translate_ROUND, - Translate_VECTOR_CONVERT_I2F, Translate_VECTOR_CONVERT_F2I, - Translate_LOAD_VECTOR_SHL, Translate_LOAD_VECTOR_SHR, - Translate_LOAD_CLOCK, Translate_LOAD_LOCAL, - Translate_STORE_LOCAL, Translate_LOAD_CONTEXT, - Translate_STORE_CONTEXT, Translate_LOAD, - Translate_STORE, Translate_PREFETCH, - Translate_MAX, Translate_VECTOR_MAX, - Translate_MIN, Translate_VECTOR_MIN, - Translate_SELECT, Translate_IS_TRUE, - Translate_IS_FALSE, Translate_COMPARE_EQ, - Translate_COMPARE_NE, Translate_COMPARE_SLT, - Translate_COMPARE_SLE, Translate_COMPARE_SGT, - Translate_COMPARE_SGE, Translate_COMPARE_ULT, - Translate_COMPARE_ULE, Translate_COMPARE_UGT, - Translate_COMPARE_UGE, Translate_DID_CARRY, - TranslateInvalid, // Translate_DID_OVERFLOW, - Translate_DID_SATURATE, Translate_VECTOR_COMPARE_EQ, - Translate_VECTOR_COMPARE_SGT, Translate_VECTOR_COMPARE_SGE, - Translate_VECTOR_COMPARE_UGT, Translate_VECTOR_COMPARE_UGE, - Translate_ADD, Translate_ADD_CARRY, - Translate_VECTOR_ADD, Translate_SUB, - Translate_VECTOR_SUB, Translate_MUL, - Translate_MUL_HI, Translate_DIV, - Translate_MUL_ADD, Translate_MUL_SUB, - Translate_NEG, Translate_ABS, - Translate_SQRT, Translate_RSQRT, - Translate_POW2, Translate_LOG2, - Translate_DOT_PRODUCT_3, Translate_DOT_PRODUCT_4, - Translate_AND, Translate_OR, - Translate_XOR, Translate_NOT, - Translate_SHL, Translate_VECTOR_SHL, - Translate_SHR, Translate_VECTOR_SHR, - Translate_SHA, Translate_VECTOR_SHA, - Translate_ROTATE_LEFT, Translate_VECTOR_ROTATE_LEFT, - Translate_BYTE_SWAP, Translate_CNTLZ, - Translate_INSERT, Translate_EXTRACT, - Translate_SPLAT, Translate_PERMUTE, - Translate_SWIZZLE, Translate_PACK, - Translate_UNPACK, - TranslateInvalid, // Translate_COMPARE_EXCHANGE, - Translate_ATOMIC_EXCHANGE, - TranslateInvalid, // Translate_ATOMIC_ADD, - TranslateInvalid, // Translate_ATOMIC_SUB, -}; - -int TranslateIntCodes(TranslationContext& ctx, Instr* i) { - TranslateFn fn = dispatch_table[i->opcode->num]; - return fn(ctx, i); -} - -} // namespace ivm -} // namespace backend -} // namespace alloy diff --git a/src/alloy/backend/ivm/ivm_intcode.h b/src/alloy/backend/ivm/ivm_intcode.h deleted file mode 100644 index 6a0a6f8f5..000000000 --- a/src/alloy/backend/ivm/ivm_intcode.h +++ /dev/null @@ -1,107 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_BACKEND_IVM_INTCODE_H_ -#define ALLOY_BACKEND_IVM_INTCODE_H_ - -#include -#include - -namespace alloy { -namespace runtime { -class ThreadState; -} // namespace runtime -} // namespace alloy - -namespace alloy { -namespace backend { -namespace ivm { - -typedef union { - int8_t i8; - uint8_t u8; - int16_t i16; - uint16_t u16; - int32_t i32; - uint32_t u32; - int64_t i64; - uint64_t u64; - float f32; - double f64; - vec128_t v128; -} Register; - -typedef struct { - Register* rf; - uint8_t* locals; - uint8_t* context; - uint8_t* membase; - int8_t did_carry; - int8_t did_saturate; - runtime::ThreadState* thread_state; - uint64_t return_address; - uint64_t call_return_address; -} IntCodeState; - -struct IntCode_s; -typedef uint32_t (*IntCodeFn)(IntCodeState& ics, const struct IntCode_s* i); - -#define IA_RETURN 0xA0000000 -#define IA_NEXT 0xB0000000 - -typedef struct IntCode_s { - IntCodeFn intcode_fn; - uint16_t flags; - uint16_t debug_flags; - - uint32_t dest_reg; - union { - struct { - uint32_t src1_reg; - uint32_t src2_reg; - uint32_t src3_reg; - // <4 bytes available> - }; - struct { - Register constant; - }; - }; - - // debugging info/etc -} IntCode; - -typedef struct LabelRef_s { - hir::Label* label; - IntCode* instr; - LabelRef_s* next; -} LabelRef; - -typedef struct SourceMapEntry_s { - uint64_t source_offset; - uint64_t intcode_index; -} SourceMapEntry; - -typedef struct { - uint32_t register_count; - size_t intcode_count; - Arena* intcode_arena; - size_t source_map_count; - Arena* source_map_arena; - Arena* scratch_arena; - LabelRef* label_ref_head; - size_t stack_size; -} TranslationContext; - -int TranslateIntCodes(TranslationContext& ctx, hir::Instr* i); - -} // namespace ivm -} // namespace backend -} // namespace alloy - -#endif // ALLOY_BACKEND_IVM_INTCODE_H_ diff --git a/src/alloy/backend/ivm/ivm_stack.cc b/src/alloy/backend/ivm/ivm_stack.cc deleted file mode 100644 index 1e80e4073..000000000 --- a/src/alloy/backend/ivm/ivm_stack.cc +++ /dev/null @@ -1,79 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -namespace alloy { -namespace backend { -namespace ivm { - -IVMStack::IVMStack() - : chunk_size_(2 * 1024 * 1024), head_chunk_(NULL), active_chunk_(NULL) {} - -IVMStack::~IVMStack() { - Chunk* chunk = head_chunk_; - while (chunk) { - Chunk* next = chunk->next; - delete chunk; - chunk = next; - } - head_chunk_ = NULL; -} - -Register* IVMStack::Alloc(size_t register_count) { - size_t size = register_count * sizeof(Register); - if (active_chunk_) { - if (active_chunk_->capacity - active_chunk_->offset < size) { - Chunk* next = active_chunk_->next; - if (!next) { - assert_true(size < chunk_size_, "need to support larger chunks"); - next = new Chunk(chunk_size_); - next->prev = active_chunk_; - active_chunk_->next = next; - } - next->offset = 0; - active_chunk_ = next; - } - } else { - head_chunk_ = active_chunk_ = new Chunk(chunk_size_); - } - - uint8_t* p = active_chunk_->buffer + active_chunk_->offset; - active_chunk_->offset += size; - return (Register*)p; -} - -void IVMStack::Free(size_t register_count) { - size_t size = register_count * sizeof(Register); - if (active_chunk_->offset == size) { - // Moving back a chunk. - active_chunk_->offset = 0; - if (active_chunk_->prev) { - active_chunk_ = active_chunk_->prev; - } - } else { - // Still in same chunk. - active_chunk_->offset -= size; - } -} - -IVMStack::Chunk::Chunk(size_t chunk_size) - : prev(NULL), next(NULL), capacity(chunk_size), buffer(0), offset(0) { - buffer = reinterpret_cast(malloc(capacity)); -} - -IVMStack::Chunk::~Chunk() { - if (buffer) { - free(buffer); - } -} - -} // namespace ivm -} // namespace backend -} // namespace alloy diff --git a/src/alloy/backend/ivm/ivm_stack.h b/src/alloy/backend/ivm/ivm_stack.h deleted file mode 100644 index f02a169f4..000000000 --- a/src/alloy/backend/ivm/ivm_stack.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_BACKEND_IVM_IVM_STACK_H_ -#define ALLOY_BACKEND_IVM_IVM_STACK_H_ - -#include - -namespace alloy { -namespace backend { -namespace ivm { - -class IVMStack { - public: - IVMStack(); - ~IVMStack(); - - Register* Alloc(size_t register_count); - void Free(size_t register_count); - - private: - class Chunk { - public: - Chunk(size_t chunk_size); - ~Chunk(); - - Chunk* prev; - Chunk* next; - - size_t capacity; - uint8_t* buffer; - size_t offset; - }; - - private: - size_t chunk_size_; - Chunk* head_chunk_; - Chunk* active_chunk_; -}; - -} // namespace ivm -} // namespace backend -} // namespace alloy - -#endif // ALLOY_BACKEND_IVM_IVM_STACK_H_ diff --git a/src/alloy/backend/ivm/sources.gypi b/src/alloy/backend/ivm/sources.gypi deleted file mode 100644 index 20306f9fb..000000000 --- a/src/alloy/backend/ivm/sources.gypi +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2013 Ben Vanik. All Rights Reserved. -{ - 'sources': [ - 'ivm_intcode.cc', - 'ivm_intcode.h', - 'ivm_assembler.cc', - 'ivm_assembler.h', - 'ivm_backend.cc', - 'ivm_backend.h', - 'ivm_function.cc', - 'ivm_function.h', - 'ivm_stack.cc', - 'ivm_stack.h', - ], -} diff --git a/src/alloy/backend/sources.gypi b/src/alloy/backend/sources.gypi index ec3be77a4..3cf3b826b 100644 --- a/src/alloy/backend/sources.gypi +++ b/src/alloy/backend/sources.gypi @@ -9,7 +9,6 @@ ], 'includes': [ - 'ivm/sources.gypi', 'x64/sources.gypi', ], } diff --git a/src/alloy/frontend/ppc/test/alloy-ppc-test.cc b/src/alloy/frontend/ppc/test/alloy-ppc-test.cc index 4970325e8..9190eaccd 100644 --- a/src/alloy/frontend/ppc/test/alloy-ppc-test.cc +++ b/src/alloy/frontend/ppc/test/alloy-ppc-test.cc @@ -8,7 +8,6 @@ */ #include -#include #include #include #include diff --git a/src/alloy/memory.cc b/src/alloy/memory.cc index c699173e0..36d1ac05f 100644 --- a/src/alloy/memory.cc +++ b/src/alloy/memory.cc @@ -73,36 +73,4 @@ SimpleMemory::SimpleMemory(size_t capacity) : memory_(capacity) { SimpleMemory::~SimpleMemory() = default; -uint8_t SimpleMemory::LoadI8(uint64_t address) { - return poly::load(membase_ + address); -} - -uint16_t SimpleMemory::LoadI16(uint64_t address) { - return poly::load(membase_ + address); -} - -uint32_t SimpleMemory::LoadI32(uint64_t address) { - return poly::load(membase_ + address); -} - -uint64_t SimpleMemory::LoadI64(uint64_t address) { - return poly::load(membase_ + address); -} - -void SimpleMemory::StoreI8(uint64_t address, uint8_t value) { - poly::store(membase_ + address, value); -} - -void SimpleMemory::StoreI16(uint64_t address, uint16_t value) { - poly::store(membase_ + address, value); -} - -void SimpleMemory::StoreI32(uint64_t address, uint32_t value) { - poly::store(membase_ + address, value); -} - -void SimpleMemory::StoreI64(uint64_t address, uint64_t value) { - poly::store(membase_ + address, value); -} - } // namespace alloy diff --git a/src/alloy/memory.h b/src/alloy/memory.h index 3d858eab9..de094f6e3 100644 --- a/src/alloy/memory.h +++ b/src/alloy/memory.h @@ -40,16 +40,6 @@ class Memory { uint64_t SearchAligned(uint64_t start, uint64_t end, const uint32_t* values, size_t value_count); - // TODO(benvanik): remove with IVM. - virtual uint8_t LoadI8(uint64_t address) = 0; - virtual uint16_t LoadI16(uint64_t address) = 0; - virtual uint32_t LoadI32(uint64_t address) = 0; - virtual uint64_t LoadI64(uint64_t address) = 0; - virtual void StoreI8(uint64_t address, uint8_t value) = 0; - virtual void StoreI16(uint64_t address, uint16_t value) = 0; - virtual void StoreI32(uint64_t address, uint32_t value) = 0; - virtual void StoreI64(uint64_t address, uint64_t value) = 0; - protected: size_t system_page_size_; uint8_t* membase_; @@ -63,16 +53,6 @@ class SimpleMemory : public Memory { SimpleMemory(size_t capacity); ~SimpleMemory() override; - // TODO(benvanik): remove with IVM. - uint8_t LoadI8(uint64_t address) override; - uint16_t LoadI16(uint64_t address) override; - uint32_t LoadI32(uint64_t address) override; - uint64_t LoadI64(uint64_t address) override; - void StoreI8(uint64_t address, uint8_t value) override; - void StoreI16(uint64_t address, uint16_t value) override; - void StoreI32(uint64_t address, uint32_t value) override; - void StoreI64(uint64_t address, uint64_t value) override; - private: std::vector memory_; }; diff --git a/src/alloy/runtime/instrument.cc b/src/alloy/runtime/instrument.cc index 3466d7cd5..8cb099fe6 100644 --- a/src/alloy/runtime/instrument.cc +++ b/src/alloy/runtime/instrument.cc @@ -53,7 +53,6 @@ bool FunctionInstrument::Attach() { // Function impl attach: // - add instrument to list - // IVM: handle in Call() // JIT: transition to instrumented state // - rewrite enter/exit to jump to instrumentation thunk // - some sort of locking required? diff --git a/src/alloy/runtime/runtime.cc b/src/alloy/runtime/runtime.cc index 5b8765bbe..5da4970da 100644 --- a/src/alloy/runtime/runtime.cc +++ b/src/alloy/runtime/runtime.cc @@ -17,10 +17,9 @@ #include // TODO(benvanik): based on compiler support -#include #include -DEFINE_string(runtime_backend, "any", "Runtime backend [any, ivm, x64]."); +DEFINE_string(runtime_backend, "any", "Runtime backend [any, x64]."); namespace alloy { namespace runtime { @@ -81,22 +80,12 @@ int Runtime::Initialize(std::unique_ptr frontend, backend.reset(new alloy::backend::x64::X64Backend(this)); } #endif // ALLOY_HAS_X64_BACKEND -#if defined(ALLOY_HAS_IVM_BACKEND) && ALLOY_HAS_IVM_BACKEND - if (FLAGS_runtime_backend == "ivm") { - backend.reset(new alloy::backend::ivm::IVMBackend(this)); - } -#endif // ALLOY_HAS_IVM_BACKEND if (FLAGS_runtime_backend == "any") { #if defined(ALLOY_HAS_X64_BACKEND) && ALLOY_HAS_X64_BACKEND if (!backend) { backend.reset(new alloy::backend::x64::X64Backend(this)); } #endif // ALLOY_HAS_X64_BACKEND -#if defined(ALLOY_HAS_IVM_BACKEND) && ALLOY_HAS_IVM_BACKEND - if (!backend) { - backend.reset(new alloy::backend::ivm::IVMBackend(this)); - } -#endif // ALLOY_HAS_IVM_BACKEND } } diff --git a/src/alloy/test/alloy-sandbox.cc b/src/alloy/test/alloy-sandbox.cc index 69ffa4d0a..8d519cf1b 100644 --- a/src/alloy/test/alloy-sandbox.cc +++ b/src/alloy/test/alloy-sandbox.cc @@ -8,7 +8,6 @@ */ #include -#include #include #include #include diff --git a/src/alloy/test/util.h b/src/alloy/test/util.h index 22734c0b2..a38692f0f 100644 --- a/src/alloy/test/util.h +++ b/src/alloy/test/util.h @@ -11,7 +11,6 @@ #define ALLOY_TEST_UTIL_H_ #include -#include #include #include #include @@ -22,7 +21,6 @@ #include -#define ALLOY_TEST_IVM 1 #define ALLOY_TEST_X64 1 namespace alloy { @@ -86,17 +84,6 @@ class TestFunction { memory_size = 16 * 1024 * 1024; memory.reset(new SimpleMemory(memory_size)); -#if ALLOY_TEST_IVM - { - auto runtime = std::make_unique(memory.get()); - auto frontend = - std::make_unique(runtime.get()); - auto backend = - std::make_unique(runtime.get()); - runtime->Initialize(std::move(frontend), std::move(backend)); - runtimes.emplace_back(std::move(runtime)); - } -#endif // ALLOY_TEST_IVM #if ALLOY_TEST_X64 { auto runtime = std::make_unique(memory.get()); diff --git a/src/xenia/cpu/processor.cc b/src/xenia/cpu/processor.cc index 4c5f1b9ca..a0a3c60f5 100644 --- a/src/xenia/cpu/processor.cc +++ b/src/xenia/cpu/processor.cc @@ -90,7 +90,6 @@ int Processor::Setup() { } std::unique_ptr backend; - // backend.reset(new alloy::backend::ivm::IVMBackend(runtime)); // backend.reset(new alloy::backend::x64::X64Backend(runtime)); int result = runtime_->Initialize(std::move(backend)); if (result) { diff --git a/src/xenia/memory.cc b/src/xenia/memory.cc index ccbb8e85e..f1da724af 100644 --- a/src/xenia/memory.cc +++ b/src/xenia/memory.cc @@ -203,8 +203,8 @@ int Memory::Initialize() { // I have no idea what this is, but games try to read/write there. VirtualAlloc(Translate(0x40000000), 0x00010000, MEM_COMMIT, PAGE_READWRITE); - StoreI32(0x40000000, 0x00C40000); - StoreI32(0x40000004, 0x00010000); + poly::store_and_swap(Translate(0x40000000), 0x00C40000); + poly::store_and_swap(Translate(0x40000004), 0x00010000); return 0; } @@ -286,62 +286,6 @@ void Memory::CancelWriteWatch(uintptr_t watch_handle) { mmio_handler_->CancelWriteWatch(watch_handle); } -uint8_t Memory::LoadI8(uint64_t address) { - uint64_t value; - if (!mmio_handler_->CheckLoad(address, &value)) { - value = *reinterpret_cast(Translate(address)); - } - return static_cast(value); -} - -uint16_t Memory::LoadI16(uint64_t address) { - uint64_t value; - if (!mmio_handler_->CheckLoad(address, &value)) { - value = *reinterpret_cast(Translate(address)); - } - return static_cast(value); -} - -uint32_t Memory::LoadI32(uint64_t address) { - uint64_t value; - if (!mmio_handler_->CheckLoad(address, &value)) { - value = *reinterpret_cast(Translate(address)); - } - return static_cast(value); -} - -uint64_t Memory::LoadI64(uint64_t address) { - uint64_t value; - if (!mmio_handler_->CheckLoad(address, &value)) { - value = *reinterpret_cast(Translate(address)); - } - return static_cast(value); -} - -void Memory::StoreI8(uint64_t address, uint8_t value) { - if (!mmio_handler_->CheckStore(address, value)) { - *reinterpret_cast(Translate(address)) = value; - } -} - -void Memory::StoreI16(uint64_t address, uint16_t value) { - if (!mmio_handler_->CheckStore(address, value)) { - *reinterpret_cast(Translate(address)) = value; - } -} - -void Memory::StoreI32(uint64_t address, uint32_t value) { - if (!mmio_handler_->CheckStore(address, value)) { - *reinterpret_cast(Translate(address)) = value; - } -} - -void Memory::StoreI64(uint64_t address, uint64_t value) { - if (!mmio_handler_->CheckStore(address, value)) { - *reinterpret_cast(Translate(address)) = value; - } -} - uint64_t Memory::HeapAlloc(uint64_t base_address, size_t size, uint32_t flags, uint32_t alignment) { // If we were given a base address we are outside of the normal heap and diff --git a/src/xenia/memory.h b/src/xenia/memory.h index 2258ee151..8bc741d77 100644 --- a/src/xenia/memory.h +++ b/src/xenia/memory.h @@ -58,15 +58,6 @@ class Memory : public alloy::Memory { void* callback_context, void* callback_data); void CancelWriteWatch(uintptr_t watch_handle); - uint8_t LoadI8(uint64_t address) override; - uint16_t LoadI16(uint64_t address) override; - uint32_t LoadI32(uint64_t address) override; - uint64_t LoadI64(uint64_t address) override; - void StoreI8(uint64_t address, uint8_t value) override; - void StoreI16(uint64_t address, uint16_t value) override; - void StoreI32(uint64_t address, uint32_t value) override; - void StoreI64(uint64_t address, uint64_t value) override; - uint64_t HeapAlloc(uint64_t base_address, size_t size, uint32_t flags, uint32_t alignment = 0x20); int HeapFree(uint64_t address, size_t size); From f632895fbb3c598325e02486dd4785195f16b45a Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 24 Jan 2015 10:21:54 -0800 Subject: [PATCH 373/388] srdi special case and tests for sldi/srdi. --- src/alloy/frontend/ppc/ppc_emit_alu.cc | 19 +++++---- .../frontend/ppc/test/bin/instr_rldicl.bin | Bin 80 -> 128 bytes .../frontend/ppc/test/bin/instr_rldicl.dis | 20 ++++++++++ .../frontend/ppc/test/bin/instr_rldicl.map | 4 ++ .../frontend/ppc/test/bin/instr_rldicr.bin | Bin 72 -> 120 bytes .../frontend/ppc/test/bin/instr_rldicr.dis | 20 ++++++++++ .../frontend/ppc/test/bin/instr_rldicr.map | 4 ++ src/alloy/frontend/ppc/test/instr_rldicl.s | 36 ++++++++++++++++++ src/alloy/frontend/ppc/test/instr_rldicr.s | 36 ++++++++++++++++++ 9 files changed, 132 insertions(+), 7 deletions(-) diff --git a/src/alloy/frontend/ppc/ppc_emit_alu.cc b/src/alloy/frontend/ppc/ppc_emit_alu.cc index bf1b5ed44..fb37b2e69 100644 --- a/src/alloy/frontend/ppc/ppc_emit_alu.cc +++ b/src/alloy/frontend/ppc/ppc_emit_alu.cc @@ -837,11 +837,16 @@ XEEMITTER(rld, 0x78000000, MDS)(PPCHIRBuilder& f, InstrData& i) { uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB; uint64_t m = XEMASK(mb, 63); Value* v = f.LoadGPR(i.MD.RT); - if (sh) { - v = f.RotateLeft(v, f.LoadConstant((int8_t)sh)); - } - if (m != 0xFFFFFFFFFFFFFFFF) { - v = f.And(v, f.LoadConstant(m)); + if (sh == 64 - mb) { + // srdi == rldicl ra,rs,64-n,n + v = f.Shr(v, int8_t(mb)); + } else { + if (sh) { + v = f.RotateLeft(v, f.LoadConstant((int8_t)sh)); + } + if (m != 0xFFFFFFFFFFFFFFFF) { + v = f.And(v, f.LoadConstant(m)); + } } f.StoreGPR(i.MD.RA, v); if (i.MD.Rc) { @@ -860,8 +865,8 @@ XEEMITTER(rld, 0x78000000, MDS)(PPCHIRBuilder& f, InstrData& i) { uint64_t m = XEMASK(0, mb); Value* v = f.LoadGPR(i.MD.RT); if (mb == 63 - sh) { - // Shift left. - v = f.Shl(v, f.LoadConstant((int8_t)sh)); + // sldi == rldicr ra,rs,n,63-n + v = f.Shl(v, int8_t(sh)); } else { if (sh) { v = f.RotateLeft(v, f.LoadConstant((int8_t)sh)); diff --git a/src/alloy/frontend/ppc/test/bin/instr_rldicl.bin b/src/alloy/frontend/ppc/test/bin/instr_rldicl.bin index 121cb7ff60d0d56282a50d9e807cfab1de803a46..1b8e7abd071e3f65482c5c4cd5e5616d8aa1ce87 100644 GIT binary patch delta 54 xcmWG&V4M(OP?5~QP|?D`;Mc&QP?7w@siNhF6NJs61Qb_-u=yWUwD3Owu>sjl5sUx; delta 5 McmZo*444oA00ij)vH$=8 diff --git a/src/alloy/frontend/ppc/test/bin/instr_rldicl.dis b/src/alloy/frontend/ppc/test/bin/instr_rldicl.dis index 226852357..9933b7437 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_rldicl.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_rldicl.dis @@ -43,3 +43,23 @@ Disassembly of section .text: 0000000000100048 : 100048: 78 83 d1 82 rldicl r3,r4,58,6 10004c: 4e 80 00 20 blr + +0000000000100050 : + 100050: 78 63 00 00 rotldi r3,r3,0 + 100054: 78 84 00 00 rotldi r4,r4,0 + 100058: 4e 80 00 20 blr + +000000000010005c : + 10005c: 78 63 f8 42 rldicl r3,r3,63,1 + 100060: 78 84 f8 42 rldicl r4,r4,63,1 + 100064: 4e 80 00 20 blr + +0000000000100068 : + 100068: 78 63 00 22 rldicl r3,r3,32,32 + 10006c: 78 84 00 22 rldicl r4,r4,32,32 + 100070: 4e 80 00 20 blr + +0000000000100074 : + 100074: 78 63 0f e0 rldicl r3,r3,1,63 + 100078: 78 84 0f e0 rldicl r4,r4,1,63 + 10007c: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_rldicl.map b/src/alloy/frontend/ppc/test/bin/instr_rldicl.map index c581b1fcc..2c701aa7b 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_rldicl.map +++ b/src/alloy/frontend/ppc/test/bin/instr_rldicl.map @@ -8,3 +8,7 @@ 0000000000000038 t test_rldicl_8 0000000000000040 t test_rldicl_9 0000000000000048 t test_rldicl_10 +0000000000000050 t test_srdi_1 +000000000000005c t test_srdi_2 +0000000000000068 t test_srdi_3 +0000000000000074 t test_srdi_4 diff --git a/src/alloy/frontend/ppc/test/bin/instr_rldicr.bin b/src/alloy/frontend/ppc/test/bin/instr_rldicr.bin index cf03dfbfc1b43a3060db98adbbb78be633679855..0a6e90dc068716b372acfa04963f8544c82184f2 100644 GIT binary patch delta 53 xcmeaMnBZYhk<9+2qJ{m5Uju_eMKb@AiWdGQ5H|ZUp!hKe`v+S^%MUgX8vq;+6R!XO delta 4 Lcmb>MnBV~b1SA2O diff --git a/src/alloy/frontend/ppc/test/bin/instr_rldicr.dis b/src/alloy/frontend/ppc/test/bin/instr_rldicr.dis index 5e5546a69..1be1d4db4 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_rldicr.dis +++ b/src/alloy/frontend/ppc/test/bin/instr_rldicr.dis @@ -39,3 +39,23 @@ Disassembly of section .text: 0000000000100040 : 100040: 78 83 f8 04 rldicr r3,r4,31,0 100044: 4e 80 00 20 blr + +0000000000100048 : + 100048: 78 63 07 e4 rldicr r3,r3,0,63 + 10004c: 78 84 07 e4 rldicr r4,r4,0,63 + 100050: 4e 80 00 20 blr + +0000000000100054 : + 100054: 78 63 0f a4 rldicr r3,r3,1,62 + 100058: 78 84 0f a4 rldicr r4,r4,1,62 + 10005c: 4e 80 00 20 blr + +0000000000100060 : + 100060: 78 63 07 c6 rldicr r3,r3,32,31 + 100064: 78 84 07 c6 rldicr r4,r4,32,31 + 100068: 4e 80 00 20 blr + +000000000010006c : + 10006c: 78 63 f8 06 rldicr r3,r3,63,0 + 100070: 78 84 f8 06 rldicr r4,r4,63,0 + 100074: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_rldicr.map b/src/alloy/frontend/ppc/test/bin/instr_rldicr.map index 93ee471fc..b576758fe 100644 --- a/src/alloy/frontend/ppc/test/bin/instr_rldicr.map +++ b/src/alloy/frontend/ppc/test/bin/instr_rldicr.map @@ -7,3 +7,7 @@ 0000000000000030 t test_rldicr_7 0000000000000038 t test_rldicr_8 0000000000000040 t test_rldicr_9 +0000000000000048 t test_sldi_1 +0000000000000054 t test_sldi_2 +0000000000000060 t test_sldi_3 +000000000000006c t test_sldi_4 diff --git a/src/alloy/frontend/ppc/test/instr_rldicl.s b/src/alloy/frontend/ppc/test/instr_rldicl.s index 2f55ff595..f301d7c98 100644 --- a/src/alloy/frontend/ppc/test/instr_rldicl.s +++ b/src/alloy/frontend/ppc/test/instr_rldicl.s @@ -67,3 +67,39 @@ test_rldicl_10: blr #_ REGISTER_OUT r3 0x58C000 #_ REGISTER_OUT r4 0x16300000 + +test_srdi_1: + #_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r4 0x0123456789ABCDEF + srdi r3, r3, 0 + srdi r4, r4, 0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_srdi_2: + #_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r4 0x0123456789ABCDEF + srdi r3, r3, 1 + srdi r4, r4, 1 + blr + #_ REGISTER_OUT r3 0x7fffffffffffffff + #_ REGISTER_OUT r4 0x0091a2b3c4d5e6f7 + +test_srdi_3: + #_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r4 0x0123456789ABCDEF + srdi r3, r3, 32 + srdi r4, r4, 32 + blr + #_ REGISTER_OUT r3 0x00000000ffffffff + #_ REGISTER_OUT r4 0x0000000001234567 + +test_srdi_4: + #_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r4 0x0123456789ABCDEF + srdi r3, r3, 63 + srdi r4, r4, 63 + blr + #_ REGISTER_OUT r3 0x0000000000000001 + #_ REGISTER_OUT r4 0x0000000000000000 diff --git a/src/alloy/frontend/ppc/test/instr_rldicr.s b/src/alloy/frontend/ppc/test/instr_rldicr.s index 7380eca31..6a249b23a 100644 --- a/src/alloy/frontend/ppc/test/instr_rldicr.s +++ b/src/alloy/frontend/ppc/test/instr_rldicr.s @@ -60,3 +60,39 @@ test_rldicr_9: blr #_ REGISTER_OUT r3 0x8000000000000000 #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_sldi_1: + #_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r4 0x0123456789ABCDEF + sldi r3, r3, 0 + sldi r4, r4, 0 + blr + #_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_OUT r4 0x0123456789ABCDEF + +test_sldi_2: + #_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r4 0x0123456789ABCDEF + sldi r3, r3, 1 + sldi r4, r4, 1 + blr + #_ REGISTER_OUT r3 0xfffffffffffffffe + #_ REGISTER_OUT r4 0x02468acf13579bde + +test_sldi_3: + #_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r4 0x0123456789ABCDEF + sldi r3, r3, 32 + sldi r4, r4, 32 + blr + #_ REGISTER_OUT r3 0xffffffff00000000 + #_ REGISTER_OUT r4 0x89abcdef00000000 + +test_sldi_4: + #_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF + #_ REGISTER_IN r4 0x0123456789ABCDEF + sldi r3, r3, 63 + sldi r4, r4, 63 + blr + #_ REGISTER_OUT r3 0x8000000000000000 + #_ REGISTER_OUT r4 0x8000000000000000 From 3f480d24bda4cec54352473fe30f09f2b27deaed Mon Sep 17 00:00:00 2001 From: sephiroth99 Date: Sat, 31 Jan 2015 01:24:45 -0500 Subject: [PATCH 374/388] libpoly: add missing include for thread_local define in logging.cc Add a missing include in logging.cc that fixes the missing definition for thread_local. Similar to issue #122. --- src/poly/logging.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/poly/logging.cc b/src/poly/logging.cc index b10760334..903537376 100644 --- a/src/poly/logging.cc +++ b/src/poly/logging.cc @@ -12,6 +12,7 @@ #include #include +#include #include #include From f4f401e927f89d26353269df740f4a2295ee14d4 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 31 Jan 2015 10:15:27 -0800 Subject: [PATCH 375/388] Removing d3dcompiler dependency. --- xenia.gyp | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/xenia.gyp b/xenia.gyp index d3f10caad..7c241be81 100644 --- a/xenia.gyp +++ b/xenia.gyp @@ -407,9 +407,6 @@ 'ole32', 'wsock32', 'Ws2_32', - 'dxgi', - 'd3d11', - 'd3dcompiler', 'xinput', 'xaudio2', 'Shell32', @@ -437,19 +434,6 @@ }], ], }, - 'conditions': [ - ['OS == "win"', { - 'copies': [ - { - 'files': [ - # Depending on which SDK you have... - '<(windows_sdk_dir)/redist/d3d/x64/d3dcompiler_47.dll', - ], - 'destination': '<(PRODUCT_DIR)', - }, - ], - }], - ], 'cflags': [ ], From 00e4a4fe1b63e3cf9e46b84b2560629976080429 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 31 Jan 2015 22:49:47 -0800 Subject: [PATCH 376/388] Fix #include format. --- src/alloy/alloy.cc | 4 +-- src/alloy/alloy.h | 8 +++--- src/alloy/arena.cc | 4 +-- src/alloy/backend/assembler.cc | 2 +- src/alloy/backend/backend.cc | 2 +- src/alloy/backend/backend.h | 2 +- src/alloy/backend/x64/x64_assembler.cc | 18 ++++++------- src/alloy/backend/x64/x64_assembler.h | 4 +-- src/alloy/backend/x64/x64_backend.cc | 10 +++---- src/alloy/backend/x64/x64_backend.h | 2 +- src/alloy/backend/x64/x64_code_cache_win.cc | 6 ++--- src/alloy/backend/x64/x64_emitter.cc | 26 +++++++++---------- src/alloy/backend/x64/x64_emitter.h | 4 +-- src/alloy/backend/x64/x64_function.cc | 8 +++--- src/alloy/backend/x64/x64_function.h | 4 +-- src/alloy/backend/x64/x64_sequences.cc | 12 ++++----- src/alloy/backend/x64/x64_thunk_emitter.cc | 4 +-- src/alloy/backend/x64/x64_thunk_emitter.h | 4 +-- src/alloy/backend/x64/x64_tracers.cc | 8 +++--- src/alloy/compiler/compiler.cc | 6 ++--- src/alloy/compiler/compiler.h | 2 +- src/alloy/compiler/compiler_pass.cc | 4 +-- src/alloy/compiler/compiler_pass.h | 2 +- src/alloy/compiler/compiler_passes.h | 24 ++++++++--------- .../passes/constant_propagation_pass.cc | 8 +++--- .../passes/constant_propagation_pass.h | 2 +- .../compiler/passes/context_promotion_pass.cc | 8 +++--- .../compiler/passes/context_promotion_pass.h | 2 +- .../passes/control_flow_analysis_pass.cc | 10 +++---- .../passes/control_flow_analysis_pass.h | 2 +- .../control_flow_simplification_pass.cc | 10 +++---- .../passes/control_flow_simplification_pass.h | 2 +- .../passes/data_flow_analysis_pass.cc | 10 +++---- .../compiler/passes/data_flow_analysis_pass.h | 2 +- .../passes/dead_code_elimination_pass.cc | 4 +-- .../passes/dead_code_elimination_pass.h | 2 +- .../compiler/passes/finalization_pass.cc | 10 +++---- src/alloy/compiler/passes/finalization_pass.h | 2 +- .../passes/register_allocation_pass.cc | 4 +-- .../passes/register_allocation_pass.h | 4 +-- .../compiler/passes/simplification_pass.cc | 4 +-- .../compiler/passes/simplification_pass.h | 2 +- src/alloy/compiler/passes/validation_pass.cc | 10 +++---- src/alloy/compiler/passes/validation_pass.h | 2 +- .../compiler/passes/value_reduction_pass.cc | 10 +++---- .../compiler/passes/value_reduction_pass.h | 2 +- src/alloy/frontend/context_info.cc | 2 +- src/alloy/frontend/frontend.cc | 4 +-- src/alloy/frontend/frontend.h | 8 +++--- src/alloy/frontend/ppc/ppc_context.cc | 2 +- src/alloy/frontend/ppc/ppc_context.h | 4 +-- src/alloy/frontend/ppc/ppc_disasm.cc | 6 ++--- src/alloy/frontend/ppc/ppc_disasm.h | 2 +- src/alloy/frontend/ppc/ppc_emit-private.h | 4 +-- src/alloy/frontend/ppc/ppc_emit.h | 2 +- src/alloy/frontend/ppc/ppc_emit_altivec.cc | 6 ++--- src/alloy/frontend/ppc/ppc_emit_alu.cc | 6 ++--- src/alloy/frontend/ppc/ppc_emit_control.cc | 6 ++--- src/alloy/frontend/ppc/ppc_emit_fpu.cc | 6 ++--- src/alloy/frontend/ppc/ppc_emit_memory.cc | 6 ++--- src/alloy/frontend/ppc/ppc_frontend.cc | 12 ++++----- src/alloy/frontend/ppc/ppc_frontend.h | 4 +-- src/alloy/frontend/ppc/ppc_hir_builder.cc | 18 ++++++------- src/alloy/frontend/ppc/ppc_hir_builder.h | 8 +++--- src/alloy/frontend/ppc/ppc_instr.cc | 8 +++--- src/alloy/frontend/ppc/ppc_instr_tables.h | 4 +-- src/alloy/frontend/ppc/ppc_scanner.cc | 14 +++++----- src/alloy/frontend/ppc/ppc_scanner.h | 2 +- src/alloy/frontend/ppc/ppc_translator.cc | 22 ++++++++-------- src/alloy/frontend/ppc/ppc_translator.h | 8 +++--- src/alloy/frontend/ppc/test/alloy-ppc-test.cc | 14 +++++----- src/alloy/hir/block.cc | 4 +-- src/alloy/hir/block.h | 2 +- src/alloy/hir/hir_builder.cc | 14 +++++----- src/alloy/hir/hir_builder.h | 10 +++---- src/alloy/hir/instr.cc | 4 +-- src/alloy/hir/instr.h | 4 +-- src/alloy/hir/opcodes.cc | 4 +-- src/alloy/hir/opcodes.h | 2 +- src/alloy/hir/value.cc | 2 +- src/alloy/hir/value.h | 10 +++---- src/alloy/memory.cc | 4 +-- src/alloy/runtime/debug_info.cc | 2 +- src/alloy/runtime/debugger.cc | 4 +-- src/alloy/runtime/debugger.h | 2 +- src/alloy/runtime/entry_table.cc | 6 ++--- src/alloy/runtime/function.cc | 10 +++---- src/alloy/runtime/function.h | 2 +- src/alloy/runtime/instrument.cc | 8 +++--- src/alloy/runtime/module.cc | 8 +++--- src/alloy/runtime/module.h | 4 +-- src/alloy/runtime/raw_module.cc | 6 ++--- src/alloy/runtime/raw_module.h | 2 +- src/alloy/runtime/runtime.cc | 12 ++++----- src/alloy/runtime/runtime.h | 16 ++++++------ src/alloy/runtime/symbol_info.cc | 2 +- src/alloy/runtime/test_module.cc | 12 ++++----- src/alloy/runtime/test_module.h | 8 +++--- src/alloy/runtime/thread_state.cc | 6 ++--- src/alloy/runtime/thread_state.h | 2 +- src/alloy/string_buffer.cc | 2 +- src/alloy/test/alloy-test.cc | 4 +-- src/alloy/test/test_add.cc | 2 +- src/alloy/test/test_byte_swap.cc | 2 +- src/alloy/test/test_extract.cc | 2 +- src/alloy/test/test_insert.cc | 2 +- src/alloy/test/test_load_vector_shl_shr.cc | 2 +- src/alloy/test/test_pack.cc | 2 +- src/alloy/test/test_permute.cc | 2 +- src/alloy/test/test_sha.cc | 2 +- src/alloy/test/test_shl.cc | 2 +- src/alloy/test/test_shr.cc | 2 +- src/alloy/test/test_swizzle.cc | 2 +- src/alloy/test/test_unpack.cc | 2 +- src/alloy/test/test_vector_add.cc | 2 +- src/alloy/test/test_vector_max.cc | 2 +- src/alloy/test/test_vector_min.cc | 2 +- src/alloy/test/test_vector_rotate_left.cc | 4 +-- src/alloy/test/test_vector_sha.cc | 2 +- src/alloy/test/test_vector_shl.cc | 2 +- src/alloy/test/test_vector_shr.cc | 2 +- src/alloy/test/util.h | 18 ++++++------- src/alloy/vec128.h | 2 +- src/poly/assert.h | 4 +-- src/poly/atomic.h | 4 +-- src/poly/byte_order.h | 4 +-- src/poly/cxx_compat.h | 2 +- src/poly/debugging.h | 2 +- src/poly/debugging_win.cc | 2 +- src/poly/logging.cc | 8 +++--- src/poly/logging.h | 2 +- src/poly/main.h | 2 +- src/poly/main_win.cc | 4 +-- src/poly/mapped_memory_win.cc | 2 +- src/poly/math.cc | 2 +- src/poly/math.h | 4 +-- src/poly/memory.cc | 2 +- src/poly/memory.h | 4 +-- src/poly/poly.h | 26 +++++++++---------- src/poly/string.cc | 2 +- src/poly/string.h | 2 +- src/poly/threading.cc | 2 +- src/poly/threading.h | 2 +- src/poly/threading_win.cc | 4 +-- src/poly/ui/control.cc | 4 +-- src/poly/ui/control.h | 4 +-- src/poly/ui/menu_item.cc | 2 +- src/poly/ui/menu_item.h | 4 +-- src/poly/ui/win32/win32_control.cc | 2 +- src/poly/ui/win32/win32_control.h | 2 +- src/poly/ui/win32/win32_loop.cc | 4 +-- src/poly/ui/win32/win32_loop.h | 4 +-- src/poly/ui/win32/win32_menu_item.cc | 2 +- src/poly/ui/win32/win32_menu_item.h | 2 +- src/poly/ui/win32/win32_window.cc | 4 +-- src/poly/ui/win32/win32_window.h | 4 +-- src/poly/ui/window.h | 6 ++--- src/xenia/apu/apu.cc | 8 +++--- src/xenia/apu/apu.h | 2 +- src/xenia/apu/audio_driver.cc | 8 +++--- src/xenia/apu/audio_driver.h | 6 ++--- src/xenia/apu/audio_system.cc | 12 ++++----- src/xenia/apu/audio_system.h | 6 ++--- src/xenia/apu/nop/nop_apu-private.h | 4 +-- src/xenia/apu/nop/nop_apu.cc | 4 +-- src/xenia/apu/nop/nop_apu.h | 2 +- src/xenia/apu/nop/nop_audio_system.cc | 4 +-- src/xenia/apu/nop/nop_audio_system.h | 6 ++--- src/xenia/apu/xaudio2/xaudio2_apu-private.h | 4 +-- src/xenia/apu/xaudio2/xaudio2_apu.cc | 4 +-- src/xenia/apu/xaudio2/xaudio2_apu.h | 2 +- src/xenia/apu/xaudio2/xaudio2_audio_driver.cc | 6 ++--- src/xenia/apu/xaudio2/xaudio2_audio_driver.h | 6 ++--- src/xenia/apu/xaudio2/xaudio2_audio_system.cc | 8 +++--- src/xenia/apu/xaudio2/xaudio2_audio_system.h | 6 ++--- src/xenia/common.h | 14 +++++----- src/xenia/cpu/cpu.cc | 2 +- src/xenia/cpu/cpu.h | 8 +++--- src/xenia/cpu/mmio_handler.cc | 4 +-- src/xenia/cpu/mmio_handler_win.cc | 2 +- src/xenia/cpu/processor.cc | 10 +++---- src/xenia/cpu/processor.h | 6 ++--- src/xenia/cpu/xenon_runtime.cc | 6 ++--- src/xenia/cpu/xenon_runtime.h | 10 +++---- src/xenia/cpu/xenon_thread_state.cc | 6 ++--- src/xenia/cpu/xenon_thread_state.h | 8 +++--- src/xenia/cpu/xex_module.cc | 10 +++---- src/xenia/cpu/xex_module.h | 6 ++--- src/xenia/debug_agent.cc | 4 +-- src/xenia/debug_agent.h | 2 +- src/xenia/emulator.cc | 26 +++++++++---------- src/xenia/emulator.h | 12 ++++----- src/xenia/export_resolver.cc | 4 +-- src/xenia/export_resolver.h | 2 +- src/xenia/gpu/gl4/circular_buffer.cc | 10 +++---- src/xenia/gpu/gl4/circular_buffer.h | 2 +- src/xenia/gpu/gl4/command_processor.cc | 20 +++++++------- src/xenia/gpu/gl4/command_processor.h | 16 ++++++------ src/xenia/gpu/gl4/draw_batcher.cc | 10 +++---- src/xenia/gpu/gl4/draw_batcher.h | 12 ++++----- src/xenia/gpu/gl4/gl4_gpu-private.h | 4 +-- src/xenia/gpu/gl4/gl4_gpu.cc | 6 ++--- src/xenia/gpu/gl4/gl4_gpu.h | 4 +-- src/xenia/gpu/gl4/gl4_graphics_system.cc | 12 ++++----- src/xenia/gpu/gl4/gl4_graphics_system.h | 10 +++---- src/xenia/gpu/gl4/gl4_profiler_display.cc | 10 +++---- src/xenia/gpu/gl4/gl4_profiler_display.h | 10 +++---- src/xenia/gpu/gl4/gl4_shader.cc | 12 ++++----- src/xenia/gpu/gl4/gl4_shader.h | 6 ++--- src/xenia/gpu/gl4/gl4_shader_translator.cc | 6 ++--- src/xenia/gpu/gl4/gl4_shader_translator.h | 12 ++++----- src/xenia/gpu/gl4/gl_context.cc | 12 ++++----- src/xenia/gpu/gl4/gl_context.h | 4 +-- src/xenia/gpu/gl4/texture_cache.cc | 8 +++--- src/xenia/gpu/gl4/texture_cache.h | 10 +++---- src/xenia/gpu/gl4/wgl_control.cc | 10 +++---- src/xenia/gpu/gl4/wgl_control.h | 8 +++--- src/xenia/gpu/gpu.cc | 6 ++--- src/xenia/gpu/gpu.h | 2 +- src/xenia/gpu/graphics_system.cc | 10 +++---- src/xenia/gpu/graphics_system.h | 6 ++--- src/xenia/gpu/register_file.cc | 4 +-- src/xenia/gpu/register_file.h | 4 +-- src/xenia/gpu/sampler_info.cc | 4 +-- src/xenia/gpu/sampler_info.h | 4 +-- src/xenia/gpu/shader.cc | 6 ++--- src/xenia/gpu/shader.h | 4 +-- src/xenia/gpu/texture_info.cc | 6 ++--- src/xenia/gpu/texture_info.h | 4 +-- src/xenia/gpu/ucode.h | 2 +- src/xenia/gpu/ucode_disassembler.cc | 2 +- src/xenia/gpu/ucode_disassembler.h | 4 +-- src/xenia/gpu/xenos.h | 4 +-- src/xenia/hid/hid.cc | 12 ++++----- src/xenia/hid/hid.h | 2 +- src/xenia/hid/input_driver.cc | 2 +- src/xenia/hid/input_driver.h | 4 +-- src/xenia/hid/input_system.cc | 8 +++--- src/xenia/hid/input_system.h | 6 ++--- src/xenia/hid/nop/nop_hid-private.h | 4 +-- src/xenia/hid/nop/nop_hid.cc | 4 +-- src/xenia/hid/nop/nop_hid.h | 2 +- src/xenia/hid/nop/nop_input_driver.cc | 4 +-- src/xenia/hid/nop/nop_input_driver.h | 6 ++--- src/xenia/hid/winkey/winkey_hid-private.h | 4 +-- src/xenia/hid/winkey/winkey_hid.cc | 4 +-- src/xenia/hid/winkey/winkey_hid.h | 2 +- src/xenia/hid/winkey/winkey_input_driver.cc | 4 +-- src/xenia/hid/winkey/winkey_input_driver.h | 6 ++--- src/xenia/hid/xinput/xinput_hid-private.h | 4 +-- src/xenia/hid/xinput/xinput_hid.cc | 4 +-- src/xenia/hid/xinput/xinput_hid.h | 2 +- src/xenia/hid/xinput/xinput_input_driver.cc | 4 +-- src/xenia/hid/xinput/xinput_input_driver.h | 6 ++--- src/xenia/kernel/app.cc | 4 +-- src/xenia/kernel/app.h | 6 ++--- src/xenia/kernel/apps/apps.cc | 4 +-- src/xenia/kernel/apps/apps.h | 6 ++--- src/xenia/kernel/apps/xmp_app.cc | 4 +-- src/xenia/kernel/apps/xmp_app.h | 6 ++--- src/xenia/kernel/async_request.cc | 6 ++--- src/xenia/kernel/async_request.h | 4 +-- src/xenia/kernel/dispatcher.cc | 6 ++--- src/xenia/kernel/dispatcher.h | 4 +-- src/xenia/kernel/fs/device.cc | 4 +-- src/xenia/kernel/fs/device.h | 4 +-- .../kernel/fs/devices/disc_image_device.cc | 8 +++--- .../kernel/fs/devices/disc_image_device.h | 6 ++--- .../kernel/fs/devices/disc_image_entry.cc | 6 ++--- .../kernel/fs/devices/disc_image_entry.h | 6 ++--- .../kernel/fs/devices/disc_image_file.cc | 8 +++--- src/xenia/kernel/fs/devices/disc_image_file.h | 4 +-- .../kernel/fs/devices/host_path_device.cc | 6 ++--- .../kernel/fs/devices/host_path_device.h | 4 +-- .../kernel/fs/devices/host_path_entry.cc | 6 ++--- src/xenia/kernel/fs/devices/host_path_entry.h | 4 +-- src/xenia/kernel/fs/devices/host_path_file.cc | 6 ++--- src/xenia/kernel/fs/devices/host_path_file.h | 4 +-- .../fs/devices/stfs_container_device.cc | 10 +++---- .../kernel/fs/devices/stfs_container_device.h | 6 ++--- .../kernel/fs/devices/stfs_container_entry.cc | 6 ++--- .../kernel/fs/devices/stfs_container_entry.h | 6 ++--- .../kernel/fs/devices/stfs_container_file.cc | 8 +++--- .../kernel/fs/devices/stfs_container_file.h | 4 +-- src/xenia/kernel/fs/entry.cc | 4 +-- src/xenia/kernel/fs/entry.h | 4 +-- src/xenia/kernel/fs/filesystem.cc | 10 +++---- src/xenia/kernel/fs/filesystem.h | 4 +-- src/xenia/kernel/fs/gdfx.cc | 4 +-- src/xenia/kernel/fs/gdfx.h | 8 +++--- src/xenia/kernel/fs/stfs.cc | 2 +- src/xenia/kernel/fs/stfs.h | 8 +++--- src/xenia/kernel/kernel.h | 2 +- src/xenia/kernel/kernel_state.cc | 26 +++++++++---------- src/xenia/kernel/kernel_state.h | 16 ++++++------ src/xenia/kernel/modules.h | 4 +-- src/xenia/kernel/native_list.cc | 2 +- src/xenia/kernel/native_list.h | 6 ++--- src/xenia/kernel/object_table.cc | 6 ++--- src/xenia/kernel/object_table.h | 4 +-- src/xenia/kernel/objects/xenumerator.cc | 2 +- src/xenia/kernel/objects/xenumerator.h | 4 +-- src/xenia/kernel/objects/xevent.cc | 2 +- src/xenia/kernel/objects/xevent.h | 4 +-- src/xenia/kernel/objects/xfile.cc | 6 ++--- src/xenia/kernel/objects/xfile.h | 4 +-- src/xenia/kernel/objects/xkernel_module.cc | 8 +++--- src/xenia/kernel/objects/xkernel_module.h | 4 +-- src/xenia/kernel/objects/xmodule.cc | 4 +-- src/xenia/kernel/objects/xmodule.h | 4 +-- src/xenia/kernel/objects/xmutant.cc | 2 +- src/xenia/kernel/objects/xmutant.h | 4 +-- src/xenia/kernel/objects/xnotify_listener.cc | 2 +- src/xenia/kernel/objects/xnotify_listener.h | 4 +-- src/xenia/kernel/objects/xsemaphore.cc | 2 +- src/xenia/kernel/objects/xsemaphore.h | 4 +-- src/xenia/kernel/objects/xthread.cc | 14 +++++----- src/xenia/kernel/objects/xthread.h | 6 ++--- src/xenia/kernel/objects/xtimer.cc | 4 +-- src/xenia/kernel/objects/xtimer.h | 4 +-- src/xenia/kernel/objects/xuser_module.cc | 10 +++---- src/xenia/kernel/objects/xuser_module.h | 8 +++--- src/xenia/kernel/user_profile.cc | 2 +- src/xenia/kernel/user_profile.h | 4 +-- src/xenia/kernel/util/export_table_pre.inc | 6 ++--- src/xenia/kernel/util/ordinal_table_pre.inc | 6 ++--- src/xenia/kernel/util/shim_utils.h | 6 ++--- src/xenia/kernel/util/xex2.cc | 16 ++++++------ src/xenia/kernel/util/xex2.h | 6 ++--- src/xenia/kernel/util/xex2_info.h | 2 +- src/xenia/kernel/xam_content.cc | 10 +++---- src/xenia/kernel/xam_info.cc | 14 +++++----- src/xenia/kernel/xam_input.cc | 14 +++++----- src/xenia/kernel/xam_module.cc | 16 ++++++------ src/xenia/kernel/xam_module.h | 8 +++--- src/xenia/kernel/xam_msg.cc | 12 ++++----- src/xenia/kernel/xam_net.cc | 10 +++---- src/xenia/kernel/xam_notify.cc | 12 ++++----- src/xenia/kernel/xam_ordinals.h | 10 +++---- src/xenia/kernel/xam_private.h | 4 +-- src/xenia/kernel/xam_ui.cc | 10 +++---- src/xenia/kernel/xam_user.cc | 14 +++++----- src/xenia/kernel/xam_video.cc | 10 +++---- src/xenia/kernel/xam_voice.cc | 12 ++++----- src/xenia/kernel/xboxkrnl_audio.cc | 14 +++++----- src/xenia/kernel/xboxkrnl_debug.cc | 12 ++++----- src/xenia/kernel/xboxkrnl_hal.cc | 10 +++---- src/xenia/kernel/xboxkrnl_io.cc | 18 ++++++------- src/xenia/kernel/xboxkrnl_memory.cc | 12 ++++----- src/xenia/kernel/xboxkrnl_misc.cc | 12 ++++----- src/xenia/kernel/xboxkrnl_module.cc | 20 +++++++------- src/xenia/kernel/xboxkrnl_module.h | 10 +++---- src/xenia/kernel/xboxkrnl_modules.cc | 14 +++++----- src/xenia/kernel/xboxkrnl_ob.cc | 14 +++++----- src/xenia/kernel/xboxkrnl_ordinals.h | 10 +++---- src/xenia/kernel/xboxkrnl_private.h | 4 +-- src/xenia/kernel/xboxkrnl_rtl.cc | 16 ++++++------ src/xenia/kernel/xboxkrnl_rtl.h | 4 +-- src/xenia/kernel/xboxkrnl_strings.cc | 16 ++++++------ src/xenia/kernel/xboxkrnl_threading.cc | 26 +++++++++---------- src/xenia/kernel/xboxkrnl_usbcam.cc | 10 +++---- src/xenia/kernel/xboxkrnl_video.cc | 20 +++++++------- src/xenia/kernel/xobject.cc | 10 +++---- src/xenia/kernel/xobject.h | 4 +-- src/xenia/logging.h | 2 +- src/xenia/memory.cc | 10 +++---- src/xenia/memory.h | 6 ++--- src/xenia/profiling.cc | 4 +-- src/xenia/profiling.h | 2 +- src/xenia/ui/main_window.cc | 8 +++--- src/xenia/ui/main_window.h | 8 +++--- src/xenia/xbox.h | 4 +-- src/xenia/xenia_main.cc | 8 +++--- 373 files changed, 1171 insertions(+), 1171 deletions(-) diff --git a/src/alloy/alloy.cc b/src/alloy/alloy.cc index e5b135a9e..2f6d095f3 100644 --- a/src/alloy/alloy.cc +++ b/src/alloy/alloy.cc @@ -7,8 +7,8 @@ ****************************************************************************** */ -#include -#include +#include "alloy/alloy.h" +#include "alloy/alloy-private.h" using namespace alloy; diff --git a/src/alloy/alloy.h b/src/alloy/alloy.h index 2b2d9f318..4f47028f0 100644 --- a/src/alloy/alloy.h +++ b/src/alloy/alloy.h @@ -10,9 +10,9 @@ #ifndef ALLOY_ALLOY_H_ #define ALLOY_ALLOY_H_ -#include -#include -#include -#include +#include "alloy/runtime/function.h" +#include "alloy/runtime/module.h" +#include "alloy/runtime/runtime.h" +#include "alloy/runtime/thread_state.h" #endif // ALLOY_ALLOY_H_ diff --git a/src/alloy/arena.cc b/src/alloy/arena.cc index 081467e72..b80c60a33 100644 --- a/src/alloy/arena.cc +++ b/src/alloy/arena.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "alloy/arena.h" -#include +#include "poly/poly.h" namespace alloy { diff --git a/src/alloy/backend/assembler.cc b/src/alloy/backend/assembler.cc index 6d5737692..b045fa615 100644 --- a/src/alloy/backend/assembler.cc +++ b/src/alloy/backend/assembler.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/backend/assembler.h" namespace alloy { namespace backend { diff --git a/src/alloy/backend/backend.cc b/src/alloy/backend/backend.cc index d66283c82..e0b1010ff 100644 --- a/src/alloy/backend/backend.cc +++ b/src/alloy/backend/backend.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/backend/backend.h" namespace alloy { namespace backend { diff --git a/src/alloy/backend/backend.h b/src/alloy/backend/backend.h index efa8371c1..ab7756252 100644 --- a/src/alloy/backend/backend.h +++ b/src/alloy/backend/backend.h @@ -12,7 +12,7 @@ #include -#include +#include "alloy/backend/machine_info.h" namespace alloy { namespace runtime { diff --git a/src/alloy/backend/x64/x64_assembler.cc b/src/alloy/backend/x64/x64_assembler.cc index a963b39e5..e57e85ef2 100644 --- a/src/alloy/backend/x64/x64_assembler.cc +++ b/src/alloy/backend/x64/x64_assembler.cc @@ -7,16 +7,16 @@ ****************************************************************************** */ -#include +#include "alloy/backend/x64/x64_assembler.h" -#include -#include -#include -#include -#include -#include -#include -#include +#include "alloy/reset_scope.h" +#include "alloy/backend/x64/x64_backend.h" +#include "alloy/backend/x64/x64_emitter.h" +#include "alloy/backend/x64/x64_function.h" +#include "alloy/hir/hir_builder.h" +#include "alloy/hir/label.h" +#include "alloy/runtime/runtime.h" +#include "xenia/profiling.h" namespace BE { #include diff --git a/src/alloy/backend/x64/x64_assembler.h b/src/alloy/backend/x64/x64_assembler.h index 03714e680..0eb9ad85e 100644 --- a/src/alloy/backend/x64/x64_assembler.h +++ b/src/alloy/backend/x64/x64_assembler.h @@ -12,8 +12,8 @@ #include -#include -#include +#include "alloy/backend/assembler.h" +#include "alloy/string_buffer.h" namespace alloy { namespace backend { diff --git a/src/alloy/backend/x64/x64_backend.cc b/src/alloy/backend/x64/x64_backend.cc index 32aed4d78..892795e9c 100644 --- a/src/alloy/backend/x64/x64_backend.cc +++ b/src/alloy/backend/x64/x64_backend.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include +#include "alloy/backend/x64/x64_backend.h" -#include -#include -#include -#include +#include "alloy/backend/x64/x64_assembler.h" +#include "alloy/backend/x64/x64_code_cache.h" +#include "alloy/backend/x64/x64_sequences.h" +#include "alloy/backend/x64/x64_thunk_emitter.h" namespace alloy { namespace backend { diff --git a/src/alloy/backend/x64/x64_backend.h b/src/alloy/backend/x64/x64_backend.h index d285417f1..b6281ce2c 100644 --- a/src/alloy/backend/x64/x64_backend.h +++ b/src/alloy/backend/x64/x64_backend.h @@ -10,7 +10,7 @@ #ifndef ALLOY_BACKEND_X64_X64_BACKEND_H_ #define ALLOY_BACKEND_X64_X64_BACKEND_H_ -#include +#include "alloy/backend/backend.h" namespace alloy { namespace backend { diff --git a/src/alloy/backend/x64/x64_code_cache_win.cc b/src/alloy/backend/x64/x64_code_cache_win.cc index 0b4a04c63..c8f336de8 100644 --- a/src/alloy/backend/x64/x64_code_cache_win.cc +++ b/src/alloy/backend/x64/x64_code_cache_win.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "alloy/backend/x64/x64_code_cache.h" -#include -#include +#include "poly/poly.h" +#include "xenia/profiling.h" namespace alloy { namespace backend { diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index 79d904ea9..a404f52fc 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -7,20 +7,20 @@ ****************************************************************************** */ -#include +#include "alloy/backend/x64/x64_emitter.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "alloy/backend/x64/x64_backend.h" +#include "alloy/backend/x64/x64_code_cache.h" +#include "alloy/backend/x64/x64_function.h" +#include "alloy/backend/x64/x64_sequences.h" +#include "alloy/backend/x64/x64_thunk_emitter.h" +#include "alloy/hir/hir_builder.h" +#include "alloy/runtime/debug_info.h" +#include "alloy/runtime/runtime.h" +#include "alloy/runtime/symbol_info.h" +#include "alloy/runtime/thread_state.h" +#include "xdb/protocol.h" +#include "xenia/profiling.h" namespace alloy { namespace backend { diff --git a/src/alloy/backend/x64/x64_emitter.h b/src/alloy/backend/x64/x64_emitter.h index 9245f408d..7cb529684 100644 --- a/src/alloy/backend/x64/x64_emitter.h +++ b/src/alloy/backend/x64/x64_emitter.h @@ -10,8 +10,8 @@ #ifndef ALLOY_BACKEND_X64_X64_EMITTER_H_ #define ALLOY_BACKEND_X64_X64_EMITTER_H_ -#include -#include +#include "alloy/hir/value.h" +#include "third_party/xbyak/xbyak/xbyak.h" namespace alloy { namespace hir { diff --git a/src/alloy/backend/x64/x64_function.cc b/src/alloy/backend/x64/x64_function.cc index 1b3cc9117..96468219d 100644 --- a/src/alloy/backend/x64/x64_function.cc +++ b/src/alloy/backend/x64/x64_function.cc @@ -7,11 +7,11 @@ ****************************************************************************** */ -#include +#include "alloy/backend/x64/x64_function.h" -#include -#include -#include +#include "alloy/backend/x64/x64_backend.h" +#include "alloy/runtime/runtime.h" +#include "alloy/runtime/thread_state.h" namespace alloy { namespace backend { diff --git a/src/alloy/backend/x64/x64_function.h b/src/alloy/backend/x64/x64_function.h index 24d4af098..b78689364 100644 --- a/src/alloy/backend/x64/x64_function.h +++ b/src/alloy/backend/x64/x64_function.h @@ -10,8 +10,8 @@ #ifndef ALLOY_BACKEND_X64_X64_FUNCTION_H_ #define ALLOY_BACKEND_X64_X64_FUNCTION_H_ -#include -#include +#include "alloy/runtime/function.h" +#include "alloy/runtime/symbol_info.h" namespace alloy { namespace backend { diff --git a/src/alloy/backend/x64/x64_sequences.cc b/src/alloy/backend/x64/x64_sequences.cc index fe422d8f0..2cef7ca64 100644 --- a/src/alloy/backend/x64/x64_sequences.cc +++ b/src/alloy/backend/x64/x64_sequences.cc @@ -22,12 +22,12 @@ // load into xmm register: // [0F 0E 0D 0C] [0B 0A 09 08] [07 06 05 04] [03 02 01 00] (w, z, y, x) -#include +#include "alloy/backend/x64/x64_sequences.h" -#include -#include -#include -#include +#include "alloy/backend/x64/x64_emitter.h" +#include "alloy/backend/x64/x64_tracers.h" +#include "alloy/hir/hir_builder.h" +#include "alloy/runtime/runtime.h" namespace alloy { namespace backend { @@ -43,7 +43,7 @@ typedef bool (*SequenceSelectFn)(X64Emitter&, const Instr*, const Instr**); std::unordered_multimap sequence_table; // Utilities/types used only in this file: -#include +#include "alloy/backend/x64/x64_sequence.inl" // Selects the right byte/word/etc from a vector. We need to flip logical // indices (0,1,2,3,4,5,6,7,...) = (3,2,1,0,7,6,5,4,...) diff --git a/src/alloy/backend/x64/x64_thunk_emitter.cc b/src/alloy/backend/x64/x64_thunk_emitter.cc index 999766662..054e41c02 100644 --- a/src/alloy/backend/x64/x64_thunk_emitter.cc +++ b/src/alloy/backend/x64/x64_thunk_emitter.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "alloy/backend/x64/x64_thunk_emitter.h" -#include +#include "third_party/xbyak/xbyak/xbyak.h" namespace alloy { namespace backend { diff --git a/src/alloy/backend/x64/x64_thunk_emitter.h b/src/alloy/backend/x64/x64_thunk_emitter.h index b8b5c612d..e8a0d4903 100644 --- a/src/alloy/backend/x64/x64_thunk_emitter.h +++ b/src/alloy/backend/x64/x64_thunk_emitter.h @@ -10,8 +10,8 @@ #ifndef ALLOY_BACKEND_X64_X64_THUNK_EMITTER_H_ #define ALLOY_BACKEND_X64_X64_THUNK_EMITTER_H_ -#include -#include +#include "alloy/backend/x64/x64_backend.h" +#include "alloy/backend/x64/x64_emitter.h" namespace alloy { namespace backend { diff --git a/src/alloy/backend/x64/x64_tracers.cc b/src/alloy/backend/x64/x64_tracers.cc index 86b1948c2..aa51892fe 100644 --- a/src/alloy/backend/x64/x64_tracers.cc +++ b/src/alloy/backend/x64/x64_tracers.cc @@ -7,11 +7,11 @@ ****************************************************************************** */ -#include +#include "alloy/backend/x64/x64_tracers.h" -#include -#include -#include +#include "alloy/backend/x64/x64_emitter.h" +#include "alloy/runtime/runtime.h" +#include "alloy/runtime/thread_state.h" using namespace alloy; using namespace alloy::backend::x64; diff --git a/src/alloy/compiler/compiler.cc b/src/alloy/compiler/compiler.cc index 50b295803..fc03d8de4 100644 --- a/src/alloy/compiler/compiler.cc +++ b/src/alloy/compiler/compiler.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "alloy/compiler/compiler.h" -#include -#include +#include "alloy/compiler/compiler_pass.h" +#include "xenia/profiling.h" namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/compiler.h b/src/alloy/compiler/compiler.h index 1f1c911f9..15188f4d7 100644 --- a/src/alloy/compiler/compiler.h +++ b/src/alloy/compiler/compiler.h @@ -13,7 +13,7 @@ #include #include -#include +#include "alloy/hir/hir_builder.h" namespace alloy { namespace runtime { diff --git a/src/alloy/compiler/compiler_pass.cc b/src/alloy/compiler/compiler_pass.cc index 67ac1700f..bc6e580f7 100644 --- a/src/alloy/compiler/compiler_pass.cc +++ b/src/alloy/compiler/compiler_pass.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "alloy/compiler/compiler_pass.h" -#include +#include "alloy/compiler/compiler.h" namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/compiler_pass.h b/src/alloy/compiler/compiler_pass.h index f00aa42ab..14831665d 100644 --- a/src/alloy/compiler/compiler_pass.h +++ b/src/alloy/compiler/compiler_pass.h @@ -10,7 +10,7 @@ #ifndef ALLOY_COMPILER_COMPILER_PASS_H_ #define ALLOY_COMPILER_COMPILER_PASS_H_ -#include +#include "alloy/hir/hir_builder.h" namespace alloy { namespace runtime { diff --git a/src/alloy/compiler/compiler_passes.h b/src/alloy/compiler/compiler_passes.h index 935b8397b..83cd1b924 100644 --- a/src/alloy/compiler/compiler_passes.h +++ b/src/alloy/compiler/compiler_passes.h @@ -10,18 +10,18 @@ #ifndef ALLOY_COMPILER_COMPILER_PASSES_H_ #define ALLOY_COMPILER_COMPILER_PASSES_H_ -#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#include -#include +#include "alloy/compiler/passes/constant_propagation_pass.h" +#include "alloy/compiler/passes/context_promotion_pass.h" +#include "alloy/compiler/passes/control_flow_analysis_pass.h" +#include "alloy/compiler/passes/control_flow_simplification_pass.h" +#include "alloy/compiler/passes/data_flow_analysis_pass.h" +#include "alloy/compiler/passes/dead_code_elimination_pass.h" +//#include "alloy/compiler/passes/dead_store_elimination_pass.h" +#include "alloy/compiler/passes/finalization_pass.h" +#include "alloy/compiler/passes/register_allocation_pass.h" +#include "alloy/compiler/passes/simplification_pass.h" +#include "alloy/compiler/passes/validation_pass.h" +#include "alloy/compiler/passes/value_reduction_pass.h" // TODO: // - mark_use/mark_set diff --git a/src/alloy/compiler/passes/constant_propagation_pass.cc b/src/alloy/compiler/passes/constant_propagation_pass.cc index 072530db9..29d1b1451 100644 --- a/src/alloy/compiler/passes/constant_propagation_pass.cc +++ b/src/alloy/compiler/passes/constant_propagation_pass.cc @@ -7,11 +7,11 @@ ****************************************************************************** */ -#include +#include "alloy/compiler/passes/constant_propagation_pass.h" -#include -#include -#include +#include "alloy/runtime/function.h" +#include "alloy/runtime/runtime.h" +#include "xenia/profiling.h" namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/passes/constant_propagation_pass.h b/src/alloy/compiler/passes/constant_propagation_pass.h index ff7241e3e..7f5d4da96 100644 --- a/src/alloy/compiler/passes/constant_propagation_pass.h +++ b/src/alloy/compiler/passes/constant_propagation_pass.h @@ -10,7 +10,7 @@ #ifndef ALLOY_COMPILER_PASSES_CONSTANT_PROPAGATION_PASS_H_ #define ALLOY_COMPILER_PASSES_CONSTANT_PROPAGATION_PASS_H_ -#include +#include "alloy/compiler/compiler_pass.h" namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/passes/context_promotion_pass.cc b/src/alloy/compiler/passes/context_promotion_pass.cc index 1b47246c0..6b630b7ca 100644 --- a/src/alloy/compiler/passes/context_promotion_pass.cc +++ b/src/alloy/compiler/passes/context_promotion_pass.cc @@ -7,13 +7,13 @@ ****************************************************************************** */ -#include +#include "alloy/compiler/passes/context_promotion_pass.h" #include -#include -#include -#include +#include "alloy/compiler/compiler.h" +#include "alloy/runtime/runtime.h" +#include "xenia/profiling.h" DEFINE_bool(store_all_context_values, false, "Don't strip dead context stores to aid in debugging."); diff --git a/src/alloy/compiler/passes/context_promotion_pass.h b/src/alloy/compiler/passes/context_promotion_pass.h index db6480da7..07b192598 100644 --- a/src/alloy/compiler/passes/context_promotion_pass.h +++ b/src/alloy/compiler/passes/context_promotion_pass.h @@ -10,7 +10,7 @@ #ifndef ALLOY_COMPILER_PASSES_CONTEXT_PROMOTION_PASS_H_ #define ALLOY_COMPILER_PASSES_CONTEXT_PROMOTION_PASS_H_ -#include +#include "alloy/compiler/compiler_pass.h" #if XE_COMPILER_MSVC #pragma warning(push) diff --git a/src/alloy/compiler/passes/control_flow_analysis_pass.cc b/src/alloy/compiler/passes/control_flow_analysis_pass.cc index ce379cee6..3fd72c49b 100644 --- a/src/alloy/compiler/passes/control_flow_analysis_pass.cc +++ b/src/alloy/compiler/passes/control_flow_analysis_pass.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include +#include "alloy/compiler/passes/control_flow_analysis_pass.h" -#include -#include -#include -#include +#include "alloy/backend/backend.h" +#include "alloy/compiler/compiler.h" +#include "alloy/runtime/runtime.h" +#include "xenia/profiling.h" namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/passes/control_flow_analysis_pass.h b/src/alloy/compiler/passes/control_flow_analysis_pass.h index bcde6cd5a..7354f0be5 100644 --- a/src/alloy/compiler/passes/control_flow_analysis_pass.h +++ b/src/alloy/compiler/passes/control_flow_analysis_pass.h @@ -10,7 +10,7 @@ #ifndef ALLOY_COMPILER_PASSES_CONTROL_FLOW_ANALYSIS_PASS_H_ #define ALLOY_COMPILER_PASSES_CONTROL_FLOW_ANALYSIS_PASS_H_ -#include +#include "alloy/compiler/compiler_pass.h" namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/passes/control_flow_simplification_pass.cc b/src/alloy/compiler/passes/control_flow_simplification_pass.cc index 1e404dbe1..89764b456 100644 --- a/src/alloy/compiler/passes/control_flow_simplification_pass.cc +++ b/src/alloy/compiler/passes/control_flow_simplification_pass.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include +#include "alloy/compiler/passes/control_flow_simplification_pass.h" -#include -#include -#include -#include +#include "alloy/backend/backend.h" +#include "alloy/compiler/compiler.h" +#include "alloy/runtime/runtime.h" +#include "xenia/profiling.h" namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/passes/control_flow_simplification_pass.h b/src/alloy/compiler/passes/control_flow_simplification_pass.h index 350ed4d9d..4c79ac57d 100644 --- a/src/alloy/compiler/passes/control_flow_simplification_pass.h +++ b/src/alloy/compiler/passes/control_flow_simplification_pass.h @@ -10,7 +10,7 @@ #ifndef ALLOY_COMPILER_PASSES_CONTROL_FLOW_SIMPLIFICATION_PASS_H_ #define ALLOY_COMPILER_PASSES_CONTROL_FLOW_SIMPLIFICATION_PASS_H_ -#include +#include "alloy/compiler/compiler_pass.h" namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/passes/data_flow_analysis_pass.cc b/src/alloy/compiler/passes/data_flow_analysis_pass.cc index b814f9260..8decd65f8 100644 --- a/src/alloy/compiler/passes/data_flow_analysis_pass.cc +++ b/src/alloy/compiler/passes/data_flow_analysis_pass.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include +#include "alloy/compiler/passes/data_flow_analysis_pass.h" -#include -#include -#include -#include +#include "alloy/backend/backend.h" +#include "alloy/compiler/compiler.h" +#include "alloy/runtime/runtime.h" +#include "xenia/profiling.h" #if XE_COMPILER_MSVC #pragma warning(push) diff --git a/src/alloy/compiler/passes/data_flow_analysis_pass.h b/src/alloy/compiler/passes/data_flow_analysis_pass.h index f3990b2ec..41ce04952 100644 --- a/src/alloy/compiler/passes/data_flow_analysis_pass.h +++ b/src/alloy/compiler/passes/data_flow_analysis_pass.h @@ -10,7 +10,7 @@ #ifndef ALLOY_COMPILER_PASSES_DATA_FLOW_ANALYSIS_PASS_H_ #define ALLOY_COMPILER_PASSES_DATA_FLOW_ANALYSIS_PASS_H_ -#include +#include "alloy/compiler/compiler_pass.h" namespace alloy { diff --git a/src/alloy/compiler/passes/dead_code_elimination_pass.cc b/src/alloy/compiler/passes/dead_code_elimination_pass.cc index b439edad3..3d36ce411 100644 --- a/src/alloy/compiler/passes/dead_code_elimination_pass.cc +++ b/src/alloy/compiler/passes/dead_code_elimination_pass.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "alloy/compiler/passes/dead_code_elimination_pass.h" -#include +#include "xenia/profiling.h" namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/passes/dead_code_elimination_pass.h b/src/alloy/compiler/passes/dead_code_elimination_pass.h index 14d8667df..3350fb573 100644 --- a/src/alloy/compiler/passes/dead_code_elimination_pass.h +++ b/src/alloy/compiler/passes/dead_code_elimination_pass.h @@ -10,7 +10,7 @@ #ifndef ALLOY_COMPILER_PASSES_DEAD_CODE_ELIMINATION_PASS_H_ #define ALLOY_COMPILER_PASSES_DEAD_CODE_ELIMINATION_PASS_H_ -#include +#include "alloy/compiler/compiler_pass.h" namespace alloy { diff --git a/src/alloy/compiler/passes/finalization_pass.cc b/src/alloy/compiler/passes/finalization_pass.cc index 12e4254d7..0c3b96392 100644 --- a/src/alloy/compiler/passes/finalization_pass.cc +++ b/src/alloy/compiler/passes/finalization_pass.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include +#include "alloy/compiler/passes/finalization_pass.h" -#include -#include -#include -#include +#include "alloy/backend/backend.h" +#include "alloy/compiler/compiler.h" +#include "alloy/runtime/runtime.h" +#include "xenia/profiling.h" namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/passes/finalization_pass.h b/src/alloy/compiler/passes/finalization_pass.h index cf951f706..1e5ca2b99 100644 --- a/src/alloy/compiler/passes/finalization_pass.h +++ b/src/alloy/compiler/passes/finalization_pass.h @@ -10,7 +10,7 @@ #ifndef ALLOY_COMPILER_PASSES_FINALIZATION_PASS_H_ #define ALLOY_COMPILER_PASSES_FINALIZATION_PASS_H_ -#include +#include "alloy/compiler/compiler_pass.h" namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/passes/register_allocation_pass.cc b/src/alloy/compiler/passes/register_allocation_pass.cc index f388f90c1..3a1ce56c5 100644 --- a/src/alloy/compiler/passes/register_allocation_pass.cc +++ b/src/alloy/compiler/passes/register_allocation_pass.cc @@ -7,11 +7,11 @@ ****************************************************************************** */ -#include +#include "alloy/compiler/passes/register_allocation_pass.h" #include -#include +#include "xenia/profiling.h" namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/passes/register_allocation_pass.h b/src/alloy/compiler/passes/register_allocation_pass.h index 6090ed527..c57a4da60 100644 --- a/src/alloy/compiler/passes/register_allocation_pass.h +++ b/src/alloy/compiler/passes/register_allocation_pass.h @@ -14,8 +14,8 @@ #include #include -#include -#include +#include "alloy/backend/machine_info.h" +#include "alloy/compiler/compiler_pass.h" namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/passes/simplification_pass.cc b/src/alloy/compiler/passes/simplification_pass.cc index c1d73db6b..cbd2ee39a 100644 --- a/src/alloy/compiler/passes/simplification_pass.cc +++ b/src/alloy/compiler/passes/simplification_pass.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "alloy/compiler/passes/simplification_pass.h" -#include +#include "xenia/profiling.h" namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/passes/simplification_pass.h b/src/alloy/compiler/passes/simplification_pass.h index 328e200a9..769a355fd 100644 --- a/src/alloy/compiler/passes/simplification_pass.h +++ b/src/alloy/compiler/passes/simplification_pass.h @@ -10,7 +10,7 @@ #ifndef ALLOY_COMPILER_PASSES_SIMPLIFICATION_PASS_H_ #define ALLOY_COMPILER_PASSES_SIMPLIFICATION_PASS_H_ -#include +#include "alloy/compiler/compiler_pass.h" namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/passes/validation_pass.cc b/src/alloy/compiler/passes/validation_pass.cc index 9b6d209fb..f4650fdf0 100644 --- a/src/alloy/compiler/passes/validation_pass.cc +++ b/src/alloy/compiler/passes/validation_pass.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include +#include "alloy/compiler/passes/validation_pass.h" -#include -#include -#include -#include +#include "alloy/backend/backend.h" +#include "alloy/compiler/compiler.h" +#include "alloy/runtime/runtime.h" +#include "xenia/profiling.h" namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/passes/validation_pass.h b/src/alloy/compiler/passes/validation_pass.h index 133187d6f..974e1da50 100644 --- a/src/alloy/compiler/passes/validation_pass.h +++ b/src/alloy/compiler/passes/validation_pass.h @@ -10,7 +10,7 @@ #ifndef ALLOY_COMPILER_PASSES_VALIDATION_PASS_H_ #define ALLOY_COMPILER_PASSES_VALIDATION_PASS_H_ -#include +#include "alloy/compiler/compiler_pass.h" namespace alloy { namespace compiler { diff --git a/src/alloy/compiler/passes/value_reduction_pass.cc b/src/alloy/compiler/passes/value_reduction_pass.cc index d46037fe0..46ade7351 100644 --- a/src/alloy/compiler/passes/value_reduction_pass.cc +++ b/src/alloy/compiler/passes/value_reduction_pass.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include +#include "alloy/compiler/passes/value_reduction_pass.h" -#include -#include -#include -#include +#include "alloy/backend/backend.h" +#include "alloy/compiler/compiler.h" +#include "alloy/runtime/runtime.h" +#include "xenia/profiling.h" #if XE_COMPILER_MSVC #pragma warning(push) diff --git a/src/alloy/compiler/passes/value_reduction_pass.h b/src/alloy/compiler/passes/value_reduction_pass.h index b2ea00bb7..430c02c18 100644 --- a/src/alloy/compiler/passes/value_reduction_pass.h +++ b/src/alloy/compiler/passes/value_reduction_pass.h @@ -10,7 +10,7 @@ #ifndef ALLOY_COMPILER_PASSES_VALUE_REDUCTION_PASS_H_ #define ALLOY_COMPILER_PASSES_VALUE_REDUCTION_PASS_H_ -#include +#include "alloy/compiler/compiler_pass.h" namespace alloy { namespace compiler { diff --git a/src/alloy/frontend/context_info.cc b/src/alloy/frontend/context_info.cc index f14109124..7917ff33f 100644 --- a/src/alloy/frontend/context_info.cc +++ b/src/alloy/frontend/context_info.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/frontend/context_info.h" namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/frontend.cc b/src/alloy/frontend/frontend.cc index a9da0bfd7..c762a6225 100644 --- a/src/alloy/frontend/frontend.cc +++ b/src/alloy/frontend/frontend.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "alloy/frontend/frontend.h" -#include +#include "alloy/runtime/runtime.h" namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/frontend.h b/src/alloy/frontend/frontend.h index 83d0f9839..5e8d4b346 100644 --- a/src/alloy/frontend/frontend.h +++ b/src/alloy/frontend/frontend.h @@ -12,10 +12,10 @@ #include -#include -#include -#include -#include +#include "alloy/frontend/context_info.h" +#include "alloy/memory.h" +#include "alloy/runtime/function.h" +#include "alloy/runtime/symbol_info.h" namespace alloy { namespace runtime { diff --git a/src/alloy/frontend/ppc/ppc_context.cc b/src/alloy/frontend/ppc/ppc_context.cc index ad94c95f2..f7a05715e 100644 --- a/src/alloy/frontend/ppc/ppc_context.cc +++ b/src/alloy/frontend/ppc/ppc_context.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/frontend/ppc/ppc_context.h" #include diff --git a/src/alloy/frontend/ppc/ppc_context.h b/src/alloy/frontend/ppc/ppc_context.h index 7fa490c96..a5c5f3719 100644 --- a/src/alloy/frontend/ppc/ppc_context.h +++ b/src/alloy/frontend/ppc/ppc_context.h @@ -10,8 +10,8 @@ #ifndef ALLOY_FRONTEND_PPC_PPC_CONTEXT_H_ #define ALLOY_FRONTEND_PPC_PPC_CONTEXT_H_ -#include -#include +#include "alloy/vec128.h" +#include "poly/poly.h" namespace alloy { namespace runtime { class Runtime; diff --git a/src/alloy/frontend/ppc/ppc_disasm.cc b/src/alloy/frontend/ppc/ppc_disasm.cc index 54746b335..3ba0fce8d 100644 --- a/src/alloy/frontend/ppc/ppc_disasm.cc +++ b/src/alloy/frontend/ppc/ppc_disasm.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "alloy/frontend/ppc/ppc_disasm.h" -#include -#include +#include "poly/poly.h" +#include "alloy/string_buffer.h" namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_disasm.h b/src/alloy/frontend/ppc/ppc_disasm.h index fe6c26be6..89e232349 100644 --- a/src/alloy/frontend/ppc/ppc_disasm.h +++ b/src/alloy/frontend/ppc/ppc_disasm.h @@ -10,7 +10,7 @@ #ifndef ALLOY_FRONTEND_PPC_PPC_DISASM_H_ #define ALLOY_FRONTEND_PPC_PPC_DISASM_H_ -#include +#include "alloy/frontend/ppc/ppc_instr.h" namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_emit-private.h b/src/alloy/frontend/ppc/ppc_emit-private.h index 3acb10ffe..a0f7dcee5 100644 --- a/src/alloy/frontend/ppc/ppc_emit-private.h +++ b/src/alloy/frontend/ppc/ppc_emit-private.h @@ -10,8 +10,8 @@ #ifndef ALLOY_FRONTEND_PPC_PPC_EMIT_PRIVATE_H_ #define ALLOY_FRONTEND_PPC_PPC_EMIT_PRIVATE_H_ -#include -#include +#include "alloy/frontend/ppc/ppc_emit.h" +#include "alloy/frontend/ppc/ppc_instr.h" namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_emit.h b/src/alloy/frontend/ppc/ppc_emit.h index 4edc4e021..18aa6959f 100644 --- a/src/alloy/frontend/ppc/ppc_emit.h +++ b/src/alloy/frontend/ppc/ppc_emit.h @@ -10,7 +10,7 @@ #ifndef ALLOY_FRONTEND_PPC_PPC_EMIT_H_ #define ALLOY_FRONTEND_PPC_PPC_EMIT_H_ -#include +#include "alloy/frontend/ppc/ppc_instr.h" namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_emit_altivec.cc b/src/alloy/frontend/ppc/ppc_emit_altivec.cc index 381634af0..a581a4c40 100644 --- a/src/alloy/frontend/ppc/ppc_emit_altivec.cc +++ b/src/alloy/frontend/ppc/ppc_emit_altivec.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "alloy/frontend/ppc/ppc_emit-private.h" -#include -#include +#include "alloy/frontend/ppc/ppc_context.h" +#include "alloy/frontend/ppc/ppc_hir_builder.h" namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_emit_alu.cc b/src/alloy/frontend/ppc/ppc_emit_alu.cc index fb37b2e69..3a3e95472 100644 --- a/src/alloy/frontend/ppc/ppc_emit_alu.cc +++ b/src/alloy/frontend/ppc/ppc_emit_alu.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "alloy/frontend/ppc/ppc_emit-private.h" -#include -#include +#include "alloy/frontend/ppc/ppc_context.h" +#include "alloy/frontend/ppc/ppc_hir_builder.h" namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_emit_control.cc b/src/alloy/frontend/ppc/ppc_emit_control.cc index 49f1a62ff..8e00b3d24 100644 --- a/src/alloy/frontend/ppc/ppc_emit_control.cc +++ b/src/alloy/frontend/ppc/ppc_emit_control.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "alloy/frontend/ppc/ppc_emit-private.h" -#include -#include +#include "alloy/frontend/ppc/ppc_context.h" +#include "alloy/frontend/ppc/ppc_hir_builder.h" namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_emit_fpu.cc b/src/alloy/frontend/ppc/ppc_emit_fpu.cc index 750054347..cc3eeeb28 100644 --- a/src/alloy/frontend/ppc/ppc_emit_fpu.cc +++ b/src/alloy/frontend/ppc/ppc_emit_fpu.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "alloy/frontend/ppc/ppc_emit-private.h" -#include -#include +#include "alloy/frontend/ppc/ppc_context.h" +#include "alloy/frontend/ppc/ppc_hir_builder.h" namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_emit_memory.cc b/src/alloy/frontend/ppc/ppc_emit_memory.cc index f0f63ac52..c95c133e7 100644 --- a/src/alloy/frontend/ppc/ppc_emit_memory.cc +++ b/src/alloy/frontend/ppc/ppc_emit_memory.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "alloy/frontend/ppc/ppc_emit-private.h" -#include -#include +#include "alloy/frontend/ppc/ppc_context.h" +#include "alloy/frontend/ppc/ppc_hir_builder.h" namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_frontend.cc b/src/alloy/frontend/ppc/ppc_frontend.cc index bc959a0d6..44dd08101 100644 --- a/src/alloy/frontend/ppc/ppc_frontend.cc +++ b/src/alloy/frontend/ppc/ppc_frontend.cc @@ -7,13 +7,13 @@ ****************************************************************************** */ -#include +#include "alloy/frontend/ppc/ppc_frontend.h" -#include -#include -#include -#include -#include +#include "alloy/frontend/ppc/ppc_context.h" +#include "alloy/frontend/ppc/ppc_disasm.h" +#include "alloy/frontend/ppc/ppc_emit.h" +#include "alloy/frontend/ppc/ppc_translator.h" +#include "alloy/runtime/runtime.h" namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_frontend.h b/src/alloy/frontend/ppc/ppc_frontend.h index 425e0318d..cec21f286 100644 --- a/src/alloy/frontend/ppc/ppc_frontend.h +++ b/src/alloy/frontend/ppc/ppc_frontend.h @@ -12,8 +12,8 @@ #include -#include -#include +#include "alloy/frontend/frontend.h" +#include "alloy/type_pool.h" namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index 06294a54c..a1abfb415 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -7,16 +7,16 @@ ****************************************************************************** */ -#include +#include "alloy/frontend/ppc/ppc_hir_builder.h" -#include -#include -#include -#include -#include -#include -#include -#include +#include "alloy/alloy-private.h" +#include "alloy/frontend/ppc/ppc_context.h" +#include "alloy/frontend/ppc/ppc_disasm.h" +#include "alloy/frontend/ppc/ppc_frontend.h" +#include "alloy/frontend/ppc/ppc_instr.h" +#include "alloy/hir/label.h" +#include "alloy/runtime/runtime.h" +#include "xenia/profiling.h" namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.h b/src/alloy/frontend/ppc/ppc_hir_builder.h index 55a3bd9ca..5fb172d96 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.h +++ b/src/alloy/frontend/ppc/ppc_hir_builder.h @@ -10,10 +10,10 @@ #ifndef ALLOY_FRONTEND_PPC_PPC_HIR_BUILDER_H_ #define ALLOY_FRONTEND_PPC_PPC_HIR_BUILDER_H_ -#include -#include -#include -#include +#include "alloy/hir/hir_builder.h" +#include "alloy/runtime/function.h" +#include "alloy/runtime/symbol_info.h" +#include "alloy/string_buffer.h" namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_instr.cc b/src/alloy/frontend/ppc/ppc_instr.cc index 04da51c9a..5551d9cd0 100644 --- a/src/alloy/frontend/ppc/ppc_instr.cc +++ b/src/alloy/frontend/ppc/ppc_instr.cc @@ -7,14 +7,14 @@ ****************************************************************************** */ -#include +#include "alloy/frontend/ppc/ppc_instr.h" #include #include -#include -#include -#include +#include "alloy/frontend/ppc/ppc_instr_tables.h" +#include "alloy/string_buffer.h" +#include "poly/poly.h" namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_instr_tables.h b/src/alloy/frontend/ppc/ppc_instr_tables.h index dec760993..26fa9815b 100644 --- a/src/alloy/frontend/ppc/ppc_instr_tables.h +++ b/src/alloy/frontend/ppc/ppc_instr_tables.h @@ -12,8 +12,8 @@ #include -#include -#include +#include "alloy/frontend/ppc/ppc_instr.h" +#include "poly/poly.h" namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_scanner.cc b/src/alloy/frontend/ppc/ppc_scanner.cc index 2ff120ea7..c45521c3d 100644 --- a/src/alloy/frontend/ppc/ppc_scanner.cc +++ b/src/alloy/frontend/ppc/ppc_scanner.cc @@ -7,17 +7,17 @@ ****************************************************************************** */ -#include +#include "alloy/frontend/ppc/ppc_scanner.h" #include #include -#include -#include -#include -#include -#include -#include +#include "alloy/frontend/ppc/ppc_frontend.h" +#include "alloy/frontend/ppc/ppc_instr.h" +#include "alloy/runtime/runtime.h" +#include "poly/logging.h" +#include "poly/memory.h" +#include "xenia/profiling.h" #if 0 #define LOGPPC(fmt, ...) PLOGCORE('p', fmt, ##__VA_ARGS__) diff --git a/src/alloy/frontend/ppc/ppc_scanner.h b/src/alloy/frontend/ppc/ppc_scanner.h index 1eddcfd35..556c4df96 100644 --- a/src/alloy/frontend/ppc/ppc_scanner.h +++ b/src/alloy/frontend/ppc/ppc_scanner.h @@ -12,7 +12,7 @@ #include -#include +#include "alloy/runtime/symbol_info.h" namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_translator.cc b/src/alloy/frontend/ppc/ppc_translator.cc index 1b21c386d..8b3fc152f 100644 --- a/src/alloy/frontend/ppc/ppc_translator.cc +++ b/src/alloy/frontend/ppc/ppc_translator.cc @@ -7,18 +7,18 @@ ****************************************************************************** */ -#include +#include "alloy/frontend/ppc/ppc_translator.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "alloy/alloy-private.h" +#include "alloy/compiler/compiler_passes.h" +#include "alloy/frontend/ppc/ppc_disasm.h" +#include "alloy/frontend/ppc/ppc_frontend.h" +#include "alloy/frontend/ppc/ppc_hir_builder.h" +#include "alloy/frontend/ppc/ppc_instr.h" +#include "alloy/frontend/ppc/ppc_scanner.h" +#include "alloy/reset_scope.h" +#include "alloy/runtime/runtime.h" +#include "xenia/profiling.h" namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/ppc_translator.h b/src/alloy/frontend/ppc/ppc_translator.h index a24ddbb46..d18dbb1a6 100644 --- a/src/alloy/frontend/ppc/ppc_translator.h +++ b/src/alloy/frontend/ppc/ppc_translator.h @@ -12,10 +12,10 @@ #include -#include -#include -#include -#include +#include "alloy/backend/assembler.h" +#include "alloy/compiler/compiler.h" +#include "alloy/runtime/symbol_info.h" +#include "alloy/string_buffer.h" namespace alloy { namespace frontend { diff --git a/src/alloy/frontend/ppc/test/alloy-ppc-test.cc b/src/alloy/frontend/ppc/test/alloy-ppc-test.cc index 9190eaccd..21a191674 100644 --- a/src/alloy/frontend/ppc/test/alloy-ppc-test.cc +++ b/src/alloy/frontend/ppc/test/alloy-ppc-test.cc @@ -7,13 +7,13 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include -#include -#include +#include "alloy/alloy.h" +#include "alloy/backend/x64/x64_backend.h" +#include "alloy/frontend/ppc/ppc_context.h" +#include "alloy/frontend/ppc/ppc_frontend.h" +#include "alloy/runtime/raw_module.h" +#include "poly/main.h" +#include "poly/poly.h" #if !XE_LIKE_WIN32 #include diff --git a/src/alloy/hir/block.cc b/src/alloy/hir/block.cc index 0327c3163..41d9b5078 100644 --- a/src/alloy/hir/block.cc +++ b/src/alloy/hir/block.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "alloy/hir/block.h" -#include +#include "alloy/hir/instr.h" namespace alloy { namespace hir { diff --git a/src/alloy/hir/block.h b/src/alloy/hir/block.h index 70f11cac2..668b5e7f7 100644 --- a/src/alloy/hir/block.h +++ b/src/alloy/hir/block.h @@ -10,7 +10,7 @@ #ifndef ALLOY_HIR_BLOCK_H_ #define ALLOY_HIR_BLOCK_H_ -#include +#include "alloy/arena.h" namespace llvm { class BitVector; diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index c981d6915..06ddda5b4 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -7,14 +7,14 @@ ****************************************************************************** */ -#include +#include "alloy/hir/hir_builder.h" -#include -#include -#include -#include -#include -#include +#include "alloy/hir/block.h" +#include "alloy/hir/instr.h" +#include "alloy/hir/label.h" +#include "alloy/runtime/symbol_info.h" +#include "alloy/string_buffer.h" +#include "xenia/profiling.h" namespace alloy { namespace hir { diff --git a/src/alloy/hir/hir_builder.h b/src/alloy/hir/hir_builder.h index 71cc4ea6d..96862fc37 100644 --- a/src/alloy/hir/hir_builder.h +++ b/src/alloy/hir/hir_builder.h @@ -12,11 +12,11 @@ #include -#include -#include -#include -#include -#include +#include "alloy/hir/block.h" +#include "alloy/hir/instr.h" +#include "alloy/hir/label.h" +#include "alloy/hir/opcodes.h" +#include "alloy/hir/value.h" namespace alloy { class StringBuffer; diff --git a/src/alloy/hir/instr.cc b/src/alloy/hir/instr.cc index 20271c016..fccd93479 100644 --- a/src/alloy/hir/instr.cc +++ b/src/alloy/hir/instr.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "alloy/hir/instr.h" -#include +#include "alloy/hir/block.h" namespace alloy { namespace hir { diff --git a/src/alloy/hir/instr.h b/src/alloy/hir/instr.h index 259ef843b..df676afba 100644 --- a/src/alloy/hir/instr.h +++ b/src/alloy/hir/instr.h @@ -10,8 +10,8 @@ #ifndef ALLOY_HIR_INSTR_H_ #define ALLOY_HIR_INSTR_H_ -#include -#include +#include "alloy/hir/opcodes.h" +#include "alloy/hir/value.h" namespace alloy { namespace runtime { diff --git a/src/alloy/hir/opcodes.cc b/src/alloy/hir/opcodes.cc index df922c493..f7349887f 100644 --- a/src/alloy/hir/opcodes.cc +++ b/src/alloy/hir/opcodes.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/hir/opcodes.h" namespace alloy { namespace hir { @@ -16,7 +16,7 @@ namespace hir { const OpcodeInfo num##_info = { \ flags, sig, name, num, \ }; -#include +#include "alloy/hir/opcodes.inl" #undef DEFINE_OPCODE } // namespace hir diff --git a/src/alloy/hir/opcodes.h b/src/alloy/hir/opcodes.h index 60aaff61f..f5b9a215b 100644 --- a/src/alloy/hir/opcodes.h +++ b/src/alloy/hir/opcodes.h @@ -285,7 +285,7 @@ typedef struct { } OpcodeInfo; #define DEFINE_OPCODE(num, name, sig, flags) extern const OpcodeInfo num##_info; -#include +#include "alloy/hir/opcodes.inl" #undef DEFINE_OPCODE } // namespace hir diff --git a/src/alloy/hir/value.cc b/src/alloy/hir/value.cc index ae90900d4..b118bcf31 100644 --- a/src/alloy/hir/value.cc +++ b/src/alloy/hir/value.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/hir/value.h" #include diff --git a/src/alloy/hir/value.h b/src/alloy/hir/value.h index 0b1fc38ad..58ada49f3 100644 --- a/src/alloy/hir/value.h +++ b/src/alloy/hir/value.h @@ -10,11 +10,11 @@ #ifndef ALLOY_HIR_VALUE_H_ #define ALLOY_HIR_VALUE_H_ -#include -#include -#include -#include -#include +#include "alloy/arena.h" +#include "alloy/backend/machine_info.h" +#include "alloy/hir/opcodes.h" +#include "alloy/vec128.h" +#include "poly/poly.h" namespace alloy { namespace hir { diff --git a/src/alloy/memory.cc b/src/alloy/memory.cc index 36d1ac05f..c5680443b 100644 --- a/src/alloy/memory.cc +++ b/src/alloy/memory.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "alloy/memory.h" -#include +#include "poly/poly.h" namespace alloy { diff --git a/src/alloy/runtime/debug_info.cc b/src/alloy/runtime/debug_info.cc index 6a34e4238..5cb9bf0a6 100644 --- a/src/alloy/runtime/debug_info.cc +++ b/src/alloy/runtime/debug_info.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/runtime/debug_info.h" #include diff --git a/src/alloy/runtime/debugger.cc b/src/alloy/runtime/debugger.cc index a5c129fc8..2ef43f231 100644 --- a/src/alloy/runtime/debugger.cc +++ b/src/alloy/runtime/debugger.cc @@ -7,11 +7,11 @@ ****************************************************************************** */ -#include +#include "alloy/runtime/debugger.h" #include -#include +#include "alloy/runtime/runtime.h" namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/debugger.h b/src/alloy/runtime/debugger.h index 6100ae7e1..a10eaddf0 100644 --- a/src/alloy/runtime/debugger.h +++ b/src/alloy/runtime/debugger.h @@ -15,7 +15,7 @@ #include #include -#include +#include "poly/delegate.h" namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/entry_table.cc b/src/alloy/runtime/entry_table.cc index b309bbc15..96c97132d 100644 --- a/src/alloy/runtime/entry_table.cc +++ b/src/alloy/runtime/entry_table.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "alloy/runtime/entry_table.h" -#include -#include +#include "poly/poly.h" +#include "xenia/profiling.h" namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/function.cc b/src/alloy/runtime/function.cc index 7f863ed29..2fee66490 100644 --- a/src/alloy/runtime/function.cc +++ b/src/alloy/runtime/function.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include +#include "alloy/runtime/function.h" -#include -#include -#include -#include +#include "alloy/runtime/debugger.h" +#include "alloy/runtime/symbol_info.h" +#include "alloy/runtime/thread_state.h" +#include "xdb/protocol.h" namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/function.h b/src/alloy/runtime/function.h index c244813a9..6400cc4aa 100644 --- a/src/alloy/runtime/function.h +++ b/src/alloy/runtime/function.h @@ -14,7 +14,7 @@ #include #include -#include +#include "alloy/runtime/debug_info.h" namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/instrument.cc b/src/alloy/runtime/instrument.cc index 8cb099fe6..939348997 100644 --- a/src/alloy/runtime/instrument.cc +++ b/src/alloy/runtime/instrument.cc @@ -7,11 +7,11 @@ ****************************************************************************** */ -#include +#include "alloy/runtime/instrument.h" -#include -#include -#include +#include "alloy/memory.h" +#include "alloy/runtime/function.h" +#include "alloy/runtime/runtime.h" namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/module.cc b/src/alloy/runtime/module.cc index 7278b9c1b..3d9dbd0b6 100644 --- a/src/alloy/runtime/module.cc +++ b/src/alloy/runtime/module.cc @@ -7,14 +7,14 @@ ****************************************************************************** */ -#include +#include "alloy/runtime/module.h" #include #include -#include -#include -#include +#include "alloy/runtime/runtime.h" +#include "poly/poly.h" +#include "xenia/profiling.h" namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/module.h b/src/alloy/runtime/module.h index 6bd50b6f0..671743bdf 100644 --- a/src/alloy/runtime/module.h +++ b/src/alloy/runtime/module.h @@ -16,8 +16,8 @@ #include #include -#include -#include +#include "alloy/memory.h" +#include "alloy/runtime/symbol_info.h" namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/raw_module.cc b/src/alloy/runtime/raw_module.cc index 2750a724e..9eaed2ba4 100644 --- a/src/alloy/runtime/raw_module.cc +++ b/src/alloy/runtime/raw_module.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "alloy/runtime/raw_module.h" -#include -#include +#include "poly/platform.h" +#include "poly/string.h" namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/raw_module.h b/src/alloy/runtime/raw_module.h index c40359f1e..af9eb6aed 100644 --- a/src/alloy/runtime/raw_module.h +++ b/src/alloy/runtime/raw_module.h @@ -12,7 +12,7 @@ #include -#include +#include "alloy/runtime/module.h" namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/runtime.cc b/src/alloy/runtime/runtime.cc index 5da4970da..f3e3ba7c1 100644 --- a/src/alloy/runtime/runtime.cc +++ b/src/alloy/runtime/runtime.cc @@ -7,17 +7,17 @@ ****************************************************************************** */ -#include +#include "alloy/runtime/runtime.h" #include -#include -#include -#include -#include +#include "alloy/runtime/module.h" +#include "poly/poly.h" +#include "xdb/protocol.h" +#include "xenia/profiling.h" // TODO(benvanik): based on compiler support -#include +#include "alloy/backend/x64/x64_backend.h" DEFINE_string(runtime_backend, "any", "Runtime backend [any, x64]."); diff --git a/src/alloy/runtime/runtime.h b/src/alloy/runtime/runtime.h index 0d0e6312b..cc572ac70 100644 --- a/src/alloy/runtime/runtime.h +++ b/src/alloy/runtime/runtime.h @@ -14,14 +14,14 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include "alloy/backend/backend.h" +#include "alloy/frontend/frontend.h" +#include "alloy/memory.h" +#include "alloy/runtime/debugger.h" +#include "alloy/runtime/entry_table.h" +#include "alloy/runtime/module.h" +#include "alloy/runtime/symbol_info.h" +#include "alloy/runtime/thread_state.h" namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/symbol_info.cc b/src/alloy/runtime/symbol_info.cc index b525bf841..968534f4b 100644 --- a/src/alloy/runtime/symbol_info.cc +++ b/src/alloy/runtime/symbol_info.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/runtime/symbol_info.h" namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/test_module.cc b/src/alloy/runtime/test_module.cc index 8ed766217..ce204ff65 100644 --- a/src/alloy/runtime/test_module.cc +++ b/src/alloy/runtime/test_module.cc @@ -7,13 +7,13 @@ ****************************************************************************** */ -#include +#include "alloy/runtime/test_module.h" -#include -#include -#include -#include -#include +#include "alloy/compiler/compiler_passes.h" +#include "alloy/reset_scope.h" +#include "alloy/runtime/runtime.h" +#include "poly/platform.h" +#include "poly/string.h" namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/test_module.h b/src/alloy/runtime/test_module.h index 822509e40..fc78bd2c0 100644 --- a/src/alloy/runtime/test_module.h +++ b/src/alloy/runtime/test_module.h @@ -14,10 +14,10 @@ #include #include -#include -#include -#include -#include +#include "alloy/backend/assembler.h" +#include "alloy/compiler/compiler.h" +#include "alloy/hir/hir_builder.h" +#include "alloy/runtime/module.h" namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/thread_state.cc b/src/alloy/runtime/thread_state.cc index 80b5ad71a..2c8e28a45 100644 --- a/src/alloy/runtime/thread_state.cc +++ b/src/alloy/runtime/thread_state.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "alloy/runtime/thread_state.h" -#include -#include +#include "alloy/runtime/runtime.h" +#include "poly/poly.h" namespace alloy { namespace runtime { diff --git a/src/alloy/runtime/thread_state.h b/src/alloy/runtime/thread_state.h index 012f0bf6f..9e91ff5d7 100644 --- a/src/alloy/runtime/thread_state.h +++ b/src/alloy/runtime/thread_state.h @@ -12,7 +12,7 @@ #include -#include +#include "alloy/memory.h" namespace alloy { namespace runtime { diff --git a/src/alloy/string_buffer.cc b/src/alloy/string_buffer.cc index 912690fdc..bd2f9d35b 100644 --- a/src/alloy/string_buffer.cc +++ b/src/alloy/string_buffer.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/string_buffer.h" #include #include diff --git a/src/alloy/test/alloy-test.cc b/src/alloy/test/alloy-test.cc index 24e88e428..6c493ce05 100644 --- a/src/alloy/test/alloy-test.cc +++ b/src/alloy/test/alloy-test.cc @@ -8,9 +8,9 @@ */ #define CATCH_CONFIG_RUNNER -#include +#include "third_party/catch/single_include/catch.hpp" -#include +#include "alloy/test/util.h" namespace alloy { namespace test { diff --git a/src/alloy/test/test_add.cc b/src/alloy/test/test_add.cc index 480874011..21c5649b1 100644 --- a/src/alloy/test/test_add.cc +++ b/src/alloy/test/test_add.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/test/util.h" #include diff --git a/src/alloy/test/test_byte_swap.cc b/src/alloy/test/test_byte_swap.cc index 03131d031..74154275b 100644 --- a/src/alloy/test/test_byte_swap.cc +++ b/src/alloy/test/test_byte_swap.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/test/util.h" using namespace alloy; using namespace alloy::hir; diff --git a/src/alloy/test/test_extract.cc b/src/alloy/test/test_extract.cc index 6090b1744..3dacd2e89 100644 --- a/src/alloy/test/test_extract.cc +++ b/src/alloy/test/test_extract.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/test/util.h" #include diff --git a/src/alloy/test/test_insert.cc b/src/alloy/test/test_insert.cc index 5bd9a756b..811a6b93a 100644 --- a/src/alloy/test/test_insert.cc +++ b/src/alloy/test/test_insert.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/test/util.h" #include diff --git a/src/alloy/test/test_load_vector_shl_shr.cc b/src/alloy/test/test_load_vector_shl_shr.cc index 508dff9d0..9d6d790db 100644 --- a/src/alloy/test/test_load_vector_shl_shr.cc +++ b/src/alloy/test/test_load_vector_shl_shr.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/test/util.h" using namespace alloy; using namespace alloy::hir; diff --git a/src/alloy/test/test_pack.cc b/src/alloy/test/test_pack.cc index 4dc82f509..c6547b557 100644 --- a/src/alloy/test/test_pack.cc +++ b/src/alloy/test/test_pack.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/test/util.h" using namespace alloy; using namespace alloy::hir; diff --git a/src/alloy/test/test_permute.cc b/src/alloy/test/test_permute.cc index 8b2f7b6a8..58192331d 100644 --- a/src/alloy/test/test_permute.cc +++ b/src/alloy/test/test_permute.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/test/util.h" using namespace alloy; using namespace alloy::hir; diff --git a/src/alloy/test/test_sha.cc b/src/alloy/test/test_sha.cc index 65f4d8553..9ed155afd 100644 --- a/src/alloy/test/test_sha.cc +++ b/src/alloy/test/test_sha.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/test/util.h" using namespace alloy; using namespace alloy::hir; diff --git a/src/alloy/test/test_shl.cc b/src/alloy/test/test_shl.cc index 7d22b8af1..31dc1d772 100644 --- a/src/alloy/test/test_shl.cc +++ b/src/alloy/test/test_shl.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/test/util.h" using namespace alloy; using namespace alloy::hir; diff --git a/src/alloy/test/test_shr.cc b/src/alloy/test/test_shr.cc index d79237000..81bd55afc 100644 --- a/src/alloy/test/test_shr.cc +++ b/src/alloy/test/test_shr.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/test/util.h" using namespace alloy; using namespace alloy::hir; diff --git a/src/alloy/test/test_swizzle.cc b/src/alloy/test/test_swizzle.cc index 04d9e4ec9..be6874701 100644 --- a/src/alloy/test/test_swizzle.cc +++ b/src/alloy/test/test_swizzle.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/test/util.h" using namespace alloy; using namespace alloy::hir; diff --git a/src/alloy/test/test_unpack.cc b/src/alloy/test/test_unpack.cc index f419419b1..14557124c 100644 --- a/src/alloy/test/test_unpack.cc +++ b/src/alloy/test/test_unpack.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/test/util.h" using namespace alloy; using namespace alloy::hir; diff --git a/src/alloy/test/test_vector_add.cc b/src/alloy/test/test_vector_add.cc index 526e3e0a5..b23cc7ac1 100644 --- a/src/alloy/test/test_vector_add.cc +++ b/src/alloy/test/test_vector_add.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/test/util.h" #include diff --git a/src/alloy/test/test_vector_max.cc b/src/alloy/test/test_vector_max.cc index ebf858cc7..0d7ddfd71 100644 --- a/src/alloy/test/test_vector_max.cc +++ b/src/alloy/test/test_vector_max.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/test/util.h" #include diff --git a/src/alloy/test/test_vector_min.cc b/src/alloy/test/test_vector_min.cc index dfa08f8db..6f981badf 100644 --- a/src/alloy/test/test_vector_min.cc +++ b/src/alloy/test/test_vector_min.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/test/util.h" #include diff --git a/src/alloy/test/test_vector_rotate_left.cc b/src/alloy/test/test_vector_rotate_left.cc index 1c8e19d5e..9d46ad7b9 100644 --- a/src/alloy/test/test_vector_rotate_left.cc +++ b/src/alloy/test/test_vector_rotate_left.cc @@ -7,8 +7,8 @@ ****************************************************************************** */ -#include -#include +#include "third_party/xbyak/xbyak/xbyak_bin2hex.h" +#include "alloy/test/util.h" using namespace alloy; using namespace alloy::hir; diff --git a/src/alloy/test/test_vector_sha.cc b/src/alloy/test/test_vector_sha.cc index ebd2f535b..38a2accb6 100644 --- a/src/alloy/test/test_vector_sha.cc +++ b/src/alloy/test/test_vector_sha.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/test/util.h" using namespace alloy; using namespace alloy::hir; diff --git a/src/alloy/test/test_vector_shl.cc b/src/alloy/test/test_vector_shl.cc index 45313427a..cda54e5b7 100644 --- a/src/alloy/test/test_vector_shl.cc +++ b/src/alloy/test/test_vector_shl.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/test/util.h" using namespace alloy; using namespace alloy::hir; diff --git a/src/alloy/test/test_vector_shr.cc b/src/alloy/test/test_vector_shr.cc index d749197ef..1a73b9ec8 100644 --- a/src/alloy/test/test_vector_shr.cc +++ b/src/alloy/test/test_vector_shr.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "alloy/test/util.h" using namespace alloy; using namespace alloy::hir; diff --git a/src/alloy/test/util.h b/src/alloy/test/util.h index a38692f0f..46267e498 100644 --- a/src/alloy/test/util.h +++ b/src/alloy/test/util.h @@ -10,16 +10,16 @@ #ifndef ALLOY_TEST_UTIL_H_ #define ALLOY_TEST_UTIL_H_ -#include -#include -#include -#include -#include -#include -#include -#include +#include "alloy/alloy.h" +#include "alloy/backend/x64/x64_backend.h" +#include "alloy/frontend/ppc/ppc_context.h" +#include "alloy/frontend/ppc/ppc_frontend.h" +#include "alloy/hir/hir_builder.h" +#include "alloy/runtime/test_module.h" +#include "poly/main.h" +#include "poly/poly.h" -#include +#include "third_party/catch/single_include/catch.hpp" #define ALLOY_TEST_X64 1 diff --git a/src/alloy/vec128.h b/src/alloy/vec128.h index f756f805e..391178550 100644 --- a/src/alloy/vec128.h +++ b/src/alloy/vec128.h @@ -10,7 +10,7 @@ #ifndef ALLOY_VEC128_H_ #define ALLOY_VEC128_H_ -#include +#include "poly/poly.h" namespace alloy { diff --git a/src/poly/assert.h b/src/poly/assert.h index 596dc2363..1063e84e5 100644 --- a/src/poly/assert.h +++ b/src/poly/assert.h @@ -12,8 +12,8 @@ #include -#include -#include +#include "poly/config.h" +#include "poly/platform.h" namespace poly { diff --git a/src/poly/atomic.h b/src/poly/atomic.h index 6c11a4172..ee6e19a50 100644 --- a/src/poly/atomic.h +++ b/src/poly/atomic.h @@ -12,8 +12,8 @@ #include -#include -#include +#include "poly/config.h" +#include "poly/platform.h" #if XE_LIKE_OSX #include diff --git a/src/poly/byte_order.h b/src/poly/byte_order.h index 8cb478a92..44eb13e9c 100644 --- a/src/poly/byte_order.h +++ b/src/poly/byte_order.h @@ -12,8 +12,8 @@ #include -#include -#include +#include "poly/config.h" +#include "poly/platform.h" #if XE_LIKE_OSX #include diff --git a/src/poly/cxx_compat.h b/src/poly/cxx_compat.h index 632be698e..74551bbe3 100644 --- a/src/poly/cxx_compat.h +++ b/src/poly/cxx_compat.h @@ -12,7 +12,7 @@ #include -#include +#include "poly/config.h" // C++11 thread local storage. // http://en.cppreference.com/w/cpp/language/storage_duration diff --git a/src/poly/debugging.h b/src/poly/debugging.h index a9c60ff25..543c38f56 100644 --- a/src/poly/debugging.h +++ b/src/poly/debugging.h @@ -12,7 +12,7 @@ #include -#include +#include "poly/config.h" namespace poly { namespace debugging { diff --git a/src/poly/debugging_win.cc b/src/poly/debugging_win.cc index 05916f700..e7218fe91 100644 --- a/src/poly/debugging_win.cc +++ b/src/poly/debugging_win.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "poly/debugging.h" #include diff --git a/src/poly/logging.cc b/src/poly/logging.cc index 903537376..1df990281 100644 --- a/src/poly/logging.cc +++ b/src/poly/logging.cc @@ -7,14 +7,14 @@ ****************************************************************************** */ -#include +#include "poly/logging.h" #include #include -#include -#include -#include +#include "poly/cxx_compat.h" +#include "poly/main.h" +#include "poly/math.h" DEFINE_bool(fast_stdout, false, "Don't lock around stdout/stderr. May introduce weirdness."); diff --git a/src/poly/logging.h b/src/poly/logging.h index 6ac8e0b75..49f13d434 100644 --- a/src/poly/logging.h +++ b/src/poly/logging.h @@ -12,7 +12,7 @@ #include -#include +#include "poly/string.h" namespace poly { diff --git a/src/poly/main.h b/src/poly/main.h index 82c02576d..497c21bae 100644 --- a/src/poly/main.h +++ b/src/poly/main.h @@ -13,7 +13,7 @@ #include #include -#include +#include "poly/platform.h" namespace poly { diff --git a/src/poly/main_win.cc b/src/poly/main_win.cc index 122fa5327..0b95a0350 100644 --- a/src/poly/main_win.cc +++ b/src/poly/main_win.cc @@ -7,14 +7,14 @@ ****************************************************************************** */ -#include +#include "poly/main.h" #include #include #include #include -#include +#include "poly/string.h" namespace poly { diff --git a/src/poly/mapped_memory_win.cc b/src/poly/mapped_memory_win.cc index e40f2144d..98162567c 100644 --- a/src/poly/mapped_memory_win.cc +++ b/src/poly/mapped_memory_win.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "poly/mapped_memory.h" #include diff --git a/src/poly/math.cc b/src/poly/math.cc index af7c661f7..6ed8c7329 100644 --- a/src/poly/math.cc +++ b/src/poly/math.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "poly/math.h" namespace poly { diff --git a/src/poly/math.h b/src/poly/math.h index 49edd2dc0..369bc9b05 100644 --- a/src/poly/math.h +++ b/src/poly/math.h @@ -17,8 +17,8 @@ #include #include -#include -#include +#include "poly/config.h" +#include "poly/platform.h" namespace poly { diff --git a/src/poly/memory.cc b/src/poly/memory.cc index 0f6e47f1c..585e38a82 100644 --- a/src/poly/memory.cc +++ b/src/poly/memory.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "poly/memory.h" #include diff --git a/src/poly/memory.h b/src/poly/memory.h index c4e5b4b90..8214b6c5c 100644 --- a/src/poly/memory.h +++ b/src/poly/memory.h @@ -13,8 +13,8 @@ #include #include -#include -#include +#include "poly/assert.h" +#include "poly/byte_order.h" namespace poly { diff --git a/src/poly/poly.h b/src/poly/poly.h index db4a1796c..c379d6697 100644 --- a/src/poly/poly.h +++ b/src/poly/poly.h @@ -10,19 +10,19 @@ #ifndef POLY_POLY_H_ #define POLY_POLY_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "poly/assert.h" +#include "poly/atomic.h" +#include "poly/byte_order.h" +#include "poly/config.h" +#include "poly/cxx_compat.h" +#include "poly/debugging.h" +#include "poly/logging.h" +#include "poly/mapped_memory.h" +#include "poly/math.h" +#include "poly/memory.h" +#include "poly/platform.h" +#include "poly/string.h" +#include "poly/threading.h" namespace poly {} // namespace poly diff --git a/src/poly/string.cc b/src/poly/string.cc index f2a822ce0..e3100f872 100644 --- a/src/poly/string.cc +++ b/src/poly/string.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "poly/string.h" #include #include diff --git a/src/poly/string.h b/src/poly/string.h index 0787ba935..8db5f9297 100644 --- a/src/poly/string.h +++ b/src/poly/string.h @@ -14,7 +14,7 @@ #include #include -#include +#include "poly/platform.h" #if XE_LIKE_WIN32 #define strcasecmp _stricmp diff --git a/src/poly/threading.cc b/src/poly/threading.cc index f879097d3..5550647d2 100644 --- a/src/poly/threading.cc +++ b/src/poly/threading.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "poly/threading.h" namespace poly { namespace threading { diff --git a/src/poly/threading.h b/src/poly/threading.h index a82eb6138..2d103c07a 100644 --- a/src/poly/threading.h +++ b/src/poly/threading.h @@ -18,7 +18,7 @@ #include #include -#include +#include "poly/config.h" namespace poly { namespace threading { diff --git a/src/poly/threading_win.cc b/src/poly/threading_win.cc index 949f68749..8af078aff 100644 --- a/src/poly/threading_win.cc +++ b/src/poly/threading_win.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "poly/threading.h" -#include +#include "poly/platform.h" namespace poly { namespace threading { diff --git a/src/poly/ui/control.cc b/src/poly/ui/control.cc index 0d2fca91b..e7a55901b 100644 --- a/src/poly/ui/control.cc +++ b/src/poly/ui/control.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "poly/ui/control.h" -#include +#include "poly/assert.h" namespace poly { namespace ui { diff --git a/src/poly/ui/control.h b/src/poly/ui/control.h index d96cf4629..0abc72ab2 100644 --- a/src/poly/ui/control.h +++ b/src/poly/ui/control.h @@ -13,8 +13,8 @@ #include #include -#include -#include +#include "poly/delegate.h" +#include "poly/ui/ui_event.h" namespace poly { namespace ui { diff --git a/src/poly/ui/menu_item.cc b/src/poly/ui/menu_item.cc index c75ab80ad..623251f98 100644 --- a/src/poly/ui/menu_item.cc +++ b/src/poly/ui/menu_item.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "poly/ui/menu_item.h" namespace poly { namespace ui { diff --git a/src/poly/ui/menu_item.h b/src/poly/ui/menu_item.h index cdd285b55..1da156e42 100644 --- a/src/poly/ui/menu_item.h +++ b/src/poly/ui/menu_item.h @@ -13,8 +13,8 @@ #include #include -#include -#include +#include "poly/delegate.h" +#include "poly/ui/ui_event.h" namespace poly { namespace ui { diff --git a/src/poly/ui/win32/win32_control.cc b/src/poly/ui/win32/win32_control.cc index d26716a2d..5d02a9d97 100644 --- a/src/poly/ui/win32/win32_control.cc +++ b/src/poly/ui/win32/win32_control.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "poly/ui/win32/win32_control.h" namespace poly { namespace ui { diff --git a/src/poly/ui/win32/win32_control.h b/src/poly/ui/win32/win32_control.h index baef5ae4f..f46de9afe 100644 --- a/src/poly/ui/win32/win32_control.h +++ b/src/poly/ui/win32/win32_control.h @@ -13,7 +13,7 @@ #include #include -#include +#include "poly/ui/control.h" namespace poly { namespace ui { diff --git a/src/poly/ui/win32/win32_loop.cc b/src/poly/ui/win32/win32_loop.cc index dad966528..ca409d5cf 100644 --- a/src/poly/ui/win32/win32_loop.cc +++ b/src/poly/ui/win32/win32_loop.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "poly/ui/win32/win32_loop.h" -#include +#include "poly/assert.h" namespace poly { namespace ui { diff --git a/src/poly/ui/win32/win32_loop.h b/src/poly/ui/win32/win32_loop.h index 629c2ee44..aa953d57e 100644 --- a/src/poly/ui/win32/win32_loop.h +++ b/src/poly/ui/win32/win32_loop.h @@ -18,8 +18,8 @@ #include #include -#include -#include +#include "poly/threading.h" +#include "poly/ui/loop.h" namespace poly { namespace ui { diff --git a/src/poly/ui/win32/win32_menu_item.cc b/src/poly/ui/win32/win32_menu_item.cc index 4824f989b..c0bc37ec0 100644 --- a/src/poly/ui/win32/win32_menu_item.cc +++ b/src/poly/ui/win32/win32_menu_item.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "poly/ui/win32/win32_menu_item.h" namespace poly { namespace ui { diff --git a/src/poly/ui/win32/win32_menu_item.h b/src/poly/ui/win32/win32_menu_item.h index 80f9a7150..b155bacce 100644 --- a/src/poly/ui/win32/win32_menu_item.h +++ b/src/poly/ui/win32/win32_menu_item.h @@ -13,7 +13,7 @@ #include #include -#include +#include "poly/ui/menu_item.h" namespace poly { namespace ui { diff --git a/src/poly/ui/win32/win32_window.cc b/src/poly/ui/win32/win32_window.cc index 62cf67371..3f3a33e82 100644 --- a/src/poly/ui/win32/win32_window.cc +++ b/src/poly/ui/win32/win32_window.cc @@ -7,13 +7,13 @@ ****************************************************************************** */ -#include +#include "poly/ui/win32/win32_window.h" #include #include #include -#include +#include "poly/logging.h" namespace poly { namespace ui { diff --git a/src/poly/ui/win32/win32_window.h b/src/poly/ui/win32/win32_window.h index 1f3b030f5..5d172afca 100644 --- a/src/poly/ui/win32/win32_window.h +++ b/src/poly/ui/win32/win32_window.h @@ -12,8 +12,8 @@ #include -#include -#include +#include "poly/ui/win32/win32_control.h" +#include "poly/ui/window.h" namespace poly { namespace ui { diff --git a/src/poly/ui/window.h b/src/poly/ui/window.h index a4e584372..62302f548 100644 --- a/src/poly/ui/window.h +++ b/src/poly/ui/window.h @@ -12,9 +12,9 @@ #include -#include -#include -#include +#include "poly/delegate.h" +#include "poly/ui/control.h" +#include "poly/ui/ui_event.h" namespace poly { namespace ui { diff --git a/src/xenia/apu/apu.cc b/src/xenia/apu/apu.cc index e7ed8c292..6a0df3a5f 100644 --- a/src/xenia/apu/apu.cc +++ b/src/xenia/apu/apu.cc @@ -7,21 +7,21 @@ ****************************************************************************** */ -#include -#include +#include "xenia/apu/apu.h" +#include "xenia/apu/apu-private.h" using namespace xe; using namespace xe::apu; DEFINE_string(apu, "any", "Audio system. Use: [any, nop, xaudio2]"); -#include +#include "xenia/apu/nop/nop_apu.h" std::unique_ptr xe::apu::CreateNop(Emulator* emulator) { return xe::apu::nop::Create(emulator); } #if XE_PLATFORM_WIN32 -#include +#include "xenia/apu/xaudio2/xaudio2_apu.h" std::unique_ptr xe::apu::CreateXAudio2(Emulator* emulator) { return xe::apu::xaudio2::Create(emulator); } diff --git a/src/xenia/apu/apu.h b/src/xenia/apu/apu.h index 2a5178a3a..c9f2931b3 100644 --- a/src/xenia/apu/apu.h +++ b/src/xenia/apu/apu.h @@ -12,7 +12,7 @@ #include -#include +#include "xenia/apu/audio_system.h" namespace xe { class Emulator; diff --git a/src/xenia/apu/audio_driver.cc b/src/xenia/apu/audio_driver.cc index e3bb88756..b896f4373 100644 --- a/src/xenia/apu/audio_driver.cc +++ b/src/xenia/apu/audio_driver.cc @@ -7,11 +7,11 @@ ****************************************************************************** */ -#include +#include "xenia/apu/audio_driver.h" -#include -#include -#include +#include "xenia/emulator.h" +#include "xenia/cpu/processor.h" +#include "xenia/cpu/xenon_thread_state.h" using namespace xe; diff --git a/src/xenia/apu/audio_driver.h b/src/xenia/apu/audio_driver.h index d100f6e8f..f2119801e 100644 --- a/src/xenia/apu/audio_driver.h +++ b/src/xenia/apu/audio_driver.h @@ -10,9 +10,9 @@ #ifndef XENIA_APU_AUDIO_DRIVER_H_ #define XENIA_APU_AUDIO_DRIVER_H_ -#include -#include -#include +#include "xenia/common.h" +#include "xenia/emulator.h" +#include "xenia/xbox.h" namespace xe { namespace apu { diff --git a/src/xenia/apu/audio_system.cc b/src/xenia/apu/audio_system.cc index f6e6c9ecf..7c646d58d 100644 --- a/src/xenia/apu/audio_system.cc +++ b/src/xenia/apu/audio_system.cc @@ -7,13 +7,13 @@ ****************************************************************************** */ -#include -#include +#include "xenia/apu/audio_system.h" +#include "xenia/apu/audio_driver.h" -#include -#include -#include -#include +#include "poly/poly.h" +#include "xenia/emulator.h" +#include "xenia/cpu/processor.h" +#include "xenia/cpu/xenon_thread_state.h" using namespace xe; using namespace xe::apu; diff --git a/src/xenia/apu/audio_system.h b/src/xenia/apu/audio_system.h index 20a24e136..3dd3c1ad2 100644 --- a/src/xenia/apu/audio_system.h +++ b/src/xenia/apu/audio_system.h @@ -15,9 +15,9 @@ #include #include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/emulator.h" +#include "xenia/xbox.h" namespace xe { namespace apu { diff --git a/src/xenia/apu/nop/nop_apu-private.h b/src/xenia/apu/nop/nop_apu-private.h index f41803693..5f3b08dfc 100644 --- a/src/xenia/apu/nop/nop_apu-private.h +++ b/src/xenia/apu/nop/nop_apu-private.h @@ -10,9 +10,9 @@ #ifndef XENIA_APU_NOP_NOP_APU_PRIVATE_H_ #define XENIA_APU_NOP_NOP_APU_PRIVATE_H_ -#include +#include "xenia/common.h" -#include +#include "xenia/apu/nop/nop_apu.h" namespace xe { diff --git a/src/xenia/apu/nop/nop_apu.cc b/src/xenia/apu/nop/nop_apu.cc index 1ab673338..74fd3ce9c 100644 --- a/src/xenia/apu/nop/nop_apu.cc +++ b/src/xenia/apu/nop/nop_apu.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "xenia/apu/nop/nop_apu.h" -#include +#include "xenia/apu/nop/nop_audio_system.h" using namespace xe; using namespace xe::apu; diff --git a/src/xenia/apu/nop/nop_apu.h b/src/xenia/apu/nop/nop_apu.h index 9159c7b60..9827551ae 100644 --- a/src/xenia/apu/nop/nop_apu.h +++ b/src/xenia/apu/nop/nop_apu.h @@ -12,7 +12,7 @@ #include -#include +#include "xenia/common.h" namespace xe { class Emulator; diff --git a/src/xenia/apu/nop/nop_audio_system.cc b/src/xenia/apu/nop/nop_audio_system.cc index d384c3de3..8901d9e96 100644 --- a/src/xenia/apu/nop/nop_audio_system.cc +++ b/src/xenia/apu/nop/nop_audio_system.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "xenia/apu/nop/nop_audio_system.h" -#include +#include "xenia/apu/apu-private.h" using namespace xe; diff --git a/src/xenia/apu/nop/nop_audio_system.h b/src/xenia/apu/nop/nop_audio_system.h index c42982572..e806ebe49 100644 --- a/src/xenia/apu/nop/nop_audio_system.h +++ b/src/xenia/apu/nop/nop_audio_system.h @@ -10,10 +10,10 @@ #ifndef XENIA_APU_NOP_NOP_AUDIO_SYSTEM_H_ #define XENIA_APU_NOP_NOP_AUDIO_SYSTEM_H_ -#include +#include "xenia/common.h" -#include -#include +#include "xenia/apu/audio_system.h" +#include "xenia/apu/nop/nop_apu-private.h" namespace xe { diff --git a/src/xenia/apu/xaudio2/xaudio2_apu-private.h b/src/xenia/apu/xaudio2/xaudio2_apu-private.h index 4c890b5e7..37190bba6 100644 --- a/src/xenia/apu/xaudio2/xaudio2_apu-private.h +++ b/src/xenia/apu/xaudio2/xaudio2_apu-private.h @@ -10,9 +10,9 @@ #ifndef XENIA_APU_XAUDIO2_XAUDIO2_APU_PRIVATE_H_ #define XENIA_APU_XAUDIO2_XAUDIO2_APU_PRIVATE_H_ -#include +#include "xenia/common.h" -#include +#include "xenia/apu/xaudio2/xaudio2_apu.h" namespace xe { diff --git a/src/xenia/apu/xaudio2/xaudio2_apu.cc b/src/xenia/apu/xaudio2/xaudio2_apu.cc index 2c02ccb5f..e3d6857e1 100644 --- a/src/xenia/apu/xaudio2/xaudio2_apu.cc +++ b/src/xenia/apu/xaudio2/xaudio2_apu.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "xenia/apu/xaudio2/xaudio2_apu.h" -#include +#include "xenia/apu/xaudio2/xaudio2_audio_system.h" using namespace xe; using namespace xe::apu; diff --git a/src/xenia/apu/xaudio2/xaudio2_apu.h b/src/xenia/apu/xaudio2/xaudio2_apu.h index 5cdd5245c..e9fbabda9 100644 --- a/src/xenia/apu/xaudio2/xaudio2_apu.h +++ b/src/xenia/apu/xaudio2/xaudio2_apu.h @@ -12,7 +12,7 @@ #include -#include +#include "xenia/common.h" namespace xe { class Emulator; diff --git a/src/xenia/apu/xaudio2/xaudio2_audio_driver.cc b/src/xenia/apu/xaudio2/xaudio2_audio_driver.cc index e3dbdd534..8515790e2 100644 --- a/src/xenia/apu/xaudio2/xaudio2_audio_driver.cc +++ b/src/xenia/apu/xaudio2/xaudio2_audio_driver.cc @@ -7,11 +7,11 @@ ****************************************************************************** */ -#include +#include "xenia/apu/xaudio2/xaudio2_audio_driver.h" -#include +#include "xenia/apu/apu-private.h" -#include +#include "xenia/emulator.h" using namespace xe; using namespace xe::apu; diff --git a/src/xenia/apu/xaudio2/xaudio2_audio_driver.h b/src/xenia/apu/xaudio2/xaudio2_audio_driver.h index 6a500f806..242e3974d 100644 --- a/src/xenia/apu/xaudio2/xaudio2_audio_driver.h +++ b/src/xenia/apu/xaudio2/xaudio2_audio_driver.h @@ -12,9 +12,9 @@ #include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/apu/audio_driver.h" +#include "xenia/apu/xaudio2/xaudio2_apu-private.h" namespace xe { namespace apu { diff --git a/src/xenia/apu/xaudio2/xaudio2_audio_system.cc b/src/xenia/apu/xaudio2/xaudio2_audio_system.cc index f87197cb4..4fee2d3b0 100644 --- a/src/xenia/apu/xaudio2/xaudio2_audio_system.cc +++ b/src/xenia/apu/xaudio2/xaudio2_audio_system.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include -#include +#include "xenia/apu/xaudio2/xaudio2_audio_system.h" +#include "xenia/apu/xaudio2/xaudio2_audio_driver.h" -#include +#include "xenia/apu/apu-private.h" -#include +#include "xenia/emulator.h" using namespace xe; using namespace xe::apu; diff --git a/src/xenia/apu/xaudio2/xaudio2_audio_system.h b/src/xenia/apu/xaudio2/xaudio2_audio_system.h index 82f01bce3..8cbc87d1f 100644 --- a/src/xenia/apu/xaudio2/xaudio2_audio_system.h +++ b/src/xenia/apu/xaudio2/xaudio2_audio_system.h @@ -12,9 +12,9 @@ #include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/apu/audio_system.h" +#include "xenia/apu/xaudio2/xaudio2_apu-private.h" namespace xe { namespace apu { diff --git a/src/xenia/common.h b/src/xenia/common.h index f20beaa90..9a19845e1 100644 --- a/src/xenia/common.h +++ b/src/xenia/common.h @@ -10,13 +10,13 @@ #ifndef XENIA_COMMON_H_ #define XENIA_COMMON_H_ -#include -#include -#include -#include -#include +#include "poly/assert.h" +#include "poly/atomic.h" +#include "poly/byte_order.h" +#include "poly/memory.h" +#include "poly/string.h" -#include -#include +#include "xenia/logging.h" +#include "xenia/profiling.h" #endif // XENIA_COMMON_H_ diff --git a/src/xenia/cpu/cpu.cc b/src/xenia/cpu/cpu.cc index 61ed9ac61..dbc6cc34b 100644 --- a/src/xenia/cpu/cpu.cc +++ b/src/xenia/cpu/cpu.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "xenia/cpu/cpu-private.h" // Debugging: DEFINE_bool(trace_function_generation, false, diff --git a/src/xenia/cpu/cpu.h b/src/xenia/cpu/cpu.h index c5253ff64..15a3d4a53 100644 --- a/src/xenia/cpu/cpu.h +++ b/src/xenia/cpu/cpu.h @@ -10,9 +10,9 @@ #ifndef XENIA_CPU_CPU_H_ #define XENIA_CPU_CPU_H_ -#include -#include -#include -#include +#include "xenia/cpu/processor.h" +#include "xenia/cpu/xenon_runtime.h" +#include "xenia/cpu/xenon_thread_state.h" +#include "xenia/cpu/xex_module.h" #endif // XENIA_CPU_CPU_H_ diff --git a/src/xenia/cpu/mmio_handler.cc b/src/xenia/cpu/mmio_handler.cc index eb6834b38..f09880030 100644 --- a/src/xenia/cpu/mmio_handler.cc +++ b/src/xenia/cpu/mmio_handler.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "xenia/cpu/mmio_handler.h" -#include +#include "poly/poly.h" namespace BE { #include diff --git a/src/xenia/cpu/mmio_handler_win.cc b/src/xenia/cpu/mmio_handler_win.cc index e645c0a64..2711ed167 100644 --- a/src/xenia/cpu/mmio_handler_win.cc +++ b/src/xenia/cpu/mmio_handler_win.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "xenia/cpu/mmio_handler.h" #include diff --git a/src/xenia/cpu/processor.cc b/src/xenia/cpu/processor.cc index a0a3c60f5..2777297d0 100644 --- a/src/xenia/cpu/processor.cc +++ b/src/xenia/cpu/processor.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include +#include "xenia/cpu/processor.h" -#include -#include -#include -#include +#include "xenia/export_resolver.h" +#include "xenia/cpu/cpu-private.h" +#include "xenia/cpu/xenon_runtime.h" +#include "xenia/cpu/xex_module.h" using namespace alloy; using namespace alloy::backend; diff --git a/src/xenia/cpu/processor.h b/src/xenia/cpu/processor.h index 5bab11ab4..84d76c1c0 100644 --- a/src/xenia/cpu/processor.h +++ b/src/xenia/cpu/processor.h @@ -13,9 +13,9 @@ #include #include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/export_resolver.h" +#include "xenia/memory.h" namespace xe { namespace cpu { diff --git a/src/xenia/cpu/xenon_runtime.cc b/src/xenia/cpu/xenon_runtime.cc index 61ca8aabe..2b9ffb306 100644 --- a/src/xenia/cpu/xenon_runtime.cc +++ b/src/xenia/cpu/xenon_runtime.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "xenia/cpu/xenon_runtime.h" -#include -#include +#include "alloy/frontend/ppc/ppc_frontend.h" +#include "xenia/cpu/xenon_thread_state.h" using namespace xe; using namespace xe::cpu; diff --git a/src/xenia/cpu/xenon_runtime.h b/src/xenia/cpu/xenon_runtime.h index deb37d8c2..3aae4f0e2 100644 --- a/src/xenia/cpu/xenon_runtime.h +++ b/src/xenia/cpu/xenon_runtime.h @@ -10,11 +10,11 @@ #ifndef XENIA_CPU_XENON_RUNTIME_H_ #define XENIA_CPU_XENON_RUNTIME_H_ -#include -#include -#include -#include -#include +#include "alloy/runtime/runtime.h" +#include "xenia/common.h" +#include "xenia/cpu/xenon_thread_state.h" +#include "xenia/export_resolver.h" +#include "xenia/memory.h" namespace xe { namespace cpu { diff --git a/src/xenia/cpu/xenon_thread_state.cc b/src/xenia/cpu/xenon_thread_state.cc index 2c8109f96..ce3083cae 100644 --- a/src/xenia/cpu/xenon_thread_state.cc +++ b/src/xenia/cpu/xenon_thread_state.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "xenia/cpu/xenon_thread_state.h" -#include -#include +#include "xdb/protocol.h" +#include "xenia/cpu/xenon_runtime.h" using namespace alloy; using namespace alloy::frontend; diff --git a/src/xenia/cpu/xenon_thread_state.h b/src/xenia/cpu/xenon_thread_state.h index 7a73bfccf..926ea04d1 100644 --- a/src/xenia/cpu/xenon_thread_state.h +++ b/src/xenia/cpu/xenon_thread_state.h @@ -10,10 +10,10 @@ #ifndef XENIA_CPU_XENON_THREAD_STATE_H_ #define XENIA_CPU_XENON_THREAD_STATE_H_ -#include -#include -#include -#include +#include "alloy/frontend/ppc/ppc_context.h" +#include "alloy/runtime/thread_state.h" +#include "xenia/common.h" +#include "xenia/memory.h" namespace xdb { namespace protocol { diff --git a/src/xenia/cpu/xex_module.cc b/src/xenia/cpu/xex_module.cc index 604e130e7..1f4940573 100644 --- a/src/xenia/cpu/xex_module.cc +++ b/src/xenia/cpu/xex_module.cc @@ -7,14 +7,14 @@ ****************************************************************************** */ -#include +#include "xenia/cpu/xex_module.h" #include -#include -#include -#include -#include +#include "poly/math.h" +#include "xenia/cpu/cpu-private.h" +#include "xenia/cpu/xenon_runtime.h" +#include "xenia/export_resolver.h" using namespace alloy; using namespace alloy::runtime; diff --git a/src/xenia/cpu/xex_module.h b/src/xenia/cpu/xex_module.h index 52a6cf9d3..222b25841 100644 --- a/src/xenia/cpu/xex_module.h +++ b/src/xenia/cpu/xex_module.h @@ -12,9 +12,9 @@ #include -#include -#include -#include +#include "alloy/runtime/module.h" +#include "xenia/common.h" +#include "xenia/kernel/util/xex2.h" namespace xe { namespace cpu { diff --git a/src/xenia/debug_agent.cc b/src/xenia/debug_agent.cc index 4c552a31a..e1df194de 100644 --- a/src/xenia/debug_agent.cc +++ b/src/xenia/debug_agent.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "xenia/debug_agent.h" -#include +#include "poly/string.h" #include DEFINE_string(trace_file, "", "Trace to the given file."); diff --git a/src/xenia/debug_agent.h b/src/xenia/debug_agent.h index 57577dced..6fd1f9d8d 100644 --- a/src/xenia/debug_agent.h +++ b/src/xenia/debug_agent.h @@ -12,7 +12,7 @@ #include -#include +#include "xenia/common.h" namespace xe { diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index 048e5f9cb..df4960e39 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -7,20 +7,20 @@ ****************************************************************************** */ -#include +#include "xenia/emulator.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "poly/poly.h" +#include "xdb/protocol.h" +#include "xenia/apu/apu.h" +#include "xenia/cpu/cpu.h" +#include "xenia/gpu/gpu.h" +#include "xenia/hid/hid.h" +#include "xenia/kernel/kernel.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/modules.h" +#include "xenia/kernel/fs/filesystem.h" +#include "xenia/memory.h" +#include "xenia/ui/main_window.h" namespace xe { diff --git a/src/xenia/emulator.h b/src/xenia/emulator.h index ecb09ff44..5a70e1efc 100644 --- a/src/xenia/emulator.h +++ b/src/xenia/emulator.h @@ -12,12 +12,12 @@ #include -#include -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/debug_agent.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/memory.h" +#include "xenia/ui/main_window.h" +#include "xenia/xbox.h" namespace xe { namespace apu { diff --git a/src/xenia/export_resolver.cc b/src/xenia/export_resolver.cc index 9de2a9515..91b982c78 100644 --- a/src/xenia/export_resolver.cc +++ b/src/xenia/export_resolver.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "xenia/export_resolver.h" -#include +#include "poly/math.h" namespace xe { diff --git a/src/xenia/export_resolver.h b/src/xenia/export_resolver.h index c8ceea761..149ad3e76 100644 --- a/src/xenia/export_resolver.h +++ b/src/xenia/export_resolver.h @@ -10,7 +10,7 @@ #ifndef XENIA_EXPORT_RESOLVER_H_ #define XENIA_EXPORT_RESOLVER_H_ -#include +#include "xenia/common.h" #include #include diff --git a/src/xenia/gpu/gl4/circular_buffer.cc b/src/xenia/gpu/gl4/circular_buffer.cc index a2554f9fb..bfd7cbf2d 100644 --- a/src/xenia/gpu/gl4/circular_buffer.cc +++ b/src/xenia/gpu/gl4/circular_buffer.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include +#include "xenia/gpu/gl4/circular_buffer.h" -#include -#include -#include -#include +#include "poly/assert.h" +#include "poly/math.h" +#include "xenia/gpu/gl4/gl4_gpu-private.h" +#include "xenia/gpu/gpu-private.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/gl4/circular_buffer.h b/src/xenia/gpu/gl4/circular_buffer.h index aaa7ea7e8..7a0232693 100644 --- a/src/xenia/gpu/gl4/circular_buffer.h +++ b/src/xenia/gpu/gl4/circular_buffer.h @@ -10,7 +10,7 @@ #ifndef XENIA_GPU_GL4_CIRCULAR_BUFFER_H_ #define XENIA_GPU_GL4_CIRCULAR_BUFFER_H_ -#include +#include "xenia/gpu/gl4/gl_context.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/gl4/command_processor.cc b/src/xenia/gpu/gl4/command_processor.cc index 203c6a000..b9676cd1d 100644 --- a/src/xenia/gpu/gl4/command_processor.cc +++ b/src/xenia/gpu/gl4/command_processor.cc @@ -7,20 +7,20 @@ ****************************************************************************** */ -#include +#include "xenia/gpu/gl4/command_processor.h" #include -#include -#include -#include -#include -#include -#include -#include -#include +#include "poly/logging.h" +#include "poly/math.h" +#include "xenia/gpu/gl4/gl4_gpu-private.h" +#include "xenia/gpu/gl4/gl4_graphics_system.h" +#include "xenia/gpu/gpu-private.h" +#include "xenia/gpu/sampler_info.h" +#include "xenia/gpu/texture_info.h" +#include "xenia/gpu/xenos.h" -#include +#include "third_party/xxhash/xxhash.h" #define XETRACECP(fmt, ...) \ if (FLAGS_trace_ring_buffer) XELOGGPU(fmt, ##__VA_ARGS__) diff --git a/src/xenia/gpu/gl4/command_processor.h b/src/xenia/gpu/gl4/command_processor.h index 6a21459dd..769b581a3 100644 --- a/src/xenia/gpu/gl4/command_processor.h +++ b/src/xenia/gpu/gl4/command_processor.h @@ -17,14 +17,14 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include "xenia/gpu/gl4/circular_buffer.h" +#include "xenia/gpu/gl4/draw_batcher.h" +#include "xenia/gpu/gl4/gl_context.h" +#include "xenia/gpu/gl4/gl4_shader.h" +#include "xenia/gpu/gl4/texture_cache.h" +#include "xenia/gpu/register_file.h" +#include "xenia/gpu/xenos.h" +#include "xenia/memory.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/gl4/draw_batcher.cc b/src/xenia/gpu/gl4/draw_batcher.cc index 304992a80..cc78afe2f 100644 --- a/src/xenia/gpu/gl4/draw_batcher.cc +++ b/src/xenia/gpu/gl4/draw_batcher.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include +#include "xenia/gpu/gl4/draw_batcher.h" -#include -#include -#include -#include +#include "poly/cxx_compat.h" +#include "poly/math.h" +#include "xenia/gpu/gl4/gl4_gpu-private.h" +#include "xenia/gpu/gpu-private.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/gl4/draw_batcher.h b/src/xenia/gpu/gl4/draw_batcher.h index f930ba2a0..b1c52dbf5 100644 --- a/src/xenia/gpu/gl4/draw_batcher.h +++ b/src/xenia/gpu/gl4/draw_batcher.h @@ -10,12 +10,12 @@ #ifndef XENIA_GPU_GL4_GL4_STATE_DATA_BUILDER_H_ #define XENIA_GPU_GL4_GL4_STATE_DATA_BUILDER_H_ -#include -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/gpu/gl4/circular_buffer.h" +#include "xenia/gpu/gl4/gl_context.h" +#include "xenia/gpu/gl4/gl4_shader.h" +#include "xenia/gpu/register_file.h" +#include "xenia/gpu/xenos.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/gl4/gl4_gpu-private.h b/src/xenia/gpu/gl4/gl4_gpu-private.h index 73937bee4..3d14b5823 100644 --- a/src/xenia/gpu/gl4/gl4_gpu-private.h +++ b/src/xenia/gpu/gl4/gl4_gpu-private.h @@ -12,8 +12,8 @@ #include -#include -#include +#include "xenia/common.h" +#include "xenia/gpu/gl4/gl4_gpu.h" DECLARE_bool(thread_safe_gl); diff --git a/src/xenia/gpu/gl4/gl4_gpu.cc b/src/xenia/gpu/gl4/gl4_gpu.cc index 3f9ef960d..be29dc6a5 100644 --- a/src/xenia/gpu/gl4/gl4_gpu.cc +++ b/src/xenia/gpu/gl4/gl4_gpu.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "xenia/gpu/gl4/gl4_gpu.h" -#include -#include +#include "xenia/gpu/gl4/gl4_gpu-private.h" +#include "xenia/gpu/gl4/gl4_graphics_system.h" DEFINE_bool(thread_safe_gl, false, "Only allow one GL context to be active at a time."); diff --git a/src/xenia/gpu/gl4/gl4_gpu.h b/src/xenia/gpu/gl4/gl4_gpu.h index 65c3dfaa6..c6144cec4 100644 --- a/src/xenia/gpu/gl4/gl4_gpu.h +++ b/src/xenia/gpu/gl4/gl4_gpu.h @@ -12,8 +12,8 @@ #include -#include -#include +#include "xenia/common.h" +#include "xenia/gpu/graphics_system.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/gl4/gl4_graphics_system.cc b/src/xenia/gpu/gl4/gl4_graphics_system.cc index a92339bd6..24bd0527a 100644 --- a/src/xenia/gpu/gl4/gl4_graphics_system.cc +++ b/src/xenia/gpu/gl4/gl4_graphics_system.cc @@ -7,13 +7,13 @@ ****************************************************************************** */ -#include +#include "xenia/gpu/gl4/gl4_graphics_system.h" -#include -#include -#include -#include -#include +#include "poly/threading.h" +#include "xenia/cpu/processor.h" +#include "xenia/gpu/gl4/gl4_gpu-private.h" +#include "xenia/gpu/gl4/gl4_profiler_display.h" +#include "xenia/gpu/gpu-private.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/gl4/gl4_graphics_system.h b/src/xenia/gpu/gl4/gl4_graphics_system.h index 17e33f84c..6a6d028d8 100644 --- a/src/xenia/gpu/gl4/gl4_graphics_system.h +++ b/src/xenia/gpu/gl4/gl4_graphics_system.h @@ -12,11 +12,11 @@ #include -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/gpu/gl4/command_processor.h" +#include "xenia/gpu/gl4/wgl_control.h" +#include "xenia/gpu/graphics_system.h" +#include "xenia/gpu/register_file.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/gl4/gl4_profiler_display.cc b/src/xenia/gpu/gl4/gl4_profiler_display.cc index f60723cce..cd31a7ad1 100644 --- a/src/xenia/gpu/gl4/gl4_profiler_display.cc +++ b/src/xenia/gpu/gl4/gl4_profiler_display.cc @@ -7,13 +7,13 @@ ****************************************************************************** */ -#include +#include "xenia/gpu/gl4/gl4_profiler_display.h" -#include +#include "third_party/microprofile/microprofileui.h" -#include -#include -#include +#include "poly/cxx_compat.h" +#include "poly/math.h" +#include "xenia/gpu/gpu-private.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/gl4/gl4_profiler_display.h b/src/xenia/gpu/gl4/gl4_profiler_display.h index d5290d62f..c7d7ea338 100644 --- a/src/xenia/gpu/gl4/gl4_profiler_display.h +++ b/src/xenia/gpu/gl4/gl4_profiler_display.h @@ -10,11 +10,11 @@ #ifndef XENIA_GPU_GL4_GL4_PROFILER_DISPLAY_H_ #define XENIA_GPU_GL4_GL4_PROFILER_DISPLAY_H_ -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/gpu/gl4/circular_buffer.h" +#include "xenia/gpu/gl4/gl_context.h" +#include "xenia/gpu/gl4/wgl_control.h" +#include "xenia/profiling.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/gl4/gl4_shader.cc b/src/xenia/gpu/gl4/gl4_shader.cc index 2255be226..3f5aba911 100644 --- a/src/xenia/gpu/gl4/gl4_shader.cc +++ b/src/xenia/gpu/gl4/gl4_shader.cc @@ -7,13 +7,13 @@ ****************************************************************************** */ -#include +#include "xenia/gpu/gl4/gl4_shader.h" -#include -#include -#include -#include -#include +#include "poly/cxx_compat.h" +#include "poly/math.h" +#include "xenia/gpu/gl4/gl4_gpu-private.h" +#include "xenia/gpu/gl4/gl4_shader_translator.h" +#include "xenia/gpu/gpu-private.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/gl4/gl4_shader.h b/src/xenia/gpu/gl4/gl4_shader.h index 1dac6b4c3..5c9b4eb24 100644 --- a/src/xenia/gpu/gl4/gl4_shader.h +++ b/src/xenia/gpu/gl4/gl4_shader.h @@ -12,9 +12,9 @@ #include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/gpu/gl4/gl_context.h" +#include "xenia/gpu/shader.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/gl4/gl4_shader_translator.cc b/src/xenia/gpu/gl4/gl4_shader_translator.cc index 1b3aff02b..28b49f31e 100644 --- a/src/xenia/gpu/gl4/gl4_shader_translator.cc +++ b/src/xenia/gpu/gl4/gl4_shader_translator.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "xenia/gpu/gl4/gl4_shader_translator.h" -#include -#include +#include "poly/math.h" +#include "xenia/gpu/gpu-private.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/gl4/gl4_shader_translator.h b/src/xenia/gpu/gl4/gl4_shader_translator.h index d0453c38b..44939a8a0 100644 --- a/src/xenia/gpu/gl4/gl4_shader_translator.h +++ b/src/xenia/gpu/gl4/gl4_shader_translator.h @@ -12,12 +12,12 @@ #include -#include -#include -#include -#include -#include -#include +#include "alloy/string_buffer.h" +#include "xenia/common.h" +#include "xenia/gpu/gl4/gl_context.h" +#include "xenia/gpu/gl4/gl4_shader.h" +#include "xenia/gpu/ucode.h" +#include "xenia/gpu/xenos.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/gl4/gl_context.cc b/src/xenia/gpu/gl4/gl_context.cc index 3d4600514..c16e15e2f 100644 --- a/src/xenia/gpu/gl4/gl_context.cc +++ b/src/xenia/gpu/gl4/gl_context.cc @@ -7,15 +7,15 @@ ****************************************************************************** */ -#include +#include "xenia/gpu/gl4/gl_context.h" #include -#include -#include -#include -#include -#include +#include "poly/assert.h" +#include "poly/cxx_compat.h" +#include "poly/logging.h" +#include "poly/math.h" +#include "xenia/gpu/gl4/gl4_gpu-private.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/gl4/gl_context.h b/src/xenia/gpu/gl4/gl_context.h index 196c99a15..9ac386f53 100644 --- a/src/xenia/gpu/gl4/gl_context.h +++ b/src/xenia/gpu/gl4/gl_context.h @@ -12,8 +12,8 @@ #include -#include -#include +#include "third_party/GL/glew.h" +#include "third_party/GL/wglew.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/gl4/texture_cache.cc b/src/xenia/gpu/gl4/texture_cache.cc index 6193b19d2..9f6634913 100644 --- a/src/xenia/gpu/gl4/texture_cache.cc +++ b/src/xenia/gpu/gl4/texture_cache.cc @@ -7,11 +7,11 @@ ****************************************************************************** */ -#include +#include "xenia/gpu/gl4/texture_cache.h" -#include -#include -#include +#include "poly/assert.h" +#include "poly/math.h" +#include "xenia/gpu/gpu-private.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/gl4/texture_cache.h b/src/xenia/gpu/gl4/texture_cache.h index 8eedfc476..1eede404a 100644 --- a/src/xenia/gpu/gl4/texture_cache.h +++ b/src/xenia/gpu/gl4/texture_cache.h @@ -14,11 +14,11 @@ #include #include -#include -#include -#include -#include -#include +#include "xenia/gpu/gl4/circular_buffer.h" +#include "xenia/gpu/gl4/gl_context.h" +#include "xenia/gpu/sampler_info.h" +#include "xenia/gpu/texture_info.h" +#include "xenia/memory.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/gl4/wgl_control.cc b/src/xenia/gpu/gl4/wgl_control.cc index 6a83c1b38..5b1c56c4d 100644 --- a/src/xenia/gpu/gl4/wgl_control.cc +++ b/src/xenia/gpu/gl4/wgl_control.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include +#include "xenia/gpu/gl4/wgl_control.h" -#include -#include -#include -#include +#include "poly/assert.h" +#include "poly/logging.h" +#include "xenia/gpu/gl4/gl4_gpu-private.h" +#include "xenia/profiling.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/gl4/wgl_control.h b/src/xenia/gpu/gl4/wgl_control.h index f180a6eb3..bced21022 100644 --- a/src/xenia/gpu/gl4/wgl_control.h +++ b/src/xenia/gpu/gl4/wgl_control.h @@ -12,10 +12,10 @@ #include -#include -#include -#include -#include +#include "poly/threading.h" +#include "poly/ui/loop.h" +#include "poly/ui/win32/win32_control.h" +#include "xenia/gpu/gl4/gl_context.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/gpu.cc b/src/xenia/gpu/gpu.cc index 47d773362..ec0037f64 100644 --- a/src/xenia/gpu/gpu.cc +++ b/src/xenia/gpu/gpu.cc @@ -7,11 +7,11 @@ ****************************************************************************** */ -#include -#include +#include "xenia/gpu/gpu.h" +#include "xenia/gpu/gpu-private.h" // TODO(benvanik): based on platform. -#include +#include "xenia/gpu/gl4/gl4_gpu.h" DEFINE_string(gpu, "any", "Graphics system. Use: [any, gl4]"); diff --git a/src/xenia/gpu/gpu.h b/src/xenia/gpu/gpu.h index 1a3aa06a7..88541f2ca 100644 --- a/src/xenia/gpu/gpu.h +++ b/src/xenia/gpu/gpu.h @@ -12,7 +12,7 @@ #include -#include +#include "xenia/gpu/graphics_system.h" namespace xe { class Emulator; diff --git a/src/xenia/gpu/graphics_system.cc b/src/xenia/gpu/graphics_system.cc index 89eca968e..47fce8166 100644 --- a/src/xenia/gpu/graphics_system.cc +++ b/src/xenia/gpu/graphics_system.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include +#include "xenia/gpu/graphics_system.h" -#include -#include -#include -#include +#include "poly/poly.h" +#include "xenia/emulator.h" +#include "xenia/cpu/processor.h" +#include "xenia/gpu/gpu-private.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/graphics_system.h b/src/xenia/gpu/graphics_system.h index 024979110..fd3184ab0 100644 --- a/src/xenia/gpu/graphics_system.h +++ b/src/xenia/gpu/graphics_system.h @@ -13,9 +13,9 @@ #include #include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/emulator.h" +#include "xenia/xbox.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/register_file.cc b/src/xenia/gpu/register_file.cc index e388d926f..a3d25e035 100644 --- a/src/xenia/gpu/register_file.cc +++ b/src/xenia/gpu/register_file.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "xenia/gpu/register_file.h" namespace xe { namespace gpu { @@ -19,7 +19,7 @@ const char* RegisterFile::GetRegisterName(uint32_t index) { #define XE_GPU_REGISTER(index, type, name) \ case index: \ return #name; -#include +#include "xenia/gpu/register_table.inc" #undef XE_GPU_REGISTER default: return nullptr; diff --git a/src/xenia/gpu/register_file.h b/src/xenia/gpu/register_file.h index 0b4b84ca5..9ac14d4d7 100644 --- a/src/xenia/gpu/register_file.h +++ b/src/xenia/gpu/register_file.h @@ -10,14 +10,14 @@ #ifndef XENIA_GPU_REGISTER_FILE_H_ #define XENIA_GPU_REGISTER_FILE_H_ -#include +#include "xenia/common.h" namespace xe { namespace gpu { enum Register { #define XE_GPU_REGISTER(index, type, name) XE_GPU_REG_##name = index, -#include +#include "xenia/gpu/register_table.inc" #undef XE_GPU_REGISTER }; diff --git a/src/xenia/gpu/sampler_info.cc b/src/xenia/gpu/sampler_info.cc index 78c023656..e7d6dcf9c 100644 --- a/src/xenia/gpu/sampler_info.cc +++ b/src/xenia/gpu/sampler_info.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "xenia/gpu/sampler_info.h" -#include +#include "third_party/xxhash/xxhash.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/sampler_info.h b/src/xenia/gpu/sampler_info.h index 57abfb4b9..c89b582ea 100644 --- a/src/xenia/gpu/sampler_info.h +++ b/src/xenia/gpu/sampler_info.h @@ -10,8 +10,8 @@ #ifndef XENIA_GPU_SAMPLER_INFO_H_ #define XENIA_GPU_SAMPLER_INFO_H_ -#include -#include +#include "xenia/gpu/ucode.h" +#include "xenia/gpu/xenos.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/shader.cc b/src/xenia/gpu/shader.cc index c79d51727..85f41fc4f 100644 --- a/src/xenia/gpu/shader.cc +++ b/src/xenia/gpu/shader.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "xenia/gpu/shader.h" -#include -#include +#include "poly/math.h" +#include "xenia/gpu/ucode_disassembler.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/shader.h b/src/xenia/gpu/shader.h index 5983b851d..cd24e9281 100644 --- a/src/xenia/gpu/shader.h +++ b/src/xenia/gpu/shader.h @@ -13,8 +13,8 @@ #include #include -#include -#include +#include "xenia/gpu/ucode.h" +#include "xenia/gpu/xenos.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/texture_info.cc b/src/xenia/gpu/texture_info.cc index 38eb711c8..04e808c13 100644 --- a/src/xenia/gpu/texture_info.cc +++ b/src/xenia/gpu/texture_info.cc @@ -7,11 +7,11 @@ ****************************************************************************** */ -#include +#include "xenia/gpu/texture_info.h" -#include +#include "third_party/xxhash/xxhash.h" -#include +#include "poly/math.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/texture_info.h b/src/xenia/gpu/texture_info.h index 1ebaee00e..fcf37a9b2 100644 --- a/src/xenia/gpu/texture_info.h +++ b/src/xenia/gpu/texture_info.h @@ -10,8 +10,8 @@ #ifndef XENIA_GPU_TEXTURE_INFO_H_ #define XENIA_GPU_TEXTURE_INFO_H_ -#include -#include +#include "xenia/gpu/ucode.h" +#include "xenia/gpu/xenos.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/ucode.h b/src/xenia/gpu/ucode.h index 7cf15d0a8..0152feeaf 100644 --- a/src/xenia/gpu/ucode.h +++ b/src/xenia/gpu/ucode.h @@ -10,7 +10,7 @@ #ifndef XENIA_GPU_UCODE_H_ #define XENIA_GPU_UCODE_H_ -#include +#include "xenia/common.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/ucode_disassembler.cc b/src/xenia/gpu/ucode_disassembler.cc index 61ba345c6..3822d7f3a 100644 --- a/src/xenia/gpu/ucode_disassembler.cc +++ b/src/xenia/gpu/ucode_disassembler.cc @@ -30,7 +30,7 @@ * SOFTWARE. */ -#include +#include "xenia/gpu/ucode_disassembler.h" #include #include diff --git a/src/xenia/gpu/ucode_disassembler.h b/src/xenia/gpu/ucode_disassembler.h index bd5ab4eff..22d09eb09 100644 --- a/src/xenia/gpu/ucode_disassembler.h +++ b/src/xenia/gpu/ucode_disassembler.h @@ -12,8 +12,8 @@ #include -#include -#include +#include "xenia/gpu/ucode.h" +#include "xenia/gpu/xenos.h" namespace xe { namespace gpu { diff --git a/src/xenia/gpu/xenos.h b/src/xenia/gpu/xenos.h index 3b8446e27..5860b9e35 100644 --- a/src/xenia/gpu/xenos.h +++ b/src/xenia/gpu/xenos.h @@ -10,8 +10,8 @@ #ifndef XENIA_GPU_XENOS_H_ #define XENIA_GPU_XENOS_H_ -#include -#include +#include "xenia/common.h" +#include "xenia/gpu/ucode.h" namespace xe { namespace gpu { diff --git a/src/xenia/hid/hid.cc b/src/xenia/hid/hid.cc index a31e40fd8..c7fcfade8 100644 --- a/src/xenia/hid/hid.cc +++ b/src/xenia/hid/hid.cc @@ -7,19 +7,19 @@ ****************************************************************************** */ -#include -#include -#include +#include "xenia/hid/hid.h" +#include "xenia/hid/hid-private.h" +#include "xenia/hid/input_driver.h" using namespace xe; using namespace xe::hid; DEFINE_string(hid, "any", "Input system. Use: [any, nop, winkey, xinput]"); -#include +#include "xenia/hid/nop/nop_hid.h" #if XE_PLATFORM_WIN32 -#include -#include +#include "xenia/hid/winkey/winkey_hid.h" +#include "xenia/hid/xinput/xinput_hid.h" #endif // WIN32 std::unique_ptr xe::hid::Create(Emulator* emulator) { diff --git a/src/xenia/hid/hid.h b/src/xenia/hid/hid.h index ca589e150..597ad0540 100644 --- a/src/xenia/hid/hid.h +++ b/src/xenia/hid/hid.h @@ -12,7 +12,7 @@ #include -#include +#include "xenia/hid/input_system.h" namespace xe { class Emulator; diff --git a/src/xenia/hid/input_driver.cc b/src/xenia/hid/input_driver.cc index a7017b03b..b74c0035c 100644 --- a/src/xenia/hid/input_driver.cc +++ b/src/xenia/hid/input_driver.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "xenia/hid/input_driver.h" namespace xe { namespace hid { diff --git a/src/xenia/hid/input_driver.h b/src/xenia/hid/input_driver.h index 4c8ecfd06..cac274ceb 100644 --- a/src/xenia/hid/input_driver.h +++ b/src/xenia/hid/input_driver.h @@ -10,8 +10,8 @@ #ifndef XENIA_HID_INPUT_DRIVER_H_ #define XENIA_HID_INPUT_DRIVER_H_ -#include -#include +#include "xenia/common.h" +#include "xenia/xbox.h" namespace xe { namespace hid { diff --git a/src/xenia/hid/input_system.cc b/src/xenia/hid/input_system.cc index 0c0431118..017791f29 100644 --- a/src/xenia/hid/input_system.cc +++ b/src/xenia/hid/input_system.cc @@ -7,11 +7,11 @@ ****************************************************************************** */ -#include +#include "xenia/hid/input_system.h" -#include -#include -#include +#include "xenia/emulator.h" +#include "xenia/cpu/processor.h" +#include "xenia/hid/input_driver.h" namespace xe { namespace hid { diff --git a/src/xenia/hid/input_system.h b/src/xenia/hid/input_system.h index 3f71866a6..adcac38ff 100644 --- a/src/xenia/hid/input_system.h +++ b/src/xenia/hid/input_system.h @@ -13,9 +13,9 @@ #include #include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/emulator.h" +#include "xenia/xbox.h" namespace xe { namespace hid { diff --git a/src/xenia/hid/nop/nop_hid-private.h b/src/xenia/hid/nop/nop_hid-private.h index a4460606c..6205b8e4a 100644 --- a/src/xenia/hid/nop/nop_hid-private.h +++ b/src/xenia/hid/nop/nop_hid-private.h @@ -10,8 +10,8 @@ #ifndef XENIA_HID_NOP_NOP_HID_PRIVATE_H_ #define XENIA_HID_NOP_NOP_HID_PRIVATE_H_ -#include -#include +#include "xenia/common.h" +#include "xenia/hid/nop/nop_hid.h" namespace xe { namespace hid { diff --git a/src/xenia/hid/nop/nop_hid.cc b/src/xenia/hid/nop/nop_hid.cc index 86240e9ae..c15ccdadd 100644 --- a/src/xenia/hid/nop/nop_hid.cc +++ b/src/xenia/hid/nop/nop_hid.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "xenia/hid/nop/nop_hid.h" -#include +#include "xenia/hid/nop/nop_input_driver.h" namespace xe { namespace hid { diff --git a/src/xenia/hid/nop/nop_hid.h b/src/xenia/hid/nop/nop_hid.h index d401ce54a..11571dabd 100644 --- a/src/xenia/hid/nop/nop_hid.h +++ b/src/xenia/hid/nop/nop_hid.h @@ -12,7 +12,7 @@ #include -#include +#include "xenia/common.h" namespace xe { namespace hid { diff --git a/src/xenia/hid/nop/nop_input_driver.cc b/src/xenia/hid/nop/nop_input_driver.cc index 459391c77..d4d392d06 100644 --- a/src/xenia/hid/nop/nop_input_driver.cc +++ b/src/xenia/hid/nop/nop_input_driver.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "xenia/hid/nop/nop_input_driver.h" -#include +#include "xenia/hid/hid-private.h" namespace xe { namespace hid { diff --git a/src/xenia/hid/nop/nop_input_driver.h b/src/xenia/hid/nop/nop_input_driver.h index 7be53bf16..7203d9d55 100644 --- a/src/xenia/hid/nop/nop_input_driver.h +++ b/src/xenia/hid/nop/nop_input_driver.h @@ -10,9 +10,9 @@ #ifndef XENIA_HID_NOP_NOP_INPUT_DRIVER_H_ #define XENIA_HID_NOP_NOP_INPUT_DRIVER_H_ -#include -#include -#include +#include "xenia/common.h" +#include "xenia/hid/input_driver.h" +#include "xenia/hid/nop/nop_hid-private.h" namespace xe { namespace hid { diff --git a/src/xenia/hid/winkey/winkey_hid-private.h b/src/xenia/hid/winkey/winkey_hid-private.h index da925e722..c51f1b3ab 100644 --- a/src/xenia/hid/winkey/winkey_hid-private.h +++ b/src/xenia/hid/winkey/winkey_hid-private.h @@ -10,8 +10,8 @@ #ifndef XENIA_HID_WINKEY_WINKEY_HID_PRIVATE_H_ #define XENIA_HID_WINKEY_WINKEY_HID_PRIVATE_H_ -#include -#include +#include "xenia/common.h" +#include "xenia/hid/winkey/winkey_hid.h" namespace xe { namespace hid { diff --git a/src/xenia/hid/winkey/winkey_hid.cc b/src/xenia/hid/winkey/winkey_hid.cc index d837a6548..2e3db1f09 100644 --- a/src/xenia/hid/winkey/winkey_hid.cc +++ b/src/xenia/hid/winkey/winkey_hid.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "xenia/hid/winkey/winkey_hid.h" -#include +#include "xenia/hid/winkey/winkey_input_driver.h" namespace xe { namespace hid { diff --git a/src/xenia/hid/winkey/winkey_hid.h b/src/xenia/hid/winkey/winkey_hid.h index cfdec12e1..9339bf356 100644 --- a/src/xenia/hid/winkey/winkey_hid.h +++ b/src/xenia/hid/winkey/winkey_hid.h @@ -12,7 +12,7 @@ #include -#include +#include "xenia/common.h" namespace xe { namespace hid { diff --git a/src/xenia/hid/winkey/winkey_input_driver.cc b/src/xenia/hid/winkey/winkey_input_driver.cc index 9f2e83653..a3cf3fbd0 100644 --- a/src/xenia/hid/winkey/winkey_input_driver.cc +++ b/src/xenia/hid/winkey/winkey_input_driver.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "xenia/hid/winkey/winkey_input_driver.h" -#include +#include "xenia/hid/hid-private.h" namespace xe { namespace hid { diff --git a/src/xenia/hid/winkey/winkey_input_driver.h b/src/xenia/hid/winkey/winkey_input_driver.h index 16bc51461..60ef6d1bc 100644 --- a/src/xenia/hid/winkey/winkey_input_driver.h +++ b/src/xenia/hid/winkey/winkey_input_driver.h @@ -10,9 +10,9 @@ #ifndef XENIA_HID_WINKEY_WINKEY_DRIVER_H_ #define XENIA_HID_WINKEY_WINKEY_DRIVER_H_ -#include -#include -#include +#include "xenia/common.h" +#include "xenia/hid/input_driver.h" +#include "xenia/hid/nop/nop_hid-private.h" namespace xe { namespace hid { diff --git a/src/xenia/hid/xinput/xinput_hid-private.h b/src/xenia/hid/xinput/xinput_hid-private.h index c9dc937ae..b6beed6f4 100644 --- a/src/xenia/hid/xinput/xinput_hid-private.h +++ b/src/xenia/hid/xinput/xinput_hid-private.h @@ -10,8 +10,8 @@ #ifndef XENIA_HID_XINPUT_XINPUT_HID_PRIVATE_H_ #define XENIA_HID_XINPUT_XINPUT_HID_PRIVATE_H_ -#include -#include +#include "xenia/common.h" +#include "xenia/hid/xinput/xinput_hid.h" namespace xe { namespace hid { diff --git a/src/xenia/hid/xinput/xinput_hid.cc b/src/xenia/hid/xinput/xinput_hid.cc index 1535d9a19..019e36d61 100644 --- a/src/xenia/hid/xinput/xinput_hid.cc +++ b/src/xenia/hid/xinput/xinput_hid.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "xenia/hid/xinput/xinput_hid.h" -#include +#include "xenia/hid/xinput/xinput_input_driver.h" namespace xe { namespace hid { diff --git a/src/xenia/hid/xinput/xinput_hid.h b/src/xenia/hid/xinput/xinput_hid.h index 7fbca77cf..859ef88ab 100644 --- a/src/xenia/hid/xinput/xinput_hid.h +++ b/src/xenia/hid/xinput/xinput_hid.h @@ -12,7 +12,7 @@ #include -#include +#include "xenia/common.h" namespace xe { namespace hid { diff --git a/src/xenia/hid/xinput/xinput_input_driver.cc b/src/xenia/hid/xinput/xinput_input_driver.cc index cad5edadb..1a19bc74a 100644 --- a/src/xenia/hid/xinput/xinput_input_driver.cc +++ b/src/xenia/hid/xinput/xinput_input_driver.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "xenia/hid/xinput/xinput_input_driver.h" -#include +#include "xenia/hid/hid-private.h" #include diff --git a/src/xenia/hid/xinput/xinput_input_driver.h b/src/xenia/hid/xinput/xinput_input_driver.h index c780b7df4..e8a83c830 100644 --- a/src/xenia/hid/xinput/xinput_input_driver.h +++ b/src/xenia/hid/xinput/xinput_input_driver.h @@ -10,9 +10,9 @@ #ifndef XENIA_HID_XINPUT_XINPUT_DRIVER_H_ #define XENIA_HID_XINPUT_XINPUT_DRIVER_H_ -#include -#include -#include +#include "xenia/common.h" +#include "xenia/hid/input_driver.h" +#include "xenia/hid/nop/nop_hid-private.h" namespace xe { namespace hid { diff --git a/src/xenia/kernel/app.cc b/src/xenia/kernel/app.cc index 3216a32fc..12deb5ce7 100644 --- a/src/xenia/kernel/app.cc +++ b/src/xenia/kernel/app.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/app.h" -#include +#include "xenia/kernel/kernel_state.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/app.h b/src/xenia/kernel/app.h index 1608a4162..c30144479 100644 --- a/src/xenia/kernel/app.h +++ b/src/xenia/kernel/app.h @@ -13,9 +13,9 @@ #include #include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/memory.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/apps/apps.cc b/src/xenia/kernel/apps/apps.cc index 88fbb40b5..9fa4a6057 100644 --- a/src/xenia/kernel/apps/apps.cc +++ b/src/xenia/kernel/apps/apps.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/apps/apps.h" -#include +#include "xenia/kernel/apps/xmp_app.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/apps/apps.h b/src/xenia/kernel/apps/apps.h index 9c0d2477c..fa6be30b0 100644 --- a/src/xenia/kernel/apps/apps.h +++ b/src/xenia/kernel/apps/apps.h @@ -10,9 +10,9 @@ #ifndef XENIA_KERNEL_XBOXKRNL_APPS_APPS_H_ #define XENIA_KERNEL_XBOXKRNL_APPS_APPS_H_ -#include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/app.h" +#include "xenia/kernel/kernel_state.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/apps/xmp_app.cc b/src/xenia/kernel/apps/xmp_app.cc index 3d04be800..27b99233f 100644 --- a/src/xenia/kernel/apps/xmp_app.cc +++ b/src/xenia/kernel/apps/xmp_app.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/apps/xmp_app.h" -#include +#include "poly/threading.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/apps/xmp_app.h b/src/xenia/kernel/apps/xmp_app.h index 0b1658f17..3c2b50640 100644 --- a/src/xenia/kernel/apps/xmp_app.h +++ b/src/xenia/kernel/apps/xmp_app.h @@ -16,9 +16,9 @@ #include #include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/app.h" +#include "xenia/kernel/kernel_state.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/async_request.cc b/src/xenia/kernel/async_request.cc index f9165a188..337128858 100644 --- a/src/xenia/kernel/async_request.cc +++ b/src/xenia/kernel/async_request.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/async_request.h" -#include -#include +#include "xenia/kernel/xobject.h" +#include "xenia/kernel/objects/xevent.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/async_request.h b/src/xenia/kernel/async_request.h index 1da5fa18a..a75a0f8a5 100644 --- a/src/xenia/kernel/async_request.h +++ b/src/xenia/kernel/async_request.h @@ -12,8 +12,8 @@ #include -#include -#include +#include "xenia/common.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/dispatcher.cc b/src/xenia/kernel/dispatcher.cc index aa6349b34..a57d7a218 100644 --- a/src/xenia/kernel/dispatcher.cc +++ b/src/xenia/kernel/dispatcher.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/dispatcher.h" -#include -#include +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/native_list.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/dispatcher.h b/src/xenia/kernel/dispatcher.h index e06a4e823..7e5875612 100644 --- a/src/xenia/kernel/dispatcher.h +++ b/src/xenia/kernel/dispatcher.h @@ -12,8 +12,8 @@ #include -#include -#include +#include "xenia/common.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/device.cc b/src/xenia/kernel/fs/device.cc index bec6f33d1..d658ab0e6 100644 --- a/src/xenia/kernel/fs/device.cc +++ b/src/xenia/kernel/fs/device.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/fs/device.h" -#include +#include "xenia/kernel/objects/xfile.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/device.h b/src/xenia/kernel/fs/device.h index f6aa4ab11..2dc2ebee8 100644 --- a/src/xenia/kernel/fs/device.h +++ b/src/xenia/kernel/fs/device.h @@ -13,8 +13,8 @@ #include #include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/fs/entry.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/devices/disc_image_device.cc b/src/xenia/kernel/fs/devices/disc_image_device.cc index 1bbb5a109..57a7bd0b9 100644 --- a/src/xenia/kernel/fs/devices/disc_image_device.cc +++ b/src/xenia/kernel/fs/devices/disc_image_device.cc @@ -7,11 +7,11 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/fs/devices/disc_image_device.h" -#include -#include -#include +#include "poly/math.h" +#include "xenia/kernel/fs/gdfx.h" +#include "xenia/kernel/fs/devices/disc_image_entry.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/devices/disc_image_device.h b/src/xenia/kernel/fs/devices/disc_image_device.h index 85af80883..5f398982f 100644 --- a/src/xenia/kernel/fs/devices/disc_image_device.h +++ b/src/xenia/kernel/fs/devices/disc_image_device.h @@ -13,9 +13,9 @@ #include #include -#include -#include -#include +#include "poly/mapped_memory.h" +#include "xenia/common.h" +#include "xenia/kernel/fs/device.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/devices/disc_image_entry.cc b/src/xenia/kernel/fs/devices/disc_image_entry.cc index ea4c90555..10c1eeff2 100644 --- a/src/xenia/kernel/fs/devices/disc_image_entry.cc +++ b/src/xenia/kernel/fs/devices/disc_image_entry.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/fs/devices/disc_image_entry.h" #include -#include -#include +#include "xenia/kernel/fs/gdfx.h" +#include "xenia/kernel/fs/devices/disc_image_file.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/devices/disc_image_entry.h b/src/xenia/kernel/fs/devices/disc_image_entry.h index 019abc46a..96bac1195 100644 --- a/src/xenia/kernel/fs/devices/disc_image_entry.h +++ b/src/xenia/kernel/fs/devices/disc_image_entry.h @@ -12,9 +12,9 @@ #include -#include -#include -#include +#include "poly/mapped_memory.h" +#include "xenia/common.h" +#include "xenia/kernel/fs/entry.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/devices/disc_image_file.cc b/src/xenia/kernel/fs/devices/disc_image_file.cc index 1efb68b3f..d7c7cebb4 100644 --- a/src/xenia/kernel/fs/devices/disc_image_file.cc +++ b/src/xenia/kernel/fs/devices/disc_image_file.cc @@ -7,13 +7,13 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/fs/devices/disc_image_file.h" #include -#include -#include -#include +#include "xenia/kernel/fs/device.h" +#include "xenia/kernel/fs/devices/disc_image_entry.h" +#include "xenia/kernel/fs/gdfx.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/devices/disc_image_file.h b/src/xenia/kernel/fs/devices/disc_image_file.h index 95e5bb83d..04926a8eb 100644 --- a/src/xenia/kernel/fs/devices/disc_image_file.h +++ b/src/xenia/kernel/fs/devices/disc_image_file.h @@ -10,8 +10,8 @@ #ifndef XENIA_KERNEL_FS_DEVICES_DISC_IMAGE_FILE_H_ #define XENIA_KERNEL_FS_DEVICES_DISC_IMAGE_FILE_H_ -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/objects/xfile.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/devices/host_path_device.cc b/src/xenia/kernel/fs/devices/host_path_device.cc index 309a389a9..faec9d8e4 100644 --- a/src/xenia/kernel/fs/devices/host_path_device.cc +++ b/src/xenia/kernel/fs/devices/host_path_device.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/fs/devices/host_path_device.h" -#include -#include +#include "xenia/kernel/fs/devices/host_path_entry.h" +#include "xenia/kernel/objects/xfile.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/devices/host_path_device.h b/src/xenia/kernel/fs/devices/host_path_device.h index 80f618e05..0dc6d5bff 100644 --- a/src/xenia/kernel/fs/devices/host_path_device.h +++ b/src/xenia/kernel/fs/devices/host_path_device.h @@ -12,8 +12,8 @@ #include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/fs/device.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/devices/host_path_entry.cc b/src/xenia/kernel/fs/devices/host_path_entry.cc index 037bb4f2d..ff71ecef9 100644 --- a/src/xenia/kernel/fs/devices/host_path_entry.cc +++ b/src/xenia/kernel/fs/devices/host_path_entry.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/fs/devices/host_path_entry.h" -#include -#include +#include "poly/mapped_memory.h" +#include "xenia/kernel/fs/devices/host_path_file.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/devices/host_path_entry.h b/src/xenia/kernel/fs/devices/host_path_entry.h index ca156b93a..b55dcbcae 100644 --- a/src/xenia/kernel/fs/devices/host_path_entry.h +++ b/src/xenia/kernel/fs/devices/host_path_entry.h @@ -10,8 +10,8 @@ #ifndef XENIA_KERNEL_FS_DEVICES_HOST_PATH_ENTRY_H_ #define XENIA_KERNEL_FS_DEVICES_HOST_PATH_ENTRY_H_ -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/fs/entry.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/devices/host_path_file.cc b/src/xenia/kernel/fs/devices/host_path_file.cc index eafd2cd1f..3d52d818c 100644 --- a/src/xenia/kernel/fs/devices/host_path_file.cc +++ b/src/xenia/kernel/fs/devices/host_path_file.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/fs/devices/host_path_file.h" -#include -#include +#include "xenia/kernel/fs/device.h" +#include "xenia/kernel/fs/devices/host_path_entry.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/devices/host_path_file.h b/src/xenia/kernel/fs/devices/host_path_file.h index cbd59c083..5e66249ce 100644 --- a/src/xenia/kernel/fs/devices/host_path_file.h +++ b/src/xenia/kernel/fs/devices/host_path_file.h @@ -12,8 +12,8 @@ #include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/objects/xfile.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/devices/stfs_container_device.cc b/src/xenia/kernel/fs/devices/stfs_container_device.cc index 0704f8b4a..443589dac 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_device.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_device.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/fs/devices/stfs_container_device.h" -#include -#include -#include -#include +#include "poly/math.h" +#include "xenia/kernel/fs/stfs.h" +#include "xenia/kernel/fs/devices/stfs_container_entry.h" +#include "xenia/kernel/objects/xfile.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/devices/stfs_container_device.h b/src/xenia/kernel/fs/devices/stfs_container_device.h index 1f5dd7607..99b6de654 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_device.h +++ b/src/xenia/kernel/fs/devices/stfs_container_device.h @@ -13,9 +13,9 @@ #include #include -#include -#include -#include +#include "poly/mapped_memory.h" +#include "xenia/common.h" +#include "xenia/kernel/fs/device.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/devices/stfs_container_entry.cc b/src/xenia/kernel/fs/devices/stfs_container_entry.cc index c28cff9e8..d3565c95b 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_entry.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_entry.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/fs/devices/stfs_container_entry.h" -#include -#include +#include "xenia/kernel/fs/stfs.h" +#include "xenia/kernel/fs/devices/stfs_container_file.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/devices/stfs_container_entry.h b/src/xenia/kernel/fs/devices/stfs_container_entry.h index 8cd6d0729..1e75aef47 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_entry.h +++ b/src/xenia/kernel/fs/devices/stfs_container_entry.h @@ -12,9 +12,9 @@ #include -#include -#include -#include +#include "poly/mapped_memory.h" +#include "xenia/common.h" +#include "xenia/kernel/fs/entry.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/devices/stfs_container_file.cc b/src/xenia/kernel/fs/devices/stfs_container_file.cc index 2baffba9c..77ef51b3d 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_file.cc +++ b/src/xenia/kernel/fs/devices/stfs_container_file.cc @@ -7,13 +7,13 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/fs/devices/stfs_container_file.h" #include -#include -#include -#include +#include "xenia/kernel/fs/device.h" +#include "xenia/kernel/fs/devices/stfs_container_entry.h" +#include "xenia/kernel/fs/stfs.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/devices/stfs_container_file.h b/src/xenia/kernel/fs/devices/stfs_container_file.h index d468130ca..64bff0c80 100644 --- a/src/xenia/kernel/fs/devices/stfs_container_file.h +++ b/src/xenia/kernel/fs/devices/stfs_container_file.h @@ -10,8 +10,8 @@ #ifndef XENIA_KERNEL_FS_DEVICES_STFS_CONTAINER_FILE_H_ #define XENIA_KERNEL_FS_DEVICES_STFS_CONTAINER_FILE_H_ -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/objects/xfile.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/entry.cc b/src/xenia/kernel/fs/entry.cc index 448207229..2af001932 100644 --- a/src/xenia/kernel/fs/entry.cc +++ b/src/xenia/kernel/fs/entry.cc @@ -7,8 +7,8 @@ ****************************************************************************** */ -#include -#include +#include "xenia/kernel/fs/entry.h" +#include "xenia/kernel/fs/device.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/entry.h b/src/xenia/kernel/fs/entry.h index 3959d083c..0553c53ad 100644 --- a/src/xenia/kernel/fs/entry.h +++ b/src/xenia/kernel/fs/entry.h @@ -13,8 +13,8 @@ #include #include -#include -#include +#include "xenia/common.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/filesystem.cc b/src/xenia/kernel/fs/filesystem.cc index 87be60c1e..fa97b9478 100644 --- a/src/xenia/kernel/fs/filesystem.cc +++ b/src/xenia/kernel/fs/filesystem.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/fs/filesystem.h" -#include -#include -#include -#include +#include "poly/string.h" +#include "xenia/kernel/fs/devices/disc_image_device.h" +#include "xenia/kernel/fs/devices/host_path_device.h" +#include "xenia/kernel/fs/devices/stfs_container_device.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/filesystem.h b/src/xenia/kernel/fs/filesystem.h index 54239cacb..690ea4284 100644 --- a/src/xenia/kernel/fs/filesystem.h +++ b/src/xenia/kernel/fs/filesystem.h @@ -15,8 +15,8 @@ #include #include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/fs/entry.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/gdfx.cc b/src/xenia/kernel/fs/gdfx.cc index 7eb8b43b2..956044374 100644 --- a/src/xenia/kernel/fs/gdfx.cc +++ b/src/xenia/kernel/fs/gdfx.cc @@ -9,9 +9,9 @@ * - abgx360 */ -#include +#include "xenia/kernel/fs/gdfx.h" -#include +#include "poly/math.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/gdfx.h b/src/xenia/kernel/fs/gdfx.h index b829efcdf..7fe2817a1 100644 --- a/src/xenia/kernel/fs/gdfx.h +++ b/src/xenia/kernel/fs/gdfx.h @@ -12,10 +12,10 @@ #include -#include -#include -#include -#include +#include "poly/mapped_memory.h" +#include "xenia/common.h" +#include "xenia/xbox.h" +#include "xenia/kernel/fs/entry.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/fs/stfs.cc b/src/xenia/kernel/fs/stfs.cc index bc0483bff..036703a52 100644 --- a/src/xenia/kernel/fs/stfs.cc +++ b/src/xenia/kernel/fs/stfs.cc @@ -9,7 +9,7 @@ * - free60 */ -#include +#include "xenia/kernel/fs/stfs.h" #include diff --git a/src/xenia/kernel/fs/stfs.h b/src/xenia/kernel/fs/stfs.h index 7d29cf204..03d13bbff 100644 --- a/src/xenia/kernel/fs/stfs.h +++ b/src/xenia/kernel/fs/stfs.h @@ -13,10 +13,10 @@ #include #include -#include -#include -#include -#include +#include "poly/mapped_memory.h" +#include "xenia/common.h" +#include "xenia/xbox.h" +#include "xenia/kernel/fs/entry.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/kernel.h b/src/xenia/kernel/kernel.h index 21c3a5cc2..e8a096cb0 100644 --- a/src/xenia/kernel/kernel.h +++ b/src/xenia/kernel/kernel.h @@ -10,6 +10,6 @@ #ifndef XENIA_KERNEL_KERNEL_H_ #define XENIA_KERNEL_KERNEL_H_ -#include +#include "xenia/kernel/modules.h" #endif // XENIA_KERNEL_KERNEL_H_ diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index c6fad30db..383dbe215 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -7,20 +7,20 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/kernel_state.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "xenia/emulator.h" +#include "xenia/kernel/dispatcher.h" +#include "xenia/kernel/xam_module.h" +#include "xenia/kernel/xboxkrnl_module.h" +#include "xenia/kernel/xboxkrnl_private.h" +#include "xenia/kernel/xobject.h" +#include "xenia/kernel/apps/apps.h" +#include "xenia/kernel/objects/xevent.h" +#include "xenia/kernel/objects/xmodule.h" +#include "xenia/kernel/objects/xnotify_listener.h" +#include "xenia/kernel/objects/xthread.h" +#include "xenia/kernel/objects/xuser_module.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/kernel_state.h b/src/xenia/kernel/kernel_state.h index ae690e21f..ebe668f44 100644 --- a/src/xenia/kernel/kernel_state.h +++ b/src/xenia/kernel/kernel_state.h @@ -13,14 +13,14 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/export_resolver.h" +#include "xenia/kernel/app.h" +#include "xenia/kernel/fs/filesystem.h" +#include "xenia/kernel/object_table.h" +#include "xenia/kernel/user_profile.h" +#include "xenia/memory.h" +#include "xenia/xbox.h" namespace xe { class Emulator; diff --git a/src/xenia/kernel/modules.h b/src/xenia/kernel/modules.h index 45e5817e8..662db1894 100644 --- a/src/xenia/kernel/modules.h +++ b/src/xenia/kernel/modules.h @@ -10,7 +10,7 @@ #ifndef XENIA_KERNEL_MODULES_H_ #define XENIA_KERNEL_MODULES_H_ -#include -#include +#include "xenia/kernel/xam_module.h" +#include "xenia/kernel/xboxkrnl_module.h" #endif // XENIA_KERNEL_MODULES_H_ diff --git a/src/xenia/kernel/native_list.cc b/src/xenia/kernel/native_list.cc index 6a301e940..3a087ef27 100644 --- a/src/xenia/kernel/native_list.cc +++ b/src/xenia/kernel/native_list.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/native_list.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/native_list.h b/src/xenia/kernel/native_list.h index d07774a2c..37f9f19bd 100644 --- a/src/xenia/kernel/native_list.h +++ b/src/xenia/kernel/native_list.h @@ -10,9 +10,9 @@ #ifndef XENIA_KERNEL_XBOXKRNL_NATIVE_LIST_H_ #define XENIA_KERNEL_XBOXKRNL_NATIVE_LIST_H_ -#include -#include -#include +#include "xenia/common.h" +#include "xenia/memory.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/object_table.cc b/src/xenia/kernel/object_table.cc index 6240280bb..203c3deb7 100644 --- a/src/xenia/kernel/object_table.cc +++ b/src/xenia/kernel/object_table.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/object_table.h" #include -#include -#include +#include "xenia/kernel/xobject.h" +#include "xenia/kernel/objects/xthread.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/object_table.h b/src/xenia/kernel/object_table.h index f49aa1194..75da74c86 100644 --- a/src/xenia/kernel/object_table.h +++ b/src/xenia/kernel/object_table.h @@ -12,8 +12,8 @@ #include -#include -#include +#include "xenia/common.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xenumerator.cc b/src/xenia/kernel/objects/xenumerator.cc index 3fe25297d..21c0e51e2 100644 --- a/src/xenia/kernel/objects/xenumerator.cc +++ b/src/xenia/kernel/objects/xenumerator.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/objects/xenumerator.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xenumerator.h b/src/xenia/kernel/objects/xenumerator.h index b1bfd0f37..2f6f32499 100644 --- a/src/xenia/kernel/objects/xenumerator.h +++ b/src/xenia/kernel/objects/xenumerator.h @@ -10,8 +10,8 @@ #ifndef XENIA_KERNEL_XBOXKRNL_XENUMERATOR_H_ #define XENIA_KERNEL_XBOXKRNL_XENUMERATOR_H_ -#include -#include +#include "xenia/kernel/xobject.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xevent.cc b/src/xenia/kernel/objects/xevent.cc index e00593409..118759f38 100644 --- a/src/xenia/kernel/objects/xevent.cc +++ b/src/xenia/kernel/objects/xevent.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/objects/xevent.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xevent.h b/src/xenia/kernel/objects/xevent.h index b4e944143..831666a50 100644 --- a/src/xenia/kernel/objects/xevent.h +++ b/src/xenia/kernel/objects/xevent.h @@ -10,8 +10,8 @@ #ifndef XENIA_KERNEL_XBOXKRNL_XEVENT_H_ #define XENIA_KERNEL_XBOXKRNL_XEVENT_H_ -#include -#include +#include "xenia/kernel/xobject.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xfile.cc b/src/xenia/kernel/objects/xfile.cc index 62060bb31..62feacae3 100644 --- a/src/xenia/kernel/objects/xfile.cc +++ b/src/xenia/kernel/objects/xfile.cc @@ -7,10 +7,10 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/objects/xfile.h" -#include -#include +#include "xenia/kernel/async_request.h" +#include "xenia/kernel/objects/xevent.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xfile.h b/src/xenia/kernel/objects/xfile.h index 42057447a..48415b56f 100644 --- a/src/xenia/kernel/objects/xfile.h +++ b/src/xenia/kernel/objects/xfile.h @@ -10,9 +10,9 @@ #ifndef XENIA_KERNEL_XBOXKRNL_XFILE_H_ #define XENIA_KERNEL_XBOXKRNL_XFILE_H_ -#include +#include "xenia/kernel/xobject.h" -#include +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xkernel_module.cc b/src/xenia/kernel/objects/xkernel_module.cc index e9444d7e9..c76803378 100644 --- a/src/xenia/kernel/objects/xkernel_module.cc +++ b/src/xenia/kernel/objects/xkernel_module.cc @@ -7,11 +7,11 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/objects/xkernel_module.h" -#include -#include -#include +#include "xenia/emulator.h" +#include "xenia/cpu/cpu.h" +#include "xenia/kernel/objects/xthread.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xkernel_module.h b/src/xenia/kernel/objects/xkernel_module.h index e2ff4c28b..6c780404b 100644 --- a/src/xenia/kernel/objects/xkernel_module.h +++ b/src/xenia/kernel/objects/xkernel_module.h @@ -10,8 +10,8 @@ #ifndef XENIA_KERNEL_XBOXKRNL_XKERNEL_MODULE_H_ #define XENIA_KERNEL_XBOXKRNL_XKERNEL_MODULE_H_ -#include -#include +#include "xenia/emulator.h" +#include "xenia/kernel/objects/xmodule.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xmodule.cc b/src/xenia/kernel/objects/xmodule.cc index aea7198f9..b64bc265e 100644 --- a/src/xenia/kernel/objects/xmodule.cc +++ b/src/xenia/kernel/objects/xmodule.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/objects/xmodule.h" -#include +#include "xdb/protocol.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xmodule.h b/src/xenia/kernel/objects/xmodule.h index dd5743684..0abe66931 100644 --- a/src/xenia/kernel/objects/xmodule.h +++ b/src/xenia/kernel/objects/xmodule.h @@ -12,8 +12,8 @@ #include -#include -#include +#include "xenia/kernel/xobject.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xmutant.cc b/src/xenia/kernel/objects/xmutant.cc index b915f314e..bb73a6260 100644 --- a/src/xenia/kernel/objects/xmutant.cc +++ b/src/xenia/kernel/objects/xmutant.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/objects/xmutant.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xmutant.h b/src/xenia/kernel/objects/xmutant.h index be554676c..11da04699 100644 --- a/src/xenia/kernel/objects/xmutant.h +++ b/src/xenia/kernel/objects/xmutant.h @@ -10,8 +10,8 @@ #ifndef XENIA_KERNEL_XBOXKRNL_XMUTANT_H_ #define XENIA_KERNEL_XBOXKRNL_XMUTANT_H_ -#include -#include +#include "xenia/kernel/xobject.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xnotify_listener.cc b/src/xenia/kernel/objects/xnotify_listener.cc index 8825de59d..495e9cfde 100644 --- a/src/xenia/kernel/objects/xnotify_listener.cc +++ b/src/xenia/kernel/objects/xnotify_listener.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/objects/xnotify_listener.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xnotify_listener.h b/src/xenia/kernel/objects/xnotify_listener.h index 708230eea..6b5eb7887 100644 --- a/src/xenia/kernel/objects/xnotify_listener.h +++ b/src/xenia/kernel/objects/xnotify_listener.h @@ -12,8 +12,8 @@ #include -#include -#include +#include "xenia/kernel/xobject.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xsemaphore.cc b/src/xenia/kernel/objects/xsemaphore.cc index c8aba8ce3..be1472463 100644 --- a/src/xenia/kernel/objects/xsemaphore.cc +++ b/src/xenia/kernel/objects/xsemaphore.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/objects/xsemaphore.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xsemaphore.h b/src/xenia/kernel/objects/xsemaphore.h index 43fb13e3d..892d3d70a 100644 --- a/src/xenia/kernel/objects/xsemaphore.h +++ b/src/xenia/kernel/objects/xsemaphore.h @@ -10,8 +10,8 @@ #ifndef XENIA_KERNEL_XBOXKRNL_XSEMAPHORE_H_ #define XENIA_KERNEL_XBOXKRNL_XSEMAPHORE_H_ -#include -#include +#include "xenia/kernel/xobject.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xthread.cc b/src/xenia/kernel/objects/xthread.cc index ed80ee3d8..7be0363a8 100644 --- a/src/xenia/kernel/objects/xthread.cc +++ b/src/xenia/kernel/objects/xthread.cc @@ -7,14 +7,14 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/objects/xthread.h" -#include -#include -#include -#include -#include -#include +#include "poly/poly.h" +#include "xdb/protocol.h" +#include "xenia/cpu/cpu.h" +#include "xenia/kernel/native_list.h" +#include "xenia/kernel/objects/xevent.h" +#include "xenia/kernel/objects/xuser_module.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xthread.h b/src/xenia/kernel/objects/xthread.h index 1f676ecba..4a4fad19d 100644 --- a/src/xenia/kernel/objects/xthread.h +++ b/src/xenia/kernel/objects/xthread.h @@ -14,9 +14,9 @@ #include #include -#include -#include -#include +#include "xenia/cpu/xenon_thread_state.h" +#include "xenia/kernel/xobject.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xtimer.cc b/src/xenia/kernel/objects/xtimer.cc index 09c5a3282..35049f80c 100644 --- a/src/xenia/kernel/objects/xtimer.cc +++ b/src/xenia/kernel/objects/xtimer.cc @@ -7,9 +7,9 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/objects/xtimer.h" -#include +#include "xenia/cpu/processor.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xtimer.h b/src/xenia/kernel/objects/xtimer.h index 3b52cd2fc..bf7fffffb 100644 --- a/src/xenia/kernel/objects/xtimer.h +++ b/src/xenia/kernel/objects/xtimer.h @@ -10,8 +10,8 @@ #ifndef XENIA_KERNEL_XBOXKRNL_XTIMER_H_ #define XENIA_KERNEL_XBOXKRNL_XTIMER_H_ -#include -#include +#include "xenia/kernel/xobject.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xuser_module.cc b/src/xenia/kernel/objects/xuser_module.cc index 2f9449448..29bf7f79c 100644 --- a/src/xenia/kernel/objects/xuser_module.cc +++ b/src/xenia/kernel/objects/xuser_module.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/objects/xuser_module.h" -#include -#include -#include -#include +#include "xenia/emulator.h" +#include "xenia/cpu/cpu.h" +#include "xenia/kernel/objects/xfile.h" +#include "xenia/kernel/objects/xthread.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/objects/xuser_module.h b/src/xenia/kernel/objects/xuser_module.h index 5d479c268..4ef694e73 100644 --- a/src/xenia/kernel/objects/xuser_module.h +++ b/src/xenia/kernel/objects/xuser_module.h @@ -10,11 +10,11 @@ #ifndef XENIA_KERNEL_XBOXKRNL_XUSER_MODULE_H_ #define XENIA_KERNEL_XBOXKRNL_XUSER_MODULE_H_ -#include +#include "xenia/kernel/objects/xmodule.h" -#include -#include -#include +#include "xenia/export_resolver.h" +#include "xenia/kernel/util/xex2.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/user_profile.cc b/src/xenia/kernel/user_profile.cc index 9c9a3cfd4..b53a9d0d7 100644 --- a/src/xenia/kernel/user_profile.cc +++ b/src/xenia/kernel/user_profile.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/user_profile.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/user_profile.h b/src/xenia/kernel/user_profile.h index d654396ae..eaccbcd95 100644 --- a/src/xenia/kernel/user_profile.h +++ b/src/xenia/kernel/user_profile.h @@ -15,8 +15,8 @@ #include #include -#include -#include +#include "xenia/common.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/util/export_table_pre.inc b/src/xenia/kernel/util/export_table_pre.inc index a03a01d4c..687591642 100644 --- a/src/xenia/kernel/util/export_table_pre.inc +++ b/src/xenia/kernel/util/export_table_pre.inc @@ -12,11 +12,11 @@ * Use this to build tables of exports: * * // Build the export table used for resolution. - * #include + * #include "xenia/kernel/util/export_table_pre.inc" * static KernelExport my_module_export_table[] = { - * #include + * #include "xenia/kernel/my_module/my_module_table.inc" * }; - * #include + * #include "xenia/kernel/util/export_table_post.inc" * export_resolver_->RegisterTable( * "my_module.xex", * my_module_export_table, poly::countof(my_module_export_table)); diff --git a/src/xenia/kernel/util/ordinal_table_pre.inc b/src/xenia/kernel/util/ordinal_table_pre.inc index 928b44b0c..d80e5098a 100644 --- a/src/xenia/kernel/util/ordinal_table_pre.inc +++ b/src/xenia/kernel/util/ordinal_table_pre.inc @@ -12,13 +12,13 @@ * Use this to build tables of constants describing the ordinals: * * // Build an ordinal enum to make it easy to lookup ordinals. - * #include + * #include "xenia/kernel/util/ordinal_table_pre.inc" * namespace ordinals { * enum { - * #include + * #include "xenia/kernel/my_module/my_module_table.inc" * }; * } // namespace ordinals - * #include + * #include "xenia/kernel/util/ordinal_table_post.inc" */ diff --git a/src/xenia/kernel/util/shim_utils.h b/src/xenia/kernel/util/shim_utils.h index 0ef263435..6b3f6bdd5 100644 --- a/src/xenia/kernel/util/shim_utils.h +++ b/src/xenia/kernel/util/shim_utils.h @@ -10,9 +10,9 @@ #ifndef XENIA_KERNEL_UTIL_SHIM_UTILS_H_ #define XENIA_KERNEL_UTIL_SHIM_UTILS_H_ -#include -#include -#include +#include "alloy/frontend/ppc/ppc_context.h" +#include "xenia/common.h" +#include "xenia/export_resolver.h" namespace xe { diff --git a/src/xenia/kernel/util/xex2.cc b/src/xenia/kernel/util/xex2.cc index 44a6a79bd..a5d62435c 100644 --- a/src/xenia/kernel/util/xex2.cc +++ b/src/xenia/kernel/util/xex2.cc @@ -7,19 +7,19 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/util/xex2.h" #include #include #include -#include -#include -#include -#include -#include -#include -#include +#include "poly/math.h" +#include "third_party/crypto/rijndael-alg-fst.h" +#include "third_party/crypto/rijndael-alg-fst.c" +#include "third_party/mspack/lzx.h" +#include "third_party/mspack/lzxd.c" +#include "third_party/mspack/mspack.h" +#include "third_party/pe/pe_image.h" // using namespace alloy; diff --git a/src/xenia/kernel/util/xex2.h b/src/xenia/kernel/util/xex2.h index bb806648d..fac0a56a6 100644 --- a/src/xenia/kernel/util/xex2.h +++ b/src/xenia/kernel/util/xex2.h @@ -10,9 +10,9 @@ #ifndef XENIA_KERNEL_UTIL_XEX2_H_ #define XENIA_KERNEL_UTIL_XEX2_H_ -#include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/util/xex2_info.h" +#include "xenia/memory.h" typedef struct { int reserved; } xe_xex2_options_t; diff --git a/src/xenia/kernel/util/xex2_info.h b/src/xenia/kernel/util/xex2_info.h index 6ebdb8674..419be0d23 100644 --- a/src/xenia/kernel/util/xex2_info.h +++ b/src/xenia/kernel/util/xex2_info.h @@ -10,7 +10,7 @@ #ifndef XENIA_KERNEL_XEX2_INFO_H_ #define XENIA_KERNEL_XEX2_INFO_H_ -#include +#include "xenia/common.h" typedef enum { XEX_HEADER_RESOURCE_INFO = 0x000002FF, diff --git a/src/xenia/kernel/xam_content.cc b/src/xenia/kernel/xam_content.cc index 3b1c97a4d..0a87f8f35 100644 --- a/src/xenia/kernel/xam_content.cc +++ b/src/xenia/kernel/xam_content.cc @@ -7,11 +7,11 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/xam_private.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam_info.cc b/src/xenia/kernel/xam_info.cc index 8109b086a..af51834dd 100644 --- a/src/xenia/kernel/xam_info.cc +++ b/src/xenia/kernel/xam_info.cc @@ -7,13 +7,13 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/objects/xenumerator.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/util/xex2.h" +#include "xenia/kernel/xam_private.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam_input.cc b/src/xenia/kernel/xam_input.cc index eafc7dda1..1cf1e326b 100644 --- a/src/xenia/kernel/xam_input.cc +++ b/src/xenia/kernel/xam_input.cc @@ -7,13 +7,13 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/emulator.h" +#include "xenia/hid/hid.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/xam_private.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam_module.cc b/src/xenia/kernel/xam_module.cc index 8fa2edff0..d32d18bef 100644 --- a/src/xenia/kernel/xam_module.cc +++ b/src/xenia/kernel/xam_module.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/xam_module.h" -#include -#include -#include -#include +#include "poly/math.h" +#include "xenia/export_resolver.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/xam_private.h" namespace xe { namespace kernel { @@ -20,11 +20,11 @@ namespace kernel { XamModule::XamModule(Emulator* emulator, KernelState* kernel_state) : XKernelModule(kernel_state, "xe:\\xam.xex") { // Build the export table used for resolution. -#include +#include "xenia/kernel/util/export_table_pre.inc" static KernelExport xam_export_table[] = { -#include +#include "xenia/kernel/xam_table.inc" }; -#include +#include "xenia/kernel/util/export_table_post.inc" export_resolver_->RegisterTable("xam.xex", xam_export_table, poly::countof(xam_export_table)); diff --git a/src/xenia/kernel/xam_module.h b/src/xenia/kernel/xam_module.h index 353f03ae5..ffa1fb0ab 100644 --- a/src/xenia/kernel/xam_module.h +++ b/src/xenia/kernel/xam_module.h @@ -10,10 +10,10 @@ #ifndef XENIA_KERNEL_XAM_H_ #define XENIA_KERNEL_XAM_H_ -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/export_resolver.h" +#include "xenia/kernel/objects/xkernel_module.h" +#include "xenia/kernel/xam_ordinals.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam_msg.cc b/src/xenia/kernel/xam_msg.cc index fca069e67..e51f8f5ff 100644 --- a/src/xenia/kernel/xam_msg.cc +++ b/src/xenia/kernel/xam_msg.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/objects/xevent.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/xam_private.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam_net.cc b/src/xenia/kernel/xam_net.cc index 3ac6ef62c..cbc6035ce 100644 --- a/src/xenia/kernel/xam_net.cc +++ b/src/xenia/kernel/xam_net.cc @@ -9,11 +9,11 @@ #include -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/xam_private.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam_notify.cc b/src/xenia/kernel/xam_notify.cc index 5a93bfb32..417a225cd 100644 --- a/src/xenia/kernel/xam_notify.cc +++ b/src/xenia/kernel/xam_notify.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/objects/xnotify_listener.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/xam_private.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam_ordinals.h b/src/xenia/kernel/xam_ordinals.h index e7a71561d..b5eeae966 100644 --- a/src/xenia/kernel/xam_ordinals.h +++ b/src/xenia/kernel/xam_ordinals.h @@ -10,16 +10,16 @@ #ifndef XENIA_KERNEL_XAM_ORDINALS_H_ #define XENIA_KERNEL_XAM_ORDINALS_H_ -#include -#include +#include "xenia/common.h" +#include "xenia/export_resolver.h" // Build an ordinal enum to make it easy to lookup ordinals. -#include +#include "xenia/kernel/util/ordinal_table_pre.inc" namespace ordinals { enum { -#include +#include "xenia/kernel/xam_table.inc" }; } // namespace ordinals -#include +#include "xenia/kernel/util/ordinal_table_post.inc" #endif // XENIA_KERNEL_XAM_ORDINALS_H_ diff --git a/src/xenia/kernel/xam_private.h b/src/xenia/kernel/xam_private.h index bca7b2ac8..87f33b060 100644 --- a/src/xenia/kernel/xam_private.h +++ b/src/xenia/kernel/xam_private.h @@ -10,8 +10,8 @@ #ifndef XENIA_KERNEL_XAM_PRIVATE_H_ #define XENIA_KERNEL_XAM_PRIVATE_H_ -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/xam_ordinals.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam_ui.cc b/src/xenia/kernel/xam_ui.cc index 553c43161..f25a20b39 100644 --- a/src/xenia/kernel/xam_ui.cc +++ b/src/xenia/kernel/xam_ui.cc @@ -7,11 +7,11 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/xam_private.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam_user.cc b/src/xenia/kernel/xam_user.cc index 4b34e5bad..c03a6649d 100644 --- a/src/xenia/kernel/xam_user.cc +++ b/src/xenia/kernel/xam_user.cc @@ -7,13 +7,13 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/objects/xenumerator.h" +#include "xenia/kernel/objects/xthread.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/xam_private.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam_video.cc b/src/xenia/kernel/xam_video.cc index 4b06939d5..fed42db97 100644 --- a/src/xenia/kernel/xam_video.cc +++ b/src/xenia/kernel/xam_video.cc @@ -7,11 +7,11 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/xam_private.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam_voice.cc b/src/xenia/kernel/xam_voice.cc index 4bdcc106e..fb48e1009 100644 --- a/src/xenia/kernel/xam_voice.cc +++ b/src/xenia/kernel/xam_voice.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/emulator.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/xam_private.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_audio.cc b/src/xenia/kernel/xboxkrnl_audio.cc index dfd723e10..c942eed79 100644 --- a/src/xenia/kernel/xboxkrnl_audio.cc +++ b/src/xenia/kernel/xboxkrnl_audio.cc @@ -7,13 +7,13 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include -#include -#include +#include "xenia/apu/apu.h" +#include "xenia/common.h" +#include "xenia/emulator.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/xboxkrnl_private.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_debug.cc b/src/xenia/kernel/xboxkrnl_debug.cc index 95aa084d6..a954d3c31 100644 --- a/src/xenia/kernel/xboxkrnl_debug.cc +++ b/src/xenia/kernel/xboxkrnl_debug.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/objects/xthread.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/xboxkrnl_private.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_hal.cc b/src/xenia/kernel/xboxkrnl_hal.cc index 4ba62f831..8c75e65f4 100644 --- a/src/xenia/kernel/xboxkrnl_hal.cc +++ b/src/xenia/kernel/xboxkrnl_hal.cc @@ -7,11 +7,11 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/xboxkrnl_private.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl_io.cc index 40dcacff7..074d82cbb 100644 --- a/src/xenia/kernel/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl_io.cc @@ -7,15 +7,15 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "poly/memory.h" +#include "xenia/common.h" +#include "xenia/kernel/async_request.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/objects/xevent.h" +#include "xenia/kernel/objects/xfile.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/xboxkrnl_private.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl_memory.cc index 8e40b8278..0a21396fc 100644 --- a/src/xenia/kernel/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl_memory.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include -#include +#include "poly/math.h" +#include "xenia/common.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/xboxkrnl_private.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_misc.cc b/src/xenia/kernel/xboxkrnl_misc.cc index cd2f5ca76..2d09ebc11 100644 --- a/src/xenia/kernel/xboxkrnl_misc.cc +++ b/src/xenia/kernel/xboxkrnl_misc.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/objects/xthread.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/xboxkrnl_private.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_module.cc b/src/xenia/kernel/xboxkrnl_module.cc index 08be07e73..2c07bcd22 100644 --- a/src/xenia/kernel/xboxkrnl_module.cc +++ b/src/xenia/kernel/xboxkrnl_module.cc @@ -7,15 +7,15 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/xboxkrnl_module.h" #include -#include -#include -#include -#include -#include -#include +#include "poly/math.h" +#include "xenia/emulator.h" +#include "xenia/export_resolver.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/xboxkrnl_private.h" +#include "xenia/kernel/objects/xuser_module.h" DEFINE_bool(abort_before_entry, false, "Abort execution right before launching the module."); @@ -26,11 +26,11 @@ namespace kernel { XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) : XKernelModule(kernel_state, "xe:\\xboxkrnl.exe") { // Build the export table used for resolution. -#include +#include "xenia/kernel/util/export_table_pre.inc" static KernelExport xboxkrnl_export_table[] = { -#include +#include "xenia/kernel/xboxkrnl_table.inc" }; -#include +#include "xenia/kernel/util/export_table_post.inc" export_resolver_->RegisterTable("xboxkrnl.exe", xboxkrnl_export_table, poly::countof(xboxkrnl_export_table)); diff --git a/src/xenia/kernel/xboxkrnl_module.h b/src/xenia/kernel/xboxkrnl_module.h index d1e97d260..74a7486cb 100644 --- a/src/xenia/kernel/xboxkrnl_module.h +++ b/src/xenia/kernel/xboxkrnl_module.h @@ -10,13 +10,13 @@ #ifndef XENIA_KERNEL_XBOXKRNL_MODULE_H_ #define XENIA_KERNEL_XBOXKRNL_MODULE_H_ -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/export_resolver.h" +#include "xenia/kernel/objects/xkernel_module.h" +#include "xenia/kernel/xboxkrnl_ordinals.h" // All of the exported functions: -#include +#include "xenia/kernel/xboxkrnl_rtl.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_modules.cc b/src/xenia/kernel/xboxkrnl_modules.cc index 1a57e4cdd..b7fdb6eda 100644 --- a/src/xenia/kernel/xboxkrnl_modules.cc +++ b/src/xenia/kernel/xboxkrnl_modules.cc @@ -7,13 +7,13 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/objects/xuser_module.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/util/xex2.h" +#include "xenia/kernel/xboxkrnl_private.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_ob.cc b/src/xenia/kernel/xboxkrnl_ob.cc index a5589e359..7aeb9a4d1 100644 --- a/src/xenia/kernel/xboxkrnl_ob.cc +++ b/src/xenia/kernel/xboxkrnl_ob.cc @@ -7,13 +7,13 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/objects/xthread.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/xboxkrnl_private.h" +#include "xenia/kernel/xobject.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_ordinals.h b/src/xenia/kernel/xboxkrnl_ordinals.h index 95c0d5087..18d8ee3bc 100644 --- a/src/xenia/kernel/xboxkrnl_ordinals.h +++ b/src/xenia/kernel/xboxkrnl_ordinals.h @@ -10,16 +10,16 @@ #ifndef XENIA_KERNEL_XBOXKRNL_ORDINALS_H_ #define XENIA_KERNEL_XBOXKRNL_ORDINALS_H_ -#include -#include +#include "xenia/common.h" +#include "xenia/export_resolver.h" // Build an ordinal enum to make it easy to lookup ordinals. -#include +#include "xenia/kernel/util/ordinal_table_pre.inc" namespace ordinals { enum { -#include +#include "xenia/kernel/xboxkrnl_table.inc" }; } // namespace ordinals -#include +#include "xenia/kernel/util/ordinal_table_post.inc" #endif // XENIA_KERNEL_XBOXKRNL_ORDINALS_H_ diff --git a/src/xenia/kernel/xboxkrnl_private.h b/src/xenia/kernel/xboxkrnl_private.h index 3bb1bc76a..89e9aeaab 100644 --- a/src/xenia/kernel/xboxkrnl_private.h +++ b/src/xenia/kernel/xboxkrnl_private.h @@ -10,8 +10,8 @@ #ifndef XENIA_KERNEL_XBOXKRNL_PRIVATE_H_ #define XENIA_KERNEL_XBOXKRNL_PRIVATE_H_ -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/xboxkrnl_ordinals.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl_rtl.cc index 8a58f39b0..e1b7ba421 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl_rtl.cc @@ -7,15 +7,15 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/xboxkrnl_rtl.h" -#include -#include -#include -#include -#include -#include -#include +#include "poly/string.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/xboxkrnl_private.h" +#include "xenia/kernel/objects/xthread.h" +#include "xenia/kernel/objects/xuser_module.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/util/xex2.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_rtl.h b/src/xenia/kernel/xboxkrnl_rtl.h index abec61852..1da3cdce5 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.h +++ b/src/xenia/kernel/xboxkrnl_rtl.h @@ -10,8 +10,8 @@ #ifndef XENIA_KERNEL_XBOXKRNL_RTL_H_ #define XENIA_KERNEL_XBOXKRNL_RTL_H_ -#include -#include +#include "xenia/common.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_strings.cc b/src/xenia/kernel/xboxkrnl_strings.cc index 0c774fbd4..9723f27a7 100644 --- a/src/xenia/kernel/xboxkrnl_strings.cc +++ b/src/xenia/kernel/xboxkrnl_strings.cc @@ -7,14 +7,14 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/objects/xthread.h" +#include "xenia/kernel/objects/xuser_module.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/util/xex2.h" +#include "xenia/kernel/xboxkrnl_private.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index 89299a2d7..b2dd2946f 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -7,19 +7,19 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/cpu/processor.h" +#include "xenia/kernel/dispatcher.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/native_list.h" +#include "xenia/kernel/objects/xevent.h" +#include "xenia/kernel/objects/xmutant.h" +#include "xenia/kernel/objects/xsemaphore.h" +#include "xenia/kernel/objects/xthread.h" +#include "xenia/kernel/objects/xtimer.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/xboxkrnl_private.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_usbcam.cc b/src/xenia/kernel/xboxkrnl_usbcam.cc index a3625b437..cba1be0da 100644 --- a/src/xenia/kernel/xboxkrnl_usbcam.cc +++ b/src/xenia/kernel/xboxkrnl_usbcam.cc @@ -7,11 +7,11 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/xboxkrnl_private.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xboxkrnl_video.cc b/src/xenia/kernel/xboxkrnl_video.cc index e15489aa7..db49b1288 100644 --- a/src/xenia/kernel/xboxkrnl_video.cc +++ b/src/xenia/kernel/xboxkrnl_video.cc @@ -7,16 +7,16 @@ ****************************************************************************** */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "xenia/common.h" +#include "xenia/cpu/cpu.h" +#include "xenia/emulator.h" +#include "xenia/gpu/graphics_system.h" +#include "xenia/gpu/xenos.h" +#include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/util/shim_utils.h" +#include "xenia/kernel/xboxkrnl_private.h" +#include "xenia/kernel/xboxkrnl_rtl.h" +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xobject.cc b/src/xenia/kernel/xobject.cc index 2016fe815..736760bf8 100644 --- a/src/xenia/kernel/xobject.cc +++ b/src/xenia/kernel/xobject.cc @@ -7,12 +7,12 @@ ****************************************************************************** */ -#include +#include "xenia/kernel/xobject.h" -#include -#include -#include -#include +#include "xenia/kernel/xboxkrnl_private.h" +#include "xenia/kernel/objects/xevent.h" +#include "xenia/kernel/objects/xmutant.h" +#include "xenia/kernel/objects/xsemaphore.h" namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xobject.h b/src/xenia/kernel/xobject.h index 021cc3e66..86e43a423 100644 --- a/src/xenia/kernel/xobject.h +++ b/src/xenia/kernel/xobject.h @@ -12,9 +12,9 @@ #include -#include +#include "xenia/kernel/kernel_state.h" -#include +#include "xenia/xbox.h" namespace xe { namespace kernel { diff --git a/src/xenia/logging.h b/src/xenia/logging.h index ebf988513..0787fa07a 100644 --- a/src/xenia/logging.h +++ b/src/xenia/logging.h @@ -12,7 +12,7 @@ #include -#include +#include "poly/logging.h" #define XE_OPTION_ENABLE_LOGGING 1 #define XE_OPTION_LOG_ERROR 1 diff --git a/src/xenia/memory.cc b/src/xenia/memory.cc index f1da724af..03beb85a2 100644 --- a/src/xenia/memory.cc +++ b/src/xenia/memory.cc @@ -7,19 +7,19 @@ ****************************************************************************** */ -#include +#include "xenia/memory.h" #include #include #include -#include -#include +#include "poly/math.h" +#include "xenia/cpu/mmio_handler.h" using namespace xe; // TODO(benvanik): move xbox.h out -#include +#include "xenia/xbox.h" #if !XE_PLATFORM_WIN32 #include @@ -38,7 +38,7 @@ using namespace xe; #if XE_DEBUG #define FOOTERS 0 #endif // XE_DEBUG -#include +#include "third_party/dlmalloc/malloc.c.h" DEFINE_bool(log_heap, false, "Log heap structure on alloc/free."); DEFINE_uint64( diff --git a/src/xenia/memory.h b/src/xenia/memory.h index 8bc741d77..868b4f293 100644 --- a/src/xenia/memory.h +++ b/src/xenia/memory.h @@ -12,10 +12,10 @@ #include -#include +#include "alloy/memory.h" -#include -#include +#include "xenia/common.h" +#include "xenia/cpu/mmio_handler.h" typedef struct xe_ppc_state xe_ppc_state_t; diff --git a/src/xenia/profiling.cc b/src/xenia/profiling.cc index f60a2a6ce..3b93c7478 100644 --- a/src/xenia/profiling.cc +++ b/src/xenia/profiling.cc @@ -7,7 +7,7 @@ ****************************************************************************** */ -#include +#include "xenia/logging.h" #define MICROPROFILE_ENABLED 1 #define MICROPROFILEUI_ENABLED 1 @@ -25,7 +25,7 @@ #include #include -#include +#include "xenia/profiling.h" namespace xe { diff --git a/src/xenia/profiling.h b/src/xenia/profiling.h index 2428c78d3..6ec644c5c 100644 --- a/src/xenia/profiling.h +++ b/src/xenia/profiling.h @@ -12,7 +12,7 @@ #include -#include +#include "poly/string.h" #define XE_OPTION_PROFILING 1 #if XE_LIKE_WIN32 diff --git a/src/xenia/ui/main_window.cc b/src/xenia/ui/main_window.cc index 059d5d9f7..52d0e19ac 100644 --- a/src/xenia/ui/main_window.cc +++ b/src/xenia/ui/main_window.cc @@ -7,11 +7,11 @@ ****************************************************************************** */ -#include +#include "xenia/ui/main_window.h" -#include -#include -#include +#include "poly/logging.h" +#include "poly/threading.h" +#include "xenia/emulator.h" namespace xe { namespace ui { diff --git a/src/xenia/ui/main_window.h b/src/xenia/ui/main_window.h index 8c83015e4..093731a95 100644 --- a/src/xenia/ui/main_window.h +++ b/src/xenia/ui/main_window.h @@ -10,12 +10,12 @@ #ifndef XENIA_UI_MAIN_WINDOW_H_ #define XENIA_UI_MAIN_WINDOW_H_ -#include -#include +#include "poly/ui/window.h" +#include "xenia/xbox.h" // TODO(benvanik): only on windows. -#include -#include +#include "poly/ui/win32/win32_loop.h" +#include "poly/ui/win32/win32_window.h" namespace xe { class Emulator; diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index 170f3e4d8..89cc78326 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -10,8 +10,8 @@ #ifndef XENIA_XBOX_H_ #define XENIA_XBOX_H_ -#include -#include +#include "poly/memory.h" +#include "xenia/common.h" namespace xe { diff --git a/src/xenia/xenia_main.cc b/src/xenia/xenia_main.cc index 165607bcc..4803c07b0 100644 --- a/src/xenia/xenia_main.cc +++ b/src/xenia/xenia_main.cc @@ -8,10 +8,10 @@ */ #include -#include -#include -#include -#include +#include "poly/main.h" +#include "xenia/emulator.h" +#include "xenia/kernel/kernel.h" +#include "xenia/ui/main_window.h" DEFINE_string(target, "", "Specifies the target .xex or .iso to execute."); From dd6a1b8cd4a1af66e4b411d9bd88e96b066cc89b Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 31 Jan 2015 22:51:45 -0800 Subject: [PATCH 377/388] Latest xbyak. --- third_party/xbyak | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/xbyak b/third_party/xbyak index 099a51d66..415ebd3c6 160000 --- a/third_party/xbyak +++ b/third_party/xbyak @@ -1 +1 @@ -Subproject commit 099a51d66535921a511e355660c231d7acdfc27d +Subproject commit 415ebd3c6bd11ff3da2cc2fecb90ff746d65cb2b From 3454d1bdf5ec9e3b08f40cfa1c43e6febd6e803b Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sat, 31 Jan 2015 23:51:45 -0800 Subject: [PATCH 378/388] EntryTable needs a rewrite. --- src/alloy/runtime/entry_table.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/alloy/runtime/entry_table.cc b/src/alloy/runtime/entry_table.cc index 96c97132d..3cbc015f6 100644 --- a/src/alloy/runtime/entry_table.cc +++ b/src/alloy/runtime/entry_table.cc @@ -39,6 +39,9 @@ Entry* EntryTable::Get(uint64_t address) { } Entry::Status EntryTable::GetOrCreate(uint64_t address, Entry** out_entry) { + // TODO(benvanik): replace with a map with wait-free for find. + // https://github.com/facebook/folly/blob/master/folly/AtomicHashMap.h + lock_.lock(); const auto& it = map_.find(address); Entry* entry = it != map_.end() ? it->second : nullptr; @@ -50,7 +53,7 @@ Entry::Status EntryTable::GetOrCreate(uint64_t address, Entry** out_entry) { do { lock_.unlock(); // TODO(benvanik): sleep for less time? - poly::threading::Sleep(std::chrono::microseconds(100)); + poly::threading::Sleep(std::chrono::microseconds(10)); lock_.lock(); } while (entry->status == Entry::STATUS_COMPILING); } From cfcd6118c2f451c98a066e44e2faef6c91874b06 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 1 Feb 2015 09:05:35 -0800 Subject: [PATCH 379/388] Fixing GetTickCount. There's likely a better way to do this (on demand), but this works for now. --- src/xenia/kernel/xboxkrnl_module.cc | 31 +++++++++++++++++++++----- src/xenia/kernel/xboxkrnl_module.h | 1 + src/xenia/kernel/xboxkrnl_threading.cc | 2 ++ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/xenia/kernel/xboxkrnl_module.cc b/src/xenia/kernel/xboxkrnl_module.cc index 2c07bcd22..20e14df5b 100644 --- a/src/xenia/kernel/xboxkrnl_module.cc +++ b/src/xenia/kernel/xboxkrnl_module.cc @@ -24,7 +24,8 @@ namespace xe { namespace kernel { XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) - : XKernelModule(kernel_state, "xe:\\xboxkrnl.exe") { + : XKernelModule(kernel_state, "xe:\\xboxkrnl.exe"), + timestamp_timer_(nullptr) { // Build the export table used for resolution. #include "xenia/kernel/util/export_table_pre.inc" static KernelExport xboxkrnl_export_table[] = { @@ -72,11 +73,13 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) // 0x00000000, 0x06, 0x00, 0x00, 0x00, 0x00000000, 0x0000, 0x0000 // Games seem to check if bit 26 (0x20) is set, which at least for xbox1 // was whether an HDD was present. Not sure what the other flags are. + // + // aomega08 says the value is 0x02000817, bit 27: debug mode on. + // When that is set, though, allocs crash in weird ways. uint32_t pXboxHardwareInfo = (uint32_t)memory_->HeapAlloc(0, 16, 0); export_resolver_->SetVariableMapping( "xboxkrnl.exe", ordinals::XboxHardwareInfo, pXboxHardwareInfo); - poly::store_and_swap(mem + pXboxHardwareInfo + 0, - 0x00000000); // flags + poly::store_and_swap(mem + pXboxHardwareInfo + 0, 0); // flags poly::store_and_swap(mem + pXboxHardwareInfo + 4, 0x06); // cpu count // Remaining 11b are zeroes? @@ -120,18 +123,34 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state) poly::store_and_swap(mem + pXboxKrnlVersion + 0, 2); poly::store_and_swap(mem + pXboxKrnlVersion + 2, 0xFFFF); poly::store_and_swap(mem + pXboxKrnlVersion + 4, 0xFFFF); - poly::store_and_swap(mem + pXboxKrnlVersion + 6, 0xFFFF); + poly::store_and_swap(mem + pXboxKrnlVersion + 6, 0x80); + poly::store_and_swap(mem + pXboxKrnlVersion + 7, 0x00); // KeTimeStampBundle (ad) + // This must be updated during execution, at 1ms intevals. + // We setup a system timer here to do that. uint32_t pKeTimeStampBundle = (uint32_t)memory_->HeapAlloc(0, 24, 0); export_resolver_->SetVariableMapping( "xboxkrnl.exe", ordinals::KeTimeStampBundle, pKeTimeStampBundle); poly::store_and_swap(mem + pKeTimeStampBundle + 0, 0); poly::store_and_swap(mem + pKeTimeStampBundle + 8, 0); - poly::store_and_swap(mem + pKeTimeStampBundle + 12, 0); + poly::store_and_swap(mem + pKeTimeStampBundle + 16, GetTickCount()); + poly::store_and_swap(mem + pKeTimeStampBundle + 20, 0); + CreateTimerQueueTimer(×tamp_timer_, nullptr, + [](PVOID param, BOOLEAN timer_or_wait_fired) { + auto timestamp_bundle = + reinterpret_cast(param); + poly::store_and_swap(timestamp_bundle + 16, + GetTickCount()); + }, + mem + pKeTimeStampBundle, 0, + 1, // 1ms + WT_EXECUTEINTIMERTHREAD); } -XboxkrnlModule::~XboxkrnlModule() {} +XboxkrnlModule::~XboxkrnlModule() { + DeleteTimerQueueTimer(nullptr, timestamp_timer_, nullptr); +} int XboxkrnlModule::LaunchModule(const char* path) { // Create and register the module. We keep it local to this function and diff --git a/src/xenia/kernel/xboxkrnl_module.h b/src/xenia/kernel/xboxkrnl_module.h index 74a7486cb..f7c1fe5ca 100644 --- a/src/xenia/kernel/xboxkrnl_module.h +++ b/src/xenia/kernel/xboxkrnl_module.h @@ -31,6 +31,7 @@ class XboxkrnlModule : public XKernelModule { int LaunchModule(const char* path); private: + HANDLE timestamp_timer_; }; } // namespace kernel diff --git a/src/xenia/kernel/xboxkrnl_threading.cc b/src/xenia/kernel/xboxkrnl_threading.cc index b2dd2946f..a7babec83 100644 --- a/src/xenia/kernel/xboxkrnl_threading.cc +++ b/src/xenia/kernel/xboxkrnl_threading.cc @@ -277,6 +277,8 @@ SHIM_CALL KeQueryPerformanceFrequency_shim(PPCContext* ppc_state, // XELOGD( // "KeQueryPerformanceFrequency()"); + // TODO(benvanik): return fixed 50000000? + uint64_t result = 0; LARGE_INTEGER frequency; if (QueryPerformanceFrequency(&frequency)) { From f60677f3599b12750188c2a4b1246e61f0be87dd Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 1 Feb 2015 11:22:56 -0800 Subject: [PATCH 380/388] mfocrf + test --- src/alloy/frontend/ppc/ppc_emit-private.h | 4 +- src/alloy/frontend/ppc/ppc_emit_control.cc | 39 ++++++++++++++++-- src/alloy/frontend/ppc/ppc_hir_builder.cc | 22 +++++++++- .../frontend/ppc/test/bin/instr_vcmpxxfp.bin | Bin 0 -> 36 bytes .../frontend/ppc/test/bin/instr_vcmpxxfp.dis | 20 +++++++++ .../frontend/ppc/test/bin/instr_vcmpxxfp.map | 3 ++ src/alloy/frontend/ppc/test/instr_vcmpxxfp.s | 32 ++++++++++++++ 7 files changed, 113 insertions(+), 7 deletions(-) create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vcmpxxfp.bin create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vcmpxxfp.dis create mode 100644 src/alloy/frontend/ppc/test/bin/instr_vcmpxxfp.map create mode 100644 src/alloy/frontend/ppc/test/instr_vcmpxxfp.s diff --git a/src/alloy/frontend/ppc/ppc_emit-private.h b/src/alloy/frontend/ppc/ppc_emit-private.h index a0f7dcee5..3b095dc13 100644 --- a/src/alloy/frontend/ppc/ppc_emit-private.h +++ b/src/alloy/frontend/ppc/ppc_emit-private.h @@ -22,8 +22,8 @@ namespace ppc { #define XEREGISTERINSTR(name, opcode) \ RegisterInstrEmit(opcode, (InstrEmitFn)InstrEmit_##name); -#define XEINSTRNOTIMPLEMENTED() -//#define XEINSTRNOTIMPLEMENTED assert_trueALWAYS +//#define XEINSTRNOTIMPLEMENTED() +#define XEINSTRNOTIMPLEMENTED() assert_always("Instruction not implemented"); //#define XEINSTRNOTIMPLEMENTED() __debugbreak() } // namespace ppc diff --git a/src/alloy/frontend/ppc/ppc_emit_control.cc b/src/alloy/frontend/ppc/ppc_emit_control.cc index 8e00b3d24..25a63f618 100644 --- a/src/alloy/frontend/ppc/ppc_emit_control.cc +++ b/src/alloy/frontend/ppc/ppc_emit_control.cc @@ -529,9 +529,42 @@ XEEMITTER(twi, 0x0C000000, D)(PPCHIRBuilder& f, InstrData& i) { // Processor control (A-26) -XEEMITTER(mfcr, 0x7C000026, X)(PPCHIRBuilder& f, InstrData& i) { - XEINSTRNOTIMPLEMENTED(); - return 1; +XEEMITTER(mfcr, 0x7C000026, XFX)(PPCHIRBuilder& f, InstrData& i) { + // mfocrf RT,FXM + // RT <- undefined + // count <- 0 + // do i = 0 to 7 + // if FXMi = 1 then + // n <- i + // count <- count + 1 + // if count = 1 then + // RT4un + 32:4un + 35 <- CR4un + 32 : 4un + 35 + + // TODO(benvanik): optimize mfcr sequences. + // Often look something like this: + // mfocrf r11, cr6 + // not r10, r11 + // extrwi r3, r10, 1, 26 + // Could recognize this and only load the appropriate CR bit. + + assert_true(i.XFX.spr & (1 << 9)); + uint32_t bits = (i.XFX.spr & 0x1FF) >> 1; + int count = 0; + int cri = 0; + for (int b = 0; b <= 7; ++b) { + if (bits & (1 << b)) { + cri = 7 - b; + ++count; + } + } + Value* v; + if (count == 1) { + v = f.LoadCR(cri); + } else { + v = f.LoadZero(INT64_TYPE); + } + f.StoreGPR(i.XFX.RT, v); + return 0; } XEEMITTER(mfspr, 0x7C0002A6, XFX)(PPCHIRBuilder& f, InstrData& i) { diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index a1abfb415..d586c2fa5 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -253,8 +253,26 @@ void PPCHIRBuilder::StoreCTR(Value* value) { } Value* PPCHIRBuilder::LoadCR(uint32_t n) { - assert_always(); - return 0; + // Construct the entire word of just the bits we care about. + // This makes it easier for the optimizer to exclude things, though + // we could be even more clever and watch sequences. + Value* v = Shl(ZeroExtend(LoadContext(offsetof(PPCContext, cr0) + (4 * n) + 0, + INT8_TYPE), + INT64_TYPE), + 4 * (7 - n) + 3); + v = Or(v, Shl(ZeroExtend(LoadContext(offsetof(PPCContext, cr0) + (4 * n) + 1, + INT8_TYPE), + INT64_TYPE), + 4 * (7 - n) + 2)); + v = Or(v, Shl(ZeroExtend(LoadContext(offsetof(PPCContext, cr0) + (4 * n) + 2, + INT8_TYPE), + INT64_TYPE), + 4 * (7 - n) + 1)); + v = Or(v, Shl(ZeroExtend(LoadContext(offsetof(PPCContext, cr0) + (4 * n) + 3, + INT8_TYPE), + INT64_TYPE), + 4 * (7 - n) + 0)); + return v; } Value* PPCHIRBuilder::LoadCRField(uint32_t n, uint32_t bit) { diff --git a/src/alloy/frontend/ppc/test/bin/instr_vcmpxxfp.bin b/src/alloy/frontend/ppc/test/bin/instr_vcmpxxfp.bin new file mode 100644 index 0000000000000000000000000000000000000000..daedb5fa5fbec93ff7043ca5783dc2b138a28f91 GIT binary patch literal 36 WcmWeg(K%LAprGd0z@Q+2gAD-5{0fr* literal 0 HcmV?d00001 diff --git a/src/alloy/frontend/ppc/test/bin/instr_vcmpxxfp.dis b/src/alloy/frontend/ppc/test/bin/instr_vcmpxxfp.dis new file mode 100644 index 000000000..cd34b261f --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vcmpxxfp.dis @@ -0,0 +1,20 @@ + +/vagrant/src/alloy/frontend/ppc/test/bin//instr_vcmpxxfp.o: file format elf64-powerpc + + +Disassembly of section .text: + +0000000000100000 : + 100000: 10 64 2c c6 .long 0x10642cc6 + 100004: 7c 70 20 26 mfocrf r3,2 + 100008: 4e 80 00 20 blr + +000000000010000c : + 10000c: 10 64 2c c6 .long 0x10642cc6 + 100010: 7c 70 20 26 mfocrf r3,2 + 100014: 4e 80 00 20 blr + +0000000000100018 : + 100018: 10 64 2c c6 .long 0x10642cc6 + 10001c: 7c 70 20 26 mfocrf r3,2 + 100020: 4e 80 00 20 blr diff --git a/src/alloy/frontend/ppc/test/bin/instr_vcmpxxfp.map b/src/alloy/frontend/ppc/test/bin/instr_vcmpxxfp.map new file mode 100644 index 000000000..2db9b1bf7 --- /dev/null +++ b/src/alloy/frontend/ppc/test/bin/instr_vcmpxxfp.map @@ -0,0 +1,3 @@ +0000000000000000 t test_vcmpxxfp_1 +000000000000000c t test_vcmpxxfp_2 +0000000000000018 t test_vcmpxxfp_3 diff --git a/src/alloy/frontend/ppc/test/instr_vcmpxxfp.s b/src/alloy/frontend/ppc/test/instr_vcmpxxfp.s new file mode 100644 index 000000000..b73bbc406 --- /dev/null +++ b/src/alloy/frontend/ppc/test/instr_vcmpxxfp.s @@ -0,0 +1,32 @@ +test_vcmpxxfp_1: + #_ REGISTER_IN v4 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_IN v5 [3f800000, 3f800000, 3f800000, 3f800000] + vcmpeqfp. v3, v4, v5 + mfocrf r3, 2 # cr6 + blr + #_ REGISTER_OUT v3 [ffffffff, ffffffff, ffffffff, ffffffff] + #_ REGISTER_OUT v4 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_OUT v5 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_OUT r3 0x00000080 + +test_vcmpxxfp_2: + #_ REGISTER_IN v4 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_IN v5 [3f800001, 3f800000, 3f800000, 3f800000] + vcmpeqfp. v3, v4, v5 + mfocrf r3, 2 # cr6 + blr + #_ REGISTER_OUT v3 [00000000, ffffffff, ffffffff, ffffffff] + #_ REGISTER_OUT v4 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_OUT v5 [3f800001, 3f800000, 3f800000, 3f800000] + #_ REGISTER_OUT r3 0x00000000 + +test_vcmpxxfp_3: + #_ REGISTER_IN v4 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_IN v5 [3f800001, 3f800001, 3f800001, 3f800001] + vcmpeqfp. v3, v4, v5 + mfocrf r3, 2 # cr6 + blr + #_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000] + #_ REGISTER_OUT v4 [3f800000, 3f800000, 3f800000, 3f800000] + #_ REGISTER_OUT v5 [3f800001, 3f800001, 3f800001, 3f800001] + #_ REGISTER_OUT r3 0x00000020 From 5f3ab7979f5a69b958dfe3971089a47b902a4eee Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 1 Feb 2015 11:38:16 -0800 Subject: [PATCH 381/388] --break_on_debugbreak --- src/alloy/alloy-private.h | 1 + src/alloy/alloy.cc | 1 + src/alloy/backend/x64/x64_emitter.cc | 5 ++++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/alloy/alloy-private.h b/src/alloy/alloy-private.h index 3efde3d21..e20e04806 100644 --- a/src/alloy/alloy-private.h +++ b/src/alloy/alloy-private.h @@ -19,5 +19,6 @@ DECLARE_bool(validate_hir); DECLARE_uint64(break_on_instruction); DECLARE_uint64(break_on_memory); +DECLARE_bool(break_on_debugbreak); #endif // ALLOY_ALLOY_PRIVATE_H_ diff --git a/src/alloy/alloy.cc b/src/alloy/alloy.cc index 2f6d095f3..3435a4950 100644 --- a/src/alloy/alloy.cc +++ b/src/alloy/alloy.cc @@ -32,3 +32,4 @@ DEFINE_uint64(break_on_instruction, 0, "int3 before the given guest address is executed."); DEFINE_uint64(break_on_memory, 0, "int3 on read/write to the given memory address."); +DEFINE_bool(break_on_debugbreak, true, "int3 on JITed __debugbreak requests."); diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index a404f52fc..77a661eda 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -9,6 +9,7 @@ #include "alloy/backend/x64/x64_emitter.h" +#include "alloy/alloy-private.h" #include "alloy/backend/x64/x64_backend.h" #include "alloy/backend/x64/x64_code_cache.h" #include "alloy/backend/x64/x64_function.h" @@ -371,7 +372,9 @@ void X64Emitter::Trap(uint16_t trap_type) { case 22: // Always trap? // TODO(benvanik): post software interrupt to debugger. - db(0xCC); + if (FLAGS_break_on_debugbreak) { + db(0xCC); + } break; default: PLOGW("Unknown trap type %d", trap_type); From 5b759d387c1b4e082f8f105a690dbea4c2e6a6db Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 1 Feb 2015 17:25:18 -0800 Subject: [PATCH 382/388] Starting to reverse XGI app. --- src/xenia/gpu/gl4/gl4_shader.cc | 3 +- src/xenia/kernel/apps/apps.cc | 2 + src/xenia/kernel/apps/sources.gypi | 2 + src/xenia/kernel/apps/xgi_app.cc | 77 ++++++++++++++++++++++++++++++ src/xenia/kernel/apps/xgi_app.h | 35 ++++++++++++++ src/xenia/kernel/xam_msg.cc | 12 +++-- 6 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 src/xenia/kernel/apps/xgi_app.cc create mode 100644 src/xenia/kernel/apps/xgi_app.h diff --git a/src/xenia/gpu/gl4/gl4_shader.cc b/src/xenia/gpu/gl4/gl4_shader.cc index 3f5aba911..da834faf0 100644 --- a/src/xenia/gpu/gl4/gl4_shader.cc +++ b/src/xenia/gpu/gl4/gl4_shader.cc @@ -105,7 +105,8 @@ bool GL4Shader::PrepareVertexArrayObject() { : GL_UNSIGNED_INT_2_10_10_10_REV; break; case VertexFormat::k_10_11_11: - assert_false(el.is_signed); + // assert_false(el.is_signed); + XELOGW("Signed k_10_11_11 vertex format not supported by GL"); comp_type = GL_UNSIGNED_INT_10F_11F_11F_REV; break; /*case VertexFormat::k_11_11_10: diff --git a/src/xenia/kernel/apps/apps.cc b/src/xenia/kernel/apps/apps.cc index 9fa4a6057..6e8395d0b 100644 --- a/src/xenia/kernel/apps/apps.cc +++ b/src/xenia/kernel/apps/apps.cc @@ -9,6 +9,7 @@ #include "xenia/kernel/apps/apps.h" +#include "xenia/kernel/apps/xgi_app.h" #include "xenia/kernel/apps/xmp_app.h" namespace xe { @@ -16,6 +17,7 @@ namespace kernel { namespace apps { void RegisterApps(KernelState* kernel_state, XAppManager* manager) { + manager->RegisterApp(std::make_unique(kernel_state)); manager->RegisterApp(std::make_unique(kernel_state)); } diff --git a/src/xenia/kernel/apps/sources.gypi b/src/xenia/kernel/apps/sources.gypi index 26c6663e2..d253e242e 100644 --- a/src/xenia/kernel/apps/sources.gypi +++ b/src/xenia/kernel/apps/sources.gypi @@ -3,6 +3,8 @@ 'sources': [ 'apps.cc', 'apps.h', + 'xgi_app.cc', + 'xgi_app.h', 'xmp_app.cc', 'xmp_app.h', ], diff --git a/src/xenia/kernel/apps/xgi_app.cc b/src/xenia/kernel/apps/xgi_app.cc new file mode 100644 index 000000000..0d2d4b546 --- /dev/null +++ b/src/xenia/kernel/apps/xgi_app.cc @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include "xenia/kernel/apps/xgi_app.h" + +#include "poly/threading.h" + +namespace xe { +namespace kernel { +namespace apps { + +XXGIApp::XXGIApp(KernelState* kernel_state) : XApp(kernel_state, 0xFB) {} + +// http://mb.mirage.org/bugzilla/xliveless/main.c + +X_RESULT XXGIApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, + uint32_t buffer_length) { + // NOTE: buffer_length may be zero or valid. + switch (message) { + case 0x000B0006: { + assert_true(!buffer_length || buffer_length == 24); + // dword r3 user index + // dword (unwritten?) + // qword 0 + // dword r4 context enum + // dword r5 value + uint32_t user_index = + poly::load_and_swap(membase_ + buffer_ptr + 0); + uint32_t context_id = + poly::load_and_swap(membase_ + buffer_ptr + 16); + uint32_t context_value = + poly::load_and_swap(membase_ + buffer_ptr + 20); + XELOGD("XUserSetContextEx(%.8X, %.8X, %.8X)", user_index, context_id, + context_value); + return X_ERROR_SUCCESS; + } + case 0x000B0007: { + // TODO(benvanik): reverse. + assert_always(); + XELOGD("XUserSetPropertyEx(...) - XGI 0x000B0007, unimplemented"); + return X_ERROR_SUCCESS; + } + case 0x000B0008: { + assert_true(!buffer_length || buffer_length == 8); + uint32_t achievement_count = + poly::load_and_swap(membase_ + buffer_ptr + 0); + uint32_t achievements_ptr = + poly::load_and_swap(membase_ + buffer_ptr + 4); + XELOGD("XUserWriteAchievements(%.8X, %.8X)", achievement_count, + achievements_ptr); + return X_ERROR_SUCCESS; + } + case 0x000B0041: { + // TODO(benvanik): reverse. + assert_always(); + XELOGD("XUserGetContext(...) - XGI 0x000B0041, unimplemented"); + return X_ERROR_SUCCESS; + } + case 0x000B0071: { + XELOGD("XGI 0x000B0071, unimplemented"); + return X_ERROR_SUCCESS; + } + } + XELOGE("Unimplemented XMsg message app=%.8X, msg=%.8X, arg1=%.8X, arg2=%.8X", + app_id(), message, buffer_ptr, buffer_length); + return X_ERROR_NOT_FOUND; +} + +} // namespace apps +} // namespace kernel +} // namespace xe diff --git a/src/xenia/kernel/apps/xgi_app.h b/src/xenia/kernel/apps/xgi_app.h new file mode 100644 index 000000000..d376e6add --- /dev/null +++ b/src/xenia/kernel/apps/xgi_app.h @@ -0,0 +1,35 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2015 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_KERNEL_XBOXKRNL_APPS_XGI_APP_H_ +#define XENIA_KERNEL_XBOXKRNL_APPS_XGI_APP_H_ + +#include "xenia/common.h" +#include "xenia/kernel/app.h" +#include "xenia/kernel/kernel_state.h" + +namespace xe { +namespace kernel { +namespace apps { + +class XXGIApp : public XApp { + public: + XXGIApp(KernelState* kernel_state); + + X_RESULT DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, + uint32_t buffer_length) override; + + private: +}; + +} // namespace apps +} // namespace kernel +} // namespace xe + +#endif // XENIA_KERNEL_XBOXKRNL_APPS_XGI_APP_H_ diff --git a/src/xenia/kernel/xam_msg.cc b/src/xenia/kernel/xam_msg.cc index e51f8f5ff..a2d36f273 100644 --- a/src/xenia/kernel/xam_msg.cc +++ b/src/xenia/kernel/xam_msg.cc @@ -43,13 +43,15 @@ SHIM_CALL XMsgStartIORequest_shim(PPCContext* ppc_state, KernelState* state) { XELOGD("XMsgStartIORequest(%.8X, %.8X, %.8X, %.8X, %d)", app, message, overlapped_ptr, buffer, buffer_length); - assert_zero(overlapped_ptr); - auto result = state->app_manager()->DispatchMessageAsync(app, message, buffer, buffer_length); if (result == X_ERROR_NOT_FOUND) { XELOGE("XMsgStartIORequest: app %.8X undefined", app); } + if (overlapped_ptr) { + state->CompleteOverlappedImmediate(overlapped_ptr, result); + result = X_ERROR_IO_PENDING; + } SHIM_SET_RETURN_32(result); } @@ -64,13 +66,15 @@ SHIM_CALL XMsgStartIORequestEx_shim(PPCContext* ppc_state, KernelState* state) { XELOGD("XMsgStartIORequestEx(%.8X, %.8X, %.8X, %.8X, %d, %.8X)", app, message, overlapped_ptr, buffer, buffer_length, unknown_ptr); - assert_zero(overlapped_ptr); - auto result = state->app_manager()->DispatchMessageAsync(app, message, buffer, buffer_length); if (result == X_ERROR_NOT_FOUND) { XELOGE("XMsgStartIORequestEx: app %.8X undefined", app); } + if (overlapped_ptr) { + state->CompleteOverlappedImmediate(overlapped_ptr, result); + result = X_ERROR_IO_PENDING; + } SHIM_SET_RETURN_32(result); } From 7b483327821f2e8fc447b13c7ecf979150c90710 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 1 Feb 2015 17:40:38 -0800 Subject: [PATCH 383/388] Reversing XUserSetPropertyEx signature. --- src/xenia/kernel/apps/xgi_app.cc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/xenia/kernel/apps/xgi_app.cc b/src/xenia/kernel/apps/xgi_app.cc index 0d2d4b546..70b49eb36 100644 --- a/src/xenia/kernel/apps/xgi_app.cc +++ b/src/xenia/kernel/apps/xgi_app.cc @@ -41,9 +41,16 @@ X_RESULT XXGIApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, return X_ERROR_SUCCESS; } case 0x000B0007: { - // TODO(benvanik): reverse. - assert_always(); - XELOGD("XUserSetPropertyEx(...) - XGI 0x000B0007, unimplemented"); + uint32_t user_index = + poly::load_and_swap(membase_ + buffer_ptr + 0); + uint32_t property_id = + poly::load_and_swap(membase_ + buffer_ptr + 16); + uint32_t value_size = + poly::load_and_swap(membase_ + buffer_ptr + 20); + uint32_t value_ptr = + poly::load_and_swap(membase_ + buffer_ptr + 24); + XELOGD("XUserSetPropertyEx(%.8X, %.8X, %d, %.8X)", user_index, + property_id, value_size, value_ptr); return X_ERROR_SUCCESS; } case 0x000B0008: { From 93ded5ef0ff8cb78cb32c869d9b6798e0ec91cdb Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 1 Feb 2015 20:49:47 -0800 Subject: [PATCH 384/388] Old style mfcr. --- src/alloy/frontend/ppc/ppc_emit_control.cc | 29 ++++++++++++---------- src/alloy/frontend/ppc/ppc_hir_builder.cc | 10 ++++++++ src/alloy/frontend/ppc/ppc_hir_builder.h | 1 + src/xenia/kernel/kernel_state.cc | 1 + 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/alloy/frontend/ppc/ppc_emit_control.cc b/src/alloy/frontend/ppc/ppc_emit_control.cc index 25a63f618..40e8a8ce3 100644 --- a/src/alloy/frontend/ppc/ppc_emit_control.cc +++ b/src/alloy/frontend/ppc/ppc_emit_control.cc @@ -547,21 +547,24 @@ XEEMITTER(mfcr, 0x7C000026, XFX)(PPCHIRBuilder& f, InstrData& i) { // extrwi r3, r10, 1, 26 // Could recognize this and only load the appropriate CR bit. - assert_true(i.XFX.spr & (1 << 9)); - uint32_t bits = (i.XFX.spr & 0x1FF) >> 1; - int count = 0; - int cri = 0; - for (int b = 0; b <= 7; ++b) { - if (bits & (1 << b)) { - cri = 7 - b; - ++count; - } - } Value* v; - if (count == 1) { - v = f.LoadCR(cri); + if (i.XFX.spr & (1 << 9)) { + uint32_t bits = (i.XFX.spr & 0x1FF) >> 1; + int count = 0; + int cri = 0; + for (int b = 0; b <= 7; ++b) { + if (bits & (1 << b)) { + cri = 7 - b; + ++count; + } + } + if (count == 1) { + v = f.LoadCR(cri); + } else { + v = f.LoadZero(INT64_TYPE); + } } else { - v = f.LoadZero(INT64_TYPE); + v = f.LoadCR(); } f.StoreGPR(i.XFX.RT, v); return 0; diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index d586c2fa5..ad4e8bc6d 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -252,6 +252,16 @@ void PPCHIRBuilder::StoreCTR(Value* value) { trace_reg.value = value; } +Value* PPCHIRBuilder::LoadCR() { + // All bits. This is expensive, but seems to be less used than the + // field-specific LoadCR. + Value* v = LoadCR(0); + for (int i = 1; i <= 7; ++i) { + v = Or(v, LoadCR(i)); + } + return v; +} + Value* PPCHIRBuilder::LoadCR(uint32_t n) { // Construct the entire word of just the bits we care about. // This makes it easier for the optimizer to exclude things, though diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.h b/src/alloy/frontend/ppc/ppc_hir_builder.h index 5fb172d96..5d09f1c78 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.h +++ b/src/alloy/frontend/ppc/ppc_hir_builder.h @@ -50,6 +50,7 @@ class PPCHIRBuilder : public hir::HIRBuilder { void StoreLR(Value* value); Value* LoadCTR(); void StoreCTR(Value* value); + Value* LoadCR(); Value* LoadCR(uint32_t n); Value* LoadCRField(uint32_t n, uint32_t bit); void StoreCR(uint32_t n, Value* value); diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index 383dbe215..70f53222a 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -33,6 +33,7 @@ KernelState* shared_kernel_state_ = nullptr; KernelState::KernelState(Emulator* emulator) : emulator_(emulator), memory_(emulator->memory()), + object_table_(nullptr), has_notified_startup_(false), process_type_(X_PROCTYPE_USER), executable_module_(nullptr) { From 493c3d76563b453cdbdeabe03b691ee452eecde8 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 1 Feb 2015 20:53:44 -0800 Subject: [PATCH 385/388] XMsgSystemProcessCall call. --- src/xenia/kernel/xam_msg.cc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/xenia/kernel/xam_msg.cc b/src/xenia/kernel/xam_msg.cc index a2d36f273..1a4648f5f 100644 --- a/src/xenia/kernel/xam_msg.cc +++ b/src/xenia/kernel/xam_msg.cc @@ -33,6 +33,23 @@ SHIM_CALL XMsgInProcessCall_shim(PPCContext* ppc_state, KernelState* state) { SHIM_SET_RETURN_32(result); } +SHIM_CALL XMsgSystemProcessCall_shim(PPCContext* ppc_state, KernelState* state) { + uint32_t app = SHIM_GET_ARG_32(0); + uint32_t message = SHIM_GET_ARG_32(1); + uint32_t buffer = SHIM_GET_ARG_32(2); + uint32_t buffer_length = SHIM_GET_ARG_32(3); + + XELOGD("XMsgSystemProcessCall(%.8X, %.8X, %.8X, %.8X)", app, message, buffer, + buffer_length); + + auto result = state->app_manager()->DispatchMessageAsync(app, message, buffer, + buffer_length); + if (result == X_ERROR_NOT_FOUND) { + XELOGE("XMsgSystemProcessCall: app %.8X undefined", app); + } + SHIM_SET_RETURN_32(result); +} + SHIM_CALL XMsgStartIORequest_shim(PPCContext* ppc_state, KernelState* state) { uint32_t app = SHIM_GET_ARG_32(0); uint32_t message = SHIM_GET_ARG_32(1); @@ -103,6 +120,7 @@ SHIM_CALL XMsgCancelIORequest_shim(PPCContext* ppc_state, KernelState* state) { void xe::kernel::xam::RegisterMsgExports(ExportResolver* export_resolver, KernelState* state) { SHIM_SET_MAPPING("xam.xex", XMsgInProcessCall, state); + SHIM_SET_MAPPING("xam.xex", XMsgSystemProcessCall, state); SHIM_SET_MAPPING("xam.xex", XMsgStartIORequest, state); SHIM_SET_MAPPING("xam.xex", XMsgStartIORequestEx, state); SHIM_SET_MAPPING("xam.xex", XMsgCancelIORequest, state); From 59adde4d7fef937f80e7f21ec5eb981137b652b7 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 1 Feb 2015 21:20:55 -0800 Subject: [PATCH 386/388] Negative size allocs. Probably. --- src/xenia/kernel/xboxkrnl_memory.cc | 2 +- src/xenia/memory.cc | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/xenia/kernel/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl_memory.cc index 0a21396fc..70c0f3d8f 100644 --- a/src/xenia/kernel/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl_memory.cc @@ -86,7 +86,7 @@ SHIM_CALL NtAllocateVirtualMemory_shim(PPCContext* ppc_state, } // Allocate. - uint32_t flags = (allocation_type & X_MEM_NOZERO); + uint32_t flags = (allocation_type & X_MEM_NOZERO) ? 0 : MEMORY_FLAG_ZERO; uint32_t addr = (uint32_t)state->memory()->HeapAlloc(base_addr_value, adjusted_size, flags); if (!addr) { diff --git a/src/xenia/memory.cc b/src/xenia/memory.cc index 03beb85a2..74865ebfd 100644 --- a/src/xenia/memory.cc +++ b/src/xenia/memory.cc @@ -447,13 +447,18 @@ int MemoryHeap::Initialize(uint64_t low, uint64_t high) { uint64_t MemoryHeap::Alloc(uint64_t base_address, size_t size, uint32_t flags, uint32_t alignment) { - lock_.lock(); size_t alloc_size = size; + if (int32_t(alloc_size) < 0) { + alloc_size = uint32_t(-alloc_size); + } size_t heap_guard_size = FLAGS_heap_guard_pages * 4096; if (heap_guard_size) { alignment = std::max(alignment, static_cast(heap_guard_size)); - alloc_size = static_cast(poly::round_up(size, heap_guard_size)); + alloc_size = + static_cast(poly::round_up(alloc_size, heap_guard_size)); } + + lock_.lock(); uint8_t* p = (uint8_t*)mspace_memalign(space_, alignment, alloc_size + heap_guard_size * 2); assert_true(reinterpret_cast(p) <= 0xFFFFFFFFFull); @@ -477,19 +482,18 @@ uint64_t MemoryHeap::Alloc(uint64_t base_address, size_t size, uint32_t flags, // If physical, we need to commit the memory in the physical address ranges // so that it can be accessed. VirtualAlloc(memory_->views_.vA0000000 + (p - memory_->views_.v00000000), - size, MEM_COMMIT, PAGE_READWRITE); + alloc_size, MEM_COMMIT, PAGE_READWRITE); VirtualAlloc(memory_->views_.vC0000000 + (p - memory_->views_.v00000000), - size, MEM_COMMIT, PAGE_READWRITE); + alloc_size, MEM_COMMIT, PAGE_READWRITE); VirtualAlloc(memory_->views_.vE0000000 + (p - memory_->views_.v00000000), - size, MEM_COMMIT, PAGE_READWRITE); + alloc_size, MEM_COMMIT, PAGE_READWRITE); } - if ((flags & X_MEM_NOZERO) && FLAGS_scribble_heap) { + if (flags & MEMORY_FLAG_ZERO) { + memset(p, 0, alloc_size); + } else if (FLAGS_scribble_heap) { // Trash the memory so that we can see bad read-before-write bugs easier. memset(p, 0xCD, alloc_size); - } else { - // Implicit clear. - memset(p, 0, alloc_size); } uint64_t address = From 487ce40123de6c9923de76ca0b55e4a2de131f4b Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 1 Feb 2015 22:29:36 -0800 Subject: [PATCH 387/388] No-op XUserGetContext. --- src/xenia/kernel/apps/xgi_app.cc | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/xenia/kernel/apps/xgi_app.cc b/src/xenia/kernel/apps/xgi_app.cc index 70b49eb36..c0b1c7d67 100644 --- a/src/xenia/kernel/apps/xgi_app.cc +++ b/src/xenia/kernel/apps/xgi_app.cc @@ -64,9 +64,18 @@ X_RESULT XXGIApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr, return X_ERROR_SUCCESS; } case 0x000B0041: { - // TODO(benvanik): reverse. - assert_always(); - XELOGD("XUserGetContext(...) - XGI 0x000B0041, unimplemented"); + assert_true(!buffer_length || buffer_length == 32); + // 00000000 2789fecc 00000000 00000000 200491e0 00000000 200491f0 20049340 + uint32_t user_index = + poly::load_and_swap(membase_ + buffer_ptr + 0); + uint32_t context_ptr = + poly::load_and_swap(membase_ + buffer_ptr + 16); + uint32_t context_id = + poly::load_and_swap(membase_ + context_ptr + 0); + XELOGD("XUserGetContext(%.8X, %.8X(%.8X))", user_index, context_ptr, + context_id); + uint32_t value = 0; + poly::store_and_swap(membase_ + context_ptr + 4, value); return X_ERROR_SUCCESS; } case 0x000B0071: { From ea1bdd2a24fb09e41344694a3c1a16376172b7cf Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 1 Feb 2015 22:44:33 -0800 Subject: [PATCH 388/388] Fixing vswprintf and adding vscwprintf. --- src/poly/byte_order.h | 3 + src/xenia/kernel/xboxkrnl_strings.cc | 86 +++++++++++++++++++--------- 2 files changed, 63 insertions(+), 26 deletions(-) diff --git a/src/poly/byte_order.h b/src/poly/byte_order.h index 44eb13e9c..1a4d19352 100644 --- a/src/poly/byte_order.h +++ b/src/poly/byte_order.h @@ -41,6 +41,9 @@ inline int16_t byte_swap(int16_t value) { return static_cast(POLY_BYTE_SWAP_16(static_cast(value))); } inline uint16_t byte_swap(uint16_t value) { return POLY_BYTE_SWAP_16(value); } +inline uint16_t byte_swap(wchar_t value) { + return static_cast(POLY_BYTE_SWAP_16(value)); +} inline int32_t byte_swap(int32_t value) { return static_cast(POLY_BYTE_SWAP_32(static_cast(value))); } diff --git a/src/xenia/kernel/xboxkrnl_strings.cc b/src/xenia/kernel/xboxkrnl_strings.cc index 9723f27a7..14e480f53 100644 --- a/src/xenia/kernel/xboxkrnl_strings.cc +++ b/src/xenia/kernel/xboxkrnl_strings.cc @@ -25,6 +25,8 @@ SHIM_CALL vsprintf_shim(PPCContext* ppc_state, KernelState* state) { uint32_t format_ptr = SHIM_GET_ARG_32(1); uint32_t arg_ptr = SHIM_GET_ARG_32(2); + XELOGD("_vsprintf(...)"); + if (format_ptr == 0) { SHIM_SET_RETURN_32(-1); return; @@ -208,6 +210,8 @@ SHIM_CALL _vsnprintf_shim(PPCContext* ppc_state, KernelState* state) { uint32_t format_ptr = SHIM_GET_ARG_32(2); uint32_t arg_ptr = SHIM_GET_ARG_32(3); + XELOGD("_vsnprintf(...)"); + if (format_ptr == 0) { SHIM_SET_RETURN_32(-1); return; @@ -355,7 +359,7 @@ SHIM_CALL _vsnprintf_shim(PPCContext* ppc_state, KernelState* state) { if (arg_extras == 0) { uint32_t value = (uint32_t)SHIM_MEM_64( arg_ptr + (arg_index * 8)); // TODO: check if this is correct... - SHIM_SET_MEM_32(value, (uint32_t)((b - buffer) / sizeof(char))); + SHIM_SET_MEM_32(value, (uint32_t)(b - buffer)); arg_index++; } else { assert_true(false); @@ -386,22 +390,8 @@ SHIM_CALL _vsnprintf_shim(PPCContext* ppc_state, KernelState* state) { SHIM_SET_RETURN_32((uint32_t)(b - buffer)); } -// TODO: clean me up! -SHIM_CALL _vswprintf_shim(PPCContext* ppc_state, KernelState* state) { - uint32_t buffer_ptr = SHIM_GET_ARG_32(0); - uint32_t format_ptr = SHIM_GET_ARG_32(1); - uint32_t arg_ptr = SHIM_GET_ARG_32(2); - - if (format_ptr == 0) { - SHIM_SET_RETURN_32(-1); - return; - } - - wchar_t* buffer = - (wchar_t*)SHIM_MEM_ADDR(buffer_ptr); // TODO: ensure it never writes past - // the end of the buffer (count)... - const wchar_t* format = (const wchar_t*)SHIM_MEM_ADDR(format_ptr); - +uint32_t vswprintf_core(wchar_t* buffer, const wchar_t* format, + const uint8_t* arg_ptr, uint8_t* membase) { // this will work since a null is the same regardless of endianness size_t format_length = wcslen(format); @@ -529,7 +519,7 @@ SHIM_CALL _vswprintf_shim(PPCContext* ppc_state, KernelState* state) { assert_true(arg_size == 8 || arg_size == 4); if (arg_size == 8) { if (arg_extras == 0) { - uint64_t value = SHIM_MEM_64( + uint64_t value = poly::load_and_swap( arg_ptr + (arg_index * 8)); // TODO: check if this is correct... int result = wsprintf(b, local, value); b += result; @@ -539,7 +529,7 @@ SHIM_CALL _vswprintf_shim(PPCContext* ppc_state, KernelState* state) { } } else if (arg_size == 4) { if (arg_extras == 0) { - uint32_t value = (uint32_t)SHIM_MEM_64( + uint32_t value = (uint32_t)poly::load_and_swap( arg_ptr + (arg_index * 8)); // TODO: check if this is correct... int result = wsprintf(b, local, value); b += result; @@ -551,9 +541,9 @@ SHIM_CALL _vswprintf_shim(PPCContext* ppc_state, KernelState* state) { } else if (*end == 'n') { assert_true(arg_size == 4); if (arg_extras == 0) { - uint32_t value = (uint32_t)SHIM_MEM_64( + uint32_t value = (uint32_t)poly::load_and_swap( arg_ptr + (arg_index * 8)); // TODO: check if this is correct... - SHIM_SET_MEM_32(value, (uint32_t)((b - buffer) / sizeof(wchar_t))); + poly::store_and_swap(membase + value, (uint32_t)(b - buffer)); arg_index++; } else { assert_true(false); @@ -565,9 +555,9 @@ SHIM_CALL _vswprintf_shim(PPCContext* ppc_state, KernelState* state) { assert_true(arg_size == 4); if (arg_extras == 0) { - uint32_t value = (uint32_t)SHIM_MEM_64( + uint32_t value = (uint32_t)poly::load_and_swap( arg_ptr + (arg_index * 8)); // TODO: check if this is correct... - const void* pointer = (void*)SHIM_MEM_ADDR(value); + const void* pointer = (void*)(membase + value); int result = wsprintf(b, local, pointer); b += result; arg_index++; @@ -581,9 +571,9 @@ SHIM_CALL _vswprintf_shim(PPCContext* ppc_state, KernelState* state) { assert_true(arg_size == 4); if (arg_extras == 0) { - uint32_t value = (uint32_t)SHIM_MEM_64( + uint32_t value = (uint32_t)poly::load_and_swap( arg_ptr + (arg_index * 8)); // TODO: check if this is correct... - const wchar_t* data = (const wchar_t*)SHIM_MEM_ADDR(value); + const wchar_t* data = (const wchar_t*)(membase + value); size_t data_length = wcslen(data); wchar_t* swapped_data = (wchar_t*)malloc((data_length + 1) * sizeof(wchar_t)); @@ -613,7 +603,50 @@ SHIM_CALL _vswprintf_shim(PPCContext* ppc_state, KernelState* state) { *swap = poly::byte_swap(*swap); } - SHIM_SET_RETURN_32((uint32_t)((b - buffer) / sizeof(wchar_t))); + return uint32_t(b - buffer); +} + +// TODO: clean me up! +SHIM_CALL _vswprintf_shim(PPCContext* ppc_state, KernelState* state) { + uint32_t buffer_ptr = SHIM_GET_ARG_32(0); + uint32_t format_ptr = SHIM_GET_ARG_32(1); + uint32_t arg_ptr = SHIM_GET_ARG_32(2); + + XELOGD("_vswprintf(...)"); + + if (format_ptr == 0) { + SHIM_SET_RETURN_32(-1); + return; + } + const wchar_t* format = (const wchar_t*)SHIM_MEM_ADDR(format_ptr); + + wchar_t* buffer = + (wchar_t*)SHIM_MEM_ADDR(buffer_ptr); // TODO: ensure it never writes past + // the end of the buffer (count)... + + uint32_t ret = + vswprintf_core(buffer, format, SHIM_MEM_ADDR(arg_ptr), SHIM_MEM_BASE); + SHIM_SET_RETURN_32(ret); +} + +SHIM_CALL _vscwprintf_shim(PPCContext* ppc_state, KernelState* state) { + uint32_t format_ptr = SHIM_GET_ARG_32(0); + uint32_t arg_ptr = SHIM_GET_ARG_32(1); + + XELOGD("_vscwprintf(...)"); + + if (format_ptr == 0) { + SHIM_SET_RETURN_32(-1); + return; + } + const wchar_t* format = (const wchar_t*)SHIM_MEM_ADDR(format_ptr); + + // HACK: this is the worst. + auto temp = new wchar_t[2048]; + uint32_t ret = + vswprintf_core(temp, format, SHIM_MEM_ADDR(arg_ptr), SHIM_MEM_BASE); + delete[] temp; + SHIM_SET_RETURN_32(ret); } } // namespace kernel @@ -624,4 +657,5 @@ void xe::kernel::xboxkrnl::RegisterStringExports( SHIM_SET_MAPPING("xboxkrnl.exe", vsprintf, state); SHIM_SET_MAPPING("xboxkrnl.exe", _vsnprintf, state); SHIM_SET_MAPPING("xboxkrnl.exe", _vswprintf, state); + SHIM_SET_MAPPING("xboxkrnl.exe", _vscwprintf, state); }