summaryrefslogtreecommitdiff
path: root/gcc/convert.c
diff options
context:
space:
mode:
authorchaoyingfu <chaoyingfu@138bc75d-0d04-0410-961f-82ee72b054a4>2007-09-07 01:24:09 +0000
committerchaoyingfu <chaoyingfu@138bc75d-0d04-0410-961f-82ee72b054a4>2007-09-07 01:24:09 +0000
commit68a556d6cb1ebf7290514725565d2cf4723ab59f (patch)
treeefee8ca8b1b0b17d1b3afab3a5bc101a5bfb2b1d /gcc/convert.c
parentb3b2f29f86807ed0ca83c011a143e65b97960b81 (diff)
downloadgcc-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.c53
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;
+ }
+}