commit
d0c840e28a
|
@ -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:
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue