This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[SH] PR 50694 - SH2A little endian does not actually work
- From: Oleg Endo <oleg dot endo at t-online dot de>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 20 Oct 2011 00:24:14 +0200
- Subject: [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")])