commit
d0c840e28a
|
@ -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, RoundMode(i->flags));
|
||||
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<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:
|
||||
v->set_constant(xe::load_and_swap<uint32_t>(
|
||||
memory->TranslateVirtual(address)));
|
||||
v->set_constant(xe::load<uint32_t>(host_addr));
|
||||
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();
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue