This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: issue of store to stack after an instruction
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);
}
}