[PATCH 1/9] rs6000: Change how we model the carry bit

Segher Boessenkool segher@kernel.crashing.org
Sat Sep 20 18:24:00 GMT 2014


This series handles most of the "small" changes for handling the carry
bit; it does not touch the "add" and scc patterns yet, and no pattern
sets or uses the carry yet either (only clobbers).

Tested as usual, no regressions.  Are these okay to apply?


Segher


- - -


Make the carry bit non-allocatable (i.e., of class NO_REGS).  It will
only ever be assigned to explicitly by machine patterns.  Let it have
mode SI or DI (if compiling for 64-bit), even though it only ever
contains 0 or 1, so that the patterns will be simpler, and combine
will have an easier time and more opportunities.  Do not allow CA
as input_operand; we have no patterns for moving CA around (such
patterns would be quite expensive).  Allow taking a subreg of CA; this
happens e.g. for sraw in 64-bit mode.


2014-09-20  Segher Boessenkool  <segher@kernel.crashing.org>

	* config/rs6000/predicates.md (ca_operand): Allow subregs.
	(input_operand): Do not allow ca_operand.
	* config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok): For the
	carry bit, allow SImode and Pmode.
	(rs6000_init_hard_regno_mode_ok): Make the carry bit class NO_REGS.


---
 gcc/config/rs6000/predicates.md | 16 ++++++++++++++--
 gcc/config/rs6000/rs6000.c      |  4 ++--
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index ef7bc69..21a14e6 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -116,8 +116,16 @@ (define_predicate "vlogical_operand"
 
 ;; Return 1 if op is the carry register.
 (define_predicate "ca_operand"
-  (and (match_code "reg")
-       (match_test "CA_REGNO_P (REGNO (op))")))
+  (match_operand 0 "register_operand")
+{
+  if (GET_CODE (op) == SUBREG)
+    op = SUBREG_REG (op);
+
+  if (!REG_P (op))
+    return 0;
+
+  return CA_REGNO_P (REGNO (op));
+})
 
 ;; Return 1 if op is a signed 5-bit constant integer.
 (define_predicate "s5bit_cint_operand"
@@ -1121,6 +1129,10 @@ (define_predicate "input_operand"
       || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
     return register_operand (op, mode);
 
+  /* We don't allow moving the carry bit around.  */
+  if (ca_operand (op, mode))
+    return 0;
+
   /* The only cases left are integral modes one word or smaller (we
      do not get called for MODE_CC values).  These can be in any
      register.  */
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 5810f68..e2fa75f 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1780,7 +1780,7 @@ rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
     return GET_MODE_CLASS (mode) == MODE_CC;
 
   if (CA_REGNO_P (regno))
-    return mode == BImode;
+    return mode == Pmode || mode == SImode;
 
   /* AltiVec only in AldyVec registers.  */
   if (ALTIVEC_REGNO_P (regno))
@@ -2475,7 +2475,7 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
 
   rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
   rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
-  rs6000_regno_regclass[CA_REGNO] = CA_REGS;
+  rs6000_regno_regclass[CA_REGNO] = NO_REGS;
   rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
   rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
   rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
-- 
1.8.1.4



More information about the Gcc-patches mailing list