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