diff --git a/src/alloy/frontend/ppc/ppc_emit_control.cc b/src/alloy/frontend/ppc/ppc_emit_control.cc index 25a63f618..40e8a8ce3 100644 --- a/src/alloy/frontend/ppc/ppc_emit_control.cc +++ b/src/alloy/frontend/ppc/ppc_emit_control.cc @@ -547,21 +547,24 @@ XEEMITTER(mfcr, 0x7C000026, XFX)(PPCHIRBuilder& f, InstrData& i) { // extrwi r3, r10, 1, 26 // Could recognize this and only load the appropriate CR bit. - assert_true(i.XFX.spr & (1 << 9)); - uint32_t bits = (i.XFX.spr & 0x1FF) >> 1; - int count = 0; - int cri = 0; - for (int b = 0; b <= 7; ++b) { - if (bits & (1 << b)) { - cri = 7 - b; - ++count; - } - } Value* v; - if (count == 1) { - v = f.LoadCR(cri); + if (i.XFX.spr & (1 << 9)) { + uint32_t bits = (i.XFX.spr & 0x1FF) >> 1; + int count = 0; + int cri = 0; + for (int b = 0; b <= 7; ++b) { + if (bits & (1 << b)) { + cri = 7 - b; + ++count; + } + } + if (count == 1) { + v = f.LoadCR(cri); + } else { + v = f.LoadZero(INT64_TYPE); + } } else { - v = f.LoadZero(INT64_TYPE); + v = f.LoadCR(); } f.StoreGPR(i.XFX.RT, v); return 0; diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index d586c2fa5..ad4e8bc6d 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -252,6 +252,16 @@ void PPCHIRBuilder::StoreCTR(Value* value) { trace_reg.value = value; } +Value* PPCHIRBuilder::LoadCR() { + // All bits. This is expensive, but seems to be less used than the + // field-specific LoadCR. + Value* v = LoadCR(0); + for (int i = 1; i <= 7; ++i) { + v = Or(v, LoadCR(i)); + } + return v; +} + Value* PPCHIRBuilder::LoadCR(uint32_t n) { // Construct the entire word of just the bits we care about. // This makes it easier for the optimizer to exclude things, though diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.h b/src/alloy/frontend/ppc/ppc_hir_builder.h index 5fb172d96..5d09f1c78 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.h +++ b/src/alloy/frontend/ppc/ppc_hir_builder.h @@ -50,6 +50,7 @@ class PPCHIRBuilder : public hir::HIRBuilder { void StoreLR(Value* value); Value* LoadCTR(); void StoreCTR(Value* value); + Value* LoadCR(); Value* LoadCR(uint32_t n); Value* LoadCRField(uint32_t n, uint32_t bit); void StoreCR(uint32_t n, Value* value); diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index 383dbe215..70f53222a 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -33,6 +33,7 @@ KernelState* shared_kernel_state_ = nullptr; KernelState::KernelState(Emulator* emulator) : emulator_(emulator), memory_(emulator->memory()), + object_table_(nullptr), has_notified_startup_(false), process_type_(X_PROCTYPE_USER), executable_module_(nullptr) {