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]

[SH] PR 50694 - SH2A little endian does not actually work


Hello,

the attached patch addresses PR 50694 and also does some cleanups in
sh.md.

I haven't run the testsuite with this one since it's basically just text
replacements, except for the changed cmpgeusi_t insn.  However, CSiBE
didn't show any code size changes with the changed insn.  As far as I
could observe it, the check for the zero special case is already being
done before insn matching. Or am I missing something there?

If desired I could run the testsuite anyways of course.

Cheers,
Oleg


ChangeLog:

2011-10-19  Oleg Endo  <oleg.endo@t-online.de>

	PR target/50694
	* config/sh/sh.h (IS_LITTLE_ENDIAN_OPTION, UNSUPPORTED_SH1,
	UNSUPPORTED_SH2A): New macros.
	(DRIVER_SELF_SPECS): Filter out unsupported options taking the
	default configuration into account.

	* config/sh/sh.c (MSW, LSW): Move macro definitions to header
	file.
	* config/sh/sh.md: Replace TARGET_LITTLE_ENDIAN conditionals
	with MSW and LSW macros where applicable.
	(cmpgeusi_t): Change insn_and_split to insn.  Remove check
	for unsigned greater or equal zero comparison and its split.
	(divsi_inv_qitable, divsi_inv_hitable): Fix warning for
	redundant '@' with single alternative.

Index: gcc/config/sh/sh.c
===================================================================
--- gcc/config/sh/sh.c	(revision 180080)
+++ gcc/config/sh/sh.c	(working copy)
@@ -61,9 +61,6 @@
 
 int code_for_indirect_jump_scratch = CODE_FOR_indirect_jump_scratch;
 
-#define MSW (TARGET_LITTLE_ENDIAN ? 1 : 0)
-#define LSW (TARGET_LITTLE_ENDIAN ? 0 : 1)
-
 /* These are some macros to abstract register modes.  */
 #define CONST_OK_FOR_ADD(size) \
   (TARGET_SHMEDIA ? CONST_OK_FOR_I10 (size) : CONST_OK_FOR_I08 (size))
Index: gcc/config/sh/sh.h
===================================================================
--- gcc/config/sh/sh.h	(revision 180080)
+++ gcc/config/sh/sh.h	(working copy)
@@ -417,10 +417,37 @@
 #define SH_DIV_STR_FOR_SIZE "call"
 #endif
 
-#define DRIVER_SELF_SPECS "%{m2a:%{ml:%eSH2a does not support little-endian}}"
+/* SH1 and SH2A do not support little-endian.  Catch such combinations
+   taking into account the default configuration.  */
+#if TARGET_ENDIAN_DEFAULT == MASK_BIG_ENDIAN
+#define IS_LITTLE_ENDIAN_OPTION "%{ml:"
+#else
+#define IS_LITTLE_ENDIAN_OPTION "%{!mb:"
+#endif
 
+#if TARGET_CPU_DEFAULT == SELECT_SH1
+#define UNSUPPORTED_SH1 IS_LITTLE_ENDIAN_OPTION \
+"%{m1|!m2*:%{!m3*:%{!m4*:%{!m5*:%eSH1 does not support little-endian}}}}}"
+#else
+#define UNSUPPORTED_SH1 IS_LITTLE_ENDIAN_OPTION \
+"%{m1:%eSH1 does not support little-endian}}"
+#endif
+
+#if TARGET_CPU_DEFAULT & MASK_HARD_SH2A
+#define UNSUPPORTED_SH2A IS_LITTLE_ENDIAN_OPTION \
+"%{m2a*|!m1:%{!m2*:%{!m3*:%{!m4*:{!m5*:%eSH2a does not supportlittle-endian}}}}}}"
+#else
+#define UNSUPPORTED_SH2A IS_LITTLE_ENDIAN_OPTION \
+"%{m2a*:%eSH2a does not support little-endian}}"
+#endif
+
+#define DRIVER_SELF_SPECS UNSUPPORTED_SH1, UNSUPPORTED_SH2A
+
 #define ASSEMBLER_DIALECT assembler_dialect
 
+#define MSW (TARGET_LITTLE_ENDIAN ? 1 : 0)
+#define LSW (TARGET_LITTLE_ENDIAN ? 0 : 1)
+
 extern int assembler_dialect;
 
 enum sh_divide_strategy_e {
Index: gcc/config/sh/sh.md
===================================================================
--- gcc/config/sh/sh.md	(revision 180080)
+++ gcc/config/sh/sh.md	(working copy)
@@ -806,19 +806,12 @@
 ;; SImode unsigned integer comparisons
 ;; -------------------------------------------------------------------------
 
-(define_insn_and_split "cmpgeusi_t"
+(define_insn "cmpgeusi_t"
   [(set (reg:SI T_REG)
 	(geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
-		(match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
+		(match_operand:SI 1 "arith_reg_operand" "r")))]
   "TARGET_SH1"
   "cmp/hs	%1,%0"
-  "&& operands[1] == CONST0_RTX (SImode)"
-  [(pc)]
-  "
-{
-  emit_insn (gen_sett ());
-  DONE;
-}"
    [(set_attr "type" "mt_group")])
 
 (define_insn "cmpgtusi_t"
@@ -943,15 +936,12 @@
    (match_dup 6)]
   "
 {
-  operands[2]
-    = gen_rtx_REG (SImode,
-		   true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
+  operands[2] = gen_rtx_REG (SImode, true_regnum (operands[0]) + MSW);
   operands[3]
     = (operands[1] == const0_rtx
        ? const0_rtx
-       : gen_rtx_REG (SImode,
-		      true_regnum (operands[1])
-		      + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
+       : gen_rtx_REG (SImode, true_regnum (operands[1]) + MSW));
+
   operands[4] = gen_lowpart (SImode, operands[0]);
   operands[5] = gen_lowpart (SImode, operands[1]);
   operands[6] = gen_label_rtx ();
@@ -1465,12 +1455,9 @@
   "
 {
   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
-  high0 = gen_rtx_REG (SImode,
-		       true_regnum (operands[0])
-		       + (TARGET_LITTLE_ENDIAN ? 1 : 0));
-  high2 = gen_rtx_REG (SImode,
-		       true_regnum (operands[2])
-		       + (TARGET_LITTLE_ENDIAN ? 1 : 0));
+  high0 = gen_rtx_REG (SImode, true_regnum (operands[0]) + MSW);
+  high2 = gen_rtx_REG (SImode, true_regnum (operands[2]) + MSW);
+
   emit_insn (gen_clrt ());
   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
   emit_insn (gen_addc1 (high0, high0, high2));
@@ -1596,12 +1583,9 @@
   "
 {
   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
-  high0 = gen_rtx_REG (SImode,
-		       true_regnum (operands[0])
-		       + (TARGET_LITTLE_ENDIAN ? 1 : 0));
-  high2 = gen_rtx_REG (SImode,
-		       true_regnum (operands[2])
-		       + (TARGET_LITTLE_ENDIAN ? 1 : 0));
+  high0 = gen_rtx_REG (SImode, true_regnum (operands[0]) + MSW);
+  high2 = gen_rtx_REG (SImode, true_regnum (operands[2]) + MSW);
+
   emit_insn (gen_clrt ());
   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
   emit_insn (gen_subc1 (high0, high0, high2));
@@ -2295,8 +2279,7 @@
 				    (match_operand:DI 2 "register_operand" "r")]
 			 UNSPEC_DIV_INV_TABLE)))]
   "TARGET_SHMEDIA"
-  "@
-	ldx.ub	%1, %2, %0"
+  "ldx.ub	%1, %2, %0"
   [(set_attr "type" "load_media")
    (set_attr "highpart" "user")])
 
@@ -2307,8 +2290,7 @@
 				    (match_operand:DI 2 "register_operand" "r")]
 			 UNSPEC_DIV_INV_TABLE)))]
   "TARGET_SHMEDIA"
-  "@
-	ldx.w	%1, %2, %0"
+  "ldx.w	%1, %2, %0"
   [(set_attr "type" "load_media")
    (set_attr "highpart" "user")])
 
@@ -4005,13 +3987,11 @@
   "TARGET_SH1 && INTVAL (operands[2]) < 32"
   "
 {
-  int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
-  int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
-  rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
-  rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
+  rtx low_src = operand_subword (operands[1], LSW, 0, DImode);
+  rtx high_src = operand_subword (operands[1], MSW, 0, DImode);
   rtx dst = gen_reg_rtx (DImode);
-  rtx low_dst = operand_subword (dst, low_word, 1, DImode);
-  rtx high_dst = operand_subword (dst, high_word, 1, DImode);
+  rtx low_dst = operand_subword (dst, LSW, 1, DImode);
+  rtx high_dst = operand_subword (dst, MSW, 1, DImode);
   rtx tmp0, tmp1;
 
   tmp0 = gen_reg_rtx (SImode);
@@ -4451,15 +4431,12 @@
   [(const_int 0)]
   "
 {
-  int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
-  int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
+  rtx low_src = operand_subword (operands[1], LSW, 0, DImode);
+  rtx high_src = operand_subword (operands[1], MSW, 0, DImode);
 
-  rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
-  rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
+  rtx low_dst = operand_subword (operands[0], LSW, 1, DImode);
+  rtx high_dst = operand_subword (operands[0], MSW, 1, DImode);
 
-  rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
-  rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
-
   emit_insn (gen_clrt ());
   emit_insn (gen_negc (low_dst, low_src));
   emit_insn (gen_negc (high_dst, high_src));
@@ -6264,8 +6241,8 @@
   int regno = true_regnum (operands[0]);
   rtx addr, insn;
   rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
-  rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
-  rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
+  rtx reg0 = gen_rtx_REG (SFmode, regno + MSW);
+  rtx reg1 = gen_rtx_REG (SFmode, regno + LSW);
 
   operands[1] = copy_rtx (mem2);
   addr = XEXP (mem2, 0);
@@ -6329,8 +6306,8 @@
 {
   int regno = true_regnum (operands[1]);
   rtx insn, addr;
-  rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
-  rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
+  rtx reg0 = gen_rtx_REG (SFmode, regno + MSW);
+  rtx reg1 = gen_rtx_REG (SFmode, regno + LSW);
 
   operands[0] = copy_rtx (operands[0]);
   PUT_MODE (operands[0], SFmode);
@@ -10055,14 +10032,13 @@
   [(set (match_dup 5) (match_dup 6))]
   "
 {
-  int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
   rtx op1 = gen_rtx_REG (SFmode,
 			 (true_regnum (operands[1])
-			  + (INTVAL (operands[4]) ^ endian)));
+			  + (INTVAL (operands[4]) ^ LSW)));
 
   operands[7] = gen_rtx_REG (SFmode,
 			     (true_regnum (operands[0])
-			      + (INTVAL (operands[3]) ^ endian)));
+			      + (INTVAL (operands[3]) ^ LSW)));
   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
 }"
   [(set_attr "type" "fparith_media")])
@@ -10084,14 +10060,10 @@
   [(set (match_dup 4) (match_dup 5))]
   "
 {
-  int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
-  rtx op1 = gen_rtx_REG (SFmode,
-			 true_regnum (operands[1]) + endian);
-  rtx op2 = gen_rtx_REG (SFmode,
-			 true_regnum (operands[2]) + endian);
+  rtx op1 = gen_rtx_REG (SFmode, true_regnum (operands[1]) + LSW);
+  rtx op2 = gen_rtx_REG (SFmode, true_regnum (operands[2]) + LSW);
 
-  operands[4] = gen_rtx_REG (SFmode,
-			     true_regnum (operands[0]) + endian);
+  operands[4] = gen_rtx_REG (SFmode, true_regnum (operands[0]) + LSW);
   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
 }"
   [(set_attr "type" "fparith_media")])
@@ -10113,14 +10085,10 @@
   [(set (match_dup 4) (match_dup 5))]
   "
 {
-  int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
-  rtx op1 = gen_rtx_REG (SFmode,
-			 true_regnum (operands[1]) + (1 ^ endian));
-  rtx op2 = gen_rtx_REG (SFmode,
-			 true_regnum (operands[2]) + (1 ^ endian));
+  rtx op1 = gen_rtx_REG (SFmode, true_regnum (operands[1]) + MSW);
+  rtx op2 = gen_rtx_REG (SFmode, true_regnum (operands[2]) + MSW);
 
-  operands[4] = gen_rtx_REG (SFmode,
-			     true_regnum (operands[0]) + (1 ^ endian));
+  operands[4] = gen_rtx_REG (SFmode, true_regnum (operands[0]) + MSW);
   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
 }"
   [(set_attr "type" "fparith_media")])

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