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]

SSE scalar move paterns



Hi
This patch adds basic move patterns for scalar SSE/SSE2 FP instructions.  While
these are not usable yet in mainline due to incomplette merger of SSE builtins
changes, with few hacks I can now generate gcc code for SSE/SSE2.  The speedups
are quite noticeable on P4 box and I need this code for sledgehammer port.
I can bootstrap, run testsuite and spec2000 benchmarks on P4 box with SSE
based FP.

While my original part was to submit these patches later, I need to merge
them to the sledgehammer CVS, since we need ABI compliant FP support, I've
decided to clean them up and submit for mainline as well.

In first part I would like to submit the FP codegen patches - this patch,
arithmetics patterns, comparisons and converison instructions.  Later I would
like to continue with helping to merge Cygnus code, improvements for regclass I
made two years ago, caller-save changes and other stuff to get good performance
out of the SSE units.

This patch introduces -msse2 switch to enable SSE2 support, as present in P4.
It also adds -mmix-sse-i387 option.  In future I would like to switch gcc
from using i387 to SSE for floats and doubles when available.  These are
faster and don't have roudning problems as i387.  This option will provide
way to use both units for the caluclations, but currently it hurts performance
badly because of register allocation issues.

Only questional bit is probably the 'Y' constraint I define to be SSE_REGS
when SSE2 is availbale.  This is basically just to reduce number of patterns
in the compiler. Perhaps we should document it as gcc internal.

Mon Feb 12 16:36:27 CET 2001  Jan Hubicka  <jh@suse.cz>

	* i386.c (print_reg): Use ANY_FP_REG instead of FP_REG
	* i386.h (MASK_128BIT_LONG_DOUBLE): Renumber
	(MASK_SSE2): New.
	(MASK_MIX_SSE_I387): New.
	(TARGET_SSE): SSE2 imply SSE.
	(TARGET_SSE2, TARGET_MIX_SSE_I387): New.
	(TARGET_SWITCHES): Add "sse2", "mix-sse-i387".
	(enum reg_class): Add new classes.
	(REG_CLASS_NAMES): Likewise.
	(REG_CLASS_CONTENTS): Likewise.
	(ANY_FP_REG_P, ANY_FP_REGNO_P, SSE_REG_P, SSE_FLOAT_MODE): New macros.
	(REG_CLASS_FROM_LETTER): 'x' and 'y' is SSE_REGS only when SSE is
	supported. Add 'Y' to be SSE_REGS when SSE2 is supported.
	(CLASS_MAX_NREGS): Use new macros.
	(REGISTER_MOVE_COST): Rewrite using SECONDARY_MEMORY_MAYBE_NEEDED.
	* i386.md (pushsf, movsf): Support SSE.
	(pushdf_nointeger, pushdf_integer, pushdf): Support SSE, update
	splitters to use ANY_FP_REGNO_P.
	(movdf_nointeger, movdf_integer): Likewise.

Index: i386.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.h,v
retrieving revision 1.147
diff -c -3 -p -r1.147 i386.h
*** i386.h	2001/02/08 19:15:37	1.147
--- i386.h	2001/02/12 22:01:50
*************** extern int target_flags;
*** 104,110 ****
  #define MASK_ACCUMULATE_OUTGOING_ARGS 0x00008000/* Accumulate outgoing args */
  #define MASK_MMX		0x00010000	/* Support MMX regs/builtins */
  #define MASK_SSE		0x00020000	/* Support SSE regs/builtins */
! #define MASK_128BIT_LONG_DOUBLE 0x00040000	/* long double size is 128bit */
  
  /* Temporary codegen switches */
  #define MASK_INTEL_SYNTAX	0x00000200
--- 104,112 ----
  #define MASK_ACCUMULATE_OUTGOING_ARGS 0x00008000/* Accumulate outgoing args */
  #define MASK_MMX		0x00010000	/* Support MMX regs/builtins */
  #define MASK_SSE		0x00020000	/* Support SSE regs/builtins */
! #define MASK_SSE2		0x00040000	/* Support SSE2 regs/builtins */
! #define MASK_128BIT_LONG_DOUBLE 0x00080000	/* long double size is 128bit */
! #define MASK_MIX_SSE_I387	0x00100000	/* Mix SSE and i387 instructions */
  
  /* Temporary codegen switches */
  #define MASK_INTEL_SYNTAX	0x00000200
*************** extern const int x86_partial_reg_depende
*** 226,232 ****
  
  #define ASSEMBLER_DIALECT ((target_flags & MASK_INTEL_SYNTAX) != 0)
  
! #define TARGET_SSE ((target_flags & MASK_SSE) != 0)
  #define TARGET_MMX ((target_flags & MASK_MMX) != 0)
  
  #define TARGET_SWITCHES							      \
--- 230,238 ----
  
  #define ASSEMBLER_DIALECT ((target_flags & MASK_INTEL_SYNTAX) != 0)
  
! #define TARGET_SSE ((target_flags & (MASK_SSE | MASK_SSE2)) != 0)
! #define TARGET_SSE2 ((target_flags & MASK_SSE2) != 0)
! #define TARGET_MIX_SSE_I387 ((target_flags & MASK_MIX_SSE_I387) != 0)
  #define TARGET_MMX ((target_flags & MASK_MMX) != 0)
  
  #define TARGET_SWITCHES							      \
*************** extern const int x86_partial_reg_depende
*** 298,306 ****
    { "no-mmx",			-MASK_MMX,				      \
      N_("Do not support MMX builtins") },				      \
    { "sse",			 MASK_SSE,				      \
!     N_("Support MMX and SSE builtins") },				      \
    { "no-sse",			-MASK_SSE,				      \
!     N_("Do not support MMX and SSE builtins") },			      \
    { "128bit-long-double",	 MASK_128BIT_LONG_DOUBLE,		      \
      N_("sizeof(long double) is 16.") },					      \
    { "96bit-long-double",	-MASK_128BIT_LONG_DOUBLE,		      \
--- 304,320 ----
    { "no-mmx",			-MASK_MMX,				      \
      N_("Do not support MMX builtins") },				      \
    { "sse",			 MASK_SSE,				      \
!     N_("Support MMX and SSE builtins and code generation") },		      \
    { "no-sse",			-MASK_SSE,				      \
!     N_("Do not support MMX and SSE builtins and code generation") },	      \
!   { "sse2",			 MASK_SSE2,				      \
!     N_("Support MMX, SSE and SSE2 builtins and code generation") },	      \
!   { "no-sse2",			-MASK_SSE2,				      \
!     N_("Do not support MMX, SSE and SSE2 builtins and code generation") },    \
!   { "mix-sse-i387",		 MASK_MIX_SSE_I387,			      \
!     N_("Use both SSE and i387 instruction sets for floating point arithmetics") },\
!   { "nomix-sse-i387",		-MASK_MIX_SSE_I387,			      \
!     N_("Use both SSE and i387 instruction sets for floating point arithmetics") },\
    { "128bit-long-double",	 MASK_128BIT_LONG_DOUBLE,		      \
      N_("sizeof(long double) is 16.") },					      \
    { "96bit-long-double",	-MASK_128BIT_LONG_DOUBLE,		      \
*************** extern int ix86_arch;
*** 765,771 ****
        : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))
  
  #define VALID_SSE_REG_MODE(MODE) \
!     ((MODE) == TImode || (MODE) == V4SFmode || (MODE) == V4SImode)
  
  #define VALID_MMX_REG_MODE(MODE) \
      ((MODE) == DImode || (MODE) == V8QImode || (MODE) == V4HImode \
--- 779,786 ----
        : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))
  
  #define VALID_SSE_REG_MODE(MODE) \
!     ((MODE) == TImode || (MODE) == V4SFmode || (MODE) == V4SImode \
!      || (MODE) == SFmode || (TARGET_SSE2 && (MODE) == DFmode))
  
  #define VALID_MMX_REG_MODE(MODE) \
      ((MODE) == DImode || (MODE) == V8QImode || (MODE) == V4HImode \
*************** enum reg_class
*** 945,957 ****
    FLOAT_REGS,
    SSE_REGS,
    MMX_REGS,
!   FLOAT_INT_REGS,		/* FLOAT_REGS and GENERAL_REGS.  */
    ALL_REGS, LIM_REG_CLASSES
  };
  
  #define N_REG_CLASSES (int) LIM_REG_CLASSES
  
  #define FLOAT_CLASS_P(CLASS) (reg_class_subset_p (CLASS, FLOAT_REGS))
  
  #define Q_CLASS_P(CLASS) (reg_class_subset_p (CLASS, Q_REGS))
  
--- 972,994 ----
    FLOAT_REGS,
    SSE_REGS,
    MMX_REGS,
!   FP_TOP_SSE_REGS,
!   FP_SECOND_SSE_REGS,
!   FLOAT_SSE_REGS,
!   FLOAT_INT_REGS,
!   INT_SSE_REGS,
!   FLOAT_INT_SSE_REGS,
    ALL_REGS, LIM_REG_CLASSES
  };
  
  #define N_REG_CLASSES (int) LIM_REG_CLASSES
  
  #define FLOAT_CLASS_P(CLASS) (reg_class_subset_p (CLASS, FLOAT_REGS))
*************** enum reg_class
*** 969,975 ****
--- 1006,1017 ----
     "FLOAT_REGS",			\
     "SSE_REGS",				\
     "MMX_REGS",				\
+    "FP_TOP_SSE_REGS",			\
+    "FP_SECOND_SSE_REGS",		\
+    "FLOAT_SSE_REGS",			\
     "FLOAT_INT_REGS",			\
+    "INT_SSE_REGS",			\
+    "FLOAT_INT_SSE_REGS",		\
     "ALL_REGS" }
  
  /* Define which registers fit in which classes.
*************** enum reg_class
*** 990,996 ****
--- 1032,1043 ----
      { 0xff00,  0x0 },			/* FLOAT_REGS */		\
  { 0x1fe00000,  0x0 },			/* SSE_REGS */			\
  { 0xe0000000, 0x1f },			/* MMX_REGS */			\
+ { 0x1fe00100,  0x0 },			/* FP_TOP_SSE_REG */		\
+ { 0x1fe00200,  0x0 },			/* FP_SECOND_SSE_REG */		\
+ { 0x1fe0ff00,  0x0 },			/* FLOAT_SSE_REGS */		\
     { 0x1ffff,  0x0 },			/* FLOAT_INT_REGS */		\
+ { 0x1fe100ff,  0x0 },			/* INT_SSE_REGS */		\
+ { 0x1fe1ffff,  0x0 },			/* FLOAT_INT_SSE_REGS */	\
  { 0xffffffff, 0x1f }							\
  }
  
*************** enum reg_class
*** 1014,1021 ****
--- 1061,1074 ----
  
  #define FP_REG_P(X) (REG_P (X) && FP_REGNO_P (REGNO (X)))
  #define FP_REGNO_P(n) ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG)
+ #define ANY_FP_REG_P(X) (REG_P (X) && ANY_FP_REGNO_P (REGNO (X)))
+ #define ANY_FP_REGNO_P(n) (FP_REGNO_P (n) || SSE_REGNO_P (n))
  
  #define SSE_REGNO_P(n) ((n) >= FIRST_SSE_REG && (n) <= LAST_SSE_REG)
+ #define SSE_REG_P(n) (REG_P (n) && SSE_REGNO_P (REGNO (n)))
+ 
+ #define SSE_FLOAT_MODE_P(m) \
+   ((TARGET_SSE && (m) == SFmode) || (TARGET_SSE2 && (m) == DFmode))
  
  #define MMX_REGNO_P(n) ((n) >= FIRST_MMX_REG && (n) <= LAST_MMX_REG)
  #define MMX_REG_P(xop) (REG_P (xop) && MMX_REGNO_P (REGNO (xop)))
*************** enum reg_class
*** 1059,1066 ****
     (C) == 'b' ? BREG :						\
     (C) == 'c' ? CREG :						\
     (C) == 'd' ? DREG :						\
!    (C) == 'x' ? SSE_REGS :					\
!    (C) == 'y' ? MMX_REGS :					\
     (C) == 'A' ? AD_REGS :					\
     (C) == 'D' ? DIREG :						\
     (C) == 'S' ? SIREG : NO_REGS)
--- 1112,1120 ----
     (C) == 'b' ? BREG :						\
     (C) == 'c' ? CREG :						\
     (C) == 'd' ? DREG :						\
!    (C) == 'x' ? TARGET_SSE ? SSE_REGS : NO_REGS :		\
!    (C) == 'Y' ? TARGET_SSE2? SSE_REGS : NO_REGS :		\
!    (C) == 'y' ? TARGET_MMX ? MMX_REGS : NO_REGS :		\
     (C) == 'A' ? AD_REGS :					\
     (C) == 'D' ? DIREG :						\
     (C) == 'S' ? SIREG : NO_REGS)
*************** enum reg_class
*** 1147,1153 ****
  /* On the 80386, this is the size of MODE in words,
     except in the FP regs, where a single reg is always enough.  */
  #define CLASS_MAX_NREGS(CLASS, MODE)					\
!  (FLOAT_CLASS_P (CLASS) || (CLASS) == SSE_REGS || (CLASS) == MMX_REGS	\
    ? 1									\
    : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
  
--- 1191,1197 ----
  /* On the 80386, this is the size of MODE in words,
     except in the FP regs, where a single reg is always enough.  */
  #define CLASS_MAX_NREGS(CLASS, MODE)					\
!  (FLOAT_CLASS_P (CLASS) || SSE_CLASS_P (CLASS) || MMX_CLASS_P (CLASS)	\
    ? 1									\
    : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
  
Index: i386.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.c,v
retrieving revision 1.211
diff -c -3 -p -r1.211 i386.c
*** i386.c	2001/02/08 19:15:37	1.211
--- i386.c	2001/02/12 22:02:43
*************** print_reg (x, code, file)
*** 3285,3291 ****
      case 4:
      case 8:
      case 12:
!       if (! FP_REG_P (x))
  	putc ('e', file);
        /* FALLTHRU */
      case 16:
--- 3292,3298 ----
      case 4:
      case 8:
      case 12:
!       if (! ANY_FP_REG_P (x))
  	putc ('e', file);
        /* FALLTHRU */
      case 16:
Index: i386.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.md,v
retrieving revision 1.204
diff -c -3 -p -r1.204 i386.md
*** i386.md	2001/01/29 18:31:35	1.204
--- i386.md	2001/02/12 22:03:15
***************
*** 2100,2107 ****
    "ix86_expand_move (SFmode, operands); DONE;")
  
  (define_insn "*pushsf"
!   [(set (match_operand:SF 0 "push_operand" "=<,<")
! 	(match_operand:SF 1 "general_no_elim_operand" "f#r,rFm#f"))]
    ""
    "*
  {
--- 2148,2155 ----
    "ix86_expand_move (SFmode, operands); DONE;")
  
  (define_insn "*pushsf"
!   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
! 	(match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x"))]
    ""
    "*
  {
***************
*** 2119,2131 ****
  
      case 1:
        return \"push{l}\\t%1\";
  
      default:
        abort ();
      }
  }"
!   [(set_attr "type" "multi,push")
!    (set_attr "mode" "SF,SI")])
  
  (define_split
    [(set (match_operand:SF 0 "push_operand" "")
--- 2167,2181 ----
  
      case 1:
        return \"push{l}\\t%1\";
+     case 2:
+       return \"#\";
  
      default:
        abort ();
      }
  }"
!   [(set_attr "type" "multi,push,multi")
!    (set_attr "mode" "SF,SI,SF")])
  
  (define_split
    [(set (match_operand:SF 0 "push_operand" "")
***************
*** 2143,2155 ****
  (define_split
    [(set (match_operand:SF 0 "push_operand" "")
  	(match_operand:SF 1 "register_operand" ""))]
!   "FP_REGNO_P (REGNO (operands[1]))"
    [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
     (set (mem:SF (reg:SI 7)) (match_dup 1))])
  
  (define_insn "*movsf_1"
!   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,m")
! 	(match_operand:SF 1 "general_operand" "fm#r,f#r,G,rmF#f,Fr#f"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && (reload_in_progress || reload_completed
         || GET_CODE (operands[1]) != CONST_DOUBLE
--- 2193,2205 ----
  (define_split
    [(set (match_operand:SF 0 "push_operand" "")
  	(match_operand:SF 1 "register_operand" ""))]
!   "ANY_FP_REGNO_P (REGNO (operands[1]))"
    [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
     (set (mem:SF (reg:SI 7)) (match_dup 1))])
  
  (define_insn "*movsf_1"
!   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,m")
! 	(match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,xm#rf,x#rf"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && (reload_in_progress || reload_completed
         || GET_CODE (operands[1]) != CONST_DOUBLE
***************
*** 2186,2198 ****
      case 3:
      case 4:
        return \"mov{l}\\t{%1, %0|%0, %1}\";
  
      default:
        abort();
      }
  }"
!   [(set_attr "type" "fmov,fmov,fmov,imov,imov")
!    (set_attr "mode" "SF,SF,SF,SI,SI")])
  
  (define_split
    [(set (match_operand:SF 0 "nonimmediate_operand" "")
--- 2236,2251 ----
      case 3:
      case 4:
        return \"mov{l}\\t{%1, %0|%0, %1}\";
+     case 5:
+     case 6:
+       return \"movss\\t{%1, %0|%0, %1}\";
  
      default:
        abort();
      }
  }"
!   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse")
!    (set_attr "mode" "SF,SF,SF,SI,SI,SF,SF")])
  
  (define_split
    [(set (match_operand:SF 0 "nonimmediate_operand" "")
***************
*** 2201,2206 ****
--- 2254,2261 ----
     && GET_CODE (operands[1]) == MEM
     && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
     && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
+    && !(SSE_REG_P (operands[0]) 
+         || (GET_CODE (operands[0]) == SUBREG && SSE_REG_P (operands[0])))
     && (!(FP_REG_P (operands[0]) || 
  	 (GET_CODE (operands[0]) == SUBREG
  	  && FP_REG_P (SUBREG_REG (operands[0]))))
***************
*** 2214,2220 ****
  	(match_operand:SF 1 "register_operand" "+f"))
     (set (match_dup 1)
  	(match_dup 0))]
!   ""
    "*
  {
    if (STACK_TOP_P (operands[0]))
--- 2269,2275 ----
  	(match_operand:SF 1 "register_operand" "+f"))
     (set (match_dup 1)
  	(match_dup 0))]
!   "reload_completed || !TARGET_SSE2"
    "*
  {
    if (STACK_TOP_P (operands[0]))
***************
*** 2237,2244 ****
  ;; pattern for optimize_size too.
  
  (define_insn "*pushdf_nointeger"
!   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
! 	(match_operand:DF 1 "general_no_elim_operand" "f,Fo#f,*r#f"))]
    "!TARGET_INTEGER_DFMODE_MOVES"
    "*
  {
--- 2292,2299 ----
  ;; pattern for optimize_size too.
  
  (define_insn "*pushdf_nointeger"
!   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
! 	(match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y"))]
    "!TARGET_INTEGER_DFMODE_MOVES"
    "*
  {
***************
*** 2256,2261 ****
--- 2311,2317 ----
  
      case 1:
      case 2:
+     case 3:
        return \"#\";
  
      default:
***************
*** 2263,2273 ****
      }
  }"
    [(set_attr "type" "multi")
!    (set_attr "mode" "DF,SI,SI")])
  
  (define_insn "*pushdf_integer"
!   [(set (match_operand:DF 0 "push_operand" "=<,<")
! 	(match_operand:DF 1 "general_no_elim_operand" "f#r,rFo#f"))]
    "TARGET_INTEGER_DFMODE_MOVES"
    "*
  {
--- 2319,2329 ----
      }
  }"
    [(set_attr "type" "multi")
!    (set_attr "mode" "DF,SI,SI,DF")])
  
  (define_insn "*pushdf_integer"
!   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
! 	(match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
    "TARGET_INTEGER_DFMODE_MOVES"
    "*
  {
***************
*** 2284,2289 ****
--- 2340,2346 ----
  	return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
  
      case 1:
+     case 2:
        return \"#\";
  
      default:
***************
*** 2291,2303 ****
      }
  }"
    [(set_attr "type" "multi")
!    (set_attr "mode" "DF,SI")])
  
  ;; %%% Kill this when call knows how to work this out.
  (define_split
    [(set (match_operand:DF 0 "push_operand" "")
  	(match_operand:DF 1 "register_operand" ""))]
!   "reload_completed && FP_REGNO_P (REGNO (operands[1]))"
    [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
     (set (mem:DF (reg:SI 7)) (match_dup 1))]
    "")
--- 2348,2360 ----
      }
  }"
    [(set_attr "type" "multi")
!    (set_attr "mode" "DF,SI,DF")])
  
  ;; %%% Kill this when call knows how to work this out.
  (define_split
    [(set (match_operand:DF 0 "push_operand" "")
  	(match_operand:DF 1 "register_operand" ""))]
!   "reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
    [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
     (set (mem:DF (reg:SI 7)) (match_dup 1))]
    "")
***************
*** 2314,2321 ****
  ;; when optimizing for size.
  
  (define_insn "*movdf_nointeger"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,f,*r,o")
! 	(match_operand:DF 1 "general_operand" "fm,f,G,*roF,F*r"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
     && (reload_in_progress || reload_completed
--- 2371,2378 ----
  ;; when optimizing for size.
  
  (define_insn "*movdf_nointeger"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,m")
! 	(match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,Ym#f,Y#f"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
     && (reload_in_progress || reload_completed
***************
*** 2353,2369 ****
      case 3:
      case 4:
        return \"#\";
  
      default:
        abort();
      }
  }"
!   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
!    (set_attr "mode" "DF,DF,DF,SI,SI")])
  
  (define_insn "*movdf_integer"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
! 	(match_operand:DF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
     && (reload_in_progress || reload_completed
--- 2410,2429 ----
      case 3:
      case 4:
        return \"#\";
+     case 5:
+     case 6:
+       return \"movsd\\t{%1, %0|%0, %1}\";
  
      default:
        abort();
      }
  }"
!   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse")
!    (set_attr "mode" "DF,DF,DF,SI,SI,DF,DF")])
  
  (define_insn "*movdf_integer"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,m")
! 	(match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,Ym#rf,Y#rf"))]
    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
     && (reload_in_progress || reload_completed
***************
*** 2402,2425 ****
      case 4:
        return \"#\";
  
      default:
        abort();
      }
  }"
!   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
!    (set_attr "mode" "DF,DF,DF,SI,SI")])
  
  (define_split
    [(set (match_operand:DF 0 "nonimmediate_operand" "")
  	(match_operand:DF 1 "general_operand" ""))]
    "reload_completed
     && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
!    && ! (FP_REG_P (operands[0]) || 
  	 (GET_CODE (operands[0]) == SUBREG
! 	  && FP_REG_P (SUBREG_REG (operands[0]))))
!    && ! (FP_REG_P (operands[1]) || 
  	 (GET_CODE (operands[1]) == SUBREG
! 	  && FP_REG_P (SUBREG_REG (operands[1]))))"
    [(set (match_dup 2) (match_dup 5))
     (set (match_dup 3) (match_dup 6))]
    "if (ix86_split_long_move (operands)) DONE;")
--- 2462,2489 ----
      case 4:
        return \"#\";
  
+     case 5:
+     case 6:
+       return \"movsd\\t{%1, %0|%0, %1}\";
+ 
      default:
        abort();
      }
  }"
!   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse")
!    (set_attr "mode" "DF,DF,DF,SI,SI,DF,DF")])
  
  (define_split
    [(set (match_operand:DF 0 "nonimmediate_operand" "")
  	(match_operand:DF 1 "general_operand" ""))]
    "reload_completed
     && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
!    && ! (ANY_FP_REG_P (operands[0]) || 
  	 (GET_CODE (operands[0]) == SUBREG
! 	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
!    && ! (ANY_FP_REG_P (operands[1]) || 
  	 (GET_CODE (operands[1]) == SUBREG
! 	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
    [(set (match_dup 2) (match_dup 5))
     (set (match_dup 3) (match_dup 6))]
    "if (ix86_split_long_move (operands)) DONE;")
***************
*** 2431,2436 ****
--- 2495,2502 ----
     && GET_CODE (operands[1]) == MEM
     && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
     && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
+    && !(SSE_REG_P (operands[0]) 
+         || (GET_CODE (operands[0]) == SUBREG && SSE_REG_P (operands[0])))
     && standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0)))"
    [(set (match_dup 0)
  	(match_dup 1))]
***************
*** 2441,2447 ****
  	(match_operand:DF 1 "register_operand" "+f"))
     (set (match_dup 1)
  	(match_dup 0))]
!   ""
    "*
  {
    if (STACK_TOP_P (operands[0]))
--- 2507,2513 ----
  	(match_operand:DF 1 "register_operand" "+f"))
     (set (match_dup 1)
  	(match_dup 0))]
!   "reload_completed || !TARGET_SSE2"
    "*
  {
    if (STACK_TOP_P (operands[0]))
***************
*** 2592,2612 ****
     && (GET_MODE (operands[0]) == XFmode
         || GET_MODE (operands[0]) == TFmode
         || GET_MODE (operands[0]) == DFmode)
!    && (!REG_P (operands[1]) || !FP_REGNO_P (REGNO (operands[1])))"
    [(const_int 0)]
    "if (!ix86_split_long_move (operands)) abort (); DONE;")
  
  (define_split
    [(set (match_operand:XF 0 "push_operand" "")
  	(match_operand:XF 1 "register_operand" ""))]
!   "FP_REGNO_P (REGNO (operands[1]))"
    [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
     (set (mem:XF (reg:SI 7)) (match_dup 1))])
  
  (define_split
    [(set (match_operand:TF 0 "push_operand" "")
  	(match_operand:TF 1 "register_operand" ""))]
!   "FP_REGNO_P (REGNO (operands[1]))"
    [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
     (set (mem:TF (reg:SI 7)) (match_dup 1))])
  
--- 2658,2678 ----
     && (GET_MODE (operands[0]) == XFmode
         || GET_MODE (operands[0]) == TFmode
         || GET_MODE (operands[0]) == DFmode)
!    && (!REG_P (operands[1]) || !ANY_FP_REGNO_P (REGNO (operands[1])))"
    [(const_int 0)]
    "if (!ix86_split_long_move (operands)) abort (); DONE;")
  
  (define_split
    [(set (match_operand:XF 0 "push_operand" "")
  	(match_operand:XF 1 "register_operand" ""))]
!   "ANY_FP_REGNO_P (REGNO (operands[1]))"
    [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
     (set (mem:XF (reg:SI 7)) (match_dup 1))])
  
  (define_split
    [(set (match_operand:TF 0 "push_operand" "")
  	(match_operand:TF 1 "register_operand" ""))]
!   "ANY_FP_REGNO_P (REGNO (operands[1]))"
    [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
     (set (mem:TF (reg:SI 7)) (match_dup 1))])
  
***************
*** 2805,2816 ****
    "reload_completed
     && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
!    && ! (FP_REG_P (operands[0]) || 
  	 (GET_CODE (operands[0]) == SUBREG
! 	  && FP_REG_P (SUBREG_REG (operands[0]))))
!    && ! (FP_REG_P (operands[1]) || 
  	 (GET_CODE (operands[1]) == SUBREG
! 	  && FP_REG_P (SUBREG_REG (operands[1]))))"
    [(set (match_dup 2) (match_dup 5))
     (set (match_dup 3) (match_dup 6))
     (set (match_dup 4) (match_dup 7))]
--- 2871,2882 ----
    "reload_completed
     && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
     && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
!    && ! (ANY_FP_REG_P (operands[0]) || 
  	 (GET_CODE (operands[0]) == SUBREG
! 	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
!    && ! (ANY_FP_REG_P (operands[1]) || 
  	 (GET_CODE (operands[1]) == SUBREG
! 	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
    [(set (match_dup 2) (match_dup 5))
     (set (match_dup 3) (match_dup 6))
     (set (match_dup 4) (match_dup 7))]


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