aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/sparc/sparc.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/sparc/sparc.c')
-rw-r--r--gcc/config/sparc/sparc.c91
1 files changed, 90 insertions, 1 deletions
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index e1e37ee..8beea52 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -148,6 +148,7 @@ static void sparc_output_addr_vec (rtx);
static void sparc_output_addr_diff_vec (rtx);
static void sparc_output_deferred_case_vectors (void);
static int check_return_regs (rtx);
+static rtx sparc_builtin_saveregs (void);
static int epilogue_renumber (rtx *, int);
static bool sparc_assemble_integer (rtx, unsigned int, int);
static int set_extends (rtx);
@@ -194,6 +195,10 @@ static rtx sparc_tls_got (void);
static const char *get_some_local_dynamic_name (void);
static int get_some_local_dynamic_name_1 (rtx *, void *);
static bool sparc_rtx_costs (rtx, int, int, int *);
+static bool sparc_promote_prototypes (tree);
+static rtx sparc_struct_value_rtx (tree, int);
+static bool sparc_return_in_memory (tree, tree);
+static bool sparc_strict_argument_naming (CUMULATIVE_ARGS *);
/* Option handling. */
@@ -277,6 +282,36 @@ enum processor_type sparc_cpu;
#undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST hook_int_rtx_0
+/* Return TRUE if the promotion described by PROMOTE_MODE should also be done
+ for outgoing function arguments.
+ This is only needed for TARGET_ARCH64, but since PROMOTE_MODE is a no-op
+ for TARGET_ARCH32 this is ok. Otherwise we'd need to add a runtime test
+ for this value. */
+#undef TARGET_PROMOTE_FUNCTION_ARGS
+#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
+
+/* Return TRUE if the promotion described by PROMOTE_MODE should also be done
+ for the return value of functions. If this macro is defined, FUNCTION_VALUE
+ must perform the same promotions done by PROMOTE_MODE.
+ This is only needed for TARGET_ARCH64, but since PROMOTE_MODE is a no-op
+ for TARGET_ARCH32 this is ok. Otherwise we'd need to add a runtime test
+ for this value. */
+#undef TARGET_PROMOTE_FUNCTION_RETURN
+#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
+
+#undef TARGET_PROMOTE_PROTOTYPES
+#define TARGET_PROMOTE_PROTOTYPES sparc_promote_prototypes
+
+#undef TARGET_STRUCT_VALUE_RTX
+#define TARGET_STRUCT_VALUE_RTX sparc_struct_value_rtx
+#undef TARGET_RETURN_IN_MEMORY
+#define TARGET_RETURN_IN_MEMORY sparc_return_in_memory
+
+#undef TARGET_EXPAND_BUILTIN_SAVEREGS
+#define TARGET_EXPAND_BUILTIN_SAVEREGS sparc_builtin_saveregs
+#undef TARGET_STRICT_ARGUMENT_NAMING
+#define TARGET_STRICT_ARGUMENT_NAMING sparc_strict_argument_naming
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Validate and override various options, and do some machine dependent
@@ -4817,6 +4852,60 @@ init_cumulative_args (struct sparc_args *cum, tree fntype,
cum->libcall_p = fntype == 0;
}
+/* Handle the PROMOTE_PROTOTYPES macro.
+ When a prototype says `char' or `short', really pass an `int'. */
+
+static bool
+sparc_promote_prototypes (tree fntype ATTRIBUTE_UNUSED)
+{
+ return TARGET_ARCH32 ? true : false;
+}
+
+/* Handle the STRICT_ARGUMENT_NAMING macro. */
+
+static bool
+sparc_strict_argument_naming (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED)
+{
+ /* For the V9 we want NAMED to mean what it says it means. */
+ return TARGET_V9 ? true : false;
+}
+
+/* Handle the RETURN_IN_MEMORY macro.
+ Specify whether to return the return value in memory. */
+
+static bool
+sparc_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
+{
+ /* SPARC ABI says that quad-precision floats and all structures are
+ returned in memory.
+ For V9: unions <= 32 bytes in size are returned in int regs,
+ structures up to 32 bytes are returned in int and fp regs. */
+ return (TARGET_ARCH32
+ ? (TYPE_MODE (type) == BLKmode
+ || TYPE_MODE (type) == TFmode)
+ : (TYPE_MODE (type) == BLKmode
+ && (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 32));
+}
+
+/* Handle the STRUCT_VALUE macro.
+ Return where to find the structure return value address. */
+
+static rtx
+sparc_struct_value_rtx (tree fndecl ATTRIBUTE_UNUSED, int incoming)
+{
+ if (TARGET_ARCH64)
+ return 0;
+ else
+ {
+ if (incoming)
+ return gen_rtx_MEM (Pmode, plus_constant (frame_pointer_rtx,
+ STRUCT_VALUE_OFFSET));
+ else
+ return gen_rtx_MEM (Pmode, plus_constant (stack_pointer_rtx,
+ STRUCT_VALUE_OFFSET));
+ }
+}
+
/* Scan the record type TYPE and return the following predicates:
- INTREGS_P: the record contains at least one field or sub-field
that is eligible for promotion in integer registers.
@@ -5730,7 +5819,7 @@ function_value (tree type, enum machine_mode mode, int incoming_p)
to determine if stdarg or varargs is used and return the address of
the first unnamed parameter. */
-rtx
+static rtx
sparc_builtin_saveregs (void)
{
int first_reg = current_function_args_info.words;