patch: temporary kludge for subregs of simd types

Aldy Hernandez aldyh@redhat.com
Thu Apr 24 21:26:00 GMT 2003


For the e500, a v2si in a vararg gets split into 2 registers.  The rtl 
we're generating is the following:

(parallel:V2SI [
         (expr_list:REG_EQUAL (reg:SI 5 r5)
             (const_int 0 [0x0]))
         (expr_list:REG_EQUAL (reg:SI 6 r6)
             (const_int 4 [0x4]))
     ])

This eventually creates a (subreg:SI (reg:V2SI 999)).  Copying these 
subregs end up with rN and rN+1 having the same (lower) half, because 
we have no way of describing subregs of simd types for hard registers.  
This problem has been discussed a few times, lastly in a thread 
entitled:

	RFC: new rtl vec_set_unit/vec_get_unit

...in which it was concluded we need new rtl to describe these 
situations.

A proper fix is in my immediate TODO list (next few weeks), but I'd 
like a kludge to fix the subregs being generated, since varargs are 
completely broken on the e500.

The following patch is a workaround, until it gets properly fixed.

Bootstrap and regtested on x86 linux.

OK for mainline and e500 branch?

2003-04-23  Aldy Hernandez  <aldyh@redhat.com>

	* expr.c (emit_group_load): Dump parallels of simd types to
	memory.

Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.525
diff -c -p -r1.525 expr.c
*** expr.c	21 Apr 2003 17:50:51 -0000	1.525
--- expr.c	23 Apr 2003 19:58:34 -0000
*************** emit_group_load (dst, orig_src, ssize)
*** 2348,2353 ****
--- 2348,2366 ----
   	  else
   	    abort ();
   	}
+       /* FIXME: A SIMD parallel will eventually lead to a subreg of a
+ 	 SIMD register, which is currently broken.  While we get GCC
+ 	 to emit proper RTL for these cases, let's dump to memory.  */
+       else if (VECTOR_MODE_P (GET_MODE (dst))
+ 	       && GET_CODE (src) == REG)
+ 	{
+ 	  int slen = GET_MODE_SIZE (GET_MODE (src));
+ 	  rtx mem;
+
+ 	  mem = assign_stack_temp (GET_MODE (src), slen, 0);
+ 	  emit_move_insn (mem, src);
+ 	  tmps[i] = adjust_address (mem, mode, (int) bytepos);
+ 	}
         else if (CONSTANT_P (src)
   	       || (GET_CODE (src) == REG && GET_MODE (src) == mode))
   	tmps[i] = src;



More information about the Gcc-patches mailing list