Fix bootstrap on 32-bit SPARC/Solaris

The 'U' constraint cannot be used with LRA.

gcc/
	PR target/113952
	PR target/117168
	* config/sparc/constraints.md ('U'): Delete.
	* config/sparc/sparc.md (*movdi_insn_sp32): Remove U alternatives.
	(*movdf_insn_sp32): Likewise.
	(*mov<VM64:mode>_insn_sp32): Likewise.
	* doc/md.texi (SPARC constraints): Remove entry for 'U'.
This commit is contained in:
Eric Botcazou 2024-10-16 13:59:50 +02:00
parent d9e02add88
commit 935b7fbd03
3 changed files with 20 additions and 75 deletions

View file

@ -145,51 +145,6 @@
(match_test "TARGET_ARCH32")
(match_test "memory_ok_for_ldd (op)")))
;; This awkward register constraint is necessary because it is not
;; possible to express the "must be even numbered register" condition
;; using register classes. The problem is that membership in a
;; register class requires that all registers of a multi-regno
;; register be included in the set. It is add_to_hard_reg_set
;; and in_hard_reg_set_p which populate and test regsets with these
;; semantics.
;;
;; So this means that we would have to put both the even and odd
;; register into the register class, which would not restrict things
;; at all.
;;
;; Using a combination of GENERAL_REGS and TARGET_HARD_REGNO_MODE_OK is
;; not a full solution either. In fact, even though IRA uses the macro
;; TARGET_HARD_REGNO_MODE_OK to calculate which registers are prohibited
;; from use in certain modes, it still can allocate an odd hard register
;; for DImode values. This is due to how IRA populates the table
;; ira_useful_class_mode_regs[][]. It suffers from the same problem
;; as using a register class to describe this restriction. Namely, it
;; sets both the odd and even part of an even register pair in the
;; regset. Therefore IRA can and will allocate odd registers for
;; DImode values on 32-bit.
;;
;; There are legitimate cases where DImode values can end up in odd
;; hard registers, the most notable example is argument passing.
;;
;; What saves us is reload and the DImode splitters. Both are
;; necessary. The odd register splitters cannot match if, for
;; example, we have a non-offsetable MEM. Reload will notice this
;; case and reload the address into a single hard register.
;;
;; The real downfall of this awkward register constraint is that it
;; does not evaluate to a true register class like a bonafide use of
;; define_register_constraint would. This means that we cannot use
;; it with LRA, since the constraint processing of LRA really depends
;; upon whether an extra constraint is for registers or not. It uses
;; reg_class_for_constraint, and checks it against NO_REGS.
(define_constraint "U"
"Pseudo-register or hard even-numbered integer register"
(and (match_code "reg")
(ior (match_test "REGNO (op) < FIRST_PSEUDO_REGISTER")
(not (match_test "reload_in_progress && reg_renumber [REGNO (op)] < 0")))
(match_test "TARGET_ARCH32")
(match_test "register_ok_for_ldd (op)")))
(define_memory_constraint "W"
"A memory with only a base register"
(match_operand 0 "mem_noofs_operand"))

View file

@ -1831,9 +1831,9 @@
(define_insn "*movdi_insn_sp32"
[(set (match_operand:DI 0 "nonimmediate_operand"
"=T,o,U,T,r,o,r,r,?*f, T,?*f, o,?*e,?*e, r,?*f,?*e, T,*b,*b")
"=T,o,r,o,r,r,?*f, T,?*f, o,?*e,?*e, r,?*f,?*e, T,*b,*b")
(match_operand:DI 1 "input_operand"
" J,J,T,U,o,r,i,r, T,?*f, o,?*f, *e, *e,?*f, r, T,?*e, J, P"))]
" J,J,o,r,i,r, T,?*f, o,?*f, *e, *e,?*f, r, T,?*e, J, P"))]
"TARGET_ARCH32
&& (register_operand (operands[0], DImode)
|| register_or_zero_operand (operands[1], DImode))"
@ -1842,8 +1842,6 @@
#
ldd\t%1, %0
std\t%1, %0
ldd\t%1, %0
std\t%1, %0
#
#
ldd\t%1, %0
@ -1858,12 +1856,11 @@
std\t%1, %0
fzero\t%0
fone\t%0"
[(set_attr "type" "store,*,load,store,load,store,*,*,fpload,fpstore,*,*,fpmove,*,*,*,fpload,fpstore,visl,
visl")
(set_attr "subtype" "*,*,regular,*,regular,*,*,*,*,*,*,*,*,*,*,*,*,*,double,double")
(set_attr "length" "*,2,*,*,*,*,2,2,*,*,2,2,*,2,2,2,*,*,*,*")
(set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double")
(set_attr "cpu_feature" "v9,*,*,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis")])
[(set_attr "type" "store,*,load,store,*,*,fpload,fpstore,*,*,fpmove,*,*,*,fpload,fpstore,visl,visl")
(set_attr "subtype" "*,*,regular,*,*,*,*,*,*,*,*,*,*,*,*,*,double,double")
(set_attr "length" "*,2,*,*,2,2,*,*,2,2,*,2,2,2,*,*,*,*")
(set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double")
(set_attr "cpu_feature" "v9,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis")])
(define_insn "*movdi_insn_sp64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e, m,b,b")
@ -2463,9 +2460,9 @@ visl")
(define_insn "*movdf_insn_sp32"
[(set (match_operand:DF 0 "nonimmediate_operand"
"=T,o,b,b,e,e,*r, f, e,T,U,T, f,o, *r,*r, o")
"=T,o,b,b,e,e,*r, f, e,T, f,o, *r,*r, o")
(match_operand:DF 1 "input_operand"
" G,G,G,C,e,e, f,*r,T#F,e,T,U,o#F,f,*rF, o,*r"))]
" G,G,G,C,e,e, f,*r,T#F,e,o#F,f,*rF, o,*r"))]
"TARGET_ARCH32
&& (register_operand (operands[0], DFmode)
|| register_or_zero_or_all_ones_operand (operands[1], DFmode))"
@ -2480,18 +2477,16 @@ visl")
#
ldd\t%1, %0
std\t%1, %0
ldd\t%1, %0
std\t%1, %0
#
#
#
ldd\t%1, %0
std\t%1, %0"
[(set_attr "type" "store,*,visl,visl,fpmove,*,*,*,fpload,fpstore,load,store,*,*,*,load,store")
(set_attr "subtype" "*,*,double,double,*,*,*,*,*,*,regular,*,*,*,*,regular,*")
(set_attr "length" "*,2,*,*,*,2,2,2,*,*,*,*,2,2,2,*,*")
(set_attr "fptype" "*,*,double,double,double,*,*,*,*,*,*,*,*,*,*,*,*")
(set_attr "cpu_feature" "v9,*,vis,vis,v9,fpunotv9,vis3,vis3,fpu,fpu,*,*,fpu,fpu,*,*,*")])
[(set_attr "type" "store,*,visl,visl,fpmove,*,*,*,fpload,fpstore,*,*,*,load,store")
(set_attr "subtype" "*,*,double,double,*,*,*,*,*,*,*,*,*,regular,*")
(set_attr "length" "*,2,*,*,*,2,2,2,*,*,2,2,2,*,*")
(set_attr "fptype" "*,*,double,double,double,*,*,*,*,*,*,*,*,*,*")
(set_attr "cpu_feature" "v9,*,vis,vis,v9,fpunotv9,vis3,vis3,fpu,fpu,fpu,fpu,*,*,*")])
(define_insn "*movdf_insn_sp64"
[(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e, e,m, *r,*r, m,*r")
@ -8493,9 +8488,9 @@ visl")
(define_insn "*mov<VM64:mode>_insn_sp32"
[(set (match_operand:VM64 0 "nonimmediate_operand"
"=T,o,e,e,e,*r, f,e,T,U,T,f,o,*r,*r, o")
"=T,o,e,e,e,*r, f,e,T,f,o,*r,*r, o")
(match_operand:VM64 1 "input_operand"
" Y,Y,Y,Z,e, f,*r,T,e,T,U,o,f,*r, o,*r"))]
" Y,Y,Y,Z,e, f,*r,T,e,o,f,*r, o,*r"))]
"TARGET_VIS
&& TARGET_ARCH32
&& (register_operand (operands[0], <VM64:MODE>mode)
@ -8510,17 +8505,15 @@ visl")
#
ldd\t%1, %0
std\t%1, %0
ldd\t%1, %0
std\t%1, %0
#
#
#
ldd\t%1, %0
std\t%1, %0"
[(set_attr "type" "store,*,visl,visl,vismv,*,*,fpload,fpstore,load,store,*,*,*,load,store")
(set_attr "subtype" "*,*,double,double,double,*,*,*,*,regular,*,*,*,*,regular,*")
(set_attr "length" "*,2,*,*,*,2,2,*,*,*,*,2,2,2,*,*")
(set_attr "cpu_feature" "*,*,vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*,*,*")])
[(set_attr "type" "store,*,visl,visl,vismv,*,*,fpload,fpstore,*,*,*,load,store")
(set_attr "subtype" "*,*,double,double,double,*,*,*,*,*,*,*,regular,*")
(set_attr "length" "*,2,*,*,*,2,2,*,*,2,2,2,*,*")
(set_attr "cpu_feature" "*,*,vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*")])
(define_split
[(set (match_operand:VM64 0 "register_operand" "")

View file

@ -3910,9 +3910,6 @@ instruction sequence
@item T
Memory address aligned to an 8-byte boundary
@item U
Even register
@item W
Memory address for @samp{e} constraint registers