]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
xtensa: Add alternative negsf2 insn pattern
authorTakayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp>
Fri, 31 Oct 2025 06:23:15 +0000 (15:23 +0900)
committerMax Filippov <jcmvbkbc@gmail.com>
Sat, 1 Nov 2025 04:38:54 +0000 (21:38 -0700)
If both the source and destination are address (GP) registers, emitting
instructions that invert the MSB of the address register is two bytes
shorter if TARGET_DENSITY is enabled than emitting a NEG.S machine inst-
ruction that uses hardware FP registers with two reloads.

     /* example */
     float test(float a) {
       return -a;
     }

     ;; before
     test:
      entry sp, 32
      wfr f0, a2
      neg.s f0, f0
      rfr a2, f0
      retw.n

     ;; after
     test:
      entry sp, 32
      movi.n a8, 1
      slli a8, a8, 31
      add.n a2, a2, a8
      retw.n

By the way, in configurations that do not use hardware FP register, the
RTL expansion pass will emit such insns by default.

gcc/ChangeLog:

* config/xtensa/xtensa.md (negsf2):
Add another insn pattern that is valid when TARGET_DENSITY is
enabled and both the source and destination are address registers.

gcc/config/xtensa/xtensa.md

index 7dc941f95714f02ce8c5d1bceb43faca0f98efea..c713451951cb6a436c2d79fb07a8c34c0d14e33a 100644 (file)
 })
 
 (define_insn "negsf2"
-  [(set (match_operand:SF 0 "register_operand" "=f")
-       (neg:SF (match_operand:SF 1 "register_operand" "f")))]
+  [(set (match_operand:SF 0 "register_operand")
+        (neg:SF (match_operand:SF 1 "register_operand")))
+   (clobber (match_scratch:SI 2))]
   "TARGET_HARD_FLOAT"
-  "neg.s\t%0, %1"
-  [(set_attr "type"    "farith")
-   (set_attr "mode"    "SF")
-   (set_attr "length"  "3")])
+  {@ [cons: =0, 1, =2; attrs: type, length]
+     [D, D, &a; arith , 7] movi.n\t%2, 1\;slli\t%2, %2, 31\;add.n\t%0, %1, %2
+     [f, f,  X; farith, 3] neg.s\t%0, %1
+  }
+  [(set_attr "mode" "SF")])
 
 \f
 ;; Logical instructions.