tree.def (FIXED_POINT_TYPE): New type.
* tree.def (FIXED_POINT_TYPE): New type. (FIXED_CST): New constant. (FIXED_CONVERT_EXPR): New expr. * doc/c-tree.texi (Types): Document FIXED_POINT_TYPE. (Expressions): Document FIXED_CST and FIXED_CONVERT_EXPR. * tree.h (struct tree_base): Add saturating_flag. Remove one bit of spare for saturating_flag. (NUMERICAL_TYPE_CHECK): Support FIXED_POINT_TYPE. (NON_SAT_FIXED_POINT_TYPE_P, SAT_FIXED_POINT_TYPE_P, FIXED_POINT_TYPE_P): Define. (TYPE_SATURATING): Define. (TREE_FIXED_CST_PTR, TREE_FIXED_CST): Define. (struct tree_fixed_cst): New. (TYPE_IBIT, TYPE_FBIT): Define. (tree_node): Add fixed_cst. (enum tree_index): Add new enumeration values of TI_SAT_SFRACT_TYPE, TI_SAT_FRACT_TYPE, TI_SAT_LFRACT_TYPE, TI_SAT_LLFRACT_TYPE, TI_SAT_USFRACT_TYPE, TI_SAT_UFRACT_TYPE, TI_SAT_ULFRACT_TYPE, TI_SAT_ULLFRACT_TYPE, TI_SFRACT_TYPE, TI_FRACT_TYPE, TI_LFRACT_TYPE, TI_LLFRACT_TYPE, TI_USFRACT_TYPE, TI_UFRACT_TYPE, TI_ULFRACT_TYPE, TI_ULLFRACT_TYPE, TI_SAT_SACCUM_TYPE, TI_SAT_ACCUM_TYPE, TI_SAT_LACCUM_TYPE, TI_SAT_LLACCUM_TYPE, TI_SAT_USACCUM_TYPE, TI_SAT_UACCUM_TYPE, TI_SAT_ULACCUM_TYPE, TI_SAT_ULLACCUM_TYPE, TI_SACCUM_TYPE, TI_ACCUM_TYPE, TI_LACCUM_TYPE, TI_LLACCUM_TYPE, TI_USACCUM_TYPE, TI_UACCUM_TYPE, TI_ULACCUM_TYPE, TI_ULLACCUM_TYPE, TI_QQ_TYPE, TI_HQ_TYPE,_TYPE, TI_SQ_TYPE, TI_DQ_TYPE, TI_TQ_TYPE, TI_UQQ_TYPE, TI_UHQ_TYPE, TI_USQ_TYPE, TI_UDQ_TYPE, TI_UTQ_TYPE, TI_SAT_QQ_TYPE, TI_SAT_HQ_TYPE, TI_SAT_SQ_TYPE, TI_SAT_DQ_TYPE, TI_SAT_TQ_TYPE, TI_SAT_UQQ_TYPE, TI_SAT_UHQ_TYPE, TI_SAT_USQ_TYPE, TI_SAT_UDQ_TYPE, TI_SAT_UTQ_TYPE, TI_HA_TYPE, TI_SA_TYPE, TI_DA_TYPE, TI_TA_TYPE, TI_UHA_TYPE, TI_USA_TYPE, TI_UDA_TYPE, TI_UTA_TYPE, TI_SAT_HA_TYPE, TI_SAT_SA_TYPE, TI_SAT_DA_TYPE, TI_SAT_TA_TYPE, TI_SAT_UHA_TYPE, TI_SAT_USA_TYPE, TI_SAT_UDA_TYPE, TI_SAT_UTA_TYPE. (sat_short_fract_type_node, sat_fract_type_node, sat_long_fract_type_node, sat_long_long_fract_type_node, sat_unsigned_short_fract_type_node, sat_unsigned_fract_type_node, sat_unsigned_long_fract_type_node, sat_unsigned_long_long_fract_type_node, short_fract_type_node, fract_type_node, long_fract_type_node, long_long_fract_type_node, unsigned_short_fract_type_node, unsigned_fract_type_node, unsigned_long_fract_type_node, unsigned_long_long_fract_type_node, sat_short_accum_type_node, sat_accum_type_node, sat_long_accum_type_node, sat_long_long_accum_type_node, sat_unsigned_short_accum_type_node, sat_unsigned_accum_type_node, sat_unsigned_long_accum_type_node, sat_unsigned_long_long_accum_type_node, short_accum_type_node, accum_type_node, long_accum_type_node, long_long_accum_type_node, unsigned_short_accum_type_node, unsigned_accum_type_node, unsigned_long_accum_type_node, unsigned_long_long_accum_type_node, qq_type_node, hq_type_node, sq_type_node, dq_type_node, tq_type_node, uqq_type_node, uhq_type_node, usq_type_node, udq_type_node, utq_type_node, sat_qq_type_node, sat_hq_type_node, sat_sq_type_node, sat_dq_type_node, sat_tq_type_node, sat_uqq_type_node, sat_uhq_type_node, sat_usq_type_node, sat_udq_type_node, sat_utq_type_node, ha_type_node, sa_type_node, da_type_node, ta_type_node, uha_type_node, usa_type_node, uda_type_node, uta_type_node, sat_ha_type_node, sat_sa_type_node, sat_da_type_node, sat_ta_type_node, sat_uha_type_node, sat_usa_type_node, sat_uda_type_node, sat_uta_type_node): New macro. (make_fract_type, make_accum_type): Declare. (make_signed_fract_type, make_unsigned_fract_type, make_sat_signed_fract_type, make_sat_unsigned_fract_type, make_signed_accum_type, make_unsigned_accum_type, make_sat_signed_accum_type, make_sat_unsigned_accum_type, make_or_reuse_signed_fract_type, make_or_reuse_unsigned_fract_type, make_or_reuse_sat_signed_fract_type, make_or_reuse_sat_unsigned_fract_type, make_or_reuse_signed_accum_type, make_or_reuse_unsigned_accum_type, make_or_reuse_sat_signed_accum_type, make_or_reuse_sat_unsigned_accum_type): New macro. (fixed_zerop): Declare. * defaults.h (SHORT_FRACT_TYPE_SIZE, FRACT_TYPE_SIZE, LONG_FRACT_TYPE_SIZE, LONG_LONG_FRACT_TYPE_SIZE, SHORT_ACCUM_TYPE_SIZE, ACCUM_TYPE_SIZE, LONG_ACCUM_TYPE_SIZE, LONG_LONG_ACCUM_TYPE_SIZE): Define. * treestruct.def: Add TS_FIXED_CST. * Makefile.in (c-pretty-print.o): Add dependence on fixed-value.h. (tree.o): Likewise. (tree-dump.o): Likewise. (print-tree.o): Likewise. (tree-pretty-print.o): Likewise. (fold-const.o): Likewise. * tree-complex.c (some_nonzerop): Handle FIXED_CST. * tree-gimple.c (is_gimple_formal_tmp_rhs): Handle FIXED_CST. (is_gimple_min_invariant): Handle FIXED_CST. * stor-layout.c (int_mode_for_mode): Handle MODE_FRACT, MODE_UFRACT, MODE_ACCUM, MODE_UACCUM, MODE_VECTOR_FRACT, MODE_VECTOR_UFRACT, MODE_VECTOR_ACCUM, MODE_VECTOR_UACCUM. (layout_type): Handle FIXED_POINT_TYPE. (make_fract_type, make_accum_type): New functions. * tree-browser.c (browse_tree): Handle FIXED_POINT_TYPE. * tree-dump.c (fixed-value.h): New include. (dump_fixed): New function. (dequeue_and_dump): Handle FIXED_POINT_TYPE and FIXED_CST. * tree-inline.c (remap_type_1): Handle FIXED_POINT_TYPE. (estimate_num_insns_1): Handle FIXED_CST and FIXED_CONVERT_EXPR. * tree-pretty-print.c (fixed-value.h): New include. (dump_generic_node): Handle FIXED_POINT_TYPE, FIXED_CST, and FIXED_CONVERT_EXPR. * tree-scalar-evolution.c (get_scalar_evolution): Handle FIXED_CST. * tree-ssa-loop-im.c (for_each_index): Handle FIXED_CST. * tree-ssa-pre.c (poolify_tree): Handle FIXED_CST. * tree-ssa-reassoc.c (break_up_subtract_bb): We can do reassociation for non-saturating fixed-point types. (reassociate_bb): Likewise. * emit-rtl.c (fixed-value.h): New include. (fconst0, fconst1): New array. (init_emit_once): Initialize fconst0 and fconst1 for fixed-point modes. * tree-vect-generic.c expand_vector_operation): Support MODE_VECTOR_FRACT, MODE_VECTOR_UFRACT, MODE_VECTOR_ACCUM, and MODE_VECTOR_UACCUM. (type_for_widest_vector_mode): Add one parameter for the saturating flag. Check scalar FRACT, UFRACT, ACCUM, and UACCUM mode to select their vector mode. Pass the satp parameter to type_for_mode for fixed-point types. (expand_vector_operations_1): Pass the saturating flag to type_for_widest_vector_mode. Support MODE_VECTOR_FRACT, MODE_VECTOR_UFRACT, MODE_VECTOR_ACCUM, and MODE_VECTOR_UACCUM. * tree-vect-transform.c (vect_is_simple_cond): Support FIXED_CST. (vectorizable_condition): Likewise. * tree.c (fixed-value.h): New include. (tree_code_size): Support FIXED_CST. (build_fixed): New function. (build_one_cst): Support FIXED_POINT_TYPE for accum types. (fixed_zerop): New function. (tree_node_structure): Support FIXED_CST. (type_contains_placeholder_1): Support FIXED_POINT_TYPE. (build_type_attribute_qual_variant): Handle FIXED_POINT_TYPE. (type_hash_eq): Handle FIXED_POINT_TYPE. (simple_cst_equal): Support FIXED_CST. (iterative_hash_expr): Handle FIXED_CST. (get_unwidened): Make sure type is not FIXED_POINT_TYPE. (get_narrower): Likewise. (variably_modified_type_p): Handle FIXED_POINT_TYPE. (make_or_reuse_fract_type, make_or_reuse_accum_type): New functions. (build_common_tree_nodes_2): Use MAKE_FIXED_TYPE_NODE_FAMILY and MAKE_FIXED_MODE_NODE macros to initialize fixed-point type nodes. (build_vector_type_for_mode): Handle MODE_VECTOR_FRACT, MODE_VECTOR_UFRACT, MODE_VECTOR_ACCUM, MODE_VECTOR_UACCUM. (initializer_zerop): Support FIXED_CST. (walk_tree): Handle FIXED_CST and FIXED_POINT_TYPE. * dwarf2out.c (base_type_die): Use DW_ATE_signed_fixed or DW_ATE_unsigned_fixed to describe FIXED_POINT_TYPE. (is_base_type): Handle FIXED_POINT_TYPE. (add_type_attribute): Handle FIXED_POINT_TYPE. (gen_type_die_with_usage): Handle FIXED_POINT_TYPE. * print-tree.c (fixed-value.h): New include. (print_node_brief): Support FIXED_CST. (print_node): Support FIXED_POINT_TYPE and FIXED_CST. * c-pretty-print.c (fixed-value.h): New include. (pp_c_type_specifier): Handle FIXED_POINT_TYPE. Need to pass TYPE_SATURATING to c_common_type_for_mode for fixed-point modes. (pp_c_direct_abstract_declarator): Handle FIXED_POINT_TYPE. Support fixed-point types for inner items in VECTOR_TYPE. (pp_c_direct_declarator): Likewise. (pp_c_declarator): Likewise. (pp_c_fixed_constant): New function. (pp_c_constant): Handle FIXED_CST. (pp_c_primary_expression): Likewise. (pp_c_expression): Likewise. * fold-const.c (fixed-value.h): New include. (negate_expr_p): Return true for FIXED_CST. (fold_negate_expr): Support FIXED_CST. (split_tree): Support FIXED_CST. (const_binop): Support FIXED_CST. (fold_convert_const_int_from_fixed): New function to convert from fixed to int. (fold_convert_const_real_from_fixed): New function to convert from fixed to real. (fold_convert_const_fixed_from_fixed): New function to convert from fixed to another fixed. (fold_convert_const_fixed_from_int): New function to convert from int to fixed. (fold_convert_const_fixed_from_real): New function to convert from real to fixed. (fold_convert_const): Support conversions from fixed to int, from fixed to real, from fixed to fixed, from int to fixed, and from real to fixed. (fold_convert): Support FIXED_CST and FIXED_POINT_TYPE. (operand_equal_p): Support FIXED_CST. (make_range): For fixed-point modes, we need to pass the saturating flag as the 2nd parameter. (tree_swap_operands_p): Handle FIXED_CST. (fold_plusminus_mult_expr): For fract modes, we cannot generate constant 1. (fold_unary): Support FIXED_CONVERT_EXPR. (fold_binary): Handle FIXED_CST. Make sure the type is not saturating, before associating operations. Ex: A + B + C, A * B * C, (A1 * C1) +/- (A2 * C2). (tree_expr_nonnegative_warnv_p): Handle FIXED_CST. (fold_negate_const): Support FIXED_CST. (fold_relational_const): Support FIXED_CST. * gimplify.c (omp_firstprivatize_type_sizes): Handle FIXED_POINT_TYPE. (gimplify_expr): Handle FIXED_CST. (gimplify_type_sizes): Handle FIXED_POINT_TYPE. * ipa-prop.c (ipa_callsite_compute_param): Support FIXED_CST. * ipa-type-escape.c (type_to_consider): Handle FIXED_POINT_TYPE. * doc/tm.texi (Type Layout): Document SHORT_FRACT_TYPE_SIZE, FRACT_TYPE_SIZE, LONG_FRACT_TYPE_SIZE, LONG_LONG_FRACT_TYPE_SIZE, SHORT_ACCUM_TYPE_SIZE, ACCUM_TYPE_SIZE, LONG_ACCUM_TYPE_SIZE, LONG_LONG_ACCUM_TYPE_SIZE. * dbxout.c (dbxout_type): Handle FIXED_POINT_TYPE. * c-aux-info.c (gen_type): Handle FIXED_POINT_TYPE. * tree-sra.c (is_sra_scalar_type): Support FIXED_POINT_TYPE. * expmed.c (extract_bit_field): Support MODE_FRACT, MODE_UFRACT, MODE_ACCUM, and MODE_UACCUM. * tree-vectorizer.c (vect_is_simple_reduction): Check for saturating fixed-point types to disable reduction. * explow.c (promote_mode): Support FIXED_POINT_TYPE. From-SVN: r127306
This commit is contained in:
parent
ad10fdc2b7
commit
325217edf0
36 changed files with 1419 additions and 44 deletions
215
gcc/ChangeLog
215
gcc/ChangeLog
|
@ -1,3 +1,218 @@
|
|||
2007-08-08 Chao-ying Fu <fu@mips.com>
|
||||
|
||||
* tree.def (FIXED_POINT_TYPE): New type.
|
||||
(FIXED_CST): New constant.
|
||||
(FIXED_CONVERT_EXPR): New expr.
|
||||
* doc/c-tree.texi (Types): Document FIXED_POINT_TYPE.
|
||||
(Expressions): Document FIXED_CST and FIXED_CONVERT_EXPR.
|
||||
* tree.h (struct tree_base): Add saturating_flag.
|
||||
Remove one bit of spare for saturating_flag.
|
||||
(NUMERICAL_TYPE_CHECK): Support FIXED_POINT_TYPE.
|
||||
(NON_SAT_FIXED_POINT_TYPE_P, SAT_FIXED_POINT_TYPE_P,
|
||||
FIXED_POINT_TYPE_P): Define.
|
||||
(TYPE_SATURATING): Define.
|
||||
(TREE_FIXED_CST_PTR, TREE_FIXED_CST): Define.
|
||||
(struct tree_fixed_cst): New.
|
||||
(TYPE_IBIT, TYPE_FBIT): Define.
|
||||
(tree_node): Add fixed_cst.
|
||||
(enum tree_index): Add new enumeration values of
|
||||
TI_SAT_SFRACT_TYPE, TI_SAT_FRACT_TYPE, TI_SAT_LFRACT_TYPE,
|
||||
TI_SAT_LLFRACT_TYPE, TI_SAT_USFRACT_TYPE, TI_SAT_UFRACT_TYPE,
|
||||
TI_SAT_ULFRACT_TYPE, TI_SAT_ULLFRACT_TYPE, TI_SFRACT_TYPE,
|
||||
TI_FRACT_TYPE, TI_LFRACT_TYPE, TI_LLFRACT_TYPE, TI_USFRACT_TYPE,
|
||||
TI_UFRACT_TYPE, TI_ULFRACT_TYPE, TI_ULLFRACT_TYPE,
|
||||
TI_SAT_SACCUM_TYPE, TI_SAT_ACCUM_TYPE, TI_SAT_LACCUM_TYPE,
|
||||
TI_SAT_LLACCUM_TYPE, TI_SAT_USACCUM_TYPE, TI_SAT_UACCUM_TYPE,
|
||||
TI_SAT_ULACCUM_TYPE, TI_SAT_ULLACCUM_TYPE, TI_SACCUM_TYPE,
|
||||
TI_ACCUM_TYPE, TI_LACCUM_TYPE, TI_LLACCUM_TYPE, TI_USACCUM_TYPE,
|
||||
TI_UACCUM_TYPE, TI_ULACCUM_TYPE, TI_ULLACCUM_TYPE,
|
||||
TI_QQ_TYPE, TI_HQ_TYPE,_TYPE, TI_SQ_TYPE, TI_DQ_TYPE, TI_TQ_TYPE,
|
||||
TI_UQQ_TYPE, TI_UHQ_TYPE, TI_USQ_TYPE, TI_UDQ_TYPE, TI_UTQ_TYPE,
|
||||
TI_SAT_QQ_TYPE, TI_SAT_HQ_TYPE, TI_SAT_SQ_TYPE, TI_SAT_DQ_TYPE,
|
||||
TI_SAT_TQ_TYPE, TI_SAT_UQQ_TYPE, TI_SAT_UHQ_TYPE, TI_SAT_USQ_TYPE,
|
||||
TI_SAT_UDQ_TYPE, TI_SAT_UTQ_TYPE, TI_HA_TYPE, TI_SA_TYPE, TI_DA_TYPE,
|
||||
TI_TA_TYPE, TI_UHA_TYPE, TI_USA_TYPE, TI_UDA_TYPE, TI_UTA_TYPE,
|
||||
TI_SAT_HA_TYPE, TI_SAT_SA_TYPE, TI_SAT_DA_TYPE, TI_SAT_TA_TYPE,
|
||||
TI_SAT_UHA_TYPE, TI_SAT_USA_TYPE, TI_SAT_UDA_TYPE, TI_SAT_UTA_TYPE.
|
||||
(sat_short_fract_type_node, sat_fract_type_node,
|
||||
sat_long_fract_type_node, sat_long_long_fract_type_node,
|
||||
sat_unsigned_short_fract_type_node, sat_unsigned_fract_type_node,
|
||||
sat_unsigned_long_fract_type_node,
|
||||
sat_unsigned_long_long_fract_type_node, short_fract_type_node,
|
||||
fract_type_node, long_fract_type_node, long_long_fract_type_node,
|
||||
unsigned_short_fract_type_node, unsigned_fract_type_node,
|
||||
unsigned_long_fract_type_node, unsigned_long_long_fract_type_node,
|
||||
sat_short_accum_type_node, sat_accum_type_node,
|
||||
sat_long_accum_type_node, sat_long_long_accum_type_node,
|
||||
sat_unsigned_short_accum_type_node, sat_unsigned_accum_type_node,
|
||||
sat_unsigned_long_accum_type_node,
|
||||
sat_unsigned_long_long_accum_type_node, short_accum_type_node,
|
||||
accum_type_node, long_accum_type_node, long_long_accum_type_node,
|
||||
unsigned_short_accum_type_node, unsigned_accum_type_node,
|
||||
unsigned_long_accum_type_node, unsigned_long_long_accum_type_node,
|
||||
qq_type_node, hq_type_node, sq_type_node, dq_type_node, tq_type_node,
|
||||
uqq_type_node, uhq_type_node, usq_type_node, udq_type_node,
|
||||
utq_type_node, sat_qq_type_node, sat_hq_type_node, sat_sq_type_node,
|
||||
sat_dq_type_node, sat_tq_type_node, sat_uqq_type_node,
|
||||
sat_uhq_type_node, sat_usq_type_node, sat_udq_type_node,
|
||||
sat_utq_type_node, ha_type_node, sa_type_node, da_type_node,
|
||||
ta_type_node, uha_type_node, usa_type_node, uda_type_node,
|
||||
uta_type_node, sat_ha_type_node, sat_sa_type_node, sat_da_type_node,
|
||||
sat_ta_type_node, sat_uha_type_node, sat_usa_type_node,
|
||||
sat_uda_type_node, sat_uta_type_node): New macro.
|
||||
(make_fract_type, make_accum_type): Declare.
|
||||
(make_signed_fract_type, make_unsigned_fract_type,
|
||||
make_sat_signed_fract_type, make_sat_unsigned_fract_type,
|
||||
make_signed_accum_type, make_unsigned_accum_type,
|
||||
make_sat_signed_accum_type, make_sat_unsigned_accum_type,
|
||||
make_or_reuse_signed_fract_type, make_or_reuse_unsigned_fract_type,
|
||||
make_or_reuse_sat_signed_fract_type,
|
||||
make_or_reuse_sat_unsigned_fract_type, make_or_reuse_signed_accum_type,
|
||||
make_or_reuse_unsigned_accum_type, make_or_reuse_sat_signed_accum_type,
|
||||
make_or_reuse_sat_unsigned_accum_type): New macro.
|
||||
(fixed_zerop): Declare.
|
||||
* defaults.h (SHORT_FRACT_TYPE_SIZE, FRACT_TYPE_SIZE,
|
||||
LONG_FRACT_TYPE_SIZE, LONG_LONG_FRACT_TYPE_SIZE,
|
||||
SHORT_ACCUM_TYPE_SIZE, ACCUM_TYPE_SIZE, LONG_ACCUM_TYPE_SIZE,
|
||||
LONG_LONG_ACCUM_TYPE_SIZE): Define.
|
||||
* treestruct.def: Add TS_FIXED_CST.
|
||||
* Makefile.in (c-pretty-print.o): Add dependence on fixed-value.h.
|
||||
(tree.o): Likewise.
|
||||
(tree-dump.o): Likewise.
|
||||
(print-tree.o): Likewise.
|
||||
(tree-pretty-print.o): Likewise.
|
||||
(fold-const.o): Likewise.
|
||||
* tree-complex.c (some_nonzerop): Handle FIXED_CST.
|
||||
* tree-gimple.c (is_gimple_formal_tmp_rhs): Handle FIXED_CST.
|
||||
(is_gimple_min_invariant): Handle FIXED_CST.
|
||||
* stor-layout.c (int_mode_for_mode): Handle MODE_FRACT, MODE_UFRACT,
|
||||
MODE_ACCUM, MODE_UACCUM, MODE_VECTOR_FRACT, MODE_VECTOR_UFRACT,
|
||||
MODE_VECTOR_ACCUM, MODE_VECTOR_UACCUM.
|
||||
(layout_type): Handle FIXED_POINT_TYPE.
|
||||
(make_fract_type, make_accum_type): New functions.
|
||||
* tree-browser.c (browse_tree): Handle FIXED_POINT_TYPE.
|
||||
* tree-dump.c (fixed-value.h): New include.
|
||||
(dump_fixed): New function.
|
||||
(dequeue_and_dump): Handle FIXED_POINT_TYPE and FIXED_CST.
|
||||
* tree-inline.c (remap_type_1): Handle FIXED_POINT_TYPE.
|
||||
(estimate_num_insns_1): Handle FIXED_CST and FIXED_CONVERT_EXPR.
|
||||
* tree-pretty-print.c (fixed-value.h): New include.
|
||||
(dump_generic_node): Handle FIXED_POINT_TYPE, FIXED_CST, and
|
||||
FIXED_CONVERT_EXPR.
|
||||
* tree-scalar-evolution.c (get_scalar_evolution): Handle FIXED_CST.
|
||||
* tree-ssa-loop-im.c (for_each_index): Handle FIXED_CST.
|
||||
* tree-ssa-pre.c (poolify_tree): Handle FIXED_CST.
|
||||
* tree-ssa-reassoc.c (break_up_subtract_bb): We can do reassociation
|
||||
for non-saturating fixed-point types.
|
||||
(reassociate_bb): Likewise.
|
||||
* emit-rtl.c (fixed-value.h): New include.
|
||||
(fconst0, fconst1): New array.
|
||||
(init_emit_once): Initialize fconst0 and fconst1 for fixed-point modes.
|
||||
* tree-vect-generic.c expand_vector_operation): Support
|
||||
MODE_VECTOR_FRACT, MODE_VECTOR_UFRACT, MODE_VECTOR_ACCUM, and
|
||||
MODE_VECTOR_UACCUM.
|
||||
(type_for_widest_vector_mode): Add one parameter for the
|
||||
saturating flag.
|
||||
Check scalar FRACT, UFRACT, ACCUM, and UACCUM mode to select their
|
||||
vector mode.
|
||||
Pass the satp parameter to type_for_mode for fixed-point types.
|
||||
(expand_vector_operations_1): Pass the saturating flag to
|
||||
type_for_widest_vector_mode.
|
||||
Support MODE_VECTOR_FRACT, MODE_VECTOR_UFRACT, MODE_VECTOR_ACCUM,
|
||||
and MODE_VECTOR_UACCUM.
|
||||
* tree-vect-transform.c (vect_is_simple_cond): Support FIXED_CST.
|
||||
(vectorizable_condition): Likewise.
|
||||
* tree.c (fixed-value.h): New include.
|
||||
(tree_code_size): Support FIXED_CST.
|
||||
(build_fixed): New function.
|
||||
(build_one_cst): Support FIXED_POINT_TYPE for accum types.
|
||||
(fixed_zerop): New function.
|
||||
(tree_node_structure): Support FIXED_CST.
|
||||
(type_contains_placeholder_1): Support FIXED_POINT_TYPE.
|
||||
(build_type_attribute_qual_variant): Handle FIXED_POINT_TYPE.
|
||||
(type_hash_eq): Handle FIXED_POINT_TYPE.
|
||||
(simple_cst_equal): Support FIXED_CST.
|
||||
(iterative_hash_expr): Handle FIXED_CST.
|
||||
(get_unwidened): Make sure type is not FIXED_POINT_TYPE.
|
||||
(get_narrower): Likewise.
|
||||
(variably_modified_type_p): Handle FIXED_POINT_TYPE.
|
||||
(make_or_reuse_fract_type, make_or_reuse_accum_type): New functions.
|
||||
(build_common_tree_nodes_2): Use MAKE_FIXED_TYPE_NODE_FAMILY and
|
||||
MAKE_FIXED_MODE_NODE macros to initialize fixed-point type
|
||||
nodes.
|
||||
(build_vector_type_for_mode): Handle MODE_VECTOR_FRACT,
|
||||
MODE_VECTOR_UFRACT, MODE_VECTOR_ACCUM, MODE_VECTOR_UACCUM.
|
||||
(initializer_zerop): Support FIXED_CST.
|
||||
(walk_tree): Handle FIXED_CST and FIXED_POINT_TYPE.
|
||||
* dwarf2out.c (base_type_die): Use DW_ATE_signed_fixed or
|
||||
DW_ATE_unsigned_fixed to describe FIXED_POINT_TYPE.
|
||||
(is_base_type): Handle FIXED_POINT_TYPE.
|
||||
(add_type_attribute): Handle FIXED_POINT_TYPE.
|
||||
(gen_type_die_with_usage): Handle FIXED_POINT_TYPE.
|
||||
* print-tree.c (fixed-value.h): New include.
|
||||
(print_node_brief): Support FIXED_CST.
|
||||
(print_node): Support FIXED_POINT_TYPE and FIXED_CST.
|
||||
* c-pretty-print.c (fixed-value.h): New include.
|
||||
(pp_c_type_specifier): Handle FIXED_POINT_TYPE. Need to pass
|
||||
TYPE_SATURATING to c_common_type_for_mode for fixed-point modes.
|
||||
(pp_c_direct_abstract_declarator): Handle FIXED_POINT_TYPE.
|
||||
Support fixed-point types for inner items in VECTOR_TYPE.
|
||||
(pp_c_direct_declarator): Likewise.
|
||||
(pp_c_declarator): Likewise.
|
||||
(pp_c_fixed_constant): New function.
|
||||
(pp_c_constant): Handle FIXED_CST.
|
||||
(pp_c_primary_expression): Likewise.
|
||||
(pp_c_expression): Likewise.
|
||||
* fold-const.c (fixed-value.h): New include.
|
||||
(negate_expr_p): Return true for FIXED_CST.
|
||||
(fold_negate_expr): Support FIXED_CST.
|
||||
(split_tree): Support FIXED_CST.
|
||||
(const_binop): Support FIXED_CST.
|
||||
(fold_convert_const_int_from_fixed): New function to convert from
|
||||
fixed to int.
|
||||
(fold_convert_const_real_from_fixed): New function to convert from
|
||||
fixed to real.
|
||||
(fold_convert_const_fixed_from_fixed): New function to convert from
|
||||
fixed to another fixed.
|
||||
(fold_convert_const_fixed_from_int): New function to convert from
|
||||
int to fixed.
|
||||
(fold_convert_const_fixed_from_real): New function to convert from
|
||||
real to fixed.
|
||||
(fold_convert_const): Support conversions from fixed to int, from
|
||||
fixed to real, from fixed to fixed, from int to fixed, and from real
|
||||
to fixed.
|
||||
(fold_convert): Support FIXED_CST and FIXED_POINT_TYPE.
|
||||
(operand_equal_p): Support FIXED_CST.
|
||||
(make_range): For fixed-point modes, we need to pass the
|
||||
saturating flag as the 2nd parameter.
|
||||
(tree_swap_operands_p): Handle FIXED_CST.
|
||||
(fold_plusminus_mult_expr): For fract modes, we cannot generate
|
||||
constant 1.
|
||||
(fold_unary): Support FIXED_CONVERT_EXPR.
|
||||
(fold_binary): Handle FIXED_CST.
|
||||
Make sure the type is not saturating, before associating operations.
|
||||
Ex: A + B + C, A * B * C, (A1 * C1) +/- (A2 * C2).
|
||||
(tree_expr_nonnegative_warnv_p): Handle FIXED_CST.
|
||||
(fold_negate_const): Support FIXED_CST.
|
||||
(fold_relational_const): Support FIXED_CST.
|
||||
* gimplify.c (omp_firstprivatize_type_sizes): Handle FIXED_POINT_TYPE.
|
||||
(gimplify_expr): Handle FIXED_CST.
|
||||
(gimplify_type_sizes): Handle FIXED_POINT_TYPE.
|
||||
* ipa-prop.c (ipa_callsite_compute_param): Support FIXED_CST.
|
||||
* ipa-type-escape.c (type_to_consider): Handle FIXED_POINT_TYPE.
|
||||
* doc/tm.texi (Type Layout): Document SHORT_FRACT_TYPE_SIZE,
|
||||
FRACT_TYPE_SIZE, LONG_FRACT_TYPE_SIZE, LONG_LONG_FRACT_TYPE_SIZE,
|
||||
SHORT_ACCUM_TYPE_SIZE, ACCUM_TYPE_SIZE, LONG_ACCUM_TYPE_SIZE,
|
||||
LONG_LONG_ACCUM_TYPE_SIZE.
|
||||
* dbxout.c (dbxout_type): Handle FIXED_POINT_TYPE.
|
||||
* c-aux-info.c (gen_type): Handle FIXED_POINT_TYPE.
|
||||
* tree-sra.c (is_sra_scalar_type): Support FIXED_POINT_TYPE.
|
||||
* expmed.c (extract_bit_field): Support MODE_FRACT, MODE_UFRACT,
|
||||
MODE_ACCUM, and MODE_UACCUM.
|
||||
* tree-vectorizer.c (vect_is_simple_reduction): Check for saturating
|
||||
fixed-point types to disable reduction.
|
||||
* explow.c (promote_mode): Support FIXED_POINT_TYPE.
|
||||
|
||||
2007-08-08 David Edelsohn <edelsohn@gnu.org>
|
||||
|
||||
* config/rs6000/x-rs6000: New file.
|
||||
|
|
|
@ -1772,7 +1772,7 @@ c-common.o : c-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
|||
|
||||
c-pretty-print.o : c-pretty-print.c $(C_PRETTY_PRINT_H) \
|
||||
$(C_TREE_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(REAL_H) \
|
||||
$(DIAGNOSTIC_H) tree-iterator.h
|
||||
$(DIAGNOSTIC_H) tree-iterator.h fixed-value.h
|
||||
|
||||
c-opts.o : c-opts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(TREE_H) $(C_PRAGMA_H) $(FLAGS_H) toplev.h langhooks.h \
|
||||
|
@ -1932,10 +1932,10 @@ tree.o : tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
|||
$(FLAGS_H) $(FUNCTION_H) $(PARAMS_H) \
|
||||
toplev.h $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) langhooks.h \
|
||||
$(REAL_H) gt-tree.h tree-iterator.h $(BASIC_BLOCK_H) $(TREE_FLOW_H) \
|
||||
$(OBSTACK_H) pointer-set.h
|
||||
$(OBSTACK_H) pointer-set.h fixed-value.h
|
||||
tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(TREE_H) langhooks.h toplev.h $(SPLAY_TREE_H) $(TREE_DUMP_H) \
|
||||
tree-iterator.h tree-pass.h $(DIAGNOSTIC_H) $(REAL_H)
|
||||
tree-iterator.h tree-pass.h $(DIAGNOSTIC_H) $(REAL_H) fixed-value.h
|
||||
tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(TREE_H) $(RTL_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h insn-config.h \
|
||||
$(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h \
|
||||
|
@ -1943,7 +1943,7 @@ tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
|||
debug.h $(DIAGNOSTIC_H) $(TREE_FLOW_H) tree-iterator.h tree-mudflap.h \
|
||||
ipa-prop.h value-prof.h
|
||||
print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
||||
$(GGC_H) langhooks.h $(REAL_H) tree-iterator.h
|
||||
$(GGC_H) langhooks.h $(REAL_H) tree-iterator.h fixed-value.h
|
||||
stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(TREE_H) $(PARAMS_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) $(RTL_H) \
|
||||
$(GGC_H) $(TM_P_H) $(TARGET_H) langhooks.h $(REGS_H) gt-stor-layout.h \
|
||||
|
@ -2267,10 +2267,10 @@ tree-nomudflap.o : $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TREE_INLINE_H) \
|
|||
tree-pretty-print.o : tree-pretty-print.c $(CONFIG_H) $(SYSTEM_H) \
|
||||
$(TREE_H) $(DIAGNOSTIC_H) $(REAL_H) $(HASHTAB_H) $(TREE_FLOW_H) \
|
||||
$(TM_H) coretypes.h tree-iterator.h tree-chrec.h langhooks.h tree-pass.h \
|
||||
value-prof.h
|
||||
value-prof.h fixed-value.h
|
||||
fold-const.o : fold-const.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(TREE_H) $(FLAGS_H) $(REAL_H) toplev.h $(HASHTAB_H) $(EXPR_H) $(RTL_H) \
|
||||
$(GGC_H) $(TM_P_H) langhooks.h $(MD5_H) intl.h
|
||||
$(GGC_H) $(TM_P_H) langhooks.h $(MD5_H) intl.h fixed-value.h
|
||||
diagnostic.o : diagnostic.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(TREE_H) version.h $(TM_P_H) $(FLAGS_H) input.h toplev.h intl.h \
|
||||
$(DIAGNOSTIC_H) langhooks.h $(LANGHOOKS_DEF_H) diagnostic.def opts.h
|
||||
|
|
|
@ -426,6 +426,7 @@ gen_type (const char *ret_val, tree t, formals_style style)
|
|||
break;
|
||||
|
||||
case INTEGER_TYPE:
|
||||
case FIXED_POINT_TYPE:
|
||||
data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
|
||||
/* Normally, `unsigned' is part of the deal. Not so if it comes
|
||||
with a type qualifier. */
|
||||
|
|
|
@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "real.h"
|
||||
#include "fixed-value.h"
|
||||
#include "c-pretty-print.h"
|
||||
#include "c-tree.h"
|
||||
#include "tree-iterator.h"
|
||||
|
@ -312,6 +313,7 @@ pp_c_type_specifier (c_pretty_printer *pp, tree t)
|
|||
case BOOLEAN_TYPE:
|
||||
case INTEGER_TYPE:
|
||||
case REAL_TYPE:
|
||||
case FIXED_POINT_TYPE:
|
||||
if (TYPE_NAME (t))
|
||||
{
|
||||
t = TYPE_NAME (t);
|
||||
|
@ -320,7 +322,10 @@ pp_c_type_specifier (c_pretty_printer *pp, tree t)
|
|||
else
|
||||
{
|
||||
int prec = TYPE_PRECISION (t);
|
||||
t = c_common_type_for_mode (TYPE_MODE (t), TYPE_UNSIGNED (t));
|
||||
if (ALL_FIXED_POINT_MODE_P (TYPE_MODE (t)))
|
||||
t = c_common_type_for_mode (TYPE_MODE (t), TYPE_SATURATING (t));
|
||||
else
|
||||
t = c_common_type_for_mode (TYPE_MODE (t), TYPE_UNSIGNED (t));
|
||||
if (TYPE_NAME (t))
|
||||
{
|
||||
pp_c_type_specifier (pp, t);
|
||||
|
@ -342,6 +347,9 @@ pp_c_type_specifier (c_pretty_printer *pp, tree t)
|
|||
case REAL_TYPE:
|
||||
pp_string (pp, "<unnamed-float:");
|
||||
break;
|
||||
case FIXED_POINT_TYPE:
|
||||
pp_string (pp, "<unnamed-fixed:");
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
@ -539,6 +547,7 @@ pp_c_direct_abstract_declarator (c_pretty_printer *pp, tree t)
|
|||
case BOOLEAN_TYPE:
|
||||
case INTEGER_TYPE:
|
||||
case REAL_TYPE:
|
||||
case FIXED_POINT_TYPE:
|
||||
case ENUMERAL_TYPE:
|
||||
case RECORD_TYPE:
|
||||
case UNION_TYPE:
|
||||
|
@ -656,6 +665,7 @@ pp_c_direct_declarator (c_pretty_printer *pp, tree t)
|
|||
|
||||
case INTEGER_TYPE:
|
||||
case REAL_TYPE:
|
||||
case FIXED_POINT_TYPE:
|
||||
case ENUMERAL_TYPE:
|
||||
case UNION_TYPE:
|
||||
case RECORD_TYPE:
|
||||
|
@ -678,6 +688,7 @@ pp_c_declarator (c_pretty_printer *pp, tree t)
|
|||
{
|
||||
case INTEGER_TYPE:
|
||||
case REAL_TYPE:
|
||||
case FIXED_POINT_TYPE:
|
||||
case ENUMERAL_TYPE:
|
||||
case UNION_TYPE:
|
||||
case RECORD_TYPE:
|
||||
|
@ -925,6 +936,16 @@ pp_c_floating_constant (c_pretty_printer *pp, tree r)
|
|||
pp_string (pp, "df");
|
||||
}
|
||||
|
||||
/* Print out a FIXED value as a decimal-floating-constant. */
|
||||
|
||||
static void
|
||||
pp_c_fixed_constant (c_pretty_printer *pp, tree r)
|
||||
{
|
||||
fixed_to_decimal (pp_buffer (pp)->digit_buffer, &TREE_FIXED_CST (r),
|
||||
sizeof (pp_buffer (pp)->digit_buffer));
|
||||
pp_string (pp, pp_buffer(pp)->digit_buffer);
|
||||
}
|
||||
|
||||
/* Pretty-print a compound literal expression. GNU extensions include
|
||||
vector constants. */
|
||||
|
||||
|
@ -953,6 +974,7 @@ pp_c_compound_literal (c_pretty_printer *pp, tree e)
|
|||
/* constant:
|
||||
integer-constant
|
||||
floating-constant
|
||||
fixed-point-constant
|
||||
enumeration-constant
|
||||
character-constant */
|
||||
|
||||
|
@ -982,6 +1004,10 @@ pp_c_constant (c_pretty_printer *pp, tree e)
|
|||
pp_c_floating_constant (pp, e);
|
||||
break;
|
||||
|
||||
case FIXED_CST:
|
||||
pp_c_fixed_constant (pp, e);
|
||||
break;
|
||||
|
||||
case STRING_CST:
|
||||
pp_c_string_literal (pp, e);
|
||||
break;
|
||||
|
@ -1037,6 +1063,7 @@ pp_c_primary_expression (c_pretty_printer *pp, tree e)
|
|||
|
||||
case INTEGER_CST:
|
||||
case REAL_CST:
|
||||
case FIXED_CST:
|
||||
case STRING_CST:
|
||||
pp_c_constant (pp, e);
|
||||
break;
|
||||
|
@ -1842,6 +1869,10 @@ pp_c_expression (c_pretty_printer *pp, tree e)
|
|||
pp_c_floating_constant (pp, e);
|
||||
break;
|
||||
|
||||
case FIXED_CST:
|
||||
pp_c_fixed_constant (pp, e);
|
||||
break;
|
||||
|
||||
case STRING_CST:
|
||||
pp_c_string_literal (pp, e);
|
||||
break;
|
||||
|
|
|
@ -1906,6 +1906,7 @@ dbxout_type (tree type, int full)
|
|||
break;
|
||||
|
||||
case REAL_TYPE:
|
||||
case FIXED_POINT_TYPE:
|
||||
/* This used to say `r1' and we used to take care
|
||||
to make sure that `int' was type number 1. */
|
||||
stabstr_C ('r');
|
||||
|
|
|
@ -454,6 +454,38 @@ along with GCC; see the file COPYING3. If not see
|
|||
#define DECIMAL128_TYPE_SIZE 128
|
||||
#endif
|
||||
|
||||
#ifndef SHORT_FRACT_TYPE_SIZE
|
||||
#define SHORT_FRACT_TYPE_SIZE BITS_PER_UNIT
|
||||
#endif
|
||||
|
||||
#ifndef FRACT_TYPE_SIZE
|
||||
#define FRACT_TYPE_SIZE (BITS_PER_UNIT * 2)
|
||||
#endif
|
||||
|
||||
#ifndef LONG_FRACT_TYPE_SIZE
|
||||
#define LONG_FRACT_TYPE_SIZE (BITS_PER_UNIT * 4)
|
||||
#endif
|
||||
|
||||
#ifndef LONG_LONG_FRACT_TYPE_SIZE
|
||||
#define LONG_LONG_FRACT_TYPE_SIZE (BITS_PER_UNIT * 8)
|
||||
#endif
|
||||
|
||||
#ifndef SHORT_ACCUM_TYPE_SIZE
|
||||
#define SHORT_ACCUM_TYPE_SIZE (SHORT_FRACT_TYPE_SIZE * 2)
|
||||
#endif
|
||||
|
||||
#ifndef ACCUM_TYPE_SIZE
|
||||
#define ACCUM_TYPE_SIZE (FRACT_TYPE_SIZE * 2)
|
||||
#endif
|
||||
|
||||
#ifndef LONG_ACCUM_TYPE_SIZE
|
||||
#define LONG_ACCUM_TYPE_SIZE (LONG_FRACT_TYPE_SIZE * 2)
|
||||
#endif
|
||||
|
||||
#ifndef LONG_LONG_ACCUM_TYPE_SIZE
|
||||
#define LONG_LONG_ACCUM_TYPE_SIZE (LONG_LONG_FRACT_TYPE_SIZE * 2)
|
||||
#endif
|
||||
|
||||
/* Width in bits of a pointer. Mind the value of the macro `Pmode'. */
|
||||
#ifndef POINTER_SIZE
|
||||
#define POINTER_SIZE BITS_PER_WORD
|
||||
|
|
|
@ -271,6 +271,7 @@ The elements are indexed from zero.
|
|||
@tindex TYPE_MIN_VALUE
|
||||
@tindex TYPE_MAX_VALUE
|
||||
@tindex REAL_TYPE
|
||||
@tindex FIXED_POINT_TYPE
|
||||
@tindex COMPLEX_TYPE
|
||||
@tindex ENUMERAL_TYPE
|
||||
@tindex BOOLEAN_TYPE
|
||||
|
@ -498,6 +499,19 @@ Used to represent the @code{float}, @code{double}, and @code{long
|
|||
double} types. The number of bits in the floating-point representation
|
||||
is given by @code{TYPE_PRECISION}, as in the @code{INTEGER_TYPE} case.
|
||||
|
||||
@item FIXED_POINT_TYPE
|
||||
Used to represent the @code{short _Fract}, @code{_Fract}, @code{long
|
||||
_Fract}, @code{long long _Fract}, @code{short _Accum}, @code{_Accum},
|
||||
@code{long _Accum}, and @code{long long _Accum} types. The number of bits
|
||||
in the fixed-point representation is given by @code{TYPE_PRECISION},
|
||||
as in the @code{INTEGER_TYPE} case. There may be padding bits, fractional
|
||||
bits and integral bits. The number of fractional bits is given by
|
||||
@code{TYPE_FBIT}, and the number of integral bits is given by @code{TYPE_IBIT}.
|
||||
The fixed-point type is unsigned if @code{TYPE_UNSIGNED} holds; otherwise,
|
||||
it is signed.
|
||||
The fixed-point type is saturating if @code{TYPE_SATURATING} holds; otherwise,
|
||||
it is not saturating.
|
||||
|
||||
@item COMPLEX_TYPE
|
||||
Used to represent GCC built-in @code{__complex__} data types. The
|
||||
@code{TREE_TYPE} is the type of the real and imaginary parts.
|
||||
|
@ -1879,6 +1893,7 @@ This macro returns the attributes on the type @var{type}.
|
|||
@findex tree_int_cst_lt
|
||||
@findex tree_int_cst_equal
|
||||
@tindex REAL_CST
|
||||
@tindex FIXED_CST
|
||||
@tindex COMPLEX_CST
|
||||
@tindex VECTOR_CST
|
||||
@tindex STRING_CST
|
||||
|
@ -1907,6 +1922,7 @@ This macro returns the attributes on the type @var{type}.
|
|||
@tindex NON_LVALUE_EXPR
|
||||
@tindex NOP_EXPR
|
||||
@tindex CONVERT_EXPR
|
||||
@tindex FIXED_CONVERT_EXPR
|
||||
@tindex THROW_EXPR
|
||||
@tindex LSHIFT_EXPR
|
||||
@tindex RSHIFT_EXPR
|
||||
|
@ -2080,6 +2096,15 @@ its bit-pattern.
|
|||
FIXME: Talk about how to obtain representations of this constant, do
|
||||
comparisons, and so forth.
|
||||
|
||||
@item FIXED_CST
|
||||
|
||||
These nodes represent fixed-point constants. The type of these constants
|
||||
is obtained with @code{TREE_TYPE}. @code{TREE_FIXED_CST_PTR} points to
|
||||
to struct fixed_value; @code{TREE_FIXED_CST} returns the structure itself.
|
||||
Struct fixed_value contains @code{data} with the size of two
|
||||
HOST_BITS_PER_WIDE_INT and @code{mode} as the associated fixed-point
|
||||
machine mode for @code{data}.
|
||||
|
||||
@item COMPLEX_CST
|
||||
These nodes are used to represent complex number constants, that is a
|
||||
@code{__complex__} whose parts are constant nodes. The
|
||||
|
@ -2246,6 +2271,13 @@ cases are always indicated explicitly. Similarly, a user-defined
|
|||
conversion is never represented by a @code{CONVERT_EXPR}; instead, the
|
||||
function calls are made explicit.
|
||||
|
||||
@item FIXED_CONVERT_EXPR
|
||||
These nodes are used to represent conversions that involve fixed-point
|
||||
values. For example, from a fixed-point value to another fixed-point value,
|
||||
from an integer to a fixed-point value, from a fixed-point value to an
|
||||
integer, from a floating-point value to a fixed-point value, or from
|
||||
a fixed-point value to a floating-point value.
|
||||
|
||||
@item THROW_EXPR
|
||||
These nodes represent @code{throw} expressions. The single operand is
|
||||
an expression for the code that should be executed to throw the
|
||||
|
|
|
@ -1605,6 +1605,54 @@ the target machine. If you don't define this, the default is two
|
|||
words.
|
||||
@end defmac
|
||||
|
||||
@defmac SHORT_FRACT_TYPE_SIZE
|
||||
A C expression for the size in bits of the type @code{short _Fract} on
|
||||
the target machine. If you don't define this, the default is
|
||||
@code{BITS_PER_UNIT}.
|
||||
@end defmac
|
||||
|
||||
@defmac FRACT_TYPE_SIZE
|
||||
A C expression for the size in bits of the type @code{_Fract} on
|
||||
the target machine. If you don't define this, the default is
|
||||
@code{BITS_PER_UNIT * 2}.
|
||||
@end defmac
|
||||
|
||||
@defmac LONG_FRACT_TYPE_SIZE
|
||||
A C expression for the size in bits of the type @code{long _Fract} on
|
||||
the target machine. If you don't define this, the default is
|
||||
@code{BITS_PER_UNIT * 4}.
|
||||
@end defmac
|
||||
|
||||
@defmac LONG_LONG_FRACT_TYPE_SIZE
|
||||
A C expression for the size in bits of the type @code{long long _Fract} on
|
||||
the target machine. If you don't define this, the default is
|
||||
@code{BITS_PER_UNIT * 8}.
|
||||
@end defmac
|
||||
|
||||
@defmac SHORT_ACCUM_TYPE_SIZE
|
||||
A C expression for the size in bits of the type @code{short _Accum} on
|
||||
the target machine. If you don't define this, the default is
|
||||
@code{BITS_PER_UNIT * 2}.
|
||||
@end defmac
|
||||
|
||||
@defmac ACCUM_TYPE_SIZE
|
||||
A C expression for the size in bits of the type @code{_Accum} on
|
||||
the target machine. If you don't define this, the default is
|
||||
@code{BITS_PER_UNIT * 4}.
|
||||
@end defmac
|
||||
|
||||
@defmac LONG_ACCUM_TYPE_SIZE
|
||||
A C expression for the size in bits of the type @code{long _Accum} on
|
||||
the target machine. If you don't define this, the default is
|
||||
@code{BITS_PER_UNIT * 8}.
|
||||
@end defmac
|
||||
|
||||
@defmac LONG_LONG_ACCUM_TYPE_SIZE
|
||||
A C expression for the size in bits of the type @code{long long _Accum} on
|
||||
the target machine. If you don't define this, the default is
|
||||
@code{BITS_PER_UNIT * 16}.
|
||||
@end defmac
|
||||
|
||||
@defmac LIBGCC2_LONG_DOUBLE_TYPE_SIZE
|
||||
Define this macro if @code{LONG_DOUBLE_TYPE_SIZE} is not constant or
|
||||
if you want routines in @file{libgcc2.a} for a size other than
|
||||
|
|
|
@ -8396,6 +8396,13 @@ base_type_die (tree type)
|
|||
encoding = DW_ATE_float;
|
||||
break;
|
||||
|
||||
case FIXED_POINT_TYPE:
|
||||
if (TYPE_UNSIGNED (type))
|
||||
encoding = DW_ATE_signed_fixed;
|
||||
else
|
||||
encoding = DW_ATE_unsigned_fixed;
|
||||
break;
|
||||
|
||||
/* Dwarf2 doesn't know anything about complex ints, so use
|
||||
a user defined type for it. */
|
||||
case COMPLEX_TYPE:
|
||||
|
@ -8440,6 +8447,7 @@ is_base_type (tree type)
|
|||
case VOID_TYPE:
|
||||
case INTEGER_TYPE:
|
||||
case REAL_TYPE:
|
||||
case FIXED_POINT_TYPE:
|
||||
case COMPLEX_TYPE:
|
||||
case BOOLEAN_TYPE:
|
||||
return 1;
|
||||
|
@ -11401,11 +11409,11 @@ add_type_attribute (dw_die_ref object_die, tree type, int decl_const,
|
|||
enum tree_code code = TREE_CODE (type);
|
||||
dw_die_ref type_die = NULL;
|
||||
|
||||
/* ??? If this type is an unnamed subrange type of an integral or
|
||||
floating-point type, use the inner type. This is because we have no
|
||||
/* ??? If this type is an unnamed subrange type of an integral, floating-point
|
||||
or fixed-point type, use the inner type. This is because we have no
|
||||
support for unnamed types in base_type_die. This can happen if this is
|
||||
an Ada subrange type. Correct solution is emit a subrange type die. */
|
||||
if ((code == INTEGER_TYPE || code == REAL_TYPE)
|
||||
if ((code == INTEGER_TYPE || code == REAL_TYPE || code == FIXED_POINT_TYPE)
|
||||
&& TREE_TYPE (type) != 0 && TYPE_NAME (type) == 0)
|
||||
type = TREE_TYPE (type), code = TREE_CODE (type);
|
||||
|
||||
|
@ -13082,6 +13090,7 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
|
|||
case VOID_TYPE:
|
||||
case INTEGER_TYPE:
|
||||
case REAL_TYPE:
|
||||
case FIXED_POINT_TYPE:
|
||||
case COMPLEX_TYPE:
|
||||
case BOOLEAN_TYPE:
|
||||
/* No DIEs needed for fundamental types. */
|
||||
|
|
|
@ -50,6 +50,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "insn-config.h"
|
||||
#include "recog.h"
|
||||
#include "real.h"
|
||||
#include "fixed-value.h"
|
||||
#include "bitmap.h"
|
||||
#include "basic-block.h"
|
||||
#include "ggc.h"
|
||||
|
@ -108,6 +109,10 @@ REAL_VALUE_TYPE dconstthird;
|
|||
REAL_VALUE_TYPE dconstsqrt2;
|
||||
REAL_VALUE_TYPE dconste;
|
||||
|
||||
/* Record fixed-point constant 0 and 1. */
|
||||
FIXED_VALUE_TYPE fconst0[MAX_FCONST0];
|
||||
FIXED_VALUE_TYPE fconst1[MAX_FCONST1];
|
||||
|
||||
/* All references to the following fixed hard registers go through
|
||||
these unique rtl objects. On machines where the frame-pointer and
|
||||
arg-pointer are the same register, they use the same unique object.
|
||||
|
@ -5256,6 +5261,62 @@ init_emit_once (int line_numbers)
|
|||
const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
|
||||
}
|
||||
|
||||
for (mode = GET_CLASS_NARROWEST_MODE (MODE_FRACT);
|
||||
mode != VOIDmode;
|
||||
mode = GET_MODE_WIDER_MODE (mode))
|
||||
{
|
||||
FCONST0(mode).data.high = 0;
|
||||
FCONST0(mode).data.low = 0;
|
||||
FCONST0(mode).mode = mode;
|
||||
}
|
||||
|
||||
for (mode = GET_CLASS_NARROWEST_MODE (MODE_UFRACT);
|
||||
mode != VOIDmode;
|
||||
mode = GET_MODE_WIDER_MODE (mode))
|
||||
{
|
||||
FCONST0(mode).data.high = 0;
|
||||
FCONST0(mode).data.low = 0;
|
||||
FCONST0(mode).mode = mode;
|
||||
}
|
||||
|
||||
for (mode = GET_CLASS_NARROWEST_MODE (MODE_ACCUM);
|
||||
mode != VOIDmode;
|
||||
mode = GET_MODE_WIDER_MODE (mode))
|
||||
{
|
||||
FCONST0(mode).data.high = 0;
|
||||
FCONST0(mode).data.low = 0;
|
||||
FCONST0(mode).mode = mode;
|
||||
|
||||
/* We store the value 1. */
|
||||
FCONST1(mode).data.high = 0;
|
||||
FCONST1(mode).data.low = 0;
|
||||
FCONST1(mode).mode = mode;
|
||||
lshift_double (1, 0, GET_MODE_FBIT (mode),
|
||||
2 * HOST_BITS_PER_WIDE_INT,
|
||||
&FCONST1(mode).data.low,
|
||||
&FCONST1(mode).data.high,
|
||||
SIGNED_FIXED_POINT_MODE_P (mode));
|
||||
}
|
||||
|
||||
for (mode = GET_CLASS_NARROWEST_MODE (MODE_UACCUM);
|
||||
mode != VOIDmode;
|
||||
mode = GET_MODE_WIDER_MODE (mode))
|
||||
{
|
||||
FCONST0(mode).data.high = 0;
|
||||
FCONST0(mode).data.low = 0;
|
||||
FCONST0(mode).mode = mode;
|
||||
|
||||
/* We store the value 1. */
|
||||
FCONST1(mode).data.high = 0;
|
||||
FCONST1(mode).data.low = 0;
|
||||
FCONST1(mode).mode = mode;
|
||||
lshift_double (1, 0, GET_MODE_FBIT (mode),
|
||||
2 * HOST_BITS_PER_WIDE_INT,
|
||||
&FCONST1(mode).data.low,
|
||||
&FCONST1(mode).data.high,
|
||||
SIGNED_FIXED_POINT_MODE_P (mode));
|
||||
}
|
||||
|
||||
for (i = (int) CCmode; i < (int) MAX_MACHINE_MODE; ++i)
|
||||
if (GET_MODE_CLASS ((enum machine_mode) i) == MODE_CC)
|
||||
const_tiny_rtx[0][i] = const0_rtx;
|
||||
|
|
|
@ -793,7 +793,7 @@ promote_mode (tree type, enum machine_mode mode, int *punsignedp,
|
|||
{
|
||||
#ifdef PROMOTE_FUNCTION_MODE
|
||||
case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
|
||||
case REAL_TYPE: case OFFSET_TYPE:
|
||||
case REAL_TYPE: case OFFSET_TYPE: case FIXED_POINT_TYPE:
|
||||
#ifdef PROMOTE_MODE
|
||||
if (for_call)
|
||||
{
|
||||
|
|
|
@ -1182,6 +1182,14 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
|
|||
|
||||
if (GET_MODE_CLASS (tmode) == MODE_FLOAT)
|
||||
new_mode = MIN_MODE_VECTOR_FLOAT;
|
||||
else if (GET_MODE_CLASS (tmode) == MODE_FRACT)
|
||||
new_mode = MIN_MODE_VECTOR_FRACT;
|
||||
else if (GET_MODE_CLASS (tmode) == MODE_UFRACT)
|
||||
new_mode = MIN_MODE_VECTOR_UFRACT;
|
||||
else if (GET_MODE_CLASS (tmode) == MODE_ACCUM)
|
||||
new_mode = MIN_MODE_VECTOR_ACCUM;
|
||||
else if (GET_MODE_CLASS (tmode) == MODE_UACCUM)
|
||||
new_mode = MIN_MODE_VECTOR_UACCUM;
|
||||
else
|
||||
new_mode = MIN_MODE_VECTOR_INT;
|
||||
|
||||
|
|
346
gcc/fold-const.c
346
gcc/fold-const.c
|
@ -54,6 +54,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "flags.h"
|
||||
#include "tree.h"
|
||||
#include "real.h"
|
||||
#include "fixed-value.h"
|
||||
#include "rtl.h"
|
||||
#include "expr.h"
|
||||
#include "tm_p.h"
|
||||
|
@ -1127,6 +1128,7 @@ negate_expr_p (tree t)
|
|||
return (INTEGRAL_TYPE_P (type)
|
||||
&& TYPE_OVERFLOW_WRAPS (type));
|
||||
|
||||
case FIXED_CST:
|
||||
case REAL_CST:
|
||||
case NEGATE_EXPR:
|
||||
return true;
|
||||
|
@ -1257,6 +1259,10 @@ fold_negate_expr (tree t)
|
|||
return tem;
|
||||
break;
|
||||
|
||||
case FIXED_CST:
|
||||
tem = fold_negate_const (t, type);
|
||||
return tem;
|
||||
|
||||
case COMPLEX_CST:
|
||||
{
|
||||
tree rpart = negate_expr (TREE_REALPART (t));
|
||||
|
@ -1479,10 +1485,12 @@ split_tree (tree in, enum tree_code code, tree *conp, tree *litp,
|
|||
/* Strip any conversions that don't change the machine mode or signedness. */
|
||||
STRIP_SIGN_NOPS (in);
|
||||
|
||||
if (TREE_CODE (in) == INTEGER_CST || TREE_CODE (in) == REAL_CST)
|
||||
if (TREE_CODE (in) == INTEGER_CST || TREE_CODE (in) == REAL_CST
|
||||
|| TREE_CODE (in) == FIXED_CST)
|
||||
*litp = in;
|
||||
else if (TREE_CODE (in) == code
|
||||
|| (! FLOAT_TYPE_P (TREE_TYPE (in))
|
||||
&& ! SAT_FIXED_POINT_TYPE_P (TREE_TYPE (in))
|
||||
/* We can associate addition and subtraction together (even
|
||||
though the C standard doesn't say so) for integers because
|
||||
the value is not affected. For reals, the value might be
|
||||
|
@ -1496,9 +1504,11 @@ split_tree (tree in, enum tree_code code, tree *conp, tree *litp,
|
|||
int neg_litp_p = 0, neg_conp_p = 0, neg_var_p = 0;
|
||||
|
||||
/* First see if either of the operands is a literal, then a constant. */
|
||||
if (TREE_CODE (op0) == INTEGER_CST || TREE_CODE (op0) == REAL_CST)
|
||||
if (TREE_CODE (op0) == INTEGER_CST || TREE_CODE (op0) == REAL_CST
|
||||
|| TREE_CODE (op0) == FIXED_CST)
|
||||
*litp = op0, op0 = 0;
|
||||
else if (TREE_CODE (op1) == INTEGER_CST || TREE_CODE (op1) == REAL_CST)
|
||||
else if (TREE_CODE (op1) == INTEGER_CST || TREE_CODE (op1) == REAL_CST
|
||||
|| TREE_CODE (op1) == FIXED_CST)
|
||||
*litp = op1, neg_litp_p = neg1_p, op1 = 0;
|
||||
|
||||
if (op0 != 0 && TREE_CONSTANT (op0))
|
||||
|
@ -1886,6 +1896,52 @@ const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
|
|||
return t;
|
||||
}
|
||||
|
||||
if (TREE_CODE (arg1) == FIXED_CST)
|
||||
{
|
||||
FIXED_VALUE_TYPE f1;
|
||||
FIXED_VALUE_TYPE f2;
|
||||
FIXED_VALUE_TYPE result;
|
||||
tree t, type;
|
||||
int sat_p;
|
||||
bool overflow_p;
|
||||
|
||||
/* The following codes are handled by fixed_arithmetic. */
|
||||
switch (code)
|
||||
{
|
||||
case PLUS_EXPR:
|
||||
case MINUS_EXPR:
|
||||
case MULT_EXPR:
|
||||
case TRUNC_DIV_EXPR:
|
||||
f2 = TREE_FIXED_CST (arg2);
|
||||
break;
|
||||
|
||||
case LSHIFT_EXPR:
|
||||
case RSHIFT_EXPR:
|
||||
f2.data.high = TREE_INT_CST_HIGH (arg2);
|
||||
f2.data.low = TREE_INT_CST_LOW (arg2);
|
||||
f2.mode = SImode;
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
f1 = TREE_FIXED_CST (arg1);
|
||||
type = TREE_TYPE (arg1);
|
||||
sat_p = TYPE_SATURATING (type);
|
||||
overflow_p = fixed_arithmetic (&result, code, &f1, &f2, sat_p);
|
||||
t = build_fixed (type, result);
|
||||
/* Propagate overflow flags. */
|
||||
if (overflow_p | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2))
|
||||
{
|
||||
TREE_OVERFLOW (t) = 1;
|
||||
TREE_CONSTANT_OVERFLOW (t) = 1;
|
||||
}
|
||||
else if (TREE_CONSTANT_OVERFLOW (arg1) | TREE_CONSTANT_OVERFLOW (arg2))
|
||||
TREE_CONSTANT_OVERFLOW (t) = 1;
|
||||
return t;
|
||||
}
|
||||
|
||||
if (TREE_CODE (arg1) == COMPLEX_CST)
|
||||
{
|
||||
tree type = TREE_TYPE (arg1);
|
||||
|
@ -2151,6 +2207,61 @@ fold_convert_const_int_from_real (enum tree_code code, tree type, tree arg1)
|
|||
return t;
|
||||
}
|
||||
|
||||
/* A subroutine of fold_convert_const handling conversions of a
|
||||
FIXED_CST to an integer type. */
|
||||
|
||||
static tree
|
||||
fold_convert_const_int_from_fixed (tree type, tree arg1)
|
||||
{
|
||||
tree t;
|
||||
double_int temp, temp_trunc;
|
||||
unsigned int mode;
|
||||
|
||||
/* Right shift FIXED_CST to temp by fbit. */
|
||||
temp = TREE_FIXED_CST (arg1).data;
|
||||
mode = TREE_FIXED_CST (arg1).mode;
|
||||
if (GET_MODE_FBIT (mode) < 2 * HOST_BITS_PER_WIDE_INT)
|
||||
{
|
||||
lshift_double (temp.low, temp.high,
|
||||
- GET_MODE_FBIT (mode), 2 * HOST_BITS_PER_WIDE_INT,
|
||||
&temp.low, &temp.high, SIGNED_FIXED_POINT_MODE_P (mode));
|
||||
|
||||
/* Left shift temp to temp_trunc by fbit. */
|
||||
lshift_double (temp.low, temp.high,
|
||||
GET_MODE_FBIT (mode), 2 * HOST_BITS_PER_WIDE_INT,
|
||||
&temp_trunc.low, &temp_trunc.high,
|
||||
SIGNED_FIXED_POINT_MODE_P (mode));
|
||||
}
|
||||
else
|
||||
{
|
||||
temp.low = 0;
|
||||
temp.high = 0;
|
||||
temp_trunc.low = 0;
|
||||
temp_trunc.high = 0;
|
||||
}
|
||||
|
||||
/* If FIXED_CST is negative, we need to round the value toward 0.
|
||||
By checking if the fractional bits are not zero to add 1 to temp. */
|
||||
if (SIGNED_FIXED_POINT_MODE_P (mode) && temp_trunc.high < 0
|
||||
&& !double_int_equal_p (TREE_FIXED_CST (arg1).data, temp_trunc))
|
||||
{
|
||||
double_int one;
|
||||
one.low = 1;
|
||||
one.high = 0;
|
||||
temp = double_int_add (temp, one);
|
||||
}
|
||||
|
||||
/* Given a fixed-point constant, make new constant with new type,
|
||||
appropriately sign-extended or truncated. */
|
||||
t = force_fit_type_double (type, temp.low, temp.high, -1,
|
||||
(temp.high < 0
|
||||
&& (TYPE_UNSIGNED (type)
|
||||
< TYPE_UNSIGNED (TREE_TYPE (arg1))))
|
||||
| TREE_OVERFLOW (arg1));
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/* A subroutine of fold_convert_const handling conversions a REAL_CST
|
||||
to another floating point type. */
|
||||
|
||||
|
@ -2167,6 +2278,102 @@ fold_convert_const_real_from_real (tree type, tree arg1)
|
|||
return t;
|
||||
}
|
||||
|
||||
/* A subroutine of fold_convert_const handling conversions a FIXED_CST
|
||||
to a floating point type. */
|
||||
|
||||
static tree
|
||||
fold_convert_const_real_from_fixed (tree type, tree arg1)
|
||||
{
|
||||
REAL_VALUE_TYPE value;
|
||||
tree t;
|
||||
|
||||
real_convert_from_fixed (&value, TYPE_MODE (type), &TREE_FIXED_CST (arg1));
|
||||
t = build_real (type, value);
|
||||
|
||||
TREE_OVERFLOW (t) = TREE_OVERFLOW (arg1);
|
||||
TREE_CONSTANT_OVERFLOW (t)
|
||||
= TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg1);
|
||||
return t;
|
||||
}
|
||||
|
||||
/* A subroutine of fold_convert_const handling conversions a FIXED_CST
|
||||
to another fixed-point type. */
|
||||
|
||||
static tree
|
||||
fold_convert_const_fixed_from_fixed (tree type, tree arg1)
|
||||
{
|
||||
FIXED_VALUE_TYPE value;
|
||||
tree t;
|
||||
bool overflow_p;
|
||||
|
||||
overflow_p = fixed_convert (&value, TYPE_MODE (type), &TREE_FIXED_CST (arg1),
|
||||
TYPE_SATURATING (type));
|
||||
t = build_fixed (type, value);
|
||||
|
||||
/* Propagate overflow flags. */
|
||||
if (overflow_p | TREE_OVERFLOW (arg1))
|
||||
{
|
||||
TREE_OVERFLOW (t) = 1;
|
||||
TREE_CONSTANT_OVERFLOW (t) = 1;
|
||||
}
|
||||
else if (TREE_CONSTANT_OVERFLOW (arg1))
|
||||
TREE_CONSTANT_OVERFLOW (t) = 1;
|
||||
return t;
|
||||
}
|
||||
|
||||
/* A subroutine of fold_convert_const handling conversions an INTEGER_CST
|
||||
to a fixed-point type. */
|
||||
|
||||
static tree
|
||||
fold_convert_const_fixed_from_int (tree type, tree arg1)
|
||||
{
|
||||
FIXED_VALUE_TYPE value;
|
||||
tree t;
|
||||
bool overflow_p;
|
||||
|
||||
overflow_p = fixed_convert_from_int (&value, TYPE_MODE (type),
|
||||
TREE_INT_CST (arg1),
|
||||
TYPE_UNSIGNED (TREE_TYPE (arg1)),
|
||||
TYPE_SATURATING (type));
|
||||
t = build_fixed (type, value);
|
||||
|
||||
/* Propagate overflow flags. */
|
||||
if (overflow_p | TREE_OVERFLOW (arg1))
|
||||
{
|
||||
TREE_OVERFLOW (t) = 1;
|
||||
TREE_CONSTANT_OVERFLOW (t) = 1;
|
||||
}
|
||||
else if (TREE_CONSTANT_OVERFLOW (arg1))
|
||||
TREE_CONSTANT_OVERFLOW (t) = 1;
|
||||
return t;
|
||||
}
|
||||
|
||||
/* A subroutine of fold_convert_const handling conversions a REAL_CST
|
||||
to a fixed-point type. */
|
||||
|
||||
static tree
|
||||
fold_convert_const_fixed_from_real (tree type, tree arg1)
|
||||
{
|
||||
FIXED_VALUE_TYPE value;
|
||||
tree t;
|
||||
bool overflow_p;
|
||||
|
||||
overflow_p = fixed_convert_from_real (&value, TYPE_MODE (type),
|
||||
&TREE_REAL_CST (arg1),
|
||||
TYPE_SATURATING (type));
|
||||
t = build_fixed (type, value);
|
||||
|
||||
/* Propagate overflow flags. */
|
||||
if (overflow_p | TREE_OVERFLOW (arg1))
|
||||
{
|
||||
TREE_OVERFLOW (t) = 1;
|
||||
TREE_CONSTANT_OVERFLOW (t) = 1;
|
||||
}
|
||||
else if (TREE_CONSTANT_OVERFLOW (arg1))
|
||||
TREE_CONSTANT_OVERFLOW (t) = 1;
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Attempt to fold type conversion operation CODE of expression ARG1 to
|
||||
type TYPE. If no simplification can be done return NULL_TREE. */
|
||||
|
||||
|
@ -2182,13 +2389,26 @@ fold_convert_const (enum tree_code code, tree type, tree arg1)
|
|||
return fold_convert_const_int_from_int (type, arg1);
|
||||
else if (TREE_CODE (arg1) == REAL_CST)
|
||||
return fold_convert_const_int_from_real (code, type, arg1);
|
||||
else if (TREE_CODE (arg1) == FIXED_CST)
|
||||
return fold_convert_const_int_from_fixed (type, arg1);
|
||||
}
|
||||
else if (TREE_CODE (type) == REAL_TYPE)
|
||||
{
|
||||
if (TREE_CODE (arg1) == INTEGER_CST)
|
||||
return build_real_from_int_cst (type, arg1);
|
||||
if (TREE_CODE (arg1) == REAL_CST)
|
||||
else if (TREE_CODE (arg1) == REAL_CST)
|
||||
return fold_convert_const_real_from_real (type, arg1);
|
||||
else if (TREE_CODE (arg1) == FIXED_CST)
|
||||
return fold_convert_const_real_from_fixed (type, arg1);
|
||||
}
|
||||
else if (TREE_CODE (type) == FIXED_POINT_TYPE)
|
||||
{
|
||||
if (TREE_CODE (arg1) == FIXED_CST)
|
||||
return fold_convert_const_fixed_from_fixed (type, arg1);
|
||||
else if (TREE_CODE (arg1) == INTEGER_CST)
|
||||
return fold_convert_const_fixed_from_int (type, arg1);
|
||||
else if (TREE_CODE (arg1) == REAL_CST)
|
||||
return fold_convert_const_fixed_from_real (type, arg1);
|
||||
}
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
@ -2300,6 +2520,12 @@ fold_convert (tree type, tree arg)
|
|||
if (tem != NULL_TREE)
|
||||
return tem;
|
||||
}
|
||||
else if (TREE_CODE (arg) == FIXED_CST)
|
||||
{
|
||||
tem = fold_convert_const (FIXED_CONVERT_EXPR, type, arg);
|
||||
if (tem != NULL_TREE)
|
||||
return tem;
|
||||
}
|
||||
|
||||
switch (TREE_CODE (orig))
|
||||
{
|
||||
|
@ -2311,6 +2537,35 @@ fold_convert (tree type, tree arg)
|
|||
case REAL_TYPE:
|
||||
return fold_build1 (NOP_EXPR, type, arg);
|
||||
|
||||
case FIXED_POINT_TYPE:
|
||||
return fold_build1 (FIXED_CONVERT_EXPR, type, arg);
|
||||
|
||||
case COMPLEX_TYPE:
|
||||
tem = fold_build1 (REALPART_EXPR, TREE_TYPE (orig), arg);
|
||||
return fold_convert (type, tem);
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
case FIXED_POINT_TYPE:
|
||||
if (TREE_CODE (arg) == FIXED_CST || TREE_CODE (arg) == INTEGER_CST
|
||||
|| TREE_CODE (arg) == REAL_CST)
|
||||
{
|
||||
tem = fold_convert_const (FIXED_CONVERT_EXPR, type, arg);
|
||||
if (tem != NULL_TREE)
|
||||
return tem;
|
||||
}
|
||||
|
||||
switch (TREE_CODE (orig))
|
||||
{
|
||||
case FIXED_POINT_TYPE:
|
||||
case INTEGER_TYPE:
|
||||
case ENUMERAL_TYPE:
|
||||
case BOOLEAN_TYPE:
|
||||
case REAL_TYPE:
|
||||
return fold_build1 (FIXED_CONVERT_EXPR, type, arg);
|
||||
|
||||
case COMPLEX_TYPE:
|
||||
tem = fold_build1 (REALPART_EXPR, TREE_TYPE (orig), arg);
|
||||
return fold_convert (type, tem);
|
||||
|
@ -2326,6 +2581,7 @@ fold_convert (tree type, tree arg)
|
|||
case BOOLEAN_TYPE: case ENUMERAL_TYPE:
|
||||
case POINTER_TYPE: case REFERENCE_TYPE:
|
||||
case REAL_TYPE:
|
||||
case FIXED_POINT_TYPE:
|
||||
return build2 (COMPLEX_EXPR, type,
|
||||
fold_convert (TREE_TYPE (type), arg),
|
||||
fold_convert (TREE_TYPE (type), integer_zero_node));
|
||||
|
@ -2808,6 +3064,10 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
|
|||
case INTEGER_CST:
|
||||
return tree_int_cst_equal (arg0, arg1);
|
||||
|
||||
case FIXED_CST:
|
||||
return FIXED_VALUES_IDENTICAL (TREE_FIXED_CST (arg0),
|
||||
TREE_FIXED_CST (arg1));
|
||||
|
||||
case REAL_CST:
|
||||
if (REAL_VALUES_IDENTICAL (TREE_REAL_CST (arg0),
|
||||
TREE_REAL_CST (arg1)))
|
||||
|
@ -4265,8 +4525,16 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh,
|
|||
if (!TYPE_UNSIGNED (exp_type) && TYPE_UNSIGNED (arg0_type))
|
||||
{
|
||||
tree high_positive;
|
||||
tree equiv_type = lang_hooks.types.type_for_mode
|
||||
(TYPE_MODE (arg0_type), 1);
|
||||
tree equiv_type;
|
||||
/* For fixed-point modes, we need to pass the saturating flag
|
||||
as the 2nd parameter. */
|
||||
if (ALL_FIXED_POINT_MODE_P (TYPE_MODE (arg0_type)))
|
||||
equiv_type = lang_hooks.types.type_for_mode
|
||||
(TYPE_MODE (arg0_type),
|
||||
TYPE_SATURATING (arg0_type));
|
||||
else
|
||||
equiv_type = lang_hooks.types.type_for_mode
|
||||
(TYPE_MODE (arg0_type), 1);
|
||||
|
||||
/* A range without an upper bound is, naturally, unbounded.
|
||||
Since convert would have cropped a very large value, use
|
||||
|
@ -6737,6 +7005,11 @@ tree_swap_operands_p (const_tree arg0, const_tree arg1, bool reorder)
|
|||
if (TREE_CODE (arg0) == REAL_CST)
|
||||
return 1;
|
||||
|
||||
if (TREE_CODE (arg1) == FIXED_CST)
|
||||
return 0;
|
||||
if (TREE_CODE (arg0) == FIXED_CST)
|
||||
return 1;
|
||||
|
||||
if (TREE_CODE (arg1) == COMPLEX_CST)
|
||||
return 0;
|
||||
if (TREE_CODE (arg0) == COMPLEX_CST)
|
||||
|
@ -7136,6 +7409,9 @@ fold_plusminus_mult_expr (enum tree_code code, tree type, tree arg0, tree arg1)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* We cannot generate constant 1 for fract. */
|
||||
if (ALL_FRACT_MODE_P (TYPE_MODE (type)))
|
||||
return NULL_TREE;
|
||||
arg00 = arg0;
|
||||
arg01 = build_one_cst (type);
|
||||
}
|
||||
|
@ -7151,6 +7427,9 @@ fold_plusminus_mult_expr (enum tree_code code, tree type, tree arg0, tree arg1)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* We cannot generate constant 1 for fract. */
|
||||
if (ALL_FRACT_MODE_P (TYPE_MODE (type)))
|
||||
return NULL_TREE;
|
||||
arg10 = arg1;
|
||||
arg11 = build_one_cst (type);
|
||||
}
|
||||
|
@ -8011,6 +8290,10 @@ fold_unary (enum tree_code code, tree type, tree op0)
|
|||
tem = fold_convert_const (code, type, op0);
|
||||
return tem ? tem : NULL_TREE;
|
||||
|
||||
case FIXED_CONVERT_EXPR:
|
||||
tem = fold_convert_const (code, type, arg0);
|
||||
return tem ? tem : NULL_TREE;
|
||||
|
||||
case VIEW_CONVERT_EXPR:
|
||||
if (TREE_TYPE (op0) == type)
|
||||
return op0;
|
||||
|
@ -9114,11 +9397,18 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
|
|||
constant but we can't do arithmetic on them. */
|
||||
if ((TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
|
||||
|| (TREE_CODE (arg0) == REAL_CST && TREE_CODE (arg1) == REAL_CST)
|
||||
|| (TREE_CODE (arg0) == FIXED_CST && TREE_CODE (arg1) == FIXED_CST)
|
||||
|| (TREE_CODE (arg0) == FIXED_CST && TREE_CODE (arg1) == INTEGER_CST)
|
||||
|| (TREE_CODE (arg0) == COMPLEX_CST && TREE_CODE (arg1) == COMPLEX_CST)
|
||||
|| (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == VECTOR_CST))
|
||||
{
|
||||
if (kind == tcc_binary)
|
||||
tem = const_binop (code, arg0, arg1, 0);
|
||||
{
|
||||
/* Make sure type and arg0 have the same saturating flag. */
|
||||
gcc_assert (TYPE_SATURATING (type)
|
||||
== TYPE_SATURATING (TREE_TYPE (arg0)));
|
||||
tem = const_binop (code, arg0, arg1, 0);
|
||||
}
|
||||
else if (kind == tcc_comparison)
|
||||
tem = fold_relational_const (code, type, arg0, arg1);
|
||||
else
|
||||
|
@ -9323,9 +9613,10 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
|
|||
}
|
||||
|
||||
/* Handle (A1 * C1) + (A2 * C2) with A1, A2 or C1, C2 being the
|
||||
same or one. */
|
||||
same or one. Make sure type is not saturating. */
|
||||
if ((TREE_CODE (arg0) == MULT_EXPR
|
||||
|| TREE_CODE (arg1) == MULT_EXPR)
|
||||
&& !TYPE_SATURATING (type)
|
||||
&& (!FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations))
|
||||
{
|
||||
tree tem = fold_plusminus_mult_expr (code, type, arg0, arg1);
|
||||
|
@ -9569,9 +9860,11 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
|
|||
/* In most languages, can't associate operations on floats through
|
||||
parentheses. Rather than remember where the parentheses were, we
|
||||
don't associate floats at all, unless the user has specified
|
||||
-funsafe-math-optimizations. */
|
||||
-funsafe-math-optimizations.
|
||||
And, we need to make sure type is not saturating. */
|
||||
|
||||
if (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
|
||||
if ((! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
|
||||
&& !TYPE_SATURATING (type))
|
||||
{
|
||||
tree var0, con0, lit0, minus_lit0;
|
||||
tree var1, con1, lit1, minus_lit1;
|
||||
|
@ -9874,9 +10167,10 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
|
|||
return tem;
|
||||
|
||||
/* Handle (A1 * C1) - (A2 * C2) with A1, A2 or C1, C2 being the
|
||||
same or one. */
|
||||
same or one. Make sure type is not saturating. */
|
||||
if ((TREE_CODE (arg0) == MULT_EXPR
|
||||
|| TREE_CODE (arg1) == MULT_EXPR)
|
||||
&& !TYPE_SATURATING (type)
|
||||
&& (!FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations))
|
||||
{
|
||||
tree tem = fold_plusminus_mult_expr (code, type, arg0, arg1);
|
||||
|
@ -13480,6 +13774,9 @@ tree_expr_nonnegative_warnv_p (tree t, bool *strict_overflow_p)
|
|||
case REAL_CST:
|
||||
return ! REAL_VALUE_NEGATIVE (TREE_REAL_CST (t));
|
||||
|
||||
case FIXED_CST:
|
||||
return ! FIXED_VALUE_NEGATIVE (TREE_FIXED_CST (t));
|
||||
|
||||
case POINTER_PLUS_EXPR:
|
||||
case PLUS_EXPR:
|
||||
if (FLOAT_TYPE_P (TREE_TYPE (t)))
|
||||
|
@ -14082,7 +14379,7 @@ fold_read_from_constant_string (tree exp)
|
|||
}
|
||||
|
||||
/* Return the tree for neg (ARG0) when ARG0 is known to be either
|
||||
an integer constant or real constant.
|
||||
an integer constant, real, or fixed-point constant.
|
||||
|
||||
TYPE is the type of the result. */
|
||||
|
||||
|
@ -14110,6 +14407,24 @@ fold_negate_const (tree arg0, tree type)
|
|||
t = build_real (type, REAL_VALUE_NEGATE (TREE_REAL_CST (arg0)));
|
||||
break;
|
||||
|
||||
case FIXED_CST:
|
||||
{
|
||||
FIXED_VALUE_TYPE f;
|
||||
bool overflow_p = fixed_arithmetic (&f, NEGATE_EXPR,
|
||||
&(TREE_FIXED_CST (arg0)), NULL,
|
||||
TYPE_SATURATING (type));
|
||||
t = build_fixed (type, f);
|
||||
/* Propagate overflow flags. */
|
||||
if (overflow_p | TREE_OVERFLOW (arg0))
|
||||
{
|
||||
TREE_OVERFLOW (t) = 1;
|
||||
TREE_CONSTANT_OVERFLOW (t) = 1;
|
||||
}
|
||||
else if (TREE_CONSTANT_OVERFLOW (arg0))
|
||||
TREE_CONSTANT_OVERFLOW (t) = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
@ -14240,6 +14555,13 @@ fold_relational_const (enum tree_code code, tree type, tree op0, tree op1)
|
|||
return constant_boolean_node (real_compare (code, c0, c1), type);
|
||||
}
|
||||
|
||||
if (TREE_CODE (op0) == FIXED_CST && TREE_CODE (op1) == FIXED_CST)
|
||||
{
|
||||
const FIXED_VALUE_TYPE *c0 = TREE_FIXED_CST_PTR (op0);
|
||||
const FIXED_VALUE_TYPE *c1 = TREE_FIXED_CST_PTR (op1);
|
||||
return constant_boolean_node (fixed_compare (code, c0, c1), type);
|
||||
}
|
||||
|
||||
/* Handle equality/inequality of complex constants. */
|
||||
if (TREE_CODE (op0) == COMPLEX_CST && TREE_CODE (op1) == COMPLEX_CST)
|
||||
{
|
||||
|
|
|
@ -4488,6 +4488,7 @@ omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
|
|||
case ENUMERAL_TYPE:
|
||||
case BOOLEAN_TYPE:
|
||||
case REAL_TYPE:
|
||||
case FIXED_POINT_TYPE:
|
||||
omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
|
||||
omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
|
||||
break;
|
||||
|
@ -5728,6 +5729,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
|
|||
/* Constants need not be gimplified. */
|
||||
case INTEGER_CST:
|
||||
case REAL_CST:
|
||||
case FIXED_CST:
|
||||
case STRING_CST:
|
||||
case COMPLEX_CST:
|
||||
case VECTOR_CST:
|
||||
|
@ -6271,6 +6273,7 @@ gimplify_type_sizes (tree type, tree *list_p)
|
|||
case ENUMERAL_TYPE:
|
||||
case BOOLEAN_TYPE:
|
||||
case REAL_TYPE:
|
||||
case FIXED_POINT_TYPE:
|
||||
gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
|
||||
gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
|
||||
|
||||
|
|
|
@ -481,7 +481,8 @@ ipa_callsite_compute_param (struct cgraph_edge *cs)
|
|||
we store CONST_IPATYPE and its value as the jump function
|
||||
of this argument. */
|
||||
else if (TREE_CODE (arg) == INTEGER_CST
|
||||
|| TREE_CODE (arg) == REAL_CST)
|
||||
|| TREE_CODE (arg) == REAL_CST
|
||||
|| TREE_CODE (arg) == FIXED_CST)
|
||||
{
|
||||
ipa_callsite_param_set_type (cs, arg_num, CONST_IPATYPE);
|
||||
ipa_callsite_param_set_info_type (cs, arg_num, arg);
|
||||
|
@ -495,7 +496,8 @@ ipa_callsite_compute_param (struct cgraph_edge *cs)
|
|||
{
|
||||
cst_decl = TREE_OPERAND (arg, 0);
|
||||
if (TREE_CODE (DECL_INITIAL (cst_decl)) == INTEGER_CST
|
||||
|| TREE_CODE (DECL_INITIAL (cst_decl)) == REAL_CST)
|
||||
|| TREE_CODE (DECL_INITIAL (cst_decl)) == REAL_CST
|
||||
|| TREE_CODE (DECL_INITIAL (cst_decl)) == FIXED_CST)
|
||||
{
|
||||
ipa_callsite_param_set_type (cs, arg_num,
|
||||
CONST_IPATYPE_REF);
|
||||
|
|
|
@ -274,6 +274,7 @@ type_to_consider (tree type)
|
|||
case INTEGER_TYPE:
|
||||
case QUAL_UNION_TYPE:
|
||||
case REAL_TYPE:
|
||||
case FIXED_POINT_TYPE:
|
||||
case RECORD_TYPE:
|
||||
case UNION_TYPE:
|
||||
case VECTOR_TYPE:
|
||||
|
|
|
@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "tm.h"
|
||||
#include "tree.h"
|
||||
#include "real.h"
|
||||
#include "fixed-value.h"
|
||||
#include "ggc.h"
|
||||
#include "langhooks.h"
|
||||
#include "tree-iterator.h"
|
||||
|
@ -147,6 +148,18 @@ print_node_brief (FILE *file, const char *prefix, const_tree node, int indent)
|
|||
fprintf (file, " %s", string);
|
||||
}
|
||||
}
|
||||
if (TREE_CODE (node) == FIXED_CST)
|
||||
{
|
||||
FIXED_VALUE_TYPE f;
|
||||
char string[60];
|
||||
|
||||
if (TREE_OVERFLOW (node))
|
||||
fprintf (file, " overflow");
|
||||
|
||||
f = TREE_FIXED_CST (node);
|
||||
fixed_to_decimal (string, &f, sizeof (string));
|
||||
fprintf (file, " %s", string);
|
||||
}
|
||||
|
||||
fprintf (file, ">");
|
||||
}
|
||||
|
@ -610,7 +623,8 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
|
|||
|
||||
print_node (file, "attributes", TYPE_ATTRIBUTES (node), indent + 4);
|
||||
|
||||
if (INTEGRAL_TYPE_P (node) || TREE_CODE (node) == REAL_TYPE)
|
||||
if (INTEGRAL_TYPE_P (node) || TREE_CODE (node) == REAL_TYPE
|
||||
|| TREE_CODE (node) == FIXED_POINT_TYPE)
|
||||
{
|
||||
fprintf (file, " precision %d", TYPE_PRECISION (node));
|
||||
print_node_brief (file, "min", TYPE_MIN_VALUE (node), indent + 4);
|
||||
|
@ -755,6 +769,20 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
|
|||
}
|
||||
break;
|
||||
|
||||
case FIXED_CST:
|
||||
{
|
||||
FIXED_VALUE_TYPE f;
|
||||
char string[64];
|
||||
|
||||
if (TREE_OVERFLOW (node))
|
||||
fprintf (file, " overflow");
|
||||
|
||||
f = TREE_FIXED_CST (node);
|
||||
fixed_to_decimal (string, &f, sizeof (string));
|
||||
fprintf (file, " %s", string);
|
||||
}
|
||||
break;
|
||||
|
||||
case VECTOR_CST:
|
||||
{
|
||||
tree vals = TREE_VECTOR_CST_ELTS (node);
|
||||
|
|
|
@ -236,6 +236,14 @@ int_mode_for_mode (enum machine_mode mode)
|
|||
case MODE_DECIMAL_FLOAT:
|
||||
case MODE_VECTOR_INT:
|
||||
case MODE_VECTOR_FLOAT:
|
||||
case MODE_FRACT:
|
||||
case MODE_ACCUM:
|
||||
case MODE_UFRACT:
|
||||
case MODE_UACCUM:
|
||||
case MODE_VECTOR_FRACT:
|
||||
case MODE_VECTOR_ACCUM:
|
||||
case MODE_VECTOR_UFRACT:
|
||||
case MODE_VECTOR_UACCUM:
|
||||
mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0);
|
||||
break;
|
||||
|
||||
|
@ -1602,6 +1610,12 @@ layout_type (tree type)
|
|||
TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
|
||||
break;
|
||||
|
||||
case FIXED_POINT_TYPE:
|
||||
/* TYPE_MODE (type) has been set already. */
|
||||
TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
|
||||
TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
|
||||
break;
|
||||
|
||||
case COMPLEX_TYPE:
|
||||
TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type));
|
||||
TYPE_MODE (type)
|
||||
|
@ -1629,6 +1643,14 @@ layout_type (tree type)
|
|||
/* First, look for a supported vector type. */
|
||||
if (SCALAR_FLOAT_MODE_P (innermode))
|
||||
mode = MIN_MODE_VECTOR_FLOAT;
|
||||
else if (SCALAR_FRACT_MODE_P (innermode))
|
||||
mode = MIN_MODE_VECTOR_FRACT;
|
||||
else if (SCALAR_UFRACT_MODE_P (innermode))
|
||||
mode = MIN_MODE_VECTOR_UFRACT;
|
||||
else if (SCALAR_ACCUM_MODE_P (innermode))
|
||||
mode = MIN_MODE_VECTOR_ACCUM;
|
||||
else if (SCALAR_UACCUM_MODE_P (innermode))
|
||||
mode = MIN_MODE_VECTOR_UACCUM;
|
||||
else
|
||||
mode = MIN_MODE_VECTOR_INT;
|
||||
|
||||
|
@ -1650,6 +1672,7 @@ layout_type (tree type)
|
|||
TYPE_MODE (type) = mode;
|
||||
}
|
||||
|
||||
TYPE_SATURATING (type) = TYPE_SATURATING (TREE_TYPE (type));
|
||||
TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type));
|
||||
TYPE_SIZE_UNIT (type) = int_const_binop (MULT_EXPR,
|
||||
TYPE_SIZE_UNIT (innertype),
|
||||
|
@ -1905,6 +1928,58 @@ make_unsigned_type (int precision)
|
|||
return type;
|
||||
}
|
||||
|
||||
/* Create and return a type for fract of PRECISION bits, UNSIGNEDP,
|
||||
and SATP. */
|
||||
|
||||
tree
|
||||
make_fract_type (int precision, int unsignedp, int satp)
|
||||
{
|
||||
tree type = make_node (FIXED_POINT_TYPE);
|
||||
|
||||
TYPE_PRECISION (type) = precision;
|
||||
|
||||
if (satp)
|
||||
TYPE_SATURATING (type) = 1;
|
||||
|
||||
/* Lay out the type: set its alignment, size, etc. */
|
||||
if (unsignedp)
|
||||
{
|
||||
TYPE_UNSIGNED (type) = 1;
|
||||
TYPE_MODE (type) = mode_for_size (precision, MODE_UFRACT, 0);
|
||||
}
|
||||
else
|
||||
TYPE_MODE (type) = mode_for_size (precision, MODE_FRACT, 0);
|
||||
layout_type (type);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/* Create and return a type for accum of PRECISION bits, UNSIGNEDP,
|
||||
and SATP. */
|
||||
|
||||
tree
|
||||
make_accum_type (int precision, int unsignedp, int satp)
|
||||
{
|
||||
tree type = make_node (FIXED_POINT_TYPE);
|
||||
|
||||
TYPE_PRECISION (type) = precision;
|
||||
|
||||
if (satp)
|
||||
TYPE_SATURATING (type) = 1;
|
||||
|
||||
/* Lay out the type: set its alignment, size, etc. */
|
||||
if (unsignedp)
|
||||
{
|
||||
TYPE_UNSIGNED (type) = 1;
|
||||
TYPE_MODE (type) = mode_for_size (precision, MODE_UACCUM, 0);
|
||||
}
|
||||
else
|
||||
TYPE_MODE (type) = mode_for_size (precision, MODE_ACCUM, 0);
|
||||
layout_type (type);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/* Initialize sizetype and bitsizetype to a reasonable and temporary
|
||||
value to enable integer types to be created. */
|
||||
|
||||
|
|
|
@ -162,7 +162,8 @@ browse_tree (tree begin)
|
|||
|
||||
case TB_MAX:
|
||||
if (head && (INTEGRAL_TYPE_P (head)
|
||||
|| TREE_CODE (head) == REAL_TYPE))
|
||||
|| TREE_CODE (head) == REAL_TYPE
|
||||
|| TREE_CODE (head) == FIXED_POINT_TYPE))
|
||||
TB_SET_HEAD (TYPE_MAX_VALUE (head));
|
||||
else
|
||||
TB_WF;
|
||||
|
@ -170,7 +171,8 @@ browse_tree (tree begin)
|
|||
|
||||
case TB_MIN:
|
||||
if (head && (INTEGRAL_TYPE_P (head)
|
||||
|| TREE_CODE (head) == REAL_TYPE))
|
||||
|| TREE_CODE (head) == REAL_TYPE
|
||||
|| TREE_CODE (head) == FIXED_POINT_TYPE))
|
||||
TB_SET_HEAD (TYPE_MIN_VALUE (head));
|
||||
else
|
||||
TB_WF;
|
||||
|
|
|
@ -96,6 +96,8 @@ some_nonzerop (tree t)
|
|||
|
||||
if (TREE_CODE (t) == REAL_CST)
|
||||
zerop = REAL_VALUES_IDENTICAL (TREE_REAL_CST (t), dconst0);
|
||||
else if (TREE_CODE (t) == FIXED_CST)
|
||||
zerop = fixed_zerop (t);
|
||||
else if (TREE_CODE (t) == INTEGER_CST)
|
||||
zerop = integer_zerop (t);
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "langhooks.h"
|
||||
#include "tree-iterator.h"
|
||||
#include "real.h"
|
||||
#include "fixed-value.h"
|
||||
|
||||
static unsigned int queue (dump_info_p, tree, int);
|
||||
static void dump_index (dump_info_p, unsigned int);
|
||||
|
@ -191,6 +192,18 @@ dump_real (dump_info_p di, const char *field, const REAL_VALUE_TYPE *r)
|
|||
di->column += strlen (buf) + 7;
|
||||
}
|
||||
|
||||
/* Dump the fixed-point value F, using FIELD to identify it. */
|
||||
|
||||
static void
|
||||
dump_fixed (dump_info_p di, const char *field, const FIXED_VALUE_TYPE *f)
|
||||
{
|
||||
char buf[32];
|
||||
fixed_to_decimal (buf, f, sizeof (buf));
|
||||
dump_maybe_newline (di);
|
||||
fprintf (di->stream, "%-4s: %s ", field, buf);
|
||||
di->column += strlen (buf) + 7;
|
||||
}
|
||||
|
||||
|
||||
/* Dump the string S. */
|
||||
|
||||
|
@ -453,6 +466,13 @@ dequeue_and_dump (dump_info_p di)
|
|||
dump_int (di, "prec", TYPE_PRECISION (t));
|
||||
break;
|
||||
|
||||
case FIXED_POINT_TYPE:
|
||||
dump_int (di, "prec", TYPE_PRECISION (t));
|
||||
dump_string_field (di, "sign", TYPE_UNSIGNED (t) ? "unsigned": "signed");
|
||||
dump_string_field (di, "saturating",
|
||||
TYPE_SATURATING (t) ? "saturating": "non-saturating");
|
||||
break;
|
||||
|
||||
case POINTER_TYPE:
|
||||
dump_child ("ptd", TREE_TYPE (t));
|
||||
break;
|
||||
|
@ -549,6 +569,10 @@ dequeue_and_dump (dump_info_p di)
|
|||
dump_real (di, "valu", TREE_REAL_CST_PTR (t));
|
||||
break;
|
||||
|
||||
case FIXED_CST:
|
||||
dump_fixed (di, "valu", TREE_FIXED_CST_PTR (t));
|
||||
break;
|
||||
|
||||
case TRUTH_NOT_EXPR:
|
||||
case ADDR_EXPR:
|
||||
case INDIRECT_REF:
|
||||
|
|
|
@ -67,6 +67,7 @@ is_gimple_formal_tmp_rhs (tree t)
|
|||
case COMPLEX_EXPR:
|
||||
case INTEGER_CST:
|
||||
case REAL_CST:
|
||||
case FIXED_CST:
|
||||
case STRING_CST:
|
||||
case COMPLEX_CST:
|
||||
case VECTOR_CST:
|
||||
|
@ -178,6 +179,7 @@ is_gimple_min_invariant (const_tree t)
|
|||
|
||||
case INTEGER_CST:
|
||||
case REAL_CST:
|
||||
case FIXED_CST:
|
||||
case STRING_CST:
|
||||
case COMPLEX_CST:
|
||||
case VECTOR_CST:
|
||||
|
|
|
@ -340,6 +340,7 @@ remap_type_1 (tree type, copy_body_data *id)
|
|||
{
|
||||
case INTEGER_TYPE:
|
||||
case REAL_TYPE:
|
||||
case FIXED_POINT_TYPE:
|
||||
case ENUMERAL_TYPE:
|
||||
case BOOLEAN_TYPE:
|
||||
t = TYPE_MIN_VALUE (new);
|
||||
|
@ -2020,6 +2021,7 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
|
|||
case IDENTIFIER_NODE:
|
||||
case INTEGER_CST:
|
||||
case REAL_CST:
|
||||
case FIXED_CST:
|
||||
case COMPLEX_CST:
|
||||
case VECTOR_CST:
|
||||
case STRING_CST:
|
||||
|
@ -2085,6 +2087,7 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
|
|||
case MINUS_EXPR:
|
||||
case MULT_EXPR:
|
||||
|
||||
case FIXED_CONVERT_EXPR:
|
||||
case FIX_TRUNC_EXPR:
|
||||
|
||||
case NEGATE_EXPR:
|
||||
|
|
|
@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "tree-iterator.h"
|
||||
#include "tree-chrec.h"
|
||||
#include "tree-pass.h"
|
||||
#include "fixed-value.h"
|
||||
#include "value-prof.h"
|
||||
|
||||
/* Local functions, macros and variables. */
|
||||
|
@ -527,6 +528,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
|
|||
case VOID_TYPE:
|
||||
case INTEGER_TYPE:
|
||||
case REAL_TYPE:
|
||||
case FIXED_POINT_TYPE:
|
||||
case COMPLEX_TYPE:
|
||||
case VECTOR_TYPE:
|
||||
case ENUMERAL_TYPE:
|
||||
|
@ -804,6 +806,14 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
|
|||
break;
|
||||
}
|
||||
|
||||
case FIXED_CST:
|
||||
{
|
||||
char string[100];
|
||||
fixed_to_decimal (string, TREE_FIXED_CST_PTR (node), sizeof (string));
|
||||
pp_string (buffer, string);
|
||||
break;
|
||||
}
|
||||
|
||||
case COMPLEX_CST:
|
||||
pp_string (buffer, "__complex__ (");
|
||||
dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
|
||||
|
@ -1378,6 +1388,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
|
|||
NIY;
|
||||
break;
|
||||
|
||||
case FIXED_CONVERT_EXPR:
|
||||
case FIX_TRUNC_EXPR:
|
||||
case FLOAT_EXPR:
|
||||
case CONVERT_EXPR:
|
||||
|
|
|
@ -600,6 +600,7 @@ get_scalar_evolution (tree scalar)
|
|||
break;
|
||||
|
||||
case REAL_CST:
|
||||
case FIXED_CST:
|
||||
case INTEGER_CST:
|
||||
res = scalar;
|
||||
break;
|
||||
|
|
|
@ -220,6 +220,7 @@ is_sra_scalar_type (tree type)
|
|||
{
|
||||
enum tree_code code = TREE_CODE (type);
|
||||
return (code == INTEGER_TYPE || code == REAL_TYPE || code == VECTOR_TYPE
|
||||
|| code == FIXED_POINT_TYPE
|
||||
|| code == ENUMERAL_TYPE || code == BOOLEAN_TYPE
|
||||
|| code == POINTER_TYPE || code == OFFSET_TYPE
|
||||
|| code == REFERENCE_TYPE);
|
||||
|
|
|
@ -204,6 +204,7 @@ for_each_index (tree *addr_p, bool (*cbck) (tree, tree *, void *), void *data)
|
|||
case COMPLEX_CST:
|
||||
case INTEGER_CST:
|
||||
case REAL_CST:
|
||||
case FIXED_CST:
|
||||
return true;
|
||||
|
||||
case TARGET_MEM_REF:
|
||||
|
|
|
@ -3081,6 +3081,7 @@ poolify_tree (tree node)
|
|||
case INTEGER_CST:
|
||||
case STRING_CST:
|
||||
case REAL_CST:
|
||||
case FIXED_CST:
|
||||
case PARM_DECL:
|
||||
case VAR_DECL:
|
||||
case RESULT_DECL:
|
||||
|
|
|
@ -1245,12 +1245,15 @@ break_up_subtract_bb (basic_block bb)
|
|||
|
||||
TREE_VISITED (stmt) = 0;
|
||||
/* If unsafe math optimizations we can do reassociation for
|
||||
non-integral types. */
|
||||
non-integral types. Or, we can do reassociation for
|
||||
non-saturating fixed-point types. */
|
||||
if ((!INTEGRAL_TYPE_P (TREE_TYPE (lhs))
|
||||
|| !INTEGRAL_TYPE_P (TREE_TYPE (rhs)))
|
||||
&& (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs))
|
||||
|| !SCALAR_FLOAT_TYPE_P (TREE_TYPE(lhs))
|
||||
|| !flag_unsafe_math_optimizations))
|
||||
|| !flag_unsafe_math_optimizations)
|
||||
&& (!NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE (rhs))
|
||||
|| !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(lhs))))
|
||||
continue;
|
||||
|
||||
/* Check for a subtract used only in an addition. If this
|
||||
|
@ -1292,12 +1295,15 @@ reassociate_bb (basic_block bb)
|
|||
continue;
|
||||
|
||||
/* If unsafe math optimizations we can do reassociation for
|
||||
non-integral types. */
|
||||
non-integral types. Or, we can do reassociation for
|
||||
non-saturating fixed-point types. */
|
||||
if ((!INTEGRAL_TYPE_P (TREE_TYPE (lhs))
|
||||
|| !INTEGRAL_TYPE_P (TREE_TYPE (rhs)))
|
||||
&& (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs))
|
||||
|| !SCALAR_FLOAT_TYPE_P (TREE_TYPE(lhs))
|
||||
|| !flag_unsafe_math_optimizations))
|
||||
|| !flag_unsafe_math_optimizations)
|
||||
&& (!NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE (rhs))
|
||||
|| !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(lhs))))
|
||||
continue;
|
||||
|
||||
if (associative_tree_code (TREE_CODE (rhs)))
|
||||
|
|
|
@ -295,7 +295,11 @@ expand_vector_operation (block_stmt_iterator *bsi, tree type, tree compute_type,
|
|||
a BLKmode vector to smaller, hardware-supported vectors), we may want
|
||||
to expand the operations in parallel. */
|
||||
if (GET_MODE_CLASS (compute_mode) != MODE_VECTOR_INT
|
||||
&& GET_MODE_CLASS (compute_mode) != MODE_VECTOR_FLOAT)
|
||||
&& GET_MODE_CLASS (compute_mode) != MODE_VECTOR_FLOAT
|
||||
&& GET_MODE_CLASS (compute_mode) != MODE_VECTOR_FRACT
|
||||
&& GET_MODE_CLASS (compute_mode) != MODE_VECTOR_UFRACT
|
||||
&& GET_MODE_CLASS (compute_mode) != MODE_VECTOR_ACCUM
|
||||
&& GET_MODE_CLASS (compute_mode) != MODE_VECTOR_UACCUM)
|
||||
switch (code)
|
||||
{
|
||||
case PLUS_EXPR:
|
||||
|
@ -340,15 +344,25 @@ expand_vector_operation (block_stmt_iterator *bsi, tree type, tree compute_type,
|
|||
}
|
||||
|
||||
/* Return a type for the widest vector mode whose components are of mode
|
||||
INNER_MODE, or NULL_TREE if none is found. */
|
||||
INNER_MODE, or NULL_TREE if none is found.
|
||||
SATP is true for saturating fixed-point types. */
|
||||
|
||||
static tree
|
||||
type_for_widest_vector_mode (enum machine_mode inner_mode, optab op)
|
||||
type_for_widest_vector_mode (enum machine_mode inner_mode, optab op, int satp)
|
||||
{
|
||||
enum machine_mode best_mode = VOIDmode, mode;
|
||||
int best_nunits = 0;
|
||||
|
||||
if (SCALAR_FLOAT_MODE_P (inner_mode))
|
||||
mode = MIN_MODE_VECTOR_FLOAT;
|
||||
else if (SCALAR_FRACT_MODE_P (inner_mode))
|
||||
mode = MIN_MODE_VECTOR_FRACT;
|
||||
else if (SCALAR_UFRACT_MODE_P (inner_mode))
|
||||
mode = MIN_MODE_VECTOR_UFRACT;
|
||||
else if (SCALAR_ACCUM_MODE_P (inner_mode))
|
||||
mode = MIN_MODE_VECTOR_ACCUM;
|
||||
else if (SCALAR_UACCUM_MODE_P (inner_mode))
|
||||
mode = MIN_MODE_VECTOR_UACCUM;
|
||||
else
|
||||
mode = MIN_MODE_VECTOR_INT;
|
||||
|
||||
|
@ -361,7 +375,13 @@ type_for_widest_vector_mode (enum machine_mode inner_mode, optab op)
|
|||
if (best_mode == VOIDmode)
|
||||
return NULL_TREE;
|
||||
else
|
||||
return lang_hooks.types.type_for_mode (best_mode, 1);
|
||||
{
|
||||
/* For fixed-point modes, we need to pass satp as the 2nd parameter. */
|
||||
if (ALL_FIXED_POINT_MODE_P (best_mode))
|
||||
return lang_hooks.types.type_for_mode (best_mode, satp);
|
||||
|
||||
return lang_hooks.types.type_for_mode (best_mode, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Process one statement. If we identify a vector operation, expand it. */
|
||||
|
@ -445,7 +465,8 @@ expand_vector_operations_1 (block_stmt_iterator *bsi)
|
|||
if (TYPE_MODE (type) == BLKmode && op)
|
||||
{
|
||||
tree vector_compute_type
|
||||
= type_for_widest_vector_mode (TYPE_MODE (TREE_TYPE (type)), op);
|
||||
= type_for_widest_vector_mode (TYPE_MODE (TREE_TYPE (type)), op,
|
||||
TYPE_SATURATING (TREE_TYPE (type)));
|
||||
if (vector_compute_type != NULL_TREE)
|
||||
compute_type = vector_compute_type;
|
||||
}
|
||||
|
@ -457,7 +478,11 @@ expand_vector_operations_1 (block_stmt_iterator *bsi)
|
|||
{
|
||||
compute_mode = TYPE_MODE (compute_type);
|
||||
if ((GET_MODE_CLASS (compute_mode) == MODE_VECTOR_INT
|
||||
|| GET_MODE_CLASS (compute_mode) == MODE_VECTOR_FLOAT)
|
||||
|| GET_MODE_CLASS (compute_mode) == MODE_VECTOR_FLOAT
|
||||
|| GET_MODE_CLASS (compute_mode) == MODE_VECTOR_FRACT
|
||||
|| GET_MODE_CLASS (compute_mode) == MODE_VECTOR_UFRACT
|
||||
|| GET_MODE_CLASS (compute_mode) == MODE_VECTOR_ACCUM
|
||||
|| GET_MODE_CLASS (compute_mode) == MODE_VECTOR_UACCUM)
|
||||
&& op != NULL
|
||||
&& op->handlers[compute_mode].insn_code != CODE_FOR_nothing)
|
||||
return;
|
||||
|
|
|
@ -4913,7 +4913,8 @@ vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo)
|
|||
if (!vect_is_simple_use (lhs, loop_vinfo, &lhs_def_stmt, &def, &dt))
|
||||
return false;
|
||||
}
|
||||
else if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (lhs) != REAL_CST)
|
||||
else if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (lhs) != REAL_CST
|
||||
&& TREE_CODE (lhs) != FIXED_CST)
|
||||
return false;
|
||||
|
||||
if (TREE_CODE (rhs) == SSA_NAME)
|
||||
|
@ -4922,7 +4923,8 @@ vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo)
|
|||
if (!vect_is_simple_use (rhs, loop_vinfo, &rhs_def_stmt, &def, &dt))
|
||||
return false;
|
||||
}
|
||||
else if (TREE_CODE (rhs) != INTEGER_CST && TREE_CODE (rhs) != REAL_CST)
|
||||
else if (TREE_CODE (rhs) != INTEGER_CST && TREE_CODE (rhs) != REAL_CST
|
||||
&& TREE_CODE (rhs) != FIXED_CST)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -5003,7 +5005,8 @@ vectorizable_condition (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
|
|||
return false;
|
||||
}
|
||||
else if (TREE_CODE (then_clause) != INTEGER_CST
|
||||
&& TREE_CODE (then_clause) != REAL_CST)
|
||||
&& TREE_CODE (then_clause) != REAL_CST
|
||||
&& TREE_CODE (then_clause) != FIXED_CST)
|
||||
return false;
|
||||
|
||||
if (TREE_CODE (else_clause) == SSA_NAME)
|
||||
|
@ -5014,7 +5017,8 @@ vectorizable_condition (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
|
|||
return false;
|
||||
}
|
||||
else if (TREE_CODE (else_clause) != INTEGER_CST
|
||||
&& TREE_CODE (else_clause) != REAL_CST)
|
||||
&& TREE_CODE (else_clause) != REAL_CST
|
||||
&& TREE_CODE (else_clause) != FIXED_CST)
|
||||
return false;
|
||||
|
||||
|
||||
|
|
|
@ -2150,6 +2150,16 @@ vect_is_simple_reduction (struct loop *loop, tree phi)
|
|||
}
|
||||
return NULL_TREE;
|
||||
}
|
||||
else if (SAT_FIXED_POINT_TYPE_P (type))
|
||||
{
|
||||
/* Changing the order of operations changes the semantics. */
|
||||
if (vect_print_dump_info (REPORT_DETAILS))
|
||||
{
|
||||
fprintf (vect_dump, "reduction: unsafe fixed-point math optimization: ");
|
||||
print_generic_expr (vect_dump, operation, TDF_SLIM);
|
||||
}
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* reduction is safe. we're dealing with one of the following:
|
||||
1) integer arithmetic and no trapv
|
||||
|
|
177
gcc/tree.c
177
gcc/tree.c
|
@ -50,6 +50,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "tree-flow.h"
|
||||
#include "params.h"
|
||||
#include "pointer-set.h"
|
||||
#include "fixed-value.h"
|
||||
|
||||
/* Each tree code class has an associated string representation.
|
||||
These must correspond to the tree_code_class entries. */
|
||||
|
@ -399,6 +400,7 @@ tree_code_size (enum tree_code code)
|
|||
{
|
||||
case INTEGER_CST: return sizeof (struct tree_int_cst);
|
||||
case REAL_CST: return sizeof (struct tree_real_cst);
|
||||
case FIXED_CST: return sizeof (struct tree_fixed_cst);
|
||||
case COMPLEX_CST: return sizeof (struct tree_complex);
|
||||
case VECTOR_CST: return sizeof (struct tree_vector);
|
||||
case STRING_CST: gcc_unreachable ();
|
||||
|
@ -1095,6 +1097,22 @@ build_constructor_from_list (tree type, tree vals)
|
|||
return t;
|
||||
}
|
||||
|
||||
/* Return a new FIXED_CST node whose type is TYPE and value is F. */
|
||||
|
||||
tree
|
||||
build_fixed (tree type, FIXED_VALUE_TYPE f)
|
||||
{
|
||||
tree v;
|
||||
FIXED_VALUE_TYPE *fp;
|
||||
|
||||
v = make_node (FIXED_CST);
|
||||
fp = ggc_alloc (sizeof (FIXED_VALUE_TYPE));
|
||||
memcpy (fp, &f, sizeof (FIXED_VALUE_TYPE));
|
||||
|
||||
TREE_TYPE (v) = type;
|
||||
TREE_FIXED_CST_PTR (v) = fp;
|
||||
return v;
|
||||
}
|
||||
|
||||
/* Return a new REAL_CST node whose type is TYPE and value is D. */
|
||||
|
||||
|
@ -1215,6 +1233,11 @@ build_one_cst (tree type)
|
|||
case REAL_TYPE:
|
||||
return build_real (type, dconst1);
|
||||
|
||||
case FIXED_POINT_TYPE:
|
||||
/* We can only generate 1 for accum types. */
|
||||
gcc_assert (ALL_SCALAR_ACCUM_MODE_P (TYPE_MODE (type)));
|
||||
return build_fixed (type, FCONST1(TYPE_MODE (type)));
|
||||
|
||||
case VECTOR_TYPE:
|
||||
{
|
||||
tree scalar, cst;
|
||||
|
@ -1434,6 +1457,15 @@ integer_nonzerop (const_tree expr)
|
|||
|| integer_nonzerop (TREE_IMAGPART (expr)))));
|
||||
}
|
||||
|
||||
/* Return 1 if EXPR is the fixed-point constant zero. */
|
||||
|
||||
int
|
||||
fixed_zerop (tree expr)
|
||||
{
|
||||
return (TREE_CODE (expr) == FIXED_CST
|
||||
&& double_int_zero_p (TREE_FIXED_CST (expr).data));
|
||||
}
|
||||
|
||||
/* Return the power of two represented by a tree node known to be a
|
||||
power of two. */
|
||||
|
||||
|
@ -2184,6 +2216,7 @@ tree_node_structure (const_tree t)
|
|||
/* tcc_constant cases. */
|
||||
case INTEGER_CST: return TS_INT_CST;
|
||||
case REAL_CST: return TS_REAL_CST;
|
||||
case FIXED_CST: return TS_FIXED_CST;
|
||||
case COMPLEX_CST: return TS_COMPLEX;
|
||||
case VECTOR_CST: return TS_VECTOR;
|
||||
case STRING_CST: return TS_STRING;
|
||||
|
@ -2324,6 +2357,7 @@ type_contains_placeholder_1 (const_tree type)
|
|||
|
||||
case INTEGER_TYPE:
|
||||
case REAL_TYPE:
|
||||
case FIXED_POINT_TYPE:
|
||||
/* Here we just check the bounds. */
|
||||
return (CONTAINS_PLACEHOLDER_P (TYPE_MIN_VALUE (type))
|
||||
|| CONTAINS_PLACEHOLDER_P (TYPE_MAX_VALUE (type)));
|
||||
|
@ -3677,6 +3711,7 @@ build_type_attribute_qual_variant (tree ttype, tree attribute, int quals)
|
|||
(TREE_INT_CST_HIGH (TYPE_MAX_VALUE (ntype)), hashcode);
|
||||
break;
|
||||
case REAL_TYPE:
|
||||
case FIXED_POINT_TYPE:
|
||||
{
|
||||
unsigned int precision = TYPE_PRECISION (ntype);
|
||||
hashcode = iterative_hash_object (precision, hashcode);
|
||||
|
@ -4551,6 +4586,9 @@ type_hash_eq (const void *va, const void *vb)
|
|||
|| tree_int_cst_equal (TYPE_MIN_VALUE (a->type),
|
||||
TYPE_MIN_VALUE (b->type))));
|
||||
|
||||
case FIXED_POINT_TYPE:
|
||||
return TYPE_SATURATING (a->type) == TYPE_SATURATING (b->type);
|
||||
|
||||
case OFFSET_TYPE:
|
||||
return TYPE_OFFSET_BASETYPE (a->type) == TYPE_OFFSET_BASETYPE (b->type);
|
||||
|
||||
|
@ -5011,6 +5049,9 @@ simple_cst_equal (const_tree t1, const_tree t2)
|
|||
case REAL_CST:
|
||||
return REAL_VALUES_IDENTICAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2));
|
||||
|
||||
case FIXED_CST:
|
||||
return FIXED_VALUES_IDENTICAL (TREE_FIXED_CST (t1), TREE_FIXED_CST (t2));
|
||||
|
||||
case STRING_CST:
|
||||
return (TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2)
|
||||
&& ! memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
|
||||
|
@ -5232,6 +5273,12 @@ iterative_hash_expr (const_tree t, hashval_t val)
|
|||
{
|
||||
unsigned int val2 = real_hash (TREE_REAL_CST_PTR (t));
|
||||
|
||||
return iterative_hash_hashval_t (val2, val);
|
||||
}
|
||||
case FIXED_CST:
|
||||
{
|
||||
unsigned int val2 = fixed_hash (TREE_FIXED_CST_PTR (t));
|
||||
|
||||
return iterative_hash_hashval_t (val2, val);
|
||||
}
|
||||
case STRING_CST:
|
||||
|
@ -6064,6 +6111,7 @@ get_unwidened (tree op, tree for_type)
|
|||
if (TREE_CODE (op) == COMPONENT_REF
|
||||
/* Since type_for_size always gives an integer type. */
|
||||
&& TREE_CODE (type) != REAL_TYPE
|
||||
&& TREE_CODE (type) != FIXED_POINT_TYPE
|
||||
/* Don't crash if field not laid out yet. */
|
||||
&& DECL_SIZE (TREE_OPERAND (op, 1)) != 0
|
||||
&& host_integerp (DECL_SIZE (TREE_OPERAND (op, 1)), 1))
|
||||
|
@ -6155,6 +6203,7 @@ get_narrower (tree op, int *unsignedp_ptr)
|
|||
if (TREE_CODE (op) == COMPONENT_REF
|
||||
/* Since type_for_size always gives an integer type. */
|
||||
&& TREE_CODE (TREE_TYPE (op)) != REAL_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (op)) != FIXED_POINT_TYPE
|
||||
/* Ensure field is laid out already. */
|
||||
&& DECL_SIZE (TREE_OPERAND (op, 1)) != 0
|
||||
&& host_integerp (DECL_SIZE (TREE_OPERAND (op, 1)), 1))
|
||||
|
@ -6378,6 +6427,7 @@ variably_modified_type_p (tree type, tree fn)
|
|||
|
||||
case INTEGER_TYPE:
|
||||
case REAL_TYPE:
|
||||
case FIXED_POINT_TYPE:
|
||||
case ENUMERAL_TYPE:
|
||||
case BOOLEAN_TYPE:
|
||||
/* Scalar types are variably modified if their end points
|
||||
|
@ -7048,6 +7098,80 @@ make_or_reuse_type (unsigned size, int unsignedp)
|
|||
return make_signed_type (size);
|
||||
}
|
||||
|
||||
/* Create or reuse a fract type by SIZE, UNSIGNEDP, and SATP. */
|
||||
|
||||
static tree
|
||||
make_or_reuse_fract_type (unsigned size, int unsignedp, int satp)
|
||||
{
|
||||
if (satp)
|
||||
{
|
||||
if (size == SHORT_FRACT_TYPE_SIZE)
|
||||
return unsignedp ? sat_unsigned_short_fract_type_node
|
||||
: sat_short_fract_type_node;
|
||||
if (size == FRACT_TYPE_SIZE)
|
||||
return unsignedp ? sat_unsigned_fract_type_node : sat_fract_type_node;
|
||||
if (size == LONG_FRACT_TYPE_SIZE)
|
||||
return unsignedp ? sat_unsigned_long_fract_type_node
|
||||
: sat_long_fract_type_node;
|
||||
if (size == LONG_LONG_FRACT_TYPE_SIZE)
|
||||
return unsignedp ? sat_unsigned_long_long_fract_type_node
|
||||
: sat_long_long_fract_type_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (size == SHORT_FRACT_TYPE_SIZE)
|
||||
return unsignedp ? unsigned_short_fract_type_node
|
||||
: short_fract_type_node;
|
||||
if (size == FRACT_TYPE_SIZE)
|
||||
return unsignedp ? unsigned_fract_type_node : fract_type_node;
|
||||
if (size == LONG_FRACT_TYPE_SIZE)
|
||||
return unsignedp ? unsigned_long_fract_type_node
|
||||
: long_fract_type_node;
|
||||
if (size == LONG_LONG_FRACT_TYPE_SIZE)
|
||||
return unsignedp ? unsigned_long_long_fract_type_node
|
||||
: long_long_fract_type_node;
|
||||
}
|
||||
|
||||
return make_fract_type (size, unsignedp, satp);
|
||||
}
|
||||
|
||||
/* Create or reuse an accum type by SIZE, UNSIGNEDP, and SATP. */
|
||||
|
||||
static tree
|
||||
make_or_reuse_accum_type (unsigned size, int unsignedp, int satp)
|
||||
{
|
||||
if (satp)
|
||||
{
|
||||
if (size == SHORT_ACCUM_TYPE_SIZE)
|
||||
return unsignedp ? sat_unsigned_short_accum_type_node
|
||||
: sat_short_accum_type_node;
|
||||
if (size == ACCUM_TYPE_SIZE)
|
||||
return unsignedp ? sat_unsigned_accum_type_node : sat_accum_type_node;
|
||||
if (size == LONG_ACCUM_TYPE_SIZE)
|
||||
return unsignedp ? sat_unsigned_long_accum_type_node
|
||||
: sat_long_accum_type_node;
|
||||
if (size == LONG_LONG_ACCUM_TYPE_SIZE)
|
||||
return unsignedp ? sat_unsigned_long_long_accum_type_node
|
||||
: sat_long_long_accum_type_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (size == SHORT_ACCUM_TYPE_SIZE)
|
||||
return unsignedp ? unsigned_short_accum_type_node
|
||||
: short_accum_type_node;
|
||||
if (size == ACCUM_TYPE_SIZE)
|
||||
return unsignedp ? unsigned_accum_type_node : accum_type_node;
|
||||
if (size == LONG_ACCUM_TYPE_SIZE)
|
||||
return unsignedp ? unsigned_long_accum_type_node
|
||||
: long_accum_type_node;
|
||||
if (size == LONG_LONG_ACCUM_TYPE_SIZE)
|
||||
return unsignedp ? unsigned_long_long_accum_type_node
|
||||
: long_long_accum_type_node;
|
||||
}
|
||||
|
||||
return make_accum_type (size, unsignedp, satp);
|
||||
}
|
||||
|
||||
/* Create nodes for all integer types (and error_mark_node) using the sizes
|
||||
of C datatypes. The caller should call set_sizetype soon after calling
|
||||
this function to select one of the types as sizetype. */
|
||||
|
@ -7195,6 +7319,50 @@ build_common_tree_nodes_2 (int short_double)
|
|||
complex_double_type_node = build_complex_type (double_type_node);
|
||||
complex_long_double_type_node = build_complex_type (long_double_type_node);
|
||||
|
||||
/* Make fixed-point nodes based on sat/non-sat and signed/unsigned. */
|
||||
#define MAKE_FIXED_TYPE_NODE(KIND,WIDTH,SIZE) \
|
||||
sat_ ## WIDTH ## KIND ## _type_node = \
|
||||
make_sat_signed_ ## KIND ## _type (SIZE); \
|
||||
sat_unsigned_ ## WIDTH ## KIND ## _type_node = \
|
||||
make_sat_unsigned_ ## KIND ## _type (SIZE); \
|
||||
WIDTH ## KIND ## _type_node = make_signed_ ## KIND ## _type (SIZE); \
|
||||
unsigned_ ## WIDTH ## KIND ## _type_node = \
|
||||
make_unsigned_ ## KIND ## _type (SIZE);
|
||||
|
||||
/* Make fixed-point type nodes based on four different widths. */
|
||||
#define MAKE_FIXED_TYPE_NODE_FAMILY(N1,N2) \
|
||||
MAKE_FIXED_TYPE_NODE (N1, short_, SHORT_ ## N2 ## _TYPE_SIZE) \
|
||||
MAKE_FIXED_TYPE_NODE (N1, , N2 ## _TYPE_SIZE) \
|
||||
MAKE_FIXED_TYPE_NODE (N1, long_, LONG_ ## N2 ## _TYPE_SIZE) \
|
||||
MAKE_FIXED_TYPE_NODE (N1, long_long_, LONG_LONG_ ## N2 ## _TYPE_SIZE)
|
||||
|
||||
/* Make fixed-point mode nodes based on sat/non-sat and signed/unsigned. */
|
||||
#define MAKE_FIXED_MODE_NODE(KIND,NAME,MODE) \
|
||||
NAME ## _type_node = \
|
||||
make_or_reuse_signed_ ## KIND ## _type (GET_MODE_BITSIZE (MODE ## mode)); \
|
||||
u ## NAME ## _type_node = \
|
||||
make_or_reuse_unsigned_ ## KIND ## _type \
|
||||
(GET_MODE_BITSIZE (U ## MODE ## mode)); \
|
||||
sat_ ## NAME ## _type_node = \
|
||||
make_or_reuse_sat_signed_ ## KIND ## _type \
|
||||
(GET_MODE_BITSIZE (MODE ## mode)); \
|
||||
sat_u ## NAME ## _type_node = \
|
||||
make_or_reuse_sat_unsigned_ ## KIND ## _type \
|
||||
(GET_MODE_BITSIZE (U ## MODE ## mode));
|
||||
|
||||
/* Fixed-point type and mode nodes. */
|
||||
MAKE_FIXED_TYPE_NODE_FAMILY (fract, FRACT)
|
||||
MAKE_FIXED_TYPE_NODE_FAMILY (accum, ACCUM)
|
||||
MAKE_FIXED_MODE_NODE (fract, qq, QQ)
|
||||
MAKE_FIXED_MODE_NODE (fract, hq, HQ)
|
||||
MAKE_FIXED_MODE_NODE (fract, sq, SQ)
|
||||
MAKE_FIXED_MODE_NODE (fract, dq, DQ)
|
||||
MAKE_FIXED_MODE_NODE (fract, tq, TQ)
|
||||
MAKE_FIXED_MODE_NODE (accum, ha, HA)
|
||||
MAKE_FIXED_MODE_NODE (accum, sa, SA)
|
||||
MAKE_FIXED_MODE_NODE (accum, da, DA)
|
||||
MAKE_FIXED_MODE_NODE (accum, ta, TA)
|
||||
|
||||
{
|
||||
tree t = targetm.build_builtin_va_list ();
|
||||
|
||||
|
@ -7458,6 +7626,10 @@ build_vector_type_for_mode (tree innertype, enum machine_mode mode)
|
|||
{
|
||||
case MODE_VECTOR_INT:
|
||||
case MODE_VECTOR_FLOAT:
|
||||
case MODE_VECTOR_FRACT:
|
||||
case MODE_VECTOR_UFRACT:
|
||||
case MODE_VECTOR_ACCUM:
|
||||
case MODE_VECTOR_UACCUM:
|
||||
nunits = GET_MODE_NUNITS (mode);
|
||||
break;
|
||||
|
||||
|
@ -7518,6 +7690,9 @@ initializer_zerop (const_tree init)
|
|||
return real_zerop (init)
|
||||
&& ! REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (init));
|
||||
|
||||
case FIXED_CST:
|
||||
return fixed_zerop (init);
|
||||
|
||||
case COMPLEX_CST:
|
||||
return integer_zerop (init)
|
||||
|| (real_zerop (init)
|
||||
|
@ -8211,6 +8386,7 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, struct pointer_set_t *pset)
|
|||
case IDENTIFIER_NODE:
|
||||
case INTEGER_CST:
|
||||
case REAL_CST:
|
||||
case FIXED_CST:
|
||||
case VECTOR_CST:
|
||||
case STRING_CST:
|
||||
case BLOCK:
|
||||
|
@ -8389,6 +8565,7 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, struct pointer_set_t *pset)
|
|||
else if (TREE_CODE (*type_p) == BOOLEAN_TYPE
|
||||
|| TREE_CODE (*type_p) == ENUMERAL_TYPE
|
||||
|| TREE_CODE (*type_p) == INTEGER_TYPE
|
||||
|| TREE_CODE (*type_p) == FIXED_POINT_TYPE
|
||||
|| TREE_CODE (*type_p) == REAL_TYPE)
|
||||
{
|
||||
WALK_SUBTREE (TYPE_MIN_VALUE (*type_p));
|
||||
|
|
13
gcc/tree.def
13
gcc/tree.def
|
@ -172,6 +172,11 @@ DEFTREECODE (REAL_TYPE, "real_type", tcc_type, 0)
|
|||
The TREE_TYPE points to the node for the type pointed to. */
|
||||
DEFTREECODE (POINTER_TYPE, "pointer_type", tcc_type, 0)
|
||||
|
||||
/* _Fract and _Accum types in Embedded-C. Different fixed-point types
|
||||
are distinguished by machine mode and by the TYPE_SIZE and the
|
||||
TYPE_PRECISION. */
|
||||
DEFTREECODE (FIXED_POINT_TYPE, "fixed_point_type", tcc_type, 0)
|
||||
|
||||
/* A reference is like a pointer except that it is coerced
|
||||
automatically to the value it points to. Used in C++. */
|
||||
DEFTREECODE (REFERENCE_TYPE, "reference_type", tcc_type, 0)
|
||||
|
@ -272,6 +277,9 @@ DEFTREECODE (INTEGER_CST, "integer_cst", tcc_constant, 0)
|
|||
/* Contents are in TREE_REAL_CST field. */
|
||||
DEFTREECODE (REAL_CST, "real_cst", tcc_constant, 0)
|
||||
|
||||
/* Contents are in TREE_FIXED_CST field. */
|
||||
DEFTREECODE (FIXED_CST, "fixed_cst", tcc_constant, 0)
|
||||
|
||||
/* Contents are in TREE_REALPART and TREE_IMAGPART fields,
|
||||
whose contents are other constant nodes. */
|
||||
DEFTREECODE (COMPLEX_CST, "complex_cst", tcc_constant, 0)
|
||||
|
@ -730,6 +738,11 @@ DEFTREECODE (RANGE_EXPR, "range_expr", tcc_binary, 2)
|
|||
represented by CONVERT_EXPR or NOP_EXPR nodes. */
|
||||
DEFTREECODE (CONVERT_EXPR, "convert_expr", tcc_unary, 1)
|
||||
|
||||
/* Conversion of a fixed-point value to an integer, a real, or a fixed-point
|
||||
value. Or conversion of a fixed-point value from an integer, a real, or
|
||||
a fixed-point value. */
|
||||
DEFTREECODE (FIXED_CONVERT_EXPR, "fixed_convert_expr", tcc_unary, 1)
|
||||
|
||||
/* Represents a conversion expected to require no code to be generated. */
|
||||
DEFTREECODE (NOP_EXPR, "nop_expr", tcc_unary, 1)
|
||||
|
||||
|
|
226
gcc/tree.h
226
gcc/tree.h
|
@ -384,6 +384,7 @@ struct tree_base GTY(())
|
|||
unsigned protected_flag : 1;
|
||||
unsigned deprecated_flag : 1;
|
||||
unsigned invariant_flag : 1;
|
||||
unsigned saturating_flag : 1;
|
||||
|
||||
unsigned lang_flag_0 : 1;
|
||||
unsigned lang_flag_1 : 1;
|
||||
|
@ -394,7 +395,7 @@ struct tree_base GTY(())
|
|||
unsigned lang_flag_6 : 1;
|
||||
unsigned visited : 1;
|
||||
|
||||
unsigned spare : 24;
|
||||
unsigned spare : 23;
|
||||
|
||||
/* FIXME tuples: Eventually, we need to move this somewhere external to
|
||||
the trees. */
|
||||
|
@ -575,6 +576,11 @@ struct gimple_stmt GTY(())
|
|||
TREE_INVARIANT in
|
||||
all expressions.
|
||||
|
||||
saturating_flag:
|
||||
|
||||
TYPE_SATURATING in
|
||||
all types
|
||||
|
||||
nowarning_flag:
|
||||
|
||||
TREE_NO_WARNING in
|
||||
|
@ -951,7 +957,8 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
|
|||
TREE_NOT_CHECK3 (T, RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE)
|
||||
|
||||
#define NUMERICAL_TYPE_CHECK(T) \
|
||||
TREE_CHECK4 (T, INTEGER_TYPE, ENUMERAL_TYPE, BOOLEAN_TYPE, REAL_TYPE)
|
||||
TREE_CHECK5 (T, INTEGER_TYPE, ENUMERAL_TYPE, BOOLEAN_TYPE, REAL_TYPE, \
|
||||
FIXED_POINT_TYPE)
|
||||
|
||||
/* Nonzero if NODE is a GIMPLE statement. */
|
||||
#define GIMPLE_STMT_P(NODE) \
|
||||
|
@ -1039,6 +1046,20 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
|
|||
|| TREE_CODE (TYPE) == BOOLEAN_TYPE \
|
||||
|| TREE_CODE (TYPE) == INTEGER_TYPE)
|
||||
|
||||
/* Nonzero if TYPE represents a non-saturating fixed-point type. */
|
||||
|
||||
#define NON_SAT_FIXED_POINT_TYPE_P(TYPE) \
|
||||
(TREE_CODE (TYPE) == FIXED_POINT_TYPE && !TYPE_SATURATING (TYPE))
|
||||
|
||||
/* Nonzero if TYPE represents a saturating fixed-point type. */
|
||||
|
||||
#define SAT_FIXED_POINT_TYPE_P(TYPE) \
|
||||
(TREE_CODE (TYPE) == FIXED_POINT_TYPE && TYPE_SATURATING (TYPE))
|
||||
|
||||
/* Nonzero if TYPE represents a fixed-point type. */
|
||||
|
||||
#define FIXED_POINT_TYPE_P(TYPE) (TREE_CODE (TYPE) == FIXED_POINT_TYPE)
|
||||
|
||||
/* Nonzero if TYPE represents a scalar floating-point type. */
|
||||
|
||||
#define SCALAR_FLOAT_TYPE_P(TYPE) (TREE_CODE (TYPE) == REAL_TYPE)
|
||||
|
@ -1336,6 +1357,9 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
|
|||
any expression node. */
|
||||
#define TREE_INVARIANT(NODE) ((NODE)->base.invariant_flag)
|
||||
|
||||
/* In fixed-point types, means a saturating type. */
|
||||
#define TYPE_SATURATING(NODE) ((NODE)->base.saturating_flag)
|
||||
|
||||
/* These flags are available for each language front end to use internally. */
|
||||
#define TREE_LANG_FLAG_0(NODE) ((NODE)->base.lang_flag_0)
|
||||
#define TREE_LANG_FLAG_1(NODE) ((NODE)->base.lang_flag_1)
|
||||
|
@ -1387,6 +1411,18 @@ struct tree_real_cst GTY(())
|
|||
struct real_value * real_cst_ptr;
|
||||
};
|
||||
|
||||
/* In a FIXED_CST node. */
|
||||
struct fixed_value;
|
||||
|
||||
#define TREE_FIXED_CST_PTR(NODE) (FIXED_CST_CHECK (NODE)->fixed_cst.fixed_cst_ptr)
|
||||
#define TREE_FIXED_CST(NODE) (*TREE_FIXED_CST_PTR (NODE))
|
||||
|
||||
struct tree_fixed_cst GTY(())
|
||||
{
|
||||
struct tree_common common;
|
||||
struct fixed_value * fixed_cst_ptr;
|
||||
};
|
||||
|
||||
/* In a STRING_CST */
|
||||
#define TREE_STRING_LENGTH(NODE) (STRING_CST_CHECK (NODE)->string.length)
|
||||
#define TREE_STRING_POINTER(NODE) \
|
||||
|
@ -2084,6 +2120,8 @@ struct tree_block GTY(())
|
|||
type node requires structural equality. */
|
||||
#define SET_TYPE_STRUCTURAL_EQUALITY(NODE) (TYPE_CANONICAL (NODE) = NULL_TREE)
|
||||
#define TYPE_LANG_SPECIFIC(NODE) (TYPE_CHECK (NODE)->type.lang_specific)
|
||||
#define TYPE_IBIT(NODE) (GET_MODE_IBIT (TYPE_MODE (NODE)))
|
||||
#define TYPE_FBIT(NODE) (GET_MODE_FBIT (TYPE_MODE (NODE)))
|
||||
|
||||
/* For a VECTOR_TYPE node, this describes a different type which is emitted
|
||||
in the debugging output. We use this to describe a vector as a
|
||||
|
@ -3365,6 +3403,7 @@ union tree_node GTY ((ptr_alias (union lang_tree_node),
|
|||
struct tree_common GTY ((tag ("TS_COMMON"))) common;
|
||||
struct tree_int_cst GTY ((tag ("TS_INT_CST"))) int_cst;
|
||||
struct tree_real_cst GTY ((tag ("TS_REAL_CST"))) real_cst;
|
||||
struct tree_fixed_cst GTY ((tag ("TS_FIXED_CST"))) fixed_cst;
|
||||
struct tree_vector GTY ((tag ("TS_VECTOR"))) vector;
|
||||
struct tree_string GTY ((tag ("TS_STRING"))) string;
|
||||
struct tree_complex GTY ((tag ("TS_COMPLEX"))) complex;
|
||||
|
@ -3476,6 +3515,75 @@ enum tree_index
|
|||
|
||||
TI_MAIN_IDENTIFIER,
|
||||
|
||||
TI_SAT_SFRACT_TYPE,
|
||||
TI_SAT_FRACT_TYPE,
|
||||
TI_SAT_LFRACT_TYPE,
|
||||
TI_SAT_LLFRACT_TYPE,
|
||||
TI_SAT_USFRACT_TYPE,
|
||||
TI_SAT_UFRACT_TYPE,
|
||||
TI_SAT_ULFRACT_TYPE,
|
||||
TI_SAT_ULLFRACT_TYPE,
|
||||
TI_SFRACT_TYPE,
|
||||
TI_FRACT_TYPE,
|
||||
TI_LFRACT_TYPE,
|
||||
TI_LLFRACT_TYPE,
|
||||
TI_USFRACT_TYPE,
|
||||
TI_UFRACT_TYPE,
|
||||
TI_ULFRACT_TYPE,
|
||||
TI_ULLFRACT_TYPE,
|
||||
TI_SAT_SACCUM_TYPE,
|
||||
TI_SAT_ACCUM_TYPE,
|
||||
TI_SAT_LACCUM_TYPE,
|
||||
TI_SAT_LLACCUM_TYPE,
|
||||
TI_SAT_USACCUM_TYPE,
|
||||
TI_SAT_UACCUM_TYPE,
|
||||
TI_SAT_ULACCUM_TYPE,
|
||||
TI_SAT_ULLACCUM_TYPE,
|
||||
TI_SACCUM_TYPE,
|
||||
TI_ACCUM_TYPE,
|
||||
TI_LACCUM_TYPE,
|
||||
TI_LLACCUM_TYPE,
|
||||
TI_USACCUM_TYPE,
|
||||
TI_UACCUM_TYPE,
|
||||
TI_ULACCUM_TYPE,
|
||||
TI_ULLACCUM_TYPE,
|
||||
TI_QQ_TYPE,
|
||||
TI_HQ_TYPE,
|
||||
TI_SQ_TYPE,
|
||||
TI_DQ_TYPE,
|
||||
TI_TQ_TYPE,
|
||||
TI_UQQ_TYPE,
|
||||
TI_UHQ_TYPE,
|
||||
TI_USQ_TYPE,
|
||||
TI_UDQ_TYPE,
|
||||
TI_UTQ_TYPE,
|
||||
TI_SAT_QQ_TYPE,
|
||||
TI_SAT_HQ_TYPE,
|
||||
TI_SAT_SQ_TYPE,
|
||||
TI_SAT_DQ_TYPE,
|
||||
TI_SAT_TQ_TYPE,
|
||||
TI_SAT_UQQ_TYPE,
|
||||
TI_SAT_UHQ_TYPE,
|
||||
TI_SAT_USQ_TYPE,
|
||||
TI_SAT_UDQ_TYPE,
|
||||
TI_SAT_UTQ_TYPE,
|
||||
TI_HA_TYPE,
|
||||
TI_SA_TYPE,
|
||||
TI_DA_TYPE,
|
||||
TI_TA_TYPE,
|
||||
TI_UHA_TYPE,
|
||||
TI_USA_TYPE,
|
||||
TI_UDA_TYPE,
|
||||
TI_UTA_TYPE,
|
||||
TI_SAT_HA_TYPE,
|
||||
TI_SAT_SA_TYPE,
|
||||
TI_SAT_DA_TYPE,
|
||||
TI_SAT_TA_TYPE,
|
||||
TI_SAT_UHA_TYPE,
|
||||
TI_SAT_USA_TYPE,
|
||||
TI_SAT_UDA_TYPE,
|
||||
TI_SAT_UTA_TYPE,
|
||||
|
||||
TI_MAX
|
||||
};
|
||||
|
||||
|
@ -3555,6 +3663,84 @@ extern GTY(()) tree global_trees[TI_MAX];
|
|||
#define dfloat64_ptr_type_node global_trees[TI_DFLOAT64_PTR_TYPE]
|
||||
#define dfloat128_ptr_type_node global_trees[TI_DFLOAT128_PTR_TYPE]
|
||||
|
||||
/* The fixed-point types. */
|
||||
#define sat_short_fract_type_node global_trees[TI_SAT_SFRACT_TYPE]
|
||||
#define sat_fract_type_node global_trees[TI_SAT_FRACT_TYPE]
|
||||
#define sat_long_fract_type_node global_trees[TI_SAT_LFRACT_TYPE]
|
||||
#define sat_long_long_fract_type_node global_trees[TI_SAT_LLFRACT_TYPE]
|
||||
#define sat_unsigned_short_fract_type_node \
|
||||
global_trees[TI_SAT_USFRACT_TYPE]
|
||||
#define sat_unsigned_fract_type_node global_trees[TI_SAT_UFRACT_TYPE]
|
||||
#define sat_unsigned_long_fract_type_node \
|
||||
global_trees[TI_SAT_ULFRACT_TYPE]
|
||||
#define sat_unsigned_long_long_fract_type_node \
|
||||
global_trees[TI_SAT_ULLFRACT_TYPE]
|
||||
#define short_fract_type_node global_trees[TI_SFRACT_TYPE]
|
||||
#define fract_type_node global_trees[TI_FRACT_TYPE]
|
||||
#define long_fract_type_node global_trees[TI_LFRACT_TYPE]
|
||||
#define long_long_fract_type_node global_trees[TI_LLFRACT_TYPE]
|
||||
#define unsigned_short_fract_type_node global_trees[TI_USFRACT_TYPE]
|
||||
#define unsigned_fract_type_node global_trees[TI_UFRACT_TYPE]
|
||||
#define unsigned_long_fract_type_node global_trees[TI_ULFRACT_TYPE]
|
||||
#define unsigned_long_long_fract_type_node \
|
||||
global_trees[TI_ULLFRACT_TYPE]
|
||||
#define sat_short_accum_type_node global_trees[TI_SAT_SACCUM_TYPE]
|
||||
#define sat_accum_type_node global_trees[TI_SAT_ACCUM_TYPE]
|
||||
#define sat_long_accum_type_node global_trees[TI_SAT_LACCUM_TYPE]
|
||||
#define sat_long_long_accum_type_node global_trees[TI_SAT_LLACCUM_TYPE]
|
||||
#define sat_unsigned_short_accum_type_node \
|
||||
global_trees[TI_SAT_USACCUM_TYPE]
|
||||
#define sat_unsigned_accum_type_node global_trees[TI_SAT_UACCUM_TYPE]
|
||||
#define sat_unsigned_long_accum_type_node \
|
||||
global_trees[TI_SAT_ULACCUM_TYPE]
|
||||
#define sat_unsigned_long_long_accum_type_node \
|
||||
global_trees[TI_SAT_ULLACCUM_TYPE]
|
||||
#define short_accum_type_node global_trees[TI_SACCUM_TYPE]
|
||||
#define accum_type_node global_trees[TI_ACCUM_TYPE]
|
||||
#define long_accum_type_node global_trees[TI_LACCUM_TYPE]
|
||||
#define long_long_accum_type_node global_trees[TI_LLACCUM_TYPE]
|
||||
#define unsigned_short_accum_type_node global_trees[TI_USACCUM_TYPE]
|
||||
#define unsigned_accum_type_node global_trees[TI_UACCUM_TYPE]
|
||||
#define unsigned_long_accum_type_node global_trees[TI_ULACCUM_TYPE]
|
||||
#define unsigned_long_long_accum_type_node \
|
||||
global_trees[TI_ULLACCUM_TYPE]
|
||||
#define qq_type_node global_trees[TI_QQ_TYPE]
|
||||
#define hq_type_node global_trees[TI_HQ_TYPE]
|
||||
#define sq_type_node global_trees[TI_SQ_TYPE]
|
||||
#define dq_type_node global_trees[TI_DQ_TYPE]
|
||||
#define tq_type_node global_trees[TI_TQ_TYPE]
|
||||
#define uqq_type_node global_trees[TI_UQQ_TYPE]
|
||||
#define uhq_type_node global_trees[TI_UHQ_TYPE]
|
||||
#define usq_type_node global_trees[TI_USQ_TYPE]
|
||||
#define udq_type_node global_trees[TI_UDQ_TYPE]
|
||||
#define utq_type_node global_trees[TI_UTQ_TYPE]
|
||||
#define sat_qq_type_node global_trees[TI_SAT_QQ_TYPE]
|
||||
#define sat_hq_type_node global_trees[TI_SAT_HQ_TYPE]
|
||||
#define sat_sq_type_node global_trees[TI_SAT_SQ_TYPE]
|
||||
#define sat_dq_type_node global_trees[TI_SAT_DQ_TYPE]
|
||||
#define sat_tq_type_node global_trees[TI_SAT_TQ_TYPE]
|
||||
#define sat_uqq_type_node global_trees[TI_SAT_UQQ_TYPE]
|
||||
#define sat_uhq_type_node global_trees[TI_SAT_UHQ_TYPE]
|
||||
#define sat_usq_type_node global_trees[TI_SAT_USQ_TYPE]
|
||||
#define sat_udq_type_node global_trees[TI_SAT_UDQ_TYPE]
|
||||
#define sat_utq_type_node global_trees[TI_SAT_UTQ_TYPE]
|
||||
#define ha_type_node global_trees[TI_HA_TYPE]
|
||||
#define sa_type_node global_trees[TI_SA_TYPE]
|
||||
#define da_type_node global_trees[TI_DA_TYPE]
|
||||
#define ta_type_node global_trees[TI_TA_TYPE]
|
||||
#define uha_type_node global_trees[TI_UHA_TYPE]
|
||||
#define usa_type_node global_trees[TI_USA_TYPE]
|
||||
#define uda_type_node global_trees[TI_UDA_TYPE]
|
||||
#define uta_type_node global_trees[TI_UTA_TYPE]
|
||||
#define sat_ha_type_node global_trees[TI_SAT_HA_TYPE]
|
||||
#define sat_sa_type_node global_trees[TI_SAT_SA_TYPE]
|
||||
#define sat_da_type_node global_trees[TI_SAT_DA_TYPE]
|
||||
#define sat_ta_type_node global_trees[TI_SAT_TA_TYPE]
|
||||
#define sat_uha_type_node global_trees[TI_SAT_UHA_TYPE]
|
||||
#define sat_usa_type_node global_trees[TI_SAT_USA_TYPE]
|
||||
#define sat_uda_type_node global_trees[TI_SAT_UDA_TYPE]
|
||||
#define sat_uta_type_node global_trees[TI_SAT_UTA_TYPE]
|
||||
|
||||
/* The node that should be placed at the end of a parameter list to
|
||||
indicate that the function does not take a variable number of
|
||||
arguments. The TREE_VALUE will be void_type_node and there will be
|
||||
|
@ -3834,6 +4020,37 @@ extern bool tree_expr_nonnegative_warnv_p (tree, bool *);
|
|||
extern bool may_negate_without_overflow_p (const_tree);
|
||||
extern tree get_inner_array_type (const_tree);
|
||||
|
||||
/* Construct various nodes representing fract or accum data types. */
|
||||
|
||||
extern tree make_fract_type (int, int, int);
|
||||
extern tree make_accum_type (int, int, int);
|
||||
|
||||
#define make_signed_fract_type(P) make_fract_type (P, 0, 0)
|
||||
#define make_unsigned_fract_type(P) make_fract_type (P, 1, 0)
|
||||
#define make_sat_signed_fract_type(P) make_fract_type (P, 0, 1)
|
||||
#define make_sat_unsigned_fract_type(P) make_fract_type (P, 1, 1)
|
||||
#define make_signed_accum_type(P) make_accum_type (P, 0, 0)
|
||||
#define make_unsigned_accum_type(P) make_accum_type (P, 1, 0)
|
||||
#define make_sat_signed_accum_type(P) make_accum_type (P, 0, 1)
|
||||
#define make_sat_unsigned_accum_type(P) make_accum_type (P, 1, 1)
|
||||
|
||||
#define make_or_reuse_signed_fract_type(P) \
|
||||
make_or_reuse_fract_type (P, 0, 0)
|
||||
#define make_or_reuse_unsigned_fract_type(P) \
|
||||
make_or_reuse_fract_type (P, 1, 0)
|
||||
#define make_or_reuse_sat_signed_fract_type(P) \
|
||||
make_or_reuse_fract_type (P, 0, 1)
|
||||
#define make_or_reuse_sat_unsigned_fract_type(P) \
|
||||
make_or_reuse_fract_type (P, 1, 1)
|
||||
#define make_or_reuse_signed_accum_type(P) \
|
||||
make_or_reuse_accum_type (P, 0, 0)
|
||||
#define make_or_reuse_unsigned_accum_type(P) \
|
||||
make_or_reuse_accum_type (P, 1, 0)
|
||||
#define make_or_reuse_sat_signed_accum_type(P) \
|
||||
make_or_reuse_accum_type (P, 0, 1)
|
||||
#define make_or_reuse_sat_unsigned_accum_type(P) \
|
||||
make_or_reuse_accum_type (P, 1, 1)
|
||||
|
||||
/* From expmed.c. Since rtl.h is included after tree.h, we can't
|
||||
put the prototype here. Rtl.h does declare the prototype if
|
||||
tree.h had been included. */
|
||||
|
@ -4209,6 +4426,11 @@ extern int integer_nonzerop (const_tree);
|
|||
extern bool cst_and_fits_in_hwi (const_tree);
|
||||
extern tree num_ending_zeros (const_tree);
|
||||
|
||||
/* fixed_zerop (tree x) is nonzero if X is a fixed-point constant of
|
||||
value 0. */
|
||||
|
||||
extern int fixed_zerop (tree);
|
||||
|
||||
/* staticp (tree x) is nonzero if X is a reference to data allocated
|
||||
at a fixed address in memory. Returns the outermost data. */
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ DEFTREESTRUCT(TS_BASE, "base")
|
|||
DEFTREESTRUCT(TS_COMMON, "common")
|
||||
DEFTREESTRUCT(TS_INT_CST, "integer cst")
|
||||
DEFTREESTRUCT(TS_REAL_CST, "real cst")
|
||||
DEFTREESTRUCT(TS_FIXED_CST, "fixed cst")
|
||||
DEFTREESTRUCT(TS_VECTOR, "vector")
|
||||
DEFTREESTRUCT(TS_STRING, "string")
|
||||
DEFTREESTRUCT(TS_COMPLEX, "complex")
|
||||
|
|
Loading…
Add table
Reference in a new issue