diff --git a/src/backend/emitter.c b/src/backend/emitter.c index 809cb82..fe5d9d2 100644 --- a/src/backend/emitter.c +++ b/src/backend/emitter.c @@ -247,7 +247,7 @@ static void emit_psq_load(FILE* out, const PPCInst* inst, bool indexed, emit_dform_ea(out, inst->rA, inst->simm, update); } fprintf(out, ";\n"); - fprintf(out, " ppc_psq_load(ctx, %uu, ea, %s, %uu, %s, 0x%08Xu);\n", + fprintf(out, " ppc_psq_load_inline(ctx, %uu, ea, %s, %uu, %s, 0x%08Xu);\n", inst->rD, inst->w ? "true" : "false", inst->i, indexed ? "true" : "false", inst->address); fprintf(out, " if (ctx->exception) return;\n"); @@ -267,7 +267,7 @@ static void emit_psq_store(FILE* out, const PPCInst* inst, bool indexed, emit_dform_ea(out, inst->rA, inst->simm, update); } fprintf(out, ";\n"); - fprintf(out, " ppc_psq_store(ctx, %uu, ea, %s, %uu, %s, 0x%08Xu);\n", + fprintf(out, " ppc_psq_store_inline(ctx, %uu, ea, %s, %uu, %s, 0x%08Xu);\n", inst->rS, inst->w ? "true" : "false", inst->i, indexed ? "true" : "false", inst->address); fprintf(out, " if (ctx->exception) return;\n"); @@ -536,7 +536,7 @@ static void emit_instruction_with_range(FILE* out, const PPCInst* inst, } if (ppc_op_uses_fpu(inst->op)) - fprintf(out, " if (!ppc_fp_available(ctx, 0x%08Xu)) return;\n", inst->address); + fprintf(out, " if (!ppc_fp_available_inline(ctx, 0x%08Xu)) return;\n", inst->address); switch (inst->op) { case PPC_OP_MULLI: diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 3f2a3d3..7e5cd8a 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -175,6 +175,14 @@ void ppc_set_xer_ov(CPUState* cpu, bool ov); void ppc_take_exception(CPUState* cpu, u32 exception, u32 vector, u32 srr0, u32 srr1_info); void ppc_program_exception(CPUState* cpu, u32 cause, u32 cia); bool ppc_fp_available(CPUState* cpu, u32 cia); + +/* MSR[FP] spelled out rather than via PPC_MSR_FP: that macro is defined in + cpu.c, not here, and defining it in the header would collide with it. */ +static inline bool ppc_fp_available_inline(CPUState* cpu, u32 cia) { + if (cpu->msr & 0x00002000u) /* MSR[FP], PPC bit 18 */ + return true; + return ppc_fp_available(cpu, cia); +} void ppc_fallback_instruction(CPUState* cpu, u32 raw, u32 cia); bool ppc_host_call(CPUState* cpu, u32 address); void ppc_system_call_exception(CPUState* cpu, u32 cia); @@ -187,6 +195,19 @@ void ppc_rfi(CPUState* cpu, u32 cia); void ppc_dcbz_l(CPUState* cpu, u32 ea, u32 cia); bool ppc_psq_load(CPUState* cpu, u8 frD, u32 ea, bool w, u8 gqr, bool indexed, u32 cia); bool ppc_psq_store(CPUState* cpu, u8 frS, u32 ea, bool w, u8 gqr, bool indexed, u32 cia); + +/* The emitter emits the _inline forms so the hosting runtime can provide a fast + path (GXRuntime does, for the unquantised GQR type-0 case). This standalone + runtime backs the tests rather than a shipping port, so it simply forwards. */ +static inline bool ppc_psq_load_inline(CPUState* cpu, u8 frD, u32 ea, bool w, + u8 gqr, bool indexed, u32 cia) { + return ppc_psq_load(cpu, frD, ea, w, gqr, indexed, cia); +} + +static inline bool ppc_psq_store_inline(CPUState* cpu, u8 frS, u32 ea, bool w, + u8 gqr, bool indexed, u32 cia) { + return ppc_psq_store(cpu, frS, ea, w, gqr, indexed, cia); +} u32 ppc_eciwx(CPUState* cpu, u32 ea, u32 cia); void ppc_ecowx(CPUState* cpu, u32 ea, u32 value, u32 cia); void ppc_tlbie(CPUState* cpu, u32 ea, u32 cia); diff --git a/tests/cmake/codegen_compile.cmake b/tests/cmake/codegen_compile.cmake index f9c0feb..b1f2258 100644 --- a/tests/cmake/codegen_compile.cmake +++ b/tests/cmake/codegen_compile.cmake @@ -42,7 +42,7 @@ endif() if(NOT generated_source MATCHES "static void loop_80004040\\(CPUState\\* ctx\\)") message(FATAL_ERROR "ordinary RAM loop was not outlined") endif() -if(NOT generated_source MATCHES "if \\(!ppc_fp_available\\(ctx, 0x8000317Cu\\)\\) return;") +if(NOT generated_source MATCHES "if \\(!ppc_fp_available_inline\\(ctx, 0x8000317Cu\\)\\) return;") message(FATAL_ERROR "generated floating-point code has no MSR FP gate") endif() if(NOT generated_source MATCHES "ppc_fallback_instruction\\(ctx, 0x7C13A0ACu")