On 7/9/24 5:44 PM, Vineet Gupta wrote:


On 6/30/24 06:59, Jeff Law wrote:

+;; TODO: isinf is a bit tricky as it require trimodal return
+;;  1 if 0x80, -1 if 0x1, 0 otherwise

It shouldn't be terrible, but it's not trivial either.

bext t0, a0, 0
neg t0
bext t1, a0, 7
czero.nez res, t0, t1
snez t1, t1
add a0, a1, a0

Or something reasonably close to that.
I wrote the "C" code and saw what compiler would do 😉 for the baseline
isa build.

      andi    a5,a0,128
      bne    a5,zero,.L7
      slli    a5,a0,63
      srai    a0,a5,63
      ret
.L7:
      li    a0,1
      ret

But again labels are hard (for me ) in md.
I'm sure there examples.  Look at <round_pattern><ANYF:mode>2

So I think I have an implementation but the issue again is md syntax
getting in the way.

+;; Implements optab for isinf
+
+(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);
+  emit_insn (gen_fclass<ANYF:mode> (rclass, operands[1]));
+
+  rtx tmp = gen_reg_rtx (word_mode);
+  rtx label = gen_label_rtx ();
+  rtx end_label = gen_label_rtx ();
+
+  /* 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;
+  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. 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.




+  emit_move_insn (operands[0], tmp2);
Aren't you going to need to use gen_lowpart if tmp2 is DI and operands[0] is SI here?


Jeff

Reply via email to