diff options
author | Uros Bizjak <ubizjak@gmail.com> | 2015-05-04 17:05:11 +0200 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2015-05-04 17:05:11 +0200 |
commit | 44d0de8d701ab3b7452de0ec5d29e5878fad4b13 (patch) | |
tree | 97b9c92480587e403af8743e13403c9a1c046ff9 | |
parent | a982bcf962c4b72371642a9369d6dea4ac05a979 (diff) | |
download | gcc-44d0de8d701ab3b7452de0ec5d29e5878fad4b13.zip gcc-44d0de8d701ab3b7452de0ec5d29e5878fad4b13.tar.gz gcc-44d0de8d701ab3b7452de0ec5d29e5878fad4b13.tar.bz2 |
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)
<case CONST_INT>: Remove HOST_BITS_PER_WIDE_INT == 32 code.
(x86_64_zext_immediate_operand): Remove CONST_DOUBLE handling.
<case CONST_INT>: Remove HOST_BITS_PER_WIDE_INT == 32 code.
(const0_operand): Also match const_wide_int.
(constm1_operand): Ditto.
(const1_operand): Ditto.
From-SVN: r222767
-rw-r--r-- | gcc/ChangeLog | 23 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 113 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 2 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 35 | ||||
-rw-r--r-- | gcc/config/i386/predicates.md | 35 |
5 files changed, 73 insertions, 135 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 756071d..819d768 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,26 @@ +2015-05-04 Uros Bizjak <ubizjak@gmail.com> + + * 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) + <case CONST_INT>: Remove HOST_BITS_PER_WIDE_INT == 32 code. + (x86_64_zext_immediate_operand): Remove CONST_DOUBLE handling. + <case CONST_INT>: 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 <rguenther@suse.de> PR tree-optimization/65965 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index cd7bb56..461094f 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 6901e2a..24ff911 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 5cac713..55c5d06 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 92533b5..26dd3e1 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); |