diff --git a/README.md b/README.md index 68c34c916..1d2ebb548 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Discussing illegal activities will get you banned. Buildbot | Status -------- | ------ -[Windows](https://ci.appveyor.com/project/benvanik/xenia/branch/master) | [![Build status](https://ci.appveyor.com/api/projects/status/ftqiy86kdfawyx3a/branch/master?svg=true)](https://ci.appveyor.com/project/benvanik/xenia/branch/master) +[Windows](https://ci.appveyor.com/project/chris-hawley/xenia-canary/branch/canary) | [![Build status](https://ci.appveyor.com/api/projects/status/5fs0ia3031l9rbpo/branch/canary?svg=true)](https://ci.appveyor.com/project/chris-hawley/xenia-canary/branch/canary) [Linux](https://travis-ci.org/xenia-project/xenia) | [![Build status](https://travis-ci.org/xenia-project/xenia.svg?branch=master)](https://travis-ci.org/xenia-project/xenia) Quite a few real games run. Quite a few don't. diff --git a/premake5.lua b/premake5.lua index 212ffc9e1..5309b5571 100644 --- a/premake5.lua +++ b/premake5.lua @@ -249,6 +249,7 @@ solution("xenia") include("src/xenia/hid") include("src/xenia/hid/nop") include("src/xenia/kernel") + include("src/xenia/net") include("src/xenia/ui") include("src/xenia/ui/spirv") include("src/xenia/ui/vk") diff --git a/src/xenia/cpu/backend/x64/x64_seq_control.cc b/src/xenia/cpu/backend/x64/x64_seq_control.cc index 80eeeebc7..46c879218 100644 --- a/src/xenia/cpu/backend/x64/x64_seq_control.cc +++ b/src/xenia/cpu/backend/x64/x64_seq_control.cc @@ -20,7 +20,59 @@ namespace backend { namespace x64 { volatile int anchor_control = 0; - +template +static void EmitFusedBranch(X64Emitter& e, const T& i) { + bool valid = i.instr->prev && i.instr->prev->dest == i.src1.value; + auto opcode = valid ? i.instr->prev->opcode->num : -1; + if (valid) { + auto name = i.src2.value->name; + switch (opcode) { + case OPCODE_IS_TRUE: + e.jnz(name, e.T_NEAR); + break; + case OPCODE_IS_FALSE: + e.jz(name, e.T_NEAR); + break; + case OPCODE_COMPARE_EQ: + e.je(name, e.T_NEAR); + break; + case OPCODE_COMPARE_NE: + e.jne(name, e.T_NEAR); + break; + case OPCODE_COMPARE_SLT: + e.jl(name, e.T_NEAR); + break; + case OPCODE_COMPARE_SLE: + e.jle(name, e.T_NEAR); + break; + case OPCODE_COMPARE_SGT: + e.jg(name, e.T_NEAR); + break; + case OPCODE_COMPARE_SGE: + e.jge(name, e.T_NEAR); + break; + case OPCODE_COMPARE_ULT: + e.jb(name, e.T_NEAR); + break; + case OPCODE_COMPARE_ULE: + e.jbe(name, e.T_NEAR); + break; + case OPCODE_COMPARE_UGT: + e.ja(name, e.T_NEAR); + break; + case OPCODE_COMPARE_UGE: + e.jae(name, e.T_NEAR); + break; + default: + e.test(i.src1, i.src1); + e.jnz(name, e.T_NEAR); + break; + } + } else { + e.test(i.src1, i.src1); + e.jnz(i.src2.value->name, e.T_NEAR); + } +} // ============================================================================ // OPCODE_DEBUG_BREAK // ============================================================================ @@ -450,43 +502,57 @@ EMITTER_OPCODE_TABLE(OPCODE_BRANCH, BRANCH); struct BRANCH_TRUE_I8 : Sequence> { static void Emit(X64Emitter& e, const EmitArgType& i) { - e.test(i.src1, i.src1); - e.jnz(i.src2.value->name, e.T_NEAR); + EmitFusedBranch(e, i); } }; struct BRANCH_TRUE_I16 : Sequence> { static void Emit(X64Emitter& e, const EmitArgType& i) { - e.test(i.src1, i.src1); - e.jnz(i.src2.value->name, e.T_NEAR); + EmitFusedBranch(e, i); } }; struct BRANCH_TRUE_I32 : Sequence> { static void Emit(X64Emitter& e, const EmitArgType& i) { - e.test(i.src1, i.src1); - e.jnz(i.src2.value->name, e.T_NEAR); + EmitFusedBranch(e, i); } }; struct BRANCH_TRUE_I64 : Sequence> { static void Emit(X64Emitter& e, const EmitArgType& i) { - e.test(i.src1, i.src1); - e.jnz(i.src2.value->name, e.T_NEAR); + EmitFusedBranch(e, i); } }; struct BRANCH_TRUE_F32 : Sequence> { static void Emit(X64Emitter& e, const EmitArgType& i) { - e.vptest(i.src1, i.src1); - e.jnz(i.src2.value->name, e.T_NEAR); + if (i.instr->prev && i.instr->prev->opcode == &OPCODE_IS_TRUE_info && + i.instr->prev->dest == i.src1.value) { + e.jnz(i.src2.value->name, e.T_NEAR); + } else if (i.instr->prev && + i.instr->prev->opcode == &OPCODE_IS_FALSE_info && + i.instr->prev->dest == i.src1.value) { + e.jz(i.src2.value->name, e.T_NEAR); + } else { + e.vptest(i.src1, i.src1); + e.jnz(i.src2.value->name, e.T_NEAR); + } } }; struct BRANCH_TRUE_F64 : Sequence> { static void Emit(X64Emitter& e, const EmitArgType& i) { - e.vptest(i.src1, i.src1); - e.jnz(i.src2.value->name, e.T_NEAR); + if (i.instr->prev && i.instr->prev->opcode == &OPCODE_IS_TRUE_info && + i.instr->prev->dest == i.src1.value) { + e.jnz(i.src2.value->name, e.T_NEAR); + } else if (i.instr->prev && + i.instr->prev->opcode == &OPCODE_IS_FALSE_info && + i.instr->prev->dest == i.src1.value) { + e.jz(i.src2.value->name, e.T_NEAR); + } else { + e.vptest(i.src1, i.src1); + e.jnz(i.src2.value->name, e.T_NEAR); + } } }; EMITTER_OPCODE_TABLE(OPCODE_BRANCH_TRUE, BRANCH_TRUE_I8, BRANCH_TRUE_I16, diff --git a/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc b/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc index b6b0376fa..acd1b5d64 100644 --- a/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc +++ b/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc @@ -712,7 +712,14 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder, bool& result) { result = true; } break; - // TODO(benvanik): ROTATE_LEFT + case OPCODE_ROTATE_LEFT: + if (i->src1.value->IsConstant() && i->src2.value->IsConstant()) { + v->set_from(i->src1.value); + v->RotateLeft(i->src2.value); + i->Remove(); + result = true; + } + break; case OPCODE_BYTE_SWAP: if (i->src1.value->IsConstant()) { v->set_from(i->src1.value); diff --git a/src/xenia/cpu/hir/value.cc b/src/xenia/cpu/hir/value.cc index 666648b03..eb487325e 100644 --- a/src/xenia/cpu/hir/value.cc +++ b/src/xenia/cpu/hir/value.cc @@ -843,6 +843,29 @@ void Value::Sha(Value* other) { } } +void Value::RotateLeft(Value* other) { + assert_true(other->type == INT8_TYPE); + auto rotation = other->constant.u8; + + switch (type) { + case INT8_TYPE: + constant.u8 = rotate_left(constant.u8, rotation); + break; + case INT16_TYPE: + constant.u16 = rotate_left(constant.u16, rotation); + break; + case INT32_TYPE: + constant.u32 = rotate_left(constant.u32, rotation); + break; + case INT64_TYPE: + constant.u64 = rotate_left(constant.u64, rotation); + break; + default: + assert_unhandled_case(type); + break; + } +} + void Value::Extract(Value* vec, Value* index) { assert_true(vec->type == VEC128_TYPE); switch (type) { diff --git a/src/xenia/cpu/hir/value.h b/src/xenia/cpu/hir/value.h index dcc95ca8c..d2e0fbf6d 100644 --- a/src/xenia/cpu/hir/value.h +++ b/src/xenia/cpu/hir/value.h @@ -519,6 +519,7 @@ class Value { void Shl(Value* other); void Shr(Value* other); void Sha(Value* other); + void RotateLeft(Value* other); void Extract(Value* vec, Value* index); void Select(Value* other, Value* ctrl); void Splat(Value* other); diff --git a/src/xenia/net/premake5.lua b/src/xenia/net/premake5.lua index 119d72080..0244dc338 100644 --- a/src/xenia/net/premake5.lua +++ b/src/xenia/net/premake5.lua @@ -1,5 +1,5 @@ project_root = "../../.." -include(project_root.."/build_tools") +include(project_root.."/tools/build") group("src") project("xenia-net-proxy") @@ -9,20 +9,15 @@ project("xenia-net-proxy") links({ project_root.."/third_party/winpcap/Lib/x64/Packet", project_root.."/third_party/winpcap/Lib/x64/wpcap", - "gflags", "xenia-base", "xxhash", }) - flags({ - "WinMain", -- Use WinMain instead of main. - }) defines({ "HAVE_REMOTE=1" }) includedirs({ project_root.."/third_party/elemental-forms/src", project_root.."/third_party/winpcap/Include", - project_root.."/build_tools/third_party/gflags/src", }) files({ "net_proxy_main.cc", @@ -33,7 +28,6 @@ project("xenia-net-proxy") filter("platforms:Windows") debugdir(project_root) debugargs({ - "--flagfile=scratch/flags.txt", "2>&1", "1>scratch/stdout-net-proxy.txt", }) \ No newline at end of file