aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen Dobbelaere <jeroen.dobbelaere@acunia.com>2002-11-15 11:21:36 +0000
committerRichard Earnshaw <rearnsha@gcc.gnu.org>2002-11-15 11:21:36 +0000
commit1741620c2673f78b1e754664c84242fb12240e2b (patch)
treef67c410d927ea568413f1da37eb5bc0959afecec
parent8e746279f38c69339f8a694e174e28c70faa5588 (diff)
downloadgcc-1741620c2673f78b1e754664c84242fb12240e2b.zip
gcc-1741620c2673f78b1e754664c84242fb12240e2b.tar.gz
gcc-1741620c2673f78b1e754664c84242fb12240e2b.tar.bz2
Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com> * config/arm/arm.h (EXPAND_BUILTIN_VA_ARG, FUNCTION_ARG_PASS_BY_REFERENCE): Define. * config/arm/arm.c (arm_va_arg, arm_function_arg_pass_by_reference): New. * config/arm/arm-protos.h: Add prototypes. From-SVN: r59127
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/arm/arm-protos.h11
-rw-r--r--gcc/config/arm/arm.c29
-rw-r--r--gcc/config/arm/arm.h12
4 files changed, 58 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d455cb9..0041b2a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2002-11-14 Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
+
+ * config/arm/arm.h (EXPAND_BUILTIN_VA_ARG,
+ FUNCTION_ARG_PASS_BY_REFERENCE): Define.
+ * config/arm/arm.c (arm_va_arg,
+ arm_function_arg_pass_by_reference): New.
+ * config/arm/arm-protos.h: Add prototypes.
+
2002-11-14 Kazu Hirata <kazu@cs.umass.edu>
* gthr-single.h: Fix formatting.
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 671fe9d..cae9bea 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -45,7 +45,8 @@ extern void arm_encode_call_attribute PARAMS ((tree, int));
extern int arm_function_ok_for_sibcall PARAMS ((tree));
#endif
#ifdef RTX_CODE
-extern int arm_hard_regno_mode_ok PARAMS ((unsigned int, enum machine_mode));
+extern int arm_hard_regno_mode_ok PARAMS ((unsigned int,
+ enum machine_mode));
extern int const_ok_for_arm PARAMS ((HOST_WIDE_INT));
extern int arm_split_constant PARAMS ((RTX_CODE, enum machine_mode,
HOST_WIDE_INT, rtx, rtx, int));
@@ -124,7 +125,8 @@ extern const char * output_move_double PARAMS ((rtx *));
extern const char * output_mov_immediate PARAMS ((rtx *));
extern const char * output_add_immediate PARAMS ((rtx *));
extern const char * arithmetic_instr PARAMS ((rtx, int));
-extern void output_ascii_pseudo_op PARAMS ((FILE *, const unsigned char *, int));
+extern void output_ascii_pseudo_op PARAMS ((FILE *, const unsigned char *,
+ int));
extern const char * output_return_instruction PARAMS ((rtx, int, int));
extern void arm_poke_function_name PARAMS ((FILE *, const char *));
extern void arm_print_operand PARAMS ((FILE *, rtx, int));
@@ -139,6 +141,11 @@ extern rtx arm_function_arg PARAMS ((CUMULATIVE_ARGS *,
enum machine_mode, tree, int));
extern void arm_init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx,
int));
+extern rtx arm_va_arg PARAMS ((tree, tree));
+extern int arm_function_arg_pass_by_reference PARAMS ((CUMULATIVE_ARGS *,
+ enum machine_mode,
+ tree, int));
+
#endif
#if defined AOF_ASSEMBLER
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index a51b95c..bc89418 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -1952,6 +1952,35 @@ arm_function_arg (pcum, mode, type, named)
return gen_rtx_REG (mode, pcum->nregs);
}
+
+/* Variable sized types are passed by reference. This is a GCC
+ extension to the ARM ABI. */
+
+int
+arm_function_arg_pass_by_reference (cum, mode, type, named)
+ CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+ tree type;
+ int named ATTRIBUTE_UNUSED;
+{
+ return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST;
+}
+
+/* Implement va_arg. */
+
+rtx
+arm_va_arg (valist, type)
+ tree valist, type;
+{
+ /* Variable sized types are passed by reference. */
+ if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
+ {
+ rtx addr = std_expand_builtin_va_arg (valist, build_pointer_type (type));
+ return gen_rtx_MEM (ptr_mode, force_reg (Pmode, addr));
+ }
+
+ return std_expand_builtin_va_arg (valist, type);
+}
/* Encode the current state of the #pragma [no_]long_calls. */
typedef enum
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 13da6f7..eda2d47 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -1487,6 +1487,14 @@ typedef struct
&& (NUM_ARG_REGS < ((CUM).nregs + ARM_NUM_REGS2 (MODE, TYPE))) \
? NUM_ARG_REGS - (CUM).nregs : 0)
+/* A C expression that indicates when an argument must be passed by
+ reference. If nonzero for an argument, a copy of that argument is
+ made in memory and a pointer to the argument is passed instead of
+ the argument itself. The pointer is passed in whatever way is
+ appropriate for passing a pointer to that type. */
+#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
+ arm_function_arg_pass_by_reference (&CUM, MODE, TYPE, NAMED)
+
/* Initialize a variable CUM of type CUMULATIVE_ARGS
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is 0.
@@ -1504,6 +1512,10 @@ typedef struct
On the ARM, r0-r3 are used to pass args. */
#define FUNCTION_ARG_REGNO_P(REGNO) (IN_RANGE ((REGNO), 0, 3))
+/* Implement `va_arg'. */
+#define EXPAND_BUILTIN_VA_ARG(valist, type) \
+ arm_va_arg (valist, type)
+
/* Tail calling. */