From 873016f06f7e68b791584af124af6162d547b897 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Tue, 1 Dec 2015 19:03:51 -0600 Subject: [PATCH 1/5] Fix double-swap in constant load --- src/xenia/cpu/compiler/passes/constant_propagation_pass.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc b/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc index 468e35ce0..29ce3e02d 100644 --- a/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc +++ b/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc @@ -197,8 +197,8 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder) { // Memory is readonly - can just return the value. switch (v->type) { case INT32_TYPE: - v->set_constant(xe::load_and_swap( - memory->TranslateVirtual(address))); + v->set_constant( + xe::load(memory->TranslateVirtual(address))); i->Remove(); break; default: From 525d62d43706821afb8f299e8992f49ea0ffb68a Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Tue, 1 Dec 2015 19:51:28 -0600 Subject: [PATCH 2/5] constant OPCODE_CONVERT and more cases for OPCODE_LOAD --- .../passes/constant_propagation_pass.cc | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc b/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc index 29ce3e02d..0663cb613 100644 --- a/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc +++ b/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc @@ -153,6 +153,14 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder) { i->Remove(); } break; + case OPCODE_CONVERT: + if (i->src1.value->IsConstant()) { + TypeName target_type = v->type; + v->set_from(i->src1.value); + v->Convert(target_type, ROUND_TO_NEAREST); + i->Remove(); + } + break; case OPCODE_ZERO_EXTEND: if (i->src1.value->IsConstant()) { TypeName target_type = v->type; @@ -195,10 +203,29 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder) { !(protect & kMemoryProtectWrite) && (protect & kMemoryProtectRead)) { // Memory is readonly - can just return the value. + auto host_addr = memory->TranslateVirtual(address); switch (v->type) { + case INT8_TYPE: + v->set_constant(xe::load(host_addr)); + i->Remove(); + break; + case INT16_TYPE: + v->set_constant(xe::load(host_addr)); + i->Remove(); + break; case INT32_TYPE: - v->set_constant( - xe::load(memory->TranslateVirtual(address))); + v->set_constant(xe::load(host_addr)); + i->Remove(); + break; + case INT64_TYPE: + v->set_constant(xe::load(host_addr)); + i->Remove(); + break; + case VEC128_TYPE: + vec128_t val; + val.low = xe::load(host_addr); + val.high = xe::load(host_addr + 8); + v->set_constant(val); i->Remove(); break; default: From 57a823ae39b22687591dc023bd34cf227dd914c4 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Tue, 1 Dec 2015 19:53:17 -0600 Subject: [PATCH 3/5] Add (commented out) code to setup page protections for xex modules. --- src/xenia/cpu/xex_module.cc | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/xenia/cpu/xex_module.cc b/src/xenia/cpu/xex_module.cc index 07730e211..ba2a24184 100644 --- a/src/xenia/cpu/xex_module.cc +++ b/src/xenia/cpu/xex_module.cc @@ -281,6 +281,34 @@ bool XexModule::Load(const std::string& name, const std::string& path, } } + // Setup memory protection. + // TODO: This introduces a load of constants into the JIT, and Xenia isn't + // quite set-up to handle constants yet... + /* + auto sec_header = xex_security_info(); + auto heap = memory()->LookupHeap(sec_header->load_address); + auto page_size = heap->page_size(); + for (uint32_t i = 0, page = 0; i < sec_header->page_descriptor_count; i++) { + // Byteswap the bitfield manually. + xex2_page_descriptor desc; + desc.value = xe::byte_swap(sec_header->page_descriptors[i].value); + + auto address = sec_header->load_address + (page * page_size); + auto size = desc.size * page_size; + switch (desc.info) { + case XEX_SECTION_CODE: + case XEX_SECTION_READONLY_DATA: + heap->Protect(address, size, kMemoryProtectRead); + break; + case XEX_SECTION_DATA: + heap->Protect(address, size, kMemoryProtectRead | kMemoryProtectWrite); + break; + } + + page += desc.size; + } + */ + return true; } From 17d18f715493c44260e5fb42294547501dd48efb Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Tue, 1 Dec 2015 20:24:34 -0600 Subject: [PATCH 4/5] Implement a few cases for Value::Cast/Convert --- src/xenia/cpu/hir/value.cc | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/xenia/cpu/hir/value.cc b/src/xenia/cpu/hir/value.cc index d8f614a7e..e0be35b58 100644 --- a/src/xenia/cpu/hir/value.cc +++ b/src/xenia/cpu/hir/value.cc @@ -77,8 +77,8 @@ uint64_t Value::AsUint64() { } void Value::Cast(TypeName target_type) { - // TODO(benvanik): big matrix. - assert_always(); + // Only need a type change. + type = target_type; } void Value::ZeroExtend(TypeName target_type) { @@ -199,8 +199,25 @@ void Value::Truncate(TypeName target_type) { } void Value::Convert(TypeName target_type, RoundMode round_mode) { - // TODO(benvanik): big matrix. - assert_always(); + switch (type) { + case FLOAT32_TYPE: + switch (target_type) { + case FLOAT64_TYPE: + type = target_type; + constant.f64 = constant.f32; + return; + } + case FLOAT64_TYPE: + switch (target_type) { + case FLOAT32_TYPE: + type = target_type; + constant.f32 = (float)constant.f64; + return; + } + default: + assert_unhandled_case(target_type); + return; + } } void Value::Round(RoundMode round_mode) { From bc1e7684cad398dd336715f52e4380330b2bf006 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Wed, 2 Dec 2015 14:03:15 -0600 Subject: [PATCH 5/5] Pass rounding mode from i->flags for OPCODE_CONVERT --- src/xenia/cpu/compiler/passes/constant_propagation_pass.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc b/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc index 0663cb613..c8a5ef632 100644 --- a/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc +++ b/src/xenia/cpu/compiler/passes/constant_propagation_pass.cc @@ -157,7 +157,7 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder) { if (i->src1.value->IsConstant()) { TypeName target_type = v->type; v->set_from(i->src1.value); - v->Convert(target_type, ROUND_TO_NEAREST); + v->Convert(target_type, RoundMode(i->flags)); i->Remove(); } break;