]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
xtensa: Make use of ROUND.S instruction
authorTakayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp>
Fri, 31 Oct 2025 06:22:35 +0000 (15:22 +0900)
committerMax Filippov <jcmvbkbc@gmail.com>
Sat, 1 Nov 2025 04:38:53 +0000 (21:38 -0700)
Due to inconsistencies in the behavior of rounding half, making this
machine instruction available was retracted in a previous commit (5f3b5b0616fe883e86e95d9476371cf87059ca7f),
but it may be useful to have it available if strict implementation of
floating-point arithmetic is not required.

gcc/ChangeLog:

* config/xtensa/xtensa.md
(c_enum "unspec", int_iterator ANY_ROUND): Add UNSPEC_ROUND.
(int_attr m_round): Add a pair of UNSPEC_ROUND and "round".
(int_attr c_round): New integer iterator attribute, that expands
to "flag_unsafe_math_optimizations" in the case of UNSPEC_ROUND,
and to "1" otherwise.
(l<m_round>sfsi2, *l<m_round>sfsi2_2x, *l<m_round>sfsi2_scaled):
Append " && <c_round>" to the conditions.

gcc/config/xtensa/xtensa.md

index e05b35bb964b0e8ad8f41d0c9d2b2bed978d6b03..7dc941f95714f02ce8c5d1bceb43faca0f98efea 100644 (file)
@@ -43,6 +43,7 @@
   UNSPEC_FRAME_BLOCKAGE
   UNSPEC_CEIL
   UNSPEC_FLOOR
+  UNSPEC_ROUND
 ])
 
 (define_c_enum "unspecv" [
 
 ;; This iterator and attribute allow FP-to-integer rounding of two types
 ;; to be generated from one template.
-(define_int_iterator ANY_ROUND [UNSPEC_CEIL UNSPEC_FLOOR])
-(define_int_attr m_round [(UNSPEC_CEIL "ceil") (UNSPEC_FLOOR "floor")])
+(define_int_iterator ANY_ROUND [UNSPEC_CEIL UNSPEC_FLOOR UNSPEC_ROUND])
+(define_int_attr m_round [(UNSPEC_CEIL "ceil") (UNSPEC_FLOOR "floor")
+                         (UNSPEC_ROUND "round")])
+(define_int_attr c_round [(UNSPEC_CEIL "1") (UNSPEC_FLOOR "1")
+                         (UNSPEC_ROUND "flag_unsafe_math_optimizations")])
 
 \f
 ;; Attributes.
 (define_insn "l<m_round>sfsi2"
   [(set (match_operand:SI 0 "register_operand" "=a")
        (unspec:SI [(match_operand:SF 1 "register_operand" "f")] ANY_ROUND))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && <c_round>"
   "<m_round>.s\t%0, %1, 0"
   [(set_attr "type"    "fconv")
    (set_attr "mode"    "SF")
   [(set (match_operand:SI 0 "register_operand" "=a")
        (unspec:SI [(plus:SF (match_operand:SF 1 "register_operand" "f")
                             (match_dup 1))] ANY_ROUND))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && <c_round>"
   "<m_round>.s\t%0, %1, 1"
   [(set_attr "type"    "fconv")
    (set_attr "mode"    "SF")
   [(set (match_operand:SI 0 "register_operand" "=a")
        (unspec:SI [(mult:SF (match_operand:SF 1 "register_operand" "f")
                             (match_operand:SF 2 "fix_scaling_operand" ""))] ANY_ROUND))]
-  "TARGET_HARD_FLOAT"
+  "TARGET_HARD_FLOAT && <c_round>"
   "<m_round>.s\t%0, %1, %U2"
   [(set_attr "type"    "fconv")
    (set_attr "mode"    "SF")