https://gcc.gnu.org/g:efc69e28d8c552a98f09a6c17cedaa189d7bce25

commit r17-3984-gefc69e28d8c552a98f09a6c17cedaa189d7bce25
Author: Takayuki 'January June' Suwa <[email protected]>
Date:   Mon Sep 7 23:04:13 2026 +0900

    xtensa: Discourage use of hardware FP registers for SFmode load/store
    
    In the Xtensa ISA, using either address (general-purpose) registers or
    hardware floating-point registers for loading or storing single-precision
    floating-point values results in no difference in semantics or speed;
    however, the former is advantageous in terms of code size when the Code
    Density Option is configured.
    
    This patch lowers the priority of H/W FP registers for SFmode load/store
    operations by prefixing the register constraints with '*' in the alternative
    specifications within the MD insn definition.
    
         /* example */
         extern float b;
         void test0(int a) {
           b = a ? b : 0;
         }
         void test1(int a) {
           b = a ? b : 1;
         }
    
         ;; before (-O2 ; TARGET_HARD_FLOAT | TARGET_DENSITY)
            .literal_position
            .literal .LC0, b
         test0:
            entry   sp, 32
            l32r    a8, .LC0
            beqz.n  a2, .L3
            lsi     f0, a8, 0       ;; load to FPR
            j       .L2
         .L3:
            const.s f0, 0           ;; set +0.f to FPR
         .L2:
            ssi     f0, a8, 0       ;; store from FPR
            retw.n
            .literal_position
            .literal .LC1, b
         test1:
            entry   sp, 32
            l32r    a8, .LC1
            beqz.n  a2, .L7
            lsi     f0, a8, 0       ;; load to FPR
            j       .L6
         .L7:
            const.s f0, 1           ;; set 1.f to FPR
         .L6:
            ssi     f0, a8, 0       ;; store from FPR
            retw.n
    
         ;; after (-O2 ; TARGET_HARD_FLOAT | TARGET_DENSITY)
            .literal_position
            .literal .LC0, b
         test0:
            entry   sp, 32
            l32r    a8, .LC0
            beqz.n  a2, .L3
            l32i.n  a9, a8, 0       ;; load to GPR (1 byte shorter)
            j       .L2
         .L3:
            movi.n  a9, 0           ;; set +0.f to GPR (1 byte shorter)
         .L2:
            s32i.n  a9, a8, 0       ;; store from GPR (1 byte shorter)
            retw.n
            .literal_position
            .literal .LC1, b
         test1:
            entry   sp, 32
            l32r    a8, .LC1
            beqz.n  a2, .L7
            lsi     f0, a8, 0       ;; load to FPR (no changes)
            j       .L6
         .L7:
            const.s f0, 1           ;; set 1.f to FPR (no changes)
                                    ;; Since this instruction constrains the
                                    ;; regclass, the lowered priority of FPR
                                    ;; is not taken into account.
         .L6:
            ssi     f0, a8, 0       ;; store from FPR (no changes)
            retw.n
    
    gcc/ChangeLog:
    
            * config/xtensa/xtensa.md (movsf_internal):
            Prefix register constraints with '*' for hardware FP register load
            and store alternatives.

Diff:
---
 gcc/config/xtensa/xtensa.md | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index d6ef0efd150e..753f23412be8 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -1411,23 +1411,23 @@
   "register_operand (operands[0], SFmode)
    || register_operand (operands[1], SFmode)"
   {@ [cons: =0, 1; attrs: type, length]
-     [D, Gz; move  , 2] movi.n\t%0, 0
-     [a, Gz; move  , 3] movi\t%0, 0
-     [f, Gc; farith, 3] const.s\t%0, %G1
-     [W, iF; move  , 6] const16\t%0, %t1\;const16\t%0, %b1
-     [a,  Y; load  , 3] movi\t%0, %y1
-     [a,  T; load  , 3] %v1l32r\t%0, %1
-     [D,  d; move  , 2] mov.n\t%0, %1
-     [a,  r; move  , 3] mov\t%0, %1
-     [f,  f; farith, 3] mov.s\t%0, %1
-     [f,  r; farith, 3] wfr\t%0, %1
-     [a,  f; farith, 3] rfr\t%0, %1
-     [D,  R; load  , 2] %v1l32i.n\t%0, %1
-     [a,  U; load  , 3] %v1l32i\t%0, %1
-     [f,  U; fload , 3] %v1lsi\t%0, %1
-     [R,  d; store , 2] %v0s32i.n\t%1, %0
-     [U,  r; store , 3] %v0s32i\t%1, %0
-     [U,  f; fstore, 3] %v0ssi\t%1, %0
+     [ D, Gz; move  , 2] movi.n\t%0, 0
+     [ a, Gz; move  , 3] movi\t%0, 0
+     [ f, Gc; farith, 3] const.s\t%0, %G1
+     [ W, iF; move  , 6] const16\t%0, %t1\;const16\t%0, %b1
+     [ a,  Y; load  , 3] movi\t%0, %y1
+     [ a,  T; load  , 3] %v1l32r\t%0, %1
+     [ D,  d; move  , 2] mov.n\t%0, %1
+     [ a,  r; move  , 3] mov\t%0, %1
+     [ f,  f; farith, 3] mov.s\t%0, %1
+     [ f,  r; farith, 3] wfr\t%0, %1
+     [ a,  f; farith, 3] rfr\t%0, %1
+     [ D,  R; load  , 2] %v1l32i.n\t%0, %1
+     [ a,  U; load  , 3] %v1l32i\t%0, %1
+     [*f,  U; fload , 3] %v1lsi\t%0, %1
+     [ R,  d; store , 2] %v0s32i.n\t%1, %0
+     [ U,  r; store , 3] %v0s32i\t%1, %0
+     [ U, *f; fstore, 3] %v0ssi\t%1, %0
   }
   [(set_attr "mode" "SF")])

Reply via email to