};
static struct aop_type _aop_t_all_fp = {
- .kind = ATK_ALL_FP,
+ .kind = ATK_FP,
.pointer_levels = 0,
.tag = NULL,
&& 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)
{
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)
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;
}
enum aop_tykind {
ATK_SIGNED_INT,
ATK_UNSIGNED_INT,
- ATK_ALL_FP,
+ ATK_FP,
ATK_ALL_POINTER,
ATK_STRUCT,
};
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
}
}
+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)
{
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;
}