]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/convert.c
pa.md (uncond_branch): New type attribute.
[gcc.git] / gcc / convert.c
index c67f510188c201d7c4770dc6727d59cd018e5285..d073ac3ee625fa707334b60cdc9db2803ec4a85e 100644 (file)
@@ -56,7 +56,9 @@ convert_to_pointer (type, expr)
       if (type_precision (intype) == POINTER_SIZE)
        return build1 (CONVERT_EXPR, type, expr);
       expr = convert (type_for_size (POINTER_SIZE, 0), expr);
-      if (TYPE_MODE (TREE_TYPE (expr)) != TYPE_MODE (type))
+      /* Modes may be different but sizes should be the same.  */
+      if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr)))
+         != GET_MODE_SIZE (TYPE_MODE (type)))
        /* There is supposed to be some integral type
           that is the same width as a pointer.  */
        abort ();
@@ -86,6 +88,10 @@ convert_to_real (type, expr)
   if (form == INTEGER_TYPE || form == ENUMERAL_TYPE)
     return build1 (FLOAT_EXPR, type, expr);
 
+  if (form == COMPLEX_TYPE)
+    return convert (type, fold (build1 (REALPART_EXPR,
+                                       TREE_TYPE (TREE_TYPE (expr)), expr)));
+
   if (form == POINTER_TYPE)
     error ("pointer value used where a floating point value was expected");
   else
@@ -94,7 +100,7 @@ convert_to_real (type, expr)
   {
     register tree tem = make_node (REAL_CST);
     TREE_TYPE (tem) = type;
-    TREE_REAL_CST (tem) = REAL_VALUE_ATOF ("0.0");
+    TREE_REAL_CST (tem) = REAL_VALUE_ATOF ("0.0", TYPE_MODE (type));
     return tem;
   }
 }
@@ -193,11 +199,22 @@ convert_to_integer (type, expr)
                /* In this case, shifting is like multiplication.  */
                goto trunc1;
              else
-               /* If it is >= that width, result is zero.
-                  Handling this with trunc1 would give the wrong result:
-                  (int) ((long long) a << 32) is well defined (as 0)
-                  but (int) a << 32 is undefined and would get a warning.  */
-               return convert_to_integer (type, integer_zero_node);
+               {
+                 /* If it is >= that width, result is zero.
+                    Handling this with trunc1 would give the wrong result:
+                    (int) ((long long) a << 32) is well defined (as 0)
+                    but (int) a << 32 is undefined and would get a
+                    warning.  */
+
+                 tree t = convert_to_integer (type, integer_zero_node);
+
+                 /* If the original expression had side-effects, we must
+                    preserve it.  */
+                 if (TREE_SIDE_EFFECTS (expr))
+                   return build (COMPOUND_EXPR, type, expr, t);
+                 else
+                   return t;
+               }
            }
          break;
 
@@ -263,10 +280,10 @@ convert_to_integer (type, expr)
                              || TREE_UNSIGNED (TREE_TYPE (arg1)))
                             ? unsigned_type (typex) : signed_type (typex));
                    return convert (type,
-                                   build_binary_op (ex_form,
-                                                    convert (typex, arg0),
-                                                    convert (typex, arg1),
-                                                    0));
+                                   fold (build (ex_form, typex,
+                                                convert (typex, arg0),
+                                                convert (typex, arg1),
+                                                0)));
                  }
              }
          }
@@ -294,9 +311,9 @@ convert_to_integer (type, expr)
                typex = (TREE_UNSIGNED (TREE_TYPE (expr))
                         ? unsigned_type (typex) : signed_type (typex));
                return convert (type,
-                               build_unary_op (ex_form,
-                                               convert (typex, TREE_OPERAND (expr, 0)),
-                                               1));
+                               fold (build1 (ex_form, typex,
+                                             convert (typex,
+                                                      TREE_OPERAND (expr, 0)))));
              }
          }
 
@@ -360,6 +377,10 @@ convert_to_integer (type, expr)
   if (form == REAL_TYPE)
     return build1 (FIX_TRUNC_EXPR, type, expr);
 
+  if (form == COMPLEX_TYPE)
+    return convert (type, fold (build1 (REALPART_EXPR,
+                                       TREE_TYPE (TREE_TYPE (expr)), expr)));
+
   error ("aggregate value used where an integer was expected");
 
   {
@@ -368,3 +389,55 @@ convert_to_integer (type, expr)
     return tem;
   }
 }
+
+/* Convert EXPR to the complex type TYPE in the usual ways.  */
+
+tree
+convert_to_complex (type, expr)
+     tree type, expr;
+{
+  register enum tree_code form = TREE_CODE (TREE_TYPE (expr));
+  tree subtype = TREE_TYPE (type);
+  
+  if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE)
+    {
+      expr = convert (subtype, expr);
+      return build (COMPLEX_EXPR, type, expr,
+                   convert (subtype, integer_zero_node));
+    }
+
+  if (form == COMPLEX_TYPE)
+    {
+      tree elt_type = TREE_TYPE (TREE_TYPE (expr));
+      if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype))
+       return expr;
+      else if (TREE_CODE (expr) == COMPLEX_EXPR)
+       return fold (build (COMPLEX_EXPR,
+                           type,
+                           convert (subtype, TREE_OPERAND (expr, 0)),
+                           convert (subtype, TREE_OPERAND (expr, 1))));
+      else
+       {
+         expr = save_expr (expr);
+         return fold (build (COMPLEX_EXPR,
+                             type,
+                             convert (subtype,
+                                      fold (build1 (REALPART_EXPR,
+                                                    TREE_TYPE (TREE_TYPE (expr)),
+                                                    expr))),
+                             convert (subtype,
+                                      fold (build1 (IMAGPART_EXPR,
+                                                    TREE_TYPE (TREE_TYPE (expr)),
+                                                    expr)))));
+       }
+    }
+
+  if (form == POINTER_TYPE)
+    error ("pointer value used where a complex was expected");
+  else
+    error ("aggregate value used where a complex was expected");
+  
+  return build (COMPLEX_EXPR, type,
+               convert (subtype, integer_zero_node),
+               convert (subtype, integer_zero_node));
+}
This page took 0.034351 seconds and 5 git commands to generate.