From 44d0de8d701ab3b7452de0ec5d29e5878fad4b13 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Mon, 4 May 2015 17:05:11 +0200 Subject: [PATCH] i386.h (TARGET_SUPPORTS_WIDE_INT): New define. * config/i386/i386.h (TARGET_SUPPORTS_WIDE_INT): New define. * config/i386/i386.c (ix86_legitimate_constant_p): Handle TImode as CONST_WIDE_INT, not CONST_DOUBLE. (ix86_cannot_force_const_mem): Handle CONST_WIDE_INT. (output_pic_addr_const): Do not handle VOIDmode CONST_DOUBLEs. (ix86_find_base_term): Do not check for CONST_DOUBLE. (ix86_print_operand): Do not handle non-FPmode CONST_DOUBLEs. (ix86_build_signbit_mask): Rewrite using wide ints. (ix86_split_to_parts) [HOST_BITS_PER_WIDE_INT < 64]: Remove. (ix86_rtx_costs): Handle CONST_WIDE_INT. (find_constant): Ditto. * config/i386/i386.md (bts, btr, btc peepholes): Rewrite using gen_int_mode. * config/i386/predicates.md (x86_64_immediate_operand) : Remove HOST_BITS_PER_WIDE_INT == 32 code. (x86_64_zext_immediate_operand): Remove CONST_DOUBLE handling. : Remove HOST_BITS_PER_WIDE_INT == 32 code. (const0_operand): Also match const_wide_int. (constm1_operand): Ditto. (const1_operand): Ditto. From-SVN: r222767 --- gcc/ChangeLog | 23 +++++++ gcc/config/i386/i386.c | 113 ++++++++++------------------------ gcc/config/i386/i386.h | 2 + gcc/config/i386/i386.md | 35 +++-------- gcc/config/i386/predicates.md | 35 +++-------- 5 files changed, 73 insertions(+), 135 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 756071d5df4..819d7681a5b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,26 @@ +2015-05-04 Uros Bizjak + + * config/i386/i386.h (TARGET_SUPPORTS_WIDE_INT): New define. + * config/i386/i386.c (ix86_legitimate_constant_p): Handle TImode + as CONST_WIDE_INT, not CONST_DOUBLE. + (ix86_cannot_force_const_mem): Handle CONST_WIDE_INT. + (output_pic_addr_const): Do not handle VOIDmode CONST_DOUBLEs. + (ix86_find_base_term): Do not check for CONST_DOUBLE. + (ix86_print_operand): Do not handle non-FPmode CONST_DOUBLEs. + (ix86_build_signbit_mask): Rewrite using wide ints. + (ix86_split_to_parts) [HOST_BITS_PER_WIDE_INT < 64]: Remove. + (ix86_rtx_costs): Handle CONST_WIDE_INT. + (find_constant): Ditto. + * config/i386/i386.md (bts, btr, btc peepholes): Rewrite + using gen_int_mode. + * config/i386/predicates.md (x86_64_immediate_operand) + : Remove HOST_BITS_PER_WIDE_INT == 32 code. + (x86_64_zext_immediate_operand): Remove CONST_DOUBLE handling. + : Remove HOST_BITS_PER_WIDE_INT == 32 code. + (const0_operand): Also match const_wide_int. + (constm1_operand): Ditto. + (const1_operand): Ditto. + 2015-05-04 Richard Biener PR tree-optimization/65965 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index cd7bb567c35..461094f4e26 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -13077,7 +13077,7 @@ ix86_legitimate_constant_p (machine_mode, rtx x) #endif break; - case CONST_DOUBLE: + case CONST_WIDE_INT: if (GET_MODE (x) == TImode && x != CONST0_RTX (TImode) && !TARGET_64BIT) @@ -13107,6 +13107,7 @@ ix86_cannot_force_const_mem (machine_mode mode, rtx x) switch (GET_CODE (x)) { case CONST_INT: + case CONST_WIDE_INT: case CONST_DOUBLE: case CONST_VECTOR: return false; @@ -13133,7 +13134,7 @@ is_imported_p (rtx x) /* Nonzero if the constant value X is a legitimate general operand when generating PIC code. It is given that flag_pic is on and - that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ + that X satisfies CONSTANT_P. */ bool legitimate_pic_operand_p (rtx x) @@ -14589,20 +14590,9 @@ output_pic_addr_const (FILE *file, rtx x, int code) break; case CONST_DOUBLE: - if (GET_MODE (x) == VOIDmode) - { - /* We can use %d if the number is <32 bits and positive. */ - if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0) - fprintf (file, "0x%lx%08lx", - (unsigned long) CONST_DOUBLE_HIGH (x), - (unsigned long) CONST_DOUBLE_LOW (x)); - else - fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x)); - } - else - /* We can't handle floating point constants; - TARGET_PRINT_OPERAND must handle them. */ - output_operand_lossage ("floating constant misused"); + /* We can't handle floating point constants; + TARGET_PRINT_OPERAND must handle them. */ + output_operand_lossage ("floating constant misused"); break; case PLUS: @@ -14962,8 +14952,7 @@ ix86_find_base_term (rtx x) return x; term = XEXP (x, 0); if (GET_CODE (term) == PLUS - && (CONST_INT_P (XEXP (term, 1)) - || GET_CODE (XEXP (term, 1)) == CONST_DOUBLE)) + && CONST_INT_P (XEXP (term, 1))) term = XEXP (term, 0); if (GET_CODE (term) != UNSPEC || (XINT (term, 1) != UNSPEC_GOTPCREL @@ -15967,7 +15956,7 @@ ix86_print_operand (FILE *file, rtx x, int code) if (code != 'P' && code != 'p') { - if (CONST_INT_P (x) || GET_CODE (x) == CONST_DOUBLE) + if (CONST_INT_P (x)) { if (ASSEMBLER_DIALECT == ASM_ATT) putc ('$', file); @@ -19444,12 +19433,9 @@ rtx ix86_build_signbit_mask (machine_mode mode, bool vect, bool invert) { machine_mode vec_mode, imode; - HOST_WIDE_INT hi, lo; - int shift = 63; - rtx v; - rtx mask; + wide_int w; + rtx mask, v; - /* Find the sign bit, sign extended to 2*HWI. */ switch (mode) { case V16SImode: @@ -19461,7 +19447,6 @@ ix86_build_signbit_mask (machine_mode mode, bool vect, bool invert) vec_mode = mode; mode = GET_MODE_INNER (mode); imode = SImode; - lo = 0x80000000, hi = lo < 0; break; case V8DImode: @@ -19473,54 +19458,25 @@ ix86_build_signbit_mask (machine_mode mode, bool vect, bool invert) vec_mode = mode; mode = GET_MODE_INNER (mode); imode = DImode; - if (HOST_BITS_PER_WIDE_INT >= 64) - lo = (HOST_WIDE_INT)1 << shift, hi = -1; - else - lo = 0, hi = (HOST_WIDE_INT)1 << (shift - HOST_BITS_PER_WIDE_INT); break; case TImode: case TFmode: vec_mode = VOIDmode; - if (HOST_BITS_PER_WIDE_INT >= 64) - { - imode = TImode; - lo = 0, hi = (HOST_WIDE_INT)1 << shift; - } - else - { - rtvec vec; - - imode = DImode; - lo = 0, hi = (HOST_WIDE_INT)1 << (shift - HOST_BITS_PER_WIDE_INT); - - if (invert) - { - lo = ~lo, hi = ~hi; - v = constm1_rtx; - } - else - v = const0_rtx; - - mask = immed_double_const (lo, hi, imode); - - vec = gen_rtvec (2, v, mask); - v = gen_rtx_CONST_VECTOR (V2DImode, vec); - v = copy_to_mode_reg (mode, gen_lowpart (mode, v)); - - return v; - } - break; + imode = TImode; + break; default: gcc_unreachable (); } + w = wi::set_bit_in_zero (GET_MODE_BITSIZE (mode) - 1, + GET_MODE_BITSIZE (mode)); if (invert) - lo = ~lo, hi = ~hi; + w = wi::bit_not (w); /* Force this value into the low part of a fp vector constant. */ - mask = immed_double_const (lo, hi, imode); + mask = immed_wide_int_const (w, imode); mask = gen_lowpart (mode, mask); if (vec_mode == VOIDmode) @@ -22735,26 +22691,21 @@ ix86_split_to_parts (rtx operand, rtx *parts, machine_mode mode) REAL_VALUE_FROM_CONST_DOUBLE (r, operand); real_to_target (l, &r, mode); - /* Do not use shift by 32 to avoid warning on 32bit systems. */ - if (HOST_BITS_PER_WIDE_INT >= 64) - parts[0] - = gen_int_mode - ((l[0] & (((HOST_WIDE_INT) 2 << 31) - 1)) - + ((((HOST_WIDE_INT) l[1]) << 31) << 1), - DImode); - else - parts[0] = immed_double_const (l[0], l[1], DImode); + /* real_to_target puts 32-bit pieces in each long. */ + parts[0] = + gen_int_mode + ((l[0] & (HOST_WIDE_INT) 0xffffffff) + | ((l[1] & (HOST_WIDE_INT) 0xffffffff) << 32), + DImode); if (upper_mode == SImode) parts[1] = gen_int_mode (l[2], SImode); - else if (HOST_BITS_PER_WIDE_INT >= 64) - parts[1] - = gen_int_mode - ((l[2] & (((HOST_WIDE_INT) 2 << 31) - 1)) - + ((((HOST_WIDE_INT) l[3]) << 31) << 1), - DImode); else - parts[1] = immed_double_const (l[2], l[3], DImode); + parts[1] = + gen_int_mode + ((l[2] & (HOST_WIDE_INT) 0xffffffff) + | ((l[3] & (HOST_WIDE_INT) 0xffffffff) << 32), + DImode); } else gcc_unreachable (); @@ -42021,12 +41972,11 @@ ix86_rtx_costs (rtx x, int code_i, int outer_code_i, int opno, int *total, *total = 0; return true; + case CONST_WIDE_INT: + *total = 0; + return true; + case CONST_DOUBLE: - if (mode == VOIDmode) - { - *total = 0; - return true; - } switch (standard_80387_constant_p (x)) { case 1: /* 0.0 */ @@ -50654,6 +50604,7 @@ find_constant (rtx in_rtx, imm_info *imm_values) break; case CONST_DOUBLE: + case CONST_WIDE_INT: (imm_values->imm)++; (imm_values->imm64)++; break; diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 6901e2aae8f..24ff911df9e 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -2563,6 +2563,8 @@ extern void debug_dispatch_window (int); /* For switching between functions with different target attributes. */ #define SWITCHABLE_TARGET 1 +#define TARGET_SUPPORTS_WIDE_INT 1 + /* Local variables: version-control: t diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 5cac713e5a3..55c5d06f51e 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -10686,17 +10686,10 @@ "TARGET_64BIT && !TARGET_USE_BT" [(const_int 0)] { - HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; - rtx op1; + int i = INTVAL (operands[1]); - if (HOST_BITS_PER_WIDE_INT >= 64) - lo = (HOST_WIDE_INT)1 << i, hi = 0; - else if (i < HOST_BITS_PER_WIDE_INT) - lo = (HOST_WIDE_INT)1 << i, hi = 0; - else - lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); + rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode); - op1 = immed_double_const (lo, hi, DImode); if (i >= 31) { emit_move_insn (operands[2], op1); @@ -10718,17 +10711,10 @@ "TARGET_64BIT && !TARGET_USE_BT" [(const_int 0)] { - HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; - rtx op1; - - if (HOST_BITS_PER_WIDE_INT >= 64) - lo = (HOST_WIDE_INT)1 << i, hi = 0; - else if (i < HOST_BITS_PER_WIDE_INT) - lo = (HOST_WIDE_INT)1 << i, hi = 0; - else - lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); + int i = INTVAL (operands[1]); - op1 = immed_double_const (~lo, ~hi, DImode); + rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode); + if (i >= 32) { emit_move_insn (operands[2], op1); @@ -10751,17 +10737,10 @@ "TARGET_64BIT && !TARGET_USE_BT" [(const_int 0)] { - HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; - rtx op1; + int i = INTVAL (operands[1]); - if (HOST_BITS_PER_WIDE_INT >= 64) - lo = (HOST_WIDE_INT)1 << i, hi = 0; - else if (i < HOST_BITS_PER_WIDE_INT) - lo = (HOST_WIDE_INT)1 << i, hi = 0; - else - lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); + rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode); - op1 = immed_double_const (lo, hi, DImode); if (i >= 31) { emit_move_insn (operands[2], op1); diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 92533b553a4..26dd3e1d7f8 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -135,18 +135,10 @@ switch (GET_CODE (op)) { case CONST_INT: - /* CONST_DOUBLES never match, since HOST_BITS_PER_WIDE_INT is known - to be at least 32 and this all acceptable constants are - represented as CONST_INT. */ - if (HOST_BITS_PER_WIDE_INT == 32) - return true; - else - { - HOST_WIDE_INT val = trunc_int_for_mode (INTVAL (op), DImode); - return trunc_int_for_mode (val, SImode) == val; - } - break; - + { + HOST_WIDE_INT val = trunc_int_for_mode (INTVAL (op), DImode); + return trunc_int_for_mode (val, SImode) == val; + } case SYMBOL_REF: /* For certain code models, the symbolic references are known to fit. in CM_SMALL_PIC model we know it fits if it is local to the shared @@ -253,21 +245,12 @@ ;; Return true if VALUE can be stored in the zero extended immediate field. (define_predicate "x86_64_zext_immediate_operand" - (match_code "const_double,const_int,symbol_ref,label_ref,const") + (match_code "const_int,symbol_ref,label_ref,const") { switch (GET_CODE (op)) { - case CONST_DOUBLE: - if (HOST_BITS_PER_WIDE_INT == 32) - return (GET_MODE (op) == VOIDmode && !CONST_DOUBLE_HIGH (op)); - else - return false; - case CONST_INT: - if (HOST_BITS_PER_WIDE_INT == 32) - return INTVAL (op) >= 0; - else - return !(INTVAL (op) & ~(HOST_WIDE_INT) 0xffffffff); + return !(INTVAL (op) & ~(HOST_WIDE_INT) 0xffffffff); case SYMBOL_REF: /* For certain code models, the symbolic references are known to fit. */ @@ -625,7 +608,7 @@ ;; Match exactly zero. (define_predicate "const0_operand" - (match_code "const_int,const_double,const_vector") + (match_code "const_int,const_wide_int,const_double,const_vector") { if (mode == VOIDmode) mode = GET_MODE (op); @@ -634,7 +617,7 @@ ;; Match -1. (define_predicate "constm1_operand" - (match_code "const_int,const_double,const_vector") + (match_code "const_int,const_wide_int,const_double,const_vector") { if (mode == VOIDmode) mode = GET_MODE (op); @@ -643,7 +626,7 @@ ;; Match one or vector filled with ones. (define_predicate "const1_operand" - (match_code "const_int,const_double,const_vector") + (match_code "const_int,const_wide_int,const_double,const_vector") { if (mode == VOIDmode) mode = GET_MODE (op); -- 2.30.2