#include "aop-type.h"
static struct aop_type _aop_t_all_signed = {
- .kind = ATK_ALL_SIGNED,
+ .kind = ATK_SIGNED_INT,
.pointer_levels = 0,
.tag = NULL,
+
+ .size = 0,
};
static struct aop_type _aop_t_all_unsigned = {
- .kind = ATK_ALL_UNSIGNED,
+ .kind = ATK_UNSIGNED_INT,
.pointer_levels = 0,
.tag = NULL,
+
+ .size = 0,
};
static struct aop_type _aop_t_all_fp = {
.kind = ATK_ALL_FP,
.pointer_levels = 0,
.tag = NULL,
+
+ .size = 0,
};
static struct aop_type _aop_t_all_pointer = {
.kind = ATK_ALL_POINTER,
.pointer_levels = 0,
.tag = NULL,
+
+ .size = 0,
+};
+
+static struct aop_type _aop_t_signed8 = {
+ .kind = ATK_SIGNED_INT,
+ .pointer_levels = 0,
+ .tag = NULL,
+
+ .size = 1,
+};
+
+static struct aop_type _aop_t_signed16 = {
+ .kind = ATK_SIGNED_INT,
+ .pointer_levels = 0,
+ .tag = NULL,
+
+ .size = 2,
+};
+
+static struct aop_type _aop_t_signed32 = {
+ .kind = ATK_SIGNED_INT,
+ .pointer_levels = 0,
+ .tag = NULL,
+
+ .size = 4,
+};
+
+static struct aop_type _aop_t_signed64 = {
+ .kind = ATK_SIGNED_INT,
+ .pointer_levels = 0,
+ .tag = NULL,
+
+ .size = 8,
+};
+
+static struct aop_type _aop_t_signed128 = {
+ .kind = ATK_SIGNED_INT,
+ .pointer_levels = 0,
+ .tag = NULL,
+
+ .size = 16,
+};
+
+static struct aop_type _aop_t_unsigned8 = {
+ .kind = ATK_UNSIGNED_INT,
+ .pointer_levels = 0,
+ .tag = NULL,
+
+ .size = 1,
+};
+
+static struct aop_type _aop_t_unsigned16 = {
+ .kind = ATK_UNSIGNED_INT,
+ .pointer_levels = 0,
+ .tag = NULL,
+
+ .size = 2,
+};
+
+static struct aop_type _aop_t_unsigned32 = {
+ .kind = ATK_UNSIGNED_INT,
+ .pointer_levels = 0,
+ .tag = NULL,
+
+ .size = 4,
+};
+
+static struct aop_type _aop_t_unsigned64 = {
+ .kind = ATK_UNSIGNED_INT,
+ .pointer_levels = 0,
+ .tag = NULL,
+
+ .size = 8,
+};
+
+static struct aop_type _aop_t_unsigned128 = {
+ .kind = ATK_UNSIGNED_INT,
+ .pointer_levels = 0,
+ .tag = NULL,
+
+ .size = 16,
};
/**
return &_aop_t_all_pointer;
}
-/* True if this is an integer type (signed or unsigned) between int8
- and int64. */
+const struct aop_type *
+aop_t_signed8 ()
+{
+ return &_aop_t_signed8;
+}
+
+const struct aop_type *
+aop_t_signed16 ()
+{
+ return &_aop_t_signed16;
+}
+
+const struct aop_type *
+aop_t_signed32 ()
+{
+ return &_aop_t_signed32;
+}
+
+const struct aop_type *
+aop_t_signed64 ()
+{
+ return &_aop_t_signed64;
+}
+
+const struct aop_type *
+aop_t_signed128 ()
+{
+ return &_aop_t_signed128;
+}
+
+const struct aop_type *
+aop_t_unsigned8 ()
+{
+ return &_aop_t_unsigned8;
+}
+
+const struct aop_type *
+aop_t_unsigned16 ()
+{
+ return &_aop_t_unsigned16;
+}
+
+const struct aop_type *
+aop_t_unsigned32 ()
+{
+ return &_aop_t_unsigned32;
+}
+
+const struct aop_type *
+aop_t_unsigned64 ()
+{
+ return &_aop_t_unsigned64;
+}
+
+const struct aop_type *
+aop_t_unsigned128 ()
+{
+ return &_aop_t_unsigned128;
+}
+
+/* Returns true if specified type is an "all signed" or "all unsigned"
+ type. */
+bool
+is_all_integer_type (const struct aop_type *type)
+{
+ return ((type->kind == ATK_SIGNED_INT || type->kind == ATK_UNSIGNED_INT)
+ && type->size <= 0);
+}
+
static bool
-is_stdint_type (tree gcc_type)
+does_int_type_match (tree gcc_type, enum aop_tykind kind, int aop_size)
{
- if (TREE_CODE (gcc_type) == INTEGER_TYPE)
- {
- HOST_WIDE_INT size = int_size_in_bytes (gcc_type);
- return (size > 0 && size <= 8);
- }
+ HOST_WIDE_INT gcc_size;
+
+ aop_assert (kind == ATK_SIGNED_INT || kind == ATK_UNSIGNED_INT);
+
+ if (TREE_CODE (gcc_type) != INTEGER_TYPE)
+ return false;
+
+ gcc_size = int_size_in_bytes (gcc_type);
+
+ /* Types do not match if one is unsigned and one is signed. */
+ if (kind == ATK_SIGNED_INT && TYPE_UNSIGNED (gcc_type))
+ return false;
+ else if (kind == ATK_UNSIGNED_INT && !TYPE_UNSIGNED (gcc_type))
+ return false;
+
+ /* If aop_size is zero (or negative) we treat it as the "all signed"
+ or all "all unsigned" type, which will match any "standard" size
+ integer. int64_t and uint64_t are the largest standard size
+ integer. */
+ if (aop_size > 0)
+ return (aop_size == gcc_size);
else
- {
- return false;
- }
+ return (gcc_size > 0 && gcc_size <= 8);
}
/* Match an actual GCC type with an AOP type specification. */
{
switch (aop_type->kind)
{
- case ATK_ALL_SIGNED:
- return (is_stdint_type (gcc_type) && !TYPE_UNSIGNED (gcc_type));
- case ATK_ALL_UNSIGNED:
- return (is_stdint_type (gcc_type) && TYPE_UNSIGNED (gcc_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);
default:
extern const struct aop_type *aop_t_all_fp ();
extern const struct aop_type *aop_t_all_pointer ();
+extern const struct aop_type *aop_t_signed8 ();
+extern const struct aop_type *aop_t_signed16 ();
+extern const struct aop_type *aop_t_signed32 ();
+extern const struct aop_type *aop_t_signed64 ();
+extern const struct aop_type *aop_t_signed128 ();
+extern const struct aop_type *aop_t_unsigned8 ();
+extern const struct aop_type *aop_t_unsigned16 ();
+extern const struct aop_type *aop_t_unsigned32 ();
+extern const struct aop_type *aop_t_unsigned64 ();
+extern const struct aop_type *aop_t_unsigned128 ();
+
extern void aop_register_pass (const char *pass_name, pass_callback callback);
extern void aop_join_on (struct aop_pointcut *pc, join_callback callback,
void *callback_param);