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]

patch: emit_group_* handle floats


Hi Richard.

Dunno, if you remember a few months ago talking about the new e500 ABI,
and problems with emit_group_*.

On e500 v2, the ABI specifies that doubles get passed and returned in
two registers (like traditional e500 and soft-float).  However, double
arithmetic gets done in a whole 64-bit register.  So... we pass them in
a pair of 32-bit registers, but then join them and use them as one.

Yeah yeah... ugly, something akin to what PPC64 does.  It does maintain
ABI compatability wrt doubles for both e500 v1 *and* soft-float.

So... emit_group_* and friends do not handle floats correctly.  Here is
a patch to fix it.

I am attaching two patches, one to emit_group_* for which I would like
approval, and a second one showing the ABI changes I have made to the
back-end using these changes.  The second one is also there to show
what I'm using to test this patch...as I need the expr.c changes in
first, before I can commit the back-end changes.

Thank you much.
Aldy

p.s. Oh yeah, what I'm doing with the back-end changes is disabling all the
e500 v2 patterns except the move patterns so I can test the ABI on 
powerpc-eabispe, instead of the slow hardware.  I don't have a working
e500 v2 simulator yet and the hardware is...well...slow.

	* expr.c (emit_group_load): Handle floats.
	(emit_group_store): Same.

Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.734
diff -c -p -r1.734 expr.c
*** expr.c	21 Oct 2004 16:15:15 -0000	1.734
--- expr.c	25 Oct 2004 21:40:54 -0000
*************** emit_group_load (rtx dst, rtx orig_src, 
*** 1570,1575 ****
--- 1570,1592 ----
  
    gcc_assert (GET_CODE (dst) == PARALLEL);
  
+   if (!SCALAR_INT_MODE_P (GET_MODE (orig_src)))
+     {
+       enum machine_mode imode = int_mode_for_mode (GET_MODE (orig_src));
+       if (imode == BLKmode)
+ 	src = assign_stack_temp (GET_MODE (orig_src), ssize, 0);
+       else
+ 	src = gen_reg_rtx (imode);
+       if (imode != BLKmode)
+ 	src = gen_lowpart (GET_MODE (orig_src), src);
+       emit_move_insn (src, orig_src);
+       /* ...and back again.  */
+       if (imode != BLKmode)
+ 	src = gen_lowpart (imode, src);
+       emit_group_load (dst, src, type, ssize);
+       return;
+     }
+ 
    /* Check for a NULL entry, used to indicate that the parameter goes
       both on the stack and in registers.  */
    if (XEXP (XVECEXP (dst, 0, 0), 0))
*************** emit_group_store (rtx orig_dst, rtx src,
*** 1726,1731 ****
--- 1743,1762 ----
  
    gcc_assert (GET_CODE (src) == PARALLEL);
  
+   if (!SCALAR_INT_MODE_P (GET_MODE (orig_dst)))
+     {
+       enum machine_mode imode = int_mode_for_mode (GET_MODE (orig_dst));
+       if (imode == BLKmode)
+         dst = assign_stack_temp (GET_MODE (orig_dst), ssize, 0);
+       else
+         dst = gen_reg_rtx (imode);
+       emit_group_store (dst, src, type, ssize);
+       if (imode != BLKmode)
+         dst = gen_lowpart (GET_MODE (orig_dst), dst);
+       emit_move_insn (orig_dst, dst);
+       return;
+     }
+ 
    /* Check for a NULL entry, used to indicate that the parameter goes
       both on the stack and in registers.  */
    if (XEXP (XVECEXP (src, 0, 0), 0))

Attachment: back-end-changes
Description: Text document


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