在 2023/11/20 上午8:47, Xi Ruoyao 写道:
The usage LSX and LASX frint/ftint instructions had some problems:

1. These instructions raises FE_INEXACT, which is not allowed with
    -fno-fp-int-builtin-inexact for most C2x section F.10.6 functions
    (the only exceptions are rint, lrint, and llrint).
2. The "frint" instruction without explicit rounding mode is used for
    roundM2, this is incorrect because roundM2 is defined "rounding
    operand 1 to the *nearest* integer, rounding away from zero in the
    event of a tie".  We actually don't have such an instruction.  Our
    frintrne instruction is roundevenM2 (unfortunately, this is not
    documented).
3. These define_insn's are written in a way not so easy to hack.

So I removed these instructions and created a "simd.md" file, then added
them and the corresponding expanders there.  The advantage of the
simd.md file is we don't need to duplicate the RTL template twice (in
lsx.md and lasx.md).
/* snip */
+;; fix_trunc is allowed to raise inexact exception even if
+;; -fno-fp-int-builtin-inexact.  Because the middle end trys to match
+;; (FIX x) and it does not know (FIX (UNSPEC_SIMD_FRINTRZ x)), we need
+;; to use define_insn_and_split instead of define_expand (expanders are
+;; not considered during matching).

Hi,

 I don’t quite understand this part. Is it because define_insn would be duplicated with the above implementation,

so define_insn_and_split is used?


Thanks.

+(define_insn_and_split "fix_trunc<mode><vimode>2"
+  [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
+       (fix:<VIMODE> (match_operand:FVEC 1 "register_operand" "f")))]
+  ""
+  "#"
+  ""
+  [(const_int 0)]
+  {
+    emit_insn (gen_<simd_isa>_<x>vftintrz_<simdifmt_for_f>_<simdfmt> (
+      operands[0], operands[1]));
+    DONE;
+  }
+  [(set_attr "type" "simd_fcvt")
+   (set_attr "mode" "<MODE>")])



Reply via email to