This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] ARM half-precision floating point, 3/8 (target hooks)
- From: Sandra Loosemore <sandra at codesourcery dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 15 Apr 2009 18:20:59 -0400
- Subject: [PATCH] ARM half-precision floating point, 3/8 (target hooks)
This patch adds the target hooks that are required to get the C and
C++ language-level support for HFmode, specifically including the
implicit promotion and restrictions on function argument/return types.
The included documentation patch should be sufficient to explain the
details.
-Sandra
2009-04-15 Sandra Loosemore <sandra@codesourcery.com>
gcc/
* doc/tm.texi (Misc): Document TARGET_INVALID_PARAMETER_TYPE,
TARGET_INVALID_RETURN_TYPE, TARGET_PROMOTED_TYPE, and
TARGET_CONVERT_TO_TYPE.
* hooks.c (hook_tree_const_tree_null): Define.
* hooks.h (hook_tree_const_tree_null): Declare.
* target.h (struct gcc_target): Add invalid_parameter_type,
invalid_return_type, promoted_type, and convert_to_type fields.
* target-def.h: (TARGET_INVALID_PARAMETER_TYPE): Define.
(TARGET_INVALID_RETURN_TYPE): Define.
(TARGET_PROMOTED_TYPE): Define.
(TARGET_CONVERT_TO_TYPE): Define.
(TARGET_INITIALIZER): Update for new fields.
* c-decl.c (grokdeclarator): Check targetm.invalid_return_type.
(grokparms): Check targetm.invalid_parameter_type.
* c-typeck.c (default_conversion): Check targetm.promoted_type.
* c-convert.c (convert): Check targetm.convert_to_type.
* cp/typeck.c (default_conversion): Check targetm.promoted_type.
* cp/decl.c (grokdeclarator): Check targetm.invalid_return_type.
(grokparms): Check targetm.invalid_parameter_type.
* cp/cvt.c (ocp_convert): Check targetm.convert_to_type.
(build_expr_type_conversion): Check targetm.promoted_type.
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi (revision 146010)
+++ gcc/doc/tm.texi (working copy)
@@ -10684,6 +10684,36 @@ and @var{type2}, or @code{NULL} if valid
the front end.
@end deftypefn
+@deftypefn {Target Hook} {const char *} TARGET_INVALID_PARAMETER_TYPE (tree @var{type})
+If defined, this macro returns the diagnostic message when it is
+invalid for functions to include parameters of type @var{type},
+or @code{NULL} if validity should be determined by
+the front end.
+@end deftypefn
+
+@deftypefn {Target Hook} {const char *} TARGET_INVALID_RETURN_TYPE (tree @var{type})
+If defined, this macro returns the diagnostic message when it is
+invalid for functions to have return type @var{type},
+or @code{NULL} if validity should be determined by
+the front end.
+@end deftypefn
+
+@deftypefn {Target Hook} {tree} TARGET_PROMOTED_TYPE (tree @var{type})
+If defined, this target hook returns the type to which values of
+@var{type} should be promoted when they appear in expressions,
+analogous to the integer promotions, or @code{NULL_TREE} to use the
+front end's normal promotion rules. This hook is useful when there are
+target-specific types with special promotion rules.
+@end deftypefn
+
+@deftypefn {Target Hook} {tree} TARGET_CONVERT_TO_TYPE (tree @var{type}, tree @var{expr})
+If defined, this hook returns the result of converting @var{expr} to
+@var{type}. It should return the converted expression,
+or @code{NULL_TREE} to apply the front end's normal conversion rules.
+This hook is useful when there are target-specific types with special
+conversion rules.
+@end deftypefn
+
@defmac TARGET_USE_JCR_SECTION
This macro determines whether to use the JCR section to register Java
classes. By default, TARGET_USE_JCR_SECTION is defined to 1 if both
Index: gcc/hooks.c
===================================================================
--- gcc/hooks.c (revision 146010)
+++ gcc/hooks.c (working copy)
@@ -335,3 +335,10 @@ hook_constcharptr_int_const_tree_const_t
{
return NULL;
}
+
+/* Generic hook that takes a const_tree and returns NULL_TREE. */
+tree
+hook_tree_const_tree_null (const_tree t ATTRIBUTE_UNUSED)
+{
+ return NULL;
+}
Index: gcc/hooks.h
===================================================================
--- gcc/hooks.h (revision 146010)
+++ gcc/hooks.h (working copy)
@@ -64,6 +64,8 @@ extern int hook_int_rtx_bool_0 (rtx, boo
extern int hook_int_size_t_constcharptr_int_0 (size_t, const char *, int);
extern int hook_int_void_no_regs (void);
+extern tree hook_tree_const_tree_null (const_tree);
+
extern tree hook_tree_tree_tree_null (tree, tree);
extern tree hook_tree_tree_tree_tree_null (tree, tree, tree);
extern tree hook_tree_tree_tree_tree_3rd_identity (tree, tree, tree);
Index: gcc/target.h
===================================================================
--- gcc/target.h (revision 146010)
+++ gcc/target.h (working copy)
@@ -901,6 +901,24 @@ struct gcc_target
is not permitted on TYPE1 and TYPE2, NULL otherwise. */
const char *(*invalid_binary_op) (int op, const_tree type1, const_tree type2);
+ /* Return the diagnostic message string if TYPE is not valid as a
+ function parameter type, NULL otherwise. */
+ const char *(*invalid_parameter_type) (const_tree type);
+
+ /* Return the diagnostic message string if TYPE is not valid as a
+ function return type, NULL otherwise. */
+ const char *(*invalid_return_type) (const_tree type);
+
+ /* If values of TYPE are promoted to some other type when used in
+ expressions (analogous to the integer promotions), return that type,
+ or NULL_TREE otherwise. */
+ tree (*promoted_type) (const_tree type);
+
+ /* Convert EXPR to TYPE, if target-specific types with special conversion
+ rules are involved. Return the converted expression, or NULL to apply
+ the standard conversion rules. */
+ tree (*convert_to_type) (tree type, tree expr);
+
/* Return the array of IRA cover classes for the current target. */
const enum reg_class *(*ira_cover_classes) (void);
Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c (revision 146010)
+++ gcc/cp/typeck.c (working copy)
@@ -1699,10 +1699,14 @@ decay_conversion (tree exp)
tree
default_conversion (tree exp)
{
+ /* Check for target-specific promotions. */
+ tree promoted_type = targetm.promoted_type (TREE_TYPE (exp));
+ if (promoted_type)
+ exp = cp_convert (promoted_type, exp);
/* Perform the integral promotions first so that bitfield
expressions (which may promote to "int", even if the bitfield is
declared "unsigned") are promoted correctly. */
- if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (exp)))
+ else if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (exp)))
exp = perform_integral_promotions (exp);
/* Perform the other conversions. */
exp = decay_conversion (exp);
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c (revision 146010)
+++ gcc/cp/decl.c (working copy)
@@ -7607,6 +7607,7 @@ grokdeclarator (const cp_declarator *dec
bool parameter_pack_p = declarator? declarator->parameter_pack_p : false;
bool set_no_warning = false;
bool template_type_arg = false;
+ const char *errmsg;
signed_p = declspecs->specs[(int)ds_signed];
unsigned_p = declspecs->specs[(int)ds_unsigned];
@@ -8286,6 +8287,12 @@ grokdeclarator (const cp_declarator *dec
type_quals = TYPE_UNQUALIFIED;
set_no_warning = true;
}
+ errmsg = targetm.invalid_return_type (type);
+ if (errmsg)
+ {
+ error (errmsg);
+ type = integer_type_node;
+ }
/* Error about some types functions can't return. */
@@ -9665,6 +9672,7 @@ grokparms (tree parmlist, tree *parms)
tree type = NULL_TREE;
tree init = TREE_PURPOSE (parm);
tree decl = TREE_VALUE (parm);
+ const char *errmsg;
if (parm == void_list_node)
break;
@@ -9698,6 +9706,14 @@ grokparms (tree parmlist, tree *parms)
init = NULL_TREE;
}
+ if (type != error_mark_node
+ && (errmsg = targetm.invalid_parameter_type (type)))
+ {
+ error (errmsg);
+ type = error_mark_node;
+ TREE_TYPE (decl) = error_mark_node;
+ }
+
if (type != error_mark_node)
{
if (deprecated_state != DEPRECATED_SUPPRESS)
Index: gcc/cp/cvt.c
===================================================================
--- gcc/cp/cvt.c (revision 146010)
+++ gcc/cp/cvt.c (working copy)
@@ -581,6 +581,7 @@ ocp_convert (tree type, tree expr, int c
tree e = expr;
enum tree_code code = TREE_CODE (type);
const char *invalid_conv_diag;
+ tree e1;
if (error_operand_p (e) || type == error_mark_node)
return error_mark_node;
@@ -629,6 +630,9 @@ ocp_convert (tree type, tree expr, int c
}
}
+ if ((e1 = targetm.convert_to_type (type, e)))
+ return e1;
+
if (code == VOID_TYPE && (convtype & CONV_STATIC))
{
e = convert_to_void (e, /*implicit=*/NULL, tf_warning_or_error);
@@ -1224,11 +1228,18 @@ build_expr_type_conversion (int desires,
tree
type_promotes_to (tree type)
{
+ tree promoted_type;
+
if (type == error_mark_node)
return error_mark_node;
type = TYPE_MAIN_VARIANT (type);
+ /* Check for promotions of target-defined types first. */
+ promoted_type = targetm.promoted_type (type);
+ if (promoted_type)
+ return promoted_type;
+
/* bool always promotes to int (not unsigned), even if it's the same
size. */
if (type == boolean_type_node)
Index: gcc/c-decl.c
===================================================================
--- gcc/c-decl.c (revision 146010)
+++ gcc/c-decl.c (working copy)
@@ -4000,6 +4000,7 @@ grokdeclarator (const struct c_declarato
bool bitfield = width != NULL;
tree element_type;
struct c_arg_info *arg_info = 0;
+ const char *errmsg;
tree expr_dummy;
bool expr_const_operands_dummy;
@@ -4583,6 +4584,12 @@ grokdeclarator (const struct c_declarato
error ("%qs declared as function returning an array", name);
type = integer_type_node;
}
+ errmsg = targetm.invalid_return_type (type);
+ if (errmsg)
+ {
+ error (errmsg);
+ type = integer_type_node;
+ }
/* Construct the function type and go to the next
inner layer of declarator. */
@@ -5096,6 +5103,7 @@ grokparms (struct c_arg_info *arg_info,
{
tree parm, type, typelt;
unsigned int parmno;
+ const char *errmsg;
/* If there is a parameter of incomplete type in a definition,
this is an error. In a declaration this is valid, and a
@@ -5139,6 +5147,14 @@ grokparms (struct c_arg_info *arg_info,
}
}
+ errmsg = targetm.invalid_parameter_type (type);
+ if (errmsg)
+ {
+ error (errmsg);
+ TREE_VALUE (typelt) = error_mark_node;
+ TREE_TYPE (parm) = error_mark_node;
+ }
+
if (DECL_NAME (parm) && TREE_USED (parm))
warn_if_shadowing (parm);
}
Index: gcc/c-typeck.c
===================================================================
--- gcc/c-typeck.c (revision 146010)
+++ gcc/c-typeck.c (working copy)
@@ -1780,6 +1780,7 @@ default_conversion (tree exp)
tree orig_exp;
tree type = TREE_TYPE (exp);
enum tree_code code = TREE_CODE (type);
+ tree promoted_type;
/* Functions and arrays have been converted during parsing. */
gcc_assert (code != FUNCTION_TYPE);
@@ -1807,6 +1808,10 @@ default_conversion (tree exp)
if (exp == error_mark_node)
return error_mark_node;
+ promoted_type = targetm.promoted_type (type);
+ if (promoted_type)
+ return convert (promoted_type, exp);
+
if (INTEGRAL_TYPE_P (type))
return perform_integral_promotions (exp);
Index: gcc/c-convert.c
===================================================================
--- gcc/c-convert.c (revision 146010)
+++ gcc/c-convert.c (working copy)
@@ -86,6 +86,8 @@ convert (tree type, tree expr)
if (type == TREE_TYPE (expr))
return expr;
+ if ((ret = targetm.convert_to_type (type, expr)))
+ return ret;
STRIP_TYPE_NOPS (e);
Index: gcc/target-def.h
===================================================================
--- gcc/target-def.h (revision 146010)
+++ gcc/target-def.h (working copy)
@@ -537,6 +537,10 @@
#define TARGET_INVALID_CONVERSION hook_constcharptr_const_tree_const_tree_null
#define TARGET_INVALID_UNARY_OP hook_constcharptr_int_const_tree_null
#define TARGET_INVALID_BINARY_OP hook_constcharptr_int_const_tree_const_tree_null
+#define TARGET_INVALID_PARAMETER_TYPE hook_constcharptr_const_tree_null
+#define TARGET_INVALID_RETURN_TYPE hook_constcharptr_const_tree_null
+#define TARGET_PROMOTED_TYPE hook_tree_const_tree_null
+#define TARGET_CONVERT_TO_TYPE hook_tree_tree_tree_null
#define TARGET_FIXED_CONDITION_CODE_REGS hook_bool_uintp_uintp_false
@@ -918,6 +922,10 @@
TARGET_INVALID_CONVERSION, \
TARGET_INVALID_UNARY_OP, \
TARGET_INVALID_BINARY_OP, \
+ TARGET_INVALID_PARAMETER_TYPE, \
+ TARGET_INVALID_RETURN_TYPE, \
+ TARGET_PROMOTED_TYPE, \
+ TARGET_CONVERT_TO_TYPE, \
TARGET_IRA_COVER_CLASSES, \
TARGET_SECONDARY_RELOAD, \
TARGET_EXPAND_TO_RTL_HOOK, \