1132718Skan/* Utility routines for data type conversion for GCC.
2132718Skan   Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1997, 1998,
3169689Skan   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
418334Speter
590075SobrienThis file is part of GCC.
618334Speter
790075SobrienGCC is free software; you can redistribute it and/or modify it under
890075Sobrienthe terms of the GNU General Public License as published by the Free
990075SobrienSoftware Foundation; either version 2, or (at your option) any later
1090075Sobrienversion.
1118334Speter
1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1490075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1590075Sobrienfor more details.
1618334Speter
1718334SpeterYou should have received a copy of the GNU General Public License
1890075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20169689Skan02110-1301, USA.  */
2118334Speter
2218334Speter
2318334Speter/* These routines are somewhat language-independent utility function
2450397Sobrien   intended to be called by the language-specific convert () functions.  */
2518334Speter
2618334Speter#include "config.h"
2790075Sobrien#include "system.h"
28132718Skan#include "coretypes.h"
29132718Skan#include "tm.h"
3018334Speter#include "tree.h"
3118334Speter#include "flags.h"
3218334Speter#include "convert.h"
3350397Sobrien#include "toplev.h"
34117395Skan#include "langhooks.h"
35132718Skan#include "real.h"
36169689Skan
3718334Speter/* Convert EXPR to some pointer or reference type TYPE.
3818334Speter   EXPR must be pointer, reference, integer, enumeral, or literal zero;
3950397Sobrien   in other cases error is called.  */
4018334Speter
4118334Spetertree
42132718Skanconvert_to_pointer (tree type, tree expr)
4318334Speter{
44169689Skan  if (TREE_TYPE (expr) == type)
45169689Skan    return expr;
46169689Skan
4718334Speter  if (integer_zerop (expr))
4818334Speter    {
49169689Skan      tree t = build_int_cst (type, 0);
50169689Skan      if (TREE_OVERFLOW (expr) || TREE_CONSTANT_OVERFLOW (expr))
51169689Skan	t = force_fit_type (t, 0, TREE_OVERFLOW (expr),
52169689Skan			    TREE_CONSTANT_OVERFLOW (expr));
53169689Skan      return t;
5418334Speter    }
5518334Speter
5650397Sobrien  switch (TREE_CODE (TREE_TYPE (expr)))
5750397Sobrien    {
5850397Sobrien    case POINTER_TYPE:
5950397Sobrien    case REFERENCE_TYPE:
60169689Skan      return fold_build1 (NOP_EXPR, type, expr);
6118334Speter
6250397Sobrien    case INTEGER_TYPE:
6350397Sobrien    case ENUMERAL_TYPE:
6450397Sobrien    case BOOLEAN_TYPE:
65169689Skan      if (TYPE_PRECISION (TREE_TYPE (expr)) != POINTER_SIZE)
66169689Skan	expr = fold_build1 (NOP_EXPR,
67261188Spfg			     lang_hooks.types.type_for_size (POINTER_SIZE, 0),
68169689Skan			    expr);
69169689Skan      return fold_build1 (CONVERT_EXPR, type, expr);
7018334Speter
71261188Spfg	/* APPLE LOCAL begin blocks (C++ ck) */
72261188Spfg    case BLOCK_POINTER_TYPE:
73261188Spfg	/* APPLE LOCAL begin radar 5809099 */
74261188Spfg	if (objc_is_id (type)
75261188Spfg		|| (TREE_CODE (type) == POINTER_TYPE && VOID_TYPE_P (TREE_TYPE (type))))
76261188Spfg	/* APPLE LOCAL end radar 5809099 */
77261188Spfg		return fold_build1 (NOP_EXPR, type, expr);
78261188Spfg	/* APPLE LOCAL end blocks (C++ ck) */
79261188Spfg      default:
80261188Spfg	error ("cannot convert to a pointer type");
81261188Spfg	return convert_to_pointer (type, integer_zero_node);
82261188Spfg    }
83261188Spfg}
8418334Speter
85261188Spfg/* APPLE LOCAL begin blocks (C++ ck) */
86261188Spfgtree
87261188Spfgconvert_to_block_pointer (tree type, tree expr)
88261188Spfg{
89261188Spfg  if (TREE_TYPE (expr) == type)
90261188Spfg      return expr;
91261188Spfg
92261188Spfg  if (integer_zerop (expr))
93261188Spfg    {
94261188Spfg      tree t = build_int_cst (type, 0);
95261188Spfg      if (TREE_OVERFLOW (expr) || TREE_CONSTANT_OVERFLOW (expr))
96261188Spfg	t = force_fit_type (t, 0, TREE_OVERFLOW (expr),
97261188Spfg						TREE_CONSTANT_OVERFLOW (expr));
98261188Spfg      return t;
9950397Sobrien    }
100261188Spfg
101261188Spfg  switch (TREE_CODE (TREE_TYPE (expr)))
102261188Spfg    {
103261188Spfg    case BLOCK_POINTER_TYPE:
104261188Spfg	return fold_build1 (NOP_EXPR, type, expr);
105261188Spfg
106261188Spfg    case INTEGER_TYPE:
107261188Spfg	if (TYPE_PRECISION (TREE_TYPE (expr)) != POINTER_SIZE)
108261188Spfg		expr = fold_build1 (NOP_EXPR,
109261188Spfg					lang_hooks.types.type_for_size (POINTER_SIZE, 0),
110261188Spfg					expr);
111261188Spfg	return fold_build1 (CONVERT_EXPR, type, expr);
112261188Spfg
113261188Spfg    case POINTER_TYPE:
114261188Spfg	/* APPLE LOCAL radar 5809099 */
115261188Spfg	if (objc_is_id (TREE_TYPE (expr)) || VOID_TYPE_P (TREE_TYPE (TREE_TYPE (expr))))
116261188Spfg		return build1 (NOP_EXPR, type, expr);
117261188Spfg	/* fall thru */
118261188Spfg
119261188Spfg      default:
120261188Spfg	error ("cannot convert to a block pointer type");
121261188Spfg	return convert_to_block_pointer (type, integer_zero_node);
122261188Spfg    }
12318334Speter}
12418334Speter
125261188Spfg/* APPLE LOCAL end blocks (C++ ck) */
126261188Spfg
127132718Skan/* Avoid any floating point extensions from EXP.  */
128132718Skantree
129132718Skanstrip_float_extensions (tree exp)
130132718Skan{
131132718Skan  tree sub, expt, subt;
132132718Skan
133132718Skan  /*  For floating point constant look up the narrowest type that can hold
134132718Skan      it properly and handle it like (type)(narrowest_type)constant.
135132718Skan      This way we can optimize for instance a=a*2.0 where "a" is float
136132718Skan      but 2.0 is double constant.  */
137132718Skan  if (TREE_CODE (exp) == REAL_CST)
138132718Skan    {
139132718Skan      REAL_VALUE_TYPE orig;
140132718Skan      tree type = NULL;
141132718Skan
142132718Skan      orig = TREE_REAL_CST (exp);
143132718Skan      if (TYPE_PRECISION (TREE_TYPE (exp)) > TYPE_PRECISION (float_type_node)
144132718Skan	  && exact_real_truncate (TYPE_MODE (float_type_node), &orig))
145132718Skan	type = float_type_node;
146132718Skan      else if (TYPE_PRECISION (TREE_TYPE (exp))
147132718Skan	       > TYPE_PRECISION (double_type_node)
148132718Skan	       && exact_real_truncate (TYPE_MODE (double_type_node), &orig))
149132718Skan	type = double_type_node;
150132718Skan      if (type)
151132718Skan	return build_real (type, real_value_truncate (TYPE_MODE (type), orig));
152132718Skan    }
153132718Skan
154169689Skan  if (TREE_CODE (exp) != NOP_EXPR
155169689Skan      && TREE_CODE (exp) != CONVERT_EXPR)
156132718Skan    return exp;
157132718Skan
158132718Skan  sub = TREE_OPERAND (exp, 0);
159132718Skan  subt = TREE_TYPE (sub);
160132718Skan  expt = TREE_TYPE (exp);
161132718Skan
162132718Skan  if (!FLOAT_TYPE_P (subt))
163132718Skan    return exp;
164132718Skan
165132718Skan  if (TYPE_PRECISION (subt) > TYPE_PRECISION (expt))
166132718Skan    return exp;
167132718Skan
168132718Skan  return strip_float_extensions (sub);
169132718Skan}
170132718Skan
171132718Skan
17218334Speter/* Convert EXPR to some floating-point type TYPE.
17318334Speter
17418334Speter   EXPR must be float, integer, or enumeral;
17550397Sobrien   in other cases error is called.  */
17618334Speter
17718334Spetertree
178132718Skanconvert_to_real (tree type, tree expr)
17918334Speter{
180132718Skan  enum built_in_function fcode = builtin_mathfn_code (expr);
181132718Skan  tree itype = TREE_TYPE (expr);
182132718Skan
183132718Skan  /* Disable until we figure out how to decide whether the functions are
184132718Skan     present in runtime.  */
185132718Skan  /* Convert (float)sqrt((double)x) where x is float into sqrtf(x) */
186132718Skan  if (optimize
187132718Skan      && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
188132718Skan          || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
189132718Skan    {
190169689Skan      switch (fcode)
191169689Skan        {
192169689Skan#define CASE_MATHFN(FN) case BUILT_IN_##FN: case BUILT_IN_##FN##L:
193169689Skan	  CASE_MATHFN (ACOS)
194169689Skan	  CASE_MATHFN (ACOSH)
195169689Skan	  CASE_MATHFN (ASIN)
196169689Skan	  CASE_MATHFN (ASINH)
197169689Skan	  CASE_MATHFN (ATAN)
198169689Skan	  CASE_MATHFN (ATANH)
199169689Skan	  CASE_MATHFN (CBRT)
200169689Skan	  CASE_MATHFN (COS)
201169689Skan	  CASE_MATHFN (COSH)
202169689Skan	  CASE_MATHFN (ERF)
203169689Skan	  CASE_MATHFN (ERFC)
204169689Skan	  CASE_MATHFN (EXP)
205169689Skan	  CASE_MATHFN (EXP10)
206169689Skan	  CASE_MATHFN (EXP2)
207169689Skan	  CASE_MATHFN (EXPM1)
208169689Skan	  CASE_MATHFN (FABS)
209169689Skan	  CASE_MATHFN (GAMMA)
210169689Skan	  CASE_MATHFN (J0)
211169689Skan	  CASE_MATHFN (J1)
212169689Skan	  CASE_MATHFN (LGAMMA)
213169689Skan	  CASE_MATHFN (LOG)
214169689Skan	  CASE_MATHFN (LOG10)
215169689Skan	  CASE_MATHFN (LOG1P)
216169689Skan	  CASE_MATHFN (LOG2)
217169689Skan	  CASE_MATHFN (LOGB)
218169689Skan	  CASE_MATHFN (POW10)
219169689Skan	  CASE_MATHFN (SIN)
220169689Skan	  CASE_MATHFN (SINH)
221169689Skan	  CASE_MATHFN (SQRT)
222169689Skan	  CASE_MATHFN (TAN)
223169689Skan	  CASE_MATHFN (TANH)
224169689Skan	  CASE_MATHFN (TGAMMA)
225169689Skan	  CASE_MATHFN (Y0)
226169689Skan	  CASE_MATHFN (Y1)
227169689Skan#undef CASE_MATHFN
228169689Skan	    {
229169689Skan	      tree arg0 = strip_float_extensions (TREE_VALUE (TREE_OPERAND (expr, 1)));
230169689Skan	      tree newtype = type;
231132718Skan
232169689Skan	      /* We have (outertype)sqrt((innertype)x).  Choose the wider mode from
233169689Skan		 the both as the safe type for operation.  */
234169689Skan	      if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (type))
235169689Skan		newtype = TREE_TYPE (arg0);
236132718Skan
237169689Skan	      /* Be careful about integer to fp conversions.
238169689Skan		 These may overflow still.  */
239169689Skan	      if (FLOAT_TYPE_P (TREE_TYPE (arg0))
240169689Skan		  && TYPE_PRECISION (newtype) < TYPE_PRECISION (itype)
241169689Skan		  && (TYPE_MODE (newtype) == TYPE_MODE (double_type_node)
242169689Skan		      || TYPE_MODE (newtype) == TYPE_MODE (float_type_node)))
243169689Skan	        {
244169689Skan		  tree arglist;
245169689Skan		  tree fn = mathfn_built_in (newtype, fcode);
246132718Skan
247169689Skan		  if (fn)
248169689Skan		  {
249169689Skan		    arglist = build_tree_list (NULL_TREE, fold (convert_to_real (newtype, arg0)));
250169689Skan		    expr = build_function_call_expr (fn, arglist);
251169689Skan		    if (newtype == type)
252169689Skan		      return expr;
253169689Skan		  }
254169689Skan		}
255132718Skan	    }
256169689Skan	default:
257169689Skan	  break;
258132718Skan	}
259132718Skan    }
260132718Skan  if (optimize
261132718Skan      && (((fcode == BUILT_IN_FLOORL
262132718Skan	   || fcode == BUILT_IN_CEILL
263169689Skan	   || fcode == BUILT_IN_ROUNDL
264169689Skan	   || fcode == BUILT_IN_RINTL
265169689Skan	   || fcode == BUILT_IN_TRUNCL
266169689Skan	   || fcode == BUILT_IN_NEARBYINTL)
267132718Skan	  && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
268132718Skan	      || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
269132718Skan	  || ((fcode == BUILT_IN_FLOOR
270132718Skan	       || fcode == BUILT_IN_CEIL
271132718Skan	       || fcode == BUILT_IN_ROUND
272169689Skan	       || fcode == BUILT_IN_RINT
273132718Skan	       || fcode == BUILT_IN_TRUNC
274132718Skan	       || fcode == BUILT_IN_NEARBYINT)
275132718Skan	      && (TYPE_MODE (type) == TYPE_MODE (float_type_node)))))
276132718Skan    {
277132718Skan      tree fn = mathfn_built_in (type, fcode);
278132718Skan
279132718Skan      if (fn)
280132718Skan	{
281169689Skan	  tree arg
282169689Skan	    = strip_float_extensions (TREE_VALUE (TREE_OPERAND (expr, 1)));
283132718Skan
284169689Skan	  /* Make sure (type)arg0 is an extension, otherwise we could end up
285169689Skan	     changing (float)floor(double d) into floorf((float)d), which is
286169689Skan	     incorrect because (float)d uses round-to-nearest and can round
287169689Skan	     up to the next integer.  */
288169689Skan	  if (TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (arg)))
289169689Skan	    return
290169689Skan	      build_function_call_expr (fn,
291169689Skan					build_tree_list (NULL_TREE,
292169689Skan					  fold (convert_to_real (type, arg))));
293132718Skan	}
294132718Skan    }
295132718Skan
296132718Skan  /* Propagate the cast into the operation.  */
297132718Skan  if (itype != type && FLOAT_TYPE_P (type))
298132718Skan    switch (TREE_CODE (expr))
299132718Skan      {
300169689Skan	/* Convert (float)-x into -(float)x.  This is safe for
301169689Skan	   round-to-nearest rounding mode.  */
302132718Skan	case ABS_EXPR:
303132718Skan	case NEGATE_EXPR:
304169689Skan	  if (!flag_rounding_math
305169689Skan	      && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (expr)))
306132718Skan	    return build1 (TREE_CODE (expr), type,
307132718Skan			   fold (convert_to_real (type,
308132718Skan						  TREE_OPERAND (expr, 0))));
309132718Skan	  break;
310132718Skan	/* Convert (outertype)((innertype0)a+(innertype1)b)
311132718Skan	   into ((newtype)a+(newtype)b) where newtype
312132718Skan	   is the widest mode from all of these.  */
313132718Skan	case PLUS_EXPR:
314132718Skan	case MINUS_EXPR:
315132718Skan	case MULT_EXPR:
316132718Skan	case RDIV_EXPR:
317132718Skan	   {
318132718Skan	     tree arg0 = strip_float_extensions (TREE_OPERAND (expr, 0));
319132718Skan	     tree arg1 = strip_float_extensions (TREE_OPERAND (expr, 1));
320132718Skan
321132718Skan	     if (FLOAT_TYPE_P (TREE_TYPE (arg0))
322132718Skan		 && FLOAT_TYPE_P (TREE_TYPE (arg1)))
323132718Skan	       {
324132718Skan		  tree newtype = type;
325169689Skan
326169689Skan		  if (TYPE_MODE (TREE_TYPE (arg0)) == SDmode
327169689Skan		      || TYPE_MODE (TREE_TYPE (arg1)) == SDmode)
328169689Skan		    newtype = dfloat32_type_node;
329169689Skan		  if (TYPE_MODE (TREE_TYPE (arg0)) == DDmode
330169689Skan		      || TYPE_MODE (TREE_TYPE (arg1)) == DDmode)
331169689Skan		    newtype = dfloat64_type_node;
332169689Skan		  if (TYPE_MODE (TREE_TYPE (arg0)) == TDmode
333169689Skan		      || TYPE_MODE (TREE_TYPE (arg1)) == TDmode)
334169689Skan                    newtype = dfloat128_type_node;
335169689Skan		  if (newtype == dfloat32_type_node
336169689Skan		      || newtype == dfloat64_type_node
337169689Skan		      || newtype == dfloat128_type_node)
338169689Skan		    {
339169689Skan		      expr = build2 (TREE_CODE (expr), newtype,
340169689Skan				     fold (convert_to_real (newtype, arg0)),
341169689Skan				     fold (convert_to_real (newtype, arg1)));
342169689Skan		      if (newtype == type)
343169689Skan			return expr;
344169689Skan		      break;
345169689Skan		    }
346169689Skan
347132718Skan		  if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (newtype))
348132718Skan		    newtype = TREE_TYPE (arg0);
349132718Skan		  if (TYPE_PRECISION (TREE_TYPE (arg1)) > TYPE_PRECISION (newtype))
350132718Skan		    newtype = TREE_TYPE (arg1);
351132718Skan		  if (TYPE_PRECISION (newtype) < TYPE_PRECISION (itype))
352132718Skan		    {
353169689Skan		      expr = build2 (TREE_CODE (expr), newtype,
354169689Skan				     fold (convert_to_real (newtype, arg0)),
355169689Skan				     fold (convert_to_real (newtype, arg1)));
356132718Skan		      if (newtype == type)
357132718Skan			return expr;
358132718Skan		    }
359132718Skan	       }
360132718Skan	   }
361132718Skan	  break;
362132718Skan	default:
363132718Skan	  break;
364132718Skan      }
365132718Skan
36650397Sobrien  switch (TREE_CODE (TREE_TYPE (expr)))
36750397Sobrien    {
36850397Sobrien    case REAL_TYPE:
369169689Skan      /* Ignore the conversion if we don't need to store intermediate
370169689Skan	 results and neither type is a decimal float.  */
371169689Skan      return build1 ((flag_float_store
372169689Skan		     || DECIMAL_FLOAT_TYPE_P (type)
373169689Skan		     || DECIMAL_FLOAT_TYPE_P (itype))
374169689Skan		     ? CONVERT_EXPR : NOP_EXPR, type, expr);
37518334Speter
37650397Sobrien    case INTEGER_TYPE:
37750397Sobrien    case ENUMERAL_TYPE:
37850397Sobrien    case BOOLEAN_TYPE:
37950397Sobrien      return build1 (FLOAT_EXPR, type, expr);
38018334Speter
38150397Sobrien    case COMPLEX_TYPE:
38250397Sobrien      return convert (type,
383169689Skan		      fold_build1 (REALPART_EXPR,
384169689Skan				   TREE_TYPE (TREE_TYPE (expr)), expr));
38518334Speter
38650397Sobrien    case POINTER_TYPE:
38750397Sobrien    case REFERENCE_TYPE:
38850397Sobrien      error ("pointer value used where a floating point value was expected");
38950397Sobrien      return convert_to_real (type, integer_zero_node);
39018334Speter
39150397Sobrien    default:
39250397Sobrien      error ("aggregate value used where a float was expected");
39350397Sobrien      return convert_to_real (type, integer_zero_node);
39450397Sobrien    }
39518334Speter}
39618334Speter
39718334Speter/* Convert EXPR to some integer (or enum) type TYPE.
39818334Speter
39990075Sobrien   EXPR must be pointer, integer, discrete (enum, char, or bool), float, or
40090075Sobrien   vector; in other cases error is called.
40118334Speter
40218334Speter   The result of this is always supposed to be a newly created tree node
40318334Speter   not in use in any existing structure.  */
40418334Speter
40518334Spetertree
406132718Skanconvert_to_integer (tree type, tree expr)
40718334Speter{
40850397Sobrien  enum tree_code ex_form = TREE_CODE (expr);
40950397Sobrien  tree intype = TREE_TYPE (expr);
41090075Sobrien  unsigned int inprec = TYPE_PRECISION (intype);
41190075Sobrien  unsigned int outprec = TYPE_PRECISION (type);
41218334Speter
41352284Sobrien  /* An INTEGER_TYPE cannot be incomplete, but an ENUMERAL_TYPE can
41452284Sobrien     be.  Consider `enum E = { a, b = (enum E) 3 };'.  */
41590075Sobrien  if (!COMPLETE_TYPE_P (type))
41652284Sobrien    {
41752284Sobrien      error ("conversion to incomplete type");
41852284Sobrien      return error_mark_node;
41952284Sobrien    }
42052284Sobrien
421169689Skan  /* Convert e.g. (long)round(d) -> lround(d).  */
422169689Skan  /* If we're converting to char, we may encounter differing behavior
423169689Skan     between converting from double->char vs double->long->char.
424169689Skan     We're in "undefined" territory but we prefer to be conservative,
425169689Skan     so only proceed in "unsafe" math mode.  */
426169689Skan  if (optimize
427169689Skan      && (flag_unsafe_math_optimizations
428169689Skan	  || (long_integer_type_node
429169689Skan	      && outprec >= TYPE_PRECISION (long_integer_type_node))))
430169689Skan    {
431169689Skan      tree s_expr = strip_float_extensions (expr);
432169689Skan      tree s_intype = TREE_TYPE (s_expr);
433169689Skan      const enum built_in_function fcode = builtin_mathfn_code (s_expr);
434169689Skan      tree fn = 0;
435169689Skan
436169689Skan      switch (fcode)
437169689Skan        {
438169689Skan	CASE_FLT_FN (BUILT_IN_CEIL):
439169689Skan	  /* Only convert in ISO C99 mode.  */
440169689Skan	  if (!TARGET_C99_FUNCTIONS)
441169689Skan	    break;
442169689Skan	  if (outprec < TYPE_PRECISION (long_integer_type_node)
443169689Skan	      || (outprec == TYPE_PRECISION (long_integer_type_node)
444169689Skan		  && !TYPE_UNSIGNED (type)))
445169689Skan	    fn = mathfn_built_in (s_intype, BUILT_IN_LCEIL);
446169689Skan	  else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
447169689Skan		   && !TYPE_UNSIGNED (type))
448169689Skan	    fn = mathfn_built_in (s_intype, BUILT_IN_LLCEIL);
449169689Skan	  break;
450169689Skan
451169689Skan	CASE_FLT_FN (BUILT_IN_FLOOR):
452169689Skan	  /* Only convert in ISO C99 mode.  */
453169689Skan	  if (!TARGET_C99_FUNCTIONS)
454169689Skan	    break;
455169689Skan	  if (outprec < TYPE_PRECISION (long_integer_type_node)
456169689Skan	      || (outprec == TYPE_PRECISION (long_integer_type_node)
457169689Skan		  && !TYPE_UNSIGNED (type)))
458169689Skan	    fn = mathfn_built_in (s_intype, BUILT_IN_LFLOOR);
459169689Skan	  else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
460169689Skan		   && !TYPE_UNSIGNED (type))
461169689Skan	    fn = mathfn_built_in (s_intype, BUILT_IN_LLFLOOR);
462169689Skan	  break;
463169689Skan
464169689Skan	CASE_FLT_FN (BUILT_IN_ROUND):
465169689Skan	  if (outprec < TYPE_PRECISION (long_integer_type_node)
466169689Skan	      || (outprec == TYPE_PRECISION (long_integer_type_node)
467169689Skan		  && !TYPE_UNSIGNED (type)))
468169689Skan	    fn = mathfn_built_in (s_intype, BUILT_IN_LROUND);
469169689Skan	  else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
470169689Skan		   && !TYPE_UNSIGNED (type))
471169689Skan	    fn = mathfn_built_in (s_intype, BUILT_IN_LLROUND);
472169689Skan	  break;
473169689Skan
474169689Skan	CASE_FLT_FN (BUILT_IN_NEARBYINT):
475169689Skan	  /* Only convert nearbyint* if we can ignore math exceptions.  */
476169689Skan	  if (flag_trapping_math)
477169689Skan	    break;
478169689Skan	  /* ... Fall through ...  */
479169689Skan	CASE_FLT_FN (BUILT_IN_RINT):
480169689Skan	  if (outprec < TYPE_PRECISION (long_integer_type_node)
481169689Skan	      || (outprec == TYPE_PRECISION (long_integer_type_node)
482169689Skan		  && !TYPE_UNSIGNED (type)))
483169689Skan	    fn = mathfn_built_in (s_intype, BUILT_IN_LRINT);
484169689Skan	  else if (outprec == TYPE_PRECISION (long_long_integer_type_node)
485169689Skan		   && !TYPE_UNSIGNED (type))
486169689Skan	    fn = mathfn_built_in (s_intype, BUILT_IN_LLRINT);
487169689Skan	  break;
488169689Skan
489169689Skan	CASE_FLT_FN (BUILT_IN_TRUNC):
490169689Skan	  {
491169689Skan	    tree arglist = TREE_OPERAND (s_expr, 1);
492169689Skan	    return convert_to_integer (type, TREE_VALUE (arglist));
493169689Skan	  }
494169689Skan
495169689Skan	default:
496169689Skan	  break;
497169689Skan	}
498169689Skan
499169689Skan      if (fn)
500169689Skan        {
501169689Skan	  tree arglist = TREE_OPERAND (s_expr, 1);
502169689Skan	  tree newexpr = build_function_call_expr (fn, arglist);
503169689Skan	  return convert_to_integer (type, newexpr);
504169689Skan	}
505169689Skan    }
506169689Skan
50750397Sobrien  switch (TREE_CODE (intype))
50818334Speter    {
50950397Sobrien    case POINTER_TYPE:
51050397Sobrien    case REFERENCE_TYPE:
511261188Spfg    /* APPLE LOCAL radar 6035389 */
512261188Spfg    case BLOCK_POINTER_TYPE:
51318334Speter      if (integer_zerop (expr))
514169689Skan	return build_int_cst (type, 0);
51518334Speter
516169689Skan      /* Convert to an unsigned integer of the correct width first,
517169689Skan	 and from there widen/truncate to the required type.  */
518169689Skan      expr = fold_build1 (CONVERT_EXPR,
519169689Skan			  lang_hooks.types.type_for_size (POINTER_SIZE, 0),
520169689Skan			  expr);
521169689Skan      return fold_convert (type, expr);
52218334Speter
52350397Sobrien    case INTEGER_TYPE:
52450397Sobrien    case ENUMERAL_TYPE:
52550397Sobrien    case BOOLEAN_TYPE:
52650397Sobrien      /* If this is a logical operation, which just returns 0 or 1, we can
527169689Skan	 change the type of the expression.  */
52818334Speter
529169689Skan      if (TREE_CODE_CLASS (ex_form) == tcc_comparison)
53018334Speter	{
531132718Skan	  expr = copy_node (expr);
53218334Speter	  TREE_TYPE (expr) = type;
53318334Speter	  return expr;
53418334Speter	}
53550397Sobrien
53650397Sobrien      /* If we are widening the type, put in an explicit conversion.
53750397Sobrien	 Similarly if we are not changing the width.  After this, we know
53850397Sobrien	 we are truncating EXPR.  */
53950397Sobrien
54018334Speter      else if (outprec >= inprec)
541132718Skan	{
542132718Skan	  enum tree_code code;
543169689Skan	  tree tem;
54418334Speter
545132718Skan	  /* If the precision of the EXPR's type is K bits and the
546132718Skan	     destination mode has more bits, and the sign is changing,
547132718Skan	     it is not safe to use a NOP_EXPR.  For example, suppose
548132718Skan	     that EXPR's type is a 3-bit unsigned integer type, the
549132718Skan	     TYPE is a 3-bit signed integer type, and the machine mode
550132718Skan	     for the types is 8-bit QImode.  In that case, the
551132718Skan	     conversion necessitates an explicit sign-extension.  In
552132718Skan	     the signed-to-unsigned case the high-order bits have to
553132718Skan	     be cleared.  */
554169689Skan	  if (TYPE_UNSIGNED (type) != TYPE_UNSIGNED (TREE_TYPE (expr))
555132718Skan	      && (TYPE_PRECISION (TREE_TYPE (expr))
556132718Skan		  != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr)))))
557132718Skan	    code = CONVERT_EXPR;
558132718Skan	  else
559132718Skan	    code = NOP_EXPR;
560132718Skan
561169689Skan	  tem = fold_unary (code, type, expr);
562169689Skan	  if (tem)
563169689Skan	    return tem;
564169689Skan
565169689Skan	  tem = build1 (code, type, expr);
566169689Skan	  TREE_NO_WARNING (tem) = 1;
567169689Skan	  return tem;
568132718Skan	}
569132718Skan
57018334Speter      /* If TYPE is an enumeral type or a type with a precision less
57118334Speter	 than the number of bits in its mode, do the conversion to the
57218334Speter	 type corresponding to its mode, then do a nop conversion
57318334Speter	 to TYPE.  */
57418334Speter      else if (TREE_CODE (type) == ENUMERAL_TYPE
57518334Speter	       || outprec != GET_MODE_BITSIZE (TYPE_MODE (type)))
57618334Speter	return build1 (NOP_EXPR, type,
577169689Skan		       convert (lang_hooks.types.type_for_mode
578169689Skan				(TYPE_MODE (type), TYPE_UNSIGNED (type)),
57918334Speter				expr));
58018334Speter
58118334Speter      /* Here detect when we can distribute the truncation down past some
58218334Speter	 arithmetic.  For example, if adding two longs and converting to an
58318334Speter	 int, we can equally well convert both to ints and then add.
58418334Speter	 For the operations handled here, such truncation distribution
58518334Speter	 is always safe.
58618334Speter	 It is desirable in these cases:
58718334Speter	 1) when truncating down to full-word from a larger size
58818334Speter	 2) when truncating takes no work.
58918334Speter	 3) when at least one operand of the arithmetic has been extended
59018334Speter	 (as by C's default conversions).  In this case we need two conversions
59118334Speter	 if we do the arithmetic as already requested, so we might as well
59218334Speter	 truncate both and then combine.  Perhaps that way we need only one.
59318334Speter
59418334Speter	 Note that in general we cannot do the arithmetic in a type
59518334Speter	 shorter than the desired result of conversion, even if the operands
59618334Speter	 are both extended from a shorter type, because they might overflow
59718334Speter	 if combined in that type.  The exceptions to this--the times when
59818334Speter	 two narrow values can be combined in their narrow type even to
59918334Speter	 make a wider result--are handled by "shorten" in build_binary_op.  */
60018334Speter
60118334Speter      switch (ex_form)
60218334Speter	{
60318334Speter	case RSHIFT_EXPR:
60418334Speter	  /* We can pass truncation down through right shifting
60518334Speter	     when the shift count is a nonpositive constant.  */
60618334Speter	  if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
607169689Skan	      && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) <= 0)
60818334Speter	    goto trunc1;
60918334Speter	  break;
61018334Speter
61118334Speter	case LSHIFT_EXPR:
61218334Speter	  /* We can pass truncation down through left shifting
613102780Skan	     when the shift count is a nonnegative constant and
614102780Skan	     the target type is unsigned.  */
61518334Speter	  if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
61618334Speter	      && tree_int_cst_sgn (TREE_OPERAND (expr, 1)) >= 0
617169689Skan	      && TYPE_UNSIGNED (type)
61818334Speter	      && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
61918334Speter	    {
62018334Speter	      /* If shift count is less than the width of the truncated type,
62118334Speter		 really shift.  */
62218334Speter	      if (tree_int_cst_lt (TREE_OPERAND (expr, 1), TYPE_SIZE (type)))
62318334Speter		/* In this case, shifting is like multiplication.  */
62418334Speter		goto trunc1;
62518334Speter	      else
62618334Speter		{
62718334Speter		  /* If it is >= that width, result is zero.
62818334Speter		     Handling this with trunc1 would give the wrong result:
62918334Speter		     (int) ((long long) a << 32) is well defined (as 0)
63018334Speter		     but (int) a << 32 is undefined and would get a
63118334Speter		     warning.  */
63218334Speter
633169689Skan		  tree t = build_int_cst (type, 0);
63418334Speter
63518334Speter		  /* If the original expression had side-effects, we must
63618334Speter		     preserve it.  */
63718334Speter		  if (TREE_SIDE_EFFECTS (expr))
638169689Skan		    return build2 (COMPOUND_EXPR, type, expr, t);
63918334Speter		  else
64018334Speter		    return t;
64118334Speter		}
64218334Speter	    }
64318334Speter	  break;
64418334Speter
64518334Speter	case MAX_EXPR:
64618334Speter	case MIN_EXPR:
64718334Speter	case MULT_EXPR:
64818334Speter	  {
64918334Speter	    tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
65018334Speter	    tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
65118334Speter
65218334Speter	    /* Don't distribute unless the output precision is at least as big
65318334Speter	       as the actual inputs.  Otherwise, the comparison of the
65418334Speter	       truncated values will be wrong.  */
65518334Speter	    if (outprec >= TYPE_PRECISION (TREE_TYPE (arg0))
65618334Speter		&& outprec >= TYPE_PRECISION (TREE_TYPE (arg1))
65718334Speter		/* If signedness of arg0 and arg1 don't match,
65818334Speter		   we can't necessarily find a type to compare them in.  */
659169689Skan		&& (TYPE_UNSIGNED (TREE_TYPE (arg0))
660169689Skan		    == TYPE_UNSIGNED (TREE_TYPE (arg1))))
66118334Speter	      goto trunc1;
66218334Speter	    break;
66318334Speter	  }
66418334Speter
66518334Speter	case PLUS_EXPR:
66618334Speter	case MINUS_EXPR:
66718334Speter	case BIT_AND_EXPR:
66818334Speter	case BIT_IOR_EXPR:
66918334Speter	case BIT_XOR_EXPR:
67018334Speter	trunc1:
67118334Speter	  {
67218334Speter	    tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
67318334Speter	    tree arg1 = get_unwidened (TREE_OPERAND (expr, 1), type);
67418334Speter
67518334Speter	    if (outprec >= BITS_PER_WORD
67618334Speter		|| TRULY_NOOP_TRUNCATION (outprec, inprec)
67718334Speter		|| inprec > TYPE_PRECISION (TREE_TYPE (arg0))
67818334Speter		|| inprec > TYPE_PRECISION (TREE_TYPE (arg1)))
67918334Speter	      {
68018334Speter		/* Do the arithmetic in type TYPEX,
68118334Speter		   then convert result to TYPE.  */
68290075Sobrien		tree typex = type;
68318334Speter
68418334Speter		/* Can't do arithmetic in enumeral types
68518334Speter		   so use an integer type that will hold the values.  */
68618334Speter		if (TREE_CODE (typex) == ENUMERAL_TYPE)
687169689Skan		  typex = lang_hooks.types.type_for_size
688169689Skan		    (TYPE_PRECISION (typex), TYPE_UNSIGNED (typex));
68918334Speter
69018334Speter		/* But now perhaps TYPEX is as wide as INPREC.
69118334Speter		   In that case, do nothing special here.
69218334Speter		   (Otherwise would recurse infinitely in convert.  */
69318334Speter		if (TYPE_PRECISION (typex) != inprec)
69418334Speter		  {
69518334Speter		    /* Don't do unsigned arithmetic where signed was wanted,
69618334Speter		       or vice versa.
69790075Sobrien		       Exception: if both of the original operands were
698132718Skan		       unsigned then we can safely do the work as unsigned.
699117395Skan		       Exception: shift operations take their type solely
700117395Skan		       from the first argument.
701117395Skan		       Exception: the LSHIFT_EXPR case above requires that
702117395Skan		       we perform this operation unsigned lest we produce
703117395Skan		       signed-overflow undefinedness.
70418334Speter		       And we may need to do it as unsigned
70518334Speter		       if we truncate to the original size.  */
706169689Skan		    if (TYPE_UNSIGNED (TREE_TYPE (expr))
707169689Skan			|| (TYPE_UNSIGNED (TREE_TYPE (arg0))
708169689Skan			    && (TYPE_UNSIGNED (TREE_TYPE (arg1))
709117395Skan				|| ex_form == LSHIFT_EXPR
710117395Skan				|| ex_form == RSHIFT_EXPR
711117395Skan				|| ex_form == LROTATE_EXPR
712117395Skan				|| ex_form == RROTATE_EXPR))
713169689Skan			|| ex_form == LSHIFT_EXPR
714169689Skan			/* If we have !flag_wrapv, and either ARG0 or
715169689Skan			   ARG1 is of a signed type, we have to do
716169689Skan			   PLUS_EXPR or MINUS_EXPR in an unsigned
717169689Skan			   type.  Otherwise, we would introduce
718169689Skan			   signed-overflow undefinedness.  */
719169689Skan			|| ((!TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0))
720169689Skan			     || !TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg1)))
721169689Skan			    && (ex_form == PLUS_EXPR
722169689Skan				|| ex_form == MINUS_EXPR)))
723169689Skan		      typex = lang_hooks.types.unsigned_type (typex);
724117395Skan		    else
725169689Skan		      typex = lang_hooks.types.signed_type (typex);
72618334Speter		    return convert (type,
727169689Skan				    fold_build2 (ex_form, typex,
72818334Speter						 convert (typex, arg0),
729169689Skan						 convert (typex, arg1)));
73018334Speter		  }
73118334Speter	      }
73218334Speter	  }
73318334Speter	  break;
73418334Speter
73518334Speter	case NEGATE_EXPR:
73618334Speter	case BIT_NOT_EXPR:
73718334Speter	  /* This is not correct for ABS_EXPR,
73818334Speter	     since we must test the sign before truncation.  */
73918334Speter	  {
740169689Skan	    tree typex;
74118334Speter
742169689Skan	    /* Don't do unsigned arithmetic where signed was wanted,
743169689Skan	       or vice versa.  */
744169689Skan	    if (TYPE_UNSIGNED (TREE_TYPE (expr)))
745169689Skan	      typex = lang_hooks.types.unsigned_type (type);
746169689Skan	    else
747169689Skan	      typex = lang_hooks.types.signed_type (type);
748169689Skan	    return convert (type,
749169689Skan			    fold_build1 (ex_form, typex,
750169689Skan					 convert (typex,
751169689Skan						  TREE_OPERAND (expr, 0))));
75218334Speter	  }
75318334Speter
75418334Speter	case NOP_EXPR:
755117395Skan	  /* Don't introduce a
756117395Skan	     "can't convert between vector values of different size" error.  */
757117395Skan	  if (TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == VECTOR_TYPE
758117395Skan	      && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_OPERAND (expr, 0))))
759117395Skan		  != GET_MODE_SIZE (TYPE_MODE (type))))
760117395Skan	    break;
76118334Speter	  /* If truncating after truncating, might as well do all at once.
76218334Speter	     If truncating after extending, we may get rid of wasted work.  */
76318334Speter	  return convert (type, get_unwidened (TREE_OPERAND (expr, 0), type));
76418334Speter
76518334Speter	case COND_EXPR:
76650397Sobrien	  /* It is sometimes worthwhile to push the narrowing down through
76750397Sobrien	     the conditional and never loses.  */
768169689Skan	  return fold_build3 (COND_EXPR, type, TREE_OPERAND (expr, 0),
769132718Skan			      convert (type, TREE_OPERAND (expr, 1)),
770169689Skan			      convert (type, TREE_OPERAND (expr, 2)));
77118334Speter
77250397Sobrien	default:
77350397Sobrien	  break;
77418334Speter	}
77518334Speter
776169689Skan      return build1 (CONVERT_EXPR, type, expr);
77718334Speter
77850397Sobrien    case REAL_TYPE:
77950397Sobrien      return build1 (FIX_TRUNC_EXPR, type, expr);
78018334Speter
78150397Sobrien    case COMPLEX_TYPE:
78250397Sobrien      return convert (type,
783169689Skan		      fold_build1 (REALPART_EXPR,
784169689Skan				   TREE_TYPE (TREE_TYPE (expr)), expr));
78518334Speter
78690075Sobrien    case VECTOR_TYPE:
787169689Skan      if (!tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (expr))))
78890075Sobrien	{
78990075Sobrien	  error ("can't convert between vector values of different size");
79090075Sobrien	  return error_mark_node;
79190075Sobrien	}
792169689Skan      return build1 (VIEW_CONVERT_EXPR, type, expr);
79390075Sobrien
79450397Sobrien    default:
79550397Sobrien      error ("aggregate value used where an integer was expected");
79650397Sobrien      return convert (type, integer_zero_node);
79750397Sobrien    }
79818334Speter}
79918334Speter
80018334Speter/* Convert EXPR to the complex type TYPE in the usual ways.  */
80118334Speter
80218334Spetertree
803132718Skanconvert_to_complex (tree type, tree expr)
80418334Speter{
80518334Speter  tree subtype = TREE_TYPE (type);
806132718Skan
80750397Sobrien  switch (TREE_CODE (TREE_TYPE (expr)))
80818334Speter    {
80950397Sobrien    case REAL_TYPE:
81050397Sobrien    case INTEGER_TYPE:
81150397Sobrien    case ENUMERAL_TYPE:
81250397Sobrien    case BOOLEAN_TYPE:
813169689Skan      return build2 (COMPLEX_EXPR, type, convert (subtype, expr),
814169689Skan		     convert (subtype, integer_zero_node));
81518334Speter
81650397Sobrien    case COMPLEX_TYPE:
81750397Sobrien      {
81850397Sobrien	tree elt_type = TREE_TYPE (TREE_TYPE (expr));
81950397Sobrien
82050397Sobrien	if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
82150397Sobrien	  return expr;
82250397Sobrien	else if (TREE_CODE (expr) == COMPLEX_EXPR)
823169689Skan	  return fold_build2 (COMPLEX_EXPR, type,
82450397Sobrien			      convert (subtype, TREE_OPERAND (expr, 0)),
825169689Skan			      convert (subtype, TREE_OPERAND (expr, 1)));
82650397Sobrien	else
82750397Sobrien	  {
82850397Sobrien	    expr = save_expr (expr);
82950397Sobrien	    return
830169689Skan	      fold_build2 (COMPLEX_EXPR, type,
83150397Sobrien			   convert (subtype,
832169689Skan				    fold_build1 (REALPART_EXPR,
833169689Skan						 TREE_TYPE (TREE_TYPE (expr)),
834169689Skan						 expr)),
835169689Skan			   convert (subtype,
836169689Skan				    fold_build1 (IMAGPART_EXPR,
837169689Skan						 TREE_TYPE (TREE_TYPE (expr)),
838169689Skan						 expr)));
83950397Sobrien	  }
84050397Sobrien      }
84150397Sobrien
84250397Sobrien    case POINTER_TYPE:
84350397Sobrien    case REFERENCE_TYPE:
84450397Sobrien      error ("pointer value used where a complex was expected");
84550397Sobrien      return convert_to_complex (type, integer_zero_node);
84650397Sobrien
84750397Sobrien    default:
84850397Sobrien      error ("aggregate value used where a complex was expected");
84950397Sobrien      return convert_to_complex (type, integer_zero_node);
85018334Speter    }
85118334Speter}
85290075Sobrien
85390075Sobrien/* Convert EXPR to the vector type TYPE in the usual ways.  */
85490075Sobrien
85590075Sobrientree
856132718Skanconvert_to_vector (tree type, tree expr)
85790075Sobrien{
85890075Sobrien  switch (TREE_CODE (TREE_TYPE (expr)))
85990075Sobrien    {
86090075Sobrien    case INTEGER_TYPE:
86190075Sobrien    case VECTOR_TYPE:
862169689Skan      if (!tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (expr))))
86390075Sobrien	{
86490075Sobrien	  error ("can't convert between vector values of different size");
86590075Sobrien	  return error_mark_node;
86690075Sobrien	}
867169689Skan      return build1 (VIEW_CONVERT_EXPR, type, expr);
86890075Sobrien
86990075Sobrien    default:
87090075Sobrien      error ("can't convert value to a vector");
871169689Skan      return error_mark_node;
87290075Sobrien    }
87390075Sobrien}
874