summaryrefslogtreecommitdiff
path: root/gcc/config/mn10300
diff options
context:
space:
mode:
authordj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>2005-09-22 00:10:28 +0000
committerdj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>2005-09-22 00:10:28 +0000
commit00b1da0e3760720da61cea4316105e21fd5d24a5 (patch)
treea8a16767f44aa12521ffd683d0425ab3e977731d /gcc/config/mn10300
parent097b55d524bd921e76ac3c6506ba5b4aa32af8f4 (diff)
downloadgcc-00b1da0e3760720da61cea4316105e21fd5d24a5.tar.gz
* config/mn10300/mn10300.c (TARGET_DEFAULT_TARGET_FLAGS): Add
MASK_PTR_A0D0. (mn10300_return_in_memory): Support variable size types also. (mn10300_pass_by_reference): Likewise. (mn10300_function_value): New. * config/mn10300/mn10300.h (FUNCTION_VALUE): Call the above. (FUNCTION_OUTGOING_VALUE): Likewise. * config/mn10300/mn10300.opt: Add -mreturn-pointer-on-d0. * doc/invoke.texi: Document it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@104508 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/mn10300')
-rw-r--r--gcc/config/mn10300/mn10300-protos.h1
-rw-r--r--gcc/config/mn10300/mn10300.c39
-rw-r--r--gcc/config/mn10300/mn10300.h5
-rw-r--r--gcc/config/mn10300/mn10300.opt4
4 files changed, 44 insertions, 5 deletions
diff --git a/gcc/config/mn10300/mn10300-protos.h b/gcc/config/mn10300/mn10300-protos.h
index 0810dad6860..b094c853b4d 100644
--- a/gcc/config/mn10300/mn10300-protos.h
+++ b/gcc/config/mn10300/mn10300-protos.h
@@ -49,6 +49,7 @@ extern bool mn10300_wide_const_load_uses_clr (rtx operands[2]);
#ifdef TREE_CODE
extern struct rtx_def *function_arg (CUMULATIVE_ARGS *,
enum machine_mode, tree, int);
+extern rtx mn10300_function_value (tree, tree, int);
#endif /* TREE_CODE */
extern void expand_prologue (void);
diff --git a/gcc/config/mn10300/mn10300.c b/gcc/config/mn10300/mn10300.c
index 789a38370b9..cf0fc9fc146 100644
--- a/gcc/config/mn10300/mn10300.c
+++ b/gcc/config/mn10300/mn10300.c
@@ -95,7 +95,7 @@ static int mn10300_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
#undef TARGET_DEFAULT_TARGET_FLAGS
-#define TARGET_DEFAULT_TARGET_FLAGS MASK_MULT_BUG
+#define TARGET_DEFAULT_TARGET_FLAGS MASK_MULT_BUG | MASK_PTR_A0D0
#undef TARGET_HANDLE_OPTION
#define TARGET_HANDLE_OPTION mn10300_handle_option
@@ -1449,7 +1449,9 @@ static bool
mn10300_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
{
/* Return values > 8 bytes in length in memory. */
- return int_size_in_bytes (type) > 8 || TYPE_MODE (type) == BLKmode;
+ return (int_size_in_bytes (type) > 8
+ || int_size_in_bytes (type) == 0
+ || TYPE_MODE (type) == BLKmode);
}
/* Flush the argument registers to the stack for a stdarg function;
@@ -1505,7 +1507,7 @@ mn10300_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
else
size = GET_MODE_SIZE (mode);
- return size > 8;
+ return (size > 8 || size == 0);
}
/* Return an RTX to represent where a value with mode MODE will be returned
@@ -1598,6 +1600,37 @@ mn10300_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
return nregs * UNITS_PER_WORD - cum->nbytes;
}
+/* Return the location of the function's value. This will be either
+ $d0 for integer functions, $a0 for pointers, or a PARALLEL of both
+ $d0 and $a0 if the -mreturn-pointer-on-do flag is set. Note that
+ we only return the PARALLEL for outgoing values; we do not want
+ callers relying on this extra copy. */
+
+rtx
+mn10300_function_value (tree valtype, tree func, int outgoing)
+{
+ rtx rv;
+ enum machine_mode mode = TYPE_MODE (valtype);
+
+ if (! POINTER_TYPE_P (valtype))
+ return gen_rtx_REG (mode, FIRST_DATA_REGNUM);
+ else if (! TARGET_PTR_A0D0 || ! outgoing
+ || current_function_returns_struct)
+ return gen_rtx_REG (mode, FIRST_ADDRESS_REGNUM);
+
+ rv = gen_rtx_PARALLEL (mode, rtvec_alloc (2));
+ XVECEXP (rv, 0, 0)
+ = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (mode, FIRST_ADDRESS_REGNUM),
+ GEN_INT (0));
+
+ XVECEXP (rv, 0, 1)
+ = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (mode, FIRST_DATA_REGNUM),
+ GEN_INT (0));
+ return rv;
+}
+
/* Output a tst insn. */
const char *
output_tst (rtx operand, rtx insn)
diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h
index 20751fd18a0..b102c398306 100644
--- a/gcc/config/mn10300/mn10300.h
+++ b/gcc/config/mn10300/mn10300.h
@@ -594,8 +594,9 @@ struct cum_arg {int nbytes; };
otherwise, FUNC is 0. */
#define FUNCTION_VALUE(VALTYPE, FUNC) \
- gen_rtx_REG (TYPE_MODE (VALTYPE), POINTER_TYPE_P (VALTYPE) \
- ? FIRST_ADDRESS_REGNUM : FIRST_DATA_REGNUM)
+ mn10300_function_value (VALTYPE, FUNC, 0)
+#define FUNCTION_OUTGOING_VALUE(VALTYPE, FUNC) \
+ mn10300_function_value (VALTYPE, FUNC, 1)
/* Define how to find the value returned by a library function
assuming the value has mode MODE. */
diff --git a/gcc/config/mn10300/mn10300.opt b/gcc/config/mn10300/mn10300.opt
index bc697045f84..7e0658c495c 100644
--- a/gcc/config/mn10300/mn10300.opt
+++ b/gcc/config/mn10300/mn10300.opt
@@ -35,3 +35,7 @@ Work around hardware multiply bug
mrelax
Target RejectNegative
Enable linker relaxations
+
+mreturn-pointer-on-d0
+Target Report Mask(PTR_A0D0)
+Return pointers in both a0 and d0