diff options
author | chaoyingfu <chaoyingfu@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-09-07 01:24:09 +0000 |
---|---|---|
committer | chaoyingfu <chaoyingfu@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-09-07 01:24:09 +0000 |
commit | 68a556d6cb1ebf7290514725565d2cf4723ab59f (patch) | |
tree | efee8ca8b1b0b17d1b3afab3a5bc101a5bfb2b1d /gcc/convert.c | |
parent | b3b2f29f86807ed0ca83c011a143e65b97960b81 (diff) | |
download | gcc-68a556d6cb1ebf7290514725565d2cf4723ab59f.tar.gz |
* ginclude/stdfix.h: New file.
* Makefile.in (USER_H): Add $(srcdir)/ginclude/stdfix.h.
(convert.o): Add dependence on fixed-value.h.
* c-convert.c (convert): Support FIXED_POINT_TYPE.
* c-cppbuiltin.c (builtin_define_fixed_point_constants): New function
to define fixed-point constants.
(c_cpp_builtins): Define fixed-point constants.
* convert.c (fixed-value.h): New include.
(convert_to_real): Update comment to include fixed-point.
Support FIXED_POINT_TYPE.
(convert_to_integer): Update comment to include fixed-point.
Support FIXED_POINT_TYPE.
(convert_to_complex): Support FIXED_POINT_TYPE.
(convert_to_fixed): New function.
* convert.h (convert_to_fixed): Declare.
* genopinit.c: Add comment about $Q for only fixed-point modes.
(optabs): Add fract_optab, fractuns_optab, satfract_optab,
satfractuns_optab, add_optab, ssadd_optab, usadd_optab, sub_optab,
sssub_optab, ussub_optab, smul_optab, ssmul_optab, usmul_optab,
ssmadd_widen_optab, usmadd_widen_optab, ssdiv_optab, udiv_optab,
usdiv_optab, ssashl_optab, usashl_optab, neg_optab, ssneg_optab,
usneg_optab for fixed-point modes.
(gen_insn): Add force_fixed to track the $Q format for all fixed-point
modes.
* optabs.c (optab_for_tree_code): For *DIV_EXPR, LSHIFT_EXPR,
PLUS_EXPR, MINUS_EXPR, MULT_EXPR, NEGATE_EXPR, return signed or
unsigned saturation optabs, when type is saturating.
(shift_optab_p): Return true for SS_ASHIFT or US_ASHIFT.
(expand_fixed_convert): New function.
(gen_fixed_libfunc, gen_signed_fixed_libfunc,
gen_unsigned_fixed_libfunc, gen_int_fp_fixed_libfunc,
gen_int_fp_signed_fixed_libfunc, gen_int_fixed_libfunc,
gen_int_signed_fixed_libfunc, gen_int_unsigned_fixed_libfunc,
gen_fract_conv_libfunc, gen_fractuns_conv_libfunc,
gen_satfract_conv_libfunc, gen_satfractuns_conv_libfunc): New
functions.
(init_optabs): Initialize ssadd_optab, usadd_optab, sssub_optab,
ussub_optab, ssmul_optab, usmul_optab, ssmadd_widen_optab,
usmadd_widen_optab, ssmsub_widen_optab, usmsub_widen_optab,
ssdiv_optab, usdiv_optab, ssashl_optab, usashl_optab, ssneg_optab,
usneg_optab, fract_optab, fractuns_optab, satfract_optab,
satfractuns_optab.
Initialize fixed-point libraries, including add, ssadd, usadd, sub,
sssub, ussub, mul, ssmul, usmul, div, ssdiv, udiv, usdiv, ashl,
ssashl, usashl, ashr, lshr, neg, ssneg, usneg, cmp, fract, satfract,
fractuns, satfractuns.
* optabs.h (enum optab_index): Add OTI_ssadd, OTI_usadd, OTI_sssub,
OTI_ussub, OTI_ssmul, OTI_usmul, OTI_ssdiv, OTI_usdiv, OTI_ssneg,
OTI_usneg, OTI_ssashl, OTI_usashl, OTI_ssmadd_widen, OTI_usmadd_widen,
OTI_ssmsub_widen, OTI_usmsub_widen.
(ssadd_optab, usadd_optab, sssub_optab, ussub_optab, ssmul_optab,
usmul_optab, ssdiv_optab, usdiv_optab, ssneg_optab, usneg_optab,
ssashl_optab, usashl_optab, ssmadd_widen_optab, usmadd_widen_optab,
umsub_widen_optab, usmsub_widen_optab): Define.
(enum convert_optab_index): Add COI_fract, COI_fractuns, COI_satfract,
COI_satfractuns.
(fract_optab, fractuns_optab, satfract_optab, satfractuns_optab):
Define.
(expand_fixed_convert): Declare.
* expr.c (convert_move): Support the move of fixed-point modes.
(emit_move_insn_1): Handle fixed-point mode to move via integer.
(categorize_ctor_elements_1): Handle FIXED_CST.
(count_type_elements): Handle FIXED_POINT_TYPE.
(expand_expr_real_1): For VECTOR_CST, check MODE_VECTOR_FRACT,
MODE_VECTOR_UFRACT, MODE_VECTOR_ACCUM, MODE_VECTOR_UACCUM.
Support FIXED_CST.
For PLUS_EXPR and MINUS_EXPR, support saturating and non-saturating
multiply and add/subtract for fixed-point types.
For MULT_EXPR, *DIV_EXPR, *SHIFT_EXPR, if the mode if a fixed-point
mode, we jump to binop directly.
Support FIXED_CONVERT_EXPR.
(do_store_flag): Check FIXED_CST to put a constant second.
(vector_mode_valid_p): Handle MODE_VECTOR_FRACT,
MODE_VECTOR_UFRACT, MODE_VECTOR_ACCUM, MODE_VECTOR_UACCUM.
(const_vector_from_tree): Support FIXED_CST.
* doc/extend.texi (Fixed-Point): New node.
* doc/md.texi (ssadd, usadd, sssub, ussub, ssmul, usmul, ssdiv, usdiv,
ssmadd, usmadd, ssmsub, usmsub, ssashl, usashl, ssneg, usneg, fract,
satfract, fractuns, satfractuns): Document them.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@128218 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/convert.c')
-rw-r--r-- | gcc/convert.c | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/gcc/convert.c b/gcc/convert.c index 97641cff051..f82604e775a 100644 --- a/gcc/convert.c +++ b/gcc/convert.c @@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see #include "toplev.h" #include "langhooks.h" #include "real.h" +#include "fixed-value.h" /* Convert EXPR to some pointer or reference type TYPE. EXPR must be pointer, reference, integer, enumeral, or literal zero; @@ -117,7 +118,7 @@ strip_float_extensions (tree exp) /* Convert EXPR to some floating-point type TYPE. - EXPR must be float, integer, or enumeral; + EXPR must be float, fixed-point, integer, or enumeral; in other cases error is called. */ tree @@ -319,6 +320,9 @@ convert_to_real (tree type, tree expr) case BOOLEAN_TYPE: return build1 (FLOAT_EXPR, type, expr); + case FIXED_POINT_TYPE: + return build1 (FIXED_CONVERT_EXPR, type, expr); + case COMPLEX_TYPE: return convert (type, fold_build1 (REALPART_EXPR, @@ -337,8 +341,8 @@ convert_to_real (tree type, tree expr) /* Convert EXPR to some integer (or enum) type TYPE. - EXPR must be pointer, integer, discrete (enum, char, or bool), float, or - vector; in other cases error is called. + EXPR must be pointer, integer, discrete (enum, char, or bool), float, + fixed-point or vector; in other cases error is called. The result of this is always supposed to be a newly created tree node not in use in any existing structure. */ @@ -713,6 +717,9 @@ convert_to_integer (tree type, tree expr) case REAL_TYPE: return build1 (FIX_TRUNC_EXPR, type, expr); + case FIXED_POINT_TYPE: + return build1 (FIXED_CONVERT_EXPR, type, expr); + case COMPLEX_TYPE: return convert (type, fold_build1 (REALPART_EXPR, @@ -742,6 +749,7 @@ convert_to_complex (tree type, tree expr) switch (TREE_CODE (TREE_TYPE (expr))) { case REAL_TYPE: + case FIXED_POINT_TYPE: case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE: @@ -806,3 +814,42 @@ convert_to_vector (tree type, tree expr) return error_mark_node; } } + +/* Convert EXPR to some fixed-point type TYPE. + + EXPR must be fixed-point, float, integer, or enumeral; + in other cases error is called. */ + +tree +convert_to_fixed (tree type, tree expr) +{ + if (integer_zerop (expr)) + { + tree fixed_zero_node = build_fixed (type, FCONST0 (TYPE_MODE (type))); + return fixed_zero_node; + } + else if (integer_onep (expr) && ALL_SCALAR_ACCUM_MODE_P (TYPE_MODE (type))) + { + tree fixed_one_node = build_fixed (type, FCONST1 (TYPE_MODE (type))); + return fixed_one_node; + } + + switch (TREE_CODE (TREE_TYPE (expr))) + { + case FIXED_POINT_TYPE: + case INTEGER_TYPE: + case ENUMERAL_TYPE: + case BOOLEAN_TYPE: + case REAL_TYPE: + return build1 (FIXED_CONVERT_EXPR, type, expr); + + case COMPLEX_TYPE: + return convert (type, + fold_build1 (REALPART_EXPR, + TREE_TYPE (TREE_TYPE (expr)), expr)); + + default: + error ("aggregate value used where a fixed-point was expected"); + return error_mark_node; + } +} |