GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
/* These routines are somewhat language-independent utility function
#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;
/* 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
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,
/* 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. */
|| !TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg1)))
&& (ex_form == PLUS_EXPR
|| ex_form == MINUS_EXPR)))
- typex = lang_hooks.types.unsigned_type (typex);
+ typex = unsigned_type_for (typex);
else
- typex = lang_hooks.types.signed_type (typex);
+ typex = signed_type_for (typex);
return convert (type,
fold_build2 (ex_form, typex,
convert (typex, arg0),
/* Don't do unsigned arithmetic where signed was wanted,
or vice versa. */
if (TYPE_UNSIGNED (TREE_TYPE (expr)))
- typex = lang_hooks.types.unsigned_type (type);
+ typex = unsigned_type_for (type);
else
- typex = lang_hooks.types.signed_type (type);
+ typex = signed_type_for (type);
return convert (type,
fold_build1 (ex_form, typex,
convert (typex,
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,
switch (TREE_CODE (TREE_TYPE (expr)))
{
case REAL_TYPE:
+ case FIXED_POINT_TYPE:
case INTEGER_TYPE:
case ENUMERAL_TYPE:
case BOOLEAN_TYPE:
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;
+ }
+}