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.
---
 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 d6ef0efd150..753f23412be 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")])
--
2.39.5

Reply via email to