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.e...@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")])