This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFA:] Don't strip unary ops when matching constraints. (PRtarget/23424)


> Date: Fri, 21 Oct 2005 04:20:35 +0200
> From: Hans-Peter Nilsson <hp@axis.com>
> Looks like I should fix the unop constraint checks to allow an
> inner subregs, as in:
> 
> (truncate:QI (subreg:DI (reg/v:TI 9 r9 [orig:164 __s ] [164]) 8))

Yup, that seems to have done it.  Those two files now compare
equal without vs. with all patches.  I have to re-do the whole
test-run to verify that no other file now is different of
course.

For the record, the updated sh.h patch is below and this updated
ChangeLog entry would be applicable, had this patch been
anything else but a proof of concept to show that the generated
sh64 code does not have to change when unops no longer are
stripped at constraint checking.  (And then I might have made an
effort to reduce the number of REG_P checks and similar.)

2005-10-20  Hans-Peter Nilsson  <hp@axis.com>

	Handle unary operators as separate constraints.
	* config/sh/sh.h (CONSTRAINT_LEN): Update for U-constraints.
	(EXTRA_CONSTRAINT_U, EXTRA_CONSTRAINT_Ue, EXTRA_CONSTRAINT_Us)
	(EXTRA_CONSTRAINT_Ut, EXTRA_CONSTRAINT_Uz, GENERAL_RTX_REG_P)
	(GENERAL_REG_OR_SUBREG_P): New macros.
	(EXTRA_CONSTRAINT_STR): Check for U-constraints.
	* config/sh/sh.md: Add Us, Ue, Ut and Uz where applicable.

Index: sh.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.h,v
retrieving revision 1.278
diff -p -u -r1.278 sh.h
--- sh.h	17 Oct 2005 12:42:51 -0000	1.278
+++ sh.h	21 Oct 2005 03:19:50 -0000
@@ -1514,17 +1514,22 @@ extern enum reg_class reg_class_from_let
    Rxx: reserved for exotic register classes.
    S: extra memory (storage) constraints (constraint len == 3)
     Sua: unaligned memory operations
+   U: unop constraints:
+    Ue: (zero_extend general_reg) or (sign_extend general_reg)
+    Us: (sign_extend general_reg)
+    Ut: (truncate general_reg)
+    Uz: (sign_extend R0)
    W: vector
    Z: zero in any mode
 
    unused CONST_INT constraint letters: LO
-   unused EXTRA_CONSTRAINT letters: D T U Y */
+   unused EXTRA_CONSTRAINT letters: D T Y */
 
 #define CONSTRAINT_LEN(C,STR) \
   (((C) == 'A' || (C) == 'B' || (C) == 'C' \
     || (C) == 'I' || (C) == 'J' || (C) == 'K' || (C) == 'P' \
     || (C) == 'R' || (C) == 'S') \
-   ? 3 : DEFAULT_CONSTRAINT_LEN ((C), (STR)))
+   ? 3 : ((C) == 'U') ? 2 : DEFAULT_CONSTRAINT_LEN ((C), (STR)))
 
 /* The letters I, J, K, L and M in a register constraint string
    can be used to stand for particular ranges of immediate operands.
@@ -2431,12 +2436,44 @@ struct sh_args {
    : (STR)[1] == 'u' && (STR)[2] == 'a' ? EXTRA_CONSTRAINT_Sua (OP) \
    : 0)
 
+#define EXTRA_CONSTRAINT_U(OP, STR) \
+  ((STR)[1] == 'e'? EXTRA_CONSTRAINT_Ue (OP) \
+   : (STR)[1] == 's' ? EXTRA_CONSTRAINT_Us (OP) \
+   : (STR)[1] == 't' ? EXTRA_CONSTRAINT_Ut (OP) \
+   : (STR)[1] == 'z' ? EXTRA_CONSTRAINT_Uz (OP) \
+   : 0)
+
+#define GENERAL_RTX_REG_P(OP) (REG_P (OP) && GENERAL_REGISTER_P (REGNO (OP)))
+
+#define GENERAL_REG_OR_SUBREG_P(OP) \
+ (GENERAL_RTX_REG_P (OP) \
+  || (GET_CODE (OP) == SUBREG && GENERAL_RTX_REG_P (XEXP (OP, 0))))
+
+#define EXTRA_CONSTRAINT_Ue(OP) \
+  ((GET_CODE (OP) == SIGN_EXTEND || GET_CODE (OP) == ZERO_EXTEND) \
+   && GENERAL_REG_OR_SUBREG_P (XEXP (OP, 0)))
+
+#define EXTRA_CONSTRAINT_Us(OP) \
+  (GET_CODE (OP) == SIGN_EXTEND \
+   && GENERAL_REG_OR_SUBREG_P (XEXP (OP, 0)))
+
+#define EXTRA_CONSTRAINT_Ut(OP) \
+  (GET_CODE (OP) == TRUNCATE \
+   && GENERAL_REG_OR_SUBREG_P (XEXP (OP, 0)))
+
+#define EXTRA_CONSTRAINT_Uz(OP) \
+  (EXTRA_CONSTRAINT_Us (OP) \
+   && (REG_P (XEXP (OP, 0)) \
+       ? REGNO (XEXP (OP, 0)) == R0_REG \
+       : REGNO (XEXP (XEXP (OP, 0), 0)) == R0_REG))
+
 #define EXTRA_CONSTRAINT_STR(OP, C, STR)		\
   ((C) == 'Q' ? EXTRA_CONSTRAINT_Q (OP)	\
    : (C) == 'A' ? EXTRA_CONSTRAINT_A ((OP), (STR)) \
    : (C) == 'B' ? EXTRA_CONSTRAINT_B ((OP), (STR)) \
    : (C) == 'C' ? EXTRA_CONSTRAINT_C ((OP), (STR)) \
    : (C) == 'S' ? EXTRA_CONSTRAINT_S ((OP), (STR)) \
+   : (C) == 'U' ? EXTRA_CONSTRAINT_U ((OP), (STR)) \
    : (C) == 'W' ? EXTRA_CONSTRAINT_W (OP) \
    : (C) == 'Z' ? EXTRA_CONSTRAINT_Z (OP) \
    : 0)
 

brgds, H-P


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]