Correctly handle "all fp" types.
authorJustin Seyster <jseyster@cs.sunysb.edu>
Tue, 24 Aug 2010 22:30:04 +0000 (18:30 -0400)
committerJustin Seyster <jseyster@cs.sunysb.edu>
Tue, 24 Aug 2010 22:30:04 +0000 (18:30 -0400)
src/aop-type.c
src/aop-type.h
src/aop-weave.c

index 5e632b512576829be23fb6700a02024b92e02d06..36df28c0e3d8812ed950af492dd46fadd4bb6a36 100644 (file)
@@ -50,7 +50,7 @@ static struct aop_type _aop_t_all_unsigned = {
 };
 
 static struct aop_type _aop_t_all_fp = {
-  .kind = ATK_ALL_FP,
+  .kind = ATK_FP,
   .pointer_levels = 0,
   .tag = NULL,
 
@@ -338,6 +338,13 @@ is_all_integer_type (const struct aop_type *type)
          && type->size <= 0);
 }
 
+/* Returns true if specified type is an "all fp" type. */
+bool
+is_all_fp_type (const struct aop_type *type)
+{
+  return ((type->kind == ATK_FP) && type->size <= 0);
+}
+
 static bool
 does_int_type_match (tree gcc_type, enum aop_tykind kind, int aop_size)
 {
@@ -366,6 +373,28 @@ does_int_type_match (tree gcc_type, enum aop_tykind kind, int aop_size)
     return (gcc_size > 0 && gcc_size <= 8);
 }
 
+static bool
+does_fp_type_match (tree gcc_type, int aop_size)
+{
+  if (TREE_CODE (gcc_type) == REAL_TYPE)
+    {
+      HOST_WIDE_INT gcc_size = int_size_in_bytes (gcc_type);
+
+      /* If aop_size is zero (or negative_ we treat it as the "all fp"
+        type, which will match any "standard" size floating point
+        type.  float and double are standard size floating point
+        types. */
+      if (aop_size > 0)
+       return (aop_size == gcc_size);
+      else
+       return (gcc_size > 0 && gcc_size <= 8);
+    }
+  else
+    {
+      return false;
+    }
+}
+
 /* Match an actual GCC type with an AOP type specification. */
 bool
 does_type_match (tree gcc_type, const struct aop_type *aop_type)
@@ -383,8 +412,8 @@ does_type_match (tree gcc_type, const struct aop_type *aop_type)
        case ATK_SIGNED_INT:
        case ATK_UNSIGNED_INT:
          return does_int_type_match (gcc_type, aop_type->kind, aop_type->size);
-       case ATK_ALL_FP:
-         return (TREE_CODE (gcc_type) == REAL_TYPE);
+       case ATK_FP:
+         return does_fp_type_match (gcc_type, aop_type->size);
        default:
          break;
        }
index a8c5754b1c15d461cc6f3b2635eb264cc205f417..5d3ca044ee7ddeab9bbc2c84a5efe903e9e44789 100644 (file)
@@ -21,7 +21,7 @@
 enum aop_tykind {
   ATK_SIGNED_INT,
   ATK_UNSIGNED_INT,
-  ATK_ALL_FP,
+  ATK_FP,
   ATK_ALL_POINTER,
 
   ATK_STRUCT,
@@ -38,6 +38,7 @@ struct aop_type {
 };
 
 extern bool is_all_integer_type (const struct aop_type *type);
+extern bool is_all_fp_type (const struct aop_type *type);
 extern bool does_type_match (tree gcc_type, const struct aop_type *aop_type);
 
 #endif
index 745aa2fd14aa83225ec1cb06c0f5f3b76db4038a..6c4f292fbb861702025a7f709df95886ed97999f 100644 (file)
@@ -118,6 +118,30 @@ cast_to_all_integer (tree val)
     }
 }
 
+static tree
+cast_to_all_fp (tree val)
+{
+  tree gcc_type;
+  HOST_WIDE_INT size;
+
+  gcc_type = TREE_TYPE (val);
+  aop_assert (TREE_CODE (gcc_type) == REAL_TYPE);
+
+  size = int_size_in_bytes (gcc_type);
+  aop_assert (size > 0 && size <= 8);
+
+  if (size != 8)
+    {
+      val = build1 (CONVERT_EXPR, double_type_node, val);
+      return val;
+    }
+  else
+    {
+      /* No cast necessary. */
+      return val;
+    }
+}
+
 static tree
 build_dynval (struct aop_dynval *dv)
 {
@@ -127,6 +151,8 @@ build_dynval (struct aop_dynval *dv)
 
   if (is_all_integer_type (dv->type))
     val = cast_to_all_integer (val);
+  else if (is_all_fp_type (dv->type))
+    val = cast_to_all_fp (val);
 
   return val;
 }