diff options
-rw-r--r-- | gcc/ChangeLog | 96 | ||||
-rw-r--r-- | gcc/Makefile.in | 2 | ||||
-rw-r--r-- | gcc/alias.c | 1 | ||||
-rw-r--r-- | gcc/cse.c | 14 | ||||
-rw-r--r-- | gcc/cselib.c | 12 | ||||
-rw-r--r-- | gcc/df-scan.c | 1 | ||||
-rw-r--r-- | gcc/doc/rtl.texi | 76 | ||||
-rw-r--r-- | gcc/emit-rtl.c | 116 | ||||
-rw-r--r-- | gcc/gcse.c | 5 | ||||
-rw-r--r-- | gcc/genemit.c | 1 | ||||
-rw-r--r-- | gcc/gengenrtl.c | 3 | ||||
-rw-r--r-- | gcc/local-alloc.c | 3 | ||||
-rw-r--r-- | gcc/loop-invariant.c | 3 | ||||
-rw-r--r-- | gcc/postreload-gcse.c | 1 | ||||
-rw-r--r-- | gcc/regclass.c | 1 | ||||
-rw-r--r-- | gcc/regrename.c | 1 | ||||
-rw-r--r-- | gcc/reload.c | 2 | ||||
-rw-r--r-- | gcc/reload1.c | 3 | ||||
-rw-r--r-- | gcc/resource.c | 2 | ||||
-rw-r--r-- | gcc/rtl.c | 4 | ||||
-rw-r--r-- | gcc/rtl.def | 49 | ||||
-rw-r--r-- | gcc/rtl.h | 17 | ||||
-rw-r--r-- | gcc/rtlanal.c | 16 | ||||
-rw-r--r-- | gcc/sched-deps.c | 1 | ||||
-rw-r--r-- | gcc/sched-vis.c | 4 | ||||
-rw-r--r-- | gcc/varasm.c | 38 |
26 files changed, 455 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6594bea4750..99d44526e4b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,99 @@ +2007-08-22 Chao-ying Fu <fu@mips.com> + + * rtl.c (rtx_code_size): Check CONST_FIXED to calcualte correct sizes + in DEF_RTL_EXPR. + (copy_rtx): Handle CONST_FIXED. + (rtx_equal_p): Likewise. + * rtl.h (fixed_value.h): New include. + (rtx_def): Add a new field of fixed_value to u. + (XCNMPFV): Define for accessing fixed_value. + (CONST_FIXED_VALUE, CONST_FIXED_VALUE_HIGH, CONST_FIXED_VALUE_LOW): + Define. + * rtl.def (CONST_FIXED): New constant. + (SS_MULT, US_MULT, SS_DIV, US_DIV, FRACT_CONVERT, + UNSIGNED_FRACT_CONVERT, SAT_FRACT, UNSIGNED_SAT_FRACT, US_NEG, + US_ASHIFT): New codes. + * doc/rtl.texi (Expressions): Document const_fixed, us_neg, ss_mult, + us_mult, ss_div, us_div, us_ashift, fract_convert, sat_fract, + unsigned_fract_convert, unsigned_sat_fract): Document them. + * varasm.c (assemble_integer): Extend to support fixed-point constants + by using different machine classes. + (decode_addr_const): Handle FIXED_CST. + (const_hash_1): Likewise. + (compare_constant): Likewise. + (copy_constant): Likewise. + (const_rtx_hash_1): Handle CONST_FIXED. + (output_constant_pool_2): Handle MODE_FRACT, MODE_UFRACT, MODE_ACCUM, + MODE_UACCUM, MODE_VECTOR_FRACT, MODE_VECTOR_UFRACT, MODE_VECTOR_ACCUM, + MODE_VECTOR_UACCUM. + (initializer_constant_valid_p): Handle FIXED_CST. + (output_constant): Support FIXED_POINT_TYPE. + * gengenrtl.c (excluded_rtx): Check CONST_FIXED to exclude. + * cse.c (hash_rtx): Support CONST_FIXED. + (exp_equiv_p): Likewise. + (cannon_reg): Likewise. + (fold_rtx): Likewise. + (equiv_constant): Likewise. + (cse_process_notes_1): Likewise. + (count_reg_usage): Likewise. + * cselib.c (entry_and_rtx_equal_p): Check CONST_FIXED. + (rtx_equal_for_cselib_p): Handle CONST_FIXED. + (wrap_constant): Check CONST_FIXED. + (cselib_hash_rtx): Support CONST_FIXED. + (cselib_subst_to_values): Likewise. + * df-scan.c (df_uses_record): Likewise. + * gcse.c (want_to_gcse_p): Likewise. + (oprs_unchanged_p): Likewise. + (oprs_not_set_p): Likewise. + (compute_transp): Likewise. + (extract_mentioned_regs_helper): Likewise. + * genemit.c (gen_exp): Likewise. + * local-alloc.c (equiv_init_varies_p): Likewise. + (contains_replace_regs): Likewise. + (memref_referenced_p): Likewise. + * loop-invariant.c (check_maybe_invariant): Likewise. + (hash_invariant_expr_1): Likewise. + (invariant_expr_equal_p): Likewise. + * postreload-gcse.c (oprs_unchanged_p): Likewise. + * regclass.c (reg_scan_mark_refs): Likewise. + * regrename.c (scan_rtx): Likewise. + * resource.c (mark_referenced_resources): Likewise. + (mark_set_resources): Likewise. + * rtlanal.c (rtx_unstable_p): Likewise. + (rtx_varies_p): Likewise. + (count_occurrences): Likewise. + (reg_mentioned_p): Likewise. + (modified_between_p): Likewise. + (modified_in_p): Likewise. + (volatile_insn_p): Likewise. + (volatile_refs_p): Likewise. + (side_effects_p): Likewise. + (may_trap_p_1): Likewise. + (inequality_comparisons_p): Likewise. + (computed_jump_p_1): Likewise. + (commutative_operand_precedence): Likewise. + * sched-deps.c (sched_analyze_2): Likewise. + * sched-vis.c (print_value): Likewise. + * reload.c (operands_match_p): Likewise. + (subst_reg_equivs): Likewise. + * reload1.c (eliminate_regs_1): Likewise. + (elimination_effects): Likewise. + (scan_paradoxical_subregs): Likewise. + * alias.c (rtx_equal_for_memref_p): Likewise. + * Makefile.in (RTL_BASE_H): Add fixed-value.h. + * emit-rtl.c (const_fixed_htab): New hash table. + (const_fixed_htab_hash, const_fixed_htab_eq, lookup_const_fixed): + Declare. + (const_fixed_htab_hash, const_fixed_htab_eq, lookup_const_fixed, + const_fixed_from_fixed_value): New functions. + (verify_rtx_sharing): Handle CONST_FIXED. + (copy_rtx_if_shared_1): Likewise. + (reset_used_flags): Likewise. + (set_used_flags): Likewise. + (copy_insn_1): Likewise. + (init_emit_once): Create const_fixed_htab. + Store fixed-point scalar and vector zero and one to const_tiny_rtx. + 2007-08-22 Zdenek Dvorak <ook@ucw.cz> PR tree-optimization/32949 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 52c11b79392..7c602870695 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -770,7 +770,7 @@ HOSTHOOKS_DEF_H = hosthooks-def.h $(HOOKS_H) LANGHOOKS_DEF_H = langhooks-def.h $(HOOKS_H) TARGET_DEF_H = target-def.h $(HOOKS_H) RTL_BASE_H = rtl.h rtl.def $(MACHMODE_H) reg-notes.def insn-notes.def \ - input.h $(REAL_H) statistics.h vec.h + input.h $(REAL_H) statistics.h vec.h fixed-value.h RTL_H = $(RTL_BASE_H) genrtl.h PARAMS_H = params.h params.def BUILTINS_DEF = builtins.def sync-builtins.def omp-builtins.def diff --git a/gcc/alias.c b/gcc/alias.c index ec298423020..a1c9685c290 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -1233,6 +1233,7 @@ rtx_equal_for_memref_p (const_rtx x, const_rtx y) case VALUE: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: /* There's no need to compare the contents of CONST_DOUBLEs or CONST_INTs because pointer equality is a good enough comparison for these nodes. */ diff --git a/gcc/cse.c b/gcc/cse.c index 6c2530ac612..c2b4d182bd0 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -2160,6 +2160,11 @@ hash_rtx (const_rtx x, enum machine_mode mode, int *do_not_record_p, + (unsigned int) CONST_DOUBLE_HIGH (x)); return hash; + case CONST_FIXED: + hash += (unsigned int) code + (unsigned int) GET_MODE (x); + hash += fixed_hash (CONST_FIXED_VALUE (x)); + return hash; + case CONST_VECTOR: { int units; @@ -2401,6 +2406,7 @@ exp_equiv_p (const_rtx x, const_rtx y, int validate, bool for_gcse) case CC0: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: return x == y; case LABEL_REF: @@ -2667,6 +2673,7 @@ canon_reg (rtx x, rtx insn) case CONST: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case LABEL_REF: @@ -2962,6 +2969,7 @@ fold_rtx (rtx x, rtx insn) case CONST: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case LABEL_REF: @@ -3028,6 +3036,7 @@ fold_rtx (rtx x, rtx insn) case SYMBOL_REF: case LABEL_REF: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: const_arg = folded_arg; break; @@ -3645,7 +3654,8 @@ equiv_constant (rtx x) /* See if we previously assigned a constant value to this SUBREG. */ if ((new = lookup_as_function (x, CONST_INT)) != 0 - || (new = lookup_as_function (x, CONST_DOUBLE)) != 0) + || (new = lookup_as_function (x, CONST_DOUBLE)) != 0 + || (new = lookup_as_function (x, CONST_FIXED)) != 0) return new; if (REG_P (SUBREG_REG (x)) @@ -5707,6 +5717,7 @@ cse_process_notes_1 (rtx x, rtx object, bool *changed) case SYMBOL_REF: case LABEL_REF: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case PC: case CC0: @@ -6317,6 +6328,7 @@ count_reg_usage (rtx x, int *counts, rtx dest, int incr) case CONST: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case LABEL_REF: diff --git a/gcc/cselib.c b/gcc/cselib.c index e93b7a86c3c..c4c77c2c5ef 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -237,7 +237,7 @@ entry_and_rtx_equal_p (const void *entry, const void *x_arg) rtx x = (rtx) x_arg; enum machine_mode mode = GET_MODE (x); - gcc_assert (GET_CODE (x) != CONST_INT + gcc_assert (GET_CODE (x) != CONST_INT && GET_CODE (x) != CONST_FIXED && (mode != VOIDmode || GET_CODE (x) != CONST_DOUBLE)); if (mode != GET_MODE (v->val_rtx)) @@ -246,6 +246,7 @@ entry_and_rtx_equal_p (const void *entry, const void *x_arg) /* Unwrap X if necessary. */ if (GET_CODE (x) == CONST && (GET_CODE (XEXP (x, 0)) == CONST_INT + || GET_CODE (XEXP (x, 0)) == CONST_FIXED || GET_CODE (XEXP (x, 0)) == CONST_DOUBLE)) x = XEXP (x, 0); @@ -472,6 +473,7 @@ rtx_equal_for_cselib_p (rtx x, rtx y) switch (GET_CODE (x)) { case CONST_DOUBLE: + case CONST_FIXED: return 0; case LABEL_REF: @@ -554,7 +556,7 @@ rtx_equal_for_cselib_p (rtx x, rtx y) static rtx wrap_constant (enum machine_mode mode, rtx x) { - if (GET_CODE (x) != CONST_INT + if (GET_CODE (x) != CONST_INT && GET_CODE (x) != CONST_FIXED && (GET_CODE (x) != CONST_DOUBLE || GET_MODE (x) != VOIDmode)) return x; gcc_assert (mode != VOIDmode); @@ -618,6 +620,11 @@ cselib_hash_rtx (rtx x, int create) + (unsigned) CONST_DOUBLE_HIGH (x)); return hash ? hash : (unsigned int) CONST_DOUBLE; + case CONST_FIXED: + hash += (unsigned int) code + (unsigned int) GET_MODE (x); + hash += fixed_hash (CONST_FIXED_VALUE (x)); + return hash ? hash : (unsigned int) CONST_FIXED; + case CONST_VECTOR: { int units; @@ -1124,6 +1131,7 @@ cselib_subst_to_values (rtx x) case CONST_DOUBLE: case CONST_VECTOR: case CONST_INT: + case CONST_FIXED: return x; case POST_INC: diff --git a/gcc/df-scan.c b/gcc/df-scan.c index 76f85c142af..08875038a5a 100644 --- a/gcc/df-scan.c +++ b/gcc/df-scan.c @@ -2821,6 +2821,7 @@ df_uses_record (struct df_collection_rec *collection_rec, case CONST_INT: case CONST: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case PC: case CC0: diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi index 247a22e9ad3..83fa0895d0d 100644 --- a/gcc/doc/rtl.texi +++ b/gcc/doc/rtl.texi @@ -1492,6 +1492,15 @@ bits but small enough to fit within twice that number of bits (GCC does not provide a mechanism to represent even larger constants). In the latter case, @var{m} will be @code{VOIDmode}. +@findex const_fixed +@item (const_fixed:@var{m} @var{addr}) +Represents a fixed-point constant of mode @var{m}. +The data structure, which contains data with the size of two +@code{HOST_BITS_PER_WIDE_INT} and the associated fixed-point mode, +is access with the macro @code{CONST_FIXED_VALUE}. The high part of data +is accessed with @code{CONST_FIXED_VALUE_HIGH}; the low part is accessed +with @code{CONST_FIXED_VALUE_LOW}. + @findex const_vector @item (const_vector:@var{m} [@var{x0} @var{x1} @dots{}]) Represents a vector constant. The square brackets stand for the vector @@ -2013,24 +2022,35 @@ still known. @findex neg @findex ss_neg +@findex us_neg @cindex negation @cindex negation with signed saturation +@cindex negation with unsigned saturation @item (neg:@var{m} @var{x}) @itemx (ss_neg:@var{m} @var{x}) +@itemx (us_neg:@var{m} @var{x}) These two expressions represent the negation (subtraction from zero) of the value represented by @var{x}, carried out in mode @var{m}. They differ in the behavior on overflow of integer modes. In the case of @code{neg}, the negation of the operand may be a number not representable in mode @var{m}, in which case it is truncated to @var{m}. @code{ss_neg} -ensures that an out-of-bounds result saturates to the maximum or minimum -representable value. +and @code{us_neg} ensure that an out-of-bounds result saturates to the +maximum or minimum signed or unsigned value. @findex mult +@findex ss_mult +@findex us_mult @cindex multiplication @cindex product +@cindex multiplication with signed saturation +@cindex multiplication with unsigned saturation @item (mult:@var{m} @var{x} @var{y}) +@itemx (ss_mult:@var{m} @var{x} @var{y}) +@itemx (us_mult:@var{m} @var{x} @var{y}) Represents the signed product of the values represented by @var{x} and @var{y} carried out in machine mode @var{m}. +@code{ss_mult} and @code{us_mult} ensure that an out-of-bounds result +saturates to the maximum or minimum signed or unsigned value. Some machines support a multiplication that generates a product wider than the operands. Write the pattern for this as @@ -2046,14 +2066,19 @@ For unsigned widening multiplication, use the same idiom, but with @code{zero_extend} instead of @code{sign_extend}. @findex div +@findex ss_div @cindex division @cindex signed division +@cindex signed division with signed saturation @cindex quotient @item (div:@var{m} @var{x} @var{y}) +@itemx (ss_div:@var{m} @var{x} @var{y}) Represents the quotient in signed division of @var{x} by @var{y}, carried out in machine mode @var{m}. If @var{m} is a floating point mode, it represents the exact quotient; otherwise, the integerized quotient. +@code{ss_div} ensures that an out-of-bounds result saturates to the maximum +or minimum signed value. Some machines have division instructions in which the operands and quotient widths are not all the same; you should represent @@ -2065,9 +2090,13 @@ such instructions using @code{truncate} and @code{sign_extend} as in, @findex udiv @cindex unsigned division +@cindex unsigned division with unsigned saturation @cindex division @item (udiv:@var{m} @var{x} @var{y}) +@itemx (us_div:@var{m} @var{x} @var{y}) Like @code{div} but represents unsigned division. +@code{us_div} ensures that an out-of-bounds result saturates to the maximum +or minimum unsigned value. @findex mod @findex umod @@ -2131,18 +2160,21 @@ fixed-point mode. @findex ashift @findex ss_ashift +@findex us_ashift @cindex left shift @cindex shift @cindex arithmetic shift @cindex arithmetic shift with signed saturation +@cindex arithmetic shift with unsigned saturation @item (ashift:@var{m} @var{x} @var{c}) @itemx (ss_ashift:@var{m} @var{x} @var{c}) -These two expressions represent the result of arithmetically shifting @var{x} +@itemx (us_ashift:@var{m} @var{x} @var{c}) +These three expressions represent the result of arithmetically shifting @var{x} left by @var{c} places. They differ in their behavior on overflow of integer modes. An @code{ashift} operation is a plain shift with no special behavior -in case of a change in the sign bit; @code{ss_ashift} saturates to the minimum -or maximum representable value if any of the bits shifted out differs from the -final sign bit. +in case of a change in the sign bit; @code{ss_ashift} and @code{us_ashift} +saturates to the minimum or maximum representable value if any of the bits +shifted out differs from the final sign bit. @var{x} have mode @var{m}, a fixed-point machine mode. @var{c} be a fixed-point mode or be a constant with mode @code{VOIDmode}; which @@ -2529,6 +2561,38 @@ When @var{m} is a floating point mode, represents the result of converting floating point value @var{x} (valid for mode @var{m}) to an integer, still represented in floating point mode @var{m}, by rounding towards zero. + +@findex fract_convert +@item (fract_convert:@var{m} @var{x}) +Represents the result of converting fixed-point value @var{x} to +fixed-point mode @var{m}, signed integer value @var{x} to +fixed-point mode @var{m}, floating-point value @var{x} to +fixed-point mode @var{m}, fixed-point value @var{x} to integer mode @var{m} +regarded as signed, or fixed-point value @var{x} to floating-point mode @var{m}. +When overflows or underflows happen, the results are undefined. + +@findex sat_fract +@item (sat_fract:@var{m} @var{x}) +Represents the result of converting fixed-point value @var{x} to +fixed-point mode @var{m}, signed integer value @var{x} to +fixed-point mode @var{m}, or floating-point value @var{x} to +fixed-point mode @var{m}. +When overflows or underflows happen, the results are saturated to the +maximum or the minimum. + +@findex unsigned_fract_convert +@item (unsigned_fract_convert:@var{m} @var{x}) +Represents the result of converting fixed-point value @var{x} to +integer mode @var{m} regarded as unsigned, or unsigned integer value @var{x} to +fixed-point mode @var{m}. +When overflows or underflows happen, the results are undefined. + +@findex unsigned_sat_fract +@item (unsigned_sat_fract:@var{m} @var{x}) +Represents the result of converting unsigned integer value @var{x} to +fixed-point mode @var{m}. +When overflows or underflows happen, the results are saturated to the +maximum or the minimum. @end table @node RTL Declarations diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 6e7230db98c..dcbeef02948 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -164,6 +164,10 @@ static GTY ((if_marked ("ggc_marked_p"), param_is (struct reg_attrs))) static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def))) htab_t const_double_htab; +/* A hash table storing all CONST_FIXEDs. */ +static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def))) + htab_t const_fixed_htab; + #define first_insn (cfun->emit->x_first_insn) #define last_insn (cfun->emit->x_last_insn) #define cur_insn_uid (cfun->emit->x_cur_insn_uid) @@ -179,6 +183,9 @@ static int const_int_htab_eq (const void *, const void *); static hashval_t const_double_htab_hash (const void *); static int const_double_htab_eq (const void *, const void *); static rtx lookup_const_double (rtx); +static hashval_t const_fixed_htab_hash (const void *); +static int const_fixed_htab_eq (const void *, const void *); +static rtx lookup_const_fixed (rtx); static hashval_t mem_attrs_htab_hash (const void *); static int mem_attrs_htab_eq (const void *, const void *); static mem_attrs *get_mem_attrs (alias_set_type, tree, rtx, rtx, unsigned int, @@ -247,6 +254,33 @@ const_double_htab_eq (const void *x, const void *y) CONST_DOUBLE_REAL_VALUE (b)); } +/* Returns a hash code for X (which is really a CONST_FIXED). */ + +static hashval_t +const_fixed_htab_hash (const void *x) +{ + rtx value = (rtx) x; + hashval_t h; + + h = fixed_hash (CONST_FIXED_VALUE (value)); + /* MODE is used in the comparison, so it should be in the hash. */ + h ^= GET_MODE (value); + return h; +} + +/* Returns nonzero if the value represented by X (really a ...) + is the same as that represented by Y (really a ...). */ + +static int +const_fixed_htab_eq (const void *x, const void *y) +{ + rtx a = (rtx)x, b = (rtx)y; + + if (GET_MODE (a) != GET_MODE (b)) + return 0; + return fixed_identical (CONST_FIXED_VALUE (a), CONST_FIXED_VALUE (b)); +} + /* Returns a hash code for X (which is a really a mem_attrs *). */ static hashval_t @@ -452,6 +486,34 @@ const_double_from_real_value (REAL_VALUE_TYPE value, enum machine_mode mode) return lookup_const_double (real); } +/* Determine whether FIXED, a CONST_FIXED, already exists in the + hash table. If so, return its counterpart; otherwise add it + to the hash table and return it. */ + +static rtx +lookup_const_fixed (rtx fixed) +{ + void **slot = htab_find_slot (const_fixed_htab, fixed, INSERT); + if (*slot == 0) + *slot = fixed; + + return (rtx) *slot; +} + +/* Return a CONST_FIXED rtx for a fixed-point value specified by + VALUE in mode MODE. */ + +rtx +const_fixed_from_fixed_value (FIXED_VALUE_TYPE value, enum machine_mode mode) +{ + rtx fixed = rtx_alloc (CONST_FIXED); + PUT_MODE (fixed, mode); + + fixed->u.fv = value; + + return lookup_const_fixed (fixed); +} + /* Return a CONST_DOUBLE or CONST_INT for a value specified as a pair of ints: I0 is the low-order word and I1 is the high-order word. Do not use this routine for non-integer modes; convert to @@ -2224,6 +2286,7 @@ verify_rtx_sharing (rtx orig, rtx insn) case REG: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case LABEL_REF: @@ -2423,6 +2486,7 @@ repeat: case REG: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case LABEL_REF: @@ -2540,6 +2604,7 @@ repeat: case REG: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case CODE_LABEL: @@ -2609,6 +2674,7 @@ set_used_flags (rtx x) case REG: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case CODE_LABEL: @@ -4838,6 +4904,7 @@ copy_insn_1 (rtx orig) case REG: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case CODE_LABEL: @@ -5096,14 +5163,17 @@ init_emit_once (int line_numbers) /* We need reg_raw_mode, so initialize the modes now. */ init_reg_modes_once (); - /* Initialize the CONST_INT, CONST_DOUBLE, and memory attribute hash - tables. */ + /* Initialize the CONST_INT, CONST_DOUBLE, CONST_FIXED, and memory attribute + hash tables. */ const_int_htab = htab_create_ggc (37, const_int_htab_hash, const_int_htab_eq, NULL); const_double_htab = htab_create_ggc (37, const_double_htab_hash, const_double_htab_eq, NULL); + const_fixed_htab = htab_create_ggc (37, const_fixed_htab_hash, + const_fixed_htab_eq, NULL); + mem_attrs_htab = htab_create_ggc (37, mem_attrs_htab_hash, mem_attrs_htab_eq, NULL); reg_attrs_htab = htab_create_ggc (37, reg_attrs_htab_hash, @@ -5280,6 +5350,8 @@ init_emit_once (int line_numbers) FCONST0(mode).data.high = 0; FCONST0(mode).data.low = 0; FCONST0(mode).mode = mode; + const_tiny_rtx[0][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE ( + FCONST0 (mode), mode); } for (mode = GET_CLASS_NARROWEST_MODE (MODE_UFRACT); @@ -5289,6 +5361,8 @@ init_emit_once (int line_numbers) FCONST0(mode).data.high = 0; FCONST0(mode).data.low = 0; FCONST0(mode).mode = mode; + const_tiny_rtx[0][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE ( + FCONST0 (mode), mode); } for (mode = GET_CLASS_NARROWEST_MODE (MODE_ACCUM); @@ -5298,6 +5372,8 @@ init_emit_once (int line_numbers) FCONST0(mode).data.high = 0; FCONST0(mode).data.low = 0; FCONST0(mode).mode = mode; + const_tiny_rtx[0][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE ( + FCONST0 (mode), mode); /* We store the value 1. */ FCONST1(mode).data.high = 0; @@ -5308,6 +5384,8 @@ init_emit_once (int line_numbers) &FCONST1(mode).data.low, &FCONST1(mode).data.high, SIGNED_FIXED_POINT_MODE_P (mode)); + const_tiny_rtx[1][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE ( + FCONST1 (mode), mode); } for (mode = GET_CLASS_NARROWEST_MODE (MODE_UACCUM); @@ -5317,6 +5395,8 @@ init_emit_once (int line_numbers) FCONST0(mode).data.high = 0; FCONST0(mode).data.low = 0; FCONST0(mode).mode = mode; + const_tiny_rtx[0][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE ( + FCONST0 (mode), mode); /* We store the value 1. */ FCONST1(mode).data.high = 0; @@ -5327,6 +5407,38 @@ init_emit_once (int line_numbers) &FCONST1(mode).data.low, &FCONST1(mode).data.high, SIGNED_FIXED_POINT_MODE_P (mode)); + const_tiny_rtx[1][(int) mode] = CONST_FIXED_FROM_FIXED_VALUE ( + FCONST1 (mode), mode); + } + + for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FRACT); + mode != VOIDmode; + mode = GET_MODE_WIDER_MODE (mode)) + { + const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0); + } + + for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_UFRACT); + mode != VOIDmode; + mode = GET_MODE_WIDER_MODE (mode)) + { + const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0); + } + + for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_ACCUM); + mode != VOIDmode; + mode = GET_MODE_WIDER_MODE (mode)) + { + const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0); + const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1); + } + + for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_UACCUM); + mode != VOIDmode; + mode = GET_MODE_WIDER_MODE (mode)) + { + const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0); + const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1); } for (i = (int) CCmode; i < (int) MAX_MACHINE_MODE; ++i) diff --git a/gcc/gcse.c b/gcc/gcse.c index be026615094..af10db68530 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -1187,6 +1187,7 @@ want_to_gcse_p (rtx x) case SUBREG: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case CALL: return 0; @@ -1283,6 +1284,7 @@ oprs_unchanged_p (const_rtx x, const_rtx insn, int avail_p) case CONST: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case LABEL_REF: @@ -2265,6 +2267,7 @@ oprs_not_set_p (const_rtx x, const_rtx insn) case CONST: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case LABEL_REF: @@ -2533,6 +2536,7 @@ compute_transp (const_rtx x, int indx, sbitmap *bmap, int set_p) case CONST: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case LABEL_REF: @@ -5568,6 +5572,7 @@ extract_mentioned_regs_helper (rtx x, rtx accum) case CONST: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case LABEL_REF: diff --git a/gcc/genemit.c b/gcc/genemit.c index e8c3f48c3fd..caf808e99c9 100644 --- a/gcc/genemit.c +++ b/gcc/genemit.c @@ -257,6 +257,7 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char *used) return; case CONST_DOUBLE: + case CONST_FIXED: /* These shouldn't be written in MD files. Instead, the appropriate routines in varasm.c should be called. */ gcc_unreachable (); diff --git a/gcc/gengenrtl.c b/gcc/gengenrtl.c index e824ea684c8..89d3011796b 100644 --- a/gcc/gengenrtl.c +++ b/gcc/gengenrtl.c @@ -156,7 +156,8 @@ special_rtx (int idx) static int excluded_rtx (int idx) { - return (strcmp (defs[idx].enumname, "CONST_DOUBLE") == 0); + return ((strcmp (defs[idx].enumname, "CONST_DOUBLE") == 0) + || (strcmp (defs[idx].enumname, "CONST_FIXED") == 0)); } /* Place a list of all format specifiers we use into the array FORMAT. */ diff --git a/gcc/local-alloc.c b/gcc/local-alloc.c index c42b7149145..dc56ca47917 100644 --- a/gcc/local-alloc.c +++ b/gcc/local-alloc.c @@ -538,6 +538,7 @@ equiv_init_varies_p (rtx x) case CONST: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case LABEL_REF: @@ -655,6 +656,7 @@ contains_replace_regs (rtx x) case LABEL_REF: case SYMBOL_REF: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case PC: case CC0: @@ -703,6 +705,7 @@ memref_referenced_p (rtx memref, rtx x) case LABEL_REF: case SYMBOL_REF: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case PC: case CC0: diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c index ebd3810ace8..e4eb2184f74 100644 --- a/gcc/loop-invariant.c +++ b/gcc/loop-invariant.c @@ -185,6 +185,7 @@ check_maybe_invariant (rtx x) { case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case SYMBOL_REF: case CONST: case LABEL_REF: @@ -283,6 +284,7 @@ hash_invariant_expr_1 (rtx insn, rtx x) { case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case SYMBOL_REF: case CONST: case LABEL_REF: @@ -343,6 +345,7 @@ invariant_expr_equal_p (rtx insn1, rtx e1, rtx insn2, rtx e2) { case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case SYMBOL_REF: case CONST: case LABEL_REF: diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c index 0f2f67b5668..3cbd7ebae0d 100644 --- a/gcc/postreload-gcse.c +++ b/gcc/postreload-gcse.c @@ -522,6 +522,7 @@ oprs_unchanged_p (rtx x, rtx insn, bool after_insn) case CONST: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case LABEL_REF: diff --git a/gcc/regclass.c b/gcc/regclass.c index b9fc2ea116a..81ac098f218 100644 --- a/gcc/regclass.c +++ b/gcc/regclass.c @@ -2244,6 +2244,7 @@ reg_scan_mark_refs (rtx x, rtx insn) case CONST: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case CC0: case PC: diff --git a/gcc/regrename.c b/gcc/regrename.c index 29f8e763d92..68a3e68f78e 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -654,6 +654,7 @@ scan_rtx (rtx insn, rtx *loc, enum reg_class cl, case CONST: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case LABEL_REF: diff --git a/gcc/reload.c b/gcc/reload.c index 06ce96bfd38..60e36ffc6c5 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -2210,6 +2210,7 @@ operands_match_p (rtx x, rtx y) { case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: return 0; case LABEL_REF: @@ -5142,6 +5143,7 @@ subst_reg_equivs (rtx ad, rtx insn) case CONST_INT: case CONST: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case LABEL_REF: diff --git a/gcc/reload1.c b/gcc/reload1.c index 319ba13f1f7..0d6b6325184 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -2411,6 +2411,7 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn, { case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case CONST: case SYMBOL_REF: @@ -2804,6 +2805,7 @@ elimination_effects (rtx x, enum machine_mode mem_mode) { case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case CONST: case SYMBOL_REF: @@ -3952,6 +3954,7 @@ scan_paradoxical_subregs (rtx x) case SYMBOL_REF: case LABEL_REF: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: /* shouldn't happen, but just in case. */ case CC0: case PC: diff --git a/gcc/resource.c b/gcc/resource.c index 77a9e7e81ef..7cb4d2ae490 100644 --- a/gcc/resource.c +++ b/gcc/resource.c @@ -222,6 +222,7 @@ mark_referenced_resources (rtx x, struct resources *res, case CONST: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case PC: case SYMBOL_REF: @@ -638,6 +639,7 @@ mark_set_resources (rtx x, struct resources *res, int in_dest, case USE: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case LABEL_REF: case SYMBOL_REF: diff --git a/gcc/rtl.c b/gcc/rtl.c index 9d487b93985..edf393f29d2 100644 --- a/gcc/rtl.c +++ b/gcc/rtl.c @@ -110,7 +110,7 @@ const enum rtx_class rtx_class[NUM_RTX_CODE] = { const unsigned char rtx_code_size[NUM_RTX_CODE] = { #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) \ - ((ENUM) == CONST_INT || (ENUM) == CONST_DOUBLE \ + ((ENUM) == CONST_INT || (ENUM) == CONST_DOUBLE || (ENUM) == CONST_FIXED\ ? RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (HOST_WIDE_INT) \ : RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (rtunion)), @@ -234,6 +234,7 @@ copy_rtx (rtx orig) case REG: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case CODE_LABEL: @@ -374,6 +375,7 @@ rtx_equal_p (const_rtx x, const_rtx y) case SCRATCH: case CONST_DOUBLE: case CONST_INT: + case CONST_FIXED: return 0; default: diff --git a/gcc/rtl.def b/gcc/rtl.def index 1131b3ad84f..9dee20016e3 100644 --- a/gcc/rtl.def +++ b/gcc/rtl.def @@ -323,6 +323,9 @@ DEF_RTL_EXPR(RESX, "resx", "i", RTX_EXTRA) /* numeric integer constant */ DEF_RTL_EXPR(CONST_INT, "const_int", "w", RTX_CONST_OBJ) +/* fixed-point constant */ +DEF_RTL_EXPR(CONST_FIXED, "const_fixed", "www", RTX_CONST_OBJ) + /* numeric floating point constant. Operands hold the value. They are all 'w' and there may be from 2 to 6; see real.h. */ @@ -452,8 +455,18 @@ DEF_RTL_EXPR(NEG, "neg", "e", RTX_UNARY) DEF_RTL_EXPR(MULT, "mult", "ee", RTX_COMM_ARITH) +/* Multiplication with signed saturation */ +DEF_RTL_EXPR(SS_MULT, "ss_mult", "ee", RTX_COMM_ARITH) +/* Multiplication with unsigned saturation */ +DEF_RTL_EXPR(US_MULT, "us_mult", "ee", RTX_COMM_ARITH) + /* Operand 0 divided by operand 1. */ DEF_RTL_EXPR(DIV, "div", "ee", RTX_BIN_ARITH) +/* Division with signed saturation */ +DEF_RTL_EXPR(SS_DIV, "ss_div", "ee", RTX_BIN_ARITH) +/* Division with unsigned saturation */ +DEF_RTL_EXPR(US_DIV, "us_div", "ee", RTX_BIN_ARITH) + /* Remainder of operand 0 divided by operand 1. */ DEF_RTL_EXPR(MOD, "mod", "ee", RTX_BIN_ARITH) @@ -576,6 +589,37 @@ DEF_RTL_EXPR(UNSIGNED_FLOAT, "unsigned_float", "e", RTX_UNARY) Value is defined only when the operand's value is an integer. */ DEF_RTL_EXPR(UNSIGNED_FIX, "unsigned_fix", "e", RTX_UNARY) +/* Conversions involving fractional fixed-point types without saturation, + including: + fractional to fractional (of different precision), + signed integer to fractional, + fractional to signed integer, + floating point to fractional, + fractional to floating point. + NOTE: fractional can be either signed or unsigned for conversions. */ +DEF_RTL_EXPR(FRACT_CONVERT, "fract_convert", "e", RTX_UNARY) + +/* Conversions involving fractional fixed-point types and unsigned integer + without saturation, including: + unsigned integer to fractional, + fractional to unsigned integer. + NOTE: fractional can be either signed or unsigned for conversions. */ +DEF_RTL_EXPR(UNSIGNED_FRACT_CONVERT, "unsigned_fract_convert", "e", RTX_UNARY) + +/* Conversions involving fractional fixed-point types with saturation, + including: + fractional to fractional (of different precision), + signed integer to fractional, + floating point to fractional. + NOTE: fractional can be either signed or unsigned for conversions. */ +DEF_RTL_EXPR(SAT_FRACT, "sat_fract", "e", RTX_UNARY) + +/* Conversions involving fractional fixed-point types and unsigned integer + with saturation, including: + unsigned integer to fractional. + NOTE: fractional can be either signed or unsigned for conversions. */ +DEF_RTL_EXPR(UNSIGNED_SAT_FRACT, "unsigned_sat_fract", "e", RTX_UNARY) + /* Absolute value */ DEF_RTL_EXPR(ABS, "abs", "e", RTX_UNARY) @@ -662,6 +706,8 @@ DEF_RTL_EXPR(SS_MINUS, "ss_minus", "ee", RTX_BIN_ARITH) /* Negation with signed saturation. */ DEF_RTL_EXPR(SS_NEG, "ss_neg", "e", RTX_UNARY) +/* Negation with unsigned saturation. */ +DEF_RTL_EXPR(US_NEG, "us_neg", "e", RTX_UNARY) /* Absolute value with signed saturation. */ DEF_RTL_EXPR(SS_ABS, "ss_abs", "e", RTX_UNARY) @@ -669,6 +715,9 @@ DEF_RTL_EXPR(SS_ABS, "ss_abs", "e", RTX_UNARY) /* Shift left with signed saturation. */ DEF_RTL_EXPR(SS_ASHIFT, "ss_ashift", "ee", RTX_BIN_ARITH) +/* Shift left with unsigned saturation. */ +DEF_RTL_EXPR(US_ASHIFT, "us_ashift", "ee", RTX_BIN_ARITH) + /* Operand 0 minus operand 1, with unsigned saturation. */ DEF_RTL_EXPR(US_MINUS, "us_minus", "ee", RTX_BIN_ARITH) diff --git a/gcc/rtl.h b/gcc/rtl.h index ff884b314a4..cf4a0052f51 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see #include "input.h" #include "real.h" #include "vec.h" +#include "fixed-value.h" #include "alias.h" #undef FFS /* Some systems predefine this symbol; don't let it interfere. */ @@ -308,6 +309,7 @@ struct rtx_def GTY((chain_next ("RTX_NEXT (&%h)"), HOST_WIDE_INT hwint[1]; struct block_symbol block_sym; struct real_value rv; + struct fixed_value fv; } GTY ((special ("rtx_def"), desc ("GET_CODE (&%0)"))) u; }; @@ -530,6 +532,13 @@ struct rtvec_def GTY(()) { __LINE__, __FUNCTION__); \ &_rtx->u.rv; }) +#define XCNMPFV(RTX, C, M) __extension__ \ +({ rtx const _rtx = (RTX); \ + if (GET_CODE (_rtx) != (C) || GET_MODE (_rtx) == (M)) \ + rtl_check_failed_code_mode (_rtx, (C), (M), true, __FILE__, \ + __LINE__, __FUNCTION__); \ + &_rtx->u.fv; }) + #define BLOCK_SYMBOL_CHECK(RTX) __extension__ \ ({ __typeof (RTX) const _symbol = (RTX); \ const unsigned int flags = RTL_CHECKC1 (_symbol, 1, SYMBOL_REF).rt_int; \ @@ -574,6 +583,7 @@ extern void rtvec_check_failed_bounds (const_rtvec, int, const char *, int, #define XCMWINT(RTX, N, C, M) ((RTX)->u.hwint[N]) #define XCNMWINT(RTX, N, C, M) ((RTX)->u.hwint[N]) #define XCNMPRV(RTX, C, M) (&(RTX)->u.rv) +#define XCNMPFV(RTX, C, M) (&(RTX)->u.fv) #define BLOCK_SYMBOL_CHECK(RTX) (&(RTX)->u.block_sym) #endif @@ -1011,6 +1021,13 @@ rhs_regno (const_rtx x) #define CONST_DOUBLE_REAL_VALUE(r) \ ((const struct real_value *) XCNMPRV (r, CONST_DOUBLE, VOIDmode)) +#define CONST_FIXED_VALUE(r) \ + ((const struct fixed_value *) XCNMPFV (r, CONST_FIXED, VOIDmode)) +#define CONST_FIXED_VALUE_HIGH(r) \ + ((HOST_WIDE_INT) (CONST_FIXED_VALUE(r)->data.high)) +#define CONST_FIXED_VALUE_LOW(r) \ + ((HOST_WIDE_INT) (CONST_FIXED_VALUE(r)->data.low)) + /* For a CONST_VECTOR, return element #n. */ #define CONST_VECTOR_ELT(RTX, N) XCVECEXP (RTX, 0, N, CONST_VECTOR) diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index b86add0ceb4..90a62cf1b99 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -120,6 +120,7 @@ rtx_unstable_p (const_rtx x) case CONST: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case LABEL_REF: @@ -194,6 +195,7 @@ rtx_varies_p (const_rtx x, bool for_alias) case CONST: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case LABEL_REF: @@ -573,6 +575,7 @@ count_occurrences (const_rtx x, const_rtx find, int count_dest) case REG: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case CODE_LABEL: @@ -659,6 +662,7 @@ reg_mentioned_p (const_rtx reg, const_rtx in) case CONST_INT: case CONST_VECTOR: case CONST_DOUBLE: + case CONST_FIXED: /* These are kept unique for a given value. */ return 0; @@ -854,6 +858,7 @@ modified_between_p (rtx x, rtx start, rtx end) { case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case CONST: case SYMBOL_REF: @@ -912,6 +917,7 @@ modified_in_p (rtx x, rtx insn) { case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case CONST: case SYMBOL_REF: @@ -1974,6 +1980,7 @@ volatile_insn_p (const_rtx x) case CONST_INT: case CONST: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case CC0: case PC: @@ -2038,6 +2045,7 @@ volatile_refs_p (const_rtx x) case CONST_INT: case CONST: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case CC0: case PC: @@ -2100,6 +2108,7 @@ side_effects_p (const_rtx x) case CONST_INT: case CONST: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case CC0: case PC: @@ -2189,6 +2198,7 @@ may_trap_p_1 (const_rtx x, unsigned flags) /* Handle these cases quickly. */ case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case LABEL_REF: @@ -2388,6 +2398,7 @@ inequality_comparisons_p (const_rtx x) case CC0: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case CONST: case LABEL_REF: @@ -2637,6 +2648,7 @@ computed_jump_p_1 (const_rtx x) case CONST: case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case REG: @@ -2873,6 +2885,8 @@ commutative_operand_precedence (rtx op) return -8; if (code == CONST_DOUBLE) return -7; + if (code == CONST_FIXED) + return -7; op = avoid_constant_pool_reference (op); code = GET_CODE (op); @@ -2883,6 +2897,8 @@ commutative_operand_precedence (rtx op) return -6; if (code == CONST_DOUBLE) return -5; + if (code == CONST_FIXED) + return -5; return -4; case RTX_EXTRA: diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c index dd74e29dcb5..a5bbac2268e 100644 --- a/gcc/sched-deps.c +++ b/gcc/sched-deps.c @@ -1680,6 +1680,7 @@ sched_analyze_2 (struct deps *deps, rtx x, rtx insn) { case CONST_INT: case CONST_DOUBLE: + case CONST_FIXED: case CONST_VECTOR: case SYMBOL_REF: case CONST: diff --git a/gcc/sched-vis.c b/gcc/sched-vis.c index 7ce0f0cc640..8f4597247e5 100644 --- a/gcc/sched-vis.c +++ b/gcc/sched-vis.c @@ -447,6 +447,10 @@ print_value (char *buf, const_rtx x, int verbose) (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x)); cur = safe_concat (buf, cur, t); break; + case CONST_FIXED: + fixed_to_decimal (t, CONST_FIXED_VALUE (x), sizeof (t)); + cur = safe_concat (buf, cur, t); + break; case CONST_STRING: cur = safe_concat (buf, cur, "\""); cur = safe_concat (buf, cur, XSTR (x, 0)); diff --git a/gcc/varasm.c b/gcc/varasm.c index 2ec4f2b876a..7b31c753c52 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -2570,11 +2570,17 @@ assemble_integer (rtx x, unsigned int size, unsigned int align, int force) enum machine_mode omode, imode; unsigned int subalign; unsigned int subsize, i; + unsigned char mclass; subsize = size > UNITS_PER_WORD? UNITS_PER_WORD : 1; subalign = MIN (align, subsize * BITS_PER_UNIT); - omode = mode_for_size (subsize * BITS_PER_UNIT, MODE_INT, 0); - imode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0); + if (GET_CODE (x) == CONST_FIXED) + mclass = GET_MODE_CLASS (GET_MODE (x)); + else + mclass = MODE_INT; + + omode = mode_for_size (subsize * BITS_PER_UNIT, mclass, 0); + imode = mode_for_size (size * BITS_PER_UNIT, mclass, 0); for (i = 0; i < size; i += subsize) { @@ -2686,6 +2692,7 @@ decode_addr_const (tree exp, struct addr_const *value) break; case REAL_CST: + case FIXED_CST: case STRING_CST: case COMPLEX_CST: case CONSTRUCTOR: @@ -2757,6 +2764,9 @@ const_hash_1 (const tree exp) case REAL_CST: return real_hash (TREE_REAL_CST_PTR (exp)); + case FIXED_CST: + return fixed_hash (TREE_FIXED_CST_PTR (exp)); + case STRING_CST: p = TREE_STRING_POINTER (exp); len = TREE_STRING_LENGTH (exp); @@ -2875,6 +2885,13 @@ compare_constant (const tree t1, const tree t2) return REAL_VALUES_IDENTICAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2)); + case FIXED_CST: + /* Fixed constants are the same only if the same width of type. */ + if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2))) + return 0; + + return FIXED_VALUES_IDENTICAL (TREE_FIXED_CST (t1), TREE_FIXED_CST (t2)); + case STRING_CST: if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2))) return 0; @@ -3001,6 +3018,7 @@ copy_constant (tree exp) case INTEGER_CST: case REAL_CST: + case FIXED_CST: case STRING_CST: return copy_node (exp); @@ -3395,6 +3413,10 @@ const_rtx_hash_1 (rtx *xp, void *data) h ^= real_hash (CONST_DOUBLE_REAL_VALUE (x)); break; + case CONST_FIXED: + h ^= fixed_hash (CONST_FIXED_VALUE (x)); + break; + case CONST_VECTOR: { int i; @@ -3636,11 +3658,19 @@ output_constant_pool_2 (enum machine_mode mode, rtx x, unsigned int align) case MODE_INT: case MODE_PARTIAL_INT: + case MODE_FRACT: + case MODE_UFRACT: + case MODE_ACCUM: + case MODE_UACCUM: assemble_integer (x, GET_MODE_SIZE (mode), align, 1); break; case MODE_VECTOR_FLOAT: case MODE_VECTOR_INT: + case MODE_VECTOR_FRACT: + case MODE_VECTOR_UFRACT: + case MODE_VECTOR_ACCUM: + case MODE_VECTOR_UACCUM: { int i, units; enum machine_mode submode = GET_MODE_INNER (mode); @@ -4058,6 +4088,7 @@ initializer_constant_valid_p (tree value, tree endtype) case INTEGER_CST: case VECTOR_CST: case REAL_CST: + case FIXED_CST: case STRING_CST: case COMPLEX_CST: return null_pointer_node; @@ -4381,10 +4412,11 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align) case POINTER_TYPE: case REFERENCE_TYPE: case OFFSET_TYPE: + case FIXED_POINT_TYPE: if (! assemble_integer (expand_expr (exp, NULL_RTX, VOIDmode, EXPAND_INITIALIZER), MIN (size, thissize), align, 0)) - error ("initializer for integer value is too complicated"); + error ("initializer for integer/fixed-point value is too complicated"); break; case REAL_TYPE: |