SSE types and structures

Jan Hubicka jh@suse.cz
Tue Jun 18 10:07:00 GMT 2002


> On Tue, Jun 18, 2002 at 05:03:59PM +0200, Jan Hubicka wrote:
> > int i;
> > __v8qi q;
> >   q = (__v8qi) (long long) i;
> [...]
> > q.c:9: error: can't convert between vector values of different size
> 
> This must be a bug in Aldy's generic vector code.
Hmm, I am not sure if I sent the patch, but here it is.
It allows casts from any size of integer mode that is IMO sensible.
I would like to get this into 3.1 tree, so I can get the mmintrin change
as well.  I didn't implemented that bit yet, as I must leave now.

Tue Jun 18 18:50:57 CEST 2002  Jan Hubicka  <jh@suse.cz>
	* convert.c (convert_to_vector): Be permisive about converting from
	integer types of different size.
	* expr.c (convert_move): Allow converting from any integer type into
	vector type
Index: convert.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/convert.c,v
retrieving revision 1.18
diff -c -3 -p -r1.18 convert.c
*** convert.c	15 Jun 2002 00:40:49 -0000	1.18
--- convert.c	18 Jun 2002 16:50:06 -0000
*************** convert_to_vector (type, expr)
*** 480,486 ****
  {
    switch (TREE_CODE (TREE_TYPE (expr)))
      {
-     case INTEGER_TYPE:
      case VECTOR_TYPE:
        if (GET_MODE_SIZE (TYPE_MODE (type))
  	  != GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr))))
--- 480,485 ----
*************** convert_to_vector (type, expr)
*** 488,493 ****
--- 487,495 ----
  	  error ("can't convert between vector values of different size");
  	  return error_mark_node;
  	}
+       return build1 (NOP_EXPR, type, expr);
+ 
+     case INTEGER_TYPE:
        return build1 (NOP_EXPR, type, expr);
  
      default:
Index: expr.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/expr.c,v
retrieving revision 1.466
diff -c -3 -p -r1.466 expr.c
*** expr.c	15 Jun 2002 20:21:22 -0000	1.466
--- expr.c	18 Jun 2002 16:50:11 -0000
*************** convert_move (to, from, unsignedp)
*** 550,561 ****
    if (VECTOR_MODE_P (to_mode) || VECTOR_MODE_P (from_mode))
      {
        if (GET_MODE_BITSIZE (from_mode) != GET_MODE_BITSIZE (to_mode))
! 	abort ();
  
        if (VECTOR_MODE_P (to_mode))
! 	from = simplify_gen_subreg (to_mode, from, GET_MODE (from), 0);
        else
! 	to = simplify_gen_subreg (from_mode, to, GET_MODE (to), 0);
  
        emit_move_insn (to, from);
        return;
--- 550,584 ----
    if (VECTOR_MODE_P (to_mode) || VECTOR_MODE_P (from_mode))
      {
        if (GET_MODE_BITSIZE (from_mode) != GET_MODE_BITSIZE (to_mode))
! 	{
! 	  enum machine_mode wide_mode;
  
+ 	  /* For vector modes we require exact match.  For integral mode
+ 	     behave like if the cast to equivalently sized integer were
+ 	     present.  */
+ 	  if (VECTOR_MODE_P (from_mode))
+ 	    abort ();
+ 	  if (GET_MODE_BITSIZE (from_mode) < GET_MODE_BITSIZE (to_mode))
+             {
+ 	      rtx reg;
+ 	      for (wide_mode = from_mode; wide_mode != VOIDmode;
+ 		   wide_mode = GET_MODE_WIDER_MODE (wide_mode))
+ 		if (GET_MODE_BITSIZE (wide_mode) >= GET_MODE_BITSIZE (to_mode))
+ 		  break;
+ 	      if (wide_mode == VOIDmode)
+ 	        abort ();
+ 	      reg = gen_reg_rtx (wide_mode);
+ 	      convert_move (reg, from, unsignedp);
+ 	      from = reg;
+ 	      from_mode = wide_mode;
+ 	    }
+ 	}
        if (VECTOR_MODE_P (to_mode))
! 	from = simplify_gen_subreg (to_mode, from, GET_MODE (from),
! 				    subreg_lowpart_offset (to_mode, from_mode));
        else
! 	to = simplify_gen_subreg (from_mode, to, GET_MODE (to),
! 				  subreg_lowpart_offset (from_mode, to_mode));
  
        emit_move_insn (to, from);
        return;



More information about the Gcc-patches mailing list