From 78aea6a2a3c68d42f5facb6b36915243f85e7bf5 Mon Sep 17 00:00:00 2001 From: rearnsha Date: Fri, 15 Nov 2002 11:21:36 +0000 Subject: [PATCH] Jeroen Dobbelaere * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@59127 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 8 ++++++++ gcc/config/arm/arm-protos.h | 11 +++++++++-- gcc/config/arm/arm.c | 29 +++++++++++++++++++++++++++++ gcc/config/arm/arm.h | 12 ++++++++++++ 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 + + * 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 * 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. */ -- 2.7.4