Eric Botcazou wrote: >> I would like to implement a compiler fix for a SPARC-cpu variant >> that does the following: >> After each "fdivs" (SPARC single-float division) save the destination >> FPU register to a stack memory location. > > Do you need to reload it afterward or just save it? >
I just need to save it. It needs to be saved so that the FPU pipeline is flushed. It could be one per function allocated stack location, or one stack location for each fdivs. I was previously using define_expand to generate a different pattern + the stack location for divsf3 and then define that pattern. It does work however it feels like a hack... -- Thanks Konrad Like this: ;;;;;;;;;;;;;;;;;; handle divsf3 ;;;;;;;;;;;;;;;; (define_expand "divsf3" [(set (match_operand:SF 0 "register_operand" "=f") (div:SF (match_operand:SF 1 "register_operand" "f") (match_operand:SF 2 "register_operand" "f"))) ] "TARGET_FPU && (!TARGET_NO_SF_DIVSQRT)" "{ output_divsf3_emit (operands[0], operands[1], operands[2], 0); DONE; }") (define_insn "divsf3_store" [(set (match_operand:SF 0 "register_operand" "=f") (div:SF (match_operand:SF 1 "register_operand" "f") (match_operand:SF 2 "register_operand" "f"))) (use (match_operand:SI 3 "general_operand" "" ))] "TARGET_FPU && TARGET_STORE_AFTER_DIVSQRT && (!TARGET_NO_SF_DIVSQRT)" "fdivs\t%%1, %%2, %%0; st %%0, [%%3] " [(set_attr "type" "multi") (set_attr "length" "2") ]) (define_insn "divsf3_nostore" [(set (match_operand:SF 0 "register_operand" "=f") (div:SF (match_operand:SF 1 "register_operand" "f") (match_operand:SF 2 "register_operand" "f")))] "TARGET_FPU && (!TARGET_STORE_AFTER_DIVSQRT) && (!TARGET_NO_SF_DIVSQRT)" "fdivs\t%1, %2, %0" [(set_attr "type" "fpdivs")]) void output_divsf3_emit (rtx dest, rtx op0, rtx op1, rtx scratch) { rtx slot0, div, divsave; div = gen_rtx_SET (VOIDmode, dest, gen_rtx_DIV (SFmode, op0, op1)); if (TARGET_STORE_AFTER_DIVSQRT) { rtx m; slot0 = assign_stack_local (SFmode, 4, 4); m = copy_to_reg (XEXP (slot0, 0)); emit_insn (gen_rtx_PARALLEL(VOIDmode, gen_rtvec (2, div, gen_rtx_USE (VOIDmode, m)))); } else { emit_insn(div); } }