[gcc(refs/users/meissner/heads/work168-tar)] Restrict SPR to appropriate integer modes.
Michael Meissner
meissner@gcc.gnu.org
Tue Jun 4 18:26:01 GMT 2024
https://gcc.gnu.org/g:8f96a3df132b456f535b8c94bb436dca44eecc39
commit 8f96a3df132b456f535b8c94bb436dca44eecc39
Author: Michael Meissner <meissner@linux.ibm.com>
Date: Tue Jun 4 13:44:01 2024 -0400
Restrict SPR to appropriate integer modes.
In preparation for the patches to add support for the TAR register, I restricted
the modes that special purpose registers (SPRs) could hold to be appropriate
sized scalar integers. I have discovered occasionally when GCC has run out of
registers, it will use the SPRs to hold values instead of spilling them to the
stack. The LR/CTR registers can hold 8/16/32-bit values and on 64-bit systems,
they can also hold 64-bit values. The VRSAVE and VSCR registers can only hold
32-bit values.
2024-06-04 Michael Meissner <meissner@linux.ibm.com>
gcc/
* config/rs6000/rs6000.cc (rs6000_hard_regno_mode_ok_uncached): Restrict
SPR registers to only hold scalar integer modes of an appropriate size.
* config/rs6000/rs6000.md (movcc_<mode>): Remove alternatives that move
values to/from the SPRs.
(movsf_hardfloat): Likewise.
(movsd_hardfloat): Likewise.
(mov<mode>_softfloat): Likewise.
(mov<mode>_softfloat32): Likewise.
(mov<mode>_hardfloat64): Likewise.
(*mov<mode>_softfloat64): Likewise.
Diff:
---
gcc/config/rs6000/rs6000.cc | 29 ++++++++++-
gcc/config/rs6000/rs6000.md | 117 +++++++++++++++++++-------------------------
2 files changed, 77 insertions(+), 69 deletions(-)
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index c5c4191127e..c2f8096beec 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -1851,9 +1851,13 @@ static int
rs6000_hard_regno_mode_ok_uncached (int regno, machine_mode mode)
{
int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
+ bool orig_complex_p = false;
if (COMPLEX_MODE_P (mode))
- mode = GET_MODE_INNER (mode);
+ {
+ mode = GET_MODE_INNER (mode);
+ orig_complex_p = true;
+ }
/* Vector pair modes need even/odd VSX register pairs. Only allow vector
registers. */
@@ -1935,6 +1939,29 @@ rs6000_hard_regno_mode_ok_uncached (int regno, machine_mode mode)
if (CA_REGNO_P (regno))
return mode == Pmode || mode == SImode;
+ /* Restrict SPR registers to only hold an appropriate sized integer mode. In
+ partciular, do not allow condition codes, complex values, or floating
+ point. VRSAVE and VSCR can only hold 32-bit values. */
+ switch (regno)
+ {
+ case VRSAVE_REGNO:
+ case VSCR_REGNO:
+ case LR_REGNO:
+ case CTR_REGNO:
+ {
+ unsigned reg_size = ((regno == VRSAVE_REGNO || regno == VSCR_REGNO)
+ ? 4
+ : UNITS_PER_WORD);
+
+ return (!orig_complex_p
+ && GET_MODE_SIZE (mode) <= reg_size
+ && SCALAR_INT_MODE_P (mode));
+ }
+
+ default:
+ break;
+ }
+
/* AltiVec only in AldyVec registers. */
if (ALTIVEC_REGNO_P (regno))
return (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 44d38df56f1..e5d3cb286cb 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -8119,9 +8119,9 @@
(define_insn "*movcc_<mode>"
[(set (match_operand:CC_any 0 "nonimmediate_operand"
- "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
+ "=y,x,?y,y,r,r,r,r,r,m")
(match_operand:CC_any 1 "general_operand"
- " y,r, r,O,x,y,r,I,*h, r,m,r"))]
+ " y,r, r,O,x,y,r,I,m,r"))]
"register_operand (operands[0], <MODE>mode)
|| register_operand (operands[1], <MODE>mode)"
"@
@@ -8133,8 +8133,6 @@
mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
mr %0,%1
li %0,%1
- mf%1 %0
- mt%0 %1
lwz%U1%X1 %0,%1
stw%U0%X0 %1,%0"
[(set_attr_alternative "type"
@@ -8148,11 +8146,9 @@
(const_string "mfcrf") (const_string "mfcr"))
(const_string "integer")
(const_string "integer")
- (const_string "mfjmpr")
- (const_string "mtjmpr")
(const_string "load")
(const_string "store")])
- (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")])
+ (set_attr "length" "*,*,12,*,*,8,*,*,*,*")])
;; For floating-point, we normally deal with the floating-point registers
;; unless -msoft-float is used. The sole exception is that parameter passing
@@ -8203,17 +8199,17 @@
;;
;; LWZ LFS LXSSP LXSSPX STFS STXSSP
;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
-;; MR MT<x> MF<x> NOP XXSPLTIDP
+;; MR XXSPLTIDP
(define_insn "movsf_hardfloat"
[(set (match_operand:SF 0 "nonimmediate_operand"
"=!r, f, v, wa, m, wY,
Z, m, wa, !r, f, wa,
- !r, *c*l, !r, *h, wa")
+ !r, wa")
(match_operand:SF 1 "input_operand"
"m, m, wY, Z, f, v,
wa, r, j, j, f, wa,
- r, r, *h, 0, eP"))]
+ r, eP"))]
"(register_operand (operands[0], SFmode)
|| register_operand (operands[1], SFmode))
&& TARGET_HARD_FLOAT
@@ -8233,32 +8229,29 @@
fmr %0,%1
xscpsgndp %x0,%x1,%x1
mr %0,%1
- mt%0 %1
- mf%1 %0
- nop
#"
[(set_attr "type"
"load, fpload, fpload, fpload, fpstore, fpstore,
fpstore, store, veclogical, integer, fpsimple, fpsimple,
- *, mtjmpr, mfjmpr, *, vecperm")
+ *, vecperm")
(set_attr "isa"
"*, *, p9v, p8v, *, p9v,
p8v, *, *, *, *, *,
- *, *, *, *, p10")
+ *, p10")
(set_attr "prefixed"
"*, *, *, *, *, *,
*, *, *, *, *, *,
- *, *, *, *, yes")])
+ *, yes")])
;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
-;; FMR MR MT%0 MF%1 NOP
+;; FMR MR
(define_insn "movsd_hardfloat"
[(set (match_operand:SD 0 "nonimmediate_operand"
"=!r, d, m, ?Z, ?d, ?r,
- f, !r, *c*l, !r, *h")
+ f, !r")
(match_operand:SD 1 "input_operand"
"m, ?Z, r, wx, r, d,
- f, r, r, *h, 0"))]
+ f, r"))]
"(register_operand (operands[0], SDmode)
|| register_operand (operands[1], SDmode))
&& TARGET_HARD_FLOAT"
@@ -8270,49 +8263,43 @@
mtvsrwz %x0,%1
mfvsrwz %0,%x1
fmr %0,%1
- mr %0,%1
- mt%0 %1
- mf%1 %0
- nop"
+ mr %0,%1"
[(set_attr "type"
"load, fpload, store, fpstore, mtvsr, mfvsr,
- fpsimple, *, mtjmpr, mfjmpr, *")
+ fpsimple, *")
(set_attr "isa"
"*, p7, *, *, p8v, p8v,
- *, *, *, *, *")])
+ *, *")])
-;; MR MT%0 MF%0 LWZ STW LI
-;; LIS G-const. F/n-const NOP
+;; MR LWZ STW LI
+;; LIS G-const. F/n-const
(define_insn "*mov<mode>_softfloat"
[(set (match_operand:FMOVE32 0 "nonimmediate_operand"
- "=r, *c*l, r, r, m, r,
- r, r, r, *h")
+ "=r, r, m, r,
+ r, r, r")
(match_operand:FMOVE32 1 "input_operand"
- "r, r, *h, m, r, I,
- L, G, Fn, 0"))]
+ "r, m, r, I,
+ L, G, Fn"))]
"(gpc_reg_operand (operands[0], <MODE>mode)
|| gpc_reg_operand (operands[1], <MODE>mode))
&& TARGET_SOFT_FLOAT"
"@
mr %0,%1
- mt%0 %1
- mf%1 %0
lwz%U1%X1 %0,%1
stw%U0%X0 %1,%0
li %0,%1
lis %0,%v1
#
- #
- nop"
+ #"
[(set_attr "type"
- "*, mtjmpr, mfjmpr, load, store, *,
- *, *, *, *")
+ "*, load, store, *,
+ *, *, *")
(set_attr "length"
- "*, *, *, *, *, *,
- *, *, 8, *")])
+ "*, *, *, *,
+ *, *, 8")])
;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
@@ -8592,20 +8579,20 @@
;; STFD LFD FMR LXSD STXSD
;; LXSDX STXSDX XXLOR XXLXOR LI 0
-;; STD LD MR MT{CTR,LR} MF{CTR,LR}
-;; NOP MFVSRD MTVSRD XXSPLTIDP
+;; STD LD MR
+;; MFVSRD MTVSRD XXSPLTIDP
(define_insn "*mov<mode>_hardfloat64"
[(set (match_operand:FMOVE64 0 "nonimmediate_operand"
"=m, d, d, <f64_p9>, wY,
<f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
- YZ, r, !r, *c*l, !r,
- *h, r, <f64_dm>, wa")
+ YZ, r, !r,
+ r, <f64_dm>, wa")
(match_operand:FMOVE64 1 "input_operand"
"d, m, d, wY, <f64_p9>,
Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
- r, YZ, r, r, *h,
- 0, <f64_dm>, r, eP"))]
+ r, YZ, r,
+ <f64_dm>, r, eP"))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT
&& (gpc_reg_operand (operands[0], <MODE>mode)
|| gpc_reg_operand (operands[1], <MODE>mode))"
@@ -8623,40 +8610,37 @@
std%U0%X0 %1,%0
ld%U1%X1 %0,%1
mr %0,%1
- mt%0 %1
- mf%1 %0
- nop
mfvsrd %0,%x1
mtvsrd %x0,%1
#"
[(set_attr "type"
"fpstore, fpload, fpsimple, fpload, fpstore,
fpload, fpstore, veclogical, veclogical, integer,
- store, load, *, mtjmpr, mfjmpr,
- *, mfvsr, mtvsr, vecperm")
+ store, load, *,
+ mfvsr, mtvsr, vecperm")
(set_attr "size" "64")
(set_attr "isa"
"*, *, *, p9v, p9v,
p7v, p7v, *, *, *,
- *, *, *, *, *,
- *, p8v, p8v, p10")
+ *, *, *,
+ p8v, p8v, p10")
(set_attr "prefixed"
"*, *, *, *, *,
*, *, *, *, *,
- *, *, *, *, *,
- *, *, *, *")])
+ *, *, *,
+ *, *, *")])
-;; STD LD MR MT<SPR> MF<SPR> G-const
-;; H-const F-const Special
+;; STD LD MR G-const
+;; H-const F-const
(define_insn "*mov<mode>_softfloat64"
[(set (match_operand:FMOVE64 0 "nonimmediate_operand"
- "=Y, r, r, *c*l, r, r,
- r, r, *h")
+ "=Y, r, r, r,
+ r, r")
(match_operand:FMOVE64 1 "input_operand"
- "r, Y, r, r, *h, G,
- H, F, 0"))]
+ "r, Y, r, G,
+ H, F"))]
"TARGET_POWERPC64 && TARGET_SOFT_FLOAT
&& (gpc_reg_operand (operands[0], <MODE>mode)
@@ -8665,19 +8649,16 @@
std%U0%X0 %1,%0
ld%U1%X1 %0,%1
mr %0,%1
- mt%0 %1
- mf%1 %0
#
#
- #
- nop"
+ #"
[(set_attr "type"
- "store, load, *, mtjmpr, mfjmpr, *,
- *, *, *")
+ "store, load, *, *,
+ *, *")
(set_attr "length"
- "*, *, *, *, *, 8,
- 12, 16, *")])
+ "*, *, *, 8,
+ 12, 16")])
;; Split the VSX prefixed instruction to support SFmode and DFmode scalar
;; constants that look like DFmode floating point values where both elements
More information about the Gcc-cvs
mailing list