/* Utility routines for data type conversion for GCC.
Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1997, 1998,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
This file is part of GCC.
#include "convert.h"
#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;
{
case POINTER_TYPE:
case REFERENCE_TYPE:
- return fold_build1_loc (loc, NOP_EXPR, type, expr);
+ {
+ /* If the pointers point to different address spaces, conversion needs
+ to be done via a ADDR_SPACE_CONVERT_EXPR instead of a NOP_EXPR. */
+ addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (type));
+ addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));
+
+ if (to_as == from_as)
+ return fold_build1_loc (loc, NOP_EXPR, type, expr);
+ else
+ return fold_build1_loc (loc, ADDR_SPACE_CONVERT_EXPR, type, expr);
+ }
case INTEGER_TYPE:
case ENUMERAL_TYPE:
tree s_intype = TREE_TYPE (s_expr);
const enum built_in_function fcode = builtin_mathfn_code (s_expr);
tree fn = 0;
-
+
switch (fcode)
{
CASE_FLT_FN (BUILT_IN_CEIL):
default:
break;
}
-
+
if (fn)
{
tree newexpr = build_call_expr (fn, 1, CALL_EXPR_ARG (s_expr, 0));
tree s_intype = TREE_TYPE (s_expr);
const enum built_in_function fcode = builtin_mathfn_code (s_expr);
tree fn = 0;
-
+
switch (fcode)
{
CASE_FLT_FN (BUILT_IN_LOGB):
}
break;
+ case TRUNC_DIV_EXPR:
+ {
+ tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
+ tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
+
+ /* Don't distribute unless the output precision is at least as big
+ as the actual inputs and it has the same signedness. */
+ if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
+ && outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
+ /* If signedness of arg0 and arg1 don't match,
+ we can't necessarily find a type to compare them in. */
+ && (TYPE_UNSIGNED (TREE_TYPE (arg0))
+ == TYPE_UNSIGNED (TREE_TYPE (arg1)))
+ /* Do not change the sign of the division. */
+ && (TYPE_UNSIGNED (TREE_TYPE (expr))
+ == TYPE_UNSIGNED (TREE_TYPE (arg0)))
+ /* Either require unsigned division or a division by
+ a constant that is not -1. */
+ && (TYPE_UNSIGNED (TREE_TYPE (arg0))
+ || (TREE_CODE (arg1) == INTEGER_CST
+ && !integer_all_onesp (arg1))))
+ goto trunc1;
+ break;
+ }
+
case MAX_EXPR:
case MIN_EXPR:
case MULT_EXPR: