i386.md revision 90286
190286Sobrien;; GCC machine description for IA-32 and x86-64.
290286Sobrien;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
390286Sobrien;; Free Software Foundation, Inc.
418334Speter;; Mostly by William Schelter.
590286Sobrien;; x86_64 support added by Jan Hubicka
690286Sobrien;;
718334Speter;; This file is part of GNU CC.
890286Sobrien;;
918334Speter;; GNU CC is free software; you can redistribute it and/or modify
1018334Speter;; it under the terms of the GNU General Public License as published by
1118334Speter;; the Free Software Foundation; either version 2, or (at your option)
1218334Speter;; any later version.
1390286Sobrien;;
1418334Speter;; GNU CC is distributed in the hope that it will be useful,
1518334Speter;; but WITHOUT ANY WARRANTY; without even the implied warranty of
1618334Speter;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1718334Speter;; GNU General Public License for more details.
1890286Sobrien;;
1918334Speter;; You should have received a copy of the GNU General Public License
2018334Speter;; along with GNU CC; see the file COPYING.  If not, write to
2118334Speter;; the Free Software Foundation, 59 Temple Place - Suite 330,
2290286Sobrien;; Boston, MA 02111-1307, USA.  */
2390286Sobrien;;
2418334Speter;; The original PO technology requires these to be ordered by speed,
2518334Speter;; so that assigner will pick the fastest.
2690286Sobrien;;
2718334Speter;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
2890286Sobrien;;
2918334Speter;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
3018334Speter;; updates for most instructions.
3190286Sobrien;;
3218334Speter;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
3318334Speter;; constraint letters.
3490286Sobrien;;
3590286Sobrien;; The special asm out single letter directives following a '%' are:
3618334Speter;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
3718334Speter;;     operands[1].
3818334Speter;; 'L' Print the opcode suffix for a 32-bit integer opcode.
3918334Speter;; 'W' Print the opcode suffix for a 16-bit integer opcode.
4018334Speter;; 'B' Print the opcode suffix for an 8-bit integer opcode.
4150650Sobrien;; 'Q' Print the opcode suffix for a 64-bit float opcode.
4218334Speter;; 'S' Print the opcode suffix for a 32-bit float opcode.
4318334Speter;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
4418334Speter;; 'J' Print the appropriate jump operand.
4590286Sobrien;;
4618334Speter;; 'b' Print the QImode name of the register for the indicated operand.
4718334Speter;;     %b0 would print %al if operands[0] is reg 0.
4818334Speter;; 'w' Likewise, print the HImode name of the register.
4918334Speter;; 'k' Likewise, print the SImode name of the register.
5018334Speter;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
5118334Speter;; 'y' Print "st(0)" instead of "st" as a register.
5290286Sobrien;;
5318334Speter;; UNSPEC usage:
5418334Speter;; 0  This is a `scas' operation.  The mode of the UNSPEC is always SImode.
5518334Speter;;    operand 0 is the memory address to scan.
5618334Speter;;    operand 1 is a register containing the value to scan for.  The mode
5718334Speter;;       of the scas opcode will be the same as the mode of this operand.
5818334Speter;;    operand 2 is the known alignment of operand 0.
5918334Speter;; 1  This is a `sin' operation.  The mode of the UNSPEC is MODE_FLOAT.
6018334Speter;;    operand 0 is the argument for `sin'.
6118334Speter;; 2  This is a `cos' operation.  The mode of the UNSPEC is MODE_FLOAT.
6218334Speter;;    operand 0 is the argument for `cos'.
6350650Sobrien;; 3  This is part of a `stack probe' operation.  The mode of the UNSPEC is 
6450650Sobrien;;    always SImode.  operand 0 is the size of the stack allocation.
6550650Sobrien;; 4  This is the source of a fake SET of the frame pointer which is used to
6650650Sobrien;;    prevent insns referencing it being scheduled across the initial
6750650Sobrien;;    decrement of the stack pointer.
6850650Sobrien;; 5  This is a `bsf' operation.
6952296Sobrien;; 6  This is the @GOT offset of a PIC address.
7052296Sobrien;; 7  This is the @GOTOFF offset of a PIC address.
7152296Sobrien;; 8  This is a reference to a symbol's @PLT address.
7290286Sobrien;; 9  This is an `fnstsw' operation.
7390286Sobrien;; 10 This is a `sahf' operation.
7490286Sobrien;; 11 This is a `fstcw' operation
7590286Sobrien;; 12 This is behaviour of add when setting carry flag.
7690286Sobrien;; 13 This is a `eh_return' placeholder.
7790286Sobrien
7890286Sobrien;; For SSE/MMX support:
7990286Sobrien;; 30 This is `fix', guaranteed to be truncating.
8090286Sobrien;; 31 This is a `emms' operation.
8190286Sobrien;; 32 This is a `maskmov' operation.
8290286Sobrien;; 33 This is a `movmsk' operation.
8390286Sobrien;; 34 This is a `non-temporal' move.
8490286Sobrien;; 36 This is used to distinguish COMISS from UCOMISS.
8590286Sobrien;; 37 This is a `ldmxcsr' operation.
8690286Sobrien;; 38 This is a forced `movaps' instruction (rather than whatever movti does)
8790286Sobrien;; 39 This is a forced `movups' instruction (rather than whatever movti does)
8890286Sobrien;; 40 This is a `stmxcsr' operation.
8990286Sobrien;; 41 This is a `shuffle' operation.
9090286Sobrien;; 42 This is a `rcp' operation.
9190286Sobrien;; 43 This is a `rsqsrt' operation.
9290286Sobrien;; 44 This is a `sfence' operation.
9390286Sobrien;; 45 This is a noop to prevent excessive combiner cleverness.
9490286Sobrien;; 46 This is a `femms' operation.
9590286Sobrien;; 49 This is a 'pavgusb' operation.
9690286Sobrien;; 50 This is a `pfrcp' operation.
9790286Sobrien;; 51 This is a `pfrcpit1' operation.
9890286Sobrien;; 52 This is a `pfrcpit2' operation.
9990286Sobrien;; 53 This is a `pfrsqrt' operation.
10090286Sobrien;; 54 This is a `pfrsqrit1' operation.
10190286Sobrien
10290286Sobrien;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
10390286Sobrien;; from i386.c.
10490286Sobrien
10590286Sobrien;; In C guard expressions, put expressions which may be compile-time
10690286Sobrien;; constants first.  This allows for better optimization.  For
10790286Sobrien;; example, write "TARGET_64BIT && reload_completed", not
10890286Sobrien;; "reload_completed && TARGET_64BIT".
10990286Sobrien
11018334Speter
11190286Sobrien;; Processor type.  This attribute must exactly match the processor_type
11290286Sobrien;; enumeration in i386.h.
11390286Sobrien(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4"
11490286Sobrien  (const (symbol_ref "ix86_cpu")))
11550650Sobrien
11652296Sobrien;; $FreeBSD: head/contrib/gcc/config/i386/i386.md 90286 2002-02-06 05:02:18Z obrien $
11752296Sobrien
11890286Sobrien;; A basic instruction type.  Refinements due to arguments to be
11990286Sobrien;; provided in other attributes.
12052296Sobrien(define_attr "type"
12190286Sobrien  "other,multi,alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,imul,idiv,ibr,setcc,push,pop,call,callv,icmov,fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,str,cld,sse,mmx,fistp"
12290286Sobrien  (const_string "other"))
12350650Sobrien
12490286Sobrien;; Main data type used by the insn
12590286Sobrien(define_attr "mode" "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF,TI"
12690286Sobrien  (const_string "unknown"))
12752296Sobrien
12890286Sobrien;; Set for i387 operations.
12990286Sobrien(define_attr "i387" ""
13090286Sobrien  (if_then_else (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
13190286Sobrien    (const_int 1)
13290286Sobrien    (const_int 0)))
13352296Sobrien
13490286Sobrien;; The (bounding maximum) length of an instruction immediate.
13590286Sobrien(define_attr "length_immediate" ""
13690286Sobrien  (cond [(eq_attr "type" "incdec,setcc,icmov,ibr,str,cld,lea,other,multi,idiv,sse,mmx")
13790286Sobrien	   (const_int 0)
13890286Sobrien	 (eq_attr "i387" "1")
13990286Sobrien	   (const_int 0)
14090286Sobrien	 (eq_attr "type" "alu1,negnot,alu,icmp,imovx,ishift,imul,push,pop")
14190286Sobrien	   (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
14290286Sobrien	 (eq_attr "type" "imov,test")
14390286Sobrien	   (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
14490286Sobrien	 (eq_attr "type" "call")
14590286Sobrien	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
14690286Sobrien	     (const_int 4)
14790286Sobrien	     (const_int 0))
14890286Sobrien	 (eq_attr "type" "callv")
14990286Sobrien	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
15090286Sobrien	     (const_int 4)
15190286Sobrien	     (const_int 0))
15290286Sobrien	 (eq_attr "type" "ibr")
15390286Sobrien	   (if_then_else (and (ge (minus (match_dup 0) (pc))
15490286Sobrien				  (const_int -128))
15590286Sobrien			      (lt (minus (match_dup 0) (pc))
15690286Sobrien				  (const_int 124)))
15790286Sobrien	     (const_int 1)
15890286Sobrien	     (const_int 4))
15990286Sobrien	 ]
16090286Sobrien	 (symbol_ref "/* Update immediate_length and other attributes! */ abort(),1")))
16152296Sobrien
16290286Sobrien;; The (bounding maximum) length of an instruction address.
16390286Sobrien(define_attr "length_address" ""
16490286Sobrien  (cond [(eq_attr "type" "str,cld,other,multi,fxch")
16590286Sobrien	   (const_int 0)
16690286Sobrien	 (and (eq_attr "type" "call")
16790286Sobrien	      (match_operand 1 "constant_call_address_operand" ""))
16890286Sobrien	     (const_int 0)
16990286Sobrien	 (and (eq_attr "type" "callv")
17090286Sobrien	      (match_operand 1 "constant_call_address_operand" ""))
17190286Sobrien	     (const_int 0)
17290286Sobrien	 ]
17390286Sobrien	 (symbol_ref "ix86_attr_length_address_default (insn)")))
17452296Sobrien
17590286Sobrien;; Set when length prefix is used.
17690286Sobrien(define_attr "prefix_data16" ""
17790286Sobrien  (if_then_else (eq_attr "mode" "HI")
17890286Sobrien    (const_int 1)
17990286Sobrien    (const_int 0)))
18052296Sobrien
18190286Sobrien;; Set when string REP prefix is used.
18290286Sobrien(define_attr "prefix_rep" "" (const_int 0))
18352296Sobrien
18490286Sobrien;; Set when 0f opcode prefix is used.
18590286Sobrien(define_attr "prefix_0f" ""
18690286Sobrien  (if_then_else (eq_attr "type" "imovx,setcc,icmov,sse,mmx")
18790286Sobrien    (const_int 1)
18890286Sobrien    (const_int 0)))
18952296Sobrien
19090286Sobrien;; Set when modrm byte is used.
19190286Sobrien(define_attr "modrm" ""
19290286Sobrien  (cond [(eq_attr "type" "str,cld")
19390286Sobrien	   (const_int 0)
19490286Sobrien	 (eq_attr "i387" "1")
19590286Sobrien	   (const_int 0)
19690286Sobrien         (and (eq_attr "type" "incdec")
19790286Sobrien	      (ior (match_operand:SI 1 "register_operand" "")
19890286Sobrien		   (match_operand:HI 1 "register_operand" "")))
19990286Sobrien	   (const_int 0)
20090286Sobrien	 (and (eq_attr "type" "push")
20190286Sobrien	      (not (match_operand 1 "memory_operand" "")))
20290286Sobrien	   (const_int 0)
20390286Sobrien	 (and (eq_attr "type" "pop")
20490286Sobrien	      (not (match_operand 0 "memory_operand" "")))
20590286Sobrien	   (const_int 0)
20690286Sobrien	 (and (eq_attr "type" "imov")
20790286Sobrien	      (and (match_operand 0 "register_operand" "")
20890286Sobrien	           (match_operand 1 "immediate_operand" "")))
20990286Sobrien	   (const_int 0)
21090286Sobrien	 ]
21190286Sobrien	 (const_int 1)))
21290286Sobrien
21390286Sobrien;; The (bounding maximum) length of an instruction in bytes.
21490286Sobrien;; ??? fistp is in fact fldcw/fistp/fldcw sequence.  Later we may want
21590286Sobrien;; to split it and compute proper length as for other insns.
21690286Sobrien(define_attr "length" ""
21790286Sobrien  (cond [(eq_attr "type" "other,multi,fistp")
21890286Sobrien	   (const_int 16)
21990286Sobrien	 ]
22090286Sobrien	 (plus (plus (attr "modrm")
22190286Sobrien		     (plus (attr "prefix_0f")
22290286Sobrien			   (plus (attr "i387")
22390286Sobrien				 (const_int 1))))
22490286Sobrien	       (plus (attr "prefix_rep")
22590286Sobrien		     (plus (attr "prefix_data16")
22690286Sobrien			   (plus (attr "length_immediate")
22790286Sobrien				 (attr "length_address")))))))
22890286Sobrien
22990286Sobrien;; The `memory' attribute is `none' if no memory is referenced, `load' or
23090286Sobrien;; `store' if there is a simple memory reference therein, or `unknown'
23190286Sobrien;; if the instruction is complex.
23290286Sobrien
23390286Sobrien(define_attr "memory" "none,load,store,both,unknown"
23490286Sobrien  (cond [(eq_attr "type" "other,multi,str")
23590286Sobrien	   (const_string "unknown")
23690286Sobrien	 (eq_attr "type" "lea,fcmov,fpspc,cld")
23790286Sobrien	   (const_string "none")
23890286Sobrien	 (eq_attr "type" "fistp")
23990286Sobrien	   (const_string "both")
24090286Sobrien	 (eq_attr "type" "push")
24190286Sobrien	   (if_then_else (match_operand 1 "memory_operand" "")
24290286Sobrien	     (const_string "both")
24390286Sobrien	     (const_string "store"))
24490286Sobrien	 (eq_attr "type" "pop,setcc")
24590286Sobrien	   (if_then_else (match_operand 0 "memory_operand" "")
24690286Sobrien	     (const_string "both")
24790286Sobrien	     (const_string "load"))
24890286Sobrien	 (eq_attr "type" "icmp,test")
24990286Sobrien	   (if_then_else (ior (match_operand 0 "memory_operand" "")
25090286Sobrien			      (match_operand 1 "memory_operand" ""))
25190286Sobrien	     (const_string "load")
25290286Sobrien	     (const_string "none"))
25390286Sobrien	 (eq_attr "type" "ibr")
25490286Sobrien	   (if_then_else (match_operand 0 "memory_operand" "")
25590286Sobrien	     (const_string "load")
25690286Sobrien	     (const_string "none"))
25790286Sobrien	 (eq_attr "type" "call")
25890286Sobrien	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
25990286Sobrien	     (const_string "none")
26090286Sobrien	     (const_string "load"))
26190286Sobrien	 (eq_attr "type" "callv")
26290286Sobrien	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
26390286Sobrien	     (const_string "none")
26490286Sobrien	     (const_string "load"))
26590286Sobrien	 (and (eq_attr "type" "alu1,negnot")
26690286Sobrien	      (match_operand 1 "memory_operand" ""))
26790286Sobrien	   (const_string "both")
26890286Sobrien	 (and (match_operand 0 "memory_operand" "")
26990286Sobrien	      (match_operand 1 "memory_operand" ""))
27090286Sobrien	   (const_string "both")
27190286Sobrien	 (match_operand 0 "memory_operand" "")
27290286Sobrien	   (const_string "store")
27390286Sobrien	 (match_operand 1 "memory_operand" "")
27490286Sobrien	   (const_string "load")
27590286Sobrien	 (and (eq_attr "type" "!icmp,test,alu1,negnot,fop1,fsgn,imov,imovx,fmov,fcmp,sse,mmx")
27690286Sobrien	      (match_operand 2 "memory_operand" ""))
27790286Sobrien	   (const_string "load")
27890286Sobrien	 (and (eq_attr "type" "icmov")
27990286Sobrien	      (match_operand 3 "memory_operand" ""))
28090286Sobrien	   (const_string "load")
28190286Sobrien	]
28252296Sobrien	(const_string "none")))
28352296Sobrien
28490286Sobrien;; Indicates if an instruction has both an immediate and a displacement.
28550650Sobrien
28690286Sobrien(define_attr "imm_disp" "false,true,unknown"
28790286Sobrien  (cond [(eq_attr "type" "other,multi")
28890286Sobrien	   (const_string "unknown")
28990286Sobrien	 (and (eq_attr "type" "icmp,test,imov")
29090286Sobrien	      (and (match_operand 0 "memory_displacement_operand" "")
29190286Sobrien		   (match_operand 1 "immediate_operand" "")))
29290286Sobrien	   (const_string "true")
29390286Sobrien	 (and (eq_attr "type" "alu,ishift,imul,idiv")
29490286Sobrien	      (and (match_operand 0 "memory_displacement_operand" "")
29590286Sobrien		   (match_operand 2 "immediate_operand" "")))
29690286Sobrien	   (const_string "true")
29790286Sobrien	]
29890286Sobrien	(const_string "false")))
29950650Sobrien
30090286Sobrien;; Indicates if an FP operation has an integer source.
30150650Sobrien
30290286Sobrien(define_attr "fp_int_src" "false,true"
30390286Sobrien  (const_string "false"))
30450650Sobrien
30590286Sobrien;; Describe a user's asm statement.
30690286Sobrien(define_asm_attributes
30790286Sobrien  [(set_attr "length" "128")
30890286Sobrien   (set_attr "type" "multi")])
30990286Sobrien
31090286Sobrien;; Pentium Scheduling
31190286Sobrien;;
31290286Sobrien;; The Pentium is an in-order core with two integer pipelines.
31350650Sobrien
31490286Sobrien;; True for insns that behave like prefixed insns on the Pentium.
31590286Sobrien(define_attr "pent_prefix" "false,true"
31690286Sobrien  (if_then_else (ior (eq_attr "prefix_0f" "1")
31790286Sobrien  		     (ior (eq_attr "prefix_data16" "1")
31890286Sobrien			  (eq_attr "prefix_rep" "1")))
31990286Sobrien    (const_string "true")
32090286Sobrien    (const_string "false")))
32150650Sobrien
32290286Sobrien;; Categorize how an instruction slots.
32350650Sobrien
32490286Sobrien;; The non-MMX Pentium slots an instruction with prefixes on U pipe only,
32590286Sobrien;; while MMX Pentium can slot it on either U or V.  Model non-MMX Pentium
32690286Sobrien;; rules, because it results in noticeably better code on non-MMX Pentium
32790286Sobrien;; and doesn't hurt much on MMX.  (Prefixed instructions are not very
32890286Sobrien;; common, so the scheduler usualy has a non-prefixed insn to pair).
32950650Sobrien
33090286Sobrien(define_attr "pent_pair" "uv,pu,pv,np"
33190286Sobrien  (cond [(eq_attr "imm_disp" "true")
33290286Sobrien	   (const_string "np")
33390286Sobrien	 (ior (eq_attr "type" "alu1,alu,imov,icmp,test,lea,incdec")
33490286Sobrien	      (and (eq_attr "type" "pop,push")
33590286Sobrien		   (eq_attr "memory" "!both")))
33690286Sobrien	   (if_then_else (eq_attr "pent_prefix" "true")
33790286Sobrien	     (const_string "pu")
33890286Sobrien	     (const_string "uv"))
33990286Sobrien	 (eq_attr "type" "ibr")
34090286Sobrien	   (const_string "pv")
34190286Sobrien	 (and (eq_attr "type" "ishift")
34290286Sobrien	      (match_operand 2 "const_int_operand" ""))
34390286Sobrien	   (const_string "pu")
34490286Sobrien	 (and (eq_attr "type" "call")
34590286Sobrien	      (match_operand 0 "constant_call_address_operand" ""))
34690286Sobrien	   (const_string "pv")
34790286Sobrien	 (and (eq_attr "type" "callv")
34890286Sobrien	      (match_operand 1 "constant_call_address_operand" ""))
34990286Sobrien	   (const_string "pv")
35090286Sobrien	]
35190286Sobrien	(const_string "np")))
35250650Sobrien
35390286Sobrien;; Rough readiness numbers.  Fine tuning happens in i386.c.
35490286Sobrien;;
35590286Sobrien;; u	describes pipe U
35690286Sobrien;; v	describes pipe V
35790286Sobrien;; uv	describes either pipe U or V for those that can issue to either
35890286Sobrien;; np	describes not paring
35990286Sobrien;; fpu	describes fpu
36090286Sobrien;; fpm	describes fp insns of different types are not pipelined.
36190286Sobrien;;
36290286Sobrien;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
36350650Sobrien
36490286Sobrien(define_function_unit "pent_np" 1 0
36590286Sobrien  (and (eq_attr "cpu" "pentium")
36690286Sobrien       (eq_attr "type" "imul"))
36790286Sobrien  11 11)
36850650Sobrien
36990286Sobrien(define_function_unit "pent_mul" 1 1
37090286Sobrien  (and (eq_attr "cpu" "pentium")
37190286Sobrien       (eq_attr "type" "imul"))
37290286Sobrien  11 11)
37350650Sobrien
37490286Sobrien;; Rep movs takes minimally 12 cycles.
37590286Sobrien(define_function_unit "pent_np" 1 0
37690286Sobrien  (and (eq_attr "cpu" "pentium")
37790286Sobrien       (eq_attr "type" "str"))
37890286Sobrien  12 12)
37950650Sobrien
38090286Sobrien; ??? IDIV for SI takes 46 cycles, for HI 30, for QI 22
38190286Sobrien(define_function_unit "pent_np" 1 0
38290286Sobrien  (and (eq_attr "cpu" "pentium")
38390286Sobrien       (eq_attr "type" "idiv"))
38490286Sobrien  46 46)
38550650Sobrien
38690286Sobrien; Fp reg-reg moves takes 1 cycle. Loads takes 1 cycle for SF/DF mode,
38790286Sobrien; 3 cycles for XFmode.  Stores takes 2 cycles for SF/DF and 3 for XF.
38890286Sobrien; fldz and fld1 takes 2 cycles.  Only reg-reg moves are pairable.
38990286Sobrien; The integer <-> fp conversion is not modeled correctly. Fild behaves
39090286Sobrien; like normal fp operation and fist takes 6 cycles.
39152296Sobrien
39290286Sobrien(define_function_unit "fpu" 1 0
39390286Sobrien  (and (eq_attr "cpu" "pentium")
39490286Sobrien       (and (eq_attr "type" "fmov")
39590286Sobrien	    (and (eq_attr "memory" "load,store")
39690286Sobrien		 (eq_attr "mode" "XF"))))
39790286Sobrien  3 3)
39852296Sobrien
39990286Sobrien(define_function_unit "pent_np" 1 0
40090286Sobrien  (and (eq_attr "cpu" "pentium")
40190286Sobrien       (and (eq_attr "type" "fmov")
40290286Sobrien	    (and (eq_attr "memory" "load,store")
40390286Sobrien		 (eq_attr "mode" "XF"))))
40490286Sobrien  3 3)
40552296Sobrien
40690286Sobrien(define_function_unit "fpu" 1 0
40790286Sobrien  (and (eq_attr "cpu" "pentium")
40890286Sobrien       (and (eq_attr "type" "fmov")
40990286Sobrien            (ior (match_operand 1 "immediate_operand" "")
41090286Sobrien	         (eq_attr "memory" "store"))))
41190286Sobrien  2 2)
41252296Sobrien
41390286Sobrien(define_function_unit "pent_np" 1 0
41490286Sobrien  (and (eq_attr "cpu" "pentium")
41590286Sobrien       (and (eq_attr "type" "fmov")
41690286Sobrien            (ior (match_operand 1 "immediate_operand" "")
41790286Sobrien	         (eq_attr "memory" "store"))))
41890286Sobrien  2 2)
41952296Sobrien
42090286Sobrien(define_function_unit "pent_np" 1 0
42190286Sobrien  (and (eq_attr "cpu" "pentium")
42290286Sobrien       (eq_attr "type" "cld"))
42352296Sobrien  2 2)
42452296Sobrien
42590286Sobrien(define_function_unit "fpu" 1 0
42690286Sobrien  (and (eq_attr "cpu" "pentium")
42790286Sobrien       (and (eq_attr "type" "fmov")
42890286Sobrien	    (eq_attr "memory" "none,load")))
42990286Sobrien  1 1)
43052296Sobrien
43190286Sobrien; Read/Modify/Write instructions usually take 3 cycles.
43290286Sobrien(define_function_unit "pent_u" 1 0
43390286Sobrien  (and (eq_attr "cpu" "pentium")
43490286Sobrien       (and (eq_attr "type" "alu,alu1,ishift")
43590286Sobrien	    (and (eq_attr "pent_pair" "pu")
43690286Sobrien		 (eq_attr "memory" "both"))))
43790286Sobrien  3 3)
43890286Sobrien
43990286Sobrien(define_function_unit "pent_uv" 2 0
44090286Sobrien  (and (eq_attr "cpu" "pentium")
44190286Sobrien       (and (eq_attr "type" "alu,alu1,ishift")
44290286Sobrien	    (and (eq_attr "pent_pair" "!np")
44390286Sobrien		 (eq_attr "memory" "both"))))
44490286Sobrien  3 3)
44590286Sobrien
44690286Sobrien(define_function_unit "pent_np" 1 0
44790286Sobrien  (and (eq_attr "cpu" "pentium")
44890286Sobrien       (and (eq_attr "type" "alu,alu1,negnot,ishift")
44990286Sobrien	    (and (eq_attr "pent_pair" "np")
45090286Sobrien		 (eq_attr "memory" "both"))))
45190286Sobrien  3 3)
45290286Sobrien
45390286Sobrien; Read/Modify or Modify/Write instructions usually take 2 cycles.
45490286Sobrien(define_function_unit "pent_u" 1 0
45590286Sobrien  (and (eq_attr "cpu" "pentium")
45690286Sobrien       (and (eq_attr "type" "alu,ishift")
45790286Sobrien	    (and (eq_attr "pent_pair" "pu")
45890286Sobrien		 (eq_attr "memory" "load,store"))))
45990286Sobrien  2 2)
46090286Sobrien
46190286Sobrien(define_function_unit "pent_uv" 2 0
46290286Sobrien  (and (eq_attr "cpu" "pentium")
46390286Sobrien       (and (eq_attr "type" "alu,ishift")
46490286Sobrien	    (and (eq_attr "pent_pair" "!np")
46590286Sobrien		 (eq_attr "memory" "load,store"))))
46690286Sobrien  2 2)
46790286Sobrien
46890286Sobrien(define_function_unit "pent_np" 1 0
46990286Sobrien  (and (eq_attr "cpu" "pentium")
47090286Sobrien       (and (eq_attr "type" "alu,ishift")
47190286Sobrien	    (and (eq_attr "pent_pair" "np")
47290286Sobrien		 (eq_attr "memory" "load,store"))))
47390286Sobrien  2 2)
47490286Sobrien
47590286Sobrien; Insns w/o memory operands and move instructions usually take one cycle.
47690286Sobrien(define_function_unit "pent_u" 1 0
47790286Sobrien  (and (eq_attr "cpu" "pentium")
47890286Sobrien       (eq_attr "pent_pair" "pu"))
47990286Sobrien  1 1)
48090286Sobrien
48190286Sobrien(define_function_unit "pent_v" 1 0
48290286Sobrien  (and (eq_attr "cpu" "pentium")
48390286Sobrien       (eq_attr "pent_pair" "pv"))
48490286Sobrien  1 1)
48590286Sobrien
48690286Sobrien(define_function_unit "pent_uv" 2 0
48790286Sobrien  (and (eq_attr "cpu" "pentium")
48890286Sobrien       (eq_attr "pent_pair" "!np"))
48990286Sobrien  1 1)
49090286Sobrien
49190286Sobrien(define_function_unit "pent_np" 1 0
49290286Sobrien  (and (eq_attr "cpu" "pentium")
49390286Sobrien       (eq_attr "pent_pair" "np"))
49490286Sobrien  1 1)
49590286Sobrien
49690286Sobrien; Pairable insns only conflict with other non-pairable insns.
49790286Sobrien(define_function_unit "pent_np" 1 0
49890286Sobrien  (and (eq_attr "cpu" "pentium")
49990286Sobrien       (and (eq_attr "type" "alu,alu1,ishift")
50090286Sobrien	    (and (eq_attr "pent_pair" "!np")
50190286Sobrien		 (eq_attr "memory" "both"))))
50290286Sobrien  3 3
50390286Sobrien  [(eq_attr "pent_pair" "np")])
50490286Sobrien
50590286Sobrien(define_function_unit "pent_np" 1 0
50690286Sobrien  (and (eq_attr "cpu" "pentium")
50790286Sobrien       (and (eq_attr "type" "alu,alu1,ishift")
50890286Sobrien	    (and (eq_attr "pent_pair" "!np")
50990286Sobrien		 (eq_attr "memory" "load,store"))))
51090286Sobrien  2 2
51190286Sobrien  [(eq_attr "pent_pair" "np")])
51290286Sobrien
51390286Sobrien(define_function_unit "pent_np" 1 0
51490286Sobrien  (and (eq_attr "cpu" "pentium")
51590286Sobrien       (eq_attr "pent_pair" "!np"))
51690286Sobrien  1 1
51790286Sobrien  [(eq_attr "pent_pair" "np")])
51890286Sobrien
51990286Sobrien; Floating point instructions usually blocks cycle longer when combined with
52090286Sobrien; integer instructions, because of the inpaired fxch instruction.
52190286Sobrien(define_function_unit "pent_np" 1 0
52290286Sobrien  (and (eq_attr "cpu" "pentium")
52390286Sobrien       (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp,fistp"))
52490286Sobrien  2 2
52590286Sobrien  [(eq_attr "type" "!fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp,fistp")])
52690286Sobrien
52790286Sobrien(define_function_unit "fpu" 1 0
52890286Sobrien  (and (eq_attr "cpu" "pentium")
52990286Sobrien       (eq_attr "type" "fcmp,fxch,fsgn"))
53090286Sobrien  1 1)
53190286Sobrien
53290286Sobrien; Addition takes 3 cycles; assume other random cruft does as well.
53390286Sobrien; ??? Trivial fp operations such as fabs or fchs takes only one cycle.
53490286Sobrien(define_function_unit "fpu" 1 0
53590286Sobrien  (and (eq_attr "cpu" "pentium")
53690286Sobrien       (eq_attr "type" "fop,fop1,fistp"))
53790286Sobrien  3 1)
53890286Sobrien
53990286Sobrien; Multiplication takes 3 cycles and is only half pipelined.
54090286Sobrien(define_function_unit "fpu" 1 0
54190286Sobrien  (and (eq_attr "cpu" "pentium")
54290286Sobrien       (eq_attr "type" "fmul"))
54390286Sobrien  3 1)
54490286Sobrien
54590286Sobrien(define_function_unit "pent_mul" 1 1
54690286Sobrien  (and (eq_attr "cpu" "pentium")
54790286Sobrien       (eq_attr "type" "fmul"))
54890286Sobrien  2 2)
54990286Sobrien
55090286Sobrien; ??? This is correct only for fdiv and sqrt -- sin/cos take 65-100 cycles. 
55190286Sobrien; They can overlap with integer insns.  Only the last two cycles can overlap
55290286Sobrien; with other fp insns.  Only fsin/fcos can overlap with multiplies.
55390286Sobrien; Only last two cycles of fsin/fcos can overlap with other instructions.
55490286Sobrien(define_function_unit "fpu" 1 0
55590286Sobrien  (and (eq_attr "cpu" "pentium")
55690286Sobrien       (eq_attr "type" "fdiv"))
55790286Sobrien  39 37)
55890286Sobrien
55990286Sobrien(define_function_unit "pent_mul" 1 1
56090286Sobrien  (and (eq_attr "cpu" "pentium")
56190286Sobrien       (eq_attr "type" "fdiv"))
56290286Sobrien  39 39)
56390286Sobrien
56490286Sobrien(define_function_unit "fpu" 1 0
56590286Sobrien  (and (eq_attr "cpu" "pentium")
56690286Sobrien       (eq_attr "type" "fpspc"))
56790286Sobrien  70 68)
56890286Sobrien
56990286Sobrien(define_function_unit "pent_mul" 1 1
57090286Sobrien  (and (eq_attr "cpu" "pentium")
57190286Sobrien       (eq_attr "type" "fpspc"))
57290286Sobrien  70 70)
57390286Sobrien
57490286Sobrien;; Pentium Pro/PII Scheduling
57590286Sobrien;;
57690286Sobrien;; The PPro has an out-of-order core, but the instruction decoders are
57790286Sobrien;; naturally in-order and asymmetric.  We get best performance by scheduling
57890286Sobrien;; for the decoders, for in doing so we give the oo execution unit the 
57990286Sobrien;; most choices.
58090286Sobrien
58190286Sobrien;; Categorize how many uops an ia32 instruction evaluates to:
58290286Sobrien;;   one --  an instruction with 1 uop can be decoded by any of the
58390286Sobrien;;           three decoders.
58490286Sobrien;;   few --  an instruction with 1 to 4 uops can be decoded only by 
58590286Sobrien;;	     decoder 0.
58690286Sobrien;;   many -- a complex instruction may take an unspecified number of
58790286Sobrien;;	     cycles to decode in decoder 0.
58890286Sobrien
58990286Sobrien(define_attr "ppro_uops" "one,few,many"
59090286Sobrien  (cond [(eq_attr "type" "other,multi,call,callv,fpspc,str")
59190286Sobrien	   (const_string "many")
59290286Sobrien	 (eq_attr "type" "icmov,fcmov,str,cld")
59390286Sobrien	   (const_string "few")
59490286Sobrien	 (eq_attr "type" "imov")
59590286Sobrien	   (if_then_else (eq_attr "memory" "store,both")
59690286Sobrien	     (const_string "few")
59790286Sobrien	     (const_string "one"))
59890286Sobrien	 (eq_attr "memory" "!none")
59990286Sobrien	   (const_string "few")
60090286Sobrien	]
60190286Sobrien	(const_string "one")))
60290286Sobrien
60390286Sobrien;; Rough readiness numbers.  Fine tuning happens in i386.c.
60490286Sobrien;;
60590286Sobrien;; p0	describes port 0.
60690286Sobrien;; p01	describes ports 0 and 1 as a pair; alu insns can issue to either.
60790286Sobrien;; p2	describes port 2 for loads.
60890286Sobrien;; p34	describes ports 3 and 4 for stores.
60990286Sobrien;; fpu	describes the fpu accessed via port 0. 
61090286Sobrien;;	??? It is less than clear if there are separate fadd and fmul units
61190286Sobrien;;	that could operate in parallel.
61290286Sobrien;;
61390286Sobrien;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
61490286Sobrien
61590286Sobrien(define_function_unit "ppro_p0" 1 0
61690286Sobrien  (and (eq_attr "cpu" "pentiumpro")
61790286Sobrien       (eq_attr "type" "ishift,lea,ibr,cld"))
61890286Sobrien  1 1)
61990286Sobrien
62090286Sobrien(define_function_unit "ppro_p0" 1 0
62190286Sobrien  (and (eq_attr "cpu" "pentiumpro")
62290286Sobrien       (eq_attr "type" "imul"))
62390286Sobrien  4 1)
62490286Sobrien
62590286Sobrien;; ??? Does the divider lock out the pipe while it works,
62690286Sobrien;; or is there a disconnected unit?
62790286Sobrien(define_function_unit "ppro_p0" 1 0
62890286Sobrien  (and (eq_attr "cpu" "pentiumpro")
62990286Sobrien       (eq_attr "type" "idiv"))
63052296Sobrien  17 17)
63152296Sobrien
63290286Sobrien(define_function_unit "ppro_p0" 1 0
63390286Sobrien  (and (eq_attr "cpu" "pentiumpro")
63490286Sobrien       (eq_attr "type" "fop,fop1,fsgn,fistp"))
63590286Sobrien  3 1)
63652296Sobrien
63790286Sobrien(define_function_unit "ppro_p0" 1 0
63890286Sobrien  (and (eq_attr "cpu" "pentiumpro")
63990286Sobrien       (eq_attr "type" "fcmov"))
64090286Sobrien  2 1)
64152296Sobrien
64290286Sobrien(define_function_unit "ppro_p0" 1 0
64390286Sobrien  (and (eq_attr "cpu" "pentiumpro")
64490286Sobrien       (eq_attr "type" "fcmp"))
64590286Sobrien  1 1)
64652296Sobrien
64790286Sobrien(define_function_unit "ppro_p0" 1 0
64890286Sobrien  (and (eq_attr "cpu" "pentiumpro")
64990286Sobrien       (eq_attr "type" "fmov"))
65090286Sobrien  1 1)
65152296Sobrien
65290286Sobrien(define_function_unit "ppro_p0" 1 0
65390286Sobrien  (and (eq_attr "cpu" "pentiumpro")
65490286Sobrien       (eq_attr "type" "fmul"))
65590286Sobrien  5 1)
65690286Sobrien
65790286Sobrien(define_function_unit "ppro_p0" 1 0
65890286Sobrien  (and (eq_attr "cpu" "pentiumpro")
65990286Sobrien       (eq_attr "type" "fdiv,fpspc"))
66090286Sobrien  56 1)
66190286Sobrien
66290286Sobrien(define_function_unit "ppro_p01" 2 0
66390286Sobrien  (and (eq_attr "cpu" "pentiumpro")
66490286Sobrien       (eq_attr "type" "!imov,fmov"))
66590286Sobrien  1 1)
66690286Sobrien
66790286Sobrien(define_function_unit "ppro_p01" 2 0
66890286Sobrien  (and (and (eq_attr "cpu" "pentiumpro")
66990286Sobrien            (eq_attr "type" "imov,fmov"))
67090286Sobrien       (eq_attr "memory" "none"))
67190286Sobrien  1 1)
67290286Sobrien
67390286Sobrien(define_function_unit "ppro_p2" 1 0
67490286Sobrien  (and (eq_attr "cpu" "pentiumpro")
67590286Sobrien       (ior (eq_attr "type" "pop")
67690286Sobrien	    (eq_attr "memory" "load,both")))
67790286Sobrien  3 1)
67890286Sobrien
67990286Sobrien(define_function_unit "ppro_p34" 1 0
68090286Sobrien  (and (eq_attr "cpu" "pentiumpro")
68190286Sobrien       (ior (eq_attr "type" "push")
68290286Sobrien	    (eq_attr "memory" "store,both")))
68390286Sobrien  1 1)
68490286Sobrien
68590286Sobrien(define_function_unit "fpu" 1 0
68690286Sobrien  (and (eq_attr "cpu" "pentiumpro")
68790286Sobrien       (eq_attr "type" "fop,fop1,fsgn,fmov,fcmp,fcmov,fistp"))
68890286Sobrien  1 1)
68990286Sobrien
69090286Sobrien(define_function_unit "fpu" 1 0
69190286Sobrien  (and (eq_attr "cpu" "pentiumpro")
69290286Sobrien       (eq_attr "type" "fmul"))
69390286Sobrien  5 2)
69490286Sobrien
69590286Sobrien(define_function_unit "fpu" 1 0
69690286Sobrien  (and (eq_attr "cpu" "pentiumpro")
69790286Sobrien       (eq_attr "type" "fdiv,fpspc"))
69890286Sobrien  56 56)
69990286Sobrien
70090286Sobrien;; imul uses the fpu.  ??? does it have the same throughput as fmul?
70190286Sobrien(define_function_unit "fpu" 1 0
70290286Sobrien  (and (eq_attr "cpu" "pentiumpro")
70390286Sobrien       (eq_attr "type" "imul"))
70490286Sobrien  4 1)
70550650Sobrien
70690286Sobrien;; AMD K6/K6-2 Scheduling
70718334Speter;;
70890286Sobrien;; The K6 has similar architecture to PPro.  Important difference is, that
70990286Sobrien;; there are only two decoders and they seems to be much slower than execution
71090286Sobrien;; units.  So we have to pay much more attention to proper decoding for
71190286Sobrien;; schedulers.  We share most of scheduler code for PPro in i386.c
71290286Sobrien;;
71390286Sobrien;; The fp unit is not pipelined and do one operation per two cycles including
71490286Sobrien;; the FXCH.
71590286Sobrien;;
71690286Sobrien;; alu	  describes both ALU units (ALU-X and ALU-Y).
71790286Sobrien;; alux   describes X alu unit
71890286Sobrien;; fpu    describes FPU unit
71990286Sobrien;; load   describes load unit.
72090286Sobrien;; branch describes branch unit.
72190286Sobrien;; store  decsribes store unit.  This unit is not modelled completely and only
72290286Sobrien;;        used to model lea operation.  Otherwise it lie outside of the critical
72390286Sobrien;;        path.
72490286Sobrien;;
72590286Sobrien;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
72618334Speter
72790286Sobrien;; The decoder specification is in the PPro section above!
72818334Speter
72990286Sobrien;; Shift instructions and certain arithmetic are issued only to X pipe.
73090286Sobrien(define_function_unit "k6_alux" 1 0
73190286Sobrien  (and (eq_attr "cpu" "k6")
73290286Sobrien       (eq_attr "type" "ishift,alu1,negnot,cld"))
73390286Sobrien  1 1)
73450650Sobrien
73590286Sobrien;; The QI mode arithmetic is issued to X pipe only.
73690286Sobrien(define_function_unit "k6_alux" 1 0
73790286Sobrien  (and (eq_attr "cpu" "k6")
73890286Sobrien       (and (eq_attr "type" "alu,alu1,negnot,icmp,test,imovx,incdec")
73990286Sobrien	    (match_operand:QI 0 "general_operand" "")))
74090286Sobrien  1 1)
74150650Sobrien
74290286Sobrien(define_function_unit "k6_alu" 2 0
74390286Sobrien  (and (eq_attr "cpu" "k6")
74490286Sobrien       (eq_attr "type" "ishift,alu1,negnot,alu,icmp,test,imovx,incdec,setcc,lea"))
74590286Sobrien  1 1)
74618334Speter
74790286Sobrien(define_function_unit "k6_alu" 2 0
74890286Sobrien  (and (eq_attr "cpu" "k6")
74990286Sobrien       (and (eq_attr "type" "imov")
75090286Sobrien       	    (eq_attr "memory" "none")))
75190286Sobrien  1 1)
75218334Speter
75390286Sobrien(define_function_unit "k6_branch" 1 0
75490286Sobrien  (and (eq_attr "cpu" "k6")
75590286Sobrien       (eq_attr "type" "call,callv,ibr"))
75690286Sobrien  1 1)
75718334Speter
75890286Sobrien;; Load unit have two cycle latency, but we take care for it in adjust_cost
75990286Sobrien(define_function_unit "k6_load" 1 0
76090286Sobrien  (and (eq_attr "cpu" "k6")
76190286Sobrien       (ior (eq_attr "type" "pop")
76290286Sobrien	    (eq_attr "memory" "load,both")))
76390286Sobrien  1 1)
76418334Speter
76590286Sobrien(define_function_unit "k6_load" 1 0
76690286Sobrien  (and (eq_attr "cpu" "k6")
76790286Sobrien       (and (eq_attr "type" "str")
76890286Sobrien	    (eq_attr "memory" "load,both")))
76990286Sobrien  10 10)
77018334Speter
77190286Sobrien;; Lea have two instructions, so latency is probably 2
77290286Sobrien(define_function_unit "k6_store" 1 0
77390286Sobrien  (and (eq_attr "cpu" "k6")
77490286Sobrien       (eq_attr "type" "lea"))
77590286Sobrien  2 1)
77618334Speter
77790286Sobrien(define_function_unit "k6_store" 1 0
77890286Sobrien  (and (eq_attr "cpu" "k6")
77990286Sobrien       (eq_attr "type" "str"))
78090286Sobrien  10 10)
78118334Speter
78290286Sobrien(define_function_unit "k6_store" 1 0
78390286Sobrien  (and (eq_attr "cpu" "k6")
78490286Sobrien       (ior (eq_attr "type" "push")
78590286Sobrien	    (eq_attr "memory" "store,both")))
78690286Sobrien  1 1)
78718334Speter
78890286Sobrien(define_function_unit "k6_fpu" 1 1
78990286Sobrien  (and (eq_attr "cpu" "k6")
79090286Sobrien       (eq_attr "type" "fop,fop1,fmov,fcmp,fistp"))
79190286Sobrien  2 2)
79218334Speter
79390286Sobrien(define_function_unit "k6_fpu" 1 1
79490286Sobrien  (and (eq_attr "cpu" "k6")
79590286Sobrien       (eq_attr "type" "fmul"))
79690286Sobrien  2 2)
79718334Speter
79890286Sobrien;; ??? Guess
79990286Sobrien(define_function_unit "k6_fpu" 1 1
80090286Sobrien  (and (eq_attr "cpu" "k6")
80190286Sobrien       (eq_attr "type" "fdiv,fpspc"))
80290286Sobrien  56 56)
80318334Speter
80490286Sobrien(define_function_unit "k6_alu" 2 0
80590286Sobrien  (and (eq_attr "cpu" "k6")
80690286Sobrien       (eq_attr "type" "imul"))
80790286Sobrien  2 2)
80818334Speter
80990286Sobrien(define_function_unit "k6_alux" 1 0
81090286Sobrien  (and (eq_attr "cpu" "k6")
81190286Sobrien       (eq_attr "type" "imul"))
81290286Sobrien  2 2)
81318334Speter
81490286Sobrien;; ??? Guess
81590286Sobrien(define_function_unit "k6_alu" 2 0
81690286Sobrien  (and (eq_attr "cpu" "k6")
81790286Sobrien       (eq_attr "type" "idiv"))
81890286Sobrien  17 17)
81918334Speter
82090286Sobrien(define_function_unit "k6_alux" 1 0
82190286Sobrien  (and (eq_attr "cpu" "k6")
82290286Sobrien       (eq_attr "type" "idiv"))
82390286Sobrien  17 17)
82490286Sobrien
82590286Sobrien;; AMD Athlon Scheduling
82690286Sobrien;;
82790286Sobrien;; The Athlon does contain three pipelined FP units, three integer units and
82890286Sobrien;; three address generation units. 
82990286Sobrien;;
83090286Sobrien;; The predecode logic is determining boundaries of instructions in the 64
83190286Sobrien;; byte cache line. So the cache line straddling problem of K6 might be issue
83290286Sobrien;; here as well, but it is not noted in the documentation.
83390286Sobrien;;
83490286Sobrien;; Three DirectPath instructions decoders and only one VectorPath decoder
83590286Sobrien;; is available. They can decode three DirectPath instructions or one VectorPath
83690286Sobrien;; instruction per cycle.
83790286Sobrien;; Decoded macro instructions are then passed to 72 entry instruction control
83890286Sobrien;; unit, that passes
83990286Sobrien;; it to the specialized integer (18 entry) and fp (36 entry) schedulers.
84090286Sobrien;;
84190286Sobrien;; The load/store queue unit is not attached to the schedulers but
84290286Sobrien;; communicates with all the execution units separately instead.
84318334Speter
84490286Sobrien(define_attr "athlon_decode" "direct,vector"
84590286Sobrien  (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str,pop,cld,fcmov")
84690286Sobrien	   (const_string "vector")
84790286Sobrien         (and (eq_attr "type" "push")
84890286Sobrien              (match_operand 1 "memory_operand" ""))
84990286Sobrien	   (const_string "vector")
85090286Sobrien         (and (eq_attr "type" "fmov")
85190286Sobrien	      (and (eq_attr "memory" "load,store")
85290286Sobrien		   (eq_attr "mode" "XF")))
85390286Sobrien	   (const_string "vector")]
85490286Sobrien	(const_string "direct")))
85518334Speter
85690286Sobrien(define_function_unit "athlon_vectordec" 1 0
85790286Sobrien  (and (eq_attr "cpu" "athlon")
85890286Sobrien       (eq_attr "athlon_decode" "vector"))
85990286Sobrien  1 1)
86018334Speter
86190286Sobrien(define_function_unit "athlon_directdec" 3 0
86290286Sobrien  (and (eq_attr "cpu" "athlon")
86390286Sobrien       (eq_attr "athlon_decode" "direct"))
86490286Sobrien  1 1)
86518334Speter
86690286Sobrien(define_function_unit "athlon_vectordec" 1 0
86790286Sobrien  (and (eq_attr "cpu" "athlon")
86890286Sobrien       (eq_attr "athlon_decode" "direct"))
86990286Sobrien  1 1 [(eq_attr "athlon_decode" "vector")])
87018334Speter
87190286Sobrien(define_function_unit "athlon_ieu" 3 0
87290286Sobrien  (and (eq_attr "cpu" "athlon")
87390286Sobrien       (eq_attr "type" "alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,ibr,call,callv,icmov,cld,pop,setcc,push,pop"))
87490286Sobrien  1 1)
87518334Speter
87690286Sobrien(define_function_unit "athlon_ieu" 3 0
87790286Sobrien  (and (eq_attr "cpu" "athlon")
87890286Sobrien       (eq_attr "type" "str"))
87990286Sobrien  15 15)
88018334Speter
88190286Sobrien(define_function_unit "athlon_ieu" 3 0
88290286Sobrien  (and (eq_attr "cpu" "athlon")
88390286Sobrien       (eq_attr "type" "imul"))
88490286Sobrien  5 0)
88518334Speter
88690286Sobrien(define_function_unit "athlon_ieu" 3 0
88790286Sobrien  (and (eq_attr "cpu" "athlon")
88890286Sobrien       (eq_attr "type" "idiv"))
88990286Sobrien  42 0)
89018334Speter
89190286Sobrien(define_function_unit "athlon_muldiv" 1 0
89290286Sobrien  (and (eq_attr "cpu" "athlon")
89390286Sobrien       (eq_attr "type" "imul"))
89490286Sobrien  5 0)
89518334Speter
89690286Sobrien(define_function_unit "athlon_muldiv" 1 0
89790286Sobrien  (and (eq_attr "cpu" "athlon")
89890286Sobrien       (eq_attr "type" "idiv"))
89990286Sobrien  42 42)
90018334Speter
90190286Sobrien(define_attr "athlon_fpunits" "none,store,mul,add,muladd,any"
90290286Sobrien  (cond [(eq_attr "type" "fop,fop1,fcmp,fistp")
90390286Sobrien	   (const_string "add")
90490286Sobrien         (eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov")
90590286Sobrien	   (const_string "mul")
90690286Sobrien	 (and (eq_attr "type" "fmov") (eq_attr "memory" "store,both"))
90790286Sobrien	   (const_string "store")
90890286Sobrien	 (and (eq_attr "type" "fmov") (eq_attr "memory" "load"))
90990286Sobrien	   (const_string "any")
91090286Sobrien         (and (eq_attr "type" "fmov")
91190286Sobrien              (ior (match_operand:SI 1 "register_operand" "")
91290286Sobrien                   (match_operand 1 "immediate_operand" "")))
91390286Sobrien	   (const_string "store")
91490286Sobrien         (eq_attr "type" "fmov")
91590286Sobrien	   (const_string "muladd")]
91690286Sobrien	(const_string "none")))
91718334Speter
91890286Sobrien;; We use latencies 1 for definitions.  This is OK to model colisions
91990286Sobrien;; in execution units.  The real latencies are modeled in the "fp" pipeline.
92090286Sobrien
92190286Sobrien;; fsin, fcos: 96-192
92290286Sobrien;; fsincos: 107-211
92390286Sobrien;; fsqrt: 19 for SFmode, 27 for DFmode, 35 for XFmode.
92490286Sobrien(define_function_unit "athlon_fp" 3 0
92590286Sobrien  (and (eq_attr "cpu" "athlon")
92690286Sobrien       (eq_attr "type" "fpspc"))
92790286Sobrien  100 1)
92890286Sobrien
92990286Sobrien;; 16 cycles for SFmode, 20 for DFmode and 24 for XFmode.
93090286Sobrien(define_function_unit "athlon_fp" 3 0
93190286Sobrien  (and (eq_attr "cpu" "athlon")
93290286Sobrien       (eq_attr "type" "fdiv"))
93390286Sobrien  24 1)
93490286Sobrien
93590286Sobrien(define_function_unit "athlon_fp" 3 0
93690286Sobrien  (and (eq_attr "cpu" "athlon")
93790286Sobrien       (eq_attr "type" "fop,fop1,fmul,fistp"))
93890286Sobrien  4 1)
93990286Sobrien
94090286Sobrien;; XFmode loads are slow.
94190286Sobrien;; XFmode store is slow too (8 cycles), but we don't need to model it, because
94290286Sobrien;; there are no dependent instructions.
94390286Sobrien
94490286Sobrien(define_function_unit "athlon_fp" 3 0
94590286Sobrien  (and (eq_attr "cpu" "athlon")
94690286Sobrien       (and (eq_attr "type" "fmov")
94790286Sobrien	    (and (eq_attr "memory" "load")
94890286Sobrien		 (eq_attr "mode" "XF"))))
94990286Sobrien  10 1)
95090286Sobrien
95190286Sobrien(define_function_unit "athlon_fp" 3 0
95290286Sobrien  (and (eq_attr "cpu" "athlon")
95390286Sobrien       (eq_attr "type" "fmov,fsgn"))
95490286Sobrien  2 1)
95590286Sobrien
95690286Sobrien;; fcmp and ftst instructions
95790286Sobrien(define_function_unit "athlon_fp" 3 0
95890286Sobrien  (and (eq_attr "cpu" "athlon")
95990286Sobrien       (and (eq_attr "type" "fcmp")
96090286Sobrien	    (eq_attr "athlon_decode" "direct")))
96190286Sobrien  3 1)
96290286Sobrien
96390286Sobrien;; fcmpi instructions.
96490286Sobrien(define_function_unit "athlon_fp" 3 0
96590286Sobrien  (and (eq_attr "cpu" "athlon")
96690286Sobrien       (and (eq_attr "type" "fcmp")
96790286Sobrien	    (eq_attr "athlon_decode" "vector")))
96890286Sobrien  3 1)
96990286Sobrien
97090286Sobrien(define_function_unit "athlon_fp" 3 0
97190286Sobrien  (and (eq_attr "cpu" "athlon")
97290286Sobrien       (eq_attr "type" "fcmov"))
97390286Sobrien  7 1)
97490286Sobrien
97590286Sobrien(define_function_unit "athlon_fp_mul" 1 0
97690286Sobrien  (and (eq_attr "cpu" "athlon")
97790286Sobrien       (eq_attr "athlon_fpunits" "mul"))
97890286Sobrien  1 1)
97990286Sobrien
98090286Sobrien(define_function_unit "athlon_fp_add" 1 0
98190286Sobrien  (and (eq_attr "cpu" "athlon")
98290286Sobrien       (eq_attr "athlon_fpunits" "add"))
98390286Sobrien  1 1)
98490286Sobrien
98590286Sobrien(define_function_unit "athlon_fp_muladd" 2 0
98690286Sobrien  (and (eq_attr "cpu" "athlon")
98790286Sobrien       (eq_attr "athlon_fpunits" "muladd,mul,add"))
98890286Sobrien  1 1)
98990286Sobrien
99090286Sobrien(define_function_unit "athlon_fp_store" 1 0
99190286Sobrien  (and (eq_attr "cpu" "athlon")
99290286Sobrien       (eq_attr "athlon_fpunits" "store"))
99390286Sobrien  1 1)
99490286Sobrien
99590286Sobrien;; We don't need to model the Address Generation Unit, since we don't model
99690286Sobrien;; the re-order buffer yet and thus we never schedule more than three operations
99790286Sobrien;; at time.  Later we may want to experiment with MD_SCHED macros modeling the
99890286Sobrien;; decoders independently on the functional units.
99990286Sobrien
100090286Sobrien;(define_function_unit "athlon_agu" 3 0
100190286Sobrien;  (and (eq_attr "cpu" "athlon")
100290286Sobrien;       (and (eq_attr "memory" "!none")
100390286Sobrien;            (eq_attr "athlon_fpunits" "none")))
100490286Sobrien;  1 1)
100590286Sobrien
100690286Sobrien;; Model load unit to avoid too long sequences of loads.  We don't need to
100790286Sobrien;; model store queue, since it is hardly going to be bottleneck.
100890286Sobrien
100990286Sobrien(define_function_unit "athlon_load" 2 0
101090286Sobrien  (and (eq_attr "cpu" "athlon")
101190286Sobrien       (eq_attr "memory" "load,both"))
101290286Sobrien  1 1)
101390286Sobrien
101490286Sobrien
101590286Sobrien;; Compare instructions.
101690286Sobrien
101790286Sobrien;; All compare insns have expanders that save the operands away without
101890286Sobrien;; actually generating RTL.  The bCOND or sCOND (emitted immediately
101990286Sobrien;; after the cmp) will actually emit the cmpM.
102090286Sobrien
102190286Sobrien(define_expand "cmpdi"
102290286Sobrien  [(set (reg:CC 17)
102390286Sobrien	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
102490286Sobrien		    (match_operand:DI 1 "x86_64_general_operand" "")))]
102590286Sobrien  ""
102618334Speter{
102790286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
102890286Sobrien    operands[0] = force_reg (DImode, operands[0]);
102990286Sobrien  ix86_compare_op0 = operands[0];
103090286Sobrien  ix86_compare_op1 = operands[1];
103118334Speter  DONE;
103290286Sobrien})
103318334Speter
103418334Speter(define_expand "cmpsi"
103590286Sobrien  [(set (reg:CC 17)
103690286Sobrien	(compare:CC (match_operand:SI 0 "cmpsi_operand" "")
103790286Sobrien		    (match_operand:SI 1 "general_operand" "")))]
103818334Speter  ""
103918334Speter{
104018334Speter  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
104118334Speter    operands[0] = force_reg (SImode, operands[0]);
104290286Sobrien  ix86_compare_op0 = operands[0];
104390286Sobrien  ix86_compare_op1 = operands[1];
104418334Speter  DONE;
104590286Sobrien})
104618334Speter
104718334Speter(define_expand "cmphi"
104890286Sobrien  [(set (reg:CC 17)
104990286Sobrien	(compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
105090286Sobrien		    (match_operand:HI 1 "general_operand" "")))]
105118334Speter  ""
105218334Speter{
105318334Speter  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
105418334Speter    operands[0] = force_reg (HImode, operands[0]);
105590286Sobrien  ix86_compare_op0 = operands[0];
105690286Sobrien  ix86_compare_op1 = operands[1];
105718334Speter  DONE;
105890286Sobrien})
105918334Speter
106018334Speter(define_expand "cmpqi"
106190286Sobrien  [(set (reg:CC 17)
106290286Sobrien	(compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
106390286Sobrien		    (match_operand:QI 1 "general_operand" "")))]
106490286Sobrien  "TARGET_QIMODE_MATH"
106518334Speter{
106618334Speter  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
106718334Speter    operands[0] = force_reg (QImode, operands[0]);
106890286Sobrien  ix86_compare_op0 = operands[0];
106990286Sobrien  ix86_compare_op1 = operands[1];
107018334Speter  DONE;
107190286Sobrien})
107218334Speter
107390286Sobrien(define_insn "cmpdi_ccno_1_rex64"
107490286Sobrien  [(set (reg 17)
107590286Sobrien	(compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
107690286Sobrien		 (match_operand:DI 1 "const0_operand" "n,n")))]
107790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
107890286Sobrien  "@
107990286Sobrien   test{q}\t{%0, %0|%0, %0}
108090286Sobrien   cmp{q}\t{%1, %0|%0, %1}"
108190286Sobrien  [(set_attr "type" "test,icmp")
108290286Sobrien   (set_attr "length_immediate" "0,1")
108390286Sobrien   (set_attr "mode" "DI")])
108418334Speter
108590286Sobrien(define_insn "*cmpdi_minus_1_rex64"
108690286Sobrien  [(set (reg 17)
108790286Sobrien	(compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
108890286Sobrien			   (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
108990286Sobrien		 (const_int 0)))]
109090286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
109190286Sobrien  "cmp{q}\t{%1, %0|%0, %1}"
109290286Sobrien  [(set_attr "type" "icmp")
109390286Sobrien   (set_attr "mode" "DI")])
109418334Speter
109590286Sobrien(define_expand "cmpdi_1_rex64"
109690286Sobrien  [(set (reg:CC 17)
109790286Sobrien	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
109890286Sobrien		    (match_operand:DI 1 "general_operand" "")))]
109990286Sobrien  "TARGET_64BIT"
110090286Sobrien  "")
110118334Speter
110290286Sobrien(define_insn "cmpdi_1_insn_rex64"
110390286Sobrien  [(set (reg 17)
110490286Sobrien	(compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
110590286Sobrien		 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
110690286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
110790286Sobrien  "cmp{q}\t{%1, %0|%0, %1}"
110890286Sobrien  [(set_attr "type" "icmp")
110990286Sobrien   (set_attr "mode" "DI")])
111050650Sobrien
111118334Speter
111290286Sobrien(define_insn "*cmpsi_ccno_1"
111390286Sobrien  [(set (reg 17)
111490286Sobrien	(compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
111590286Sobrien		 (match_operand:SI 1 "const0_operand" "n,n")))]
111690286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
111790286Sobrien  "@
111890286Sobrien   test{l}\t{%0, %0|%0, %0}
111990286Sobrien   cmp{l}\t{%1, %0|%0, %1}"
112090286Sobrien  [(set_attr "type" "test,icmp")
112190286Sobrien   (set_attr "length_immediate" "0,1")
112290286Sobrien   (set_attr "mode" "SI")])
112350650Sobrien
112490286Sobrien(define_insn "*cmpsi_minus_1"
112590286Sobrien  [(set (reg 17)
112690286Sobrien	(compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
112790286Sobrien			   (match_operand:SI 1 "general_operand" "ri,mr"))
112890286Sobrien		 (const_int 0)))]
112990286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)"
113090286Sobrien  "cmp{l}\t{%1, %0|%0, %1}"
113190286Sobrien  [(set_attr "type" "icmp")
113290286Sobrien   (set_attr "mode" "SI")])
113318334Speter
113490286Sobrien(define_expand "cmpsi_1"
113590286Sobrien  [(set (reg:CC 17)
113690286Sobrien	(compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
113790286Sobrien		    (match_operand:SI 1 "general_operand" "ri,mr")))]
113890286Sobrien  ""
113990286Sobrien  "")
114018334Speter
114190286Sobrien(define_insn "*cmpsi_1_insn"
114290286Sobrien  [(set (reg 17)
114390286Sobrien	(compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
114490286Sobrien		 (match_operand:SI 1 "general_operand" "ri,mr")))]
114590286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
114690286Sobrien    && ix86_match_ccmode (insn, CCmode)"
114790286Sobrien  "cmp{l}\t{%1, %0|%0, %1}"
114890286Sobrien  [(set_attr "type" "icmp")
114990286Sobrien   (set_attr "mode" "SI")])
115018334Speter
115190286Sobrien(define_insn "*cmphi_ccno_1"
115290286Sobrien  [(set (reg 17)
115390286Sobrien	(compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
115490286Sobrien		 (match_operand:HI 1 "const0_operand" "n,n")))]
115590286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
115690286Sobrien  "@
115790286Sobrien   test{w}\t{%0, %0|%0, %0}
115890286Sobrien   cmp{w}\t{%1, %0|%0, %1}"
115990286Sobrien  [(set_attr "type" "test,icmp")
116090286Sobrien   (set_attr "length_immediate" "0,1")
116190286Sobrien   (set_attr "mode" "HI")])
116218334Speter
116390286Sobrien(define_insn "*cmphi_minus_1"
116490286Sobrien  [(set (reg 17)
116590286Sobrien	(compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
116690286Sobrien			   (match_operand:HI 1 "general_operand" "ri,mr"))
116790286Sobrien		 (const_int 0)))]
116890286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)"
116990286Sobrien  "cmp{w}\t{%1, %0|%0, %1}"
117090286Sobrien  [(set_attr "type" "icmp")
117190286Sobrien   (set_attr "mode" "HI")])
117250650Sobrien
117390286Sobrien(define_insn "*cmphi_1"
117490286Sobrien  [(set (reg 17)
117590286Sobrien	(compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
117690286Sobrien		 (match_operand:HI 1 "general_operand" "ri,mr")))]
117790286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
117890286Sobrien   && ix86_match_ccmode (insn, CCmode)"
117990286Sobrien  "cmp{w}\t{%1, %0|%0, %1}"
118090286Sobrien  [(set_attr "type" "icmp")
118190286Sobrien   (set_attr "mode" "HI")])
118218334Speter
118390286Sobrien(define_insn "*cmpqi_ccno_1"
118490286Sobrien  [(set (reg 17)
118590286Sobrien	(compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
118690286Sobrien		 (match_operand:QI 1 "const0_operand" "n,n")))]
118790286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
118890286Sobrien  "@
118990286Sobrien   test{b}\t{%0, %0|%0, %0}
119090286Sobrien   cmp{b}\t{$0, %0|%0, 0}"
119190286Sobrien  [(set_attr "type" "test,icmp")
119290286Sobrien   (set_attr "length_immediate" "0,1")
119390286Sobrien   (set_attr "mode" "QI")])
119418334Speter
119590286Sobrien(define_insn "*cmpqi_1"
119690286Sobrien  [(set (reg 17)
119790286Sobrien	(compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
119890286Sobrien		 (match_operand:QI 1 "general_operand" "qi,mq")))]
119990286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
120090286Sobrien    && ix86_match_ccmode (insn, CCmode)"
120190286Sobrien  "cmp{b}\t{%1, %0|%0, %1}"
120290286Sobrien  [(set_attr "type" "icmp")
120390286Sobrien   (set_attr "mode" "QI")])
120418334Speter
120590286Sobrien(define_insn "*cmpqi_minus_1"
120690286Sobrien  [(set (reg 17)
120790286Sobrien	(compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
120890286Sobrien			   (match_operand:QI 1 "general_operand" "qi,mq"))
120990286Sobrien		 (const_int 0)))]
121090286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)"
121190286Sobrien  "cmp{b}\t{%1, %0|%0, %1}"
121290286Sobrien  [(set_attr "type" "icmp")
121390286Sobrien   (set_attr "mode" "QI")])
121418334Speter
121590286Sobrien(define_insn "*cmpqi_ext_1"
121690286Sobrien  [(set (reg 17)
121790286Sobrien	(compare
121890286Sobrien	  (match_operand:QI 0 "general_operand" "Qm")
121990286Sobrien	  (subreg:QI
122090286Sobrien	    (zero_extract:SI
122190286Sobrien	      (match_operand 1 "ext_register_operand" "Q")
122290286Sobrien	      (const_int 8)
122390286Sobrien	      (const_int 8)) 0)))]
122490286Sobrien  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
122590286Sobrien  "cmp{b}\t{%h1, %0|%0, %h1}"
122690286Sobrien  [(set_attr "type" "icmp")
122790286Sobrien   (set_attr "mode" "QI")])
122890286Sobrien
122990286Sobrien(define_insn "*cmpqi_ext_1_rex64"
123090286Sobrien  [(set (reg 17)
123190286Sobrien	(compare
123290286Sobrien	  (match_operand:QI 0 "register_operand" "Q")
123390286Sobrien	  (subreg:QI
123490286Sobrien	    (zero_extract:SI
123590286Sobrien	      (match_operand 1 "ext_register_operand" "Q")
123690286Sobrien	      (const_int 8)
123790286Sobrien	      (const_int 8)) 0)))]
123890286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
123990286Sobrien  "cmp{b}\t{%h1, %0|%0, %h1}"
124090286Sobrien  [(set_attr "type" "icmp")
124190286Sobrien   (set_attr "mode" "QI")])
124290286Sobrien
124390286Sobrien(define_insn "*cmpqi_ext_2"
124490286Sobrien  [(set (reg 17)
124590286Sobrien	(compare
124690286Sobrien	  (subreg:QI
124790286Sobrien	    (zero_extract:SI
124890286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
124990286Sobrien	      (const_int 8)
125090286Sobrien	      (const_int 8)) 0)
125190286Sobrien	  (match_operand:QI 1 "const0_operand" "n")))]
125290286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
125390286Sobrien  "test{b}\t%h0, %h0"
125490286Sobrien  [(set_attr "type" "test")
125590286Sobrien   (set_attr "length_immediate" "0")
125690286Sobrien   (set_attr "mode" "QI")])
125790286Sobrien
125890286Sobrien(define_expand "cmpqi_ext_3"
125990286Sobrien  [(set (reg:CC 17)
126090286Sobrien	(compare:CC
126190286Sobrien	  (subreg:QI
126290286Sobrien	    (zero_extract:SI
126390286Sobrien	      (match_operand 0 "ext_register_operand" "")
126490286Sobrien	      (const_int 8)
126590286Sobrien	      (const_int 8)) 0)
126690286Sobrien	  (match_operand:QI 1 "general_operand" "")))]
126790286Sobrien  ""
126890286Sobrien  "")
126990286Sobrien
127090286Sobrien(define_insn "cmpqi_ext_3_insn"
127190286Sobrien  [(set (reg 17)
127290286Sobrien	(compare
127390286Sobrien	  (subreg:QI
127490286Sobrien	    (zero_extract:SI
127590286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
127690286Sobrien	      (const_int 8)
127790286Sobrien	      (const_int 8)) 0)
127890286Sobrien	  (match_operand:QI 1 "general_operand" "Qmn")))]
127990286Sobrien  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
128090286Sobrien  "cmp{b}\t{%1, %h0|%h0, %1}"
128190286Sobrien  [(set_attr "type" "icmp")
128290286Sobrien   (set_attr "mode" "QI")])
128390286Sobrien
128490286Sobrien(define_insn "cmpqi_ext_3_insn_rex64"
128590286Sobrien  [(set (reg 17)
128690286Sobrien	(compare
128790286Sobrien	  (subreg:QI
128890286Sobrien	    (zero_extract:SI
128990286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
129090286Sobrien	      (const_int 8)
129190286Sobrien	      (const_int 8)) 0)
129290286Sobrien	  (match_operand:QI 1 "nonmemory_operand" "Qn")))]
129390286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
129490286Sobrien  "cmp{b}\t{%1, %h0|%h0, %1}"
129590286Sobrien  [(set_attr "type" "icmp")
129690286Sobrien   (set_attr "mode" "QI")])
129790286Sobrien
129890286Sobrien(define_insn "*cmpqi_ext_4"
129990286Sobrien  [(set (reg 17)
130090286Sobrien	(compare
130190286Sobrien	  (subreg:QI
130290286Sobrien	    (zero_extract:SI
130390286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
130490286Sobrien	      (const_int 8)
130590286Sobrien	      (const_int 8)) 0)
130690286Sobrien	  (subreg:QI
130790286Sobrien	    (zero_extract:SI
130890286Sobrien	      (match_operand 1 "ext_register_operand" "Q")
130990286Sobrien	      (const_int 8)
131090286Sobrien	      (const_int 8)) 0)))]
131190286Sobrien  "ix86_match_ccmode (insn, CCmode)"
131290286Sobrien  "cmp{b}\t{%h1, %h0|%h0, %h1}"
131390286Sobrien  [(set_attr "type" "icmp")
131490286Sobrien   (set_attr "mode" "QI")])
131590286Sobrien
131690286Sobrien;; These implement float point compares.
131790286Sobrien;; %%% See if we can get away with VOIDmode operands on the actual insns,
131890286Sobrien;; which would allow mix and match FP modes on the compares.  Which is what
131990286Sobrien;; the old patterns did, but with many more of them.
132090286Sobrien
132118334Speter(define_expand "cmpxf"
132290286Sobrien  [(set (reg:CC 17)
132390286Sobrien	(compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
132490286Sobrien		    (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
132590286Sobrien  "!TARGET_64BIT && TARGET_80387"
132690286Sobrien{
132790286Sobrien  ix86_compare_op0 = operands[0];
132890286Sobrien  ix86_compare_op1 = operands[1];
132990286Sobrien  DONE;
133090286Sobrien})
133190286Sobrien
133290286Sobrien(define_expand "cmptf"
133390286Sobrien  [(set (reg:CC 17)
133490286Sobrien	(compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
133590286Sobrien		    (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
133618334Speter  "TARGET_80387"
133718334Speter{
133890286Sobrien  ix86_compare_op0 = operands[0];
133990286Sobrien  ix86_compare_op1 = operands[1];
134018334Speter  DONE;
134190286Sobrien})
134218334Speter
134318334Speter(define_expand "cmpdf"
134490286Sobrien  [(set (reg:CC 17)
134590286Sobrien	(compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
134690286Sobrien		    (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
134790286Sobrien  "TARGET_80387 || TARGET_SSE2"
134818334Speter{
134990286Sobrien  ix86_compare_op0 = operands[0];
135090286Sobrien  ix86_compare_op1 = operands[1];
135118334Speter  DONE;
135290286Sobrien})
135318334Speter
135418334Speter(define_expand "cmpsf"
135590286Sobrien  [(set (reg:CC 17)
135690286Sobrien	(compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
135790286Sobrien		    (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
135890286Sobrien  "TARGET_80387 || TARGET_SSE"
135918334Speter{
136090286Sobrien  ix86_compare_op0 = operands[0];
136190286Sobrien  ix86_compare_op1 = operands[1];
136218334Speter  DONE;
136390286Sobrien})
136418334Speter
136590286Sobrien;; FP compares, step 1:
136690286Sobrien;; Set the FP condition codes.
136790286Sobrien;;
136890286Sobrien;; CCFPmode	compare with exceptions
136990286Sobrien;; CCFPUmode	compare with no exceptions
137018334Speter
137190286Sobrien;; %%% It is an unfortunate fact that ftst has no non-popping variant,
137290286Sobrien;; and that fp moves clobber the condition codes, and that there is
137390286Sobrien;; currently no way to describe this fact to reg-stack.  So there are
137490286Sobrien;; no splitters yet for this.
137518334Speter
137690286Sobrien;; %%% YIKES!  This scheme does not retain a strong connection between 
137790286Sobrien;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
137890286Sobrien;; work!  Only allow tos/mem with tos in op 0.
137990286Sobrien;;
138090286Sobrien;; Hmm, of course, this is what the actual _hardware_ does.  Perhaps
138190286Sobrien;; things aren't as bad as they sound...
138290286Sobrien
138390286Sobrien(define_insn "*cmpfp_0"
138490286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
138590286Sobrien	(unspec:HI
138690286Sobrien	  [(compare:CCFP (match_operand 1 "register_operand" "f")
138790286Sobrien		         (match_operand 2 "const0_operand" "X"))] 9))]
138890286Sobrien  "TARGET_80387
138990286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
139090286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
139190286Sobrien{
139290286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
139390286Sobrien    return "ftst\;fnstsw\t%0\;fstp\t%y0";
139490286Sobrien  else
139590286Sobrien    return "ftst\;fnstsw\t%0";
139690286Sobrien}
139790286Sobrien  [(set_attr "type" "multi")
139890286Sobrien   (set_attr "mode" "unknownfp")])
139990286Sobrien
140090286Sobrien;; We may not use "#" to split and emit these, since the REG_DEAD notes
140190286Sobrien;; used to manage the reg stack popping would not be preserved.
140290286Sobrien
140390286Sobrien(define_insn "*cmpfp_2_sf"
140490286Sobrien  [(set (reg:CCFP 18)
140590286Sobrien	(compare:CCFP
140690286Sobrien	  (match_operand:SF 0 "register_operand" "f")
140790286Sobrien	  (match_operand:SF 1 "nonimmediate_operand" "fm")))]
140818334Speter  "TARGET_80387"
140990286Sobrien  "* return output_fp_compare (insn, operands, 0, 0);"
141090286Sobrien  [(set_attr "type" "fcmp")
141190286Sobrien   (set_attr "mode" "SF")])
141218334Speter
141390286Sobrien(define_insn "*cmpfp_2_sf_1"
141490286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
141590286Sobrien	(unspec:HI
141690286Sobrien	  [(compare:CCFP
141790286Sobrien	     (match_operand:SF 1 "register_operand" "f")
141890286Sobrien	     (match_operand:SF 2 "nonimmediate_operand" "fm"))] 9))]
141918334Speter  "TARGET_80387"
142090286Sobrien  "* return output_fp_compare (insn, operands, 2, 0);"
142190286Sobrien  [(set_attr "type" "fcmp")
142290286Sobrien   (set_attr "mode" "SF")])
142318334Speter
142490286Sobrien(define_insn "*cmpfp_2_df"
142590286Sobrien  [(set (reg:CCFP 18)
142690286Sobrien	(compare:CCFP
142790286Sobrien	  (match_operand:DF 0 "register_operand" "f")
142890286Sobrien	  (match_operand:DF 1 "nonimmediate_operand" "fm")))]
142918334Speter  "TARGET_80387"
143090286Sobrien  "* return output_fp_compare (insn, operands, 0, 0);"
143190286Sobrien  [(set_attr "type" "fcmp")
143290286Sobrien   (set_attr "mode" "DF")])
143318334Speter
143490286Sobrien(define_insn "*cmpfp_2_df_1"
143590286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
143690286Sobrien	(unspec:HI
143790286Sobrien	  [(compare:CCFP
143890286Sobrien	     (match_operand:DF 1 "register_operand" "f")
143990286Sobrien	     (match_operand:DF 2 "nonimmediate_operand" "fm"))] 9))]
144018334Speter  "TARGET_80387"
144190286Sobrien  "* return output_fp_compare (insn, operands, 2, 0);"
144290286Sobrien  [(set_attr "type" "multi")
144390286Sobrien   (set_attr "mode" "DF")])
144418334Speter
144590286Sobrien(define_insn "*cmpfp_2_xf"
144690286Sobrien  [(set (reg:CCFP 18)
144790286Sobrien	(compare:CCFP
144890286Sobrien	  (match_operand:XF 0 "register_operand" "f")
144990286Sobrien	  (match_operand:XF 1 "register_operand" "f")))]
145090286Sobrien  "!TARGET_64BIT && TARGET_80387"
145190286Sobrien  "* return output_fp_compare (insn, operands, 0, 0);"
145290286Sobrien  [(set_attr "type" "fcmp")
145390286Sobrien   (set_attr "mode" "XF")])
145418334Speter
145590286Sobrien(define_insn "*cmpfp_2_tf"
145690286Sobrien  [(set (reg:CCFP 18)
145790286Sobrien	(compare:CCFP
145890286Sobrien	  (match_operand:TF 0 "register_operand" "f")
145990286Sobrien	  (match_operand:TF 1 "register_operand" "f")))]
146090286Sobrien  "TARGET_80387"
146190286Sobrien  "* return output_fp_compare (insn, operands, 0, 0);"
146290286Sobrien  [(set_attr "type" "fcmp")
146390286Sobrien   (set_attr "mode" "XF")])
146418334Speter
146590286Sobrien(define_insn "*cmpfp_2_xf_1"
146690286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
146790286Sobrien	(unspec:HI
146890286Sobrien	  [(compare:CCFP
146990286Sobrien	     (match_operand:XF 1 "register_operand" "f")
147090286Sobrien	     (match_operand:XF 2 "register_operand" "f"))] 9))]
147190286Sobrien  "!TARGET_64BIT && TARGET_80387"
147290286Sobrien  "* return output_fp_compare (insn, operands, 2, 0);"
147390286Sobrien  [(set_attr "type" "multi")
147490286Sobrien   (set_attr "mode" "XF")])
147518334Speter
147690286Sobrien(define_insn "*cmpfp_2_tf_1"
147790286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
147890286Sobrien	(unspec:HI
147990286Sobrien	  [(compare:CCFP
148090286Sobrien	     (match_operand:TF 1 "register_operand" "f")
148190286Sobrien	     (match_operand:TF 2 "register_operand" "f"))] 9))]
148290286Sobrien  "TARGET_80387"
148390286Sobrien  "* return output_fp_compare (insn, operands, 2, 0);"
148490286Sobrien  [(set_attr "type" "multi")
148590286Sobrien   (set_attr "mode" "XF")])
148618334Speter
148790286Sobrien(define_insn "*cmpfp_2u"
148890286Sobrien  [(set (reg:CCFPU 18)
148990286Sobrien	(compare:CCFPU
149090286Sobrien	  (match_operand 0 "register_operand" "f")
149190286Sobrien	  (match_operand 1 "register_operand" "f")))]
149290286Sobrien  "TARGET_80387
149390286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))
149490286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
149590286Sobrien  "* return output_fp_compare (insn, operands, 0, 1);"
149690286Sobrien  [(set_attr "type" "fcmp")
149790286Sobrien   (set_attr "mode" "unknownfp")])
149818334Speter
149990286Sobrien(define_insn "*cmpfp_2u_1"
150090286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
150190286Sobrien	(unspec:HI
150290286Sobrien	  [(compare:CCFPU
150390286Sobrien	     (match_operand 1 "register_operand" "f")
150490286Sobrien	     (match_operand 2 "register_operand" "f"))] 9))]
150590286Sobrien  "TARGET_80387
150690286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
150790286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
150890286Sobrien  "* return output_fp_compare (insn, operands, 2, 1);"
150990286Sobrien  [(set_attr "type" "multi")
151090286Sobrien   (set_attr "mode" "unknownfp")])
151118334Speter
151290286Sobrien;; Patterns to match the SImode-in-memory ficom instructions.
151390286Sobrien;;
151490286Sobrien;; %%% Play games with accepting gp registers, as otherwise we have to
151590286Sobrien;; force them to memory during rtl generation, which is no good.  We
151690286Sobrien;; can get rid of this once we teach reload to do memory input reloads 
151790286Sobrien;; via pushes.
151818334Speter
151990286Sobrien(define_insn "*ficom_1"
152090286Sobrien  [(set (reg:CCFP 18)
152190286Sobrien	(compare:CCFP
152290286Sobrien	  (match_operand 0 "register_operand" "f,f")
152390286Sobrien	  (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
152490286Sobrien  "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
152590286Sobrien   && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
152690286Sobrien  "#")
152718334Speter
152890286Sobrien;; Split the not-really-implemented gp register case into a
152990286Sobrien;; push-op-pop sequence.
153090286Sobrien;;
153190286Sobrien;; %%% This is most efficient, but am I gonna get in trouble
153290286Sobrien;; for separating cc0_setter and cc0_user?
153318334Speter
153490286Sobrien(define_split
153590286Sobrien  [(set (reg:CCFP 18)
153690286Sobrien	(compare:CCFP
153790286Sobrien	  (match_operand:SF 0 "register_operand" "")
153890286Sobrien	  (float (match_operand:SI 1 "register_operand" ""))))]
153990286Sobrien  "0 && TARGET_80387 && reload_completed"
154090286Sobrien  [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
154190286Sobrien   (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
154290286Sobrien   (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
154390286Sobrien              (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
154490286Sobrien  "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
154590286Sobrien   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
154618334Speter
154790286Sobrien;; FP compares, step 2
154890286Sobrien;; Move the fpsw to ax.
154918334Speter
155090286Sobrien(define_insn "x86_fnstsw_1"
155190286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
155290286Sobrien	(unspec:HI [(reg 18)] 9))]
155390286Sobrien  "TARGET_80387"
155490286Sobrien  "fnstsw\t%0"
155590286Sobrien  [(set_attr "length" "2")
155690286Sobrien   (set_attr "mode" "SI")
155790286Sobrien   (set_attr "i387" "1")
155890286Sobrien   (set_attr "ppro_uops" "few")])
155918334Speter
156090286Sobrien;; FP compares, step 3
156190286Sobrien;; Get ax into flags, general case.
156250650Sobrien
156390286Sobrien(define_insn "x86_sahf_1"
156490286Sobrien  [(set (reg:CC 17)
156590286Sobrien	(unspec:CC [(match_operand:HI 0 "register_operand" "a")] 10))]
156690286Sobrien  "!TARGET_64BIT"
156790286Sobrien  "sahf"
156890286Sobrien  [(set_attr "length" "1")
156990286Sobrien   (set_attr "athlon_decode" "vector")
157090286Sobrien   (set_attr "mode" "SI")
157190286Sobrien   (set_attr "ppro_uops" "one")])
157218334Speter
157390286Sobrien;; Pentium Pro can do steps 1 through 3 in one go.
157418334Speter
157590286Sobrien(define_insn "*cmpfp_i"
157690286Sobrien  [(set (reg:CCFP 17)
157790286Sobrien	(compare:CCFP (match_operand 0 "register_operand" "f")
157890286Sobrien		      (match_operand 1 "register_operand" "f")))]
157990286Sobrien  "TARGET_80387 && TARGET_CMOVE
158090286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
158190286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))
158290286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[0])"
158390286Sobrien  "* return output_fp_compare (insn, operands, 1, 0);"
158490286Sobrien  [(set_attr "type" "fcmp")
158590286Sobrien   (set_attr "mode" "unknownfp")
158690286Sobrien   (set_attr "athlon_decode" "vector")])
158718334Speter
158890286Sobrien(define_insn "*cmpfp_i_sse"
158990286Sobrien  [(set (reg:CCFP 17)
159090286Sobrien	(compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
159190286Sobrien		      (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
159290286Sobrien  "TARGET_80387
159390286Sobrien   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
159490286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[0])"
159590286Sobrien  "* return output_fp_compare (insn, operands, 1, 0);"
159690286Sobrien  [(set_attr "type" "fcmp,sse")
159790286Sobrien   (set_attr "mode" "unknownfp")
159890286Sobrien   (set_attr "athlon_decode" "vector")])
159918334Speter
160090286Sobrien(define_insn "*cmpfp_i_sse_only"
160190286Sobrien  [(set (reg:CCFP 17)
160290286Sobrien	(compare:CCFP (match_operand 0 "register_operand" "x")
160390286Sobrien		      (match_operand 1 "nonimmediate_operand" "xm")))]
160490286Sobrien  "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
160590286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[0])"
160690286Sobrien  "* return output_fp_compare (insn, operands, 1, 0);"
160790286Sobrien  [(set_attr "type" "sse")
160890286Sobrien   (set_attr "mode" "unknownfp")
160990286Sobrien   (set_attr "athlon_decode" "vector")])
161018334Speter
161190286Sobrien(define_insn "*cmpfp_iu"
161290286Sobrien  [(set (reg:CCFPU 17)
161390286Sobrien	(compare:CCFPU (match_operand 0 "register_operand" "f")
161490286Sobrien		       (match_operand 1 "register_operand" "f")))]
161590286Sobrien  "TARGET_80387 && TARGET_CMOVE
161690286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
161790286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))
161890286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
161990286Sobrien  "* return output_fp_compare (insn, operands, 1, 1);"
162090286Sobrien  [(set_attr "type" "fcmp")
162190286Sobrien   (set_attr "mode" "unknownfp")
162290286Sobrien   (set_attr "athlon_decode" "vector")])
162318334Speter
162490286Sobrien(define_insn "*cmpfp_iu_sse"
162590286Sobrien  [(set (reg:CCFPU 17)
162690286Sobrien	(compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
162790286Sobrien		       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
162890286Sobrien  "TARGET_80387
162990286Sobrien   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
163090286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
163190286Sobrien  "* return output_fp_compare (insn, operands, 1, 1);"
163290286Sobrien  [(set_attr "type" "fcmp,sse")
163390286Sobrien   (set_attr "mode" "unknownfp")
163490286Sobrien   (set_attr "athlon_decode" "vector")])
163550650Sobrien
163690286Sobrien(define_insn "*cmpfp_iu_sse_only"
163790286Sobrien  [(set (reg:CCFPU 17)
163890286Sobrien	(compare:CCFPU (match_operand 0 "register_operand" "x")
163990286Sobrien		       (match_operand 1 "nonimmediate_operand" "xm")))]
164090286Sobrien  "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
164190286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
164290286Sobrien  "* return output_fp_compare (insn, operands, 1, 1);"
164390286Sobrien  [(set_attr "type" "sse")
164490286Sobrien   (set_attr "mode" "unknownfp")
164590286Sobrien   (set_attr "athlon_decode" "vector")])
164690286Sobrien
164790286Sobrien;; Move instructions.
164818334Speter
164918334Speter;; General case of fullword move.
165018334Speter
165118334Speter(define_expand "movsi"
165290286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
165318334Speter	(match_operand:SI 1 "general_operand" ""))]
165418334Speter  ""
165590286Sobrien  "ix86_expand_move (SImode, operands); DONE;")
165618334Speter
165790286Sobrien;; Push/pop instructions.  They are separate since autoinc/dec is not a
165890286Sobrien;; general_operand.
165990286Sobrien;;
166090286Sobrien;; %%% We don't use a post-inc memory reference because x86 is not a 
166190286Sobrien;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
166290286Sobrien;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
166390286Sobrien;; targets without our curiosities, and it is just as easy to represent
166490286Sobrien;; this differently.
166518334Speter
166690286Sobrien(define_insn "*pushsi2"
166790286Sobrien  [(set (match_operand:SI 0 "push_operand" "=<")
166890286Sobrien	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
166990286Sobrien  "!TARGET_64BIT"
167090286Sobrien  "push{l}\t%1"
167190286Sobrien  [(set_attr "type" "push")
167290286Sobrien   (set_attr "mode" "SI")])
167318334Speter
167490286Sobrien;; For 64BIT abi we always round up to 8 bytes.
167590286Sobrien(define_insn "*pushsi2_rex64"
167690286Sobrien  [(set (match_operand:SI 0 "push_operand" "=X")
167790286Sobrien	(match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
167890286Sobrien  "TARGET_64BIT"
167990286Sobrien  "push{q}\t%q1"
168090286Sobrien  [(set_attr "type" "push")
168190286Sobrien   (set_attr "mode" "SI")])
168218334Speter
168390286Sobrien(define_insn "*pushsi2_prologue"
168490286Sobrien  [(set (match_operand:SI 0 "push_operand" "=<")
168590286Sobrien	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))
168690286Sobrien   (clobber (mem:BLK (scratch)))]
168790286Sobrien  "!TARGET_64BIT"
168890286Sobrien  "push{l}\t%1"
168990286Sobrien  [(set_attr "type" "push")
169090286Sobrien   (set_attr "mode" "SI")])
169152296Sobrien
169290286Sobrien(define_insn "*popsi1_epilogue"
169390286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
169490286Sobrien	(mem:SI (reg:SI 7)))
169590286Sobrien   (set (reg:SI 7)
169690286Sobrien	(plus:SI (reg:SI 7) (const_int 4)))
169790286Sobrien   (clobber (mem:BLK (scratch)))]
169890286Sobrien  "!TARGET_64BIT"
169990286Sobrien  "pop{l}\t%0"
170090286Sobrien  [(set_attr "type" "pop")
170190286Sobrien   (set_attr "mode" "SI")])
170218334Speter
170390286Sobrien(define_insn "popsi1"
170490286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
170590286Sobrien	(mem:SI (reg:SI 7)))
170690286Sobrien   (set (reg:SI 7)
170790286Sobrien	(plus:SI (reg:SI 7) (const_int 4)))]
170890286Sobrien  "!TARGET_64BIT"
170990286Sobrien  "pop{l}\t%0"
171090286Sobrien  [(set_attr "type" "pop")
171190286Sobrien   (set_attr "mode" "SI")])
171218334Speter
171390286Sobrien(define_insn "*movsi_xor"
171490286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
171590286Sobrien	(match_operand:SI 1 "const0_operand" "i"))
171690286Sobrien   (clobber (reg:CC 17))]
171790286Sobrien  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
171890286Sobrien  "xor{l}\t{%0, %0|%0, %0}"
171990286Sobrien  [(set_attr "type" "alu1")
172090286Sobrien   (set_attr "mode" "SI")
172190286Sobrien   (set_attr "length_immediate" "0")])
172218334Speter
172390286Sobrien(define_insn "*movsi_or"
172490286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
172590286Sobrien	(match_operand:SI 1 "immediate_operand" "i"))
172690286Sobrien   (clobber (reg:CC 17))]
172790286Sobrien  "reload_completed && GET_CODE (operands[1]) == CONST_INT
172890286Sobrien   && INTVAL (operands[1]) == -1
172990286Sobrien   && (TARGET_PENTIUM || optimize_size)"
173090286Sobrien{
173190286Sobrien  operands[1] = constm1_rtx;
173290286Sobrien  return "or{l}\t{%1, %0|%0, %1}";
173390286Sobrien}
173490286Sobrien  [(set_attr "type" "alu1")
173590286Sobrien   (set_attr "mode" "SI")
173690286Sobrien   (set_attr "length_immediate" "1")])
173718334Speter
173890286Sobrien(define_insn "*movsi_1"
173990286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=*a,r,*a,m,!*y,!rm,!*Y,!rm,!*Y")
174090286Sobrien	(match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,rm,*y,rm,*Y,*Y"))]
174190286Sobrien  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
174250650Sobrien{
174390286Sobrien  switch (get_attr_type (insn))
174490286Sobrien    {
174590286Sobrien    case TYPE_SSE:
174690286Sobrien      if (get_attr_mode (insn) == TImode)
174790286Sobrien        return "movdqa\t{%1, %0|%0, %1}";
174890286Sobrien      return "movd\t{%1, %0|%0, %1}";
174952296Sobrien
175090286Sobrien    case TYPE_MMX:
175190286Sobrien      return "movd\t{%1, %0|%0, %1}";
175252296Sobrien
175390286Sobrien    case TYPE_LEA:
175490286Sobrien      return "lea{l}\t{%1, %0|%0, %1}";
175518334Speter
175690286Sobrien    default:
175790286Sobrien      if (flag_pic && SYMBOLIC_CONST (operands[1]))
175890286Sobrien	abort();
175990286Sobrien      return "mov{l}\t{%1, %0|%0, %1}";
176090286Sobrien    }
176190286Sobrien}
176290286Sobrien  [(set (attr "type")
176390286Sobrien     (cond [(eq_attr "alternative" "4,5")
176490286Sobrien	      (const_string "mmx")
176590286Sobrien	    (eq_attr "alternative" "6,7,8")
176690286Sobrien	      (const_string "sse")
176790286Sobrien	    (and (ne (symbol_ref "flag_pic") (const_int 0))
176890286Sobrien		 (match_operand:SI 1 "symbolic_operand" ""))
176990286Sobrien	      (const_string "lea")
177090286Sobrien	   ]
177190286Sobrien	   (const_string "imov")))
177290286Sobrien   (set_attr "modrm" "0,*,0,*,*,*,*,*,*")
177390286Sobrien   (set_attr "mode" "SI,SI,SI,SI,SI,SI,TI,SI,SI")])
177450650Sobrien
177590286Sobrien;; Stores and loads of ax to arbitary constant address.
177690286Sobrien;; We fake an second form of instruction to force reload to load address
177790286Sobrien;; into register when rax is not available
177890286Sobrien(define_insn "*movabssi_1_rex64"
177990286Sobrien  [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
178090286Sobrien	(match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
178190286Sobrien  "TARGET_64BIT"
178290286Sobrien  "@
178390286Sobrien   movabs{l}\t{%1, %P0|%P0, %1}
178490286Sobrien   mov{l}\t{%1, %a0|%a0, %1}
178590286Sobrien   movabs{l}\t{%1, %a0|%a0, %1}"
178690286Sobrien  [(set_attr "type" "imov")
178790286Sobrien   (set_attr "modrm" "0,*,*")
178890286Sobrien   (set_attr "length_address" "8,0,0")
178990286Sobrien   (set_attr "length_immediate" "0,*,*")
179090286Sobrien   (set_attr "memory" "store")
179190286Sobrien   (set_attr "mode" "SI")])
179250650Sobrien
179390286Sobrien(define_insn "*movabssi_2_rex64"
179490286Sobrien  [(set (match_operand:SI 0 "register_operand" "=a,r")
179590286Sobrien        (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
179690286Sobrien  "TARGET_64BIT"
179790286Sobrien  "@
179890286Sobrien   movabs{l}\t{%P1, %0|%0, %P1}
179990286Sobrien   mov{l}\t{%a1, %0|%0, %a1}"
180090286Sobrien  [(set_attr "type" "imov")
180190286Sobrien   (set_attr "modrm" "0,*")
180290286Sobrien   (set_attr "length_address" "8,0")
180390286Sobrien   (set_attr "length_immediate" "0")
180490286Sobrien   (set_attr "memory" "load")
180590286Sobrien   (set_attr "mode" "SI")])
180690286Sobrien
180790286Sobrien(define_insn "*swapsi"
180890286Sobrien  [(set (match_operand:SI 0 "register_operand" "+r")
180990286Sobrien	(match_operand:SI 1 "register_operand" "+r"))
181090286Sobrien   (set (match_dup 1)
181190286Sobrien	(match_dup 0))]
181250650Sobrien  ""
181390286Sobrien  "xchg{l}\t%1, %0"
181490286Sobrien  [(set_attr "type" "imov")
181590286Sobrien   (set_attr "pent_pair" "np")
181690286Sobrien   (set_attr "athlon_decode" "vector")
181790286Sobrien   (set_attr "mode" "SI")
181890286Sobrien   (set_attr "modrm" "0")
181990286Sobrien   (set_attr "ppro_uops" "few")])
182018334Speter
182190286Sobrien(define_expand "movhi"
182290286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
182390286Sobrien        (match_operand:HI 1 "general_operand" ""))]
182490286Sobrien  ""
182590286Sobrien  "ix86_expand_move (HImode, operands); DONE;")
182618334Speter
182790286Sobrien(define_insn "*pushhi2"
182890286Sobrien  [(set (match_operand:HI 0 "push_operand" "=<,<")
182990286Sobrien	(match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
183090286Sobrien  "!TARGET_64BIT"
183190286Sobrien  "@
183290286Sobrien   push{w}\t{|WORD PTR }%1
183390286Sobrien   push{w}\t%1"
183490286Sobrien  [(set_attr "type" "push")
183590286Sobrien   (set_attr "mode" "HI")])
183618334Speter
183790286Sobrien;; For 64BIT abi we always round up to 8 bytes.
183890286Sobrien(define_insn "*pushhi2_rex64"
183990286Sobrien  [(set (match_operand:HI 0 "push_operand" "=X")
184090286Sobrien	(match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
184190286Sobrien  "TARGET_64BIT"
184290286Sobrien  "push{q}\t%q1"
184390286Sobrien  [(set_attr "type" "push")
184490286Sobrien   (set_attr "mode" "QI")])
184590286Sobrien
184690286Sobrien(define_insn "*movhi_1"
184790286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=*a,r,r,*a,r,m")
184890286Sobrien	(match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))]
184990286Sobrien  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
185018334Speter{
185190286Sobrien  switch (get_attr_type (insn))
185218334Speter    {
185390286Sobrien    case TYPE_IMOVX:
185490286Sobrien      /* movzwl is faster than movw on p2 due to partial word stalls,
185590286Sobrien	 though not as fast as an aligned movl.  */
185690286Sobrien      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
185790286Sobrien    default:
185890286Sobrien      if (get_attr_mode (insn) == MODE_SI)
185990286Sobrien        return "mov{l}\t{%k1, %k0|%k0, %k1}";
186090286Sobrien      else
186190286Sobrien        return "mov{w}\t{%1, %0|%0, %1}";
186218334Speter    }
186390286Sobrien}
186490286Sobrien  [(set (attr "type")
186590286Sobrien     (cond [(and (eq_attr "alternative" "0,1")
186690286Sobrien		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
186790286Sobrien			  (const_int 0))
186890286Sobrien		      (eq (symbol_ref "TARGET_HIMODE_MATH")
186990286Sobrien			  (const_int 0))))
187090286Sobrien	      (const_string "imov")
187190286Sobrien	    (and (eq_attr "alternative" "2,3,4")
187290286Sobrien		 (match_operand:HI 1 "aligned_operand" ""))
187390286Sobrien	      (const_string "imov")
187490286Sobrien	    (and (ne (symbol_ref "TARGET_MOVX")
187590286Sobrien		     (const_int 0))
187690286Sobrien		 (eq_attr "alternative" "0,1,3,4"))
187790286Sobrien	      (const_string "imovx")
187890286Sobrien	   ]
187990286Sobrien	   (const_string "imov")))
188090286Sobrien    (set (attr "mode")
188190286Sobrien      (cond [(eq_attr "type" "imovx")
188290286Sobrien	       (const_string "SI")
188390286Sobrien	     (and (eq_attr "alternative" "2,3,4")
188490286Sobrien		  (match_operand:HI 1 "aligned_operand" ""))
188590286Sobrien	       (const_string "SI")
188690286Sobrien	     (and (eq_attr "alternative" "0,1")
188790286Sobrien		  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
188890286Sobrien			   (const_int 0))
188990286Sobrien		       (eq (symbol_ref "TARGET_HIMODE_MATH")
189090286Sobrien			   (const_int 0))))
189190286Sobrien	       (const_string "SI")
189290286Sobrien	    ]
189390286Sobrien	    (const_string "HI")))
189490286Sobrien   (set_attr "modrm" "0,*,*,0,*,*")])
189518334Speter
189690286Sobrien;; Stores and loads of ax to arbitary constant address.
189790286Sobrien;; We fake an second form of instruction to force reload to load address
189890286Sobrien;; into register when rax is not available
189990286Sobrien(define_insn "*movabshi_1_rex64"
190090286Sobrien  [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
190190286Sobrien	(match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
190290286Sobrien  "TARGET_64BIT"
190390286Sobrien  "@
190490286Sobrien   movabs{w}\t{%1, %P0|%P0, %1}
190590286Sobrien   mov{w}\t{%1, %a0|%a0, %1}
190690286Sobrien   movabs{w}\t{%1, %a0|%a0, %1}"
190790286Sobrien  [(set_attr "type" "imov")
190890286Sobrien   (set_attr "modrm" "0,*,*")
190990286Sobrien   (set_attr "length_address" "8,0,0")
191090286Sobrien   (set_attr "length_immediate" "0,*,*")
191190286Sobrien   (set_attr "memory" "store")
191290286Sobrien   (set_attr "mode" "HI")])
191318334Speter
191490286Sobrien(define_insn "*movabshi_2_rex64"
191590286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a,r")
191690286Sobrien        (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
191790286Sobrien  "TARGET_64BIT"
191890286Sobrien  "@
191990286Sobrien   movabs{w}\t{%P1, %0|%0, %P1}
192090286Sobrien   mov{w}\t{%a1, %0|%0, %a1}"
192190286Sobrien  [(set_attr "type" "imov")
192290286Sobrien   (set_attr "modrm" "0,*")
192390286Sobrien   (set_attr "length_address" "8,0")
192490286Sobrien   (set_attr "length_immediate" "0")
192590286Sobrien   (set_attr "memory" "load")
192690286Sobrien   (set_attr "mode" "HI")])
192718334Speter
192890286Sobrien(define_insn "*swaphi_1"
192990286Sobrien  [(set (match_operand:HI 0 "register_operand" "+r")
193090286Sobrien	(match_operand:HI 1 "register_operand" "+r"))
193190286Sobrien   (set (match_dup 1)
193290286Sobrien	(match_dup 0))]
193390286Sobrien  "TARGET_PARTIAL_REG_STALL"
193490286Sobrien  "xchg{w}\t%1, %0"
193590286Sobrien  [(set_attr "type" "imov")
193690286Sobrien   (set_attr "pent_pair" "np")
193790286Sobrien   (set_attr "mode" "HI")
193890286Sobrien   (set_attr "modrm" "0")
193990286Sobrien   (set_attr "ppro_uops" "few")])
194018334Speter
194190286Sobrien(define_insn "*swaphi_2"
194290286Sobrien  [(set (match_operand:HI 0 "register_operand" "+r")
194390286Sobrien	(match_operand:HI 1 "register_operand" "+r"))
194490286Sobrien   (set (match_dup 1)
194590286Sobrien	(match_dup 0))]
194690286Sobrien  "! TARGET_PARTIAL_REG_STALL"
194790286Sobrien  "xchg{l}\t%k1, %k0"
194890286Sobrien  [(set_attr "type" "imov")
194990286Sobrien   (set_attr "pent_pair" "np")
195090286Sobrien   (set_attr "mode" "SI")
195190286Sobrien   (set_attr "modrm" "0")
195290286Sobrien   (set_attr "ppro_uops" "few")])
195318334Speter
195418334Speter(define_expand "movstricthi"
195590286Sobrien  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
195618334Speter	(match_operand:HI 1 "general_operand" ""))]
195790286Sobrien  "! TARGET_PARTIAL_REG_STALL || optimize_size"
195818334Speter{
195918334Speter  /* Don't generate memory->memory moves, go through a register */
196090286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
196190286Sobrien    operands[1] = force_reg (HImode, operands[1]);
196290286Sobrien})
196318334Speter
196490286Sobrien(define_insn "*movstricthi_1"
196590286Sobrien  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
196690286Sobrien	(match_operand:HI 1 "general_operand" "rn,m"))]
196790286Sobrien  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
196890286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
196990286Sobrien  "mov{w}\t{%1, %0|%0, %1}"
197090286Sobrien  [(set_attr "type" "imov")
197190286Sobrien   (set_attr "mode" "HI")])
197252296Sobrien
197390286Sobrien(define_insn "*movstricthi_xor"
197490286Sobrien  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
197590286Sobrien	(match_operand:HI 1 "const0_operand" "i"))
197690286Sobrien   (clobber (reg:CC 17))]
197790286Sobrien  "reload_completed
197890286Sobrien   && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
197990286Sobrien  "xor{w}\t{%0, %0|%0, %0}"
198090286Sobrien  [(set_attr "type" "alu1")
198190286Sobrien   (set_attr "mode" "HI")
198290286Sobrien   (set_attr "length_immediate" "0")])
198352296Sobrien
198490286Sobrien(define_expand "movqi"
198590286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
198690286Sobrien	(match_operand:QI 1 "general_operand" ""))]
198790286Sobrien  ""
198890286Sobrien  "ix86_expand_move (QImode, operands); DONE;")
198918334Speter
199090286Sobrien;; emit_push_insn when it calls move_by_pieces requires an insn to
199190286Sobrien;; "push a byte".  But actually we use pushw, which has the effect
199290286Sobrien;; of rounding the amount pushed up to a halfword.
199318334Speter
199490286Sobrien(define_insn "*pushqi2"
199590286Sobrien  [(set (match_operand:QI 0 "push_operand" "=X,X")
199690286Sobrien	(match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
199790286Sobrien  "!TARGET_64BIT"
199890286Sobrien  "@
199990286Sobrien   push{w}\t{|word ptr }%1
200090286Sobrien   push{w}\t%w1"
200190286Sobrien  [(set_attr "type" "push")
200290286Sobrien   (set_attr "mode" "HI")])
200318334Speter
200490286Sobrien;; For 64BIT abi we always round up to 8 bytes.
200590286Sobrien(define_insn "*pushqi2_rex64"
200690286Sobrien  [(set (match_operand:QI 0 "push_operand" "=X")
200790286Sobrien	(match_operand:QI 1 "nonmemory_no_elim_operand" "ri"))]
200890286Sobrien  "TARGET_64BIT"
200990286Sobrien  "push{q}\t%q1"
201090286Sobrien  [(set_attr "type" "push")
201190286Sobrien   (set_attr "mode" "QI")])
201290286Sobrien
201390286Sobrien;; Situation is quite tricky about when to choose full sized (SImode) move
201490286Sobrien;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
201590286Sobrien;; partial register dependency machines (such as AMD Athlon), where QImode
201690286Sobrien;; moves issue extra dependency and for partial register stalls machines
201790286Sobrien;; that don't use QImode patterns (and QImode move cause stall on the next
201890286Sobrien;; instruction).
201990286Sobrien;;
202090286Sobrien;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
202190286Sobrien;; register stall machines with, where we use QImode instructions, since
202290286Sobrien;; partial register stall can be caused there.  Then we use movzx.
202390286Sobrien(define_insn "*movqi_1"
202490286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
202590286Sobrien	(match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
202690286Sobrien  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
202790286Sobrien{
202890286Sobrien  switch (get_attr_type (insn))
202990286Sobrien    {
203090286Sobrien    case TYPE_IMOVX:
203190286Sobrien      if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
203290286Sobrien	abort ();
203390286Sobrien      return "movz{bl|x}\t{%1, %k0|%k0, %1}";
203490286Sobrien    default:
203590286Sobrien      if (get_attr_mode (insn) == MODE_SI)
203690286Sobrien        return "mov{l}\t{%k1, %k0|%k0, %k1}";
203790286Sobrien      else
203890286Sobrien        return "mov{b}\t{%1, %0|%0, %1}";
203990286Sobrien    }
204090286Sobrien}
204190286Sobrien  [(set (attr "type")
204290286Sobrien     (cond [(and (eq_attr "alternative" "3")
204390286Sobrien		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
204490286Sobrien			  (const_int 0))
204590286Sobrien		      (eq (symbol_ref "TARGET_QIMODE_MATH")
204690286Sobrien			  (const_int 0))))
204790286Sobrien	      (const_string "imov")
204890286Sobrien	    (eq_attr "alternative" "3,5")
204990286Sobrien	      (const_string "imovx")
205090286Sobrien	    (and (ne (symbol_ref "TARGET_MOVX")
205190286Sobrien		     (const_int 0))
205290286Sobrien		 (eq_attr "alternative" "2"))
205390286Sobrien	      (const_string "imovx")
205490286Sobrien	   ]
205590286Sobrien	   (const_string "imov")))
205690286Sobrien   (set (attr "mode")
205790286Sobrien      (cond [(eq_attr "alternative" "3,4,5")
205890286Sobrien	       (const_string "SI")
205990286Sobrien	     (eq_attr "alternative" "6")
206090286Sobrien	       (const_string "QI")
206190286Sobrien	     (eq_attr "type" "imovx")
206290286Sobrien	       (const_string "SI")
206390286Sobrien	     (and (eq_attr "type" "imov")
206490286Sobrien		  (and (eq_attr "alternative" "0,1,2")
206590286Sobrien		       (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
206690286Sobrien			   (const_int 0))))
206790286Sobrien	       (const_string "SI")
206890286Sobrien	     ;; Avoid partial register stalls when not using QImode arithmetic
206990286Sobrien	     (and (eq_attr "type" "imov")
207090286Sobrien		  (and (eq_attr "alternative" "0,1,2")
207190286Sobrien		       (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
207290286Sobrien				(const_int 0))
207390286Sobrien			    (eq (symbol_ref "TARGET_QIMODE_MATH")
207490286Sobrien				(const_int 0)))))
207590286Sobrien	       (const_string "SI")
207690286Sobrien	   ]
207790286Sobrien	   (const_string "QI")))])
207890286Sobrien
207990286Sobrien(define_expand "reload_outqi"
208090286Sobrien  [(parallel [(match_operand:QI 0 "" "=m")
208190286Sobrien              (match_operand:QI 1 "register_operand" "r")
208290286Sobrien              (match_operand:QI 2 "register_operand" "=&q")])]
208318334Speter  ""
208490286Sobrien{
208590286Sobrien  rtx op0, op1, op2;
208690286Sobrien  op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
208718334Speter
208890286Sobrien  if (reg_overlap_mentioned_p (op2, op0))
208990286Sobrien    abort ();
209090286Sobrien  if (! q_regs_operand (op1, QImode))
209190286Sobrien    {
209290286Sobrien      emit_insn (gen_movqi (op2, op1));
209390286Sobrien      op1 = op2;
209490286Sobrien    }
209590286Sobrien  emit_insn (gen_movqi (op0, op1));
209690286Sobrien  DONE;
209790286Sobrien})
209890286Sobrien
209990286Sobrien(define_insn "*swapqi"
210090286Sobrien  [(set (match_operand:QI 0 "register_operand" "+r")
210190286Sobrien	(match_operand:QI 1 "register_operand" "+r"))
210290286Sobrien   (set (match_dup 1)
210390286Sobrien	(match_dup 0))]
210450650Sobrien  ""
210590286Sobrien  "xchg{b}\t%1, %0"
210690286Sobrien  [(set_attr "type" "imov")
210790286Sobrien   (set_attr "pent_pair" "np")
210890286Sobrien   (set_attr "mode" "QI")
210990286Sobrien   (set_attr "modrm" "0")
211090286Sobrien   (set_attr "ppro_uops" "few")])
211190286Sobrien
211290286Sobrien(define_expand "movstrictqi"
211390286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
211490286Sobrien	(match_operand:QI 1 "general_operand" ""))]
211590286Sobrien  "! TARGET_PARTIAL_REG_STALL"
211618334Speter{
211790286Sobrien  /* Don't generate memory->memory moves, go through a register.  */
211890286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
211990286Sobrien    operands[1] = force_reg (QImode, operands[1]);
212090286Sobrien})
212118334Speter
212290286Sobrien(define_insn "*movstrictqi_1"
212390286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
212490286Sobrien	(match_operand:QI 1 "general_operand" "*qn,m"))]
212590286Sobrien  "! TARGET_PARTIAL_REG_STALL
212690286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
212790286Sobrien  "mov{b}\t{%1, %0|%0, %1}"
212890286Sobrien  [(set_attr "type" "imov")
212990286Sobrien   (set_attr "mode" "QI")])
213018334Speter
213190286Sobrien(define_insn "*movstrictqi_xor"
213290286Sobrien  [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
213390286Sobrien	(match_operand:QI 1 "const0_operand" "i"))
213490286Sobrien   (clobber (reg:CC 17))]
213590286Sobrien  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
213690286Sobrien  "xor{b}\t{%0, %0|%0, %0}"
213790286Sobrien  [(set_attr "type" "alu1")
213890286Sobrien   (set_attr "mode" "QI")
213990286Sobrien   (set_attr "length_immediate" "0")])
214018334Speter
214190286Sobrien(define_insn "*movsi_extv_1"
214290286Sobrien  [(set (match_operand:SI 0 "register_operand" "=R")
214390286Sobrien	(sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
214490286Sobrien			 (const_int 8)
214590286Sobrien			 (const_int 8)))]
214618334Speter  ""
214790286Sobrien  "movs{bl|x}\t{%h1, %0|%0, %h1}"
214890286Sobrien  [(set_attr "type" "imovx")
214990286Sobrien   (set_attr "mode" "SI")])
215090286Sobrien
215190286Sobrien(define_insn "*movhi_extv_1"
215290286Sobrien  [(set (match_operand:HI 0 "register_operand" "=R")
215390286Sobrien	(sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
215490286Sobrien			 (const_int 8)
215590286Sobrien			 (const_int 8)))]
215690286Sobrien  ""
215790286Sobrien  "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
215890286Sobrien  [(set_attr "type" "imovx")
215990286Sobrien   (set_attr "mode" "SI")])
216090286Sobrien
216190286Sobrien(define_insn "*movqi_extv_1"
216290286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
216390286Sobrien        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
216490286Sobrien                         (const_int 8)
216590286Sobrien                         (const_int 8)))]
216690286Sobrien  "!TARGET_64BIT"
216718334Speter{
216890286Sobrien  switch (get_attr_type (insn))
216918334Speter    {
217090286Sobrien    case TYPE_IMOVX:
217190286Sobrien      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
217290286Sobrien    default:
217390286Sobrien      return "mov{b}\t{%h1, %0|%0, %h1}";
217418334Speter    }
217590286Sobrien}
217690286Sobrien  [(set (attr "type")
217790286Sobrien     (if_then_else (and (match_operand:QI 0 "register_operand" "")
217890286Sobrien			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
217990286Sobrien			     (ne (symbol_ref "TARGET_MOVX")
218090286Sobrien				 (const_int 0))))
218190286Sobrien	(const_string "imovx")
218290286Sobrien	(const_string "imov")))
218390286Sobrien   (set (attr "mode")
218490286Sobrien     (if_then_else (eq_attr "type" "imovx")
218590286Sobrien	(const_string "SI")
218690286Sobrien	(const_string "QI")))])
218718334Speter
218890286Sobrien(define_insn "*movqi_extv_1_rex64"
218990286Sobrien  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
219090286Sobrien        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
219190286Sobrien                         (const_int 8)
219290286Sobrien                         (const_int 8)))]
219390286Sobrien  "TARGET_64BIT"
219418334Speter{
219590286Sobrien  switch (get_attr_type (insn))
219650650Sobrien    {
219790286Sobrien    case TYPE_IMOVX:
219890286Sobrien      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
219990286Sobrien    default:
220090286Sobrien      return "mov{b}\t{%h1, %0|%0, %h1}";
220150650Sobrien    }
220290286Sobrien}
220390286Sobrien  [(set (attr "type")
220490286Sobrien     (if_then_else (and (match_operand:QI 0 "register_operand" "")
220590286Sobrien			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
220690286Sobrien			     (ne (symbol_ref "TARGET_MOVX")
220790286Sobrien				 (const_int 0))))
220890286Sobrien	(const_string "imovx")
220990286Sobrien	(const_string "imov")))
221090286Sobrien   (set (attr "mode")
221190286Sobrien     (if_then_else (eq_attr "type" "imovx")
221290286Sobrien	(const_string "SI")
221390286Sobrien	(const_string "QI")))])
221418334Speter
221590286Sobrien;; Stores and loads of ax to arbitary constant address.
221690286Sobrien;; We fake an second form of instruction to force reload to load address
221790286Sobrien;; into register when rax is not available
221890286Sobrien(define_insn "*movabsqi_1_rex64"
221990286Sobrien  [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
222090286Sobrien	(match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
222190286Sobrien  "TARGET_64BIT"
222290286Sobrien  "@
222390286Sobrien   movabs{b}\t{%1, %P0|%P0, %1}
222490286Sobrien   mov{b}\t{%1, %a0|%a0, %1}
222590286Sobrien   movabs{b}\t{%1, %a0|%a0, %1}"
222690286Sobrien  [(set_attr "type" "imov")
222790286Sobrien   (set_attr "modrm" "0,*,*")
222890286Sobrien   (set_attr "length_address" "8,0,0")
222990286Sobrien   (set_attr "length_immediate" "0,*,*")
223090286Sobrien   (set_attr "memory" "store")
223190286Sobrien   (set_attr "mode" "QI")])
223218334Speter
223390286Sobrien(define_insn "*movabsqi_2_rex64"
223490286Sobrien  [(set (match_operand:QI 0 "register_operand" "=a,r")
223590286Sobrien        (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
223690286Sobrien  "TARGET_64BIT"
223790286Sobrien  "@
223890286Sobrien   movabs{b}\t{%P1, %0|%0, %P1}
223990286Sobrien   mov{b}\t{%a1, %0|%0, %a1}"
224090286Sobrien  [(set_attr "type" "imov")
224190286Sobrien   (set_attr "modrm" "0,*")
224290286Sobrien   (set_attr "length_address" "8,0")
224390286Sobrien   (set_attr "length_immediate" "0")
224490286Sobrien   (set_attr "memory" "load")
224590286Sobrien   (set_attr "mode" "QI")])
224618334Speter
224790286Sobrien(define_insn "*movsi_extzv_1"
224890286Sobrien  [(set (match_operand:SI 0 "register_operand" "=R")
224990286Sobrien	(zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
225090286Sobrien			 (const_int 8)
225190286Sobrien			 (const_int 8)))]
225290286Sobrien  ""
225390286Sobrien  "movz{bl|x}\t{%h1, %0|%0, %h1}"
225490286Sobrien  [(set_attr "type" "imovx")
225590286Sobrien   (set_attr "mode" "SI")])
225618334Speter
225790286Sobrien(define_insn "*movqi_extzv_2"
225890286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
225990286Sobrien        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
226090286Sobrien				    (const_int 8)
226190286Sobrien				    (const_int 8)) 0))]
226290286Sobrien  "!TARGET_64BIT"
226318334Speter{
226490286Sobrien  switch (get_attr_type (insn))
226518334Speter    {
226690286Sobrien    case TYPE_IMOVX:
226790286Sobrien      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
226890286Sobrien    default:
226990286Sobrien      return "mov{b}\t{%h1, %0|%0, %h1}";
227018334Speter    }
227190286Sobrien}
227290286Sobrien  [(set (attr "type")
227390286Sobrien     (if_then_else (and (match_operand:QI 0 "register_operand" "")
227490286Sobrien			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
227590286Sobrien			     (ne (symbol_ref "TARGET_MOVX")
227690286Sobrien				 (const_int 0))))
227790286Sobrien	(const_string "imovx")
227890286Sobrien	(const_string "imov")))
227990286Sobrien   (set (attr "mode")
228090286Sobrien     (if_then_else (eq_attr "type" "imovx")
228190286Sobrien	(const_string "SI")
228290286Sobrien	(const_string "QI")))])
228318334Speter
228490286Sobrien(define_insn "*movqi_extzv_2_rex64"
228590286Sobrien  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
228690286Sobrien        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
228790286Sobrien				    (const_int 8)
228890286Sobrien				    (const_int 8)) 0))]
228990286Sobrien  "TARGET_64BIT"
229018334Speter{
229190286Sobrien  switch (get_attr_type (insn))
229290286Sobrien    {
229390286Sobrien    case TYPE_IMOVX:
229490286Sobrien      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
229590286Sobrien    default:
229690286Sobrien      return "mov{b}\t{%h1, %0|%0, %h1}";
229790286Sobrien    }
229890286Sobrien}
229990286Sobrien  [(set (attr "type")
230090286Sobrien     (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
230190286Sobrien			(ne (symbol_ref "TARGET_MOVX")
230290286Sobrien			    (const_int 0)))
230390286Sobrien	(const_string "imovx")
230490286Sobrien	(const_string "imov")))
230590286Sobrien   (set (attr "mode")
230690286Sobrien     (if_then_else (eq_attr "type" "imovx")
230790286Sobrien	(const_string "SI")
230890286Sobrien	(const_string "QI")))])
230918334Speter
231090286Sobrien(define_insn "movsi_insv_1"
231190286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
231290286Sobrien			 (const_int 8)
231390286Sobrien			 (const_int 8))
231490286Sobrien	(match_operand:SI 1 "general_operand" "Qmn"))]
231590286Sobrien  "!TARGET_64BIT"
231690286Sobrien  "mov{b}\t{%b1, %h0|%h0, %b1}"
231790286Sobrien  [(set_attr "type" "imov")
231890286Sobrien   (set_attr "mode" "QI")])
231952296Sobrien
232090286Sobrien(define_insn "*movsi_insv_1_rex64"
232190286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
232290286Sobrien			 (const_int 8)
232390286Sobrien			 (const_int 8))
232490286Sobrien	(match_operand:SI 1 "nonmemory_operand" "Qn"))]
232590286Sobrien  "TARGET_64BIT"
232690286Sobrien  "mov{b}\t{%b1, %h0|%h0, %b1}"
232790286Sobrien  [(set_attr "type" "imov")
232890286Sobrien   (set_attr "mode" "QI")])
232918334Speter
233090286Sobrien(define_insn "*movqi_insv_2"
233190286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
233290286Sobrien			 (const_int 8)
233390286Sobrien			 (const_int 8))
233490286Sobrien	(and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
233590286Sobrien			     (const_int 8))
233690286Sobrien		(const_int 255)))]
233790286Sobrien  ""
233890286Sobrien  "mov{b}\t{%h1, %h0|%h0, %h1}"
233990286Sobrien  [(set_attr "type" "imov")
234090286Sobrien   (set_attr "mode" "QI")])
234118334Speter
234290286Sobrien(define_expand "movdi"
234390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
234490286Sobrien	(match_operand:DI 1 "general_operand" ""))]
234590286Sobrien  ""
234690286Sobrien  "ix86_expand_move (DImode, operands); DONE;")
234718334Speter
234890286Sobrien(define_insn "*pushdi"
234990286Sobrien  [(set (match_operand:DI 0 "push_operand" "=<")
235090286Sobrien	(match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
235190286Sobrien  "!TARGET_64BIT"
235290286Sobrien  "#")
235390286Sobrien
235490286Sobrien(define_insn "pushdi2_rex64"
235590286Sobrien  [(set (match_operand:DI 0 "push_operand" "=<,!<")
235690286Sobrien	(match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
235790286Sobrien  "TARGET_64BIT"
235890286Sobrien  "@
235990286Sobrien   push{q}\t%1
236090286Sobrien   #"
236190286Sobrien  [(set_attr "type" "push,multi")
236290286Sobrien   (set_attr "mode" "DI")])
236390286Sobrien
236490286Sobrien;; Convert impossible pushes of immediate to existing instructions.
236590286Sobrien;; First try to get scratch register and go through it.  In case this
236690286Sobrien;; fails, push sign extended lower part first and then overwrite
236790286Sobrien;; upper part by 32bit move.
236890286Sobrien(define_peephole2
236990286Sobrien  [(match_scratch:DI 2 "r")
237090286Sobrien   (set (match_operand:DI 0 "push_operand" "")
237190286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
237290286Sobrien  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
237390286Sobrien   && !x86_64_immediate_operand (operands[1], DImode)"
237490286Sobrien  [(set (match_dup 2) (match_dup 1))
237590286Sobrien   (set (match_dup 0) (match_dup 2))]
237690286Sobrien  "")
237790286Sobrien
237890286Sobrien;; We need to define this as both peepholer and splitter for case
237990286Sobrien;; peephole2 pass is not run.
238090286Sobrien(define_peephole2
238190286Sobrien  [(set (match_operand:DI 0 "push_operand" "")
238290286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
238390286Sobrien  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
238490286Sobrien   && !x86_64_immediate_operand (operands[1], DImode) && 1"
238590286Sobrien  [(set (match_dup 0) (match_dup 1))
238690286Sobrien   (set (match_dup 2) (match_dup 3))]
238790286Sobrien  "split_di (operands + 1, 1, operands + 2, operands + 3);
238890286Sobrien   operands[1] = gen_lowpart (DImode, operands[2]);
238990286Sobrien   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
239090286Sobrien						    GEN_INT (4)));
239190286Sobrien  ")
239290286Sobrien
239390286Sobrien(define_split
239490286Sobrien  [(set (match_operand:DI 0 "push_operand" "")
239590286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
239690286Sobrien  "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
239790286Sobrien   && !symbolic_operand (operands[1], DImode)
239890286Sobrien   && !x86_64_immediate_operand (operands[1], DImode)"
239990286Sobrien  [(set (match_dup 0) (match_dup 1))
240090286Sobrien   (set (match_dup 2) (match_dup 3))]
240190286Sobrien  "split_di (operands + 1, 1, operands + 2, operands + 3);
240290286Sobrien   operands[1] = gen_lowpart (DImode, operands[2]);
240390286Sobrien   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
240490286Sobrien						    GEN_INT (4)));
240590286Sobrien  ")
240690286Sobrien
240790286Sobrien(define_insn "*pushdi2_prologue_rex64"
240890286Sobrien  [(set (match_operand:DI 0 "push_operand" "=<")
240990286Sobrien	(match_operand:DI 1 "general_no_elim_operand" "re*m"))
241090286Sobrien   (clobber (mem:BLK (scratch)))]
241190286Sobrien  "TARGET_64BIT"
241290286Sobrien  "push{q}\t%1"
241390286Sobrien  [(set_attr "type" "push")
241490286Sobrien   (set_attr "mode" "DI")])
241590286Sobrien
241690286Sobrien(define_insn "*popdi1_epilogue_rex64"
241790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
241890286Sobrien	(mem:DI (reg:DI 7)))
241990286Sobrien   (set (reg:DI 7)
242090286Sobrien	(plus:DI (reg:DI 7) (const_int 8)))
242190286Sobrien   (clobber (mem:BLK (scratch)))]
242290286Sobrien  "TARGET_64BIT"
242390286Sobrien  "pop{q}\t%0"
242490286Sobrien  [(set_attr "type" "pop")
242590286Sobrien   (set_attr "mode" "DI")])
242690286Sobrien
242790286Sobrien(define_insn "popdi1"
242890286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
242990286Sobrien	(mem:DI (reg:DI 7)))
243090286Sobrien   (set (reg:DI 7)
243190286Sobrien	(plus:DI (reg:DI 7) (const_int 8)))]
243290286Sobrien  "TARGET_64BIT"
243390286Sobrien  "pop{q}\t%0"
243490286Sobrien  [(set_attr "type" "pop")
243590286Sobrien   (set_attr "mode" "DI")])
243690286Sobrien
243790286Sobrien(define_insn "*movdi_xor_rex64"
243890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
243990286Sobrien	(match_operand:DI 1 "const0_operand" "i"))
244090286Sobrien   (clobber (reg:CC 17))]
244190286Sobrien  "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
244290286Sobrien   && reload_completed"
244390286Sobrien  "xor{l}\t{%k0, %k0|%k0, %k0}"
244490286Sobrien  [(set_attr "type" "alu1")
244590286Sobrien   (set_attr "mode" "SI")
244690286Sobrien   (set_attr "length_immediate" "0")])
244790286Sobrien
244890286Sobrien(define_insn "*movdi_or_rex64"
244990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
245090286Sobrien	(match_operand:DI 1 "const_int_operand" "i"))
245190286Sobrien   (clobber (reg:CC 17))]
245290286Sobrien  "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
245390286Sobrien   && reload_completed
245490286Sobrien   && GET_CODE (operands[1]) == CONST_INT
245590286Sobrien   && INTVAL (operands[1]) == -1"
245618334Speter{
245790286Sobrien  operands[1] = constm1_rtx;
245890286Sobrien  return "or{q}\t{%1, %0|%0, %1}";
245990286Sobrien}
246090286Sobrien  [(set_attr "type" "alu1")
246190286Sobrien   (set_attr "mode" "DI")
246290286Sobrien   (set_attr "length_immediate" "1")])
246318334Speter
246490286Sobrien(define_insn "*movdi_2"
246590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,*Y,!*Y")
246690286Sobrien	(match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
246790286Sobrien  "!TARGET_64BIT
246890286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
246990286Sobrien  "@
247090286Sobrien   #
247190286Sobrien   #
247290286Sobrien   movq\t{%1, %0|%0, %1}
247390286Sobrien   movq\t{%1, %0|%0, %1}
247490286Sobrien   movq\t{%1, %0|%0, %1}
247590286Sobrien   movdqa\t{%1, %0|%0, %1}
247690286Sobrien   movq\t{%1, %0|%0, %1}"
247790286Sobrien  [(set_attr "type" "*,*,mmx,mmx,sse,sse,sse")
247890286Sobrien   (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
247918334Speter
248090286Sobrien(define_split
248190286Sobrien  [(set (match_operand:DI 0 "push_operand" "")
248290286Sobrien        (match_operand:DI 1 "general_operand" ""))]
248390286Sobrien  "!TARGET_64BIT && reload_completed
248490286Sobrien   && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
248590286Sobrien  [(const_int 0)]
248690286Sobrien  "ix86_split_long_move (operands); DONE;")
248718334Speter
248890286Sobrien;; %%% This multiword shite has got to go.
248990286Sobrien(define_split
249090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
249190286Sobrien        (match_operand:DI 1 "general_operand" ""))]
249290286Sobrien  "!TARGET_64BIT && reload_completed
249390286Sobrien   && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
249490286Sobrien   && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
249590286Sobrien  [(const_int 0)]
249690286Sobrien  "ix86_split_long_move (operands); DONE;")
249718334Speter
249890286Sobrien(define_insn "*movdi_1_rex64"
249990286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!m*y,!*y,!*Y,!m,!*Y")
250090286Sobrien	(match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,m,*Y,*Y,*m"))]
250190286Sobrien  "TARGET_64BIT
250290286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
250390286Sobrien{
250490286Sobrien  switch (get_attr_type (insn))
250590286Sobrien    {
250690286Sobrien    case TYPE_SSE:
250790286Sobrien      if (register_operand (operands[0], DImode)
250890286Sobrien	  && register_operand (operands[1], DImode))
250990286Sobrien	  return "movdqa\t{%1, %0|%0, %1}";
251090286Sobrien      /* FALLTHRU */
251190286Sobrien    case TYPE_MMX:
251290286Sobrien      return "movq\t{%1, %0|%0, %1}";
251390286Sobrien    case TYPE_MULTI:
251490286Sobrien      return "#";
251590286Sobrien    case TYPE_LEA:
251690286Sobrien      return "lea{q}\t{%a1, %0|%0, %a1}";
251790286Sobrien    default:
251890286Sobrien      if (flag_pic && SYMBOLIC_CONST (operands[1]))
251990286Sobrien	abort ();
252090286Sobrien      if (get_attr_mode (insn) == MODE_SI)
252190286Sobrien	return "mov{l}\t{%k1, %k0|%k0, %k1}";
252290286Sobrien      else if (which_alternative == 2)
252390286Sobrien	return "movabs{q}\t{%1, %0|%0, %1}";
252418334Speter      else
252590286Sobrien	return "mov{q}\t{%1, %0|%0, %1}";
252618334Speter    }
252790286Sobrien}
252890286Sobrien  [(set (attr "type")
252990286Sobrien     (cond [(eq_attr "alternative" "5,6")
253090286Sobrien	      (const_string "mmx")
253190286Sobrien	    (eq_attr "alternative" "7,8")
253290286Sobrien	      (const_string "sse")
253390286Sobrien	    (eq_attr "alternative" "4")
253490286Sobrien	      (const_string "multi")
253590286Sobrien 	    (and (ne (symbol_ref "flag_pic") (const_int 0))
253690286Sobrien		 (match_operand:DI 1 "symbolic_operand" ""))
253790286Sobrien	      (const_string "lea")
253890286Sobrien	   ]
253990286Sobrien	   (const_string "imov")))
254090286Sobrien   (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*")
254190286Sobrien   (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*")
254290286Sobrien   (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI")])
254350650Sobrien
254490286Sobrien;; Stores and loads of ax to arbitary constant address.
254590286Sobrien;; We fake an second form of instruction to force reload to load address
254690286Sobrien;; into register when rax is not available
254790286Sobrien(define_insn "*movabsdi_1_rex64"
254890286Sobrien  [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
254990286Sobrien	(match_operand:DI 1 "nonmemory_operand" "a,er,i"))]
255090286Sobrien  "TARGET_64BIT"
255190286Sobrien  "@
255290286Sobrien   movabs{q}\t{%1, %P0|%P0, %1}
255390286Sobrien   mov{q}\t{%1, %a0|%a0, %1}
255490286Sobrien   movabs{q}\t{%1, %a0|%a0, %1}"
255590286Sobrien  [(set_attr "type" "imov")
255690286Sobrien   (set_attr "modrm" "0,*,*")
255790286Sobrien   (set_attr "length_address" "8,0,0")
255890286Sobrien   (set_attr "length_immediate" "0,*,*")
255990286Sobrien   (set_attr "memory" "store")
256090286Sobrien   (set_attr "mode" "DI")])
256118334Speter
256290286Sobrien(define_insn "*movabsdi_2_rex64"
256390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a,r")
256490286Sobrien        (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
256590286Sobrien  "TARGET_64BIT"
256690286Sobrien  "@
256790286Sobrien   movabs{q}\t{%P1, %0|%0, %P1}
256890286Sobrien   mov{q}\t{%a1, %0|%0, %a1}"
256990286Sobrien  [(set_attr "type" "imov")
257090286Sobrien   (set_attr "modrm" "0,*")
257190286Sobrien   (set_attr "length_address" "8,0")
257290286Sobrien   (set_attr "length_immediate" "0")
257390286Sobrien   (set_attr "memory" "load")
257490286Sobrien   (set_attr "mode" "DI")])
257590286Sobrien
257690286Sobrien;; Convert impossible stores of immediate to existing instructions.
257790286Sobrien;; First try to get scratch register and go through it.  In case this
257890286Sobrien;; fails, move by 32bit parts.
257990286Sobrien(define_peephole2
258090286Sobrien  [(match_scratch:DI 2 "r")
258190286Sobrien   (set (match_operand:DI 0 "memory_operand" "")
258290286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
258390286Sobrien  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
258490286Sobrien   && !x86_64_immediate_operand (operands[1], DImode)"
258590286Sobrien  [(set (match_dup 2) (match_dup 1))
258690286Sobrien   (set (match_dup 0) (match_dup 2))]
258752296Sobrien  "")
258850650Sobrien
258990286Sobrien;; We need to define this as both peepholer and splitter for case
259090286Sobrien;; peephole2 pass is not run.
259190286Sobrien(define_peephole2
259290286Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
259390286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
259490286Sobrien  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
259590286Sobrien   && !x86_64_immediate_operand (operands[1], DImode) && 1"
259690286Sobrien  [(set (match_dup 2) (match_dup 3))
259790286Sobrien   (set (match_dup 4) (match_dup 5))]
259890286Sobrien  "split_di (operands, 2, operands + 2, operands + 4);")
259990286Sobrien
260090286Sobrien(define_split
260190286Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
260290286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
260390286Sobrien  "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
260490286Sobrien   && !symbolic_operand (operands[1], DImode)
260590286Sobrien   && !x86_64_immediate_operand (operands[1], DImode)"
260690286Sobrien  [(set (match_dup 2) (match_dup 3))
260790286Sobrien   (set (match_dup 4) (match_dup 5))]
260890286Sobrien  "split_di (operands, 2, operands + 2, operands + 4);")
260990286Sobrien
261090286Sobrien(define_insn "*swapdi_rex64"
261190286Sobrien  [(set (match_operand:DI 0 "register_operand" "+r")
261290286Sobrien	(match_operand:DI 1 "register_operand" "+r"))
261390286Sobrien   (set (match_dup 1)
261490286Sobrien	(match_dup 0))]
261590286Sobrien  "TARGET_64BIT"
261690286Sobrien  "xchg{q}\t%1, %0"
261790286Sobrien  [(set_attr "type" "imov")
261890286Sobrien   (set_attr "pent_pair" "np")
261990286Sobrien   (set_attr "athlon_decode" "vector")
262090286Sobrien   (set_attr "mode" "DI")
262190286Sobrien   (set_attr "modrm" "0")
262290286Sobrien   (set_attr "ppro_uops" "few")])
262390286Sobrien
262490286Sobrien  
262550650Sobrien(define_expand "movsf"
262690286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "")
262750650Sobrien	(match_operand:SF 1 "general_operand" ""))]
262818334Speter  ""
262990286Sobrien  "ix86_expand_move (SFmode, operands); DONE;")
263090286Sobrien
263190286Sobrien(define_insn "*pushsf"
263290286Sobrien  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
263390286Sobrien	(match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
263490286Sobrien  "!TARGET_64BIT"
263518334Speter{
263690286Sobrien  switch (which_alternative)
263718334Speter    {
263890286Sobrien    case 0:
263990286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
264090286Sobrien      operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
264190286Sobrien      operands[2] = stack_pointer_rtx;
264290286Sobrien      operands[3] = GEN_INT (4);
264390286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
264490286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
264590286Sobrien      else
264690286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
264718334Speter
264890286Sobrien    case 1:
264990286Sobrien      return "push{l}\t%1";
265090286Sobrien    case 2:
265190286Sobrien      return "#";
265290286Sobrien
265390286Sobrien    default:
265490286Sobrien      abort ();
265518334Speter    }
265690286Sobrien}
265790286Sobrien  [(set_attr "type" "multi,push,multi")
265890286Sobrien   (set_attr "mode" "SF,SI,SF")])
265918334Speter
266090286Sobrien(define_insn "*pushsf_rex64"
266190286Sobrien  [(set (match_operand:SF 0 "push_operand" "=X,X,X")
266290286Sobrien	(match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
266390286Sobrien  "TARGET_64BIT"
266418334Speter{
266590286Sobrien  switch (which_alternative)
266690286Sobrien    {
266790286Sobrien    case 0:
266890286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
266990286Sobrien      operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
267090286Sobrien      operands[2] = stack_pointer_rtx;
267190286Sobrien      operands[3] = GEN_INT (8);
267290286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
267390286Sobrien	return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
267490286Sobrien      else
267590286Sobrien	return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
267618334Speter
267790286Sobrien    case 1:
267890286Sobrien      return "push{q}\t%q1";
267918334Speter
268090286Sobrien    case 2:
268190286Sobrien      return "#";
268290286Sobrien
268390286Sobrien    default:
268490286Sobrien      abort ();
268518334Speter    }
268690286Sobrien}
268790286Sobrien  [(set_attr "type" "multi,push,multi")
268890286Sobrien   (set_attr "mode" "SF,DI,SF")])
268918334Speter
269090286Sobrien(define_split
269190286Sobrien  [(set (match_operand:SF 0 "push_operand" "")
269290286Sobrien	(match_operand:SF 1 "memory_operand" ""))]
269390286Sobrien  "reload_completed
269490286Sobrien   && GET_CODE (operands[1]) == MEM
269590286Sobrien   && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
269690286Sobrien   && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
269790286Sobrien  [(set (match_dup 0)
269890286Sobrien	(match_dup 1))]
269990286Sobrien  "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
270018334Speter
270190286Sobrien
270290286Sobrien;; %%% Kill this when call knows how to work this out.
270390286Sobrien(define_split
270490286Sobrien  [(set (match_operand:SF 0 "push_operand" "")
270590286Sobrien	(match_operand:SF 1 "register_operand" ""))]
270690286Sobrien  "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
270790286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
270890286Sobrien   (set (mem:SF (reg:SI 7)) (match_dup 1))])
270990286Sobrien
271090286Sobrien(define_split
271190286Sobrien  [(set (match_operand:SF 0 "push_operand" "")
271290286Sobrien	(match_operand:SF 1 "register_operand" ""))]
271390286Sobrien  "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
271490286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
271590286Sobrien   (set (mem:SF (reg:DI 7)) (match_dup 1))])
271690286Sobrien
271790286Sobrien(define_insn "*movsf_1"
271890286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m")
271990286Sobrien	(match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf"))]
272090286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
272190286Sobrien   && (reload_in_progress || reload_completed
272290286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
272390286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
272490286Sobrien       || memory_operand (operands[0], SFmode))" 
272590286Sobrien{
272690286Sobrien  switch (which_alternative)
272718334Speter    {
272890286Sobrien    case 0:
272990286Sobrien      if (REG_P (operands[1])
273090286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
273190286Sobrien        return "fstp\t%y0";
273290286Sobrien      else if (STACK_TOP_P (operands[0]))
273390286Sobrien        return "fld%z1\t%y1";
273418334Speter      else
273590286Sobrien        return "fst\t%y0";
273618334Speter
273790286Sobrien    case 1:
273890286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
273990286Sobrien        return "fstp%z0\t%y0";
274090286Sobrien      else
274190286Sobrien        return "fst%z0\t%y0";
274218334Speter
274390286Sobrien    case 2:
274490286Sobrien      switch (standard_80387_constant_p (operands[1]))
274590286Sobrien        {
274690286Sobrien        case 1:
274790286Sobrien	  return "fldz";
274890286Sobrien	case 2:
274990286Sobrien	  return "fld1";
275090286Sobrien	}
275190286Sobrien      abort();
275218334Speter
275390286Sobrien    case 3:
275490286Sobrien    case 4:
275590286Sobrien      return "mov{l}\t{%1, %0|%0, %1}";
275690286Sobrien    case 5:
275790286Sobrien      return "pxor\t%0, %0";
275890286Sobrien    case 6:
275990286Sobrien      if (TARGET_PARTIAL_REG_DEPENDENCY)
276090286Sobrien	return "movaps\t{%1, %0|%0, %1}";
276190286Sobrien      else
276290286Sobrien	return "movss\t{%1, %0|%0, %1}";
276390286Sobrien    case 7:
276490286Sobrien    case 8:
276590286Sobrien      return "movss\t{%1, %0|%0, %1}";
276618334Speter
276790286Sobrien    default:
276890286Sobrien      abort();
276990286Sobrien    }
277090286Sobrien}
277190286Sobrien  [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse,sse,sse")
277290286Sobrien   (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF")])
277318334Speter
277490286Sobrien(define_insn "*swapsf"
277590286Sobrien  [(set (match_operand:SF 0 "register_operand" "+f")
277690286Sobrien	(match_operand:SF 1 "register_operand" "+f"))
277718334Speter   (set (match_dup 1)
277818334Speter	(match_dup 0))]
277990286Sobrien  "reload_completed || !TARGET_SSE"
278018334Speter{
278118334Speter  if (STACK_TOP_P (operands[0]))
278290286Sobrien    return "fxch\t%1";
278318334Speter  else
278490286Sobrien    return "fxch\t%0";
278590286Sobrien}
278690286Sobrien  [(set_attr "type" "fxch")
278790286Sobrien   (set_attr "mode" "SF")])
278818334Speter
278990286Sobrien(define_expand "movdf"
279090286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "")
279190286Sobrien	(match_operand:DF 1 "general_operand" ""))]
279290286Sobrien  ""
279390286Sobrien  "ix86_expand_move (DFmode, operands); DONE;")
279452296Sobrien
279590286Sobrien;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
279690286Sobrien;; Size of pushdf using integer insturctions is 2+2*memory operand size
279790286Sobrien;; On the average, pushdf using integers can be still shorter.  Allow this
279890286Sobrien;; pattern for optimize_size too.
279990286Sobrien
280090286Sobrien(define_insn "*pushdf_nointeger"
280190286Sobrien  [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
280290286Sobrien	(match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
280390286Sobrien  "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
280418334Speter{
280590286Sobrien  switch (which_alternative)
280618334Speter    {
280790286Sobrien    case 0:
280890286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
280990286Sobrien      operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
281090286Sobrien      operands[2] = stack_pointer_rtx;
281190286Sobrien      operands[3] = GEN_INT (8);
281290286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
281390286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
281490286Sobrien      else
281590286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
281618334Speter
281790286Sobrien    case 1:
281890286Sobrien    case 2:
281990286Sobrien    case 3:
282090286Sobrien      return "#";
282118334Speter
282290286Sobrien    default:
282390286Sobrien      abort ();
282490286Sobrien    }
282590286Sobrien}
282690286Sobrien  [(set_attr "type" "multi")
282790286Sobrien   (set_attr "mode" "DF,SI,SI,DF")])
282818334Speter
282990286Sobrien(define_insn "*pushdf_integer"
283090286Sobrien  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
283190286Sobrien	(match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
283290286Sobrien  "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
283390286Sobrien{
283490286Sobrien  switch (which_alternative)
283590286Sobrien    {
283690286Sobrien    case 0:
283790286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
283890286Sobrien      operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
283990286Sobrien      operands[2] = stack_pointer_rtx;
284090286Sobrien      operands[3] = GEN_INT (8);
284190286Sobrien      if (TARGET_64BIT)
284290286Sobrien	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
284390286Sobrien	  return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
284490286Sobrien	else
284590286Sobrien	  return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
284618334Speter      else
284790286Sobrien	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
284890286Sobrien	  return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
284990286Sobrien	else
285090286Sobrien	  return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
285118334Speter
285250650Sobrien
285390286Sobrien    case 1:
285490286Sobrien    case 2:
285590286Sobrien      return "#";
285650650Sobrien
285790286Sobrien    default:
285890286Sobrien      abort ();
285990286Sobrien    }
286090286Sobrien}
286190286Sobrien  [(set_attr "type" "multi")
286290286Sobrien   (set_attr "mode" "DF,SI,DF")])
286318334Speter
286490286Sobrien;; %%% Kill this when call knows how to work this out.
286552296Sobrien(define_split
286652296Sobrien  [(set (match_operand:DF 0 "push_operand" "")
286790286Sobrien	(match_operand:DF 1 "register_operand" ""))]
286890286Sobrien  "!TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
286990286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
287090286Sobrien   (set (mem:DF (reg:SI 7)) (match_dup 1))]
287152296Sobrien  "")
287250650Sobrien
287390286Sobrien(define_split
287490286Sobrien  [(set (match_operand:DF 0 "push_operand" "")
287590286Sobrien	(match_operand:DF 1 "register_operand" ""))]
287690286Sobrien  "TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
287790286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
287890286Sobrien   (set (mem:DF (reg:DI 7)) (match_dup 1))]
287990286Sobrien  "")
288090286Sobrien
288190286Sobrien(define_split
288290286Sobrien  [(set (match_operand:DF 0 "push_operand" "")
288350650Sobrien	(match_operand:DF 1 "general_operand" ""))]
288490286Sobrien  "reload_completed"
288590286Sobrien  [(const_int 0)]
288690286Sobrien  "ix86_split_long_move (operands); DONE;")
288790286Sobrien
288890286Sobrien;; Moving is usually shorter when only FP registers are used. This separate
288990286Sobrien;; movdf pattern avoids the use of integer registers for FP operations
289090286Sobrien;; when optimizing for size.
289190286Sobrien
289290286Sobrien(define_insn "*movdf_nointeger"
289390286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
289490286Sobrien	(match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,H,Y#f,YHm#f,Y#f"))]
289590286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
289690286Sobrien   && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
289790286Sobrien   && (reload_in_progress || reload_completed
289890286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
289990286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
290090286Sobrien       || memory_operand (operands[0], DFmode))" 
290118334Speter{
290290286Sobrien  switch (which_alternative)
290318334Speter    {
290490286Sobrien    case 0:
290590286Sobrien      if (REG_P (operands[1])
290690286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
290790286Sobrien        return "fstp\t%y0";
290890286Sobrien      else if (STACK_TOP_P (operands[0]))
290990286Sobrien        return "fld%z1\t%y1";
291090286Sobrien      else
291190286Sobrien        return "fst\t%y0";
291218334Speter
291390286Sobrien    case 1:
291490286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
291590286Sobrien        return "fstp%z0\t%y0";
291690286Sobrien      else
291790286Sobrien        return "fst%z0\t%y0";
291818334Speter
291990286Sobrien    case 2:
292090286Sobrien      switch (standard_80387_constant_p (operands[1]))
292190286Sobrien        {
292290286Sobrien        case 1:
292390286Sobrien	  return "fldz";
292490286Sobrien	case 2:
292590286Sobrien	  return "fld1";
292690286Sobrien	}
292790286Sobrien      abort();
292818334Speter
292990286Sobrien    case 3:
293090286Sobrien    case 4:
293190286Sobrien      return "#";
293290286Sobrien    case 5:
293390286Sobrien      return "pxor\t%0, %0";
293490286Sobrien    case 6:
293590286Sobrien      if (TARGET_PARTIAL_REG_DEPENDENCY)
293690286Sobrien	return "movapd\t{%1, %0|%0, %1}";
293790286Sobrien      else
293890286Sobrien	return "movsd\t{%1, %0|%0, %1}";
293990286Sobrien    case 7:
294090286Sobrien    case 8:
294190286Sobrien        return "movsd\t{%1, %0|%0, %1}";
294218334Speter
294390286Sobrien    default:
294490286Sobrien      abort();
294518334Speter    }
294690286Sobrien}
294790286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
294890286Sobrien   (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
294918334Speter
295090286Sobrien(define_insn "*movdf_integer"
295190286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
295290286Sobrien	(match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,H,Y#rf,Ym#rf,Y#rf"))]
295390286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
295490286Sobrien   && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
295590286Sobrien   && (reload_in_progress || reload_completed
295690286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
295790286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
295890286Sobrien       || memory_operand (operands[0], DFmode))" 
295990286Sobrien{
296090286Sobrien  switch (which_alternative)
296118334Speter    {
296290286Sobrien    case 0:
296390286Sobrien      if (REG_P (operands[1])
296490286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
296590286Sobrien        return "fstp\t%y0";
296690286Sobrien      else if (STACK_TOP_P (operands[0]))
296790286Sobrien        return "fld%z1\t%y1";
296818334Speter      else
296990286Sobrien        return "fst\t%y0";
297018334Speter
297190286Sobrien    case 1:
297290286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
297390286Sobrien        return "fstp%z0\t%y0";
297490286Sobrien      else
297590286Sobrien        return "fst%z0\t%y0";
297618334Speter
297790286Sobrien    case 2:
297890286Sobrien      switch (standard_80387_constant_p (operands[1]))
297990286Sobrien        {
298090286Sobrien        case 1:
298190286Sobrien	  return "fldz";
298290286Sobrien	case 2:
298390286Sobrien	  return "fld1";
298490286Sobrien	}
298590286Sobrien      abort();
298618334Speter
298790286Sobrien    case 3:
298890286Sobrien    case 4:
298990286Sobrien      return "#";
299018334Speter
299190286Sobrien    case 5:
299290286Sobrien      return "pxor\t%0, %0";
299390286Sobrien    case 6:
299490286Sobrien      if (TARGET_PARTIAL_REG_DEPENDENCY)
299590286Sobrien	return "movapd\t{%1, %0|%0, %1}";
299690286Sobrien      else
299790286Sobrien	return "movsd\t{%1, %0|%0, %1}";
299890286Sobrien    case 7:
299990286Sobrien    case 8:
300090286Sobrien      return "movsd\t{%1, %0|%0, %1}";
300118334Speter
300290286Sobrien    default:
300390286Sobrien      abort();
300490286Sobrien    }
300590286Sobrien}
300690286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
300790286Sobrien   (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
300818334Speter
300990286Sobrien(define_split
301090286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "")
301190286Sobrien	(match_operand:DF 1 "general_operand" ""))]
301290286Sobrien  "reload_completed
301390286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
301490286Sobrien   && ! (ANY_FP_REG_P (operands[0]) || 
301590286Sobrien	 (GET_CODE (operands[0]) == SUBREG
301690286Sobrien	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
301790286Sobrien   && ! (ANY_FP_REG_P (operands[1]) || 
301890286Sobrien	 (GET_CODE (operands[1]) == SUBREG
301990286Sobrien	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
302090286Sobrien  [(const_int 0)]
302190286Sobrien  "ix86_split_long_move (operands); DONE;")
302250650Sobrien
302390286Sobrien(define_insn "*swapdf"
302490286Sobrien  [(set (match_operand:DF 0 "register_operand" "+f")
302590286Sobrien	(match_operand:DF 1 "register_operand" "+f"))
302618334Speter   (set (match_dup 1)
302718334Speter	(match_dup 0))]
302890286Sobrien  "reload_completed || !TARGET_SSE2"
302918334Speter{
303018334Speter  if (STACK_TOP_P (operands[0]))
303190286Sobrien    return "fxch\t%1";
303218334Speter  else
303390286Sobrien    return "fxch\t%0";
303490286Sobrien}
303590286Sobrien  [(set_attr "type" "fxch")
303690286Sobrien   (set_attr "mode" "DF")])
303718334Speter
303890286Sobrien(define_expand "movxf"
303990286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "")
304090286Sobrien	(match_operand:XF 1 "general_operand" ""))]
304190286Sobrien  "!TARGET_64BIT"
304290286Sobrien  "ix86_expand_move (XFmode, operands); DONE;")
304390286Sobrien
304490286Sobrien(define_expand "movtf"
304590286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "")
304690286Sobrien	(match_operand:TF 1 "general_operand" ""))]
304790286Sobrien  ""
304890286Sobrien  "ix86_expand_move (TFmode, operands); DONE;")
304990286Sobrien
305090286Sobrien;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
305190286Sobrien;; Size of pushdf using integer insturctions is 3+3*memory operand size
305290286Sobrien;; Pushing using integer instructions is longer except for constants
305390286Sobrien;; and direct memory references.
305490286Sobrien;; (assuming that any given constant is pushed only once, but this ought to be
305590286Sobrien;;  handled elsewhere).
305690286Sobrien
305790286Sobrien(define_insn "*pushxf_nointeger"
305890286Sobrien  [(set (match_operand:XF 0 "push_operand" "=X,X,X")
305990286Sobrien	(match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
306090286Sobrien  "!TARGET_64BIT && optimize_size"
306118334Speter{
306290286Sobrien  switch (which_alternative)
306318334Speter    {
306490286Sobrien    case 0:
306590286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
306690286Sobrien      operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
306790286Sobrien      operands[2] = stack_pointer_rtx;
306890286Sobrien      operands[3] = GEN_INT (12);
306990286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
307090286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
307190286Sobrien      else
307290286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
307318334Speter
307490286Sobrien    case 1:
307590286Sobrien    case 2:
307690286Sobrien      return "#";
307718334Speter
307890286Sobrien    default:
307990286Sobrien      abort ();
308090286Sobrien    }
308190286Sobrien}
308290286Sobrien  [(set_attr "type" "multi")
308390286Sobrien   (set_attr "mode" "XF,SI,SI")])
308450650Sobrien
308590286Sobrien(define_insn "*pushtf_nointeger"
308690286Sobrien  [(set (match_operand:TF 0 "push_operand" "=<,<,<")
308790286Sobrien	(match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
308890286Sobrien  "optimize_size"
308990286Sobrien{
309090286Sobrien  switch (which_alternative)
309190286Sobrien    {
309290286Sobrien    case 0:
309390286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
309490286Sobrien      operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
309590286Sobrien      operands[2] = stack_pointer_rtx;
309690286Sobrien      operands[3] = GEN_INT (16);
309790286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
309890286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
309990286Sobrien      else
310090286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
310118334Speter
310290286Sobrien    case 1:
310390286Sobrien    case 2:
310490286Sobrien      return "#";
310590286Sobrien
310690286Sobrien    default:
310790286Sobrien      abort ();
310818334Speter    }
310990286Sobrien}
311090286Sobrien  [(set_attr "type" "multi")
311190286Sobrien   (set_attr "mode" "XF,SI,SI")])
311250650Sobrien
311390286Sobrien(define_insn "*pushxf_integer"
311490286Sobrien  [(set (match_operand:XF 0 "push_operand" "=<,<")
311590286Sobrien	(match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
311690286Sobrien  "!TARGET_64BIT && !optimize_size"
311790286Sobrien{
311890286Sobrien  switch (which_alternative)
311990286Sobrien    {
312090286Sobrien    case 0:
312190286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
312290286Sobrien      operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
312390286Sobrien      operands[2] = stack_pointer_rtx;
312490286Sobrien      operands[3] = GEN_INT (12);
312590286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
312690286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
312790286Sobrien      else
312890286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
312950650Sobrien
313090286Sobrien    case 1:
313190286Sobrien      return "#";
313218334Speter
313390286Sobrien    default:
313490286Sobrien      abort ();
313590286Sobrien    }
313690286Sobrien}
313790286Sobrien  [(set_attr "type" "multi")
313890286Sobrien   (set_attr "mode" "XF,SI")])
313990286Sobrien
314090286Sobrien(define_insn "*pushtf_integer"
314190286Sobrien  [(set (match_operand:TF 0 "push_operand" "=<,<")
314290286Sobrien	(match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
314390286Sobrien  "!optimize_size"
314490286Sobrien{
314590286Sobrien  switch (which_alternative)
314690286Sobrien    {
314790286Sobrien    case 0:
314890286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
314990286Sobrien      operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
315090286Sobrien      operands[2] = stack_pointer_rtx;
315190286Sobrien      operands[3] = GEN_INT (16);
315290286Sobrien      if (TARGET_64BIT)
315390286Sobrien	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
315490286Sobrien	  return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
315590286Sobrien	else
315690286Sobrien	  return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
315790286Sobrien      else
315890286Sobrien	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
315990286Sobrien	  return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
316090286Sobrien	else
316190286Sobrien	  return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
316290286Sobrien
316390286Sobrien    case 1:
316490286Sobrien      return "#";
316590286Sobrien
316690286Sobrien    default:
316790286Sobrien      abort ();
316890286Sobrien    }
316990286Sobrien}
317090286Sobrien  [(set_attr "type" "multi")
317190286Sobrien   (set_attr "mode" "XF,SI")])
317290286Sobrien
317352296Sobrien(define_split
317490286Sobrien  [(set (match_operand 0 "push_operand" "")
317590286Sobrien	(match_operand 1 "general_operand" ""))]
317690286Sobrien  "reload_completed
317790286Sobrien   && (GET_MODE (operands[0]) == XFmode
317890286Sobrien       || GET_MODE (operands[0]) == TFmode
317990286Sobrien       || GET_MODE (operands[0]) == DFmode)
318090286Sobrien   && (!REG_P (operands[1]) || !ANY_FP_REGNO_P (REGNO (operands[1])))"
318190286Sobrien  [(const_int 0)]
318290286Sobrien  "ix86_split_long_move (operands); DONE;")
318390286Sobrien
318490286Sobrien(define_split
318552296Sobrien  [(set (match_operand:XF 0 "push_operand" "")
318690286Sobrien	(match_operand:XF 1 "register_operand" ""))]
318790286Sobrien  "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
318890286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
318990286Sobrien   (set (mem:XF (reg:SI 7)) (match_dup 1))])
319050650Sobrien
319190286Sobrien(define_split
319290286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
319390286Sobrien	(match_operand:TF 1 "register_operand" ""))]
319490286Sobrien  "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
319590286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
319690286Sobrien   (set (mem:TF (reg:SI 7)) (match_dup 1))])
319790286Sobrien
319890286Sobrien(define_split
319990286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
320090286Sobrien	(match_operand:TF 1 "register_operand" ""))]
320190286Sobrien  "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
320290286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
320390286Sobrien   (set (mem:TF (reg:DI 7)) (match_dup 1))])
320490286Sobrien
320590286Sobrien;; Do not use integer registers when optimizing for size
320690286Sobrien(define_insn "*movxf_nointeger"
320790286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
320890286Sobrien	(match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
320990286Sobrien  "!TARGET_64BIT
321090286Sobrien   && optimize_size
321190286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
321290286Sobrien   && (reload_in_progress || reload_completed
321390286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
321490286Sobrien       || memory_operand (operands[0], XFmode))" 
321518334Speter{
321690286Sobrien  switch (which_alternative)
321718334Speter    {
321890286Sobrien    case 0:
321990286Sobrien      if (REG_P (operands[1])
322090286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
322190286Sobrien        return "fstp\t%y0";
322290286Sobrien      else if (STACK_TOP_P (operands[0]))
322390286Sobrien        return "fld%z1\t%y1";
322490286Sobrien      else
322590286Sobrien        return "fst\t%y0";
322690286Sobrien
322790286Sobrien    case 1:
322890286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
322990286Sobrien	 we need one, follow the store with a load.  */
323090286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
323190286Sobrien        return "fstp%z0\t%y0\;fld%z0\t%y0";
323290286Sobrien      else
323390286Sobrien        return "fstp%z0\t%y0";
323490286Sobrien
323590286Sobrien    case 2:
323690286Sobrien      switch (standard_80387_constant_p (operands[1]))
323790286Sobrien        {
323890286Sobrien        case 1:
323990286Sobrien	  return "fldz";
324090286Sobrien	case 2:
324190286Sobrien	  return "fld1";
324290286Sobrien	}
324390286Sobrien      break;
324490286Sobrien
324590286Sobrien    case 3: case 4:
324690286Sobrien      return "#";
324750650Sobrien    }
324890286Sobrien  abort();
324990286Sobrien}
325090286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
325190286Sobrien   (set_attr "mode" "XF,XF,XF,SI,SI")])
325218334Speter
325390286Sobrien(define_insn "*movtf_nointeger"
325490286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
325590286Sobrien	(match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
325690286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
325790286Sobrien   && optimize_size
325890286Sobrien   && (reload_in_progress || reload_completed
325990286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
326090286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
326190286Sobrien       || memory_operand (operands[0], TFmode))" 
326290286Sobrien{
326390286Sobrien  switch (which_alternative)
326450650Sobrien    {
326590286Sobrien    case 0:
326690286Sobrien      if (REG_P (operands[1])
326790286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
326890286Sobrien        return "fstp\t%y0";
326990286Sobrien      else if (STACK_TOP_P (operands[0]))
327090286Sobrien        return "fld%z1\t%y1";
327190286Sobrien      else
327290286Sobrien        return "fst\t%y0";
327318334Speter
327490286Sobrien    case 1:
327590286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
327690286Sobrien	 we need one, follow the store with a load.  */
327790286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
327890286Sobrien        return "fstp%z0\t%y0\;fld%z0\t%y0";
327990286Sobrien      else
328090286Sobrien        return "fstp%z0\t%y0";
328118334Speter
328290286Sobrien    case 2:
328390286Sobrien      switch (standard_80387_constant_p (operands[1]))
328490286Sobrien        {
328590286Sobrien        case 1:
328690286Sobrien	  return "fldz";
328790286Sobrien	case 2:
328890286Sobrien	  return "fld1";
328990286Sobrien	}
329090286Sobrien      break;
329118334Speter
329290286Sobrien    case 3: case 4:
329390286Sobrien      return "#";
329490286Sobrien    }
329590286Sobrien  abort();
329690286Sobrien}
329790286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
329890286Sobrien   (set_attr "mode" "XF,XF,XF,SI,SI")])
329918334Speter
330090286Sobrien(define_insn "*movxf_integer"
330190286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
330290286Sobrien	(match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
330390286Sobrien  "!TARGET_64BIT
330490286Sobrien   && !optimize_size
330590286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
330690286Sobrien   && (reload_in_progress || reload_completed
330790286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
330890286Sobrien       || memory_operand (operands[0], XFmode))" 
330990286Sobrien{
331090286Sobrien  switch (which_alternative)
331118334Speter    {
331290286Sobrien    case 0:
331390286Sobrien      if (REG_P (operands[1])
331490286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
331590286Sobrien        return "fstp\t%y0";
331690286Sobrien      else if (STACK_TOP_P (operands[0]))
331790286Sobrien        return "fld%z1\t%y1";
331818334Speter      else
331990286Sobrien        return "fst\t%y0";
332018334Speter
332190286Sobrien    case 1:
332290286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
332390286Sobrien	 we need one, follow the store with a load.  */
332490286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
332590286Sobrien        return "fstp%z0\t%y0\;fld%z0\t%y0";
332690286Sobrien      else
332790286Sobrien        return "fstp%z0\t%y0";
332818334Speter
332990286Sobrien    case 2:
333090286Sobrien      switch (standard_80387_constant_p (operands[1]))
333190286Sobrien        {
333290286Sobrien        case 1:
333390286Sobrien	  return "fldz";
333490286Sobrien	case 2:
333590286Sobrien	  return "fld1";
333690286Sobrien	}
333790286Sobrien      break;
333818334Speter
333990286Sobrien    case 3: case 4:
334090286Sobrien      return "#";
334118334Speter    }
334290286Sobrien  abort();
334390286Sobrien}
334490286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
334590286Sobrien   (set_attr "mode" "XF,XF,XF,SI,SI")])
334618334Speter
334790286Sobrien(define_insn "*movtf_integer"
334890286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
334990286Sobrien	(match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
335090286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
335190286Sobrien   && !optimize_size
335290286Sobrien   && (reload_in_progress || reload_completed
335390286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
335490286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
335590286Sobrien       || memory_operand (operands[0], TFmode))" 
335690286Sobrien{
335790286Sobrien  switch (which_alternative)
335890286Sobrien    {
335990286Sobrien    case 0:
336090286Sobrien      if (REG_P (operands[1])
336190286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
336290286Sobrien        return "fstp\t%y0";
336390286Sobrien      else if (STACK_TOP_P (operands[0]))
336490286Sobrien        return "fld%z1\t%y1";
336590286Sobrien      else
336690286Sobrien        return "fst\t%y0";
336718334Speter
336890286Sobrien    case 1:
336990286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
337090286Sobrien	 we need one, follow the store with a load.  */
337190286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
337290286Sobrien        return "fstp%z0\t%y0\;fld%z0\t%y0";
337390286Sobrien      else
337490286Sobrien        return "fstp%z0\t%y0";
337518334Speter
337690286Sobrien    case 2:
337790286Sobrien      switch (standard_80387_constant_p (operands[1]))
337890286Sobrien        {
337990286Sobrien        case 1:
338090286Sobrien	  return "fldz";
338190286Sobrien	case 2:
338290286Sobrien	  return "fld1";
338390286Sobrien	}
338490286Sobrien      break;
338518334Speter
338690286Sobrien    case 3: case 4:
338790286Sobrien      return "#";
338890286Sobrien    }
338990286Sobrien  abort();
339090286Sobrien}
339190286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
339290286Sobrien   (set_attr "mode" "XF,XF,XF,SI,SI")])
339318334Speter
339490286Sobrien(define_split
339590286Sobrien  [(set (match_operand 0 "nonimmediate_operand" "")
339690286Sobrien	(match_operand 1 "general_operand" ""))]
339790286Sobrien  "reload_completed
339890286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
339990286Sobrien   && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
340090286Sobrien   && ! (ANY_FP_REG_P (operands[0]) || 
340190286Sobrien	 (GET_CODE (operands[0]) == SUBREG
340290286Sobrien	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
340390286Sobrien   && ! (ANY_FP_REG_P (operands[1]) || 
340490286Sobrien	 (GET_CODE (operands[1]) == SUBREG
340590286Sobrien	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
340690286Sobrien  [(const_int 0)]
340790286Sobrien  "ix86_split_long_move (operands); DONE;")
340818334Speter
340990286Sobrien(define_split
341090286Sobrien  [(set (match_operand 0 "register_operand" "")
341190286Sobrien	(match_operand 1 "memory_operand" ""))]
341290286Sobrien  "reload_completed
341390286Sobrien   && GET_CODE (operands[1]) == MEM
341490286Sobrien   && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
341590286Sobrien       || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
341690286Sobrien   && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
341790286Sobrien   && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
341890286Sobrien   && (!(SSE_REG_P (operands[0]) || 
341990286Sobrien	 (GET_CODE (operands[0]) == SUBREG
342090286Sobrien	  && SSE_REG_P (SUBREG_REG (operands[0]))))
342190286Sobrien       || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
342290286Sobrien   && (!(FP_REG_P (operands[0]) || 
342390286Sobrien	 (GET_CODE (operands[0]) == SUBREG
342490286Sobrien	  && FP_REG_P (SUBREG_REG (operands[0]))))
342590286Sobrien       || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
342690286Sobrien  [(set (match_dup 0)
342790286Sobrien	(match_dup 1))]
342890286Sobrien  "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
342990286Sobrien
343090286Sobrien(define_insn "swapxf"
343190286Sobrien  [(set (match_operand:XF 0 "register_operand" "+f")
343290286Sobrien	(match_operand:XF 1 "register_operand" "+f"))
343318334Speter   (set (match_dup 1)
343418334Speter	(match_dup 0))]
343518334Speter  ""
343618334Speter{
343718334Speter  if (STACK_TOP_P (operands[0]))
343890286Sobrien    return "fxch\t%1";
343918334Speter  else
344090286Sobrien    return "fxch\t%0";
344190286Sobrien}
344290286Sobrien  [(set_attr "type" "fxch")
344390286Sobrien   (set_attr "mode" "XF")])
344418334Speter
344590286Sobrien(define_insn "swaptf"
344690286Sobrien  [(set (match_operand:TF 0 "register_operand" "+f")
344790286Sobrien	(match_operand:TF 1 "register_operand" "+f"))
344890286Sobrien   (set (match_dup 1)
344990286Sobrien	(match_dup 0))]
345018334Speter  ""
345118334Speter{
345290286Sobrien  if (STACK_TOP_P (operands[0]))
345390286Sobrien    return "fxch\t%1";
345490286Sobrien  else
345590286Sobrien    return "fxch\t%0";
345690286Sobrien}
345790286Sobrien  [(set_attr "type" "fxch")
345890286Sobrien   (set_attr "mode" "XF")])
345918334Speter
346090286Sobrien;; Zero extension instructions
346118334Speter
346252296Sobrien(define_expand "zero_extendhisi2"
346352296Sobrien  [(set (match_operand:SI 0 "register_operand" "")
346490286Sobrien     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
346552296Sobrien  ""
346690286Sobrien{
346790286Sobrien  if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
346818334Speter    {
346990286Sobrien      operands[1] = force_reg (HImode, operands[1]);
347090286Sobrien      emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
347190286Sobrien      DONE;
347218334Speter    }
347390286Sobrien})
347418334Speter
347590286Sobrien(define_insn "zero_extendhisi2_and"
347690286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
347790286Sobrien     (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
347890286Sobrien   (clobber (reg:CC 17))]
347990286Sobrien  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
348090286Sobrien  "#"
348190286Sobrien  [(set_attr "type" "alu1")
348290286Sobrien   (set_attr "mode" "SI")])
348350650Sobrien
348450650Sobrien(define_split
348550650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
348690286Sobrien	(zero_extend:SI (match_operand:HI 1 "register_operand" "")))
348790286Sobrien   (clobber (reg:CC 17))]
348890286Sobrien  "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
348990286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
349090286Sobrien	      (clobber (reg:CC 17))])]
349190286Sobrien  "")
349250650Sobrien
349390286Sobrien(define_insn "*zero_extendhisi2_movzwl"
349490286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
349590286Sobrien     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
349690286Sobrien  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
349790286Sobrien  "movz{wl|x}\t{%1, %0|%0, %1}"
349890286Sobrien  [(set_attr "type" "imovx")
349990286Sobrien   (set_attr "mode" "SI")])
350050650Sobrien
350152296Sobrien(define_expand "zero_extendqihi2"
350290286Sobrien  [(parallel
350390286Sobrien    [(set (match_operand:HI 0 "register_operand" "")
350490286Sobrien       (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
350590286Sobrien     (clobber (reg:CC 17))])]
350652296Sobrien  ""
350752296Sobrien  "")
350852296Sobrien
350990286Sobrien(define_insn "*zero_extendqihi2_and"
351090286Sobrien  [(set (match_operand:HI 0 "register_operand" "=r,?&q")
351190286Sobrien     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
351290286Sobrien   (clobber (reg:CC 17))]
351390286Sobrien  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
351490286Sobrien  "#"
351590286Sobrien  [(set_attr "type" "alu1")
351690286Sobrien   (set_attr "mode" "HI")])
351752296Sobrien
351890286Sobrien(define_insn "*zero_extendqihi2_movzbw_and"
351990286Sobrien  [(set (match_operand:HI 0 "register_operand" "=r,r")
352090286Sobrien     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
352190286Sobrien   (clobber (reg:CC 17))]
352290286Sobrien  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
352390286Sobrien  "#"
352490286Sobrien  [(set_attr "type" "imovx,alu1")
352590286Sobrien   (set_attr "mode" "HI")])
352652296Sobrien
352790286Sobrien(define_insn "*zero_extendqihi2_movzbw"
352890286Sobrien  [(set (match_operand:HI 0 "register_operand" "=r")
352990286Sobrien     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
353090286Sobrien  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
353190286Sobrien  "movz{bw|x}\t{%1, %0|%0, %1}"
353290286Sobrien  [(set_attr "type" "imovx")
353390286Sobrien   (set_attr "mode" "HI")])
353450650Sobrien
353590286Sobrien;; For the movzbw case strip only the clobber
353650650Sobrien(define_split
353750650Sobrien  [(set (match_operand:HI 0 "register_operand" "")
353890286Sobrien	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
353990286Sobrien   (clobber (reg:CC 17))]
354090286Sobrien  "reload_completed 
354190286Sobrien   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
354290286Sobrien   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
354390286Sobrien  [(set (match_operand:HI 0 "register_operand" "")
354490286Sobrien	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
354550650Sobrien
354690286Sobrien;; When source and destination does not overlap, clear destination
354790286Sobrien;; first and then do the movb
354850650Sobrien(define_split
354950650Sobrien  [(set (match_operand:HI 0 "register_operand" "")
355090286Sobrien	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
355190286Sobrien   (clobber (reg:CC 17))]
355290286Sobrien  "reload_completed
355390286Sobrien   && ANY_QI_REG_P (operands[0])
355490286Sobrien   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
355590286Sobrien   && !reg_overlap_mentioned_p (operands[0], operands[1])"
355690286Sobrien  [(set (match_dup 0) (const_int 0))
355790286Sobrien   (set (strict_low_part (match_dup 2)) (match_dup 1))]
355890286Sobrien  "operands[2] = gen_lowpart (QImode, operands[0]);")
355950650Sobrien
356090286Sobrien;; Rest is handled by single and.
356150650Sobrien(define_split
356250650Sobrien  [(set (match_operand:HI 0 "register_operand" "")
356390286Sobrien	(zero_extend:HI (match_operand:QI 1 "register_operand" "")))
356490286Sobrien   (clobber (reg:CC 17))]
356590286Sobrien  "reload_completed
356690286Sobrien   && true_regnum (operands[0]) == true_regnum (operands[1])"
356790286Sobrien  [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
356890286Sobrien	      (clobber (reg:CC 17))])]
356990286Sobrien  "")
357050650Sobrien
357152296Sobrien(define_expand "zero_extendqisi2"
357290286Sobrien  [(parallel
357390286Sobrien    [(set (match_operand:SI 0 "register_operand" "")
357490286Sobrien       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
357590286Sobrien     (clobber (reg:CC 17))])]
357652296Sobrien  ""
357752296Sobrien  "")
357852296Sobrien
357990286Sobrien(define_insn "*zero_extendqisi2_and"
358090286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,?&q")
358190286Sobrien     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
358290286Sobrien   (clobber (reg:CC 17))]
358390286Sobrien  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
358490286Sobrien  "#"
358590286Sobrien  [(set_attr "type" "alu1")
358690286Sobrien   (set_attr "mode" "SI")])
358752296Sobrien
358890286Sobrien(define_insn "*zero_extendqisi2_movzbw_and"
358990286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,r")
359090286Sobrien     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
359190286Sobrien   (clobber (reg:CC 17))]
359290286Sobrien  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
359390286Sobrien  "#"
359490286Sobrien  [(set_attr "type" "imovx,alu1")
359590286Sobrien   (set_attr "mode" "SI")])
359650650Sobrien
359790286Sobrien(define_insn "*zero_extendqisi2_movzbw"
359890286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
359990286Sobrien     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
360090286Sobrien  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
360190286Sobrien  "movz{bl|x}\t{%1, %0|%0, %1}"
360290286Sobrien  [(set_attr "type" "imovx")
360390286Sobrien   (set_attr "mode" "SI")])
360418334Speter
360590286Sobrien;; For the movzbl case strip only the clobber
360650650Sobrien(define_split
360750650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
360890286Sobrien	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
360990286Sobrien   (clobber (reg:CC 17))]
361090286Sobrien  "reload_completed 
361190286Sobrien   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
361290286Sobrien   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
361390286Sobrien  [(set (match_dup 0)
361490286Sobrien	(zero_extend:SI (match_dup 1)))])
361550650Sobrien
361690286Sobrien;; When source and destination does not overlap, clear destination
361790286Sobrien;; first and then do the movb
361850650Sobrien(define_split
361950650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
362090286Sobrien	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
362190286Sobrien   (clobber (reg:CC 17))]
362290286Sobrien  "reload_completed
362390286Sobrien   && ANY_QI_REG_P (operands[0])
362490286Sobrien   && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
362590286Sobrien   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
362690286Sobrien   && !reg_overlap_mentioned_p (operands[0], operands[1])"
362790286Sobrien  [(set (match_dup 0) (const_int 0))
362890286Sobrien   (set (strict_low_part (match_dup 2)) (match_dup 1))]
362990286Sobrien  "operands[2] = gen_lowpart (QImode, operands[0]);")
363050650Sobrien
363190286Sobrien;; Rest is handled by single and.
363250650Sobrien(define_split
363350650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
363490286Sobrien	(zero_extend:SI (match_operand:QI 1 "register_operand" "")))
363590286Sobrien   (clobber (reg:CC 17))]
363690286Sobrien  "reload_completed
363790286Sobrien   && true_regnum (operands[0]) == true_regnum (operands[1])"
363890286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
363990286Sobrien	      (clobber (reg:CC 17))])]
364090286Sobrien  "")
364150650Sobrien
364290286Sobrien;; %%% Kill me once multi-word ops are sane.
364390286Sobrien(define_expand "zero_extendsidi2"
364490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
364590286Sobrien     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
364618334Speter  ""
364790286Sobrien  "if (!TARGET_64BIT)
364890286Sobrien     {
364990286Sobrien       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
365090286Sobrien       DONE;
365190286Sobrien     }
365290286Sobrien  ")
365350650Sobrien
365490286Sobrien(define_insn "zero_extendsidi2_32"
365590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
365690286Sobrien	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
365790286Sobrien   (clobber (reg:CC 17))]
365890286Sobrien  "!TARGET_64BIT"
365990286Sobrien  "#"
366090286Sobrien  [(set_attr "mode" "SI")])
366190286Sobrien
366290286Sobrien(define_insn "zero_extendsidi2_rex64"
366390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
366490286Sobrien     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
366590286Sobrien  "TARGET_64BIT"
366690286Sobrien  "@
366790286Sobrien   mov\t{%k1, %k0|%k0, %k1}
366890286Sobrien   #"
366990286Sobrien  [(set_attr "type" "imovx,imov")
367090286Sobrien   (set_attr "mode" "SI,DI")])
367190286Sobrien
367290286Sobrien(define_split
367390286Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
367490286Sobrien     (zero_extend:DI (match_dup 0)))]
367590286Sobrien  "TARGET_64BIT"
367690286Sobrien  [(set (match_dup 4) (const_int 0))]
367790286Sobrien  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
367890286Sobrien
367952296Sobrien(define_split 
368052296Sobrien  [(set (match_operand:DI 0 "register_operand" "")
368190286Sobrien	(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
368290286Sobrien   (clobber (reg:CC 17))]
368390286Sobrien  "!TARGET_64BIT && reload_completed
368490286Sobrien   && true_regnum (operands[0]) == true_regnum (operands[1])"
368552296Sobrien  [(set (match_dup 4) (const_int 0))]
368652296Sobrien  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
368750650Sobrien
368852296Sobrien(define_split 
368952296Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
369090286Sobrien	(zero_extend:DI (match_operand:SI 1 "general_operand" "")))
369190286Sobrien   (clobber (reg:CC 17))]
369290286Sobrien  "!TARGET_64BIT && reload_completed"
369352296Sobrien  [(set (match_dup 3) (match_dup 1))
369452296Sobrien   (set (match_dup 4) (const_int 0))]
369552296Sobrien  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
369690286Sobrien
369790286Sobrien(define_insn "zero_extendhidi2"
369890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
369990286Sobrien     (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
370090286Sobrien  "TARGET_64BIT"
370190286Sobrien  "@
370290286Sobrien   movz{wl|x}\t{%1, %k0|%k0, %1} 
370390286Sobrien   movz{wq|x}\t{%1, %0|%0, %1}"
370490286Sobrien  [(set_attr "type" "imovx")
370590286Sobrien   (set_attr "mode" "SI,DI")])
370690286Sobrien
370790286Sobrien(define_insn "zero_extendqidi2"
370890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
370990286Sobrien     (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
371090286Sobrien  "TARGET_64BIT"
371190286Sobrien  "@
371290286Sobrien   movz{bl|x}\t{%1, %k0|%k0, %1} 
371390286Sobrien   movz{bq|x}\t{%1, %0|%0, %1}"
371490286Sobrien  [(set_attr "type" "imovx")
371590286Sobrien   (set_attr "mode" "SI,DI")])
371618334Speter
371790286Sobrien;; Sign extension instructions
371818334Speter
371990286Sobrien(define_expand "extendsidi2"
372090286Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
372190286Sobrien		   (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
372290286Sobrien	      (clobber (reg:CC 17))
372390286Sobrien	      (clobber (match_scratch:SI 2 ""))])]
372490286Sobrien  ""
372590286Sobrien{
372690286Sobrien  if (TARGET_64BIT)
372790286Sobrien    {
372890286Sobrien      emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
372990286Sobrien      DONE;
373090286Sobrien    }
373190286Sobrien})
373290286Sobrien
373390286Sobrien(define_insn "*extendsidi2_1"
373490286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
373590286Sobrien	(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
373690286Sobrien   (clobber (reg:CC 17))
373752296Sobrien   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
373890286Sobrien  "!TARGET_64BIT"
373952296Sobrien  "#")
374052296Sobrien
374190286Sobrien(define_insn "extendsidi2_rex64"
374290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=*a,r")
374390286Sobrien	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
374490286Sobrien  "TARGET_64BIT"
374590286Sobrien  "@
374690286Sobrien   {cltq|cdqe}
374790286Sobrien   movs{lq|x}\t{%1,%0|%0, %1}"
374890286Sobrien  [(set_attr "type" "imovx")
374990286Sobrien   (set_attr "mode" "DI")
375090286Sobrien   (set_attr "prefix_0f" "0")
375190286Sobrien   (set_attr "modrm" "0,1")])
375290286Sobrien
375390286Sobrien(define_insn "extendhidi2"
375490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
375590286Sobrien	(sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
375690286Sobrien  "TARGET_64BIT"
375790286Sobrien  "movs{wq|x}\t{%1,%0|%0, %1}"
375890286Sobrien  [(set_attr "type" "imovx")
375990286Sobrien   (set_attr "mode" "DI")])
376090286Sobrien
376190286Sobrien(define_insn "extendqidi2"
376290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
376390286Sobrien	(sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
376490286Sobrien  "TARGET_64BIT"
376590286Sobrien  "movs{bq|x}\t{%1,%0|%0, %1}"
376690286Sobrien   [(set_attr "type" "imovx")
376790286Sobrien    (set_attr "mode" "DI")])
376890286Sobrien
376952296Sobrien;; Extend to memory case when source register does die.
377052296Sobrien(define_split 
377152296Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
377252296Sobrien	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
377390286Sobrien   (clobber (reg:CC 17))
377452296Sobrien   (clobber (match_operand:SI 2 "register_operand" ""))]
377590286Sobrien  "(reload_completed
377652296Sobrien    && dead_or_set_p (insn, operands[1])
377752296Sobrien    && !reg_mentioned_p (operands[1], operands[0]))"
377852296Sobrien  [(set (match_dup 3) (match_dup 1))
377990286Sobrien   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
378090286Sobrien	      (clobber (reg:CC 17))])
378152296Sobrien   (set (match_dup 4) (match_dup 1))]
378252296Sobrien  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
378352296Sobrien
378452296Sobrien;; Extend to memory case when source register does not die.
378552296Sobrien(define_split 
378652296Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
378752296Sobrien	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
378890286Sobrien   (clobber (reg:CC 17))
378952296Sobrien   (clobber (match_operand:SI 2 "register_operand" ""))]
379090286Sobrien  "reload_completed"
379152296Sobrien  [(const_int 0)]
379218334Speter{
379352296Sobrien  split_di (&operands[0], 1, &operands[3], &operands[4]);
379452296Sobrien
379552296Sobrien  emit_move_insn (operands[3], operands[1]);
379652296Sobrien
379752296Sobrien  /* Generate a cltd if possible and doing so it profitable.  */
379852296Sobrien  if (true_regnum (operands[1]) == 0
379952296Sobrien      && true_regnum (operands[2]) == 1
380090286Sobrien      && (optimize_size || TARGET_USE_CLTD))
380118334Speter    {
380290286Sobrien      emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
380318334Speter    }
380452296Sobrien  else
380552296Sobrien    {
380652296Sobrien      emit_move_insn (operands[2], operands[1]);
380790286Sobrien      emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
380852296Sobrien    }
380952296Sobrien  emit_move_insn (operands[4], operands[2]);
381052296Sobrien  DONE;
381190286Sobrien})
381218334Speter
381352296Sobrien;; Extend to register case.  Optimize case where source and destination
381452296Sobrien;; registers match and cases where we can use cltd.
381552296Sobrien(define_split 
381652296Sobrien  [(set (match_operand:DI 0 "register_operand" "")
381752296Sobrien	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
381890286Sobrien   (clobber (reg:CC 17))
381952296Sobrien   (clobber (match_scratch:SI 2 ""))]
382052296Sobrien  "reload_completed"
382152296Sobrien  [(const_int 0)]
382252296Sobrien{
382352296Sobrien  split_di (&operands[0], 1, &operands[3], &operands[4]);
382418334Speter
382552296Sobrien  if (true_regnum (operands[3]) != true_regnum (operands[1]))
382652296Sobrien    emit_move_insn (operands[3], operands[1]);
382752296Sobrien
382852296Sobrien  /* Generate a cltd if possible and doing so it profitable.  */
382952296Sobrien  if (true_regnum (operands[3]) == 0
383090286Sobrien      && (optimize_size || TARGET_USE_CLTD))
383152296Sobrien    {
383290286Sobrien      emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
383352296Sobrien      DONE;
383452296Sobrien    }
383552296Sobrien
383652296Sobrien  if (true_regnum (operands[4]) != true_regnum (operands[1]))
383752296Sobrien    emit_move_insn (operands[4], operands[1]);
383852296Sobrien
383990286Sobrien  emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
384052296Sobrien  DONE;
384190286Sobrien})
384218334Speter
384318334Speter(define_insn "extendhisi2"
384490286Sobrien  [(set (match_operand:SI 0 "register_operand" "=*a,r")
384590286Sobrien	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
384618334Speter  ""
384718334Speter{
384890286Sobrien  switch (get_attr_prefix_0f (insn))
384990286Sobrien    {
385090286Sobrien    case 0:
385190286Sobrien      return "{cwtl|cwde}";
385290286Sobrien    default:
385390286Sobrien      return "movs{wl|x}\t{%1,%0|%0, %1}";
385490286Sobrien    }
385590286Sobrien}
385690286Sobrien  [(set_attr "type" "imovx")
385790286Sobrien   (set_attr "mode" "SI")
385890286Sobrien   (set (attr "prefix_0f")
385990286Sobrien     ;; movsx is short decodable while cwtl is vector decoded.
386090286Sobrien     (if_then_else (and (eq_attr "cpu" "!k6")
386190286Sobrien			(eq_attr "alternative" "0"))
386290286Sobrien	(const_string "0")
386390286Sobrien	(const_string "1")))
386490286Sobrien   (set (attr "modrm")
386590286Sobrien     (if_then_else (eq_attr "prefix_0f" "0")
386690286Sobrien	(const_string "0")
386790286Sobrien	(const_string "1")))])
386818334Speter
386990286Sobrien(define_insn "*extendhisi2_zext"
387090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=*a,r")
387190286Sobrien	(zero_extend:DI
387290286Sobrien	  (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
387390286Sobrien  "TARGET_64BIT"
387490286Sobrien{
387590286Sobrien  switch (get_attr_prefix_0f (insn))
387690286Sobrien    {
387790286Sobrien    case 0:
387890286Sobrien      return "{cwtl|cwde}";
387990286Sobrien    default:
388090286Sobrien      return "movs{wl|x}\t{%1,%k0|%k0, %1}";
388190286Sobrien    }
388290286Sobrien}
388390286Sobrien  [(set_attr "type" "imovx")
388490286Sobrien   (set_attr "mode" "SI")
388590286Sobrien   (set (attr "prefix_0f")
388690286Sobrien     ;; movsx is short decodable while cwtl is vector decoded.
388790286Sobrien     (if_then_else (and (eq_attr "cpu" "!k6")
388890286Sobrien			(eq_attr "alternative" "0"))
388990286Sobrien	(const_string "0")
389090286Sobrien	(const_string "1")))
389190286Sobrien   (set (attr "modrm")
389290286Sobrien     (if_then_else (eq_attr "prefix_0f" "0")
389390286Sobrien	(const_string "0")
389490286Sobrien	(const_string "1")))])
389518334Speter
389618334Speter(define_insn "extendqihi2"
389790286Sobrien  [(set (match_operand:HI 0 "register_operand" "=*a,r")
389890286Sobrien	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
389918334Speter  ""
390018334Speter{
390190286Sobrien  switch (get_attr_prefix_0f (insn))
390290286Sobrien    {
390390286Sobrien    case 0:
390490286Sobrien      return "{cbtw|cbw}";
390590286Sobrien    default:
390690286Sobrien      return "movs{bw|x}\t{%1,%0|%0, %1}";
390790286Sobrien    }
390890286Sobrien}
390990286Sobrien  [(set_attr "type" "imovx")
391090286Sobrien   (set_attr "mode" "HI")
391190286Sobrien   (set (attr "prefix_0f")
391290286Sobrien     ;; movsx is short decodable while cwtl is vector decoded.
391390286Sobrien     (if_then_else (and (eq_attr "cpu" "!k6")
391490286Sobrien			(eq_attr "alternative" "0"))
391590286Sobrien	(const_string "0")
391690286Sobrien	(const_string "1")))
391790286Sobrien   (set (attr "modrm")
391890286Sobrien     (if_then_else (eq_attr "prefix_0f" "0")
391990286Sobrien	(const_string "0")
392090286Sobrien	(const_string "1")))])
392118334Speter
392218334Speter(define_insn "extendqisi2"
392350650Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
392450650Sobrien	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
392518334Speter  ""
392690286Sobrien  "movs{bl|x}\t{%1,%0|%0, %1}"
392790286Sobrien   [(set_attr "type" "imovx")
392890286Sobrien    (set_attr "mode" "SI")])
392950650Sobrien
393090286Sobrien(define_insn "*extendqisi2_zext"
393190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
393290286Sobrien	(zero_extend:DI
393390286Sobrien	  (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
393490286Sobrien  "TARGET_64BIT"
393590286Sobrien  "movs{bl|x}\t{%1,%k0|%k0, %1}"
393690286Sobrien   [(set_attr "type" "imovx")
393790286Sobrien    (set_attr "mode" "SI")])
393818334Speter
393990286Sobrien;; Conversions between float and double.
394050650Sobrien
394190286Sobrien;; These are all no-ops in the model used for the 80387.  So just
394290286Sobrien;; emit moves.
394350650Sobrien
394490286Sobrien;; %%% Kill these when call knows how to work out a DFmode push earlier. 
394590286Sobrien(define_insn "*dummy_extendsfdf2"
394690286Sobrien  [(set (match_operand:DF 0 "push_operand" "=<")
394790286Sobrien	(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
394890286Sobrien  "0"
394990286Sobrien  "#")
395050650Sobrien
395190286Sobrien(define_split
395290286Sobrien  [(set (match_operand:DF 0 "push_operand" "")
395390286Sobrien	(float_extend:DF (match_operand:SF 1 "register_operand" "")))]
395490286Sobrien  "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
395590286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
395690286Sobrien   (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
395750650Sobrien
395890286Sobrien(define_split
395990286Sobrien  [(set (match_operand:DF 0 "push_operand" "")
396090286Sobrien	(float_extend:DF (match_operand:SF 1 "register_operand" "")))]
396190286Sobrien  "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
396290286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
396390286Sobrien   (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
396450650Sobrien
396590286Sobrien(define_insn "*dummy_extendsfxf2"
396690286Sobrien  [(set (match_operand:XF 0 "push_operand" "=<")
396790286Sobrien	(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
396890286Sobrien  "0"
396990286Sobrien  "#")
397050650Sobrien
397190286Sobrien(define_split
397290286Sobrien  [(set (match_operand:XF 0 "push_operand" "")
397390286Sobrien	(float_extend:XF (match_operand:SF 1 "register_operand" "")))]
397490286Sobrien  "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
397590286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
397690286Sobrien   (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
397750650Sobrien
397890286Sobrien(define_insn "*dummy_extendsftf2"
397990286Sobrien  [(set (match_operand:TF 0 "push_operand" "=<")
398090286Sobrien	(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
398190286Sobrien  "0"
398290286Sobrien  "#")
398350650Sobrien
398490286Sobrien(define_split
398590286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
398690286Sobrien	(float_extend:TF (match_operand:SF 1 "register_operand" "")))]
398790286Sobrien  "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
398890286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
398990286Sobrien   (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
399050650Sobrien
399190286Sobrien(define_split
399290286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
399390286Sobrien	(float_extend:TF (match_operand:SF 1 "register_operand" "")))]
399490286Sobrien  "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
399590286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
399690286Sobrien   (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
399718334Speter
399890286Sobrien(define_insn "*dummy_extenddfxf2"
399990286Sobrien  [(set (match_operand:XF 0 "push_operand" "=<")
400090286Sobrien	(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
400190286Sobrien  "0"
400290286Sobrien  "#")
400352296Sobrien
400490286Sobrien(define_split
400590286Sobrien  [(set (match_operand:XF 0 "push_operand" "")
400690286Sobrien	(float_extend:XF (match_operand:DF 1 "register_operand" "")))]
400790286Sobrien  "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
400890286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
400990286Sobrien   (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
401052296Sobrien
401190286Sobrien(define_insn "*dummy_extenddftf2"
401290286Sobrien  [(set (match_operand:TF 0 "push_operand" "=<")
401390286Sobrien	(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
401490286Sobrien  "0"
401590286Sobrien  "#")
401618334Speter
401752296Sobrien(define_split
401890286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
401990286Sobrien	(float_extend:TF (match_operand:DF 1 "register_operand" "")))]
402090286Sobrien  "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
402190286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
402290286Sobrien   (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
402318334Speter
402452296Sobrien(define_split
402590286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
402690286Sobrien	(float_extend:TF (match_operand:DF 1 "register_operand" "")))]
402790286Sobrien  "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
402890286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
402990286Sobrien   (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
403018334Speter
403190286Sobrien(define_expand "extendsfdf2"
403252296Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "")
403390286Sobrien        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
403490286Sobrien  "TARGET_80387 || TARGET_SSE2"
403552296Sobrien{
403690286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
403790286Sobrien    operands[1] = force_reg (SFmode, operands[1]);
403890286Sobrien})
403918334Speter
404090286Sobrien(define_insn "*extendsfdf2_1"
404190286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
404290286Sobrien        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
404390286Sobrien  "(TARGET_80387 || TARGET_SSE2)
404490286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
404552296Sobrien{
404690286Sobrien  switch (which_alternative)
404790286Sobrien    {
404890286Sobrien    case 0:
404990286Sobrien      if (REG_P (operands[1])
405090286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
405190286Sobrien        return "fstp\t%y0";
405290286Sobrien      else if (STACK_TOP_P (operands[0]))
405390286Sobrien        return "fld%z1\t%y1";
405490286Sobrien      else
405590286Sobrien        return "fst\t%y0";
405652296Sobrien
405790286Sobrien    case 1:
405890286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
405990286Sobrien        return "fstp%z0\t%y0";
406018334Speter
406190286Sobrien      else
406290286Sobrien        return "fst%z0\t%y0";
406390286Sobrien    case 2:
406490286Sobrien      return "cvtss2sd\t{%1, %0|%0, %1}";
406518334Speter
406690286Sobrien    default:
406790286Sobrien      abort ();
406890286Sobrien    }
406990286Sobrien}
407090286Sobrien  [(set_attr "type" "fmov,fmov,sse")
407190286Sobrien   (set_attr "mode" "SF,XF,DF")])
407218334Speter
407390286Sobrien(define_insn "*extendsfdf2_1_sse_only"
407490286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
407590286Sobrien        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
407690286Sobrien  "!TARGET_80387 && TARGET_SSE2
407790286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
407890286Sobrien  "cvtss2sd\t{%1, %0|%0, %1}"
407990286Sobrien  [(set_attr "type" "sse")
408090286Sobrien   (set_attr "mode" "DF")])
408118334Speter
408290286Sobrien(define_expand "extendsfxf2"
408352296Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "")
408490286Sobrien        (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))]
408590286Sobrien  "!TARGET_64BIT && TARGET_80387"
408690286Sobrien{
408790286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
408890286Sobrien    operands[1] = force_reg (SFmode, operands[1]);
408990286Sobrien})
409018334Speter
409190286Sobrien(define_insn "*extendsfxf2_1"
409252296Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
409390286Sobrien        (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
409490286Sobrien  "!TARGET_64BIT && TARGET_80387
409590286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
409652296Sobrien{
409790286Sobrien  switch (which_alternative)
409890286Sobrien    {
409990286Sobrien    case 0:
410090286Sobrien      if (REG_P (operands[1])
410190286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
410290286Sobrien        return "fstp\t%y0";
410390286Sobrien      else if (STACK_TOP_P (operands[0]))
410490286Sobrien        return "fld%z1\t%y1";
410590286Sobrien      else
410690286Sobrien        return "fst\t%y0";
410718334Speter
410890286Sobrien    case 1:
410990286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
411090286Sobrien	 we need one, follow the store with a load.  */
411190286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
411290286Sobrien        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
411390286Sobrien      else
411490286Sobrien        return "fstp%z0\t%y0";
411590286Sobrien
411690286Sobrien    default:
411790286Sobrien      abort ();
411890286Sobrien    }
411990286Sobrien}
412090286Sobrien  [(set_attr "type" "fmov")
412190286Sobrien   (set_attr "mode" "SF,XF")])
412290286Sobrien
412390286Sobrien(define_expand "extendsftf2"
412490286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "")
412590286Sobrien        (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))]
412652296Sobrien  "TARGET_80387"
412752296Sobrien{
412852296Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
412952296Sobrien    operands[1] = force_reg (SFmode, operands[1]);
413090286Sobrien})
413152296Sobrien
413290286Sobrien(define_insn "*extendsftf2_1"
413390286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
413490286Sobrien        (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
413590286Sobrien  "TARGET_80387
413690286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
413718334Speter{
413890286Sobrien  switch (which_alternative)
413990286Sobrien    {
414090286Sobrien    case 0:
414190286Sobrien      if (REG_P (operands[1])
414290286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
414390286Sobrien        return "fstp\t%y0";
414490286Sobrien      else if (STACK_TOP_P (operands[0]))
414590286Sobrien        return "fld%z1\t%y1";
414690286Sobrien      else
414790286Sobrien        return "fst\t%y0";
414818334Speter
414990286Sobrien    case 1:
415090286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
415190286Sobrien	 we need one, follow the store with a load.  */
415290286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
415390286Sobrien        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
415490286Sobrien      else
415590286Sobrien        return "fstp%z0\t%y0";
415618334Speter
415790286Sobrien    default:
415890286Sobrien      abort ();
415990286Sobrien    }
416090286Sobrien}
416190286Sobrien  [(set_attr "type" "fmov")
416290286Sobrien   (set_attr "mode" "SF,XF")])
416318334Speter
416490286Sobrien(define_expand "extenddfxf2"
416552296Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "")
416690286Sobrien        (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))]
416790286Sobrien  "!TARGET_64BIT && TARGET_80387"
416890286Sobrien{
416990286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
417090286Sobrien    operands[1] = force_reg (DFmode, operands[1]);
417190286Sobrien})
417218334Speter
417390286Sobrien(define_insn "*extenddfxf2_1"
417452296Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
417590286Sobrien        (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
417690286Sobrien  "!TARGET_64BIT && TARGET_80387
417790286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
417852296Sobrien{
417990286Sobrien  switch (which_alternative)
418090286Sobrien    {
418190286Sobrien    case 0:
418290286Sobrien      if (REG_P (operands[1])
418390286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
418490286Sobrien        return "fstp\t%y0";
418590286Sobrien      else if (STACK_TOP_P (operands[0]))
418690286Sobrien        return "fld%z1\t%y1";
418790286Sobrien      else
418890286Sobrien        return "fst\t%y0";
418918334Speter
419090286Sobrien    case 1:
419190286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
419290286Sobrien	 we need one, follow the store with a load.  */
419390286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
419490286Sobrien        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
419590286Sobrien      else
419690286Sobrien        return "fstp%z0\t%y0";
419790286Sobrien
419890286Sobrien    default:
419990286Sobrien      abort ();
420090286Sobrien    }
420190286Sobrien}
420290286Sobrien  [(set_attr "type" "fmov")
420390286Sobrien   (set_attr "mode" "DF,XF")])
420490286Sobrien
420590286Sobrien(define_expand "extenddftf2"
420690286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "")
420790286Sobrien        (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))]
420890286Sobrien  "TARGET_80387"
420990286Sobrien{
421090286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
421190286Sobrien    operands[1] = force_reg (DFmode, operands[1]);
421290286Sobrien})
421390286Sobrien
421490286Sobrien(define_insn "*extenddftf2_1"
421590286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
421690286Sobrien        (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
421790286Sobrien  "TARGET_80387
421890286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
421990286Sobrien{
422090286Sobrien  switch (which_alternative)
422190286Sobrien    {
422290286Sobrien    case 0:
422390286Sobrien      if (REG_P (operands[1])
422490286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
422590286Sobrien        return "fstp\t%y0";
422690286Sobrien      else if (STACK_TOP_P (operands[0]))
422790286Sobrien        return "fld%z1\t%y1";
422890286Sobrien      else
422990286Sobrien        return "fst\t%y0";
423090286Sobrien
423190286Sobrien    case 1:
423290286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
423390286Sobrien	 we need one, follow the store with a load.  */
423490286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
423590286Sobrien        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
423690286Sobrien      else
423790286Sobrien        return "fstp%z0\t%y0";
423890286Sobrien
423990286Sobrien    default:
424090286Sobrien      abort ();
424190286Sobrien    }
424290286Sobrien}
424390286Sobrien  [(set_attr "type" "fmov")
424490286Sobrien   (set_attr "mode" "DF,XF")])
424590286Sobrien
424690286Sobrien;; %%% This seems bad bad news.
424790286Sobrien;; This cannot output into an f-reg because there is no way to be sure
424890286Sobrien;; of truncating in that case.  Otherwise this is just like a simple move
424990286Sobrien;; insn.  So we pretend we can output to a reg in order to get better
425090286Sobrien;; register preferencing, but we really use a stack slot.
425190286Sobrien
425218334Speter(define_expand "truncdfsf2"
425318334Speter  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
425418334Speter		   (float_truncate:SF
425518334Speter		    (match_operand:DF 1 "register_operand" "")))
425618334Speter	      (clobber (match_dup 2))])]
425790286Sobrien  "TARGET_80387 || TARGET_SSE2"
425818334Speter  "
425990286Sobrien   if (TARGET_80387)
426090286Sobrien     operands[2] = assign_386_stack_local (SFmode, 0);
426190286Sobrien   else
426290286Sobrien     {
426390286Sobrien	emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
426490286Sobrien	DONE;
426590286Sobrien     }
426690286Sobrien")
426790286Sobrien
426890286Sobrien(define_insn "*truncdfsf2_1"
426990286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
427090286Sobrien	(float_truncate:SF
427190286Sobrien	 (match_operand:DF 1 "register_operand" "f,f,f,f")))
427290286Sobrien   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
427390286Sobrien  "TARGET_80387 && !TARGET_SSE2"
427418334Speter{
427590286Sobrien  switch (which_alternative)
427690286Sobrien    {
427790286Sobrien    case 0:
427890286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
427990286Sobrien	return "fstp%z0\t%y0";
428090286Sobrien      else
428190286Sobrien	return "fst%z0\t%y0";
428290286Sobrien    default:
428390286Sobrien      abort ();
428490286Sobrien    }
428590286Sobrien}
428690286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
428790286Sobrien   (set_attr "mode" "SF,SF,SF,SF")])
428818334Speter
428990286Sobrien(define_insn "*truncdfsf2_1_sse"
429090286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,Y")
429118334Speter	(float_truncate:SF
429290286Sobrien	 (match_operand:DF 1 "nonimmediate_operand" "f,f,f,f,mY")))
429390286Sobrien   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
429490286Sobrien  "TARGET_80387 && TARGET_SSE2"
429518334Speter{
429690286Sobrien  switch (which_alternative)
429790286Sobrien    {
429890286Sobrien    case 0:
429990286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
430090286Sobrien	return "fstp%z0\t%y0";
430190286Sobrien      else
430290286Sobrien	return "fst%z0\t%y0";
430390286Sobrien    case 4:
430490286Sobrien      return "cvtsd2ss\t{%1, %0|%0, %1}";
430590286Sobrien    default:
430690286Sobrien      abort ();
430790286Sobrien    }
430890286Sobrien}
430990286Sobrien  [(set_attr "type" "fmov,multi,multi,multi,sse")
431090286Sobrien   (set_attr "mode" "SF,SF,SF,SF,DF")])
431118334Speter
431290286Sobrien(define_insn "*truncdfsf2_2"
431390286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,!m")
431490286Sobrien	(float_truncate:SF
431590286Sobrien	 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
431690286Sobrien  "TARGET_80387 && TARGET_SSE2
431790286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
431890286Sobrien{
431990286Sobrien  switch (which_alternative)
432090286Sobrien    {
432190286Sobrien    case 0:
432290286Sobrien      return "cvtsd2ss\t{%1, %0|%0, %1}";
432390286Sobrien    case 1:
432490286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
432590286Sobrien	return "fstp%z0\t%y0";
432690286Sobrien      else
432790286Sobrien	return "fst%z0\t%y0";
432890286Sobrien    default:
432990286Sobrien      abort ();
433090286Sobrien    }
433190286Sobrien}
433290286Sobrien  [(set_attr "type" "sse,fmov")
433390286Sobrien   (set_attr "mode" "DF,SF")])
433452296Sobrien
433590286Sobrien(define_insn "truncdfsf2_3"
433690286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
433790286Sobrien	(float_truncate:SF
433890286Sobrien	 (match_operand:DF 1 "register_operand" "f")))]
433990286Sobrien  "TARGET_80387"
434090286Sobrien{
434190286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
434290286Sobrien    return "fstp%z0\t%y0";
434318334Speter  else
434490286Sobrien    return "fst%z0\t%y0";
434590286Sobrien}
434690286Sobrien  [(set_attr "type" "fmov")
434790286Sobrien   (set_attr "mode" "SF")])
434818334Speter
434990286Sobrien(define_insn "truncdfsf2_sse_only"
435090286Sobrien  [(set (match_operand:SF 0 "register_operand" "=Y")
435190286Sobrien	(float_truncate:SF
435290286Sobrien	 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
435390286Sobrien  "!TARGET_80387 && TARGET_SSE2"
435490286Sobrien  "cvtsd2ss\t{%1, %0|%0, %1}"
435590286Sobrien  [(set_attr "type" "sse")
435690286Sobrien   (set_attr "mode" "DF")])
435752296Sobrien
435852296Sobrien(define_split
435990286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
436090286Sobrien	(float_truncate:SF
436190286Sobrien	 (match_operand:DF 1 "register_operand" "")))
436252296Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
436390286Sobrien  "TARGET_80387"
436490286Sobrien  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
436552296Sobrien  "")
436652296Sobrien
436752296Sobrien(define_split
436890286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "")
436990286Sobrien	(float_truncate:SF
437090286Sobrien	 (match_operand:DF 1 "nonimmediate_operand" "")))
437190286Sobrien   (clobber (match_operand 2 "" ""))]
437290286Sobrien  "TARGET_80387 && reload_completed
437390286Sobrien   && !FP_REG_P (operands[0]) && !FP_REG_P (operands[1])"
437490286Sobrien  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
437590286Sobrien  "")
437690286Sobrien
437790286Sobrien(define_split
437890286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
437990286Sobrien	(float_truncate:SF
438090286Sobrien	 (match_operand:DF 1 "register_operand" "")))
438152296Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
438290286Sobrien  "TARGET_80387 && reload_completed
438390286Sobrien   && FP_REG_P (operands[1])"
438490286Sobrien  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
438590286Sobrien   (set (match_dup 0) (match_dup 2))]
438652296Sobrien  "")
438752296Sobrien
438890286Sobrien(define_expand "truncxfsf2"
438990286Sobrien  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
439090286Sobrien		   (float_truncate:SF
439190286Sobrien		    (match_operand:XF 1 "register_operand" "")))
439290286Sobrien	      (clobber (match_dup 2))])]
439390286Sobrien  "!TARGET_64BIT && TARGET_80387"
439490286Sobrien  "operands[2] = assign_386_stack_local (SFmode, 0);")
439552296Sobrien
439690286Sobrien(define_insn "*truncxfsf2_1"
439790286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
439890286Sobrien	(float_truncate:SF
439990286Sobrien	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
440090286Sobrien   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
440190286Sobrien  "!TARGET_64BIT && TARGET_80387"
440290286Sobrien{
440390286Sobrien  switch (which_alternative)
440490286Sobrien    {
440590286Sobrien    case 0:
440690286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
440790286Sobrien	return "fstp%z0\t%y0";
440890286Sobrien      else
440990286Sobrien	return "fst%z0\t%y0";
441090286Sobrien    default:
441190286Sobrien      abort();
441290286Sobrien    }
441390286Sobrien}
441490286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
441590286Sobrien   (set_attr "mode" "SF")])
441690286Sobrien
441790286Sobrien(define_insn "*truncxfsf2_2"
441852296Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
441990286Sobrien	(float_truncate:SF
442090286Sobrien	 (match_operand:XF 1 "register_operand" "f")))]
442190286Sobrien  "!TARGET_64BIT && TARGET_80387"
442218334Speter{
442390286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
442490286Sobrien    return "fstp%z0\t%y0";
442518334Speter  else
442690286Sobrien    return "fst%z0\t%y0";
442790286Sobrien}
442890286Sobrien  [(set_attr "type" "fmov")
442990286Sobrien   (set_attr "mode" "SF")])
443052296Sobrien
443190286Sobrien(define_split
443290286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
443390286Sobrien	(float_truncate:SF
443490286Sobrien	 (match_operand:XF 1 "register_operand" "")))
443590286Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
443690286Sobrien  "TARGET_80387"
443790286Sobrien  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
443890286Sobrien  "")
443990286Sobrien
444090286Sobrien(define_split
444190286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
444290286Sobrien	(float_truncate:SF
444390286Sobrien	 (match_operand:XF 1 "register_operand" "")))
444490286Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
444590286Sobrien  "TARGET_80387 && reload_completed"
444690286Sobrien  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
444790286Sobrien   (set (match_dup 0) (match_dup 2))]
444890286Sobrien  "")
444990286Sobrien
445090286Sobrien(define_expand "trunctfsf2"
445152296Sobrien  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
445252296Sobrien		   (float_truncate:SF
445390286Sobrien		    (match_operand:TF 1 "register_operand" "")))
445452296Sobrien	      (clobber (match_dup 2))])]
445552296Sobrien  "TARGET_80387"
445690286Sobrien  "operands[2] = assign_386_stack_local (SFmode, 0);")
445790286Sobrien
445890286Sobrien(define_insn "*trunctfsf2_1"
445990286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
446090286Sobrien	(float_truncate:SF
446190286Sobrien	 (match_operand:TF 1 "register_operand" "f,f,f,f")))
446290286Sobrien   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
446390286Sobrien  "TARGET_80387"
446452296Sobrien{
446590286Sobrien  switch (which_alternative)
446690286Sobrien    {
446790286Sobrien    case 0:
446890286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
446990286Sobrien	return "fstp%z0\t%y0";
447090286Sobrien      else
447190286Sobrien	return "fst%z0\t%y0";
447290286Sobrien    default:
447390286Sobrien      abort();
447490286Sobrien    }
447590286Sobrien}
447690286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
447790286Sobrien   (set_attr "mode" "SF")])
447818334Speter
447990286Sobrien(define_insn "*trunctfsf2_2"
448090286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
448152296Sobrien	(float_truncate:SF
448290286Sobrien	 (match_operand:TF 1 "register_operand" "f")))]
448318334Speter  "TARGET_80387"
448418334Speter{
448590286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
448690286Sobrien    return "fstp%z0\t%y0";
448718334Speter  else
448890286Sobrien    return "fst%z0\t%y0";
448990286Sobrien}
449090286Sobrien  [(set_attr "type" "fmov")
449190286Sobrien   (set_attr "mode" "SF")])
449218334Speter
449352296Sobrien(define_split
449490286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
449590286Sobrien	(float_truncate:SF
449690286Sobrien	 (match_operand:TF 1 "register_operand" "")))
449752296Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
449890286Sobrien  "TARGET_80387"
449990286Sobrien  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
450052296Sobrien  "")
450152296Sobrien
450252296Sobrien(define_split
450390286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
450490286Sobrien	(float_truncate:SF
450590286Sobrien	 (match_operand:TF 1 "register_operand" "")))
450652296Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
450752296Sobrien  "TARGET_80387 && reload_completed"
450890286Sobrien  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
450990286Sobrien   (set (match_dup 0) (match_dup 2))]
451052296Sobrien  "")
451152296Sobrien
451218334Speter
451352296Sobrien(define_expand "truncxfdf2"
451452296Sobrien  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
451552296Sobrien		   (float_truncate:DF
451652296Sobrien		    (match_operand:XF 1 "register_operand" "")))
451752296Sobrien	      (clobber (match_dup 2))])]
451890286Sobrien  "!TARGET_64BIT && TARGET_80387"
451990286Sobrien  "operands[2] = assign_386_stack_local (DFmode, 0);")
452018334Speter
452190286Sobrien(define_insn "*truncxfdf2_1"
452290286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
452352296Sobrien	(float_truncate:DF
452490286Sobrien	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
452590286Sobrien   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
452690286Sobrien  "!TARGET_64BIT && TARGET_80387"
452718334Speter{
452890286Sobrien  switch (which_alternative)
452952296Sobrien    {
453090286Sobrien    case 0:
453190286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
453290286Sobrien	return "fstp%z0\t%y0";
453390286Sobrien      else
453490286Sobrien	return "fst%z0\t%y0";
453590286Sobrien    default:
453690286Sobrien      abort();
453752296Sobrien    }
453890286Sobrien  abort ();
453990286Sobrien}
454090286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
454190286Sobrien   (set_attr "mode" "DF")])
454252296Sobrien
454390286Sobrien(define_insn "*truncxfdf2_2"
454490286Sobrien  [(set (match_operand:DF 0 "memory_operand" "=m")
454590286Sobrien	(float_truncate:DF
454690286Sobrien	  (match_operand:XF 1 "register_operand" "f")))]
454790286Sobrien  "!TARGET_64BIT && TARGET_80387"
454890286Sobrien{
454990286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
455090286Sobrien    return "fstp%z0\t%y0";
455190286Sobrien  else
455290286Sobrien    return "fst%z0\t%y0";
455390286Sobrien}
455490286Sobrien  [(set_attr "type" "fmov")
455590286Sobrien   (set_attr "mode" "DF")])
455652296Sobrien
455752296Sobrien(define_split
455890286Sobrien  [(set (match_operand:DF 0 "memory_operand" "")
455990286Sobrien	(float_truncate:DF
456090286Sobrien	 (match_operand:XF 1 "register_operand" "")))
456152296Sobrien   (clobber (match_operand:DF 2 "memory_operand" ""))]
456290286Sobrien  "TARGET_80387"
456390286Sobrien  [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
456452296Sobrien  "")
456552296Sobrien
456652296Sobrien(define_split
456790286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
456890286Sobrien	(float_truncate:DF
456990286Sobrien	 (match_operand:XF 1 "register_operand" "")))
457052296Sobrien   (clobber (match_operand:DF 2 "memory_operand" ""))]
457152296Sobrien  "TARGET_80387 && reload_completed"
457290286Sobrien  [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
457390286Sobrien   (set (match_dup 0) (match_dup 2))]
457452296Sobrien  "")
457552296Sobrien
457690286Sobrien(define_expand "trunctfdf2"
457790286Sobrien  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
457890286Sobrien		   (float_truncate:DF
457990286Sobrien		    (match_operand:TF 1 "register_operand" "")))
458090286Sobrien	      (clobber (match_dup 2))])]
458118334Speter  "TARGET_80387"
458290286Sobrien  "operands[2] = assign_386_stack_local (DFmode, 0);")
458318334Speter
458490286Sobrien(define_insn "*trunctfdf2_1"
458590286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
458690286Sobrien	(float_truncate:DF
458790286Sobrien	 (match_operand:TF 1 "register_operand" "f,f,f,f")))
458890286Sobrien   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
458918334Speter  "TARGET_80387"
459018334Speter{
459190286Sobrien  switch (which_alternative)
459290286Sobrien    {
459390286Sobrien    case 0:
459490286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
459590286Sobrien	return "fstp%z0\t%y0";
459690286Sobrien      else
459790286Sobrien	return "fst%z0\t%y0";
459890286Sobrien    default:
459990286Sobrien      abort();
460090286Sobrien    }
460190286Sobrien  abort ();
460290286Sobrien}
460390286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
460490286Sobrien   (set_attr "mode" "DF")])
460518334Speter
460690286Sobrien	(define_insn "*trunctfdf2_2"
460790286Sobrien  [(set (match_operand:DF 0 "memory_operand" "=m")
460890286Sobrien	(float_truncate:DF
460990286Sobrien	  (match_operand:TF 1 "register_operand" "f")))]
461052296Sobrien  "TARGET_80387"
461118334Speter{
461290286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
461390286Sobrien    return "fstp%z0\t%y0";
461490286Sobrien  else
461590286Sobrien    return "fst%z0\t%y0";
461690286Sobrien}
461790286Sobrien  [(set_attr "type" "fmov")
461890286Sobrien   (set_attr "mode" "DF")])
461918334Speter
462090286Sobrien(define_split
462190286Sobrien  [(set (match_operand:DF 0 "memory_operand" "")
462290286Sobrien	(float_truncate:DF
462390286Sobrien	 (match_operand:TF 1 "register_operand" "")))
462490286Sobrien   (clobber (match_operand:DF 2 "memory_operand" ""))]
462518334Speter  "TARGET_80387"
462690286Sobrien  [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
462790286Sobrien  "")
462818334Speter
462990286Sobrien(define_split
463090286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
463190286Sobrien	(float_truncate:DF
463290286Sobrien	 (match_operand:TF 1 "register_operand" "")))
463390286Sobrien   (clobber (match_operand:DF 2 "memory_operand" ""))]
463490286Sobrien  "TARGET_80387 && reload_completed"
463590286Sobrien  [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
463690286Sobrien   (set (match_dup 0) (match_dup 2))]
463790286Sobrien  "")
463818334Speter
463990286Sobrien
464090286Sobrien;; %%% Break up all these bad boys.
464190286Sobrien
464290286Sobrien;; Signed conversion to DImode.
464390286Sobrien
464490286Sobrien(define_expand "fix_truncxfdi2"
464590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
464690286Sobrien        (fix:DI (match_operand:XF 1 "register_operand" "")))]
464790286Sobrien  "!TARGET_64BIT && TARGET_80387"
464890286Sobrien  "")
464990286Sobrien
465090286Sobrien(define_expand "fix_trunctfdi2"
465190286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
465290286Sobrien	(fix:DI (match_operand:TF 1 "register_operand" "")))]
465318334Speter  "TARGET_80387"
465490286Sobrien  "")
465518334Speter
465652296Sobrien(define_expand "fix_truncdfdi2"
465790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
465890286Sobrien        (fix:DI (match_operand:DF 1 "register_operand" "")))]
465990286Sobrien  "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
466018334Speter{
466190286Sobrien  if (TARGET_64BIT && TARGET_SSE2)
466290286Sobrien   {
466390286Sobrien     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
466490286Sobrien     emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
466590286Sobrien     if (out != operands[0])
466690286Sobrien	emit_move_insn (operands[0], out);
466790286Sobrien     DONE;
466890286Sobrien   }
466990286Sobrien})
467018334Speter
467190286Sobrien(define_expand "fix_truncsfdi2"
467290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
467390286Sobrien	(fix:DI (match_operand:SF 1 "register_operand" "")))]
467490286Sobrien  "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
467590286Sobrien{
467690286Sobrien  if (TARGET_SSE && TARGET_64BIT)
467790286Sobrien   {
467890286Sobrien     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
467990286Sobrien     emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
468090286Sobrien     if (out != operands[0])
468190286Sobrien	emit_move_insn (operands[0], out);
468290286Sobrien     DONE;
468390286Sobrien   }
468490286Sobrien})
468552296Sobrien
468690286Sobrien;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
468790286Sobrien;; of the machinery.
468890286Sobrien(define_insn_and_split "*fix_truncdi_1"
468990286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
469090286Sobrien	(fix:DI (match_operand 1 "register_operand" "f,f")))]
469190286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
469290286Sobrien   && !reload_completed && !reload_in_progress
469390286Sobrien   && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
469490286Sobrien  "#"
469590286Sobrien  "&& 1"
469690286Sobrien  [(const_int 0)]
469790286Sobrien{
469890286Sobrien  operands[2] = assign_386_stack_local (HImode, 1);
469990286Sobrien  operands[3] = assign_386_stack_local (HImode, 2);
470090286Sobrien  if (memory_operand (operands[0], VOIDmode))
470190286Sobrien    emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
470290286Sobrien				       operands[2], operands[3]));
470390286Sobrien  else
470490286Sobrien    {
470590286Sobrien      operands[4] = assign_386_stack_local (DImode, 0);
470690286Sobrien      emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
470790286Sobrien					   operands[2], operands[3],
470890286Sobrien					   operands[4]));
470990286Sobrien    }
471090286Sobrien  DONE;
471190286Sobrien}
471290286Sobrien  [(set_attr "type" "fistp")])
471390286Sobrien
471490286Sobrien(define_insn "fix_truncdi_nomemory"
471590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
471690286Sobrien	(fix:DI (match_operand 1 "register_operand" "f,f")))
471790286Sobrien   (use (match_operand:HI 2 "memory_operand" "m,m"))
471890286Sobrien   (use (match_operand:HI 3 "memory_operand" "m,m"))
471990286Sobrien   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
472090286Sobrien   (clobber (match_scratch:DF 5 "=&1f,&1f"))]
472190286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
472290286Sobrien   && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
472390286Sobrien  "#"
472490286Sobrien  [(set_attr "type" "fistp")])
472590286Sobrien
472690286Sobrien(define_insn "fix_truncdi_memory"
472790286Sobrien  [(set (match_operand:DI 0 "memory_operand" "=m")
472890286Sobrien	(fix:DI (match_operand 1 "register_operand" "f")))
472990286Sobrien   (use (match_operand:HI 2 "memory_operand" "m"))
473090286Sobrien   (use (match_operand:HI 3 "memory_operand" "m"))
473190286Sobrien   (clobber (match_scratch:DF 4 "=&1f"))]
473290286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
473390286Sobrien   && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
473490286Sobrien  "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
473590286Sobrien  [(set_attr "type" "fistp")])
473690286Sobrien
473790286Sobrien(define_split 
473890286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
473990286Sobrien	(fix:DI (match_operand 1 "register_operand" "")))
474090286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
474190286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
474290286Sobrien   (clobber (match_operand:DI 4 "memory_operand" ""))
474390286Sobrien   (clobber (match_scratch 5 ""))]
474490286Sobrien  "reload_completed"
474590286Sobrien  [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
474690286Sobrien	      (use (match_dup 2))
474790286Sobrien	      (use (match_dup 3))
474890286Sobrien	      (clobber (match_dup 5))])
474990286Sobrien   (set (match_dup 0) (match_dup 4))]
475090286Sobrien  "")
475190286Sobrien
475290286Sobrien(define_split 
475390286Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
475490286Sobrien	(fix:DI (match_operand 1 "register_operand" "")))
475590286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
475690286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
475790286Sobrien   (clobber (match_operand:DI 4 "memory_operand" ""))
475890286Sobrien   (clobber (match_scratch 5 ""))]
475990286Sobrien  "reload_completed"
476090286Sobrien  [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
476190286Sobrien	      (use (match_dup 2))
476290286Sobrien	      (use (match_dup 3))
476390286Sobrien	      (clobber (match_dup 5))])]
476490286Sobrien  "")
476590286Sobrien
476690286Sobrien;; When SSE available, it is always faster to use it!
476790286Sobrien(define_insn "fix_truncsfdi_sse"
476890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
476990286Sobrien	(fix:DI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
477090286Sobrien  "TARGET_64BIT && TARGET_SSE"
477190286Sobrien  "cvttss2si{q}\t{%1, %0|%0, %1}"
477290286Sobrien  [(set_attr "type" "sse")])
477390286Sobrien
477490286Sobrien(define_insn "fix_truncdfdi_sse"
477590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
477690286Sobrien	(fix:DI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
477790286Sobrien  "TARGET_64BIT && TARGET_SSE2"
477890286Sobrien  "cvttsd2si{q}\t{%1, %0|%0, %1}"
477990286Sobrien  [(set_attr "type" "sse")])
478090286Sobrien
478190286Sobrien;; Signed conversion to SImode.
478290286Sobrien
478352296Sobrien(define_expand "fix_truncxfsi2"
478490286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
478590286Sobrien	(fix:SI (match_operand:XF 1 "register_operand" "")))]
478690286Sobrien  "!TARGET_64BIT && TARGET_80387"
478790286Sobrien  "")
478890286Sobrien
478990286Sobrien(define_expand "fix_trunctfsi2"
479090286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
479190286Sobrien	(fix:SI (match_operand:TF 1 "register_operand" "")))]
479218334Speter  "TARGET_80387"
479390286Sobrien  "")
479490286Sobrien
479590286Sobrien(define_expand "fix_truncdfsi2"
479690286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
479790286Sobrien	(fix:SI (match_operand:DF 1 "register_operand" "")))]
479890286Sobrien  "TARGET_80387 || TARGET_SSE2"
479918334Speter{
480090286Sobrien  if (TARGET_SSE2)
480190286Sobrien   {
480290286Sobrien     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
480390286Sobrien     emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
480490286Sobrien     if (out != operands[0])
480590286Sobrien	emit_move_insn (operands[0], out);
480690286Sobrien     DONE;
480790286Sobrien   }
480890286Sobrien})
480918334Speter
481090286Sobrien(define_expand "fix_truncsfsi2"
481190286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
481290286Sobrien	(fix:SI (match_operand:SF 1 "register_operand" "")))]
481390286Sobrien  "TARGET_80387 || TARGET_SSE"
481490286Sobrien{
481590286Sobrien  if (TARGET_SSE)
481690286Sobrien   {
481790286Sobrien     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
481890286Sobrien     emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
481990286Sobrien     if (out != operands[0])
482090286Sobrien	emit_move_insn (operands[0], out);
482190286Sobrien     DONE;
482290286Sobrien   }
482390286Sobrien})
482452296Sobrien
482590286Sobrien;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
482690286Sobrien;; of the machinery.
482790286Sobrien(define_insn_and_split "*fix_truncsi_1"
482890286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
482990286Sobrien	(fix:SI (match_operand 1 "register_operand" "f,f")))]
483090286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
483190286Sobrien   && !reload_completed && !reload_in_progress
483290286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
483390286Sobrien  "#"
483490286Sobrien  "&& 1"
483590286Sobrien  [(const_int 0)]
483618334Speter{
483790286Sobrien  operands[2] = assign_386_stack_local (HImode, 1);
483890286Sobrien  operands[3] = assign_386_stack_local (HImode, 2);
483990286Sobrien  if (memory_operand (operands[0], VOIDmode))
484090286Sobrien    emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
484190286Sobrien				       operands[2], operands[3]));
484290286Sobrien  else
484390286Sobrien    {
484490286Sobrien      operands[4] = assign_386_stack_local (SImode, 0);
484590286Sobrien      emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
484690286Sobrien					   operands[2], operands[3],
484790286Sobrien					   operands[4]));
484890286Sobrien    }
484990286Sobrien  DONE;
485090286Sobrien}
485190286Sobrien  [(set_attr "type" "fistp")])
485218334Speter
485390286Sobrien(define_insn "fix_truncsi_nomemory"
485490286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
485590286Sobrien	(fix:SI (match_operand 1 "register_operand" "f,f")))
485690286Sobrien   (use (match_operand:HI 2 "memory_operand" "m,m"))
485790286Sobrien   (use (match_operand:HI 3 "memory_operand" "m,m"))
485890286Sobrien   (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
485990286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
486090286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
486190286Sobrien  "#"
486290286Sobrien  [(set_attr "type" "fistp")])
486390286Sobrien
486490286Sobrien(define_insn "fix_truncsi_memory"
486590286Sobrien  [(set (match_operand:SI 0 "memory_operand" "=m")
486690286Sobrien	(fix:SI (match_operand 1 "register_operand" "f")))
486790286Sobrien   (use (match_operand:HI 2 "memory_operand" "m"))
486890286Sobrien   (use (match_operand:HI 3 "memory_operand" "m"))]
486990286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
487090286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
487152296Sobrien  "* return output_fix_trunc (insn, operands);"
487290286Sobrien  [(set_attr "type" "fistp")])
487318334Speter
487490286Sobrien;; When SSE available, it is always faster to use it!
487590286Sobrien(define_insn "fix_truncsfsi_sse"
487690286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
487790286Sobrien	(fix:SI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
487890286Sobrien  "TARGET_SSE"
487990286Sobrien  "cvttss2si\t{%1, %0|%0, %1}"
488090286Sobrien  [(set_attr "type" "sse")])
488152296Sobrien
488290286Sobrien(define_insn "fix_truncdfsi_sse"
488390286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
488490286Sobrien	(fix:SI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
488590286Sobrien  "TARGET_SSE2"
488690286Sobrien  "cvttsd2si\t{%1, %0|%0, %1}"
488790286Sobrien  [(set_attr "type" "sse")])
488852296Sobrien
488990286Sobrien(define_split 
489090286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
489190286Sobrien	(fix:SI (match_operand 1 "register_operand" "")))
489290286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
489390286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
489490286Sobrien   (clobber (match_operand:SI 4 "memory_operand" ""))]
489590286Sobrien  "reload_completed"
489690286Sobrien  [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
489790286Sobrien	      (use (match_dup 2))
489890286Sobrien	      (use (match_dup 3))])
489990286Sobrien   (set (match_dup 0) (match_dup 4))]
490090286Sobrien  "")
490118334Speter
490290286Sobrien(define_split 
490390286Sobrien  [(set (match_operand:SI 0 "memory_operand" "")
490490286Sobrien	(fix:SI (match_operand 1 "register_operand" "")))
490590286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
490690286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
490790286Sobrien   (clobber (match_operand:SI 4 "memory_operand" ""))]
490890286Sobrien  "reload_completed"
490990286Sobrien  [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
491090286Sobrien	      (use (match_dup 2))
491190286Sobrien	      (use (match_dup 3))])]
491252296Sobrien  "")
491352296Sobrien
491490286Sobrien;; Signed conversion to HImode.
491590286Sobrien
491690286Sobrien(define_expand "fix_truncxfhi2"
491790286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
491890286Sobrien        (fix:HI (match_operand:XF 1 "register_operand" "")))]
491990286Sobrien  "!TARGET_64BIT && TARGET_80387"
492052296Sobrien  "")
492152296Sobrien
492290286Sobrien(define_expand "fix_trunctfhi2"
492390286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
492490286Sobrien	(fix:HI (match_operand:TF 1 "register_operand" "")))]
492518334Speter  "TARGET_80387"
492690286Sobrien  "")
492718334Speter
492890286Sobrien(define_expand "fix_truncdfhi2"
492990286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
493090286Sobrien	(fix:HI (match_operand:DF 1 "register_operand" "")))]
493190286Sobrien  "TARGET_80387 && !TARGET_SSE2"
493290286Sobrien  "")
493318334Speter
493490286Sobrien(define_expand "fix_truncsfhi2"
493590286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
493690286Sobrien	(fix:HI (match_operand:SF 1 "register_operand" "")))]
493790286Sobrien  "TARGET_80387 && !TARGET_SSE"
493890286Sobrien  "")
493952296Sobrien
494090286Sobrien;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
494190286Sobrien;; of the machinery.
494290286Sobrien(define_insn_and_split "*fix_trunchi_1"
494390286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
494490286Sobrien	(fix:HI (match_operand 1 "register_operand" "f,f")))]
494590286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
494690286Sobrien   && !reload_completed && !reload_in_progress
494790286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
494890286Sobrien  "#"
494990286Sobrien  ""
495090286Sobrien  [(const_int 0)]
495190286Sobrien{
495290286Sobrien  operands[2] = assign_386_stack_local (HImode, 1);
495390286Sobrien  operands[3] = assign_386_stack_local (HImode, 2);
495490286Sobrien  if (memory_operand (operands[0], VOIDmode))
495590286Sobrien    emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
495690286Sobrien				       operands[2], operands[3]));
495790286Sobrien  else
495890286Sobrien    {
495990286Sobrien      operands[4] = assign_386_stack_local (HImode, 0);
496090286Sobrien      emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
496190286Sobrien					   operands[2], operands[3],
496290286Sobrien					   operands[4]));
496390286Sobrien    }
496490286Sobrien  DONE;
496590286Sobrien}
496690286Sobrien  [(set_attr "type" "fistp")])
496790286Sobrien
496890286Sobrien(define_insn "fix_trunchi_nomemory"
496990286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
497090286Sobrien	(fix:HI (match_operand 1 "register_operand" "f,f")))
497190286Sobrien   (use (match_operand:HI 2 "memory_operand" "m,m"))
497290286Sobrien   (use (match_operand:HI 3 "memory_operand" "m,m"))
497390286Sobrien   (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
497490286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
497590286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
497690286Sobrien  "#"
497790286Sobrien  [(set_attr "type" "fistp")])
497890286Sobrien
497990286Sobrien(define_insn "fix_trunchi_memory"
498090286Sobrien  [(set (match_operand:HI 0 "memory_operand" "=m")
498190286Sobrien	(fix:HI (match_operand 1 "register_operand" "f")))
498290286Sobrien   (use (match_operand:HI 2 "memory_operand" "m"))
498390286Sobrien   (use (match_operand:HI 3 "memory_operand" "m"))]
498490286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
498590286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
498690286Sobrien  "* return output_fix_trunc (insn, operands);"
498790286Sobrien  [(set_attr "type" "fistp")])
498890286Sobrien
498990286Sobrien(define_split 
499090286Sobrien  [(set (match_operand:HI 0 "memory_operand" "")
499190286Sobrien	(fix:HI (match_operand 1 "register_operand" "")))
499290286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
499390286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
499490286Sobrien   (clobber (match_operand:HI 4 "memory_operand" ""))]
499590286Sobrien  "reload_completed"
499690286Sobrien  [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
499790286Sobrien	      (use (match_dup 2))
499890286Sobrien	      (use (match_dup 3))])]
499918334Speter  "")
500018334Speter
500190286Sobrien(define_split 
500290286Sobrien  [(set (match_operand:HI 0 "register_operand" "")
500390286Sobrien	(fix:HI (match_operand 1 "register_operand" "")))
500490286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
500590286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
500690286Sobrien   (clobber (match_operand:HI 4 "memory_operand" ""))]
500790286Sobrien  "reload_completed"
500890286Sobrien  [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
500990286Sobrien	      (use (match_dup 2))
501090286Sobrien	      (use (match_dup 3))
501190286Sobrien	      (clobber (match_dup 4))])
501290286Sobrien   (set (match_dup 0) (match_dup 4))]
501352296Sobrien  "")
501452296Sobrien
501590286Sobrien;; %% Not used yet.
501690286Sobrien(define_insn "x86_fnstcw_1"
501790286Sobrien  [(set (match_operand:HI 0 "memory_operand" "=m")
501890286Sobrien	(unspec:HI [(reg:HI 18)] 11))]
501952296Sobrien  "TARGET_80387"
502090286Sobrien  "fnstcw\t%0"
502190286Sobrien  [(set_attr "length" "2")
502290286Sobrien   (set_attr "mode" "HI")
502390286Sobrien   (set_attr "i387" "1")
502490286Sobrien   (set_attr "ppro_uops" "few")])
502552296Sobrien
502690286Sobrien(define_insn "x86_fldcw_1"
502790286Sobrien  [(set (reg:HI 18)
502890286Sobrien	(unspec:HI [(match_operand:HI 0 "memory_operand" "m")] 12))]
502952296Sobrien  "TARGET_80387"
503090286Sobrien  "fldcw\t%0"
503190286Sobrien  [(set_attr "length" "2")
503290286Sobrien   (set_attr "mode" "HI")
503390286Sobrien   (set_attr "i387" "1")
503490286Sobrien   (set_attr "athlon_decode" "vector")
503590286Sobrien   (set_attr "ppro_uops" "few")])
503690286Sobrien
503790286Sobrien;; Conversion between fixed point and floating point.
503852296Sobrien
503990286Sobrien;; Even though we only accept memory inputs, the backend _really_
504090286Sobrien;; wants to be able to do this between registers.
504190286Sobrien
504290286Sobrien(define_insn "floathisf2"
504352296Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
504490286Sobrien	(float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
504590286Sobrien  "TARGET_80387 && !TARGET_SSE"
504690286Sobrien  "@
504790286Sobrien   fild%z1\t%1
504890286Sobrien   #"
504990286Sobrien  [(set_attr "type" "fmov,multi")
505090286Sobrien   (set_attr "mode" "SF")
505190286Sobrien   (set_attr "fp_int_src" "true")])
505252296Sobrien
505390286Sobrien(define_expand "floatsisf2"
505418334Speter  [(set (match_operand:SF 0 "register_operand" "")
505590286Sobrien	(float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
505690286Sobrien  "TARGET_SSE || TARGET_80387"
505718334Speter  "")
505818334Speter
505990286Sobrien(define_insn "*floatsisf2_i387"
506090286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
506190286Sobrien	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
506290286Sobrien  "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
506390286Sobrien  "@
506490286Sobrien   fild%z1\t%1
506590286Sobrien   #
506690286Sobrien   cvtsi2ss\t{%1, %0|%0, %1}"
506790286Sobrien  [(set_attr "type" "fmov,multi,sse")
506890286Sobrien   (set_attr "mode" "SF")
506990286Sobrien   (set_attr "fp_int_src" "true")])
507090286Sobrien
507190286Sobrien(define_insn "*floatsisf2_sse"
507290286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
507390286Sobrien	(float:SF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
507490286Sobrien  "TARGET_SSE"
507590286Sobrien  "cvtsi2ss\t{%1, %0|%0, %1}"
507690286Sobrien  [(set_attr "type" "sse")
507790286Sobrien   (set_attr "mode" "SF")
507890286Sobrien   (set_attr "fp_int_src" "true")])
507990286Sobrien
508090286Sobrien(define_expand "floatdisf2"
508152296Sobrien  [(set (match_operand:SF 0 "register_operand" "")
508290286Sobrien	(float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
508390286Sobrien  "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
508452296Sobrien  "")
508552296Sobrien
508690286Sobrien(define_insn "*floatdisf2_i387_only"
508790286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,?f")
508890286Sobrien	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
508990286Sobrien  "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
509090286Sobrien  "@
509190286Sobrien   fild%z1\t%1
509290286Sobrien   #"
509390286Sobrien  [(set_attr "type" "fmov,multi")
509490286Sobrien   (set_attr "mode" "SF")
509590286Sobrien   (set_attr "fp_int_src" "true")])
509652296Sobrien
509790286Sobrien(define_insn "*floatdisf2_i387"
509890286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
509990286Sobrien	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
510090286Sobrien  "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
510190286Sobrien  "@
510290286Sobrien   fild%z1\t%1
510390286Sobrien   #
510490286Sobrien   cvtsi2ss{q}\t{%1, %0|%0, %1}"
510590286Sobrien  [(set_attr "type" "fmov,multi,sse")
510690286Sobrien   (set_attr "mode" "SF")
510790286Sobrien   (set_attr "fp_int_src" "true")])
510852296Sobrien
510990286Sobrien(define_insn "*floatdisf2_sse"
511090286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
511190286Sobrien	(float:SF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
511290286Sobrien  "TARGET_64BIT && TARGET_SSE"
511390286Sobrien  "cvtsi2ss{q}\t{%1, %0|%0, %1}"
511490286Sobrien  [(set_attr "type" "sse")
511590286Sobrien   (set_attr "mode" "SF")
511690286Sobrien   (set_attr "fp_int_src" "true")])
511790286Sobrien
511890286Sobrien(define_insn "floathidf2"
511952296Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
512090286Sobrien	(float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
512190286Sobrien  "TARGET_80387 && !TARGET_SSE2"
512290286Sobrien  "@
512390286Sobrien   fild%z1\t%1
512490286Sobrien   #"
512590286Sobrien  [(set_attr "type" "fmov,multi")
512690286Sobrien   (set_attr "mode" "DF")
512790286Sobrien   (set_attr "fp_int_src" "true")])
512852296Sobrien
512990286Sobrien(define_expand "floatsidf2"
513018334Speter  [(set (match_operand:DF 0 "register_operand" "")
513190286Sobrien	(float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
513290286Sobrien  ""
513352296Sobrien  "")
513452296Sobrien
513590286Sobrien(define_insn "*floatsidf2_i387"
513690286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
513790286Sobrien	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
513890286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
513990286Sobrien  "@
514090286Sobrien   fild%z1\t%1
514190286Sobrien   #
514290286Sobrien   cvtsi2sd\t{%1, %0|%0, %1}"
514390286Sobrien  [(set_attr "type" "fmov,multi,sse")
514490286Sobrien   (set_attr "mode" "DF")
514590286Sobrien   (set_attr "fp_int_src" "true")])
514690286Sobrien
514790286Sobrien(define_insn "*floatsidf2_sse"
514890286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
514990286Sobrien	(float:DF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
515090286Sobrien  "TARGET_SSE2"
515190286Sobrien  "cvtsi2sd\t{%1, %0|%0, %1}"
515290286Sobrien  [(set_attr "type" "sse")
515390286Sobrien   (set_attr "mode" "DF")
515490286Sobrien   (set_attr "fp_int_src" "true")])
515590286Sobrien
515690286Sobrien(define_expand "floatdidf2"
515752296Sobrien  [(set (match_operand:DF 0 "register_operand" "")
515890286Sobrien	(float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
515990286Sobrien  "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
516052296Sobrien  "")
516152296Sobrien
516290286Sobrien(define_insn "*floatdidf2_i387_only"
516390286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,?f")
516490286Sobrien	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
516590286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
516690286Sobrien  "@
516790286Sobrien   fild%z1\t%1
516890286Sobrien   #"
516990286Sobrien  [(set_attr "type" "fmov,multi")
517090286Sobrien   (set_attr "mode" "DF")
517190286Sobrien   (set_attr "fp_int_src" "true")])
517290286Sobrien
517390286Sobrien(define_insn "*floatdidf2_i387"
517490286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
517590286Sobrien	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
517690286Sobrien  "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
517790286Sobrien  "@
517890286Sobrien   fild%z1\t%1
517990286Sobrien   #
518090286Sobrien   cvtsi2sd{q}\t{%1, %0|%0, %1}"
518190286Sobrien  [(set_attr "type" "fmov,multi,sse")
518290286Sobrien   (set_attr "mode" "DF")
518390286Sobrien   (set_attr "fp_int_src" "true")])
518490286Sobrien
518590286Sobrien(define_insn "*floatdidf2_sse"
518690286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
518790286Sobrien	(float:DF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
518890286Sobrien  "TARGET_SSE2"
518990286Sobrien  "cvtsi2sd{q}\t{%1, %0|%0, %1}"
519090286Sobrien  [(set_attr "type" "sse")
519190286Sobrien   (set_attr "mode" "DF")
519290286Sobrien   (set_attr "fp_int_src" "true")])
519390286Sobrien
519490286Sobrien(define_insn "floathixf2"
519590286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
519690286Sobrien	(float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
519790286Sobrien  "!TARGET_64BIT && TARGET_80387"
519890286Sobrien  "@
519990286Sobrien   fild%z1\t%1
520090286Sobrien   #"
520190286Sobrien  [(set_attr "type" "fmov,multi")
520290286Sobrien   (set_attr "mode" "XF")
520390286Sobrien   (set_attr "fp_int_src" "true")])
520490286Sobrien
520590286Sobrien(define_insn "floathitf2"
520690286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
520790286Sobrien	(float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
520818334Speter  "TARGET_80387"
520990286Sobrien  "@
521090286Sobrien   fild%z1\t%1
521190286Sobrien   #"
521290286Sobrien  [(set_attr "type" "fmov,multi")
521390286Sobrien   (set_attr "mode" "XF")
521490286Sobrien   (set_attr "fp_int_src" "true")])
521552296Sobrien
521690286Sobrien(define_insn "floatsixf2"
521790286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
521890286Sobrien	(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
521990286Sobrien  "!TARGET_64BIT && TARGET_80387"
522090286Sobrien  "@
522190286Sobrien   fild%z1\t%1
522290286Sobrien   #"
522390286Sobrien  [(set_attr "type" "fmov,multi")
522490286Sobrien   (set_attr "mode" "XF")
522590286Sobrien   (set_attr "fp_int_src" "true")])
522690286Sobrien
522790286Sobrien(define_insn "floatsitf2"
522890286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
522990286Sobrien	(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
523052296Sobrien  "TARGET_80387"
523190286Sobrien  "@
523290286Sobrien   fild%z1\t%1
523390286Sobrien   #"
523490286Sobrien  [(set_attr "type" "fmov,multi")
523590286Sobrien   (set_attr "mode" "XF")
523690286Sobrien   (set_attr "fp_int_src" "true")])
523752296Sobrien
523890286Sobrien(define_insn "floatdixf2"
523990286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
524090286Sobrien	(float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
524190286Sobrien  "!TARGET_64BIT && TARGET_80387"
524290286Sobrien  "@
524390286Sobrien   fild%z1\t%1
524490286Sobrien   #"
524590286Sobrien  [(set_attr "type" "fmov,multi")
524690286Sobrien   (set_attr "mode" "XF")
524790286Sobrien   (set_attr "fp_int_src" "true")])
524890286Sobrien
524990286Sobrien(define_insn "floatditf2"
525090286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
525190286Sobrien	(float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
525252296Sobrien  "TARGET_80387"
525390286Sobrien  "@
525490286Sobrien   fild%z1\t%1
525590286Sobrien   #"
525690286Sobrien  [(set_attr "type" "fmov,multi")
525790286Sobrien   (set_attr "mode" "XF")
525890286Sobrien   (set_attr "fp_int_src" "true")])
525952296Sobrien
526090286Sobrien;; %%% Kill these when reload knows how to do it.
526152296Sobrien(define_split
526290286Sobrien  [(set (match_operand 0 "register_operand" "")
526390286Sobrien	(float (match_operand 1 "register_operand" "")))]
526490286Sobrien  "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))
526590286Sobrien   && FP_REG_P (operands[0])"
526690286Sobrien  [(const_int 0)]
526790286Sobrien{
526890286Sobrien  operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
526990286Sobrien  operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
527090286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
527190286Sobrien  ix86_free_from_memory (GET_MODE (operands[1]));
527290286Sobrien  DONE;
527390286Sobrien})
527490286Sobrien
527590286Sobrien;; Add instructions
527618334Speter
527790286Sobrien;; %%% splits for addsidi3
527890286Sobrien;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
527990286Sobrien;	(plus:DI (match_operand:DI 1 "general_operand" "")
528090286Sobrien;		 (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
528152296Sobrien
528290286Sobrien(define_expand "adddi3"
528390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
528490286Sobrien	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
528590286Sobrien		 (match_operand:DI 2 "x86_64_general_operand" "")))
528690286Sobrien   (clobber (reg:CC 17))]
528790286Sobrien  ""
528890286Sobrien  "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
528952296Sobrien
529090286Sobrien(define_insn "*adddi3_1"
529190286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
529290286Sobrien	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
529390286Sobrien		 (match_operand:DI 2 "general_operand" "roiF,riF")))
529490286Sobrien   (clobber (reg:CC 17))]
529590286Sobrien  "!TARGET_64BIT"
529652296Sobrien  "#")
529752296Sobrien
529852296Sobrien(define_split
529990286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
530090286Sobrien	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
530190286Sobrien		 (match_operand:DI 2 "general_operand" "")))
530290286Sobrien   (clobber (reg:CC 17))]
530390286Sobrien  "!TARGET_64BIT && reload_completed"
530490286Sobrien  [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)] 12))
530590286Sobrien	      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
530690286Sobrien   (parallel [(set (match_dup 3)
530790286Sobrien		   (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
530890286Sobrien				     (match_dup 4))
530990286Sobrien			    (match_dup 5)))
531090286Sobrien	      (clobber (reg:CC 17))])]
531190286Sobrien  "split_di (operands+0, 1, operands+0, operands+3);
531290286Sobrien   split_di (operands+1, 1, operands+1, operands+4);
531390286Sobrien   split_di (operands+2, 1, operands+2, operands+5);")
531418334Speter
531590286Sobrien(define_insn "*adddi3_carry_rex64"
531690286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
531790286Sobrien	  (plus:DI (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
531890286Sobrien			    (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
531990286Sobrien		   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
532090286Sobrien   (clobber (reg:CC 17))]
532190286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
532290286Sobrien  "adc{q}\t{%2, %0|%0, %2}"
532390286Sobrien  [(set_attr "type" "alu")
532490286Sobrien   (set_attr "pent_pair" "pu")
532590286Sobrien   (set_attr "mode" "DI")
532690286Sobrien   (set_attr "ppro_uops" "few")])
532752296Sobrien
532890286Sobrien(define_insn "*adddi3_cc_rex64"
532990286Sobrien  [(set (reg:CC 17) (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
533090286Sobrien				(match_operand:DI 2 "x86_64_general_operand" "re,rm")] 12))
533190286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
533290286Sobrien	(plus:DI (match_dup 1) (match_dup 2)))]
533390286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
533490286Sobrien  "add{q}\t{%2, %0|%0, %2}"
533590286Sobrien  [(set_attr "type" "alu")
533690286Sobrien   (set_attr "mode" "DI")])
533752296Sobrien
533890286Sobrien(define_insn "*addsi3_carry"
533990286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
534090286Sobrien	  (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
534190286Sobrien			    (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
534290286Sobrien		   (match_operand:SI 2 "general_operand" "ri,rm")))
534390286Sobrien   (clobber (reg:CC 17))]
534490286Sobrien  "ix86_binary_operator_ok (PLUS, SImode, operands)"
534590286Sobrien  "adc{l}\t{%2, %0|%0, %2}"
534690286Sobrien  [(set_attr "type" "alu")
534790286Sobrien   (set_attr "pent_pair" "pu")
534890286Sobrien   (set_attr "mode" "SI")
534990286Sobrien   (set_attr "ppro_uops" "few")])
535052296Sobrien
535190286Sobrien(define_insn "*addsi3_carry_zext"
535290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
535390286Sobrien	  (zero_extend:DI 
535490286Sobrien	    (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
535590286Sobrien			      (match_operand:SI 1 "nonimmediate_operand" "%0"))
535690286Sobrien		     (match_operand:SI 2 "general_operand" "rim"))))
535790286Sobrien   (clobber (reg:CC 17))]
535890286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
535990286Sobrien  "adc{l}\t{%2, %k0|%k0, %2}"
536090286Sobrien  [(set_attr "type" "alu")
536190286Sobrien   (set_attr "pent_pair" "pu")
536290286Sobrien   (set_attr "mode" "SI")
536390286Sobrien   (set_attr "ppro_uops" "few")])
536452296Sobrien
536590286Sobrien(define_insn "*addsi3_cc"
536690286Sobrien  [(set (reg:CC 17) (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
536790286Sobrien			        (match_operand:SI 2 "general_operand" "ri,rm")] 12))
536890286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
536990286Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
537090286Sobrien  "ix86_binary_operator_ok (PLUS, SImode, operands)"
537190286Sobrien  "add{l}\t{%2, %0|%0, %2}"
537290286Sobrien  [(set_attr "type" "alu")
537390286Sobrien   (set_attr "mode" "SI")])
537418334Speter
537590286Sobrien(define_insn "addqi3_cc"
537690286Sobrien  [(set (reg:CC 17) (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
537790286Sobrien			        (match_operand:QI 2 "general_operand" "qi,qm")] 12))
537890286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
537990286Sobrien	(plus:QI (match_dup 1) (match_dup 2)))]
538090286Sobrien  "ix86_binary_operator_ok (PLUS, QImode, operands)"
538190286Sobrien  "add{b}\t{%2, %0|%0, %2}"
538290286Sobrien  [(set_attr "type" "alu")
538390286Sobrien   (set_attr "mode" "QI")])
538418334Speter
538590286Sobrien(define_expand "addsi3"
538690286Sobrien  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
538790286Sobrien		   (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
538890286Sobrien			    (match_operand:SI 2 "general_operand" "")))
538990286Sobrien	      (clobber (reg:CC 17))])]
539090286Sobrien  ""
539190286Sobrien  "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
539218334Speter
539390286Sobrien(define_insn "*lea_1"
539490286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
539590286Sobrien	(match_operand:SI 1 "address_operand" "p"))]
539690286Sobrien  "!TARGET_64BIT"
539790286Sobrien  "lea{l}\t{%a1, %0|%0, %a1}"
539890286Sobrien  [(set_attr "type" "lea")
539990286Sobrien   (set_attr "mode" "SI")])
540018334Speter
540190286Sobrien(define_insn "*lea_1_rex64"
540290286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
540390286Sobrien	(subreg:SI (match_operand:DI 1 "address_operand" "p") 0))]
540490286Sobrien  "TARGET_64BIT"
540590286Sobrien  "lea{l}\t{%a1, %0|%0, %a1}"
540690286Sobrien  [(set_attr "type" "lea")
540790286Sobrien   (set_attr "mode" "SI")])
540818334Speter
540990286Sobrien(define_insn "*lea_1_zext"
541090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
541190286Sobrien	(zero_extend:DI (subreg:SI (match_operand:DI 1 "address_operand" "p") 0)))]
541290286Sobrien  "TARGET_64BIT"
541390286Sobrien  "lea{l}\t{%a1, %k0|%k0, %a1}"
541490286Sobrien  [(set_attr "type" "lea")
541590286Sobrien   (set_attr "mode" "SI")])
541690286Sobrien
541790286Sobrien(define_insn "*lea_2_rex64"
541890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
541990286Sobrien	(match_operand:DI 1 "address_operand" "p"))]
542090286Sobrien  "TARGET_64BIT"
542190286Sobrien  "lea{q}\t{%a1, %0|%0, %a1}"
542290286Sobrien  [(set_attr "type" "lea")
542390286Sobrien   (set_attr "mode" "DI")])
542490286Sobrien
542590286Sobrien;; The lea patterns for non-Pmodes needs to be matched by several
542690286Sobrien;; insns converted to real lea by splitters.
542790286Sobrien
542890286Sobrien(define_insn_and_split "*lea_general_1"
542990286Sobrien  [(set (match_operand 0 "register_operand" "=r")
543090286Sobrien	(plus (plus (match_operand 1 "register_operand" "r")
543190286Sobrien		    (match_operand 2 "register_operand" "r"))
543290286Sobrien	      (match_operand 3 "immediate_operand" "i")))]
543390286Sobrien  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
543490286Sobrien    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
543590286Sobrien   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
543690286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])
543790286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[2])
543890286Sobrien   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
543990286Sobrien       || GET_MODE (operands[3]) == VOIDmode)"
544090286Sobrien  "#"
544190286Sobrien  "&& reload_completed"
544290286Sobrien  [(const_int 0)]
544390286Sobrien{
544490286Sobrien  rtx pat;
544590286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
544690286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
544790286Sobrien  operands[2] = gen_lowpart (Pmode, operands[2]);
544890286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
544990286Sobrien  pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
545090286Sobrien  		      operands[3]);
545190286Sobrien  if (Pmode != SImode)
545290286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
545390286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
545490286Sobrien  DONE;
545590286Sobrien}
545690286Sobrien  [(set_attr "type" "lea")
545790286Sobrien   (set_attr "mode" "SI")])
545890286Sobrien
545990286Sobrien(define_insn_and_split "*lea_general_1_zext"
546090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
546190286Sobrien	(zero_extend:DI
546290286Sobrien	  (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
546390286Sobrien			    (match_operand:SI 2 "register_operand" "r"))
546490286Sobrien		   (match_operand:SI 3 "immediate_operand" "i"))))]
546590286Sobrien  "TARGET_64BIT"
546690286Sobrien  "#"
546790286Sobrien  "&& reload_completed"
546852296Sobrien  [(set (match_dup 0)
546990286Sobrien	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
547090286Sobrien						     (match_dup 2))
547190286Sobrien					    (match_dup 3)) 0)))]
547290286Sobrien{
547390286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
547490286Sobrien  operands[2] = gen_lowpart (Pmode, operands[2]);
547590286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
547690286Sobrien}
547790286Sobrien  [(set_attr "type" "lea")
547890286Sobrien   (set_attr "mode" "SI")])
547952296Sobrien
548090286Sobrien(define_insn_and_split "*lea_general_2"
548190286Sobrien  [(set (match_operand 0 "register_operand" "=r")
548290286Sobrien	(plus (mult (match_operand 1 "register_operand" "r")
548390286Sobrien		    (match_operand 2 "const248_operand" "i"))
548490286Sobrien	      (match_operand 3 "nonmemory_operand" "ri")))]
548590286Sobrien  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
548690286Sobrien    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
548790286Sobrien   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
548890286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])
548990286Sobrien   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
549090286Sobrien       || GET_MODE (operands[3]) == VOIDmode)"
549190286Sobrien  "#"
549290286Sobrien  "&& reload_completed"
549390286Sobrien  [(const_int 0)]
549490286Sobrien{
549590286Sobrien  rtx pat;
549690286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
549790286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
549890286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
549990286Sobrien  pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
550090286Sobrien  		      operands[3]);
550190286Sobrien  if (Pmode != SImode)
550290286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
550390286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
550490286Sobrien  DONE;
550590286Sobrien}
550690286Sobrien  [(set_attr "type" "lea")
550790286Sobrien   (set_attr "mode" "SI")])
550852296Sobrien
550990286Sobrien(define_insn_and_split "*lea_general_2_zext"
551090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
551190286Sobrien	(zero_extend:DI
551290286Sobrien	  (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
551390286Sobrien			    (match_operand:SI 2 "const248_operand" "n"))
551490286Sobrien		   (match_operand:SI 3 "nonmemory_operand" "ri"))))]
551590286Sobrien  "TARGET_64BIT"
551690286Sobrien  "#"
551790286Sobrien  "&& reload_completed"
551890286Sobrien  [(set (match_dup 0)
551990286Sobrien	(zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
552090286Sobrien						     (match_dup 2))
552190286Sobrien					    (match_dup 3)) 0)))]
552290286Sobrien{
552390286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
552490286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
552590286Sobrien}
552690286Sobrien  [(set_attr "type" "lea")
552790286Sobrien   (set_attr "mode" "SI")])
552818334Speter
552990286Sobrien(define_insn_and_split "*lea_general_3"
553090286Sobrien  [(set (match_operand 0 "register_operand" "=r")
553190286Sobrien	(plus (plus (mult (match_operand 1 "register_operand" "r")
553290286Sobrien			  (match_operand 2 "const248_operand" "i"))
553390286Sobrien		    (match_operand 3 "register_operand" "r"))
553490286Sobrien	      (match_operand 4 "immediate_operand" "i")))]
553590286Sobrien  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
553690286Sobrien    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
553790286Sobrien   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
553890286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])
553990286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[3])"
554090286Sobrien  "#"
554190286Sobrien  "&& reload_completed"
554290286Sobrien  [(const_int 0)]
554390286Sobrien{
554490286Sobrien  rtx pat;
554590286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
554690286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
554790286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
554890286Sobrien  operands[4] = gen_lowpart (Pmode, operands[4]);
554990286Sobrien  pat = gen_rtx_PLUS (Pmode,
555090286Sobrien  		      gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
555190286Sobrien		      					 operands[2]),
555290286Sobrien				    operands[3]),
555390286Sobrien  		      operands[4]);
555490286Sobrien  if (Pmode != SImode)
555590286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
555690286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
555790286Sobrien  DONE;
555890286Sobrien}
555990286Sobrien  [(set_attr "type" "lea")
556090286Sobrien   (set_attr "mode" "SI")])
556152296Sobrien
556290286Sobrien(define_insn_and_split "*lea_general_3_zext"
556390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
556490286Sobrien	(zero_extend:DI
556590286Sobrien	  (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
556690286Sobrien				     (match_operand:SI 2 "const248_operand" "n"))
556790286Sobrien			    (match_operand:SI 3 "register_operand" "r"))
556890286Sobrien		   (match_operand:SI 4 "immediate_operand" "i"))))]
556990286Sobrien  "TARGET_64BIT"
557090286Sobrien  "#"
557190286Sobrien  "&& reload_completed"
557290286Sobrien  [(set (match_dup 0)
557390286Sobrien	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
557490286Sobrien							      (match_dup 2))
557590286Sobrien						     (match_dup 3))
557690286Sobrien					    (match_dup 4)) 0)))]
557790286Sobrien{
557890286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
557990286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
558090286Sobrien  operands[4] = gen_lowpart (Pmode, operands[4]);
558190286Sobrien}
558290286Sobrien  [(set_attr "type" "lea")
558390286Sobrien   (set_attr "mode" "SI")])
558418334Speter
558590286Sobrien(define_insn "*adddi_1_rex64"
558690286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
558790286Sobrien	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
558890286Sobrien		 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
558990286Sobrien   (clobber (reg:CC 17))]
559090286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
559190286Sobrien{
559290286Sobrien  switch (get_attr_type (insn))
559390286Sobrien    {
559490286Sobrien    case TYPE_LEA:
559590286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
559690286Sobrien      return "lea{q}\t{%a2, %0|%0, %a2}";
559790286Sobrien
559890286Sobrien    case TYPE_INCDEC:
559990286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
560090286Sobrien	abort ();
560190286Sobrien      if (operands[2] == const1_rtx)
560290286Sobrien        return "inc{q}\t%0";
560390286Sobrien      else if (operands[2] == constm1_rtx)
560490286Sobrien        return "dec{q}\t%0";
560590286Sobrien      else
560690286Sobrien	abort ();
560790286Sobrien
560890286Sobrien    default:
560990286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
561090286Sobrien	abort ();
561190286Sobrien
561290286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
561390286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
561490286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
561590286Sobrien	  /* Avoid overflows.  */
561690286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
561790286Sobrien          && (INTVAL (operands[2]) == 128
561890286Sobrien	      || (INTVAL (operands[2]) < 0
561990286Sobrien		  && INTVAL (operands[2]) != -128)))
562090286Sobrien        {
562190286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
562290286Sobrien          return "sub{q}\t{%2, %0|%0, %2}";
562390286Sobrien        }
562490286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
562590286Sobrien    }
562690286Sobrien}
562790286Sobrien  [(set (attr "type")
562890286Sobrien     (cond [(eq_attr "alternative" "2")
562990286Sobrien	      (const_string "lea")
563090286Sobrien	    ; Current assemblers are broken and do not allow @GOTOFF in
563190286Sobrien	    ; ought but a memory context.
563290286Sobrien	    (match_operand:DI 2 "pic_symbolic_operand" "")
563390286Sobrien	      (const_string "lea")
563490286Sobrien	    (match_operand:DI 2 "incdec_operand" "")
563590286Sobrien	      (const_string "incdec")
563690286Sobrien	   ]
563790286Sobrien	   (const_string "alu")))
563890286Sobrien   (set_attr "mode" "DI")])
563990286Sobrien
564090286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
564152296Sobrien(define_split
564290286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
564390286Sobrien	(plus:DI (match_operand:DI 1 "register_operand" "")
564490286Sobrien		 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
564590286Sobrien   (clobber (reg:CC 17))]
564690286Sobrien  "TARGET_64BIT && reload_completed
564790286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
564852296Sobrien  [(set (match_dup 0)
564990286Sobrien	(plus:DI (match_dup 1)
565090286Sobrien		 (match_dup 2)))]
565152296Sobrien  "")
565252296Sobrien
565390286Sobrien(define_insn "*adddi_2_rex64"
565490286Sobrien  [(set (reg 17)
565590286Sobrien	(compare
565690286Sobrien	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
565790286Sobrien		   (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
565890286Sobrien	  (const_int 0)))			
565990286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
566090286Sobrien	(plus:DI (match_dup 1) (match_dup 2)))]
566190286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
566290286Sobrien   && ix86_binary_operator_ok (PLUS, DImode, operands)
566390286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
566490286Sobrien      ought but a memory context.  */
566590286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
566690286Sobrien{
566790286Sobrien  switch (get_attr_type (insn))
566890286Sobrien    {
566990286Sobrien    case TYPE_INCDEC:
567090286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
567190286Sobrien	abort ();
567290286Sobrien      if (operands[2] == const1_rtx)
567390286Sobrien        return "inc{q}\t%0";
567490286Sobrien      else if (operands[2] == constm1_rtx)
567590286Sobrien        return "dec{q}\t%0";
567690286Sobrien      else
567790286Sobrien	abort ();
567852296Sobrien
567990286Sobrien    default:
568090286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
568190286Sobrien	abort ();
568290286Sobrien      /* ???? We ought to handle there the 32bit case too
568390286Sobrien	 - do we need new constrant?  */
568490286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
568590286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
568690286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
568790286Sobrien	  /* Avoid overflows.  */
568890286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
568990286Sobrien          && (INTVAL (operands[2]) == 128
569090286Sobrien	      || (INTVAL (operands[2]) < 0
569190286Sobrien		  && INTVAL (operands[2]) != -128)))
569290286Sobrien        {
569390286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
569490286Sobrien          return "sub{q}\t{%2, %0|%0, %2}";
569590286Sobrien        }
569690286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
569790286Sobrien    }
569890286Sobrien}
569990286Sobrien  [(set (attr "type")
570090286Sobrien     (if_then_else (match_operand:DI 2 "incdec_operand" "")
570190286Sobrien	(const_string "incdec")
570290286Sobrien	(const_string "alu")))
570390286Sobrien   (set_attr "mode" "DI")])
570418334Speter
570590286Sobrien(define_insn "*adddi_3_rex64"
570690286Sobrien  [(set (reg 17)
570790286Sobrien	(compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
570890286Sobrien		 (match_operand:DI 1 "x86_64_general_operand" "%0")))
570990286Sobrien   (clobber (match_scratch:DI 0 "=r"))]
571090286Sobrien  "TARGET_64BIT
571190286Sobrien   && ix86_match_ccmode (insn, CCZmode)
571290286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
571390286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
571490286Sobrien      ought but a memory context.  */
571590286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
571650650Sobrien{
571790286Sobrien  switch (get_attr_type (insn))
571890286Sobrien    {
571990286Sobrien    case TYPE_INCDEC:
572090286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
572190286Sobrien	abort ();
572290286Sobrien      if (operands[2] == const1_rtx)
572390286Sobrien        return "inc{q}\t%0";
572490286Sobrien      else if (operands[2] == constm1_rtx)
572590286Sobrien        return "dec{q}\t%0";
572690286Sobrien      else
572790286Sobrien	abort ();
572850650Sobrien
572990286Sobrien    default:
573090286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
573190286Sobrien	abort ();
573290286Sobrien      /* ???? We ought to handle there the 32bit case too
573390286Sobrien	 - do we need new constrant?  */
573490286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
573590286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
573690286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
573790286Sobrien	  /* Avoid overflows.  */
573890286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
573990286Sobrien          && (INTVAL (operands[2]) == 128
574090286Sobrien	      || (INTVAL (operands[2]) < 0
574190286Sobrien		  && INTVAL (operands[2]) != -128)))
574290286Sobrien        {
574390286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
574490286Sobrien          return "sub{q}\t{%2, %0|%0, %2}";
574590286Sobrien        }
574690286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
574790286Sobrien    }
574890286Sobrien}
574990286Sobrien  [(set (attr "type")
575090286Sobrien     (if_then_else (match_operand:DI 2 "incdec_operand" "")
575190286Sobrien	(const_string "incdec")
575290286Sobrien	(const_string "alu")))
575390286Sobrien   (set_attr "mode" "DI")])
575450650Sobrien
575590286Sobrien; For comparisons against 1, -1 and 128, we may generate better code
575690286Sobrien; by converting cmp to add, inc or dec as done by peephole2.  This pattern
575790286Sobrien; is matched then.  We can't accept general immediate, because for
575890286Sobrien; case of overflows,  the result is messed up.
575990286Sobrien; This pattern also don't hold of 0x8000000000000000, since the value overflows
576090286Sobrien; when negated.
576190286Sobrien; Also carry flag is reversed compared to cmp, so this conversion is valid
576290286Sobrien; only for comparisons not depending on it.
576390286Sobrien(define_insn "*adddi_4_rex64"
576490286Sobrien  [(set (reg 17)
576590286Sobrien	(compare (match_operand:DI 1 "nonimmediate_operand" "0")
576690286Sobrien		 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
576790286Sobrien   (clobber (match_scratch:DI 0 "=rm"))]
576890286Sobrien  "TARGET_64BIT
576990286Sobrien   &&  ix86_match_ccmode (insn, CCGCmode)"
577090286Sobrien{
577190286Sobrien  switch (get_attr_type (insn))
577290286Sobrien    {
577390286Sobrien    case TYPE_INCDEC:
577490286Sobrien      if (operands[2] == constm1_rtx)
577590286Sobrien        return "inc{q}\t%0";
577690286Sobrien      else if (operands[2] == const1_rtx)
577790286Sobrien        return "dec{q}\t%0";
577890286Sobrien      else
577990286Sobrien	abort();
578050650Sobrien
578190286Sobrien    default:
578290286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
578390286Sobrien	abort ();
578490286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
578590286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
578690286Sobrien      if ((INTVAL (operands[2]) == -128
578790286Sobrien	   || (INTVAL (operands[2]) > 0
578890286Sobrien	       && INTVAL (operands[2]) != 128))
578990286Sobrien	  /* Avoid overflows.  */
579090286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
579190286Sobrien	return "sub{q}\t{%2, %0|%0, %2}";
579290286Sobrien      operands[2] = GEN_INT (-INTVAL (operands[2]));
579390286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
579490286Sobrien    }
579590286Sobrien}
579690286Sobrien  [(set (attr "type")
579790286Sobrien     (if_then_else (match_operand:DI 2 "incdec_operand" "")
579890286Sobrien	(const_string "incdec")
579990286Sobrien	(const_string "alu")))
580090286Sobrien   (set_attr "mode" "DI")])
580190286Sobrien
580290286Sobrien(define_insn "*adddi_5_rex64"
580390286Sobrien  [(set (reg 17)
580490286Sobrien	(compare
580590286Sobrien	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
580690286Sobrien		   (match_operand:DI 2 "x86_64_general_operand" "rme"))
580790286Sobrien	  (const_int 0)))			
580890286Sobrien   (clobber (match_scratch:DI 0 "=r"))]
580990286Sobrien  "TARGET_64BIT
581090286Sobrien   && ix86_match_ccmode (insn, CCGOCmode)
581190286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
581290286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
581390286Sobrien      ought but a memory context.  */
581490286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
581590286Sobrien{
581690286Sobrien  switch (get_attr_type (insn))
581750650Sobrien    {
581890286Sobrien    case TYPE_INCDEC:
581990286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
582090286Sobrien	abort ();
582190286Sobrien      if (operands[2] == const1_rtx)
582290286Sobrien        return "inc{q}\t%0";
582390286Sobrien      else if (operands[2] == constm1_rtx)
582490286Sobrien        return "dec{q}\t%0";
582590286Sobrien      else
582690286Sobrien	abort();
582750650Sobrien
582890286Sobrien    default:
582990286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
583090286Sobrien	abort ();
583190286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
583290286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
583390286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
583490286Sobrien	  /* Avoid overflows.  */
583590286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
583690286Sobrien          && (INTVAL (operands[2]) == 128
583790286Sobrien	      || (INTVAL (operands[2]) < 0
583890286Sobrien		  && INTVAL (operands[2]) != -128)))
583990286Sobrien        {
584090286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
584190286Sobrien          return "sub{q}\t{%2, %0|%0, %2}";
584290286Sobrien        }
584390286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
584450650Sobrien    }
584590286Sobrien}
584690286Sobrien  [(set (attr "type")
584790286Sobrien     (if_then_else (match_operand:DI 2 "incdec_operand" "")
584890286Sobrien	(const_string "incdec")
584990286Sobrien	(const_string "alu")))
585090286Sobrien   (set_attr "mode" "DI")])
585150650Sobrien
585250650Sobrien
585390286Sobrien(define_insn "*addsi_1"
585490286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
585590286Sobrien	(plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
585690286Sobrien		 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
585790286Sobrien   (clobber (reg:CC 17))]
585890286Sobrien  "ix86_binary_operator_ok (PLUS, SImode, operands)"
585950650Sobrien{
586090286Sobrien  switch (get_attr_type (insn))
586190286Sobrien    {
586290286Sobrien    case TYPE_LEA:
586390286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
586490286Sobrien      return "lea{l}\t{%a2, %0|%0, %a2}";
586550650Sobrien
586690286Sobrien    case TYPE_INCDEC:
586790286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
586890286Sobrien	abort ();
586990286Sobrien      if (operands[2] == const1_rtx)
587090286Sobrien        return "inc{l}\t%0";
587190286Sobrien      else if (operands[2] == constm1_rtx)
587290286Sobrien        return "dec{l}\t%0";
587390286Sobrien      else
587490286Sobrien	abort();
587550650Sobrien
587690286Sobrien    default:
587790286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
587890286Sobrien	abort ();
587950650Sobrien
588090286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
588190286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
588290286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
588390286Sobrien          && (INTVAL (operands[2]) == 128
588490286Sobrien	      || (INTVAL (operands[2]) < 0
588590286Sobrien		  && INTVAL (operands[2]) != -128)))
588690286Sobrien        {
588790286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
588890286Sobrien          return "sub{l}\t{%2, %0|%0, %2}";
588990286Sobrien        }
589090286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
589190286Sobrien    }
589290286Sobrien}
589390286Sobrien  [(set (attr "type")
589490286Sobrien     (cond [(eq_attr "alternative" "2")
589590286Sobrien	      (const_string "lea")
589690286Sobrien	    ; Current assemblers are broken and do not allow @GOTOFF in
589790286Sobrien	    ; ought but a memory context.
589890286Sobrien	    (match_operand:SI 2 "pic_symbolic_operand" "")
589990286Sobrien	      (const_string "lea")
590090286Sobrien	    (match_operand:SI 2 "incdec_operand" "")
590190286Sobrien	      (const_string "incdec")
590290286Sobrien	   ]
590390286Sobrien	   (const_string "alu")))
590490286Sobrien   (set_attr "mode" "SI")])
590590286Sobrien
590690286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
590790286Sobrien(define_split
590890286Sobrien  [(set (match_operand 0 "register_operand" "")
590990286Sobrien	(plus (match_operand 1 "register_operand" "")
591090286Sobrien              (match_operand 2 "nonmemory_operand" "")))
591190286Sobrien   (clobber (reg:CC 17))]
591290286Sobrien  "reload_completed
591390286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
591490286Sobrien  [(const_int 0)]
591590286Sobrien{
591690286Sobrien  rtx pat;
591790286Sobrien  /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
591890286Sobrien     may confuse gen_lowpart.  */
591990286Sobrien  if (GET_MODE (operands[0]) != Pmode)
592050650Sobrien    {
592190286Sobrien      operands[1] = gen_lowpart (Pmode, operands[1]);
592290286Sobrien      operands[2] = gen_lowpart (Pmode, operands[2]);
592390286Sobrien    }
592490286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
592590286Sobrien  pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
592690286Sobrien  if (Pmode != SImode)
592790286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
592890286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
592990286Sobrien  DONE;
593090286Sobrien})
593150650Sobrien
593290286Sobrien;; It may seem that nonimmediate operand is proper one for operand 1.
593390286Sobrien;; The addsi_1 pattern allows nonimmediate operand at that place and
593490286Sobrien;; we take care in ix86_binary_operator_ok to not allow two memory
593590286Sobrien;; operands so proper swapping will be done in reload.  This allow
593690286Sobrien;; patterns constructed from addsi_1 to match.
593790286Sobrien(define_insn "addsi_1_zext"
593890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
593990286Sobrien	(zero_extend:DI
594090286Sobrien	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
594190286Sobrien		   (match_operand:SI 2 "general_operand" "rmni,rni"))))
594290286Sobrien   (clobber (reg:CC 17))]
594390286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
594490286Sobrien{
594590286Sobrien  switch (get_attr_type (insn))
594690286Sobrien    {
594790286Sobrien    case TYPE_LEA:
594890286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
594990286Sobrien      return "lea{l}\t{%a2, %k0|%k0, %a2}";
595090286Sobrien
595190286Sobrien    case TYPE_INCDEC:
595290286Sobrien      if (operands[2] == const1_rtx)
595390286Sobrien        return "inc{l}\t%k0";
595490286Sobrien      else if (operands[2] == constm1_rtx)
595590286Sobrien        return "dec{l}\t%k0";
595650650Sobrien      else
595790286Sobrien	abort();
595890286Sobrien
595990286Sobrien    default:
596090286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
596190286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
596290286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
596390286Sobrien          && (INTVAL (operands[2]) == 128
596490286Sobrien	      || (INTVAL (operands[2]) < 0
596590286Sobrien		  && INTVAL (operands[2]) != -128)))
596690286Sobrien        {
596790286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
596890286Sobrien          return "sub{l}\t{%2, %k0|%k0, %2}";
596990286Sobrien        }
597090286Sobrien      return "add{l}\t{%2, %k0|%k0, %2}";
597150650Sobrien    }
597290286Sobrien}
597390286Sobrien  [(set (attr "type")
597490286Sobrien     (cond [(eq_attr "alternative" "1")
597590286Sobrien	      (const_string "lea")
597690286Sobrien	    ; Current assemblers are broken and do not allow @GOTOFF in
597790286Sobrien	    ; ought but a memory context.
597890286Sobrien	    (match_operand:SI 2 "pic_symbolic_operand" "")
597990286Sobrien	      (const_string "lea")
598090286Sobrien	    (match_operand:SI 2 "incdec_operand" "")
598190286Sobrien	      (const_string "incdec")
598290286Sobrien	   ]
598390286Sobrien	   (const_string "alu")))
598490286Sobrien   (set_attr "mode" "SI")])
598550650Sobrien
598690286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
598790286Sobrien(define_split
598890286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
598990286Sobrien	(zero_extend:DI
599090286Sobrien	  (plus:SI (match_operand:SI 1 "register_operand" "")
599190286Sobrien		   (match_operand:SI 2 "nonmemory_operand" ""))))
599290286Sobrien   (clobber (reg:CC 17))]
599390286Sobrien  "reload_completed
599490286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
599590286Sobrien  [(set (match_dup 0)
599690286Sobrien	(zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
599790286Sobrien{
599890286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
599990286Sobrien  operands[2] = gen_lowpart (Pmode, operands[2]);
600090286Sobrien})
600150650Sobrien
600290286Sobrien(define_insn "*addsi_2"
600390286Sobrien  [(set (reg 17)
600490286Sobrien	(compare
600590286Sobrien	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
600690286Sobrien		   (match_operand:SI 2 "general_operand" "rmni,rni"))
600790286Sobrien	  (const_int 0)))			
600890286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
600990286Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
601090286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
601190286Sobrien   && ix86_binary_operator_ok (PLUS, SImode, operands)
601290286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
601390286Sobrien      ought but a memory context.  */
601490286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
601518334Speter{
601690286Sobrien  switch (get_attr_type (insn))
601790286Sobrien    {
601890286Sobrien    case TYPE_INCDEC:
601990286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
602090286Sobrien	abort ();
602190286Sobrien      if (operands[2] == const1_rtx)
602290286Sobrien        return "inc{l}\t%0";
602390286Sobrien      else if (operands[2] == constm1_rtx)
602490286Sobrien        return "dec{l}\t%0";
602590286Sobrien      else
602690286Sobrien	abort();
602718334Speter
602890286Sobrien    default:
602990286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
603090286Sobrien	abort ();
603190286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
603290286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
603390286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
603490286Sobrien          && (INTVAL (operands[2]) == 128
603590286Sobrien	      || (INTVAL (operands[2]) < 0
603690286Sobrien		  && INTVAL (operands[2]) != -128)))
603790286Sobrien        {
603890286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
603990286Sobrien          return "sub{l}\t{%2, %0|%0, %2}";
604090286Sobrien        }
604190286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
604290286Sobrien    }
604390286Sobrien}
604490286Sobrien  [(set (attr "type")
604590286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
604690286Sobrien	(const_string "incdec")
604790286Sobrien	(const_string "alu")))
604890286Sobrien   (set_attr "mode" "SI")])
604918334Speter
605090286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
605190286Sobrien(define_insn "*addsi_2_zext"
605290286Sobrien  [(set (reg 17)
605390286Sobrien	(compare
605490286Sobrien	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
605590286Sobrien		   (match_operand:SI 2 "general_operand" "rmni"))
605690286Sobrien	  (const_int 0)))			
605790286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
605890286Sobrien	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
605990286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
606090286Sobrien   && ix86_binary_operator_ok (PLUS, SImode, operands)
606190286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
606290286Sobrien      ought but a memory context.  */
606390286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
606490286Sobrien{
606590286Sobrien  switch (get_attr_type (insn))
606618334Speter    {
606790286Sobrien    case TYPE_INCDEC:
606890286Sobrien      if (operands[2] == const1_rtx)
606990286Sobrien        return "inc{l}\t%k0";
607090286Sobrien      else if (operands[2] == constm1_rtx)
607190286Sobrien        return "dec{l}\t%k0";
607290286Sobrien      else
607390286Sobrien	abort();
607490286Sobrien
607590286Sobrien    default:
607690286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
607790286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
607890286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
607990286Sobrien          && (INTVAL (operands[2]) == 128
608090286Sobrien	      || (INTVAL (operands[2]) < 0
608190286Sobrien		  && INTVAL (operands[2]) != -128)))
608290286Sobrien        {
608390286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
608490286Sobrien          return "sub{l}\t{%2, %k0|%k0, %2}";
608590286Sobrien        }
608690286Sobrien      return "add{l}\t{%2, %k0|%k0, %2}";
608718334Speter    }
608890286Sobrien}
608990286Sobrien  [(set (attr "type")
609090286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
609190286Sobrien	(const_string "incdec")
609290286Sobrien	(const_string "alu")))
609390286Sobrien   (set_attr "mode" "SI")])
609418334Speter
609590286Sobrien(define_insn "*addsi_3"
609690286Sobrien  [(set (reg 17)
609790286Sobrien	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
609890286Sobrien		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
609990286Sobrien   (clobber (match_scratch:SI 0 "=r"))]
610090286Sobrien  "ix86_match_ccmode (insn, CCZmode)
610190286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
610290286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
610390286Sobrien      ought but a memory context.  */
610490286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
610590286Sobrien{
610690286Sobrien  switch (get_attr_type (insn))
610718334Speter    {
610890286Sobrien    case TYPE_INCDEC:
610990286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
611090286Sobrien	abort ();
611190286Sobrien      if (operands[2] == const1_rtx)
611290286Sobrien        return "inc{l}\t%0";
611390286Sobrien      else if (operands[2] == constm1_rtx)
611490286Sobrien        return "dec{l}\t%0";
611590286Sobrien      else
611690286Sobrien	abort();
611718334Speter
611890286Sobrien    default:
611990286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
612090286Sobrien	abort ();
612190286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
612290286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
612390286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
612490286Sobrien          && (INTVAL (operands[2]) == 128
612590286Sobrien	      || (INTVAL (operands[2]) < 0
612690286Sobrien		  && INTVAL (operands[2]) != -128)))
612790286Sobrien        {
612890286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
612990286Sobrien          return "sub{l}\t{%2, %0|%0, %2}";
613090286Sobrien        }
613190286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
613290286Sobrien    }
613390286Sobrien}
613490286Sobrien  [(set (attr "type")
613590286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
613690286Sobrien	(const_string "incdec")
613790286Sobrien	(const_string "alu")))
613890286Sobrien   (set_attr "mode" "SI")])
613990286Sobrien
614090286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
614190286Sobrien(define_insn "*addsi_3_zext"
614290286Sobrien  [(set (reg 17)
614390286Sobrien	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
614490286Sobrien		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
614590286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
614690286Sobrien	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
614790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
614890286Sobrien   && ix86_binary_operator_ok (PLUS, SImode, operands)
614990286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
615090286Sobrien      ought but a memory context.  */
615190286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
615290286Sobrien{
615390286Sobrien  switch (get_attr_type (insn))
615490286Sobrien    {
615590286Sobrien    case TYPE_INCDEC:
615690286Sobrien      if (operands[2] == const1_rtx)
615790286Sobrien        return "inc{l}\t%k0";
615890286Sobrien      else if (operands[2] == constm1_rtx)
615990286Sobrien        return "dec{l}\t%k0";
616018334Speter      else
616190286Sobrien	abort();
616290286Sobrien
616390286Sobrien    default:
616490286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
616590286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
616690286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
616790286Sobrien          && (INTVAL (operands[2]) == 128
616890286Sobrien	      || (INTVAL (operands[2]) < 0
616990286Sobrien		  && INTVAL (operands[2]) != -128)))
617090286Sobrien        {
617190286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
617290286Sobrien          return "sub{l}\t{%2, %k0|%k0, %2}";
617390286Sobrien        }
617490286Sobrien      return "add{l}\t{%2, %k0|%k0, %2}";
617518334Speter    }
617690286Sobrien}
617790286Sobrien  [(set (attr "type")
617890286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
617990286Sobrien	(const_string "incdec")
618090286Sobrien	(const_string "alu")))
618190286Sobrien   (set_attr "mode" "SI")])
618218334Speter
618390286Sobrien; For comparisons agains 1, -1 and 128, we may generate better code
618490286Sobrien; by converting cmp to add, inc or dec as done by peephole2.  This pattern
618590286Sobrien; is matched then.  We can't accept general immediate, because for
618690286Sobrien; case of overflows,  the result is messed up.
618790286Sobrien; This pattern also don't hold of 0x80000000, since the value overflows
618890286Sobrien; when negated.
618990286Sobrien; Also carry flag is reversed compared to cmp, so this conversion is valid
619090286Sobrien; only for comparisons not depending on it.
619190286Sobrien(define_insn "*addsi_4"
619290286Sobrien  [(set (reg 17)
619390286Sobrien	(compare (match_operand:SI 1 "nonimmediate_operand" "0")
619490286Sobrien		 (match_operand:SI 2 "const_int_operand" "n")))
619590286Sobrien   (clobber (match_scratch:SI 0 "=rm"))]
619690286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
619790286Sobrien   && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
619890286Sobrien{
619990286Sobrien  switch (get_attr_type (insn))
620018334Speter    {
620190286Sobrien    case TYPE_INCDEC:
620290286Sobrien      if (operands[2] == constm1_rtx)
620390286Sobrien        return "inc{l}\t%0";
620490286Sobrien      else if (operands[2] == const1_rtx)
620590286Sobrien        return "dec{l}\t%0";
620690286Sobrien      else
620790286Sobrien	abort();
620818334Speter
620990286Sobrien    default:
621090286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
621190286Sobrien	abort ();
621290286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
621390286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
621490286Sobrien      if ((INTVAL (operands[2]) == -128
621590286Sobrien	   || (INTVAL (operands[2]) > 0
621690286Sobrien	       && INTVAL (operands[2]) != 128)))
621790286Sobrien	return "sub{l}\t{%2, %0|%0, %2}";
621890286Sobrien      operands[2] = GEN_INT (-INTVAL (operands[2]));
621990286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
622018334Speter    }
622190286Sobrien}
622290286Sobrien  [(set (attr "type")
622390286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
622490286Sobrien	(const_string "incdec")
622590286Sobrien	(const_string "alu")))
622690286Sobrien   (set_attr "mode" "SI")])
622718334Speter
622890286Sobrien(define_insn "*addsi_5"
622990286Sobrien  [(set (reg 17)
623090286Sobrien	(compare
623190286Sobrien	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
623290286Sobrien		   (match_operand:SI 2 "general_operand" "rmni"))
623390286Sobrien	  (const_int 0)))			
623490286Sobrien   (clobber (match_scratch:SI 0 "=r"))]
623590286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
623690286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
623790286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
623890286Sobrien      ought but a memory context.  */
623990286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
624090286Sobrien{
624190286Sobrien  switch (get_attr_type (insn))
624218334Speter    {
624390286Sobrien    case TYPE_INCDEC:
624490286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
624590286Sobrien	abort ();
624690286Sobrien      if (operands[2] == const1_rtx)
624790286Sobrien        return "inc{l}\t%0";
624890286Sobrien      else if (operands[2] == constm1_rtx)
624990286Sobrien        return "dec{l}\t%0";
625090286Sobrien      else
625190286Sobrien	abort();
625290286Sobrien
625390286Sobrien    default:
625490286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
625590286Sobrien	abort ();
625690286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
625790286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
625890286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
625990286Sobrien          && (INTVAL (operands[2]) == 128
626090286Sobrien	      || (INTVAL (operands[2]) < 0
626190286Sobrien		  && INTVAL (operands[2]) != -128)))
626290286Sobrien        {
626390286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
626490286Sobrien          return "sub{l}\t{%2, %0|%0, %2}";
626590286Sobrien        }
626690286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
626718334Speter    }
626890286Sobrien}
626990286Sobrien  [(set (attr "type")
627090286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
627190286Sobrien	(const_string "incdec")
627290286Sobrien	(const_string "alu")))
627390286Sobrien   (set_attr "mode" "SI")])
627418334Speter
627590286Sobrien(define_expand "addhi3"
627690286Sobrien  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
627790286Sobrien		   (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
627890286Sobrien			    (match_operand:HI 2 "general_operand" "")))
627990286Sobrien	      (clobber (reg:CC 17))])]
628090286Sobrien  "TARGET_HIMODE_MATH"
628190286Sobrien  "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
628218334Speter
628390286Sobrien;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
628490286Sobrien;; type optimizations enabled by define-splits.  This is not important
628590286Sobrien;; for PII, and in fact harmful because of partial register stalls.
628618334Speter
628790286Sobrien(define_insn "*addhi_1_lea"
628890286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
628990286Sobrien	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
629090286Sobrien		 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
629190286Sobrien   (clobber (reg:CC 17))]
629290286Sobrien  "!TARGET_PARTIAL_REG_STALL
629390286Sobrien   && ix86_binary_operator_ok (PLUS, HImode, operands)"
629490286Sobrien{
629590286Sobrien  switch (get_attr_type (insn))
629690286Sobrien    {
629790286Sobrien    case TYPE_LEA:
629890286Sobrien      return "#";
629990286Sobrien    case TYPE_INCDEC:
630090286Sobrien      if (operands[2] == const1_rtx)
630190286Sobrien	return "inc{w}\t%0";
630290286Sobrien      else if (operands[2] == constm1_rtx
630390286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
630490286Sobrien		   && INTVAL (operands[2]) == 65535))
630590286Sobrien	return "dec{w}\t%0";
630690286Sobrien      abort();
630718334Speter
630890286Sobrien    default:
630990286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
631090286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
631190286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
631290286Sobrien          && (INTVAL (operands[2]) == 128
631390286Sobrien	      || (INTVAL (operands[2]) < 0
631490286Sobrien		  && INTVAL (operands[2]) != -128)))
631590286Sobrien	{
631690286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
631790286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
631890286Sobrien	}
631990286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
632090286Sobrien    }
632190286Sobrien}
632290286Sobrien  [(set (attr "type")
632390286Sobrien     (if_then_else (eq_attr "alternative" "2")
632490286Sobrien	(const_string "lea")
632590286Sobrien	(if_then_else (match_operand:HI 2 "incdec_operand" "")
632690286Sobrien	   (const_string "incdec")
632790286Sobrien	   (const_string "alu"))))
632890286Sobrien   (set_attr "mode" "HI,HI,SI")])
632950650Sobrien
633090286Sobrien(define_insn "*addhi_1"
633190286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
633290286Sobrien	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
633390286Sobrien		 (match_operand:HI 2 "general_operand" "ri,rm")))
633490286Sobrien   (clobber (reg:CC 17))]
633590286Sobrien  "TARGET_PARTIAL_REG_STALL
633690286Sobrien   && ix86_binary_operator_ok (PLUS, HImode, operands)"
633718334Speter{
633890286Sobrien  switch (get_attr_type (insn))
633918334Speter    {
634090286Sobrien    case TYPE_INCDEC:
634190286Sobrien      if (operands[2] == const1_rtx)
634290286Sobrien	return "inc{w}\t%0";
634390286Sobrien      else if (operands[2] == constm1_rtx
634490286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
634590286Sobrien		   && INTVAL (operands[2]) == 65535))
634690286Sobrien	return "dec{w}\t%0";
634790286Sobrien      abort();
634818334Speter
634990286Sobrien    default:
635090286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
635190286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
635290286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
635390286Sobrien          && (INTVAL (operands[2]) == 128
635490286Sobrien	      || (INTVAL (operands[2]) < 0
635590286Sobrien		  && INTVAL (operands[2]) != -128)))
635618334Speter	{
635790286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
635890286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
635918334Speter	}
636090286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
636190286Sobrien    }
636290286Sobrien}
636390286Sobrien  [(set (attr "type")
636490286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
636590286Sobrien	(const_string "incdec")
636690286Sobrien	(const_string "alu")))
636790286Sobrien   (set_attr "mode" "HI")])
636818334Speter
636990286Sobrien(define_insn "*addhi_2"
637090286Sobrien  [(set (reg 17)
637190286Sobrien	(compare
637290286Sobrien	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
637390286Sobrien		   (match_operand:HI 2 "general_operand" "rmni,rni"))
637490286Sobrien	  (const_int 0)))			
637590286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
637690286Sobrien	(plus:HI (match_dup 1) (match_dup 2)))]
637790286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
637890286Sobrien   && ix86_binary_operator_ok (PLUS, HImode, operands)"
637990286Sobrien{
638090286Sobrien  switch (get_attr_type (insn))
638190286Sobrien    {
638290286Sobrien    case TYPE_INCDEC:
638390286Sobrien      if (operands[2] == const1_rtx)
638490286Sobrien	return "inc{w}\t%0";
638590286Sobrien      else if (operands[2] == constm1_rtx
638690286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
638790286Sobrien		   && INTVAL (operands[2]) == 65535))
638890286Sobrien	return "dec{w}\t%0";
638990286Sobrien      abort();
639090286Sobrien
639190286Sobrien    default:
639290286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
639390286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
639490286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
639590286Sobrien          && (INTVAL (operands[2]) == 128
639690286Sobrien	      || (INTVAL (operands[2]) < 0
639790286Sobrien		  && INTVAL (operands[2]) != -128)))
639818334Speter	{
639990286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
640090286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
640118334Speter	}
640290286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
640318334Speter    }
640490286Sobrien}
640590286Sobrien  [(set (attr "type")
640690286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
640790286Sobrien	(const_string "incdec")
640890286Sobrien	(const_string "alu")))
640990286Sobrien   (set_attr "mode" "HI")])
641018334Speter
641190286Sobrien(define_insn "*addhi_3"
641290286Sobrien  [(set (reg 17)
641390286Sobrien	(compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
641490286Sobrien		 (match_operand:HI 1 "nonimmediate_operand" "%0")))
641590286Sobrien   (clobber (match_scratch:HI 0 "=r"))]
641690286Sobrien  "ix86_match_ccmode (insn, CCZmode)
641790286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
641890286Sobrien{
641990286Sobrien  switch (get_attr_type (insn))
642090286Sobrien    {
642190286Sobrien    case TYPE_INCDEC:
642290286Sobrien      if (operands[2] == const1_rtx)
642390286Sobrien	return "inc{w}\t%0";
642490286Sobrien      else if (operands[2] == constm1_rtx
642590286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
642690286Sobrien		   && INTVAL (operands[2]) == 65535))
642790286Sobrien	return "dec{w}\t%0";
642890286Sobrien      abort();
642950650Sobrien
643090286Sobrien    default:
643190286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
643290286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
643390286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
643490286Sobrien          && (INTVAL (operands[2]) == 128
643590286Sobrien	      || (INTVAL (operands[2]) < 0
643690286Sobrien		  && INTVAL (operands[2]) != -128)))
643790286Sobrien	{
643890286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
643990286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
644090286Sobrien	}
644190286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
644290286Sobrien    }
644390286Sobrien}
644490286Sobrien  [(set (attr "type")
644590286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
644690286Sobrien	(const_string "incdec")
644790286Sobrien	(const_string "alu")))
644890286Sobrien   (set_attr "mode" "HI")])
644918334Speter
645090286Sobrien; See comments above addsi_3_imm for details.
645190286Sobrien(define_insn "*addhi_4"
645290286Sobrien  [(set (reg 17)
645390286Sobrien	(compare (match_operand:HI 1 "nonimmediate_operand" "0")
645490286Sobrien		 (match_operand:HI 2 "const_int_operand" "n")))
645590286Sobrien   (clobber (match_scratch:HI 0 "=rm"))]
645690286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
645790286Sobrien   && (INTVAL (operands[2]) & 0xffff) != 0x8000"
645890286Sobrien{
645990286Sobrien  switch (get_attr_type (insn))
646090286Sobrien    {
646190286Sobrien    case TYPE_INCDEC:
646290286Sobrien      if (operands[2] == constm1_rtx
646390286Sobrien	  || (GET_CODE (operands[2]) == CONST_INT
646490286Sobrien	      && INTVAL (operands[2]) == 65535))
646590286Sobrien        return "inc{w}\t%0";
646690286Sobrien      else if (operands[2] == const1_rtx)
646790286Sobrien        return "dec{w}\t%0";
646890286Sobrien      else
646990286Sobrien	abort();
647018334Speter
647190286Sobrien    default:
647290286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
647390286Sobrien	abort ();
647490286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
647590286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
647690286Sobrien      if ((INTVAL (operands[2]) == -128
647790286Sobrien	   || (INTVAL (operands[2]) > 0
647890286Sobrien	       && INTVAL (operands[2]) != 128)))
647990286Sobrien	return "sub{w}\t{%2, %0|%0, %2}";
648090286Sobrien      operands[2] = GEN_INT (-INTVAL (operands[2]));
648190286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
648250650Sobrien    }
648390286Sobrien}
648490286Sobrien  [(set (attr "type")
648590286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
648690286Sobrien	(const_string "incdec")
648790286Sobrien	(const_string "alu")))
648890286Sobrien   (set_attr "mode" "SI")])
648950650Sobrien
649018334Speter
649190286Sobrien(define_insn "*addhi_5"
649290286Sobrien  [(set (reg 17)
649390286Sobrien	(compare
649490286Sobrien	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
649590286Sobrien		   (match_operand:HI 2 "general_operand" "rmni"))
649690286Sobrien	  (const_int 0)))			
649790286Sobrien   (clobber (match_scratch:HI 0 "=r"))]
649890286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
649990286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
650050650Sobrien{
650190286Sobrien  switch (get_attr_type (insn))
650250650Sobrien    {
650390286Sobrien    case TYPE_INCDEC:
650490286Sobrien      if (operands[2] == const1_rtx)
650590286Sobrien	return "inc{w}\t%0";
650690286Sobrien      else if (operands[2] == constm1_rtx
650790286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
650890286Sobrien		   && INTVAL (operands[2]) == 65535))
650990286Sobrien	return "dec{w}\t%0";
651090286Sobrien      abort();
651150650Sobrien
651290286Sobrien    default:
651390286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
651490286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
651590286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
651690286Sobrien          && (INTVAL (operands[2]) == 128
651790286Sobrien	      || (INTVAL (operands[2]) < 0
651890286Sobrien		  && INTVAL (operands[2]) != -128)))
651990286Sobrien	{
652090286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
652190286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
652290286Sobrien	}
652390286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
652450650Sobrien    }
652590286Sobrien}
652690286Sobrien  [(set (attr "type")
652790286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
652890286Sobrien	(const_string "incdec")
652990286Sobrien	(const_string "alu")))
653090286Sobrien   (set_attr "mode" "HI")])
653150650Sobrien
653290286Sobrien(define_expand "addqi3"
653390286Sobrien  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
653490286Sobrien		   (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
653590286Sobrien			    (match_operand:QI 2 "general_operand" "")))
653690286Sobrien	      (clobber (reg:CC 17))])]
653790286Sobrien  "TARGET_QIMODE_MATH"
653890286Sobrien  "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
653950650Sobrien
654090286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
654190286Sobrien(define_insn "*addqi_1_lea"
654290286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
654390286Sobrien	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
654490286Sobrien		 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
654590286Sobrien   (clobber (reg:CC 17))]
654690286Sobrien  "!TARGET_PARTIAL_REG_STALL
654790286Sobrien   && ix86_binary_operator_ok (PLUS, QImode, operands)"
654890286Sobrien{
654990286Sobrien  int widen = (which_alternative == 2);
655090286Sobrien  switch (get_attr_type (insn))
655190286Sobrien    {
655290286Sobrien    case TYPE_LEA:
655390286Sobrien      return "#";
655490286Sobrien    case TYPE_INCDEC:
655590286Sobrien      if (operands[2] == const1_rtx)
655690286Sobrien	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
655790286Sobrien      else if (operands[2] == constm1_rtx
655890286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
655990286Sobrien		   && INTVAL (operands[2]) == 255))
656090286Sobrien	return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
656190286Sobrien      abort();
656218334Speter
656390286Sobrien    default:
656490286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
656590286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
656690286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
656790286Sobrien          && (INTVAL (operands[2]) == 128
656890286Sobrien	      || (INTVAL (operands[2]) < 0
656990286Sobrien		  && INTVAL (operands[2]) != -128)))
657090286Sobrien	{
657190286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
657290286Sobrien	  if (widen)
657390286Sobrien	    return "sub{l}\t{%2, %k0|%k0, %2}";
657490286Sobrien	  else
657590286Sobrien	    return "sub{b}\t{%2, %0|%0, %2}";
657690286Sobrien	}
657790286Sobrien      if (widen)
657890286Sobrien        return "add{l}\t{%k2, %k0|%k0, %k2}";
657990286Sobrien      else
658090286Sobrien        return "add{b}\t{%2, %0|%0, %2}";
658190286Sobrien    }
658290286Sobrien}
658390286Sobrien  [(set (attr "type")
658490286Sobrien     (if_then_else (eq_attr "alternative" "3")
658590286Sobrien	(const_string "lea")
658690286Sobrien	(if_then_else (match_operand:QI 2 "incdec_operand" "")
658790286Sobrien	   (const_string "incdec")
658890286Sobrien	   (const_string "alu"))))
658990286Sobrien   (set_attr "mode" "QI,QI,SI,SI")])
659050650Sobrien
659190286Sobrien(define_insn "*addqi_1"
659290286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
659390286Sobrien	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
659490286Sobrien		 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
659590286Sobrien   (clobber (reg:CC 17))]
659690286Sobrien  "TARGET_PARTIAL_REG_STALL
659790286Sobrien   && ix86_binary_operator_ok (PLUS, QImode, operands)"
659818334Speter{
659990286Sobrien  int widen = (which_alternative == 2);
660090286Sobrien  switch (get_attr_type (insn))
660152296Sobrien    {
660290286Sobrien    case TYPE_INCDEC:
660390286Sobrien      if (operands[2] == const1_rtx)
660490286Sobrien	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
660590286Sobrien      else if (operands[2] == constm1_rtx
660690286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
660790286Sobrien		   && INTVAL (operands[2]) == 255))
660890286Sobrien	return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
660990286Sobrien      abort();
661052296Sobrien
661190286Sobrien    default:
661290286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
661390286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
661490286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
661590286Sobrien          && (INTVAL (operands[2]) == 128
661690286Sobrien	      || (INTVAL (operands[2]) < 0
661790286Sobrien		  && INTVAL (operands[2]) != -128)))
661890286Sobrien	{
661990286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
662090286Sobrien	  if (widen)
662190286Sobrien	    return "sub{l}\t{%2, %k0|%k0, %2}";
662290286Sobrien	  else
662390286Sobrien	    return "sub{b}\t{%2, %0|%0, %2}";
662490286Sobrien	}
662590286Sobrien      if (widen)
662690286Sobrien        return "add{l}\t{%k2, %k0|%k0, %k2}";
662790286Sobrien      else
662890286Sobrien        return "add{b}\t{%2, %0|%0, %2}";
662952296Sobrien    }
663090286Sobrien}
663190286Sobrien  [(set (attr "type")
663290286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
663390286Sobrien	(const_string "incdec")
663490286Sobrien	(const_string "alu")))
663590286Sobrien   (set_attr "mode" "QI,QI,SI")])
663652296Sobrien
663790286Sobrien(define_insn "*addqi_2"
663890286Sobrien  [(set (reg 17)
663990286Sobrien	(compare
664090286Sobrien	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
664190286Sobrien		   (match_operand:QI 2 "general_operand" "qmni,qni"))
664290286Sobrien	  (const_int 0)))
664390286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
664490286Sobrien	(plus:QI (match_dup 1) (match_dup 2)))]
664590286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
664690286Sobrien   && ix86_binary_operator_ok (PLUS, QImode, operands)"
664790286Sobrien{
664890286Sobrien  switch (get_attr_type (insn))
664918334Speter    {
665090286Sobrien    case TYPE_INCDEC:
665190286Sobrien      if (operands[2] == const1_rtx)
665290286Sobrien	return "inc{b}\t%0";
665390286Sobrien      else if (operands[2] == constm1_rtx
665490286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
665590286Sobrien		   && INTVAL (operands[2]) == 255))
665690286Sobrien	return "dec{b}\t%0";
665790286Sobrien      abort();
665818334Speter
665990286Sobrien    default:
666090286Sobrien      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
666190286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
666290286Sobrien          && INTVAL (operands[2]) < 0)
666390286Sobrien	{
666490286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
666590286Sobrien	  return "sub{b}\t{%2, %0|%0, %2}";
666690286Sobrien	}
666790286Sobrien      return "add{b}\t{%2, %0|%0, %2}";
666818334Speter    }
666990286Sobrien}
667090286Sobrien  [(set (attr "type")
667190286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
667290286Sobrien	(const_string "incdec")
667390286Sobrien	(const_string "alu")))
667490286Sobrien   (set_attr "mode" "QI")])
667518334Speter
667690286Sobrien(define_insn "*addqi_3"
667790286Sobrien  [(set (reg 17)
667890286Sobrien	(compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
667990286Sobrien		 (match_operand:QI 1 "nonimmediate_operand" "%0")))
668090286Sobrien   (clobber (match_scratch:QI 0 "=q"))]
668190286Sobrien  "ix86_match_ccmode (insn, CCZmode)
668290286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
668390286Sobrien{
668490286Sobrien  switch (get_attr_type (insn))
668550650Sobrien    {
668690286Sobrien    case TYPE_INCDEC:
668790286Sobrien      if (operands[2] == const1_rtx)
668890286Sobrien	return "inc{b}\t%0";
668990286Sobrien      else if (operands[2] == constm1_rtx
669090286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
669190286Sobrien		   && INTVAL (operands[2]) == 255))
669290286Sobrien	return "dec{b}\t%0";
669390286Sobrien      abort();
669450650Sobrien
669590286Sobrien    default:
669690286Sobrien      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
669790286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
669890286Sobrien          && INTVAL (operands[2]) < 0)
669950650Sobrien	{
670090286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
670190286Sobrien	  return "sub{b}\t{%2, %0|%0, %2}";
670290286Sobrien	}
670390286Sobrien      return "add{b}\t{%2, %0|%0, %2}";
670490286Sobrien    }
670590286Sobrien}
670690286Sobrien  [(set (attr "type")
670790286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
670890286Sobrien	(const_string "incdec")
670990286Sobrien	(const_string "alu")))
671090286Sobrien   (set_attr "mode" "QI")])
671150650Sobrien
671290286Sobrien; See comments above addsi_3_imm for details.
671390286Sobrien(define_insn "*addqi_4"
671490286Sobrien  [(set (reg 17)
671590286Sobrien	(compare (match_operand:QI 1 "nonimmediate_operand" "0")
671690286Sobrien		 (match_operand:QI 2 "const_int_operand" "n")))
671790286Sobrien   (clobber (match_scratch:QI 0 "=qm"))]
671890286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
671990286Sobrien   && (INTVAL (operands[2]) & 0xff) != 0x80"
672090286Sobrien{
672190286Sobrien  switch (get_attr_type (insn))
672290286Sobrien    {
672390286Sobrien    case TYPE_INCDEC:
672490286Sobrien      if (operands[2] == constm1_rtx
672590286Sobrien	  || (GET_CODE (operands[2]) == CONST_INT
672690286Sobrien	      && INTVAL (operands[2]) == 255))
672790286Sobrien        return "inc{b}\t%0";
672890286Sobrien      else if (operands[2] == const1_rtx)
672990286Sobrien        return "dec{b}\t%0";
673090286Sobrien      else
673190286Sobrien	abort();
673250650Sobrien
673390286Sobrien    default:
673490286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
673590286Sobrien	abort ();
673690286Sobrien      if (INTVAL (operands[2]) < 0)
673790286Sobrien        {
673890286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
673990286Sobrien          return "add{b}\t{%2, %0|%0, %2}";
674090286Sobrien        }
674190286Sobrien      return "sub{b}\t{%2, %0|%0, %2}";
674250650Sobrien    }
674390286Sobrien}
674490286Sobrien  [(set (attr "type")
674590286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
674690286Sobrien	(const_string "incdec")
674790286Sobrien	(const_string "alu")))
674890286Sobrien   (set_attr "mode" "QI")])
674950650Sobrien
675018334Speter
675190286Sobrien(define_insn "*addqi_5"
675290286Sobrien  [(set (reg 17)
675390286Sobrien	(compare
675490286Sobrien	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
675590286Sobrien		   (match_operand:QI 2 "general_operand" "qmni"))
675690286Sobrien	  (const_int 0)))
675790286Sobrien   (clobber (match_scratch:QI 0 "=q"))]
675890286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
675990286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
676090286Sobrien{
676190286Sobrien  switch (get_attr_type (insn))
676290286Sobrien    {
676390286Sobrien    case TYPE_INCDEC:
676490286Sobrien      if (operands[2] == const1_rtx)
676590286Sobrien	return "inc{b}\t%0";
676690286Sobrien      else if (operands[2] == constm1_rtx
676790286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
676890286Sobrien		   && INTVAL (operands[2]) == 255))
676990286Sobrien	return "dec{b}\t%0";
677090286Sobrien      abort();
677118334Speter
677290286Sobrien    default:
677390286Sobrien      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
677490286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
677590286Sobrien          && INTVAL (operands[2]) < 0)
677690286Sobrien	{
677790286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
677890286Sobrien	  return "sub{b}\t{%2, %0|%0, %2}";
677990286Sobrien	}
678090286Sobrien      return "add{b}\t{%2, %0|%0, %2}";
678190286Sobrien    }
678290286Sobrien}
678390286Sobrien  [(set (attr "type")
678490286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
678590286Sobrien	(const_string "incdec")
678690286Sobrien	(const_string "alu")))
678790286Sobrien   (set_attr "mode" "QI")])
678818334Speter
678950650Sobrien
679090286Sobrien(define_insn "addqi_ext_1"
679190286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
679290286Sobrien			 (const_int 8)
679390286Sobrien			 (const_int 8))
679490286Sobrien	(plus:SI
679590286Sobrien	  (zero_extract:SI
679690286Sobrien	    (match_operand 1 "ext_register_operand" "0")
679790286Sobrien	    (const_int 8)
679890286Sobrien	    (const_int 8))
679990286Sobrien	  (match_operand:QI 2 "general_operand" "Qmn")))
680090286Sobrien   (clobber (reg:CC 17))]
680190286Sobrien  "!TARGET_64BIT"
680218334Speter{
680390286Sobrien  switch (get_attr_type (insn))
680452296Sobrien    {
680590286Sobrien    case TYPE_INCDEC:
680690286Sobrien      if (operands[2] == const1_rtx)
680790286Sobrien	return "inc{b}\t%h0";
680890286Sobrien      else if (operands[2] == constm1_rtx
680990286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
681090286Sobrien		   && INTVAL (operands[2]) == 255))
681190286Sobrien	return "dec{b}\t%h0";
681290286Sobrien      abort();
681352296Sobrien
681490286Sobrien    default:
681590286Sobrien      return "add{b}\t{%2, %h0|%h0, %2}";
681652296Sobrien    }
681790286Sobrien}
681890286Sobrien  [(set (attr "type")
681990286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
682090286Sobrien	(const_string "incdec")
682190286Sobrien	(const_string "alu")))
682290286Sobrien   (set_attr "mode" "QI")])
682318334Speter
682490286Sobrien(define_insn "*addqi_ext_1_rex64"
682590286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
682690286Sobrien			 (const_int 8)
682790286Sobrien			 (const_int 8))
682890286Sobrien	(plus:SI
682990286Sobrien	  (zero_extract:SI
683090286Sobrien	    (match_operand 1 "ext_register_operand" "0")
683190286Sobrien	    (const_int 8)
683290286Sobrien	    (const_int 8))
683390286Sobrien	  (match_operand:QI 2 "nonmemory_operand" "Qn")))
683490286Sobrien   (clobber (reg:CC 17))]
683590286Sobrien  "TARGET_64BIT"
683690286Sobrien{
683790286Sobrien  switch (get_attr_type (insn))
683890286Sobrien    {
683990286Sobrien    case TYPE_INCDEC:
684090286Sobrien      if (operands[2] == const1_rtx)
684190286Sobrien	return "inc{b}\t%h0";
684290286Sobrien      else if (operands[2] == constm1_rtx
684390286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
684490286Sobrien		   && INTVAL (operands[2]) == 255))
684590286Sobrien	return "dec{b}\t%h0";
684690286Sobrien      abort();
684718334Speter
684890286Sobrien    default:
684990286Sobrien      return "add{b}\t{%2, %h0|%h0, %2}";
685090286Sobrien    }
685190286Sobrien}
685290286Sobrien  [(set (attr "type")
685390286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
685490286Sobrien	(const_string "incdec")
685590286Sobrien	(const_string "alu")))
685690286Sobrien   (set_attr "mode" "QI")])
685718334Speter
685890286Sobrien(define_insn "*addqi_ext_2"
685990286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
686090286Sobrien			 (const_int 8)
686190286Sobrien			 (const_int 8))
686290286Sobrien	(plus:SI
686390286Sobrien	  (zero_extract:SI
686490286Sobrien	    (match_operand 1 "ext_register_operand" "%0")
686590286Sobrien	    (const_int 8)
686690286Sobrien	    (const_int 8))
686790286Sobrien	  (zero_extract:SI
686890286Sobrien	    (match_operand 2 "ext_register_operand" "Q")
686990286Sobrien	    (const_int 8)
687090286Sobrien	    (const_int 8))))
687190286Sobrien   (clobber (reg:CC 17))]
687290286Sobrien  ""
687390286Sobrien  "add{b}\t{%h2, %h0|%h0, %h2}"
687490286Sobrien  [(set_attr "type" "alu")
687590286Sobrien   (set_attr "mode" "QI")])
687618334Speter
687718334Speter;; The patterns that match these are at the end of this file.
687818334Speter
687918334Speter(define_expand "addxf3"
688018334Speter  [(set (match_operand:XF 0 "register_operand" "")
688150650Sobrien	(plus:XF (match_operand:XF 1 "register_operand" "")
688250650Sobrien		 (match_operand:XF 2 "register_operand" "")))]
688390286Sobrien  "!TARGET_64BIT && TARGET_80387"
688490286Sobrien  "")
688590286Sobrien
688690286Sobrien(define_expand "addtf3"
688790286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
688890286Sobrien	(plus:TF (match_operand:TF 1 "register_operand" "")
688990286Sobrien		 (match_operand:TF 2 "register_operand" "")))]
689018334Speter  "TARGET_80387"
689118334Speter  "")
689218334Speter
689318334Speter(define_expand "adddf3"
689418334Speter  [(set (match_operand:DF 0 "register_operand" "")
689590286Sobrien	(plus:DF (match_operand:DF 1 "register_operand" "")
689618334Speter		 (match_operand:DF 2 "nonimmediate_operand" "")))]
689790286Sobrien  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
689818334Speter  "")
689918334Speter
690018334Speter(define_expand "addsf3"
690118334Speter  [(set (match_operand:SF 0 "register_operand" "")
690290286Sobrien	(plus:SF (match_operand:SF 1 "register_operand" "")
690318334Speter		 (match_operand:SF 2 "nonimmediate_operand" "")))]
690490286Sobrien  "TARGET_80387 || TARGET_SSE_MATH"
690518334Speter  "")
690618334Speter
690790286Sobrien;; Subtract instructions
690818334Speter
690990286Sobrien;; %%% splits for subsidi3
691050650Sobrien
691190286Sobrien(define_expand "subdi3"
691290286Sobrien  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
691390286Sobrien		   (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
691490286Sobrien			     (match_operand:DI 2 "x86_64_general_operand" "")))
691590286Sobrien	      (clobber (reg:CC 17))])]
691618334Speter  ""
691790286Sobrien  "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
691818334Speter
691990286Sobrien(define_insn "*subdi3_1"
692090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
692190286Sobrien	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
692290286Sobrien		  (match_operand:DI 2 "general_operand" "roiF,riF")))
692390286Sobrien   (clobber (reg:CC 17))]
692490286Sobrien  "!TARGET_64BIT"
692590286Sobrien  "#")
692618334Speter
692790286Sobrien(define_split
692890286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
692990286Sobrien	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
693090286Sobrien		  (match_operand:DI 2 "general_operand" "")))
693190286Sobrien   (clobber (reg:CC 17))]
693290286Sobrien  "!TARGET_64BIT && reload_completed"
693390286Sobrien  [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
693490286Sobrien	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
693590286Sobrien   (parallel [(set (match_dup 3)
693690286Sobrien		   (minus:SI (match_dup 4)
693790286Sobrien			     (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
693890286Sobrien				      (match_dup 5))))
693990286Sobrien	      (clobber (reg:CC 17))])]
694090286Sobrien  "split_di (operands+0, 1, operands+0, operands+3);
694190286Sobrien   split_di (operands+1, 1, operands+1, operands+4);
694290286Sobrien   split_di (operands+2, 1, operands+2, operands+5);")
694318334Speter
694490286Sobrien(define_insn "subdi3_carry_rex64"
694590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
694690286Sobrien	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
694790286Sobrien	    (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
694890286Sobrien	       (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
694990286Sobrien   (clobber (reg:CC 17))]
695090286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
695190286Sobrien  "sbb{q}\t{%2, %0|%0, %2}"
695290286Sobrien  [(set_attr "type" "alu")
695390286Sobrien   (set_attr "pent_pair" "pu")
695490286Sobrien   (set_attr "ppro_uops" "few")
695590286Sobrien   (set_attr "mode" "DI")])
695618334Speter
695790286Sobrien(define_insn "*subdi_1_rex64"
695890286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
695990286Sobrien	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
696090286Sobrien		  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
696190286Sobrien   (clobber (reg:CC 17))]
696290286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
696390286Sobrien  "sub{q}\t{%2, %0|%0, %2}"
696490286Sobrien  [(set_attr "type" "alu")
696590286Sobrien   (set_attr "mode" "DI")])
696618334Speter
696790286Sobrien(define_insn "*subdi_2_rex64"
696890286Sobrien  [(set (reg 17)
696990286Sobrien	(compare
697090286Sobrien	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
697190286Sobrien		    (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
697290286Sobrien	  (const_int 0)))
697390286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
697490286Sobrien	(minus:DI (match_dup 1) (match_dup 2)))]
697590286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
697690286Sobrien   && ix86_binary_operator_ok (MINUS, DImode, operands)"
697790286Sobrien  "sub{q}\t{%2, %0|%0, %2}"
697890286Sobrien  [(set_attr "type" "alu")
697990286Sobrien   (set_attr "mode" "DI")])
698052296Sobrien
698190286Sobrien(define_insn "*subdi_3_rex63"
698290286Sobrien  [(set (reg 17)
698390286Sobrien	(compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
698490286Sobrien		 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
698590286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
698690286Sobrien	(minus:DI (match_dup 1) (match_dup 2)))]
698790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
698890286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
698990286Sobrien  "sub{q}\t{%2, %0|%0, %2}"
699090286Sobrien  [(set_attr "type" "alu")
699190286Sobrien   (set_attr "mode" "DI")])
699218334Speter
699318334Speter
699490286Sobrien(define_insn "subsi3_carry"
699590286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
699690286Sobrien	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
699790286Sobrien	    (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
699890286Sobrien	       (match_operand:SI 2 "general_operand" "ri,rm"))))
699990286Sobrien   (clobber (reg:CC 17))]
700090286Sobrien  "ix86_binary_operator_ok (MINUS, SImode, operands)"
700190286Sobrien  "sbb{l}\t{%2, %0|%0, %2}"
700290286Sobrien  [(set_attr "type" "alu")
700390286Sobrien   (set_attr "pent_pair" "pu")
700490286Sobrien   (set_attr "ppro_uops" "few")
700590286Sobrien   (set_attr "mode" "SI")])
700618334Speter
700790286Sobrien(define_insn "subsi3_carry_zext"
700890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=rm,r")
700990286Sobrien	  (zero_extend:DI
701090286Sobrien	    (minus:SI (match_operand:SI 1 "register_operand" "0,0")
701190286Sobrien	      (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
701290286Sobrien		 (match_operand:SI 2 "general_operand" "ri,rm")))))
701390286Sobrien   (clobber (reg:CC 17))]
701490286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
701590286Sobrien  "sbb{l}\t{%2, %k0|%k0, %2}"
701690286Sobrien  [(set_attr "type" "alu")
701790286Sobrien   (set_attr "pent_pair" "pu")
701890286Sobrien   (set_attr "ppro_uops" "few")
701990286Sobrien   (set_attr "mode" "SI")])
702018334Speter
702150650Sobrien(define_expand "subsi3"
702290286Sobrien  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
702390286Sobrien		   (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
702490286Sobrien			     (match_operand:SI 2 "general_operand" "")))
702590286Sobrien	      (clobber (reg:CC 17))])]
702650650Sobrien  ""
702790286Sobrien  "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
702850650Sobrien
702990286Sobrien(define_insn "*subsi_1"
703050650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
703150650Sobrien	(minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
703290286Sobrien		  (match_operand:SI 2 "general_operand" "ri,rm")))
703390286Sobrien   (clobber (reg:CC 17))]
703450650Sobrien  "ix86_binary_operator_ok (MINUS, SImode, operands)"
703590286Sobrien  "sub{l}\t{%2, %0|%0, %2}"
703690286Sobrien  [(set_attr "type" "alu")
703790286Sobrien   (set_attr "mode" "SI")])
703818334Speter
703990286Sobrien(define_insn "*subsi_1_zext"
704090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
704190286Sobrien	(zero_extend:DI
704290286Sobrien	  (minus:SI (match_operand:SI 1 "register_operand" "0")
704390286Sobrien		    (match_operand:SI 2 "general_operand" "rim"))))
704490286Sobrien   (clobber (reg:CC 17))]
704590286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
704690286Sobrien  "sub{l}\t{%2, %k0|%k0, %2}"
704790286Sobrien  [(set_attr "type" "alu")
704890286Sobrien   (set_attr "mode" "SI")])
704990286Sobrien
705090286Sobrien(define_insn "*subsi_2"
705190286Sobrien  [(set (reg 17)
705290286Sobrien	(compare
705390286Sobrien	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
705490286Sobrien		    (match_operand:SI 2 "general_operand" "ri,rm"))
705590286Sobrien	  (const_int 0)))
705690286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
705790286Sobrien	(minus:SI (match_dup 1) (match_dup 2)))]
705890286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
705990286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
706090286Sobrien  "sub{l}\t{%2, %0|%0, %2}"
706190286Sobrien  [(set_attr "type" "alu")
706290286Sobrien   (set_attr "mode" "SI")])
706390286Sobrien
706490286Sobrien(define_insn "*subsi_2_zext"
706590286Sobrien  [(set (reg 17)
706690286Sobrien	(compare
706790286Sobrien	  (minus:SI (match_operand:SI 1 "register_operand" "0")
706890286Sobrien		    (match_operand:SI 2 "general_operand" "rim"))
706990286Sobrien	  (const_int 0)))
707090286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
707190286Sobrien	(zero_extend:DI
707290286Sobrien	  (minus:SI (match_dup 1)
707390286Sobrien		    (match_dup 2))))]
707490286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
707590286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
707690286Sobrien  "sub{l}\t{%2, %k0|%k0, %2}"
707790286Sobrien  [(set_attr "type" "alu")
707890286Sobrien   (set_attr "mode" "SI")])
707990286Sobrien
708090286Sobrien(define_insn "*subsi_3"
708190286Sobrien  [(set (reg 17)
708290286Sobrien	(compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
708390286Sobrien		 (match_operand:SI 2 "general_operand" "ri,rm")))
708490286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
708590286Sobrien	(minus:SI (match_dup 1) (match_dup 2)))]
708690286Sobrien  "ix86_match_ccmode (insn, CCmode)
708790286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
708890286Sobrien  "sub{l}\t{%2, %0|%0, %2}"
708990286Sobrien  [(set_attr "type" "alu")
709090286Sobrien   (set_attr "mode" "SI")])
709190286Sobrien
709290286Sobrien(define_insn "*subsi_3_zext"
709390286Sobrien  [(set (reg 17)
709490286Sobrien	(compare (match_operand:SI 1 "nonimmediate_operand" "0")
709590286Sobrien		 (match_operand:SI 2 "general_operand" "rim")))
709690286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
709790286Sobrien	(zero_extend:DI
709890286Sobrien	  (minus:SI (match_dup 1)
709990286Sobrien		    (match_dup 2))))]
710090286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
710190286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
710290286Sobrien  "sub{q}\t{%2, %0|%0, %2}"
710390286Sobrien  [(set_attr "type" "alu")
710490286Sobrien   (set_attr "mode" "DI")])
710590286Sobrien
710650650Sobrien(define_expand "subhi3"
710790286Sobrien  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
710890286Sobrien		   (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
710990286Sobrien			     (match_operand:HI 2 "general_operand" "")))
711090286Sobrien	      (clobber (reg:CC 17))])]
711190286Sobrien  "TARGET_HIMODE_MATH"
711290286Sobrien  "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
711350650Sobrien
711490286Sobrien(define_insn "*subhi_1"
711550650Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
711650650Sobrien	(minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
711790286Sobrien		  (match_operand:HI 2 "general_operand" "ri,rm")))
711890286Sobrien   (clobber (reg:CC 17))]
711950650Sobrien  "ix86_binary_operator_ok (MINUS, HImode, operands)"
712090286Sobrien  "sub{w}\t{%2, %0|%0, %2}"
712190286Sobrien  [(set_attr "type" "alu")
712290286Sobrien   (set_attr "mode" "HI")])
712350650Sobrien
712490286Sobrien(define_insn "*subhi_2"
712590286Sobrien  [(set (reg 17)
712690286Sobrien	(compare
712790286Sobrien	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
712890286Sobrien		    (match_operand:HI 2 "general_operand" "ri,rm"))
712990286Sobrien	  (const_int 0)))
713090286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
713190286Sobrien	(minus:HI (match_dup 1) (match_dup 2)))]
713290286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
713390286Sobrien   && ix86_binary_operator_ok (MINUS, HImode, operands)"
713490286Sobrien  "sub{w}\t{%2, %0|%0, %2}"
713590286Sobrien  [(set_attr "type" "alu")
713690286Sobrien   (set_attr "mode" "HI")])
713790286Sobrien
713890286Sobrien(define_insn "*subhi_3"
713990286Sobrien  [(set (reg 17)
714090286Sobrien	(compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
714190286Sobrien		 (match_operand:HI 2 "general_operand" "ri,rm")))
714290286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
714390286Sobrien	(minus:HI (match_dup 1) (match_dup 2)))]
714490286Sobrien  "ix86_match_ccmode (insn, CCmode)
714590286Sobrien   && ix86_binary_operator_ok (MINUS, HImode, operands)"
714690286Sobrien  "sub{w}\t{%2, %0|%0, %2}"
714790286Sobrien  [(set_attr "type" "alu")
714890286Sobrien   (set_attr "mode" "HI")])
714990286Sobrien
715050650Sobrien(define_expand "subqi3"
715190286Sobrien  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
715290286Sobrien		   (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
715390286Sobrien			     (match_operand:QI 2 "general_operand" "")))
715490286Sobrien	      (clobber (reg:CC 17))])]
715590286Sobrien  "TARGET_QIMODE_MATH"
715690286Sobrien  "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
715718334Speter
715890286Sobrien(define_insn "*subqi_1"
715950650Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
716050650Sobrien	(minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
716190286Sobrien		  (match_operand:QI 2 "general_operand" "qn,qmn")))
716290286Sobrien   (clobber (reg:CC 17))]
716350650Sobrien  "ix86_binary_operator_ok (MINUS, QImode, operands)"
716490286Sobrien  "sub{b}\t{%2, %0|%0, %2}"
716590286Sobrien  [(set_attr "type" "alu")
716690286Sobrien   (set_attr "mode" "QI")])
716718334Speter
716890286Sobrien(define_insn "*subqi_2"
716990286Sobrien  [(set (reg 17)
717090286Sobrien	(compare
717190286Sobrien	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
717290286Sobrien		    (match_operand:QI 2 "general_operand" "qi,qm"))
717390286Sobrien	  (const_int 0)))
717490286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
717590286Sobrien	(minus:HI (match_dup 1) (match_dup 2)))]
717690286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
717790286Sobrien   && ix86_binary_operator_ok (MINUS, QImode, operands)"
717890286Sobrien  "sub{b}\t{%2, %0|%0, %2}"
717990286Sobrien  [(set_attr "type" "alu")
718090286Sobrien   (set_attr "mode" "QI")])
718190286Sobrien
718290286Sobrien(define_insn "*subqi_3"
718390286Sobrien  [(set (reg 17)
718490286Sobrien	(compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
718590286Sobrien		 (match_operand:QI 2 "general_operand" "qi,qm")))
718690286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
718790286Sobrien	(minus:HI (match_dup 1) (match_dup 2)))]
718890286Sobrien  "ix86_match_ccmode (insn, CCmode)
718990286Sobrien   && ix86_binary_operator_ok (MINUS, QImode, operands)"
719090286Sobrien  "sub{b}\t{%2, %0|%0, %2}"
719190286Sobrien  [(set_attr "type" "alu")
719290286Sobrien   (set_attr "mode" "QI")])
719390286Sobrien
719418334Speter;; The patterns that match these are at the end of this file.
719518334Speter
719618334Speter(define_expand "subxf3"
719718334Speter  [(set (match_operand:XF 0 "register_operand" "")
719850650Sobrien	(minus:XF (match_operand:XF 1 "register_operand" "")
719950650Sobrien		  (match_operand:XF 2 "register_operand" "")))]
720090286Sobrien  "!TARGET_64BIT && TARGET_80387"
720190286Sobrien  "")
720290286Sobrien
720390286Sobrien(define_expand "subtf3"
720490286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
720590286Sobrien	(minus:TF (match_operand:TF 1 "register_operand" "")
720690286Sobrien		  (match_operand:TF 2 "register_operand" "")))]
720718334Speter  "TARGET_80387"
720818334Speter  "")
720918334Speter
721018334Speter(define_expand "subdf3"
721118334Speter  [(set (match_operand:DF 0 "register_operand" "")
721290286Sobrien	(minus:DF (match_operand:DF 1 "register_operand" "")
721318334Speter		  (match_operand:DF 2 "nonimmediate_operand" "")))]
721490286Sobrien  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
721518334Speter  "")
721618334Speter
721718334Speter(define_expand "subsf3"
721818334Speter  [(set (match_operand:SF 0 "register_operand" "")
721990286Sobrien	(minus:SF (match_operand:SF 1 "register_operand" "")
722018334Speter		  (match_operand:SF 2 "nonimmediate_operand" "")))]
722190286Sobrien  "TARGET_80387 || TARGET_SSE_MATH"
722218334Speter  "")
722318334Speter
722490286Sobrien;; Multiply instructions
722518334Speter
722690286Sobrien(define_expand "muldi3"
722790286Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
722890286Sobrien		   (mult:DI (match_operand:DI 1 "register_operand" "")
722990286Sobrien			    (match_operand:DI 2 "x86_64_general_operand" "")))
723090286Sobrien	      (clobber (reg:CC 17))])]
723190286Sobrien  "TARGET_64BIT"
723290286Sobrien  "")
723318334Speter
723490286Sobrien(define_insn "*muldi3_1_rex64"
723590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
723690286Sobrien	(mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,0,0")
723790286Sobrien		 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
723890286Sobrien   (clobber (reg:CC 17))]
723990286Sobrien  "TARGET_64BIT
724090286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
724190286Sobrien  "@
724290286Sobrien   imul{q}\t{%2, %1, %0|%0, %1, %2}
724390286Sobrien   imul{q}\t{%2, %1, %0|%0, %1, %2}
724490286Sobrien   imul{q}\t{%2, %0|%0, %2}"
724590286Sobrien  [(set_attr "type" "imul")
724690286Sobrien   (set_attr "prefix_0f" "0,0,1")
724790286Sobrien   (set_attr "mode" "DI")])
724818334Speter
724990286Sobrien(define_expand "mulsi3"
725090286Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "")
725190286Sobrien		   (mult:SI (match_operand:SI 1 "register_operand" "")
725290286Sobrien			    (match_operand:SI 2 "general_operand" "")))
725390286Sobrien	      (clobber (reg:CC 17))])]
725418334Speter  ""
725590286Sobrien  "")
725618334Speter
725790286Sobrien(define_insn "*mulsi3_1"
725890286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
725990286Sobrien	(mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
726090286Sobrien		 (match_operand:SI 2 "general_operand" "K,i,mr")))
726190286Sobrien   (clobber (reg:CC 17))]
726290286Sobrien  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
726390286Sobrien  ; For the {r,0,i} alternative (i.e., register <- register * immediate),
726490286Sobrien  ; there are two ways of writing the exact same machine instruction
726590286Sobrien  ; in assembly language.  One, for example, is:
726690286Sobrien  ;
726790286Sobrien  ;   imul $12, %eax
726890286Sobrien  ;
726990286Sobrien  ; while the other is:
727090286Sobrien  ;
727190286Sobrien  ;   imul $12, %eax, %eax
727290286Sobrien  ;
727390286Sobrien  ; The first is simply short-hand for the latter.  But, some assemblers,
727490286Sobrien  ; like the SCO OSR5 COFF assembler, don't handle the first form.
727590286Sobrien  "@
727690286Sobrien   imul{l}\t{%2, %1, %0|%0, %1, %2}
727790286Sobrien   imul{l}\t{%2, %1, %0|%0, %1, %2}
727890286Sobrien   imul{l}\t{%2, %0|%0, %2}"
727990286Sobrien  [(set_attr "type" "imul")
728090286Sobrien   (set_attr "prefix_0f" "0,0,1")
728190286Sobrien   (set_attr "mode" "SI")])
728290286Sobrien
728390286Sobrien(define_insn "*mulsi3_1_zext"
728490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
728590286Sobrien	(zero_extend:DI
728690286Sobrien	  (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
728790286Sobrien		   (match_operand:SI 2 "general_operand" "K,i,mr"))))
728890286Sobrien   (clobber (reg:CC 17))]
728990286Sobrien  "TARGET_64BIT
729090286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
729190286Sobrien  ; For the {r,0,i} alternative (i.e., register <- register * immediate),
729290286Sobrien  ; there are two ways of writing the exact same machine instruction
729390286Sobrien  ; in assembly language.  One, for example, is:
729490286Sobrien  ;
729590286Sobrien  ;   imul $12, %eax
729690286Sobrien  ;
729790286Sobrien  ; while the other is:
729890286Sobrien  ;
729990286Sobrien  ;   imul $12, %eax, %eax
730090286Sobrien  ;
730190286Sobrien  ; The first is simply short-hand for the latter.  But, some assemblers,
730290286Sobrien  ; like the SCO OSR5 COFF assembler, don't handle the first form.
730390286Sobrien  "@
730490286Sobrien   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
730590286Sobrien   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
730690286Sobrien   imul{l}\t{%2, %k0|%k0, %2}"
730790286Sobrien  [(set_attr "type" "imul")
730890286Sobrien   (set_attr "prefix_0f" "0,0,1")
730990286Sobrien   (set_attr "mode" "SI")])
731090286Sobrien
731190286Sobrien(define_expand "mulhi3"
731290286Sobrien  [(parallel [(set (match_operand:HI 0 "register_operand" "")
731390286Sobrien		   (mult:HI (match_operand:HI 1 "register_operand" "")
731490286Sobrien			    (match_operand:HI 2 "general_operand" "")))
731590286Sobrien	      (clobber (reg:CC 17))])]
731690286Sobrien  "TARGET_HIMODE_MATH"
731790286Sobrien  "")
731890286Sobrien
731990286Sobrien(define_insn "*mulhi3_1"
732090286Sobrien  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
732190286Sobrien	(mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0")
732290286Sobrien		 (match_operand:HI 2 "general_operand" "K,i,mr")))
732390286Sobrien   (clobber (reg:CC 17))]
732490286Sobrien  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
732590286Sobrien  ; %%% There was a note about "Assembler has weird restrictions",
732690286Sobrien  ; concerning alternative 1 when op1 == op0.  True?
732790286Sobrien  "@
732890286Sobrien   imul{w}\t{%2, %1, %0|%0, %1, %2}
732990286Sobrien   imul{w}\t{%2, %1, %0|%0, %1, %2}
733090286Sobrien   imul{w}\t{%2, %0|%0, %2}"
733190286Sobrien  [(set_attr "type" "imul")
733290286Sobrien   (set_attr "prefix_0f" "0,0,1")
733390286Sobrien   (set_attr "mode" "HI")])
733490286Sobrien
733590286Sobrien(define_insn "mulqi3"
733690286Sobrien  [(set (match_operand:QI 0 "register_operand" "=a")
733790286Sobrien	(mult:QI (match_operand:QI 1 "register_operand" "%0")
733890286Sobrien		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
733990286Sobrien   (clobber (reg:CC 17))]
734090286Sobrien  "TARGET_QIMODE_MATH"
734190286Sobrien  "mul{b}\t%2"
734290286Sobrien  [(set_attr "type" "imul")
734390286Sobrien   (set_attr "length_immediate" "0")
734490286Sobrien   (set_attr "mode" "QI")])
734590286Sobrien
734618334Speter(define_insn "umulqihi3"
734750650Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
734850650Sobrien	(mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
734990286Sobrien		 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
735090286Sobrien   (clobber (reg:CC 17))]
735190286Sobrien  "TARGET_QIMODE_MATH"
735290286Sobrien  "mul{b}\t%2"
735390286Sobrien  [(set_attr "type" "imul")
735490286Sobrien   (set_attr "length_immediate" "0")
735590286Sobrien   (set_attr "mode" "QI")])
735618334Speter
735718334Speter(define_insn "mulqihi3"
735850650Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
735950650Sobrien	(mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
736090286Sobrien		 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
736190286Sobrien   (clobber (reg:CC 17))]
736290286Sobrien  "TARGET_QIMODE_MATH"
736390286Sobrien  "imul{b}\t%2"
736490286Sobrien  [(set_attr "type" "imul")
736590286Sobrien   (set_attr "length_immediate" "0")
736690286Sobrien   (set_attr "mode" "QI")])
736718334Speter
736890286Sobrien(define_insn "umulditi3"
736990286Sobrien  [(set (match_operand:TI 0 "register_operand" "=A")
737090286Sobrien	(mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "%0"))
737190286Sobrien		 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
737290286Sobrien   (clobber (reg:CC 17))]
737390286Sobrien  "TARGET_64BIT"
737490286Sobrien  "mul{q}\t%2"
737590286Sobrien  [(set_attr "type" "imul")
737690286Sobrien   (set_attr "ppro_uops" "few")
737790286Sobrien   (set_attr "length_immediate" "0")
737890286Sobrien   (set_attr "mode" "DI")])
737990286Sobrien
738090286Sobrien;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
738118334Speter(define_insn "umulsidi3"
738218334Speter  [(set (match_operand:DI 0 "register_operand" "=A")
738318334Speter	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
738490286Sobrien		 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
738590286Sobrien   (clobber (reg:CC 17))]
738690286Sobrien  "!TARGET_64BIT"
738790286Sobrien  "mul{l}\t%2"
738890286Sobrien  [(set_attr "type" "imul")
738990286Sobrien   (set_attr "ppro_uops" "few")
739090286Sobrien   (set_attr "length_immediate" "0")
739190286Sobrien   (set_attr "mode" "SI")])
739218334Speter
739390286Sobrien(define_insn "mulditi3"
739490286Sobrien  [(set (match_operand:TI 0 "register_operand" "=A")
739590286Sobrien	(mult:TI (sign_extend:TI (match_operand:DI 1 "register_operand" "%0"))
739690286Sobrien		 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
739790286Sobrien   (clobber (reg:CC 17))]
739890286Sobrien  "TARGET_64BIT"
739990286Sobrien  "imul{q}\t%2"
740090286Sobrien  [(set_attr "type" "imul")
740190286Sobrien   (set_attr "length_immediate" "0")
740290286Sobrien   (set_attr "mode" "DI")])
740390286Sobrien
740418334Speter(define_insn "mulsidi3"
740518334Speter  [(set (match_operand:DI 0 "register_operand" "=A")
740618334Speter	(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
740790286Sobrien		 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
740890286Sobrien   (clobber (reg:CC 17))]
740990286Sobrien  "!TARGET_64BIT"
741090286Sobrien  "imul{l}\t%2"
741190286Sobrien  [(set_attr "type" "imul")
741290286Sobrien   (set_attr "length_immediate" "0")
741390286Sobrien   (set_attr "mode" "SI")])
741418334Speter
741590286Sobrien(define_insn "*umuldi3_highpart_rex64"
741690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
741790286Sobrien	(truncate:DI
741890286Sobrien	  (lshiftrt:TI
741990286Sobrien	    (mult:TI (zero_extend:TI
742090286Sobrien		       (match_operand:DI 1 "register_operand" "%a"))
742190286Sobrien		     (zero_extend:TI
742290286Sobrien		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
742390286Sobrien	    (const_int 64))))
742490286Sobrien   (clobber (match_scratch:DI 3 "=a"))
742590286Sobrien   (clobber (reg:CC 17))]
742690286Sobrien  "TARGET_64BIT"
742790286Sobrien  "mul{q}\t%2"
742890286Sobrien  [(set_attr "type" "imul")
742990286Sobrien   (set_attr "ppro_uops" "few")
743090286Sobrien   (set_attr "length_immediate" "0")
743190286Sobrien   (set_attr "mode" "DI")])
743290286Sobrien
743318334Speter(define_insn "umulsi3_highpart"
743418334Speter  [(set (match_operand:SI 0 "register_operand" "=d")
743590286Sobrien	(truncate:SI
743690286Sobrien	  (lshiftrt:DI
743790286Sobrien	    (mult:DI (zero_extend:DI
743890286Sobrien		       (match_operand:SI 1 "register_operand" "%a"))
743990286Sobrien		     (zero_extend:DI
744090286Sobrien		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
744190286Sobrien	    (const_int 32))))
744290286Sobrien   (clobber (match_scratch:SI 3 "=a"))
744390286Sobrien   (clobber (reg:CC 17))]
744490286Sobrien  ""
744590286Sobrien  "mul{l}\t%2"
744690286Sobrien  [(set_attr "type" "imul")
744790286Sobrien   (set_attr "ppro_uops" "few")
744890286Sobrien   (set_attr "length_immediate" "0")
744990286Sobrien   (set_attr "mode" "SI")])
745018334Speter
745190286Sobrien(define_insn "*umulsi3_highpart_zext"
745290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
745390286Sobrien	(zero_extend:DI (truncate:SI
745490286Sobrien	  (lshiftrt:DI
745590286Sobrien	    (mult:DI (zero_extend:DI
745690286Sobrien		       (match_operand:SI 1 "register_operand" "%a"))
745790286Sobrien		     (zero_extend:DI
745890286Sobrien		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
745990286Sobrien	    (const_int 32)))))
746090286Sobrien   (clobber (match_scratch:SI 3 "=a"))
746190286Sobrien   (clobber (reg:CC 17))]
746290286Sobrien  "TARGET_64BIT"
746390286Sobrien  "mul{l}\t%2"
746490286Sobrien  [(set_attr "type" "imul")
746590286Sobrien   (set_attr "ppro_uops" "few")
746690286Sobrien   (set_attr "length_immediate" "0")
746790286Sobrien   (set_attr "mode" "SI")])
746890286Sobrien
746990286Sobrien(define_insn "*smuldi3_highpart_rex64"
747090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
747190286Sobrien	(truncate:DI
747290286Sobrien	  (lshiftrt:TI
747390286Sobrien	    (mult:TI (sign_extend:TI
747490286Sobrien		       (match_operand:DI 1 "register_operand" "%a"))
747590286Sobrien		     (sign_extend:TI
747690286Sobrien		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
747790286Sobrien	    (const_int 64))))
747890286Sobrien   (clobber (match_scratch:DI 3 "=a"))
747990286Sobrien   (clobber (reg:CC 17))]
748090286Sobrien  "TARGET_64BIT"
748190286Sobrien  "imul{q}\t%2"
748290286Sobrien  [(set_attr "type" "imul")
748390286Sobrien   (set_attr "ppro_uops" "few")
748490286Sobrien   (set_attr "mode" "DI")])
748590286Sobrien
748618334Speter(define_insn "smulsi3_highpart"
748718334Speter  [(set (match_operand:SI 0 "register_operand" "=d")
748890286Sobrien	(truncate:SI
748990286Sobrien	  (lshiftrt:DI
749090286Sobrien	    (mult:DI (sign_extend:DI
749190286Sobrien		       (match_operand:SI 1 "register_operand" "%a"))
749290286Sobrien		     (sign_extend:DI
749390286Sobrien		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
749490286Sobrien	    (const_int 32))))
749590286Sobrien   (clobber (match_scratch:SI 3 "=a"))
749690286Sobrien   (clobber (reg:CC 17))]
749790286Sobrien  ""
749890286Sobrien  "imul{l}\t%2"
749990286Sobrien  [(set_attr "type" "imul")
750090286Sobrien   (set_attr "ppro_uops" "few")
750190286Sobrien   (set_attr "mode" "SI")])
750218334Speter
750390286Sobrien(define_insn "*smulsi3_highpart_zext"
750490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
750590286Sobrien	(zero_extend:DI (truncate:SI
750690286Sobrien	  (lshiftrt:DI
750790286Sobrien	    (mult:DI (sign_extend:DI
750890286Sobrien		       (match_operand:SI 1 "register_operand" "%a"))
750990286Sobrien		     (sign_extend:DI
751090286Sobrien		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
751190286Sobrien	    (const_int 32)))))
751290286Sobrien   (clobber (match_scratch:SI 3 "=a"))
751390286Sobrien   (clobber (reg:CC 17))]
751490286Sobrien  "TARGET_64BIT"
751590286Sobrien  "imul{l}\t%2"
751690286Sobrien  [(set_attr "type" "imul")
751790286Sobrien   (set_attr "ppro_uops" "few")
751890286Sobrien   (set_attr "mode" "SI")])
751990286Sobrien
752018334Speter;; The patterns that match these are at the end of this file.
752118334Speter
752218334Speter(define_expand "mulxf3"
752318334Speter  [(set (match_operand:XF 0 "register_operand" "")
752450650Sobrien	(mult:XF (match_operand:XF 1 "register_operand" "")
752550650Sobrien		 (match_operand:XF 2 "register_operand" "")))]
752690286Sobrien  "!TARGET_64BIT && TARGET_80387"
752790286Sobrien  "")
752890286Sobrien
752990286Sobrien(define_expand "multf3"
753090286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
753190286Sobrien	(mult:TF (match_operand:TF 1 "register_operand" "")
753290286Sobrien		 (match_operand:TF 2 "register_operand" "")))]
753318334Speter  "TARGET_80387"
753418334Speter  "")
753518334Speter
753618334Speter(define_expand "muldf3"
753718334Speter  [(set (match_operand:DF 0 "register_operand" "")
753850650Sobrien	(mult:DF (match_operand:DF 1 "register_operand" "")
753918334Speter		 (match_operand:DF 2 "nonimmediate_operand" "")))]
754090286Sobrien  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
754118334Speter  "")
754218334Speter
754318334Speter(define_expand "mulsf3"
754418334Speter  [(set (match_operand:SF 0 "register_operand" "")
754550650Sobrien	(mult:SF (match_operand:SF 1 "register_operand" "")
754618334Speter		 (match_operand:SF 2 "nonimmediate_operand" "")))]
754790286Sobrien  "TARGET_80387 || TARGET_SSE_MATH"
754818334Speter  "")
754918334Speter
755090286Sobrien;; Divide instructions
755118334Speter
755218334Speter(define_insn "divqi3"
755350650Sobrien  [(set (match_operand:QI 0 "register_operand" "=a")
755450650Sobrien	(div:QI (match_operand:HI 1 "register_operand" "0")
755590286Sobrien		(match_operand:QI 2 "nonimmediate_operand" "qm")))
755690286Sobrien   (clobber (reg:CC 17))]
755790286Sobrien  "TARGET_QIMODE_MATH"
755890286Sobrien  "idiv{b}\t%2"
755990286Sobrien  [(set_attr "type" "idiv")
756090286Sobrien   (set_attr "mode" "QI")
756190286Sobrien   (set_attr "ppro_uops" "few")])
756218334Speter
756318334Speter(define_insn "udivqi3"
756450650Sobrien  [(set (match_operand:QI 0 "register_operand" "=a")
756550650Sobrien	(udiv:QI (match_operand:HI 1 "register_operand" "0")
756690286Sobrien		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
756790286Sobrien   (clobber (reg:CC 17))]
756890286Sobrien  "TARGET_QIMODE_MATH"
756990286Sobrien  "div{b}\t%2"
757090286Sobrien  [(set_attr "type" "idiv")
757190286Sobrien   (set_attr "mode" "QI")
757290286Sobrien   (set_attr "ppro_uops" "few")])
757318334Speter
757418334Speter;; The patterns that match these are at the end of this file.
757518334Speter
757618334Speter(define_expand "divxf3"
757718334Speter  [(set (match_operand:XF 0 "register_operand" "")
757850650Sobrien	(div:XF (match_operand:XF 1 "register_operand" "")
757950650Sobrien		(match_operand:XF 2 "register_operand" "")))]
758090286Sobrien  "!TARGET_64BIT && TARGET_80387"
758190286Sobrien  "")
758290286Sobrien
758390286Sobrien(define_expand "divtf3"
758490286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
758590286Sobrien	(div:TF (match_operand:TF 1 "register_operand" "")
758690286Sobrien		(match_operand:TF 2 "register_operand" "")))]
758718334Speter  "TARGET_80387"
758818334Speter  "")
758918334Speter
759018334Speter(define_expand "divdf3"
759118334Speter  [(set (match_operand:DF 0 "register_operand" "")
759250650Sobrien 	(div:DF (match_operand:DF 1 "register_operand" "")
759350650Sobrien 		(match_operand:DF 2 "nonimmediate_operand" "")))]
759490286Sobrien   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
759550650Sobrien   "")
759650650Sobrien 
759718334Speter(define_expand "divsf3"
759818334Speter  [(set (match_operand:SF 0 "register_operand" "")
759950650Sobrien	(div:SF (match_operand:SF 1 "register_operand" "")
760018334Speter		(match_operand:SF 2 "nonimmediate_operand" "")))]
760190286Sobrien  "TARGET_80387 || TARGET_SSE_MATH"
760218334Speter  "")
760318334Speter
760418334Speter;; Remainder instructions.
760518334Speter
760690286Sobrien(define_expand "divmoddi4"
760790286Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
760890286Sobrien		   (div:DI (match_operand:DI 1 "register_operand" "")
760990286Sobrien			   (match_operand:DI 2 "nonimmediate_operand" "")))
761090286Sobrien	      (set (match_operand:DI 3 "register_operand" "")
761190286Sobrien		   (mod:DI (match_dup 1) (match_dup 2)))
761290286Sobrien	      (clobber (reg:CC 17))])]
761390286Sobrien  "TARGET_64BIT"
761490286Sobrien  "")
761590286Sobrien
761690286Sobrien;; Allow to come the parameter in eax or edx to avoid extra moves.
761790286Sobrien;; Penalize eax case sligthly because it results in worse scheduling
761890286Sobrien;; of code.
761990286Sobrien(define_insn "*divmoddi4_nocltd_rex64"
762090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=&a,?a")
762190286Sobrien	(div:DI (match_operand:DI 2 "register_operand" "1,0")
762290286Sobrien		(match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
762390286Sobrien   (set (match_operand:DI 1 "register_operand" "=&d,&d")
762490286Sobrien	(mod:DI (match_dup 2) (match_dup 3)))
762590286Sobrien   (clobber (reg:CC 17))]
762690286Sobrien  "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
762790286Sobrien  "#"
762890286Sobrien  [(set_attr "type" "multi")])
762990286Sobrien
763090286Sobrien(define_insn "*divmoddi4_cltd_rex64"
763190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a")
763290286Sobrien	(div:DI (match_operand:DI 2 "register_operand" "a")
763390286Sobrien		(match_operand:DI 3 "nonimmediate_operand" "rm")))
763490286Sobrien   (set (match_operand:DI 1 "register_operand" "=&d")
763590286Sobrien	(mod:DI (match_dup 2) (match_dup 3)))
763690286Sobrien   (clobber (reg:CC 17))]
763790286Sobrien  "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
763890286Sobrien  "#"
763990286Sobrien  [(set_attr "type" "multi")])
764090286Sobrien
764190286Sobrien(define_insn "*divmoddi_noext_rex64"
764290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a")
764390286Sobrien	(div:DI (match_operand:DI 1 "register_operand" "0")
764490286Sobrien		(match_operand:DI 2 "nonimmediate_operand" "rm")))
764590286Sobrien   (set (match_operand:DI 3 "register_operand" "=d")
764690286Sobrien	(mod:DI (match_dup 1) (match_dup 2)))
764790286Sobrien   (use (match_operand:DI 4 "register_operand" "3"))
764890286Sobrien   (clobber (reg:CC 17))]
764990286Sobrien  "TARGET_64BIT"
765090286Sobrien  "idiv{q}\t%2"
765190286Sobrien  [(set_attr "type" "idiv")
765290286Sobrien   (set_attr "mode" "DI")
765390286Sobrien   (set_attr "ppro_uops" "few")])
765490286Sobrien
765590286Sobrien(define_split
765690286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
765790286Sobrien	(div:DI (match_operand:DI 1 "register_operand" "")
765890286Sobrien		(match_operand:DI 2 "nonimmediate_operand" "")))
765990286Sobrien   (set (match_operand:DI 3 "register_operand" "")
766090286Sobrien	(mod:DI (match_dup 1) (match_dup 2)))
766190286Sobrien   (clobber (reg:CC 17))]
766290286Sobrien  "TARGET_64BIT && reload_completed"
766390286Sobrien  [(parallel [(set (match_dup 3)
766490286Sobrien		   (ashiftrt:DI (match_dup 4) (const_int 63)))
766590286Sobrien	      (clobber (reg:CC 17))])
766690286Sobrien   (parallel [(set (match_dup 0)
766790286Sobrien	           (div:DI (reg:DI 0) (match_dup 2)))
766890286Sobrien	      (set (match_dup 3)
766990286Sobrien		   (mod:DI (reg:DI 0) (match_dup 2)))
767090286Sobrien	      (use (match_dup 3))
767190286Sobrien	      (clobber (reg:CC 17))])]
767290286Sobrien{
767390286Sobrien  /* Avoid use of cltd in favour of a mov+shift.  */
767490286Sobrien  if (!TARGET_USE_CLTD && !optimize_size)
767590286Sobrien    {
767690286Sobrien      if (true_regnum (operands[1]))
767790286Sobrien        emit_move_insn (operands[0], operands[1]);
767890286Sobrien      else
767990286Sobrien	emit_move_insn (operands[3], operands[1]);
768090286Sobrien      operands[4] = operands[3];
768190286Sobrien    }
768290286Sobrien  else
768390286Sobrien    {
768490286Sobrien      if (true_regnum (operands[1]))
768590286Sobrien	abort();
768690286Sobrien      operands[4] = operands[1];
768790286Sobrien    }
768890286Sobrien})
768990286Sobrien
769090286Sobrien
769190286Sobrien(define_expand "divmodsi4"
769290286Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "")
769390286Sobrien		   (div:SI (match_operand:SI 1 "register_operand" "")
769490286Sobrien			   (match_operand:SI 2 "nonimmediate_operand" "")))
769590286Sobrien	      (set (match_operand:SI 3 "register_operand" "")
769690286Sobrien		   (mod:SI (match_dup 1) (match_dup 2)))
769790286Sobrien	      (clobber (reg:CC 17))])]
769890286Sobrien  ""
769990286Sobrien  "")
770090286Sobrien
770190286Sobrien;; Allow to come the parameter in eax or edx to avoid extra moves.
770290286Sobrien;; Penalize eax case sligthly because it results in worse scheduling
770390286Sobrien;; of code.
770490286Sobrien(define_insn "*divmodsi4_nocltd"
770590286Sobrien  [(set (match_operand:SI 0 "register_operand" "=&a,?a")
770690286Sobrien	(div:SI (match_operand:SI 2 "register_operand" "1,0")
770790286Sobrien		(match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
770890286Sobrien   (set (match_operand:SI 1 "register_operand" "=&d,&d")
770990286Sobrien	(mod:SI (match_dup 2) (match_dup 3)))
771090286Sobrien   (clobber (reg:CC 17))]
771190286Sobrien  "!optimize_size && !TARGET_USE_CLTD"
771290286Sobrien  "#"
771390286Sobrien  [(set_attr "type" "multi")])
771490286Sobrien
771590286Sobrien(define_insn "*divmodsi4_cltd"
771618334Speter  [(set (match_operand:SI 0 "register_operand" "=a")
771790286Sobrien	(div:SI (match_operand:SI 2 "register_operand" "a")
771890286Sobrien		(match_operand:SI 3 "nonimmediate_operand" "rm")))
771990286Sobrien   (set (match_operand:SI 1 "register_operand" "=&d")
772090286Sobrien	(mod:SI (match_dup 2) (match_dup 3)))
772190286Sobrien   (clobber (reg:CC 17))]
772290286Sobrien  "optimize_size || TARGET_USE_CLTD"
772390286Sobrien  "#"
772490286Sobrien  [(set_attr "type" "multi")])
772590286Sobrien
772690286Sobrien(define_insn "*divmodsi_noext"
772790286Sobrien  [(set (match_operand:SI 0 "register_operand" "=a")
772818334Speter	(div:SI (match_operand:SI 1 "register_operand" "0")
772950650Sobrien		(match_operand:SI 2 "nonimmediate_operand" "rm")))
773090286Sobrien   (set (match_operand:SI 3 "register_operand" "=d")
773190286Sobrien	(mod:SI (match_dup 1) (match_dup 2)))
773290286Sobrien   (use (match_operand:SI 4 "register_operand" "3"))
773390286Sobrien   (clobber (reg:CC 17))]
773418334Speter  ""
773590286Sobrien  "idiv{l}\t%2"
773690286Sobrien  [(set_attr "type" "idiv")
773790286Sobrien   (set_attr "mode" "SI")
773890286Sobrien   (set_attr "ppro_uops" "few")])
773990286Sobrien
774090286Sobrien(define_split
774190286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
774290286Sobrien	(div:SI (match_operand:SI 1 "register_operand" "")
774390286Sobrien		(match_operand:SI 2 "nonimmediate_operand" "")))
774490286Sobrien   (set (match_operand:SI 3 "register_operand" "")
774590286Sobrien	(mod:SI (match_dup 1) (match_dup 2)))
774690286Sobrien   (clobber (reg:CC 17))]
774790286Sobrien  "reload_completed"
774890286Sobrien  [(parallel [(set (match_dup 3)
774990286Sobrien		   (ashiftrt:SI (match_dup 4) (const_int 31)))
775090286Sobrien	      (clobber (reg:CC 17))])
775190286Sobrien   (parallel [(set (match_dup 0)
775290286Sobrien	           (div:SI (reg:SI 0) (match_dup 2)))
775390286Sobrien	      (set (match_dup 3)
775490286Sobrien		   (mod:SI (reg:SI 0) (match_dup 2)))
775590286Sobrien	      (use (match_dup 3))
775690286Sobrien	      (clobber (reg:CC 17))])]
775718334Speter{
775890286Sobrien  /* Avoid use of cltd in favour of a mov+shift.  */
775990286Sobrien  if (!TARGET_USE_CLTD && !optimize_size)
776090286Sobrien    {
776190286Sobrien      if (true_regnum (operands[1]))
776290286Sobrien        emit_move_insn (operands[0], operands[1]);
776390286Sobrien      else
776490286Sobrien	emit_move_insn (operands[3], operands[1]);
776590286Sobrien      operands[4] = operands[3];
776690286Sobrien    }
776790286Sobrien  else
776890286Sobrien    {
776990286Sobrien      if (true_regnum (operands[1]))
777090286Sobrien	abort();
777190286Sobrien      operands[4] = operands[1];
777290286Sobrien    }
777390286Sobrien})
777490286Sobrien;; %%% Split me.
777518334Speter(define_insn "divmodhi4"
777618334Speter  [(set (match_operand:HI 0 "register_operand" "=a")
777718334Speter	(div:HI (match_operand:HI 1 "register_operand" "0")
777850650Sobrien		(match_operand:HI 2 "nonimmediate_operand" "rm")))
777918334Speter   (set (match_operand:HI 3 "register_operand" "=&d")
778090286Sobrien	(mod:HI (match_dup 1) (match_dup 2)))
778190286Sobrien   (clobber (reg:CC 17))]
778290286Sobrien  "TARGET_HIMODE_MATH"
778390286Sobrien  "cwtd\;idiv{w}\t%2"
778490286Sobrien  [(set_attr "type" "multi")
778590286Sobrien   (set_attr "length_immediate" "0")
778690286Sobrien   (set_attr "mode" "SI")])
778718334Speter
778890286Sobrien(define_insn "udivmoddi4"
778990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a")
779090286Sobrien	(udiv:DI (match_operand:DI 1 "register_operand" "0")
779190286Sobrien		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
779290286Sobrien   (set (match_operand:DI 3 "register_operand" "=&d")
779390286Sobrien	(umod:DI (match_dup 1) (match_dup 2)))
779490286Sobrien   (clobber (reg:CC 17))]
779590286Sobrien  "TARGET_64BIT"
779690286Sobrien  "xor{q}\t%3, %3\;div{q}\t%2"
779790286Sobrien  [(set_attr "type" "multi")
779890286Sobrien   (set_attr "length_immediate" "0")
779990286Sobrien   (set_attr "mode" "DI")])
780090286Sobrien
780190286Sobrien(define_insn "*udivmoddi4_noext"
780290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a")
780390286Sobrien	(udiv:DI (match_operand:DI 1 "register_operand" "0")
780490286Sobrien		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
780590286Sobrien   (set (match_operand:DI 3 "register_operand" "=d")
780690286Sobrien	(umod:DI (match_dup 1) (match_dup 2)))
780790286Sobrien   (use (match_dup 3))
780890286Sobrien   (clobber (reg:CC 17))]
780990286Sobrien  "TARGET_64BIT"
781090286Sobrien  "div{q}\t%2"
781190286Sobrien  [(set_attr "type" "idiv")
781290286Sobrien   (set_attr "ppro_uops" "few")
781390286Sobrien   (set_attr "mode" "DI")])
781490286Sobrien
781590286Sobrien(define_split
781690286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
781790286Sobrien	(udiv:DI (match_operand:DI 1 "register_operand" "")
781890286Sobrien		 (match_operand:DI 2 "nonimmediate_operand" "")))
781990286Sobrien   (set (match_operand:DI 3 "register_operand" "")
782090286Sobrien	(umod:DI (match_dup 1) (match_dup 2)))
782190286Sobrien   (clobber (reg:CC 17))]
782290286Sobrien  "TARGET_64BIT && reload_completed"
782390286Sobrien  [(set (match_dup 3) (const_int 0))
782490286Sobrien   (parallel [(set (match_dup 0)
782590286Sobrien		   (udiv:DI (match_dup 1) (match_dup 2)))
782690286Sobrien	      (set (match_dup 3)
782790286Sobrien		   (umod:DI (match_dup 1) (match_dup 2)))
782890286Sobrien	      (use (match_dup 3))
782990286Sobrien	      (clobber (reg:CC 17))])]
783090286Sobrien  "")
783190286Sobrien
783218334Speter(define_insn "udivmodsi4"
783318334Speter  [(set (match_operand:SI 0 "register_operand" "=a")
783418334Speter	(udiv:SI (match_operand:SI 1 "register_operand" "0")
783550650Sobrien		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
783618334Speter   (set (match_operand:SI 3 "register_operand" "=&d")
783790286Sobrien	(umod:SI (match_dup 1) (match_dup 2)))
783890286Sobrien   (clobber (reg:CC 17))]
783918334Speter  ""
784090286Sobrien  "xor{l}\t%3, %3\;div{l}\t%2"
784190286Sobrien  [(set_attr "type" "multi")
784290286Sobrien   (set_attr "length_immediate" "0")
784390286Sobrien   (set_attr "mode" "SI")])
784418334Speter
784590286Sobrien(define_insn "*udivmodsi4_noext"
784690286Sobrien  [(set (match_operand:SI 0 "register_operand" "=a")
784790286Sobrien	(udiv:SI (match_operand:SI 1 "register_operand" "0")
784890286Sobrien		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
784990286Sobrien   (set (match_operand:SI 3 "register_operand" "=d")
785090286Sobrien	(umod:SI (match_dup 1) (match_dup 2)))
785190286Sobrien   (use (match_dup 3))
785290286Sobrien   (clobber (reg:CC 17))]
785390286Sobrien  ""
785490286Sobrien  "div{l}\t%2"
785590286Sobrien  [(set_attr "type" "idiv")
785690286Sobrien   (set_attr "ppro_uops" "few")
785790286Sobrien   (set_attr "mode" "SI")])
785890286Sobrien
785990286Sobrien(define_split
786090286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
786190286Sobrien	(udiv:SI (match_operand:SI 1 "register_operand" "")
786290286Sobrien		 (match_operand:SI 2 "nonimmediate_operand" "")))
786390286Sobrien   (set (match_operand:SI 3 "register_operand" "")
786490286Sobrien	(umod:SI (match_dup 1) (match_dup 2)))
786590286Sobrien   (clobber (reg:CC 17))]
786690286Sobrien  "reload_completed"
786790286Sobrien  [(set (match_dup 3) (const_int 0))
786890286Sobrien   (parallel [(set (match_dup 0)
786990286Sobrien		   (udiv:SI (match_dup 1) (match_dup 2)))
787090286Sobrien	      (set (match_dup 3)
787190286Sobrien		   (umod:SI (match_dup 1) (match_dup 2)))
787290286Sobrien	      (use (match_dup 3))
787390286Sobrien	      (clobber (reg:CC 17))])]
787490286Sobrien  "")
787590286Sobrien
787690286Sobrien(define_expand "udivmodhi4"
787790286Sobrien  [(set (match_dup 4) (const_int 0))
787890286Sobrien   (parallel [(set (match_operand:HI 0 "register_operand" "")
787990286Sobrien		   (udiv:HI (match_operand:HI 1 "register_operand" "")
788090286Sobrien		 	    (match_operand:HI 2 "nonimmediate_operand" "")))
788190286Sobrien	      (set (match_operand:HI 3 "register_operand" "")
788290286Sobrien	   	   (umod:HI (match_dup 1) (match_dup 2)))
788390286Sobrien	      (use (match_dup 4))
788490286Sobrien	      (clobber (reg:CC 17))])]
788590286Sobrien  "TARGET_HIMODE_MATH"
788690286Sobrien  "operands[4] = gen_reg_rtx (HImode);")
788790286Sobrien
788890286Sobrien(define_insn "*udivmodhi_noext"
788918334Speter  [(set (match_operand:HI 0 "register_operand" "=a")
789018334Speter	(udiv:HI (match_operand:HI 1 "register_operand" "0")
789150650Sobrien		 (match_operand:HI 2 "nonimmediate_operand" "rm")))
789290286Sobrien   (set (match_operand:HI 3 "register_operand" "=d")
789390286Sobrien	(umod:HI (match_dup 1) (match_dup 2)))
789490286Sobrien   (use (match_operand:HI 4 "register_operand" "3"))
789590286Sobrien   (clobber (reg:CC 17))]
789618334Speter  ""
789790286Sobrien  "div{w}\t%2"
789890286Sobrien  [(set_attr "type" "idiv")
789990286Sobrien   (set_attr "mode" "HI")
790090286Sobrien   (set_attr "ppro_uops" "few")])
790118334Speter
790290286Sobrien;; We can not use div/idiv for double division, because it causes
790390286Sobrien;; "division by zero" on the overflow and that's not what we expect
790490286Sobrien;; from truncate.  Because true (non truncating) double division is
790590286Sobrien;; never generated, we can't create this insn anyway.
790690286Sobrien;
790790286Sobrien;(define_insn ""
790890286Sobrien;  [(set (match_operand:SI 0 "register_operand" "=a")
790990286Sobrien;	(truncate:SI
791090286Sobrien;	  (udiv:DI (match_operand:DI 1 "register_operand" "A")
791190286Sobrien;		   (zero_extend:DI
791290286Sobrien;		     (match_operand:SI 2 "nonimmediate_operand" "rm")))))
791390286Sobrien;   (set (match_operand:SI 3 "register_operand" "=d")
791490286Sobrien;	(truncate:SI
791590286Sobrien;	  (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
791690286Sobrien;   (clobber (reg:CC 17))]
791790286Sobrien;  ""
791890286Sobrien;  "div{l}\t{%2, %0|%0, %2}"
791990286Sobrien;  [(set_attr "type" "idiv")
792090286Sobrien;   (set_attr "ppro_uops" "few")])
792190286Sobrien
792290286Sobrien;;- Logical AND instructions
792318334Speter
792490286Sobrien;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
792590286Sobrien;; Note that this excludes ah.
792690286Sobrien
792790286Sobrien(define_insn "*testdi_1_rex64"
792890286Sobrien  [(set (reg 17)
792990286Sobrien	(compare
793090286Sobrien	  (and:DI (match_operand:DI 0 "nonimmediate_operand" "%*a,r,*a,r,rm")
793190286Sobrien		  (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,Z,e,e,re"))
793290286Sobrien	  (const_int 0)))]
793390286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
793490286Sobrien  "@
793590286Sobrien   test{l}\t{%k1, %k0|%k0, %k1} 
793690286Sobrien   test{l}\t{%k1, %k0|%k0, %k1} 
793790286Sobrien   test{q}\t{%1, %0|%0, %1} 
793890286Sobrien   test{q}\t{%1, %0|%0, %1} 
793990286Sobrien   test{q}\t{%1, %0|%0, %1}"
794090286Sobrien  [(set_attr "type" "test")
794190286Sobrien   (set_attr "modrm" "0,1,0,1,1")
794290286Sobrien   (set_attr "mode" "SI,SI,DI,DI,DI")
794390286Sobrien   (set_attr "pent_pair" "uv,np,uv,np,uv")])
794490286Sobrien
794590286Sobrien(define_insn "testsi_1"
794690286Sobrien  [(set (reg 17)
794790286Sobrien	(compare
794890286Sobrien	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
794990286Sobrien		  (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
795090286Sobrien	  (const_int 0)))]
795190286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
795290286Sobrien  "test{l}\t{%1, %0|%0, %1}"
795390286Sobrien  [(set_attr "type" "test")
795490286Sobrien   (set_attr "modrm" "0,1,1")
795590286Sobrien   (set_attr "mode" "SI")
795690286Sobrien   (set_attr "pent_pair" "uv,np,uv")])
795790286Sobrien
795890286Sobrien(define_expand "testsi_ccno_1"
795990286Sobrien  [(set (reg:CCNO 17)
796090286Sobrien	(compare:CCNO
796190286Sobrien	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
796290286Sobrien		  (match_operand:SI 1 "nonmemory_operand" ""))
796390286Sobrien	  (const_int 0)))]
796418334Speter  ""
796590286Sobrien  "")
796618334Speter
796790286Sobrien(define_insn "*testhi_1"
796890286Sobrien  [(set (reg 17)
796990286Sobrien        (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
797090286Sobrien			 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
797190286Sobrien		 (const_int 0)))]
797290286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
797390286Sobrien  "test{w}\t{%1, %0|%0, %1}"
797490286Sobrien  [(set_attr "type" "test")
797590286Sobrien   (set_attr "modrm" "0,1,1")
797690286Sobrien   (set_attr "mode" "HI")
797790286Sobrien   (set_attr "pent_pair" "uv,np,uv")])
797818334Speter
797990286Sobrien(define_expand "testqi_ccz_1"
798090286Sobrien  [(set (reg:CCZ 17)
798190286Sobrien        (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
798290286Sobrien			     (match_operand:QI 1 "nonmemory_operand" ""))
798390286Sobrien		 (const_int 0)))]
798490286Sobrien  ""
798590286Sobrien  "")
798618334Speter
798790286Sobrien(define_insn "*testqi_1"
798890286Sobrien  [(set (reg 17)
798990286Sobrien        (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
799090286Sobrien			 (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
799190286Sobrien		 (const_int 0)))]
799290286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
799318334Speter{
799490286Sobrien  if (which_alternative == 3)
799518334Speter    {
799690286Sobrien      if (GET_CODE (operands[1]) == CONST_INT
799790286Sobrien	  && (INTVAL (operands[1]) & 0xffffff00))
799890286Sobrien	operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
799990286Sobrien      return "test{l}\t{%1, %k0|%k0, %1}";
800050650Sobrien    }
800190286Sobrien  return "test{b}\t{%1, %0|%0, %1}";
800290286Sobrien}
800390286Sobrien  [(set_attr "type" "test")
800490286Sobrien   (set_attr "modrm" "0,1,1,1")
800590286Sobrien   (set_attr "mode" "QI,QI,QI,SI")
800690286Sobrien   (set_attr "pent_pair" "uv,np,uv,np")])
800718334Speter
800890286Sobrien(define_expand "testqi_ext_ccno_0"
800990286Sobrien  [(set (reg:CCNO 17)
801090286Sobrien	(compare:CCNO
801190286Sobrien	  (and:SI
801290286Sobrien	    (zero_extract:SI
801390286Sobrien	      (match_operand 0 "ext_register_operand" "")
801490286Sobrien	      (const_int 8)
801590286Sobrien	      (const_int 8))
801690286Sobrien	    (match_operand 1 "const_int_operand" ""))
801790286Sobrien	  (const_int 0)))]
801890286Sobrien  ""
801990286Sobrien  "")
802018334Speter
802190286Sobrien(define_insn "*testqi_ext_0"
802290286Sobrien  [(set (reg 17)
802390286Sobrien	(compare
802490286Sobrien	  (and:SI
802590286Sobrien	    (zero_extract:SI
802690286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
802790286Sobrien	      (const_int 8)
802890286Sobrien	      (const_int 8))
802990286Sobrien	    (match_operand 1 "const_int_operand" "n"))
803090286Sobrien	  (const_int 0)))]
803190286Sobrien  "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff
803290286Sobrien   && ix86_match_ccmode (insn, CCNOmode)"
803390286Sobrien  "test{b}\t{%1, %h0|%h0, %1}"
803490286Sobrien  [(set_attr "type" "test")
803590286Sobrien   (set_attr "mode" "QI")
803690286Sobrien   (set_attr "length_immediate" "1")
803790286Sobrien   (set_attr "pent_pair" "np")])
803850650Sobrien
803990286Sobrien(define_insn "*testqi_ext_1"
804090286Sobrien  [(set (reg 17)
804190286Sobrien	(compare
804290286Sobrien	  (and:SI
804390286Sobrien	    (zero_extract:SI
804490286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
804590286Sobrien	      (const_int 8)
804690286Sobrien	      (const_int 8))
804790286Sobrien	    (zero_extend:SI
804890286Sobrien	      (match_operand:QI 1 "nonimmediate_operand" "Qm")))
804990286Sobrien	  (const_int 0)))]
805090286Sobrien  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
805190286Sobrien  "test{b}\t{%1, %h0|%h0, %1}"
805290286Sobrien  [(set_attr "type" "test")
805390286Sobrien   (set_attr "mode" "QI")])
805418334Speter
805590286Sobrien(define_insn "*testqi_ext_1_rex64"
805690286Sobrien  [(set (reg 17)
805790286Sobrien	(compare
805890286Sobrien	  (and:SI
805990286Sobrien	    (zero_extract:SI
806090286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
806190286Sobrien	      (const_int 8)
806290286Sobrien	      (const_int 8))
806390286Sobrien	    (zero_extend:SI
806490286Sobrien	      (match_operand:QI 1 "register_operand" "Q")))
806590286Sobrien	  (const_int 0)))]
806690286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
806790286Sobrien  "test{b}\t{%1, %h0|%h0, %1}"
806890286Sobrien  [(set_attr "type" "test")
806990286Sobrien   (set_attr "mode" "QI")])
807018334Speter
807190286Sobrien(define_insn "*testqi_ext_2"
807290286Sobrien  [(set (reg 17)
807390286Sobrien	(compare
807490286Sobrien	  (and:SI
807590286Sobrien	    (zero_extract:SI
807690286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
807790286Sobrien	      (const_int 8)
807890286Sobrien	      (const_int 8))
807990286Sobrien	    (zero_extract:SI
808090286Sobrien	      (match_operand 1 "ext_register_operand" "Q")
808190286Sobrien	      (const_int 8)
808290286Sobrien	      (const_int 8)))
808390286Sobrien	  (const_int 0)))]
808490286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
808590286Sobrien  "test{b}\t{%h1, %h0|%h0, %h1}"
808690286Sobrien  [(set_attr "type" "test")
808790286Sobrien   (set_attr "mode" "QI")])
808850650Sobrien
808990286Sobrien;; Combine likes to form bit extractions for some tests.  Humor it.
809090286Sobrien(define_insn "*testqi_ext_3"
809190286Sobrien  [(set (reg 17)
809290286Sobrien        (compare (zero_extract:SI
809390286Sobrien		   (match_operand 0 "nonimmediate_operand" "rm")
809490286Sobrien		   (match_operand:SI 1 "const_int_operand" "")
809590286Sobrien		   (match_operand:SI 2 "const_int_operand" ""))
809690286Sobrien		 (const_int 0)))]
809790286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
809890286Sobrien   && (GET_MODE (operands[0]) == SImode
809990286Sobrien       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
810090286Sobrien       || GET_MODE (operands[0]) == HImode
810190286Sobrien       || GET_MODE (operands[0]) == QImode)"
810290286Sobrien  "#")
810350650Sobrien
810490286Sobrien(define_insn "*testqi_ext_3_rex64"
810590286Sobrien  [(set (reg 17)
810690286Sobrien        (compare (zero_extract:DI
810790286Sobrien		   (match_operand 0 "nonimmediate_operand" "rm")
810890286Sobrien		   (match_operand:DI 1 "const_int_operand" "")
810990286Sobrien		   (match_operand:DI 2 "const_int_operand" ""))
811090286Sobrien		 (const_int 0)))]
811190286Sobrien  "TARGET_64BIT
811290286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
811390286Sobrien   /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
811490286Sobrien   && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
811590286Sobrien   /* Ensure that resulting mask is zero or sign extended operand.  */
811690286Sobrien   && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
811790286Sobrien       || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
811890286Sobrien	   && INTVAL (operands[1]) > 32))
811990286Sobrien   && (GET_MODE (operands[0]) == SImode
812090286Sobrien       || GET_MODE (operands[0]) == DImode
812190286Sobrien       || GET_MODE (operands[0]) == HImode
812290286Sobrien       || GET_MODE (operands[0]) == QImode)"
812390286Sobrien  "#")
812450650Sobrien
812590286Sobrien(define_split
812690286Sobrien  [(set (reg 17)
812790286Sobrien        (compare (zero_extract
812890286Sobrien		   (match_operand 0 "nonimmediate_operand" "")
812990286Sobrien		   (match_operand 1 "const_int_operand" "")
813090286Sobrien		   (match_operand 2 "const_int_operand" ""))
813190286Sobrien		 (const_int 0)))]
813290286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
813390286Sobrien  [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
813490286Sobrien{
813590286Sobrien  HOST_WIDE_INT len = INTVAL (operands[1]);
813690286Sobrien  HOST_WIDE_INT pos = INTVAL (operands[2]);
813790286Sobrien  HOST_WIDE_INT mask;
813890286Sobrien  enum machine_mode mode, submode;
813918334Speter
814090286Sobrien  mode = GET_MODE (operands[0]);
814190286Sobrien  if (GET_CODE (operands[0]) == MEM)
814290286Sobrien    {
814390286Sobrien      /* ??? Combine likes to put non-volatile mem extractions in QImode
814490286Sobrien	 no matter the size of the test.  So find a mode that works.  */
814590286Sobrien      if (! MEM_VOLATILE_P (operands[0]))
814618334Speter	{
814790286Sobrien	  mode = smallest_mode_for_size (pos + len, MODE_INT);
814890286Sobrien	  operands[0] = adjust_address (operands[0], mode, 0);
814990286Sobrien	}
815090286Sobrien    }
815190286Sobrien  else if (GET_CODE (operands[0]) == SUBREG
815290286Sobrien	   && (submode = GET_MODE (SUBREG_REG (operands[0])),
815390286Sobrien	       GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
815490286Sobrien	   && pos + len <= GET_MODE_BITSIZE (submode))
815590286Sobrien    {
815690286Sobrien      /* Narrow a paradoxical subreg to prevent partial register stalls.  */
815790286Sobrien      mode = submode;
815890286Sobrien      operands[0] = SUBREG_REG (operands[0]);
815990286Sobrien    }
816090286Sobrien  else if (mode == HImode && pos + len <= 8)
816190286Sobrien    {
816290286Sobrien      /* Small HImode tests can be converted to QImode.  */
816390286Sobrien      mode = QImode;
816490286Sobrien      operands[0] = gen_lowpart (QImode, operands[0]);
816590286Sobrien    }
816618334Speter
816790286Sobrien  mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
816890286Sobrien  mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
816918334Speter
817090286Sobrien  operands[3] = gen_rtx_AND (mode, operands[0],
817190286Sobrien			     GEN_INT (trunc_int_for_mode (mask, mode)));
817290286Sobrien})
817350650Sobrien
817490286Sobrien;; %%% This used to optimize known byte-wide and operations to memory,
817590286Sobrien;; and sometimes to QImode registers.  If this is considered useful,
817690286Sobrien;; it should be done with splitters.
817718334Speter
817890286Sobrien(define_expand "anddi3"
817990286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
818090286Sobrien	(and:DI (match_operand:DI 1 "nonimmediate_operand" "")
818190286Sobrien		(match_operand:DI 2 "x86_64_szext_general_operand" "")))
818290286Sobrien   (clobber (reg:CC 17))]
818390286Sobrien  "TARGET_64BIT"
818490286Sobrien  "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
818550650Sobrien
818690286Sobrien(define_insn "*anddi_1_rex64"
818790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
818890286Sobrien	(and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
818990286Sobrien		(match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
819090286Sobrien   (clobber (reg:CC 17))]
819190286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
819290286Sobrien{
819390286Sobrien  switch (get_attr_type (insn))
819490286Sobrien    {
819590286Sobrien    case TYPE_IMOVX:
819690286Sobrien      {
819790286Sobrien	enum machine_mode mode;
819850650Sobrien
819990286Sobrien	if (GET_CODE (operands[2]) != CONST_INT)
820090286Sobrien	  abort ();
820190286Sobrien        if (INTVAL (operands[2]) == 0xff)
820290286Sobrien	  mode = QImode;
820390286Sobrien	else if (INTVAL (operands[2]) == 0xffff)
820490286Sobrien	  mode = HImode;
820590286Sobrien	else
820690286Sobrien	  abort ();
820790286Sobrien	
820890286Sobrien	operands[1] = gen_lowpart (mode, operands[1]);
820990286Sobrien	if (mode == QImode)
821090286Sobrien	  return "movz{bq|x}\t{%1,%0|%0, %1}";
821190286Sobrien	else
821290286Sobrien	  return "movz{wq|x}\t{%1,%0|%0, %1}";
821390286Sobrien      }
821450650Sobrien
821550650Sobrien    default:
821690286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
821790286Sobrien	abort ();
821890286Sobrien      if (get_attr_mode (insn) == MODE_SI)
821990286Sobrien	return "and{l}\t{%k2, %k0|%k0, %k2}";
822090286Sobrien      else
822190286Sobrien	return "and{q}\t{%2, %0|%0, %2}";
822218334Speter    }
822390286Sobrien}
822490286Sobrien  [(set_attr "type" "alu,alu,alu,imovx")
822590286Sobrien   (set_attr "length_immediate" "*,*,*,0")
822690286Sobrien   (set_attr "mode" "SI,DI,DI,DI")])
822718334Speter
822890286Sobrien(define_insn "*anddi_2"
822990286Sobrien  [(set (reg 17)
823090286Sobrien	(compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
823190286Sobrien			 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
823290286Sobrien		 (const_int 0)))
823390286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
823490286Sobrien	(and:DI (match_dup 1) (match_dup 2)))]
823590286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
823690286Sobrien   && ix86_binary_operator_ok (AND, DImode, operands)"
823790286Sobrien  "@
823890286Sobrien   and{l}\t{%k2, %k0|%k0, %k2} 
823990286Sobrien   and{q}\t{%2, %0|%0, %2} 
824090286Sobrien   and{q}\t{%2, %0|%0, %2}"
824190286Sobrien  [(set_attr "type" "alu")
824290286Sobrien   (set_attr "mode" "SI,DI,DI")])
824318334Speter
824490286Sobrien(define_expand "andsi3"
824590286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
824690286Sobrien	(and:SI (match_operand:SI 1 "nonimmediate_operand" "")
824790286Sobrien		(match_operand:SI 2 "general_operand" "")))
824890286Sobrien   (clobber (reg:CC 17))]
824918334Speter  ""
825090286Sobrien  "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
825190286Sobrien
825290286Sobrien(define_insn "*andsi_1"
825390286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
825490286Sobrien	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
825590286Sobrien		(match_operand:SI 2 "general_operand" "ri,rm,L")))
825690286Sobrien   (clobber (reg:CC 17))]
825790286Sobrien  "ix86_binary_operator_ok (AND, SImode, operands)"
825818334Speter{
825990286Sobrien  switch (get_attr_type (insn))
826018334Speter    {
826190286Sobrien    case TYPE_IMOVX:
826290286Sobrien      {
826390286Sobrien	enum machine_mode mode;
826418334Speter
826590286Sobrien	if (GET_CODE (operands[2]) != CONST_INT)
826690286Sobrien	  abort ();
826790286Sobrien        if (INTVAL (operands[2]) == 0xff)
826890286Sobrien	  mode = QImode;
826990286Sobrien	else if (INTVAL (operands[2]) == 0xffff)
827090286Sobrien	  mode = HImode;
827190286Sobrien	else
827290286Sobrien	  abort ();
827390286Sobrien	
827490286Sobrien	operands[1] = gen_lowpart (mode, operands[1]);
827590286Sobrien	if (mode == QImode)
827690286Sobrien	  return "movz{bl|x}\t{%1,%0|%0, %1}";
827790286Sobrien	else
827890286Sobrien	  return "movz{wl|x}\t{%1,%0|%0, %1}";
827990286Sobrien      }
828018334Speter
828190286Sobrien    default:
828290286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
828390286Sobrien	abort ();
828490286Sobrien      return "and{l}\t{%2, %0|%0, %2}";
828590286Sobrien    }
828690286Sobrien}
828790286Sobrien  [(set_attr "type" "alu,alu,imovx")
828890286Sobrien   (set_attr "length_immediate" "*,*,0")
828990286Sobrien   (set_attr "mode" "SI")])
829018334Speter
829190286Sobrien(define_split
829290286Sobrien  [(set (match_operand 0 "register_operand" "")
829390286Sobrien	(and (match_dup 0)
829490286Sobrien	     (const_int -65536)))
829590286Sobrien   (clobber (reg:CC 17))]
829690286Sobrien  "optimize_size"
829790286Sobrien  [(set (strict_low_part (match_dup 1)) (const_int 0))]
829890286Sobrien  "operands[1] = gen_lowpart (HImode, operands[0]);")
829918334Speter
830090286Sobrien(define_split
830190286Sobrien  [(set (match_operand 0 "ext_register_operand" "")
830290286Sobrien	(and (match_dup 0)
830390286Sobrien	     (const_int -256)))
830490286Sobrien   (clobber (reg:CC 17))]
830590286Sobrien  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
830690286Sobrien  [(set (strict_low_part (match_dup 1)) (const_int 0))]
830790286Sobrien  "operands[1] = gen_lowpart (QImode, operands[0]);")
830818334Speter
830990286Sobrien(define_split
831090286Sobrien  [(set (match_operand 0 "ext_register_operand" "")
831190286Sobrien	(and (match_dup 0)
831290286Sobrien	     (const_int -65281)))
831390286Sobrien   (clobber (reg:CC 17))]
831490286Sobrien  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
831590286Sobrien  [(parallel [(set (zero_extract:SI (match_dup 0)
831690286Sobrien				    (const_int 8)
831790286Sobrien				    (const_int 8))
831890286Sobrien		   (xor:SI 
831990286Sobrien		     (zero_extract:SI (match_dup 0)
832090286Sobrien				      (const_int 8)
832190286Sobrien				      (const_int 8))
832290286Sobrien		     (zero_extract:SI (match_dup 0)
832390286Sobrien				      (const_int 8)
832490286Sobrien				      (const_int 8))))
832590286Sobrien	      (clobber (reg:CC 17))])]
832690286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);")
832750650Sobrien
832890286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
832990286Sobrien(define_insn "*andsi_1_zext"
833090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
833190286Sobrien	(zero_extend:DI
833290286Sobrien	  (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
833390286Sobrien		  (match_operand:SI 2 "general_operand" "rim"))))
833490286Sobrien   (clobber (reg:CC 17))]
833590286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
833690286Sobrien  "and{l}\t{%2, %k0|%k0, %2}"
833790286Sobrien  [(set_attr "type" "alu")
833890286Sobrien   (set_attr "mode" "SI")])
833918334Speter
834090286Sobrien(define_insn "*andsi_2"
834190286Sobrien  [(set (reg 17)
834290286Sobrien	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
834390286Sobrien			 (match_operand:SI 2 "general_operand" "rim,ri"))
834490286Sobrien		 (const_int 0)))
834590286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
834690286Sobrien	(and:SI (match_dup 1) (match_dup 2)))]
834790286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
834890286Sobrien   && ix86_binary_operator_ok (AND, SImode, operands)"
834990286Sobrien  "and{l}\t{%2, %0|%0, %2}"
835090286Sobrien  [(set_attr "type" "alu")
835190286Sobrien   (set_attr "mode" "SI")])
835290286Sobrien
835390286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
835490286Sobrien(define_insn "*andsi_2_zext"
835590286Sobrien  [(set (reg 17)
835690286Sobrien	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
835790286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
835890286Sobrien		 (const_int 0)))
835990286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
836090286Sobrien	(zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
836190286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
836290286Sobrien   && ix86_binary_operator_ok (AND, SImode, operands)"
836390286Sobrien  "and{l}\t{%2, %k0|%k0, %2}"
836490286Sobrien  [(set_attr "type" "alu")
836590286Sobrien   (set_attr "mode" "SI")])
836690286Sobrien
836790286Sobrien(define_expand "andhi3"
836890286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
836990286Sobrien	(and:HI (match_operand:HI 1 "nonimmediate_operand" "")
837090286Sobrien		(match_operand:HI 2 "general_operand" "")))
837190286Sobrien   (clobber (reg:CC 17))]
837290286Sobrien  "TARGET_HIMODE_MATH"
837390286Sobrien  "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
837490286Sobrien
837590286Sobrien(define_insn "*andhi_1"
837690286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
837790286Sobrien	(and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
837890286Sobrien		(match_operand:HI 2 "general_operand" "ri,rm,L")))
837990286Sobrien   (clobber (reg:CC 17))]
838090286Sobrien  "ix86_binary_operator_ok (AND, HImode, operands)"
838190286Sobrien{
838290286Sobrien  switch (get_attr_type (insn))
838350650Sobrien    {
838490286Sobrien    case TYPE_IMOVX:
838590286Sobrien      if (GET_CODE (operands[2]) != CONST_INT)
838690286Sobrien	abort ();
838790286Sobrien      if (INTVAL (operands[2]) == 0xff)
838890286Sobrien	return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
838990286Sobrien      abort ();
839090286Sobrien
839190286Sobrien    default:
839290286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
839390286Sobrien	abort ();
839490286Sobrien
839590286Sobrien      return "and{w}\t{%2, %0|%0, %2}";
839650650Sobrien    }
839790286Sobrien}
839890286Sobrien  [(set_attr "type" "alu,alu,imovx")
839990286Sobrien   (set_attr "length_immediate" "*,*,0")
840090286Sobrien   (set_attr "mode" "HI,HI,SI")])
840150650Sobrien
840290286Sobrien(define_insn "*andhi_2"
840390286Sobrien  [(set (reg 17)
840490286Sobrien	(compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
840590286Sobrien			 (match_operand:HI 2 "general_operand" "rim,ri"))
840690286Sobrien		 (const_int 0)))
840790286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
840890286Sobrien	(and:HI (match_dup 1) (match_dup 2)))]
840990286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
841090286Sobrien   && ix86_binary_operator_ok (AND, HImode, operands)"
841190286Sobrien  "and{w}\t{%2, %0|%0, %2}"
841290286Sobrien  [(set_attr "type" "alu")
841390286Sobrien   (set_attr "mode" "HI")])
841490286Sobrien
841590286Sobrien(define_expand "andqi3"
841690286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
841790286Sobrien	(and:QI (match_operand:QI 1 "nonimmediate_operand" "")
841890286Sobrien		(match_operand:QI 2 "general_operand" "")))
841990286Sobrien   (clobber (reg:CC 17))]
842090286Sobrien  "TARGET_QIMODE_MATH"
842190286Sobrien  "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
842290286Sobrien
842390286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
842490286Sobrien(define_insn "*andqi_1"
842590286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
842690286Sobrien	(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
842790286Sobrien		(match_operand:QI 2 "general_operand" "qi,qmi,ri")))
842890286Sobrien   (clobber (reg:CC 17))]
842990286Sobrien  "ix86_binary_operator_ok (AND, QImode, operands)"
843090286Sobrien  "@
843190286Sobrien   and{b}\t{%2, %0|%0, %2}
843290286Sobrien   and{b}\t{%2, %0|%0, %2}
843390286Sobrien   and{l}\t{%k2, %k0|%k0, %k2}"
843490286Sobrien  [(set_attr "type" "alu")
843590286Sobrien   (set_attr "mode" "QI,QI,SI")])
843690286Sobrien
843790286Sobrien(define_insn "*andqi_1_slp"
843890286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
843990286Sobrien	(and:QI (match_dup 0)
844090286Sobrien		(match_operand:QI 1 "general_operand" "qi,qmi")))
844190286Sobrien   (clobber (reg:CC 17))]
844290286Sobrien  ""
844390286Sobrien  "and{b}\t{%1, %0|%0, %1}"
844490286Sobrien  [(set_attr "type" "alu1")
844590286Sobrien   (set_attr "mode" "QI")])
844690286Sobrien
844790286Sobrien(define_insn "*andqi_2"
844890286Sobrien  [(set (reg 17)
844990286Sobrien	(compare (and:QI
845090286Sobrien		   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
845190286Sobrien		   (match_operand:QI 2 "general_operand" "qim,qi,i"))
845290286Sobrien		 (const_int 0)))
845390286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
845490286Sobrien	(and:QI (match_dup 1) (match_dup 2)))]
845590286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
845690286Sobrien   && ix86_binary_operator_ok (AND, QImode, operands)"
845790286Sobrien{
845890286Sobrien  if (which_alternative == 2)
845950650Sobrien    {
846090286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
846190286Sobrien          && (INTVAL (operands[2]) & 0xffffff00))
846290286Sobrien        operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
846390286Sobrien      return "and{l}\t{%2, %k0|%k0, %2}";
846450650Sobrien    }
846590286Sobrien  return "and{b}\t{%2, %0|%0, %2}";
846690286Sobrien}
846790286Sobrien  [(set_attr "type" "alu")
846890286Sobrien   (set_attr "mode" "QI,QI,SI")])
846950650Sobrien
847090286Sobrien(define_insn "*andqi_2_slp"
847190286Sobrien  [(set (reg 17)
847290286Sobrien	(compare (and:QI
847390286Sobrien		   (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
847490286Sobrien		   (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
847590286Sobrien		 (const_int 0)))
847690286Sobrien   (set (strict_low_part (match_dup 0))
847790286Sobrien	(and:QI (match_dup 0) (match_dup 1)))]
847890286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
847990286Sobrien  "and{b}\t{%1, %0|%0, %1}"
848090286Sobrien  [(set_attr "type" "alu1")
848190286Sobrien   (set_attr "mode" "QI")])
848218334Speter
848390286Sobrien;; ??? A bug in recog prevents it from recognizing a const_int as an
848490286Sobrien;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
848590286Sobrien;; for a QImode operand, which of course failed.
848618334Speter
848790286Sobrien(define_insn "andqi_ext_0"
848890286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
848990286Sobrien			 (const_int 8)
849090286Sobrien			 (const_int 8))
849190286Sobrien	(and:SI 
849290286Sobrien	  (zero_extract:SI
849390286Sobrien	    (match_operand 1 "ext_register_operand" "0")
849490286Sobrien	    (const_int 8)
849590286Sobrien	    (const_int 8))
849690286Sobrien	  (match_operand 2 "const_int_operand" "n")))
849790286Sobrien   (clobber (reg:CC 17))]
849890286Sobrien  "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
849990286Sobrien  "and{b}\t{%2, %h0|%h0, %2}"
850090286Sobrien  [(set_attr "type" "alu")
850190286Sobrien   (set_attr "length_immediate" "1")
850290286Sobrien   (set_attr "mode" "QI")])
850318334Speter
850490286Sobrien;; Generated by peephole translating test to and.  This shows up
850590286Sobrien;; often in fp comparisons.
850690286Sobrien
850790286Sobrien(define_insn "*andqi_ext_0_cc"
850890286Sobrien  [(set (reg 17)
850990286Sobrien	(compare
851090286Sobrien	  (and:SI
851190286Sobrien	    (zero_extract:SI
851290286Sobrien	      (match_operand 1 "ext_register_operand" "0")
851390286Sobrien	      (const_int 8)
851490286Sobrien	      (const_int 8))
851590286Sobrien	    (match_operand 2 "const_int_operand" "n"))
851690286Sobrien	  (const_int 0)))
851790286Sobrien   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
851890286Sobrien			 (const_int 8)
851990286Sobrien			 (const_int 8))
852090286Sobrien	(and:SI 
852190286Sobrien	  (zero_extract:SI
852290286Sobrien	    (match_dup 1)
852390286Sobrien	    (const_int 8)
852490286Sobrien	    (const_int 8))
852590286Sobrien	  (match_dup 2)))]
852690286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
852790286Sobrien   && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
852890286Sobrien  "and{b}\t{%2, %h0|%h0, %2}"
852990286Sobrien  [(set_attr "type" "alu")
853090286Sobrien   (set_attr "length_immediate" "1")
853190286Sobrien   (set_attr "mode" "QI")])
853290286Sobrien
853390286Sobrien(define_insn "*andqi_ext_1"
853490286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
853590286Sobrien			 (const_int 8)
853690286Sobrien			 (const_int 8))
853790286Sobrien	(and:SI 
853890286Sobrien	  (zero_extract:SI
853990286Sobrien	    (match_operand 1 "ext_register_operand" "0")
854090286Sobrien	    (const_int 8)
854190286Sobrien	    (const_int 8))
854290286Sobrien	  (zero_extend:SI
854390286Sobrien	    (match_operand:QI 2 "general_operand" "Qm"))))
854490286Sobrien   (clobber (reg:CC 17))]
854590286Sobrien  "!TARGET_64BIT"
854690286Sobrien  "and{b}\t{%2, %h0|%h0, %2}"
854790286Sobrien  [(set_attr "type" "alu")
854890286Sobrien   (set_attr "length_immediate" "0")
854990286Sobrien   (set_attr "mode" "QI")])
855090286Sobrien
855190286Sobrien(define_insn "*andqi_ext_1_rex64"
855290286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
855390286Sobrien			 (const_int 8)
855490286Sobrien			 (const_int 8))
855590286Sobrien	(and:SI 
855690286Sobrien	  (zero_extract:SI
855790286Sobrien	    (match_operand 1 "ext_register_operand" "0")
855890286Sobrien	    (const_int 8)
855990286Sobrien	    (const_int 8))
856090286Sobrien	  (zero_extend:SI
856190286Sobrien	    (match_operand 2 "ext_register_operand" "Q"))))
856290286Sobrien   (clobber (reg:CC 17))]
856390286Sobrien  "TARGET_64BIT"
856490286Sobrien  "and{b}\t{%2, %h0|%h0, %2}"
856590286Sobrien  [(set_attr "type" "alu")
856690286Sobrien   (set_attr "length_immediate" "0")
856790286Sobrien   (set_attr "mode" "QI")])
856890286Sobrien
856990286Sobrien(define_insn "*andqi_ext_2"
857090286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
857190286Sobrien			 (const_int 8)
857290286Sobrien			 (const_int 8))
857318334Speter	(and:SI
857490286Sobrien	  (zero_extract:SI
857590286Sobrien	    (match_operand 1 "ext_register_operand" "%0")
857690286Sobrien	    (const_int 8)
857790286Sobrien	    (const_int 8))
857890286Sobrien	  (zero_extract:SI
857990286Sobrien	    (match_operand 2 "ext_register_operand" "Q")
858090286Sobrien	    (const_int 8)
858190286Sobrien	    (const_int 8))))
858290286Sobrien   (clobber (reg:CC 17))]
858390286Sobrien  ""
858490286Sobrien  "and{b}\t{%h2, %h0|%h0, %h2}"
858590286Sobrien  [(set_attr "type" "alu")
858690286Sobrien   (set_attr "length_immediate" "0")
858790286Sobrien   (set_attr "mode" "QI")])
858818334Speter
858990286Sobrien;; Logical inclusive OR instructions
859018334Speter
859190286Sobrien;; %%% This used to optimize known byte-wide and operations to memory.
859290286Sobrien;; If this is considered useful, it should be done with splitters.
859390286Sobrien
859490286Sobrien(define_expand "iordi3"
859590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
859690286Sobrien	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
859790286Sobrien		(match_operand:DI 2 "x86_64_general_operand" "")))
859890286Sobrien   (clobber (reg:CC 17))]
859990286Sobrien  "TARGET_64BIT"
860090286Sobrien  "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
860190286Sobrien
860290286Sobrien(define_insn "*iordi_1_rex64"
860390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
860490286Sobrien	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
860590286Sobrien		(match_operand:DI 2 "x86_64_general_operand" "re,rme")))
860690286Sobrien   (clobber (reg:CC 17))]
860790286Sobrien  "TARGET_64BIT
860890286Sobrien   && ix86_binary_operator_ok (IOR, DImode, operands)"
860990286Sobrien  "or{q}\t{%2, %0|%0, %2}"
861090286Sobrien  [(set_attr "type" "alu")
861190286Sobrien   (set_attr "mode" "DI")])
861290286Sobrien
861390286Sobrien(define_insn "*iordi_2_rex64"
861490286Sobrien  [(set (reg 17)
861590286Sobrien	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
861690286Sobrien			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
861790286Sobrien		 (const_int 0)))
861890286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
861990286Sobrien	(ior:DI (match_dup 1) (match_dup 2)))]
862090286Sobrien  "TARGET_64BIT
862190286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
862290286Sobrien   && ix86_binary_operator_ok (IOR, DImode, operands)"
862390286Sobrien  "or{q}\t{%2, %0|%0, %2}"
862490286Sobrien  [(set_attr "type" "alu")
862590286Sobrien   (set_attr "mode" "DI")])
862690286Sobrien
862790286Sobrien(define_insn "*iordi_3_rex64"
862890286Sobrien  [(set (reg 17)
862990286Sobrien	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
863090286Sobrien			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
863190286Sobrien		 (const_int 0)))
863290286Sobrien   (clobber (match_scratch:DI 0 "=r"))]
863390286Sobrien  "TARGET_64BIT
863490286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
863590286Sobrien   && ix86_binary_operator_ok (IOR, DImode, operands)"
863690286Sobrien  "or{q}\t{%2, %0|%0, %2}"
863790286Sobrien  [(set_attr "type" "alu")
863890286Sobrien   (set_attr "mode" "DI")])
863990286Sobrien
864090286Sobrien
864190286Sobrien(define_expand "iorsi3"
864290286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
864390286Sobrien	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
864490286Sobrien		(match_operand:SI 2 "general_operand" "")))
864590286Sobrien   (clobber (reg:CC 17))]
864690286Sobrien  ""
864790286Sobrien  "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
864890286Sobrien
864990286Sobrien(define_insn "*iorsi_1"
865050650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
865150650Sobrien	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
865290286Sobrien		(match_operand:SI 2 "general_operand" "ri,rmi")))
865390286Sobrien   (clobber (reg:CC 17))]
865490286Sobrien  "ix86_binary_operator_ok (IOR, SImode, operands)"
865590286Sobrien  "or{l}\t{%2, %0|%0, %2}"
865690286Sobrien  [(set_attr "type" "alu")
865790286Sobrien   (set_attr "mode" "SI")])
865850650Sobrien
865990286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
866090286Sobrien(define_insn "*iorsi_1_zext"
866190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=rm")
866290286Sobrien	(zero_extend:DI
866390286Sobrien	  (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
866490286Sobrien		  (match_operand:SI 2 "general_operand" "rim"))))
866590286Sobrien   (clobber (reg:CC 17))]
866690286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
866790286Sobrien  "or{l}\t{%2, %k0|%k0, %2}"
866890286Sobrien  [(set_attr "type" "alu")
866990286Sobrien   (set_attr "mode" "SI")])
867050650Sobrien
867190286Sobrien(define_insn "*iorsi_1_zext_imm"
867290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=rm")
867390286Sobrien	(ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
867490286Sobrien		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
867590286Sobrien   (clobber (reg:CC 17))]
867690286Sobrien  "TARGET_64BIT"
867790286Sobrien  "or{l}\t{%2, %k0|%k0, %2}"
867890286Sobrien  [(set_attr "type" "alu")
867990286Sobrien   (set_attr "mode" "SI")])
868050650Sobrien
868190286Sobrien(define_insn "*iorsi_2"
868290286Sobrien  [(set (reg 17)
868390286Sobrien	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
868490286Sobrien			 (match_operand:SI 2 "general_operand" "rim,ri"))
868590286Sobrien		 (const_int 0)))
868690286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
868790286Sobrien	(ior:SI (match_dup 1) (match_dup 2)))]
868890286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
868990286Sobrien   && ix86_binary_operator_ok (IOR, SImode, operands)"
869090286Sobrien  "or{l}\t{%2, %0|%0, %2}"
869190286Sobrien  [(set_attr "type" "alu")
869290286Sobrien   (set_attr "mode" "SI")])
869350650Sobrien
869490286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
869590286Sobrien;; ??? Special case for immediate operand is missing - it is tricky.
869690286Sobrien(define_insn "*iorsi_2_zext"
869790286Sobrien  [(set (reg 17)
869890286Sobrien	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
869990286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
870090286Sobrien		 (const_int 0)))
870190286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
870290286Sobrien	(zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
870390286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
870490286Sobrien   && ix86_binary_operator_ok (IOR, SImode, operands)"
870590286Sobrien  "or{l}\t{%2, %k0|%k0, %2}"
870690286Sobrien  [(set_attr "type" "alu")
870790286Sobrien   (set_attr "mode" "SI")])
870850650Sobrien
870990286Sobrien(define_insn "*iorsi_2_zext_imm"
871090286Sobrien  [(set (reg 17)
871190286Sobrien	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
871290286Sobrien			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
871390286Sobrien		 (const_int 0)))
871490286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
871590286Sobrien	(ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
871690286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
871790286Sobrien   && ix86_binary_operator_ok (IOR, SImode, operands)"
871890286Sobrien  "or{l}\t{%2, %k0|%k0, %2}"
871990286Sobrien  [(set_attr "type" "alu")
872090286Sobrien   (set_attr "mode" "SI")])
872150650Sobrien
872290286Sobrien(define_insn "*iorsi_3"
872390286Sobrien  [(set (reg 17)
872490286Sobrien	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
872590286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
872690286Sobrien		 (const_int 0)))
872790286Sobrien   (clobber (match_scratch:SI 0 "=r"))]
872890286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
872990286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
873090286Sobrien  "or{l}\t{%2, %0|%0, %2}"
873190286Sobrien  [(set_attr "type" "alu")
873290286Sobrien   (set_attr "mode" "SI")])
873350650Sobrien
873490286Sobrien(define_expand "iorhi3"
873590286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
873690286Sobrien	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
873790286Sobrien		(match_operand:HI 2 "general_operand" "")))
873890286Sobrien   (clobber (reg:CC 17))]
873990286Sobrien  "TARGET_HIMODE_MATH"
874090286Sobrien  "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
874150650Sobrien
874290286Sobrien(define_insn "*iorhi_1"
874390286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
874490286Sobrien	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
874590286Sobrien		(match_operand:HI 2 "general_operand" "rmi,ri")))
874690286Sobrien   (clobber (reg:CC 17))]
874790286Sobrien  "ix86_binary_operator_ok (IOR, HImode, operands)"
874890286Sobrien  "or{w}\t{%2, %0|%0, %2}"
874990286Sobrien  [(set_attr "type" "alu")
875090286Sobrien   (set_attr "mode" "HI")])
875118334Speter
875290286Sobrien(define_insn "*iorhi_2"
875390286Sobrien  [(set (reg 17)
875490286Sobrien	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
875590286Sobrien			 (match_operand:HI 2 "general_operand" "rim,ri"))
875690286Sobrien		 (const_int 0)))
875790286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
875890286Sobrien	(ior:HI (match_dup 1) (match_dup 2)))]
875990286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
876090286Sobrien   && ix86_binary_operator_ok (IOR, HImode, operands)"
876190286Sobrien  "or{w}\t{%2, %0|%0, %2}"
876290286Sobrien  [(set_attr "type" "alu")
876390286Sobrien   (set_attr "mode" "HI")])
876418334Speter
876590286Sobrien(define_insn "*iorhi_3"
876690286Sobrien  [(set (reg 17)
876790286Sobrien	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
876890286Sobrien			 (match_operand:HI 2 "general_operand" "rim"))
876990286Sobrien		 (const_int 0)))
877090286Sobrien   (clobber (match_scratch:HI 0 "=r"))]
877190286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
877290286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
877390286Sobrien  "or{w}\t{%2, %0|%0, %2}"
877490286Sobrien  [(set_attr "type" "alu")
877590286Sobrien   (set_attr "mode" "HI")])
877650650Sobrien
877790286Sobrien(define_expand "iorqi3"
877890286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
877990286Sobrien	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
878090286Sobrien		(match_operand:QI 2 "general_operand" "")))
878190286Sobrien   (clobber (reg:CC 17))]
878290286Sobrien  "TARGET_QIMODE_MATH"
878390286Sobrien  "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
878418334Speter
878590286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
878690286Sobrien(define_insn "*iorqi_1"
878790286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
878890286Sobrien	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
878990286Sobrien		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
879090286Sobrien   (clobber (reg:CC 17))]
879190286Sobrien  "ix86_binary_operator_ok (IOR, QImode, operands)"
879290286Sobrien  "@
879390286Sobrien   or{b}\t{%2, %0|%0, %2}
879490286Sobrien   or{b}\t{%2, %0|%0, %2}
879590286Sobrien   or{l}\t{%k2, %k0|%k0, %k2}"
879690286Sobrien  [(set_attr "type" "alu")
879790286Sobrien   (set_attr "mode" "QI,QI,SI")])
879850650Sobrien
879990286Sobrien(define_insn "*iorqi_1_slp"
880090286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
880190286Sobrien	(ior:QI (match_dup 0)
880290286Sobrien		(match_operand:QI 1 "general_operand" "qmi,qi")))
880390286Sobrien   (clobber (reg:CC 17))]
880490286Sobrien  ""
880590286Sobrien  "or{b}\t{%1, %0|%0, %1}"
880690286Sobrien  [(set_attr "type" "alu1")
880790286Sobrien   (set_attr "mode" "QI")])
880818334Speter
880990286Sobrien(define_insn "*iorqi_2"
881090286Sobrien  [(set (reg 17)
881190286Sobrien	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
881290286Sobrien			 (match_operand:QI 2 "general_operand" "qim,qi"))
881390286Sobrien		 (const_int 0)))
881490286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
881590286Sobrien	(ior:QI (match_dup 1) (match_dup 2)))]
881690286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
881790286Sobrien   && ix86_binary_operator_ok (IOR, QImode, operands)"
881890286Sobrien  "or{b}\t{%2, %0|%0, %2}"
881990286Sobrien  [(set_attr "type" "alu")
882090286Sobrien   (set_attr "mode" "QI")])
882118334Speter
882290286Sobrien(define_insn "*iorqi_2_slp"
882390286Sobrien  [(set (reg 17)
882490286Sobrien	(compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
882590286Sobrien			 (match_operand:QI 1 "general_operand" "qim,qi"))
882690286Sobrien		 (const_int 0)))
882790286Sobrien   (set (strict_low_part (match_dup 0))
882890286Sobrien	(ior:QI (match_dup 0) (match_dup 1)))]
882990286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
883090286Sobrien  "or{b}\t{%1, %0|%0, %1}"
883190286Sobrien  [(set_attr "type" "alu1")
883290286Sobrien   (set_attr "mode" "QI")])
883318334Speter
883490286Sobrien(define_insn "*iorqi_3"
883590286Sobrien  [(set (reg 17)
883690286Sobrien	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
883790286Sobrien			 (match_operand:QI 2 "general_operand" "qim"))
883890286Sobrien		 (const_int 0)))
883990286Sobrien   (clobber (match_scratch:QI 0 "=q"))]
884090286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
884190286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
884290286Sobrien  "or{b}\t{%2, %0|%0, %2}"
884390286Sobrien  [(set_attr "type" "alu")
884490286Sobrien   (set_attr "mode" "QI")])
884518334Speter
884690286Sobrien
884790286Sobrien;; Logical XOR instructions
884890286Sobrien
884990286Sobrien;; %%% This used to optimize known byte-wide and operations to memory.
885090286Sobrien;; If this is considered useful, it should be done with splitters.
885190286Sobrien
885290286Sobrien(define_expand "xordi3"
885390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
885490286Sobrien	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
885590286Sobrien		(match_operand:DI 2 "x86_64_general_operand" "")))
885690286Sobrien   (clobber (reg:CC 17))]
885790286Sobrien  "TARGET_64BIT"
885890286Sobrien  "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
885990286Sobrien
886090286Sobrien(define_insn "*xordi_1_rex64"
886190286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
886290286Sobrien	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
886390286Sobrien		(match_operand:DI 2 "x86_64_general_operand" "re,rm")))
886490286Sobrien   (clobber (reg:CC 17))]
886590286Sobrien  "TARGET_64BIT
886690286Sobrien   && ix86_binary_operator_ok (XOR, DImode, operands)"
886790286Sobrien  "@
886890286Sobrien   xor{q}\t{%2, %0|%0, %2} 
886990286Sobrien   xor{q}\t{%2, %0|%0, %2}"
887090286Sobrien  [(set_attr "type" "alu")
887190286Sobrien   (set_attr "mode" "DI,DI")])
887290286Sobrien
887390286Sobrien(define_insn "*xordi_2_rex64"
887490286Sobrien  [(set (reg 17)
887590286Sobrien	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
887690286Sobrien			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
887790286Sobrien		 (const_int 0)))
887890286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
887990286Sobrien	(xor:DI (match_dup 1) (match_dup 2)))]
888090286Sobrien  "TARGET_64BIT
888190286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
888290286Sobrien   && ix86_binary_operator_ok (XOR, DImode, operands)"
888390286Sobrien  "@
888490286Sobrien   xor{q}\t{%2, %0|%0, %2} 
888590286Sobrien   xor{q}\t{%2, %0|%0, %2}"
888690286Sobrien  [(set_attr "type" "alu")
888790286Sobrien   (set_attr "mode" "DI,DI")])
888890286Sobrien
888990286Sobrien(define_insn "*xordi_3_rex64"
889090286Sobrien  [(set (reg 17)
889190286Sobrien	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
889290286Sobrien			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
889390286Sobrien		 (const_int 0)))
889490286Sobrien   (clobber (match_scratch:DI 0 "=r"))]
889590286Sobrien  "TARGET_64BIT
889690286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
889790286Sobrien   && ix86_binary_operator_ok (XOR, DImode, operands)"
889890286Sobrien  "xor{q}\t{%2, %0|%0, %2}"
889990286Sobrien  [(set_attr "type" "alu")
890090286Sobrien   (set_attr "mode" "DI")])
890190286Sobrien
890290286Sobrien(define_expand "xorsi3"
890390286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
890490286Sobrien	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
890590286Sobrien		(match_operand:SI 2 "general_operand" "")))
890690286Sobrien   (clobber (reg:CC 17))]
890718334Speter  ""
890890286Sobrien  "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
890918334Speter
891090286Sobrien(define_insn "*xorsi_1"
891190286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
891290286Sobrien	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
891390286Sobrien		(match_operand:SI 2 "general_operand" "ri,rm")))
891490286Sobrien   (clobber (reg:CC 17))]
891590286Sobrien  "ix86_binary_operator_ok (XOR, SImode, operands)"
891690286Sobrien  "xor{l}\t{%2, %0|%0, %2}"
891790286Sobrien  [(set_attr "type" "alu")
891890286Sobrien   (set_attr "mode" "SI")])
891918334Speter
892090286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
892190286Sobrien;; Add speccase for immediates
892290286Sobrien(define_insn "*xorsi_1_zext"
892390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
892490286Sobrien	(zero_extend:DI
892590286Sobrien	  (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
892690286Sobrien		  (match_operand:SI 2 "general_operand" "rim"))))
892790286Sobrien   (clobber (reg:CC 17))]
892890286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
892990286Sobrien  "xor{l}\t{%2, %k0|%k0, %2}"
893090286Sobrien  [(set_attr "type" "alu")
893190286Sobrien   (set_attr "mode" "SI")])
893250650Sobrien
893390286Sobrien(define_insn "*xorsi_1_zext_imm"
893490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
893590286Sobrien	(xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
893690286Sobrien		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
893790286Sobrien   (clobber (reg:CC 17))]
893890286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
893990286Sobrien  "xor{l}\t{%2, %k0|%k0, %2}"
894090286Sobrien  [(set_attr "type" "alu")
894190286Sobrien   (set_attr "mode" "SI")])
894250650Sobrien
894390286Sobrien(define_insn "*xorsi_2"
894490286Sobrien  [(set (reg 17)
894590286Sobrien	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
894690286Sobrien			 (match_operand:SI 2 "general_operand" "rim,ri"))
894790286Sobrien		 (const_int 0)))
894890286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
894990286Sobrien	(xor:SI (match_dup 1) (match_dup 2)))]
895090286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
895190286Sobrien   && ix86_binary_operator_ok (XOR, SImode, operands)"
895290286Sobrien  "xor{l}\t{%2, %0|%0, %2}"
895390286Sobrien  [(set_attr "type" "alu")
895490286Sobrien   (set_attr "mode" "SI")])
895550650Sobrien
895690286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
895790286Sobrien;; ??? Special case for immediate operand is missing - it is tricky.
895890286Sobrien(define_insn "*xorsi_2_zext"
895990286Sobrien  [(set (reg 17)
896090286Sobrien	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
896190286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
896290286Sobrien		 (const_int 0)))
896390286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
896490286Sobrien	(zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
896590286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
896690286Sobrien   && ix86_binary_operator_ok (XOR, SImode, operands)"
896790286Sobrien  "xor{l}\t{%2, %k0|%k0, %2}"
896890286Sobrien  [(set_attr "type" "alu")
896990286Sobrien   (set_attr "mode" "SI")])
897050650Sobrien
897190286Sobrien(define_insn "*xorsi_2_zext_imm"
897290286Sobrien  [(set (reg 17)
897390286Sobrien	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
897490286Sobrien			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
897590286Sobrien		 (const_int 0)))
897690286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
897790286Sobrien	(xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
897890286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
897990286Sobrien   && ix86_binary_operator_ok (XOR, SImode, operands)"
898090286Sobrien  "xor{l}\t{%2, %k0|%k0, %2}"
898190286Sobrien  [(set_attr "type" "alu")
898290286Sobrien   (set_attr "mode" "SI")])
898350650Sobrien
898490286Sobrien(define_insn "*xorsi_3"
898590286Sobrien  [(set (reg 17)
898690286Sobrien	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
898790286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
898890286Sobrien		 (const_int 0)))
898990286Sobrien   (clobber (match_scratch:SI 0 "=r"))]
899090286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
899190286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
899290286Sobrien  "xor{l}\t{%2, %0|%0, %2}"
899390286Sobrien  [(set_attr "type" "alu")
899490286Sobrien   (set_attr "mode" "SI")])
899518334Speter
899690286Sobrien(define_expand "xorhi3"
899790286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
899890286Sobrien	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
899990286Sobrien		(match_operand:HI 2 "general_operand" "")))
900090286Sobrien   (clobber (reg:CC 17))]
900190286Sobrien  "TARGET_HIMODE_MATH"
900290286Sobrien  "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
900318334Speter
900490286Sobrien(define_insn "*xorhi_1"
900590286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
900690286Sobrien	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
900790286Sobrien		(match_operand:HI 2 "general_operand" "rmi,ri")))
900890286Sobrien   (clobber (reg:CC 17))]
900990286Sobrien  "ix86_binary_operator_ok (XOR, HImode, operands)"
901090286Sobrien  "xor{w}\t{%2, %0|%0, %2}"
901190286Sobrien  [(set_attr "type" "alu")
901290286Sobrien   (set_attr "mode" "HI")])
901318334Speter
901490286Sobrien(define_insn "*xorhi_2"
901590286Sobrien  [(set (reg 17)
901690286Sobrien	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
901790286Sobrien			 (match_operand:HI 2 "general_operand" "rim,ri"))
901890286Sobrien		 (const_int 0)))
901990286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
902090286Sobrien	(xor:HI (match_dup 1) (match_dup 2)))]
902190286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
902290286Sobrien   && ix86_binary_operator_ok (XOR, HImode, operands)"
902390286Sobrien  "xor{w}\t{%2, %0|%0, %2}"
902490286Sobrien  [(set_attr "type" "alu")
902590286Sobrien   (set_attr "mode" "HI")])
902650650Sobrien
902790286Sobrien(define_insn "*xorhi_3"
902890286Sobrien  [(set (reg 17)
902990286Sobrien	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
903090286Sobrien			 (match_operand:HI 2 "general_operand" "rim"))
903190286Sobrien		 (const_int 0)))
903290286Sobrien   (clobber (match_scratch:HI 0 "=r"))]
903390286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
903490286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
903590286Sobrien  "xor{w}\t{%2, %0|%0, %2}"
903690286Sobrien  [(set_attr "type" "alu")
903790286Sobrien   (set_attr "mode" "HI")])
903850650Sobrien
903990286Sobrien(define_expand "xorqi3"
904090286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
904190286Sobrien	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
904290286Sobrien		(match_operand:QI 2 "general_operand" "")))
904390286Sobrien   (clobber (reg:CC 17))]
904490286Sobrien  "TARGET_QIMODE_MATH"
904590286Sobrien  "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
904650650Sobrien
904790286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
904890286Sobrien(define_insn "*xorqi_1"
904990286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
905090286Sobrien	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
905190286Sobrien		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
905290286Sobrien   (clobber (reg:CC 17))]
905390286Sobrien  "ix86_binary_operator_ok (XOR, QImode, operands)"
905490286Sobrien  "@
905590286Sobrien   xor{b}\t{%2, %0|%0, %2}
905690286Sobrien   xor{b}\t{%2, %0|%0, %2}
905790286Sobrien   xor{l}\t{%k2, %k0|%k0, %k2}"
905890286Sobrien  [(set_attr "type" "alu")
905990286Sobrien   (set_attr "mode" "QI,QI,SI")])
906018334Speter
906190286Sobrien(define_insn "*xorqi_ext_1"
906290286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
906390286Sobrien			 (const_int 8)
906490286Sobrien			 (const_int 8))
906590286Sobrien	(xor:SI 
906690286Sobrien	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
906790286Sobrien	  		   (const_int 8)
906890286Sobrien			   (const_int 8))
906990286Sobrien	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
907090286Sobrien	  		   (const_int 8)
907190286Sobrien			   (const_int 8))))
907290286Sobrien   (clobber (reg:CC 17))]
907390286Sobrien  ""
907490286Sobrien  "xor{b}\t{%h2, %h0|%h0, %h2}"
907590286Sobrien  [(set_attr "type" "alu")
907690286Sobrien   (set_attr "length_immediate" "0")
907790286Sobrien   (set_attr "mode" "QI")])
907850650Sobrien
907990286Sobrien(define_insn "*xorqi_cc_1"
908090286Sobrien  [(set (reg 17)
908190286Sobrien	(compare
908290286Sobrien	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
908390286Sobrien		  (match_operand:QI 2 "general_operand" "qim,qi"))
908490286Sobrien	  (const_int 0)))
908590286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
908690286Sobrien	(xor:QI (match_dup 1) (match_dup 2)))]
908790286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
908890286Sobrien   && ix86_binary_operator_ok (XOR, QImode, operands)"
908990286Sobrien  "xor{b}\t{%2, %0|%0, %2}"
909090286Sobrien  [(set_attr "type" "alu")
909190286Sobrien   (set_attr "mode" "QI")])
909250650Sobrien
909390286Sobrien(define_insn "*xorqi_cc_2"
909490286Sobrien  [(set (reg 17)
909590286Sobrien	(compare
909690286Sobrien	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
909790286Sobrien		  (match_operand:QI 2 "general_operand" "qim"))
909890286Sobrien	  (const_int 0)))
909990286Sobrien   (clobber (match_scratch:QI 0 "=q"))]
910090286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
910190286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
910290286Sobrien  "xor{b}\t{%2, %0|%0, %2}"
910390286Sobrien  [(set_attr "type" "alu")
910490286Sobrien   (set_attr "mode" "QI")])
910518334Speter
910690286Sobrien(define_insn "*xorqi_cc_ext_1"
910790286Sobrien  [(set (reg 17)
910890286Sobrien	(compare
910990286Sobrien	  (xor:SI
911090286Sobrien	    (zero_extract:SI
911190286Sobrien	      (match_operand 1 "ext_register_operand" "0")
911290286Sobrien	      (const_int 8)
911390286Sobrien	      (const_int 8))
911490286Sobrien	    (match_operand:QI 2 "general_operand" "qmn"))
911590286Sobrien	  (const_int 0)))
911690286Sobrien   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
911790286Sobrien			 (const_int 8)
911890286Sobrien			 (const_int 8))
911990286Sobrien	(xor:SI 
912090286Sobrien	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
912190286Sobrien	  (match_dup 2)))]
912290286Sobrien  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
912390286Sobrien  "xor{b}\t{%2, %h0|%h0, %2}"
912490286Sobrien  [(set_attr "type" "alu")
912590286Sobrien   (set_attr "mode" "QI")])
912690286Sobrien
912790286Sobrien(define_insn "*xorqi_cc_ext_1_rex64"
912890286Sobrien  [(set (reg 17)
912990286Sobrien	(compare
913090286Sobrien	  (xor:SI
913190286Sobrien	    (zero_extract:SI
913290286Sobrien	      (match_operand 1 "ext_register_operand" "0")
913390286Sobrien	      (const_int 8)
913490286Sobrien	      (const_int 8))
913590286Sobrien	    (match_operand:QI 2 "nonmemory_operand" "Qn"))
913690286Sobrien	  (const_int 0)))
913790286Sobrien   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
913890286Sobrien			 (const_int 8)
913990286Sobrien			 (const_int 8))
914090286Sobrien	(xor:SI 
914190286Sobrien	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
914290286Sobrien	  (match_dup 2)))]
914390286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
914490286Sobrien  "xor{b}\t{%2, %h0|%h0, %2}"
914590286Sobrien  [(set_attr "type" "alu")
914690286Sobrien   (set_attr "mode" "QI")])
914790286Sobrien
914890286Sobrien(define_expand "xorqi_cc_ext_1"
914990286Sobrien  [(parallel [
915090286Sobrien     (set (reg:CCNO 17)
915190286Sobrien	  (compare:CCNO
915290286Sobrien	    (xor:SI
915390286Sobrien	      (zero_extract:SI
915490286Sobrien		(match_operand 1 "ext_register_operand" "")
915590286Sobrien		(const_int 8)
915690286Sobrien		(const_int 8))
915790286Sobrien	      (match_operand:QI 2 "general_operand" ""))
915890286Sobrien	    (const_int 0)))
915990286Sobrien     (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
916090286Sobrien			   (const_int 8)
916190286Sobrien			   (const_int 8))
916290286Sobrien	  (xor:SI 
916390286Sobrien	    (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
916490286Sobrien	    (match_dup 2)))])]
916518334Speter  ""
916690286Sobrien  "")
916718334Speter
916890286Sobrien;; Negation instructions
916918334Speter
917090286Sobrien(define_expand "negdi2"
917190286Sobrien  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
917290286Sobrien		   (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
917390286Sobrien	      (clobber (reg:CC 17))])]
917418334Speter  ""
917590286Sobrien  "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
917650650Sobrien
917790286Sobrien(define_insn "*negdi2_1"
917890286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
917990286Sobrien	(neg:DI (match_operand:DI 1 "general_operand" "0")))
918090286Sobrien   (clobber (reg:CC 17))]
918190286Sobrien  "!TARGET_64BIT
918290286Sobrien   && ix86_unary_operator_ok (NEG, DImode, operands)"
918390286Sobrien  "#")
918450650Sobrien
918590286Sobrien(define_split
918690286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
918790286Sobrien	(neg:DI (match_operand:DI 1 "general_operand" "")))
918890286Sobrien   (clobber (reg:CC 17))]
918990286Sobrien  "!TARGET_64BIT && reload_completed"
919090286Sobrien  [(parallel
919190286Sobrien    [(set (reg:CCZ 17)
919290286Sobrien	  (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
919390286Sobrien     (set (match_dup 0) (neg:SI (match_dup 2)))])
919490286Sobrien   (parallel
919590286Sobrien    [(set (match_dup 1)
919690286Sobrien	  (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
919790286Sobrien			    (match_dup 3))
919890286Sobrien		   (const_int 0)))
919990286Sobrien     (clobber (reg:CC 17))])
920090286Sobrien   (parallel
920190286Sobrien    [(set (match_dup 1)
920290286Sobrien	  (neg:SI (match_dup 1)))
920390286Sobrien     (clobber (reg:CC 17))])]
920490286Sobrien  "split_di (operands+1, 1, operands+2, operands+3);
920590286Sobrien   split_di (operands+0, 1, operands+0, operands+1);")
920650650Sobrien
920790286Sobrien(define_insn "*negdi2_1_rex64"
920890286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
920990286Sobrien	(neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
921090286Sobrien   (clobber (reg:CC 17))]
921190286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
921290286Sobrien  "neg{q}\t%0"
921390286Sobrien  [(set_attr "type" "negnot")
921490286Sobrien   (set_attr "mode" "DI")])
921550650Sobrien
921690286Sobrien;; The problem with neg is that it does not perform (compare x 0),
921790286Sobrien;; it really performs (compare 0 x), which leaves us with the zero
921890286Sobrien;; flag being the only useful item.
921950650Sobrien
922090286Sobrien(define_insn "*negdi2_cmpz_rex64"
922190286Sobrien  [(set (reg:CCZ 17)
922290286Sobrien	(compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
922390286Sobrien		     (const_int 0)))
922490286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
922590286Sobrien	(neg:DI (match_dup 1)))]
922690286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
922790286Sobrien  "neg{q}\t%0"
922890286Sobrien  [(set_attr "type" "negnot")
922990286Sobrien   (set_attr "mode" "DI")])
923050650Sobrien
923118334Speter
923290286Sobrien(define_expand "negsi2"
923390286Sobrien  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
923490286Sobrien		   (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
923590286Sobrien	      (clobber (reg:CC 17))])]
923690286Sobrien  ""
923790286Sobrien  "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
923818334Speter
923990286Sobrien(define_insn "*negsi2_1"
924090286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
924190286Sobrien	(neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
924290286Sobrien   (clobber (reg:CC 17))]
924390286Sobrien  "ix86_unary_operator_ok (NEG, SImode, operands)"
924490286Sobrien  "neg{l}\t%0"
924590286Sobrien  [(set_attr "type" "negnot")
924690286Sobrien   (set_attr "mode" "SI")])
924750650Sobrien
924890286Sobrien;; Combine is quite creative about this pattern.
924990286Sobrien(define_insn "*negsi2_1_zext"
925090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
925190286Sobrien	(lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
925290286Sobrien					(const_int 32)))
925390286Sobrien		     (const_int 32)))
925490286Sobrien   (clobber (reg:CC 17))]
925590286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
925690286Sobrien  "neg{l}\t%k0"
925790286Sobrien  [(set_attr "type" "negnot")
925890286Sobrien   (set_attr "mode" "SI")])
925950650Sobrien
926090286Sobrien;; The problem with neg is that it does not perform (compare x 0),
926190286Sobrien;; it really performs (compare 0 x), which leaves us with the zero
926290286Sobrien;; flag being the only useful item.
926318334Speter
926490286Sobrien(define_insn "*negsi2_cmpz"
926590286Sobrien  [(set (reg:CCZ 17)
926690286Sobrien	(compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
926790286Sobrien		     (const_int 0)))
926890286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
926990286Sobrien	(neg:SI (match_dup 1)))]
927090286Sobrien  "ix86_unary_operator_ok (NEG, SImode, operands)"
927190286Sobrien  "neg{l}\t%0"
927290286Sobrien  [(set_attr "type" "negnot")
927390286Sobrien   (set_attr "mode" "SI")])
927450650Sobrien
927590286Sobrien(define_insn "*negsi2_cmpz_zext"
927690286Sobrien  [(set (reg:CCZ 17)
927790286Sobrien	(compare:CCZ (lshiftrt:DI
927890286Sobrien		       (neg:DI (ashift:DI
927990286Sobrien				 (match_operand:DI 1 "register_operand" "0")
928090286Sobrien				 (const_int 32)))
928190286Sobrien		       (const_int 32))
928290286Sobrien		     (const_int 0)))
928390286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
928490286Sobrien	(lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
928590286Sobrien					(const_int 32)))
928690286Sobrien		     (const_int 32)))]
928790286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
928890286Sobrien  "neg{l}\t%k0"
928990286Sobrien  [(set_attr "type" "negnot")
929090286Sobrien   (set_attr "mode" "SI")])
929190286Sobrien
929290286Sobrien(define_expand "neghi2"
929390286Sobrien  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
929490286Sobrien		   (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
929590286Sobrien	      (clobber (reg:CC 17))])]
929690286Sobrien  "TARGET_HIMODE_MATH"
929790286Sobrien  "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
929890286Sobrien
929990286Sobrien(define_insn "*neghi2_1"
930090286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
930190286Sobrien	(neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
930290286Sobrien   (clobber (reg:CC 17))]
930390286Sobrien  "ix86_unary_operator_ok (NEG, HImode, operands)"
930490286Sobrien  "neg{w}\t%0"
930590286Sobrien  [(set_attr "type" "negnot")
930690286Sobrien   (set_attr "mode" "HI")])
930790286Sobrien
930890286Sobrien(define_insn "*neghi2_cmpz"
930990286Sobrien  [(set (reg:CCZ 17)
931090286Sobrien	(compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
931190286Sobrien		     (const_int 0)))
931290286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
931390286Sobrien	(neg:HI (match_dup 1)))]
931490286Sobrien  "ix86_unary_operator_ok (NEG, HImode, operands)"
931590286Sobrien  "neg{w}\t%0"
931690286Sobrien  [(set_attr "type" "negnot")
931790286Sobrien   (set_attr "mode" "HI")])
931890286Sobrien
931990286Sobrien(define_expand "negqi2"
932090286Sobrien  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
932190286Sobrien		   (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
932290286Sobrien	      (clobber (reg:CC 17))])]
932390286Sobrien  "TARGET_QIMODE_MATH"
932490286Sobrien  "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
932590286Sobrien
932690286Sobrien(define_insn "*negqi2_1"
932790286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
932890286Sobrien	(neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
932990286Sobrien   (clobber (reg:CC 17))]
933090286Sobrien  "ix86_unary_operator_ok (NEG, QImode, operands)"
933190286Sobrien  "neg{b}\t%0"
933290286Sobrien  [(set_attr "type" "negnot")
933390286Sobrien   (set_attr "mode" "QI")])
933490286Sobrien
933590286Sobrien(define_insn "*negqi2_cmpz"
933690286Sobrien  [(set (reg:CCZ 17)
933790286Sobrien	(compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
933890286Sobrien		     (const_int 0)))
933990286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
934090286Sobrien	(neg:QI (match_dup 1)))]
934190286Sobrien  "ix86_unary_operator_ok (NEG, QImode, operands)"
934290286Sobrien  "neg{b}\t%0"
934390286Sobrien  [(set_attr "type" "negnot")
934490286Sobrien   (set_attr "mode" "QI")])
934590286Sobrien
934690286Sobrien;; Changing of sign for FP values is doable using integer unit too.
934790286Sobrien
934890286Sobrien(define_expand "negsf2"
934990286Sobrien  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
935090286Sobrien		   (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
935190286Sobrien	      (clobber (reg:CC 17))])]
935290286Sobrien  "TARGET_80387"
935390286Sobrien  "if (TARGET_SSE)
935490286Sobrien     {
935590286Sobrien       /* In case operand is in memory,  we will not use SSE.  */
935690286Sobrien       if (memory_operand (operands[0], VOIDmode)
935790286Sobrien	   && rtx_equal_p (operands[0], operands[1]))
935890286Sobrien	 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
935990286Sobrien       else
936018334Speter	{
936190286Sobrien	  /* Using SSE is tricky, since we need bitwise negation of -0
936290286Sobrien	     in register.  */
936390286Sobrien	  rtx reg = gen_reg_rtx (SFmode);
936490286Sobrien	  rtx dest = operands[0];
936518334Speter
936690286Sobrien	  operands[1] = force_reg (SFmode, operands[1]);
936790286Sobrien	  operands[0] = force_reg (SFmode, operands[0]);
936890286Sobrien	  emit_move_insn (reg,
936990286Sobrien			  gen_lowpart (SFmode,
937090286Sobrien				       GEN_INT (trunc_int_for_mode (0x80000000,
937190286Sobrien							            SImode))));
937290286Sobrien	  emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
937390286Sobrien	  if (dest != operands[0])
937490286Sobrien	    emit_move_insn (dest, operands[0]);
937550650Sobrien	}
937690286Sobrien       DONE;
937790286Sobrien     }
937890286Sobrien   ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
937918334Speter
938090286Sobrien(define_insn "negsf2_memory"
938190286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
938290286Sobrien	(neg:SF (match_operand:SF 1 "memory_operand" "0")))
938390286Sobrien   (clobber (reg:CC 17))]
938490286Sobrien  "ix86_unary_operator_ok (NEG, SFmode, operands)"
938590286Sobrien  "#")
938618334Speter
938790286Sobrien(define_insn "negsf2_ifs"
938890286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
938990286Sobrien	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
939090286Sobrien   (use (match_operand:SF 2 "nonmemory_operand" "x,0#x,*g#x,*g#x"))
939190286Sobrien   (clobber (reg:CC 17))]
939290286Sobrien  "TARGET_SSE
939390286Sobrien   && (reload_in_progress || reload_completed
939490286Sobrien       || (register_operand (operands[0], VOIDmode)
939590286Sobrien	   && register_operand (operands[1], VOIDmode)))"
939690286Sobrien  "#")
939718334Speter
939890286Sobrien(define_split
939990286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
940090286Sobrien	(neg:SF (match_operand:SF 1 "memory_operand" "")))
940190286Sobrien   (use (match_operand:SF 2 "" ""))
940290286Sobrien   (clobber (reg:CC 17))]
940318334Speter  ""
940490286Sobrien  [(parallel [(set (match_dup 0)
940590286Sobrien		   (neg:SF (match_dup 1)))
940690286Sobrien	      (clobber (reg:CC 17))])])
940790286Sobrien
940890286Sobrien(define_split
940990286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
941090286Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "")))
941190286Sobrien   (use (match_operand:SF 2 "" ""))
941290286Sobrien   (clobber (reg:CC 17))]
941390286Sobrien  "reload_completed && !SSE_REG_P (operands[0])"
941490286Sobrien  [(parallel [(set (match_dup 0)
941590286Sobrien		   (neg:SF (match_dup 1)))
941690286Sobrien	      (clobber (reg:CC 17))])])
941790286Sobrien
941890286Sobrien(define_split
941990286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
942090286Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "")))
942190286Sobrien   (use (match_operand:SF 2 "register_operand" ""))
942290286Sobrien   (clobber (reg:CC 17))]
942390286Sobrien  "reload_completed && SSE_REG_P (operands[0])"
942490286Sobrien  [(set (subreg:TI (match_dup 0) 0)
942590286Sobrien	(xor:TI (subreg:TI (match_dup 1) 0)
942690286Sobrien		(subreg:TI (match_dup 2) 0)))]
942718334Speter{
942890286Sobrien  if (operands_match_p (operands[0], operands[2]))
942918334Speter    {
943090286Sobrien      rtx tmp;
943190286Sobrien      tmp = operands[1];
943290286Sobrien      operands[1] = operands[2];
943390286Sobrien      operands[2] = tmp;
943490286Sobrien    }
943590286Sobrien})
943618334Speter
943718334Speter
943890286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
943990286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
944090286Sobrien;; to itself.
944190286Sobrien(define_insn "*negsf2_if"
944290286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
944390286Sobrien	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
944490286Sobrien   (clobber (reg:CC 17))]
944590286Sobrien  "TARGET_80387 && !TARGET_SSE
944690286Sobrien   && ix86_unary_operator_ok (NEG, SFmode, operands)"
944790286Sobrien  "#")
944818334Speter
944990286Sobrien(define_split
945090286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
945190286Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "")))
945290286Sobrien   (clobber (reg:CC 17))]
945390286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
945490286Sobrien  [(set (match_dup 0)
945590286Sobrien	(neg:SF (match_dup 1)))]
945690286Sobrien  "")
945790286Sobrien
945890286Sobrien(define_split
945990286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
946090286Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "")))
946190286Sobrien   (clobber (reg:CC 17))]
946290286Sobrien  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
946390286Sobrien  [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
946490286Sobrien	      (clobber (reg:CC 17))])]
946590286Sobrien  "operands[1] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
946690286Sobrien   operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
946790286Sobrien
946890286Sobrien(define_split
946990286Sobrien  [(set (match_operand 0 "memory_operand" "")
947090286Sobrien	(neg (match_operand 1 "memory_operand" "")))
947190286Sobrien   (clobber (reg:CC 17))]
947290286Sobrien  "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
947390286Sobrien  [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
947490286Sobrien	      (clobber (reg:CC 17))])]
947590286Sobrien{
947690286Sobrien  int size = GET_MODE_SIZE (GET_MODE (operands[1]));
947790286Sobrien
947890286Sobrien  /* XFmode's size is 12, TFmode 16, but only 10 bytes are used.  */
947990286Sobrien  if (size >= 12)
948090286Sobrien    size = 10;
948190286Sobrien  operands[0] = adjust_address (operands[0], QImode, size - 1);
948290286Sobrien  operands[1] = GEN_INT (trunc_int_for_mode (0x80, QImode));
948390286Sobrien})
948490286Sobrien
948590286Sobrien(define_expand "negdf2"
948690286Sobrien  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
948790286Sobrien		   (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
948890286Sobrien	      (clobber (reg:CC 17))])]
948990286Sobrien  "TARGET_80387"
949090286Sobrien  "if (TARGET_SSE2)
949190286Sobrien     {
949290286Sobrien       /* In case operand is in memory,  we will not use SSE.  */
949390286Sobrien       if (memory_operand (operands[0], VOIDmode)
949490286Sobrien	   && rtx_equal_p (operands[0], operands[1]))
949590286Sobrien	 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
949690286Sobrien       else
949718334Speter	{
949890286Sobrien	  /* Using SSE is tricky, since we need bitwise negation of -0
949990286Sobrien	     in register.  */
950090286Sobrien	  rtx reg = gen_reg_rtx (DFmode);
950190286Sobrien#if HOST_BITS_PER_WIDE_INT >= 64
950290286Sobrien	  rtx imm = GEN_INT (trunc_int_for_mode(((HOST_WIDE_INT)1) << 63,
950390286Sobrien					        DImode));
950490286Sobrien#else
950590286Sobrien	  rtx imm = immed_double_const (0, 0x80000000, DImode);
950690286Sobrien#endif
950790286Sobrien	  rtx dest = operands[0];
950818334Speter
950990286Sobrien	  operands[1] = force_reg (DFmode, operands[1]);
951090286Sobrien	  operands[0] = force_reg (DFmode, operands[0]);
951190286Sobrien	  emit_move_insn (reg, gen_lowpart (DFmode, imm));
951290286Sobrien	  emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
951390286Sobrien	  if (dest != operands[0])
951490286Sobrien	    emit_move_insn (dest, operands[0]);
951518334Speter	}
951690286Sobrien       DONE;
951790286Sobrien     }
951890286Sobrien   ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
951918334Speter
952090286Sobrien(define_insn "negdf2_memory"
952190286Sobrien  [(set (match_operand:DF 0 "memory_operand" "=m")
952290286Sobrien	(neg:DF (match_operand:DF 1 "memory_operand" "0")))
952390286Sobrien   (clobber (reg:CC 17))]
952490286Sobrien  "ix86_unary_operator_ok (NEG, DFmode, operands)"
952590286Sobrien  "#")
952650650Sobrien
952790286Sobrien(define_insn "negdf2_ifs"
952890286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
952990286Sobrien	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
953090286Sobrien   (use (match_operand:DF 2 "nonmemory_operand" "Y,0,*g#Y,*g#Y"))
953190286Sobrien   (clobber (reg:CC 17))]
953290286Sobrien  "!TARGET_64BIT && TARGET_SSE2
953390286Sobrien   && (reload_in_progress || reload_completed
953490286Sobrien       || (register_operand (operands[0], VOIDmode)
953590286Sobrien	   && register_operand (operands[1], VOIDmode)))"
953690286Sobrien  "#")
953750650Sobrien
953890286Sobrien(define_insn "*negdf2_ifs_rex64"
953990286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,fm#Yr,r#Yf")
954090286Sobrien	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
954190286Sobrien   (use (match_operand:DF 2 "general_operand" "Y,0,*g#Yr,*rm"))
954290286Sobrien   (clobber (reg:CC 17))]
954390286Sobrien  "TARGET_64BIT && TARGET_SSE2
954490286Sobrien   && (reload_in_progress || reload_completed
954590286Sobrien       || (register_operand (operands[0], VOIDmode)
954690286Sobrien	   && register_operand (operands[1], VOIDmode)))"
954790286Sobrien  "#")
954818334Speter
954990286Sobrien(define_split
955090286Sobrien  [(set (match_operand:DF 0 "memory_operand" "")
955190286Sobrien	(neg:DF (match_operand:DF 1 "memory_operand" "")))
955290286Sobrien   (use (match_operand:DF 2 "" ""))
955390286Sobrien   (clobber (reg:CC 17))]
955418334Speter  ""
955590286Sobrien  [(parallel [(set (match_dup 0)
955690286Sobrien		   (neg:DF (match_dup 1)))
955790286Sobrien	      (clobber (reg:CC 17))])])
955850650Sobrien
955990286Sobrien(define_split
956090286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
956190286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
956290286Sobrien   (use (match_operand:DF 2 "" ""))
956390286Sobrien   (clobber (reg:CC 17))]
956490286Sobrien  "reload_completed && !SSE_REG_P (operands[0])
956590286Sobrien   && (!TARGET_64BIT || FP_REG_P (operands[0]))"
956690286Sobrien  [(parallel [(set (match_dup 0)
956790286Sobrien		   (neg:DF (match_dup 1)))
956890286Sobrien	      (clobber (reg:CC 17))])])
956950650Sobrien
957090286Sobrien(define_split
957190286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
957290286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
957390286Sobrien   (use (match_operand:DF 2 "" ""))
957490286Sobrien   (clobber (reg:CC 17))]
957590286Sobrien  "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
957690286Sobrien  [(parallel [(set (match_dup 0)
957790286Sobrien		   (xor:DI (match_dup 1) (match_dup 2)))
957890286Sobrien	      (clobber (reg:CC 17))])]
957990286Sobrien   "operands[0] = gen_lowpart (DImode, operands[0]);
958090286Sobrien    operands[1] = gen_lowpart (DImode, operands[1]);
958190286Sobrien    operands[2] = gen_lowpart (DImode, operands[2]);")
958252296Sobrien
958390286Sobrien(define_split
958490286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
958590286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
958690286Sobrien   (use (match_operand:DF 2 "register_operand" ""))
958790286Sobrien   (clobber (reg:CC 17))]
958890286Sobrien  "reload_completed && SSE_REG_P (operands[0])"
958990286Sobrien  [(set (subreg:TI (match_dup 0) 0)
959090286Sobrien	(xor:TI (subreg:TI (match_dup 1) 0)
959190286Sobrien		(subreg:TI (match_dup 2) 0)))]
959290286Sobrien{
959390286Sobrien  if (operands_match_p (operands[0], operands[2]))
959490286Sobrien    {
959590286Sobrien      rtx tmp;
959690286Sobrien      tmp = operands[1];
959790286Sobrien      operands[1] = operands[2];
959890286Sobrien      operands[2] = tmp;
959990286Sobrien    }
960090286Sobrien})
960152296Sobrien
960290286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
960390286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
960490286Sobrien;; to itself.
960590286Sobrien(define_insn "*negdf2_if"
960690286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
960790286Sobrien	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
960890286Sobrien   (clobber (reg:CC 17))]
960990286Sobrien  "!TARGET_64BIT && TARGET_80387
961090286Sobrien   && ix86_unary_operator_ok (NEG, DFmode, operands)"
961190286Sobrien  "#")
961250650Sobrien
961390286Sobrien;; FIXME: We should to allow integer registers here.  Problem is that
961490286Sobrien;; we need another scratch register to get constant from.
961590286Sobrien;; Forcing constant to mem if no register available in peep2 should be
961690286Sobrien;; safe even for PIC mode, because of RIP relative addressing.
961790286Sobrien(define_insn "*negdf2_if_rex64"
961890286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
961990286Sobrien	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
962090286Sobrien   (clobber (reg:CC 17))]
962190286Sobrien  "TARGET_64BIT && TARGET_80387
962290286Sobrien   && ix86_unary_operator_ok (NEG, DFmode, operands)"
962390286Sobrien  "#")
962490286Sobrien
962550650Sobrien(define_split
962690286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
962790286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
962890286Sobrien   (clobber (reg:CC 17))]
962990286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
963090286Sobrien  [(set (match_dup 0)
963190286Sobrien	(neg:DF (match_dup 1)))]
963290286Sobrien  "")
963350650Sobrien
963490286Sobrien(define_split
963590286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
963690286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
963790286Sobrien   (clobber (reg:CC 17))]
963890286Sobrien  "!TARGET_64BIT && TARGET_80387 && reload_completed
963990286Sobrien   && !FP_REGNO_P (REGNO (operands[0]))"
964090286Sobrien  [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
964190286Sobrien	      (clobber (reg:CC 17))])]
964290286Sobrien  "operands[4] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
964390286Sobrien   split_di (operands+0, 1, operands+2, operands+3);")
964418334Speter
964590286Sobrien(define_expand "negxf2"
964690286Sobrien  [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
964790286Sobrien		   (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
964890286Sobrien	      (clobber (reg:CC 17))])]
964990286Sobrien  "!TARGET_64BIT && TARGET_80387"
965090286Sobrien  "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
965118334Speter
965290286Sobrien(define_expand "negtf2"
965390286Sobrien  [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
965490286Sobrien		   (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
965590286Sobrien	      (clobber (reg:CC 17))])]
965690286Sobrien  "TARGET_80387"
965790286Sobrien  "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
965818334Speter
965990286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
966090286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
966190286Sobrien;; to itself.
966290286Sobrien(define_insn "*negxf2_if"
966390286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
966490286Sobrien	(neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
966590286Sobrien   (clobber (reg:CC 17))]
966690286Sobrien  "!TARGET_64BIT && TARGET_80387
966790286Sobrien   && ix86_unary_operator_ok (NEG, XFmode, operands)"
966890286Sobrien  "#")
966918334Speter
967090286Sobrien(define_split
967190286Sobrien  [(set (match_operand:XF 0 "register_operand" "")
967290286Sobrien	(neg:XF (match_operand:XF 1 "register_operand" "")))
967390286Sobrien   (clobber (reg:CC 17))]
967490286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
967590286Sobrien  [(set (match_dup 0)
967690286Sobrien	(neg:XF (match_dup 1)))]
967790286Sobrien  "")
967818334Speter
967990286Sobrien(define_split
968090286Sobrien  [(set (match_operand:XF 0 "register_operand" "")
968190286Sobrien	(neg:XF (match_operand:XF 1 "register_operand" "")))
968290286Sobrien   (clobber (reg:CC 17))]
968390286Sobrien  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
968490286Sobrien  [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
968590286Sobrien	      (clobber (reg:CC 17))])]
968690286Sobrien  "operands[1] = GEN_INT (0x8000);
968790286Sobrien   operands[0] = gen_rtx_REG (SImode,
968890286Sobrien			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
968918334Speter
969090286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
969190286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
969290286Sobrien;; to itself.
969390286Sobrien(define_insn "*negtf2_if"
969490286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
969590286Sobrien	(neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
969690286Sobrien   (clobber (reg:CC 17))]
969790286Sobrien  "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
969890286Sobrien  "#")
969918334Speter
970090286Sobrien(define_split
970190286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
970290286Sobrien	(neg:TF (match_operand:TF 1 "register_operand" "")))
970390286Sobrien   (clobber (reg:CC 17))]
970490286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
970590286Sobrien  [(set (match_dup 0)
970690286Sobrien	(neg:TF (match_dup 1)))]
970790286Sobrien  "")
970818334Speter
970990286Sobrien(define_split
971090286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
971190286Sobrien	(neg:TF (match_operand:TF 1 "register_operand" "")))
971290286Sobrien   (clobber (reg:CC 17))]
971390286Sobrien  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
971490286Sobrien  [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
971590286Sobrien	      (clobber (reg:CC 17))])]
971690286Sobrien  "operands[1] = GEN_INT (0x8000);
971790286Sobrien   operands[0] = gen_rtx_REG (SImode,
971890286Sobrien			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
971990286Sobrien
972090286Sobrien;; Conditionize these after reload. If they matches before reload, we 
972190286Sobrien;; lose the clobber and ability to use integer instructions.
972290286Sobrien
972390286Sobrien(define_insn "*negsf2_1"
972418334Speter  [(set (match_operand:SF 0 "register_operand" "=f")
972550650Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "0")))]
972690286Sobrien  "TARGET_80387 && reload_completed"
972752296Sobrien  "fchs"
972890286Sobrien  [(set_attr "type" "fsgn")
972990286Sobrien   (set_attr "mode" "SF")
973090286Sobrien   (set_attr "ppro_uops" "few")])
973118334Speter
973290286Sobrien(define_insn "*negdf2_1"
973318334Speter  [(set (match_operand:DF 0 "register_operand" "=f")
973450650Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "0")))]
973590286Sobrien  "TARGET_80387 && reload_completed"
973652296Sobrien  "fchs"
973790286Sobrien  [(set_attr "type" "fsgn")
973890286Sobrien   (set_attr "mode" "DF")
973990286Sobrien   (set_attr "ppro_uops" "few")])
974018334Speter
974190286Sobrien(define_insn "*negextendsfdf2"
974218334Speter  [(set (match_operand:DF 0 "register_operand" "=f")
974390286Sobrien	(neg:DF (float_extend:DF
974490286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
974518334Speter  "TARGET_80387"
974652296Sobrien  "fchs"
974790286Sobrien  [(set_attr "type" "fsgn")
974890286Sobrien   (set_attr "mode" "DF")
974990286Sobrien   (set_attr "ppro_uops" "few")])
975018334Speter
975190286Sobrien(define_insn "*negxf2_1"
975218334Speter  [(set (match_operand:XF 0 "register_operand" "=f")
975350650Sobrien	(neg:XF (match_operand:XF 1 "register_operand" "0")))]
975490286Sobrien  "!TARGET_64BIT && TARGET_80387 && reload_completed"
975552296Sobrien  "fchs"
975690286Sobrien  [(set_attr "type" "fsgn")
975790286Sobrien   (set_attr "mode" "XF")
975890286Sobrien   (set_attr "ppro_uops" "few")])
975918334Speter
976090286Sobrien(define_insn "*negextenddfxf2"
976118334Speter  [(set (match_operand:XF 0 "register_operand" "=f")
976290286Sobrien	(neg:XF (float_extend:XF
976390286Sobrien		  (match_operand:DF 1 "register_operand" "0"))))]
976490286Sobrien  "!TARGET_64BIT && TARGET_80387"
976590286Sobrien  "fchs"
976690286Sobrien  [(set_attr "type" "fsgn")
976790286Sobrien   (set_attr "mode" "XF")
976890286Sobrien   (set_attr "ppro_uops" "few")])
976990286Sobrien
977090286Sobrien(define_insn "*negextendsfxf2"
977190286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
977290286Sobrien	(neg:XF (float_extend:XF
977390286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
977490286Sobrien  "!TARGET_64BIT && TARGET_80387"
977590286Sobrien  "fchs"
977690286Sobrien  [(set_attr "type" "fsgn")
977790286Sobrien   (set_attr "mode" "XF")
977890286Sobrien   (set_attr "ppro_uops" "few")])
977990286Sobrien
978090286Sobrien(define_insn "*negtf2_1"
978190286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
978290286Sobrien	(neg:TF (match_operand:TF 1 "register_operand" "0")))]
978390286Sobrien  "TARGET_80387 && reload_completed"
978490286Sobrien  "fchs"
978590286Sobrien  [(set_attr "type" "fsgn")
978690286Sobrien   (set_attr "mode" "XF")
978790286Sobrien   (set_attr "ppro_uops" "few")])
978890286Sobrien
978990286Sobrien(define_insn "*negextenddftf2"
979090286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
979190286Sobrien	(neg:TF (float_extend:TF
979290286Sobrien		  (match_operand:DF 1 "register_operand" "0"))))]
979318334Speter  "TARGET_80387"
979452296Sobrien  "fchs"
979590286Sobrien  [(set_attr "type" "fsgn")
979690286Sobrien   (set_attr "mode" "XF")
979790286Sobrien   (set_attr "ppro_uops" "few")])
979890286Sobrien
979990286Sobrien(define_insn "*negextendsftf2"
980090286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
980190286Sobrien	(neg:TF (float_extend:TF
980290286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
980390286Sobrien  "TARGET_80387"
980490286Sobrien  "fchs"
980590286Sobrien  [(set_attr "type" "fsgn")
980690286Sobrien   (set_attr "mode" "XF")
980790286Sobrien   (set_attr "ppro_uops" "few")])
980818334Speter
980918334Speter;; Absolute value instructions
981018334Speter
981190286Sobrien(define_expand "abssf2"
981290286Sobrien  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
981390286Sobrien		   (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
981490286Sobrien	      (clobber (reg:CC 17))])]
981590286Sobrien  "TARGET_80387"
981690286Sobrien  "if (TARGET_SSE)
981790286Sobrien     {
981890286Sobrien       /* In case operand is in memory,  we will not use SSE.  */
981990286Sobrien       if (memory_operand (operands[0], VOIDmode)
982090286Sobrien	   && rtx_equal_p (operands[0], operands[1]))
982190286Sobrien	 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
982290286Sobrien       else
982390286Sobrien	{
982490286Sobrien	  /* Using SSE is tricky, since we need bitwise negation of -0
982590286Sobrien	     in register.  */
982690286Sobrien	  rtx reg = gen_reg_rtx (SFmode);
982790286Sobrien	  rtx dest = operands[0];
982890286Sobrien
982990286Sobrien	  operands[1] = force_reg (SFmode, operands[1]);
983090286Sobrien	  operands[0] = force_reg (SFmode, operands[0]);
983190286Sobrien	  emit_move_insn (reg,
983290286Sobrien			  gen_lowpart (SFmode,
983390286Sobrien				       GEN_INT (trunc_int_for_mode (0x80000000,
983490286Sobrien							            SImode))));
983590286Sobrien	  emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
983690286Sobrien	  if (dest != operands[0])
983790286Sobrien	    emit_move_insn (dest, operands[0]);
983890286Sobrien	}
983990286Sobrien       DONE;
984090286Sobrien     }
984190286Sobrien   ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
984290286Sobrien
984390286Sobrien(define_insn "abssf2_memory"
984490286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
984590286Sobrien	(abs:SF (match_operand:SF 1 "memory_operand" "0")))
984690286Sobrien   (clobber (reg:CC 17))]
984790286Sobrien  "ix86_unary_operator_ok (ABS, SFmode, operands)"
984890286Sobrien  "#")
984990286Sobrien
985090286Sobrien(define_insn "abssf2_ifs"
985190286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,f#xr,rm#xf")
985290286Sobrien	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "x,0,0")))
985390286Sobrien   (use (match_operand:SF 2 "nonmemory_operand" "*0#x,*g#x,*g#x"))
985490286Sobrien   (clobber (reg:CC 17))]
985590286Sobrien  "TARGET_SSE
985690286Sobrien   && (reload_in_progress || reload_completed
985790286Sobrien       || (register_operand (operands[0], VOIDmode)
985890286Sobrien	   && register_operand (operands[1], VOIDmode)))"
985990286Sobrien  "#")
986090286Sobrien
986190286Sobrien(define_split
986290286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
986390286Sobrien	(abs:SF (match_operand:SF 1 "memory_operand" "")))
986490286Sobrien   (use (match_operand:SF 2 "" ""))
986590286Sobrien   (clobber (reg:CC 17))]
986690286Sobrien  ""
986790286Sobrien  [(parallel [(set (match_dup 0)
986890286Sobrien		   (abs:SF (match_dup 1)))
986990286Sobrien	      (clobber (reg:CC 17))])])
987090286Sobrien
987190286Sobrien(define_split
987290286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
987390286Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "")))
987490286Sobrien   (use (match_operand:SF 2 "" ""))
987590286Sobrien   (clobber (reg:CC 17))]
987690286Sobrien  "reload_completed && !SSE_REG_P (operands[0])"
987790286Sobrien  [(parallel [(set (match_dup 0)
987890286Sobrien		   (abs:SF (match_dup 1)))
987990286Sobrien	      (clobber (reg:CC 17))])])
988090286Sobrien
988190286Sobrien(define_split
988290286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
988390286Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "")))
988490286Sobrien   (use (match_operand:SF 2 "register_operand" ""))
988590286Sobrien   (clobber (reg:CC 17))]
988690286Sobrien  "reload_completed && SSE_REG_P (operands[0])"
988790286Sobrien  [(set (subreg:TI (match_dup 0) 0)
988890286Sobrien	(and:TI (not:TI (subreg:TI (match_dup 2) 0))
988990286Sobrien		(subreg:TI (match_dup 1) 0)))])
989090286Sobrien
989190286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
989290286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
989390286Sobrien;; to itself.
989490286Sobrien(define_insn "*abssf2_if"
989590286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
989690286Sobrien	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
989790286Sobrien   (clobber (reg:CC 17))]
989890286Sobrien  "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
989990286Sobrien  "#")
990090286Sobrien
990190286Sobrien(define_split
990290286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
990390286Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "")))
990490286Sobrien   (clobber (reg:CC 17))]
990590286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0]))"
990690286Sobrien  [(set (match_dup 0)
990790286Sobrien	(abs:SF (match_dup 1)))]
990890286Sobrien  "")
990990286Sobrien
991090286Sobrien(define_split
991190286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
991290286Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "")))
991390286Sobrien   (clobber (reg:CC 17))]
991490286Sobrien  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
991590286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
991690286Sobrien	      (clobber (reg:CC 17))])]
991790286Sobrien  "operands[1] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
991890286Sobrien   operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
991990286Sobrien
992090286Sobrien(define_split
992190286Sobrien  [(set (match_operand 0 "memory_operand" "")
992290286Sobrien	(abs (match_operand 1 "memory_operand" "")))
992390286Sobrien   (clobber (reg:CC 17))]
992490286Sobrien  "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
992590286Sobrien  [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
992690286Sobrien	      (clobber (reg:CC 17))])]
992790286Sobrien{
992890286Sobrien  int size = GET_MODE_SIZE (GET_MODE (operands[1]));
992990286Sobrien
993090286Sobrien  /* XFmode's size is 12, TFmode 16, but only 10 bytes are used.  */
993190286Sobrien  if (size >= 12)
993290286Sobrien    size = 10;
993390286Sobrien  operands[0] = adjust_address (operands[0], QImode, size - 1);
993490286Sobrien  operands[1] = GEN_INT (trunc_int_for_mode (~0x80, QImode));
993590286Sobrien})
993690286Sobrien
993790286Sobrien(define_expand "absdf2"
993890286Sobrien  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
993990286Sobrien		   (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
994090286Sobrien	      (clobber (reg:CC 17))])]
994190286Sobrien  "TARGET_80387"
994290286Sobrien  "if (TARGET_SSE2)
994390286Sobrien     {
994490286Sobrien       /* In case operand is in memory,  we will not use SSE.  */
994590286Sobrien       if (memory_operand (operands[0], VOIDmode)
994690286Sobrien	   && rtx_equal_p (operands[0], operands[1]))
994790286Sobrien	 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
994890286Sobrien       else
994990286Sobrien	{
995090286Sobrien	  /* Using SSE is tricky, since we need bitwise negation of -0
995190286Sobrien	     in register.  */
995290286Sobrien	  rtx reg = gen_reg_rtx (DFmode);
995390286Sobrien#if HOST_BITS_PER_WIDE_INT >= 64
995490286Sobrien	  rtx imm = GEN_INT (trunc_int_for_mode(((HOST_WIDE_INT)1) << 63,
995590286Sobrien					        DImode));
995690286Sobrien#else
995790286Sobrien	  rtx imm = immed_double_const (0, 0x80000000, DImode);
995890286Sobrien#endif
995990286Sobrien	  rtx dest = operands[0];
996090286Sobrien
996190286Sobrien	  operands[1] = force_reg (DFmode, operands[1]);
996290286Sobrien	  operands[0] = force_reg (DFmode, operands[0]);
996390286Sobrien	  emit_move_insn (reg, gen_lowpart (DFmode, imm));
996490286Sobrien	  emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
996590286Sobrien	  if (dest != operands[0])
996690286Sobrien	    emit_move_insn (dest, operands[0]);
996790286Sobrien	}
996890286Sobrien       DONE;
996990286Sobrien     }
997090286Sobrien   ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
997190286Sobrien
997290286Sobrien(define_insn "absdf2_memory"
997390286Sobrien  [(set (match_operand:DF 0 "memory_operand" "=m")
997490286Sobrien	(abs:DF (match_operand:DF 1 "memory_operand" "0")))
997590286Sobrien   (clobber (reg:CC 17))]
997690286Sobrien  "ix86_unary_operator_ok (ABS, DFmode, operands)"
997790286Sobrien  "#")
997890286Sobrien
997990286Sobrien(define_insn "absdf2_ifs"
998090286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr,mr#Yf")
998190286Sobrien	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0,0")))
998290286Sobrien   (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y,*g#Y"))
998390286Sobrien   (clobber (reg:CC 17))]
998490286Sobrien  "!TARGET_64BIT && TARGET_SSE2
998590286Sobrien   && (reload_in_progress || reload_completed
998690286Sobrien       || (register_operand (operands[0], VOIDmode)
998790286Sobrien	   && register_operand (operands[1], VOIDmode)))"
998890286Sobrien  "#")
998990286Sobrien
999090286Sobrien(define_insn "*absdf2_ifs_rex64"
999190286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr")
999290286Sobrien	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0")))
999390286Sobrien   (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y"))
999490286Sobrien   (clobber (reg:CC 17))]
999590286Sobrien  "TARGET_64BIT && TARGET_SSE2
999690286Sobrien   && (reload_in_progress || reload_completed
999790286Sobrien       || (register_operand (operands[0], VOIDmode)
999890286Sobrien	   && register_operand (operands[1], VOIDmode)))"
999990286Sobrien  "#")
1000090286Sobrien
1000190286Sobrien(define_split
1000290286Sobrien  [(set (match_operand:DF 0 "memory_operand" "")
1000390286Sobrien	(abs:DF (match_operand:DF 1 "memory_operand" "")))
1000490286Sobrien   (use (match_operand:DF 2 "" ""))
1000590286Sobrien   (clobber (reg:CC 17))]
1000690286Sobrien  ""
1000790286Sobrien  [(parallel [(set (match_dup 0)
1000890286Sobrien		   (abs:DF (match_dup 1)))
1000990286Sobrien	      (clobber (reg:CC 17))])])
1001090286Sobrien
1001190286Sobrien(define_split
1001290286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1001390286Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "")))
1001490286Sobrien   (use (match_operand:DF 2 "" ""))
1001590286Sobrien   (clobber (reg:CC 17))]
1001690286Sobrien  "reload_completed && !SSE_REG_P (operands[0])"
1001790286Sobrien  [(parallel [(set (match_dup 0)
1001890286Sobrien		   (abs:DF (match_dup 1)))
1001990286Sobrien	      (clobber (reg:CC 17))])])
1002090286Sobrien
1002190286Sobrien(define_split
1002290286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1002390286Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "")))
1002490286Sobrien   (use (match_operand:DF 2 "register_operand" ""))
1002590286Sobrien   (clobber (reg:CC 17))]
1002690286Sobrien  "reload_completed && SSE_REG_P (operands[0])"
1002790286Sobrien  [(set (subreg:TI (match_dup 0) 0)
1002890286Sobrien	(and:TI (not:TI (subreg:TI (match_dup 2) 0))
1002990286Sobrien		(subreg:TI (match_dup 1) 0)))])
1003090286Sobrien
1003190286Sobrien
1003290286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
1003390286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
1003490286Sobrien;; to itself.
1003590286Sobrien(define_insn "*absdf2_if"
1003690286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
1003790286Sobrien	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
1003890286Sobrien   (clobber (reg:CC 17))]
1003990286Sobrien  "!TARGET_64BIT && TARGET_80387
1004090286Sobrien   && ix86_unary_operator_ok (ABS, DFmode, operands)"
1004190286Sobrien  "#")
1004290286Sobrien
1004390286Sobrien;; FIXME: We should to allow integer registers here.  Problem is that
1004490286Sobrien;; we need another scratch register to get constant from.
1004590286Sobrien;; Forcing constant to mem if no register available in peep2 should be
1004690286Sobrien;; safe even for PIC mode, because of RIP relative addressing.
1004790286Sobrien(define_insn "*absdf2_if_rex64"
1004890286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
1004990286Sobrien	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
1005090286Sobrien   (clobber (reg:CC 17))]
1005190286Sobrien  "TARGET_64BIT && TARGET_80387
1005290286Sobrien   && ix86_unary_operator_ok (ABS, DFmode, operands)"
1005390286Sobrien  "#")
1005490286Sobrien
1005590286Sobrien(define_split
1005690286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1005790286Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "")))
1005890286Sobrien   (clobber (reg:CC 17))]
1005990286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
1006090286Sobrien  [(set (match_dup 0)
1006190286Sobrien	(abs:DF (match_dup 1)))]
1006290286Sobrien  "")
1006390286Sobrien
1006490286Sobrien(define_split
1006590286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1006690286Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "")))
1006790286Sobrien   (clobber (reg:CC 17))]
1006890286Sobrien  "!TARGET_64BIT && TARGET_80387 && reload_completed &&
1006990286Sobrien   !FP_REGNO_P (REGNO (operands[0]))"
1007090286Sobrien  [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
1007190286Sobrien	      (clobber (reg:CC 17))])]
1007290286Sobrien  "operands[4] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
1007390286Sobrien   split_di (operands+0, 1, operands+2, operands+3);")
1007490286Sobrien
1007590286Sobrien(define_expand "absxf2"
1007690286Sobrien  [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
1007790286Sobrien		   (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
1007890286Sobrien	      (clobber (reg:CC 17))])]
1007990286Sobrien  "!TARGET_64BIT && TARGET_80387"
1008090286Sobrien  "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
1008190286Sobrien
1008290286Sobrien(define_expand "abstf2"
1008390286Sobrien  [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
1008490286Sobrien		   (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
1008590286Sobrien	      (clobber (reg:CC 17))])]
1008690286Sobrien  "TARGET_80387"
1008790286Sobrien  "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
1008890286Sobrien
1008990286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
1009090286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
1009190286Sobrien;; to itself.
1009290286Sobrien(define_insn "*absxf2_if"
1009390286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
1009490286Sobrien	(abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
1009590286Sobrien   (clobber (reg:CC 17))]
1009690286Sobrien  "!TARGET_64BIT && TARGET_80387
1009790286Sobrien   && ix86_unary_operator_ok (ABS, XFmode, operands)"
1009890286Sobrien  "#")
1009990286Sobrien
1010090286Sobrien(define_split
1010190286Sobrien  [(set (match_operand:XF 0 "register_operand" "")
1010290286Sobrien	(abs:XF (match_operand:XF 1 "register_operand" "")))
1010390286Sobrien   (clobber (reg:CC 17))]
1010490286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
1010590286Sobrien  [(set (match_dup 0)
1010690286Sobrien	(abs:XF (match_dup 1)))]
1010790286Sobrien  "")
1010890286Sobrien
1010990286Sobrien(define_split
1011090286Sobrien  [(set (match_operand:XF 0 "register_operand" "")
1011190286Sobrien	(abs:XF (match_operand:XF 1 "register_operand" "")))
1011290286Sobrien   (clobber (reg:CC 17))]
1011390286Sobrien  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
1011490286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
1011590286Sobrien	      (clobber (reg:CC 17))])]
1011690286Sobrien  "operands[1] = GEN_INT (~0x8000);
1011790286Sobrien   operands[0] = gen_rtx_REG (SImode,
1011890286Sobrien			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
1011990286Sobrien
1012090286Sobrien(define_insn "*abstf2_if"
1012190286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
1012290286Sobrien	(abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
1012390286Sobrien   (clobber (reg:CC 17))]
1012490286Sobrien  "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
1012590286Sobrien  "#")
1012690286Sobrien
1012790286Sobrien(define_split
1012890286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
1012990286Sobrien	(abs:TF (match_operand:TF 1 "register_operand" "")))
1013090286Sobrien   (clobber (reg:CC 17))]
1013190286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
1013290286Sobrien  [(set (match_dup 0)
1013390286Sobrien	(abs:TF (match_dup 1)))]
1013490286Sobrien  "")
1013590286Sobrien
1013690286Sobrien(define_split
1013790286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
1013890286Sobrien	(abs:TF (match_operand:TF 1 "register_operand" "")))
1013990286Sobrien   (clobber (reg:CC 17))]
1014090286Sobrien  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
1014190286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
1014290286Sobrien	      (clobber (reg:CC 17))])]
1014390286Sobrien  "operands[1] = GEN_INT (~0x8000);
1014490286Sobrien   operands[0] = gen_rtx_REG (SImode,
1014590286Sobrien			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
1014690286Sobrien
1014790286Sobrien(define_insn "*abssf2_1"
1014818334Speter  [(set (match_operand:SF 0 "register_operand" "=f")
1014950650Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "0")))]
1015090286Sobrien  "TARGET_80387 && reload_completed"
1015150650Sobrien  "fabs"
1015290286Sobrien  [(set_attr "type" "fsgn")
1015390286Sobrien   (set_attr "mode" "SF")])
1015418334Speter
1015590286Sobrien(define_insn "*absdf2_1"
1015618334Speter  [(set (match_operand:DF 0 "register_operand" "=f")
1015750650Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "0")))]
1015890286Sobrien  "TARGET_80387 && reload_completed"
1015950650Sobrien  "fabs"
1016090286Sobrien  [(set_attr "type" "fsgn")
1016190286Sobrien   (set_attr "mode" "DF")])
1016218334Speter
1016390286Sobrien(define_insn "*absextendsfdf2"
1016418334Speter  [(set (match_operand:DF 0 "register_operand" "=f")
1016590286Sobrien	(abs:DF (float_extend:DF
1016690286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
1016718334Speter  "TARGET_80387"
1016850650Sobrien  "fabs"
1016990286Sobrien  [(set_attr "type" "fsgn")
1017090286Sobrien   (set_attr "mode" "DF")])
1017118334Speter
1017290286Sobrien(define_insn "*absxf2_1"
1017318334Speter  [(set (match_operand:XF 0 "register_operand" "=f")
1017450650Sobrien	(abs:XF (match_operand:XF 1 "register_operand" "0")))]
1017590286Sobrien  "!TARGET_64BIT && TARGET_80387 && reload_completed"
1017650650Sobrien  "fabs"
1017790286Sobrien  [(set_attr "type" "fsgn")
1017890286Sobrien   (set_attr "mode" "DF")])
1017918334Speter
1018090286Sobrien(define_insn "*absextenddfxf2"
1018118334Speter  [(set (match_operand:XF 0 "register_operand" "=f")
1018290286Sobrien	(abs:XF (float_extend:XF
1018390286Sobrien	  (match_operand:DF 1 "register_operand" "0"))))]
1018490286Sobrien  "!TARGET_64BIT && TARGET_80387"
1018550650Sobrien  "fabs"
1018690286Sobrien  [(set_attr "type" "fsgn")
1018790286Sobrien   (set_attr "mode" "XF")])
1018818334Speter
1018990286Sobrien(define_insn "*absextendsfxf2"
1019090286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1019190286Sobrien	(abs:XF (float_extend:XF
1019290286Sobrien	  (match_operand:SF 1 "register_operand" "0"))))]
1019390286Sobrien  "!TARGET_64BIT && TARGET_80387"
1019490286Sobrien  "fabs"
1019590286Sobrien  [(set_attr "type" "fsgn")
1019690286Sobrien   (set_attr "mode" "XF")])
1019718334Speter
1019890286Sobrien(define_insn "*abstf2_1"
1019990286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1020090286Sobrien	(abs:TF (match_operand:TF 1 "register_operand" "0")))]
1020190286Sobrien  "TARGET_80387 && reload_completed"
1020290286Sobrien  "fabs"
1020390286Sobrien  [(set_attr "type" "fsgn")
1020490286Sobrien   (set_attr "mode" "DF")])
1020518334Speter
1020690286Sobrien(define_insn "*absextenddftf2"
1020790286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1020890286Sobrien	(abs:TF (float_extend:TF
1020990286Sobrien	  (match_operand:DF 1 "register_operand" "0"))))]
1021090286Sobrien  "TARGET_80387"
1021190286Sobrien  "fabs"
1021290286Sobrien  [(set_attr "type" "fsgn")
1021390286Sobrien   (set_attr "mode" "XF")])
1021418334Speter
1021590286Sobrien(define_insn "*absextendsftf2"
1021690286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1021790286Sobrien	(abs:TF (float_extend:TF
1021890286Sobrien	  (match_operand:SF 1 "register_operand" "0"))))]
1021990286Sobrien  "TARGET_80387"
1022090286Sobrien  "fabs"
1022190286Sobrien  [(set_attr "type" "fsgn")
1022290286Sobrien   (set_attr "mode" "XF")])
1022390286Sobrien
1022490286Sobrien;; One complement instructions
1022518334Speter
1022690286Sobrien(define_expand "one_cmpldi2"
1022790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1022890286Sobrien	(not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
1022990286Sobrien  "TARGET_64BIT"
1023090286Sobrien  "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
1023118334Speter
1023290286Sobrien(define_insn "*one_cmpldi2_1_rex64"
1023390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1023490286Sobrien	(not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
1023590286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
1023690286Sobrien  "not{q}\t%0"
1023790286Sobrien  [(set_attr "type" "negnot")
1023890286Sobrien   (set_attr "mode" "DI")])
1023918334Speter
1024090286Sobrien(define_insn "*one_cmpldi2_2_rex64"
1024190286Sobrien  [(set (reg 17)
1024290286Sobrien	(compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
1024390286Sobrien		 (const_int 0)))
1024490286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1024590286Sobrien	(not:DI (match_dup 1)))]
1024690286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
1024790286Sobrien   && ix86_unary_operator_ok (NOT, DImode, operands)"
1024890286Sobrien  "#"
1024990286Sobrien  [(set_attr "type" "alu1")
1025090286Sobrien   (set_attr "mode" "DI")])
1025118334Speter
1025290286Sobrien(define_split
1025390286Sobrien  [(set (reg 17)
1025490286Sobrien	(compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
1025590286Sobrien		 (const_int 0)))
1025690286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "")
1025790286Sobrien	(not:DI (match_dup 1)))]
1025890286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
1025990286Sobrien  [(parallel [(set (reg:CCNO 17)
1026090286Sobrien		   (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
1026190286Sobrien				 (const_int 0)))
1026290286Sobrien	      (set (match_dup 0)
1026390286Sobrien		   (xor:DI (match_dup 1) (const_int -1)))])]
1026490286Sobrien  "")
1026518334Speter
1026690286Sobrien(define_expand "one_cmplsi2"
1026790286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1026890286Sobrien	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
1026990286Sobrien  ""
1027090286Sobrien  "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
1027118334Speter
1027290286Sobrien(define_insn "*one_cmplsi2_1"
1027390286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1027490286Sobrien	(not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
1027590286Sobrien  "ix86_unary_operator_ok (NOT, SImode, operands)"
1027690286Sobrien  "not{l}\t%0"
1027790286Sobrien  [(set_attr "type" "negnot")
1027890286Sobrien   (set_attr "mode" "SI")])
1027918334Speter
1028090286Sobrien;; ??? Currently never generated - xor is used instead.
1028190286Sobrien(define_insn "*one_cmplsi2_1_zext"
1028290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1028390286Sobrien	(zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
1028490286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
1028590286Sobrien  "not{l}\t%k0"
1028690286Sobrien  [(set_attr "type" "negnot")
1028790286Sobrien   (set_attr "mode" "SI")])
1028818334Speter
1028990286Sobrien(define_insn "*one_cmplsi2_2"
1029090286Sobrien  [(set (reg 17)
1029190286Sobrien	(compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
1029290286Sobrien		 (const_int 0)))
1029390286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1029490286Sobrien	(not:SI (match_dup 1)))]
1029590286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
1029690286Sobrien   && ix86_unary_operator_ok (NOT, SImode, operands)"
1029790286Sobrien  "#"
1029890286Sobrien  [(set_attr "type" "alu1")
1029990286Sobrien   (set_attr "mode" "SI")])
1030018334Speter
1030190286Sobrien(define_split
1030290286Sobrien  [(set (reg 17)
1030390286Sobrien	(compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
1030490286Sobrien		 (const_int 0)))
1030590286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "")
1030690286Sobrien	(not:SI (match_dup 1)))]
1030790286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
1030890286Sobrien  [(parallel [(set (reg:CCNO 17)
1030990286Sobrien		   (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
1031090286Sobrien				 (const_int 0)))
1031190286Sobrien	      (set (match_dup 0)
1031290286Sobrien		   (xor:SI (match_dup 1) (const_int -1)))])]
1031390286Sobrien  "")
1031418334Speter
1031590286Sobrien;; ??? Currently never generated - xor is used instead.
1031690286Sobrien(define_insn "*one_cmplsi2_2_zext"
1031790286Sobrien  [(set (reg 17)
1031890286Sobrien	(compare (not:SI (match_operand:SI 1 "register_operand" "0"))
1031990286Sobrien		 (const_int 0)))
1032090286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1032190286Sobrien	(zero_extend:DI (not:SI (match_dup 1))))]
1032290286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
1032390286Sobrien   && ix86_unary_operator_ok (NOT, SImode, operands)"
1032490286Sobrien  "#"
1032590286Sobrien  [(set_attr "type" "alu1")
1032690286Sobrien   (set_attr "mode" "SI")])
1032718334Speter
1032890286Sobrien(define_split
1032990286Sobrien  [(set (reg 17)
1033090286Sobrien	(compare (not:SI (match_operand:SI 1 "register_operand" ""))
1033190286Sobrien		 (const_int 0)))
1033290286Sobrien   (set (match_operand:DI 0 "register_operand" "")
1033390286Sobrien	(zero_extend:DI (not:SI (match_dup 1))))]
1033490286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
1033590286Sobrien  [(parallel [(set (reg:CCNO 17)
1033690286Sobrien		   (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
1033790286Sobrien				 (const_int 0)))
1033890286Sobrien	      (set (match_dup 0)
1033990286Sobrien		   (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
1034090286Sobrien  "")
1034118334Speter
1034290286Sobrien(define_expand "one_cmplhi2"
1034390286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1034490286Sobrien	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
1034590286Sobrien  "TARGET_HIMODE_MATH"
1034690286Sobrien  "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
1034752296Sobrien
1034890286Sobrien(define_insn "*one_cmplhi2_1"
1034950650Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1035050650Sobrien	(not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
1035190286Sobrien  "ix86_unary_operator_ok (NOT, HImode, operands)"
1035290286Sobrien  "not{w}\t%0"
1035390286Sobrien  [(set_attr "type" "negnot")
1035490286Sobrien   (set_attr "mode" "HI")])
1035518334Speter
1035690286Sobrien(define_insn "*one_cmplhi2_2"
1035790286Sobrien  [(set (reg 17)
1035890286Sobrien	(compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
1035990286Sobrien		 (const_int 0)))
1036090286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1036190286Sobrien	(not:HI (match_dup 1)))]
1036290286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
1036390286Sobrien   && ix86_unary_operator_ok (NEG, HImode, operands)"
1036490286Sobrien  "#"
1036590286Sobrien  [(set_attr "type" "alu1")
1036690286Sobrien   (set_attr "mode" "HI")])
1036752296Sobrien
1036890286Sobrien(define_split
1036990286Sobrien  [(set (reg 17)
1037090286Sobrien	(compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
1037190286Sobrien		 (const_int 0)))
1037290286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "")
1037390286Sobrien	(not:HI (match_dup 1)))]
1037490286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
1037590286Sobrien  [(parallel [(set (reg:CCNO 17)
1037690286Sobrien		   (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
1037790286Sobrien		      		 (const_int 0)))
1037890286Sobrien	      (set (match_dup 0)
1037990286Sobrien		   (xor:HI (match_dup 1) (const_int -1)))])]
1038090286Sobrien  "")
1038152296Sobrien
1038290286Sobrien;; %%% Potential partial reg stall on alternative 1.  What to do?
1038390286Sobrien(define_expand "one_cmplqi2"
1038490286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1038590286Sobrien	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
1038690286Sobrien  "TARGET_QIMODE_MATH"
1038790286Sobrien  "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
1038890286Sobrien
1038990286Sobrien(define_insn "*one_cmplqi2_1"
1039090286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
1039190286Sobrien	(not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
1039290286Sobrien  "ix86_unary_operator_ok (NOT, QImode, operands)"
1039390286Sobrien  "@
1039490286Sobrien   not{b}\t%0
1039590286Sobrien   not{l}\t%k0"
1039690286Sobrien  [(set_attr "type" "negnot")
1039790286Sobrien   (set_attr "mode" "QI,SI")])
1039890286Sobrien
1039990286Sobrien(define_insn "*one_cmplqi2_2"
1040090286Sobrien  [(set (reg 17)
1040190286Sobrien	(compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
1040290286Sobrien		 (const_int 0)))
1040390286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1040490286Sobrien	(not:QI (match_dup 1)))]
1040590286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
1040690286Sobrien   && ix86_unary_operator_ok (NOT, QImode, operands)"
1040790286Sobrien  "#"
1040890286Sobrien  [(set_attr "type" "alu1")
1040990286Sobrien   (set_attr "mode" "QI")])
1041090286Sobrien
1041190286Sobrien(define_split
1041290286Sobrien  [(set (reg 17)
1041390286Sobrien	(compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
1041490286Sobrien		 (const_int 0)))
1041590286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "")
1041690286Sobrien	(not:QI (match_dup 1)))]
1041790286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
1041890286Sobrien  [(parallel [(set (reg:CCNO 17)
1041990286Sobrien		   (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
1042090286Sobrien		      		 (const_int 0)))
1042190286Sobrien	      (set (match_dup 0)
1042290286Sobrien		   (xor:QI (match_dup 1) (const_int -1)))])]
1042390286Sobrien  "")
1042418334Speter
1042590286Sobrien;; Arithmetic shift instructions
1042618334Speter
1042718334Speter;; DImode shifts are implemented using the i386 "shift double" opcode,
1042818334Speter;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
1042918334Speter;; is variable, then the count is in %cl and the "imm" operand is dropped
1043018334Speter;; from the assembler input.
1043190286Sobrien;;
1043218334Speter;; This instruction shifts the target reg/mem as usual, but instead of
1043318334Speter;; shifting in zeros, bits are shifted in from reg operand.  If the insn
1043418334Speter;; is a left shift double, bits are taken from the high order bits of
1043518334Speter;; reg, else if the insn is a shift right double, bits are taken from the
1043618334Speter;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
1043718334Speter;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
1043890286Sobrien;;
1043918334Speter;; Since sh[lr]d does not change the `reg' operand, that is done
1044018334Speter;; separately, making all shifts emit pairs of shift double and normal
1044118334Speter;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
1044218334Speter;; support a 63 bit shift, each shift where the count is in a reg expands
1044350650Sobrien;; to a pair of shifts, a branch, a shift by 32 and a label.
1044490286Sobrien;;
1044518334Speter;; If the shift count is a constant, we need never emit more than one
1044618334Speter;; shift pair, instead using moves and sign extension for counts greater
1044718334Speter;; than 31.
1044818334Speter
1044918334Speter(define_expand "ashldi3"
1045090286Sobrien  [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
1045190286Sobrien		   (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
1045290286Sobrien			      (match_operand:QI 2 "nonmemory_operand" "")))
1045390286Sobrien	      (clobber (reg:CC 17))])]
1045418334Speter  ""
1045518334Speter{
1045690286Sobrien  if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
1045718334Speter    {
1045890286Sobrien      emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
1045990286Sobrien      DONE;
1046018334Speter    }
1046190286Sobrien  ix86_expand_binary_operator (ASHIFT, DImode, operands);
1046218334Speter  DONE;
1046390286Sobrien})
1046418334Speter
1046590286Sobrien(define_insn "*ashldi3_1_rex64"
1046690286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
1046790286Sobrien	(ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
1046890286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
1046990286Sobrien   (clobber (reg:CC 17))]
1047090286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
1047118334Speter{
1047290286Sobrien  switch (get_attr_type (insn))
1047390286Sobrien    {
1047490286Sobrien    case TYPE_ALU:
1047590286Sobrien      if (operands[2] != const1_rtx)
1047690286Sobrien	abort ();
1047790286Sobrien      if (!rtx_equal_p (operands[0], operands[1]))
1047890286Sobrien	abort ();
1047990286Sobrien      return "add{q}\t{%0, %0|%0, %0}";
1048018334Speter
1048190286Sobrien    case TYPE_LEA:
1048290286Sobrien      if (GET_CODE (operands[2]) != CONST_INT
1048390286Sobrien	  || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
1048490286Sobrien	abort ();
1048590286Sobrien      operands[1] = gen_rtx_MULT (DImode, operands[1],
1048690286Sobrien				  GEN_INT (1 << INTVAL (operands[2])));
1048790286Sobrien      return "lea{q}\t{%a1, %0|%0, %a1}";
1048818334Speter
1048990286Sobrien    default:
1049090286Sobrien      if (REG_P (operands[2]))
1049190286Sobrien	return "sal{q}\t{%b2, %0|%0, %b2}";
1049290286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1049390286Sobrien	       && INTVAL (operands[2]) == 1
1049490286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1049590286Sobrien	return "sal{q}\t%0";
1049690286Sobrien      else
1049790286Sobrien	return "sal{q}\t{%2, %0|%0, %2}";
1049890286Sobrien    }
1049990286Sobrien}
1050090286Sobrien  [(set (attr "type")
1050190286Sobrien     (cond [(eq_attr "alternative" "1")
1050290286Sobrien	      (const_string "lea")
1050390286Sobrien            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1050490286Sobrien		          (const_int 0))
1050590286Sobrien		      (match_operand 0 "register_operand" ""))
1050690286Sobrien		 (match_operand 2 "const1_operand" ""))
1050790286Sobrien	      (const_string "alu")
1050890286Sobrien	   ]
1050990286Sobrien	   (const_string "ishift")))
1051090286Sobrien   (set_attr "mode" "DI")])
1051118334Speter
1051290286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
1051390286Sobrien(define_split
1051490286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1051590286Sobrien	(ashift:DI (match_operand:DI 1 "register_operand" "")
1051690286Sobrien		   (match_operand:QI 2 "immediate_operand" "")))
1051790286Sobrien   (clobber (reg:CC 17))]
1051890286Sobrien  "TARGET_64BIT && reload_completed
1051990286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
1052090286Sobrien  [(set (match_dup 0)
1052190286Sobrien	(mult:DI (match_dup 1)
1052290286Sobrien		 (match_dup 2)))]
1052390286Sobrien  "operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
1052490286Sobrien					      DImode));")
1052590286Sobrien
1052690286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1052790286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1052890286Sobrien;; zero are optimized away.
1052990286Sobrien(define_insn "*ashldi3_cmp_rex64"
1053090286Sobrien  [(set (reg 17)
1053190286Sobrien	(compare
1053290286Sobrien	  (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1053390286Sobrien		     (match_operand:QI 2 "immediate_operand" "e"))
1053490286Sobrien	  (const_int 0)))
1053590286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1053690286Sobrien	(ashift:DI (match_dup 1) (match_dup 2)))]
1053790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1053890286Sobrien   && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
1053990286Sobrien{
1054090286Sobrien  switch (get_attr_type (insn))
1054118334Speter    {
1054290286Sobrien    case TYPE_ALU:
1054390286Sobrien      if (operands[2] != const1_rtx)
1054490286Sobrien	abort ();
1054590286Sobrien      return "add{q}\t{%0, %0|%0, %0}";
1054618334Speter
1054790286Sobrien    default:
1054890286Sobrien      if (REG_P (operands[2]))
1054990286Sobrien	return "sal{q}\t{%b2, %0|%0, %b2}";
1055090286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1055190286Sobrien	       && INTVAL (operands[2]) == 1
1055290286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1055390286Sobrien	return "sal{q}\t%0";
1055490286Sobrien      else
1055590286Sobrien	return "sal{q}\t{%2, %0|%0, %2}";
1055618334Speter    }
1055790286Sobrien}
1055890286Sobrien  [(set (attr "type")
1055990286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1056090286Sobrien		          (const_int 0))
1056190286Sobrien		      (match_operand 0 "register_operand" ""))
1056290286Sobrien		 (match_operand 2 "const1_operand" ""))
1056390286Sobrien	      (const_string "alu")
1056490286Sobrien	   ]
1056590286Sobrien	   (const_string "ishift")))
1056690286Sobrien   (set_attr "mode" "DI")])
1056718334Speter
1056890286Sobrien(define_insn "ashldi3_1"
1056990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1057018334Speter	(ashift:DI (match_operand:DI 1 "register_operand" "0")
1057190286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "Jc")))
1057290286Sobrien   (clobber (match_scratch:SI 3 "=&r"))
1057390286Sobrien   (clobber (reg:CC 17))]
1057490286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1057590286Sobrien  "#"
1057690286Sobrien  [(set_attr "type" "multi")])
1057790286Sobrien
1057890286Sobrien(define_insn "*ashldi3_2"
1057990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1058090286Sobrien	(ashift:DI (match_operand:DI 1 "register_operand" "0")
1058190286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "Jc")))
1058290286Sobrien   (clobber (reg:CC 17))]
1058390286Sobrien  "!TARGET_64BIT"
1058490286Sobrien  "#"
1058590286Sobrien  [(set_attr "type" "multi")])
1058690286Sobrien
1058790286Sobrien(define_split
1058890286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1058990286Sobrien	(ashift:DI (match_operand:DI 1 "register_operand" "")
1059090286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1059190286Sobrien   (clobber (match_scratch:SI 3 ""))
1059290286Sobrien   (clobber (reg:CC 17))]
1059390286Sobrien  "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
1059490286Sobrien  [(const_int 0)]
1059590286Sobrien  "ix86_split_ashldi (operands, operands[3]); DONE;")
1059690286Sobrien
1059790286Sobrien(define_split
1059890286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1059990286Sobrien	(ashift:DI (match_operand:DI 1 "register_operand" "")
1060090286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1060190286Sobrien   (clobber (reg:CC 17))]
1060290286Sobrien  "!TARGET_64BIT && reload_completed"
1060390286Sobrien  [(const_int 0)]
1060490286Sobrien  "ix86_split_ashldi (operands, NULL_RTX); DONE;")
1060590286Sobrien
1060690286Sobrien(define_insn "x86_shld_1"
1060790286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
1060890286Sobrien        (ior:SI (ashift:SI (match_dup 0)
1060990286Sobrien		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
1061090286Sobrien		(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1061190286Sobrien		  (minus:QI (const_int 32) (match_dup 2)))))
1061290286Sobrien   (clobber (reg:CC 17))]
1061318334Speter  ""
1061490286Sobrien  "@
1061590286Sobrien   shld{l}\t{%2, %1, %0|%0, %1, %2}
1061690286Sobrien   shld{l}\t{%s2%1, %0|%0, %1, %2}"
1061790286Sobrien  [(set_attr "type" "ishift")
1061890286Sobrien   (set_attr "prefix_0f" "1")
1061990286Sobrien   (set_attr "mode" "SI")
1062090286Sobrien   (set_attr "pent_pair" "np")
1062190286Sobrien   (set_attr "athlon_decode" "vector")
1062290286Sobrien   (set_attr "ppro_uops" "few")])
1062390286Sobrien
1062490286Sobrien(define_expand "x86_shift_adj_1"
1062590286Sobrien  [(set (reg:CCZ 17)
1062690286Sobrien	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
1062790286Sobrien			     (const_int 32))
1062890286Sobrien		     (const_int 0)))
1062990286Sobrien   (set (match_operand:SI 0 "register_operand" "")
1063090286Sobrien        (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
1063190286Sobrien			 (match_operand:SI 1 "register_operand" "")
1063290286Sobrien			 (match_dup 0)))
1063390286Sobrien   (set (match_dup 1)
1063490286Sobrien	(if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
1063590286Sobrien			 (match_operand:SI 3 "register_operand" "r")
1063690286Sobrien			 (match_dup 1)))]
1063790286Sobrien  "TARGET_CMOVE"
1063890286Sobrien  "")
1063990286Sobrien
1064090286Sobrien(define_expand "x86_shift_adj_2"
1064190286Sobrien  [(use (match_operand:SI 0 "register_operand" ""))
1064290286Sobrien   (use (match_operand:SI 1 "register_operand" ""))
1064390286Sobrien   (use (match_operand:QI 2 "register_operand" ""))]
1064490286Sobrien  ""
1064518334Speter{
1064690286Sobrien  rtx label = gen_label_rtx ();
1064790286Sobrien  rtx tmp;
1064818334Speter
1064990286Sobrien  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
1065018334Speter
1065190286Sobrien  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
1065290286Sobrien  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1065390286Sobrien  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
1065490286Sobrien			      gen_rtx_LABEL_REF (VOIDmode, label),
1065590286Sobrien			      pc_rtx);
1065690286Sobrien  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
1065790286Sobrien  JUMP_LABEL (tmp) = label;
1065818334Speter
1065990286Sobrien  emit_move_insn (operands[0], operands[1]);
1066090286Sobrien  emit_move_insn (operands[1], const0_rtx);
1066118334Speter
1066290286Sobrien  emit_label (label);
1066390286Sobrien  LABEL_NUSES (label) = 1;
1066490286Sobrien
1066590286Sobrien  DONE;
1066690286Sobrien})
1066790286Sobrien
1066852296Sobrien(define_expand "ashlsi3"
1066952296Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1067052296Sobrien	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
1067190286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1067290286Sobrien   (clobber (reg:CC 17))]
1067352296Sobrien  ""
1067490286Sobrien  "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
1067518334Speter
1067690286Sobrien(define_insn "*ashlsi3_1"
1067790286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
1067890286Sobrien	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
1067990286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
1068090286Sobrien   (clobber (reg:CC 17))]
1068190286Sobrien  "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
1068290286Sobrien{
1068390286Sobrien  switch (get_attr_type (insn))
1068490286Sobrien    {
1068590286Sobrien    case TYPE_ALU:
1068690286Sobrien      if (operands[2] != const1_rtx)
1068790286Sobrien	abort ();
1068890286Sobrien      if (!rtx_equal_p (operands[0], operands[1]))
1068990286Sobrien	abort ();
1069090286Sobrien      return "add{l}\t{%0, %0|%0, %0}";
1069190286Sobrien
1069290286Sobrien    case TYPE_LEA:
1069390286Sobrien      return "#";
1069490286Sobrien
1069590286Sobrien    default:
1069690286Sobrien      if (REG_P (operands[2]))
1069790286Sobrien	return "sal{l}\t{%b2, %0|%0, %b2}";
1069890286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1069990286Sobrien	       && INTVAL (operands[2]) == 1
1070090286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1070190286Sobrien	return "sal{l}\t%0";
1070290286Sobrien      else
1070390286Sobrien	return "sal{l}\t{%2, %0|%0, %2}";
1070490286Sobrien    }
1070590286Sobrien}
1070690286Sobrien  [(set (attr "type")
1070790286Sobrien     (cond [(eq_attr "alternative" "1")
1070890286Sobrien	      (const_string "lea")
1070990286Sobrien            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1071090286Sobrien		          (const_int 0))
1071190286Sobrien		      (match_operand 0 "register_operand" ""))
1071290286Sobrien		 (match_operand 2 "const1_operand" ""))
1071390286Sobrien	      (const_string "alu")
1071490286Sobrien	   ]
1071590286Sobrien	   (const_string "ishift")))
1071690286Sobrien   (set_attr "mode" "SI")])
1071790286Sobrien
1071890286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
1071990286Sobrien(define_split
1072090286Sobrien  [(set (match_operand 0 "register_operand" "")
1072190286Sobrien	(ashift (match_operand 1 "register_operand" "")
1072290286Sobrien                (match_operand:QI 2 "const_int_operand" "")))
1072390286Sobrien   (clobber (reg:CC 17))]
1072490286Sobrien  "reload_completed
1072590286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
1072690286Sobrien  [(const_int 0)]
1072790286Sobrien{
1072890286Sobrien  rtx pat;
1072990286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
1073090286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
1073190286Sobrien  operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
1073290286Sobrien					     Pmode));
1073390286Sobrien  pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
1073490286Sobrien  if (Pmode != SImode)
1073590286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
1073690286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
1073790286Sobrien  DONE;
1073890286Sobrien})
1073990286Sobrien
1074090286Sobrien(define_insn "*ashlsi3_1_zext"
1074190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1074290286Sobrien	(zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
1074390286Sobrien			(match_operand:QI 2 "nonmemory_operand" "cI,M"))))
1074490286Sobrien   (clobber (reg:CC 17))]
1074590286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
1074690286Sobrien{
1074790286Sobrien  switch (get_attr_type (insn))
1074890286Sobrien    {
1074990286Sobrien    case TYPE_ALU:
1075090286Sobrien      if (operands[2] != const1_rtx)
1075190286Sobrien	abort ();
1075290286Sobrien      return "add{l}\t{%k0, %k0|%k0, %k0}";
1075390286Sobrien
1075490286Sobrien    case TYPE_LEA:
1075590286Sobrien      return "#";
1075690286Sobrien
1075790286Sobrien    default:
1075890286Sobrien      if (REG_P (operands[2]))
1075990286Sobrien	return "sal{l}\t{%b2, %k0|%k0, %b2}";
1076090286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1076190286Sobrien	       && INTVAL (operands[2]) == 1
1076290286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1076390286Sobrien	return "sal{l}\t%k0";
1076490286Sobrien      else
1076590286Sobrien	return "sal{l}\t{%2, %k0|%k0, %2}";
1076690286Sobrien    }
1076790286Sobrien}
1076890286Sobrien  [(set (attr "type")
1076990286Sobrien     (cond [(eq_attr "alternative" "1")
1077090286Sobrien	      (const_string "lea")
1077190286Sobrien            (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1077290286Sobrien		     (const_int 0))
1077390286Sobrien		 (match_operand 2 "const1_operand" ""))
1077490286Sobrien	      (const_string "alu")
1077590286Sobrien	   ]
1077690286Sobrien	   (const_string "ishift")))
1077790286Sobrien   (set_attr "mode" "SI")])
1077890286Sobrien
1077990286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
1078090286Sobrien(define_split
1078190286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1078290286Sobrien	(zero_extend:DI (ashift (match_operand 1 "register_operand" "")
1078390286Sobrien				(match_operand:QI 2 "const_int_operand" ""))))
1078490286Sobrien   (clobber (reg:CC 17))]
1078590286Sobrien  "reload_completed
1078690286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
1078790286Sobrien  [(set (match_dup 0) (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
1078890286Sobrien{
1078990286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
1079090286Sobrien  operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
1079190286Sobrien					     Pmode));
1079290286Sobrien})
1079390286Sobrien
1079490286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1079590286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1079690286Sobrien;; zero are optimized away.
1079790286Sobrien(define_insn "*ashlsi3_cmp"
1079890286Sobrien  [(set (reg 17)
1079990286Sobrien	(compare
1080090286Sobrien	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1080190286Sobrien		     (match_operand:QI 2 "immediate_operand" "I"))
1080290286Sobrien	  (const_int 0)))
1080390286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1080490286Sobrien	(ashift:SI (match_dup 1) (match_dup 2)))]
1080590286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1080690286Sobrien   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
1080790286Sobrien{
1080890286Sobrien  switch (get_attr_type (insn))
1080990286Sobrien    {
1081090286Sobrien    case TYPE_ALU:
1081190286Sobrien      if (operands[2] != const1_rtx)
1081290286Sobrien	abort ();
1081390286Sobrien      return "add{l}\t{%0, %0|%0, %0}";
1081490286Sobrien
1081590286Sobrien    default:
1081690286Sobrien      if (REG_P (operands[2]))
1081790286Sobrien	return "sal{l}\t{%b2, %0|%0, %b2}";
1081890286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1081990286Sobrien	       && INTVAL (operands[2]) == 1
1082090286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1082190286Sobrien	return "sal{l}\t%0";
1082290286Sobrien      else
1082390286Sobrien	return "sal{l}\t{%2, %0|%0, %2}";
1082490286Sobrien    }
1082590286Sobrien}
1082690286Sobrien  [(set (attr "type")
1082790286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1082890286Sobrien		          (const_int 0))
1082990286Sobrien		      (match_operand 0 "register_operand" ""))
1083090286Sobrien		 (match_operand 2 "const1_operand" ""))
1083190286Sobrien	      (const_string "alu")
1083290286Sobrien	   ]
1083390286Sobrien	   (const_string "ishift")))
1083490286Sobrien   (set_attr "mode" "SI")])
1083590286Sobrien
1083690286Sobrien(define_insn "*ashlsi3_cmp_zext"
1083790286Sobrien  [(set (reg 17)
1083890286Sobrien	(compare
1083990286Sobrien	  (ashift:SI (match_operand:SI 1 "register_operand" "0")
1084090286Sobrien		     (match_operand:QI 2 "immediate_operand" "I"))
1084190286Sobrien	  (const_int 0)))
1084290286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1084390286Sobrien	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
1084490286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1084590286Sobrien   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
1084690286Sobrien{
1084790286Sobrien  switch (get_attr_type (insn))
1084890286Sobrien    {
1084990286Sobrien    case TYPE_ALU:
1085090286Sobrien      if (operands[2] != const1_rtx)
1085190286Sobrien	abort ();
1085290286Sobrien      return "add{l}\t{%k0, %k0|%k0, %k0}";
1085390286Sobrien
1085490286Sobrien    default:
1085590286Sobrien      if (REG_P (operands[2]))
1085690286Sobrien	return "sal{l}\t{%b2, %k0|%k0, %b2}";
1085790286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1085890286Sobrien	       && INTVAL (operands[2]) == 1
1085990286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1086090286Sobrien	return "sal{l}\t%k0";
1086190286Sobrien      else
1086290286Sobrien	return "sal{l}\t{%2, %k0|%k0, %2}";
1086390286Sobrien    }
1086490286Sobrien}
1086590286Sobrien  [(set (attr "type")
1086690286Sobrien     (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1086790286Sobrien		     (const_int 0))
1086890286Sobrien		 (match_operand 2 "const1_operand" ""))
1086990286Sobrien	      (const_string "alu")
1087090286Sobrien	   ]
1087190286Sobrien	   (const_string "ishift")))
1087290286Sobrien   (set_attr "mode" "SI")])
1087390286Sobrien
1087452296Sobrien(define_expand "ashlhi3"
1087552296Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1087652296Sobrien	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
1087790286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1087890286Sobrien   (clobber (reg:CC 17))]
1087990286Sobrien  "TARGET_HIMODE_MATH"
1088090286Sobrien  "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
1088118334Speter
1088290286Sobrien(define_insn "*ashlhi3_1_lea"
1088390286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
1088490286Sobrien	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
1088590286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
1088690286Sobrien   (clobber (reg:CC 17))]
1088790286Sobrien  "!TARGET_PARTIAL_REG_STALL
1088890286Sobrien   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
1088990286Sobrien{
1089090286Sobrien  switch (get_attr_type (insn))
1089190286Sobrien    {
1089290286Sobrien    case TYPE_LEA:
1089390286Sobrien      return "#";
1089490286Sobrien    case TYPE_ALU:
1089590286Sobrien      if (operands[2] != const1_rtx)
1089690286Sobrien	abort ();
1089790286Sobrien      return "add{w}\t{%0, %0|%0, %0}";
1089890286Sobrien
1089990286Sobrien    default:
1090090286Sobrien      if (REG_P (operands[2]))
1090190286Sobrien	return "sal{w}\t{%b2, %0|%0, %b2}";
1090290286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1090390286Sobrien	       && INTVAL (operands[2]) == 1
1090490286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1090590286Sobrien	return "sal{w}\t%0";
1090690286Sobrien      else
1090790286Sobrien	return "sal{w}\t{%2, %0|%0, %2}";
1090890286Sobrien    }
1090990286Sobrien}
1091090286Sobrien  [(set (attr "type")
1091190286Sobrien     (cond [(eq_attr "alternative" "1")
1091290286Sobrien	      (const_string "lea")
1091390286Sobrien            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1091490286Sobrien		          (const_int 0))
1091590286Sobrien		      (match_operand 0 "register_operand" ""))
1091690286Sobrien		 (match_operand 2 "const1_operand" ""))
1091790286Sobrien	      (const_string "alu")
1091890286Sobrien	   ]
1091990286Sobrien	   (const_string "ishift")))
1092090286Sobrien   (set_attr "mode" "HI,SI")])
1092190286Sobrien
1092290286Sobrien(define_insn "*ashlhi3_1"
1092390286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1092490286Sobrien	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1092590286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI")))
1092690286Sobrien   (clobber (reg:CC 17))]
1092790286Sobrien  "TARGET_PARTIAL_REG_STALL
1092890286Sobrien   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
1092990286Sobrien{
1093090286Sobrien  switch (get_attr_type (insn))
1093190286Sobrien    {
1093290286Sobrien    case TYPE_ALU:
1093390286Sobrien      if (operands[2] != const1_rtx)
1093490286Sobrien	abort ();
1093590286Sobrien      return "add{w}\t{%0, %0|%0, %0}";
1093690286Sobrien
1093790286Sobrien    default:
1093890286Sobrien      if (REG_P (operands[2]))
1093990286Sobrien	return "sal{w}\t{%b2, %0|%0, %b2}";
1094090286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1094190286Sobrien	       && INTVAL (operands[2]) == 1
1094290286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1094390286Sobrien	return "sal{w}\t%0";
1094490286Sobrien      else
1094590286Sobrien	return "sal{w}\t{%2, %0|%0, %2}";
1094690286Sobrien    }
1094790286Sobrien}
1094890286Sobrien  [(set (attr "type")
1094990286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1095090286Sobrien		          (const_int 0))
1095190286Sobrien		      (match_operand 0 "register_operand" ""))
1095290286Sobrien		 (match_operand 2 "const1_operand" ""))
1095390286Sobrien	      (const_string "alu")
1095490286Sobrien	   ]
1095590286Sobrien	   (const_string "ishift")))
1095690286Sobrien   (set_attr "mode" "HI")])
1095790286Sobrien
1095890286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1095990286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1096090286Sobrien;; zero are optimized away.
1096190286Sobrien(define_insn "*ashlhi3_cmp"
1096290286Sobrien  [(set (reg 17)
1096390286Sobrien	(compare
1096490286Sobrien	  (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1096590286Sobrien		     (match_operand:QI 2 "immediate_operand" "I"))
1096690286Sobrien	  (const_int 0)))
1096790286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1096890286Sobrien	(ashift:HI (match_dup 1) (match_dup 2)))]
1096990286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1097090286Sobrien   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
1097190286Sobrien{
1097290286Sobrien  switch (get_attr_type (insn))
1097390286Sobrien    {
1097490286Sobrien    case TYPE_ALU:
1097590286Sobrien      if (operands[2] != const1_rtx)
1097690286Sobrien	abort ();
1097790286Sobrien      return "add{w}\t{%0, %0|%0, %0}";
1097890286Sobrien
1097990286Sobrien    default:
1098090286Sobrien      if (REG_P (operands[2]))
1098190286Sobrien	return "sal{w}\t{%b2, %0|%0, %b2}";
1098290286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1098390286Sobrien	       && INTVAL (operands[2]) == 1
1098490286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1098590286Sobrien	return "sal{w}\t%0";
1098690286Sobrien      else
1098790286Sobrien	return "sal{w}\t{%2, %0|%0, %2}";
1098890286Sobrien    }
1098990286Sobrien}
1099090286Sobrien  [(set (attr "type")
1099190286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1099290286Sobrien		          (const_int 0))
1099390286Sobrien		      (match_operand 0 "register_operand" ""))
1099490286Sobrien		 (match_operand 2 "const1_operand" ""))
1099590286Sobrien	      (const_string "alu")
1099690286Sobrien	   ]
1099790286Sobrien	   (const_string "ishift")))
1099890286Sobrien   (set_attr "mode" "HI")])
1099990286Sobrien
1100052296Sobrien(define_expand "ashlqi3"
1100152296Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1100252296Sobrien	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
1100390286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1100490286Sobrien   (clobber (reg:CC 17))]
1100590286Sobrien  "TARGET_QIMODE_MATH"
1100690286Sobrien  "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
1100718334Speter
1100890286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
1100918334Speter
1101090286Sobrien(define_insn "*ashlqi3_1_lea"
1101190286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
1101290286Sobrien	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
1101390286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
1101490286Sobrien   (clobber (reg:CC 17))]
1101590286Sobrien  "!TARGET_PARTIAL_REG_STALL
1101690286Sobrien   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
1101790286Sobrien{
1101890286Sobrien  switch (get_attr_type (insn))
1101990286Sobrien    {
1102090286Sobrien    case TYPE_LEA:
1102190286Sobrien      return "#";
1102290286Sobrien    case TYPE_ALU:
1102390286Sobrien      if (operands[2] != const1_rtx)
1102490286Sobrien	abort ();
1102590286Sobrien      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
1102690286Sobrien        return "add{l}\t{%k0, %k0|%k0, %k0}";
1102790286Sobrien      else
1102890286Sobrien        return "add{b}\t{%0, %0|%0, %0}";
1102918334Speter
1103090286Sobrien    default:
1103190286Sobrien      if (REG_P (operands[2]))
1103290286Sobrien	{
1103390286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1103490286Sobrien	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
1103590286Sobrien	  else
1103690286Sobrien	    return "sal{b}\t{%b2, %0|%0, %b2}";
1103790286Sobrien	}
1103890286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1103990286Sobrien	       && INTVAL (operands[2]) == 1
1104090286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1104190286Sobrien	{
1104290286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1104390286Sobrien	    return "sal{l}\t%0";
1104490286Sobrien	  else
1104590286Sobrien	    return "sal{b}\t%0";
1104690286Sobrien	}
1104790286Sobrien      else
1104890286Sobrien	{
1104990286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1105090286Sobrien	    return "sal{l}\t{%2, %k0|%k0, %2}";
1105190286Sobrien	  else
1105290286Sobrien	    return "sal{b}\t{%2, %0|%0, %2}";
1105390286Sobrien	}
1105490286Sobrien    }
1105590286Sobrien}
1105690286Sobrien  [(set (attr "type")
1105790286Sobrien     (cond [(eq_attr "alternative" "2")
1105890286Sobrien	      (const_string "lea")
1105990286Sobrien            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1106090286Sobrien		          (const_int 0))
1106190286Sobrien		      (match_operand 0 "register_operand" ""))
1106290286Sobrien		 (match_operand 2 "const1_operand" ""))
1106390286Sobrien	      (const_string "alu")
1106490286Sobrien	   ]
1106590286Sobrien	   (const_string "ishift")))
1106690286Sobrien   (set_attr "mode" "QI,SI,SI")])
1106718334Speter
1106890286Sobrien(define_insn "*ashlqi3_1"
1106990286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
1107090286Sobrien	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1107190286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
1107290286Sobrien   (clobber (reg:CC 17))]
1107390286Sobrien  "TARGET_PARTIAL_REG_STALL
1107490286Sobrien   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
1107590286Sobrien{
1107690286Sobrien  switch (get_attr_type (insn))
1107790286Sobrien    {
1107890286Sobrien    case TYPE_ALU:
1107990286Sobrien      if (operands[2] != const1_rtx)
1108090286Sobrien	abort ();
1108190286Sobrien      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
1108290286Sobrien        return "add{l}\t{%k0, %k0|%k0, %k0}";
1108390286Sobrien      else
1108490286Sobrien        return "add{b}\t{%0, %0|%0, %0}";
1108552296Sobrien
1108690286Sobrien    default:
1108790286Sobrien      if (REG_P (operands[2]))
1108890286Sobrien	{
1108990286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1109090286Sobrien	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
1109190286Sobrien	  else
1109290286Sobrien	    return "sal{b}\t{%b2, %0|%0, %b2}";
1109390286Sobrien	}
1109490286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1109590286Sobrien	       && INTVAL (operands[2]) == 1
1109690286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1109790286Sobrien	{
1109890286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1109990286Sobrien	    return "sal{l}\t%0";
1110090286Sobrien	  else
1110190286Sobrien	    return "sal{b}\t%0";
1110290286Sobrien	}
1110390286Sobrien      else
1110490286Sobrien	{
1110590286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1110690286Sobrien	    return "sal{l}\t{%2, %k0|%k0, %2}";
1110790286Sobrien	  else
1110890286Sobrien	    return "sal{b}\t{%2, %0|%0, %2}";
1110990286Sobrien	}
1111090286Sobrien    }
1111190286Sobrien}
1111290286Sobrien  [(set (attr "type")
1111390286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1111490286Sobrien		          (const_int 0))
1111590286Sobrien		      (match_operand 0 "register_operand" ""))
1111690286Sobrien		 (match_operand 2 "const1_operand" ""))
1111790286Sobrien	      (const_string "alu")
1111890286Sobrien	   ]
1111990286Sobrien	   (const_string "ishift")))
1112090286Sobrien   (set_attr "mode" "QI,SI")])
1112118334Speter
1112290286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1112390286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1112490286Sobrien;; zero are optimized away.
1112590286Sobrien(define_insn "*ashlqi3_cmp"
1112690286Sobrien  [(set (reg 17)
1112790286Sobrien	(compare
1112890286Sobrien	  (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1112990286Sobrien		     (match_operand:QI 2 "immediate_operand" "I"))
1113090286Sobrien	  (const_int 0)))
1113190286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1113290286Sobrien	(ashift:QI (match_dup 1) (match_dup 2)))]
1113390286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1113490286Sobrien   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
1113590286Sobrien{
1113690286Sobrien  switch (get_attr_type (insn))
1113790286Sobrien    {
1113890286Sobrien    case TYPE_ALU:
1113990286Sobrien      if (operands[2] != const1_rtx)
1114090286Sobrien	abort ();
1114190286Sobrien      return "add{b}\t{%0, %0|%0, %0}";
1114218334Speter
1114390286Sobrien    default:
1114490286Sobrien      if (REG_P (operands[2]))
1114590286Sobrien	return "sal{b}\t{%b2, %0|%0, %b2}";
1114690286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1114790286Sobrien	       && INTVAL (operands[2]) == 1
1114890286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1114990286Sobrien	return "sal{b}\t%0";
1115090286Sobrien      else
1115190286Sobrien	return "sal{b}\t{%2, %0|%0, %2}";
1115290286Sobrien    }
1115390286Sobrien}
1115490286Sobrien  [(set (attr "type")
1115590286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1115690286Sobrien		          (const_int 0))
1115790286Sobrien		      (match_operand 0 "register_operand" ""))
1115890286Sobrien		 (match_operand 2 "const1_operand" ""))
1115990286Sobrien	      (const_string "alu")
1116090286Sobrien	   ]
1116190286Sobrien	   (const_string "ishift")))
1116290286Sobrien   (set_attr "mode" "QI")])
1116318334Speter
1116418334Speter;; See comment above `ashldi3' about how this works.
1116518334Speter
1116618334Speter(define_expand "ashrdi3"
1116790286Sobrien  [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
1116890286Sobrien		   (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
1116990286Sobrien				(match_operand:QI 2 "nonmemory_operand" "")))
1117090286Sobrien	      (clobber (reg:CC 17))])]
1117118334Speter  ""
1117218334Speter{
1117390286Sobrien  if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
1117418334Speter    {
1117590286Sobrien      emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
1117690286Sobrien      DONE;
1117718334Speter    }
1117890286Sobrien  ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
1117918334Speter  DONE;
1118090286Sobrien})
1118118334Speter
1118290286Sobrien(define_insn "ashrdi3_63_rex64"
1118390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
1118490286Sobrien	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
1118590286Sobrien		     (match_operand:DI 2 "const_int_operand" "i,i")))
1118690286Sobrien   (clobber (reg:CC 17))]
1118790286Sobrien  "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
1118890286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
1118990286Sobrien  "@
1119090286Sobrien   {cqto|cqo}
1119190286Sobrien   sar{q}\t{%2, %0|%0, %2}"
1119290286Sobrien  [(set_attr "type" "imovx,ishift")
1119390286Sobrien   (set_attr "prefix_0f" "0,*")
1119490286Sobrien   (set_attr "length_immediate" "0,*")
1119590286Sobrien   (set_attr "modrm" "0,1")
1119690286Sobrien   (set_attr "mode" "DI")])
1119750650Sobrien
1119890286Sobrien(define_insn "*ashrdi3_1_one_bit_rex64"
1119990286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1120090286Sobrien	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1120190286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1120290286Sobrien   (clobber (reg:CC 17))]
1120390286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
1120490286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1120590286Sobrien  "sar{q}\t%0"
1120690286Sobrien  [(set_attr "type" "ishift")
1120790286Sobrien   (set (attr "length") 
1120890286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1120990286Sobrien	(const_string "2")
1121090286Sobrien	(const_string "*")))])
1121150650Sobrien
1121290286Sobrien(define_insn "*ashrdi3_1_rex64"
1121390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
1121490286Sobrien	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
1121590286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
1121690286Sobrien   (clobber (reg:CC 17))]
1121790286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
1121890286Sobrien  "@
1121990286Sobrien   sar{q}\t{%2, %0|%0, %2}
1122090286Sobrien   sar{q}\t{%b2, %0|%0, %b2}"
1122190286Sobrien  [(set_attr "type" "ishift")
1122290286Sobrien   (set_attr "mode" "DI")])
1122350650Sobrien
1122490286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1122590286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1122690286Sobrien;; zero are optimized away.
1122790286Sobrien(define_insn "*ashrdi3_one_bit_cmp_rex64"
1122890286Sobrien  [(set (reg 17)
1122990286Sobrien	(compare
1123090286Sobrien	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1123190286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1123290286Sobrien	  (const_int 0)))
1123390286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1123490286Sobrien	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
1123590286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1123690286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1123790286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
1123890286Sobrien  "sar{q}\t%0"
1123990286Sobrien  [(set_attr "type" "ishift")
1124090286Sobrien   (set (attr "length") 
1124190286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1124290286Sobrien	(const_string "2")
1124390286Sobrien	(const_string "*")))])
1124450650Sobrien
1124590286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1124690286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1124790286Sobrien;; zero are optimized away.
1124890286Sobrien(define_insn "*ashrdi3_cmp_rex64"
1124990286Sobrien  [(set (reg 17)
1125090286Sobrien	(compare
1125190286Sobrien	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1125290286Sobrien		       (match_operand:QI 2 "const_int_operand" "n"))
1125390286Sobrien	  (const_int 0)))
1125490286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1125590286Sobrien	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
1125690286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1125790286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
1125890286Sobrien  "sar{q}\t{%2, %0|%0, %2}"
1125990286Sobrien  [(set_attr "type" "ishift")
1126090286Sobrien   (set_attr "mode" "DI")])
1126118334Speter
1126218334Speter
1126390286Sobrien(define_insn "ashrdi3_1"
1126490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1126590286Sobrien	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
1126690286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
1126790286Sobrien   (clobber (match_scratch:SI 3 "=&r"))
1126890286Sobrien   (clobber (reg:CC 17))]
1126990286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1127090286Sobrien  "#"
1127190286Sobrien  [(set_attr "type" "multi")])
1127218334Speter
1127390286Sobrien(define_insn "*ashrdi3_2"
1127490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1127590286Sobrien	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
1127690286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
1127790286Sobrien   (clobber (reg:CC 17))]
1127890286Sobrien  "!TARGET_64BIT"
1127990286Sobrien  "#"
1128090286Sobrien  [(set_attr "type" "multi")])
1128118334Speter
1128290286Sobrien(define_split
1128390286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1128490286Sobrien	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
1128590286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1128690286Sobrien   (clobber (match_scratch:SI 3 ""))
1128790286Sobrien   (clobber (reg:CC 17))]
1128890286Sobrien  "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
1128990286Sobrien  [(const_int 0)]
1129090286Sobrien  "ix86_split_ashrdi (operands, operands[3]); DONE;")
1129118334Speter
1129290286Sobrien(define_split
1129390286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1129490286Sobrien	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
1129590286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1129690286Sobrien   (clobber (reg:CC 17))]
1129790286Sobrien  "!TARGET_64BIT && reload_completed"
1129890286Sobrien  [(const_int 0)]
1129990286Sobrien  "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
1130018334Speter
1130190286Sobrien(define_insn "x86_shrd_1"
1130290286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
1130390286Sobrien        (ior:SI (ashiftrt:SI (match_dup 0)
1130490286Sobrien		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
1130590286Sobrien		(ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1130690286Sobrien		  (minus:QI (const_int 32) (match_dup 2)))))
1130790286Sobrien   (clobber (reg:CC 17))]
1130818334Speter  ""
1130990286Sobrien  "@
1131090286Sobrien   shrd{l}\t{%2, %1, %0|%0, %1, %2}
1131190286Sobrien   shrd{l}\t{%s2%1, %0|%0, %1, %2}"
1131290286Sobrien  [(set_attr "type" "ishift")
1131390286Sobrien   (set_attr "prefix_0f" "1")
1131490286Sobrien   (set_attr "pent_pair" "np")
1131590286Sobrien   (set_attr "ppro_uops" "few")
1131690286Sobrien   (set_attr "mode" "SI")])
1131790286Sobrien
1131890286Sobrien(define_expand "x86_shift_adj_3"
1131990286Sobrien  [(use (match_operand:SI 0 "register_operand" ""))
1132090286Sobrien   (use (match_operand:SI 1 "register_operand" ""))
1132190286Sobrien   (use (match_operand:QI 2 "register_operand" ""))]
1132290286Sobrien  ""
1132318334Speter{
1132490286Sobrien  rtx label = gen_label_rtx ();
1132590286Sobrien  rtx tmp;
1132618334Speter
1132790286Sobrien  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
1132818334Speter
1132990286Sobrien  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
1133090286Sobrien  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1133190286Sobrien  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
1133290286Sobrien			      gen_rtx_LABEL_REF (VOIDmode, label),
1133390286Sobrien			      pc_rtx);
1133490286Sobrien  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
1133590286Sobrien  JUMP_LABEL (tmp) = label;
1133618334Speter
1133790286Sobrien  emit_move_insn (operands[0], operands[1]);
1133890286Sobrien  emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
1133918334Speter
1134090286Sobrien  emit_label (label);
1134190286Sobrien  LABEL_NUSES (label) = 1;
1134290286Sobrien
1134390286Sobrien  DONE;
1134490286Sobrien})
1134590286Sobrien
1134652296Sobrien(define_insn "ashrsi3_31"
1134790286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
1134890286Sobrien	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
1134990286Sobrien		     (match_operand:SI 2 "const_int_operand" "i,i")))
1135090286Sobrien   (clobber (reg:CC 17))]
1135190286Sobrien  "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
1135290286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1135352296Sobrien  "@
1135490286Sobrien   {cltd|cdq}
1135590286Sobrien   sar{l}\t{%2, %0|%0, %2}"
1135690286Sobrien  [(set_attr "type" "imovx,ishift")
1135790286Sobrien   (set_attr "prefix_0f" "0,*")
1135890286Sobrien   (set_attr "length_immediate" "0,*")
1135990286Sobrien   (set_attr "modrm" "0,1")
1136090286Sobrien   (set_attr "mode" "SI")])
1136152296Sobrien
1136290286Sobrien(define_insn "*ashrsi3_31_zext"
1136390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=*d,r")
1136490286Sobrien	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
1136590286Sobrien				     (match_operand:SI 2 "const_int_operand" "i,i"))))
1136690286Sobrien   (clobber (reg:CC 17))]
1136790286Sobrien  "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
1136890286Sobrien   && INTVAL (operands[2]) == 31
1136990286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1137090286Sobrien  "@
1137190286Sobrien   {cltd|cdq}
1137290286Sobrien   sar{l}\t{%2, %k0|%k0, %2}"
1137390286Sobrien  [(set_attr "type" "imovx,ishift")
1137490286Sobrien   (set_attr "prefix_0f" "0,*")
1137590286Sobrien   (set_attr "length_immediate" "0,*")
1137690286Sobrien   (set_attr "modrm" "0,1")
1137790286Sobrien   (set_attr "mode" "SI")])
1137890286Sobrien
1137990286Sobrien(define_expand "ashrsi3"
1138090286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1138190286Sobrien	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
1138290286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1138390286Sobrien   (clobber (reg:CC 17))]
1138490286Sobrien  ""
1138590286Sobrien  "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
1138690286Sobrien
1138790286Sobrien(define_insn "*ashrsi3_1_one_bit"
1138850650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1138950650Sobrien	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1139090286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1139190286Sobrien   (clobber (reg:CC 17))]
1139290286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
1139390286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1139490286Sobrien  "sar{l}\t%0"
1139590286Sobrien  [(set_attr "type" "ishift")
1139690286Sobrien   (set (attr "length") 
1139790286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1139890286Sobrien	(const_string "2")
1139990286Sobrien	(const_string "*")))])
1140018334Speter
1140190286Sobrien(define_insn "*ashrsi3_1_one_bit_zext"
1140290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1140390286Sobrien	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
1140490286Sobrien				     (match_operand:QI 2 "const_int_1_operand" ""))))
1140590286Sobrien   (clobber (reg:CC 17))]
1140690286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
1140790286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1140890286Sobrien  "sar{l}\t%k0"
1140990286Sobrien  [(set_attr "type" "ishift")
1141090286Sobrien   (set_attr "length" "2")])
1141190286Sobrien
1141290286Sobrien(define_insn "*ashrsi3_1"
1141390286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1141490286Sobrien	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1141590286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1141690286Sobrien   (clobber (reg:CC 17))]
1141790286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1141890286Sobrien  "@
1141990286Sobrien   sar{l}\t{%2, %0|%0, %2}
1142090286Sobrien   sar{l}\t{%b2, %0|%0, %b2}"
1142190286Sobrien  [(set_attr "type" "ishift")
1142290286Sobrien   (set_attr "mode" "SI")])
1142390286Sobrien
1142490286Sobrien(define_insn "*ashrsi3_1_zext"
1142590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1142690286Sobrien	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
1142790286Sobrien				     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
1142890286Sobrien   (clobber (reg:CC 17))]
1142990286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1143090286Sobrien  "@
1143190286Sobrien   sar{l}\t{%2, %k0|%k0, %2}
1143290286Sobrien   sar{l}\t{%b2, %k0|%k0, %b2}"
1143390286Sobrien  [(set_attr "type" "ishift")
1143490286Sobrien   (set_attr "mode" "SI")])
1143590286Sobrien
1143690286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1143790286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1143890286Sobrien;; zero are optimized away.
1143990286Sobrien(define_insn "*ashrsi3_one_bit_cmp"
1144090286Sobrien  [(set (reg 17)
1144190286Sobrien	(compare
1144290286Sobrien	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1144390286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1144490286Sobrien	  (const_int 0)))
1144590286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1144690286Sobrien	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
1144790286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1144890286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1144990286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1145090286Sobrien  "sar{l}\t%0"
1145190286Sobrien  [(set_attr "type" "ishift")
1145290286Sobrien   (set (attr "length") 
1145390286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1145490286Sobrien	(const_string "2")
1145590286Sobrien	(const_string "*")))])
1145690286Sobrien
1145790286Sobrien(define_insn "*ashrsi3_one_bit_cmp_zext"
1145890286Sobrien  [(set (reg 17)
1145990286Sobrien	(compare
1146090286Sobrien	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
1146190286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1146290286Sobrien	  (const_int 0)))
1146390286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1146490286Sobrien	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
1146590286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
1146690286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1146790286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1146890286Sobrien  "sar{l}\t%k0"
1146990286Sobrien  [(set_attr "type" "ishift")
1147090286Sobrien   (set_attr "length" "2")])
1147190286Sobrien
1147290286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1147390286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1147490286Sobrien;; zero are optimized away.
1147590286Sobrien(define_insn "*ashrsi3_cmp"
1147690286Sobrien  [(set (reg 17)
1147790286Sobrien	(compare
1147890286Sobrien	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1147990286Sobrien		       (match_operand:QI 2 "immediate_operand" "I"))
1148090286Sobrien	  (const_int 0)))
1148190286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1148290286Sobrien	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
1148390286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1148490286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1148590286Sobrien  "sar{l}\t{%2, %0|%0, %2}"
1148690286Sobrien  [(set_attr "type" "ishift")
1148790286Sobrien   (set_attr "mode" "SI")])
1148890286Sobrien
1148990286Sobrien(define_insn "*ashrsi3_cmp_zext"
1149090286Sobrien  [(set (reg 17)
1149190286Sobrien	(compare
1149290286Sobrien	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
1149390286Sobrien		       (match_operand:QI 2 "immediate_operand" "I"))
1149490286Sobrien	  (const_int 0)))
1149590286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1149690286Sobrien	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
1149790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1149890286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1149990286Sobrien  "sar{l}\t{%2, %k0|%k0, %2}"
1150090286Sobrien  [(set_attr "type" "ishift")
1150190286Sobrien   (set_attr "mode" "SI")])
1150290286Sobrien
1150390286Sobrien(define_expand "ashrhi3"
1150490286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1150590286Sobrien	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
1150690286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1150790286Sobrien   (clobber (reg:CC 17))]
1150890286Sobrien  "TARGET_HIMODE_MATH"
1150990286Sobrien  "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
1151090286Sobrien
1151190286Sobrien(define_insn "*ashrhi3_1_one_bit"
1151250650Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1151350650Sobrien	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1151490286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1151590286Sobrien   (clobber (reg:CC 17))]
1151690286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
1151790286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1151890286Sobrien  "sar{w}\t%0"
1151990286Sobrien  [(set_attr "type" "ishift")
1152090286Sobrien   (set (attr "length") 
1152190286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1152290286Sobrien	(const_string "2")
1152390286Sobrien	(const_string "*")))])
1152418334Speter
1152590286Sobrien(define_insn "*ashrhi3_1"
1152690286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
1152790286Sobrien	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
1152890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1152990286Sobrien   (clobber (reg:CC 17))]
1153090286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
1153190286Sobrien  "@
1153290286Sobrien   sar{w}\t{%2, %0|%0, %2}
1153390286Sobrien   sar{w}\t{%b2, %0|%0, %b2}"
1153490286Sobrien  [(set_attr "type" "ishift")
1153590286Sobrien   (set_attr "mode" "HI")])
1153690286Sobrien
1153790286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1153890286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1153990286Sobrien;; zero are optimized away.
1154090286Sobrien(define_insn "*ashrhi3_one_bit_cmp"
1154190286Sobrien  [(set (reg 17)
1154290286Sobrien	(compare
1154390286Sobrien	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1154490286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1154590286Sobrien	  (const_int 0)))
1154690286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1154790286Sobrien	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
1154890286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1154990286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1155090286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
1155190286Sobrien  "sar{w}\t%0"
1155290286Sobrien  [(set_attr "type" "ishift")
1155390286Sobrien   (set (attr "length") 
1155490286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1155590286Sobrien	(const_string "2")
1155690286Sobrien	(const_string "*")))])
1155790286Sobrien
1155890286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1155990286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1156090286Sobrien;; zero are optimized away.
1156190286Sobrien(define_insn "*ashrhi3_cmp"
1156290286Sobrien  [(set (reg 17)
1156390286Sobrien	(compare
1156490286Sobrien	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1156590286Sobrien		       (match_operand:QI 2 "immediate_operand" "I"))
1156690286Sobrien	  (const_int 0)))
1156790286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1156890286Sobrien	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
1156990286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1157090286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
1157190286Sobrien  "sar{w}\t{%2, %0|%0, %2}"
1157290286Sobrien  [(set_attr "type" "ishift")
1157390286Sobrien   (set_attr "mode" "HI")])
1157490286Sobrien
1157590286Sobrien(define_expand "ashrqi3"
1157690286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1157790286Sobrien	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
1157890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1157990286Sobrien   (clobber (reg:CC 17))]
1158090286Sobrien  "TARGET_QIMODE_MATH"
1158190286Sobrien  "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
1158290286Sobrien
1158390286Sobrien(define_insn "*ashrqi3_1_one_bit"
1158450650Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1158550650Sobrien	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1158690286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1158790286Sobrien   (clobber (reg:CC 17))]
1158890286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
1158990286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1159090286Sobrien  "sar{b}\t%0"
1159190286Sobrien  [(set_attr "type" "ishift")
1159290286Sobrien   (set (attr "length") 
1159390286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1159490286Sobrien	(const_string "2")
1159590286Sobrien	(const_string "*")))])
1159690286Sobrien
1159790286Sobrien(define_insn "*ashrqi3_1"
1159890286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
1159990286Sobrien	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1160090286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1160190286Sobrien   (clobber (reg:CC 17))]
1160290286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
1160390286Sobrien  "@
1160490286Sobrien   sar{b}\t{%2, %0|%0, %2}
1160590286Sobrien   sar{b}\t{%b2, %0|%0, %b2}"
1160690286Sobrien  [(set_attr "type" "ishift")
1160790286Sobrien   (set_attr "mode" "QI")])
1160890286Sobrien
1160990286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1161090286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1161190286Sobrien;; zero are optimized away.
1161290286Sobrien(define_insn "*ashrqi3_one_bit_cmp"
1161390286Sobrien  [(set (reg 17)
1161490286Sobrien	(compare
1161590286Sobrien	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1161690286Sobrien		       (match_operand:QI 2 "const_int_1_operand" "I"))
1161790286Sobrien	  (const_int 0)))
1161890286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1161990286Sobrien	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
1162090286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1162190286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1162290286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
1162390286Sobrien  "sar{b}\t%0"
1162490286Sobrien  [(set_attr "type" "ishift")
1162590286Sobrien   (set (attr "length") 
1162690286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1162790286Sobrien	(const_string "2")
1162890286Sobrien	(const_string "*")))])
1162990286Sobrien
1163090286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1163190286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1163290286Sobrien;; zero are optimized away.
1163390286Sobrien(define_insn "*ashrqi3_cmp"
1163490286Sobrien  [(set (reg 17)
1163590286Sobrien	(compare
1163690286Sobrien	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1163790286Sobrien		       (match_operand:QI 2 "immediate_operand" "I"))
1163890286Sobrien	  (const_int 0)))
1163990286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=rm")
1164090286Sobrien	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
1164190286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1164290286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
1164390286Sobrien  "sar{b}\t{%2, %0|%0, %2}"
1164490286Sobrien  [(set_attr "type" "ishift")
1164590286Sobrien   (set_attr "mode" "QI")])
1164618334Speter
1164790286Sobrien;; Logical shift instructions
1164818334Speter
1164918334Speter;; See comment above `ashldi3' about how this works.
1165018334Speter
1165118334Speter(define_expand "lshrdi3"
1165290286Sobrien  [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
1165390286Sobrien		   (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
1165490286Sobrien			        (match_operand:QI 2 "nonmemory_operand" "")))
1165590286Sobrien	      (clobber (reg:CC 17))])]
1165618334Speter  ""
1165718334Speter{
1165890286Sobrien  if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
1165918334Speter    {
1166090286Sobrien      emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
1166190286Sobrien      DONE;
1166218334Speter    }
1166390286Sobrien  ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
1166418334Speter  DONE;
1166590286Sobrien})
1166618334Speter
1166790286Sobrien(define_insn "*lshrdi3_1_one_bit_rex64"
1166890286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1166990286Sobrien	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1167090286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1167190286Sobrien   (clobber (reg:CC 17))]
1167290286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
1167390286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1167490286Sobrien  "shr{q}\t%0"
1167590286Sobrien  [(set_attr "type" "ishift")
1167690286Sobrien   (set (attr "length") 
1167790286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1167890286Sobrien	(const_string "2")
1167990286Sobrien	(const_string "*")))])
1168050650Sobrien
1168190286Sobrien(define_insn "*lshrdi3_1_rex64"
1168290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
1168390286Sobrien	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
1168490286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
1168590286Sobrien   (clobber (reg:CC 17))]
1168690286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1168790286Sobrien  "@
1168890286Sobrien   shr{q}\t{%2, %0|%0, %2}
1168990286Sobrien   shr{q}\t{%b2, %0|%0, %b2}"
1169090286Sobrien  [(set_attr "type" "ishift")
1169190286Sobrien   (set_attr "mode" "DI")])
1169250650Sobrien
1169390286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1169490286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1169590286Sobrien;; zero are optimized away.
1169690286Sobrien(define_insn "*lshrdi3_cmp_one_bit_rex64"
1169790286Sobrien  [(set (reg 17)
1169890286Sobrien	(compare
1169990286Sobrien	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1170090286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1170190286Sobrien	  (const_int 0)))
1170290286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1170390286Sobrien	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
1170490286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1170590286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1170690286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1170790286Sobrien  "shr{q}\t%0"
1170890286Sobrien  [(set_attr "type" "ishift")
1170990286Sobrien   (set (attr "length") 
1171090286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1171190286Sobrien	(const_string "2")
1171290286Sobrien	(const_string "*")))])
1171350650Sobrien
1171490286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1171590286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1171690286Sobrien;; zero are optimized away.
1171790286Sobrien(define_insn "*lshrdi3_cmp_rex64"
1171890286Sobrien  [(set (reg 17)
1171990286Sobrien	(compare
1172090286Sobrien	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1172190286Sobrien		       (match_operand:QI 2 "const_int_operand" "e"))
1172290286Sobrien	  (const_int 0)))
1172390286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1172490286Sobrien	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
1172590286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1172690286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1172790286Sobrien  "shr{q}\t{%2, %0|%0, %2}"
1172890286Sobrien  [(set_attr "type" "ishift")
1172990286Sobrien   (set_attr "mode" "DI")])
1173050650Sobrien
1173190286Sobrien(define_insn "lshrdi3_1"
1173290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1173318334Speter	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
1173490286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
1173590286Sobrien   (clobber (match_scratch:SI 3 "=&r"))
1173690286Sobrien   (clobber (reg:CC 17))]
1173790286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1173890286Sobrien  "#"
1173990286Sobrien  [(set_attr "type" "multi")])
1174018334Speter
1174190286Sobrien(define_insn "*lshrdi3_2"
1174290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1174390286Sobrien	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
1174490286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
1174590286Sobrien   (clobber (reg:CC 17))]
1174690286Sobrien  "!TARGET_64BIT"
1174790286Sobrien  "#"
1174890286Sobrien  [(set_attr "type" "multi")])
1174918334Speter
1175090286Sobrien(define_split 
1175190286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1175290286Sobrien	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
1175390286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1175490286Sobrien   (clobber (match_scratch:SI 3 ""))
1175590286Sobrien   (clobber (reg:CC 17))]
1175690286Sobrien  "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
1175790286Sobrien  [(const_int 0)]
1175890286Sobrien  "ix86_split_lshrdi (operands, operands[3]); DONE;")
1175918334Speter
1176090286Sobrien(define_split 
1176190286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1176290286Sobrien	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
1176390286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1176490286Sobrien   (clobber (reg:CC 17))]
1176590286Sobrien  "!TARGET_64BIT && reload_completed"
1176690286Sobrien  [(const_int 0)]
1176790286Sobrien  "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
1176818334Speter
1176990286Sobrien(define_expand "lshrsi3"
1177090286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1177190286Sobrien	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
1177290286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1177390286Sobrien   (clobber (reg:CC 17))]
1177490286Sobrien  ""
1177590286Sobrien  "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
1177618334Speter
1177790286Sobrien(define_insn "*lshrsi3_1_one_bit"
1177890286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1177990286Sobrien	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1178090286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1178190286Sobrien   (clobber (reg:CC 17))]
1178290286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
1178390286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1178490286Sobrien  "shr{l}\t%0"
1178590286Sobrien  [(set_attr "type" "ishift")
1178690286Sobrien   (set (attr "length") 
1178790286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1178890286Sobrien	(const_string "2")
1178990286Sobrien	(const_string "*")))])
1179018334Speter
1179190286Sobrien(define_insn "*lshrsi3_1_one_bit_zext"
1179290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1179390286Sobrien	(lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
1179490286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1179590286Sobrien   (clobber (reg:CC 17))]
1179690286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
1179790286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1179890286Sobrien  "shr{l}\t%k0"
1179990286Sobrien  [(set_attr "type" "ishift")
1180090286Sobrien   (set_attr "length" "2")])
1180118334Speter
1180290286Sobrien(define_insn "*lshrsi3_1"
1180390286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1180490286Sobrien	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1180590286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1180690286Sobrien   (clobber (reg:CC 17))]
1180790286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1180890286Sobrien  "@
1180990286Sobrien   shr{l}\t{%2, %0|%0, %2}
1181090286Sobrien   shr{l}\t{%b2, %0|%0, %b2}"
1181190286Sobrien  [(set_attr "type" "ishift")
1181290286Sobrien   (set_attr "mode" "SI")])
1181318334Speter
1181490286Sobrien(define_insn "*lshrsi3_1_zext"
1181590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1181690286Sobrien	(zero_extend:DI
1181790286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1181890286Sobrien		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
1181990286Sobrien   (clobber (reg:CC 17))]
1182090286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1182190286Sobrien  "@
1182290286Sobrien   shr{l}\t{%2, %k0|%k0, %2}
1182390286Sobrien   shr{l}\t{%b2, %k0|%k0, %b2}"
1182490286Sobrien  [(set_attr "type" "ishift")
1182590286Sobrien   (set_attr "mode" "SI")])
1182618334Speter
1182790286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1182890286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1182990286Sobrien;; zero are optimized away.
1183090286Sobrien(define_insn "*lshrsi3_one_bit_cmp"
1183190286Sobrien  [(set (reg 17)
1183290286Sobrien	(compare
1183390286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1183490286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1183590286Sobrien	  (const_int 0)))
1183690286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1183790286Sobrien	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
1183890286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1183990286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1184090286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1184190286Sobrien  "shr{l}\t%0"
1184290286Sobrien  [(set_attr "type" "ishift")
1184390286Sobrien   (set (attr "length") 
1184490286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1184590286Sobrien	(const_string "2")
1184690286Sobrien	(const_string "*")))])
1184718334Speter
1184890286Sobrien(define_insn "*lshrsi3_cmp_one_bit_zext"
1184990286Sobrien  [(set (reg 17)
1185090286Sobrien	(compare
1185190286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
1185290286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1185390286Sobrien	  (const_int 0)))
1185490286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1185590286Sobrien	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
1185690286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1185790286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1185890286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1185990286Sobrien  "shr{l}\t%k0"
1186090286Sobrien  [(set_attr "type" "ishift")
1186190286Sobrien   (set_attr "length" "2")])
1186218334Speter
1186390286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1186490286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1186590286Sobrien;; zero are optimized away.
1186690286Sobrien(define_insn "*lshrsi3_cmp"
1186790286Sobrien  [(set (reg 17)
1186890286Sobrien	(compare
1186990286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1187090286Sobrien		       (match_operand:QI 2 "immediate_operand" "I"))
1187190286Sobrien	  (const_int 0)))
1187290286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1187390286Sobrien	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
1187490286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1187590286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1187690286Sobrien  "shr{l}\t{%2, %0|%0, %2}"
1187790286Sobrien  [(set_attr "type" "ishift")
1187890286Sobrien   (set_attr "mode" "SI")])
1187990286Sobrien
1188090286Sobrien(define_insn "*lshrsi3_cmp_zext"
1188190286Sobrien  [(set (reg 17)
1188290286Sobrien	(compare
1188390286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
1188490286Sobrien		       (match_operand:QI 2 "immediate_operand" "I"))
1188590286Sobrien	  (const_int 0)))
1188690286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1188790286Sobrien	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
1188890286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1188990286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1189090286Sobrien  "shr{l}\t{%2, %k0|%k0, %2}"
1189190286Sobrien  [(set_attr "type" "ishift")
1189290286Sobrien   (set_attr "mode" "SI")])
1189390286Sobrien
1189490286Sobrien(define_expand "lshrhi3"
1189590286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1189690286Sobrien	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
1189790286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1189890286Sobrien   (clobber (reg:CC 17))]
1189990286Sobrien  "TARGET_HIMODE_MATH"
1190090286Sobrien  "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
1190190286Sobrien
1190290286Sobrien(define_insn "*lshrhi3_1_one_bit"
1190350650Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1190450650Sobrien	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1190590286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1190690286Sobrien   (clobber (reg:CC 17))]
1190790286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
1190890286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1190990286Sobrien  "shr{w}\t%0"
1191090286Sobrien  [(set_attr "type" "ishift")
1191190286Sobrien   (set (attr "length") 
1191290286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1191390286Sobrien	(const_string "2")
1191490286Sobrien	(const_string "*")))])
1191518334Speter
1191690286Sobrien(define_insn "*lshrhi3_1"
1191790286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
1191890286Sobrien	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
1191990286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1192090286Sobrien   (clobber (reg:CC 17))]
1192190286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1192290286Sobrien  "@
1192390286Sobrien   shr{w}\t{%2, %0|%0, %2}
1192490286Sobrien   shr{w}\t{%b2, %0|%0, %b2}"
1192590286Sobrien  [(set_attr "type" "ishift")
1192690286Sobrien   (set_attr "mode" "HI")])
1192790286Sobrien
1192890286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1192990286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1193090286Sobrien;; zero are optimized away.
1193190286Sobrien(define_insn "*lshrhi3_one_bit_cmp"
1193290286Sobrien  [(set (reg 17)
1193390286Sobrien	(compare
1193490286Sobrien	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1193590286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1193690286Sobrien	  (const_int 0)))
1193790286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1193890286Sobrien	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
1193990286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1194090286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1194190286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1194290286Sobrien  "shr{w}\t%0"
1194390286Sobrien  [(set_attr "type" "ishift")
1194490286Sobrien   (set (attr "length") 
1194590286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1194690286Sobrien	(const_string "2")
1194790286Sobrien	(const_string "*")))])
1194890286Sobrien
1194990286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1195090286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1195190286Sobrien;; zero are optimized away.
1195290286Sobrien(define_insn "*lshrhi3_cmp"
1195390286Sobrien  [(set (reg 17)
1195490286Sobrien	(compare
1195590286Sobrien	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1195690286Sobrien		       (match_operand:QI 2 "immediate_operand" "I"))
1195790286Sobrien	  (const_int 0)))
1195890286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1195990286Sobrien	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
1196090286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1196190286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1196290286Sobrien  "shr{w}\t{%2, %0|%0, %2}"
1196390286Sobrien  [(set_attr "type" "ishift")
1196490286Sobrien   (set_attr "mode" "HI")])
1196590286Sobrien
1196690286Sobrien(define_expand "lshrqi3"
1196790286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1196890286Sobrien	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
1196990286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1197090286Sobrien   (clobber (reg:CC 17))]
1197190286Sobrien  "TARGET_QIMODE_MATH"
1197290286Sobrien  "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
1197390286Sobrien
1197490286Sobrien(define_insn "*lshrqi3_1_one_bit"
1197550650Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1197650650Sobrien	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1197790286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1197890286Sobrien   (clobber (reg:CC 17))]
1197990286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
1198090286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1198190286Sobrien  "shr{b}\t%0"
1198290286Sobrien  [(set_attr "type" "ishift")
1198390286Sobrien   (set (attr "length") 
1198490286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1198590286Sobrien	(const_string "2")
1198690286Sobrien	(const_string "*")))])
1198790286Sobrien
1198890286Sobrien(define_insn "*lshrqi3_1"
1198990286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
1199090286Sobrien	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1199190286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1199290286Sobrien   (clobber (reg:CC 17))]
1199390286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
1199490286Sobrien  "@
1199590286Sobrien   shr{b}\t{%2, %0|%0, %2}
1199690286Sobrien   shr{b}\t{%b2, %0|%0, %b2}"
1199790286Sobrien  [(set_attr "type" "ishift")
1199890286Sobrien   (set_attr "mode" "QI")])
1199990286Sobrien
1200090286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1200190286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1200290286Sobrien;; zero are optimized away.
1200390286Sobrien(define_insn "*lshrqi2_one_bit_cmp"
1200490286Sobrien  [(set (reg 17)
1200590286Sobrien	(compare
1200690286Sobrien	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1200790286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1200890286Sobrien	  (const_int 0)))
1200990286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1201090286Sobrien	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
1201190286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1201290286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1201390286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
1201490286Sobrien  "shr{b}\t%0"
1201590286Sobrien  [(set_attr "type" "ishift")
1201690286Sobrien   (set (attr "length") 
1201790286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1201890286Sobrien	(const_string "2")
1201990286Sobrien	(const_string "*")))])
1202090286Sobrien
1202190286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1202290286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1202390286Sobrien;; zero are optimized away.
1202490286Sobrien(define_insn "*lshrqi2_cmp"
1202590286Sobrien  [(set (reg 17)
1202690286Sobrien	(compare
1202790286Sobrien	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1202890286Sobrien		       (match_operand:QI 2 "immediate_operand" "I"))
1202990286Sobrien	  (const_int 0)))
1203090286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1203190286Sobrien	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
1203290286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1203390286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
1203490286Sobrien  "shr{b}\t{%2, %0|%0, %2}"
1203590286Sobrien  [(set_attr "type" "ishift")
1203690286Sobrien   (set_attr "mode" "QI")])
1203718334Speter
1203890286Sobrien;; Rotate instructions
1203918334Speter
1204090286Sobrien(define_expand "rotldi3"
1204190286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1204290286Sobrien	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
1204390286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1204490286Sobrien   (clobber (reg:CC 17))]
1204590286Sobrien  "TARGET_64BIT"
1204690286Sobrien  "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
1204718334Speter
1204890286Sobrien(define_insn "*rotlsi3_1_one_bit_rex64"
1204990286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1205090286Sobrien	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1205190286Sobrien		   (match_operand:QI 2 "const_int_1_operand" "")))
1205290286Sobrien   (clobber (reg:CC 17))]
1205390286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
1205490286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1205590286Sobrien  "rol{q}\t%0"
1205690286Sobrien  [(set_attr "type" "ishift")
1205790286Sobrien   (set (attr "length") 
1205890286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1205990286Sobrien	(const_string "2")
1206090286Sobrien	(const_string "*")))])
1206118334Speter
1206290286Sobrien(define_insn "*rotldi3_1_rex64"
1206390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
1206490286Sobrien	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
1206590286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "e,c")))
1206690286Sobrien   (clobber (reg:CC 17))]
1206790286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
1206890286Sobrien  "@
1206990286Sobrien   rol{q}\t{%2, %0|%0, %2}
1207090286Sobrien   rol{q}\t{%b2, %0|%0, %b2}"
1207190286Sobrien  [(set_attr "type" "ishift")
1207290286Sobrien   (set_attr "mode" "DI")])
1207390286Sobrien
1207490286Sobrien(define_expand "rotlsi3"
1207590286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1207690286Sobrien	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
1207790286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1207890286Sobrien   (clobber (reg:CC 17))]
1207918334Speter  ""
1208090286Sobrien  "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
1208118334Speter
1208290286Sobrien(define_insn "*rotlsi3_1_one_bit"
1208350650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1208490286Sobrien	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1208590286Sobrien		   (match_operand:QI 2 "const_int_1_operand" "")))
1208690286Sobrien   (clobber (reg:CC 17))]
1208790286Sobrien  "ix86_binary_operator_ok (ROTATE, SImode, operands)
1208890286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1208990286Sobrien  "rol{l}\t%0"
1209090286Sobrien  [(set_attr "type" "ishift")
1209190286Sobrien   (set (attr "length") 
1209290286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1209390286Sobrien	(const_string "2")
1209490286Sobrien	(const_string "*")))])
1209518334Speter
1209690286Sobrien(define_insn "*rotlsi3_1_one_bit_zext"
1209790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1209890286Sobrien	(zero_extend:DI
1209990286Sobrien	  (rotate:SI (match_operand:SI 1 "register_operand" "0")
1210090286Sobrien		     (match_operand:QI 2 "const_int_1_operand" ""))))
1210190286Sobrien   (clobber (reg:CC 17))]
1210290286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
1210390286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1210490286Sobrien  "rol{l}\t%k0"
1210590286Sobrien  [(set_attr "type" "ishift")
1210690286Sobrien   (set_attr "length" "2")])
1210718334Speter
1210890286Sobrien(define_insn "*rotlsi3_1"
1210990286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1211090286Sobrien	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1211190286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
1211290286Sobrien   (clobber (reg:CC 17))]
1211390286Sobrien  "ix86_binary_operator_ok (ROTATE, SImode, operands)"
1211490286Sobrien  "@
1211590286Sobrien   rol{l}\t{%2, %0|%0, %2}
1211690286Sobrien   rol{l}\t{%b2, %0|%0, %b2}"
1211790286Sobrien  [(set_attr "type" "ishift")
1211890286Sobrien   (set_attr "mode" "SI")])
1211918334Speter
1212090286Sobrien(define_insn "*rotlsi3_1_zext"
1212190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1212290286Sobrien	(zero_extend:DI
1212390286Sobrien	  (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
1212490286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
1212590286Sobrien   (clobber (reg:CC 17))]
1212690286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
1212790286Sobrien  "@
1212890286Sobrien   rol{l}\t{%2, %k0|%k0, %2}
1212990286Sobrien   rol{l}\t{%b2, %k0|%k0, %b2}"
1213090286Sobrien  [(set_attr "type" "ishift")
1213190286Sobrien   (set_attr "mode" "SI")])
1213218334Speter
1213390286Sobrien(define_expand "rotlhi3"
1213490286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1213590286Sobrien	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
1213690286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1213790286Sobrien   (clobber (reg:CC 17))]
1213890286Sobrien  "TARGET_HIMODE_MATH"
1213990286Sobrien  "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
1214018334Speter
1214190286Sobrien(define_insn "*rotlhi3_1_one_bit"
1214290286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1214390286Sobrien	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1214490286Sobrien		   (match_operand:QI 2 "const_int_1_operand" "")))
1214590286Sobrien   (clobber (reg:CC 17))]
1214690286Sobrien  "ix86_binary_operator_ok (ROTATE, HImode, operands)
1214790286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1214890286Sobrien  "rol{w}\t%0"
1214990286Sobrien  [(set_attr "type" "ishift")
1215090286Sobrien   (set (attr "length") 
1215190286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1215290286Sobrien	(const_string "2")
1215390286Sobrien	(const_string "*")))])
1215418334Speter
1215590286Sobrien(define_insn "*rotlhi3_1"
1215690286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
1215790286Sobrien	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
1215890286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
1215990286Sobrien   (clobber (reg:CC 17))]
1216090286Sobrien  "ix86_binary_operator_ok (ROTATE, HImode, operands)"
1216190286Sobrien  "@
1216290286Sobrien   rol{w}\t{%2, %0|%0, %2}
1216390286Sobrien   rol{w}\t{%b2, %0|%0, %b2}"
1216490286Sobrien  [(set_attr "type" "ishift")
1216590286Sobrien   (set_attr "mode" "HI")])
1216618334Speter
1216790286Sobrien(define_expand "rotlqi3"
1216890286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1216990286Sobrien	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
1217090286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1217190286Sobrien   (clobber (reg:CC 17))]
1217290286Sobrien  "TARGET_QIMODE_MATH"
1217390286Sobrien  "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
1217418334Speter
1217590286Sobrien(define_insn "*rotlqi3_1_one_bit"
1217690286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1217790286Sobrien	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1217890286Sobrien		   (match_operand:QI 2 "const_int_1_operand" "")))
1217990286Sobrien   (clobber (reg:CC 17))]
1218090286Sobrien  "ix86_binary_operator_ok (ROTATE, QImode, operands)
1218190286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1218290286Sobrien  "rol{b}\t%0"
1218390286Sobrien  [(set_attr "type" "ishift")
1218490286Sobrien   (set (attr "length") 
1218590286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1218690286Sobrien	(const_string "2")
1218790286Sobrien	(const_string "*")))])
1218818334Speter
1218990286Sobrien(define_insn "*rotlqi3_1"
1219090286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
1219190286Sobrien	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1219290286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
1219390286Sobrien   (clobber (reg:CC 17))]
1219490286Sobrien  "ix86_binary_operator_ok (ROTATE, QImode, operands)"
1219590286Sobrien  "@
1219690286Sobrien   rol{b}\t{%2, %0|%0, %2}
1219790286Sobrien   rol{b}\t{%b2, %0|%0, %b2}"
1219890286Sobrien  [(set_attr "type" "ishift")
1219990286Sobrien   (set_attr "mode" "QI")])
1220018334Speter
1220190286Sobrien(define_expand "rotrdi3"
1220290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1220390286Sobrien	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
1220490286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1220590286Sobrien   (clobber (reg:CC 17))]
1220690286Sobrien  "TARGET_64BIT"
1220790286Sobrien  "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
1220818334Speter
1220990286Sobrien(define_insn "*rotrdi3_1_one_bit_rex64"
1221090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1221190286Sobrien	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1221290286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1221390286Sobrien   (clobber (reg:CC 17))]
1221490286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
1221590286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1221690286Sobrien  "ror{q}\t%0"
1221790286Sobrien  [(set_attr "type" "ishift")
1221890286Sobrien   (set (attr "length") 
1221990286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1222090286Sobrien	(const_string "2")
1222190286Sobrien	(const_string "*")))])
1222218334Speter
1222390286Sobrien(define_insn "*rotrdi3_1_rex64"
1222490286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
1222590286Sobrien	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
1222690286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
1222790286Sobrien   (clobber (reg:CC 17))]
1222890286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
1222990286Sobrien  "@
1223090286Sobrien   ror{q}\t{%2, %0|%0, %2}
1223190286Sobrien   ror{q}\t{%b2, %0|%0, %b2}"
1223290286Sobrien  [(set_attr "type" "ishift")
1223390286Sobrien   (set_attr "mode" "DI")])
1223490286Sobrien
1223590286Sobrien(define_expand "rotrsi3"
1223690286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1223790286Sobrien	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
1223890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1223990286Sobrien   (clobber (reg:CC 17))]
1224090286Sobrien  ""
1224190286Sobrien  "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
1224290286Sobrien
1224390286Sobrien(define_insn "*rotrsi3_1_one_bit"
1224450650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1224590286Sobrien	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1224690286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1224790286Sobrien   (clobber (reg:CC 17))]
1224890286Sobrien  "ix86_binary_operator_ok (ROTATERT, SImode, operands)
1224990286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1225090286Sobrien  "ror{l}\t%0"
1225190286Sobrien  [(set_attr "type" "ishift")
1225290286Sobrien   (set (attr "length") 
1225390286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1225490286Sobrien	(const_string "2")
1225590286Sobrien	(const_string "*")))])
1225618334Speter
1225790286Sobrien(define_insn "*rotrsi3_1_one_bit_zext"
1225890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1225990286Sobrien	(zero_extend:DI
1226090286Sobrien	  (rotatert:SI (match_operand:SI 1 "register_operand" "0")
1226190286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))))
1226290286Sobrien   (clobber (reg:CC 17))]
1226390286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
1226490286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1226590286Sobrien  "ror{l}\t%k0"
1226690286Sobrien  [(set_attr "type" "ishift")
1226790286Sobrien   (set (attr "length") 
1226890286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1226990286Sobrien	(const_string "2")
1227090286Sobrien	(const_string "*")))])
1227118334Speter
1227290286Sobrien(define_insn "*rotrsi3_1"
1227390286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1227490286Sobrien	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1227590286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1227690286Sobrien   (clobber (reg:CC 17))]
1227790286Sobrien  "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
1227890286Sobrien  "@
1227990286Sobrien   ror{l}\t{%2, %0|%0, %2}
1228090286Sobrien   ror{l}\t{%b2, %0|%0, %b2}"
1228190286Sobrien  [(set_attr "type" "ishift")
1228290286Sobrien   (set_attr "mode" "SI")])
1228318334Speter
1228490286Sobrien(define_insn "*rotrsi3_1_zext"
1228590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1228690286Sobrien	(zero_extend:DI
1228790286Sobrien	  (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
1228890286Sobrien		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
1228990286Sobrien   (clobber (reg:CC 17))]
1229090286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
1229190286Sobrien  "@
1229290286Sobrien   ror{l}\t{%2, %k0|%k0, %2}
1229390286Sobrien   ror{l}\t{%b2, %k0|%k0, %b2}"
1229490286Sobrien  [(set_attr "type" "ishift")
1229590286Sobrien   (set_attr "mode" "SI")])
1229618334Speter
1229790286Sobrien(define_expand "rotrhi3"
1229890286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1229990286Sobrien	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
1230090286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1230190286Sobrien   (clobber (reg:CC 17))]
1230290286Sobrien  "TARGET_HIMODE_MATH"
1230390286Sobrien  "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
1230418334Speter
1230590286Sobrien(define_insn "*rotrhi3_one_bit"
1230690286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1230790286Sobrien	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1230890286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1230990286Sobrien   (clobber (reg:CC 17))]
1231090286Sobrien  "ix86_binary_operator_ok (ROTATERT, HImode, operands)
1231190286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1231290286Sobrien  "ror{w}\t%0"
1231390286Sobrien  [(set_attr "type" "ishift")
1231490286Sobrien   (set (attr "length") 
1231590286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1231690286Sobrien	(const_string "2")
1231790286Sobrien	(const_string "*")))])
1231818334Speter
1231990286Sobrien(define_insn "*rotrhi3"
1232090286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
1232190286Sobrien	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
1232290286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1232390286Sobrien   (clobber (reg:CC 17))]
1232490286Sobrien  "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
1232590286Sobrien  "@
1232690286Sobrien   ror{w}\t{%2, %0|%0, %2}
1232790286Sobrien   ror{w}\t{%b2, %0|%0, %b2}"
1232890286Sobrien  [(set_attr "type" "ishift")
1232990286Sobrien   (set_attr "mode" "HI")])
1233018334Speter
1233190286Sobrien(define_expand "rotrqi3"
1233290286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1233390286Sobrien	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
1233490286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1233590286Sobrien   (clobber (reg:CC 17))]
1233690286Sobrien  "TARGET_QIMODE_MATH"
1233790286Sobrien  "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
1233818334Speter
1233990286Sobrien(define_insn "*rotrqi3_1_one_bit"
1234090286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1234190286Sobrien	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1234290286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1234390286Sobrien   (clobber (reg:CC 17))]
1234490286Sobrien  "ix86_binary_operator_ok (ROTATERT, QImode, operands)
1234590286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1234690286Sobrien  "ror{b}\t%0"
1234790286Sobrien  [(set_attr "type" "ishift")
1234890286Sobrien   (set (attr "length") 
1234990286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1235090286Sobrien	(const_string "2")
1235190286Sobrien	(const_string "*")))])
1235218334Speter
1235390286Sobrien(define_insn "*rotrqi3_1"
1235490286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
1235590286Sobrien	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1235690286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1235790286Sobrien   (clobber (reg:CC 17))]
1235890286Sobrien  "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
1235990286Sobrien  "@
1236090286Sobrien   ror{b}\t{%2, %0|%0, %2}
1236190286Sobrien   ror{b}\t{%b2, %0|%0, %b2}"
1236290286Sobrien  [(set_attr "type" "ishift")
1236390286Sobrien   (set_attr "mode" "QI")])
1236490286Sobrien
1236590286Sobrien;; Bit set / bit test instructions
1236618334Speter
1236790286Sobrien(define_expand "extv"
1236890286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1236990286Sobrien	(sign_extract:SI (match_operand:SI 1 "register_operand" "")
1237090286Sobrien			 (match_operand:SI 2 "immediate_operand" "")
1237190286Sobrien			 (match_operand:SI 3 "immediate_operand" "")))]
1237290286Sobrien  ""
1237318334Speter{
1237490286Sobrien  /* Handle extractions from %ah et al.  */
1237590286Sobrien  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
1237690286Sobrien    FAIL;
1237718334Speter
1237890286Sobrien  /* From mips.md: extract_bit_field doesn't verify that our source
1237990286Sobrien     matches the predicate, so check it again here.  */
1238090286Sobrien  if (! register_operand (operands[1], VOIDmode))
1238190286Sobrien    FAIL;
1238290286Sobrien})
1238318334Speter
1238490286Sobrien(define_expand "extzv"
1238590286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1238690286Sobrien	(zero_extract:SI (match_operand 1 "ext_register_operand" "")
1238790286Sobrien			 (match_operand:SI 2 "immediate_operand" "")
1238890286Sobrien			 (match_operand:SI 3 "immediate_operand" "")))]
1238990286Sobrien  ""
1239090286Sobrien{
1239190286Sobrien  /* Handle extractions from %ah et al.  */
1239290286Sobrien  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
1239390286Sobrien    FAIL;
1239418334Speter
1239590286Sobrien  /* From mips.md: extract_bit_field doesn't verify that our source
1239690286Sobrien     matches the predicate, so check it again here.  */
1239790286Sobrien  if (! register_operand (operands[1], VOIDmode))
1239890286Sobrien    FAIL;
1239990286Sobrien})
1240018334Speter
1240190286Sobrien(define_expand "insv"
1240290286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
1240390286Sobrien			 (match_operand:SI 1 "immediate_operand" "")
1240490286Sobrien			 (match_operand:SI 2 "immediate_operand" ""))
1240590286Sobrien        (match_operand:SI 3 "register_operand" ""))]
1240690286Sobrien  ""
1240790286Sobrien{
1240890286Sobrien  /* Handle extractions from %ah et al.  */
1240990286Sobrien  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
1241090286Sobrien    FAIL;
1241118334Speter
1241290286Sobrien  /* From mips.md: insert_bit_field doesn't verify that our source
1241390286Sobrien     matches the predicate, so check it again here.  */
1241490286Sobrien  if (! register_operand (operands[0], VOIDmode))
1241590286Sobrien    FAIL;
1241690286Sobrien})
1241718334Speter
1241890286Sobrien;; %%% bts, btr, btc, bt.
1241918334Speter
1242018334Speter;; Store-flag instructions.
1242118334Speter
1242218334Speter;; For all sCOND expanders, also expand the compare or test insn that
1242318334Speter;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
1242418334Speter
1242590286Sobrien;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
1242690286Sobrien;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
1242790286Sobrien;; way, which can later delete the movzx if only QImode is needed.
1242890286Sobrien
1242918334Speter(define_expand "seq"
1243090286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1243190286Sobrien        (eq:QI (reg:CC 17) (const_int 0)))]
1243218334Speter  ""
1243390286Sobrien  "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
1243418334Speter
1243518334Speter(define_expand "sne"
1243690286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1243790286Sobrien        (ne:QI (reg:CC 17) (const_int 0)))]
1243818334Speter  ""
1243990286Sobrien  "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
1244018334Speter
1244118334Speter(define_expand "sgt"
1244290286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1244390286Sobrien        (gt:QI (reg:CC 17) (const_int 0)))]
1244418334Speter  ""
1244590286Sobrien  "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
1244618334Speter
1244718334Speter(define_expand "sgtu"
1244890286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1244990286Sobrien        (gtu:QI (reg:CC 17) (const_int 0)))]
1245018334Speter  ""
1245190286Sobrien  "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
1245218334Speter
1245318334Speter(define_expand "slt"
1245490286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1245590286Sobrien        (lt:QI (reg:CC 17) (const_int 0)))]
1245618334Speter  ""
1245790286Sobrien  "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
1245818334Speter
1245918334Speter(define_expand "sltu"
1246090286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1246190286Sobrien        (ltu:QI (reg:CC 17) (const_int 0)))]
1246218334Speter  ""
1246390286Sobrien  "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
1246418334Speter
1246518334Speter(define_expand "sge"
1246690286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1246790286Sobrien        (ge:QI (reg:CC 17) (const_int 0)))]
1246818334Speter  ""
1246990286Sobrien  "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
1247018334Speter
1247118334Speter(define_expand "sgeu"
1247290286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1247390286Sobrien        (geu:QI (reg:CC 17) (const_int 0)))]
1247418334Speter  ""
1247590286Sobrien  "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
1247618334Speter
1247718334Speter(define_expand "sle"
1247890286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1247990286Sobrien        (le:QI (reg:CC 17) (const_int 0)))]
1248018334Speter  ""
1248190286Sobrien  "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
1248218334Speter
1248318334Speter(define_expand "sleu"
1248490286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1248590286Sobrien        (leu:QI (reg:CC 17) (const_int 0)))]
1248618334Speter  ""
1248790286Sobrien  "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
1248818334Speter
1248990286Sobrien(define_expand "sunordered"
1249090286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1249190286Sobrien        (unordered:QI (reg:CC 17) (const_int 0)))]
1249290286Sobrien  "TARGET_80387 || TARGET_SSE"
1249390286Sobrien  "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
1249452296Sobrien
1249590286Sobrien(define_expand "sordered"
1249690286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1249790286Sobrien        (ordered:QI (reg:CC 17) (const_int 0)))]
1249890286Sobrien  "TARGET_80387"
1249990286Sobrien  "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
1250090286Sobrien
1250190286Sobrien(define_expand "suneq"
1250290286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1250390286Sobrien        (uneq:QI (reg:CC 17) (const_int 0)))]
1250490286Sobrien  "TARGET_80387 || TARGET_SSE"
1250590286Sobrien  "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
1250690286Sobrien
1250790286Sobrien(define_expand "sunge"
1250890286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1250990286Sobrien        (unge:QI (reg:CC 17) (const_int 0)))]
1251090286Sobrien  "TARGET_80387 || TARGET_SSE"
1251190286Sobrien  "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
1251290286Sobrien
1251390286Sobrien(define_expand "sungt"
1251490286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1251590286Sobrien        (ungt:QI (reg:CC 17) (const_int 0)))]
1251690286Sobrien  "TARGET_80387 || TARGET_SSE"
1251790286Sobrien  "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
1251890286Sobrien
1251990286Sobrien(define_expand "sunle"
1252090286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1252190286Sobrien        (unle:QI (reg:CC 17) (const_int 0)))]
1252290286Sobrien  "TARGET_80387 || TARGET_SSE"
1252390286Sobrien  "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
1252490286Sobrien
1252590286Sobrien(define_expand "sunlt"
1252690286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1252790286Sobrien        (unlt:QI (reg:CC 17) (const_int 0)))]
1252890286Sobrien  "TARGET_80387 || TARGET_SSE"
1252990286Sobrien  "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
1253090286Sobrien
1253190286Sobrien(define_expand "sltgt"
1253290286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1253390286Sobrien        (ltgt:QI (reg:CC 17) (const_int 0)))]
1253490286Sobrien  "TARGET_80387 || TARGET_SSE"
1253590286Sobrien  "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
1253690286Sobrien
1253790286Sobrien(define_insn "*setcc_1"
1253852296Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1253990286Sobrien	(match_operator:QI 1 "ix86_comparison_operator"
1254090286Sobrien	  [(reg 17) (const_int 0)]))]
1254190286Sobrien  ""
1254290286Sobrien  "set%C1\t%0"
1254390286Sobrien  [(set_attr "type" "setcc")
1254490286Sobrien   (set_attr "mode" "QI")])
1254590286Sobrien
1254690286Sobrien(define_insn "setcc_2"
1254790286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
1254890286Sobrien	(match_operator:QI 1 "ix86_comparison_operator"
1254990286Sobrien	  [(reg 17) (const_int 0)]))]
1255090286Sobrien  ""
1255190286Sobrien  "set%C1\t%0"
1255290286Sobrien  [(set_attr "type" "setcc")
1255390286Sobrien   (set_attr "mode" "QI")])
1255490286Sobrien
1255590286Sobrien;; In general it is not safe to assume too much about CCmode registers,
1255690286Sobrien;; so simplify-rtx stops when it sees a second one.  Under certain 
1255790286Sobrien;; conditions this is safe on x86, so help combine not create
1255890286Sobrien;;
1255990286Sobrien;;	seta	%al
1256090286Sobrien;;	testb	%al, %al
1256190286Sobrien;;	sete	%al
1256290286Sobrien
1256390286Sobrien(define_split 
1256490286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1256590286Sobrien	(ne:QI (match_operator 1 "ix86_comparison_operator"
1256690286Sobrien	         [(reg 17) (const_int 0)])
1256790286Sobrien	    (const_int 0)))]
1256890286Sobrien  ""
1256990286Sobrien  [(set (match_dup 0) (match_dup 1))]
1257052296Sobrien{
1257190286Sobrien  PUT_MODE (operands[1], QImode);
1257290286Sobrien})
1257352296Sobrien
1257490286Sobrien(define_split 
1257590286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1257690286Sobrien	(ne:QI (match_operator 1 "ix86_comparison_operator"
1257790286Sobrien	         [(reg 17) (const_int 0)])
1257890286Sobrien	    (const_int 0)))]
1257990286Sobrien  ""
1258090286Sobrien  [(set (match_dup 0) (match_dup 1))]
1258190286Sobrien{
1258290286Sobrien  PUT_MODE (operands[1], QImode);
1258390286Sobrien})
1258452296Sobrien
1258590286Sobrien(define_split 
1258690286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1258790286Sobrien	(eq:QI (match_operator 1 "ix86_comparison_operator"
1258890286Sobrien	         [(reg 17) (const_int 0)])
1258990286Sobrien	    (const_int 0)))]
1259090286Sobrien  ""
1259190286Sobrien  [(set (match_dup 0) (match_dup 1))]
1259290286Sobrien{
1259390286Sobrien  rtx new_op1 = copy_rtx (operands[1]);
1259490286Sobrien  operands[1] = new_op1;
1259590286Sobrien  PUT_MODE (new_op1, QImode);
1259690286Sobrien  PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
1259790286Sobrien					GET_MODE (XEXP (new_op1, 0))));
1259890286Sobrien
1259990286Sobrien  /* Make sure that (a) the CCmode we have for the flags is strong
1260090286Sobrien     enough for the reversed compare or (b) we have a valid FP compare.  */
1260190286Sobrien  if (! ix86_comparison_operator (new_op1, VOIDmode))
1260290286Sobrien    FAIL;
1260390286Sobrien})
1260490286Sobrien
1260590286Sobrien(define_split 
1260690286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1260790286Sobrien	(eq:QI (match_operator 1 "ix86_comparison_operator"
1260890286Sobrien	         [(reg 17) (const_int 0)])
1260990286Sobrien	    (const_int 0)))]
1261090286Sobrien  ""
1261190286Sobrien  [(set (match_dup 0) (match_dup 1))]
1261290286Sobrien{
1261390286Sobrien  rtx new_op1 = copy_rtx (operands[1]);
1261490286Sobrien  operands[1] = new_op1;
1261590286Sobrien  PUT_MODE (new_op1, QImode);
1261690286Sobrien  PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
1261790286Sobrien					GET_MODE (XEXP (new_op1, 0))));
1261890286Sobrien
1261990286Sobrien  /* Make sure that (a) the CCmode we have for the flags is strong
1262090286Sobrien     enough for the reversed compare or (b) we have a valid FP compare.  */
1262190286Sobrien  if (! ix86_comparison_operator (new_op1, VOIDmode))
1262290286Sobrien    FAIL;
1262390286Sobrien})
1262490286Sobrien
1262590286Sobrien;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
1262690286Sobrien;; subsequent logical operations are used to imitate conditional moves.
1262790286Sobrien;; 0xffffffff is NaN, but not in normalized form, so we can't represent
1262890286Sobrien;; it directly.  Futher holding this value in pseudo register might bring
1262990286Sobrien;; problem in implicit normalization in spill code.
1263090286Sobrien;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
1263190286Sobrien;; instructions after reload by splitting the conditional move patterns.
1263290286Sobrien
1263390286Sobrien(define_insn "*sse_setccsf"
1263490286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1263590286Sobrien	(match_operator:SF 1 "sse_comparison_operator"
1263690286Sobrien	  [(match_operand:SF 2 "register_operand" "0")
1263790286Sobrien	   (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
1263890286Sobrien  "TARGET_SSE && reload_completed"
1263990286Sobrien  "cmp%D1ss\t{%3, %0|%0, %3}"
1264090286Sobrien  [(set_attr "type" "sse")
1264190286Sobrien   (set_attr "mode" "SF")])
1264290286Sobrien
1264390286Sobrien(define_insn "*sse_setccdf"
1264490286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1264590286Sobrien	(match_operator:DF 1 "sse_comparison_operator"
1264690286Sobrien	  [(match_operand:DF 2 "register_operand" "0")
1264790286Sobrien	   (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
1264890286Sobrien  "TARGET_SSE2 && reload_completed"
1264990286Sobrien  "cmp%D1sd\t{%3, %0|%0, %3}"
1265090286Sobrien  [(set_attr "type" "sse")
1265190286Sobrien   (set_attr "mode" "DF")])
1265218334Speter
1265318334Speter;; Basic conditional jump instructions.
1265418334Speter;; We ignore the overflow flag for signed branch instructions.
1265518334Speter
1265618334Speter;; For all bCOND expanders, also expand the compare or test insn that
1265790286Sobrien;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
1265818334Speter
1265918334Speter(define_expand "beq"
1266090286Sobrien  [(set (pc)
1266190286Sobrien	(if_then_else (match_dup 1)
1266218334Speter		      (label_ref (match_operand 0 "" ""))
1266318334Speter		      (pc)))]
1266418334Speter  ""
1266590286Sobrien  "ix86_expand_branch (EQ, operands[0]); DONE;")
1266618334Speter
1266718334Speter(define_expand "bne"
1266890286Sobrien  [(set (pc)
1266990286Sobrien	(if_then_else (match_dup 1)
1267018334Speter		      (label_ref (match_operand 0 "" ""))
1267118334Speter		      (pc)))]
1267218334Speter  ""
1267390286Sobrien  "ix86_expand_branch (NE, operands[0]); DONE;")
1267418334Speter
1267518334Speter(define_expand "bgt"
1267690286Sobrien  [(set (pc)
1267790286Sobrien	(if_then_else (match_dup 1)
1267818334Speter		      (label_ref (match_operand 0 "" ""))
1267918334Speter		      (pc)))]
1268018334Speter  ""
1268190286Sobrien  "ix86_expand_branch (GT, operands[0]); DONE;")
1268218334Speter
1268318334Speter(define_expand "bgtu"
1268490286Sobrien  [(set (pc)
1268590286Sobrien	(if_then_else (match_dup 1)
1268618334Speter		      (label_ref (match_operand 0 "" ""))
1268718334Speter		      (pc)))]
1268818334Speter  ""
1268990286Sobrien  "ix86_expand_branch (GTU, operands[0]); DONE;")
1269018334Speter
1269118334Speter(define_expand "blt"
1269290286Sobrien  [(set (pc)
1269390286Sobrien	(if_then_else (match_dup 1)
1269418334Speter		      (label_ref (match_operand 0 "" ""))
1269518334Speter		      (pc)))]
1269618334Speter  ""
1269790286Sobrien  "ix86_expand_branch (LT, operands[0]); DONE;")
1269818334Speter
1269918334Speter(define_expand "bltu"
1270090286Sobrien  [(set (pc)
1270190286Sobrien	(if_then_else (match_dup 1)
1270218334Speter		      (label_ref (match_operand 0 "" ""))
1270318334Speter		      (pc)))]
1270418334Speter  ""
1270590286Sobrien  "ix86_expand_branch (LTU, operands[0]); DONE;")
1270618334Speter
1270718334Speter(define_expand "bge"
1270890286Sobrien  [(set (pc)
1270990286Sobrien	(if_then_else (match_dup 1)
1271018334Speter		      (label_ref (match_operand 0 "" ""))
1271118334Speter		      (pc)))]
1271218334Speter  ""
1271390286Sobrien  "ix86_expand_branch (GE, operands[0]); DONE;")
1271418334Speter
1271518334Speter(define_expand "bgeu"
1271690286Sobrien  [(set (pc)
1271790286Sobrien	(if_then_else (match_dup 1)
1271818334Speter		      (label_ref (match_operand 0 "" ""))
1271918334Speter		      (pc)))]
1272018334Speter  ""
1272190286Sobrien  "ix86_expand_branch (GEU, operands[0]); DONE;")
1272218334Speter
1272318334Speter(define_expand "ble"
1272490286Sobrien  [(set (pc)
1272590286Sobrien	(if_then_else (match_dup 1)
1272618334Speter		      (label_ref (match_operand 0 "" ""))
1272718334Speter		      (pc)))]
1272818334Speter  ""
1272990286Sobrien  "ix86_expand_branch (LE, operands[0]); DONE;")
1273018334Speter
1273118334Speter(define_expand "bleu"
1273290286Sobrien  [(set (pc)
1273390286Sobrien	(if_then_else (match_dup 1)
1273418334Speter		      (label_ref (match_operand 0 "" ""))
1273518334Speter		      (pc)))]
1273618334Speter  ""
1273790286Sobrien  "ix86_expand_branch (LEU, operands[0]); DONE;")
1273818334Speter
1273990286Sobrien(define_expand "bunordered"
1274018334Speter  [(set (pc)
1274190286Sobrien	(if_then_else (match_dup 1)
1274290286Sobrien		      (label_ref (match_operand 0 "" ""))
1274318334Speter		      (pc)))]
1274490286Sobrien  "TARGET_80387 || TARGET_SSE"
1274590286Sobrien  "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
1274618334Speter
1274790286Sobrien(define_expand "bordered"
1274890286Sobrien  [(set (pc)
1274990286Sobrien	(if_then_else (match_dup 1)
1275090286Sobrien		      (label_ref (match_operand 0 "" ""))
1275190286Sobrien		      (pc)))]
1275290286Sobrien  "TARGET_80387 || TARGET_SSE"
1275390286Sobrien  "ix86_expand_branch (ORDERED, operands[0]); DONE;")
1275418334Speter
1275590286Sobrien(define_expand "buneq"
1275618334Speter  [(set (pc)
1275790286Sobrien	(if_then_else (match_dup 1)
1275890286Sobrien		      (label_ref (match_operand 0 "" ""))
1275990286Sobrien		      (pc)))]
1276090286Sobrien  "TARGET_80387 || TARGET_SSE"
1276190286Sobrien  "ix86_expand_branch (UNEQ, operands[0]); DONE;")
1276218334Speter
1276390286Sobrien(define_expand "bunge"
1276490286Sobrien  [(set (pc)
1276590286Sobrien	(if_then_else (match_dup 1)
1276690286Sobrien		      (label_ref (match_operand 0 "" ""))
1276790286Sobrien		      (pc)))]
1276890286Sobrien  "TARGET_80387 || TARGET_SSE"
1276990286Sobrien  "ix86_expand_branch (UNGE, operands[0]); DONE;")
1277018334Speter
1277190286Sobrien(define_expand "bungt"
1277218334Speter  [(set (pc)
1277390286Sobrien	(if_then_else (match_dup 1)
1277490286Sobrien		      (label_ref (match_operand 0 "" ""))
1277590286Sobrien		      (pc)))]
1277690286Sobrien  "TARGET_80387 || TARGET_SSE"
1277790286Sobrien  "ix86_expand_branch (UNGT, operands[0]); DONE;")
1277818334Speter
1277990286Sobrien(define_expand "bunle"
1278090286Sobrien  [(set (pc)
1278190286Sobrien	(if_then_else (match_dup 1)
1278290286Sobrien		      (label_ref (match_operand 0 "" ""))
1278390286Sobrien		      (pc)))]
1278490286Sobrien  "TARGET_80387 || TARGET_SSE"
1278590286Sobrien  "ix86_expand_branch (UNLE, operands[0]); DONE;")
1278618334Speter
1278790286Sobrien(define_expand "bunlt"
1278890286Sobrien  [(set (pc)
1278990286Sobrien	(if_then_else (match_dup 1)
1279090286Sobrien		      (label_ref (match_operand 0 "" ""))
1279190286Sobrien		      (pc)))]
1279290286Sobrien  "TARGET_80387 || TARGET_SSE"
1279390286Sobrien  "ix86_expand_branch (UNLT, operands[0]); DONE;")
1279418334Speter
1279590286Sobrien(define_expand "bltgt"
1279690286Sobrien  [(set (pc)
1279790286Sobrien	(if_then_else (match_dup 1)
1279890286Sobrien		      (label_ref (match_operand 0 "" ""))
1279990286Sobrien		      (pc)))]
1280090286Sobrien  "TARGET_80387 || TARGET_SSE"
1280190286Sobrien  "ix86_expand_branch (LTGT, operands[0]); DONE;")
1280218334Speter
1280390286Sobrien(define_insn "*jcc_1"
1280490286Sobrien  [(set (pc)
1280590286Sobrien	(if_then_else (match_operator 1 "ix86_comparison_operator"
1280690286Sobrien				      [(reg 17) (const_int 0)])
1280790286Sobrien		      (label_ref (match_operand 0 "" ""))
1280890286Sobrien		      (pc)))]
1280918334Speter  ""
1281090286Sobrien  "%+j%C1\t%l0"
1281190286Sobrien  [(set_attr "type" "ibr")
1281290286Sobrien   (set (attr "prefix_0f")
1281390286Sobrien	   (if_then_else (and (ge (minus (match_dup 0) (pc))
1281490286Sobrien				  (const_int -128))
1281590286Sobrien			      (lt (minus (match_dup 0) (pc))
1281690286Sobrien				  (const_int 124)))
1281790286Sobrien	     (const_int 0)
1281890286Sobrien	     (const_int 1)))])
1281918334Speter
1282090286Sobrien(define_insn "*jcc_2"
1282118334Speter  [(set (pc)
1282290286Sobrien	(if_then_else (match_operator 1 "ix86_comparison_operator"
1282390286Sobrien				      [(reg 17) (const_int 0)])
1282490286Sobrien		      (pc)
1282590286Sobrien		      (label_ref (match_operand 0 "" ""))))]
1282618334Speter  ""
1282790286Sobrien  "%+j%c1\t%l0"
1282890286Sobrien  [(set_attr "type" "ibr")
1282990286Sobrien   (set (attr "prefix_0f")
1283090286Sobrien	   (if_then_else (and (ge (minus (match_dup 0) (pc))
1283190286Sobrien				  (const_int -128))
1283290286Sobrien			      (lt (minus (match_dup 0) (pc))
1283390286Sobrien				  (const_int 124)))
1283490286Sobrien	     (const_int 0)
1283590286Sobrien	     (const_int 1)))])
1283690286Sobrien
1283790286Sobrien;; In general it is not safe to assume too much about CCmode registers,
1283890286Sobrien;; so simplify-rtx stops when it sees a second one.  Under certain 
1283990286Sobrien;; conditions this is safe on x86, so help combine not create
1284090286Sobrien;;
1284190286Sobrien;;	seta	%al
1284290286Sobrien;;	testb	%al, %al
1284390286Sobrien;;	je	Lfoo
1284490286Sobrien
1284590286Sobrien(define_split 
1284690286Sobrien  [(set (pc)
1284790286Sobrien	(if_then_else (ne (match_operator 0 "ix86_comparison_operator"
1284890286Sobrien				      [(reg 17) (const_int 0)])
1284990286Sobrien			  (const_int 0))
1285090286Sobrien		      (label_ref (match_operand 1 "" ""))
1285190286Sobrien		      (pc)))]
1285290286Sobrien  ""
1285390286Sobrien  [(set (pc)
1285490286Sobrien	(if_then_else (match_dup 0)
1285590286Sobrien		      (label_ref (match_dup 1))
1285690286Sobrien		      (pc)))]
1285718334Speter{
1285890286Sobrien  PUT_MODE (operands[0], VOIDmode);
1285990286Sobrien})
1286090286Sobrien  
1286190286Sobrien(define_split 
1286290286Sobrien  [(set (pc)
1286390286Sobrien	(if_then_else (eq (match_operator 0 "ix86_comparison_operator"
1286490286Sobrien				      [(reg 17) (const_int 0)])
1286590286Sobrien			  (const_int 0))
1286690286Sobrien		      (label_ref (match_operand 1 "" ""))
1286790286Sobrien		      (pc)))]
1286890286Sobrien  ""
1286990286Sobrien  [(set (pc)
1287090286Sobrien	(if_then_else (match_dup 0)
1287190286Sobrien		      (label_ref (match_dup 1))
1287290286Sobrien		      (pc)))]
1287390286Sobrien{
1287490286Sobrien  rtx new_op0 = copy_rtx (operands[0]);
1287590286Sobrien  operands[0] = new_op0;
1287690286Sobrien  PUT_MODE (new_op0, VOIDmode);
1287790286Sobrien  PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
1287890286Sobrien					GET_MODE (XEXP (new_op0, 0))));
1287952296Sobrien
1288090286Sobrien  /* Make sure that (a) the CCmode we have for the flags is strong
1288190286Sobrien     enough for the reversed compare or (b) we have a valid FP compare.  */
1288290286Sobrien  if (! ix86_comparison_operator (new_op0, VOIDmode))
1288390286Sobrien    FAIL;
1288490286Sobrien})
1288552296Sobrien
1288690286Sobrien;; Define combination compare-and-branch fp compare instructions to use
1288790286Sobrien;; during early optimization.  Splitting the operation apart early makes
1288890286Sobrien;; for bad code when we want to reverse the operation.
1288918334Speter
1289090286Sobrien(define_insn "*fp_jcc_1"
1289190286Sobrien  [(set (pc)
1289290286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1289390286Sobrien			[(match_operand 1 "register_operand" "f")
1289490286Sobrien			 (match_operand 2 "register_operand" "f")])
1289590286Sobrien	  (label_ref (match_operand 3 "" ""))
1289690286Sobrien	  (pc)))
1289790286Sobrien   (clobber (reg:CCFP 18))
1289890286Sobrien   (clobber (reg:CCFP 17))]
1289990286Sobrien  "TARGET_CMOVE && TARGET_80387
1290090286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1290190286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
1290290286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1290390286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1290490286Sobrien  "#")
1290518334Speter
1290690286Sobrien(define_insn "*fp_jcc_1_sse"
1290790286Sobrien  [(set (pc)
1290890286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1290990286Sobrien			[(match_operand 1 "register_operand" "f#x,x#f")
1291090286Sobrien			 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
1291190286Sobrien	  (label_ref (match_operand 3 "" ""))
1291290286Sobrien	  (pc)))
1291390286Sobrien   (clobber (reg:CCFP 18))
1291490286Sobrien   (clobber (reg:CCFP 17))]
1291590286Sobrien  "TARGET_80387
1291690286Sobrien   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1291790286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1291890286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1291990286Sobrien  "#")
1292018334Speter
1292190286Sobrien(define_insn "*fp_jcc_1_sse_only"
1292290286Sobrien  [(set (pc)
1292390286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1292490286Sobrien			[(match_operand 1 "register_operand" "x")
1292590286Sobrien			 (match_operand 2 "nonimmediate_operand" "xm")])
1292690286Sobrien	  (label_ref (match_operand 3 "" ""))
1292790286Sobrien	  (pc)))
1292890286Sobrien   (clobber (reg:CCFP 18))
1292990286Sobrien   (clobber (reg:CCFP 17))]
1293090286Sobrien  "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1293190286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1293290286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1293390286Sobrien  "#")
1293418334Speter
1293590286Sobrien(define_insn "*fp_jcc_2"
1293618334Speter  [(set (pc)
1293790286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1293890286Sobrien			[(match_operand 1 "register_operand" "f")
1293990286Sobrien			 (match_operand 2 "register_operand" "f")])
1294090286Sobrien	  (pc)
1294190286Sobrien	  (label_ref (match_operand 3 "" ""))))
1294290286Sobrien   (clobber (reg:CCFP 18))
1294390286Sobrien   (clobber (reg:CCFP 17))]
1294490286Sobrien  "TARGET_CMOVE && TARGET_80387
1294590286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1294690286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
1294790286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1294890286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1294990286Sobrien  "#")
1295018334Speter
1295190286Sobrien(define_insn "*fp_jcc_2_sse"
1295290286Sobrien  [(set (pc)
1295390286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1295490286Sobrien			[(match_operand 1 "register_operand" "f#x,x#f")
1295590286Sobrien			 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
1295690286Sobrien	  (pc)
1295790286Sobrien	  (label_ref (match_operand 3 "" ""))))
1295890286Sobrien   (clobber (reg:CCFP 18))
1295990286Sobrien   (clobber (reg:CCFP 17))]
1296090286Sobrien  "TARGET_80387
1296190286Sobrien   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1296290286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1296390286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1296490286Sobrien  "#")
1296518334Speter
1296690286Sobrien(define_insn "*fp_jcc_2_sse_only"
1296790286Sobrien  [(set (pc)
1296890286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1296990286Sobrien			[(match_operand 1 "register_operand" "x")
1297090286Sobrien			 (match_operand 2 "nonimmediate_operand" "xm")])
1297190286Sobrien	  (pc)
1297290286Sobrien	  (label_ref (match_operand 3 "" ""))))
1297390286Sobrien   (clobber (reg:CCFP 18))
1297490286Sobrien   (clobber (reg:CCFP 17))]
1297590286Sobrien  "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1297690286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1297790286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1297890286Sobrien  "#")
1297918334Speter
1298090286Sobrien(define_insn "*fp_jcc_3"
1298190286Sobrien  [(set (pc)
1298290286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1298390286Sobrien			[(match_operand 1 "register_operand" "f")
1298490286Sobrien			 (match_operand 2 "nonimmediate_operand" "fm")])
1298590286Sobrien	  (label_ref (match_operand 3 "" ""))
1298690286Sobrien	  (pc)))
1298790286Sobrien   (clobber (reg:CCFP 18))
1298890286Sobrien   (clobber (reg:CCFP 17))
1298990286Sobrien   (clobber (match_scratch:HI 4 "=a"))]
1299090286Sobrien  "TARGET_80387
1299190286Sobrien   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
1299290286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1299390286Sobrien   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
1299490286Sobrien   && SELECT_CC_MODE (GET_CODE (operands[0]),
1299590286Sobrien		      operands[1], operands[2]) == CCFPmode
1299690286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1299790286Sobrien  "#")
1299818334Speter
1299990286Sobrien(define_insn "*fp_jcc_4"
1300050650Sobrien  [(set (pc)
1300190286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1300290286Sobrien			[(match_operand 1 "register_operand" "f")
1300390286Sobrien			 (match_operand 2 "nonimmediate_operand" "fm")])
1300490286Sobrien	  (pc)
1300590286Sobrien	  (label_ref (match_operand 3 "" ""))))
1300690286Sobrien   (clobber (reg:CCFP 18))
1300790286Sobrien   (clobber (reg:CCFP 17))
1300890286Sobrien   (clobber (match_scratch:HI 4 "=a"))]
1300990286Sobrien  "TARGET_80387
1301090286Sobrien   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
1301190286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1301290286Sobrien   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
1301390286Sobrien   && SELECT_CC_MODE (GET_CODE (operands[0]),
1301490286Sobrien		      operands[1], operands[2]) == CCFPmode
1301590286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1301690286Sobrien  "#")
1301750650Sobrien
1301890286Sobrien(define_insn "*fp_jcc_5"
1301950650Sobrien  [(set (pc)
1302090286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1302190286Sobrien			[(match_operand 1 "register_operand" "f")
1302290286Sobrien			 (match_operand 2 "register_operand" "f")])
1302390286Sobrien	  (label_ref (match_operand 3 "" ""))
1302490286Sobrien	  (pc)))
1302590286Sobrien   (clobber (reg:CCFP 18))
1302690286Sobrien   (clobber (reg:CCFP 17))
1302790286Sobrien   (clobber (match_scratch:HI 4 "=a"))]
1302890286Sobrien  "TARGET_80387
1302990286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
1303090286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1303190286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1303290286Sobrien  "#")
1303350650Sobrien
1303490286Sobrien(define_insn "*fp_jcc_6"
1303550650Sobrien  [(set (pc)
1303690286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1303790286Sobrien			[(match_operand 1 "register_operand" "f")
1303890286Sobrien			 (match_operand 2 "register_operand" "f")])
1303990286Sobrien	  (pc)
1304090286Sobrien	  (label_ref (match_operand 3 "" ""))))
1304190286Sobrien   (clobber (reg:CCFP 18))
1304290286Sobrien   (clobber (reg:CCFP 17))
1304390286Sobrien   (clobber (match_scratch:HI 4 "=a"))]
1304490286Sobrien  "TARGET_80387
1304590286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
1304690286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1304790286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1304890286Sobrien  "#")
1304950650Sobrien
1305090286Sobrien(define_split
1305150650Sobrien  [(set (pc)
1305290286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1305390286Sobrien			[(match_operand 1 "register_operand" "")
1305490286Sobrien			 (match_operand 2 "nonimmediate_operand" "")])
1305590286Sobrien	  (match_operand 3 "" "")
1305690286Sobrien	  (match_operand 4 "" "")))
1305790286Sobrien   (clobber (reg:CCFP 18))
1305890286Sobrien   (clobber (reg:CCFP 17))]
1305990286Sobrien  "reload_completed"
1306090286Sobrien  [(const_int 0)]
1306150650Sobrien{
1306290286Sobrien  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
1306390286Sobrien			operands[3], operands[4], NULL_RTX);
1306490286Sobrien  DONE;
1306590286Sobrien})
1306650650Sobrien
1306790286Sobrien(define_split
1306850650Sobrien  [(set (pc)
1306990286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1307090286Sobrien			[(match_operand 1 "register_operand" "")
1307190286Sobrien			 (match_operand 2 "nonimmediate_operand" "")])
1307290286Sobrien	  (match_operand 3 "" "")
1307390286Sobrien	  (match_operand 4 "" "")))
1307490286Sobrien   (clobber (reg:CCFP 18))
1307590286Sobrien   (clobber (reg:CCFP 17))
1307690286Sobrien   (clobber (match_scratch:HI 5 "=a"))]
1307790286Sobrien  "reload_completed"
1307890286Sobrien  [(set (pc)
1307990286Sobrien	(if_then_else (match_dup 6)
1308090286Sobrien	  (match_dup 3)
1308190286Sobrien	  (match_dup 4)))]
1308250650Sobrien{
1308390286Sobrien  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
1308490286Sobrien			operands[3], operands[4], operands[5]);
1308590286Sobrien  DONE;
1308690286Sobrien})
1308790286Sobrien
1308890286Sobrien;; Unconditional and other jump instructions
1308950650Sobrien
1309090286Sobrien(define_insn "jump"
1309150650Sobrien  [(set (pc)
1309290286Sobrien	(label_ref (match_operand 0 "" "")))]
1309350650Sobrien  ""
1309490286Sobrien  "jmp\t%l0"
1309590286Sobrien  [(set_attr "type" "ibr")])
1309690286Sobrien
1309790286Sobrien(define_expand "indirect_jump"
1309890286Sobrien  [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
1309990286Sobrien  ""
1310090286Sobrien  "")
1310190286Sobrien
1310290286Sobrien(define_insn "*indirect_jump"
1310390286Sobrien  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
1310490286Sobrien  "!TARGET_64BIT"
1310590286Sobrien  "jmp\t%A0"
1310690286Sobrien  [(set_attr "type" "ibr")
1310790286Sobrien   (set_attr "length_immediate" "0")])
1310890286Sobrien
1310990286Sobrien(define_insn "*indirect_jump_rtx64"
1311090286Sobrien  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
1311190286Sobrien  "TARGET_64BIT"
1311290286Sobrien  "jmp\t%A0"
1311390286Sobrien  [(set_attr "type" "ibr")
1311490286Sobrien   (set_attr "length_immediate" "0")])
1311590286Sobrien
1311690286Sobrien(define_expand "tablejump"
1311790286Sobrien  [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
1311890286Sobrien	      (use (label_ref (match_operand 1 "" "")))])]
1311990286Sobrien  ""
1312050650Sobrien{
1312190286Sobrien  /* In PIC mode, the table entries are stored GOT-relative.  Convert
1312290286Sobrien     the relative address to an absolute address.  */
1312390286Sobrien  if (flag_pic)
1312490286Sobrien    {
1312590286Sobrien      if (TARGET_64BIT)
1312690286Sobrien	operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1312790286Sobrien					   gen_rtx_LABEL_REF (Pmode, operands[1]),
1312890286Sobrien					   NULL_RTX, 0,
1312990286Sobrien					   OPTAB_DIRECT);
1313090286Sobrien      else if (HAVE_AS_GOTOFF_IN_DATA)
1313190286Sobrien	{
1313290286Sobrien	  operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1313390286Sobrien					     pic_offset_table_rtx, NULL_RTX,
1313490286Sobrien					     1, OPTAB_DIRECT);
1313590286Sobrien	  current_function_uses_pic_offset_table = 1;
1313690286Sobrien	}
1313790286Sobrien      else
1313890286Sobrien	{
1313990286Sobrien	  operands[0] = expand_simple_binop (Pmode, MINUS, pic_offset_table_rtx,
1314090286Sobrien					     operands[0], NULL_RTX, 1,
1314190286Sobrien					     OPTAB_DIRECT);
1314290286Sobrien	  current_function_uses_pic_offset_table = 1;
1314390286Sobrien	}
1314490286Sobrien    }
1314590286Sobrien})
1314650650Sobrien
1314790286Sobrien(define_insn "*tablejump_1"
1314890286Sobrien  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
1314990286Sobrien   (use (label_ref (match_operand 1 "" "")))]
1315090286Sobrien  "!TARGET_64BIT"
1315190286Sobrien  "jmp\t%A0"
1315290286Sobrien  [(set_attr "type" "ibr")
1315390286Sobrien   (set_attr "length_immediate" "0")])
1315418334Speter
1315590286Sobrien(define_insn "*tablejump_1_rtx64"
1315690286Sobrien  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
1315790286Sobrien   (use (label_ref (match_operand 1 "" "")))]
1315890286Sobrien  "TARGET_64BIT"
1315990286Sobrien  "jmp\t%A0"
1316090286Sobrien  [(set_attr "type" "ibr")
1316190286Sobrien   (set_attr "length_immediate" "0")])
1316290286Sobrien
1316390286Sobrien;; Loop instruction
1316490286Sobrien;;
1316590286Sobrien;; This is all complicated by the fact that since this is a jump insn
1316690286Sobrien;; we must handle our own reloads.
1316718334Speter
1316890286Sobrien(define_expand "doloop_end"
1316990286Sobrien  [(use (match_operand 0 "" ""))        ; loop pseudo
1317090286Sobrien   (use (match_operand 1 "" ""))        ; iterations; zero if unknown
1317190286Sobrien   (use (match_operand 2 "" ""))        ; max iterations
1317290286Sobrien   (use (match_operand 3 "" ""))        ; loop level 
1317390286Sobrien   (use (match_operand 4 "" ""))]       ; label
1317490286Sobrien  "!TARGET_64BIT && TARGET_USE_LOOP"
1317590286Sobrien  "                                 
1317618334Speter{
1317790286Sobrien  /* Only use cloop on innermost loops.  */
1317890286Sobrien  if (INTVAL (operands[3]) > 1)
1317990286Sobrien    FAIL;
1318090286Sobrien  if (GET_MODE (operands[0]) != SImode)
1318190286Sobrien    FAIL;
1318290286Sobrien  emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
1318390286Sobrien					   operands[0]));
1318490286Sobrien  DONE;
1318518334Speter}")
1318618334Speter
1318790286Sobrien(define_insn "doloop_end_internal"
1318818334Speter  [(set (pc)
1318990286Sobrien	(if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
1319090286Sobrien			  (const_int 1))
1319190286Sobrien		      (label_ref (match_operand 0 "" ""))
1319290286Sobrien		      (pc)))
1319390286Sobrien   (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
1319490286Sobrien	(plus:SI (match_dup 1)
1319590286Sobrien		 (const_int -1)))
1319690286Sobrien   (clobber (match_scratch:SI 3 "=X,X,r"))
1319790286Sobrien   (clobber (reg:CC 17))]
1319890286Sobrien  "!TARGET_64BIT && TARGET_USE_LOOP"
1319918334Speter{
1320090286Sobrien  if (which_alternative != 0)
1320190286Sobrien    return "#";
1320290286Sobrien  if (get_attr_length (insn) == 2)
1320390286Sobrien    return "%+loop\t%l0";
1320490286Sobrien  else
1320590286Sobrien    return "dec{l}\t%1\;%+jne\t%l0";
1320690286Sobrien}
1320790286Sobrien  [(set_attr "ppro_uops" "many")
1320890286Sobrien   (set (attr "type")
1320990286Sobrien	(if_then_else (and (eq_attr "alternative" "0")
1321090286Sobrien			   (and (ge (minus (match_dup 0) (pc))
1321190286Sobrien			            (const_int -128))
1321290286Sobrien			        (lt (minus (match_dup 0) (pc))
1321390286Sobrien			            (const_int 124))))
1321490286Sobrien		      (const_string "ibr")
1321590286Sobrien		      (const_string "multi")))])
1321618334Speter
1321790286Sobrien(define_split
1321890286Sobrien  [(set (pc)
1321990286Sobrien	(if_then_else (ne (match_operand:SI 1 "register_operand" "")
1322090286Sobrien			  (const_int 1))
1322190286Sobrien		      (match_operand 0 "" "")
1322290286Sobrien		      (pc)))
1322390286Sobrien   (set (match_dup 1)
1322490286Sobrien	(plus:SI (match_dup 1)
1322590286Sobrien		 (const_int -1)))
1322690286Sobrien   (clobber (match_scratch:SI 2 ""))
1322790286Sobrien   (clobber (reg:CC 17))]
1322890286Sobrien  "!TARGET_64BIT && TARGET_USE_LOOP
1322990286Sobrien   && reload_completed
1323090286Sobrien   && REGNO (operands[1]) != 2"
1323190286Sobrien  [(parallel [(set (reg:CCZ 17)
1323290286Sobrien		   (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
1323390286Sobrien				 (const_int 0)))
1323490286Sobrien	      (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
1323590286Sobrien   (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
1323690286Sobrien			   (match_dup 0)
1323790286Sobrien			   (pc)))]
1323890286Sobrien  "")
1323990286Sobrien  
1324090286Sobrien(define_split
1324190286Sobrien  [(set (pc)
1324290286Sobrien	(if_then_else (ne (match_operand:SI 1 "register_operand" "")
1324390286Sobrien			  (const_int 1))
1324490286Sobrien		      (match_operand 0 "" "")
1324590286Sobrien		      (pc)))
1324690286Sobrien   (set (match_operand:SI 2 "nonimmediate_operand" "")
1324790286Sobrien	(plus:SI (match_dup 1)
1324890286Sobrien		 (const_int -1)))
1324990286Sobrien   (clobber (match_scratch:SI 3 ""))
1325090286Sobrien   (clobber (reg:CC 17))]
1325190286Sobrien  "!TARGET_64BIT && TARGET_USE_LOOP
1325290286Sobrien   && reload_completed
1325390286Sobrien   && (! REG_P (operands[2])
1325490286Sobrien       || ! rtx_equal_p (operands[1], operands[2]))"
1325590286Sobrien  [(set (match_dup 3) (match_dup 1))
1325690286Sobrien   (parallel [(set (reg:CCZ 17)
1325790286Sobrien		   (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
1325890286Sobrien				(const_int 0)))
1325990286Sobrien	      (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
1326090286Sobrien   (set (match_dup 2) (match_dup 3))
1326190286Sobrien   (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
1326290286Sobrien			   (match_dup 0)
1326390286Sobrien			   (pc)))]
1326490286Sobrien  "")
1326518334Speter
1326690286Sobrien;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
1326718334Speter
1326890286Sobrien(define_peephole2
1326990286Sobrien  [(set (reg 17) (match_operand 0 "" ""))
1327090286Sobrien   (set (match_operand:QI 1 "register_operand" "")
1327190286Sobrien	(match_operator:QI 2 "ix86_comparison_operator"
1327290286Sobrien	  [(reg 17) (const_int 0)]))
1327390286Sobrien   (set (match_operand 3 "q_regs_operand" "")
1327490286Sobrien	(zero_extend (match_dup 1)))]
1327590286Sobrien  "(peep2_reg_dead_p (3, operands[1])
1327690286Sobrien    || operands_match_p (operands[1], operands[3]))
1327790286Sobrien   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
1327890286Sobrien  [(set (match_dup 4) (match_dup 0))
1327990286Sobrien   (set (strict_low_part (match_dup 5))
1328090286Sobrien	(match_dup 2))]
1328118334Speter{
1328290286Sobrien  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
1328390286Sobrien  operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
1328490286Sobrien  ix86_expand_clear (operands[3]);
1328590286Sobrien})
1328618334Speter
1328790286Sobrien;; Similar, but match zero_extendhisi2_and, which adds a clobber.
1328818334Speter
1328990286Sobrien(define_peephole2
1329090286Sobrien  [(set (reg 17) (match_operand 0 "" ""))
1329190286Sobrien   (set (match_operand:QI 1 "register_operand" "")
1329290286Sobrien	(match_operator:QI 2 "ix86_comparison_operator"
1329390286Sobrien	  [(reg 17) (const_int 0)]))
1329490286Sobrien   (parallel [(set (match_operand 3 "q_regs_operand" "")
1329590286Sobrien		   (zero_extend (match_dup 1)))
1329690286Sobrien	      (clobber (reg:CC 17))])]
1329790286Sobrien  "(peep2_reg_dead_p (3, operands[1])
1329890286Sobrien    || operands_match_p (operands[1], operands[3]))
1329990286Sobrien   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
1330090286Sobrien  [(set (match_dup 4) (match_dup 0))
1330190286Sobrien   (set (strict_low_part (match_dup 5))
1330290286Sobrien	(match_dup 2))]
1330390286Sobrien{
1330490286Sobrien  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
1330590286Sobrien  operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
1330690286Sobrien  ix86_expand_clear (operands[3]);
1330790286Sobrien})
1330890286Sobrien
1330990286Sobrien;; Call instructions.
1331018334Speter
1331190286Sobrien;; The predicates normally associated with named expanders are not properly
1331290286Sobrien;; checked for calls.  This is a bug in the generic code, but it isn't that
1331390286Sobrien;; easy to fix.  Ignore it for now and be prepared to fix things up.
1331418334Speter
1331518334Speter;; Call subroutine returning no value.
1331618334Speter
1331718334Speter(define_expand "call_pop"
1331890286Sobrien  [(parallel [(call (match_operand:QI 0 "" "")
1331990286Sobrien		    (match_operand:SI 1 "" ""))
1332018334Speter	      (set (reg:SI 7)
1332118334Speter		   (plus:SI (reg:SI 7)
1332290286Sobrien			    (match_operand:SI 3 "" "")))])]
1332390286Sobrien  "!TARGET_64BIT"
1332418334Speter{
1332552296Sobrien  if (operands[3] == const0_rtx)
1332652296Sobrien    {
1332790286Sobrien      emit_insn (gen_call (operands[0], operands[1], constm1_rtx));
1332852296Sobrien      DONE;
1332952296Sobrien    }
1333090286Sobrien  /* Static functions and indirect calls don't need
1333190286Sobrien     current_function_uses_pic_offset_table.  */
1333290286Sobrien  if (flag_pic
1333390286Sobrien      && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
1333490286Sobrien      && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
1333518334Speter    current_function_uses_pic_offset_table = 1;
1333690286Sobrien  if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
1333790286Sobrien    XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1333890286Sobrien  if (TARGET_64BIT)
1333990286Sobrien    abort();
1334090286Sobrien})
1334118334Speter
1334290286Sobrien(define_insn "*call_pop_0"
1334390286Sobrien  [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
1334490286Sobrien	 (match_operand:SI 1 "" ""))
1334518334Speter   (set (reg:SI 7) (plus:SI (reg:SI 7)
1334690286Sobrien			    (match_operand:SI 2 "immediate_operand" "")))]
1334790286Sobrien  "!TARGET_64BIT"
1334818334Speter{
1334990286Sobrien  if (SIBLING_CALL_P (insn))
1335090286Sobrien    return "jmp\t%P0";
1335190286Sobrien  else
1335290286Sobrien    return "call\t%P0";
1335390286Sobrien}
1335490286Sobrien  [(set_attr "type" "call")])
1335590286Sobrien  
1335690286Sobrien(define_insn "*call_pop_1"
1335790286Sobrien  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
1335890286Sobrien	 (match_operand:SI 1 "" ""))
1335990286Sobrien   (set (reg:SI 7) (plus:SI (reg:SI 7)
1336090286Sobrien			    (match_operand:SI 2 "immediate_operand" "i")))]
1336190286Sobrien  "!TARGET_64BIT"
1336290286Sobrien{
1336390286Sobrien  if (constant_call_address_operand (operands[0], Pmode))
1336418334Speter    {
1336590286Sobrien      if (SIBLING_CALL_P (insn))
1336690286Sobrien	return "jmp\t%P0";
1336790286Sobrien      else
1336890286Sobrien	return "call\t%P0";
1336918334Speter    }
1337090286Sobrien  if (SIBLING_CALL_P (insn))
1337190286Sobrien    return "jmp\t%A0";
1337218334Speter  else
1337390286Sobrien    return "call\t%A0";
1337490286Sobrien}
1337590286Sobrien  [(set_attr "type" "call")])
1337618334Speter
1337718334Speter(define_expand "call"
1337890286Sobrien  [(call (match_operand:QI 0 "" "")
1337990286Sobrien	 (match_operand 1 "" ""))
1338090286Sobrien   (use (match_operand 2 "" ""))]
1338118334Speter  ;; Operand 1 not used on the i386.
1338218334Speter  ""
1338318334Speter{
1338490286Sobrien  rtx insn;
1338590286Sobrien  /* Static functions and indirect calls don't need
1338690286Sobrien     current_function_uses_pic_offset_table.  */
1338790286Sobrien  if (flag_pic
1338890286Sobrien      && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
1338990286Sobrien      && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
1339018334Speter    current_function_uses_pic_offset_table = 1;
1339118334Speter
1339290286Sobrien  if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
1339390286Sobrien    XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1339490286Sobrien  if (TARGET_64BIT && INTVAL (operands[2]) >= 0)
1339590286Sobrien    {
1339690286Sobrien      rtx reg = gen_rtx_REG (QImode, 0);
1339790286Sobrien      emit_move_insn (reg, operands[2]);
1339890286Sobrien      insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
1339990286Sobrien      use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
1340090286Sobrien      DONE;
1340190286Sobrien    }
1340290286Sobrien   insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
1340390286Sobrien   DONE;
1340490286Sobrien})
1340518334Speter
1340690286Sobrien(define_expand "call_exp"
1340790286Sobrien  [(call (match_operand:QI 0 "" "")
1340890286Sobrien	 (match_operand 1 "" ""))]
1340990286Sobrien  ""
1341090286Sobrien  "")
1341118334Speter
1341290286Sobrien(define_insn "*call_0"
1341390286Sobrien  [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
1341490286Sobrien	 (match_operand 1 "" ""))]
1341518334Speter  ""
1341618334Speter{
1341790286Sobrien  if (SIBLING_CALL_P (insn))
1341890286Sobrien    return "jmp\t%P0";
1341990286Sobrien  else
1342090286Sobrien    return "call\t%P0";
1342190286Sobrien}
1342290286Sobrien  [(set_attr "type" "call")])
1342390286Sobrien
1342490286Sobrien(define_insn "*call_1"
1342590286Sobrien  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
1342690286Sobrien	 (match_operand 1 "" ""))]
1342790286Sobrien  "!TARGET_64BIT"
1342890286Sobrien{
1342990286Sobrien  if (constant_call_address_operand (operands[0], QImode))
1343018334Speter    {
1343190286Sobrien      if (SIBLING_CALL_P (insn))
1343290286Sobrien	return "jmp\t%P0";
1343390286Sobrien      else
1343490286Sobrien	return "call\t%P0";
1343518334Speter    }
1343690286Sobrien  if (SIBLING_CALL_P (insn))
1343790286Sobrien    return "jmp\t%A0";
1343818334Speter  else
1343990286Sobrien    return "call\t%A0";
1344090286Sobrien}
1344190286Sobrien  [(set_attr "type" "call")])
1344218334Speter
1344390286Sobrien(define_insn "*call_1_rex64"
1344490286Sobrien  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
1344590286Sobrien	 (match_operand 1 "" ""))]
1344690286Sobrien  "TARGET_64BIT"
1344790286Sobrien{
1344890286Sobrien  if (constant_call_address_operand (operands[0], QImode))
1344990286Sobrien    {
1345090286Sobrien      if (SIBLING_CALL_P (insn))
1345190286Sobrien	return "jmp\t%P0";
1345290286Sobrien      else
1345390286Sobrien	return "call\t%P0";
1345490286Sobrien    }
1345590286Sobrien  if (SIBLING_CALL_P (insn))
1345690286Sobrien    return "jmp\t%A0";
1345790286Sobrien  else
1345890286Sobrien    return "call\t%A0";
1345990286Sobrien}
1346090286Sobrien  [(set_attr "type" "call")])
1346118334Speter
1346218334Speter;; Call subroutine, returning value in operand 0
1346318334Speter;; (which must be a hard register).
1346418334Speter
1346518334Speter(define_expand "call_value_pop"
1346618334Speter  [(parallel [(set (match_operand 0 "" "")
1346790286Sobrien		   (call (match_operand:QI 1 "" "")
1346890286Sobrien			 (match_operand:SI 2 "" "")))
1346918334Speter	      (set (reg:SI 7)
1347018334Speter		   (plus:SI (reg:SI 7)
1347190286Sobrien			    (match_operand:SI 4 "" "")))])]
1347290286Sobrien  "!TARGET_64BIT"
1347318334Speter{
1347452296Sobrien  if (operands[4] == const0_rtx)
1347552296Sobrien    {
1347690286Sobrien      emit_insn (gen_call_value (operands[0], operands[1], operands[2],
1347790286Sobrien				 constm1_rtx));
1347852296Sobrien      DONE;
1347952296Sobrien    }
1348090286Sobrien  /* Static functions and indirect calls don't need
1348190286Sobrien     current_function_uses_pic_offset_table.  */
1348290286Sobrien  if (flag_pic
1348390286Sobrien      && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1348490286Sobrien      && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
1348518334Speter    current_function_uses_pic_offset_table = 1;
1348690286Sobrien  if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
1348790286Sobrien    XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1348890286Sobrien})
1348918334Speter
1349018334Speter(define_expand "call_value"
1349118334Speter  [(set (match_operand 0 "" "")
1349290286Sobrien	(call (match_operand:QI 1 "" "")
1349390286Sobrien	      (match_operand:SI 2 "" "")))
1349490286Sobrien   (use (match_operand:SI 3 "" ""))]
1349518334Speter  ;; Operand 2 not used on the i386.
1349618334Speter  ""
1349718334Speter{
1349890286Sobrien  rtx insn;
1349990286Sobrien  /* Static functions and indirect calls don't need
1350090286Sobrien     current_function_uses_pic_offset_table.  */
1350190286Sobrien  if (flag_pic
1350290286Sobrien      && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1350390286Sobrien      && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
1350418334Speter    current_function_uses_pic_offset_table = 1;
1350590286Sobrien  if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
1350690286Sobrien    XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1350790286Sobrien  if (TARGET_64BIT && INTVAL (operands[3]) >= 0)
1350818334Speter    {
1350990286Sobrien      rtx reg = gen_rtx_REG (QImode, 0);
1351090286Sobrien      emit_move_insn (reg, operands[3]);
1351190286Sobrien      insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
1351290286Sobrien						 operands[2]));
1351390286Sobrien      use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
1351490286Sobrien      DONE;
1351518334Speter    }
1351690286Sobrien  insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
1351790286Sobrien					     operands[2]));
1351890286Sobrien  DONE;
1351990286Sobrien})
1352018334Speter
1352190286Sobrien(define_expand "call_value_exp"
1352290286Sobrien  [(set (match_operand 0 "" "")
1352390286Sobrien	(call (match_operand:QI 1 "" "")
1352490286Sobrien	      (match_operand:SI 2 "" "")))]
1352590286Sobrien  ""
1352690286Sobrien  "")
1352718334Speter
1352818334Speter;; Call subroutine returning any type.
1352918334Speter
1353018334Speter(define_expand "untyped_call"
1353118334Speter  [(parallel [(call (match_operand 0 "" "")
1353218334Speter		    (const_int 0))
1353318334Speter	      (match_operand 1 "" "")
1353418334Speter	      (match_operand 2 "" "")])]
1353518334Speter  ""
1353618334Speter{
1353718334Speter  int i;
1353818334Speter
1353918334Speter  /* In order to give reg-stack an easier job in validating two
1354018334Speter     coprocessor registers as containing a possible return value,
1354118334Speter     simply pretend the untyped call returns a complex long double
1354218334Speter     value.  */
1354350650Sobrien
1354418334Speter  emit_call_insn (TARGET_80387
1354550650Sobrien                  ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
1354690286Sobrien				    operands[0], const0_rtx,
1354790286Sobrien				    GEN_INT (SSE_REGPARM_MAX - 1))
1354890286Sobrien                  : gen_call (operands[0], const0_rtx,
1354990286Sobrien			      GEN_INT (SSE_REGPARM_MAX - 1)));
1355018334Speter
1355118334Speter  for (i = 0; i < XVECLEN (operands[2], 0); i++)
1355218334Speter    {
1355318334Speter      rtx set = XVECEXP (operands[2], 0, i);
1355418334Speter      emit_move_insn (SET_DEST (set), SET_SRC (set));
1355518334Speter    }
1355618334Speter
1355718334Speter  /* The optimizer does not know that the call sets the function value
1355818334Speter     registers we stored in the result block.  We avoid problems by
1355918334Speter     claiming that all hard registers are used and clobbered at this
1356018334Speter     point.  */
1356118334Speter  emit_insn (gen_blockage ());
1356218334Speter
1356318334Speter  DONE;
1356490286Sobrien})
1356590286Sobrien
1356690286Sobrien;; Prologue and epilogue instructions
1356718334Speter
1356818334Speter;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1356918334Speter;; all of memory.  This blocks insns from being moved across this point.
1357018334Speter
1357118334Speter(define_insn "blockage"
1357218334Speter  [(unspec_volatile [(const_int 0)] 0)]
1357318334Speter  ""
1357452296Sobrien  ""
1357590286Sobrien  [(set_attr "length" "0")])
1357618334Speter
1357718334Speter;; Insn emitted into the body of a function to return from a function.
1357818334Speter;; This is only done if the function's epilogue is known to be simple.
1357990286Sobrien;; See comments for ix86_can_use_return_insn_p in i386.c.
1358018334Speter
1358150650Sobrien(define_expand "return"
1358218334Speter  [(return)]
1358350650Sobrien  "ix86_can_use_return_insn_p ()"
1358490286Sobrien{
1358590286Sobrien  if (current_function_pops_args)
1358690286Sobrien    {
1358790286Sobrien      rtx popc = GEN_INT (current_function_pops_args);
1358890286Sobrien      emit_jump_insn (gen_return_pop_internal (popc));
1358990286Sobrien      DONE;
1359090286Sobrien    }
1359190286Sobrien})
1359250650Sobrien
1359350650Sobrien(define_insn "return_internal"
1359450650Sobrien  [(return)]
1359550650Sobrien  "reload_completed"
1359652296Sobrien  "ret"
1359790286Sobrien  [(set_attr "length" "1")
1359890286Sobrien   (set_attr "length_immediate" "0")
1359990286Sobrien   (set_attr "modrm" "0")])
1360050650Sobrien
1360150650Sobrien(define_insn "return_pop_internal"
1360250650Sobrien  [(return)
1360350650Sobrien   (use (match_operand:SI 0 "const_int_operand" ""))]
1360450650Sobrien  "reload_completed"
1360590286Sobrien  "ret\t%0"
1360690286Sobrien  [(set_attr "length" "3")
1360790286Sobrien   (set_attr "length_immediate" "2")
1360890286Sobrien   (set_attr "modrm" "0")])
1360950650Sobrien
1361090286Sobrien(define_insn "return_indirect_internal"
1361190286Sobrien  [(return)
1361290286Sobrien   (use (match_operand:SI 0 "register_operand" "r"))]
1361390286Sobrien  "reload_completed"
1361490286Sobrien  "jmp\t%A0"
1361590286Sobrien  [(set_attr "type" "ibr")
1361690286Sobrien   (set_attr "length_immediate" "0")])
1361790286Sobrien
1361850650Sobrien(define_insn "nop"
1361950650Sobrien  [(const_int 0)]
1362050650Sobrien  ""
1362152296Sobrien  "nop"
1362290286Sobrien  [(set_attr "length" "1")
1362390286Sobrien   (set_attr "length_immediate" "0")
1362490286Sobrien   (set_attr "modrm" "0")
1362590286Sobrien   (set_attr "ppro_uops" "one")])
1362650650Sobrien
1362750650Sobrien(define_expand "prologue"
1362850650Sobrien  [(const_int 1)]
1362950650Sobrien  ""
1363090286Sobrien  "ix86_expand_prologue (); DONE;")
1363150650Sobrien
1363250650Sobrien(define_insn "prologue_set_got"
1363390286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1363490286Sobrien	(unspec_volatile:SI
1363550650Sobrien	 [(plus:SI (match_dup 0)
1363650650Sobrien		   (plus:SI (match_operand:SI 1 "symbolic_operand" "")
1363790286Sobrien			    (minus:SI (pc) (match_operand 2 "" ""))))] 1))
1363890286Sobrien   (clobber (reg:CC 17))]
1363990286Sobrien  "!TARGET_64BIT"
1364050650Sobrien{
1364190286Sobrien  if (GET_CODE (operands[2]) == LABEL_REF)
1364290286Sobrien     operands[2] = XEXP (operands[2], 0);
1364350650Sobrien  if (TARGET_DEEP_BRANCH_PREDICTION) 
1364490286Sobrien    return "add{l}\t{%1, %0|%0, %1}";
1364550650Sobrien  else  
1364690286Sobrien    return "add{l}\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}";
1364790286Sobrien}
1364890286Sobrien  [(set_attr "type" "alu")
1364990286Sobrien   ; Since this insn may have two constant operands, we must set the
1365090286Sobrien   ; length manually.
1365190286Sobrien   (set_attr "length_immediate" "4")
1365290286Sobrien   (set_attr "mode" "SI")])
1365350650Sobrien
1365450650Sobrien(define_insn "prologue_get_pc"
1365590286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1365690286Sobrien    (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
1365790286Sobrien  "!TARGET_64BIT"
1365850650Sobrien{
1365990286Sobrien  if (GET_CODE (operands[1]) == LABEL_REF)
1366090286Sobrien    operands[1] = XEXP (operands[1], 0);
1366190286Sobrien  output_asm_insn ("call\t%X1", operands);
1366290286Sobrien  if (! TARGET_DEEP_BRANCH_PREDICTION)
1366350650Sobrien    {
1366490286Sobrien      ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1366590286Sobrien				 CODE_LABEL_NUMBER (operands[1]));
1366690286Sobrien    }
1366750650Sobrien  RET;
1366890286Sobrien}
1366990286Sobrien  [(set_attr "type" "multi")])
1367050650Sobrien
1367150650Sobrien(define_expand "epilogue"
1367250650Sobrien  [(const_int 1)]
1367350650Sobrien  ""
1367490286Sobrien  "ix86_expand_epilogue (1); DONE;")
1367550650Sobrien
1367690286Sobrien(define_expand "sibcall_epilogue"
1367790286Sobrien  [(const_int 1)]
1367850650Sobrien  ""
1367990286Sobrien  "ix86_expand_epilogue (0); DONE;")
1368050650Sobrien
1368190286Sobrien(define_expand "eh_return"
1368290286Sobrien  [(use (match_operand 0 "register_operand" ""))
1368390286Sobrien   (use (match_operand 1 "register_operand" ""))]
1368450650Sobrien  ""
1368550650Sobrien{
1368690286Sobrien  rtx tmp, sa = operands[0], ra = operands[1];
1368750650Sobrien
1368890286Sobrien  /* Tricky bit: we write the address of the handler to which we will
1368990286Sobrien     be returning into someone else's stack frame, one word below the
1369090286Sobrien     stack address we wish to restore.  */
1369190286Sobrien  tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
1369290286Sobrien  tmp = plus_constant (tmp, -UNITS_PER_WORD);
1369390286Sobrien  tmp = gen_rtx_MEM (Pmode, tmp);
1369490286Sobrien  emit_move_insn (tmp, ra);
1369518334Speter
1369690286Sobrien  if (Pmode == SImode)
1369790286Sobrien    emit_insn (gen_eh_return_si (sa));
1369890286Sobrien  else
1369990286Sobrien    emit_insn (gen_eh_return_di (sa));
1370090286Sobrien  emit_barrier ();
1370190286Sobrien  DONE;
1370290286Sobrien})
1370318334Speter
1370490286Sobrien(define_insn_and_split "eh_return_si"
1370590286Sobrien  [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")] 13)]
1370690286Sobrien  "!TARGET_64BIT"
1370790286Sobrien  "#"
1370890286Sobrien  "reload_completed"
1370990286Sobrien  [(const_int 1)]
1371090286Sobrien  "ix86_expand_epilogue (2); DONE;")
1371118334Speter
1371290286Sobrien(define_insn_and_split "eh_return_di"
1371390286Sobrien  [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")] 13)]
1371490286Sobrien  "TARGET_64BIT"
1371590286Sobrien  "#"
1371690286Sobrien  "reload_completed"
1371790286Sobrien  [(const_int 1)]
1371890286Sobrien  "ix86_expand_epilogue (2); DONE;")
1371918334Speter
1372090286Sobrien(define_insn "leave"
1372190286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
1372290286Sobrien   (set (reg:SI 6) (mem:SI (reg:SI 6)))
1372390286Sobrien   (clobber (mem:BLK (scratch)))]
1372490286Sobrien  "!TARGET_64BIT"
1372590286Sobrien  "leave"
1372690286Sobrien  [(set_attr "length_immediate" "0")
1372790286Sobrien   (set_attr "length" "1")
1372890286Sobrien   (set_attr "modrm" "0")
1372990286Sobrien   (set_attr "modrm" "0")
1373090286Sobrien   (set_attr "athlon_decode" "vector")
1373190286Sobrien   (set_attr "ppro_uops" "few")])
1373218334Speter
1373390286Sobrien(define_insn "leave_rex64"
1373490286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
1373590286Sobrien   (set (reg:DI 6) (mem:DI (reg:DI 6)))
1373690286Sobrien   (clobber (mem:BLK (scratch)))]
1373790286Sobrien  "TARGET_64BIT"
1373890286Sobrien  "leave"
1373990286Sobrien  [(set_attr "length_immediate" "0")
1374090286Sobrien   (set_attr "length" "1")
1374190286Sobrien   (set_attr "modrm" "0")
1374290286Sobrien   (set_attr "modrm" "0")
1374390286Sobrien   (set_attr "athlon_decode" "vector")
1374490286Sobrien   (set_attr "ppro_uops" "few")])
1374590286Sobrien
1374690286Sobrien(define_expand "ffssi2"
1374790286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "") 
1374890286Sobrien	(ffs:SI (match_operand:SI 1 "general_operand" "")))]
1374918334Speter  ""
1375018334Speter{
1375190286Sobrien  rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
1375290286Sobrien  rtx in = operands[1];
1375318334Speter
1375490286Sobrien  if (TARGET_CMOVE)
1375518334Speter    {
1375690286Sobrien      emit_move_insn (tmp, constm1_rtx);
1375790286Sobrien      emit_insn (gen_ffssi_1 (out, in));
1375890286Sobrien      emit_insn (gen_rtx_SET (VOIDmode, out,
1375990286Sobrien		  gen_rtx_IF_THEN_ELSE (SImode, 
1376090286Sobrien		    gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
1376190286Sobrien				const0_rtx),
1376290286Sobrien		    tmp,
1376390286Sobrien		    out)));
1376490286Sobrien      emit_insn (gen_addsi3 (out, out, const1_rtx));
1376590286Sobrien      emit_move_insn (operands[0], out);
1376618334Speter    }
1376718334Speter
1376890286Sobrien  /* Pentium bsf instruction is extremly slow.  The following code is
1376990286Sobrien     recommended by the Intel Optimizing Manual as a reasonable replacement:
1377090286Sobrien           TEST    EAX,EAX
1377190286Sobrien	   JZ      SHORT BS2
1377290286Sobrien	   XOR     ECX,ECX
1377390286Sobrien	   MOV     DWORD PTR [TEMP+4],ECX
1377490286Sobrien	   SUB     ECX,EAX
1377590286Sobrien	   AND     EAX,ECX
1377690286Sobrien	   MOV     DWORD PTR [TEMP],EAX
1377790286Sobrien	   FILD    QWORD PTR [TEMP]
1377890286Sobrien	   FSTP    QWORD PTR [TEMP]
1377990286Sobrien	   WAIT    ; WAIT only needed for compatibility with
1378090286Sobrien	           ; earlier processors
1378190286Sobrien	   MOV     ECX, DWORD PTR [TEMP+4]
1378290286Sobrien	   SHR     ECX,20
1378390286Sobrien	   SUB     ECX,3FFH
1378490286Sobrien	   TEST    EAX,EAX       ; clear zero flag
1378590286Sobrien       BS2:
1378690286Sobrien     Following piece of code expand ffs to similar beast.
1378790286Sobrien       */
1378850650Sobrien
1378990286Sobrien  else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
1379090286Sobrien    {
1379190286Sobrien      rtx label = gen_label_rtx ();
1379290286Sobrien      rtx lo, hi;
1379390286Sobrien      rtx mem = assign_386_stack_local (DImode, 0);
1379490286Sobrien      rtx fptmp = gen_reg_rtx (DFmode);
1379590286Sobrien      split_di (&mem, 1, &lo, &hi);
1379650650Sobrien
1379790286Sobrien      emit_move_insn (out, const0_rtx);
1379850650Sobrien
1379990286Sobrien      emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, label);
1380050650Sobrien
1380190286Sobrien      emit_move_insn (hi, out);
1380290286Sobrien      emit_insn (gen_subsi3 (out, out, in));
1380390286Sobrien      emit_insn (gen_andsi3 (out, out, in));
1380490286Sobrien      emit_move_insn (lo, out);
1380590286Sobrien      emit_insn (gen_floatdidf2 (fptmp,mem));
1380690286Sobrien      emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
1380790286Sobrien      emit_move_insn (out, hi);
1380890286Sobrien      emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
1380990286Sobrien      emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
1381050650Sobrien
1381190286Sobrien      emit_label (label);
1381290286Sobrien      LABEL_NUSES (label) = 1;
1381350650Sobrien
1381490286Sobrien      emit_move_insn (operands[0], out);
1381590286Sobrien    }
1381690286Sobrien  else
1381750650Sobrien    {
1381890286Sobrien      emit_move_insn (tmp, const0_rtx);
1381990286Sobrien      emit_insn (gen_ffssi_1 (out, in));
1382090286Sobrien      emit_insn (gen_rtx_SET (VOIDmode, 
1382190286Sobrien		  gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
1382290286Sobrien		  gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
1382390286Sobrien			      const0_rtx)));
1382490286Sobrien      emit_insn (gen_negsi2 (tmp, tmp));
1382590286Sobrien      emit_insn (gen_iorsi3 (out, out, tmp));
1382690286Sobrien      emit_insn (gen_addsi3 (out, out, const1_rtx));
1382790286Sobrien      emit_move_insn (operands[0], out);
1382850650Sobrien    }
1382990286Sobrien  DONE;  
1383090286Sobrien})
1383150650Sobrien
1383290286Sobrien(define_insn "ffssi_1"
1383390286Sobrien  [(set (reg:CCZ 17)
1383490286Sobrien        (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
1383590286Sobrien		     (const_int 0)))
1383690286Sobrien   (set (match_operand:SI 0 "register_operand" "=r")
1383790286Sobrien	(unspec:SI [(match_dup 1)] 5))]
1383818334Speter  ""
1383990286Sobrien  "bsf{l}\t{%1, %0|%0, %1}"
1384090286Sobrien  [(set_attr "prefix_0f" "1")
1384190286Sobrien   (set_attr "ppro_uops" "few")])
1384218334Speter
1384390286Sobrien;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
1384490286Sobrien;; and slower than the two-byte movzx insn needed to do the work in SImode.
1384590286Sobrien
1384690286Sobrien;; These patterns match the binary 387 instructions for addM3, subM3,
1384790286Sobrien;; mulM3 and divM3.  There are three patterns for each of DFmode and
1384890286Sobrien;; SFmode.  The first is the normal insn, the second the same insn but
1384990286Sobrien;; with one operand a conversion, and the third the same insn but with
1385090286Sobrien;; the other operand a conversion.  The conversion may be SFmode or
1385190286Sobrien;; SImode if the target mode DFmode, but only SImode if the target mode
1385290286Sobrien;; is SFmode.
1385318334Speter
1385490286Sobrien;; Gcc is slightly more smart about handling normal two address instructions
1385590286Sobrien;; so use special patterns for add and mull.
1385690286Sobrien(define_insn "*fop_sf_comm_nosse"
1385790286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
1385890286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1385990286Sobrien			[(match_operand:SF 1 "register_operand" "%0")
1386090286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
1386190286Sobrien  "TARGET_80387 && !TARGET_SSE_MATH
1386290286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
1386390286Sobrien  "* return output_387_binary_op (insn, operands);"
1386490286Sobrien  [(set (attr "type") 
1386590286Sobrien	(if_then_else (match_operand:SF 3 "mult_operator" "") 
1386690286Sobrien	   (const_string "fmul")
1386790286Sobrien	   (const_string "fop")))
1386890286Sobrien   (set_attr "mode" "SF")])
1386918334Speter
1387090286Sobrien(define_insn "*fop_sf_comm"
1387190286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
1387290286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1387390286Sobrien			[(match_operand:SF 1 "register_operand" "%0,0")
1387490286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
1387590286Sobrien  "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
1387690286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
1387790286Sobrien  "* return output_387_binary_op (insn, operands);"
1387890286Sobrien  [(set (attr "type") 
1387990286Sobrien	(if_then_else (eq_attr "alternative" "1")
1388090286Sobrien           (const_string "sse")
1388190286Sobrien	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
1388290286Sobrien	      (const_string "fmul")
1388390286Sobrien	      (const_string "fop"))))
1388490286Sobrien   (set_attr "mode" "SF")])
1388518334Speter
1388690286Sobrien(define_insn "*fop_sf_comm_sse"
1388790286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1388890286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1388990286Sobrien			[(match_operand:SF 1 "register_operand" "%0")
1389090286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
1389190286Sobrien  "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
1389290286Sobrien  "* return output_387_binary_op (insn, operands);"
1389390286Sobrien  [(set_attr "type" "sse")
1389490286Sobrien   (set_attr "mode" "SF")])
1389518334Speter
1389690286Sobrien(define_insn "*fop_df_comm_nosse"
1389790286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1389890286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1389990286Sobrien			[(match_operand:DF 1 "register_operand" "%0")
1390090286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
1390190286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
1390290286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
1390390286Sobrien  "* return output_387_binary_op (insn, operands);"
1390490286Sobrien  [(set (attr "type") 
1390590286Sobrien	(if_then_else (match_operand:SF 3 "mult_operator" "") 
1390690286Sobrien	   (const_string "fmul")
1390790286Sobrien	   (const_string "fop")))
1390890286Sobrien   (set_attr "mode" "DF")])
1390918334Speter
1391090286Sobrien(define_insn "*fop_df_comm"
1391190286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
1391290286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1391390286Sobrien			[(match_operand:DF 1 "register_operand" "%0,0")
1391490286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
1391590286Sobrien  "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
1391690286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
1391790286Sobrien  "* return output_387_binary_op (insn, operands);"
1391890286Sobrien  [(set (attr "type") 
1391990286Sobrien	(if_then_else (eq_attr "alternative" "1")
1392090286Sobrien           (const_string "sse")
1392190286Sobrien	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
1392290286Sobrien	      (const_string "fmul")
1392390286Sobrien	      (const_string "fop"))))
1392490286Sobrien   (set_attr "mode" "DF")])
1392518334Speter
1392690286Sobrien(define_insn "*fop_df_comm_sse"
1392790286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1392890286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1392990286Sobrien			[(match_operand:DF 1 "register_operand" "%0")
1393090286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
1393190286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH
1393290286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
1393390286Sobrien  "* return output_387_binary_op (insn, operands);"
1393490286Sobrien  [(set_attr "type" "sse")
1393590286Sobrien   (set_attr "mode" "DF")])
1393618334Speter
1393790286Sobrien(define_insn "*fop_xf_comm"
1393890286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1393990286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1394090286Sobrien			[(match_operand:XF 1 "register_operand" "%0")
1394190286Sobrien			 (match_operand:XF 2 "register_operand" "f")]))]
1394290286Sobrien  "!TARGET_64BIT && TARGET_80387
1394390286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
1394490286Sobrien  "* return output_387_binary_op (insn, operands);"
1394590286Sobrien  [(set (attr "type") 
1394690286Sobrien        (if_then_else (match_operand:XF 3 "mult_operator" "") 
1394790286Sobrien           (const_string "fmul")
1394890286Sobrien           (const_string "fop")))
1394990286Sobrien   (set_attr "mode" "XF")])
1395018334Speter
1395190286Sobrien(define_insn "*fop_tf_comm"
1395290286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1395390286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1395490286Sobrien			[(match_operand:TF 1 "register_operand" "%0")
1395590286Sobrien			 (match_operand:TF 2 "register_operand" "f")]))]
1395690286Sobrien  "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
1395790286Sobrien  "* return output_387_binary_op (insn, operands);"
1395890286Sobrien  [(set (attr "type") 
1395990286Sobrien        (if_then_else (match_operand:TF 3 "mult_operator" "") 
1396090286Sobrien           (const_string "fmul")
1396190286Sobrien           (const_string "fop")))
1396290286Sobrien   (set_attr "mode" "XF")])
1396318334Speter
1396490286Sobrien(define_insn "*fop_sf_1_nosse"
1396590286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
1396690286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1396790286Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "0,fm")
1396890286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
1396990286Sobrien  "TARGET_80387 && !TARGET_SSE_MATH
1397090286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
1397190286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1397290286Sobrien  "* return output_387_binary_op (insn, operands);"
1397390286Sobrien  [(set (attr "type") 
1397490286Sobrien        (cond [(match_operand:SF 3 "mult_operator" "") 
1397590286Sobrien                 (const_string "fmul")
1397690286Sobrien               (match_operand:SF 3 "div_operator" "") 
1397790286Sobrien                 (const_string "fdiv")
1397890286Sobrien              ]
1397990286Sobrien              (const_string "fop")))
1398090286Sobrien   (set_attr "mode" "SF")])
1398118334Speter
1398290286Sobrien(define_insn "*fop_sf_1"
1398390286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f,x")
1398490286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1398590286Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
1398690286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
1398790286Sobrien  "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
1398890286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
1398990286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1399090286Sobrien  "* return output_387_binary_op (insn, operands);"
1399190286Sobrien  [(set (attr "type") 
1399290286Sobrien        (cond [(eq_attr "alternative" "2")
1399390286Sobrien                 (const_string "sse")
1399490286Sobrien	       (match_operand:SF 3 "mult_operator" "") 
1399590286Sobrien                 (const_string "fmul")
1399690286Sobrien               (match_operand:SF 3 "div_operator" "") 
1399790286Sobrien                 (const_string "fdiv")
1399890286Sobrien              ]
1399990286Sobrien              (const_string "fop")))
1400090286Sobrien   (set_attr "mode" "SF")])
1400118334Speter
1400290286Sobrien(define_insn "*fop_sf_1_sse"
1400390286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1400490286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1400590286Sobrien			[(match_operand:SF 1 "register_operand" "0")
1400690286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
1400790286Sobrien  "TARGET_SSE_MATH
1400890286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
1400990286Sobrien  "* return output_387_binary_op (insn, operands);"
1401090286Sobrien  [(set_attr "type" "sse")
1401190286Sobrien   (set_attr "mode" "SF")])
1401218334Speter
1401390286Sobrien;; ??? Add SSE splitters for these!
1401490286Sobrien(define_insn "*fop_sf_2"
1401590286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
1401690286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1401790286Sobrien	  [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
1401890286Sobrien	   (match_operand:SF 2 "register_operand" "0,0")]))]
1401990286Sobrien  "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
1402090286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1402190286Sobrien  [(set (attr "type") 
1402290286Sobrien        (cond [(match_operand:SF 3 "mult_operator" "") 
1402390286Sobrien                 (const_string "fmul")
1402490286Sobrien               (match_operand:SF 3 "div_operator" "") 
1402590286Sobrien                 (const_string "fdiv")
1402690286Sobrien              ]
1402790286Sobrien              (const_string "fop")))
1402890286Sobrien   (set_attr "fp_int_src" "true")
1402990286Sobrien   (set_attr "ppro_uops" "many")
1403090286Sobrien   (set_attr "mode" "SI")])
1403118334Speter
1403290286Sobrien(define_insn "*fop_sf_3"
1403390286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
1403490286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1403590286Sobrien	  [(match_operand:SF 1 "register_operand" "0,0")
1403690286Sobrien	   (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1403790286Sobrien  "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
1403890286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1403990286Sobrien  [(set (attr "type") 
1404090286Sobrien        (cond [(match_operand:SF 3 "mult_operator" "") 
1404190286Sobrien                 (const_string "fmul")
1404290286Sobrien               (match_operand:SF 3 "div_operator" "") 
1404390286Sobrien                 (const_string "fdiv")
1404490286Sobrien              ]
1404590286Sobrien              (const_string "fop")))
1404690286Sobrien   (set_attr "fp_int_src" "true")
1404790286Sobrien   (set_attr "ppro_uops" "many")
1404890286Sobrien   (set_attr "mode" "SI")])
1404918334Speter
1405090286Sobrien(define_insn "*fop_df_1_nosse"
1405190286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
1405290286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1405390286Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "0,fm")
1405490286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
1405590286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
1405690286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
1405790286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1405890286Sobrien  "* return output_387_binary_op (insn, operands);"
1405990286Sobrien  [(set (attr "type") 
1406090286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1406190286Sobrien                 (const_string "fmul")
1406290286Sobrien               (match_operand:DF 3 "div_operator" "") 
1406390286Sobrien                 (const_string "fdiv")
1406490286Sobrien              ]
1406590286Sobrien              (const_string "fop")))
1406690286Sobrien   (set_attr "mode" "DF")])
1406718334Speter
1406818334Speter
1406990286Sobrien(define_insn "*fop_df_1"
1407090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
1407190286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1407290286Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
1407390286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
1407490286Sobrien  "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
1407590286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
1407690286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1407790286Sobrien  "* return output_387_binary_op (insn, operands);"
1407890286Sobrien  [(set (attr "type") 
1407990286Sobrien        (cond [(eq_attr "alternative" "2")
1408090286Sobrien                 (const_string "sse")
1408190286Sobrien	       (match_operand:DF 3 "mult_operator" "") 
1408290286Sobrien                 (const_string "fmul")
1408390286Sobrien               (match_operand:DF 3 "div_operator" "") 
1408490286Sobrien                 (const_string "fdiv")
1408590286Sobrien              ]
1408690286Sobrien              (const_string "fop")))
1408790286Sobrien   (set_attr "mode" "DF")])
1408818334Speter
1408990286Sobrien(define_insn "*fop_df_1_sse"
1409090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1409190286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1409290286Sobrien			[(match_operand:DF 1 "register_operand" "0")
1409390286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
1409490286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH
1409590286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
1409690286Sobrien  "* return output_387_binary_op (insn, operands);"
1409790286Sobrien  [(set_attr "type" "sse")])
1409818334Speter
1409990286Sobrien;; ??? Add SSE splitters for these!
1410090286Sobrien(define_insn "*fop_df_2"
1410190286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
1410290286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1410390286Sobrien	   [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
1410490286Sobrien	    (match_operand:DF 2 "register_operand" "0,0")]))]
1410590286Sobrien  "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
1410690286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1410790286Sobrien  [(set (attr "type") 
1410890286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1410990286Sobrien                 (const_string "fmul")
1411090286Sobrien               (match_operand:DF 3 "div_operator" "") 
1411190286Sobrien                 (const_string "fdiv")
1411290286Sobrien              ]
1411390286Sobrien              (const_string "fop")))
1411490286Sobrien   (set_attr "fp_int_src" "true")
1411590286Sobrien   (set_attr "ppro_uops" "many")
1411690286Sobrien   (set_attr "mode" "SI")])
1411718334Speter
1411890286Sobrien(define_insn "*fop_df_3"
1411990286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
1412090286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1412190286Sobrien	   [(match_operand:DF 1 "register_operand" "0,0")
1412290286Sobrien	    (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1412390286Sobrien  "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
1412490286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1412590286Sobrien  [(set (attr "type") 
1412690286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1412790286Sobrien                 (const_string "fmul")
1412890286Sobrien               (match_operand:DF 3 "div_operator" "") 
1412990286Sobrien                 (const_string "fdiv")
1413090286Sobrien              ]
1413190286Sobrien              (const_string "fop")))
1413290286Sobrien   (set_attr "fp_int_src" "true")
1413390286Sobrien   (set_attr "ppro_uops" "many")
1413490286Sobrien   (set_attr "mode" "SI")])
1413518334Speter
1413690286Sobrien(define_insn "*fop_df_4"
1413790286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
1413890286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1413990286Sobrien	   [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
1414090286Sobrien	    (match_operand:DF 2 "register_operand" "0,f")]))]
1414190286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
1414290286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1414390286Sobrien  "* return output_387_binary_op (insn, operands);"
1414490286Sobrien  [(set (attr "type") 
1414590286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1414690286Sobrien                 (const_string "fmul")
1414790286Sobrien               (match_operand:DF 3 "div_operator" "") 
1414890286Sobrien                 (const_string "fdiv")
1414990286Sobrien              ]
1415090286Sobrien              (const_string "fop")))
1415190286Sobrien   (set_attr "mode" "SF")])
1415218334Speter
1415390286Sobrien(define_insn "*fop_df_5"
1415418334Speter  [(set (match_operand:DF 0 "register_operand" "=f,f")
1415590286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1415690286Sobrien	  [(match_operand:DF 1 "register_operand" "0,f")
1415790286Sobrien	   (float_extend:DF
1415890286Sobrien	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
1415990286Sobrien  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
1416050650Sobrien  "* return output_387_binary_op (insn, operands);"
1416150650Sobrien  [(set (attr "type") 
1416290286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1416390286Sobrien                 (const_string "fmul")
1416490286Sobrien               (match_operand:DF 3 "div_operator" "") 
1416590286Sobrien                 (const_string "fdiv")
1416650650Sobrien              ]
1416790286Sobrien              (const_string "fop")))
1416890286Sobrien   (set_attr "mode" "SF")])
1416918334Speter
1417090286Sobrien(define_insn "*fop_xf_1"
1417118334Speter  [(set (match_operand:XF 0 "register_operand" "=f,f")
1417290286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1417350650Sobrien			[(match_operand:XF 1 "register_operand" "0,f")
1417450650Sobrien			 (match_operand:XF 2 "register_operand" "f,0")]))]
1417590286Sobrien  "!TARGET_64BIT && TARGET_80387
1417690286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
1417750650Sobrien  "* return output_387_binary_op (insn, operands);"
1417850650Sobrien  [(set (attr "type") 
1417990286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1418090286Sobrien                 (const_string "fmul")
1418190286Sobrien               (match_operand:XF 3 "div_operator" "") 
1418290286Sobrien                 (const_string "fdiv")
1418350650Sobrien              ]
1418490286Sobrien              (const_string "fop")))
1418590286Sobrien   (set_attr "mode" "XF")])
1418618334Speter
1418790286Sobrien(define_insn "*fop_tf_1"
1418890286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1418990286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1419090286Sobrien			[(match_operand:TF 1 "register_operand" "0,f")
1419190286Sobrien			 (match_operand:TF 2 "register_operand" "f,0")]))]
1419290286Sobrien  "TARGET_80387
1419390286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
1419490286Sobrien  "* return output_387_binary_op (insn, operands);"
1419590286Sobrien  [(set (attr "type") 
1419690286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1419790286Sobrien                 (const_string "fmul")
1419890286Sobrien               (match_operand:TF 3 "div_operator" "") 
1419990286Sobrien                 (const_string "fdiv")
1420090286Sobrien              ]
1420190286Sobrien              (const_string "fop")))
1420290286Sobrien   (set_attr "mode" "XF")])
1420390286Sobrien
1420490286Sobrien(define_insn "*fop_xf_2"
1420518334Speter  [(set (match_operand:XF 0 "register_operand" "=f,f")
1420690286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1420790286Sobrien	   [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
1420890286Sobrien	    (match_operand:XF 2 "register_operand" "0,0")]))]
1420990286Sobrien  "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
1421090286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1421190286Sobrien  [(set (attr "type") 
1421290286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1421390286Sobrien                 (const_string "fmul")
1421490286Sobrien               (match_operand:XF 3 "div_operator" "") 
1421590286Sobrien                 (const_string "fdiv")
1421690286Sobrien              ]
1421790286Sobrien              (const_string "fop")))
1421890286Sobrien   (set_attr "fp_int_src" "true")
1421990286Sobrien   (set_attr "mode" "SI")
1422090286Sobrien   (set_attr "ppro_uops" "many")])
1422190286Sobrien
1422290286Sobrien(define_insn "*fop_tf_2"
1422390286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1422490286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1422590286Sobrien	   [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
1422690286Sobrien	    (match_operand:TF 2 "register_operand" "0,0")]))]
1422790286Sobrien  "TARGET_80387 && TARGET_USE_FIOP"
1422890286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1422990286Sobrien  [(set (attr "type") 
1423090286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1423190286Sobrien                 (const_string "fmul")
1423290286Sobrien               (match_operand:TF 3 "div_operator" "") 
1423390286Sobrien                 (const_string "fdiv")
1423490286Sobrien              ]
1423590286Sobrien              (const_string "fop")))
1423690286Sobrien   (set_attr "fp_int_src" "true")
1423790286Sobrien   (set_attr "mode" "SI")
1423890286Sobrien   (set_attr "ppro_uops" "many")])
1423990286Sobrien
1424090286Sobrien(define_insn "*fop_xf_3"
1424190286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1424290286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1424390286Sobrien	  [(match_operand:XF 1 "register_operand" "0,0")
1424490286Sobrien	   (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1424590286Sobrien  "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
1424690286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1424790286Sobrien  [(set (attr "type") 
1424890286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1424990286Sobrien                 (const_string "fmul")
1425090286Sobrien               (match_operand:XF 3 "div_operator" "") 
1425190286Sobrien                 (const_string "fdiv")
1425290286Sobrien              ]
1425390286Sobrien              (const_string "fop")))
1425490286Sobrien   (set_attr "fp_int_src" "true")
1425590286Sobrien   (set_attr "mode" "SI")
1425690286Sobrien   (set_attr "ppro_uops" "many")])
1425790286Sobrien
1425890286Sobrien(define_insn "*fop_tf_3"
1425990286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1426090286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1426190286Sobrien	  [(match_operand:TF 1 "register_operand" "0,0")
1426290286Sobrien	   (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1426390286Sobrien  "TARGET_80387 && TARGET_USE_FIOP"
1426490286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1426590286Sobrien  [(set (attr "type") 
1426690286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1426790286Sobrien                 (const_string "fmul")
1426890286Sobrien               (match_operand:TF 3 "div_operator" "") 
1426990286Sobrien                 (const_string "fdiv")
1427090286Sobrien              ]
1427190286Sobrien              (const_string "fop")))
1427290286Sobrien   (set_attr "fp_int_src" "true")
1427390286Sobrien   (set_attr "mode" "SI")
1427490286Sobrien   (set_attr "ppro_uops" "many")])
1427590286Sobrien
1427690286Sobrien(define_insn "*fop_xf_4"
1427790286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1427890286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1427950650Sobrien	   [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
1428050650Sobrien	    (match_operand:XF 2 "register_operand" "0,f")]))]
1428190286Sobrien  "!TARGET_64BIT && TARGET_80387"
1428290286Sobrien  "* return output_387_binary_op (insn, operands);"
1428390286Sobrien  [(set (attr "type") 
1428490286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1428590286Sobrien                 (const_string "fmul")
1428690286Sobrien               (match_operand:XF 3 "div_operator" "") 
1428790286Sobrien                 (const_string "fdiv")
1428890286Sobrien              ]
1428990286Sobrien              (const_string "fop")))
1429090286Sobrien   (set_attr "mode" "SF")])
1429190286Sobrien
1429290286Sobrien(define_insn "*fop_tf_4"
1429390286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1429490286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1429590286Sobrien	   [(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
1429690286Sobrien	    (match_operand:TF 2 "register_operand" "0,f")]))]
1429718334Speter  "TARGET_80387"
1429850650Sobrien  "* return output_387_binary_op (insn, operands);"
1429950650Sobrien  [(set (attr "type") 
1430090286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1430190286Sobrien                 (const_string "fmul")
1430290286Sobrien               (match_operand:TF 3 "div_operator" "") 
1430390286Sobrien                 (const_string "fdiv")
1430450650Sobrien              ]
1430590286Sobrien              (const_string "fop")))
1430690286Sobrien   (set_attr "mode" "SF")])
1430718334Speter
1430890286Sobrien(define_insn "*fop_xf_5"
1430918334Speter  [(set (match_operand:XF 0 "register_operand" "=f,f")
1431090286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1431150650Sobrien	  [(match_operand:XF 1 "register_operand" "0,f")
1431218334Speter	   (float_extend:XF
1431350650Sobrien	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
1431490286Sobrien  "!TARGET_64BIT && TARGET_80387"
1431550650Sobrien  "* return output_387_binary_op (insn, operands);"
1431650650Sobrien  [(set (attr "type") 
1431790286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1431890286Sobrien                 (const_string "fmul")
1431990286Sobrien               (match_operand:XF 3 "div_operator" "") 
1432090286Sobrien                 (const_string "fdiv")
1432150650Sobrien              ]
1432290286Sobrien              (const_string "fop")))
1432390286Sobrien   (set_attr "mode" "SF")])
1432418334Speter
1432590286Sobrien(define_insn "*fop_tf_5"
1432690286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1432790286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1432890286Sobrien	  [(match_operand:TF 1 "register_operand" "0,f")
1432990286Sobrien	   (float_extend:TF
1433090286Sobrien	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
1433118334Speter  "TARGET_80387"
1433250650Sobrien  "* return output_387_binary_op (insn, operands);"
1433350650Sobrien  [(set (attr "type") 
1433490286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1433590286Sobrien                 (const_string "fmul")
1433690286Sobrien               (match_operand:TF 3 "div_operator" "") 
1433790286Sobrien                 (const_string "fdiv")
1433850650Sobrien              ]
1433990286Sobrien              (const_string "fop")))
1434090286Sobrien   (set_attr "mode" "SF")])
1434118334Speter
1434290286Sobrien(define_insn "*fop_xf_6"
1434390286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1434490286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1434590286Sobrien	   [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
1434690286Sobrien	    (match_operand:XF 2 "register_operand" "0,f")]))]
1434790286Sobrien  "!TARGET_64BIT && TARGET_80387"
1434890286Sobrien  "* return output_387_binary_op (insn, operands);"
1434990286Sobrien  [(set (attr "type") 
1435090286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1435190286Sobrien                 (const_string "fmul")
1435290286Sobrien               (match_operand:XF 3 "div_operator" "") 
1435390286Sobrien                 (const_string "fdiv")
1435490286Sobrien              ]
1435590286Sobrien              (const_string "fop")))
1435690286Sobrien   (set_attr "mode" "DF")])
1435790286Sobrien
1435890286Sobrien(define_insn "*fop_tf_6"
1435990286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1436090286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1436190286Sobrien	   [(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
1436290286Sobrien	    (match_operand:TF 2 "register_operand" "0,f")]))]
1436318334Speter  "TARGET_80387"
1436450650Sobrien  "* return output_387_binary_op (insn, operands);"
1436550650Sobrien  [(set (attr "type") 
1436690286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1436790286Sobrien                 (const_string "fmul")
1436890286Sobrien               (match_operand:TF 3 "div_operator" "") 
1436990286Sobrien                 (const_string "fdiv")
1437050650Sobrien              ]
1437190286Sobrien              (const_string "fop")))
1437290286Sobrien   (set_attr "mode" "DF")])
1437318334Speter
1437490286Sobrien(define_insn "*fop_xf_7"
1437590286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1437690286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1437790286Sobrien	  [(match_operand:XF 1 "register_operand" "0,f")
1437890286Sobrien	   (float_extend:XF
1437990286Sobrien	    (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
1438090286Sobrien  "!TARGET_64BIT && TARGET_80387"
1438190286Sobrien  "* return output_387_binary_op (insn, operands);"
1438290286Sobrien  [(set (attr "type") 
1438390286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1438490286Sobrien                 (const_string "fmul")
1438590286Sobrien               (match_operand:XF 3 "div_operator" "") 
1438690286Sobrien                 (const_string "fdiv")
1438790286Sobrien              ]
1438890286Sobrien              (const_string "fop")))
1438990286Sobrien   (set_attr "mode" "DF")])
1439090286Sobrien
1439190286Sobrien(define_insn "*fop_tf_7"
1439290286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1439390286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1439490286Sobrien	  [(match_operand:TF 1 "register_operand" "0,f")
1439590286Sobrien	   (float_extend:TF
1439690286Sobrien	    (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
1439718334Speter  "TARGET_80387"
1439850650Sobrien  "* return output_387_binary_op (insn, operands);"
1439950650Sobrien  [(set (attr "type") 
1440090286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1440190286Sobrien                 (const_string "fmul")
1440290286Sobrien               (match_operand:TF 3 "div_operator" "") 
1440390286Sobrien                 (const_string "fdiv")
1440450650Sobrien              ]
1440590286Sobrien              (const_string "fop")))
1440690286Sobrien   (set_attr "mode" "DF")])
1440790286Sobrien
1440890286Sobrien(define_split
1440990286Sobrien  [(set (match_operand 0 "register_operand" "")
1441090286Sobrien	(match_operator 3 "binary_fp_operator"
1441190286Sobrien	   [(float (match_operand:SI 1 "register_operand" ""))
1441290286Sobrien	    (match_operand 2 "register_operand" "")]))]
1441390286Sobrien  "TARGET_80387 && reload_completed
1441490286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))"
1441590286Sobrien  [(const_int 0)]
1441690286Sobrien{ 
1441790286Sobrien  operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
1441890286Sobrien  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
1441990286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
1442090286Sobrien			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
1442190286Sobrien					  GET_MODE (operands[3]),
1442290286Sobrien					  operands[4],
1442390286Sobrien					  operands[2])));
1442490286Sobrien  ix86_free_from_memory (GET_MODE (operands[1]));
1442590286Sobrien  DONE;
1442690286Sobrien})
1442790286Sobrien
1442890286Sobrien(define_split
1442990286Sobrien  [(set (match_operand 0 "register_operand" "")
1443090286Sobrien	(match_operator 3 "binary_fp_operator"
1443190286Sobrien	   [(match_operand 1 "register_operand" "")
1443290286Sobrien	    (float (match_operand:SI 2 "register_operand" ""))]))]
1443390286Sobrien  "TARGET_80387 && reload_completed
1443490286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))"
1443590286Sobrien  [(const_int 0)]
1443690286Sobrien{
1443790286Sobrien  operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
1443890286Sobrien  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
1443990286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
1444090286Sobrien			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
1444190286Sobrien					  GET_MODE (operands[3]),
1444290286Sobrien					  operands[1],
1444390286Sobrien					  operands[4])));
1444490286Sobrien  ix86_free_from_memory (GET_MODE (operands[2]));
1444590286Sobrien  DONE;
1444690286Sobrien})
1444718334Speter
1444890286Sobrien;; FPU special functions.
1444990286Sobrien
1445090286Sobrien(define_expand "sqrtsf2"
1445190286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1445290286Sobrien	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
1445390286Sobrien  "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
1445490286Sobrien{
1445590286Sobrien  if (!TARGET_SSE_MATH)
1445690286Sobrien    operands[1] = force_reg (SFmode, operands[1]);
1445790286Sobrien})
1445890286Sobrien
1445990286Sobrien(define_insn "sqrtsf2_1"
1446090286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
1446190286Sobrien	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
1446290286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1446390286Sobrien   && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
1446490286Sobrien  "@
1446590286Sobrien   fsqrt
1446690286Sobrien   sqrtss\t{%1, %0|%0, %1}"
1446790286Sobrien  [(set_attr "type" "fpspc,sse")
1446890286Sobrien   (set_attr "mode" "SF,SF")
1446990286Sobrien   (set_attr "athlon_decode" "direct,*")])
1447090286Sobrien
1447190286Sobrien(define_insn "sqrtsf2_1_sse_only"
1447290286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1447390286Sobrien	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
1447490286Sobrien  "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
1447590286Sobrien  "sqrtss\t{%1, %0|%0, %1}"
1447690286Sobrien  [(set_attr "type" "sse")
1447790286Sobrien   (set_attr "mode" "SF")
1447890286Sobrien   (set_attr "athlon_decode" "*")])
1447990286Sobrien
1448090286Sobrien(define_insn "sqrtsf2_i387"
1448190286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
1448290286Sobrien	(sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
1448390286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1448490286Sobrien   && !TARGET_SSE_MATH"
1448590286Sobrien  "fsqrt"
1448690286Sobrien  [(set_attr "type" "fpspc")
1448790286Sobrien   (set_attr "mode" "SF")
1448890286Sobrien   (set_attr "athlon_decode" "direct")])
1448990286Sobrien
1449090286Sobrien(define_expand "sqrtdf2"
1449190286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1449290286Sobrien	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
1449390286Sobrien  "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
1449490286Sobrien   || (TARGET_SSE2 && TARGET_SSE_MATH)"
1449590286Sobrien{
1449690286Sobrien  if (!TARGET_SSE2 || !TARGET_SSE_MATH)
1449790286Sobrien    operands[1] = force_reg (DFmode, operands[1]);
1449890286Sobrien})
1449990286Sobrien
1450090286Sobrien(define_insn "sqrtdf2_1"
1450190286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
1450290286Sobrien	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
1450390286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1450490286Sobrien   && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
1450590286Sobrien  "@
1450690286Sobrien   fsqrt
1450790286Sobrien   sqrtsd\t{%1, %0|%0, %1}"
1450890286Sobrien  [(set_attr "type" "fpspc,sse")
1450990286Sobrien   (set_attr "mode" "DF,DF")
1451090286Sobrien   (set_attr "athlon_decode" "direct,*")])
1451190286Sobrien
1451290286Sobrien(define_insn "sqrtdf2_1_sse_only"
1451390286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1451490286Sobrien	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
1451590286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
1451690286Sobrien  "sqrtsd\t{%1, %0|%0, %1}"
1451790286Sobrien  [(set_attr "type" "sse")
1451890286Sobrien   (set_attr "mode" "DF")
1451990286Sobrien   (set_attr "athlon_decode" "*")])
1452090286Sobrien
1452190286Sobrien(define_insn "sqrtdf2_i387"
1452290286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1452390286Sobrien	(sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
1452490286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1452590286Sobrien   && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
1452690286Sobrien  "fsqrt"
1452790286Sobrien  [(set_attr "type" "fpspc")
1452890286Sobrien   (set_attr "mode" "DF")
1452990286Sobrien   (set_attr "athlon_decode" "direct")])
1453090286Sobrien
1453190286Sobrien(define_insn "*sqrtextendsfdf2"
1453290286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1453390286Sobrien	(sqrt:DF (float_extend:DF
1453490286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
1453590286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1453690286Sobrien   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
1453790286Sobrien  "fsqrt"
1453890286Sobrien  [(set_attr "type" "fpspc")
1453990286Sobrien   (set_attr "mode" "DF")
1454090286Sobrien   (set_attr "athlon_decode" "direct")])
1454190286Sobrien
1454290286Sobrien(define_insn "sqrtxf2"
1454390286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1454490286Sobrien	(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
1454590286Sobrien  "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
1454690286Sobrien   && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
1454790286Sobrien  "fsqrt"
1454890286Sobrien  [(set_attr "type" "fpspc")
1454990286Sobrien   (set_attr "mode" "XF")
1455090286Sobrien   (set_attr "athlon_decode" "direct")])
1455190286Sobrien
1455290286Sobrien(define_insn "sqrttf2"
1455390286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1455490286Sobrien	(sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
1455590286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1455690286Sobrien   && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
1455790286Sobrien  "fsqrt"
1455890286Sobrien  [(set_attr "type" "fpspc")
1455990286Sobrien   (set_attr "mode" "XF")
1456090286Sobrien   (set_attr "athlon_decode" "direct")])
1456190286Sobrien
1456290286Sobrien(define_insn "*sqrtextenddfxf2"
1456390286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1456490286Sobrien	(sqrt:XF (float_extend:XF
1456590286Sobrien		  (match_operand:DF 1 "register_operand" "0"))))]
1456690286Sobrien  "!TARGET_64BIT && TARGET_80387 && TARGET_NO_FANCY_MATH_387"
1456790286Sobrien  "fsqrt"
1456890286Sobrien  [(set_attr "type" "fpspc")
1456990286Sobrien   (set_attr "mode" "XF")
1457090286Sobrien   (set_attr "athlon_decode" "direct")])
1457190286Sobrien
1457290286Sobrien(define_insn "*sqrtextenddftf2"
1457390286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1457490286Sobrien	(sqrt:TF (float_extend:TF
1457590286Sobrien		  (match_operand:DF 1 "register_operand" "0"))))]
1457690286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
1457790286Sobrien  "fsqrt"
1457890286Sobrien  [(set_attr "type" "fpspc")
1457990286Sobrien   (set_attr "mode" "XF")
1458090286Sobrien   (set_attr "athlon_decode" "direct")])
1458190286Sobrien
1458290286Sobrien(define_insn "*sqrtextendsfxf2"
1458390286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1458490286Sobrien	(sqrt:XF (float_extend:XF
1458590286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
1458690286Sobrien  "!TARGET_64BIT && TARGET_80387 && TARGET_NO_FANCY_MATH_387"
1458790286Sobrien  "fsqrt"
1458890286Sobrien  [(set_attr "type" "fpspc")
1458990286Sobrien   (set_attr "mode" "XF")
1459090286Sobrien   (set_attr "athlon_decode" "direct")])
1459190286Sobrien
1459290286Sobrien(define_insn "*sqrtextendsftf2"
1459390286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1459490286Sobrien	(sqrt:TF (float_extend:TF
1459590286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
1459690286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
1459790286Sobrien  "fsqrt"
1459890286Sobrien  [(set_attr "type" "fpspc")
1459990286Sobrien   (set_attr "mode" "XF")
1460090286Sobrien   (set_attr "athlon_decode" "direct")])
1460190286Sobrien
1460290286Sobrien(define_insn "sindf2"
1460390286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1460490286Sobrien	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
1460590286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1460690286Sobrien   && flag_unsafe_math_optimizations"
1460790286Sobrien  "fsin"
1460890286Sobrien  [(set_attr "type" "fpspc")
1460990286Sobrien   (set_attr "mode" "DF")])
1461090286Sobrien
1461190286Sobrien(define_insn "sinsf2"
1461290286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
1461390286Sobrien	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
1461490286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1461590286Sobrien   && flag_unsafe_math_optimizations"
1461690286Sobrien  "fsin"
1461790286Sobrien  [(set_attr "type" "fpspc")
1461890286Sobrien   (set_attr "mode" "SF")])
1461990286Sobrien
1462090286Sobrien(define_insn "*sinextendsfdf2"
1462190286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1462290286Sobrien	(unspec:DF [(float_extend:DF
1462390286Sobrien		     (match_operand:SF 1 "register_operand" "0"))] 1))]
1462490286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1462590286Sobrien   && flag_unsafe_math_optimizations"
1462690286Sobrien  "fsin"
1462790286Sobrien  [(set_attr "type" "fpspc")
1462890286Sobrien   (set_attr "mode" "DF")])
1462990286Sobrien
1463090286Sobrien(define_insn "sinxf2"
1463190286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1463290286Sobrien	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
1463390286Sobrien  "!TARGET_64BIT && TARGET_80387 && TARGET_NO_FANCY_MATH_387
1463490286Sobrien   && flag_unsafe_math_optimizations"
1463590286Sobrien  "fsin"
1463690286Sobrien  [(set_attr "type" "fpspc")
1463790286Sobrien   (set_attr "mode" "XF")])
1463890286Sobrien
1463990286Sobrien(define_insn "sintf2"
1464090286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1464190286Sobrien	(unspec:TF [(match_operand:TF 1 "register_operand" "0")] 1))]
1464290286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1464390286Sobrien   && flag_unsafe_math_optimizations"
1464490286Sobrien  "fsin"
1464590286Sobrien  [(set_attr "type" "fpspc")
1464690286Sobrien   (set_attr "mode" "XF")])
1464790286Sobrien
1464890286Sobrien(define_insn "cosdf2"
1464990286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1465090286Sobrien	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
1465190286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1465290286Sobrien   && flag_unsafe_math_optimizations"
1465390286Sobrien  "fcos"
1465490286Sobrien  [(set_attr "type" "fpspc")
1465590286Sobrien   (set_attr "mode" "DF")])
1465690286Sobrien
1465790286Sobrien(define_insn "cossf2"
1465890286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
1465990286Sobrien	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
1466090286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1466190286Sobrien   && flag_unsafe_math_optimizations"
1466290286Sobrien  "fcos"
1466390286Sobrien  [(set_attr "type" "fpspc")
1466490286Sobrien   (set_attr "mode" "SF")])
1466590286Sobrien
1466690286Sobrien(define_insn "*cosextendsfdf2"
1466790286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1466890286Sobrien	(unspec:DF [(float_extend:DF
1466990286Sobrien		     (match_operand:SF 1 "register_operand" "0"))] 2))]
1467090286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1467190286Sobrien   && flag_unsafe_math_optimizations"
1467290286Sobrien  "fcos"
1467390286Sobrien  [(set_attr "type" "fpspc")
1467490286Sobrien   (set_attr "mode" "DF")])
1467590286Sobrien
1467690286Sobrien(define_insn "cosxf2"
1467790286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1467890286Sobrien	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
1467990286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1468090286Sobrien   && flag_unsafe_math_optimizations"
1468190286Sobrien  "fcos"
1468290286Sobrien  [(set_attr "type" "fpspc")
1468390286Sobrien   (set_attr "mode" "XF")])
1468490286Sobrien
1468590286Sobrien(define_insn "costf2"
1468690286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1468790286Sobrien	(unspec:TF [(match_operand:TF 1 "register_operand" "0")] 2))]
1468890286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1468990286Sobrien   && flag_unsafe_math_optimizations"
1469090286Sobrien  "fcos"
1469190286Sobrien  [(set_attr "type" "fpspc")
1469290286Sobrien   (set_attr "mode" "XF")])
1469390286Sobrien
1469490286Sobrien;; Block operation instructions
1469590286Sobrien
1469690286Sobrien(define_insn "cld"
1469790286Sobrien [(set (reg:SI 19) (const_int 0))]
1469890286Sobrien ""
1469990286Sobrien "cld"
1470090286Sobrien  [(set_attr "type" "cld")])
1470190286Sobrien
1470290286Sobrien(define_expand "movstrsi"
1470390286Sobrien  [(use (match_operand:BLK 0 "memory_operand" ""))
1470490286Sobrien   (use (match_operand:BLK 1 "memory_operand" ""))
1470590286Sobrien   (use (match_operand:SI 2 "nonmemory_operand" ""))
1470690286Sobrien   (use (match_operand:SI 3 "const_int_operand" ""))]
1470718334Speter  ""
1470818334Speter{
1470990286Sobrien if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
1471090286Sobrien   DONE;
1471190286Sobrien else
1471290286Sobrien   FAIL;
1471390286Sobrien})
1471490286Sobrien
1471590286Sobrien(define_expand "movstrdi"
1471690286Sobrien  [(use (match_operand:BLK 0 "memory_operand" ""))
1471790286Sobrien   (use (match_operand:BLK 1 "memory_operand" ""))
1471890286Sobrien   (use (match_operand:DI 2 "nonmemory_operand" ""))
1471990286Sobrien   (use (match_operand:DI 3 "const_int_operand" ""))]
1472090286Sobrien  "TARGET_64BIT"
1472190286Sobrien{
1472290286Sobrien if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
1472390286Sobrien   DONE;
1472490286Sobrien else
1472590286Sobrien   FAIL;
1472690286Sobrien})
1472790286Sobrien
1472890286Sobrien;; Most CPUs don't like single string operations
1472990286Sobrien;; Handle this case here to simplify previous expander.
1473090286Sobrien
1473190286Sobrien(define_expand "strmovdi_rex64"
1473290286Sobrien  [(set (match_dup 2)
1473390286Sobrien  	(mem:DI (match_operand:DI 1 "register_operand" "")))
1473490286Sobrien   (set (mem:DI (match_operand:DI 0 "register_operand" ""))
1473590286Sobrien        (match_dup 2))
1473690286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
1473790286Sobrien	      (clobber (reg:CC 17))])
1473890286Sobrien   (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
1473990286Sobrien	      (clobber (reg:CC 17))])]
1474090286Sobrien  "TARGET_64BIT"
1474190286Sobrien{
1474290286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1474350650Sobrien    {
1474490286Sobrien      emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
1474590286Sobrien				     operands[1]));
1474690286Sobrien      DONE;
1474790286Sobrien    }
1474890286Sobrien  else 
1474990286Sobrien    operands[2] = gen_reg_rtx (DImode);
1475090286Sobrien})
1475150650Sobrien
1475250650Sobrien
1475390286Sobrien(define_expand "strmovsi"
1475490286Sobrien  [(set (match_dup 2)
1475590286Sobrien  	(mem:SI (match_operand:SI 1 "register_operand" "")))
1475690286Sobrien   (set (mem:SI (match_operand:SI 0 "register_operand" ""))
1475790286Sobrien        (match_dup 2))
1475890286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
1475990286Sobrien	      (clobber (reg:CC 17))])
1476090286Sobrien   (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
1476190286Sobrien	      (clobber (reg:CC 17))])]
1476290286Sobrien  ""
1476390286Sobrien{
1476490286Sobrien  if (TARGET_64BIT)
1476590286Sobrien    {
1476690286Sobrien      emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
1476790286Sobrien      DONE;
1476890286Sobrien    }
1476990286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1477090286Sobrien    {
1477190286Sobrien      emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
1477290286Sobrien				operands[1]));
1477390286Sobrien      DONE;
1477490286Sobrien    }
1477590286Sobrien  else 
1477690286Sobrien    operands[2] = gen_reg_rtx (SImode);
1477790286Sobrien})
1477850650Sobrien
1477990286Sobrien(define_expand "strmovsi_rex64"
1478090286Sobrien  [(set (match_dup 2)
1478190286Sobrien  	(mem:SI (match_operand:DI 1 "register_operand" "")))
1478290286Sobrien   (set (mem:SI (match_operand:DI 0 "register_operand" ""))
1478390286Sobrien        (match_dup 2))
1478490286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
1478590286Sobrien	      (clobber (reg:CC 17))])
1478690286Sobrien   (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
1478790286Sobrien	      (clobber (reg:CC 17))])]
1478890286Sobrien  "TARGET_64BIT"
1478990286Sobrien{
1479090286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1479190286Sobrien    {
1479290286Sobrien      emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
1479390286Sobrien				     operands[1]));
1479490286Sobrien      DONE;
1479590286Sobrien    }
1479690286Sobrien  else 
1479790286Sobrien    operands[2] = gen_reg_rtx (SImode);
1479890286Sobrien})
1479950650Sobrien
1480090286Sobrien(define_expand "strmovhi"
1480190286Sobrien  [(set (match_dup 2)
1480290286Sobrien  	(mem:HI (match_operand:SI 1 "register_operand" "")))
1480390286Sobrien   (set (mem:HI (match_operand:SI 0 "register_operand" ""))
1480490286Sobrien        (match_dup 2))
1480590286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
1480690286Sobrien	      (clobber (reg:CC 17))])
1480790286Sobrien   (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
1480890286Sobrien	      (clobber (reg:CC 17))])]
1480990286Sobrien  ""
1481090286Sobrien{
1481190286Sobrien  if (TARGET_64BIT)
1481290286Sobrien    {
1481390286Sobrien      emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
1481490286Sobrien      DONE;
1481590286Sobrien    }
1481690286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1481790286Sobrien    {
1481890286Sobrien      emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
1481990286Sobrien				operands[1]));
1482090286Sobrien      DONE;
1482190286Sobrien    }
1482290286Sobrien  else 
1482390286Sobrien    operands[2] = gen_reg_rtx (HImode);
1482490286Sobrien})
1482550650Sobrien
1482690286Sobrien(define_expand "strmovhi_rex64"
1482790286Sobrien  [(set (match_dup 2)
1482890286Sobrien  	(mem:HI (match_operand:DI 1 "register_operand" "")))
1482990286Sobrien   (set (mem:HI (match_operand:DI 0 "register_operand" ""))
1483090286Sobrien        (match_dup 2))
1483190286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
1483290286Sobrien	      (clobber (reg:CC 17))])
1483390286Sobrien   (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
1483490286Sobrien	      (clobber (reg:CC 17))])]
1483590286Sobrien  "TARGET_64BIT"
1483690286Sobrien{
1483790286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1483890286Sobrien    {
1483990286Sobrien      emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
1484090286Sobrien				     operands[1]));
1484150650Sobrien      DONE;
1484250650Sobrien    }
1484390286Sobrien  else 
1484490286Sobrien    operands[2] = gen_reg_rtx (HImode);
1484590286Sobrien})
1484650650Sobrien
1484790286Sobrien(define_expand "strmovqi"
1484890286Sobrien  [(set (match_dup 2)
1484990286Sobrien  	(mem:QI (match_operand:SI 1 "register_operand" "")))
1485090286Sobrien   (set (mem:QI (match_operand:SI 0 "register_operand" ""))
1485190286Sobrien        (match_dup 2))
1485290286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
1485390286Sobrien	      (clobber (reg:CC 17))])
1485490286Sobrien   (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
1485590286Sobrien	      (clobber (reg:CC 17))])]
1485690286Sobrien  ""
1485790286Sobrien{
1485890286Sobrien  if (TARGET_64BIT)
1485990286Sobrien    {
1486090286Sobrien      emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
1486190286Sobrien      DONE;
1486290286Sobrien    }
1486390286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1486490286Sobrien    {
1486590286Sobrien      emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
1486690286Sobrien				operands[1]));
1486790286Sobrien      DONE;
1486890286Sobrien    }
1486990286Sobrien  else 
1487090286Sobrien    operands[2] = gen_reg_rtx (QImode);
1487190286Sobrien})
1487218334Speter
1487390286Sobrien(define_expand "strmovqi_rex64"
1487490286Sobrien  [(set (match_dup 2)
1487590286Sobrien  	(mem:QI (match_operand:DI 1 "register_operand" "")))
1487690286Sobrien   (set (mem:QI (match_operand:DI 0 "register_operand" ""))
1487790286Sobrien        (match_dup 2))
1487890286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
1487990286Sobrien	      (clobber (reg:CC 17))])
1488090286Sobrien   (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
1488190286Sobrien	      (clobber (reg:CC 17))])]
1488290286Sobrien  "TARGET_64BIT"
1488390286Sobrien{
1488490286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1488590286Sobrien    {
1488690286Sobrien      emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
1488790286Sobrien				     operands[1]));
1488890286Sobrien      DONE;
1488990286Sobrien    }
1489090286Sobrien  else 
1489190286Sobrien    operands[2] = gen_reg_rtx (QImode);
1489290286Sobrien})
1489318334Speter
1489490286Sobrien(define_insn "strmovdi_rex_1"
1489590286Sobrien  [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
1489690286Sobrien	(mem:DI (match_operand:DI 3 "register_operand" "1")))
1489790286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1489890286Sobrien	(plus:DI (match_dup 2)
1489990286Sobrien		 (const_int 8)))
1490090286Sobrien   (set (match_operand:DI 1 "register_operand" "=S")
1490190286Sobrien	(plus:DI (match_dup 3)
1490290286Sobrien		 (const_int 8)))
1490390286Sobrien   (use (reg:SI 19))]
1490490286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1490590286Sobrien  "movsq"
1490690286Sobrien  [(set_attr "type" "str")
1490790286Sobrien   (set_attr "mode" "DI")
1490890286Sobrien   (set_attr "memory" "both")])
1490990286Sobrien
1491090286Sobrien(define_insn "strmovsi_1"
1491190286Sobrien  [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
1491290286Sobrien	(mem:SI (match_operand:SI 3 "register_operand" "1")))
1491390286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1491490286Sobrien	(plus:SI (match_dup 2)
1491590286Sobrien		 (const_int 4)))
1491690286Sobrien   (set (match_operand:SI 1 "register_operand" "=S")
1491790286Sobrien	(plus:SI (match_dup 3)
1491890286Sobrien		 (const_int 4)))
1491990286Sobrien   (use (reg:SI 19))]
1492090286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1492190286Sobrien  "{movsl|movsd}"
1492290286Sobrien  [(set_attr "type" "str")
1492390286Sobrien   (set_attr "mode" "SI")
1492490286Sobrien   (set_attr "memory" "both")])
1492590286Sobrien
1492690286Sobrien(define_insn "strmovsi_rex_1"
1492790286Sobrien  [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
1492890286Sobrien	(mem:SI (match_operand:DI 3 "register_operand" "1")))
1492990286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1493090286Sobrien	(plus:DI (match_dup 2)
1493190286Sobrien		 (const_int 4)))
1493290286Sobrien   (set (match_operand:DI 1 "register_operand" "=S")
1493390286Sobrien	(plus:DI (match_dup 3)
1493490286Sobrien		 (const_int 4)))
1493590286Sobrien   (use (reg:SI 19))]
1493690286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1493790286Sobrien  "{movsl|movsd}"
1493890286Sobrien  [(set_attr "type" "str")
1493990286Sobrien   (set_attr "mode" "SI")
1494090286Sobrien   (set_attr "memory" "both")])
1494190286Sobrien
1494290286Sobrien(define_insn "strmovhi_1"
1494390286Sobrien  [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
1494490286Sobrien	(mem:HI (match_operand:SI 3 "register_operand" "1")))
1494590286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1494690286Sobrien	(plus:SI (match_dup 2)
1494790286Sobrien		 (const_int 2)))
1494890286Sobrien   (set (match_operand:SI 1 "register_operand" "=S")
1494990286Sobrien	(plus:SI (match_dup 3)
1495090286Sobrien		 (const_int 2)))
1495190286Sobrien   (use (reg:SI 19))]
1495290286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1495390286Sobrien  "movsw"
1495490286Sobrien  [(set_attr "type" "str")
1495590286Sobrien   (set_attr "memory" "both")
1495690286Sobrien   (set_attr "mode" "HI")])
1495790286Sobrien
1495890286Sobrien(define_insn "strmovhi_rex_1"
1495990286Sobrien  [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
1496090286Sobrien	(mem:HI (match_operand:DI 3 "register_operand" "1")))
1496190286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1496290286Sobrien	(plus:DI (match_dup 2)
1496390286Sobrien		 (const_int 2)))
1496490286Sobrien   (set (match_operand:DI 1 "register_operand" "=S")
1496590286Sobrien	(plus:DI (match_dup 3)
1496690286Sobrien		 (const_int 2)))
1496790286Sobrien   (use (reg:SI 19))]
1496890286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1496990286Sobrien  "movsw"
1497090286Sobrien  [(set_attr "type" "str")
1497190286Sobrien   (set_attr "memory" "both")
1497290286Sobrien   (set_attr "mode" "HI")])
1497390286Sobrien
1497490286Sobrien(define_insn "strmovqi_1"
1497590286Sobrien  [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
1497690286Sobrien	(mem:QI (match_operand:SI 3 "register_operand" "1")))
1497790286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1497890286Sobrien	(plus:SI (match_dup 2)
1497990286Sobrien		 (const_int 1)))
1498090286Sobrien   (set (match_operand:SI 1 "register_operand" "=S")
1498190286Sobrien	(plus:SI (match_dup 3)
1498290286Sobrien		 (const_int 1)))
1498390286Sobrien   (use (reg:SI 19))]
1498490286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1498590286Sobrien  "movsb"
1498690286Sobrien  [(set_attr "type" "str")
1498790286Sobrien   (set_attr "memory" "both")
1498890286Sobrien   (set_attr "mode" "QI")])
1498990286Sobrien
1499090286Sobrien(define_insn "strmovqi_rex_1"
1499190286Sobrien  [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
1499290286Sobrien	(mem:QI (match_operand:DI 3 "register_operand" "1")))
1499390286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1499490286Sobrien	(plus:DI (match_dup 2)
1499590286Sobrien		 (const_int 1)))
1499690286Sobrien   (set (match_operand:DI 1 "register_operand" "=S")
1499790286Sobrien	(plus:DI (match_dup 3)
1499890286Sobrien		 (const_int 1)))
1499990286Sobrien   (use (reg:SI 19))]
1500090286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1500190286Sobrien  "movsb"
1500290286Sobrien  [(set_attr "type" "str")
1500390286Sobrien   (set_attr "memory" "both")
1500490286Sobrien   (set_attr "mode" "QI")])
1500590286Sobrien
1500690286Sobrien(define_insn "rep_movdi_rex64"
1500790286Sobrien  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
1500890286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1500990286Sobrien        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
1501090286Sobrien			    (const_int 3))
1501190286Sobrien		 (match_operand:DI 3 "register_operand" "0")))
1501290286Sobrien   (set (match_operand:DI 1 "register_operand" "=S") 
1501390286Sobrien        (plus:DI (ashift:DI (match_dup 5) (const_int 3))
1501490286Sobrien		 (match_operand:DI 4 "register_operand" "1")))
1501590286Sobrien   (set (mem:BLK (match_dup 3))
1501690286Sobrien	(mem:BLK (match_dup 4)))
1501790286Sobrien   (use (match_dup 5))
1501890286Sobrien   (use (reg:SI 19))]
1501990286Sobrien  "TARGET_64BIT"
1502090286Sobrien  "{rep\;movsq|rep movsq}"
1502190286Sobrien  [(set_attr "type" "str")
1502290286Sobrien   (set_attr "prefix_rep" "1")
1502390286Sobrien   (set_attr "memory" "both")
1502490286Sobrien   (set_attr "mode" "DI")])
1502590286Sobrien
1502690286Sobrien(define_insn "rep_movsi"
1502790286Sobrien  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
1502890286Sobrien   (set (match_operand:SI 0 "register_operand" "=D") 
1502990286Sobrien        (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
1503090286Sobrien			    (const_int 2))
1503190286Sobrien		 (match_operand:SI 3 "register_operand" "0")))
1503290286Sobrien   (set (match_operand:SI 1 "register_operand" "=S") 
1503390286Sobrien        (plus:SI (ashift:SI (match_dup 5) (const_int 2))
1503490286Sobrien		 (match_operand:SI 4 "register_operand" "1")))
1503590286Sobrien   (set (mem:BLK (match_dup 3))
1503690286Sobrien	(mem:BLK (match_dup 4)))
1503790286Sobrien   (use (match_dup 5))
1503890286Sobrien   (use (reg:SI 19))]
1503990286Sobrien  "!TARGET_64BIT"
1504090286Sobrien  "{rep\;movsl|rep movsd}"
1504190286Sobrien  [(set_attr "type" "str")
1504290286Sobrien   (set_attr "prefix_rep" "1")
1504390286Sobrien   (set_attr "memory" "both")
1504490286Sobrien   (set_attr "mode" "SI")])
1504590286Sobrien
1504690286Sobrien(define_insn "rep_movsi_rex64"
1504790286Sobrien  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
1504890286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1504990286Sobrien        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
1505090286Sobrien			    (const_int 2))
1505190286Sobrien		 (match_operand:DI 3 "register_operand" "0")))
1505290286Sobrien   (set (match_operand:DI 1 "register_operand" "=S") 
1505390286Sobrien        (plus:DI (ashift:DI (match_dup 5) (const_int 2))
1505490286Sobrien		 (match_operand:DI 4 "register_operand" "1")))
1505590286Sobrien   (set (mem:BLK (match_dup 3))
1505690286Sobrien	(mem:BLK (match_dup 4)))
1505790286Sobrien   (use (match_dup 5))
1505890286Sobrien   (use (reg:SI 19))]
1505990286Sobrien  "TARGET_64BIT"
1506090286Sobrien  "{rep\;movsl|rep movsd}"
1506190286Sobrien  [(set_attr "type" "str")
1506290286Sobrien   (set_attr "prefix_rep" "1")
1506390286Sobrien   (set_attr "memory" "both")
1506490286Sobrien   (set_attr "mode" "SI")])
1506590286Sobrien
1506690286Sobrien(define_insn "rep_movqi"
1506790286Sobrien  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
1506890286Sobrien   (set (match_operand:SI 0 "register_operand" "=D") 
1506990286Sobrien        (plus:SI (match_operand:SI 3 "register_operand" "0")
1507090286Sobrien		 (match_operand:SI 5 "register_operand" "2")))
1507190286Sobrien   (set (match_operand:SI 1 "register_operand" "=S") 
1507290286Sobrien        (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
1507390286Sobrien   (set (mem:BLK (match_dup 3))
1507490286Sobrien	(mem:BLK (match_dup 4)))
1507590286Sobrien   (use (match_dup 5))
1507690286Sobrien   (use (reg:SI 19))]
1507790286Sobrien  "!TARGET_64BIT"
1507890286Sobrien  "{rep\;movsb|rep movsb}"
1507990286Sobrien  [(set_attr "type" "str")
1508090286Sobrien   (set_attr "prefix_rep" "1")
1508190286Sobrien   (set_attr "memory" "both")
1508290286Sobrien   (set_attr "mode" "SI")])
1508390286Sobrien
1508490286Sobrien(define_insn "rep_movqi_rex64"
1508590286Sobrien  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
1508690286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1508790286Sobrien        (plus:DI (match_operand:DI 3 "register_operand" "0")
1508890286Sobrien		 (match_operand:DI 5 "register_operand" "2")))
1508990286Sobrien   (set (match_operand:DI 1 "register_operand" "=S") 
1509090286Sobrien        (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
1509190286Sobrien   (set (mem:BLK (match_dup 3))
1509290286Sobrien	(mem:BLK (match_dup 4)))
1509390286Sobrien   (use (match_dup 5))
1509490286Sobrien   (use (reg:SI 19))]
1509590286Sobrien  "TARGET_64BIT"
1509690286Sobrien  "{rep\;movsb|rep movsb}"
1509790286Sobrien  [(set_attr "type" "str")
1509890286Sobrien   (set_attr "prefix_rep" "1")
1509990286Sobrien   (set_attr "memory" "both")
1510090286Sobrien   (set_attr "mode" "SI")])
1510190286Sobrien
1510290286Sobrien(define_expand "clrstrsi"
1510390286Sobrien   [(use (match_operand:BLK 0 "memory_operand" ""))
1510490286Sobrien    (use (match_operand:SI 1 "nonmemory_operand" ""))
1510590286Sobrien    (use (match_operand 2 "const_int_operand" ""))]
1510618334Speter  ""
1510718334Speter{
1510890286Sobrien if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
1510990286Sobrien   DONE;
1511090286Sobrien else
1511190286Sobrien   FAIL;
1511290286Sobrien})
1511318334Speter
1511490286Sobrien(define_expand "clrstrdi"
1511590286Sobrien   [(use (match_operand:BLK 0 "memory_operand" ""))
1511690286Sobrien    (use (match_operand:DI 1 "nonmemory_operand" ""))
1511790286Sobrien    (use (match_operand 2 "const_int_operand" ""))]
1511890286Sobrien  "TARGET_64BIT"
1511990286Sobrien{
1512090286Sobrien if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
1512190286Sobrien   DONE;
1512290286Sobrien else
1512390286Sobrien   FAIL;
1512490286Sobrien})
1512550650Sobrien
1512690286Sobrien;; Most CPUs don't like single string operations
1512790286Sobrien;; Handle this case here to simplify previous expander.
1512850650Sobrien
1512990286Sobrien(define_expand "strsetdi_rex64"
1513090286Sobrien  [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
1513190286Sobrien	(match_operand:DI 1 "register_operand" ""))
1513290286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
1513390286Sobrien	      (clobber (reg:CC 17))])]
1513490286Sobrien  "TARGET_64BIT"
1513590286Sobrien{
1513690286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1513790286Sobrien    {
1513890286Sobrien      emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
1513990286Sobrien      DONE;
1514090286Sobrien    }
1514190286Sobrien})
1514290286Sobrien
1514390286Sobrien(define_expand "strsetsi"
1514490286Sobrien  [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
1514590286Sobrien	(match_operand:SI 1 "register_operand" ""))
1514690286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
1514790286Sobrien	      (clobber (reg:CC 17))])]
1514890286Sobrien  ""
1514990286Sobrien{
1515090286Sobrien  if (TARGET_64BIT)
1515190286Sobrien    {
1515290286Sobrien      emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
1515390286Sobrien      DONE;
1515490286Sobrien    }
1515590286Sobrien  else if (TARGET_SINGLE_STRINGOP || optimize_size)
1515690286Sobrien    {
1515790286Sobrien      emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
1515890286Sobrien      DONE;
1515990286Sobrien    }
1516090286Sobrien})
1516190286Sobrien
1516290286Sobrien(define_expand "strsetsi_rex64"
1516390286Sobrien  [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
1516490286Sobrien	(match_operand:SI 1 "register_operand" ""))
1516590286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
1516690286Sobrien	      (clobber (reg:CC 17))])]
1516790286Sobrien  "TARGET_64BIT"
1516890286Sobrien{
1516990286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1517090286Sobrien    {
1517190286Sobrien      emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
1517290286Sobrien      DONE;
1517390286Sobrien    }
1517490286Sobrien})
1517590286Sobrien
1517690286Sobrien(define_expand "strsethi"
1517790286Sobrien  [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
1517890286Sobrien	(match_operand:HI 1 "register_operand" ""))
1517990286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
1518090286Sobrien	      (clobber (reg:CC 17))])]
1518190286Sobrien  ""
1518290286Sobrien{
1518390286Sobrien  if (TARGET_64BIT)
1518490286Sobrien    {
1518590286Sobrien      emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
1518690286Sobrien      DONE;
1518790286Sobrien    }
1518890286Sobrien  else if (TARGET_SINGLE_STRINGOP || optimize_size)
1518990286Sobrien    {
1519090286Sobrien      emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
1519190286Sobrien      DONE;
1519290286Sobrien    }
1519390286Sobrien})
1519490286Sobrien
1519590286Sobrien(define_expand "strsethi_rex64"
1519690286Sobrien  [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
1519790286Sobrien	(match_operand:HI 1 "register_operand" ""))
1519890286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
1519990286Sobrien	      (clobber (reg:CC 17))])]
1520090286Sobrien  "TARGET_64BIT"
1520190286Sobrien{
1520290286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1520390286Sobrien    {
1520490286Sobrien      emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
1520590286Sobrien      DONE;
1520690286Sobrien    }
1520790286Sobrien})
1520890286Sobrien
1520990286Sobrien(define_expand "strsetqi"
1521090286Sobrien  [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
1521190286Sobrien	(match_operand:QI 1 "register_operand" ""))
1521290286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
1521390286Sobrien	      (clobber (reg:CC 17))])]
1521490286Sobrien  ""
1521590286Sobrien{
1521690286Sobrien  if (TARGET_64BIT)
1521790286Sobrien    {
1521890286Sobrien      emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
1521990286Sobrien      DONE;
1522090286Sobrien    }
1522190286Sobrien  else if (TARGET_SINGLE_STRINGOP || optimize_size)
1522290286Sobrien    {
1522390286Sobrien      emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
1522490286Sobrien      DONE;
1522590286Sobrien    }
1522690286Sobrien})
1522790286Sobrien
1522890286Sobrien(define_expand "strsetqi_rex64"
1522990286Sobrien  [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
1523090286Sobrien	(match_operand:QI 1 "register_operand" ""))
1523190286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
1523290286Sobrien	      (clobber (reg:CC 17))])]
1523390286Sobrien  "TARGET_64BIT"
1523490286Sobrien{
1523590286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1523690286Sobrien    {
1523790286Sobrien      emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
1523890286Sobrien      DONE;
1523990286Sobrien    }
1524090286Sobrien})
1524190286Sobrien
1524290286Sobrien(define_insn "strsetdi_rex_1"
1524390286Sobrien  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
1524490286Sobrien	(match_operand:SI 2 "register_operand" "a"))
1524590286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1524690286Sobrien	(plus:DI (match_dup 1)
1524790286Sobrien		 (const_int 8)))
1524890286Sobrien   (use (reg:SI 19))]
1524990286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1525090286Sobrien  "stosq"
1525190286Sobrien  [(set_attr "type" "str")
1525290286Sobrien   (set_attr "memory" "store")
1525390286Sobrien   (set_attr "mode" "DI")])
1525490286Sobrien
1525590286Sobrien(define_insn "strsetsi_1"
1525690286Sobrien  [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
1525790286Sobrien	(match_operand:SI 2 "register_operand" "a"))
1525890286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1525990286Sobrien	(plus:SI (match_dup 1)
1526090286Sobrien		 (const_int 4)))
1526190286Sobrien   (use (reg:SI 19))]
1526290286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1526390286Sobrien  "{stosl|stosd}"
1526490286Sobrien  [(set_attr "type" "str")
1526590286Sobrien   (set_attr "memory" "store")
1526690286Sobrien   (set_attr "mode" "SI")])
1526790286Sobrien
1526890286Sobrien(define_insn "strsetsi_rex_1"
1526990286Sobrien  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
1527090286Sobrien	(match_operand:SI 2 "register_operand" "a"))
1527190286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1527290286Sobrien	(plus:DI (match_dup 1)
1527390286Sobrien		 (const_int 4)))
1527490286Sobrien   (use (reg:SI 19))]
1527590286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1527690286Sobrien  "{stosl|stosd}"
1527790286Sobrien  [(set_attr "type" "str")
1527890286Sobrien   (set_attr "memory" "store")
1527990286Sobrien   (set_attr "mode" "SI")])
1528090286Sobrien
1528190286Sobrien(define_insn "strsethi_1"
1528290286Sobrien  [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
1528390286Sobrien	(match_operand:HI 2 "register_operand" "a"))
1528490286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1528590286Sobrien	(plus:SI (match_dup 1)
1528690286Sobrien		 (const_int 2)))
1528790286Sobrien   (use (reg:SI 19))]
1528890286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1528990286Sobrien  "stosw"
1529090286Sobrien  [(set_attr "type" "str")
1529190286Sobrien   (set_attr "memory" "store")
1529290286Sobrien   (set_attr "mode" "HI")])
1529390286Sobrien
1529490286Sobrien(define_insn "strsethi_rex_1"
1529590286Sobrien  [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
1529690286Sobrien	(match_operand:HI 2 "register_operand" "a"))
1529790286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1529890286Sobrien	(plus:DI (match_dup 1)
1529990286Sobrien		 (const_int 2)))
1530090286Sobrien   (use (reg:SI 19))]
1530190286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1530290286Sobrien  "stosw"
1530390286Sobrien  [(set_attr "type" "str")
1530490286Sobrien   (set_attr "memory" "store")
1530590286Sobrien   (set_attr "mode" "HI")])
1530690286Sobrien
1530790286Sobrien(define_insn "strsetqi_1"
1530890286Sobrien  [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
1530990286Sobrien	(match_operand:QI 2 "register_operand" "a"))
1531090286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1531190286Sobrien	(plus:SI (match_dup 1)
1531290286Sobrien		 (const_int 1)))
1531390286Sobrien   (use (reg:SI 19))]
1531490286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1531590286Sobrien  "stosb"
1531690286Sobrien  [(set_attr "type" "str")
1531790286Sobrien   (set_attr "memory" "store")
1531890286Sobrien   (set_attr "mode" "QI")])
1531990286Sobrien
1532090286Sobrien(define_insn "strsetqi_rex_1"
1532190286Sobrien  [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
1532290286Sobrien	(match_operand:QI 2 "register_operand" "a"))
1532390286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1532490286Sobrien	(plus:DI (match_dup 1)
1532590286Sobrien		 (const_int 1)))
1532690286Sobrien   (use (reg:SI 19))]
1532790286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1532890286Sobrien  "stosb"
1532990286Sobrien  [(set_attr "type" "str")
1533090286Sobrien   (set_attr "memory" "store")
1533190286Sobrien   (set_attr "mode" "QI")])
1533290286Sobrien
1533390286Sobrien(define_insn "rep_stosdi_rex64"
1533490286Sobrien  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
1533590286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1533690286Sobrien        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
1533790286Sobrien			    (const_int 3))
1533890286Sobrien		 (match_operand:DI 3 "register_operand" "0")))
1533990286Sobrien   (set (mem:BLK (match_dup 3))
1534090286Sobrien	(const_int 0))
1534190286Sobrien   (use (match_operand:DI 2 "register_operand" "a"))
1534290286Sobrien   (use (match_dup 4))
1534390286Sobrien   (use (reg:SI 19))]
1534490286Sobrien  "TARGET_64BIT"
1534590286Sobrien  "{rep\;stosq|rep stosq}"
1534690286Sobrien  [(set_attr "type" "str")
1534790286Sobrien   (set_attr "prefix_rep" "1")
1534890286Sobrien   (set_attr "memory" "store")
1534990286Sobrien   (set_attr "mode" "DI")])
1535090286Sobrien
1535190286Sobrien(define_insn "rep_stossi"
1535290286Sobrien  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
1535390286Sobrien   (set (match_operand:SI 0 "register_operand" "=D") 
1535490286Sobrien        (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
1535590286Sobrien			    (const_int 2))
1535690286Sobrien		 (match_operand:SI 3 "register_operand" "0")))
1535790286Sobrien   (set (mem:BLK (match_dup 3))
1535890286Sobrien	(const_int 0))
1535990286Sobrien   (use (match_operand:SI 2 "register_operand" "a"))
1536090286Sobrien   (use (match_dup 4))
1536190286Sobrien   (use (reg:SI 19))]
1536290286Sobrien  "!TARGET_64BIT"
1536390286Sobrien  "{rep\;stosl|rep stosd}"
1536490286Sobrien  [(set_attr "type" "str")
1536590286Sobrien   (set_attr "prefix_rep" "1")
1536690286Sobrien   (set_attr "memory" "store")
1536790286Sobrien   (set_attr "mode" "SI")])
1536890286Sobrien
1536990286Sobrien(define_insn "rep_stossi_rex64"
1537090286Sobrien  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
1537190286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1537290286Sobrien        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
1537390286Sobrien			    (const_int 2))
1537490286Sobrien		 (match_operand:DI 3 "register_operand" "0")))
1537590286Sobrien   (set (mem:BLK (match_dup 3))
1537690286Sobrien	(const_int 0))
1537790286Sobrien   (use (match_operand:SI 2 "register_operand" "a"))
1537890286Sobrien   (use (match_dup 4))
1537990286Sobrien   (use (reg:SI 19))]
1538090286Sobrien  "TARGET_64BIT"
1538190286Sobrien  "{rep\;stosl|rep stosd}"
1538290286Sobrien  [(set_attr "type" "str")
1538390286Sobrien   (set_attr "prefix_rep" "1")
1538490286Sobrien   (set_attr "memory" "store")
1538590286Sobrien   (set_attr "mode" "SI")])
1538690286Sobrien
1538790286Sobrien(define_insn "rep_stosqi"
1538890286Sobrien  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
1538990286Sobrien   (set (match_operand:SI 0 "register_operand" "=D") 
1539090286Sobrien        (plus:SI (match_operand:SI 3 "register_operand" "0")
1539190286Sobrien		 (match_operand:SI 4 "register_operand" "1")))
1539290286Sobrien   (set (mem:BLK (match_dup 3))
1539390286Sobrien	(const_int 0))
1539490286Sobrien   (use (match_operand:QI 2 "register_operand" "a"))
1539590286Sobrien   (use (match_dup 4))
1539690286Sobrien   (use (reg:SI 19))]
1539790286Sobrien  "!TARGET_64BIT"
1539890286Sobrien  "{rep\;stosb|rep stosb}"
1539990286Sobrien  [(set_attr "type" "str")
1540090286Sobrien   (set_attr "prefix_rep" "1")
1540190286Sobrien   (set_attr "memory" "store")
1540290286Sobrien   (set_attr "mode" "QI")])
1540390286Sobrien
1540490286Sobrien(define_insn "rep_stosqi_rex64"
1540590286Sobrien  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
1540690286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1540790286Sobrien        (plus:DI (match_operand:DI 3 "register_operand" "0")
1540890286Sobrien		 (match_operand:DI 4 "register_operand" "1")))
1540990286Sobrien   (set (mem:BLK (match_dup 3))
1541090286Sobrien	(const_int 0))
1541190286Sobrien   (use (match_operand:QI 2 "register_operand" "a"))
1541290286Sobrien   (use (match_dup 4))
1541390286Sobrien   (use (reg:DI 19))]
1541490286Sobrien  "TARGET_64BIT"
1541590286Sobrien  "{rep\;stosb|rep stosb}"
1541690286Sobrien  [(set_attr "type" "str")
1541790286Sobrien   (set_attr "prefix_rep" "1")
1541890286Sobrien   (set_attr "memory" "store")
1541990286Sobrien   (set_attr "mode" "QI")])
1542090286Sobrien
1542190286Sobrien(define_expand "cmpstrsi"
1542250650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1542390286Sobrien	(compare:SI (match_operand:BLK 1 "general_operand" "")
1542490286Sobrien		    (match_operand:BLK 2 "general_operand" "")))
1542590286Sobrien   (use (match_operand 3 "general_operand" ""))
1542690286Sobrien   (use (match_operand 4 "immediate_operand" ""))]
1542790286Sobrien  ""
1542850650Sobrien{
1542990286Sobrien  rtx addr1, addr2, out, outlow, count, countreg, align;
1543050650Sobrien
1543190286Sobrien  out = operands[0];
1543290286Sobrien  if (GET_CODE (out) != REG)
1543390286Sobrien    out = gen_reg_rtx (SImode);
1543450650Sobrien
1543590286Sobrien  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1543690286Sobrien  addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
1543790286Sobrien  
1543890286Sobrien  count = operands[3];
1543990286Sobrien  countreg = ix86_zero_extend_to_Pmode (count);
1544050650Sobrien
1544190286Sobrien  /* %%% Iff we are testing strict equality, we can use known alignment
1544290286Sobrien     to good advantage.  This may be possible with combine, particularly
1544390286Sobrien     once cc0 is dead.  */
1544490286Sobrien  align = operands[4];
1544550650Sobrien
1544690286Sobrien  emit_insn (gen_cld ());
1544790286Sobrien  if (GET_CODE (count) == CONST_INT)
1544890286Sobrien    {
1544990286Sobrien      if (INTVAL (count) == 0)
1545090286Sobrien	{
1545190286Sobrien	  emit_move_insn (operands[0], const0_rtx);
1545290286Sobrien	  DONE;
1545390286Sobrien	}
1545490286Sobrien      if (TARGET_64BIT)
1545590286Sobrien	emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
1545690286Sobrien					  addr1, addr2, countreg));
1545790286Sobrien      else
1545890286Sobrien	emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
1545990286Sobrien				      addr1, addr2, countreg));
1546090286Sobrien    }
1546190286Sobrien  else
1546290286Sobrien    {
1546390286Sobrien      if (TARGET_64BIT)
1546490286Sobrien	{
1546590286Sobrien	  emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
1546690286Sobrien	  emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
1546790286Sobrien					 addr1, addr2, countreg));
1546890286Sobrien	}
1546990286Sobrien      else
1547090286Sobrien	{
1547190286Sobrien	  emit_insn (gen_cmpsi_1 (countreg, countreg));
1547290286Sobrien	  emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
1547390286Sobrien				     addr1, addr2, countreg));
1547490286Sobrien	}
1547590286Sobrien    }
1547690286Sobrien
1547790286Sobrien  outlow = gen_lowpart (QImode, out);
1547890286Sobrien  emit_insn (gen_cmpintqi (outlow));
1547990286Sobrien  emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
1548090286Sobrien
1548190286Sobrien  if (operands[0] != out)
1548290286Sobrien    emit_move_insn (operands[0], out);
1548390286Sobrien
1548490286Sobrien  DONE;
1548590286Sobrien})
1548690286Sobrien
1548790286Sobrien;; Produce a tri-state integer (-1, 0, 1) from condition codes.
1548890286Sobrien
1548990286Sobrien(define_expand "cmpintqi"
1549090286Sobrien  [(set (match_dup 1)
1549190286Sobrien	(gtu:QI (reg:CC 17) (const_int 0)))
1549290286Sobrien   (set (match_dup 2)
1549390286Sobrien	(ltu:QI (reg:CC 17) (const_int 0)))
1549490286Sobrien   (parallel [(set (match_operand:QI 0 "register_operand" "")
1549590286Sobrien		   (minus:QI (match_dup 1)
1549690286Sobrien			     (match_dup 2)))
1549790286Sobrien	      (clobber (reg:CC 17))])]
1549890286Sobrien  ""
1549990286Sobrien  "operands[1] = gen_reg_rtx (QImode);
1550090286Sobrien   operands[2] = gen_reg_rtx (QImode);")
1550190286Sobrien
1550290286Sobrien;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
1550390286Sobrien;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
1550490286Sobrien
1550590286Sobrien(define_insn "cmpstrqi_nz_1"
1550690286Sobrien  [(set (reg:CC 17)
1550790286Sobrien	(compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
1550890286Sobrien		    (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
1550990286Sobrien   (use (match_operand:SI 6 "register_operand" "2"))
1551090286Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
1551190286Sobrien   (use (reg:SI 19))
1551290286Sobrien   (clobber (match_operand:SI 0 "register_operand" "=S"))
1551390286Sobrien   (clobber (match_operand:SI 1 "register_operand" "=D"))
1551490286Sobrien   (clobber (match_operand:SI 2 "register_operand" "=c"))]
1551590286Sobrien  "!TARGET_64BIT"
1551690286Sobrien  "repz{\;| }cmpsb"
1551790286Sobrien  [(set_attr "type" "str")
1551890286Sobrien   (set_attr "mode" "QI")
1551990286Sobrien   (set_attr "prefix_rep" "1")])
1552090286Sobrien
1552190286Sobrien(define_insn "cmpstrqi_nz_rex_1"
1552290286Sobrien  [(set (reg:CC 17)
1552390286Sobrien	(compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
1552490286Sobrien		    (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
1552590286Sobrien   (use (match_operand:DI 6 "register_operand" "2"))
1552690286Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
1552790286Sobrien   (use (reg:SI 19))
1552890286Sobrien   (clobber (match_operand:DI 0 "register_operand" "=S"))
1552990286Sobrien   (clobber (match_operand:DI 1 "register_operand" "=D"))
1553090286Sobrien   (clobber (match_operand:DI 2 "register_operand" "=c"))]
1553190286Sobrien  "TARGET_64BIT"
1553290286Sobrien  "repz{\;| }cmpsb"
1553390286Sobrien  [(set_attr "type" "str")
1553490286Sobrien   (set_attr "mode" "QI")
1553590286Sobrien   (set_attr "prefix_rep" "1")])
1553690286Sobrien
1553790286Sobrien;; The same, but the count is not known to not be zero.
1553890286Sobrien
1553990286Sobrien(define_insn "cmpstrqi_1"
1554090286Sobrien  [(set (reg:CC 17)
1554190286Sobrien	(if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
1554290286Sobrien			     (const_int 0))
1554390286Sobrien	  (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
1554490286Sobrien		      (mem:BLK (match_operand:SI 5 "register_operand" "1")))
1554590286Sobrien	  (const_int 0)))
1554690286Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
1554790286Sobrien   (use (reg:CC 17))
1554890286Sobrien   (use (reg:SI 19))
1554990286Sobrien   (clobber (match_operand:SI 0 "register_operand" "=S"))
1555090286Sobrien   (clobber (match_operand:SI 1 "register_operand" "=D"))
1555190286Sobrien   (clobber (match_operand:SI 2 "register_operand" "=c"))]
1555290286Sobrien  "!TARGET_64BIT"
1555390286Sobrien  "repz{\;| }cmpsb"
1555490286Sobrien  [(set_attr "type" "str")
1555590286Sobrien   (set_attr "mode" "QI")
1555690286Sobrien   (set_attr "prefix_rep" "1")])
1555790286Sobrien
1555890286Sobrien(define_insn "cmpstrqi_rex_1"
1555990286Sobrien  [(set (reg:CC 17)
1556090286Sobrien	(if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
1556190286Sobrien			     (const_int 0))
1556290286Sobrien	  (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
1556390286Sobrien		      (mem:BLK (match_operand:DI 5 "register_operand" "1")))
1556490286Sobrien	  (const_int 0)))
1556590286Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
1556690286Sobrien   (use (reg:CC 17))
1556790286Sobrien   (use (reg:SI 19))
1556890286Sobrien   (clobber (match_operand:DI 0 "register_operand" "=S"))
1556990286Sobrien   (clobber (match_operand:DI 1 "register_operand" "=D"))
1557090286Sobrien   (clobber (match_operand:DI 2 "register_operand" "=c"))]
1557190286Sobrien  "TARGET_64BIT"
1557290286Sobrien  "repz{\;| }cmpsb"
1557390286Sobrien  [(set_attr "type" "str")
1557490286Sobrien   (set_attr "mode" "QI")
1557590286Sobrien   (set_attr "prefix_rep" "1")])
1557690286Sobrien
1557790286Sobrien(define_expand "strlensi"
1557852296Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1557990286Sobrien	(unspec:SI [(match_operand:BLK 1 "general_operand" "")
1558090286Sobrien		    (match_operand:QI 2 "immediate_operand" "")
1558190286Sobrien		    (match_operand 3 "immediate_operand" "")] 0))]
1558290286Sobrien  ""
1558390286Sobrien{
1558490286Sobrien if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
1558590286Sobrien   DONE;
1558690286Sobrien else
1558790286Sobrien   FAIL;
1558890286Sobrien})
1558990286Sobrien
1559090286Sobrien(define_expand "strlendi"
1559190286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1559290286Sobrien	(unspec:DI [(match_operand:BLK 1 "general_operand" "")
1559390286Sobrien		    (match_operand:QI 2 "immediate_operand" "")
1559490286Sobrien		    (match_operand 3 "immediate_operand" "")] 0))]
1559590286Sobrien  ""
1559690286Sobrien{
1559790286Sobrien if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
1559890286Sobrien   DONE;
1559990286Sobrien else
1560090286Sobrien   FAIL;
1560190286Sobrien})
1560290286Sobrien
1560390286Sobrien(define_insn "strlenqi_1"
1560490286Sobrien  [(set (match_operand:SI 0 "register_operand" "=&c")
1560590286Sobrien	(unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
1560690286Sobrien		    (match_operand:QI 2 "register_operand" "a")
1560790286Sobrien		    (match_operand:SI 3 "immediate_operand" "i")
1560890286Sobrien		    (match_operand:SI 4 "register_operand" "0")] 0))
1560990286Sobrien   (use (reg:SI 19))
1561090286Sobrien   (clobber (match_operand:SI 1 "register_operand" "=D"))
1561190286Sobrien   (clobber (reg:CC 17))]
1561290286Sobrien  "!TARGET_64BIT"
1561390286Sobrien  "repnz{\;| }scasb"
1561490286Sobrien  [(set_attr "type" "str")
1561590286Sobrien   (set_attr "mode" "QI")
1561690286Sobrien   (set_attr "prefix_rep" "1")])
1561790286Sobrien
1561890286Sobrien(define_insn "strlenqi_rex_1"
1561990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=&c")
1562090286Sobrien	(unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
1562190286Sobrien		    (match_operand:QI 2 "register_operand" "a")
1562290286Sobrien		    (match_operand:DI 3 "immediate_operand" "i")
1562390286Sobrien		    (match_operand:DI 4 "register_operand" "0")] 0))
1562490286Sobrien   (use (reg:SI 19))
1562590286Sobrien   (clobber (match_operand:DI 1 "register_operand" "=D"))
1562690286Sobrien   (clobber (reg:CC 17))]
1562790286Sobrien  "TARGET_64BIT"
1562890286Sobrien  "repnz{\;| }scasb"
1562990286Sobrien  [(set_attr "type" "str")
1563090286Sobrien   (set_attr "mode" "QI")
1563190286Sobrien   (set_attr "prefix_rep" "1")])
1563290286Sobrien
1563390286Sobrien;; Peephole optimizations to clean up after cmpstr*.  This should be
1563490286Sobrien;; handled in combine, but it is not currently up to the task.
1563590286Sobrien;; When used for their truth value, the cmpstr* expanders generate
1563690286Sobrien;; code like this:
1563790286Sobrien;;
1563890286Sobrien;;   repz cmpsb
1563990286Sobrien;;   seta 	%al
1564090286Sobrien;;   setb 	%dl
1564190286Sobrien;;   cmpb 	%al, %dl
1564290286Sobrien;;   jcc	label
1564390286Sobrien;;
1564490286Sobrien;; The intermediate three instructions are unnecessary.
1564590286Sobrien
1564690286Sobrien;; This one handles cmpstr*_nz_1...
1564790286Sobrien(define_peephole2
1564890286Sobrien  [(parallel[
1564990286Sobrien     (set (reg:CC 17)
1565090286Sobrien	  (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
1565190286Sobrien		      (mem:BLK (match_operand 5 "register_operand" ""))))
1565290286Sobrien     (use (match_operand 6 "register_operand" ""))
1565390286Sobrien     (use (match_operand:SI 3 "immediate_operand" ""))
1565490286Sobrien     (use (reg:SI 19))
1565590286Sobrien     (clobber (match_operand 0 "register_operand" ""))
1565690286Sobrien     (clobber (match_operand 1 "register_operand" ""))
1565790286Sobrien     (clobber (match_operand 2 "register_operand" ""))])
1565890286Sobrien   (set (match_operand:QI 7 "register_operand" "")
1565990286Sobrien	(gtu:QI (reg:CC 17) (const_int 0)))
1566090286Sobrien   (set (match_operand:QI 8 "register_operand" "")
1566190286Sobrien	(ltu:QI (reg:CC 17) (const_int 0)))
1566290286Sobrien   (set (reg 17)
1566390286Sobrien	(compare (match_dup 7) (match_dup 8)))
1566490286Sobrien  ]
1566590286Sobrien  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
1566690286Sobrien  [(parallel[
1566790286Sobrien     (set (reg:CC 17)
1566890286Sobrien	  (compare:CC (mem:BLK (match_dup 4))
1566990286Sobrien		      (mem:BLK (match_dup 5))))
1567090286Sobrien     (use (match_dup 6))
1567190286Sobrien     (use (match_dup 3))
1567290286Sobrien     (use (reg:SI 19))
1567390286Sobrien     (clobber (match_dup 0))
1567490286Sobrien     (clobber (match_dup 1))
1567590286Sobrien     (clobber (match_dup 2))])]
1567650650Sobrien  "")
1567750650Sobrien
1567890286Sobrien;; ...and this one handles cmpstr*_1.
1567990286Sobrien(define_peephole2
1568090286Sobrien  [(parallel[
1568190286Sobrien     (set (reg:CC 17)
1568290286Sobrien	  (if_then_else:CC (ne (match_operand 6 "register_operand" "")
1568390286Sobrien			       (const_int 0))
1568490286Sobrien	    (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
1568590286Sobrien		        (mem:BLK (match_operand 5 "register_operand" "")))
1568690286Sobrien	    (const_int 0)))
1568790286Sobrien     (use (match_operand:SI 3 "immediate_operand" ""))
1568890286Sobrien     (use (reg:CC 17))
1568990286Sobrien     (use (reg:SI 19))
1569090286Sobrien     (clobber (match_operand 0 "register_operand" ""))
1569190286Sobrien     (clobber (match_operand 1 "register_operand" ""))
1569290286Sobrien     (clobber (match_operand 2 "register_operand" ""))])
1569390286Sobrien   (set (match_operand:QI 7 "register_operand" "")
1569490286Sobrien	(gtu:QI (reg:CC 17) (const_int 0)))
1569590286Sobrien   (set (match_operand:QI 8 "register_operand" "")
1569690286Sobrien	(ltu:QI (reg:CC 17) (const_int 0)))
1569790286Sobrien   (set (reg 17)
1569890286Sobrien	(compare (match_dup 7) (match_dup 8)))
1569990286Sobrien  ]
1570090286Sobrien  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
1570190286Sobrien  [(parallel[
1570290286Sobrien     (set (reg:CC 17)
1570390286Sobrien	  (if_then_else:CC (ne (match_dup 6)
1570490286Sobrien			       (const_int 0))
1570590286Sobrien	    (compare:CC (mem:BLK (match_dup 4))
1570690286Sobrien			(mem:BLK (match_dup 5)))
1570790286Sobrien	    (const_int 0)))
1570890286Sobrien     (use (match_dup 3))
1570990286Sobrien     (use (reg:CC 17))
1571090286Sobrien     (use (reg:SI 19))
1571190286Sobrien     (clobber (match_dup 0))
1571290286Sobrien     (clobber (match_dup 1))
1571390286Sobrien     (clobber (match_dup 2))])]
1571450650Sobrien  "")
1571550650Sobrien
1571690286Sobrien
1571790286Sobrien
1571890286Sobrien;; Conditional move instructions.
1571990286Sobrien
1572090286Sobrien(define_expand "movdicc"
1572190286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1572290286Sobrien	(if_then_else:DI (match_operand 1 "comparison_operator" "")
1572390286Sobrien			 (match_operand:DI 2 "general_operand" "")
1572490286Sobrien			 (match_operand:DI 3 "general_operand" "")))]
1572590286Sobrien  "TARGET_64BIT"
1572690286Sobrien  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
1572790286Sobrien
1572890286Sobrien(define_insn "x86_movdicc_0_m1_rex64"
1572990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1573090286Sobrien	(if_then_else:DI (ltu (reg:CC 17) (const_int 0))
1573190286Sobrien	  (const_int -1)
1573290286Sobrien	  (const_int 0)))
1573390286Sobrien   (clobber (reg:CC 17))]
1573490286Sobrien  "TARGET_64BIT"
1573590286Sobrien  "sbb{q}\t%0, %0"
1573690286Sobrien  ; Since we don't have the proper number of operands for an alu insn,
1573790286Sobrien  ; fill in all the blanks.
1573890286Sobrien  [(set_attr "type" "alu")
1573990286Sobrien   (set_attr "memory" "none")
1574090286Sobrien   (set_attr "imm_disp" "false")
1574190286Sobrien   (set_attr "mode" "DI")
1574290286Sobrien   (set_attr "length_immediate" "0")])
1574390286Sobrien
1574490286Sobrien(define_insn "*movdicc_c_rex64"
1574590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1574690286Sobrien	(if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
1574790286Sobrien				[(reg 17) (const_int 0)])
1574890286Sobrien		      (match_operand:DI 2 "nonimmediate_operand" "rm,0")
1574990286Sobrien		      (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
1575090286Sobrien  "TARGET_64BIT && TARGET_CMOVE
1575190286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1575290286Sobrien  "@
1575390286Sobrien   cmov%C1\t{%2, %0|%0, %2}
1575490286Sobrien   cmov%c1\t{%3, %0|%0, %3}"
1575590286Sobrien  [(set_attr "type" "icmov")
1575690286Sobrien   (set_attr "mode" "DI")])
1575790286Sobrien
1575890286Sobrien(define_expand "movsicc"
1575990286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1576090286Sobrien	(if_then_else:SI (match_operand 1 "comparison_operator" "")
1576190286Sobrien			 (match_operand:SI 2 "general_operand" "")
1576290286Sobrien			 (match_operand:SI 3 "general_operand" "")))]
1576390286Sobrien  ""
1576490286Sobrien  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
1576590286Sobrien
1576690286Sobrien;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
1576790286Sobrien;; the register first winds up with `sbbl $0,reg', which is also weird.
1576890286Sobrien;; So just document what we're doing explicitly.
1576990286Sobrien
1577090286Sobrien(define_insn "x86_movsicc_0_m1"
1577190286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1577290286Sobrien	(if_then_else:SI (ltu (reg:CC 17) (const_int 0))
1577390286Sobrien	  (const_int -1)
1577490286Sobrien	  (const_int 0)))
1577590286Sobrien   (clobber (reg:CC 17))]
1577690286Sobrien  ""
1577790286Sobrien  "sbb{l}\t%0, %0"
1577890286Sobrien  ; Since we don't have the proper number of operands for an alu insn,
1577990286Sobrien  ; fill in all the blanks.
1578090286Sobrien  [(set_attr "type" "alu")
1578190286Sobrien   (set_attr "memory" "none")
1578290286Sobrien   (set_attr "imm_disp" "false")
1578390286Sobrien   (set_attr "mode" "SI")
1578490286Sobrien   (set_attr "length_immediate" "0")])
1578590286Sobrien
1578690286Sobrien(define_insn "*movsicc_noc"
1578750650Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,r")
1578890286Sobrien	(if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
1578990286Sobrien				[(reg 17) (const_int 0)])
1579050650Sobrien		      (match_operand:SI 2 "nonimmediate_operand" "rm,0")
1579150650Sobrien		      (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
1579290286Sobrien  "TARGET_CMOVE
1579390286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1579490286Sobrien  "@
1579590286Sobrien   cmov%C1\t{%2, %0|%0, %2}
1579690286Sobrien   cmov%c1\t{%3, %0|%0, %3}"
1579790286Sobrien  [(set_attr "type" "icmov")
1579890286Sobrien   (set_attr "mode" "SI")])
1579950650Sobrien
1580050650Sobrien(define_expand "movhicc"
1580150650Sobrien  [(set (match_operand:HI 0 "register_operand" "")
1580250650Sobrien	(if_then_else:HI (match_operand 1 "comparison_operator" "")
1580350650Sobrien			 (match_operand:HI 2 "nonimmediate_operand" "")
1580450650Sobrien			 (match_operand:HI 3 "nonimmediate_operand" "")))]
1580590286Sobrien  "TARGET_CMOVE && TARGET_HIMODE_MATH"
1580690286Sobrien  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
1580750650Sobrien
1580890286Sobrien(define_insn "*movhicc_noc"
1580950650Sobrien  [(set (match_operand:HI 0 "register_operand" "=r,r")
1581090286Sobrien	(if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
1581190286Sobrien				[(reg 17) (const_int 0)])
1581250650Sobrien		      (match_operand:HI 2 "nonimmediate_operand" "rm,0")
1581350650Sobrien		      (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
1581490286Sobrien  "TARGET_CMOVE
1581590286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1581690286Sobrien  "@
1581790286Sobrien   cmov%C1\t{%2, %0|%0, %2}
1581890286Sobrien   cmov%c1\t{%3, %0|%0, %3}"
1581990286Sobrien  [(set_attr "type" "icmov")
1582090286Sobrien   (set_attr "mode" "HI")])
1582150650Sobrien
1582250650Sobrien(define_expand "movsfcc"
1582350650Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1582450650Sobrien	(if_then_else:SF (match_operand 1 "comparison_operator" "")
1582550650Sobrien			 (match_operand:SF 2 "register_operand" "")
1582650650Sobrien			 (match_operand:SF 3 "register_operand" "")))]
1582750650Sobrien  "TARGET_CMOVE"
1582890286Sobrien  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
1582950650Sobrien
1583090286Sobrien(define_insn "*movsfcc_1"
1583190286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
1583290286Sobrien	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
1583390286Sobrien				[(reg 17) (const_int 0)])
1583490286Sobrien		      (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
1583590286Sobrien		      (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
1583690286Sobrien  "TARGET_CMOVE
1583790286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1583890286Sobrien  "@
1583990286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1584090286Sobrien   fcmov%f1\t{%3, %0|%0, %3}
1584190286Sobrien   cmov%C1\t{%2, %0|%0, %2}
1584290286Sobrien   cmov%c1\t{%3, %0|%0, %3}"
1584390286Sobrien  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
1584490286Sobrien   (set_attr "mode" "SF,SF,SI,SI")])
1584550650Sobrien
1584690286Sobrien(define_expand "movdfcc"
1584790286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1584890286Sobrien	(if_then_else:DF (match_operand 1 "comparison_operator" "")
1584990286Sobrien			 (match_operand:DF 2 "register_operand" "")
1585090286Sobrien			 (match_operand:DF 3 "register_operand" "")))]
1585190286Sobrien  "TARGET_CMOVE"
1585290286Sobrien  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
1585350650Sobrien
1585490286Sobrien(define_insn "*movdfcc_1"
1585590286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
1585690286Sobrien	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
1585790286Sobrien				[(reg 17) (const_int 0)])
1585890286Sobrien		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
1585990286Sobrien		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
1586090286Sobrien  "!TARGET_64BIT && TARGET_CMOVE
1586190286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1586290286Sobrien  "@
1586390286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1586490286Sobrien   fcmov%f1\t{%3, %0|%0, %3}
1586590286Sobrien   #
1586690286Sobrien   #"
1586790286Sobrien  [(set_attr "type" "fcmov,fcmov,multi,multi")
1586890286Sobrien   (set_attr "mode" "DF")])
1586950650Sobrien
1587090286Sobrien(define_insn "*movdfcc_1_rex64"
1587190286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
1587290286Sobrien	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
1587390286Sobrien				[(reg 17) (const_int 0)])
1587490286Sobrien		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
1587590286Sobrien		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
1587690286Sobrien  "TARGET_64BIT && TARGET_CMOVE
1587790286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1587890286Sobrien  "@
1587990286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1588090286Sobrien   fcmov%f1\t{%3, %0|%0, %3}
1588190286Sobrien   cmov%C1\t{%2, %0|%0, %2}
1588290286Sobrien   cmov%c1\t{%3, %0|%0, %3}"
1588390286Sobrien  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
1588490286Sobrien   (set_attr "mode" "DF")])
1588550650Sobrien
1588690286Sobrien(define_split
1588790286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1588890286Sobrien	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
1588990286Sobrien				[(match_operand 4 "" "") (const_int 0)])
1589090286Sobrien		      (match_operand:DF 2 "nonimmediate_operand" "")
1589190286Sobrien		      (match_operand:DF 3 "nonimmediate_operand" "")))]
1589290286Sobrien  "!TARGET_64BIT && !ANY_FP_REG_P (operands[0]) && reload_completed"
1589390286Sobrien  [(set (match_dup 2)
1589490286Sobrien	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
1589590286Sobrien		      (match_dup 5)
1589690286Sobrien		      (match_dup 7)))
1589790286Sobrien   (set (match_dup 3)
1589890286Sobrien	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
1589990286Sobrien		      (match_dup 6)
1590090286Sobrien		      (match_dup 8)))]
1590190286Sobrien  "split_di (operands+2, 1, operands+5, operands+6);
1590290286Sobrien   split_di (operands+3, 1, operands+7, operands+8);
1590390286Sobrien   split_di (operands, 1, operands+2, operands+3);")
1590450650Sobrien
1590590286Sobrien(define_expand "movxfcc"
1590690286Sobrien  [(set (match_operand:XF 0 "register_operand" "")
1590790286Sobrien	(if_then_else:XF (match_operand 1 "comparison_operator" "")
1590890286Sobrien			 (match_operand:XF 2 "register_operand" "")
1590990286Sobrien			 (match_operand:XF 3 "register_operand" "")))]
1591090286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1591190286Sobrien  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
1591250650Sobrien
1591390286Sobrien(define_expand "movtfcc"
1591490286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
1591590286Sobrien	(if_then_else:TF (match_operand 1 "comparison_operator" "")
1591690286Sobrien			 (match_operand:TF 2 "register_operand" "")
1591790286Sobrien			 (match_operand:TF 3 "register_operand" "")))]
1591890286Sobrien  "TARGET_CMOVE"
1591990286Sobrien  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
1592090286Sobrien
1592190286Sobrien(define_insn "*movxfcc_1"
1592290286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1592390286Sobrien	(if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
1592490286Sobrien				[(reg 17) (const_int 0)])
1592590286Sobrien		      (match_operand:XF 2 "register_operand" "f,0")
1592690286Sobrien		      (match_operand:XF 3 "register_operand" "0,f")))]
1592790286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1592890286Sobrien  "@
1592990286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1593090286Sobrien   fcmov%f1\t{%3, %0|%0, %3}"
1593190286Sobrien  [(set_attr "type" "fcmov")
1593290286Sobrien   (set_attr "mode" "XF")])
1593390286Sobrien
1593490286Sobrien(define_insn "*movtfcc_1"
1593590286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1593690286Sobrien	(if_then_else:TF (match_operator 1 "fcmov_comparison_operator" 
1593790286Sobrien				[(reg 17) (const_int 0)])
1593890286Sobrien		      (match_operand:TF 2 "register_operand" "f,0")
1593990286Sobrien		      (match_operand:TF 3 "register_operand" "0,f")))]
1594090286Sobrien  "TARGET_CMOVE"
1594190286Sobrien  "@
1594290286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1594390286Sobrien   fcmov%f1\t{%3, %0|%0, %3}"
1594490286Sobrien  [(set_attr "type" "fcmov")
1594590286Sobrien   (set_attr "mode" "XF")])
1594690286Sobrien
1594790286Sobrien(define_expand "minsf3"
1594890286Sobrien  [(parallel [
1594990286Sobrien     (set (match_operand:SF 0 "register_operand" "")
1595090286Sobrien	  (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
1595190286Sobrien			       (match_operand:SF 2 "nonimmediate_operand" ""))
1595290286Sobrien			   (match_dup 1)
1595390286Sobrien			   (match_dup 2)))
1595490286Sobrien     (clobber (reg:CC 17))])]
1595590286Sobrien  "TARGET_SSE"
1595690286Sobrien  "")
1595790286Sobrien
1595890286Sobrien(define_insn "*minsf"
1595990286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
1596090286Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
1596190286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
1596290286Sobrien			 (match_dup 1)
1596390286Sobrien			 (match_dup 2)))
1596490286Sobrien   (clobber (reg:CC 17))]
1596590286Sobrien  "TARGET_SSE && TARGET_IEEE_FP"
1596650650Sobrien  "#")
1596750650Sobrien
1596890286Sobrien(define_insn "*minsf_nonieee"
1596990286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
1597090286Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "%0,0")
1597190286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
1597290286Sobrien			 (match_dup 1)
1597390286Sobrien			 (match_dup 2)))
1597490286Sobrien   (clobber (reg:CC 17))]
1597590286Sobrien  "TARGET_SSE && !TARGET_IEEE_FP"
1597650650Sobrien  "#")
1597750650Sobrien
1597850650Sobrien(define_split
1597952296Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1598090286Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
1598190286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" ""))
1598290286Sobrien			 (match_operand:SF 3 "register_operand" "")
1598390286Sobrien			 (match_operand:SF 4 "nonimmediate_operand" "")))
1598490286Sobrien   (clobber (reg:CC 17))]
1598590286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1598690286Sobrien   && ((operands_match_p (operands[1], operands[3])
1598790286Sobrien	&& operands_match_p (operands[2], operands[4]))
1598890286Sobrien       || (operands_match_p (operands[1], operands[4])
1598990286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1599090286Sobrien  [(set (match_dup 0)
1599190286Sobrien	(if_then_else:SF (lt (match_dup 1)
1599290286Sobrien			     (match_dup 2))
1599390286Sobrien			 (match_dup 1)
1599490286Sobrien			 (match_dup 2)))])
1599550650Sobrien
1599690286Sobrien;; We can't represent the LT test directly.  Do this by swapping the operands.
1599790286Sobrien
1599850650Sobrien(define_split
1599952296Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1600090286Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
1600190286Sobrien			     (match_operand:SF 2 "register_operand" ""))
1600290286Sobrien			 (match_operand:SF 3 "register_operand" "")
1600390286Sobrien			 (match_operand:SF 4 "register_operand" "")))
1600490286Sobrien   (clobber (reg:CC 17))]
1600590286Sobrien  "FP_REG_P (operands[0]) && reload_completed
1600690286Sobrien   && ((operands_match_p (operands[1], operands[3])
1600790286Sobrien	&& operands_match_p (operands[2], operands[4]))
1600890286Sobrien       || (operands_match_p (operands[1], operands[4])
1600990286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1601090286Sobrien  [(set (reg:CCFP 17)
1601190286Sobrien	(compare:CCFP (match_dup 2)
1601290286Sobrien		      (match_dup 1)))
1601350650Sobrien   (set (match_dup 0)
1601490286Sobrien	(if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
1601590286Sobrien			 (match_dup 1)
1601690286Sobrien			 (match_dup 2)))])
1601750650Sobrien
1601890286Sobrien(define_insn "*minsf_sse"
1601990286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1602090286Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
1602190286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm"))
1602290286Sobrien			 (match_dup 1)
1602390286Sobrien			 (match_dup 2)))]
1602490286Sobrien  "TARGET_SSE && reload_completed"
1602590286Sobrien  "minss\t{%2, %0|%0, %2}"
1602690286Sobrien  [(set_attr "type" "sse")
1602790286Sobrien   (set_attr "mode" "SF")])
1602850650Sobrien
1602990286Sobrien(define_expand "mindf3"
1603090286Sobrien  [(parallel [
1603190286Sobrien     (set (match_operand:DF 0 "register_operand" "")
1603290286Sobrien	  (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
1603390286Sobrien			       (match_operand:DF 2 "nonimmediate_operand" ""))
1603490286Sobrien			   (match_dup 1)
1603590286Sobrien			   (match_dup 2)))
1603690286Sobrien     (clobber (reg:CC 17))])]
1603790286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH"
1603890286Sobrien  "#")
1603990286Sobrien
1604090286Sobrien(define_insn "*mindf"
1604190286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
1604290286Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
1604390286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
1604490286Sobrien			 (match_dup 1)
1604590286Sobrien			 (match_dup 2)))
1604690286Sobrien   (clobber (reg:CC 17))]
1604790286Sobrien  "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
1604890286Sobrien  "#")
1604990286Sobrien
1605090286Sobrien(define_insn "*mindf_nonieee"
1605190286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
1605290286Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "%0,0")
1605390286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
1605490286Sobrien			 (match_dup 1)
1605590286Sobrien			 (match_dup 2)))
1605690286Sobrien   (clobber (reg:CC 17))]
1605790286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP"
1605890286Sobrien  "#")
1605990286Sobrien
1606090286Sobrien(define_split
1606150650Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1606290286Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
1606390286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" ""))
1606490286Sobrien			 (match_operand:DF 3 "register_operand" "")
1606590286Sobrien			 (match_operand:DF 4 "nonimmediate_operand" "")))
1606690286Sobrien   (clobber (reg:CC 17))]
1606790286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1606890286Sobrien   && ((operands_match_p (operands[1], operands[3])
1606990286Sobrien	&& operands_match_p (operands[2], operands[4]))
1607090286Sobrien       || (operands_match_p (operands[1], operands[4])
1607190286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1607290286Sobrien  [(set (match_dup 0)
1607390286Sobrien	(if_then_else:DF (lt (match_dup 1)
1607490286Sobrien			     (match_dup 2))
1607590286Sobrien			 (match_dup 1)
1607690286Sobrien			 (match_dup 2)))])
1607750650Sobrien
1607890286Sobrien;; We can't represent the LT test directly.  Do this by swapping the operands.
1607990286Sobrien(define_split
1608090286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1608190286Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
1608290286Sobrien			     (match_operand:DF 2 "register_operand" ""))
1608390286Sobrien			 (match_operand:DF 3 "register_operand" "")
1608490286Sobrien			 (match_operand:DF 4 "register_operand" "")))
1608590286Sobrien   (clobber (reg:CC 17))]
1608690286Sobrien  "FP_REG_P (operands[0]) && reload_completed
1608790286Sobrien   && ((operands_match_p (operands[1], operands[3])
1608890286Sobrien	&& operands_match_p (operands[2], operands[4]))
1608990286Sobrien       || (operands_match_p (operands[1], operands[4])
1609090286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1609190286Sobrien  [(set (reg:CCFP 17)
1609290286Sobrien	(compare:CCFP (match_dup 2)
1609390286Sobrien		      (match_dup 2)))
1609490286Sobrien   (set (match_dup 0)
1609590286Sobrien	(if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
1609690286Sobrien			 (match_dup 1)
1609790286Sobrien			 (match_dup 2)))])
1609850650Sobrien
1609990286Sobrien(define_insn "*mindf_sse"
1610090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1610190286Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
1610290286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym"))
1610390286Sobrien			 (match_dup 1)
1610490286Sobrien			 (match_dup 2)))]
1610590286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
1610690286Sobrien  "minsd\t{%2, %0|%0, %2}"
1610790286Sobrien  [(set_attr "type" "sse")
1610890286Sobrien   (set_attr "mode" "DF")])
1610950650Sobrien
1611090286Sobrien(define_expand "maxsf3"
1611190286Sobrien  [(parallel [
1611290286Sobrien     (set (match_operand:SF 0 "register_operand" "")
1611390286Sobrien	  (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
1611490286Sobrien			       (match_operand:SF 2 "nonimmediate_operand" ""))
1611590286Sobrien			   (match_dup 1)
1611690286Sobrien			   (match_dup 2)))
1611790286Sobrien     (clobber (reg:CC 17))])]
1611890286Sobrien  "TARGET_SSE"
1611990286Sobrien  "#")
1612050650Sobrien
1612190286Sobrien(define_insn "*maxsf"
1612290286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
1612390286Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
1612490286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
1612590286Sobrien			 (match_dup 1)
1612690286Sobrien			 (match_dup 2)))
1612790286Sobrien   (clobber (reg:CC 17))]
1612890286Sobrien  "TARGET_SSE && TARGET_IEEE_FP"
1612990286Sobrien  "#")
1613050650Sobrien
1613190286Sobrien(define_insn "*maxsf_nonieee"
1613290286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
1613390286Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "%0,0")
1613490286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
1613590286Sobrien			 (match_dup 1)
1613690286Sobrien			 (match_dup 2)))
1613790286Sobrien   (clobber (reg:CC 17))]
1613890286Sobrien  "TARGET_SSE && !TARGET_IEEE_FP"
1613990286Sobrien  "#")
1614050650Sobrien
1614190286Sobrien(define_split
1614290286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1614390286Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
1614490286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" ""))
1614590286Sobrien			 (match_operand:SF 3 "register_operand" "")
1614690286Sobrien			 (match_operand:SF 4 "nonimmediate_operand" "")))
1614790286Sobrien   (clobber (reg:CC 17))]
1614890286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1614990286Sobrien   && ((operands_match_p (operands[1], operands[3])
1615090286Sobrien	&& operands_match_p (operands[2], operands[4]))
1615190286Sobrien       || (operands_match_p (operands[1], operands[4])
1615290286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1615390286Sobrien  [(set (match_dup 0)
1615490286Sobrien	(if_then_else:SF (gt (match_dup 1)
1615590286Sobrien			     (match_dup 2))
1615690286Sobrien			 (match_dup 1)
1615790286Sobrien			 (match_dup 2)))])
1615850650Sobrien
1615990286Sobrien(define_split
1616090286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1616190286Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
1616290286Sobrien			     (match_operand:SF 2 "register_operand" ""))
1616390286Sobrien			 (match_operand:SF 3 "register_operand" "")
1616490286Sobrien			 (match_operand:SF 4 "register_operand" "")))
1616590286Sobrien   (clobber (reg:CC 17))]
1616690286Sobrien  "FP_REG_P (operands[0]) && reload_completed
1616790286Sobrien   && ((operands_match_p (operands[1], operands[3])
1616890286Sobrien	&& operands_match_p (operands[2], operands[4]))
1616990286Sobrien       || (operands_match_p (operands[1], operands[4])
1617090286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1617190286Sobrien  [(set (reg:CCFP 17)
1617290286Sobrien	(compare:CCFP (match_dup 1)
1617390286Sobrien		      (match_dup 2)))
1617490286Sobrien   (set (match_dup 0)
1617590286Sobrien	(if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
1617690286Sobrien			 (match_dup 1)
1617790286Sobrien			 (match_dup 2)))])
1617890286Sobrien
1617990286Sobrien(define_insn "*maxsf_sse"
1618090286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1618190286Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
1618290286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm"))
1618390286Sobrien			 (match_dup 1)
1618490286Sobrien			 (match_dup 2)))]
1618590286Sobrien  "TARGET_SSE && reload_completed"
1618690286Sobrien  "maxss\t{%2, %0|%0, %2}"
1618790286Sobrien  [(set_attr "type" "sse")
1618890286Sobrien   (set_attr "mode" "SF")])
1618990286Sobrien
1619090286Sobrien(define_expand "maxdf3"
1619190286Sobrien  [(parallel [
1619290286Sobrien     (set (match_operand:DF 0 "register_operand" "")
1619390286Sobrien	  (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
1619490286Sobrien			       (match_operand:DF 2 "nonimmediate_operand" ""))
1619590286Sobrien			   (match_dup 1)
1619690286Sobrien			   (match_dup 2)))
1619790286Sobrien     (clobber (reg:CC 17))])]
1619890286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH"
1619950650Sobrien  "#")
1620050650Sobrien
1620190286Sobrien(define_insn "*maxdf"
1620290286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
1620390286Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
1620490286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
1620590286Sobrien			 (match_dup 1)
1620690286Sobrien			 (match_dup 2)))
1620790286Sobrien   (clobber (reg:CC 17))]
1620890286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
1620950650Sobrien  "#")
1621050650Sobrien
1621190286Sobrien(define_insn "*maxdf_nonieee"
1621290286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
1621390286Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "%0,0")
1621490286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
1621590286Sobrien			 (match_dup 1)
1621690286Sobrien			 (match_dup 2)))
1621790286Sobrien   (clobber (reg:CC 17))]
1621890286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP"
1621990286Sobrien  "#")
1622090286Sobrien
1622150650Sobrien(define_split
1622252296Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1622390286Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
1622490286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" ""))
1622590286Sobrien			 (match_operand:DF 3 "register_operand" "")
1622690286Sobrien			 (match_operand:DF 4 "nonimmediate_operand" "")))
1622790286Sobrien   (clobber (reg:CC 17))]
1622890286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1622990286Sobrien   && ((operands_match_p (operands[1], operands[3])
1623090286Sobrien	&& operands_match_p (operands[2], operands[4]))
1623190286Sobrien       || (operands_match_p (operands[1], operands[4])
1623290286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1623390286Sobrien  [(set (match_dup 0)
1623490286Sobrien	(if_then_else:DF (gt (match_dup 1)
1623590286Sobrien			     (match_dup 2))
1623690286Sobrien			 (match_dup 1)
1623790286Sobrien			 (match_dup 2)))])
1623850650Sobrien
1623950650Sobrien(define_split
1624052296Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1624190286Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
1624290286Sobrien			     (match_operand:DF 2 "register_operand" ""))
1624390286Sobrien			 (match_operand:DF 3 "register_operand" "")
1624490286Sobrien			 (match_operand:DF 4 "register_operand" "")))
1624590286Sobrien   (clobber (reg:CC 17))]
1624690286Sobrien  "FP_REG_P (operands[0]) && reload_completed
1624790286Sobrien   && ((operands_match_p (operands[1], operands[3])
1624890286Sobrien	&& operands_match_p (operands[2], operands[4]))
1624990286Sobrien       || (operands_match_p (operands[1], operands[4])
1625090286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1625190286Sobrien  [(set (reg:CCFP 17)
1625290286Sobrien	(compare:CCFP (match_dup 1)
1625390286Sobrien		      (match_dup 2)))
1625450650Sobrien   (set (match_dup 0)
1625590286Sobrien	(if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
1625690286Sobrien			 (match_dup 1)
1625790286Sobrien			 (match_dup 2)))])
1625850650Sobrien
1625990286Sobrien(define_insn "*maxdf_sse"
1626090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1626190286Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
1626290286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym"))
1626390286Sobrien			 (match_dup 1)
1626490286Sobrien			 (match_dup 2)))]
1626590286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
1626690286Sobrien  "maxsd\t{%2, %0|%0, %2}"
1626790286Sobrien  [(set_attr "type" "sse")
1626890286Sobrien   (set_attr "mode" "DF")])
1626990286Sobrien
1627090286Sobrien;; Misc patterns (?)
1627150650Sobrien
1627290286Sobrien;; This pattern exists to put a dependency on all ebp-based memory accesses.
1627390286Sobrien;; Otherwise there will be nothing to keep
1627490286Sobrien;; 
1627590286Sobrien;; [(set (reg ebp) (reg esp))]
1627690286Sobrien;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
1627790286Sobrien;;  (clobber (eflags)]
1627890286Sobrien;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
1627990286Sobrien;;
1628090286Sobrien;; in proper program order.
1628190286Sobrien(define_expand "pro_epilogue_adjust_stack"
1628290286Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
1628390286Sobrien		   (plus:SI (match_operand:SI 1 "register_operand" "0,r")
1628490286Sobrien			    (match_operand:SI 2 "immediate_operand" "i,i")))
1628590286Sobrien	      (clobber (reg:CC 17))
1628690286Sobrien	      (clobber (mem:BLK (scratch)))])]
1628790286Sobrien ""
1628850650Sobrien{
1628990286Sobrien  if (TARGET_64BIT)
1629090286Sobrien    {
1629190286Sobrien      emit_insn (gen_pro_epilogue_adjust_stack_rex64
1629290286Sobrien		 (operands[0], operands[1], operands[2]));
1629390286Sobrien      DONE;
1629490286Sobrien    }
1629590286Sobrien})
1629650650Sobrien
1629790286Sobrien(define_insn "*pro_epilogue_adjust_stack_1"
1629890286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,r")
1629990286Sobrien	(plus:SI (match_operand:SI 1 "register_operand" "0,r")
1630090286Sobrien	         (match_operand:SI 2 "immediate_operand" "i,i")))
1630190286Sobrien   (clobber (reg:CC 17))
1630290286Sobrien   (clobber (mem:BLK (scratch)))]
1630390286Sobrien  "!TARGET_64BIT"
1630490286Sobrien{
1630590286Sobrien  switch (get_attr_type (insn))
1630690286Sobrien    {
1630790286Sobrien    case TYPE_IMOV:
1630890286Sobrien      return "mov{l}\t{%1, %0|%0, %1}";
1630950650Sobrien
1631090286Sobrien    case TYPE_ALU:
1631190286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
1631290286Sobrien          && (INTVAL (operands[2]) == 128
1631390286Sobrien	      || (INTVAL (operands[2]) < 0
1631490286Sobrien	          && INTVAL (operands[2]) != -128)))
1631590286Sobrien	{
1631690286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
1631790286Sobrien	  return "sub{l}\t{%2, %0|%0, %2}";
1631890286Sobrien	}
1631990286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
1632050650Sobrien
1632190286Sobrien    case TYPE_LEA:
1632290286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
1632390286Sobrien      return "lea{l}\t{%a2, %0|%0, %a2}";
1632490286Sobrien
1632590286Sobrien    default:
1632690286Sobrien      abort ();
1632790286Sobrien    }
1632890286Sobrien}
1632990286Sobrien  [(set (attr "type")
1633090286Sobrien	(cond [(eq_attr "alternative" "0")
1633190286Sobrien		 (const_string "alu")
1633290286Sobrien	       (match_operand:SI 2 "const0_operand" "")
1633390286Sobrien		 (const_string "imov")
1633490286Sobrien	      ]
1633590286Sobrien	      (const_string "lea")))
1633690286Sobrien   (set_attr "mode" "SI")])
1633790286Sobrien
1633890286Sobrien(define_insn "pro_epilogue_adjust_stack_rex64"
1633990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1634090286Sobrien	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
1634190286Sobrien		 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
1634290286Sobrien   (clobber (reg:CC 17))
1634390286Sobrien   (clobber (mem:BLK (scratch)))]
1634490286Sobrien  "TARGET_64BIT"
1634590286Sobrien{
1634690286Sobrien  switch (get_attr_type (insn))
1634750650Sobrien    {
1634890286Sobrien    case TYPE_IMOV:
1634990286Sobrien      return "mov{q}\t{%1, %0|%0, %1}";
1635050650Sobrien
1635190286Sobrien    case TYPE_ALU:
1635290286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
1635390286Sobrien          && (INTVAL (operands[2]) == 128
1635490286Sobrien	      || (INTVAL (operands[2]) < 0
1635590286Sobrien	          && INTVAL (operands[2]) != -128)))
1635690286Sobrien	{
1635790286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
1635890286Sobrien	  return "sub{q}\t{%2, %0|%0, %2}";
1635990286Sobrien	}
1636090286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
1636150650Sobrien
1636290286Sobrien    case TYPE_LEA:
1636390286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
1636490286Sobrien      return "lea{q}\t{%a2, %0|%0, %a2}";
1636550650Sobrien
1636650650Sobrien    default:
1636790286Sobrien      abort ();
1636850650Sobrien    }
1636990286Sobrien}
1637090286Sobrien  [(set (attr "type")
1637190286Sobrien	(cond [(eq_attr "alternative" "0")
1637290286Sobrien		 (const_string "alu")
1637390286Sobrien	       (match_operand:DI 2 "const0_operand" "")
1637490286Sobrien		 (const_string "imov")
1637590286Sobrien	      ]
1637690286Sobrien	      (const_string "lea")))
1637790286Sobrien   (set_attr "mode" "DI")])
1637850650Sobrien
1637990286Sobrien
1638090286Sobrien;; Placeholder for the conditional moves.  This one is split either to SSE
1638190286Sobrien;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
1638290286Sobrien;; fact is that compares supported by the cmp??ss instructions are exactly
1638390286Sobrien;; swapped of those supported by cmove sequence.
1638490286Sobrien;; The EQ/NE comparisons also needs bit care, since they are not directly
1638590286Sobrien;; supported by i387 comparisons and we do need to emit two conditional moves
1638690286Sobrien;; in tandem.
1638790286Sobrien
1638890286Sobrien(define_insn "sse_movsfcc"
1638990286Sobrien  [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
1639090286Sobrien	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
1639190286Sobrien			[(match_operand:SF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
1639290286Sobrien			 (match_operand:SF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
1639390286Sobrien		      (match_operand:SF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
1639490286Sobrien		      (match_operand:SF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
1639590286Sobrien   (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
1639690286Sobrien   (clobber (reg:CC 17))]
1639790286Sobrien  "TARGET_SSE
1639890286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
1639990286Sobrien   && (!TARGET_IEEE_FP
1640090286Sobrien       || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
1640150650Sobrien  "#")
1640250650Sobrien
1640390286Sobrien(define_insn "sse_movsfcc_eq"
1640490286Sobrien  [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
1640590286Sobrien	(if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
1640690286Sobrien			     (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
1640790286Sobrien		      (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
1640890286Sobrien		      (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
1640990286Sobrien   (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
1641090286Sobrien   (clobber (reg:CC 17))]
1641190286Sobrien  "TARGET_SSE
1641290286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1641350650Sobrien  "#")
1641450650Sobrien
1641590286Sobrien(define_insn "sse_movdfcc"
1641690286Sobrien  [(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
1641790286Sobrien	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
1641890286Sobrien			[(match_operand:DF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
1641990286Sobrien			 (match_operand:DF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
1642090286Sobrien		      (match_operand:DF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
1642190286Sobrien		      (match_operand:DF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
1642290286Sobrien   (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
1642390286Sobrien   (clobber (reg:CC 17))]
1642490286Sobrien  "TARGET_SSE2
1642590286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
1642690286Sobrien   && (!TARGET_IEEE_FP
1642790286Sobrien       || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
1642890286Sobrien  "#")
1642990286Sobrien
1643090286Sobrien(define_insn "sse_movdfcc_eq"
1643190286Sobrien  [(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
1643290286Sobrien	(if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
1643390286Sobrien			     (match_operand:DF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
1643490286Sobrien		      (match_operand:DF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
1643590286Sobrien		      (match_operand:DF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
1643690286Sobrien   (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
1643790286Sobrien   (clobber (reg:CC 17))]
1643890286Sobrien  "TARGET_SSE
1643990286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1644090286Sobrien  "#")
1644190286Sobrien
1644290286Sobrien;; For non-sse moves just expand the usual cmove sequence.
1644350650Sobrien(define_split
1644490286Sobrien  [(set (match_operand 0 "register_operand" "")
1644590286Sobrien	(if_then_else (match_operator 1 "comparison_operator"
1644690286Sobrien			[(match_operand 4 "nonimmediate_operand" "")
1644790286Sobrien			 (match_operand 5 "register_operand" "")])
1644890286Sobrien		      (match_operand 2 "nonimmediate_operand" "")
1644990286Sobrien		      (match_operand 3 "nonimmediate_operand" "")))
1645090286Sobrien   (clobber (match_operand 6 "" ""))
1645190286Sobrien   (clobber (reg:CC 17))]
1645290286Sobrien  "!SSE_REG_P (operands[0]) && reload_completed
1645390286Sobrien   && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
1645490286Sobrien  [(const_int 0)]
1645590286Sobrien{
1645690286Sobrien   ix86_compare_op0 = operands[5];
1645790286Sobrien   ix86_compare_op1 = operands[4];
1645890286Sobrien   operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
1645990286Sobrien				 VOIDmode, operands[5], operands[4]);
1646090286Sobrien   ix86_expand_fp_movcc (operands);
1646190286Sobrien   DONE;
1646290286Sobrien})
1646350650Sobrien
1646490286Sobrien;; Split SSE based conditional move into seqence:
1646590286Sobrien;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
1646690286Sobrien;; and   op2, op0   -  zero op2 if comparison was false
1646790286Sobrien;; nand  op0, op3   -  load op3 to op0 if comparison was false
1646890286Sobrien;; or	 op2, op0   -  get the non-zero one into the result.
1646950650Sobrien(define_split
1647090286Sobrien  [(set (match_operand 0 "register_operand" "")
1647190286Sobrien	(if_then_else (match_operator 1 "sse_comparison_operator"
1647290286Sobrien			[(match_operand 4 "register_operand" "")
1647390286Sobrien			 (match_operand 5 "nonimmediate_operand" "")])
1647490286Sobrien		      (match_operand 2 "register_operand" "")
1647590286Sobrien		      (match_operand 3 "register_operand" "")))
1647690286Sobrien   (clobber (match_operand 6 "" ""))
1647790286Sobrien   (clobber (reg:CC 17))]
1647890286Sobrien  "SSE_REG_P (operands[0]) && reload_completed"
1647990286Sobrien  [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
1648090286Sobrien   (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
1648190286Sobrien					    (subreg:TI (match_dup 4) 0)))
1648290286Sobrien   (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
1648390286Sobrien					    (subreg:TI (match_dup 3) 0)))
1648490286Sobrien   (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
1648590286Sobrien					    (subreg:TI (match_dup 7) 0)))]
1648690286Sobrien{
1648790286Sobrien  PUT_MODE (operands[1], GET_MODE (operands[0]));
1648890286Sobrien  if (operands_match_p (operands[0], operands[4]))
1648990286Sobrien    operands[6] = operands[4], operands[7] = operands[2];
1649090286Sobrien  else
1649190286Sobrien    operands[6] = operands[2], operands[7] = operands[4];
1649290286Sobrien})
1649350650Sobrien
1649490286Sobrien;; Special case of conditional move we can handle effectivly.
1649590286Sobrien;; Do not brother with the integer/floating point case, since these are
1649690286Sobrien;; bot considerably slower, unlike in the generic case.
1649790286Sobrien(define_insn "*sse_movsfcc_const0_1"
1649890286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1649990286Sobrien	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
1650090286Sobrien			[(match_operand:SF 4 "register_operand" "0")
1650190286Sobrien			 (match_operand:SF 5 "nonimmediate_operand" "xm")])
1650290286Sobrien		      (match_operand:SF 2 "register_operand" "x")
1650390286Sobrien		      (match_operand:SF 3 "const0_operand" "X")))]
1650490286Sobrien  "TARGET_SSE"
1650590286Sobrien  "#")
1650650650Sobrien
1650790286Sobrien(define_insn "*sse_movsfcc_const0_2"
1650890286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1650990286Sobrien	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
1651090286Sobrien			[(match_operand:SF 4 "register_operand" "0")
1651190286Sobrien			 (match_operand:SF 5 "nonimmediate_operand" "xm")])
1651290286Sobrien		      (match_operand:SF 2 "const0_operand" "X")
1651390286Sobrien		      (match_operand:SF 3 "register_operand" "x")))]
1651490286Sobrien  "TARGET_SSE"
1651590286Sobrien  "#")
1651650650Sobrien
1651790286Sobrien(define_insn "*sse_movsfcc_const0_3"
1651890286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1651990286Sobrien	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
1652090286Sobrien			[(match_operand:SF 4 "nonimmediate_operand" "xm")
1652190286Sobrien			 (match_operand:SF 5 "register_operand" "0")])
1652290286Sobrien		      (match_operand:SF 2 "register_operand" "x")
1652390286Sobrien		      (match_operand:SF 3 "const0_operand" "X")))]
1652490286Sobrien  "TARGET_SSE"
1652590286Sobrien  "#")
1652650650Sobrien
1652790286Sobrien(define_insn "*sse_movsfcc_const0_4"
1652890286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1652990286Sobrien	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
1653090286Sobrien			[(match_operand:SF 4 "nonimmediate_operand" "xm")
1653190286Sobrien			 (match_operand:SF 5 "register_operand" "0")])
1653290286Sobrien		      (match_operand:SF 2 "const0_operand" "X")
1653390286Sobrien		      (match_operand:SF 3 "register_operand" "x")))]
1653490286Sobrien  "TARGET_SSE"
1653550650Sobrien  "#")
1653650650Sobrien
1653790286Sobrien(define_insn "*sse_movdfcc_const0_1"
1653890286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1653990286Sobrien	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
1654090286Sobrien			[(match_operand:SF 4 "register_operand" "0")
1654190286Sobrien			 (match_operand:SF 5 "nonimmediate_operand" "xm")])
1654290286Sobrien		      (match_operand:SF 2 "register_operand" "x")
1654390286Sobrien		      (match_operand:SF 3 "const0_operand" "X")))]
1654490286Sobrien  "TARGET_SSE2"
1654550650Sobrien  "#")
1654650650Sobrien
1654790286Sobrien(define_insn "*sse_movdfcc_const0_2"
1654890286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1654990286Sobrien	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
1655090286Sobrien			[(match_operand:SF 4 "register_operand" "0")
1655190286Sobrien			 (match_operand:SF 5 "nonimmediate_operand" "xm")])
1655290286Sobrien		      (match_operand:SF 2 "const0_operand" "X")
1655390286Sobrien		      (match_operand:SF 3 "register_operand" "x")))]
1655490286Sobrien  "TARGET_SSE2"
1655590286Sobrien  "#")
1655650650Sobrien
1655790286Sobrien(define_insn "*sse_movdfcc_const0_3"
1655890286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1655990286Sobrien	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
1656090286Sobrien			[(match_operand:SF 4 "nonimmediate_operand" "xm")
1656190286Sobrien			 (match_operand:SF 5 "register_operand" "0")])
1656290286Sobrien		      (match_operand:SF 2 "register_operand" "x")
1656390286Sobrien		      (match_operand:SF 3 "const0_operand" "X")))]
1656490286Sobrien  "TARGET_SSE2"
1656590286Sobrien  "#")
1656650650Sobrien
1656790286Sobrien(define_insn "*sse_movdfcc_const0_4"
1656890286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1656990286Sobrien	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
1657090286Sobrien			[(match_operand:SF 4 "nonimmediate_operand" "xm")
1657190286Sobrien			 (match_operand:SF 5 "register_operand" "0")])
1657290286Sobrien		      (match_operand:SF 2 "const0_operand" "X")
1657390286Sobrien		      (match_operand:SF 3 "register_operand" "x")))]
1657490286Sobrien  "TARGET_SSE2"
1657590286Sobrien  "#")
1657650650Sobrien
1657790286Sobrien(define_split
1657890286Sobrien  [(set (match_operand 0 "register_operand" "")
1657990286Sobrien	(if_then_else (match_operator 1 "comparison_operator"
1658090286Sobrien			[(match_operand 4 "register_operand" "")
1658190286Sobrien			 (match_operand 5 "nonimmediate_operand" "")])
1658290286Sobrien		      (match_operand 2 "nonmemory_operand" "")
1658390286Sobrien		      (match_operand 3 "nonmemory_operand" "")))]
1658490286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1658590286Sobrien   && (const0_operand (operands[2], GET_MODE (operands[0]))
1658690286Sobrien       || const0_operand (operands[3], GET_MODE (operands[0])))"
1658790286Sobrien  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
1658890286Sobrien   (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
1658990286Sobrien					    (subreg:TI (match_dup 7) 0)))]
1659090286Sobrien{
1659190286Sobrien  PUT_MODE (operands[1], GET_MODE (operands[0]));
1659290286Sobrien  if (!sse_comparison_operator (operands[1], VOIDmode))
1659390286Sobrien    {
1659490286Sobrien      rtx tmp = operands[5];
1659590286Sobrien      operands[5] = operands[4];
1659690286Sobrien      operands[4] = tmp;
1659790286Sobrien      PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
1659890286Sobrien    }
1659990286Sobrien  if (const0_operand (operands[2], GET_MODE (operands[0])))
1660090286Sobrien    {
1660190286Sobrien      operands[7] = operands[3];
1660290286Sobrien      operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
1660390286Sobrien							 0));
1660490286Sobrien    }
1660590286Sobrien  else
1660690286Sobrien    {
1660790286Sobrien      operands[7] = operands[2];
1660890286Sobrien      operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
1660990286Sobrien    }
1661090286Sobrien})
1661150650Sobrien
1661290286Sobrien(define_expand "allocate_stack_worker"
1661390286Sobrien  [(match_operand:SI 0 "register_operand" "")]
1661490286Sobrien  "TARGET_STACK_PROBE"
1661590286Sobrien{
1661690286Sobrien  if (TARGET_64BIT)
1661790286Sobrien    emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
1661890286Sobrien  else
1661990286Sobrien    emit_insn (gen_allocate_stack_worker_1 (operands[0]));
1662090286Sobrien  DONE;
1662190286Sobrien})
1662250650Sobrien
1662390286Sobrien(define_insn "allocate_stack_worker_1"
1662450650Sobrien  [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
1662550650Sobrien   (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
1662690286Sobrien   (clobber (match_dup 0))
1662790286Sobrien   (clobber (reg:CC 17))]
1662890286Sobrien  "!TARGET_64BIT && TARGET_STACK_PROBE"
1662990286Sobrien  "call\t__alloca"
1663090286Sobrien  [(set_attr "type" "multi")
1663190286Sobrien   (set_attr "length" "5")])
1663250650Sobrien
1663390286Sobrien(define_insn "allocate_stack_worker_rex64"
1663490286Sobrien  [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] 3)
1663590286Sobrien   (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
1663690286Sobrien   (clobber (match_dup 0))
1663790286Sobrien   (clobber (reg:CC 17))]
1663890286Sobrien  "TARGET_64BIT && TARGET_STACK_PROBE"
1663990286Sobrien  "call\t__alloca"
1664090286Sobrien  [(set_attr "type" "multi")
1664190286Sobrien   (set_attr "length" "5")])
1664290286Sobrien
1664350650Sobrien(define_expand "allocate_stack"
1664490286Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
1664590286Sobrien		   (minus:SI (reg:SI 7)
1664690286Sobrien			     (match_operand:SI 1 "general_operand" "")))
1664790286Sobrien	      (clobber (reg:CC 17))])
1664890286Sobrien   (parallel [(set (reg:SI 7)
1664990286Sobrien		   (minus:SI (reg:SI 7) (match_dup 1)))
1665090286Sobrien	      (clobber (reg:CC 17))])]
1665190286Sobrien  "TARGET_STACK_PROBE"
1665250650Sobrien{
1665350650Sobrien#ifdef CHECK_STACK_LIMIT
1665450650Sobrien  if (GET_CODE (operands[1]) == CONST_INT
1665550650Sobrien      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
1665650650Sobrien    emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
1665750650Sobrien			   operands[1]));
1665850650Sobrien  else 
1665950650Sobrien#endif
1666050650Sobrien    emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
1666150650Sobrien							    operands[1])));
1666250650Sobrien
1666350650Sobrien  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
1666450650Sobrien  DONE;
1666590286Sobrien})
1666650650Sobrien
1666790286Sobrien(define_expand "builtin_setjmp_receiver"
1666890286Sobrien  [(label_ref (match_operand 0 "" ""))]
1666990286Sobrien  "!TARGET_64BIT && flag_pic"
1667050650Sobrien{
1667190286Sobrien  load_pic_register ();
1667256391Sobrien  DONE;
1667390286Sobrien})
1667490286Sobrien
1667590286Sobrien;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
1667656391Sobrien
1667790286Sobrien(define_split
1667890286Sobrien  [(set (match_operand 0 "register_operand" "")
1667990286Sobrien	(match_operator 3 "promotable_binary_operator"
1668090286Sobrien	   [(match_operand 1 "register_operand" "")
1668190286Sobrien	    (match_operand 2 "aligned_operand" "")]))
1668290286Sobrien   (clobber (reg:CC 17))]
1668390286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
1668490286Sobrien   && ((GET_MODE (operands[0]) == HImode 
1668590286Sobrien	&& (!optimize_size || GET_CODE (operands[2]) != CONST_INT
1668690286Sobrien	    || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
1668790286Sobrien       || (GET_MODE (operands[0]) == QImode 
1668890286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1668990286Sobrien  [(parallel [(set (match_dup 0)
1669090286Sobrien		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
1669190286Sobrien	      (clobber (reg:CC 17))])]
1669290286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);
1669390286Sobrien   operands[1] = gen_lowpart (SImode, operands[1]);
1669490286Sobrien   if (GET_CODE (operands[3]) != ASHIFT)
1669590286Sobrien     operands[2] = gen_lowpart (SImode, operands[2]);
1669690286Sobrien   PUT_MODE (operands[3], SImode);")
1669790286Sobrien
1669890286Sobrien(define_split
1669990286Sobrien  [(set (reg 17)
1670090286Sobrien	(compare (and (match_operand 1 "aligned_operand" "")
1670190286Sobrien		      (match_operand 2 "const_int_operand" ""))
1670290286Sobrien		 (const_int 0)))
1670390286Sobrien   (set (match_operand 0 "register_operand" "")
1670490286Sobrien	(and (match_dup 1) (match_dup 2)))]
1670590286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
1670690286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
1670790286Sobrien   && (GET_MODE (operands[0]) == HImode
1670890286Sobrien       || (GET_MODE (operands[0]) == QImode 
1670990286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1671090286Sobrien  [(parallel [(set (reg:CCNO 17)
1671190286Sobrien		   (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
1671290286Sobrien			         (const_int 0)))
1671390286Sobrien	      (set (match_dup 0)
1671490286Sobrien		   (and:SI (match_dup 1) (match_dup 2)))])]
1671590286Sobrien  "operands[2]
1671690286Sobrien     = GEN_INT (trunc_int_for_mode (INTVAL (operands[2])
1671790286Sobrien				    & GET_MODE_MASK (GET_MODE (operands[0])),
1671890286Sobrien				    SImode));
1671990286Sobrien   operands[0] = gen_lowpart (SImode, operands[0]);
1672090286Sobrien   operands[1] = gen_lowpart (SImode, operands[1]);")
1672190286Sobrien
1672290286Sobrien(define_split
1672390286Sobrien  [(set (reg 17)
1672490286Sobrien	(compare (and (match_operand 0 "aligned_operand" "")
1672590286Sobrien		      (match_operand 1 "const_int_operand" ""))
1672690286Sobrien		 (const_int 0)))]
1672790286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
1672890286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
1672990286Sobrien   && (GET_MODE (operands[0]) == HImode
1673090286Sobrien       || (GET_MODE (operands[0]) == QImode 
1673190286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1673290286Sobrien  [(set (reg:CCNO 17)
1673390286Sobrien	(compare:CCNO (and:SI (match_dup 0) (match_dup 1))
1673490286Sobrien		      (const_int 0)))]
1673590286Sobrien  "operands[1]
1673690286Sobrien     = GEN_INT (trunc_int_for_mode (INTVAL (operands[1])
1673790286Sobrien				    & GET_MODE_MASK (GET_MODE (operands[0])),
1673890286Sobrien				    SImode));
1673990286Sobrien   operands[0] = gen_lowpart (SImode, operands[0]);")
1674090286Sobrien
1674190286Sobrien(define_split
1674290286Sobrien  [(set (match_operand 0 "register_operand" "")
1674390286Sobrien	(neg (match_operand 1 "register_operand" "")))
1674490286Sobrien   (clobber (reg:CC 17))]
1674590286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
1674690286Sobrien   && (GET_MODE (operands[0]) == HImode
1674790286Sobrien       || (GET_MODE (operands[0]) == QImode 
1674890286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1674990286Sobrien  [(parallel [(set (match_dup 0)
1675090286Sobrien		   (neg:SI (match_dup 1)))
1675190286Sobrien	      (clobber (reg:CC 17))])]
1675290286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);
1675390286Sobrien   operands[1] = gen_lowpart (SImode, operands[1]);")
1675490286Sobrien
1675590286Sobrien(define_split
1675690286Sobrien  [(set (match_operand 0 "register_operand" "")
1675790286Sobrien	(not (match_operand 1 "register_operand" "")))]
1675890286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
1675990286Sobrien   && (GET_MODE (operands[0]) == HImode
1676090286Sobrien       || (GET_MODE (operands[0]) == QImode 
1676190286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1676290286Sobrien  [(set (match_dup 0)
1676390286Sobrien	(not:SI (match_dup 1)))]
1676490286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);
1676590286Sobrien   operands[1] = gen_lowpart (SImode, operands[1]);")
1676690286Sobrien
1676790286Sobrien(define_split 
1676890286Sobrien  [(set (match_operand 0 "register_operand" "")
1676990286Sobrien	(if_then_else (match_operator 1 "comparison_operator" 
1677090286Sobrien				[(reg 17) (const_int 0)])
1677190286Sobrien		      (match_operand 2 "register_operand" "")
1677290286Sobrien		      (match_operand 3 "register_operand" "")))]
1677390286Sobrien  "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
1677490286Sobrien   && (GET_MODE (operands[0]) == HImode
1677590286Sobrien       || (GET_MODE (operands[0]) == QImode 
1677690286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1677790286Sobrien  [(set (match_dup 0)
1677890286Sobrien	(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
1677990286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);
1678090286Sobrien   operands[2] = gen_lowpart (SImode, operands[2]);
1678190286Sobrien   operands[3] = gen_lowpart (SImode, operands[3]);")
1678290286Sobrien			
1678390286Sobrien
1678490286Sobrien;; RTL Peephole optimizations, run before sched2.  These primarily look to
1678590286Sobrien;; transform a complex memory operation into two memory to register operations.
1678690286Sobrien
1678790286Sobrien;; Don't push memory operands
1678890286Sobrien(define_peephole2
1678990286Sobrien  [(set (match_operand:SI 0 "push_operand" "")
1679090286Sobrien	(match_operand:SI 1 "memory_operand" ""))
1679190286Sobrien   (match_scratch:SI 2 "r")]
1679290286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1679390286Sobrien  [(set (match_dup 2) (match_dup 1))
1679490286Sobrien   (set (match_dup 0) (match_dup 2))]
1679590286Sobrien  "")
1679690286Sobrien
1679790286Sobrien(define_peephole2
1679890286Sobrien  [(set (match_operand:DI 0 "push_operand" "")
1679990286Sobrien	(match_operand:DI 1 "memory_operand" ""))
1680090286Sobrien   (match_scratch:DI 2 "r")]
1680190286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1680290286Sobrien  [(set (match_dup 2) (match_dup 1))
1680390286Sobrien   (set (match_dup 0) (match_dup 2))]
1680490286Sobrien  "")
1680590286Sobrien
1680690286Sobrien;; We need to handle SFmode only, because DFmode and XFmode is split to
1680790286Sobrien;; SImode pushes.
1680890286Sobrien(define_peephole2
1680990286Sobrien  [(set (match_operand:SF 0 "push_operand" "")
1681090286Sobrien	(match_operand:SF 1 "memory_operand" ""))
1681190286Sobrien   (match_scratch:SF 2 "r")]
1681290286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1681390286Sobrien  [(set (match_dup 2) (match_dup 1))
1681490286Sobrien   (set (match_dup 0) (match_dup 2))]
1681590286Sobrien  "")
1681690286Sobrien
1681790286Sobrien(define_peephole2
1681890286Sobrien  [(set (match_operand:HI 0 "push_operand" "")
1681990286Sobrien	(match_operand:HI 1 "memory_operand" ""))
1682090286Sobrien   (match_scratch:HI 2 "r")]
1682190286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1682290286Sobrien  [(set (match_dup 2) (match_dup 1))
1682390286Sobrien   (set (match_dup 0) (match_dup 2))]
1682490286Sobrien  "")
1682590286Sobrien
1682690286Sobrien(define_peephole2
1682790286Sobrien  [(set (match_operand:QI 0 "push_operand" "")
1682890286Sobrien	(match_operand:QI 1 "memory_operand" ""))
1682990286Sobrien   (match_scratch:QI 2 "q")]
1683090286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1683190286Sobrien  [(set (match_dup 2) (match_dup 1))
1683290286Sobrien   (set (match_dup 0) (match_dup 2))]
1683390286Sobrien  "")
1683490286Sobrien
1683590286Sobrien;; Don't move an immediate directly to memory when the instruction
1683690286Sobrien;; gets too big.
1683790286Sobrien(define_peephole2
1683890286Sobrien  [(match_scratch:SI 1 "r")
1683990286Sobrien   (set (match_operand:SI 0 "memory_operand" "")
1684090286Sobrien        (const_int 0))]
1684190286Sobrien  "! optimize_size
1684290286Sobrien   && ! TARGET_USE_MOV0
1684390286Sobrien   && TARGET_SPLIT_LONG_MOVES
1684490286Sobrien   && get_attr_length (insn) >= ix86_cost->large_insn
1684590286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1684690286Sobrien  [(parallel [(set (match_dup 1) (const_int 0))
1684790286Sobrien	      (clobber (reg:CC 17))])
1684890286Sobrien   (set (match_dup 0) (match_dup 1))]
1684990286Sobrien  "")
1685090286Sobrien
1685190286Sobrien(define_peephole2
1685290286Sobrien  [(match_scratch:HI 1 "r")
1685390286Sobrien   (set (match_operand:HI 0 "memory_operand" "")
1685490286Sobrien        (const_int 0))]
1685590286Sobrien  "! optimize_size
1685690286Sobrien   && ! TARGET_USE_MOV0
1685790286Sobrien   && TARGET_SPLIT_LONG_MOVES
1685890286Sobrien   && get_attr_length (insn) >= ix86_cost->large_insn
1685990286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1686090286Sobrien  [(parallel [(set (match_dup 2) (const_int 0))
1686190286Sobrien	      (clobber (reg:CC 17))])
1686290286Sobrien   (set (match_dup 0) (match_dup 1))]
1686390286Sobrien  "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
1686490286Sobrien
1686590286Sobrien(define_peephole2
1686690286Sobrien  [(match_scratch:QI 1 "q")
1686790286Sobrien   (set (match_operand:QI 0 "memory_operand" "")
1686890286Sobrien        (const_int 0))]
1686990286Sobrien  "! optimize_size
1687090286Sobrien   && ! TARGET_USE_MOV0
1687190286Sobrien   && TARGET_SPLIT_LONG_MOVES
1687290286Sobrien   && get_attr_length (insn) >= ix86_cost->large_insn
1687390286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1687490286Sobrien  [(parallel [(set (match_dup 2) (const_int 0))
1687590286Sobrien	      (clobber (reg:CC 17))])
1687690286Sobrien   (set (match_dup 0) (match_dup 1))]
1687790286Sobrien  "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
1687890286Sobrien
1687990286Sobrien(define_peephole2
1688090286Sobrien  [(match_scratch:SI 2 "r")
1688190286Sobrien   (set (match_operand:SI 0 "memory_operand" "")
1688290286Sobrien        (match_operand:SI 1 "immediate_operand" ""))]
1688390286Sobrien  "! optimize_size
1688490286Sobrien   && get_attr_length (insn) >= ix86_cost->large_insn
1688590286Sobrien   && TARGET_SPLIT_LONG_MOVES"
1688690286Sobrien  [(set (match_dup 2) (match_dup 1))
1688790286Sobrien   (set (match_dup 0) (match_dup 2))]
1688890286Sobrien  "")
1688990286Sobrien
1689090286Sobrien(define_peephole2
1689190286Sobrien  [(match_scratch:HI 2 "r")
1689290286Sobrien   (set (match_operand:HI 0 "memory_operand" "")
1689390286Sobrien        (match_operand:HI 1 "immediate_operand" ""))]
1689490286Sobrien  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
1689590286Sobrien  && TARGET_SPLIT_LONG_MOVES"
1689690286Sobrien  [(set (match_dup 2) (match_dup 1))
1689790286Sobrien   (set (match_dup 0) (match_dup 2))]
1689890286Sobrien  "")
1689990286Sobrien
1690090286Sobrien(define_peephole2
1690190286Sobrien  [(match_scratch:QI 2 "q")
1690290286Sobrien   (set (match_operand:QI 0 "memory_operand" "")
1690390286Sobrien        (match_operand:QI 1 "immediate_operand" ""))]
1690490286Sobrien  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
1690590286Sobrien  && TARGET_SPLIT_LONG_MOVES"
1690690286Sobrien  [(set (match_dup 2) (match_dup 1))
1690790286Sobrien   (set (match_dup 0) (match_dup 2))]
1690890286Sobrien  "")
1690990286Sobrien
1691090286Sobrien;; Don't compare memory with zero, load and use a test instead.
1691190286Sobrien(define_peephole2
1691290286Sobrien  [(set (reg 17)
1691390286Sobrien	(compare (match_operand:SI 0 "memory_operand" "")
1691490286Sobrien	         (const_int 0)))
1691590286Sobrien   (match_scratch:SI 3 "r")]
1691690286Sobrien  "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
1691790286Sobrien  [(set (match_dup 3) (match_dup 0))
1691890286Sobrien   (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
1691990286Sobrien  "")
1692090286Sobrien
1692190286Sobrien;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
1692290286Sobrien;; Don't split NOTs with a displacement operand, because resulting XOR
1692390286Sobrien;; will not be pariable anyway.
1692490286Sobrien;;
1692590286Sobrien;; On AMD K6, NOT is vector decoded with memory operand that can not be
1692690286Sobrien;; represented using a modRM byte.  The XOR replacement is long decoded,
1692790286Sobrien;; so this split helps here as well.
1692890286Sobrien;;
1692990286Sobrien;; Note: Can't do this as a regular split because we can't get proper
1693090286Sobrien;; lifetime information then.
1693190286Sobrien
1693290286Sobrien(define_peephole2
1693390286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1693490286Sobrien	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
1693590286Sobrien  "!optimize_size
1693690286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)
1693790286Sobrien   && ((TARGET_PENTIUM 
1693890286Sobrien        && (GET_CODE (operands[0]) != MEM
1693990286Sobrien            || !memory_displacement_operand (operands[0], SImode)))
1694090286Sobrien       || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
1694190286Sobrien  [(parallel [(set (match_dup 0)
1694290286Sobrien		   (xor:SI (match_dup 1) (const_int -1)))
1694390286Sobrien	      (clobber (reg:CC 17))])]
1694490286Sobrien  "")
1694590286Sobrien
1694690286Sobrien(define_peephole2
1694790286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1694890286Sobrien	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
1694990286Sobrien  "!optimize_size
1695090286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)
1695190286Sobrien   && ((TARGET_PENTIUM 
1695290286Sobrien        && (GET_CODE (operands[0]) != MEM
1695390286Sobrien            || !memory_displacement_operand (operands[0], HImode)))
1695490286Sobrien       || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
1695590286Sobrien  [(parallel [(set (match_dup 0)
1695690286Sobrien		   (xor:HI (match_dup 1) (const_int -1)))
1695790286Sobrien	      (clobber (reg:CC 17))])]
1695890286Sobrien  "")
1695990286Sobrien
1696090286Sobrien(define_peephole2
1696190286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1696290286Sobrien	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
1696390286Sobrien  "!optimize_size
1696490286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)
1696590286Sobrien   && ((TARGET_PENTIUM 
1696690286Sobrien        && (GET_CODE (operands[0]) != MEM
1696790286Sobrien            || !memory_displacement_operand (operands[0], QImode)))
1696890286Sobrien       || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
1696990286Sobrien  [(parallel [(set (match_dup 0)
1697090286Sobrien		   (xor:QI (match_dup 1) (const_int -1)))
1697190286Sobrien	      (clobber (reg:CC 17))])]
1697290286Sobrien  "")
1697390286Sobrien
1697490286Sobrien;; Non pairable "test imm, reg" instructions can be translated to
1697590286Sobrien;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
1697690286Sobrien;; byte opcode instead of two, have a short form for byte operands),
1697790286Sobrien;; so do it for other CPUs as well.  Given that the value was dead,
1697890286Sobrien;; this should not create any new dependencies.  Pass on the sub-word
1697990286Sobrien;; versions if we're concerned about partial register stalls.
1698090286Sobrien
1698190286Sobrien(define_peephole2
1698290286Sobrien  [(set (reg 17)
1698390286Sobrien	(compare (and:SI (match_operand:SI 0 "register_operand" "")
1698490286Sobrien			 (match_operand:SI 1 "immediate_operand" ""))
1698590286Sobrien		 (const_int 0)))]
1698690286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
1698790286Sobrien   && (true_regnum (operands[0]) != 0
1698890286Sobrien       || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
1698990286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1699090286Sobrien  [(parallel
1699190286Sobrien     [(set (reg:CCNO 17)
1699290286Sobrien	   (compare:CCNO (and:SI (match_dup 0)
1699390286Sobrien			         (match_dup 1))
1699490286Sobrien		         (const_int 0)))
1699590286Sobrien      (set (match_dup 0)
1699690286Sobrien	   (and:SI (match_dup 0) (match_dup 1)))])]
1699790286Sobrien  "")
1699890286Sobrien
1699990286Sobrien;; We don't need to handle HImode case, because it will be promoted to SImode
1700090286Sobrien;; on ! TARGET_PARTIAL_REG_STALL
1700190286Sobrien
1700290286Sobrien(define_peephole2
1700390286Sobrien  [(set (reg 17)
1700490286Sobrien	(compare (and:QI (match_operand:QI 0 "register_operand" "")
1700590286Sobrien			 (match_operand:QI 1 "immediate_operand" ""))
1700690286Sobrien		 (const_int 0)))]
1700790286Sobrien  "! TARGET_PARTIAL_REG_STALL
1700890286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
1700990286Sobrien   && true_regnum (operands[0]) != 0
1701090286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1701190286Sobrien  [(parallel
1701290286Sobrien     [(set (reg:CCNO 17)
1701390286Sobrien	   (compare:CCNO (and:QI (match_dup 0)
1701490286Sobrien 			         (match_dup 1))
1701590286Sobrien		         (const_int 0)))
1701690286Sobrien      (set (match_dup 0)
1701790286Sobrien	   (and:QI (match_dup 0) (match_dup 1)))])]
1701890286Sobrien  "")
1701990286Sobrien
1702090286Sobrien(define_peephole2
1702190286Sobrien  [(set (reg 17)
1702290286Sobrien	(compare
1702390286Sobrien	  (and:SI
1702490286Sobrien	    (zero_extract:SI
1702590286Sobrien	      (match_operand 0 "ext_register_operand" "")
1702690286Sobrien	      (const_int 8)
1702790286Sobrien	      (const_int 8))
1702890286Sobrien	    (match_operand 1 "const_int_operand" ""))
1702990286Sobrien	  (const_int 0)))]
1703090286Sobrien  "! TARGET_PARTIAL_REG_STALL
1703190286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
1703290286Sobrien   && true_regnum (operands[0]) != 0
1703390286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1703490286Sobrien  [(parallel [(set (reg:CCNO 17)
1703590286Sobrien		   (compare:CCNO
1703690286Sobrien		       (and:SI
1703790286Sobrien			 (zero_extract:SI
1703890286Sobrien			 (match_dup 0)
1703990286Sobrien			 (const_int 8)
1704090286Sobrien			 (const_int 8))
1704190286Sobrien			(match_dup 1))
1704290286Sobrien		   (const_int 0)))
1704390286Sobrien	      (set (zero_extract:SI (match_dup 0)
1704490286Sobrien				    (const_int 8)
1704590286Sobrien				    (const_int 8))
1704690286Sobrien		   (and:SI 
1704790286Sobrien		     (zero_extract:SI
1704890286Sobrien		       (match_dup 0)
1704990286Sobrien		       (const_int 8)
1705090286Sobrien		       (const_int 8))
1705190286Sobrien		     (match_dup 1)))])]
1705290286Sobrien  "")
1705390286Sobrien
1705490286Sobrien;; Don't do logical operations with memory inputs.
1705590286Sobrien(define_peephole2
1705690286Sobrien  [(match_scratch:SI 2 "r")
1705790286Sobrien   (parallel [(set (match_operand:SI 0 "register_operand" "")
1705890286Sobrien                   (match_operator:SI 3 "arith_or_logical_operator"
1705990286Sobrien                     [(match_dup 0)
1706090286Sobrien                      (match_operand:SI 1 "memory_operand" "")]))
1706190286Sobrien              (clobber (reg:CC 17))])]
1706290286Sobrien  "! optimize_size && ! TARGET_READ_MODIFY"
1706390286Sobrien  [(set (match_dup 2) (match_dup 1))
1706490286Sobrien   (parallel [(set (match_dup 0)
1706590286Sobrien                   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
1706690286Sobrien              (clobber (reg:CC 17))])]
1706790286Sobrien  "")
1706890286Sobrien
1706990286Sobrien(define_peephole2
1707090286Sobrien  [(match_scratch:SI 2 "r")
1707190286Sobrien   (parallel [(set (match_operand:SI 0 "register_operand" "")
1707290286Sobrien                   (match_operator:SI 3 "arith_or_logical_operator"
1707390286Sobrien                     [(match_operand:SI 1 "memory_operand" "")
1707490286Sobrien                      (match_dup 0)]))
1707590286Sobrien              (clobber (reg:CC 17))])]
1707690286Sobrien  "! optimize_size && ! TARGET_READ_MODIFY"
1707790286Sobrien  [(set (match_dup 2) (match_dup 1))
1707890286Sobrien   (parallel [(set (match_dup 0)
1707990286Sobrien                   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
1708090286Sobrien              (clobber (reg:CC 17))])]
1708190286Sobrien  "")
1708290286Sobrien
1708390286Sobrien; Don't do logical operations with memory outputs
1708490286Sobrien;
1708590286Sobrien; These two don't make sense for PPro/PII -- we're expanding a 4-uop
1708690286Sobrien; instruction into two 1-uop insns plus a 2-uop insn.  That last has
1708790286Sobrien; the same decoder scheduling characteristics as the original.
1708890286Sobrien
1708990286Sobrien(define_peephole2
1709090286Sobrien  [(match_scratch:SI 2 "r")
1709190286Sobrien   (parallel [(set (match_operand:SI 0 "memory_operand" "")
1709290286Sobrien                   (match_operator:SI 3 "arith_or_logical_operator"
1709390286Sobrien                     [(match_dup 0)
1709490286Sobrien                      (match_operand:SI 1 "nonmemory_operand" "")]))
1709590286Sobrien              (clobber (reg:CC 17))])]
1709690286Sobrien  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
1709790286Sobrien  [(set (match_dup 2) (match_dup 0))
1709890286Sobrien   (parallel [(set (match_dup 2)
1709990286Sobrien                   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
1710090286Sobrien              (clobber (reg:CC 17))])
1710190286Sobrien   (set (match_dup 0) (match_dup 2))]
1710290286Sobrien  "")
1710390286Sobrien
1710490286Sobrien(define_peephole2
1710590286Sobrien  [(match_scratch:SI 2 "r")
1710690286Sobrien   (parallel [(set (match_operand:SI 0 "memory_operand" "")
1710790286Sobrien                   (match_operator:SI 3 "arith_or_logical_operator"
1710890286Sobrien                     [(match_operand:SI 1 "nonmemory_operand" "")
1710990286Sobrien                      (match_dup 0)]))
1711090286Sobrien              (clobber (reg:CC 17))])]
1711190286Sobrien  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
1711290286Sobrien  [(set (match_dup 2) (match_dup 0))
1711390286Sobrien   (parallel [(set (match_dup 2)
1711490286Sobrien                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
1711590286Sobrien              (clobber (reg:CC 17))])
1711690286Sobrien   (set (match_dup 0) (match_dup 2))]
1711790286Sobrien  "")
1711890286Sobrien
1711990286Sobrien;; Attempt to always use XOR for zeroing registers.
1712090286Sobrien(define_peephole2
1712190286Sobrien  [(set (match_operand 0 "register_operand" "")
1712290286Sobrien	(const_int 0))]
1712390286Sobrien  "(GET_MODE (operands[0]) == QImode
1712490286Sobrien    || GET_MODE (operands[0]) == HImode
1712590286Sobrien    || GET_MODE (operands[0]) == SImode
1712690286Sobrien    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
1712790286Sobrien   && (! TARGET_USE_MOV0 || optimize_size)
1712890286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1712990286Sobrien  [(parallel [(set (match_dup 0) (const_int 0))
1713090286Sobrien	      (clobber (reg:CC 17))])]
1713190286Sobrien  "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
1713290286Sobrien			      true_regnum (operands[0]));")
1713390286Sobrien
1713490286Sobrien(define_peephole2
1713590286Sobrien  [(set (strict_low_part (match_operand 0 "register_operand" ""))
1713690286Sobrien	(const_int 0))]
1713790286Sobrien  "(GET_MODE (operands[0]) == QImode
1713890286Sobrien    || GET_MODE (operands[0]) == HImode)
1713990286Sobrien   && (! TARGET_USE_MOV0 || optimize_size)
1714090286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1714190286Sobrien  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
1714290286Sobrien	      (clobber (reg:CC 17))])])
1714390286Sobrien
1714490286Sobrien;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
1714590286Sobrien(define_peephole2
1714690286Sobrien  [(set (match_operand 0 "register_operand" "")
1714790286Sobrien	(const_int -1))]
1714890286Sobrien  "(GET_MODE (operands[0]) == HImode
1714990286Sobrien    || GET_MODE (operands[0]) == SImode 
1715090286Sobrien    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
1715190286Sobrien   && (optimize_size || TARGET_PENTIUM)
1715290286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1715390286Sobrien  [(parallel [(set (match_dup 0) (const_int -1))
1715490286Sobrien	      (clobber (reg:CC 17))])]
1715590286Sobrien  "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
1715690286Sobrien			      true_regnum (operands[0]));")
1715790286Sobrien
1715890286Sobrien;; Attempt to convert simple leas to adds. These can be created by
1715990286Sobrien;; move expanders.
1716090286Sobrien(define_peephole2
1716190286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1716290286Sobrien  	(plus:SI (match_dup 0)
1716390286Sobrien		 (match_operand:SI 1 "nonmemory_operand" "")))]
1716490286Sobrien  "peep2_regno_dead_p (0, FLAGS_REG)"
1716590286Sobrien  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
1716690286Sobrien	      (clobber (reg:CC 17))])]
1716790286Sobrien  "")
1716890286Sobrien
1716990286Sobrien(define_peephole2
1717090286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1717190286Sobrien  	(subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
1717290286Sobrien			    (match_operand:DI 2 "nonmemory_operand" "")) 0))]
1717390286Sobrien  "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
1717490286Sobrien  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
1717590286Sobrien	      (clobber (reg:CC 17))])]
1717690286Sobrien  "operands[2] = gen_lowpart (SImode, operands[2]);")
1717790286Sobrien
1717890286Sobrien(define_peephole2
1717990286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1718090286Sobrien  	(plus:DI (match_dup 0)
1718190286Sobrien		 (match_operand:DI 1 "x86_64_general_operand" "")))]
1718290286Sobrien  "peep2_regno_dead_p (0, FLAGS_REG)"
1718390286Sobrien  [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1718490286Sobrien	      (clobber (reg:CC 17))])]
1718590286Sobrien  "")
1718690286Sobrien
1718790286Sobrien(define_peephole2
1718890286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1718990286Sobrien  	(mult:SI (match_dup 0)
1719090286Sobrien		 (match_operand:SI 1 "const_int_operand" "")))]
1719190286Sobrien  "exact_log2 (INTVAL (operands[1])) >= 0
1719290286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1719390286Sobrien  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
1719490286Sobrien	      (clobber (reg:CC 17))])]
1719590286Sobrien  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
1719690286Sobrien
1719790286Sobrien(define_peephole2
1719890286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1719990286Sobrien  	(mult:DI (match_dup 0)
1720090286Sobrien		 (match_operand:DI 1 "const_int_operand" "")))]
1720190286Sobrien  "exact_log2 (INTVAL (operands[1])) >= 0
1720290286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1720390286Sobrien  [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
1720490286Sobrien	      (clobber (reg:CC 17))])]
1720590286Sobrien  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
1720690286Sobrien
1720790286Sobrien(define_peephole2
1720890286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1720990286Sobrien  	(subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
1721090286Sobrien		   (match_operand:DI 2 "const_int_operand" "")) 0))]
1721190286Sobrien  "exact_log2 (INTVAL (operands[1])) >= 0
1721290286Sobrien   && REGNO (operands[0]) == REGNO (operands[1])
1721390286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1721490286Sobrien  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
1721590286Sobrien	      (clobber (reg:CC 17))])]
1721690286Sobrien  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
1721790286Sobrien
1721890286Sobrien;; The ESP adjustments can be done by the push and pop instructions.  Resulting
1721990286Sobrien;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
1722090286Sobrien;; many CPUs it is also faster, since special hardware to avoid esp
1722190286Sobrien;; dependencies is present.
1722290286Sobrien
1722390286Sobrien;; While some of these conversions may be done using splitters, we use peepholes
1722490286Sobrien;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
1722590286Sobrien
1722690286Sobrien;; Convert prologue esp subtractions to push.
1722790286Sobrien;; We need register to push.  In order to keep verify_flow_info happy we have
1722890286Sobrien;; two choices
1722990286Sobrien;; - use scratch and clobber it in order to avoid dependencies
1723090286Sobrien;; - use already live register
1723190286Sobrien;; We can't use the second way right now, since there is no reliable way how to
1723290286Sobrien;; verify that given register is live.  First choice will also most likely in
1723390286Sobrien;; fewer dependencies.  On the place of esp adjustments it is very likely that
1723490286Sobrien;; call clobbered registers are dead.  We may want to use base pointer as an
1723590286Sobrien;; alternative when no register is available later.
1723690286Sobrien
1723790286Sobrien(define_peephole2
1723890286Sobrien  [(match_scratch:SI 0 "r")
1723990286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
1724090286Sobrien	      (clobber (reg:CC 17))
1724190286Sobrien	      (clobber (mem:BLK (scratch)))])]
1724290286Sobrien  "optimize_size || !TARGET_SUB_ESP_4"
1724390286Sobrien  [(clobber (match_dup 0))
1724490286Sobrien   (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
1724590286Sobrien	      (clobber (mem:BLK (scratch)))])])
1724690286Sobrien
1724790286Sobrien(define_peephole2
1724890286Sobrien  [(match_scratch:SI 0 "r")
1724990286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1725090286Sobrien	      (clobber (reg:CC 17))
1725190286Sobrien	      (clobber (mem:BLK (scratch)))])]
1725290286Sobrien  "optimize_size || !TARGET_SUB_ESP_8"
1725390286Sobrien  [(clobber (match_dup 0))
1725490286Sobrien   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
1725590286Sobrien   (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
1725690286Sobrien	      (clobber (mem:BLK (scratch)))])])
1725790286Sobrien
1725890286Sobrien;; Convert esp subtractions to push.
1725990286Sobrien(define_peephole2
1726090286Sobrien  [(match_scratch:SI 0 "r")
1726190286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
1726290286Sobrien	      (clobber (reg:CC 17))])]
1726390286Sobrien  "optimize_size || !TARGET_SUB_ESP_4"
1726490286Sobrien  [(clobber (match_dup 0))
1726590286Sobrien   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
1726690286Sobrien
1726790286Sobrien(define_peephole2
1726890286Sobrien  [(match_scratch:SI 0 "r")
1726990286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1727090286Sobrien	      (clobber (reg:CC 17))])]
1727190286Sobrien  "optimize_size || !TARGET_SUB_ESP_8"
1727290286Sobrien  [(clobber (match_dup 0))
1727390286Sobrien   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
1727490286Sobrien   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
1727590286Sobrien
1727690286Sobrien;; Convert epilogue deallocator to pop.
1727790286Sobrien(define_peephole2
1727890286Sobrien  [(match_scratch:SI 0 "r")
1727990286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1728090286Sobrien	      (clobber (reg:CC 17))
1728190286Sobrien	      (clobber (mem:BLK (scratch)))])]
1728290286Sobrien  "optimize_size || !TARGET_ADD_ESP_4"
1728390286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1728490286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1728590286Sobrien	      (clobber (mem:BLK (scratch)))])]
1728690286Sobrien  "")
1728790286Sobrien
1728890286Sobrien;; Two pops case is tricky, since pop causes dependency on destination register.
1728990286Sobrien;; We use two registers if available.
1729090286Sobrien(define_peephole2
1729190286Sobrien  [(match_scratch:SI 0 "r")
1729290286Sobrien   (match_scratch:SI 1 "r")
1729390286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
1729490286Sobrien	      (clobber (reg:CC 17))
1729590286Sobrien	      (clobber (mem:BLK (scratch)))])]
1729690286Sobrien  "optimize_size || !TARGET_ADD_ESP_8"
1729790286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1729890286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1729990286Sobrien	      (clobber (mem:BLK (scratch)))])
1730090286Sobrien   (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1730190286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1730290286Sobrien  "")
1730390286Sobrien
1730490286Sobrien(define_peephole2
1730590286Sobrien  [(match_scratch:SI 0 "r")
1730690286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
1730790286Sobrien	      (clobber (reg:CC 17))
1730890286Sobrien	      (clobber (mem:BLK (scratch)))])]
1730990286Sobrien  "optimize_size"
1731090286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1731190286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1731290286Sobrien	      (clobber (mem:BLK (scratch)))])
1731390286Sobrien   (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1731490286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1731590286Sobrien  "")
1731690286Sobrien
1731790286Sobrien;; Convert esp additions to pop.
1731890286Sobrien(define_peephole2
1731990286Sobrien  [(match_scratch:SI 0 "r")
1732090286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1732190286Sobrien	      (clobber (reg:CC 17))])]
1732290286Sobrien  ""
1732390286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1732490286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1732590286Sobrien  "")
1732690286Sobrien
1732790286Sobrien;; Two pops case is tricky, since pop causes dependency on destination register.
1732890286Sobrien;; We use two registers if available.
1732990286Sobrien(define_peephole2
1733090286Sobrien  [(match_scratch:SI 0 "r")
1733190286Sobrien   (match_scratch:SI 1 "r")
1733290286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
1733390286Sobrien	      (clobber (reg:CC 17))])]
1733490286Sobrien  ""
1733590286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1733690286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
1733790286Sobrien   (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1733890286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1733990286Sobrien  "")
1734090286Sobrien
1734190286Sobrien(define_peephole2
1734290286Sobrien  [(match_scratch:SI 0 "r")
1734390286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
1734490286Sobrien	      (clobber (reg:CC 17))])]
1734590286Sobrien  "optimize_size"
1734690286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1734790286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
1734890286Sobrien   (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1734990286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1735090286Sobrien  "")
1735190286Sobrien
1735290286Sobrien;; Convert compares with 1 to shorter inc/dec operations when CF is not
1735390286Sobrien;; required and register dies.
1735490286Sobrien(define_peephole2
1735590286Sobrien  [(set (reg 17)
1735690286Sobrien	(compare (match_operand:SI 0 "register_operand" "")
1735790286Sobrien		 (match_operand:SI 1 "incdec_operand" "")))]
1735890286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
1735990286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1736090286Sobrien  [(parallel [(set (reg:CCGC 17)
1736190286Sobrien		   (compare:CCGC (match_dup 0)
1736290286Sobrien				 (match_dup 1)))
1736390286Sobrien	      (clobber (match_dup 0))])]
1736490286Sobrien  "")
1736590286Sobrien
1736690286Sobrien(define_peephole2
1736790286Sobrien  [(set (reg 17)
1736890286Sobrien	(compare (match_operand:HI 0 "register_operand" "")
1736990286Sobrien		 (match_operand:HI 1 "incdec_operand" "")))]
1737090286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
1737190286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1737290286Sobrien  [(parallel [(set (reg:CCGC 17)
1737390286Sobrien		   (compare:CCGC (match_dup 0)
1737490286Sobrien				 (match_dup 1)))
1737590286Sobrien	      (clobber (match_dup 0))])]
1737690286Sobrien  "")
1737790286Sobrien
1737890286Sobrien(define_peephole2
1737990286Sobrien  [(set (reg 17)
1738090286Sobrien	(compare (match_operand:QI 0 "register_operand" "")
1738190286Sobrien		 (match_operand:QI 1 "incdec_operand" "")))]
1738290286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
1738390286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1738490286Sobrien  [(parallel [(set (reg:CCGC 17)
1738590286Sobrien		   (compare:CCGC (match_dup 0)
1738690286Sobrien				 (match_dup 1)))
1738790286Sobrien	      (clobber (match_dup 0))])]
1738890286Sobrien  "")
1738990286Sobrien
1739090286Sobrien;; Convert compares with 128 to shorter add -128
1739190286Sobrien(define_peephole2
1739290286Sobrien  [(set (reg 17)
1739390286Sobrien	(compare (match_operand:SI 0 "register_operand" "")
1739490286Sobrien		 (const_int 128)))]
1739590286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
1739690286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1739790286Sobrien  [(parallel [(set (reg:CCGC 17)
1739890286Sobrien		   (compare:CCGC (match_dup 0)
1739990286Sobrien			         (const_int 128)))
1740090286Sobrien	      (clobber (match_dup 0))])]
1740190286Sobrien  "")
1740290286Sobrien
1740390286Sobrien(define_peephole2
1740490286Sobrien  [(set (reg 17)
1740590286Sobrien	(compare (match_operand:HI 0 "register_operand" "")
1740690286Sobrien		 (const_int 128)))]
1740790286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
1740890286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1740990286Sobrien  [(parallel [(set (reg:CCGC 17)
1741090286Sobrien		   (compare:CCGC (match_dup 0)
1741190286Sobrien			         (const_int 128)))
1741290286Sobrien	      (clobber (match_dup 0))])]
1741390286Sobrien  "")
1741490286Sobrien
1741590286Sobrien(define_peephole2
1741690286Sobrien  [(match_scratch:DI 0 "r")
1741790286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
1741890286Sobrien	      (clobber (reg:CC 17))
1741990286Sobrien	      (clobber (mem:BLK (scratch)))])]
1742090286Sobrien  "optimize_size || !TARGET_SUB_ESP_4"
1742190286Sobrien  [(clobber (match_dup 0))
1742290286Sobrien   (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
1742390286Sobrien	      (clobber (mem:BLK (scratch)))])])
1742490286Sobrien
1742590286Sobrien(define_peephole2
1742690286Sobrien  [(match_scratch:DI 0 "r")
1742790286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
1742890286Sobrien	      (clobber (reg:CC 17))
1742990286Sobrien	      (clobber (mem:BLK (scratch)))])]
1743090286Sobrien  "optimize_size || !TARGET_SUB_ESP_8"
1743190286Sobrien  [(clobber (match_dup 0))
1743290286Sobrien   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
1743390286Sobrien   (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
1743490286Sobrien	      (clobber (mem:BLK (scratch)))])])
1743590286Sobrien
1743690286Sobrien;; Convert esp subtractions to push.
1743790286Sobrien(define_peephole2
1743890286Sobrien  [(match_scratch:DI 0 "r")
1743990286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
1744090286Sobrien	      (clobber (reg:CC 17))])]
1744190286Sobrien  "optimize_size || !TARGET_SUB_ESP_4"
1744290286Sobrien  [(clobber (match_dup 0))
1744390286Sobrien   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
1744490286Sobrien
1744590286Sobrien(define_peephole2
1744690286Sobrien  [(match_scratch:DI 0 "r")
1744790286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
1744890286Sobrien	      (clobber (reg:CC 17))])]
1744990286Sobrien  "optimize_size || !TARGET_SUB_ESP_8"
1745090286Sobrien  [(clobber (match_dup 0))
1745190286Sobrien   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
1745290286Sobrien   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
1745390286Sobrien
1745490286Sobrien;; Convert epilogue deallocator to pop.
1745590286Sobrien(define_peephole2
1745690286Sobrien  [(match_scratch:DI 0 "r")
1745790286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1745890286Sobrien	      (clobber (reg:CC 17))
1745990286Sobrien	      (clobber (mem:BLK (scratch)))])]
1746090286Sobrien  "optimize_size || !TARGET_ADD_ESP_4"
1746190286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1746290286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1746390286Sobrien	      (clobber (mem:BLK (scratch)))])]
1746490286Sobrien  "")
1746590286Sobrien
1746690286Sobrien;; Two pops case is tricky, since pop causes dependency on destination register.
1746790286Sobrien;; We use two registers if available.
1746890286Sobrien(define_peephole2
1746990286Sobrien  [(match_scratch:DI 0 "r")
1747090286Sobrien   (match_scratch:DI 1 "r")
1747190286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
1747290286Sobrien	      (clobber (reg:CC 17))
1747390286Sobrien	      (clobber (mem:BLK (scratch)))])]
1747490286Sobrien  "optimize_size || !TARGET_ADD_ESP_8"
1747590286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1747690286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1747790286Sobrien	      (clobber (mem:BLK (scratch)))])
1747890286Sobrien   (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
1747990286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1748090286Sobrien  "")
1748190286Sobrien
1748290286Sobrien(define_peephole2
1748390286Sobrien  [(match_scratch:DI 0 "r")
1748490286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
1748590286Sobrien	      (clobber (reg:CC 17))
1748690286Sobrien	      (clobber (mem:BLK (scratch)))])]
1748790286Sobrien  "optimize_size"
1748890286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1748990286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1749090286Sobrien	      (clobber (mem:BLK (scratch)))])
1749190286Sobrien   (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1749290286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1749390286Sobrien  "")
1749490286Sobrien
1749590286Sobrien;; Convert esp additions to pop.
1749690286Sobrien(define_peephole2
1749790286Sobrien  [(match_scratch:DI 0 "r")
1749890286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1749990286Sobrien	      (clobber (reg:CC 17))])]
1750090286Sobrien  ""
1750190286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1750290286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1750390286Sobrien  "")
1750490286Sobrien
1750590286Sobrien;; Two pops case is tricky, since pop causes dependency on destination register.
1750690286Sobrien;; We use two registers if available.
1750790286Sobrien(define_peephole2
1750890286Sobrien  [(match_scratch:DI 0 "r")
1750990286Sobrien   (match_scratch:DI 1 "r")
1751090286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
1751190286Sobrien	      (clobber (reg:CC 17))])]
1751290286Sobrien  ""
1751390286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1751490286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
1751590286Sobrien   (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
1751690286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1751790286Sobrien  "")
1751890286Sobrien
1751990286Sobrien(define_peephole2
1752090286Sobrien  [(match_scratch:DI 0 "r")
1752190286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
1752290286Sobrien	      (clobber (reg:CC 17))])]
1752390286Sobrien  "optimize_size"
1752490286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1752590286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
1752690286Sobrien   (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1752790286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1752890286Sobrien  "")
1752990286Sobrien
1753090286Sobrien;; Call-value patterns last so that the wildcard operand does not
1753190286Sobrien;; disrupt insn-recog's switch tables.
1753290286Sobrien
1753390286Sobrien(define_insn "*call_value_pop_0"
1753490286Sobrien  [(set (match_operand 0 "" "")
1753590286Sobrien	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
1753690286Sobrien	      (match_operand:SI 2 "" "")))
1753790286Sobrien   (set (reg:SI 7) (plus:SI (reg:SI 7)
1753890286Sobrien			    (match_operand:SI 3 "immediate_operand" "")))]
1753990286Sobrien  "!TARGET_64BIT"
1754090286Sobrien{
1754190286Sobrien  if (SIBLING_CALL_P (insn))
1754290286Sobrien    return "jmp\t%P1";
1754390286Sobrien  else
1754490286Sobrien    return "call\t%P1";
1754590286Sobrien}
1754690286Sobrien  [(set_attr "type" "callv")])
1754790286Sobrien
1754890286Sobrien(define_insn "*call_value_pop_1"
1754990286Sobrien  [(set (match_operand 0 "" "")
1755090286Sobrien	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
1755190286Sobrien	      (match_operand:SI 2 "" "")))
1755290286Sobrien   (set (reg:SI 7) (plus:SI (reg:SI 7)
1755390286Sobrien			    (match_operand:SI 3 "immediate_operand" "i")))]
1755490286Sobrien  "!TARGET_64BIT"
1755590286Sobrien{
1755690286Sobrien  if (constant_call_address_operand (operands[1], QImode))
1755790286Sobrien    {
1755890286Sobrien      if (SIBLING_CALL_P (insn))
1755990286Sobrien	return "jmp\t%P1";
1756090286Sobrien      else
1756190286Sobrien	return "call\t%P1";
1756290286Sobrien    }
1756390286Sobrien  if (SIBLING_CALL_P (insn))
1756490286Sobrien    return "jmp\t%A1";
1756590286Sobrien  else
1756690286Sobrien    return "call\t%A1";
1756790286Sobrien}
1756890286Sobrien  [(set_attr "type" "callv")])
1756990286Sobrien
1757090286Sobrien(define_insn "*call_value_0"
1757190286Sobrien  [(set (match_operand 0 "" "")
1757290286Sobrien	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
1757390286Sobrien	      (match_operand:SI 2 "" "")))]
1757490286Sobrien  "!TARGET_64BIT"
1757590286Sobrien{
1757690286Sobrien  if (SIBLING_CALL_P (insn))
1757790286Sobrien    return "jmp\t%P1";
1757890286Sobrien  else
1757990286Sobrien    return "call\t%P1";
1758090286Sobrien}
1758190286Sobrien  [(set_attr "type" "callv")])
1758290286Sobrien
1758390286Sobrien(define_insn "*call_value_0_rex64"
1758490286Sobrien  [(set (match_operand 0 "" "")
1758590286Sobrien	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
1758690286Sobrien	      (match_operand:DI 2 "const_int_operand" "")))]
1758790286Sobrien  "TARGET_64BIT"
1758890286Sobrien{
1758990286Sobrien  if (SIBLING_CALL_P (insn))
1759090286Sobrien    return "jmp\t%P1";
1759190286Sobrien  else
1759290286Sobrien    return "call\t%P1";
1759390286Sobrien}
1759490286Sobrien  [(set_attr "type" "callv")])
1759590286Sobrien
1759690286Sobrien(define_insn "*call_value_1"
1759790286Sobrien  [(set (match_operand 0 "" "")
1759890286Sobrien	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
1759990286Sobrien	      (match_operand:SI 2 "" "")))]
1760090286Sobrien  "!TARGET_64BIT"
1760190286Sobrien{
1760290286Sobrien  if (constant_call_address_operand (operands[1], QImode))
1760390286Sobrien    {
1760490286Sobrien      if (SIBLING_CALL_P (insn))
1760590286Sobrien	return "jmp\t%P1";
1760690286Sobrien      else
1760790286Sobrien	return "call\t%P1";
1760890286Sobrien    }
1760990286Sobrien  if (SIBLING_CALL_P (insn))
1761090286Sobrien    return "jmp\t%*%1";
1761190286Sobrien  else
1761290286Sobrien    return "call\t%*%1";
1761390286Sobrien}
1761490286Sobrien  [(set_attr "type" "callv")])
1761590286Sobrien
1761690286Sobrien(define_insn "*call_value_1_rex64"
1761790286Sobrien  [(set (match_operand 0 "" "")
1761890286Sobrien	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
1761990286Sobrien	      (match_operand:DI 2 "" "")))]
1762090286Sobrien  "TARGET_64BIT"
1762190286Sobrien{
1762290286Sobrien  if (constant_call_address_operand (operands[1], QImode))
1762390286Sobrien    {
1762490286Sobrien      if (SIBLING_CALL_P (insn))
1762590286Sobrien	return "jmp\t%P1";
1762690286Sobrien      else
1762790286Sobrien	return "call\t%P1";
1762890286Sobrien    }
1762990286Sobrien  if (SIBLING_CALL_P (insn))
1763090286Sobrien    return "jmp\t%A1";
1763190286Sobrien  else
1763290286Sobrien    return "call\t%A1";
1763390286Sobrien}
1763490286Sobrien  [(set_attr "type" "callv")])
1763590286Sobrien
1763690286Sobrien(define_insn "trap"
1763790286Sobrien  [(trap_if (const_int 1) (const_int 5))]
1763890286Sobrien  ""
1763990286Sobrien  "int\t$5")
1764090286Sobrien
1764190286Sobrien;;; ix86 doesn't have conditional trap instructions, but we fake them
1764290286Sobrien;;; for the sake of bounds checking.  By emitting bounds checks as
1764390286Sobrien;;; conditional traps rather than as conditional jumps around
1764490286Sobrien;;; unconditional traps we avoid introducing spurious basic-block
1764590286Sobrien;;; boundaries and facilitate elimination of redundant checks.  In
1764690286Sobrien;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
1764790286Sobrien;;; interrupt 5.
1764890286Sobrien;;; 
1764990286Sobrien;;; FIXME: Static branch prediction rules for ix86 are such that
1765090286Sobrien;;; forward conditional branches predict as untaken.  As implemented
1765190286Sobrien;;; below, pseudo conditional traps violate that rule.  We should use
1765290286Sobrien;;; .pushsection/.popsection to place all of the `int 5's in a special
1765390286Sobrien;;; section loaded at the end of the text segment and branch forward
1765490286Sobrien;;; there on bounds-failure, and then jump back immediately (in case
1765590286Sobrien;;; the system chooses to ignore bounds violations, or to report
1765690286Sobrien;;; violations and continue execution).
1765790286Sobrien
1765890286Sobrien(define_expand "conditional_trap"
1765990286Sobrien  [(trap_if (match_operator 0 "comparison_operator"
1766090286Sobrien	     [(match_dup 2) (const_int 0)])
1766190286Sobrien	    (match_operand 1 "const_int_operand" ""))]
1766290286Sobrien  ""
1766390286Sobrien{
1766490286Sobrien  emit_insn (gen_rtx_TRAP_IF (VOIDmode,
1766590286Sobrien			      ix86_expand_compare (GET_CODE (operands[0]),
1766690286Sobrien						   NULL, NULL),
1766790286Sobrien			      operands[1]));
1766890286Sobrien  DONE;
1766990286Sobrien})
1767090286Sobrien
1767190286Sobrien(define_insn "*conditional_trap_1"
1767290286Sobrien  [(trap_if (match_operator 0 "comparison_operator"
1767390286Sobrien	     [(reg 17) (const_int 0)])
1767490286Sobrien	    (match_operand 1 "const_int_operand" ""))]
1767590286Sobrien  ""
1767690286Sobrien{
1767790286Sobrien  operands[2] = gen_label_rtx ();
1767890286Sobrien  output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
1767990286Sobrien  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1768090286Sobrien			     CODE_LABEL_NUMBER (operands[2]));
1768190286Sobrien  RET;
1768290286Sobrien})
1768390286Sobrien
1768490286Sobrien	;; Pentium III SIMD instructions.
1768590286Sobrien
1768690286Sobrien;; Moves for SSE/MMX regs.
1768790286Sobrien
1768890286Sobrien(define_insn "movv4sf_internal"
1768990286Sobrien  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
1769090286Sobrien	(match_operand:V4SF 1 "nonimmediate_operand" "xm,x"))]
1769190286Sobrien  "TARGET_SSE"
1769290286Sobrien  ;; @@@ let's try to use movaps here.
1769390286Sobrien  "movaps\t{%1, %0|%0, %1}"
1769490286Sobrien  [(set_attr "type" "sse")])
1769590286Sobrien
1769690286Sobrien(define_insn "movv4si_internal"
1769790286Sobrien  [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,m")
1769890286Sobrien	(match_operand:V4SI 1 "nonimmediate_operand" "xm,x"))]
1769990286Sobrien  "TARGET_SSE"
1770090286Sobrien  ;; @@@ let's try to use movaps here.
1770190286Sobrien  "movaps\t{%1, %0|%0, %1}"
1770290286Sobrien  [(set_attr "type" "sse")])
1770390286Sobrien
1770490286Sobrien(define_insn "movv8qi_internal"
1770590286Sobrien  [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m")
1770690286Sobrien	(match_operand:V8QI 1 "nonimmediate_operand" "ym,y"))]
1770790286Sobrien  "TARGET_MMX"
1770890286Sobrien  "movq\t{%1, %0|%0, %1}"
1770990286Sobrien  [(set_attr "type" "mmx")])
1771090286Sobrien
1771190286Sobrien(define_insn "movv4hi_internal"
1771290286Sobrien  [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m")
1771390286Sobrien	(match_operand:V4HI 1 "nonimmediate_operand" "ym,y"))]
1771490286Sobrien  "TARGET_MMX"
1771590286Sobrien  "movq\t{%1, %0|%0, %1}"
1771690286Sobrien  [(set_attr "type" "mmx")])
1771790286Sobrien
1771890286Sobrien(define_insn "movv2si_internal"
1771990286Sobrien  [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m")
1772090286Sobrien	(match_operand:V2SI 1 "nonimmediate_operand" "ym,y"))]
1772190286Sobrien  "TARGET_MMX"
1772290286Sobrien  "movq\t{%1, %0|%0, %1}"
1772390286Sobrien  [(set_attr "type" "mmx")])
1772490286Sobrien
1772590286Sobrien(define_insn "movv2sf_internal"
1772690286Sobrien  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,m")
1772790286Sobrien        (match_operand:V2SF 1 "nonimmediate_operand" "ym,y"))]
1772890286Sobrien  "TARGET_3DNOW"
1772990286Sobrien  "movq\\t{%1, %0|%0, %1}"
1773090286Sobrien  [(set_attr "type" "mmx")])
1773190286Sobrien
1773290286Sobrien(define_expand "movti"
1773390286Sobrien  [(set (match_operand:TI 0 "general_operand" "")
1773490286Sobrien	(match_operand:TI 1 "general_operand" ""))]
1773590286Sobrien  "TARGET_SSE || TARGET_64BIT"
1773690286Sobrien{
1773790286Sobrien  if (TARGET_64BIT)
1773890286Sobrien    ix86_expand_move (TImode, operands);
1773990286Sobrien  else
1774090286Sobrien    ix86_expand_vector_move (TImode, operands);
1774190286Sobrien  DONE;
1774290286Sobrien})
1774390286Sobrien
1774490286Sobrien(define_expand "movv4sf"
1774590286Sobrien  [(set (match_operand:V4SF 0 "general_operand" "")
1774690286Sobrien	(match_operand:V4SF 1 "general_operand" ""))]
1774790286Sobrien  "TARGET_SSE"
1774890286Sobrien{
1774990286Sobrien  ix86_expand_vector_move (V4SFmode, operands);
1775090286Sobrien  DONE;
1775190286Sobrien})
1775290286Sobrien
1775390286Sobrien(define_expand "movv4si"
1775490286Sobrien  [(set (match_operand:V4SI 0 "general_operand" "")
1775590286Sobrien	(match_operand:V4SI 1 "general_operand" ""))]
1775690286Sobrien  "TARGET_MMX"
1775790286Sobrien{
1775890286Sobrien  ix86_expand_vector_move (V4SImode, operands);
1775990286Sobrien  DONE;
1776090286Sobrien})
1776190286Sobrien
1776290286Sobrien(define_expand "movv2si"
1776390286Sobrien  [(set (match_operand:V2SI 0 "general_operand" "")
1776490286Sobrien	(match_operand:V2SI 1 "general_operand" ""))]
1776590286Sobrien  "TARGET_MMX"
1776690286Sobrien{
1776790286Sobrien  ix86_expand_vector_move (V2SImode, operands);
1776890286Sobrien  DONE;
1776990286Sobrien})
1777090286Sobrien
1777190286Sobrien(define_expand "movv4hi"
1777290286Sobrien  [(set (match_operand:V4HI 0 "general_operand" "")
1777390286Sobrien	(match_operand:V4HI 1 "general_operand" ""))]
1777490286Sobrien  "TARGET_MMX"
1777590286Sobrien{
1777690286Sobrien  ix86_expand_vector_move (V4HImode, operands);
1777790286Sobrien  DONE;
1777890286Sobrien})
1777990286Sobrien
1778090286Sobrien(define_expand "movv8qi"
1778190286Sobrien  [(set (match_operand:V8QI 0 "general_operand" "")
1778290286Sobrien	(match_operand:V8QI 1 "general_operand" ""))]
1778390286Sobrien  "TARGET_MMX"
1778490286Sobrien{
1778590286Sobrien  ix86_expand_vector_move (V8QImode, operands);
1778690286Sobrien  DONE;
1778790286Sobrien})
1778890286Sobrien
1778990286Sobrien(define_expand "movv2sf"
1779090286Sobrien  [(set (match_operand:V2SF 0 "general_operand" "")
1779190286Sobrien	(match_operand:V2SF 1 "general_operand" ""))]
1779290286Sobrien   "TARGET_3DNOW"
1779390286Sobrien{
1779490286Sobrien  ix86_expand_vector_move (V2SFmode, operands);
1779590286Sobrien  DONE;
1779690286Sobrien})
1779790286Sobrien
1779890286Sobrien(define_insn_and_split "*pushti"
1779990286Sobrien  [(set (match_operand:TI 0 "push_operand" "=<")
1780090286Sobrien	(match_operand:TI 1 "nonmemory_operand" "x"))]
1780190286Sobrien  "TARGET_SSE"
1780290286Sobrien  "#"
1780390286Sobrien  ""
1780490286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
1780590286Sobrien   (set (mem:TI (reg:SI 7)) (match_dup 1))]
1780690286Sobrien  ""
1780790286Sobrien  [(set_attr "type" "sse")])
1780890286Sobrien
1780990286Sobrien(define_insn_and_split "*pushv4sf"
1781090286Sobrien  [(set (match_operand:V4SF 0 "push_operand" "=<")
1781190286Sobrien	(match_operand:V4SF 1 "nonmemory_operand" "x"))]
1781290286Sobrien  "TARGET_SSE"
1781390286Sobrien  "#"
1781490286Sobrien  ""
1781590286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
1781690286Sobrien   (set (mem:V4SF (reg:SI 7)) (match_dup 1))]
1781790286Sobrien  ""
1781890286Sobrien  [(set_attr "type" "sse")])
1781990286Sobrien
1782090286Sobrien(define_insn_and_split "*pushv4si"
1782190286Sobrien  [(set (match_operand:V4SI 0 "push_operand" "=<")
1782290286Sobrien	(match_operand:V4SI 1 "nonmemory_operand" "x"))]
1782390286Sobrien  "TARGET_SSE"
1782490286Sobrien  "#"
1782590286Sobrien  ""
1782690286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
1782790286Sobrien   (set (mem:V4SI (reg:SI 7)) (match_dup 1))]
1782890286Sobrien  ""
1782990286Sobrien  [(set_attr "type" "sse")])
1783090286Sobrien
1783190286Sobrien(define_insn_and_split "*pushv2si"
1783290286Sobrien  [(set (match_operand:V2SI 0 "push_operand" "=<")
1783390286Sobrien	(match_operand:V2SI 1 "nonmemory_operand" "y"))]
1783490286Sobrien  "TARGET_MMX"
1783590286Sobrien  "#"
1783690286Sobrien  ""
1783790286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1783890286Sobrien   (set (mem:V2SI (reg:SI 7)) (match_dup 1))]
1783990286Sobrien  ""
1784090286Sobrien  [(set_attr "type" "mmx")])
1784190286Sobrien
1784290286Sobrien(define_insn_and_split "*pushv4hi"
1784390286Sobrien  [(set (match_operand:V4HI 0 "push_operand" "=<")
1784490286Sobrien	(match_operand:V4HI 1 "nonmemory_operand" "y"))]
1784590286Sobrien  "TARGET_MMX"
1784690286Sobrien  "#"
1784790286Sobrien  ""
1784890286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1784990286Sobrien   (set (mem:V4HI (reg:SI 7)) (match_dup 1))]
1785090286Sobrien  ""
1785190286Sobrien  [(set_attr "type" "mmx")])
1785290286Sobrien
1785390286Sobrien(define_insn_and_split "*pushv8qi"
1785490286Sobrien  [(set (match_operand:V8QI 0 "push_operand" "=<")
1785590286Sobrien	(match_operand:V8QI 1 "nonmemory_operand" "y"))]
1785690286Sobrien  "TARGET_MMX"
1785790286Sobrien  "#"
1785890286Sobrien  ""
1785990286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1786090286Sobrien   (set (mem:V8QI (reg:SI 7)) (match_dup 1))]
1786190286Sobrien  ""
1786290286Sobrien  [(set_attr "type" "mmx")])
1786390286Sobrien
1786490286Sobrien(define_insn_and_split "*pushv2sf"
1786590286Sobrien  [(set (match_operand:V2SF 0 "push_operand" "=<")
1786690286Sobrien	(match_operand:V2SF 1 "nonmemory_operand" "y"))]
1786790286Sobrien  "TARGET_3DNOW"
1786890286Sobrien  "#"
1786990286Sobrien  ""
1787090286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1787190286Sobrien   (set (mem:V2SF (reg:SI 7)) (match_dup 1))]
1787290286Sobrien  ""
1787390286Sobrien  [(set_attr "type" "mmx")])
1787490286Sobrien
1787590286Sobrien(define_insn "movti_internal"
1787690286Sobrien  [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1787790286Sobrien	(match_operand:TI 1 "general_operand" "O,xm,x"))]
1787890286Sobrien  "TARGET_SSE && !TARGET_64BIT"
1787990286Sobrien  "@
1788090286Sobrien   xorps\t%0, %0
1788190286Sobrien   movaps\t{%1, %0|%0, %1}
1788290286Sobrien   movaps\t{%1, %0|%0, %1}"
1788390286Sobrien  [(set_attr "type" "sse")])
1788490286Sobrien
1788590286Sobrien(define_insn "*movti_rex64"
1788690286Sobrien  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,mx,x")
1788790286Sobrien	(match_operand:TI 1 "general_operand" "riFo,riF,O,x,m"))]
1788890286Sobrien  "TARGET_64BIT
1788990286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1789090286Sobrien  "@
1789190286Sobrien   #
1789290286Sobrien   #
1789390286Sobrien   xorps\t%0, %0
1789490286Sobrien   movaps\\t{%1, %0|%0, %1}
1789590286Sobrien   movaps\\t{%1, %0|%0, %1}"
1789690286Sobrien  [(set_attr "type" "*,*,sse,sse,sse")
1789790286Sobrien   (set_attr "mode" "TI")])
1789890286Sobrien
1789990286Sobrien(define_split
1790090286Sobrien  [(set (match_operand:TI 0 "nonimmediate_operand" "")
1790190286Sobrien        (match_operand:TI 1 "general_operand" ""))]
1790290286Sobrien  "reload_completed && !SSE_REG_P (operands[0])
1790390286Sobrien   && !SSE_REG_P (operands[1])"
1790490286Sobrien  [(const_int 0)]
1790590286Sobrien  "ix86_split_long_move (operands); DONE;")
1790690286Sobrien
1790790286Sobrien;; These two patterns are useful for specifying exactly whether to use
1790890286Sobrien;; movaps or movups
1790990286Sobrien(define_insn "sse_movaps"
1791090286Sobrien  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
1791190286Sobrien	(unspec:V4SF
1791290286Sobrien	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")] 38))]
1791390286Sobrien  "TARGET_SSE"
1791490286Sobrien  "@
1791590286Sobrien   movaps\t{%1, %0|%0, %1}
1791690286Sobrien   movaps\t{%1, %0|%0, %1}"
1791790286Sobrien  [(set_attr "type" "sse")])
1791890286Sobrien
1791990286Sobrien(define_insn "sse_movups"
1792090286Sobrien  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
1792190286Sobrien	(unspec:V4SF
1792290286Sobrien	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")] 39))]
1792390286Sobrien  "TARGET_SSE"
1792490286Sobrien  "@
1792590286Sobrien   movups\t{%1, %0|%0, %1}
1792690286Sobrien   movups\t{%1, %0|%0, %1}"
1792790286Sobrien  [(set_attr "type" "sse")])
1792890286Sobrien
1792990286Sobrien
1793090286Sobrien;; SSE Strange Moves.
1793190286Sobrien
1793290286Sobrien(define_insn "sse_movmskps"
1793390286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1793490286Sobrien	(unspec:SI [(match_operand:V4SF 1 "register_operand" "x")] 33))]
1793590286Sobrien  "TARGET_SSE"
1793690286Sobrien  "movmskps\t{%1, %0|%0, %1}"
1793790286Sobrien  [(set_attr "type" "sse")])
1793890286Sobrien
1793990286Sobrien(define_insn "mmx_pmovmskb"
1794090286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1794190286Sobrien	(unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] 33))]
1794290286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1794390286Sobrien  "pmovmskb\t{%1, %0|%0, %1}"
1794490286Sobrien  [(set_attr "type" "sse")])
1794590286Sobrien
1794690286Sobrien(define_insn "mmx_maskmovq"
1794790286Sobrien  [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
1794890286Sobrien	(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1794990286Sobrien		      (match_operand:V8QI 2 "register_operand" "y")] 32))]
1795090286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1795190286Sobrien  ;; @@@ check ordering of operands in intel/nonintel syntax
1795290286Sobrien  "maskmovq\t{%2, %1|%1, %2}"
1795390286Sobrien  [(set_attr "type" "sse")])
1795490286Sobrien
1795590286Sobrien(define_insn "sse_movntv4sf"
1795690286Sobrien  [(set (match_operand:V4SF 0 "memory_operand" "=m")
1795790286Sobrien	(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")] 34))]
1795890286Sobrien  "TARGET_SSE"
1795990286Sobrien  "movntps\t{%1, %0|%0, %1}"
1796090286Sobrien  [(set_attr "type" "sse")])
1796190286Sobrien
1796290286Sobrien(define_insn "sse_movntdi"
1796390286Sobrien  [(set (match_operand:DI 0 "memory_operand" "=m")
1796490286Sobrien	(unspec:DI [(match_operand:DI 1 "register_operand" "y")] 34))]
1796590286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1796690286Sobrien  "movntq\t{%1, %0|%0, %1}"
1796790286Sobrien  [(set_attr "type" "sse")])
1796890286Sobrien
1796990286Sobrien(define_insn "sse_movhlps"
1797090286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1797190286Sobrien	(vec_merge:V4SF
1797290286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1797390286Sobrien	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
1797490286Sobrien			  (parallel [(const_int 2)
1797590286Sobrien				     (const_int 3)
1797690286Sobrien				     (const_int 0)
1797790286Sobrien				     (const_int 1)]))
1797890286Sobrien	 (const_int 3)))]
1797990286Sobrien  "TARGET_SSE"
1798090286Sobrien  "movhlps\t{%2, %0|%0, %2}"
1798190286Sobrien  [(set_attr "type" "sse")])
1798290286Sobrien
1798390286Sobrien(define_insn "sse_movlhps"
1798490286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1798590286Sobrien	(vec_merge:V4SF
1798690286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1798790286Sobrien	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
1798890286Sobrien			  (parallel [(const_int 2)
1798990286Sobrien				     (const_int 3)
1799090286Sobrien				     (const_int 0)
1799190286Sobrien				     (const_int 1)]))
1799290286Sobrien	 (const_int 12)))]
1799390286Sobrien  "TARGET_SSE"
1799490286Sobrien  "movlhps\t{%2, %0|%0, %2}"
1799590286Sobrien  [(set_attr "type" "sse")])
1799690286Sobrien
1799790286Sobrien(define_insn "sse_movhps"
1799890286Sobrien  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
1799990286Sobrien	(vec_merge:V4SF
1800090286Sobrien	 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
1800190286Sobrien	 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
1800290286Sobrien	 (const_int 12)))]
1800390286Sobrien  "TARGET_SSE
1800490286Sobrien   && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
1800590286Sobrien  "movhps\t{%2, %0|%0, %2}"
1800690286Sobrien  [(set_attr "type" "sse")])
1800790286Sobrien
1800890286Sobrien(define_insn "sse_movlps"
1800990286Sobrien  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
1801090286Sobrien	(vec_merge:V4SF
1801190286Sobrien	 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
1801290286Sobrien	 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
1801390286Sobrien	 (const_int 3)))]
1801490286Sobrien  "TARGET_SSE
1801590286Sobrien   && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
1801690286Sobrien  "movlps\t{%2, %0|%0, %2}"
1801790286Sobrien  [(set_attr "type" "sse")])
1801890286Sobrien
1801990286Sobrien(define_insn "sse_loadss"
1802090286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1802190286Sobrien	(vec_merge:V4SF
1802290286Sobrien	 (match_operand:V4SF 1 "memory_operand" "m")
1802390286Sobrien	 (vec_duplicate:V4SF (float:SF (const_int 0)))
1802490286Sobrien	 (const_int 1)))]
1802590286Sobrien  "TARGET_SSE"
1802690286Sobrien  "movss\t{%1, %0|%0, %1}"
1802790286Sobrien  [(set_attr "type" "sse")])
1802890286Sobrien
1802990286Sobrien(define_insn "sse_movss"
1803090286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1803190286Sobrien	(vec_merge:V4SF
1803290286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1803390286Sobrien	 (match_operand:V4SF 2 "register_operand" "x")
1803490286Sobrien	 (const_int 1)))]
1803590286Sobrien  "TARGET_SSE"
1803690286Sobrien  "movss\t{%2, %0|%0, %2}"
1803790286Sobrien  [(set_attr "type" "sse")])
1803890286Sobrien
1803990286Sobrien(define_insn "sse_storess"
1804090286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
1804190286Sobrien	(vec_select:SF
1804290286Sobrien	 (match_operand:V4SF 1 "register_operand" "x")
1804390286Sobrien	 (parallel [(const_int 0)])))]
1804490286Sobrien  "TARGET_SSE"
1804590286Sobrien  "movss\t{%1, %0|%0, %1}"
1804690286Sobrien  [(set_attr "type" "sse")])
1804790286Sobrien
1804890286Sobrien(define_insn "sse_shufps"
1804990286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1805090286Sobrien        (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
1805190286Sobrien		      (match_operand:V4SF 2 "nonimmediate_operand" "xm")
1805290286Sobrien		      (match_operand:SI 3 "immediate_operand" "i")] 41))]
1805390286Sobrien  "TARGET_SSE"
1805490286Sobrien  ;; @@@ check operand order for intel/nonintel syntax
1805590286Sobrien  "shufps\t{%3, %2, %0|%0, %2, %3}"
1805690286Sobrien  [(set_attr "type" "sse")])
1805790286Sobrien
1805890286Sobrien
1805990286Sobrien;; SSE arithmetic
1806090286Sobrien
1806190286Sobrien(define_insn "addv4sf3"
1806290286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1806390286Sobrien        (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
1806490286Sobrien	           (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1806590286Sobrien  "TARGET_SSE"
1806690286Sobrien  "addps\t{%2, %0|%0, %2}"
1806790286Sobrien  [(set_attr "type" "sse")])
1806890286Sobrien
1806990286Sobrien(define_insn "vmaddv4sf3"
1807090286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1807190286Sobrien	(vec_merge:V4SF
1807290286Sobrien	 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
1807390286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1807490286Sobrien	 (match_dup 1)
1807590286Sobrien	 (const_int 1)))]
1807690286Sobrien  "TARGET_SSE"
1807790286Sobrien  "addss\t{%2, %0|%0, %2}"
1807890286Sobrien  [(set_attr "type" "sse")])
1807990286Sobrien
1808090286Sobrien(define_insn "subv4sf3"
1808190286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1808290286Sobrien        (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
1808390286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1808490286Sobrien  "TARGET_SSE"
1808590286Sobrien  "subps\t{%2, %0|%0, %2}"
1808690286Sobrien  [(set_attr "type" "sse")])
1808790286Sobrien
1808890286Sobrien(define_insn "vmsubv4sf3"
1808990286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1809090286Sobrien	(vec_merge:V4SF
1809190286Sobrien	 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
1809290286Sobrien		     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1809390286Sobrien	 (match_dup 1)
1809490286Sobrien	 (const_int 1)))]
1809590286Sobrien  "TARGET_SSE"
1809690286Sobrien  "subss\t{%2, %0|%0, %2}"
1809790286Sobrien  [(set_attr "type" "sse")])
1809890286Sobrien
1809990286Sobrien(define_insn "mulv4sf3"
1810090286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1810190286Sobrien        (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
1810290286Sobrien	           (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1810390286Sobrien  "TARGET_SSE"
1810490286Sobrien  "mulps\t{%2, %0|%0, %2}"
1810590286Sobrien  [(set_attr "type" "sse")])
1810690286Sobrien
1810790286Sobrien(define_insn "vmmulv4sf3"
1810890286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1810990286Sobrien	(vec_merge:V4SF
1811090286Sobrien	 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
1811190286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1811290286Sobrien	 (match_dup 1)
1811390286Sobrien	 (const_int 1)))]
1811490286Sobrien  "TARGET_SSE"
1811590286Sobrien  "mulss\t{%2, %0|%0, %2}"
1811690286Sobrien  [(set_attr "type" "sse")])
1811790286Sobrien
1811890286Sobrien(define_insn "divv4sf3"
1811990286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1812090286Sobrien        (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
1812190286Sobrien	          (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1812290286Sobrien  "TARGET_SSE"
1812390286Sobrien  "divps\t{%2, %0|%0, %2}"
1812490286Sobrien  [(set_attr "type" "sse")])
1812590286Sobrien
1812690286Sobrien(define_insn "vmdivv4sf3"
1812790286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1812890286Sobrien	(vec_merge:V4SF
1812990286Sobrien	 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
1813090286Sobrien		   (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1813190286Sobrien	 (match_dup 1)
1813290286Sobrien	 (const_int 1)))]
1813390286Sobrien  "TARGET_SSE"
1813490286Sobrien  "divss\t{%2, %0|%0, %2}"
1813590286Sobrien  [(set_attr "type" "sse")])
1813690286Sobrien
1813790286Sobrien
1813890286Sobrien;; SSE square root/reciprocal
1813990286Sobrien
1814090286Sobrien(define_insn "rcpv4sf2"
1814190286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1814290286Sobrien        (unspec:V4SF
1814390286Sobrien	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 42))]
1814490286Sobrien  "TARGET_SSE"
1814590286Sobrien  "rcpps\t{%1, %0|%0, %1}"
1814690286Sobrien  [(set_attr "type" "sse")])
1814790286Sobrien
1814890286Sobrien(define_insn "vmrcpv4sf2"
1814990286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1815090286Sobrien	(vec_merge:V4SF
1815190286Sobrien	 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 42)
1815290286Sobrien	 (match_operand:V4SF 2 "register_operand" "0")
1815390286Sobrien	 (const_int 1)))]
1815490286Sobrien  "TARGET_SSE"
1815590286Sobrien  "rcpss\t{%1, %0|%0, %1}"
1815690286Sobrien  [(set_attr "type" "sse")])
1815790286Sobrien
1815890286Sobrien(define_insn "rsqrtv4sf2"
1815990286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1816090286Sobrien        (unspec:V4SF
1816190286Sobrien	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 43))]
1816290286Sobrien  "TARGET_SSE"
1816390286Sobrien  "rsqrtps\t{%1, %0|%0, %1}"
1816490286Sobrien  [(set_attr "type" "sse")])
1816590286Sobrien
1816690286Sobrien(define_insn "vmrsqrtv4sf2"
1816790286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1816890286Sobrien	(vec_merge:V4SF
1816990286Sobrien	 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 43)
1817090286Sobrien	 (match_operand:V4SF 2 "register_operand" "0")
1817190286Sobrien	 (const_int 1)))]
1817290286Sobrien  "TARGET_SSE"
1817390286Sobrien  "rsqrtss\t{%1, %0|%0, %1}"
1817490286Sobrien  [(set_attr "type" "sse")])
1817590286Sobrien
1817690286Sobrien(define_insn "sqrtv4sf2"
1817790286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1817890286Sobrien        (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
1817990286Sobrien  "TARGET_SSE"
1818090286Sobrien  "sqrtps\t{%1, %0|%0, %1}"
1818190286Sobrien  [(set_attr "type" "sse")])
1818290286Sobrien
1818390286Sobrien(define_insn "vmsqrtv4sf2"
1818490286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1818590286Sobrien	(vec_merge:V4SF
1818690286Sobrien	 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
1818790286Sobrien	 (match_operand:V4SF 2 "register_operand" "0")
1818890286Sobrien	 (const_int 1)))]
1818990286Sobrien  "TARGET_SSE"
1819090286Sobrien  "sqrtss\t{%1, %0|%0, %1}"
1819190286Sobrien  [(set_attr "type" "sse")])
1819290286Sobrien
1819390286Sobrien;; SSE logical operations.
1819490286Sobrien
1819590286Sobrien;; These are not called andti3 etc. because we really really don't want
1819690286Sobrien;; the compiler to widen DImode ands to TImode ands and then try to move
1819790286Sobrien;; into DImode subregs of SSE registers, and them together, and move out
1819890286Sobrien;; of DImode subregs again!
1819990286Sobrien
1820090286Sobrien(define_insn "*sse_andti3_df_1"
1820190286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
1820290286Sobrien        (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
1820390286Sobrien		(subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
1820490286Sobrien  "TARGET_SSE2"
1820590286Sobrien  "andpd\t{%2, %0|%0, %2}"
1820690286Sobrien  [(set_attr "type" "sse")])
1820790286Sobrien
1820890286Sobrien(define_insn "*sse_andti3_df_2"
1820990286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
1821090286Sobrien        (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
1821190286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "Ym")))]
1821290286Sobrien  "TARGET_SSE2"
1821390286Sobrien  "andpd\t{%2, %0|%0, %2}"
1821490286Sobrien  [(set_attr "type" "sse")])
1821590286Sobrien
1821690286Sobrien(define_insn "*sse_andti3_sf_1"
1821790286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
1821890286Sobrien        (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
1821990286Sobrien		(subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
1822090286Sobrien  "TARGET_SSE"
1822190286Sobrien  "andps\t{%2, %0|%0, %2}"
1822290286Sobrien  [(set_attr "type" "sse")])
1822390286Sobrien
1822490286Sobrien(define_insn "*sse_andti3_sf_2"
1822590286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
1822690286Sobrien        (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
1822790286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1822890286Sobrien  "TARGET_SSE"
1822990286Sobrien  "andps\t{%2, %0|%0, %2}"
1823090286Sobrien  [(set_attr "type" "sse")])
1823190286Sobrien
1823290286Sobrien(define_insn "sse_andti3"
1823390286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1823490286Sobrien        (and:TI (match_operand:TI 1 "register_operand" "%0")
1823590286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1823690286Sobrien  "TARGET_SSE && !TARGET_SSE2"
1823790286Sobrien  "andps\t{%2, %0|%0, %2}"
1823890286Sobrien  [(set_attr "type" "sse")])
1823990286Sobrien
1824090286Sobrien(define_insn "*sse_andti3_sse2"
1824190286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1824290286Sobrien        (and:TI (match_operand:TI 1 "register_operand" "%0")
1824390286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1824490286Sobrien  "TARGET_SSE2"
1824590286Sobrien  "pand\t{%2, %0|%0, %2}"
1824690286Sobrien  [(set_attr "type" "sse")])
1824790286Sobrien
1824890286Sobrien(define_insn "*sse_nandti3_df"
1824990286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
1825090286Sobrien        (and:TI (not:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0))
1825190286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "Ym")))]
1825290286Sobrien  "TARGET_SSE2"
1825390286Sobrien  "andnpd\t{%2, %0|%0, %2}"
1825490286Sobrien  [(set_attr "type" "sse")])
1825590286Sobrien
1825690286Sobrien(define_insn "*sse_nandti3_sf"
1825790286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
1825890286Sobrien        (and:TI (not:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0))
1825990286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1826090286Sobrien  "TARGET_SSE"
1826190286Sobrien  "andnps\t{%2, %0|%0, %2}"
1826290286Sobrien  [(set_attr "type" "sse")])
1826390286Sobrien
1826490286Sobrien(define_insn "sse_nandti3"
1826590286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1826690286Sobrien        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
1826790286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1826890286Sobrien  "TARGET_SSE && !TARGET_SSE2"
1826990286Sobrien  "andnps\t{%2, %0|%0, %2}"
1827090286Sobrien  [(set_attr "type" "sse")])
1827190286Sobrien
1827290286Sobrien(define_insn "*sse_nandti3_sse2"
1827390286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1827490286Sobrien        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
1827590286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1827690286Sobrien  "TARGET_SSE2"
1827790286Sobrien  "pnand\t{%2, %0|%0, %2}"
1827890286Sobrien  [(set_attr "type" "sse")])
1827990286Sobrien
1828090286Sobrien(define_insn "*sse_iorti3_df_1"
1828190286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
1828290286Sobrien        (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
1828390286Sobrien		(subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
1828490286Sobrien  "TARGET_SSE2"
1828590286Sobrien  "orpd\t{%2, %0|%0, %2}"
1828690286Sobrien  [(set_attr "type" "sse")])
1828790286Sobrien
1828890286Sobrien(define_insn "*sse_iorti3_df_2"
1828990286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
1829090286Sobrien        (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
1829190286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "Ym")))]
1829290286Sobrien  "TARGET_SSE2"
1829390286Sobrien  "orpd\t{%2, %0|%0, %2}"
1829490286Sobrien  [(set_attr "type" "sse")])
1829590286Sobrien
1829690286Sobrien(define_insn "*sse_iorti3_sf_1"
1829790286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
1829890286Sobrien        (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
1829990286Sobrien		(subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
1830090286Sobrien  "TARGET_SSE"
1830190286Sobrien  "orps\t{%2, %0|%0, %2}"
1830290286Sobrien  [(set_attr "type" "sse")])
1830390286Sobrien
1830490286Sobrien(define_insn "*sse_iorti3_sf_2"
1830590286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
1830690286Sobrien        (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
1830790286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1830890286Sobrien  "TARGET_SSE"
1830990286Sobrien  "orps\t{%2, %0|%0, %2}"
1831090286Sobrien  [(set_attr "type" "sse")])
1831190286Sobrien
1831290286Sobrien(define_insn "sse_iorti3"
1831390286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1831490286Sobrien        (ior:TI (match_operand:TI 1 "register_operand" "%0")
1831590286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1831690286Sobrien  "TARGET_SSE && !TARGET_SSE2"
1831790286Sobrien  "orps\t{%2, %0|%0, %2}"
1831890286Sobrien  [(set_attr "type" "sse")])
1831990286Sobrien
1832090286Sobrien(define_insn "*sse_iorti3_sse2"
1832190286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1832290286Sobrien        (ior:TI (match_operand:TI 1 "register_operand" "%0")
1832390286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1832490286Sobrien  "TARGET_SSE2"
1832590286Sobrien  "por\t{%2, %0|%0, %2}"
1832690286Sobrien  [(set_attr "type" "sse")])
1832790286Sobrien
1832890286Sobrien(define_insn "*sse_xorti3_df_1"
1832990286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
1833090286Sobrien        (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
1833190286Sobrien		(subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
1833290286Sobrien  "TARGET_SSE2"
1833390286Sobrien  "xorpd\t{%2, %0|%0, %2}"
1833490286Sobrien  [(set_attr "type" "sse")])
1833590286Sobrien
1833690286Sobrien(define_insn "*sse_xorti3_df_2"
1833790286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
1833890286Sobrien        (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
1833990286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "Ym")))]
1834090286Sobrien  "TARGET_SSE2"
1834190286Sobrien  "xorpd\t{%2, %0|%0, %2}"
1834290286Sobrien  [(set_attr "type" "sse")])
1834390286Sobrien
1834490286Sobrien(define_insn "*sse_xorti3_sf_1"
1834590286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
1834690286Sobrien        (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
1834790286Sobrien		(subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
1834890286Sobrien  "TARGET_SSE"
1834990286Sobrien  "xorps\t{%2, %0|%0, %2}"
1835090286Sobrien  [(set_attr "type" "sse")])
1835190286Sobrien
1835290286Sobrien(define_insn "*sse_xorti3_sf_2"
1835390286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
1835490286Sobrien        (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
1835590286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1835690286Sobrien  "TARGET_SSE"
1835790286Sobrien  "xorps\t{%2, %0|%0, %2}"
1835890286Sobrien  [(set_attr "type" "sse")])
1835990286Sobrien
1836090286Sobrien(define_insn "sse_xorti3"
1836190286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1836290286Sobrien        (xor:TI (match_operand:TI 1 "register_operand" "%0")
1836390286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1836490286Sobrien  "TARGET_SSE && !TARGET_SSE2"
1836590286Sobrien  "xorps\t{%2, %0|%0, %2}"
1836690286Sobrien  [(set_attr "type" "sse")])
1836790286Sobrien
1836890286Sobrien(define_insn "*sse_xorti3_sse2"
1836990286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1837090286Sobrien        (xor:TI (match_operand:TI 1 "register_operand" "%0")
1837190286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1837290286Sobrien  "TARGET_SSE2"
1837390286Sobrien  "pxor\t{%2, %0|%0, %2}"
1837490286Sobrien  [(set_attr "type" "sse")])
1837590286Sobrien
1837690286Sobrien;; Use xor, but don't show input operands so they aren't live before
1837790286Sobrien;; this insn.
1837890286Sobrien(define_insn "sse_clrv4sf"
1837990286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1838090286Sobrien        (unspec:V4SF [(const_int 0)] 45))]
1838190286Sobrien  "TARGET_SSE"
1838290286Sobrien  "xorps\t{%0, %0|%0, %0}"
1838390286Sobrien  [(set_attr "type" "sse")
1838490286Sobrien   (set_attr "memory" "none")])
1838590286Sobrien
1838690286Sobrien;; SSE mask-generating compares
1838790286Sobrien
1838890286Sobrien(define_insn "maskcmpv4sf3"
1838990286Sobrien  [(set (match_operand:V4SI 0 "register_operand" "=x")
1839090286Sobrien        (match_operator:V4SI 3 "sse_comparison_operator"
1839190286Sobrien		[(match_operand:V4SF 1 "register_operand" "0")
1839290286Sobrien		 (match_operand:V4SF 2 "register_operand" "x")]))]
1839390286Sobrien  "TARGET_SSE"
1839490286Sobrien  "cmp%D3ps\t{%2, %0|%0, %2}"
1839590286Sobrien  [(set_attr "type" "sse")])
1839690286Sobrien
1839790286Sobrien(define_insn "maskncmpv4sf3"
1839890286Sobrien  [(set (match_operand:V4SI 0 "register_operand" "=x")
1839990286Sobrien        (not:V4SI
1840090286Sobrien	 (match_operator:V4SI 3 "sse_comparison_operator"
1840190286Sobrien		[(match_operand:V4SF 1 "register_operand" "0")
1840290286Sobrien		 (match_operand:V4SF 2 "register_operand" "x")])))]
1840390286Sobrien  "TARGET_SSE"
1840490286Sobrien{
1840590286Sobrien  if (GET_CODE (operands[3]) == UNORDERED)
1840690286Sobrien    return "cmpordps\t{%2, %0|%0, %2}";
1840790286Sobrien  else
1840890286Sobrien    return "cmpn%D3ps\t{%2, %0|%0, %2}";
1840990286Sobrien}
1841090286Sobrien  [(set_attr "type" "sse")])
1841190286Sobrien
1841290286Sobrien(define_insn "vmmaskcmpv4sf3"
1841390286Sobrien  [(set (match_operand:V4SI 0 "register_operand" "=x")
1841490286Sobrien	(vec_merge:V4SI
1841590286Sobrien	 (match_operator:V4SI 3 "sse_comparison_operator"
1841690286Sobrien		[(match_operand:V4SF 1 "register_operand" "0")
1841790286Sobrien		 (match_operand:V4SF 2 "register_operand" "x")])
1841890286Sobrien	 (match_dup 1)
1841990286Sobrien	 (const_int 1)))]
1842090286Sobrien  "TARGET_SSE"
1842190286Sobrien  "cmp%D3ss\t{%2, %0|%0, %2}"
1842290286Sobrien  [(set_attr "type" "sse")])
1842390286Sobrien
1842490286Sobrien(define_insn "vmmaskncmpv4sf3"
1842590286Sobrien  [(set (match_operand:V4SI 0 "register_operand" "=x")
1842690286Sobrien	(vec_merge:V4SI
1842790286Sobrien	 (not:V4SI
1842890286Sobrien	  (match_operator:V4SI 3 "sse_comparison_operator"
1842990286Sobrien		[(match_operand:V4SF 1 "register_operand" "0")
1843090286Sobrien		 (match_operand:V4SF 2 "register_operand" "x")]))
1843190286Sobrien	 (subreg:V4SI (match_dup 1) 0)
1843290286Sobrien	 (const_int 1)))]
1843390286Sobrien  "TARGET_SSE"
1843490286Sobrien{
1843590286Sobrien  if (GET_CODE (operands[3]) == UNORDERED)
1843690286Sobrien    return "cmpordss\t{%2, %0|%0, %2}";
1843790286Sobrien  else
1843890286Sobrien    return "cmpn%D3ss\t{%2, %0|%0, %2}";
1843990286Sobrien}
1844090286Sobrien  [(set_attr "type" "sse")])
1844190286Sobrien
1844290286Sobrien(define_insn "sse_comi"
1844390286Sobrien  [(set (reg:CCFP 17)
1844490286Sobrien        (match_operator:CCFP 2 "sse_comparison_operator"
1844590286Sobrien			[(vec_select:SF
1844690286Sobrien			  (match_operand:V4SF 0 "register_operand" "x")
1844790286Sobrien			  (parallel [(const_int 0)]))
1844890286Sobrien			 (vec_select:SF
1844990286Sobrien			  (match_operand:V4SF 1 "register_operand" "x")
1845090286Sobrien			  (parallel [(const_int 0)]))]))]
1845190286Sobrien  "TARGET_SSE"
1845290286Sobrien  "comiss\t{%1, %0|%0, %1}"
1845390286Sobrien  [(set_attr "type" "sse")])
1845490286Sobrien
1845590286Sobrien(define_insn "sse_ucomi"
1845690286Sobrien  [(set (reg:CCFPU 17)
1845790286Sobrien	(match_operator:CCFPU 2 "sse_comparison_operator"
1845890286Sobrien			[(vec_select:SF
1845990286Sobrien			  (match_operand:V4SF 0 "register_operand" "x")
1846090286Sobrien			  (parallel [(const_int 0)]))
1846190286Sobrien			 (vec_select:SF
1846290286Sobrien			  (match_operand:V4SF 1 "register_operand" "x")
1846390286Sobrien			  (parallel [(const_int 0)]))]))]
1846490286Sobrien  "TARGET_SSE"
1846590286Sobrien  "ucomiss\t{%1, %0|%0, %1}"
1846690286Sobrien  [(set_attr "type" "sse")])
1846790286Sobrien
1846890286Sobrien
1846990286Sobrien;; SSE unpack
1847090286Sobrien
1847190286Sobrien(define_insn "sse_unpckhps"
1847290286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1847390286Sobrien	(vec_merge:V4SF
1847490286Sobrien	 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
1847590286Sobrien			  (parallel [(const_int 2)
1847690286Sobrien				     (const_int 0)
1847790286Sobrien				     (const_int 3)
1847890286Sobrien				     (const_int 1)]))
1847990286Sobrien	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
1848090286Sobrien			  (parallel [(const_int 0)
1848190286Sobrien				     (const_int 2)
1848290286Sobrien				     (const_int 1)
1848390286Sobrien				     (const_int 3)]))
1848490286Sobrien	 (const_int 5)))]
1848590286Sobrien  "TARGET_SSE"
1848690286Sobrien  "unpckhps\t{%2, %0|%0, %2}"
1848790286Sobrien  [(set_attr "type" "sse")])
1848890286Sobrien
1848990286Sobrien(define_insn "sse_unpcklps"
1849090286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1849190286Sobrien	(vec_merge:V4SF
1849290286Sobrien	 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
1849390286Sobrien			  (parallel [(const_int 0)
1849490286Sobrien				     (const_int 2)
1849590286Sobrien				     (const_int 1)
1849690286Sobrien				     (const_int 3)]))
1849790286Sobrien	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
1849890286Sobrien			  (parallel [(const_int 2)
1849990286Sobrien				     (const_int 0)
1850090286Sobrien				     (const_int 3)
1850190286Sobrien				     (const_int 1)]))
1850290286Sobrien	 (const_int 5)))]
1850390286Sobrien  "TARGET_SSE"
1850490286Sobrien  "unpcklps\t{%2, %0|%0, %2}"
1850590286Sobrien  [(set_attr "type" "sse")])
1850690286Sobrien
1850790286Sobrien
1850890286Sobrien;; SSE min/max
1850990286Sobrien
1851090286Sobrien(define_insn "smaxv4sf3"
1851190286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1851290286Sobrien        (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
1851390286Sobrien		   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1851490286Sobrien  "TARGET_SSE"
1851590286Sobrien  "maxps\t{%2, %0|%0, %2}"
1851690286Sobrien  [(set_attr "type" "sse")])
1851790286Sobrien
1851890286Sobrien(define_insn "vmsmaxv4sf3"
1851990286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1852090286Sobrien	(vec_merge:V4SF
1852190286Sobrien	 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
1852290286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1852390286Sobrien	 (match_dup 1)
1852490286Sobrien	 (const_int 1)))]
1852590286Sobrien  "TARGET_SSE"
1852690286Sobrien  "maxss\t{%2, %0|%0, %2}"
1852790286Sobrien  [(set_attr "type" "sse")])
1852890286Sobrien
1852990286Sobrien(define_insn "sminv4sf3"
1853090286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1853190286Sobrien        (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
1853290286Sobrien		   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1853390286Sobrien  "TARGET_SSE"
1853490286Sobrien  "minps\t{%2, %0|%0, %2}"
1853590286Sobrien  [(set_attr "type" "sse")])
1853690286Sobrien
1853790286Sobrien(define_insn "vmsminv4sf3"
1853890286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1853990286Sobrien	(vec_merge:V4SF
1854090286Sobrien	 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
1854190286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1854290286Sobrien	 (match_dup 1)
1854390286Sobrien	 (const_int 1)))]
1854490286Sobrien  "TARGET_SSE"
1854590286Sobrien  "minss\t{%2, %0|%0, %2}"
1854690286Sobrien  [(set_attr "type" "sse")])
1854790286Sobrien
1854890286Sobrien
1854990286Sobrien;; SSE <-> integer/MMX conversions
1855090286Sobrien
1855190286Sobrien(define_insn "cvtpi2ps"
1855290286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1855390286Sobrien	(vec_merge:V4SF
1855490286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1855590286Sobrien	 (vec_duplicate:V4SF
1855690286Sobrien	  (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
1855790286Sobrien	 (const_int 12)))]
1855890286Sobrien  "TARGET_SSE"
1855990286Sobrien  "cvtpi2ps\t{%2, %0|%0, %2}"
1856090286Sobrien  [(set_attr "type" "sse")])
1856190286Sobrien
1856290286Sobrien(define_insn "cvtps2pi"
1856390286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1856490286Sobrien	(vec_select:V2SI
1856590286Sobrien	 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
1856690286Sobrien	 (parallel [(const_int 0) (const_int 1)])))]
1856790286Sobrien  "TARGET_SSE"
1856890286Sobrien  "cvtps2pi\t{%1, %0|%0, %1}"
1856990286Sobrien  [(set_attr "type" "sse")])
1857090286Sobrien
1857190286Sobrien(define_insn "cvttps2pi"
1857290286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1857390286Sobrien	(vec_select:V2SI
1857490286Sobrien	 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 30)
1857590286Sobrien	 (parallel [(const_int 0) (const_int 1)])))]
1857690286Sobrien  "TARGET_SSE"
1857790286Sobrien  "cvttps2pi\t{%1, %0|%0, %1}"
1857890286Sobrien  [(set_attr "type" "sse")])
1857990286Sobrien
1858090286Sobrien(define_insn "cvtsi2ss"
1858190286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1858290286Sobrien	(vec_merge:V4SF
1858390286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1858490286Sobrien	 (vec_duplicate:V4SF
1858590286Sobrien	  (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm")))
1858690286Sobrien	 (const_int 14)))]
1858790286Sobrien  "TARGET_SSE"
1858890286Sobrien  "cvtsi2ss\t{%2, %0|%0, %2}"
1858990286Sobrien  [(set_attr "type" "sse")])
1859090286Sobrien
1859190286Sobrien(define_insn "cvtss2si"
1859290286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1859390286Sobrien	(vec_select:SI
1859490286Sobrien	 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
1859590286Sobrien	 (parallel [(const_int 0)])))]
1859690286Sobrien  "TARGET_SSE"
1859790286Sobrien  "cvtss2si\t{%1, %0|%0, %1}"
1859890286Sobrien  [(set_attr "type" "sse")])
1859990286Sobrien
1860090286Sobrien(define_insn "cvttss2si"
1860190286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1860290286Sobrien	(vec_select:SI
1860390286Sobrien	 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 30)
1860490286Sobrien	 (parallel [(const_int 0)])))]
1860590286Sobrien  "TARGET_SSE"
1860690286Sobrien  "cvttss2si\t{%1, %0|%0, %1}"
1860790286Sobrien  [(set_attr "type" "sse")])
1860890286Sobrien
1860990286Sobrien
1861090286Sobrien;; MMX insns
1861190286Sobrien
1861290286Sobrien;; MMX arithmetic
1861390286Sobrien
1861490286Sobrien(define_insn "addv8qi3"
1861590286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1861690286Sobrien        (plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1861790286Sobrien	           (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1861890286Sobrien  "TARGET_MMX"
1861990286Sobrien  "paddb\t{%2, %0|%0, %2}"
1862090286Sobrien  [(set_attr "type" "mmx")])
1862190286Sobrien
1862290286Sobrien(define_insn "addv4hi3"
1862390286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1862490286Sobrien        (plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
1862590286Sobrien	           (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1862690286Sobrien  "TARGET_MMX"
1862790286Sobrien  "paddw\t{%2, %0|%0, %2}"
1862890286Sobrien  [(set_attr "type" "mmx")])
1862990286Sobrien
1863090286Sobrien(define_insn "addv2si3"
1863190286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1863290286Sobrien        (plus:V2SI (match_operand:V2SI 1 "register_operand" "0")
1863390286Sobrien	           (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
1863490286Sobrien  "TARGET_MMX"
1863590286Sobrien  "paddd\t{%2, %0|%0, %2}"
1863690286Sobrien  [(set_attr "type" "mmx")])
1863790286Sobrien
1863890286Sobrien(define_insn "ssaddv8qi3"
1863990286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1864090286Sobrien        (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1864190286Sobrien		      (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1864290286Sobrien  "TARGET_MMX"
1864390286Sobrien  "paddsb\t{%2, %0|%0, %2}"
1864490286Sobrien  [(set_attr "type" "mmx")])
1864590286Sobrien
1864690286Sobrien(define_insn "ssaddv4hi3"
1864790286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1864890286Sobrien        (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
1864990286Sobrien		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1865090286Sobrien  "TARGET_MMX"
1865190286Sobrien  "paddsw\t{%2, %0|%0, %2}"
1865290286Sobrien  [(set_attr "type" "mmx")])
1865390286Sobrien
1865490286Sobrien(define_insn "usaddv8qi3"
1865590286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1865690286Sobrien        (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1865790286Sobrien		      (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1865890286Sobrien  "TARGET_MMX"
1865990286Sobrien  "paddusb\t{%2, %0|%0, %2}"
1866090286Sobrien  [(set_attr "type" "mmx")])
1866190286Sobrien
1866290286Sobrien(define_insn "usaddv4hi3"
1866390286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1866490286Sobrien        (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
1866590286Sobrien		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1866690286Sobrien  "TARGET_MMX"
1866790286Sobrien  "paddusw\t{%2, %0|%0, %2}"
1866890286Sobrien  [(set_attr "type" "mmx")])
1866990286Sobrien
1867090286Sobrien(define_insn "subv8qi3"
1867190286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1867290286Sobrien        (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1867390286Sobrien		    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1867490286Sobrien  "TARGET_MMX"
1867590286Sobrien  "psubb\t{%2, %0|%0, %2}"
1867690286Sobrien  [(set_attr "type" "mmx")])
1867790286Sobrien
1867890286Sobrien(define_insn "subv4hi3"
1867990286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1868090286Sobrien        (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
1868190286Sobrien		    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1868290286Sobrien  "TARGET_MMX"
1868390286Sobrien  "psubw\t{%2, %0|%0, %2}"
1868490286Sobrien  [(set_attr "type" "mmx")])
1868590286Sobrien
1868690286Sobrien(define_insn "subv2si3"
1868790286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1868890286Sobrien        (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
1868990286Sobrien		    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
1869090286Sobrien  "TARGET_MMX"
1869190286Sobrien  "psubd\t{%2, %0|%0, %2}"
1869290286Sobrien  [(set_attr "type" "mmx")])
1869390286Sobrien
1869490286Sobrien(define_insn "sssubv8qi3"
1869590286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1869690286Sobrien        (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1869790286Sobrien		       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1869890286Sobrien  "TARGET_MMX"
1869990286Sobrien  "psubsb\t{%2, %0|%0, %2}"
1870090286Sobrien  [(set_attr "type" "mmx")])
1870190286Sobrien
1870290286Sobrien(define_insn "sssubv4hi3"
1870390286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1870490286Sobrien        (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
1870590286Sobrien		       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1870690286Sobrien  "TARGET_MMX"
1870790286Sobrien  "psubsw\t{%2, %0|%0, %2}"
1870890286Sobrien  [(set_attr "type" "mmx")])
1870990286Sobrien
1871090286Sobrien(define_insn "ussubv8qi3"
1871190286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1871290286Sobrien        (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1871390286Sobrien		       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1871490286Sobrien  "TARGET_MMX"
1871590286Sobrien  "psubusb\t{%2, %0|%0, %2}"
1871690286Sobrien  [(set_attr "type" "mmx")])
1871790286Sobrien
1871890286Sobrien(define_insn "ussubv4hi3"
1871990286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1872090286Sobrien        (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
1872190286Sobrien		       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1872290286Sobrien  "TARGET_MMX"
1872390286Sobrien  "psubusw\t{%2, %0|%0, %2}"
1872490286Sobrien  [(set_attr "type" "mmx")])
1872590286Sobrien
1872690286Sobrien(define_insn "mulv4hi3"
1872790286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1872890286Sobrien        (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
1872990286Sobrien		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1873090286Sobrien  "TARGET_MMX"
1873190286Sobrien  "pmullw\t{%2, %0|%0, %2}"
1873290286Sobrien  [(set_attr "type" "mmx")])
1873390286Sobrien
1873490286Sobrien(define_insn "smulv4hi3_highpart"
1873590286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1873690286Sobrien	(truncate:V4HI
1873790286Sobrien	 (lshiftrt:V4SI
1873890286Sobrien	  (mult:V4SI (sign_extend:V4SI
1873990286Sobrien		      (match_operand:V4HI 1 "register_operand" "0"))
1874090286Sobrien		     (sign_extend:V4SI
1874190286Sobrien		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1874290286Sobrien	  (const_int 16))))]
1874390286Sobrien  "TARGET_MMX"
1874490286Sobrien  "pmulhw\t{%2, %0|%0, %2}"
1874590286Sobrien  [(set_attr "type" "mmx")])
1874690286Sobrien
1874790286Sobrien(define_insn "umulv4hi3_highpart"
1874890286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1874990286Sobrien	(truncate:V4HI
1875090286Sobrien	 (lshiftrt:V4SI
1875190286Sobrien	  (mult:V4SI (zero_extend:V4SI
1875290286Sobrien		      (match_operand:V4HI 1 "register_operand" "0"))
1875390286Sobrien		     (zero_extend:V4SI
1875490286Sobrien		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1875590286Sobrien	  (const_int 16))))]
1875690286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1875790286Sobrien  "pmulhuw\t{%2, %0|%0, %2}"
1875890286Sobrien  [(set_attr "type" "mmx")])
1875990286Sobrien
1876090286Sobrien(define_insn "mmx_pmaddwd"
1876190286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1876290286Sobrien        (plus:V2SI
1876390286Sobrien	 (mult:V2SI
1876490286Sobrien	  (sign_extend:V2SI
1876590286Sobrien	   (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
1876690286Sobrien			    (parallel [(const_int 0) (const_int 2)])))
1876790286Sobrien	  (sign_extend:V2SI
1876890286Sobrien	   (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
1876990286Sobrien			    (parallel [(const_int 0) (const_int 2)]))))
1877090286Sobrien	 (mult:V2SI
1877190286Sobrien	  (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
1877290286Sobrien					     (parallel [(const_int 1)
1877390286Sobrien							(const_int 3)])))
1877490286Sobrien	  (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
1877590286Sobrien					     (parallel [(const_int 1)
1877690286Sobrien							(const_int 3)]))))))]
1877790286Sobrien  "TARGET_MMX"
1877890286Sobrien  "pmaddwd\t{%2, %0|%0, %2}"
1877990286Sobrien  [(set_attr "type" "mmx")])
1878090286Sobrien
1878190286Sobrien
1878290286Sobrien;; MMX logical operations
1878390286Sobrien;; Note we don't want to declare these as regular iordi3 insns to prevent
1878490286Sobrien;; normal code that also wants to use the FPU from getting broken.
1878590286Sobrien;; The UNSPECs are there to prevent the combiner from getting overly clever.
1878690286Sobrien(define_insn "mmx_iordi3"
1878790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1878890286Sobrien        (unspec:DI
1878990286Sobrien	 [(ior:DI (match_operand:DI 1 "register_operand" "0")
1879090286Sobrien		  (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
1879190286Sobrien  "TARGET_MMX"
1879290286Sobrien  "por\t{%2, %0|%0, %2}"
1879390286Sobrien  [(set_attr "type" "mmx")])
1879490286Sobrien
1879590286Sobrien(define_insn "mmx_xordi3"
1879690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1879790286Sobrien        (unspec:DI
1879890286Sobrien	 [(xor:DI (match_operand:DI 1 "register_operand" "0")
1879990286Sobrien		  (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
1880090286Sobrien  "TARGET_MMX"
1880190286Sobrien  "pxor\t{%2, %0|%0, %2}"
1880290286Sobrien  [(set_attr "type" "mmx")
1880390286Sobrien   (set_attr "memory" "none")])
1880490286Sobrien
1880590286Sobrien;; Same as pxor, but don't show input operands so that we don't think
1880690286Sobrien;; they are live.
1880790286Sobrien(define_insn "mmx_clrdi"
1880890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1880990286Sobrien        (unspec:DI [(const_int 0)] 45))]
1881090286Sobrien  "TARGET_MMX"
1881190286Sobrien  "pxor\t{%0, %0|%0, %0}"
1881290286Sobrien  [(set_attr "type" "mmx")
1881390286Sobrien   (set_attr "memory" "none")])
1881490286Sobrien
1881590286Sobrien(define_insn "mmx_anddi3"
1881690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1881790286Sobrien        (unspec:DI
1881890286Sobrien	 [(and:DI (match_operand:DI 1 "register_operand" "0")
1881990286Sobrien		  (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
1882090286Sobrien  "TARGET_MMX"
1882190286Sobrien  "pand\t{%2, %0|%0, %2}"
1882290286Sobrien  [(set_attr "type" "mmx")])
1882390286Sobrien
1882490286Sobrien(define_insn "mmx_nanddi3"
1882590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1882690286Sobrien        (unspec:DI
1882790286Sobrien	 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
1882890286Sobrien			  (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
1882990286Sobrien  "TARGET_MMX"
1883090286Sobrien  "pandn\t{%2, %0|%0, %2}"
1883190286Sobrien  [(set_attr "type" "mmx")])
1883290286Sobrien
1883390286Sobrien
1883490286Sobrien;; MMX unsigned averages/sum of absolute differences
1883590286Sobrien
1883690286Sobrien(define_insn "mmx_uavgv8qi3"
1883790286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1883890286Sobrien        (ashiftrt:V8QI
1883990286Sobrien	 (plus:V8QI (plus:V8QI
1884090286Sobrien		     (match_operand:V8QI 1 "register_operand" "0")
1884190286Sobrien		     (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1884290286Sobrien		    (vec_const:V8QI (parallel [(const_int 1)
1884390286Sobrien					       (const_int 1)
1884490286Sobrien					       (const_int 1)
1884590286Sobrien					       (const_int 1)
1884690286Sobrien					       (const_int 1)
1884790286Sobrien					       (const_int 1)
1884890286Sobrien					       (const_int 1)
1884990286Sobrien					       (const_int 1)])))
1885090286Sobrien	 (const_int 1)))]
1885190286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1885290286Sobrien  "pavgb\t{%2, %0|%0, %2}"
1885390286Sobrien  [(set_attr "type" "sse")])
1885490286Sobrien
1885590286Sobrien(define_insn "mmx_uavgv4hi3"
1885690286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1885790286Sobrien        (ashiftrt:V4HI
1885890286Sobrien	 (plus:V4HI (plus:V4HI
1885990286Sobrien		     (match_operand:V4HI 1 "register_operand" "0")
1886090286Sobrien		     (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1886190286Sobrien		    (vec_const:V4HI (parallel [(const_int 1)
1886290286Sobrien					       (const_int 1)
1886390286Sobrien					       (const_int 1)
1886490286Sobrien					       (const_int 1)])))
1886590286Sobrien	 (const_int 1)))]
1886690286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1886790286Sobrien  "pavgw\t{%2, %0|%0, %2}"
1886890286Sobrien  [(set_attr "type" "sse")])
1886990286Sobrien
1887090286Sobrien(define_insn "mmx_psadbw"
1887190286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1887290286Sobrien        (abs:V8QI (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1887390286Sobrien			      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))))]
1887490286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1887590286Sobrien  "psadbw\t{%2, %0|%0, %2}"
1887690286Sobrien  [(set_attr "type" "sse")])
1887790286Sobrien
1887890286Sobrien
1887990286Sobrien;; MMX insert/extract/shuffle
1888090286Sobrien
1888190286Sobrien(define_insn "mmx_pinsrw"
1888290286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1888390286Sobrien        (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
1888490286Sobrien			(vec_duplicate:V4HI
1888590286Sobrien			 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
1888690286Sobrien			(match_operand:SI 3 "immediate_operand" "i")))]
1888790286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1888890286Sobrien  "pinsrw\t{%3, %2, %0|%0, %2, %3}"
1888990286Sobrien  [(set_attr "type" "sse")])
1889090286Sobrien
1889190286Sobrien(define_insn "mmx_pextrw"
1889290286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1889390286Sobrien        (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
1889490286Sobrien				       (parallel
1889590286Sobrien					[(match_operand:SI 2 "immediate_operand" "i")]))))]
1889690286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1889790286Sobrien  "pextrw\t{%2, %1, %0|%0, %1, %2}"
1889890286Sobrien  [(set_attr "type" "sse")])
1889990286Sobrien
1890090286Sobrien(define_insn "mmx_pshufw"
1890190286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1890290286Sobrien        (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
1890390286Sobrien		      (match_operand:SI 2 "immediate_operand" "i")] 41))]
1890490286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1890590286Sobrien  "pshufw\t{%2, %1, %0|%0, %1, %2}"
1890690286Sobrien  [(set_attr "type" "sse")])
1890790286Sobrien
1890890286Sobrien
1890990286Sobrien;; MMX mask-generating comparisons
1891090286Sobrien
1891190286Sobrien(define_insn "eqv8qi3"
1891290286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1891390286Sobrien        (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
1891490286Sobrien		 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1891590286Sobrien  "TARGET_MMX"
1891690286Sobrien  "pcmpeqb\t{%2, %0|%0, %2}"
1891790286Sobrien  [(set_attr "type" "mmx")])
1891890286Sobrien
1891990286Sobrien(define_insn "eqv4hi3"
1892090286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1892190286Sobrien        (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
1892290286Sobrien		 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1892390286Sobrien  "TARGET_MMX"
1892490286Sobrien  "pcmpeqw\t{%2, %0|%0, %2}"
1892590286Sobrien  [(set_attr "type" "mmx")])
1892690286Sobrien
1892790286Sobrien(define_insn "eqv2si3"
1892890286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1892990286Sobrien        (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
1893090286Sobrien		 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
1893190286Sobrien  "TARGET_MMX"
1893290286Sobrien  "pcmpeqd\t{%2, %0|%0, %2}"
1893390286Sobrien  [(set_attr "type" "mmx")])
1893490286Sobrien
1893590286Sobrien(define_insn "gtv8qi3"
1893690286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1893790286Sobrien        (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
1893890286Sobrien		 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1893990286Sobrien  "TARGET_MMX"
1894090286Sobrien  "pcmpgtb\t{%2, %0|%0, %2}"
1894190286Sobrien  [(set_attr "type" "mmx")])
1894290286Sobrien
1894390286Sobrien(define_insn "gtv4hi3"
1894490286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1894590286Sobrien        (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
1894690286Sobrien		 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1894790286Sobrien  "TARGET_MMX"
1894890286Sobrien  "pcmpgtw\t{%2, %0|%0, %2}"
1894990286Sobrien  [(set_attr "type" "mmx")])
1895090286Sobrien
1895190286Sobrien(define_insn "gtv2si3"
1895290286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1895390286Sobrien        (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
1895490286Sobrien		 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
1895590286Sobrien  "TARGET_MMX"
1895690286Sobrien  "pcmpgtd\t{%2, %0|%0, %2}"
1895790286Sobrien  [(set_attr "type" "mmx")])
1895890286Sobrien
1895990286Sobrien
1896090286Sobrien;; MMX max/min insns
1896190286Sobrien
1896290286Sobrien(define_insn "umaxv8qi3"
1896390286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1896490286Sobrien        (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
1896590286Sobrien		   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1896690286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1896790286Sobrien  "pmaxub\t{%2, %0|%0, %2}"
1896890286Sobrien  [(set_attr "type" "sse")])
1896990286Sobrien
1897090286Sobrien(define_insn "smaxv4hi3"
1897190286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1897290286Sobrien        (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
1897390286Sobrien		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1897490286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1897590286Sobrien  "pmaxsw\t{%2, %0|%0, %2}"
1897690286Sobrien  [(set_attr "type" "sse")])
1897790286Sobrien
1897890286Sobrien(define_insn "uminv8qi3"
1897990286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1898090286Sobrien        (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
1898190286Sobrien		   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1898290286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1898390286Sobrien  "pminub\t{%2, %0|%0, %2}"
1898490286Sobrien  [(set_attr "type" "sse")])
1898590286Sobrien
1898690286Sobrien(define_insn "sminv4hi3"
1898790286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1898890286Sobrien        (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
1898990286Sobrien		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1899090286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1899190286Sobrien  "pminsw\t{%2, %0|%0, %2}"
1899290286Sobrien  [(set_attr "type" "sse")])
1899390286Sobrien
1899490286Sobrien
1899590286Sobrien;; MMX shifts
1899690286Sobrien
1899790286Sobrien(define_insn "ashrv4hi3"
1899890286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1899990286Sobrien        (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
1900090286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1900190286Sobrien  "TARGET_MMX"
1900290286Sobrien  "psraw\t{%2, %0|%0, %2}"
1900390286Sobrien  [(set_attr "type" "mmx")])
1900490286Sobrien
1900590286Sobrien(define_insn "ashrv2si3"
1900690286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1900790286Sobrien        (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
1900890286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1900990286Sobrien  "TARGET_MMX"
1901090286Sobrien  "psrad\t{%2, %0|%0, %2}"
1901190286Sobrien  [(set_attr "type" "mmx")])
1901290286Sobrien
1901390286Sobrien(define_insn "lshrv4hi3"
1901490286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1901590286Sobrien        (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
1901690286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1901790286Sobrien  "TARGET_MMX"
1901890286Sobrien  "psrlw\t{%2, %0|%0, %2}"
1901990286Sobrien  [(set_attr "type" "mmx")])
1902090286Sobrien
1902190286Sobrien(define_insn "lshrv2si3"
1902290286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1902390286Sobrien        (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
1902490286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1902590286Sobrien  "TARGET_MMX"
1902690286Sobrien  "psrld\t{%2, %0|%0, %2}"
1902790286Sobrien  [(set_attr "type" "mmx")])
1902890286Sobrien
1902990286Sobrien;; See logical MMX insns.
1903090286Sobrien(define_insn "mmx_lshrdi3"
1903190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1903290286Sobrien        (unspec:DI
1903390286Sobrien	  [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
1903490286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
1903590286Sobrien  "TARGET_MMX"
1903690286Sobrien  "psrlq\t{%2, %0|%0, %2}"
1903790286Sobrien  [(set_attr "type" "mmx")])
1903890286Sobrien
1903990286Sobrien(define_insn "ashlv4hi3"
1904090286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1904190286Sobrien        (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
1904290286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1904390286Sobrien  "TARGET_MMX"
1904490286Sobrien  "psllw\t{%2, %0|%0, %2}"
1904590286Sobrien  [(set_attr "type" "mmx")])
1904690286Sobrien
1904790286Sobrien(define_insn "ashlv2si3"
1904890286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1904990286Sobrien        (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
1905090286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1905190286Sobrien  "TARGET_MMX"
1905290286Sobrien  "pslld\t{%2, %0|%0, %2}"
1905390286Sobrien  [(set_attr "type" "mmx")])
1905490286Sobrien
1905590286Sobrien;; See logical MMX insns.
1905690286Sobrien(define_insn "mmx_ashldi3"
1905790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1905890286Sobrien        (unspec:DI
1905990286Sobrien	 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
1906090286Sobrien		     (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
1906190286Sobrien  "TARGET_MMX"
1906290286Sobrien  "psllq\t{%2, %0|%0, %2}"
1906390286Sobrien  [(set_attr "type" "mmx")])
1906490286Sobrien
1906590286Sobrien
1906690286Sobrien;; MMX pack/unpack insns.
1906790286Sobrien
1906890286Sobrien(define_insn "mmx_packsswb"
1906990286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1907090286Sobrien	(vec_concat:V8QI
1907190286Sobrien	 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
1907290286Sobrien	 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
1907390286Sobrien  "TARGET_MMX"
1907490286Sobrien  "packsswb\t{%2, %0|%0, %2}"
1907590286Sobrien  [(set_attr "type" "mmx")])
1907690286Sobrien
1907790286Sobrien(define_insn "mmx_packssdw"
1907890286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1907990286Sobrien	(vec_concat:V4HI
1908090286Sobrien	 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
1908190286Sobrien	 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
1908290286Sobrien  "TARGET_MMX"
1908390286Sobrien  "packssdw\t{%2, %0|%0, %2}"
1908490286Sobrien  [(set_attr "type" "mmx")])
1908590286Sobrien
1908690286Sobrien(define_insn "mmx_packuswb"
1908790286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1908890286Sobrien	(vec_concat:V8QI
1908990286Sobrien	 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
1909090286Sobrien	 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
1909190286Sobrien  "TARGET_MMX"
1909290286Sobrien  "packuswb\t{%2, %0|%0, %2}"
1909390286Sobrien  [(set_attr "type" "mmx")])
1909490286Sobrien
1909590286Sobrien(define_insn "mmx_punpckhbw"
1909690286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1909790286Sobrien	(vec_merge:V8QI
1909890286Sobrien	 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
1909990286Sobrien			  (parallel [(const_int 4)
1910090286Sobrien				     (const_int 0)
1910190286Sobrien				     (const_int 5)
1910290286Sobrien				     (const_int 1)
1910390286Sobrien				     (const_int 6)
1910490286Sobrien				     (const_int 2)
1910590286Sobrien				     (const_int 7)
1910690286Sobrien				     (const_int 3)]))
1910790286Sobrien	 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
1910890286Sobrien			  (parallel [(const_int 0)
1910990286Sobrien				     (const_int 4)
1911090286Sobrien				     (const_int 1)
1911190286Sobrien				     (const_int 5)
1911290286Sobrien				     (const_int 2)
1911390286Sobrien				     (const_int 6)
1911490286Sobrien				     (const_int 3)
1911590286Sobrien				     (const_int 7)]))
1911690286Sobrien	 (const_int 85)))]
1911790286Sobrien  "TARGET_MMX"
1911890286Sobrien  "punpckhbw\t{%2, %0|%0, %2}"
1911990286Sobrien  [(set_attr "type" "mmx")])
1912090286Sobrien
1912190286Sobrien(define_insn "mmx_punpckhwd"
1912290286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1912390286Sobrien	(vec_merge:V4HI
1912490286Sobrien	 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
1912590286Sobrien			  (parallel [(const_int 0)
1912690286Sobrien				     (const_int 2)
1912790286Sobrien				     (const_int 1)
1912890286Sobrien				     (const_int 3)]))
1912990286Sobrien	 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
1913090286Sobrien			  (parallel [(const_int 2)
1913190286Sobrien				     (const_int 0)
1913290286Sobrien				     (const_int 3)
1913390286Sobrien				     (const_int 1)]))
1913490286Sobrien	 (const_int 5)))]
1913590286Sobrien  "TARGET_MMX"
1913690286Sobrien  "punpckhwd\t{%2, %0|%0, %2}"
1913790286Sobrien  [(set_attr "type" "mmx")])
1913890286Sobrien
1913990286Sobrien(define_insn "mmx_punpckhdq"
1914090286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1914190286Sobrien	(vec_merge:V2SI
1914290286Sobrien	 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
1914390286Sobrien			  (parallel [(const_int 0)
1914490286Sobrien				     (const_int 1)]))
1914590286Sobrien	 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
1914690286Sobrien			  (parallel [(const_int 1)
1914790286Sobrien				     (const_int 0)]))
1914890286Sobrien	 (const_int 1)))]
1914990286Sobrien  "TARGET_MMX"
1915090286Sobrien  "punpckhdq\t{%2, %0|%0, %2}"
1915190286Sobrien  [(set_attr "type" "mmx")])
1915290286Sobrien
1915390286Sobrien(define_insn "mmx_punpcklbw"
1915490286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1915590286Sobrien	(vec_merge:V8QI
1915690286Sobrien	 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
1915790286Sobrien			  (parallel [(const_int 0)
1915890286Sobrien				     (const_int 4)
1915990286Sobrien				     (const_int 1)
1916090286Sobrien				     (const_int 5)
1916190286Sobrien				     (const_int 2)
1916290286Sobrien				     (const_int 6)
1916390286Sobrien				     (const_int 3)
1916490286Sobrien				     (const_int 7)]))
1916590286Sobrien	 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
1916690286Sobrien			  (parallel [(const_int 4)
1916790286Sobrien				     (const_int 0)
1916890286Sobrien				     (const_int 5)
1916990286Sobrien				     (const_int 1)
1917090286Sobrien				     (const_int 6)
1917190286Sobrien				     (const_int 2)
1917290286Sobrien				     (const_int 7)
1917390286Sobrien				     (const_int 3)]))
1917490286Sobrien	 (const_int 85)))]
1917590286Sobrien  "TARGET_MMX"
1917690286Sobrien  "punpcklbw\t{%2, %0|%0, %2}"
1917790286Sobrien  [(set_attr "type" "mmx")])
1917890286Sobrien
1917990286Sobrien(define_insn "mmx_punpcklwd"
1918090286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1918190286Sobrien	(vec_merge:V4HI
1918290286Sobrien	 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
1918390286Sobrien			  (parallel [(const_int 2)
1918490286Sobrien				     (const_int 0)
1918590286Sobrien				     (const_int 3)
1918690286Sobrien				     (const_int 1)]))
1918790286Sobrien	 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
1918890286Sobrien			  (parallel [(const_int 0)
1918990286Sobrien				     (const_int 2)
1919090286Sobrien				     (const_int 1)
1919190286Sobrien				     (const_int 3)]))
1919290286Sobrien	 (const_int 5)))]
1919390286Sobrien  "TARGET_MMX"
1919490286Sobrien  "punpcklwd\t{%2, %0|%0, %2}"
1919590286Sobrien  [(set_attr "type" "mmx")])
1919690286Sobrien
1919790286Sobrien(define_insn "mmx_punpckldq"
1919890286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1919990286Sobrien	(vec_merge:V2SI
1920090286Sobrien	 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
1920190286Sobrien			   (parallel [(const_int 1)
1920290286Sobrien				      (const_int 0)]))
1920390286Sobrien	 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
1920490286Sobrien			  (parallel [(const_int 0)
1920590286Sobrien				     (const_int 1)]))
1920690286Sobrien	 (const_int 1)))]
1920790286Sobrien  "TARGET_MMX"
1920890286Sobrien  "punpckldq\t{%2, %0|%0, %2}"
1920990286Sobrien  [(set_attr "type" "mmx")])
1921090286Sobrien
1921190286Sobrien
1921290286Sobrien;; Miscellaneous stuff
1921390286Sobrien
1921490286Sobrien(define_insn "emms"
1921590286Sobrien  [(unspec_volatile [(const_int 0)] 31)
1921690286Sobrien   (clobber (reg:XF 8))
1921790286Sobrien   (clobber (reg:XF 9))
1921890286Sobrien   (clobber (reg:XF 10))
1921990286Sobrien   (clobber (reg:XF 11))
1922090286Sobrien   (clobber (reg:XF 12))
1922190286Sobrien   (clobber (reg:XF 13))
1922290286Sobrien   (clobber (reg:XF 14))
1922390286Sobrien   (clobber (reg:XF 15))
1922490286Sobrien   (clobber (reg:DI 29))
1922590286Sobrien   (clobber (reg:DI 30))
1922690286Sobrien   (clobber (reg:DI 31))
1922790286Sobrien   (clobber (reg:DI 32))
1922890286Sobrien   (clobber (reg:DI 33))
1922990286Sobrien   (clobber (reg:DI 34))
1923090286Sobrien   (clobber (reg:DI 35))
1923190286Sobrien   (clobber (reg:DI 36))]
1923290286Sobrien  "TARGET_MMX"
1923390286Sobrien  "emms"
1923490286Sobrien  [(set_attr "type" "mmx")
1923590286Sobrien   (set_attr "memory" "unknown")])
1923690286Sobrien
1923790286Sobrien(define_insn "ldmxcsr"
1923890286Sobrien  [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 37)]
1923990286Sobrien  "TARGET_MMX"
1924090286Sobrien  "ldmxcsr\t%0"
1924190286Sobrien  [(set_attr "type" "mmx")
1924290286Sobrien   (set_attr "memory" "load")])
1924390286Sobrien
1924490286Sobrien(define_insn "stmxcsr"
1924590286Sobrien  [(set (match_operand:SI 0 "memory_operand" "=m")
1924690286Sobrien	(unspec_volatile:SI [(const_int 0)] 40))]
1924790286Sobrien  "TARGET_MMX"
1924890286Sobrien  "stmxcsr\t%0"
1924990286Sobrien  [(set_attr "type" "mmx")
1925090286Sobrien   (set_attr "memory" "store")])
1925190286Sobrien
1925290286Sobrien(define_expand "sfence"
1925390286Sobrien  [(set (match_dup 0)
1925490286Sobrien	(unspec:BLK [(match_dup 0)] 44))]
1925590286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1925690286Sobrien{
1925790286Sobrien  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
1925890286Sobrien  MEM_VOLATILE_P (operands[0]) = 1;
1925990286Sobrien})
1926090286Sobrien
1926190286Sobrien(define_insn "*sfence_insn"
1926290286Sobrien  [(set (match_operand:BLK 0 "" "")
1926390286Sobrien	(unspec:BLK [(match_dup 0)] 44))]
1926490286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1926590286Sobrien  "sfence"
1926690286Sobrien  [(set_attr "type" "sse")
1926790286Sobrien   (set_attr "memory" "unknown")])
1926890286Sobrien
1926990286Sobrien(define_expand "sse_prologue_save"
1927090286Sobrien  [(parallel [(set (match_operand:BLK 0 "" "")
1927190286Sobrien		   (unspec:BLK [(reg:DI 21)
1927290286Sobrien				(reg:DI 22)
1927390286Sobrien				(reg:DI 23)
1927490286Sobrien				(reg:DI 24)
1927590286Sobrien				(reg:DI 25)
1927690286Sobrien				(reg:DI 26)
1927790286Sobrien				(reg:DI 27)
1927890286Sobrien				(reg:DI 28)] 13))
1927990286Sobrien	      (use (match_operand:DI 1 "register_operand" ""))
1928090286Sobrien	      (use (match_operand:DI 2 "immediate_operand" ""))
1928190286Sobrien	      (use (label_ref:DI (match_operand 3 "" "")))])]
1928290286Sobrien  "TARGET_64BIT"
1928390286Sobrien  "")
1928490286Sobrien
1928590286Sobrien(define_insn "*sse_prologue_save_insn"
1928690286Sobrien  [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
1928790286Sobrien			  (match_operand:DI 4 "const_int_operand" "n")))
1928890286Sobrien	(unspec:BLK [(reg:DI 21)
1928990286Sobrien		     (reg:DI 22)
1929090286Sobrien		     (reg:DI 23)
1929190286Sobrien		     (reg:DI 24)
1929290286Sobrien		     (reg:DI 25)
1929390286Sobrien		     (reg:DI 26)
1929490286Sobrien		     (reg:DI 27)
1929590286Sobrien		     (reg:DI 28)] 13))
1929690286Sobrien   (use (match_operand:DI 1 "register_operand" "r"))
1929790286Sobrien   (use (match_operand:DI 2 "const_int_operand" "i"))
1929890286Sobrien   (use (label_ref:DI (match_operand 3 "" "X")))]
1929990286Sobrien  "TARGET_64BIT
1930090286Sobrien   && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
1930190286Sobrien   && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
1930290286Sobrien  "*
1930390286Sobrien{
1930490286Sobrien  int i;
1930590286Sobrien  operands[0] = gen_rtx_MEM (Pmode,
1930690286Sobrien			     gen_rtx_PLUS (Pmode, operands[0], operands[4]));
1930790286Sobrien  output_asm_insn (\"jmp\\t%A1\", operands);
1930890286Sobrien  for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
1930990286Sobrien    {
1931090286Sobrien      operands[4] = adjust_address (operands[0], DImode, i*16);
1931190286Sobrien      operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
1931290286Sobrien      PUT_MODE (operands[4], TImode);
1931390286Sobrien      if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
1931490286Sobrien        output_asm_insn (\"rex\", operands);
1931590286Sobrien      output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
1931690286Sobrien    }
1931790286Sobrien  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
1931890286Sobrien			     CODE_LABEL_NUMBER (operands[3]));
1931990286Sobrien  RET;
1932090286Sobrien}
1932156391Sobrien  "
1932290286Sobrien  [(set_attr "type" "other")
1932390286Sobrien   (set_attr "length_immediate" "0")
1932490286Sobrien   (set_attr "length_address" "0")
1932590286Sobrien   (set_attr "length" "135")
1932690286Sobrien   (set_attr "memory" "store")
1932790286Sobrien   (set_attr "modrm" "0")
1932890286Sobrien   (set_attr "mode" "DI")])
1932990286Sobrien
1933090286Sobrien;; 3Dnow! instructions
1933190286Sobrien
1933290286Sobrien(define_insn "addv2sf3"
1933390286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1933490286Sobrien	(plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
1933590286Sobrien		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1933690286Sobrien  "TARGET_3DNOW"
1933790286Sobrien  "pfadd\\t{%2, %0|%0, %2}"
1933890286Sobrien  [(set_attr "type" "mmx")])
1933990286Sobrien
1934090286Sobrien(define_insn "subv2sf3"
1934190286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1934290286Sobrien        (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
1934390286Sobrien		    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1934490286Sobrien  "TARGET_3DNOW"
1934590286Sobrien  "pfsub\\t{%2, %0|%0, %2}"
1934690286Sobrien  [(set_attr "type" "mmx")])
1934790286Sobrien
1934890286Sobrien(define_insn "subrv2sf3"
1934990286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1935090286Sobrien        (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
1935190286Sobrien                    (match_operand:V2SF 1 "register_operand" "0")))]
1935290286Sobrien  "TARGET_3DNOW"
1935390286Sobrien  "pfsubr\\t{%2, %0|%0, %2}"
1935490286Sobrien  [(set_attr "type" "mmx")])
1935590286Sobrien
1935690286Sobrien(define_insn "gtv2sf3"
1935790286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1935890286Sobrien	(gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
1935990286Sobrien		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1936090286Sobrien "TARGET_3DNOW"
1936190286Sobrien  "pfcmpgt\\t{%2, %0|%0, %2}"
1936290286Sobrien  [(set_attr "type" "mmx")])
1936390286Sobrien
1936490286Sobrien(define_insn "gev2sf3"
1936590286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1936690286Sobrien	(ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
1936790286Sobrien		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1936890286Sobrien  "TARGET_3DNOW"
1936990286Sobrien  "pfcmpge\\t{%2, %0|%0, %2}"
1937090286Sobrien  [(set_attr "type" "mmx")])
1937190286Sobrien
1937290286Sobrien(define_insn "eqv2sf3"
1937390286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1937490286Sobrien	(eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
1937590286Sobrien		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1937690286Sobrien  "TARGET_3DNOW"
1937790286Sobrien  "pfcmpeq\\t{%2, %0|%0, %2}"
1937890286Sobrien  [(set_attr "type" "mmx")])
1937990286Sobrien
1938090286Sobrien(define_insn "pfmaxv2sf3"
1938190286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1938290286Sobrien        (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
1938390286Sobrien                   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1938490286Sobrien  "TARGET_3DNOW"
1938590286Sobrien  "pfmax\\t{%2, %0|%0, %2}"
1938690286Sobrien  [(set_attr "type" "mmx")])
1938790286Sobrien
1938890286Sobrien(define_insn "pfminv2sf3"
1938990286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1939090286Sobrien        (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
1939190286Sobrien                   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1939290286Sobrien  "TARGET_3DNOW"
1939390286Sobrien  "pfmin\\t{%2, %0|%0, %2}"
1939490286Sobrien  [(set_attr "type" "mmx")])
1939590286Sobrien
1939690286Sobrien(define_insn "mulv2sf3"
1939790286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1939890286Sobrien	(mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
1939990286Sobrien		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1940090286Sobrien  "TARGET_3DNOW"
1940190286Sobrien  "pfmul\\t{%2, %0|%0, %2}"
1940290286Sobrien  [(set_attr "type" "mmx")])
1940390286Sobrien
1940490286Sobrien(define_insn "femms"
1940590286Sobrien  [(unspec_volatile [(const_int 0)] 46)
1940690286Sobrien   (clobber (reg:XF 8))
1940790286Sobrien   (clobber (reg:XF 9))
1940890286Sobrien   (clobber (reg:XF 10))
1940990286Sobrien   (clobber (reg:XF 11))
1941090286Sobrien   (clobber (reg:XF 12))
1941190286Sobrien   (clobber (reg:XF 13))
1941290286Sobrien   (clobber (reg:XF 14))
1941390286Sobrien   (clobber (reg:XF 15))
1941490286Sobrien   (clobber (reg:DI 29))
1941590286Sobrien   (clobber (reg:DI 30))
1941690286Sobrien   (clobber (reg:DI 31))
1941790286Sobrien   (clobber (reg:DI 32))
1941890286Sobrien   (clobber (reg:DI 33))
1941990286Sobrien   (clobber (reg:DI 34))
1942090286Sobrien   (clobber (reg:DI 35))
1942190286Sobrien   (clobber (reg:DI 36))]
1942290286Sobrien  "TARGET_3DNOW"
1942390286Sobrien  "femms"
1942490286Sobrien  [(set_attr "type" "mmx")])
1942590286Sobrien
1942690286Sobrien(define_insn "pf2id"
1942790286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1942890286Sobrien	(fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
1942990286Sobrien  "TARGET_3DNOW"
1943090286Sobrien  "pf2id\\t{%1, %0|%0, %1}"
1943190286Sobrien  [(set_attr "type" "mmx")])
1943290286Sobrien
1943390286Sobrien(define_insn "pf2iw"
1943490286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1943590286Sobrien	(sign_extend:V2SI
1943690286Sobrien	   (ss_truncate:V2HI
1943790286Sobrien	      (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
1943890286Sobrien  "TARGET_3DNOW_A"
1943990286Sobrien  "pf2iw\\t{%1, %0|%0, %1}"
1944090286Sobrien  [(set_attr "type" "mmx")])
1944190286Sobrien
1944290286Sobrien(define_insn "pfacc"
1944390286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1944490286Sobrien	(vec_concat:V2SF
1944590286Sobrien	   (plus:SF
1944690286Sobrien	      (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
1944790286Sobrien			     (parallel [(const_int  0)]))
1944890286Sobrien	      (vec_select:SF (match_dup 1)
1944990286Sobrien			     (parallel [(const_int 1)])))
1945090286Sobrien           (plus:SF
1945190286Sobrien              (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
1945290286Sobrien			     (parallel [(const_int  0)]))
1945390286Sobrien              (vec_select:SF (match_dup 2)
1945490286Sobrien			     (parallel [(const_int 1)])))))]
1945590286Sobrien  "TARGET_3DNOW"
1945690286Sobrien  "pfacc\\t{%2, %0|%0, %2}"
1945790286Sobrien  [(set_attr "type" "mmx")])
1945890286Sobrien
1945990286Sobrien(define_insn "pfnacc"
1946090286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1946190286Sobrien  	(vec_concat:V2SF
1946290286Sobrien           (minus:SF
1946390286Sobrien              (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
1946490286Sobrien			     (parallel [(const_int 0)]))
1946590286Sobrien              (vec_select:SF (match_dup 1)
1946690286Sobrien			     (parallel [(const_int 1)])))
1946790286Sobrien           (minus:SF
1946890286Sobrien              (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
1946990286Sobrien			     (parallel [(const_int  0)]))
1947090286Sobrien              (vec_select:SF (match_dup 2)
1947190286Sobrien			     (parallel [(const_int 1)])))))]
1947290286Sobrien  "TARGET_3DNOW_A"
1947390286Sobrien  "pfnacc\\t{%2, %0|%0, %2}"
1947490286Sobrien  [(set_attr "type" "mmx")])
1947590286Sobrien
1947690286Sobrien(define_insn "pfpnacc"
1947790286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1947890286Sobrien        (vec_concat:V2SF
1947990286Sobrien           (minus:SF
1948090286Sobrien              (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
1948190286Sobrien			     (parallel [(const_int 0)]))
1948290286Sobrien              (vec_select:SF (match_dup 1)
1948390286Sobrien			     (parallel [(const_int 1)])))
1948490286Sobrien           (plus:SF
1948590286Sobrien              (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
1948690286Sobrien			     (parallel [(const_int 0)]))
1948790286Sobrien              (vec_select:SF (match_dup 2)
1948890286Sobrien			     (parallel [(const_int 1)])))))]
1948990286Sobrien  "TARGET_3DNOW_A"
1949090286Sobrien  "pfpnacc\\t{%2, %0|%0, %2}"
1949190286Sobrien  [(set_attr "type" "mmx")])
1949290286Sobrien
1949390286Sobrien(define_insn "pi2fw"
1949490286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1949590286Sobrien	(float:V2SF
1949690286Sobrien	   (vec_concat:V2SI
1949790286Sobrien	      (sign_extend:SI
1949890286Sobrien		 (truncate:HI
1949990286Sobrien		    (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1950090286Sobrien				   (parallel [(const_int 0)]))))
1950190286Sobrien              (sign_extend:SI
1950290286Sobrien		 (truncate:HI
1950390286Sobrien                    (vec_select:SI (match_dup 1)
1950490286Sobrien				   (parallel [(const_int  1)])))))))]
1950590286Sobrien  "TARGET_3DNOW_A"
1950690286Sobrien  "pi2fw\\t{%1, %0|%0, %1}"
1950790286Sobrien  [(set_attr "type" "mmx")])
1950890286Sobrien
1950990286Sobrien(define_insn "floatv2si2"
1951090286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1951190286Sobrien	(float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
1951290286Sobrien  "TARGET_3DNOW"
1951390286Sobrien  "pi2fd\\t{%1, %0|%0, %1}"
1951490286Sobrien  [(set_attr "type" "mmx")])
1951590286Sobrien
1951690286Sobrien;; This insn is identical to pavgb in operation, but the opcode is
1951790286Sobrien;; different.  To avoid accidentally matching pavgb, use an unspec.
1951890286Sobrien
1951990286Sobrien(define_insn "pavgusb"
1952090286Sobrien [(set (match_operand:V8QI 0 "register_operand" "=y")
1952190286Sobrien       (unspec:V8QI
1952290286Sobrien          [(match_operand:V8QI 1 "register_operand" "0")
1952390286Sobrien           (match_operand:V8QI 2 "nonimmediate_operand" "ym")] 49))]
1952490286Sobrien  "TARGET_3DNOW"
1952590286Sobrien  "pavgusb\\t{%2, %0|%0, %2}"
1952690286Sobrien  [(set_attr "type" "mmx")])
1952790286Sobrien
1952890286Sobrien;; 3DNow reciprical and sqrt
1952990286Sobrien 
1953090286Sobrien(define_insn "pfrcpv2sf2"
1953190286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1953290286Sobrien        (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 50))]
1953390286Sobrien  "TARGET_3DNOW"
1953490286Sobrien  "pfrcp\\t{%1, %0|%0, %1}"
1953590286Sobrien  [(set_attr "type" "mmx")])
1953690286Sobrien
1953790286Sobrien(define_insn "pfrcpit1v2sf3"
1953890286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1953990286Sobrien	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
1954090286Sobrien		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 51))]
1954190286Sobrien  "TARGET_3DNOW"
1954290286Sobrien  "pfrcpit1\\t{%2, %0|%0, %2}"
1954390286Sobrien  [(set_attr "type" "mmx")])
1954490286Sobrien
1954590286Sobrien(define_insn "pfrcpit2v2sf3"
1954690286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1954790286Sobrien	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
1954890286Sobrien		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 52))]
1954990286Sobrien  "TARGET_3DNOW"
1955090286Sobrien  "pfrcpit2\\t{%2, %0|%0, %2}"
1955190286Sobrien  [(set_attr "type" "mmx")])
1955290286Sobrien
1955390286Sobrien(define_insn "pfrsqrtv2sf2"
1955490286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1955590286Sobrien	(unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 53))]
1955690286Sobrien  "TARGET_3DNOW"
1955790286Sobrien   "pfrsqrt\\t{%1, %0|%0, %1}"
1955890286Sobrien   [(set_attr "type" "mmx")])
1955990286Sobrien		
1956090286Sobrien(define_insn "pfrsqit1v2sf3"
1956190286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1956290286Sobrien	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
1956390286Sobrien		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 54))]
1956490286Sobrien  "TARGET_3DNOW"
1956590286Sobrien  "pfrsqit1\\t{%2, %0|%0, %2}"
1956690286Sobrien  [(set_attr "type" "mmx")])
1956790286Sobrien
1956890286Sobrien(define_insn "pmulhrwv4hi3"
1956990286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1957090286Sobrien	(truncate:V4HI
1957190286Sobrien	   (lshiftrt:V4SI
1957290286Sobrien	      (plus:V4SI
1957390286Sobrien	         (mult:V4SI
1957490286Sobrien	            (sign_extend:V4SI
1957590286Sobrien		       (match_operand:V4HI 1 "register_operand" "0"))
1957690286Sobrien	            (sign_extend:V4SI
1957790286Sobrien		       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1957890286Sobrien	      (vec_const:V4SI
1957990286Sobrien	         (parallel [(const_int 32768)
1958090286Sobrien			    (const_int 32768)
1958190286Sobrien			    (const_int 32768)
1958290286Sobrien			    (const_int 32768)])))
1958390286Sobrien	   (const_int 16))))]
1958490286Sobrien  "TARGET_3DNOW"
1958590286Sobrien  "pmulhrw\\t{%2, %0|%0, %2}"
1958690286Sobrien  [(set_attr "type" "mmx")])
1958790286Sobrien
1958890286Sobrien(define_insn "pswapdv2si2"
1958990286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1959090286Sobrien	(vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1959190286Sobrien			 (parallel [(const_int 1) (const_int 0)])))]
1959290286Sobrien  "TARGET_3DNOW_A"
1959390286Sobrien  "pswapd\\t{%1, %0|%0, %1}"
1959490286Sobrien  [(set_attr "type" "mmx")])
1959590286Sobrien
1959690286Sobrien(define_insn "pswapdv2sf2"
1959790286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1959890286Sobrien	(vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
1959990286Sobrien			 (parallel [(const_int 1) (const_int 0)])))]
1960090286Sobrien  "TARGET_3DNOW_A"
1960190286Sobrien  "pswapd\\t{%1, %0|%0, %1}"
1960290286Sobrien  [(set_attr "type" "mmx")])
1960390286Sobrien
1960490286Sobrien(define_expand "prefetch"
1960590286Sobrien  [(prefetch (match_operand:SI 0 "address_operand" "")
1960690286Sobrien	     (match_operand:SI 1 "const_int_operand" "")
1960790286Sobrien	     (match_operand:SI 2 "const_int_operand" ""))]
1960890286Sobrien  "TARGET_PREFETCH_SSE || TARGET_3DNOW"
1960956391Sobrien{
1961090286Sobrien  int rw = INTVAL (operands[1]);
1961190286Sobrien  int locality = INTVAL (operands[2]);
1961290286Sobrien
1961390286Sobrien  if (rw != 0 && rw != 1)
1961490286Sobrien    abort ();
1961590286Sobrien  if (locality < 0 || locality > 3)
1961690286Sobrien    abort ();
1961790286Sobrien
1961890286Sobrien  /* Use 3dNOW prefetch in case we are asking for write prefetch not
1961990286Sobrien     suported by SSE counterpart or the SSE prefetch is not available
1962090286Sobrien     (K6 machines).  Otherwise use SSE prefetch as it allows specifying
1962190286Sobrien     of locality.  */
1962290286Sobrien  if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
1962390286Sobrien    operands[2] = GEN_INT (3);
1962490286Sobrien  else
1962590286Sobrien    operands[1] = const0_rtx;
1962690286Sobrien})
1962790286Sobrien
1962890286Sobrien(define_insn "*prefetch_sse"
1962990286Sobrien  [(prefetch (match_operand:SI 0 "address_operand" "p")
1963090286Sobrien	     (const_int 0)
1963190286Sobrien	     (match_operand:SI 1 "const_int_operand" ""))]
1963290286Sobrien  "TARGET_PREFETCH_SSE"
1963390286Sobrien{
1963490286Sobrien  static const char * const patterns[4] = {
1963590286Sobrien   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
1963690286Sobrien  };
1963790286Sobrien
1963890286Sobrien  int locality = INTVAL (operands[1]);
1963990286Sobrien  if (locality < 0 || locality > 3)
1964090286Sobrien    abort ();
1964190286Sobrien
1964290286Sobrien  return patterns[locality];  
1964390286Sobrien}
1964490286Sobrien  [(set_attr "type" "sse")])
1964590286Sobrien
1964690286Sobrien(define_insn "*prefetch_3dnow"
1964790286Sobrien  [(prefetch (match_operand:SI 0 "address_operand" "p")
1964890286Sobrien	     (match_operand:SI 1 "const_int_operand" "n")
1964990286Sobrien	     (const_int 3))]
1965090286Sobrien  "TARGET_3DNOW"
1965190286Sobrien{
1965290286Sobrien  if (INTVAL (operands[1]) == 0)
1965390286Sobrien    return "prefetch\t%a0";
1965490286Sobrien  else
1965590286Sobrien    return "prefetchw\t%a0";
1965690286Sobrien}
1965790286Sobrien  [(set_attr "type" "mmx")])
19658