Merge pull request #477 from DrChat/compiler_fixes

Compiler fixes
This commit is contained in:
Ben Vanik 2015-12-02 12:06:54 -08:00
commit d0c840e28a
3 changed files with 78 additions and 6 deletions

View File

@ -153,6 +153,14 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder) {
i->Remove(); i->Remove();
} }
break; break;
case OPCODE_CONVERT:
if (i->src1.value->IsConstant()) {
TypeName target_type = v->type;
v->set_from(i->src1.value);
v->Convert(target_type, RoundMode(i->flags));
i->Remove();
}
break;
case OPCODE_ZERO_EXTEND: case OPCODE_ZERO_EXTEND:
if (i->src1.value->IsConstant()) { if (i->src1.value->IsConstant()) {
TypeName target_type = v->type; TypeName target_type = v->type;
@ -195,10 +203,29 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder) {
!(protect & kMemoryProtectWrite) && !(protect & kMemoryProtectWrite) &&
(protect & kMemoryProtectRead)) { (protect & kMemoryProtectRead)) {
// Memory is readonly - can just return the value. // Memory is readonly - can just return the value.
auto host_addr = memory->TranslateVirtual(address);
switch (v->type) { switch (v->type) {
case INT8_TYPE:
v->set_constant(xe::load<uint8_t>(host_addr));
i->Remove();
break;
case INT16_TYPE:
v->set_constant(xe::load<uint16_t>(host_addr));
i->Remove();
break;
case INT32_TYPE: case INT32_TYPE:
v->set_constant(xe::load_and_swap<uint32_t>( v->set_constant(xe::load<uint32_t>(host_addr));
memory->TranslateVirtual(address))); i->Remove();
break;
case INT64_TYPE:
v->set_constant(xe::load<uint64_t>(host_addr));
i->Remove();
break;
case VEC128_TYPE:
vec128_t val;
val.low = xe::load<uint64_t>(host_addr);
val.high = xe::load<uint64_t>(host_addr + 8);
v->set_constant(val);
i->Remove(); i->Remove();
break; break;
default: default:

View File

@ -77,8 +77,8 @@ uint64_t Value::AsUint64() {
} }
void Value::Cast(TypeName target_type) { void Value::Cast(TypeName target_type) {
// TODO(benvanik): big matrix. // Only need a type change.
assert_always(); type = target_type;
} }
void Value::ZeroExtend(TypeName 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) { void Value::Convert(TypeName target_type, RoundMode round_mode) {
// TODO(benvanik): big matrix. switch (type) {
assert_always(); 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) { void Value::Round(RoundMode round_mode) {

View File

@ -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; return true;
} }