Merge remote-tracking branch 'canary/canary'
This commit is contained in:
commit
e0ea242b35
|
@ -23,7 +23,7 @@ Discussing illegal activities will get you banned.
|
||||||
|
|
||||||
Buildbot | Status
|
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)
|
[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.
|
Quite a few real games run. Quite a few don't.
|
||||||
|
|
|
@ -249,6 +249,7 @@ solution("xenia")
|
||||||
include("src/xenia/hid")
|
include("src/xenia/hid")
|
||||||
include("src/xenia/hid/nop")
|
include("src/xenia/hid/nop")
|
||||||
include("src/xenia/kernel")
|
include("src/xenia/kernel")
|
||||||
|
include("src/xenia/net")
|
||||||
include("src/xenia/ui")
|
include("src/xenia/ui")
|
||||||
include("src/xenia/ui/spirv")
|
include("src/xenia/ui/spirv")
|
||||||
include("src/xenia/ui/vk")
|
include("src/xenia/ui/vk")
|
||||||
|
|
|
@ -20,7 +20,59 @@ namespace backend {
|
||||||
namespace x64 {
|
namespace x64 {
|
||||||
|
|
||||||
volatile int anchor_control = 0;
|
volatile int anchor_control = 0;
|
||||||
|
template <typename T>
|
||||||
|
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
|
// OPCODE_DEBUG_BREAK
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
@ -450,43 +502,57 @@ EMITTER_OPCODE_TABLE(OPCODE_BRANCH, BRANCH);
|
||||||
struct BRANCH_TRUE_I8
|
struct BRANCH_TRUE_I8
|
||||||
: Sequence<BRANCH_TRUE_I8, I<OPCODE_BRANCH_TRUE, VoidOp, I8Op, LabelOp>> {
|
: Sequence<BRANCH_TRUE_I8, I<OPCODE_BRANCH_TRUE, VoidOp, I8Op, LabelOp>> {
|
||||||
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
||||||
e.test(i.src1, i.src1);
|
EmitFusedBranch(e, i);
|
||||||
e.jnz(i.src2.value->name, e.T_NEAR);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct BRANCH_TRUE_I16
|
struct BRANCH_TRUE_I16
|
||||||
: Sequence<BRANCH_TRUE_I16, I<OPCODE_BRANCH_TRUE, VoidOp, I16Op, LabelOp>> {
|
: Sequence<BRANCH_TRUE_I16, I<OPCODE_BRANCH_TRUE, VoidOp, I16Op, LabelOp>> {
|
||||||
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
||||||
e.test(i.src1, i.src1);
|
EmitFusedBranch(e, i);
|
||||||
e.jnz(i.src2.value->name, e.T_NEAR);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct BRANCH_TRUE_I32
|
struct BRANCH_TRUE_I32
|
||||||
: Sequence<BRANCH_TRUE_I32, I<OPCODE_BRANCH_TRUE, VoidOp, I32Op, LabelOp>> {
|
: Sequence<BRANCH_TRUE_I32, I<OPCODE_BRANCH_TRUE, VoidOp, I32Op, LabelOp>> {
|
||||||
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
||||||
e.test(i.src1, i.src1);
|
EmitFusedBranch(e, i);
|
||||||
e.jnz(i.src2.value->name, e.T_NEAR);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct BRANCH_TRUE_I64
|
struct BRANCH_TRUE_I64
|
||||||
: Sequence<BRANCH_TRUE_I64, I<OPCODE_BRANCH_TRUE, VoidOp, I64Op, LabelOp>> {
|
: Sequence<BRANCH_TRUE_I64, I<OPCODE_BRANCH_TRUE, VoidOp, I64Op, LabelOp>> {
|
||||||
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
||||||
e.test(i.src1, i.src1);
|
EmitFusedBranch(e, i);
|
||||||
e.jnz(i.src2.value->name, e.T_NEAR);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct BRANCH_TRUE_F32
|
struct BRANCH_TRUE_F32
|
||||||
: Sequence<BRANCH_TRUE_F32, I<OPCODE_BRANCH_TRUE, VoidOp, F32Op, LabelOp>> {
|
: Sequence<BRANCH_TRUE_F32, I<OPCODE_BRANCH_TRUE, VoidOp, F32Op, LabelOp>> {
|
||||||
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
||||||
e.vptest(i.src1, i.src1);
|
if (i.instr->prev && i.instr->prev->opcode == &OPCODE_IS_TRUE_info &&
|
||||||
e.jnz(i.src2.value->name, e.T_NEAR);
|
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
|
struct BRANCH_TRUE_F64
|
||||||
: Sequence<BRANCH_TRUE_F64, I<OPCODE_BRANCH_TRUE, VoidOp, F64Op, LabelOp>> {
|
: Sequence<BRANCH_TRUE_F64, I<OPCODE_BRANCH_TRUE, VoidOp, F64Op, LabelOp>> {
|
||||||
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
||||||
e.vptest(i.src1, i.src1);
|
if (i.instr->prev && i.instr->prev->opcode == &OPCODE_IS_TRUE_info &&
|
||||||
e.jnz(i.src2.value->name, e.T_NEAR);
|
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,
|
EMITTER_OPCODE_TABLE(OPCODE_BRANCH_TRUE, BRANCH_TRUE_I8, BRANCH_TRUE_I16,
|
||||||
|
|
|
@ -712,7 +712,14 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder, bool& result) {
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case OPCODE_BYTE_SWAP:
|
||||||
if (i->src1.value->IsConstant()) {
|
if (i->src1.value->IsConstant()) {
|
||||||
v->set_from(i->src1.value);
|
v->set_from(i->src1.value);
|
||||||
|
|
|
@ -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<uint8_t>(constant.u8, rotation);
|
||||||
|
break;
|
||||||
|
case INT16_TYPE:
|
||||||
|
constant.u16 = rotate_left<uint16_t>(constant.u16, rotation);
|
||||||
|
break;
|
||||||
|
case INT32_TYPE:
|
||||||
|
constant.u32 = rotate_left<uint32_t>(constant.u32, rotation);
|
||||||
|
break;
|
||||||
|
case INT64_TYPE:
|
||||||
|
constant.u64 = rotate_left<uint64_t>(constant.u64, rotation);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert_unhandled_case(type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Value::Extract(Value* vec, Value* index) {
|
void Value::Extract(Value* vec, Value* index) {
|
||||||
assert_true(vec->type == VEC128_TYPE);
|
assert_true(vec->type == VEC128_TYPE);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
|
@ -519,6 +519,7 @@ class Value {
|
||||||
void Shl(Value* other);
|
void Shl(Value* other);
|
||||||
void Shr(Value* other);
|
void Shr(Value* other);
|
||||||
void Sha(Value* other);
|
void Sha(Value* other);
|
||||||
|
void RotateLeft(Value* other);
|
||||||
void Extract(Value* vec, Value* index);
|
void Extract(Value* vec, Value* index);
|
||||||
void Select(Value* other, Value* ctrl);
|
void Select(Value* other, Value* ctrl);
|
||||||
void Splat(Value* other);
|
void Splat(Value* other);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
project_root = "../../.."
|
project_root = "../../.."
|
||||||
include(project_root.."/build_tools")
|
include(project_root.."/tools/build")
|
||||||
|
|
||||||
group("src")
|
group("src")
|
||||||
project("xenia-net-proxy")
|
project("xenia-net-proxy")
|
||||||
|
@ -9,20 +9,15 @@ project("xenia-net-proxy")
|
||||||
links({
|
links({
|
||||||
project_root.."/third_party/winpcap/Lib/x64/Packet",
|
project_root.."/third_party/winpcap/Lib/x64/Packet",
|
||||||
project_root.."/third_party/winpcap/Lib/x64/wpcap",
|
project_root.."/third_party/winpcap/Lib/x64/wpcap",
|
||||||
"gflags",
|
|
||||||
"xenia-base",
|
"xenia-base",
|
||||||
"xxhash",
|
"xxhash",
|
||||||
})
|
})
|
||||||
flags({
|
|
||||||
"WinMain", -- Use WinMain instead of main.
|
|
||||||
})
|
|
||||||
defines({
|
defines({
|
||||||
"HAVE_REMOTE=1"
|
"HAVE_REMOTE=1"
|
||||||
})
|
})
|
||||||
includedirs({
|
includedirs({
|
||||||
project_root.."/third_party/elemental-forms/src",
|
project_root.."/third_party/elemental-forms/src",
|
||||||
project_root.."/third_party/winpcap/Include",
|
project_root.."/third_party/winpcap/Include",
|
||||||
project_root.."/build_tools/third_party/gflags/src",
|
|
||||||
})
|
})
|
||||||
files({
|
files({
|
||||||
"net_proxy_main.cc",
|
"net_proxy_main.cc",
|
||||||
|
@ -33,7 +28,6 @@ project("xenia-net-proxy")
|
||||||
filter("platforms:Windows")
|
filter("platforms:Windows")
|
||||||
debugdir(project_root)
|
debugdir(project_root)
|
||||||
debugargs({
|
debugargs({
|
||||||
"--flagfile=scratch/flags.txt",
|
|
||||||
"2>&1",
|
"2>&1",
|
||||||
"1>scratch/stdout-net-proxy.txt",
|
"1>scratch/stdout-net-proxy.txt",
|
||||||
})
|
})
|
Loading…
Reference in New Issue