summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/builtins.c4
-rw-r--r--gcc/config/ia64/ia64.c60
-rw-r--r--gcc/doc/tm.texi8
-rw-r--r--gcc/doc/tm.texi.in4
-rw-r--r--gcc/target.def20
-rw-r--r--gcc/targhooks.c10
-rw-r--r--gcc/targhooks.h2
7 files changed, 99 insertions, 9 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index ca69efa10d7..611b777ec9c 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -1334,7 +1334,7 @@ apply_args_size (void)
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (FUNCTION_ARG_REGNO_P (regno))
{
- mode = reg_raw_mode[regno];
+ mode = targetm.calls.get_raw_arg_mode (regno);
gcc_assert (mode != VOIDmode);
@@ -1370,7 +1370,7 @@ apply_result_size (void)
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (targetm.calls.function_value_regno_p (regno))
{
- mode = reg_raw_mode[regno];
+ mode = targetm.calls.get_raw_result_mode (regno);
gcc_assert (mode != VOIDmode);
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 96031504f3f..4a738095c6e 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -209,6 +209,14 @@ static void ia64_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
tree, int *, int);
static int ia64_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
tree, bool);
+static rtx ia64_function_arg_1 (const CUMULATIVE_ARGS *, enum machine_mode,
+ const_tree, bool, bool);
+static rtx ia64_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
+ const_tree, bool);
+static rtx ia64_function_incoming_arg (CUMULATIVE_ARGS *,
+ enum machine_mode, const_tree, bool);
+static void ia64_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
+ const_tree, bool);
static bool ia64_function_ok_for_sibcall (tree, tree);
static bool ia64_return_in_memory (const_tree, const_tree);
static rtx ia64_function_value (const_tree, const_tree, bool);
@@ -325,6 +333,7 @@ static void ia64_dwarf_handle_frame_unspec (const char *, rtx, int);
static tree ia64_builtin_decl (unsigned, bool);
static reg_class_t ia64_preferred_reload_class (rtx, reg_class_t);
+static enum machine_mode ia64_get_reg_raw_mode (int regno);
/* Table of valid machine attributes. */
static const struct attribute_spec ia64_attribute_table[] =
@@ -481,6 +490,12 @@ static const struct default_options ia64_option_optimization_table[] =
#define TARGET_FUNCTION_OK_FOR_SIBCALL ia64_function_ok_for_sibcall
#undef TARGET_ARG_PARTIAL_BYTES
#define TARGET_ARG_PARTIAL_BYTES ia64_arg_partial_bytes
+#undef TARGET_FUNCTION_ARG
+#define TARGET_FUNCTION_ARG ia64_function_arg
+#undef TARGET_FUNCTION_INCOMING_ARG
+#define TARGET_FUNCTION_INCOMING_ARG ia64_function_incoming_arg
+#undef TARGET_FUNCTION_ARG_ADVANCE
+#define TARGET_FUNCTION_ARG_ADVANCE ia64_function_arg_advance
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK ia64_output_mi_thunk
@@ -545,6 +560,10 @@ static const struct default_options ia64_option_optimization_table[] =
#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
#undef TARGET_MUST_PASS_IN_STACK
#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
+#undef TARGET_GET_RAW_RESULT_MODE
+#define TARGET_GET_RAW_RESULT_MODE ia64_get_reg_raw_mode
+#undef TARGET_GET_RAW_ARG_MODE
+#define TARGET_GET_RAW_ARG_MODE ia64_get_reg_raw_mode
#undef TARGET_GIMPLIFY_VA_ARG_EXPR
#define TARGET_GIMPLIFY_VA_ARG_EXPR ia64_gimplify_va_arg
@@ -4250,7 +4269,7 @@ hfa_element_mode (const_tree type, bool nested)
/* Return the number of words required to hold a quantity of TYPE and MODE
when passed as an argument. */
static int
-ia64_function_arg_words (tree type, enum machine_mode mode)
+ia64_function_arg_words (const_tree type, enum machine_mode mode)
{
int words;
@@ -4276,7 +4295,8 @@ ia64_function_arg_words (tree type, enum machine_mode mode)
all as if they had 16 byte alignment. Such aggregates can occur
only if gcc extensions are used. */
static int
-ia64_function_arg_offset (CUMULATIVE_ARGS *cum, tree type, int words)
+ia64_function_arg_offset (const CUMULATIVE_ARGS *cum,
+ const_tree type, int words)
{
/* No registers are skipped on VMS. */
if (TARGET_ABI_OPEN_VMS || (cum->words & 1) == 0)
@@ -4295,9 +4315,9 @@ ia64_function_arg_offset (CUMULATIVE_ARGS *cum, tree type, int words)
/* ??? 128-bit quad-precision floats are always passed in general
registers. */
-rtx
-ia64_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
- int named, int incoming)
+static rtx
+ia64_function_arg_1 (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ const_tree type, bool named, bool incoming)
{
int basereg = (incoming ? GR_ARG_FIRST : AR_ARG_FIRST);
int words = ia64_function_arg_words (type, mode);
@@ -4486,6 +4506,25 @@ ia64_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
}
}
+/* Implement TARGET_FUNCION_ARG target hook. */
+
+static rtx
+ia64_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ const_tree type, bool named)
+{
+ return ia64_function_arg_1 (cum, mode, type, named, false);
+}
+
+/* Implement TARGET_FUNCION_INCOMING_ARG target hook. */
+
+static rtx
+ia64_function_incoming_arg (CUMULATIVE_ARGS *cum,
+ enum machine_mode mode,
+ const_tree type, bool named)
+{
+ return ia64_function_arg_1 (cum, mode, type, named, true);
+}
+
/* Return number of bytes, at the beginning of the argument, that must be
put in registers. 0 is the argument is entirely in registers or entirely
in memory. */
@@ -4531,9 +4570,9 @@ ia64_arg_type (enum machine_mode mode)
/* Update CUM to point after this argument. This is patterned after
ia64_function_arg. */
-void
+static void
ia64_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
- tree type, int named)
+ const_tree type, bool named)
{
int words = ia64_function_arg_words (type, mode);
int offset = ia64_function_arg_offset (cum, type, words);
@@ -10959,5 +10998,12 @@ ia64_dconst_0_375 (void)
return ia64_dconst_0_375_rtx;
}
+static enum machine_mode
+ia64_get_reg_raw_mode (int regno)
+{
+ if (FR_REGNO_P (regno))
+ return XFmode;
+ return default_get_reg_raw_mode(regno);
+}
#include "gt-ia64.h"
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 66a092fbc1a..a8d27a3e6cc 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -4606,6 +4606,14 @@ This macro has effect in @option{-fpcc-struct-return} mode, but it does
nothing when you use @option{-freg-struct-return} mode.
@end defmac
+@deftypefn {Target Hook} {enum machine_mode} TARGET_GET_RAW_RESULT_MODE (int @var{regno})
+This target hook returns the mode to be used when accessing raw return registers in @code{__builtin_return}. Define this macro if the value in @var{reg_raw_mode} is not correct.
+@end deftypefn
+
+@deftypefn {Target Hook} {enum machine_mode} TARGET_GET_RAW_ARG_MODE (int @var{regno})
+This target hook returns the mode to be used when accessing raw argument registers in @code{__builtin_apply_args}. Define this macro if the value in @var{reg_raw_mode} is not correct.
+@end deftypefn
+
@node Caller Saves
@subsection Caller-Saves Register Allocation
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index a5fb0007920..47d4aa21704 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -4600,6 +4600,10 @@ This macro has effect in @option{-fpcc-struct-return} mode, but it does
nothing when you use @option{-freg-struct-return} mode.
@end defmac
+@hook TARGET_GET_RAW_RESULT_MODE
+
+@hook TARGET_GET_RAW_ARG_MODE
+
@node Caller Saves
@subsection Caller-Saves Register Allocation
diff --git a/gcc/target.def b/gcc/target.def
index cc69c9193d4..98cea58c40d 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -1982,6 +1982,26 @@ DEFHOOK
int, (tree fundecl, tree funtype, int size),
default_return_pops_args)
+/* Return a mode wide enough to copy any function value that might be
+ returned. */
+DEFHOOK
+(get_raw_result_mode,
+ "This target hook returns the mode to be used when accessing raw return\
+ registers in @code{__builtin_return}. Define this macro if the value\
+ in @var{reg_raw_mode} is not correct.",
+ enum machine_mode, (int regno),
+ default_get_reg_raw_mode)
+
+/* Return a mode wide enough to copy any argument value that might be
+ passed. */
+DEFHOOK
+(get_raw_arg_mode,
+ "This target hook returns the mode to be used when accessing raw argument\
+ registers in @code{__builtin_apply_args}. Define this macro if the value\
+ in @var{reg_raw_mode} is not correct.",
+ enum machine_mode, (int regno),
+ default_get_reg_raw_mode)
+
HOOK_VECTOR_END (calls)
/* Return the diagnostic message string if conversion from FROMTYPE
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index b6aefdbe58f..22bba3b33bc 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -64,6 +64,7 @@ along with GCC; see the file COPYING3. If not see
#include "target-def.h"
#include "ggc.h"
#include "hard-reg-set.h"
+#include "regs.h"
#include "reload.h"
#include "optabs.h"
#include "recog.h"
@@ -1333,6 +1334,15 @@ sjlj_except_unwind_info (void)
return UI_SJLJ;
}
+/* To be used by targets where reg_raw_mode doesn't return the right
+ mode for registers used in apply_builtin_return and apply_builtin_arg. */
+
+enum machine_mode
+default_get_reg_raw_mode(int regno)
+{
+ return reg_raw_mode[regno];
+}
+
const struct default_options empty_optimization_table[] =
{
{ OPT_LEVELS_NONE, 0, NULL, 0 }
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index e89ac8ec432..87625137de3 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -168,4 +168,6 @@ extern int default_loop_align_max_skip (rtx);
extern int default_label_align_max_skip (rtx);
extern int default_jump_align_max_skip (rtx);
+extern enum machine_mode default_get_reg_raw_mode(int);
+
extern const struct default_options empty_optimization_table[];