gimple va_arg for arm

Richard Henderson rth@redhat.com
Thu Jul 8 23:51:00 GMT 2004


Not committed, since I'm not 100% certain about the curiousness with
the alignment of arg_pointer_rtx.  It seems to me that if it's necessary
to reduce the alignment for va_arg, then its necessary all of the time.

Richard E, can you confirm that this works?


r~


        * config/arm/arm-protos.h (arm_va_arg): Remove.
        * config/arm/arm.c (TARGET_GIMPLIFY_VA_ARG_EXPR): New.
        (arm_gimplify_va_arg_expr): Rewrite from arm_va_arg.
	(arm_init_expanders): Fix alignment of arg_pointer_rtx.
        * config/arm/arm.h (EXPAND_BUILTIN_VA_ARG): Remove.

Index: config/arm/arm-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm-protos.h,v
retrieving revision 1.69
diff -c -p -d -r1.69 arm-protos.h
*** config/arm/arm-protos.h	7 Jul 2004 19:24:05 -0000	1.69
--- config/arm/arm-protos.h	8 Jul 2004 22:07:57 -0000
*************** extern const char *vfp_output_fstmx (rtx
*** 155,161 ****
  #if defined TREE_CODE
  extern rtx arm_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
  extern void arm_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
- extern rtx arm_va_arg (tree, tree);
  extern int arm_function_arg_pass_by_reference (CUMULATIVE_ARGS *,
  					       enum machine_mode, tree, int);
  extern bool arm_needs_doubleword_align (enum machine_mode, tree);
--- 155,160 ----
Index: config/arm/arm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.373
diff -c -p -d -r1.373 arm.c
*** config/arm/arm.c	8 Jul 2004 07:42:02 -0000	1.373
--- config/arm/arm.c	8 Jul 2004 22:07:58 -0000
*************** static rtx arm_expand_binop_builtin (enu
*** 140,145 ****
--- 140,146 ----
  static rtx arm_expand_unop_builtin (enum insn_code, tree, rtx, int);
  static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
  static void emit_constant_insn (rtx cond, rtx pattern);
+ static tree arm_gimplify_va_arg_expr (tree, tree, tree *, tree *);
  
  #ifdef OBJECT_FORMAT_ELF
  static void arm_elf_asm_named_section (const char *, unsigned int);
*************** static bool arm_cookie_has_size (void);
*** 261,266 ****
--- 262,269 ----
  
  #undef  TARGET_SETUP_INCOMING_VARARGS
  #define TARGET_SETUP_INCOMING_VARARGS arm_setup_incoming_varargs
+ #undef TARGET_GIMPLIFY_VA_ARG_EXPR
+ #define TARGET_GIMPLIFY_VA_ARG_EXPR arm_gimplify_va_arg_expr
  
  #undef TARGET_DEFAULT_SHORT_ENUMS
  #define TARGET_DEFAULT_SHORT_ENUMS arm_default_short_enums
*************** arm_function_arg_pass_by_reference (CUMU
*** 2393,2432 ****
  
  /* Implement va_arg.  */
  
! rtx
! arm_va_arg (tree valist, tree type)
  {
-   int align;
- 
    /* 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));
!     }
! 
!   align = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
!   if (align > PARM_BOUNDARY)
!     {
!       tree mask;
!       tree t;
! 
!       /* Maintain 64-bit alignment of the valist pointer by
! 	 constructing:   valist = ((valist + (8 - 1)) & -8).  */
!       mask = build_int_2 (- (align / BITS_PER_UNIT), -1);
!       t = build_int_2 ((align / BITS_PER_UNIT) - 1, 0);
!       t = build (PLUS_EXPR,    TREE_TYPE (valist), valist, t);
!       t = build (BIT_AND_EXPR, TREE_TYPE (t), t, mask);
!       t = build (MODIFY_EXPR,  TREE_TYPE (valist), valist, t);
!       TREE_SIDE_EFFECTS (t) = 1;
!       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
! 
!       /* This is to stop the combine pass optimizing
! 	 away the alignment adjustment.  */
!       mark_reg_pointer (arg_pointer_rtx, PARM_BOUNDARY);
!     }
  
!   return std_expand_builtin_va_arg (valist, type);
  }
  
  /* Encode the current state of the #pragma [no_]long_calls.  */
--- 2396,2409 ----
  
  /* Implement va_arg.  */
  
! static tree
! arm_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
  {
    /* Variable sized types are passed by reference.  */
    if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
!     return ind_gimplify_va_arg_expr (valist, type, pre_p, post_p);
  
!   return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
  }
  
  /* Encode the current state of the #pragma [no_]long_calls.  */
*************** arm_init_expanders (void)
*** 13142,13147 ****
--- 13119,13129 ----
  {
    /* Arrange to initialize and mark the machine per-function status.  */
    init_machine_status = arm_init_machine_status;
+ 
+   /* This is to stop the combine pass optimizing away the alignment
+      adjustment of va_arg.  */
+   if (cfun)
+     mark_reg_pointer (arg_pointer_rtx, PARM_BOUNDARY);
  }
  
  
Index: config/arm/arm.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.h,v
retrieving revision 1.242
diff -c -p -d -r1.242 arm.h
*** config/arm/arm.h	5 Jul 2004 19:49:12 -0000	1.242
--- config/arm/arm.h	8 Jul 2004 22:07:58 -0000
*************** typedef struct
*** 1734,1743 ****
      || (TARGET_IWMMXT_ABI		\
  	&& IN_RANGE ((REGNO), FIRST_IWMMXT_REGNUM, FIRST_IWMMXT_REGNUM + 9)))
  
- /* Implement `va_arg'.  */
- #define EXPAND_BUILTIN_VA_ARG(valist, type) \
-   arm_va_arg (valist, type)
- 
  
  /* If your target environment doesn't prefix user functions with an
     underscore, you may wish to re-define this to prevent any conflicts.
--- 1734,1739 ----



More information about the Gcc-patches mailing list