This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: patch: teach assign_parm* about float parallels


> I'm not sure how to show the problem though.  You'd have to have a
> target for which DImode was passed in multiple registers, "int" maps
> to DImode and "short" maps to something smaller.  But I don't think
> such an ABI exists.
> 
> > I've also added a check for BLKmode, for good measure, but I doubt
> > any one is passing BLKmode's in parallels for function arguments.
> 
> Definitely there are.  See amd64 or ia64 or sparc64 ABIs.

Eeech, I'm going to pretend I didn't see this (ia64):

      /* In big-endian mode, an anonymous SFmode value must be represented
         as (parallel:SF [(expr_list (reg:DI n) (const_int 0))]) to force
         the value into the high half of the general register.  */

*shudder*

> But in that case I'd consider it a large bug if
> 
>    ((data->nominal_mode == BLKmode || data->passed_mode == BLKmode)
>     && data->nominal_mode != data->passed_mode)
> 
> were true.  So in my opinion,
> 
>   data->nominal_mode != data->passed_mode
> 
> is still the correct test.  A comment block describing the possible
> combinations wouldn't be out of place.

Ok, how about the patch below?  Tests are stillllll going, but it
did squash 16 regressions on my target ;-).

Thanks for your help.

	* function.c (assign_parm_setup_block): Handle parallels correctly.

Index: function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.584
diff -c -p -r1.584 function.c
*** function.c	19 Oct 2004 14:43:52 -0000	1.584
--- function.c	27 Oct 2004 22:12:34 -0000
*************** assign_parm_setup_block (tree parm, stru
*** 2550,2557 ****
      {
        rtx parmreg = gen_reg_rtx (data->nominal_mode);
  
!       emit_group_store (parmreg, entry_parm, data->nominal_type,
! 			int_size_in_bytes (data->nominal_type));
        SET_DECL_RTL (parm, parmreg);
        return;
      }
--- 2550,2577 ----
      {
        rtx parmreg = gen_reg_rtx (data->nominal_mode);
  
!       /* For values returned in multiple registers, handle possible
! 	 incompatible calls to emit_group_store.
! 
! 	 For example, the following would be invalid, and would have to
! 	 be fixed by the conditional below:
! 
! 	   emit_group_store ((reg:SF), (parallel:DF))
! 	   emit_group_store ((reg:SI), (parallel:DI))
! 
! 	 An example of this are doubles in e500 v2:
! 	   (parallel:DF (expr_list (reg:SI) (const_int 0))
! 	                (expr_list (reg:SI) (const_int 4))).  */
!       if (data->nominal_mode != data->passed_mode)
! 	{
! 	  rtx t = gen_reg_rtx (GET_MODE (entry_parm));
! 	  emit_group_store (t, entry_parm, NULL_TREE,
! 			    GET_MODE_SIZE (GET_MODE (entry_parm)));
! 	  convert_move (parmreg, t, 0);
! 	}
!       else
! 	emit_group_store (parmreg, entry_parm, data->nominal_type,
! 			  int_size_in_bytes (data->nominal_type));
        SET_DECL_RTL (parm, parmreg);
        return;
      }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]