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]

fix x86_64 gcc.dg-struct-layout-1/t027


This is the last compat failure I see for this target.  Two problems:

First, I failed to properly update *all* of the varargs code during
my previous round of abi fixes.  Oops.

Second, and much more serious, MMX vs FPU usage.  What happened is that
we had a v2si value, and gcc thought it'd be great to put that in %mm0.
Well, now that we've done that, all fpu instructions (including loads)
produce NaNs.  This continues until an emms or femms instruction is 
issued.  Which the compiler never generates by itself.

The patch for the second problem here is just a teeny workaround.  I
adjust the register class preferences such that data movement by itself
does not suggest that the mmx registers are to be preferred.  In the
short term, I will disable vectorization with mmx for gcc 4.0.  In the
long term, mmx code generation will have to be rewritten from scratch,
requiring two or three brand new passes to manage the mode changes.

Tested on i686 and x86-64 linux.


r~


        * config/i386/i386.c (ix86_gimplify_va_arg): Also pass the result
        of type_natural_mode to examine_argument.

        * config/i386/i386.md (mov<MMXMODEI>_internal_rex64): New.
        (movv2sf_internal_rex64): New.
        (mov<MMXMODEI>_internal): Use no register preferences at all.
        (movv2sf_internal): Likewise.

Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.764
diff -c -p -d -r1.764 i386.c
*** config/i386/i386.c	23 Dec 2004 10:38:14 -0000	1.764
--- config/i386/i386.c	27 Dec 2004 03:47:39 -0000
*************** ix86_gimplify_va_arg (tree valist, tree 
*** 3350,3355 ****
--- 3350,3356 ----
    rtx container;
    int indirect_p = 0;
    tree ptrtype;
+   enum machine_mode nat_mode;
  
    /* Only 64bit target needs something special.  */
    if (!TARGET_64BIT)
*************** ix86_gimplify_va_arg (tree valist, tree 
*** 3372,3380 ****
    size = int_size_in_bytes (type);
    rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
  
!   container = construct_container (type_natural_mode (type), TYPE_MODE (type),
! 				   type, 0, REGPARM_MAX, SSE_REGPARM_MAX,
! 				   intreg, 0);
  
    /* Pull the value out of the saved registers.  */
  
--- 3373,3381 ----
    size = int_size_in_bytes (type);
    rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
  
!   nat_mode = type_natural_mode (type);
!   container = construct_container (nat_mode, TYPE_MODE (type), type, 0,
! 				   REGPARM_MAX, SSE_REGPARM_MAX, intreg, 0);
  
    /* Pull the value out of the saved registers.  */
  
*************** ix86_gimplify_va_arg (tree valist, tree 
*** 3390,3397 ****
        lab_false = create_artificial_label ();
        lab_over = create_artificial_label ();
  
!       examine_argument (TYPE_MODE (type), type, 0,
! 		        &needed_intregs, &needed_sseregs);
  
        need_temp = (!REG_P (container)
  		   && ((needed_intregs && TYPE_ALIGN (type) > 64)
--- 3391,3397 ----
        lab_false = create_artificial_label ();
        lab_over = create_artificial_label ();
  
!       examine_argument (nat_mode, type, 0, &needed_intregs, &needed_sseregs);
  
        need_temp = (!REG_P (container)
  		   && ((needed_intregs && TYPE_ALIGN (type) > 64)
Index: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.593
diff -c -p -d -r1.593 i386.md
*** config/i386/i386.md	24 Dec 2004 06:49:34 -0000	1.593
--- config/i386/i386.md	27 Dec 2004 03:47:44 -0000
***************
*** 19853,19863 ****
    DONE;
  })
  
  (define_insn "*mov<mode>_internal"
    [(set (match_operand:MMXMODEI 0 "nonimmediate_operand"
! 					"=y,y ,m,!y,!*Y,*x,?*x,?m")
  	(match_operand:MMXMODEI 1 "vector_move_operand"
! 					"C ,ym,y,*Y,y  ,C ,*xm,*x"))]
    "TARGET_MMX
     && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
    "@
--- 19853,19886 ----
    DONE;
  })
  
+ (define_insn "*mov<mode>_internal_rex64"
+   [(set (match_operand:MMXMODEI 0 "nonimmediate_operand"
+ 				"=rm,r,*y,*y ,m ,*y,Y ,x,x ,m,r,x")
+ 	(match_operand:MMXMODEI 1 "vector_move_operand"
+ 				"Cr ,m,C ,*ym,*y,Y ,*y,C,xm,x,x,r"))]
+   "TARGET_64BIT && TARGET_MMX
+    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
+   "@
+     movq\t{%1, %0|%0, %1}
+     movq\t{%1, %0|%0, %1}
+     pxor\t%0, %0
+     movq\t{%1, %0|%0, %1}
+     movq\t{%1, %0|%0, %1}
+     movdq2q\t{%1, %0|%0, %1}
+     movq2dq\t{%1, %0|%0, %1}
+     pxor\t%0, %0
+     movq\t{%1, %0|%0, %1}
+     movq\t{%1, %0|%0, %1}
+     movd\t{%1, %0|%0, %1}
+     movd\t{%1, %0|%0, %1}"
+   [(set_attr "type" "imov,imov,mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov,ssemov,ssemov")
+    (set_attr "mode" "DI")])
+ 
  (define_insn "*mov<mode>_internal"
    [(set (match_operand:MMXMODEI 0 "nonimmediate_operand"
! 					"=*y,*y ,m ,*y,*Y,*x,*x ,m")
  	(match_operand:MMXMODEI 1 "vector_move_operand"
! 					"C  ,*ym,*y,*Y,*y,C ,*xm,*x"))]
    "TARGET_MMX
     && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
    "@
***************
*** 19881,19891 ****
    DONE;
  })
  
  (define_insn "*movv2sf_internal"
    [(set (match_operand:V2SF 0 "nonimmediate_operand"
! 					"=y,y ,m,!y,!*Y,*x,?*x,?m")
          (match_operand:V2SF 1 "vector_move_operand"
! 					"C ,ym,y,*Y,y  ,C ,*xm,*x"))]
    "TARGET_MMX
     && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
    "@
--- 19904,19937 ----
    DONE;
  })
  
+ (define_insn "*movv2sf_internal_rex64"
+   [(set (match_operand:V2SF 0 "nonimmediate_operand"
+ 				"=rm,r,*y ,*y ,m ,*y,Y ,x,x ,m,r,x")
+         (match_operand:V2SF 1 "vector_move_operand"
+ 				"Cr ,m ,C ,*ym,*y,Y ,*y,C,xm,x,x,r"))]
+   "TARGET_64BIT && TARGET_MMX
+    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
+   "@
+     movq\t{%1, %0|%0, %1}
+     movq\t{%1, %0|%0, %1}
+     pxor\t%0, %0
+     movq\t{%1, %0|%0, %1}
+     movq\t{%1, %0|%0, %1}
+     movdq2q\t{%1, %0|%0, %1}
+     movq2dq\t{%1, %0|%0, %1}
+     xorps\t%0, %0
+     movlps\t{%1, %0|%0, %1}
+     movlps\t{%1, %0|%0, %1}
+     movd\t{%1, %0|%0, %1}
+     movd\t{%1, %0|%0, %1}"
+   [(set_attr "type" "imov,imov,mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov,ssemov,ssemov,ssemov")
+    (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,V4SF,V2SF,V2SF,DI,DI")])
+ 
  (define_insn "*movv2sf_internal"
    [(set (match_operand:V2SF 0 "nonimmediate_operand"
! 					"=*y,*y ,m,*y,*Y,*x,*x ,m")
          (match_operand:V2SF 1 "vector_move_operand"
! 					"C ,*ym,*y,*Y,*y,C ,*xm,*x"))]
    "TARGET_MMX
     && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
    "@


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