From ebe75517d4ffdb7045a607c6c5426306dbf662ee Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sat, 23 Aug 2003 23:18:58 +0200 Subject: [PATCH] re PR c/11369 (too relaxed checking with -Wstrict-prototypes) PR target/11369 * i386.c (ix86_expand_carry_flag_compare): Validate operand. PR target/11031 * i386.c (const_0_to_3_operand, const_0_to_7_operand, const_0_to_15_operand, const_0_to_255_operand): New predicates. * i386.h (PREDICATE_CODES): Add these. * i386.c (pinsrw and pextrw patterns): Use them. PR target/10984 * i386.c (ix86_expand_binop_builtin): Behave sanely for VOIDmodes. PR target/8869 * expr.c (convert_modes): Deal properly with integer to vector constant conversion. PR target/8871 * i386.md (zero_extendsidi2*): Add MMX and SSE alternatives. From-SVN: r70751 --- gcc/ChangeLog | 21 +++++++++++++ gcc/config/i386/i386.c | 49 ++++++++++++++++++++++++------ gcc/config/i386/i386.h | 4 +++ gcc/config/i386/i386.md | 67 +++++++++++++++++++++++++++++++---------- gcc/expr.c | 9 ++++++ 5 files changed, 124 insertions(+), 26 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 75bb6424bee..f329133f142 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +Wed Aug 20 12:08:55 CEST 2003 Jan Hubicka + + PR target/11369 + * i386.c (ix86_expand_carry_flag_compare): Validate operand. + + PR target/11031 + * i386.c (const_0_to_3_operand, const_0_to_7_operand, + const_0_to_15_operand, const_0_to_255_operand): New predicates. + * i386.h (PREDICATE_CODES): Add these. + * i386.c (pinsrw and pextrw patterns): Use them. + + PR target/10984 + * i386.c (ix86_expand_binop_builtin): Behave sanely for VOIDmodes. + + PR target/8869 + * expr.c (convert_modes): Deal properly with integer to vector + constant conversion. + + PR target/8871 + * i386.md (zero_extendsidi2*): Add MMX and SSE alternatives. + 2003-08-23 Ulrich Weigand * config/s390/s390.h (LOAD_EXTEND_OP): Remove. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index aa6433aea49..1609b748114 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -3596,6 +3596,32 @@ const248_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) && (INTVAL (op) == 2 || INTVAL (op) == 4 || INTVAL (op) == 8)); } +int +const_0_to_3_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) +{ + return (GET_CODE (op) == CONST_INT && INTVAL (op) >= 0 && INTVAL (op) < 4); +} + +int +const_0_to_7_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) +{ + return (GET_CODE (op) == CONST_INT && INTVAL (op) >= 0 && INTVAL (op) < 8); +} + +int +const_0_to_15_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) +{ + return (GET_CODE (op) == CONST_INT && INTVAL (op) >= 0 && INTVAL (op) < 16); +} + +int +const_0_to_255_operand (register rtx op, + enum machine_mode mode ATTRIBUTE_UNUSED) +{ + return (GET_CODE (op) == CONST_INT && INTVAL (op) >= 0 && INTVAL (op) < 256); +} + + /* True if this is a constant appropriate for an increment or decrement. */ int @@ -9400,11 +9426,6 @@ ix86_expand_carry_flag_compare (enum rtx_code code, rtx op0, rtx op1, rtx *pop) return false; code = (code == GTU ? GEU : LTU); } - else if (!nonimmediate_operand (op1, mode) - || !general_operand (op0, mode)) - /* Swapping operands in this case would generate an - unrecognizable insn. */ - return false; else { rtx tmp = op1; @@ -9433,6 +9454,13 @@ ix86_expand_carry_flag_compare (enum rtx_code code, rtx op0, rtx op1, rtx *pop) default: return false; } + /* Swapping operands may cause constant to appear as first operand. */ + if (!nonimmediate_operand (op0, VOIDmode)) + { + if (no_new_pseudos) + return false; + op0 = force_reg (mode, op0); + } ix86_compare_op0 = op0; ix86_compare_op1 = op1; *pop = ix86_expand_compare (code, NULL, NULL); @@ -13508,7 +13536,8 @@ ix86_expand_binop_builtin (enum insn_code icode, tree arglist, rtx target) /* In case the insn wants input operands in modes different from the result, abort. */ - if (GET_MODE (op0) != mode0 || GET_MODE (op1) != mode1) + if ((GET_MODE (op0) != mode0 && GET_MODE (op0) != VOIDmode) + || (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)) abort (); if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) @@ -13773,8 +13802,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, op0 = copy_to_mode_reg (mode0, op0); if (! (*insn_data[icode].operand[2].predicate) (op1, mode1)) { - /* @@@ better error message */ - error ("selector must be an immediate"); + error ("selector must be an integer constant in the range 0..%i", + fcode == IX86_BUILTIN_PEXTRW ? 3:7); return gen_reg_rtx (tmode); } if (target == 0 @@ -13809,8 +13838,8 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, op1 = copy_to_mode_reg (mode1, op1); if (! (*insn_data[icode].operand[3].predicate) (op2, mode2)) { - /* @@@ better error message */ - error ("selector must be an immediate"); + error ("selector must be an integer constant in the range 0..%i", + fcode == IX86_BUILTIN_PINSRW ? 15:255); return const0_rtx; } if (target == 0 diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 86efe3541b4..718c52530e2 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -3018,6 +3018,10 @@ do { \ {"const0_operand", {CONST_INT, CONST_DOUBLE}}, \ {"const1_operand", {CONST_INT}}, \ {"const248_operand", {CONST_INT}}, \ + {"const_0_to_3_operand", {CONST_INT}}, \ + {"const_0_to_7_operand", {CONST_INT}}, \ + {"const_0_to_15_operand", {CONST_INT}}, \ + {"const_0_to_255_operand", {CONST_INT}}, \ {"incdec_operand", {CONST_INT}}, \ {"mmx_reg_operand", {REG}}, \ {"reg_no_sp_operand", {SUBREG, REG}}, \ diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 9b6abef6034..6fa1650f7d7 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -3278,22 +3278,56 @@ ") (define_insn "zero_extendsidi2_32" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o") - (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r"))) + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y") + (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m"))) (clobber (reg:CC 17))] - "!TARGET_64BIT" - "#" - [(set_attr "mode" "SI")]) + "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES" + "@ + # + # + # + movd\t{%1, %0|%0, %1} + movd\t{%1, %0|%0, %1}" + [(set_attr "mode" "SI,SI,SI,DI,TI") + (set_attr "type" "multi,multi,multi,mmxmov,ssemov")]) + +(define_insn "*zero_extendsidi2_32_1" + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y") + (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm"))) + (clobber (reg:CC 17))] + "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES" + "@ + # + # + # + movd\t{%1, %0|%0, %1} + movd\t{%1, %0|%0, %1}" + [(set_attr "mode" "SI,SI,SI,DI,TI") + (set_attr "type" "multi,multi,multi,mmxmov,ssemov")]) (define_insn "zero_extendsidi2_rex64" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o") - (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))] - "TARGET_64BIT" + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y") + (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))] + "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES" "@ mov\t{%k1, %k0|%k0, %k1} - #" - [(set_attr "type" "imovx,imov") - (set_attr "mode" "SI,DI")]) + # + movd\t{%1, %0|%0, %1} + movd\t{%1, %0|%0, %1}" + [(set_attr "type" "imovx,imov,mmxmov,ssemov") + (set_attr "mode" "SI,DI,DI,TI")]) + +(define_insn "*zero_extendsidi2_rex64_1" + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?") + (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))] + "TARGET_64BIT && TARGET_INTER_UNIT_MOVES" + "@ + mov\t{%k1, %k0|%k0, %k1} + # + movd\t{%1, %0|%0, %1} + movd\t{%1, %0|%0, %1}" + [(set_attr "type" "imovx,imov,mmxmov,ssemov") + (set_attr "mode" "SI,DI,SI,SI")]) (define_split [(set (match_operand:DI 0 "memory_operand" "") @@ -3315,7 +3349,8 @@ [(set (match_operand:DI 0 "nonimmediate_operand" "") (zero_extend:DI (match_operand:SI 1 "general_operand" ""))) (clobber (reg:CC 17))] - "!TARGET_64BIT && reload_completed" + "!TARGET_64BIT && reload_completed + && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])" [(set (match_dup 3) (match_dup 1)) (set (match_dup 4) (const_int 0))] "split_di (&operands[0], 1, &operands[3], &operands[4]);") @@ -21228,7 +21263,7 @@ (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0") (vec_duplicate:V4HI (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm"))) - (match_operand:SI 3 "immediate_operand" "i")))] + (match_operand:SI 3 "const_0_to_15_operand" "N")))] "TARGET_SSE || TARGET_3DNOW_A" "pinsrw\t{%3, %2, %0|%0, %2, %3}" [(set_attr "type" "mmxcvt") @@ -21238,7 +21273,7 @@ [(set (match_operand:SI 0 "register_operand" "=r") (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y") (parallel - [(match_operand:SI 2 "immediate_operand" "i")]))))] + [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))] "TARGET_SSE || TARGET_3DNOW_A" "pextrw\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "mmxcvt") @@ -22924,7 +22959,7 @@ (vec_duplicate:V8HI (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm"))) - (match_operand:SI 3 "immediate_operand" "i")))] + (match_operand:SI 3 "const_0_to_255_operand" "N")))] "TARGET_SSE2" "pinsrw\t{%3, %2, %0|%0, %2, %3}" [(set_attr "type" "ssecvt") @@ -22935,7 +22970,7 @@ (zero_extend:SI (vec_select:HI (match_operand:V8HI 1 "register_operand" "x") (parallel - [(match_operand:SI 2 "immediate_operand" "i")]))))] + [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))] "TARGET_SSE2" "pextrw\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "ssecvt") diff --git a/gcc/expr.c b/gcc/expr.c index 0dd49400ec1..b7f71c627ba 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -1419,6 +1419,15 @@ convert_modes (enum machine_mode mode, enum machine_mode oldmode, rtx x, int uns return gen_lowpart (mode, x); } + /* Converting from integer constant into mode is always equivalent to an + subreg operation. */ + if (VECTOR_MODE_P (mode) && GET_MODE (x) == VOIDmode) + { + if (GET_MODE_BITSIZE (mode) != GET_MODE_BITSIZE (oldmode)) + abort (); + return simplify_gen_subreg (mode, x, oldmode, 0); + } + temp = gen_reg_rtx (mode); convert_move (temp, x, unsignedp); return temp;