On 7/9/24 21:36, Jeff Law wrote:
>>>>>> +;; TODO: isinf is a bit tricky as it require trimodal return
>>>>>> +;; 1 if 0x80, -1 if 0x1, 0 otherwise
[..]
>> + rtx tmp2 = gen_reg_rtx (word_mode);
>> + emit_insn (gen_ashldi3 (tmp2, rclass, GEN_INT (w)));
>> + emit_insn (gen_lshrdi3 (tmp2, tmp2, GEN_INT (w)));
>>
>> Above doesn't work for the simple case where we have int return value of
>> the builtin.
> "doesn't work" does not give me enough information to guess what's
> wrong.
Sorry for being terse and tardy with that half arsed effort - I can
blame summer and rush to send the patch right before heading for
vacation :-)
> I do see that you're explicitly gen_ashldi3 and gen_lshrdi3,
> that'll work for rv64, but won't work for rv32.
>
> If you're generating code without immediately faulting, then I'd look
> at the .expand dump to see if the resulting code makes sense. If you're
> faulting, it'd be helpful to know where/why.
Yeah because of the mixing SI and DI modes the following emit_move_insn
() was ICE'ing.
I did get the implementation working, posting below for posterity (and
some redemption that I did get it working as desired)
(define_expand "isinf<ANYF:mode>2"
[(set (match_operand 0 "register_operand" "=r")
(match_operand:ANYF 1 "register_operand" " f"))]
"TARGET_HARD_FLOAT"
{
if (GET_MODE (operands[0]) != SImode
&& GET_MODE (operands[0]) != word_mode)
FAIL;
rtx rclass = gen_reg_rtx (word_mode);
rtx tmp = gen_reg_rtx (word_mode);
rtx t_op0 = operands[0];
rtx label = gen_label_rtx ();
rtx end_label = gen_label_rtx ();
emit_insn (gen_fclass<ANYF:mode> (rclass, operands[1]));
/* positive infinity */
riscv_emit_binary (AND, tmp, rclass, GEN_INT (0x80));
riscv_expand_conditional_branch (label, NE, tmp, const0_rtx);
/* negative infinity return -1 */
HOST_WIDE_INT w = GET_MODE_BITSIZE(word_mode) - 1;
riscv_emit_binary (AND, tmp, rclass, GEN_INT (0x1));
riscv_emit_unary (NEG, tmp, tmp);
riscv_emit_binary (ASHIFTRT, tmp, tmp, GEN_INT (w));
if (TARGET_64BIT && GET_MODE (operands[0]) == SImode)
{
t_op0 = gen_reg_rtx (DImode);
emit_insn (gen_extend_insn (t_op0, operands[0], DImode, SImode, 0));
}
emit_move_insn (t_op0, tmp);
emit_jump_insn (gen_jump (end_label));
emit_barrier ();
/* positive infinity return 1 */
emit_label (label);
emit_move_insn (t_op0, GEN_INT (1));
emit_label (end_label);
if (TARGET_64BIT)
{
t_op0 = gen_lowpart (SImode, t_op0);
SUBREG_PROMOTED_VAR_P (t_op0) = 1;
SUBREG_PROMOTED_SET (t_op0, SRP_SIGNED);
emit_move_insn (operands[0], t_op0);
}
DONE;
})
But this causes 1 additional failure in testsuite as tg-test.h ->
type-generic-1.[cC] expect a 1 for negative infinity.
Meaning we need to go back to bimodal semantics.
Thx,
-Vineet