rtl.c (rtx_code_size): Check CONST_FIXED to calcualte correct sizes in DEF_RTL_EXPR.
* 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. From-SVN: r127725
This commit is contained in:
parent
9851005046
commit
091a3ac7b8
26 changed files with 455 additions and 17 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
14
gcc/cse.c
14
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:
|
||||
|
|
12
gcc/cselib.c
12
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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
116
gcc/emit-rtl.c
116
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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
49
gcc/rtl.def
49
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)
|
||||
|
||||
|
|
17
gcc/rtl.h
17
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)
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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));
|
||||
|
|
38
gcc/varasm.c
38
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:
|
||||
|
|
Loading…
Add table
Reference in a new issue