i386.md revision 102802
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 102802 2002-09-01 21:13:32Z kan $
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
173896294Sobrien; The first alternative is used only to compute proper length of instruction.
173996294Sobrien; Reload's algorithm does not take into account the cost of spill instructions
174096294Sobrien; needed to free register in given class, so avoid it from choosing the first
174196294Sobrien; alternative when eax is not available.
174296294Sobrien
174390286Sobrien(define_insn "*movsi_1"
174496294Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=*?a,r,*?a,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
174596294Sobrien	(match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,rm,*y,*y,rm,*Y,*Y"))]
174690286Sobrien  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
174750650Sobrien{
174890286Sobrien  switch (get_attr_type (insn))
174990286Sobrien    {
175090286Sobrien    case TYPE_SSE:
175190286Sobrien      if (get_attr_mode (insn) == TImode)
175290286Sobrien        return "movdqa\t{%1, %0|%0, %1}";
175390286Sobrien      return "movd\t{%1, %0|%0, %1}";
175452296Sobrien
175590286Sobrien    case TYPE_MMX:
175696294Sobrien      if (get_attr_mode (insn) == DImode)
175796294Sobrien	return "movq\t{%1, %0|%0, %1}";
175890286Sobrien      return "movd\t{%1, %0|%0, %1}";
175952296Sobrien
176090286Sobrien    case TYPE_LEA:
176190286Sobrien      return "lea{l}\t{%1, %0|%0, %1}";
176218334Speter
176390286Sobrien    default:
176490286Sobrien      if (flag_pic && SYMBOLIC_CONST (operands[1]))
176590286Sobrien	abort();
176690286Sobrien      return "mov{l}\t{%1, %0|%0, %1}";
176790286Sobrien    }
176890286Sobrien}
176990286Sobrien  [(set (attr "type")
177096294Sobrien     (cond [(eq_attr "alternative" "4,5,6")
177190286Sobrien	      (const_string "mmx")
177296294Sobrien	    (eq_attr "alternative" "7,8,9")
177390286Sobrien	      (const_string "sse")
177490286Sobrien	    (and (ne (symbol_ref "flag_pic") (const_int 0))
177590286Sobrien		 (match_operand:SI 1 "symbolic_operand" ""))
177690286Sobrien	      (const_string "lea")
177790286Sobrien	   ]
177890286Sobrien	   (const_string "imov")))
177996294Sobrien   (set_attr "modrm" "0,*,0,*,*,*,*,*,*,*")
178096294Sobrien   (set_attr "mode" "SI,SI,SI,SI,SI,SI,DI,TI,SI,SI")])
178150650Sobrien
178290286Sobrien;; Stores and loads of ax to arbitary constant address.
178390286Sobrien;; We fake an second form of instruction to force reload to load address
178490286Sobrien;; into register when rax is not available
178590286Sobrien(define_insn "*movabssi_1_rex64"
178690286Sobrien  [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
178790286Sobrien	(match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
178890286Sobrien  "TARGET_64BIT"
178990286Sobrien  "@
179090286Sobrien   movabs{l}\t{%1, %P0|%P0, %1}
179190286Sobrien   mov{l}\t{%1, %a0|%a0, %1}
179290286Sobrien   movabs{l}\t{%1, %a0|%a0, %1}"
179390286Sobrien  [(set_attr "type" "imov")
179490286Sobrien   (set_attr "modrm" "0,*,*")
179590286Sobrien   (set_attr "length_address" "8,0,0")
179690286Sobrien   (set_attr "length_immediate" "0,*,*")
179790286Sobrien   (set_attr "memory" "store")
179890286Sobrien   (set_attr "mode" "SI")])
179950650Sobrien
180090286Sobrien(define_insn "*movabssi_2_rex64"
180190286Sobrien  [(set (match_operand:SI 0 "register_operand" "=a,r")
180290286Sobrien        (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
180390286Sobrien  "TARGET_64BIT"
180490286Sobrien  "@
180590286Sobrien   movabs{l}\t{%P1, %0|%0, %P1}
180690286Sobrien   mov{l}\t{%a1, %0|%0, %a1}"
180790286Sobrien  [(set_attr "type" "imov")
180890286Sobrien   (set_attr "modrm" "0,*")
180990286Sobrien   (set_attr "length_address" "8,0")
181090286Sobrien   (set_attr "length_immediate" "0")
181190286Sobrien   (set_attr "memory" "load")
181290286Sobrien   (set_attr "mode" "SI")])
181390286Sobrien
181490286Sobrien(define_insn "*swapsi"
181590286Sobrien  [(set (match_operand:SI 0 "register_operand" "+r")
181690286Sobrien	(match_operand:SI 1 "register_operand" "+r"))
181790286Sobrien   (set (match_dup 1)
181890286Sobrien	(match_dup 0))]
181950650Sobrien  ""
182090286Sobrien  "xchg{l}\t%1, %0"
182190286Sobrien  [(set_attr "type" "imov")
182290286Sobrien   (set_attr "pent_pair" "np")
182390286Sobrien   (set_attr "athlon_decode" "vector")
182490286Sobrien   (set_attr "mode" "SI")
182590286Sobrien   (set_attr "modrm" "0")
182690286Sobrien   (set_attr "ppro_uops" "few")])
182718334Speter
182890286Sobrien(define_expand "movhi"
182990286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
183090286Sobrien        (match_operand:HI 1 "general_operand" ""))]
183190286Sobrien  ""
183290286Sobrien  "ix86_expand_move (HImode, operands); DONE;")
183318334Speter
183490286Sobrien(define_insn "*pushhi2"
183590286Sobrien  [(set (match_operand:HI 0 "push_operand" "=<,<")
183690286Sobrien	(match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
183790286Sobrien  "!TARGET_64BIT"
183890286Sobrien  "@
183990286Sobrien   push{w}\t{|WORD PTR }%1
184090286Sobrien   push{w}\t%1"
184190286Sobrien  [(set_attr "type" "push")
184290286Sobrien   (set_attr "mode" "HI")])
184318334Speter
184490286Sobrien;; For 64BIT abi we always round up to 8 bytes.
184590286Sobrien(define_insn "*pushhi2_rex64"
184690286Sobrien  [(set (match_operand:HI 0 "push_operand" "=X")
184790286Sobrien	(match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
184890286Sobrien  "TARGET_64BIT"
184990286Sobrien  "push{q}\t%q1"
185090286Sobrien  [(set_attr "type" "push")
185190286Sobrien   (set_attr "mode" "QI")])
185290286Sobrien
185396294Sobrien; The first alternative is used only to compute proper length of instruction.
185496294Sobrien; Reload's algorithm does not take into account the cost of spill instructions
185596294Sobrien; needed to free register in given class, so avoid it from choosing the first
185696294Sobrien; alternative when eax is not available.
185796294Sobrien
185890286Sobrien(define_insn "*movhi_1"
185996294Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=*?a,r,r,*?a,r,m")
186090286Sobrien	(match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))]
186190286Sobrien  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
186218334Speter{
186390286Sobrien  switch (get_attr_type (insn))
186418334Speter    {
186590286Sobrien    case TYPE_IMOVX:
186690286Sobrien      /* movzwl is faster than movw on p2 due to partial word stalls,
186790286Sobrien	 though not as fast as an aligned movl.  */
186890286Sobrien      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
186990286Sobrien    default:
187090286Sobrien      if (get_attr_mode (insn) == MODE_SI)
187190286Sobrien        return "mov{l}\t{%k1, %k0|%k0, %k1}";
187290286Sobrien      else
187390286Sobrien        return "mov{w}\t{%1, %0|%0, %1}";
187418334Speter    }
187590286Sobrien}
187690286Sobrien  [(set (attr "type")
187790286Sobrien     (cond [(and (eq_attr "alternative" "0,1")
187890286Sobrien		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
187990286Sobrien			  (const_int 0))
188090286Sobrien		      (eq (symbol_ref "TARGET_HIMODE_MATH")
188190286Sobrien			  (const_int 0))))
188290286Sobrien	      (const_string "imov")
188390286Sobrien	    (and (eq_attr "alternative" "2,3,4")
188490286Sobrien		 (match_operand:HI 1 "aligned_operand" ""))
188590286Sobrien	      (const_string "imov")
188690286Sobrien	    (and (ne (symbol_ref "TARGET_MOVX")
188790286Sobrien		     (const_int 0))
188890286Sobrien		 (eq_attr "alternative" "0,1,3,4"))
188990286Sobrien	      (const_string "imovx")
189090286Sobrien	   ]
189190286Sobrien	   (const_string "imov")))
189290286Sobrien    (set (attr "mode")
189390286Sobrien      (cond [(eq_attr "type" "imovx")
189490286Sobrien	       (const_string "SI")
189590286Sobrien	     (and (eq_attr "alternative" "2,3,4")
189690286Sobrien		  (match_operand:HI 1 "aligned_operand" ""))
189790286Sobrien	       (const_string "SI")
189890286Sobrien	     (and (eq_attr "alternative" "0,1")
189990286Sobrien		  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
190090286Sobrien			   (const_int 0))
190190286Sobrien		       (eq (symbol_ref "TARGET_HIMODE_MATH")
190290286Sobrien			   (const_int 0))))
190390286Sobrien	       (const_string "SI")
190490286Sobrien	    ]
190590286Sobrien	    (const_string "HI")))
190690286Sobrien   (set_attr "modrm" "0,*,*,0,*,*")])
190718334Speter
190890286Sobrien;; Stores and loads of ax to arbitary constant address.
190990286Sobrien;; We fake an second form of instruction to force reload to load address
191090286Sobrien;; into register when rax is not available
191190286Sobrien(define_insn "*movabshi_1_rex64"
191290286Sobrien  [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
191390286Sobrien	(match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
191490286Sobrien  "TARGET_64BIT"
191590286Sobrien  "@
191690286Sobrien   movabs{w}\t{%1, %P0|%P0, %1}
191790286Sobrien   mov{w}\t{%1, %a0|%a0, %1}
191890286Sobrien   movabs{w}\t{%1, %a0|%a0, %1}"
191990286Sobrien  [(set_attr "type" "imov")
192090286Sobrien   (set_attr "modrm" "0,*,*")
192190286Sobrien   (set_attr "length_address" "8,0,0")
192290286Sobrien   (set_attr "length_immediate" "0,*,*")
192390286Sobrien   (set_attr "memory" "store")
192490286Sobrien   (set_attr "mode" "HI")])
192518334Speter
192690286Sobrien(define_insn "*movabshi_2_rex64"
192790286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a,r")
192890286Sobrien        (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
192990286Sobrien  "TARGET_64BIT"
193090286Sobrien  "@
193190286Sobrien   movabs{w}\t{%P1, %0|%0, %P1}
193290286Sobrien   mov{w}\t{%a1, %0|%0, %a1}"
193390286Sobrien  [(set_attr "type" "imov")
193490286Sobrien   (set_attr "modrm" "0,*")
193590286Sobrien   (set_attr "length_address" "8,0")
193690286Sobrien   (set_attr "length_immediate" "0")
193790286Sobrien   (set_attr "memory" "load")
193890286Sobrien   (set_attr "mode" "HI")])
193918334Speter
194090286Sobrien(define_insn "*swaphi_1"
194190286Sobrien  [(set (match_operand:HI 0 "register_operand" "+r")
194290286Sobrien	(match_operand:HI 1 "register_operand" "+r"))
194390286Sobrien   (set (match_dup 1)
194490286Sobrien	(match_dup 0))]
194590286Sobrien  "TARGET_PARTIAL_REG_STALL"
194690286Sobrien  "xchg{w}\t%1, %0"
194790286Sobrien  [(set_attr "type" "imov")
194890286Sobrien   (set_attr "pent_pair" "np")
194990286Sobrien   (set_attr "mode" "HI")
195090286Sobrien   (set_attr "modrm" "0")
195190286Sobrien   (set_attr "ppro_uops" "few")])
195218334Speter
195390286Sobrien(define_insn "*swaphi_2"
195490286Sobrien  [(set (match_operand:HI 0 "register_operand" "+r")
195590286Sobrien	(match_operand:HI 1 "register_operand" "+r"))
195690286Sobrien   (set (match_dup 1)
195790286Sobrien	(match_dup 0))]
195890286Sobrien  "! TARGET_PARTIAL_REG_STALL"
195990286Sobrien  "xchg{l}\t%k1, %k0"
196090286Sobrien  [(set_attr "type" "imov")
196190286Sobrien   (set_attr "pent_pair" "np")
196290286Sobrien   (set_attr "mode" "SI")
196390286Sobrien   (set_attr "modrm" "0")
196490286Sobrien   (set_attr "ppro_uops" "few")])
196518334Speter
196618334Speter(define_expand "movstricthi"
196790286Sobrien  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
196818334Speter	(match_operand:HI 1 "general_operand" ""))]
196990286Sobrien  "! TARGET_PARTIAL_REG_STALL || optimize_size"
197018334Speter{
197118334Speter  /* Don't generate memory->memory moves, go through a register */
197290286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
197390286Sobrien    operands[1] = force_reg (HImode, operands[1]);
197490286Sobrien})
197518334Speter
197690286Sobrien(define_insn "*movstricthi_1"
197790286Sobrien  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
197890286Sobrien	(match_operand:HI 1 "general_operand" "rn,m"))]
197990286Sobrien  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
198090286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
198190286Sobrien  "mov{w}\t{%1, %0|%0, %1}"
198290286Sobrien  [(set_attr "type" "imov")
198390286Sobrien   (set_attr "mode" "HI")])
198452296Sobrien
198590286Sobrien(define_insn "*movstricthi_xor"
198690286Sobrien  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
198790286Sobrien	(match_operand:HI 1 "const0_operand" "i"))
198890286Sobrien   (clobber (reg:CC 17))]
198990286Sobrien  "reload_completed
199090286Sobrien   && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
199190286Sobrien  "xor{w}\t{%0, %0|%0, %0}"
199290286Sobrien  [(set_attr "type" "alu1")
199390286Sobrien   (set_attr "mode" "HI")
199490286Sobrien   (set_attr "length_immediate" "0")])
199552296Sobrien
199690286Sobrien(define_expand "movqi"
199790286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
199890286Sobrien	(match_operand:QI 1 "general_operand" ""))]
199990286Sobrien  ""
200090286Sobrien  "ix86_expand_move (QImode, operands); DONE;")
200118334Speter
200290286Sobrien;; emit_push_insn when it calls move_by_pieces requires an insn to
200390286Sobrien;; "push a byte".  But actually we use pushw, which has the effect
200490286Sobrien;; of rounding the amount pushed up to a halfword.
200518334Speter
200690286Sobrien(define_insn "*pushqi2"
200790286Sobrien  [(set (match_operand:QI 0 "push_operand" "=X,X")
200890286Sobrien	(match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
200990286Sobrien  "!TARGET_64BIT"
201090286Sobrien  "@
201190286Sobrien   push{w}\t{|word ptr }%1
201290286Sobrien   push{w}\t%w1"
201390286Sobrien  [(set_attr "type" "push")
201490286Sobrien   (set_attr "mode" "HI")])
201518334Speter
201690286Sobrien;; For 64BIT abi we always round up to 8 bytes.
201790286Sobrien(define_insn "*pushqi2_rex64"
201890286Sobrien  [(set (match_operand:QI 0 "push_operand" "=X")
2019102802Skan	(match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
202090286Sobrien  "TARGET_64BIT"
202190286Sobrien  "push{q}\t%q1"
202290286Sobrien  [(set_attr "type" "push")
202390286Sobrien   (set_attr "mode" "QI")])
202490286Sobrien
202590286Sobrien;; Situation is quite tricky about when to choose full sized (SImode) move
202690286Sobrien;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
202790286Sobrien;; partial register dependency machines (such as AMD Athlon), where QImode
202890286Sobrien;; moves issue extra dependency and for partial register stalls machines
202990286Sobrien;; that don't use QImode patterns (and QImode move cause stall on the next
203090286Sobrien;; instruction).
203190286Sobrien;;
203290286Sobrien;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
203390286Sobrien;; register stall machines with, where we use QImode instructions, since
203490286Sobrien;; partial register stall can be caused there.  Then we use movzx.
203590286Sobrien(define_insn "*movqi_1"
203690286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
203790286Sobrien	(match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
203890286Sobrien  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
203990286Sobrien{
204090286Sobrien  switch (get_attr_type (insn))
204190286Sobrien    {
204290286Sobrien    case TYPE_IMOVX:
204390286Sobrien      if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
204490286Sobrien	abort ();
204590286Sobrien      return "movz{bl|x}\t{%1, %k0|%k0, %1}";
204690286Sobrien    default:
204790286Sobrien      if (get_attr_mode (insn) == MODE_SI)
204890286Sobrien        return "mov{l}\t{%k1, %k0|%k0, %k1}";
204990286Sobrien      else
205090286Sobrien        return "mov{b}\t{%1, %0|%0, %1}";
205190286Sobrien    }
205290286Sobrien}
205390286Sobrien  [(set (attr "type")
205490286Sobrien     (cond [(and (eq_attr "alternative" "3")
205590286Sobrien		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
205690286Sobrien			  (const_int 0))
205790286Sobrien		      (eq (symbol_ref "TARGET_QIMODE_MATH")
205890286Sobrien			  (const_int 0))))
205990286Sobrien	      (const_string "imov")
206090286Sobrien	    (eq_attr "alternative" "3,5")
206190286Sobrien	      (const_string "imovx")
206290286Sobrien	    (and (ne (symbol_ref "TARGET_MOVX")
206390286Sobrien		     (const_int 0))
206490286Sobrien		 (eq_attr "alternative" "2"))
206590286Sobrien	      (const_string "imovx")
206690286Sobrien	   ]
206790286Sobrien	   (const_string "imov")))
206890286Sobrien   (set (attr "mode")
206990286Sobrien      (cond [(eq_attr "alternative" "3,4,5")
207090286Sobrien	       (const_string "SI")
207190286Sobrien	     (eq_attr "alternative" "6")
207290286Sobrien	       (const_string "QI")
207390286Sobrien	     (eq_attr "type" "imovx")
207490286Sobrien	       (const_string "SI")
207590286Sobrien	     (and (eq_attr "type" "imov")
207690286Sobrien		  (and (eq_attr "alternative" "0,1,2")
207790286Sobrien		       (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
207890286Sobrien			   (const_int 0))))
207990286Sobrien	       (const_string "SI")
208090286Sobrien	     ;; Avoid partial register stalls when not using QImode arithmetic
208190286Sobrien	     (and (eq_attr "type" "imov")
208290286Sobrien		  (and (eq_attr "alternative" "0,1,2")
208390286Sobrien		       (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
208490286Sobrien				(const_int 0))
208590286Sobrien			    (eq (symbol_ref "TARGET_QIMODE_MATH")
208690286Sobrien				(const_int 0)))))
208790286Sobrien	       (const_string "SI")
208890286Sobrien	   ]
208990286Sobrien	   (const_string "QI")))])
209090286Sobrien
209190286Sobrien(define_expand "reload_outqi"
209290286Sobrien  [(parallel [(match_operand:QI 0 "" "=m")
209390286Sobrien              (match_operand:QI 1 "register_operand" "r")
209490286Sobrien              (match_operand:QI 2 "register_operand" "=&q")])]
209518334Speter  ""
209690286Sobrien{
209790286Sobrien  rtx op0, op1, op2;
209890286Sobrien  op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
209918334Speter
210090286Sobrien  if (reg_overlap_mentioned_p (op2, op0))
210190286Sobrien    abort ();
210290286Sobrien  if (! q_regs_operand (op1, QImode))
210390286Sobrien    {
210490286Sobrien      emit_insn (gen_movqi (op2, op1));
210590286Sobrien      op1 = op2;
210690286Sobrien    }
210790286Sobrien  emit_insn (gen_movqi (op0, op1));
210890286Sobrien  DONE;
210990286Sobrien})
211090286Sobrien
211190286Sobrien(define_insn "*swapqi"
211290286Sobrien  [(set (match_operand:QI 0 "register_operand" "+r")
211390286Sobrien	(match_operand:QI 1 "register_operand" "+r"))
211490286Sobrien   (set (match_dup 1)
211590286Sobrien	(match_dup 0))]
211650650Sobrien  ""
211790286Sobrien  "xchg{b}\t%1, %0"
211890286Sobrien  [(set_attr "type" "imov")
211990286Sobrien   (set_attr "pent_pair" "np")
212090286Sobrien   (set_attr "mode" "QI")
212190286Sobrien   (set_attr "modrm" "0")
212290286Sobrien   (set_attr "ppro_uops" "few")])
212390286Sobrien
212490286Sobrien(define_expand "movstrictqi"
212590286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
212690286Sobrien	(match_operand:QI 1 "general_operand" ""))]
212790286Sobrien  "! TARGET_PARTIAL_REG_STALL"
212818334Speter{
212990286Sobrien  /* Don't generate memory->memory moves, go through a register.  */
213090286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
213190286Sobrien    operands[1] = force_reg (QImode, operands[1]);
213290286Sobrien})
213318334Speter
213490286Sobrien(define_insn "*movstrictqi_1"
213590286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
213690286Sobrien	(match_operand:QI 1 "general_operand" "*qn,m"))]
213790286Sobrien  "! TARGET_PARTIAL_REG_STALL
213890286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
213990286Sobrien  "mov{b}\t{%1, %0|%0, %1}"
214090286Sobrien  [(set_attr "type" "imov")
214190286Sobrien   (set_attr "mode" "QI")])
214218334Speter
214390286Sobrien(define_insn "*movstrictqi_xor"
214490286Sobrien  [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
214590286Sobrien	(match_operand:QI 1 "const0_operand" "i"))
214690286Sobrien   (clobber (reg:CC 17))]
214790286Sobrien  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
214890286Sobrien  "xor{b}\t{%0, %0|%0, %0}"
214990286Sobrien  [(set_attr "type" "alu1")
215090286Sobrien   (set_attr "mode" "QI")
215190286Sobrien   (set_attr "length_immediate" "0")])
215218334Speter
215390286Sobrien(define_insn "*movsi_extv_1"
215490286Sobrien  [(set (match_operand:SI 0 "register_operand" "=R")
215590286Sobrien	(sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
215690286Sobrien			 (const_int 8)
215790286Sobrien			 (const_int 8)))]
215818334Speter  ""
215990286Sobrien  "movs{bl|x}\t{%h1, %0|%0, %h1}"
216090286Sobrien  [(set_attr "type" "imovx")
216190286Sobrien   (set_attr "mode" "SI")])
216290286Sobrien
216390286Sobrien(define_insn "*movhi_extv_1"
216490286Sobrien  [(set (match_operand:HI 0 "register_operand" "=R")
216590286Sobrien	(sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
216690286Sobrien			 (const_int 8)
216790286Sobrien			 (const_int 8)))]
216890286Sobrien  ""
216990286Sobrien  "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
217090286Sobrien  [(set_attr "type" "imovx")
217190286Sobrien   (set_attr "mode" "SI")])
217290286Sobrien
217390286Sobrien(define_insn "*movqi_extv_1"
217490286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
217590286Sobrien        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
217690286Sobrien                         (const_int 8)
217790286Sobrien                         (const_int 8)))]
217890286Sobrien  "!TARGET_64BIT"
217918334Speter{
218090286Sobrien  switch (get_attr_type (insn))
218118334Speter    {
218290286Sobrien    case TYPE_IMOVX:
218390286Sobrien      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
218490286Sobrien    default:
218590286Sobrien      return "mov{b}\t{%h1, %0|%0, %h1}";
218618334Speter    }
218790286Sobrien}
218890286Sobrien  [(set (attr "type")
218990286Sobrien     (if_then_else (and (match_operand:QI 0 "register_operand" "")
219090286Sobrien			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
219190286Sobrien			     (ne (symbol_ref "TARGET_MOVX")
219290286Sobrien				 (const_int 0))))
219390286Sobrien	(const_string "imovx")
219490286Sobrien	(const_string "imov")))
219590286Sobrien   (set (attr "mode")
219690286Sobrien     (if_then_else (eq_attr "type" "imovx")
219790286Sobrien	(const_string "SI")
219890286Sobrien	(const_string "QI")))])
219918334Speter
220090286Sobrien(define_insn "*movqi_extv_1_rex64"
220190286Sobrien  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
220290286Sobrien        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
220390286Sobrien                         (const_int 8)
220490286Sobrien                         (const_int 8)))]
220590286Sobrien  "TARGET_64BIT"
220618334Speter{
220790286Sobrien  switch (get_attr_type (insn))
220850650Sobrien    {
220990286Sobrien    case TYPE_IMOVX:
221090286Sobrien      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
221190286Sobrien    default:
221290286Sobrien      return "mov{b}\t{%h1, %0|%0, %h1}";
221350650Sobrien    }
221490286Sobrien}
221590286Sobrien  [(set (attr "type")
221690286Sobrien     (if_then_else (and (match_operand:QI 0 "register_operand" "")
221790286Sobrien			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
221890286Sobrien			     (ne (symbol_ref "TARGET_MOVX")
221990286Sobrien				 (const_int 0))))
222090286Sobrien	(const_string "imovx")
222190286Sobrien	(const_string "imov")))
222290286Sobrien   (set (attr "mode")
222390286Sobrien     (if_then_else (eq_attr "type" "imovx")
222490286Sobrien	(const_string "SI")
222590286Sobrien	(const_string "QI")))])
222618334Speter
222790286Sobrien;; Stores and loads of ax to arbitary constant address.
222890286Sobrien;; We fake an second form of instruction to force reload to load address
222990286Sobrien;; into register when rax is not available
223090286Sobrien(define_insn "*movabsqi_1_rex64"
223190286Sobrien  [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
223290286Sobrien	(match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
223390286Sobrien  "TARGET_64BIT"
223490286Sobrien  "@
223590286Sobrien   movabs{b}\t{%1, %P0|%P0, %1}
223690286Sobrien   mov{b}\t{%1, %a0|%a0, %1}
223790286Sobrien   movabs{b}\t{%1, %a0|%a0, %1}"
223890286Sobrien  [(set_attr "type" "imov")
223990286Sobrien   (set_attr "modrm" "0,*,*")
224090286Sobrien   (set_attr "length_address" "8,0,0")
224190286Sobrien   (set_attr "length_immediate" "0,*,*")
224290286Sobrien   (set_attr "memory" "store")
224390286Sobrien   (set_attr "mode" "QI")])
224418334Speter
224590286Sobrien(define_insn "*movabsqi_2_rex64"
224690286Sobrien  [(set (match_operand:QI 0 "register_operand" "=a,r")
224790286Sobrien        (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
224890286Sobrien  "TARGET_64BIT"
224990286Sobrien  "@
225090286Sobrien   movabs{b}\t{%P1, %0|%0, %P1}
225190286Sobrien   mov{b}\t{%a1, %0|%0, %a1}"
225290286Sobrien  [(set_attr "type" "imov")
225390286Sobrien   (set_attr "modrm" "0,*")
225490286Sobrien   (set_attr "length_address" "8,0")
225590286Sobrien   (set_attr "length_immediate" "0")
225690286Sobrien   (set_attr "memory" "load")
225790286Sobrien   (set_attr "mode" "QI")])
225818334Speter
225990286Sobrien(define_insn "*movsi_extzv_1"
226090286Sobrien  [(set (match_operand:SI 0 "register_operand" "=R")
226190286Sobrien	(zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
226290286Sobrien			 (const_int 8)
226390286Sobrien			 (const_int 8)))]
226490286Sobrien  ""
226590286Sobrien  "movz{bl|x}\t{%h1, %0|%0, %h1}"
226690286Sobrien  [(set_attr "type" "imovx")
226790286Sobrien   (set_attr "mode" "SI")])
226818334Speter
226990286Sobrien(define_insn "*movqi_extzv_2"
227090286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
227190286Sobrien        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
227290286Sobrien				    (const_int 8)
227390286Sobrien				    (const_int 8)) 0))]
227490286Sobrien  "!TARGET_64BIT"
227518334Speter{
227690286Sobrien  switch (get_attr_type (insn))
227718334Speter    {
227890286Sobrien    case TYPE_IMOVX:
227990286Sobrien      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
228090286Sobrien    default:
228190286Sobrien      return "mov{b}\t{%h1, %0|%0, %h1}";
228218334Speter    }
228390286Sobrien}
228490286Sobrien  [(set (attr "type")
228590286Sobrien     (if_then_else (and (match_operand:QI 0 "register_operand" "")
228690286Sobrien			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
228790286Sobrien			     (ne (symbol_ref "TARGET_MOVX")
228890286Sobrien				 (const_int 0))))
228990286Sobrien	(const_string "imovx")
229090286Sobrien	(const_string "imov")))
229190286Sobrien   (set (attr "mode")
229290286Sobrien     (if_then_else (eq_attr "type" "imovx")
229390286Sobrien	(const_string "SI")
229490286Sobrien	(const_string "QI")))])
229518334Speter
229690286Sobrien(define_insn "*movqi_extzv_2_rex64"
229790286Sobrien  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
229890286Sobrien        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
229990286Sobrien				    (const_int 8)
230090286Sobrien				    (const_int 8)) 0))]
230190286Sobrien  "TARGET_64BIT"
230218334Speter{
230390286Sobrien  switch (get_attr_type (insn))
230490286Sobrien    {
230590286Sobrien    case TYPE_IMOVX:
230690286Sobrien      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
230790286Sobrien    default:
230890286Sobrien      return "mov{b}\t{%h1, %0|%0, %h1}";
230990286Sobrien    }
231090286Sobrien}
231190286Sobrien  [(set (attr "type")
231290286Sobrien     (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
231390286Sobrien			(ne (symbol_ref "TARGET_MOVX")
231490286Sobrien			    (const_int 0)))
231590286Sobrien	(const_string "imovx")
231690286Sobrien	(const_string "imov")))
231790286Sobrien   (set (attr "mode")
231890286Sobrien     (if_then_else (eq_attr "type" "imovx")
231990286Sobrien	(const_string "SI")
232090286Sobrien	(const_string "QI")))])
232118334Speter
232290286Sobrien(define_insn "movsi_insv_1"
232390286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
232490286Sobrien			 (const_int 8)
232590286Sobrien			 (const_int 8))
232690286Sobrien	(match_operand:SI 1 "general_operand" "Qmn"))]
232790286Sobrien  "!TARGET_64BIT"
232890286Sobrien  "mov{b}\t{%b1, %h0|%h0, %b1}"
232990286Sobrien  [(set_attr "type" "imov")
233090286Sobrien   (set_attr "mode" "QI")])
233152296Sobrien
233290286Sobrien(define_insn "*movsi_insv_1_rex64"
233390286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
233490286Sobrien			 (const_int 8)
233590286Sobrien			 (const_int 8))
233690286Sobrien	(match_operand:SI 1 "nonmemory_operand" "Qn"))]
233790286Sobrien  "TARGET_64BIT"
233890286Sobrien  "mov{b}\t{%b1, %h0|%h0, %b1}"
233990286Sobrien  [(set_attr "type" "imov")
234090286Sobrien   (set_attr "mode" "QI")])
234118334Speter
234290286Sobrien(define_insn "*movqi_insv_2"
234390286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
234490286Sobrien			 (const_int 8)
234590286Sobrien			 (const_int 8))
234690286Sobrien	(and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
234790286Sobrien			     (const_int 8))
234890286Sobrien		(const_int 255)))]
234990286Sobrien  ""
235090286Sobrien  "mov{b}\t{%h1, %h0|%h0, %h1}"
235190286Sobrien  [(set_attr "type" "imov")
235290286Sobrien   (set_attr "mode" "QI")])
235318334Speter
235490286Sobrien(define_expand "movdi"
235590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
235690286Sobrien	(match_operand:DI 1 "general_operand" ""))]
235790286Sobrien  ""
235890286Sobrien  "ix86_expand_move (DImode, operands); DONE;")
235918334Speter
236090286Sobrien(define_insn "*pushdi"
236190286Sobrien  [(set (match_operand:DI 0 "push_operand" "=<")
236290286Sobrien	(match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
236390286Sobrien  "!TARGET_64BIT"
236490286Sobrien  "#")
236590286Sobrien
236690286Sobrien(define_insn "pushdi2_rex64"
236790286Sobrien  [(set (match_operand:DI 0 "push_operand" "=<,!<")
236890286Sobrien	(match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
236990286Sobrien  "TARGET_64BIT"
237090286Sobrien  "@
237190286Sobrien   push{q}\t%1
237290286Sobrien   #"
237390286Sobrien  [(set_attr "type" "push,multi")
237490286Sobrien   (set_attr "mode" "DI")])
237590286Sobrien
237690286Sobrien;; Convert impossible pushes of immediate to existing instructions.
237790286Sobrien;; First try to get scratch register and go through it.  In case this
237890286Sobrien;; fails, push sign extended lower part first and then overwrite
237990286Sobrien;; upper part by 32bit move.
238090286Sobrien(define_peephole2
238190286Sobrien  [(match_scratch:DI 2 "r")
238290286Sobrien   (set (match_operand:DI 0 "push_operand" "")
238390286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
238490286Sobrien  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
238590286Sobrien   && !x86_64_immediate_operand (operands[1], DImode)"
238690286Sobrien  [(set (match_dup 2) (match_dup 1))
238790286Sobrien   (set (match_dup 0) (match_dup 2))]
238890286Sobrien  "")
238990286Sobrien
239090286Sobrien;; We need to define this as both peepholer and splitter for case
239190286Sobrien;; peephole2 pass is not run.
239290286Sobrien(define_peephole2
239390286Sobrien  [(set (match_operand:DI 0 "push_operand" "")
239490286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
239590286Sobrien  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
239690286Sobrien   && !x86_64_immediate_operand (operands[1], DImode) && 1"
239790286Sobrien  [(set (match_dup 0) (match_dup 1))
239890286Sobrien   (set (match_dup 2) (match_dup 3))]
239990286Sobrien  "split_di (operands + 1, 1, operands + 2, operands + 3);
240090286Sobrien   operands[1] = gen_lowpart (DImode, operands[2]);
240190286Sobrien   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
240290286Sobrien						    GEN_INT (4)));
240390286Sobrien  ")
240490286Sobrien
240590286Sobrien(define_split
240690286Sobrien  [(set (match_operand:DI 0 "push_operand" "")
240790286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
240890286Sobrien  "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
240990286Sobrien   && !symbolic_operand (operands[1], DImode)
241090286Sobrien   && !x86_64_immediate_operand (operands[1], DImode)"
241190286Sobrien  [(set (match_dup 0) (match_dup 1))
241290286Sobrien   (set (match_dup 2) (match_dup 3))]
241390286Sobrien  "split_di (operands + 1, 1, operands + 2, operands + 3);
241490286Sobrien   operands[1] = gen_lowpart (DImode, operands[2]);
241590286Sobrien   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
241690286Sobrien						    GEN_INT (4)));
241790286Sobrien  ")
241890286Sobrien
241990286Sobrien(define_insn "*pushdi2_prologue_rex64"
242090286Sobrien  [(set (match_operand:DI 0 "push_operand" "=<")
242190286Sobrien	(match_operand:DI 1 "general_no_elim_operand" "re*m"))
242290286Sobrien   (clobber (mem:BLK (scratch)))]
242390286Sobrien  "TARGET_64BIT"
242490286Sobrien  "push{q}\t%1"
242590286Sobrien  [(set_attr "type" "push")
242690286Sobrien   (set_attr "mode" "DI")])
242790286Sobrien
242890286Sobrien(define_insn "*popdi1_epilogue_rex64"
242990286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
243090286Sobrien	(mem:DI (reg:DI 7)))
243190286Sobrien   (set (reg:DI 7)
243290286Sobrien	(plus:DI (reg:DI 7) (const_int 8)))
243390286Sobrien   (clobber (mem:BLK (scratch)))]
243490286Sobrien  "TARGET_64BIT"
243590286Sobrien  "pop{q}\t%0"
243690286Sobrien  [(set_attr "type" "pop")
243790286Sobrien   (set_attr "mode" "DI")])
243890286Sobrien
243990286Sobrien(define_insn "popdi1"
244090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
244190286Sobrien	(mem:DI (reg:DI 7)))
244290286Sobrien   (set (reg:DI 7)
244390286Sobrien	(plus:DI (reg:DI 7) (const_int 8)))]
244490286Sobrien  "TARGET_64BIT"
244590286Sobrien  "pop{q}\t%0"
244690286Sobrien  [(set_attr "type" "pop")
244790286Sobrien   (set_attr "mode" "DI")])
244890286Sobrien
244990286Sobrien(define_insn "*movdi_xor_rex64"
245090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
245190286Sobrien	(match_operand:DI 1 "const0_operand" "i"))
245290286Sobrien   (clobber (reg:CC 17))]
245390286Sobrien  "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
245490286Sobrien   && reload_completed"
245590286Sobrien  "xor{l}\t{%k0, %k0|%k0, %k0}"
245690286Sobrien  [(set_attr "type" "alu1")
245790286Sobrien   (set_attr "mode" "SI")
245890286Sobrien   (set_attr "length_immediate" "0")])
245990286Sobrien
246090286Sobrien(define_insn "*movdi_or_rex64"
246190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
246290286Sobrien	(match_operand:DI 1 "const_int_operand" "i"))
246390286Sobrien   (clobber (reg:CC 17))]
246490286Sobrien  "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
246590286Sobrien   && reload_completed
246690286Sobrien   && GET_CODE (operands[1]) == CONST_INT
246790286Sobrien   && INTVAL (operands[1]) == -1"
246818334Speter{
246990286Sobrien  operands[1] = constm1_rtx;
247090286Sobrien  return "or{q}\t{%1, %0|%0, %1}";
247190286Sobrien}
247290286Sobrien  [(set_attr "type" "alu1")
247390286Sobrien   (set_attr "mode" "DI")
247490286Sobrien   (set_attr "length_immediate" "1")])
247518334Speter
247690286Sobrien(define_insn "*movdi_2"
247796294Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
247890286Sobrien	(match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
247990286Sobrien  "!TARGET_64BIT
248090286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
248190286Sobrien  "@
248290286Sobrien   #
248390286Sobrien   #
248490286Sobrien   movq\t{%1, %0|%0, %1}
248590286Sobrien   movq\t{%1, %0|%0, %1}
248690286Sobrien   movq\t{%1, %0|%0, %1}
248790286Sobrien   movdqa\t{%1, %0|%0, %1}
248890286Sobrien   movq\t{%1, %0|%0, %1}"
248990286Sobrien  [(set_attr "type" "*,*,mmx,mmx,sse,sse,sse")
249090286Sobrien   (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
249118334Speter
249290286Sobrien(define_split
249390286Sobrien  [(set (match_operand:DI 0 "push_operand" "")
249490286Sobrien        (match_operand:DI 1 "general_operand" ""))]
249590286Sobrien  "!TARGET_64BIT && reload_completed
249690286Sobrien   && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
249790286Sobrien  [(const_int 0)]
249890286Sobrien  "ix86_split_long_move (operands); DONE;")
249918334Speter
250090286Sobrien;; %%% This multiword shite has got to go.
250190286Sobrien(define_split
250290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
250390286Sobrien        (match_operand:DI 1 "general_operand" ""))]
250490286Sobrien  "!TARGET_64BIT && reload_completed
250590286Sobrien   && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
250690286Sobrien   && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
250790286Sobrien  [(const_int 0)]
250890286Sobrien  "ix86_split_long_move (operands); DONE;")
250918334Speter
251090286Sobrien(define_insn "*movdi_1_rex64"
251190286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!m*y,!*y,!*Y,!m,!*Y")
251290286Sobrien	(match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,m,*Y,*Y,*m"))]
251390286Sobrien  "TARGET_64BIT
251490286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
251590286Sobrien{
251690286Sobrien  switch (get_attr_type (insn))
251790286Sobrien    {
251890286Sobrien    case TYPE_SSE:
251990286Sobrien      if (register_operand (operands[0], DImode)
252090286Sobrien	  && register_operand (operands[1], DImode))
252190286Sobrien	  return "movdqa\t{%1, %0|%0, %1}";
252290286Sobrien      /* FALLTHRU */
252390286Sobrien    case TYPE_MMX:
252490286Sobrien      return "movq\t{%1, %0|%0, %1}";
252590286Sobrien    case TYPE_MULTI:
252690286Sobrien      return "#";
252790286Sobrien    case TYPE_LEA:
252890286Sobrien      return "lea{q}\t{%a1, %0|%0, %a1}";
252990286Sobrien    default:
253090286Sobrien      if (flag_pic && SYMBOLIC_CONST (operands[1]))
253190286Sobrien	abort ();
253290286Sobrien      if (get_attr_mode (insn) == MODE_SI)
253390286Sobrien	return "mov{l}\t{%k1, %k0|%k0, %k1}";
253490286Sobrien      else if (which_alternative == 2)
253590286Sobrien	return "movabs{q}\t{%1, %0|%0, %1}";
253618334Speter      else
253790286Sobrien	return "mov{q}\t{%1, %0|%0, %1}";
253818334Speter    }
253990286Sobrien}
254090286Sobrien  [(set (attr "type")
254190286Sobrien     (cond [(eq_attr "alternative" "5,6")
254290286Sobrien	      (const_string "mmx")
254390286Sobrien	    (eq_attr "alternative" "7,8")
254490286Sobrien	      (const_string "sse")
254590286Sobrien	    (eq_attr "alternative" "4")
254690286Sobrien	      (const_string "multi")
254790286Sobrien 	    (and (ne (symbol_ref "flag_pic") (const_int 0))
254890286Sobrien		 (match_operand:DI 1 "symbolic_operand" ""))
254990286Sobrien	      (const_string "lea")
255090286Sobrien	   ]
255190286Sobrien	   (const_string "imov")))
255290286Sobrien   (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*")
255390286Sobrien   (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*")
255490286Sobrien   (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI")])
255550650Sobrien
255690286Sobrien;; Stores and loads of ax to arbitary constant address.
255790286Sobrien;; We fake an second form of instruction to force reload to load address
255890286Sobrien;; into register when rax is not available
255990286Sobrien(define_insn "*movabsdi_1_rex64"
2560102802Skan  [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2561102802Skan	(match_operand:DI 1 "nonmemory_operand" "a,er"))]
256290286Sobrien  "TARGET_64BIT"
256390286Sobrien  "@
256490286Sobrien   movabs{q}\t{%1, %P0|%P0, %1}
2565102802Skan   mov{q}\t{%1, %a0|%a0, %1}"
256690286Sobrien  [(set_attr "type" "imov")
2567102802Skan   (set_attr "modrm" "0,*")
2568102802Skan   (set_attr "length_address" "8,0")
2569102802Skan   (set_attr "length_immediate" "0,*")
257090286Sobrien   (set_attr "memory" "store")
257190286Sobrien   (set_attr "mode" "DI")])
257218334Speter
257390286Sobrien(define_insn "*movabsdi_2_rex64"
257490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a,r")
257590286Sobrien        (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
257690286Sobrien  "TARGET_64BIT"
257790286Sobrien  "@
257890286Sobrien   movabs{q}\t{%P1, %0|%0, %P1}
257990286Sobrien   mov{q}\t{%a1, %0|%0, %a1}"
258090286Sobrien  [(set_attr "type" "imov")
258190286Sobrien   (set_attr "modrm" "0,*")
258290286Sobrien   (set_attr "length_address" "8,0")
258390286Sobrien   (set_attr "length_immediate" "0")
258490286Sobrien   (set_attr "memory" "load")
258590286Sobrien   (set_attr "mode" "DI")])
258690286Sobrien
258790286Sobrien;; Convert impossible stores of immediate to existing instructions.
258890286Sobrien;; First try to get scratch register and go through it.  In case this
258990286Sobrien;; fails, move by 32bit parts.
259090286Sobrien(define_peephole2
259190286Sobrien  [(match_scratch:DI 2 "r")
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)"
259690286Sobrien  [(set (match_dup 2) (match_dup 1))
259790286Sobrien   (set (match_dup 0) (match_dup 2))]
259852296Sobrien  "")
259950650Sobrien
260090286Sobrien;; We need to define this as both peepholer and splitter for case
260190286Sobrien;; peephole2 pass is not run.
260290286Sobrien(define_peephole2
260390286Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
260490286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
260590286Sobrien  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
260690286Sobrien   && !x86_64_immediate_operand (operands[1], DImode) && 1"
260790286Sobrien  [(set (match_dup 2) (match_dup 3))
260890286Sobrien   (set (match_dup 4) (match_dup 5))]
260990286Sobrien  "split_di (operands, 2, operands + 2, operands + 4);")
261090286Sobrien
261190286Sobrien(define_split
261290286Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
261390286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
261490286Sobrien  "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
261590286Sobrien   && !symbolic_operand (operands[1], DImode)
261690286Sobrien   && !x86_64_immediate_operand (operands[1], DImode)"
261790286Sobrien  [(set (match_dup 2) (match_dup 3))
261890286Sobrien   (set (match_dup 4) (match_dup 5))]
261990286Sobrien  "split_di (operands, 2, operands + 2, operands + 4);")
262090286Sobrien
262190286Sobrien(define_insn "*swapdi_rex64"
262290286Sobrien  [(set (match_operand:DI 0 "register_operand" "+r")
262390286Sobrien	(match_operand:DI 1 "register_operand" "+r"))
262490286Sobrien   (set (match_dup 1)
262590286Sobrien	(match_dup 0))]
262690286Sobrien  "TARGET_64BIT"
262790286Sobrien  "xchg{q}\t%1, %0"
262890286Sobrien  [(set_attr "type" "imov")
262990286Sobrien   (set_attr "pent_pair" "np")
263090286Sobrien   (set_attr "athlon_decode" "vector")
263190286Sobrien   (set_attr "mode" "DI")
263290286Sobrien   (set_attr "modrm" "0")
263390286Sobrien   (set_attr "ppro_uops" "few")])
263490286Sobrien
263590286Sobrien  
263650650Sobrien(define_expand "movsf"
263790286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "")
263850650Sobrien	(match_operand:SF 1 "general_operand" ""))]
263918334Speter  ""
264090286Sobrien  "ix86_expand_move (SFmode, operands); DONE;")
264190286Sobrien
264290286Sobrien(define_insn "*pushsf"
264390286Sobrien  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
264490286Sobrien	(match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
264590286Sobrien  "!TARGET_64BIT"
264618334Speter{
264790286Sobrien  switch (which_alternative)
264818334Speter    {
264990286Sobrien    case 0:
265090286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
265190286Sobrien      operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
265290286Sobrien      operands[2] = stack_pointer_rtx;
265390286Sobrien      operands[3] = GEN_INT (4);
265490286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
265590286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
265690286Sobrien      else
265790286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
265818334Speter
265990286Sobrien    case 1:
266090286Sobrien      return "push{l}\t%1";
266190286Sobrien    case 2:
266290286Sobrien      return "#";
266390286Sobrien
266490286Sobrien    default:
266590286Sobrien      abort ();
266618334Speter    }
266790286Sobrien}
266890286Sobrien  [(set_attr "type" "multi,push,multi")
266990286Sobrien   (set_attr "mode" "SF,SI,SF")])
267018334Speter
267190286Sobrien(define_insn "*pushsf_rex64"
267290286Sobrien  [(set (match_operand:SF 0 "push_operand" "=X,X,X")
267390286Sobrien	(match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
267490286Sobrien  "TARGET_64BIT"
267518334Speter{
267690286Sobrien  switch (which_alternative)
267790286Sobrien    {
267890286Sobrien    case 0:
267990286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
268090286Sobrien      operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
268190286Sobrien      operands[2] = stack_pointer_rtx;
268290286Sobrien      operands[3] = GEN_INT (8);
268390286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
268490286Sobrien	return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
268590286Sobrien      else
268690286Sobrien	return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
268718334Speter
268890286Sobrien    case 1:
268990286Sobrien      return "push{q}\t%q1";
269018334Speter
269190286Sobrien    case 2:
269290286Sobrien      return "#";
269390286Sobrien
269490286Sobrien    default:
269590286Sobrien      abort ();
269618334Speter    }
269790286Sobrien}
269890286Sobrien  [(set_attr "type" "multi,push,multi")
269990286Sobrien   (set_attr "mode" "SF,DI,SF")])
270018334Speter
270190286Sobrien(define_split
270290286Sobrien  [(set (match_operand:SF 0 "push_operand" "")
270390286Sobrien	(match_operand:SF 1 "memory_operand" ""))]
270490286Sobrien  "reload_completed
270590286Sobrien   && GET_CODE (operands[1]) == MEM
270690286Sobrien   && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
270790286Sobrien   && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
270890286Sobrien  [(set (match_dup 0)
270990286Sobrien	(match_dup 1))]
271090286Sobrien  "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
271118334Speter
271290286Sobrien
271390286Sobrien;; %%% Kill this when call knows how to work this out.
271490286Sobrien(define_split
271590286Sobrien  [(set (match_operand:SF 0 "push_operand" "")
271690286Sobrien	(match_operand:SF 1 "register_operand" ""))]
271790286Sobrien  "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
271890286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
271990286Sobrien   (set (mem:SF (reg:SI 7)) (match_dup 1))])
272090286Sobrien
272190286Sobrien(define_split
272290286Sobrien  [(set (match_operand:SF 0 "push_operand" "")
272390286Sobrien	(match_operand:SF 1 "register_operand" ""))]
272490286Sobrien  "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
272590286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
272690286Sobrien   (set (mem:SF (reg:DI 7)) (match_dup 1))])
272790286Sobrien
272890286Sobrien(define_insn "*movsf_1"
272996294Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
273096294Sobrien	(match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf,rm,*y,*y"))]
273190286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
273290286Sobrien   && (reload_in_progress || reload_completed
273390286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
273490286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
273590286Sobrien       || memory_operand (operands[0], SFmode))" 
273690286Sobrien{
273790286Sobrien  switch (which_alternative)
273818334Speter    {
273990286Sobrien    case 0:
274090286Sobrien      if (REG_P (operands[1])
274190286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
274290286Sobrien        return "fstp\t%y0";
274390286Sobrien      else if (STACK_TOP_P (operands[0]))
274490286Sobrien        return "fld%z1\t%y1";
274518334Speter      else
274690286Sobrien        return "fst\t%y0";
274718334Speter
274890286Sobrien    case 1:
274990286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
275090286Sobrien        return "fstp%z0\t%y0";
275190286Sobrien      else
275290286Sobrien        return "fst%z0\t%y0";
275318334Speter
275490286Sobrien    case 2:
275590286Sobrien      switch (standard_80387_constant_p (operands[1]))
275690286Sobrien        {
275790286Sobrien        case 1:
275890286Sobrien	  return "fldz";
275990286Sobrien	case 2:
276090286Sobrien	  return "fld1";
276190286Sobrien	}
276290286Sobrien      abort();
276318334Speter
276490286Sobrien    case 3:
276590286Sobrien    case 4:
276690286Sobrien      return "mov{l}\t{%1, %0|%0, %1}";
276790286Sobrien    case 5:
276896294Sobrien      if (TARGET_SSE2)
276996294Sobrien	return "pxor\t%0, %0";
277096294Sobrien      else
277196294Sobrien	return "xorps\t%0, %0";
277290286Sobrien    case 6:
277390286Sobrien      if (TARGET_PARTIAL_REG_DEPENDENCY)
277490286Sobrien	return "movaps\t{%1, %0|%0, %1}";
277590286Sobrien      else
277690286Sobrien	return "movss\t{%1, %0|%0, %1}";
277790286Sobrien    case 7:
277890286Sobrien    case 8:
277990286Sobrien      return "movss\t{%1, %0|%0, %1}";
278018334Speter
278196294Sobrien    case 9:
278296294Sobrien    case 10:
278396294Sobrien      return "movd\t{%1, %0|%0, %1}";
278496294Sobrien
278596294Sobrien    case 11:
278696294Sobrien      return "movq\t{%1, %0|%0, %1}";
278796294Sobrien
278890286Sobrien    default:
278990286Sobrien      abort();
279090286Sobrien    }
279190286Sobrien}
279296294Sobrien  [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse,sse,sse,mmx,mmx,mmx")
279396294Sobrien   (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF,SI,SI,DI")])
279418334Speter
279590286Sobrien(define_insn "*swapsf"
279690286Sobrien  [(set (match_operand:SF 0 "register_operand" "+f")
279790286Sobrien	(match_operand:SF 1 "register_operand" "+f"))
279818334Speter   (set (match_dup 1)
279918334Speter	(match_dup 0))]
280090286Sobrien  "reload_completed || !TARGET_SSE"
280118334Speter{
280218334Speter  if (STACK_TOP_P (operands[0]))
280390286Sobrien    return "fxch\t%1";
280418334Speter  else
280590286Sobrien    return "fxch\t%0";
280690286Sobrien}
280790286Sobrien  [(set_attr "type" "fxch")
280890286Sobrien   (set_attr "mode" "SF")])
280918334Speter
281090286Sobrien(define_expand "movdf"
281190286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "")
281290286Sobrien	(match_operand:DF 1 "general_operand" ""))]
281390286Sobrien  ""
281490286Sobrien  "ix86_expand_move (DFmode, operands); DONE;")
281552296Sobrien
281690286Sobrien;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
281790286Sobrien;; Size of pushdf using integer insturctions is 2+2*memory operand size
281890286Sobrien;; On the average, pushdf using integers can be still shorter.  Allow this
281990286Sobrien;; pattern for optimize_size too.
282090286Sobrien
282190286Sobrien(define_insn "*pushdf_nointeger"
282290286Sobrien  [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
282390286Sobrien	(match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
282490286Sobrien  "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
282518334Speter{
282690286Sobrien  switch (which_alternative)
282718334Speter    {
282890286Sobrien    case 0:
282990286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
283090286Sobrien      operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
283190286Sobrien      operands[2] = stack_pointer_rtx;
283290286Sobrien      operands[3] = GEN_INT (8);
283390286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
283490286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
283590286Sobrien      else
283690286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
283718334Speter
283890286Sobrien    case 1:
283990286Sobrien    case 2:
284090286Sobrien    case 3:
284190286Sobrien      return "#";
284218334Speter
284390286Sobrien    default:
284490286Sobrien      abort ();
284590286Sobrien    }
284690286Sobrien}
284790286Sobrien  [(set_attr "type" "multi")
284890286Sobrien   (set_attr "mode" "DF,SI,SI,DF")])
284918334Speter
285090286Sobrien(define_insn "*pushdf_integer"
285190286Sobrien  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
285290286Sobrien	(match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
285390286Sobrien  "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
285490286Sobrien{
285590286Sobrien  switch (which_alternative)
285690286Sobrien    {
285790286Sobrien    case 0:
285890286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
285990286Sobrien      operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
286090286Sobrien      operands[2] = stack_pointer_rtx;
286190286Sobrien      operands[3] = GEN_INT (8);
286290286Sobrien      if (TARGET_64BIT)
286390286Sobrien	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
286490286Sobrien	  return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
286590286Sobrien	else
286690286Sobrien	  return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
286718334Speter      else
286890286Sobrien	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
286990286Sobrien	  return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
287090286Sobrien	else
287190286Sobrien	  return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
287218334Speter
287350650Sobrien
287490286Sobrien    case 1:
287590286Sobrien    case 2:
287690286Sobrien      return "#";
287750650Sobrien
287890286Sobrien    default:
287990286Sobrien      abort ();
288090286Sobrien    }
288190286Sobrien}
288290286Sobrien  [(set_attr "type" "multi")
288390286Sobrien   (set_attr "mode" "DF,SI,DF")])
288418334Speter
288590286Sobrien;; %%% Kill this when call knows how to work this out.
288652296Sobrien(define_split
288752296Sobrien  [(set (match_operand:DF 0 "push_operand" "")
288890286Sobrien	(match_operand:DF 1 "register_operand" ""))]
288990286Sobrien  "!TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
289090286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
289190286Sobrien   (set (mem:DF (reg:SI 7)) (match_dup 1))]
289252296Sobrien  "")
289350650Sobrien
289490286Sobrien(define_split
289590286Sobrien  [(set (match_operand:DF 0 "push_operand" "")
289690286Sobrien	(match_operand:DF 1 "register_operand" ""))]
289790286Sobrien  "TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
289890286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
289990286Sobrien   (set (mem:DF (reg:DI 7)) (match_dup 1))]
290090286Sobrien  "")
290190286Sobrien
290290286Sobrien(define_split
290390286Sobrien  [(set (match_operand:DF 0 "push_operand" "")
290450650Sobrien	(match_operand:DF 1 "general_operand" ""))]
290590286Sobrien  "reload_completed"
290690286Sobrien  [(const_int 0)]
290790286Sobrien  "ix86_split_long_move (operands); DONE;")
290890286Sobrien
290990286Sobrien;; Moving is usually shorter when only FP registers are used. This separate
291090286Sobrien;; movdf pattern avoids the use of integer registers for FP operations
291190286Sobrien;; when optimizing for size.
291290286Sobrien
291390286Sobrien(define_insn "*movdf_nointeger"
291490286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
291590286Sobrien	(match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,H,Y#f,YHm#f,Y#f"))]
291690286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
291790286Sobrien   && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
291890286Sobrien   && (reload_in_progress || reload_completed
291990286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
292090286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
292190286Sobrien       || memory_operand (operands[0], DFmode))" 
292218334Speter{
292390286Sobrien  switch (which_alternative)
292418334Speter    {
292590286Sobrien    case 0:
292690286Sobrien      if (REG_P (operands[1])
292790286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
292890286Sobrien        return "fstp\t%y0";
292990286Sobrien      else if (STACK_TOP_P (operands[0]))
293090286Sobrien        return "fld%z1\t%y1";
293190286Sobrien      else
293290286Sobrien        return "fst\t%y0";
293318334Speter
293490286Sobrien    case 1:
293590286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
293690286Sobrien        return "fstp%z0\t%y0";
293790286Sobrien      else
293890286Sobrien        return "fst%z0\t%y0";
293918334Speter
294090286Sobrien    case 2:
294190286Sobrien      switch (standard_80387_constant_p (operands[1]))
294290286Sobrien        {
294390286Sobrien        case 1:
294490286Sobrien	  return "fldz";
294590286Sobrien	case 2:
294690286Sobrien	  return "fld1";
294790286Sobrien	}
294890286Sobrien      abort();
294918334Speter
295090286Sobrien    case 3:
295190286Sobrien    case 4:
295290286Sobrien      return "#";
295390286Sobrien    case 5:
295490286Sobrien      return "pxor\t%0, %0";
295590286Sobrien    case 6:
295690286Sobrien      if (TARGET_PARTIAL_REG_DEPENDENCY)
295790286Sobrien	return "movapd\t{%1, %0|%0, %1}";
295890286Sobrien      else
295990286Sobrien	return "movsd\t{%1, %0|%0, %1}";
296090286Sobrien    case 7:
296190286Sobrien    case 8:
296290286Sobrien        return "movsd\t{%1, %0|%0, %1}";
296318334Speter
296490286Sobrien    default:
296590286Sobrien      abort();
296618334Speter    }
296790286Sobrien}
296890286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
296990286Sobrien   (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
297018334Speter
297190286Sobrien(define_insn "*movdf_integer"
297290286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
297390286Sobrien	(match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,H,Y#rf,Ym#rf,Y#rf"))]
297490286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
297590286Sobrien   && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
297690286Sobrien   && (reload_in_progress || reload_completed
297790286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
297890286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
297990286Sobrien       || memory_operand (operands[0], DFmode))" 
298090286Sobrien{
298190286Sobrien  switch (which_alternative)
298218334Speter    {
298390286Sobrien    case 0:
298490286Sobrien      if (REG_P (operands[1])
298590286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
298690286Sobrien        return "fstp\t%y0";
298790286Sobrien      else if (STACK_TOP_P (operands[0]))
298890286Sobrien        return "fld%z1\t%y1";
298918334Speter      else
299090286Sobrien        return "fst\t%y0";
299118334Speter
299290286Sobrien    case 1:
299390286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
299490286Sobrien        return "fstp%z0\t%y0";
299590286Sobrien      else
299690286Sobrien        return "fst%z0\t%y0";
299718334Speter
299890286Sobrien    case 2:
299990286Sobrien      switch (standard_80387_constant_p (operands[1]))
300090286Sobrien        {
300190286Sobrien        case 1:
300290286Sobrien	  return "fldz";
300390286Sobrien	case 2:
300490286Sobrien	  return "fld1";
300590286Sobrien	}
300690286Sobrien      abort();
300718334Speter
300890286Sobrien    case 3:
300990286Sobrien    case 4:
301090286Sobrien      return "#";
301118334Speter
301290286Sobrien    case 5:
301390286Sobrien      return "pxor\t%0, %0";
301490286Sobrien    case 6:
301590286Sobrien      if (TARGET_PARTIAL_REG_DEPENDENCY)
301690286Sobrien	return "movapd\t{%1, %0|%0, %1}";
301790286Sobrien      else
301890286Sobrien	return "movsd\t{%1, %0|%0, %1}";
301990286Sobrien    case 7:
302090286Sobrien    case 8:
302190286Sobrien      return "movsd\t{%1, %0|%0, %1}";
302218334Speter
302390286Sobrien    default:
302490286Sobrien      abort();
302590286Sobrien    }
302690286Sobrien}
302790286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
302890286Sobrien   (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
302918334Speter
303090286Sobrien(define_split
303190286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "")
303290286Sobrien	(match_operand:DF 1 "general_operand" ""))]
303390286Sobrien  "reload_completed
303490286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
303590286Sobrien   && ! (ANY_FP_REG_P (operands[0]) || 
303690286Sobrien	 (GET_CODE (operands[0]) == SUBREG
303790286Sobrien	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
303890286Sobrien   && ! (ANY_FP_REG_P (operands[1]) || 
303990286Sobrien	 (GET_CODE (operands[1]) == SUBREG
304090286Sobrien	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
304190286Sobrien  [(const_int 0)]
304290286Sobrien  "ix86_split_long_move (operands); DONE;")
304350650Sobrien
304490286Sobrien(define_insn "*swapdf"
304590286Sobrien  [(set (match_operand:DF 0 "register_operand" "+f")
304690286Sobrien	(match_operand:DF 1 "register_operand" "+f"))
304718334Speter   (set (match_dup 1)
304818334Speter	(match_dup 0))]
304990286Sobrien  "reload_completed || !TARGET_SSE2"
305018334Speter{
305118334Speter  if (STACK_TOP_P (operands[0]))
305290286Sobrien    return "fxch\t%1";
305318334Speter  else
305490286Sobrien    return "fxch\t%0";
305590286Sobrien}
305690286Sobrien  [(set_attr "type" "fxch")
305790286Sobrien   (set_attr "mode" "DF")])
305818334Speter
305990286Sobrien(define_expand "movxf"
306090286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "")
306190286Sobrien	(match_operand:XF 1 "general_operand" ""))]
306290286Sobrien  "!TARGET_64BIT"
306390286Sobrien  "ix86_expand_move (XFmode, operands); DONE;")
306490286Sobrien
306590286Sobrien(define_expand "movtf"
306690286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "")
306790286Sobrien	(match_operand:TF 1 "general_operand" ""))]
306890286Sobrien  ""
306990286Sobrien  "ix86_expand_move (TFmode, operands); DONE;")
307090286Sobrien
307190286Sobrien;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
307290286Sobrien;; Size of pushdf using integer insturctions is 3+3*memory operand size
307390286Sobrien;; Pushing using integer instructions is longer except for constants
307490286Sobrien;; and direct memory references.
307590286Sobrien;; (assuming that any given constant is pushed only once, but this ought to be
307690286Sobrien;;  handled elsewhere).
307790286Sobrien
307890286Sobrien(define_insn "*pushxf_nointeger"
307990286Sobrien  [(set (match_operand:XF 0 "push_operand" "=X,X,X")
308090286Sobrien	(match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
308190286Sobrien  "!TARGET_64BIT && optimize_size"
308218334Speter{
308390286Sobrien  switch (which_alternative)
308418334Speter    {
308590286Sobrien    case 0:
308690286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
308790286Sobrien      operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
308890286Sobrien      operands[2] = stack_pointer_rtx;
308990286Sobrien      operands[3] = GEN_INT (12);
309090286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
309190286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
309290286Sobrien      else
309390286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
309418334Speter
309590286Sobrien    case 1:
309690286Sobrien    case 2:
309790286Sobrien      return "#";
309818334Speter
309990286Sobrien    default:
310090286Sobrien      abort ();
310190286Sobrien    }
310290286Sobrien}
310390286Sobrien  [(set_attr "type" "multi")
310490286Sobrien   (set_attr "mode" "XF,SI,SI")])
310550650Sobrien
310690286Sobrien(define_insn "*pushtf_nointeger"
310790286Sobrien  [(set (match_operand:TF 0 "push_operand" "=<,<,<")
310890286Sobrien	(match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
310990286Sobrien  "optimize_size"
311090286Sobrien{
311190286Sobrien  switch (which_alternative)
311290286Sobrien    {
311390286Sobrien    case 0:
311490286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
311590286Sobrien      operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
311690286Sobrien      operands[2] = stack_pointer_rtx;
311790286Sobrien      operands[3] = GEN_INT (16);
311890286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
311990286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
312090286Sobrien      else
312190286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
312218334Speter
312390286Sobrien    case 1:
312490286Sobrien    case 2:
312590286Sobrien      return "#";
312690286Sobrien
312790286Sobrien    default:
312890286Sobrien      abort ();
312918334Speter    }
313090286Sobrien}
313190286Sobrien  [(set_attr "type" "multi")
313290286Sobrien   (set_attr "mode" "XF,SI,SI")])
313350650Sobrien
313490286Sobrien(define_insn "*pushxf_integer"
313590286Sobrien  [(set (match_operand:XF 0 "push_operand" "=<,<")
313690286Sobrien	(match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
313790286Sobrien  "!TARGET_64BIT && !optimize_size"
313890286Sobrien{
313990286Sobrien  switch (which_alternative)
314090286Sobrien    {
314190286Sobrien    case 0:
314290286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
314390286Sobrien      operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
314490286Sobrien      operands[2] = stack_pointer_rtx;
314590286Sobrien      operands[3] = GEN_INT (12);
314690286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
314790286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
314890286Sobrien      else
314990286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
315050650Sobrien
315190286Sobrien    case 1:
315290286Sobrien      return "#";
315318334Speter
315490286Sobrien    default:
315590286Sobrien      abort ();
315690286Sobrien    }
315790286Sobrien}
315890286Sobrien  [(set_attr "type" "multi")
315990286Sobrien   (set_attr "mode" "XF,SI")])
316090286Sobrien
316190286Sobrien(define_insn "*pushtf_integer"
316290286Sobrien  [(set (match_operand:TF 0 "push_operand" "=<,<")
316390286Sobrien	(match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
316490286Sobrien  "!optimize_size"
316590286Sobrien{
316690286Sobrien  switch (which_alternative)
316790286Sobrien    {
316890286Sobrien    case 0:
316990286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
317090286Sobrien      operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
317190286Sobrien      operands[2] = stack_pointer_rtx;
317290286Sobrien      operands[3] = GEN_INT (16);
317390286Sobrien      if (TARGET_64BIT)
317490286Sobrien	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
317590286Sobrien	  return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
317690286Sobrien	else
317790286Sobrien	  return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
317890286Sobrien      else
317990286Sobrien	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
318090286Sobrien	  return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
318190286Sobrien	else
318290286Sobrien	  return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
318390286Sobrien
318490286Sobrien    case 1:
318590286Sobrien      return "#";
318690286Sobrien
318790286Sobrien    default:
318890286Sobrien      abort ();
318990286Sobrien    }
319090286Sobrien}
319190286Sobrien  [(set_attr "type" "multi")
319290286Sobrien   (set_attr "mode" "XF,SI")])
319390286Sobrien
319452296Sobrien(define_split
319590286Sobrien  [(set (match_operand 0 "push_operand" "")
319690286Sobrien	(match_operand 1 "general_operand" ""))]
319790286Sobrien  "reload_completed
319890286Sobrien   && (GET_MODE (operands[0]) == XFmode
319990286Sobrien       || GET_MODE (operands[0]) == TFmode
320090286Sobrien       || GET_MODE (operands[0]) == DFmode)
320190286Sobrien   && (!REG_P (operands[1]) || !ANY_FP_REGNO_P (REGNO (operands[1])))"
320290286Sobrien  [(const_int 0)]
320390286Sobrien  "ix86_split_long_move (operands); DONE;")
320490286Sobrien
320590286Sobrien(define_split
320652296Sobrien  [(set (match_operand:XF 0 "push_operand" "")
320790286Sobrien	(match_operand:XF 1 "register_operand" ""))]
320890286Sobrien  "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
320990286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
321090286Sobrien   (set (mem:XF (reg:SI 7)) (match_dup 1))])
321150650Sobrien
321290286Sobrien(define_split
321390286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
321490286Sobrien	(match_operand:TF 1 "register_operand" ""))]
321590286Sobrien  "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
321690286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
321790286Sobrien   (set (mem:TF (reg:SI 7)) (match_dup 1))])
321890286Sobrien
321990286Sobrien(define_split
322090286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
322190286Sobrien	(match_operand:TF 1 "register_operand" ""))]
322290286Sobrien  "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
322390286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
322490286Sobrien   (set (mem:TF (reg:DI 7)) (match_dup 1))])
322590286Sobrien
322690286Sobrien;; Do not use integer registers when optimizing for size
322790286Sobrien(define_insn "*movxf_nointeger"
322890286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
322990286Sobrien	(match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
323090286Sobrien  "!TARGET_64BIT
323190286Sobrien   && optimize_size
323290286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
323390286Sobrien   && (reload_in_progress || reload_completed
323490286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
323590286Sobrien       || memory_operand (operands[0], XFmode))" 
323618334Speter{
323790286Sobrien  switch (which_alternative)
323818334Speter    {
323990286Sobrien    case 0:
324090286Sobrien      if (REG_P (operands[1])
324190286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
324290286Sobrien        return "fstp\t%y0";
324390286Sobrien      else if (STACK_TOP_P (operands[0]))
324490286Sobrien        return "fld%z1\t%y1";
324590286Sobrien      else
324690286Sobrien        return "fst\t%y0";
324790286Sobrien
324890286Sobrien    case 1:
324990286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
325090286Sobrien	 we need one, follow the store with a load.  */
325190286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
325290286Sobrien        return "fstp%z0\t%y0\;fld%z0\t%y0";
325390286Sobrien      else
325490286Sobrien        return "fstp%z0\t%y0";
325590286Sobrien
325690286Sobrien    case 2:
325790286Sobrien      switch (standard_80387_constant_p (operands[1]))
325890286Sobrien        {
325990286Sobrien        case 1:
326090286Sobrien	  return "fldz";
326190286Sobrien	case 2:
326290286Sobrien	  return "fld1";
326390286Sobrien	}
326490286Sobrien      break;
326590286Sobrien
326690286Sobrien    case 3: case 4:
326790286Sobrien      return "#";
326850650Sobrien    }
326990286Sobrien  abort();
327090286Sobrien}
327190286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
327290286Sobrien   (set_attr "mode" "XF,XF,XF,SI,SI")])
327318334Speter
327490286Sobrien(define_insn "*movtf_nointeger"
327590286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
327690286Sobrien	(match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
327790286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
327890286Sobrien   && optimize_size
327990286Sobrien   && (reload_in_progress || reload_completed
328090286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
328190286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
328290286Sobrien       || memory_operand (operands[0], TFmode))" 
328390286Sobrien{
328490286Sobrien  switch (which_alternative)
328550650Sobrien    {
328690286Sobrien    case 0:
328790286Sobrien      if (REG_P (operands[1])
328890286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
328990286Sobrien        return "fstp\t%y0";
329090286Sobrien      else if (STACK_TOP_P (operands[0]))
329190286Sobrien        return "fld%z1\t%y1";
329290286Sobrien      else
329390286Sobrien        return "fst\t%y0";
329418334Speter
329590286Sobrien    case 1:
329690286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
329790286Sobrien	 we need one, follow the store with a load.  */
329890286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
329990286Sobrien        return "fstp%z0\t%y0\;fld%z0\t%y0";
330090286Sobrien      else
330190286Sobrien        return "fstp%z0\t%y0";
330218334Speter
330390286Sobrien    case 2:
330490286Sobrien      switch (standard_80387_constant_p (operands[1]))
330590286Sobrien        {
330690286Sobrien        case 1:
330790286Sobrien	  return "fldz";
330890286Sobrien	case 2:
330990286Sobrien	  return "fld1";
331090286Sobrien	}
331190286Sobrien      break;
331218334Speter
331390286Sobrien    case 3: case 4:
331490286Sobrien      return "#";
331590286Sobrien    }
331690286Sobrien  abort();
331790286Sobrien}
331890286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
331990286Sobrien   (set_attr "mode" "XF,XF,XF,SI,SI")])
332018334Speter
332190286Sobrien(define_insn "*movxf_integer"
332290286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
332390286Sobrien	(match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
332490286Sobrien  "!TARGET_64BIT
332590286Sobrien   && !optimize_size
332690286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
332790286Sobrien   && (reload_in_progress || reload_completed
332890286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
332990286Sobrien       || memory_operand (operands[0], XFmode))" 
333090286Sobrien{
333190286Sobrien  switch (which_alternative)
333218334Speter    {
333390286Sobrien    case 0:
333490286Sobrien      if (REG_P (operands[1])
333590286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
333690286Sobrien        return "fstp\t%y0";
333790286Sobrien      else if (STACK_TOP_P (operands[0]))
333890286Sobrien        return "fld%z1\t%y1";
333918334Speter      else
334090286Sobrien        return "fst\t%y0";
334118334Speter
334290286Sobrien    case 1:
334390286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
334490286Sobrien	 we need one, follow the store with a load.  */
334590286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
334690286Sobrien        return "fstp%z0\t%y0\;fld%z0\t%y0";
334790286Sobrien      else
334890286Sobrien        return "fstp%z0\t%y0";
334918334Speter
335090286Sobrien    case 2:
335190286Sobrien      switch (standard_80387_constant_p (operands[1]))
335290286Sobrien        {
335390286Sobrien        case 1:
335490286Sobrien	  return "fldz";
335590286Sobrien	case 2:
335690286Sobrien	  return "fld1";
335790286Sobrien	}
335890286Sobrien      break;
335918334Speter
336090286Sobrien    case 3: case 4:
336190286Sobrien      return "#";
336218334Speter    }
336390286Sobrien  abort();
336490286Sobrien}
336590286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
336690286Sobrien   (set_attr "mode" "XF,XF,XF,SI,SI")])
336718334Speter
336890286Sobrien(define_insn "*movtf_integer"
336990286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
337090286Sobrien	(match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
337190286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
337290286Sobrien   && !optimize_size
337390286Sobrien   && (reload_in_progress || reload_completed
337490286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
337590286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
337690286Sobrien       || memory_operand (operands[0], TFmode))" 
337790286Sobrien{
337890286Sobrien  switch (which_alternative)
337990286Sobrien    {
338090286Sobrien    case 0:
338190286Sobrien      if (REG_P (operands[1])
338290286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
338390286Sobrien        return "fstp\t%y0";
338490286Sobrien      else if (STACK_TOP_P (operands[0]))
338590286Sobrien        return "fld%z1\t%y1";
338690286Sobrien      else
338790286Sobrien        return "fst\t%y0";
338818334Speter
338990286Sobrien    case 1:
339090286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
339190286Sobrien	 we need one, follow the store with a load.  */
339290286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
339390286Sobrien        return "fstp%z0\t%y0\;fld%z0\t%y0";
339490286Sobrien      else
339590286Sobrien        return "fstp%z0\t%y0";
339618334Speter
339790286Sobrien    case 2:
339890286Sobrien      switch (standard_80387_constant_p (operands[1]))
339990286Sobrien        {
340090286Sobrien        case 1:
340190286Sobrien	  return "fldz";
340290286Sobrien	case 2:
340390286Sobrien	  return "fld1";
340490286Sobrien	}
340590286Sobrien      break;
340618334Speter
340790286Sobrien    case 3: case 4:
340890286Sobrien      return "#";
340990286Sobrien    }
341090286Sobrien  abort();
341190286Sobrien}
341290286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
341390286Sobrien   (set_attr "mode" "XF,XF,XF,SI,SI")])
341418334Speter
341590286Sobrien(define_split
341690286Sobrien  [(set (match_operand 0 "nonimmediate_operand" "")
341790286Sobrien	(match_operand 1 "general_operand" ""))]
341890286Sobrien  "reload_completed
341990286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
342090286Sobrien   && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
342190286Sobrien   && ! (ANY_FP_REG_P (operands[0]) || 
342290286Sobrien	 (GET_CODE (operands[0]) == SUBREG
342390286Sobrien	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
342490286Sobrien   && ! (ANY_FP_REG_P (operands[1]) || 
342590286Sobrien	 (GET_CODE (operands[1]) == SUBREG
342690286Sobrien	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
342790286Sobrien  [(const_int 0)]
342890286Sobrien  "ix86_split_long_move (operands); DONE;")
342918334Speter
343090286Sobrien(define_split
343190286Sobrien  [(set (match_operand 0 "register_operand" "")
343290286Sobrien	(match_operand 1 "memory_operand" ""))]
343390286Sobrien  "reload_completed
343490286Sobrien   && GET_CODE (operands[1]) == MEM
343590286Sobrien   && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
343690286Sobrien       || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
343790286Sobrien   && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
343890286Sobrien   && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
343990286Sobrien   && (!(SSE_REG_P (operands[0]) || 
344090286Sobrien	 (GET_CODE (operands[0]) == SUBREG
344190286Sobrien	  && SSE_REG_P (SUBREG_REG (operands[0]))))
344290286Sobrien       || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
344390286Sobrien   && (!(FP_REG_P (operands[0]) || 
344490286Sobrien	 (GET_CODE (operands[0]) == SUBREG
344590286Sobrien	  && FP_REG_P (SUBREG_REG (operands[0]))))
344690286Sobrien       || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
344790286Sobrien  [(set (match_dup 0)
344890286Sobrien	(match_dup 1))]
344990286Sobrien  "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
345090286Sobrien
345190286Sobrien(define_insn "swapxf"
345290286Sobrien  [(set (match_operand:XF 0 "register_operand" "+f")
345390286Sobrien	(match_operand:XF 1 "register_operand" "+f"))
345418334Speter   (set (match_dup 1)
345518334Speter	(match_dup 0))]
345618334Speter  ""
345718334Speter{
345818334Speter  if (STACK_TOP_P (operands[0]))
345990286Sobrien    return "fxch\t%1";
346018334Speter  else
346190286Sobrien    return "fxch\t%0";
346290286Sobrien}
346390286Sobrien  [(set_attr "type" "fxch")
346490286Sobrien   (set_attr "mode" "XF")])
346518334Speter
346690286Sobrien(define_insn "swaptf"
346790286Sobrien  [(set (match_operand:TF 0 "register_operand" "+f")
346890286Sobrien	(match_operand:TF 1 "register_operand" "+f"))
346990286Sobrien   (set (match_dup 1)
347090286Sobrien	(match_dup 0))]
347118334Speter  ""
347218334Speter{
347390286Sobrien  if (STACK_TOP_P (operands[0]))
347490286Sobrien    return "fxch\t%1";
347590286Sobrien  else
347690286Sobrien    return "fxch\t%0";
347790286Sobrien}
347890286Sobrien  [(set_attr "type" "fxch")
347990286Sobrien   (set_attr "mode" "XF")])
348018334Speter
348190286Sobrien;; Zero extension instructions
348218334Speter
348352296Sobrien(define_expand "zero_extendhisi2"
348452296Sobrien  [(set (match_operand:SI 0 "register_operand" "")
348590286Sobrien     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
348652296Sobrien  ""
348790286Sobrien{
348890286Sobrien  if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
348918334Speter    {
349090286Sobrien      operands[1] = force_reg (HImode, operands[1]);
349190286Sobrien      emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
349290286Sobrien      DONE;
349318334Speter    }
349490286Sobrien})
349518334Speter
349690286Sobrien(define_insn "zero_extendhisi2_and"
349790286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
349890286Sobrien     (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
349990286Sobrien   (clobber (reg:CC 17))]
350090286Sobrien  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
350190286Sobrien  "#"
350290286Sobrien  [(set_attr "type" "alu1")
350390286Sobrien   (set_attr "mode" "SI")])
350450650Sobrien
350550650Sobrien(define_split
350650650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
350790286Sobrien	(zero_extend:SI (match_operand:HI 1 "register_operand" "")))
350890286Sobrien   (clobber (reg:CC 17))]
350990286Sobrien  "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
351090286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
351190286Sobrien	      (clobber (reg:CC 17))])]
351290286Sobrien  "")
351350650Sobrien
351490286Sobrien(define_insn "*zero_extendhisi2_movzwl"
351590286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
351690286Sobrien     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
351790286Sobrien  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
351890286Sobrien  "movz{wl|x}\t{%1, %0|%0, %1}"
351990286Sobrien  [(set_attr "type" "imovx")
352090286Sobrien   (set_attr "mode" "SI")])
352150650Sobrien
352252296Sobrien(define_expand "zero_extendqihi2"
352390286Sobrien  [(parallel
352490286Sobrien    [(set (match_operand:HI 0 "register_operand" "")
352590286Sobrien       (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
352690286Sobrien     (clobber (reg:CC 17))])]
352752296Sobrien  ""
352852296Sobrien  "")
352952296Sobrien
353090286Sobrien(define_insn "*zero_extendqihi2_and"
353190286Sobrien  [(set (match_operand:HI 0 "register_operand" "=r,?&q")
353290286Sobrien     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
353390286Sobrien   (clobber (reg:CC 17))]
353490286Sobrien  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
353590286Sobrien  "#"
353690286Sobrien  [(set_attr "type" "alu1")
353790286Sobrien   (set_attr "mode" "HI")])
353852296Sobrien
353990286Sobrien(define_insn "*zero_extendqihi2_movzbw_and"
354090286Sobrien  [(set (match_operand:HI 0 "register_operand" "=r,r")
354190286Sobrien     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
354290286Sobrien   (clobber (reg:CC 17))]
354390286Sobrien  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
354490286Sobrien  "#"
354590286Sobrien  [(set_attr "type" "imovx,alu1")
354690286Sobrien   (set_attr "mode" "HI")])
354752296Sobrien
354890286Sobrien(define_insn "*zero_extendqihi2_movzbw"
354990286Sobrien  [(set (match_operand:HI 0 "register_operand" "=r")
355090286Sobrien     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
355190286Sobrien  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
355290286Sobrien  "movz{bw|x}\t{%1, %0|%0, %1}"
355390286Sobrien  [(set_attr "type" "imovx")
355490286Sobrien   (set_attr "mode" "HI")])
355550650Sobrien
355690286Sobrien;; For the movzbw case strip only the clobber
355750650Sobrien(define_split
355850650Sobrien  [(set (match_operand:HI 0 "register_operand" "")
355990286Sobrien	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
356090286Sobrien   (clobber (reg:CC 17))]
356190286Sobrien  "reload_completed 
356290286Sobrien   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
356390286Sobrien   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
356490286Sobrien  [(set (match_operand:HI 0 "register_operand" "")
356590286Sobrien	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
356650650Sobrien
356790286Sobrien;; When source and destination does not overlap, clear destination
356890286Sobrien;; first and then do the movb
356950650Sobrien(define_split
357050650Sobrien  [(set (match_operand:HI 0 "register_operand" "")
357190286Sobrien	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
357290286Sobrien   (clobber (reg:CC 17))]
357390286Sobrien  "reload_completed
357490286Sobrien   && ANY_QI_REG_P (operands[0])
357590286Sobrien   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
357690286Sobrien   && !reg_overlap_mentioned_p (operands[0], operands[1])"
357790286Sobrien  [(set (match_dup 0) (const_int 0))
357890286Sobrien   (set (strict_low_part (match_dup 2)) (match_dup 1))]
357990286Sobrien  "operands[2] = gen_lowpart (QImode, operands[0]);")
358050650Sobrien
358190286Sobrien;; Rest is handled by single and.
358250650Sobrien(define_split
358350650Sobrien  [(set (match_operand:HI 0 "register_operand" "")
358490286Sobrien	(zero_extend:HI (match_operand:QI 1 "register_operand" "")))
358590286Sobrien   (clobber (reg:CC 17))]
358690286Sobrien  "reload_completed
358790286Sobrien   && true_regnum (operands[0]) == true_regnum (operands[1])"
358890286Sobrien  [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
358990286Sobrien	      (clobber (reg:CC 17))])]
359090286Sobrien  "")
359150650Sobrien
359252296Sobrien(define_expand "zero_extendqisi2"
359390286Sobrien  [(parallel
359490286Sobrien    [(set (match_operand:SI 0 "register_operand" "")
359590286Sobrien       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
359690286Sobrien     (clobber (reg:CC 17))])]
359752296Sobrien  ""
359852296Sobrien  "")
359952296Sobrien
360090286Sobrien(define_insn "*zero_extendqisi2_and"
360190286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,?&q")
360290286Sobrien     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
360390286Sobrien   (clobber (reg:CC 17))]
360490286Sobrien  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
360590286Sobrien  "#"
360690286Sobrien  [(set_attr "type" "alu1")
360790286Sobrien   (set_attr "mode" "SI")])
360852296Sobrien
360990286Sobrien(define_insn "*zero_extendqisi2_movzbw_and"
361090286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,r")
361190286Sobrien     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
361290286Sobrien   (clobber (reg:CC 17))]
361390286Sobrien  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
361490286Sobrien  "#"
361590286Sobrien  [(set_attr "type" "imovx,alu1")
361690286Sobrien   (set_attr "mode" "SI")])
361750650Sobrien
361890286Sobrien(define_insn "*zero_extendqisi2_movzbw"
361990286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
362090286Sobrien     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
362190286Sobrien  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
362290286Sobrien  "movz{bl|x}\t{%1, %0|%0, %1}"
362390286Sobrien  [(set_attr "type" "imovx")
362490286Sobrien   (set_attr "mode" "SI")])
362518334Speter
362690286Sobrien;; For the movzbl case strip only the clobber
362750650Sobrien(define_split
362850650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
362990286Sobrien	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
363090286Sobrien   (clobber (reg:CC 17))]
363190286Sobrien  "reload_completed 
363290286Sobrien   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
363390286Sobrien   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
363490286Sobrien  [(set (match_dup 0)
363590286Sobrien	(zero_extend:SI (match_dup 1)))])
363650650Sobrien
363790286Sobrien;; When source and destination does not overlap, clear destination
363890286Sobrien;; first and then do the movb
363950650Sobrien(define_split
364050650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
364190286Sobrien	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
364290286Sobrien   (clobber (reg:CC 17))]
364390286Sobrien  "reload_completed
364490286Sobrien   && ANY_QI_REG_P (operands[0])
364590286Sobrien   && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
364690286Sobrien   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
364790286Sobrien   && !reg_overlap_mentioned_p (operands[0], operands[1])"
364890286Sobrien  [(set (match_dup 0) (const_int 0))
364990286Sobrien   (set (strict_low_part (match_dup 2)) (match_dup 1))]
365090286Sobrien  "operands[2] = gen_lowpart (QImode, operands[0]);")
365150650Sobrien
365290286Sobrien;; Rest is handled by single and.
365350650Sobrien(define_split
365450650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
365590286Sobrien	(zero_extend:SI (match_operand:QI 1 "register_operand" "")))
365690286Sobrien   (clobber (reg:CC 17))]
365790286Sobrien  "reload_completed
365890286Sobrien   && true_regnum (operands[0]) == true_regnum (operands[1])"
365990286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
366090286Sobrien	      (clobber (reg:CC 17))])]
366190286Sobrien  "")
366250650Sobrien
366390286Sobrien;; %%% Kill me once multi-word ops are sane.
366490286Sobrien(define_expand "zero_extendsidi2"
366590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
366690286Sobrien     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
366718334Speter  ""
366890286Sobrien  "if (!TARGET_64BIT)
366990286Sobrien     {
367090286Sobrien       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
367190286Sobrien       DONE;
367290286Sobrien     }
367390286Sobrien  ")
367450650Sobrien
367590286Sobrien(define_insn "zero_extendsidi2_32"
367690286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
367790286Sobrien	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
367890286Sobrien   (clobber (reg:CC 17))]
367990286Sobrien  "!TARGET_64BIT"
368090286Sobrien  "#"
368190286Sobrien  [(set_attr "mode" "SI")])
368290286Sobrien
368390286Sobrien(define_insn "zero_extendsidi2_rex64"
368490286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
368590286Sobrien     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
368690286Sobrien  "TARGET_64BIT"
368790286Sobrien  "@
368890286Sobrien   mov\t{%k1, %k0|%k0, %k1}
368990286Sobrien   #"
369090286Sobrien  [(set_attr "type" "imovx,imov")
369190286Sobrien   (set_attr "mode" "SI,DI")])
369290286Sobrien
369390286Sobrien(define_split
369490286Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
369590286Sobrien     (zero_extend:DI (match_dup 0)))]
369690286Sobrien  "TARGET_64BIT"
369790286Sobrien  [(set (match_dup 4) (const_int 0))]
369890286Sobrien  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
369990286Sobrien
370052296Sobrien(define_split 
370152296Sobrien  [(set (match_operand:DI 0 "register_operand" "")
370290286Sobrien	(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
370390286Sobrien   (clobber (reg:CC 17))]
370490286Sobrien  "!TARGET_64BIT && reload_completed
370590286Sobrien   && true_regnum (operands[0]) == true_regnum (operands[1])"
370652296Sobrien  [(set (match_dup 4) (const_int 0))]
370752296Sobrien  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
370850650Sobrien
370952296Sobrien(define_split 
371052296Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
371190286Sobrien	(zero_extend:DI (match_operand:SI 1 "general_operand" "")))
371290286Sobrien   (clobber (reg:CC 17))]
371390286Sobrien  "!TARGET_64BIT && reload_completed"
371452296Sobrien  [(set (match_dup 3) (match_dup 1))
371552296Sobrien   (set (match_dup 4) (const_int 0))]
371652296Sobrien  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
371790286Sobrien
371890286Sobrien(define_insn "zero_extendhidi2"
371990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
372090286Sobrien     (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
372190286Sobrien  "TARGET_64BIT"
372290286Sobrien  "@
372390286Sobrien   movz{wl|x}\t{%1, %k0|%k0, %1} 
372490286Sobrien   movz{wq|x}\t{%1, %0|%0, %1}"
372590286Sobrien  [(set_attr "type" "imovx")
372690286Sobrien   (set_attr "mode" "SI,DI")])
372790286Sobrien
372890286Sobrien(define_insn "zero_extendqidi2"
372990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
373090286Sobrien     (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
373190286Sobrien  "TARGET_64BIT"
373290286Sobrien  "@
373390286Sobrien   movz{bl|x}\t{%1, %k0|%k0, %1} 
373490286Sobrien   movz{bq|x}\t{%1, %0|%0, %1}"
373590286Sobrien  [(set_attr "type" "imovx")
373690286Sobrien   (set_attr "mode" "SI,DI")])
373718334Speter
373890286Sobrien;; Sign extension instructions
373918334Speter
374090286Sobrien(define_expand "extendsidi2"
374190286Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
374290286Sobrien		   (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
374390286Sobrien	      (clobber (reg:CC 17))
374490286Sobrien	      (clobber (match_scratch:SI 2 ""))])]
374590286Sobrien  ""
374690286Sobrien{
374790286Sobrien  if (TARGET_64BIT)
374890286Sobrien    {
374990286Sobrien      emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
375090286Sobrien      DONE;
375190286Sobrien    }
375290286Sobrien})
375390286Sobrien
375490286Sobrien(define_insn "*extendsidi2_1"
375590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
375690286Sobrien	(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
375790286Sobrien   (clobber (reg:CC 17))
375852296Sobrien   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
375990286Sobrien  "!TARGET_64BIT"
376052296Sobrien  "#")
376152296Sobrien
376290286Sobrien(define_insn "extendsidi2_rex64"
376390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=*a,r")
376490286Sobrien	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
376590286Sobrien  "TARGET_64BIT"
376690286Sobrien  "@
376790286Sobrien   {cltq|cdqe}
376890286Sobrien   movs{lq|x}\t{%1,%0|%0, %1}"
376990286Sobrien  [(set_attr "type" "imovx")
377090286Sobrien   (set_attr "mode" "DI")
377190286Sobrien   (set_attr "prefix_0f" "0")
377290286Sobrien   (set_attr "modrm" "0,1")])
377390286Sobrien
377490286Sobrien(define_insn "extendhidi2"
377590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
377690286Sobrien	(sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
377790286Sobrien  "TARGET_64BIT"
377890286Sobrien  "movs{wq|x}\t{%1,%0|%0, %1}"
377990286Sobrien  [(set_attr "type" "imovx")
378090286Sobrien   (set_attr "mode" "DI")])
378190286Sobrien
378290286Sobrien(define_insn "extendqidi2"
378390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
378490286Sobrien	(sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
378590286Sobrien  "TARGET_64BIT"
378690286Sobrien  "movs{bq|x}\t{%1,%0|%0, %1}"
378790286Sobrien   [(set_attr "type" "imovx")
378890286Sobrien    (set_attr "mode" "DI")])
378990286Sobrien
379052296Sobrien;; Extend to memory case when source register does die.
379152296Sobrien(define_split 
379252296Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
379352296Sobrien	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
379490286Sobrien   (clobber (reg:CC 17))
379552296Sobrien   (clobber (match_operand:SI 2 "register_operand" ""))]
379690286Sobrien  "(reload_completed
379752296Sobrien    && dead_or_set_p (insn, operands[1])
379852296Sobrien    && !reg_mentioned_p (operands[1], operands[0]))"
379952296Sobrien  [(set (match_dup 3) (match_dup 1))
380090286Sobrien   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
380190286Sobrien	      (clobber (reg:CC 17))])
380252296Sobrien   (set (match_dup 4) (match_dup 1))]
380352296Sobrien  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
380452296Sobrien
380552296Sobrien;; Extend to memory case when source register does not die.
380652296Sobrien(define_split 
380752296Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
380852296Sobrien	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
380990286Sobrien   (clobber (reg:CC 17))
381052296Sobrien   (clobber (match_operand:SI 2 "register_operand" ""))]
381190286Sobrien  "reload_completed"
381252296Sobrien  [(const_int 0)]
381318334Speter{
381452296Sobrien  split_di (&operands[0], 1, &operands[3], &operands[4]);
381552296Sobrien
381652296Sobrien  emit_move_insn (operands[3], operands[1]);
381752296Sobrien
381852296Sobrien  /* Generate a cltd if possible and doing so it profitable.  */
381952296Sobrien  if (true_regnum (operands[1]) == 0
382052296Sobrien      && true_regnum (operands[2]) == 1
382190286Sobrien      && (optimize_size || TARGET_USE_CLTD))
382218334Speter    {
382390286Sobrien      emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
382418334Speter    }
382552296Sobrien  else
382652296Sobrien    {
382752296Sobrien      emit_move_insn (operands[2], operands[1]);
382890286Sobrien      emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
382952296Sobrien    }
383052296Sobrien  emit_move_insn (operands[4], operands[2]);
383152296Sobrien  DONE;
383290286Sobrien})
383318334Speter
383452296Sobrien;; Extend to register case.  Optimize case where source and destination
383552296Sobrien;; registers match and cases where we can use cltd.
383652296Sobrien(define_split 
383752296Sobrien  [(set (match_operand:DI 0 "register_operand" "")
383852296Sobrien	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
383990286Sobrien   (clobber (reg:CC 17))
384052296Sobrien   (clobber (match_scratch:SI 2 ""))]
384152296Sobrien  "reload_completed"
384252296Sobrien  [(const_int 0)]
384352296Sobrien{
384452296Sobrien  split_di (&operands[0], 1, &operands[3], &operands[4]);
384518334Speter
384652296Sobrien  if (true_regnum (operands[3]) != true_regnum (operands[1]))
384752296Sobrien    emit_move_insn (operands[3], operands[1]);
384852296Sobrien
384952296Sobrien  /* Generate a cltd if possible and doing so it profitable.  */
385052296Sobrien  if (true_regnum (operands[3]) == 0
385190286Sobrien      && (optimize_size || TARGET_USE_CLTD))
385252296Sobrien    {
385390286Sobrien      emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
385452296Sobrien      DONE;
385552296Sobrien    }
385652296Sobrien
385752296Sobrien  if (true_regnum (operands[4]) != true_regnum (operands[1]))
385852296Sobrien    emit_move_insn (operands[4], operands[1]);
385952296Sobrien
386090286Sobrien  emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
386152296Sobrien  DONE;
386290286Sobrien})
386318334Speter
386418334Speter(define_insn "extendhisi2"
386590286Sobrien  [(set (match_operand:SI 0 "register_operand" "=*a,r")
386690286Sobrien	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
386718334Speter  ""
386818334Speter{
386990286Sobrien  switch (get_attr_prefix_0f (insn))
387090286Sobrien    {
387190286Sobrien    case 0:
387290286Sobrien      return "{cwtl|cwde}";
387390286Sobrien    default:
387490286Sobrien      return "movs{wl|x}\t{%1,%0|%0, %1}";
387590286Sobrien    }
387690286Sobrien}
387790286Sobrien  [(set_attr "type" "imovx")
387890286Sobrien   (set_attr "mode" "SI")
387990286Sobrien   (set (attr "prefix_0f")
388090286Sobrien     ;; movsx is short decodable while cwtl is vector decoded.
388190286Sobrien     (if_then_else (and (eq_attr "cpu" "!k6")
388290286Sobrien			(eq_attr "alternative" "0"))
388390286Sobrien	(const_string "0")
388490286Sobrien	(const_string "1")))
388590286Sobrien   (set (attr "modrm")
388690286Sobrien     (if_then_else (eq_attr "prefix_0f" "0")
388790286Sobrien	(const_string "0")
388890286Sobrien	(const_string "1")))])
388918334Speter
389090286Sobrien(define_insn "*extendhisi2_zext"
389190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=*a,r")
389290286Sobrien	(zero_extend:DI
389390286Sobrien	  (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
389490286Sobrien  "TARGET_64BIT"
389590286Sobrien{
389690286Sobrien  switch (get_attr_prefix_0f (insn))
389790286Sobrien    {
389890286Sobrien    case 0:
389990286Sobrien      return "{cwtl|cwde}";
390090286Sobrien    default:
390190286Sobrien      return "movs{wl|x}\t{%1,%k0|%k0, %1}";
390290286Sobrien    }
390390286Sobrien}
390490286Sobrien  [(set_attr "type" "imovx")
390590286Sobrien   (set_attr "mode" "SI")
390690286Sobrien   (set (attr "prefix_0f")
390790286Sobrien     ;; movsx is short decodable while cwtl is vector decoded.
390890286Sobrien     (if_then_else (and (eq_attr "cpu" "!k6")
390990286Sobrien			(eq_attr "alternative" "0"))
391090286Sobrien	(const_string "0")
391190286Sobrien	(const_string "1")))
391290286Sobrien   (set (attr "modrm")
391390286Sobrien     (if_then_else (eq_attr "prefix_0f" "0")
391490286Sobrien	(const_string "0")
391590286Sobrien	(const_string "1")))])
391618334Speter
391718334Speter(define_insn "extendqihi2"
391890286Sobrien  [(set (match_operand:HI 0 "register_operand" "=*a,r")
391990286Sobrien	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
392018334Speter  ""
392118334Speter{
392290286Sobrien  switch (get_attr_prefix_0f (insn))
392390286Sobrien    {
392490286Sobrien    case 0:
392590286Sobrien      return "{cbtw|cbw}";
392690286Sobrien    default:
392790286Sobrien      return "movs{bw|x}\t{%1,%0|%0, %1}";
392890286Sobrien    }
392990286Sobrien}
393090286Sobrien  [(set_attr "type" "imovx")
393190286Sobrien   (set_attr "mode" "HI")
393290286Sobrien   (set (attr "prefix_0f")
393390286Sobrien     ;; movsx is short decodable while cwtl is vector decoded.
393490286Sobrien     (if_then_else (and (eq_attr "cpu" "!k6")
393590286Sobrien			(eq_attr "alternative" "0"))
393690286Sobrien	(const_string "0")
393790286Sobrien	(const_string "1")))
393890286Sobrien   (set (attr "modrm")
393990286Sobrien     (if_then_else (eq_attr "prefix_0f" "0")
394090286Sobrien	(const_string "0")
394190286Sobrien	(const_string "1")))])
394218334Speter
394318334Speter(define_insn "extendqisi2"
394450650Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
394550650Sobrien	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
394618334Speter  ""
394790286Sobrien  "movs{bl|x}\t{%1,%0|%0, %1}"
394890286Sobrien   [(set_attr "type" "imovx")
394990286Sobrien    (set_attr "mode" "SI")])
395050650Sobrien
395190286Sobrien(define_insn "*extendqisi2_zext"
395290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
395390286Sobrien	(zero_extend:DI
395490286Sobrien	  (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
395590286Sobrien  "TARGET_64BIT"
395690286Sobrien  "movs{bl|x}\t{%1,%k0|%k0, %1}"
395790286Sobrien   [(set_attr "type" "imovx")
395890286Sobrien    (set_attr "mode" "SI")])
395918334Speter
396090286Sobrien;; Conversions between float and double.
396150650Sobrien
396290286Sobrien;; These are all no-ops in the model used for the 80387.  So just
396390286Sobrien;; emit moves.
396450650Sobrien
396590286Sobrien;; %%% Kill these when call knows how to work out a DFmode push earlier. 
396690286Sobrien(define_insn "*dummy_extendsfdf2"
396790286Sobrien  [(set (match_operand:DF 0 "push_operand" "=<")
396890286Sobrien	(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
396990286Sobrien  "0"
397090286Sobrien  "#")
397150650Sobrien
397290286Sobrien(define_split
397390286Sobrien  [(set (match_operand:DF 0 "push_operand" "")
397490286Sobrien	(float_extend:DF (match_operand:SF 1 "register_operand" "")))]
397590286Sobrien  "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
397690286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
397790286Sobrien   (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
397850650Sobrien
397990286Sobrien(define_split
398090286Sobrien  [(set (match_operand:DF 0 "push_operand" "")
398190286Sobrien	(float_extend:DF (match_operand:SF 1 "register_operand" "")))]
398290286Sobrien  "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
398390286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
398490286Sobrien   (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
398550650Sobrien
398690286Sobrien(define_insn "*dummy_extendsfxf2"
398790286Sobrien  [(set (match_operand:XF 0 "push_operand" "=<")
398890286Sobrien	(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
398990286Sobrien  "0"
399090286Sobrien  "#")
399150650Sobrien
399290286Sobrien(define_split
399390286Sobrien  [(set (match_operand:XF 0 "push_operand" "")
399490286Sobrien	(float_extend:XF (match_operand:SF 1 "register_operand" "")))]
399590286Sobrien  "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
399690286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
399790286Sobrien   (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
399850650Sobrien
399990286Sobrien(define_insn "*dummy_extendsftf2"
400090286Sobrien  [(set (match_operand:TF 0 "push_operand" "=<")
400190286Sobrien	(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
400290286Sobrien  "0"
400390286Sobrien  "#")
400450650Sobrien
400590286Sobrien(define_split
400690286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
400790286Sobrien	(float_extend:TF (match_operand:SF 1 "register_operand" "")))]
400890286Sobrien  "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
400990286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
401090286Sobrien   (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
401150650Sobrien
401290286Sobrien(define_split
401390286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
401490286Sobrien	(float_extend:TF (match_operand:SF 1 "register_operand" "")))]
401590286Sobrien  "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
401690286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
401790286Sobrien   (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
401818334Speter
401990286Sobrien(define_insn "*dummy_extenddfxf2"
402090286Sobrien  [(set (match_operand:XF 0 "push_operand" "=<")
402190286Sobrien	(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
402290286Sobrien  "0"
402390286Sobrien  "#")
402452296Sobrien
402590286Sobrien(define_split
402690286Sobrien  [(set (match_operand:XF 0 "push_operand" "")
402790286Sobrien	(float_extend:XF (match_operand:DF 1 "register_operand" "")))]
402890286Sobrien  "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
402990286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
403090286Sobrien   (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
403152296Sobrien
403290286Sobrien(define_insn "*dummy_extenddftf2"
403390286Sobrien  [(set (match_operand:TF 0 "push_operand" "=<")
403490286Sobrien	(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
403590286Sobrien  "0"
403690286Sobrien  "#")
403718334Speter
403852296Sobrien(define_split
403990286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
404090286Sobrien	(float_extend:TF (match_operand:DF 1 "register_operand" "")))]
404190286Sobrien  "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
404290286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
404390286Sobrien   (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
404418334Speter
404552296Sobrien(define_split
404690286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
404790286Sobrien	(float_extend:TF (match_operand:DF 1 "register_operand" "")))]
404890286Sobrien  "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
404990286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
405090286Sobrien   (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
405118334Speter
405290286Sobrien(define_expand "extendsfdf2"
405352296Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "")
405490286Sobrien        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
405590286Sobrien  "TARGET_80387 || TARGET_SSE2"
405652296Sobrien{
405790286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
405890286Sobrien    operands[1] = force_reg (SFmode, operands[1]);
405990286Sobrien})
406018334Speter
406190286Sobrien(define_insn "*extendsfdf2_1"
406290286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
406390286Sobrien        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
406490286Sobrien  "(TARGET_80387 || TARGET_SSE2)
406590286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
406652296Sobrien{
406790286Sobrien  switch (which_alternative)
406890286Sobrien    {
406990286Sobrien    case 0:
407090286Sobrien      if (REG_P (operands[1])
407190286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
407290286Sobrien        return "fstp\t%y0";
407390286Sobrien      else if (STACK_TOP_P (operands[0]))
407490286Sobrien        return "fld%z1\t%y1";
407590286Sobrien      else
407690286Sobrien        return "fst\t%y0";
407752296Sobrien
407890286Sobrien    case 1:
407990286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
408090286Sobrien        return "fstp%z0\t%y0";
408118334Speter
408290286Sobrien      else
408390286Sobrien        return "fst%z0\t%y0";
408490286Sobrien    case 2:
408590286Sobrien      return "cvtss2sd\t{%1, %0|%0, %1}";
408618334Speter
408790286Sobrien    default:
408890286Sobrien      abort ();
408990286Sobrien    }
409090286Sobrien}
409190286Sobrien  [(set_attr "type" "fmov,fmov,sse")
409290286Sobrien   (set_attr "mode" "SF,XF,DF")])
409318334Speter
409490286Sobrien(define_insn "*extendsfdf2_1_sse_only"
409590286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
409690286Sobrien        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
409790286Sobrien  "!TARGET_80387 && TARGET_SSE2
409890286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
409990286Sobrien  "cvtss2sd\t{%1, %0|%0, %1}"
410090286Sobrien  [(set_attr "type" "sse")
410190286Sobrien   (set_attr "mode" "DF")])
410218334Speter
410390286Sobrien(define_expand "extendsfxf2"
410452296Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "")
410590286Sobrien        (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))]
410690286Sobrien  "!TARGET_64BIT && TARGET_80387"
410790286Sobrien{
410890286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
410990286Sobrien    operands[1] = force_reg (SFmode, operands[1]);
411090286Sobrien})
411118334Speter
411290286Sobrien(define_insn "*extendsfxf2_1"
411352296Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
411490286Sobrien        (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
411590286Sobrien  "!TARGET_64BIT && TARGET_80387
411690286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
411752296Sobrien{
411890286Sobrien  switch (which_alternative)
411990286Sobrien    {
412090286Sobrien    case 0:
412190286Sobrien      if (REG_P (operands[1])
412290286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
412390286Sobrien        return "fstp\t%y0";
412490286Sobrien      else if (STACK_TOP_P (operands[0]))
412590286Sobrien        return "fld%z1\t%y1";
412690286Sobrien      else
412790286Sobrien        return "fst\t%y0";
412818334Speter
412990286Sobrien    case 1:
413090286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
413190286Sobrien	 we need one, follow the store with a load.  */
413290286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
413390286Sobrien        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
413490286Sobrien      else
413590286Sobrien        return "fstp%z0\t%y0";
413690286Sobrien
413790286Sobrien    default:
413890286Sobrien      abort ();
413990286Sobrien    }
414090286Sobrien}
414190286Sobrien  [(set_attr "type" "fmov")
414290286Sobrien   (set_attr "mode" "SF,XF")])
414390286Sobrien
414490286Sobrien(define_expand "extendsftf2"
414590286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "")
414690286Sobrien        (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))]
414752296Sobrien  "TARGET_80387"
414852296Sobrien{
414952296Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
415052296Sobrien    operands[1] = force_reg (SFmode, operands[1]);
415190286Sobrien})
415252296Sobrien
415390286Sobrien(define_insn "*extendsftf2_1"
415490286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
415590286Sobrien        (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
415690286Sobrien  "TARGET_80387
415790286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
415818334Speter{
415990286Sobrien  switch (which_alternative)
416090286Sobrien    {
416190286Sobrien    case 0:
416290286Sobrien      if (REG_P (operands[1])
416390286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
416490286Sobrien        return "fstp\t%y0";
416590286Sobrien      else if (STACK_TOP_P (operands[0]))
416690286Sobrien        return "fld%z1\t%y1";
416790286Sobrien      else
416890286Sobrien        return "fst\t%y0";
416918334Speter
417090286Sobrien    case 1:
417190286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
417290286Sobrien	 we need one, follow the store with a load.  */
417390286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
417490286Sobrien        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
417590286Sobrien      else
417690286Sobrien        return "fstp%z0\t%y0";
417718334Speter
417890286Sobrien    default:
417990286Sobrien      abort ();
418090286Sobrien    }
418190286Sobrien}
418290286Sobrien  [(set_attr "type" "fmov")
418390286Sobrien   (set_attr "mode" "SF,XF")])
418418334Speter
418590286Sobrien(define_expand "extenddfxf2"
418652296Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "")
418790286Sobrien        (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))]
418890286Sobrien  "!TARGET_64BIT && TARGET_80387"
418990286Sobrien{
419090286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
419190286Sobrien    operands[1] = force_reg (DFmode, operands[1]);
419290286Sobrien})
419318334Speter
419490286Sobrien(define_insn "*extenddfxf2_1"
419552296Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
419690286Sobrien        (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
419790286Sobrien  "!TARGET_64BIT && TARGET_80387
419890286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
419952296Sobrien{
420090286Sobrien  switch (which_alternative)
420190286Sobrien    {
420290286Sobrien    case 0:
420390286Sobrien      if (REG_P (operands[1])
420490286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
420590286Sobrien        return "fstp\t%y0";
420690286Sobrien      else if (STACK_TOP_P (operands[0]))
420790286Sobrien        return "fld%z1\t%y1";
420890286Sobrien      else
420990286Sobrien        return "fst\t%y0";
421018334Speter
421190286Sobrien    case 1:
421290286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
421390286Sobrien	 we need one, follow the store with a load.  */
421490286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
421590286Sobrien        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
421690286Sobrien      else
421790286Sobrien        return "fstp%z0\t%y0";
421890286Sobrien
421990286Sobrien    default:
422090286Sobrien      abort ();
422190286Sobrien    }
422290286Sobrien}
422390286Sobrien  [(set_attr "type" "fmov")
422490286Sobrien   (set_attr "mode" "DF,XF")])
422590286Sobrien
422690286Sobrien(define_expand "extenddftf2"
422790286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "")
422890286Sobrien        (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))]
422990286Sobrien  "TARGET_80387"
423090286Sobrien{
423190286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
423290286Sobrien    operands[1] = force_reg (DFmode, operands[1]);
423390286Sobrien})
423490286Sobrien
423590286Sobrien(define_insn "*extenddftf2_1"
423690286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
423790286Sobrien        (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
423890286Sobrien  "TARGET_80387
423990286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
424090286Sobrien{
424190286Sobrien  switch (which_alternative)
424290286Sobrien    {
424390286Sobrien    case 0:
424490286Sobrien      if (REG_P (operands[1])
424590286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
424690286Sobrien        return "fstp\t%y0";
424790286Sobrien      else if (STACK_TOP_P (operands[0]))
424890286Sobrien        return "fld%z1\t%y1";
424990286Sobrien      else
425090286Sobrien        return "fst\t%y0";
425190286Sobrien
425290286Sobrien    case 1:
425390286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
425490286Sobrien	 we need one, follow the store with a load.  */
425590286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
425690286Sobrien        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
425790286Sobrien      else
425890286Sobrien        return "fstp%z0\t%y0";
425990286Sobrien
426090286Sobrien    default:
426190286Sobrien      abort ();
426290286Sobrien    }
426390286Sobrien}
426490286Sobrien  [(set_attr "type" "fmov")
426590286Sobrien   (set_attr "mode" "DF,XF")])
426690286Sobrien
426790286Sobrien;; %%% This seems bad bad news.
426890286Sobrien;; This cannot output into an f-reg because there is no way to be sure
426990286Sobrien;; of truncating in that case.  Otherwise this is just like a simple move
427090286Sobrien;; insn.  So we pretend we can output to a reg in order to get better
427190286Sobrien;; register preferencing, but we really use a stack slot.
427290286Sobrien
427318334Speter(define_expand "truncdfsf2"
427418334Speter  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
427518334Speter		   (float_truncate:SF
427618334Speter		    (match_operand:DF 1 "register_operand" "")))
427718334Speter	      (clobber (match_dup 2))])]
427890286Sobrien  "TARGET_80387 || TARGET_SSE2"
427918334Speter  "
428090286Sobrien   if (TARGET_80387)
428190286Sobrien     operands[2] = assign_386_stack_local (SFmode, 0);
428290286Sobrien   else
428390286Sobrien     {
428490286Sobrien	emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
428590286Sobrien	DONE;
428690286Sobrien     }
428790286Sobrien")
428890286Sobrien
428990286Sobrien(define_insn "*truncdfsf2_1"
429090286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
429190286Sobrien	(float_truncate:SF
429290286Sobrien	 (match_operand:DF 1 "register_operand" "f,f,f,f")))
429390286Sobrien   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
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    default:
430490286Sobrien      abort ();
430590286Sobrien    }
430690286Sobrien}
430790286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
430890286Sobrien   (set_attr "mode" "SF,SF,SF,SF")])
430918334Speter
431090286Sobrien(define_insn "*truncdfsf2_1_sse"
431190286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,Y")
431218334Speter	(float_truncate:SF
431390286Sobrien	 (match_operand:DF 1 "nonimmediate_operand" "f,f,f,f,mY")))
431490286Sobrien   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
431590286Sobrien  "TARGET_80387 && TARGET_SSE2"
431618334Speter{
431790286Sobrien  switch (which_alternative)
431890286Sobrien    {
431990286Sobrien    case 0:
432090286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
432190286Sobrien	return "fstp%z0\t%y0";
432290286Sobrien      else
432390286Sobrien	return "fst%z0\t%y0";
432490286Sobrien    case 4:
432590286Sobrien      return "cvtsd2ss\t{%1, %0|%0, %1}";
432690286Sobrien    default:
432790286Sobrien      abort ();
432890286Sobrien    }
432990286Sobrien}
433090286Sobrien  [(set_attr "type" "fmov,multi,multi,multi,sse")
433190286Sobrien   (set_attr "mode" "SF,SF,SF,SF,DF")])
433218334Speter
433390286Sobrien(define_insn "*truncdfsf2_2"
433490286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,!m")
433590286Sobrien	(float_truncate:SF
433690286Sobrien	 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
433790286Sobrien  "TARGET_80387 && TARGET_SSE2
433890286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
433990286Sobrien{
434090286Sobrien  switch (which_alternative)
434190286Sobrien    {
434290286Sobrien    case 0:
434390286Sobrien      return "cvtsd2ss\t{%1, %0|%0, %1}";
434490286Sobrien    case 1:
434590286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
434690286Sobrien	return "fstp%z0\t%y0";
434790286Sobrien      else
434890286Sobrien	return "fst%z0\t%y0";
434990286Sobrien    default:
435090286Sobrien      abort ();
435190286Sobrien    }
435290286Sobrien}
435390286Sobrien  [(set_attr "type" "sse,fmov")
435490286Sobrien   (set_attr "mode" "DF,SF")])
435552296Sobrien
435690286Sobrien(define_insn "truncdfsf2_3"
435790286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
435890286Sobrien	(float_truncate:SF
435990286Sobrien	 (match_operand:DF 1 "register_operand" "f")))]
436090286Sobrien  "TARGET_80387"
436190286Sobrien{
436290286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
436390286Sobrien    return "fstp%z0\t%y0";
436418334Speter  else
436590286Sobrien    return "fst%z0\t%y0";
436690286Sobrien}
436790286Sobrien  [(set_attr "type" "fmov")
436890286Sobrien   (set_attr "mode" "SF")])
436918334Speter
437090286Sobrien(define_insn "truncdfsf2_sse_only"
437190286Sobrien  [(set (match_operand:SF 0 "register_operand" "=Y")
437290286Sobrien	(float_truncate:SF
437390286Sobrien	 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
437490286Sobrien  "!TARGET_80387 && TARGET_SSE2"
437590286Sobrien  "cvtsd2ss\t{%1, %0|%0, %1}"
437690286Sobrien  [(set_attr "type" "sse")
437790286Sobrien   (set_attr "mode" "DF")])
437852296Sobrien
437952296Sobrien(define_split
438090286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
438190286Sobrien	(float_truncate:SF
438290286Sobrien	 (match_operand:DF 1 "register_operand" "")))
438352296Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
438490286Sobrien  "TARGET_80387"
438590286Sobrien  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
438652296Sobrien  "")
438752296Sobrien
438852296Sobrien(define_split
438990286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "")
439090286Sobrien	(float_truncate:SF
439190286Sobrien	 (match_operand:DF 1 "nonimmediate_operand" "")))
439290286Sobrien   (clobber (match_operand 2 "" ""))]
439390286Sobrien  "TARGET_80387 && reload_completed
439490286Sobrien   && !FP_REG_P (operands[0]) && !FP_REG_P (operands[1])"
439590286Sobrien  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
439690286Sobrien  "")
439790286Sobrien
439890286Sobrien(define_split
439990286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
440090286Sobrien	(float_truncate:SF
440190286Sobrien	 (match_operand:DF 1 "register_operand" "")))
440252296Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
440390286Sobrien  "TARGET_80387 && reload_completed
440490286Sobrien   && FP_REG_P (operands[1])"
440590286Sobrien  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
440690286Sobrien   (set (match_dup 0) (match_dup 2))]
440752296Sobrien  "")
440852296Sobrien
440990286Sobrien(define_expand "truncxfsf2"
441090286Sobrien  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
441190286Sobrien		   (float_truncate:SF
441290286Sobrien		    (match_operand:XF 1 "register_operand" "")))
441390286Sobrien	      (clobber (match_dup 2))])]
441490286Sobrien  "!TARGET_64BIT && TARGET_80387"
441590286Sobrien  "operands[2] = assign_386_stack_local (SFmode, 0);")
441652296Sobrien
441790286Sobrien(define_insn "*truncxfsf2_1"
441890286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
441990286Sobrien	(float_truncate:SF
442090286Sobrien	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
442190286Sobrien   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
442290286Sobrien  "!TARGET_64BIT && TARGET_80387"
442390286Sobrien{
442490286Sobrien  switch (which_alternative)
442590286Sobrien    {
442690286Sobrien    case 0:
442790286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
442890286Sobrien	return "fstp%z0\t%y0";
442990286Sobrien      else
443090286Sobrien	return "fst%z0\t%y0";
443190286Sobrien    default:
443290286Sobrien      abort();
443390286Sobrien    }
443490286Sobrien}
443590286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
443690286Sobrien   (set_attr "mode" "SF")])
443790286Sobrien
443890286Sobrien(define_insn "*truncxfsf2_2"
443952296Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
444090286Sobrien	(float_truncate:SF
444190286Sobrien	 (match_operand:XF 1 "register_operand" "f")))]
444290286Sobrien  "!TARGET_64BIT && TARGET_80387"
444318334Speter{
444490286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
444590286Sobrien    return "fstp%z0\t%y0";
444618334Speter  else
444790286Sobrien    return "fst%z0\t%y0";
444890286Sobrien}
444990286Sobrien  [(set_attr "type" "fmov")
445090286Sobrien   (set_attr "mode" "SF")])
445152296Sobrien
445290286Sobrien(define_split
445390286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
445490286Sobrien	(float_truncate:SF
445590286Sobrien	 (match_operand:XF 1 "register_operand" "")))
445690286Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
445790286Sobrien  "TARGET_80387"
445890286Sobrien  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
445990286Sobrien  "")
446090286Sobrien
446190286Sobrien(define_split
446290286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
446390286Sobrien	(float_truncate:SF
446490286Sobrien	 (match_operand:XF 1 "register_operand" "")))
446590286Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
446690286Sobrien  "TARGET_80387 && reload_completed"
446790286Sobrien  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
446890286Sobrien   (set (match_dup 0) (match_dup 2))]
446990286Sobrien  "")
447090286Sobrien
447190286Sobrien(define_expand "trunctfsf2"
447252296Sobrien  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
447352296Sobrien		   (float_truncate:SF
447490286Sobrien		    (match_operand:TF 1 "register_operand" "")))
447552296Sobrien	      (clobber (match_dup 2))])]
447652296Sobrien  "TARGET_80387"
447790286Sobrien  "operands[2] = assign_386_stack_local (SFmode, 0);")
447890286Sobrien
447990286Sobrien(define_insn "*trunctfsf2_1"
448090286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
448190286Sobrien	(float_truncate:SF
448290286Sobrien	 (match_operand:TF 1 "register_operand" "f,f,f,f")))
448390286Sobrien   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
448490286Sobrien  "TARGET_80387"
448552296Sobrien{
448690286Sobrien  switch (which_alternative)
448790286Sobrien    {
448890286Sobrien    case 0:
448990286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
449090286Sobrien	return "fstp%z0\t%y0";
449190286Sobrien      else
449290286Sobrien	return "fst%z0\t%y0";
449390286Sobrien    default:
449490286Sobrien      abort();
449590286Sobrien    }
449690286Sobrien}
449790286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
449890286Sobrien   (set_attr "mode" "SF")])
449918334Speter
450090286Sobrien(define_insn "*trunctfsf2_2"
450190286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
450252296Sobrien	(float_truncate:SF
450390286Sobrien	 (match_operand:TF 1 "register_operand" "f")))]
450418334Speter  "TARGET_80387"
450518334Speter{
450690286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
450790286Sobrien    return "fstp%z0\t%y0";
450818334Speter  else
450990286Sobrien    return "fst%z0\t%y0";
451090286Sobrien}
451190286Sobrien  [(set_attr "type" "fmov")
451290286Sobrien   (set_attr "mode" "SF")])
451318334Speter
451452296Sobrien(define_split
451590286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
451690286Sobrien	(float_truncate:SF
451790286Sobrien	 (match_operand:TF 1 "register_operand" "")))
451852296Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
451990286Sobrien  "TARGET_80387"
452090286Sobrien  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
452152296Sobrien  "")
452252296Sobrien
452352296Sobrien(define_split
452490286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
452590286Sobrien	(float_truncate:SF
452690286Sobrien	 (match_operand:TF 1 "register_operand" "")))
452752296Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
452852296Sobrien  "TARGET_80387 && reload_completed"
452990286Sobrien  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
453090286Sobrien   (set (match_dup 0) (match_dup 2))]
453152296Sobrien  "")
453252296Sobrien
453318334Speter
453452296Sobrien(define_expand "truncxfdf2"
453552296Sobrien  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
453652296Sobrien		   (float_truncate:DF
453752296Sobrien		    (match_operand:XF 1 "register_operand" "")))
453852296Sobrien	      (clobber (match_dup 2))])]
453990286Sobrien  "!TARGET_64BIT && TARGET_80387"
454090286Sobrien  "operands[2] = assign_386_stack_local (DFmode, 0);")
454118334Speter
454290286Sobrien(define_insn "*truncxfdf2_1"
454390286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
454452296Sobrien	(float_truncate:DF
454590286Sobrien	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
454690286Sobrien   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
454790286Sobrien  "!TARGET_64BIT && TARGET_80387"
454818334Speter{
454990286Sobrien  switch (which_alternative)
455052296Sobrien    {
455190286Sobrien    case 0:
455290286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
455390286Sobrien	return "fstp%z0\t%y0";
455490286Sobrien      else
455590286Sobrien	return "fst%z0\t%y0";
455690286Sobrien    default:
455790286Sobrien      abort();
455852296Sobrien    }
455990286Sobrien  abort ();
456090286Sobrien}
456190286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
456290286Sobrien   (set_attr "mode" "DF")])
456352296Sobrien
456490286Sobrien(define_insn "*truncxfdf2_2"
456590286Sobrien  [(set (match_operand:DF 0 "memory_operand" "=m")
456690286Sobrien	(float_truncate:DF
456790286Sobrien	  (match_operand:XF 1 "register_operand" "f")))]
456890286Sobrien  "!TARGET_64BIT && TARGET_80387"
456990286Sobrien{
457090286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
457190286Sobrien    return "fstp%z0\t%y0";
457290286Sobrien  else
457390286Sobrien    return "fst%z0\t%y0";
457490286Sobrien}
457590286Sobrien  [(set_attr "type" "fmov")
457690286Sobrien   (set_attr "mode" "DF")])
457752296Sobrien
457852296Sobrien(define_split
457990286Sobrien  [(set (match_operand:DF 0 "memory_operand" "")
458090286Sobrien	(float_truncate:DF
458190286Sobrien	 (match_operand:XF 1 "register_operand" "")))
458252296Sobrien   (clobber (match_operand:DF 2 "memory_operand" ""))]
458390286Sobrien  "TARGET_80387"
458490286Sobrien  [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
458552296Sobrien  "")
458652296Sobrien
458752296Sobrien(define_split
458890286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
458990286Sobrien	(float_truncate:DF
459090286Sobrien	 (match_operand:XF 1 "register_operand" "")))
459152296Sobrien   (clobber (match_operand:DF 2 "memory_operand" ""))]
459252296Sobrien  "TARGET_80387 && reload_completed"
459390286Sobrien  [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
459490286Sobrien   (set (match_dup 0) (match_dup 2))]
459552296Sobrien  "")
459652296Sobrien
459790286Sobrien(define_expand "trunctfdf2"
459890286Sobrien  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
459990286Sobrien		   (float_truncate:DF
460090286Sobrien		    (match_operand:TF 1 "register_operand" "")))
460190286Sobrien	      (clobber (match_dup 2))])]
460218334Speter  "TARGET_80387"
460390286Sobrien  "operands[2] = assign_386_stack_local (DFmode, 0);")
460418334Speter
460590286Sobrien(define_insn "*trunctfdf2_1"
460690286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
460790286Sobrien	(float_truncate:DF
460890286Sobrien	 (match_operand:TF 1 "register_operand" "f,f,f,f")))
460990286Sobrien   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
461018334Speter  "TARGET_80387"
461118334Speter{
461290286Sobrien  switch (which_alternative)
461390286Sobrien    {
461490286Sobrien    case 0:
461590286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
461690286Sobrien	return "fstp%z0\t%y0";
461790286Sobrien      else
461890286Sobrien	return "fst%z0\t%y0";
461990286Sobrien    default:
462090286Sobrien      abort();
462190286Sobrien    }
462290286Sobrien  abort ();
462390286Sobrien}
462490286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
462590286Sobrien   (set_attr "mode" "DF")])
462618334Speter
462790286Sobrien	(define_insn "*trunctfdf2_2"
462890286Sobrien  [(set (match_operand:DF 0 "memory_operand" "=m")
462990286Sobrien	(float_truncate:DF
463090286Sobrien	  (match_operand:TF 1 "register_operand" "f")))]
463152296Sobrien  "TARGET_80387"
463218334Speter{
463390286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
463490286Sobrien    return "fstp%z0\t%y0";
463590286Sobrien  else
463690286Sobrien    return "fst%z0\t%y0";
463790286Sobrien}
463890286Sobrien  [(set_attr "type" "fmov")
463990286Sobrien   (set_attr "mode" "DF")])
464018334Speter
464190286Sobrien(define_split
464290286Sobrien  [(set (match_operand:DF 0 "memory_operand" "")
464390286Sobrien	(float_truncate:DF
464490286Sobrien	 (match_operand:TF 1 "register_operand" "")))
464590286Sobrien   (clobber (match_operand:DF 2 "memory_operand" ""))]
464618334Speter  "TARGET_80387"
464790286Sobrien  [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
464890286Sobrien  "")
464918334Speter
465090286Sobrien(define_split
465190286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
465290286Sobrien	(float_truncate:DF
465390286Sobrien	 (match_operand:TF 1 "register_operand" "")))
465490286Sobrien   (clobber (match_operand:DF 2 "memory_operand" ""))]
465590286Sobrien  "TARGET_80387 && reload_completed"
465690286Sobrien  [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
465790286Sobrien   (set (match_dup 0) (match_dup 2))]
465890286Sobrien  "")
465918334Speter
466090286Sobrien
466190286Sobrien;; %%% Break up all these bad boys.
466290286Sobrien
466390286Sobrien;; Signed conversion to DImode.
466490286Sobrien
466590286Sobrien(define_expand "fix_truncxfdi2"
466690286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
466790286Sobrien        (fix:DI (match_operand:XF 1 "register_operand" "")))]
466890286Sobrien  "!TARGET_64BIT && TARGET_80387"
466990286Sobrien  "")
467090286Sobrien
467190286Sobrien(define_expand "fix_trunctfdi2"
467290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
467390286Sobrien	(fix:DI (match_operand:TF 1 "register_operand" "")))]
467418334Speter  "TARGET_80387"
467590286Sobrien  "")
467618334Speter
467752296Sobrien(define_expand "fix_truncdfdi2"
467890286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
467990286Sobrien        (fix:DI (match_operand:DF 1 "register_operand" "")))]
468090286Sobrien  "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
468118334Speter{
468290286Sobrien  if (TARGET_64BIT && TARGET_SSE2)
468390286Sobrien   {
468490286Sobrien     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
468590286Sobrien     emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
468690286Sobrien     if (out != operands[0])
468790286Sobrien	emit_move_insn (operands[0], out);
468890286Sobrien     DONE;
468990286Sobrien   }
469090286Sobrien})
469118334Speter
469290286Sobrien(define_expand "fix_truncsfdi2"
469390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
469490286Sobrien	(fix:DI (match_operand:SF 1 "register_operand" "")))]
469590286Sobrien  "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
469690286Sobrien{
469790286Sobrien  if (TARGET_SSE && TARGET_64BIT)
469890286Sobrien   {
469990286Sobrien     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
470090286Sobrien     emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
470190286Sobrien     if (out != operands[0])
470290286Sobrien	emit_move_insn (operands[0], out);
470390286Sobrien     DONE;
470490286Sobrien   }
470590286Sobrien})
470652296Sobrien
470790286Sobrien;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
470890286Sobrien;; of the machinery.
470990286Sobrien(define_insn_and_split "*fix_truncdi_1"
471090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
471190286Sobrien	(fix:DI (match_operand 1 "register_operand" "f,f")))]
471290286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
471390286Sobrien   && !reload_completed && !reload_in_progress
471490286Sobrien   && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
471590286Sobrien  "#"
471690286Sobrien  "&& 1"
471790286Sobrien  [(const_int 0)]
471890286Sobrien{
471990286Sobrien  operands[2] = assign_386_stack_local (HImode, 1);
472090286Sobrien  operands[3] = assign_386_stack_local (HImode, 2);
472190286Sobrien  if (memory_operand (operands[0], VOIDmode))
472290286Sobrien    emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
472390286Sobrien				       operands[2], operands[3]));
472490286Sobrien  else
472590286Sobrien    {
472690286Sobrien      operands[4] = assign_386_stack_local (DImode, 0);
472790286Sobrien      emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
472890286Sobrien					   operands[2], operands[3],
472990286Sobrien					   operands[4]));
473090286Sobrien    }
473190286Sobrien  DONE;
473290286Sobrien}
473390286Sobrien  [(set_attr "type" "fistp")])
473490286Sobrien
473590286Sobrien(define_insn "fix_truncdi_nomemory"
473690286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
473790286Sobrien	(fix:DI (match_operand 1 "register_operand" "f,f")))
473890286Sobrien   (use (match_operand:HI 2 "memory_operand" "m,m"))
473990286Sobrien   (use (match_operand:HI 3 "memory_operand" "m,m"))
474090286Sobrien   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
474190286Sobrien   (clobber (match_scratch:DF 5 "=&1f,&1f"))]
474290286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
474390286Sobrien   && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
474490286Sobrien  "#"
474590286Sobrien  [(set_attr "type" "fistp")])
474690286Sobrien
474790286Sobrien(define_insn "fix_truncdi_memory"
474890286Sobrien  [(set (match_operand:DI 0 "memory_operand" "=m")
474990286Sobrien	(fix:DI (match_operand 1 "register_operand" "f")))
475090286Sobrien   (use (match_operand:HI 2 "memory_operand" "m"))
475190286Sobrien   (use (match_operand:HI 3 "memory_operand" "m"))
475290286Sobrien   (clobber (match_scratch:DF 4 "=&1f"))]
475390286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
475490286Sobrien   && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
475590286Sobrien  "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
475690286Sobrien  [(set_attr "type" "fistp")])
475790286Sobrien
475890286Sobrien(define_split 
475990286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
476090286Sobrien	(fix:DI (match_operand 1 "register_operand" "")))
476190286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
476290286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
476390286Sobrien   (clobber (match_operand:DI 4 "memory_operand" ""))
476490286Sobrien   (clobber (match_scratch 5 ""))]
476590286Sobrien  "reload_completed"
476690286Sobrien  [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
476790286Sobrien	      (use (match_dup 2))
476890286Sobrien	      (use (match_dup 3))
476990286Sobrien	      (clobber (match_dup 5))])
477090286Sobrien   (set (match_dup 0) (match_dup 4))]
477190286Sobrien  "")
477290286Sobrien
477390286Sobrien(define_split 
477490286Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
477590286Sobrien	(fix:DI (match_operand 1 "register_operand" "")))
477690286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
477790286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
477890286Sobrien   (clobber (match_operand:DI 4 "memory_operand" ""))
477990286Sobrien   (clobber (match_scratch 5 ""))]
478090286Sobrien  "reload_completed"
478190286Sobrien  [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
478290286Sobrien	      (use (match_dup 2))
478390286Sobrien	      (use (match_dup 3))
478490286Sobrien	      (clobber (match_dup 5))])]
478590286Sobrien  "")
478690286Sobrien
478790286Sobrien;; When SSE available, it is always faster to use it!
478890286Sobrien(define_insn "fix_truncsfdi_sse"
478990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
479090286Sobrien	(fix:DI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
479190286Sobrien  "TARGET_64BIT && TARGET_SSE"
479290286Sobrien  "cvttss2si{q}\t{%1, %0|%0, %1}"
479390286Sobrien  [(set_attr "type" "sse")])
479490286Sobrien
479590286Sobrien(define_insn "fix_truncdfdi_sse"
479690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
479790286Sobrien	(fix:DI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
479890286Sobrien  "TARGET_64BIT && TARGET_SSE2"
479990286Sobrien  "cvttsd2si{q}\t{%1, %0|%0, %1}"
480090286Sobrien  [(set_attr "type" "sse")])
480190286Sobrien
480290286Sobrien;; Signed conversion to SImode.
480390286Sobrien
480452296Sobrien(define_expand "fix_truncxfsi2"
480590286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
480690286Sobrien	(fix:SI (match_operand:XF 1 "register_operand" "")))]
480790286Sobrien  "!TARGET_64BIT && TARGET_80387"
480890286Sobrien  "")
480990286Sobrien
481090286Sobrien(define_expand "fix_trunctfsi2"
481190286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
481290286Sobrien	(fix:SI (match_operand:TF 1 "register_operand" "")))]
481318334Speter  "TARGET_80387"
481490286Sobrien  "")
481590286Sobrien
481690286Sobrien(define_expand "fix_truncdfsi2"
481790286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
481890286Sobrien	(fix:SI (match_operand:DF 1 "register_operand" "")))]
481990286Sobrien  "TARGET_80387 || TARGET_SSE2"
482018334Speter{
482190286Sobrien  if (TARGET_SSE2)
482290286Sobrien   {
482390286Sobrien     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
482490286Sobrien     emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
482590286Sobrien     if (out != operands[0])
482690286Sobrien	emit_move_insn (operands[0], out);
482790286Sobrien     DONE;
482890286Sobrien   }
482990286Sobrien})
483018334Speter
483190286Sobrien(define_expand "fix_truncsfsi2"
483290286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
483390286Sobrien	(fix:SI (match_operand:SF 1 "register_operand" "")))]
483490286Sobrien  "TARGET_80387 || TARGET_SSE"
483590286Sobrien{
483690286Sobrien  if (TARGET_SSE)
483790286Sobrien   {
483890286Sobrien     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
483990286Sobrien     emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
484090286Sobrien     if (out != operands[0])
484190286Sobrien	emit_move_insn (operands[0], out);
484290286Sobrien     DONE;
484390286Sobrien   }
484490286Sobrien})
484552296Sobrien
484690286Sobrien;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
484790286Sobrien;; of the machinery.
484890286Sobrien(define_insn_and_split "*fix_truncsi_1"
484990286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
485090286Sobrien	(fix:SI (match_operand 1 "register_operand" "f,f")))]
485190286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
485290286Sobrien   && !reload_completed && !reload_in_progress
485390286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
485490286Sobrien  "#"
485590286Sobrien  "&& 1"
485690286Sobrien  [(const_int 0)]
485718334Speter{
485890286Sobrien  operands[2] = assign_386_stack_local (HImode, 1);
485990286Sobrien  operands[3] = assign_386_stack_local (HImode, 2);
486090286Sobrien  if (memory_operand (operands[0], VOIDmode))
486190286Sobrien    emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
486290286Sobrien				       operands[2], operands[3]));
486390286Sobrien  else
486490286Sobrien    {
486590286Sobrien      operands[4] = assign_386_stack_local (SImode, 0);
486690286Sobrien      emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
486790286Sobrien					   operands[2], operands[3],
486890286Sobrien					   operands[4]));
486990286Sobrien    }
487090286Sobrien  DONE;
487190286Sobrien}
487290286Sobrien  [(set_attr "type" "fistp")])
487318334Speter
487490286Sobrien(define_insn "fix_truncsi_nomemory"
487590286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
487690286Sobrien	(fix:SI (match_operand 1 "register_operand" "f,f")))
487790286Sobrien   (use (match_operand:HI 2 "memory_operand" "m,m"))
487890286Sobrien   (use (match_operand:HI 3 "memory_operand" "m,m"))
487990286Sobrien   (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
488090286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
488190286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
488290286Sobrien  "#"
488390286Sobrien  [(set_attr "type" "fistp")])
488490286Sobrien
488590286Sobrien(define_insn "fix_truncsi_memory"
488690286Sobrien  [(set (match_operand:SI 0 "memory_operand" "=m")
488790286Sobrien	(fix:SI (match_operand 1 "register_operand" "f")))
488890286Sobrien   (use (match_operand:HI 2 "memory_operand" "m"))
488990286Sobrien   (use (match_operand:HI 3 "memory_operand" "m"))]
489090286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
489190286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
489252296Sobrien  "* return output_fix_trunc (insn, operands);"
489390286Sobrien  [(set_attr "type" "fistp")])
489418334Speter
489590286Sobrien;; When SSE available, it is always faster to use it!
489690286Sobrien(define_insn "fix_truncsfsi_sse"
489790286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
489890286Sobrien	(fix:SI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
489990286Sobrien  "TARGET_SSE"
490090286Sobrien  "cvttss2si\t{%1, %0|%0, %1}"
490190286Sobrien  [(set_attr "type" "sse")])
490252296Sobrien
490390286Sobrien(define_insn "fix_truncdfsi_sse"
490490286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
490590286Sobrien	(fix:SI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
490690286Sobrien  "TARGET_SSE2"
490790286Sobrien  "cvttsd2si\t{%1, %0|%0, %1}"
490890286Sobrien  [(set_attr "type" "sse")])
490952296Sobrien
491090286Sobrien(define_split 
491190286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
491290286Sobrien	(fix:SI (match_operand 1 "register_operand" "")))
491390286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
491490286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
491590286Sobrien   (clobber (match_operand:SI 4 "memory_operand" ""))]
491690286Sobrien  "reload_completed"
491790286Sobrien  [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
491890286Sobrien	      (use (match_dup 2))
491990286Sobrien	      (use (match_dup 3))])
492090286Sobrien   (set (match_dup 0) (match_dup 4))]
492190286Sobrien  "")
492218334Speter
492390286Sobrien(define_split 
492490286Sobrien  [(set (match_operand:SI 0 "memory_operand" "")
492590286Sobrien	(fix:SI (match_operand 1 "register_operand" "")))
492690286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
492790286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
492890286Sobrien   (clobber (match_operand:SI 4 "memory_operand" ""))]
492990286Sobrien  "reload_completed"
493090286Sobrien  [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
493190286Sobrien	      (use (match_dup 2))
493290286Sobrien	      (use (match_dup 3))])]
493352296Sobrien  "")
493452296Sobrien
493590286Sobrien;; Signed conversion to HImode.
493690286Sobrien
493790286Sobrien(define_expand "fix_truncxfhi2"
493890286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
493990286Sobrien        (fix:HI (match_operand:XF 1 "register_operand" "")))]
494090286Sobrien  "!TARGET_64BIT && TARGET_80387"
494152296Sobrien  "")
494252296Sobrien
494390286Sobrien(define_expand "fix_trunctfhi2"
494490286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
494590286Sobrien	(fix:HI (match_operand:TF 1 "register_operand" "")))]
494618334Speter  "TARGET_80387"
494790286Sobrien  "")
494818334Speter
494990286Sobrien(define_expand "fix_truncdfhi2"
495090286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
495190286Sobrien	(fix:HI (match_operand:DF 1 "register_operand" "")))]
495290286Sobrien  "TARGET_80387 && !TARGET_SSE2"
495390286Sobrien  "")
495418334Speter
495590286Sobrien(define_expand "fix_truncsfhi2"
495690286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
495790286Sobrien	(fix:HI (match_operand:SF 1 "register_operand" "")))]
495890286Sobrien  "TARGET_80387 && !TARGET_SSE"
495990286Sobrien  "")
496052296Sobrien
496190286Sobrien;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
496290286Sobrien;; of the machinery.
496390286Sobrien(define_insn_and_split "*fix_trunchi_1"
496490286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
496590286Sobrien	(fix:HI (match_operand 1 "register_operand" "f,f")))]
496690286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
496790286Sobrien   && !reload_completed && !reload_in_progress
496890286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
496990286Sobrien  "#"
497090286Sobrien  ""
497190286Sobrien  [(const_int 0)]
497290286Sobrien{
497390286Sobrien  operands[2] = assign_386_stack_local (HImode, 1);
497490286Sobrien  operands[3] = assign_386_stack_local (HImode, 2);
497590286Sobrien  if (memory_operand (operands[0], VOIDmode))
497690286Sobrien    emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
497790286Sobrien				       operands[2], operands[3]));
497890286Sobrien  else
497990286Sobrien    {
498090286Sobrien      operands[4] = assign_386_stack_local (HImode, 0);
498190286Sobrien      emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
498290286Sobrien					   operands[2], operands[3],
498390286Sobrien					   operands[4]));
498490286Sobrien    }
498590286Sobrien  DONE;
498690286Sobrien}
498790286Sobrien  [(set_attr "type" "fistp")])
498890286Sobrien
498990286Sobrien(define_insn "fix_trunchi_nomemory"
499090286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
499190286Sobrien	(fix:HI (match_operand 1 "register_operand" "f,f")))
499290286Sobrien   (use (match_operand:HI 2 "memory_operand" "m,m"))
499390286Sobrien   (use (match_operand:HI 3 "memory_operand" "m,m"))
499490286Sobrien   (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
499590286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
499690286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
499790286Sobrien  "#"
499890286Sobrien  [(set_attr "type" "fistp")])
499990286Sobrien
500090286Sobrien(define_insn "fix_trunchi_memory"
500190286Sobrien  [(set (match_operand:HI 0 "memory_operand" "=m")
500290286Sobrien	(fix:HI (match_operand 1 "register_operand" "f")))
500390286Sobrien   (use (match_operand:HI 2 "memory_operand" "m"))
500490286Sobrien   (use (match_operand:HI 3 "memory_operand" "m"))]
500590286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
500690286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
500790286Sobrien  "* return output_fix_trunc (insn, operands);"
500890286Sobrien  [(set_attr "type" "fistp")])
500990286Sobrien
501090286Sobrien(define_split 
501190286Sobrien  [(set (match_operand:HI 0 "memory_operand" "")
501290286Sobrien	(fix:HI (match_operand 1 "register_operand" "")))
501390286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
501490286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
501590286Sobrien   (clobber (match_operand:HI 4 "memory_operand" ""))]
501690286Sobrien  "reload_completed"
501790286Sobrien  [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
501890286Sobrien	      (use (match_dup 2))
501990286Sobrien	      (use (match_dup 3))])]
502018334Speter  "")
502118334Speter
502290286Sobrien(define_split 
502390286Sobrien  [(set (match_operand:HI 0 "register_operand" "")
502490286Sobrien	(fix:HI (match_operand 1 "register_operand" "")))
502590286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
502690286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
502790286Sobrien   (clobber (match_operand:HI 4 "memory_operand" ""))]
502890286Sobrien  "reload_completed"
502990286Sobrien  [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
503090286Sobrien	      (use (match_dup 2))
503190286Sobrien	      (use (match_dup 3))
503290286Sobrien	      (clobber (match_dup 4))])
503390286Sobrien   (set (match_dup 0) (match_dup 4))]
503452296Sobrien  "")
503552296Sobrien
503690286Sobrien;; %% Not used yet.
503790286Sobrien(define_insn "x86_fnstcw_1"
503890286Sobrien  [(set (match_operand:HI 0 "memory_operand" "=m")
503990286Sobrien	(unspec:HI [(reg:HI 18)] 11))]
504052296Sobrien  "TARGET_80387"
504190286Sobrien  "fnstcw\t%0"
504290286Sobrien  [(set_attr "length" "2")
504390286Sobrien   (set_attr "mode" "HI")
504490286Sobrien   (set_attr "i387" "1")
504590286Sobrien   (set_attr "ppro_uops" "few")])
504652296Sobrien
504790286Sobrien(define_insn "x86_fldcw_1"
504890286Sobrien  [(set (reg:HI 18)
504990286Sobrien	(unspec:HI [(match_operand:HI 0 "memory_operand" "m")] 12))]
505052296Sobrien  "TARGET_80387"
505190286Sobrien  "fldcw\t%0"
505290286Sobrien  [(set_attr "length" "2")
505390286Sobrien   (set_attr "mode" "HI")
505490286Sobrien   (set_attr "i387" "1")
505590286Sobrien   (set_attr "athlon_decode" "vector")
505690286Sobrien   (set_attr "ppro_uops" "few")])
505790286Sobrien
505890286Sobrien;; Conversion between fixed point and floating point.
505952296Sobrien
506090286Sobrien;; Even though we only accept memory inputs, the backend _really_
506190286Sobrien;; wants to be able to do this between registers.
506290286Sobrien
506390286Sobrien(define_insn "floathisf2"
506452296Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
506590286Sobrien	(float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
506690286Sobrien  "TARGET_80387 && !TARGET_SSE"
506790286Sobrien  "@
506890286Sobrien   fild%z1\t%1
506990286Sobrien   #"
507090286Sobrien  [(set_attr "type" "fmov,multi")
507190286Sobrien   (set_attr "mode" "SF")
507290286Sobrien   (set_attr "fp_int_src" "true")])
507352296Sobrien
507490286Sobrien(define_expand "floatsisf2"
507518334Speter  [(set (match_operand:SF 0 "register_operand" "")
507690286Sobrien	(float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
507790286Sobrien  "TARGET_SSE || TARGET_80387"
507818334Speter  "")
507918334Speter
508090286Sobrien(define_insn "*floatsisf2_i387"
508190286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
508290286Sobrien	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
508390286Sobrien  "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
508490286Sobrien  "@
508590286Sobrien   fild%z1\t%1
508690286Sobrien   #
508790286Sobrien   cvtsi2ss\t{%1, %0|%0, %1}"
508890286Sobrien  [(set_attr "type" "fmov,multi,sse")
508990286Sobrien   (set_attr "mode" "SF")
509090286Sobrien   (set_attr "fp_int_src" "true")])
509190286Sobrien
509290286Sobrien(define_insn "*floatsisf2_sse"
509390286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
509490286Sobrien	(float:SF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
509590286Sobrien  "TARGET_SSE"
509690286Sobrien  "cvtsi2ss\t{%1, %0|%0, %1}"
509790286Sobrien  [(set_attr "type" "sse")
509890286Sobrien   (set_attr "mode" "SF")
509990286Sobrien   (set_attr "fp_int_src" "true")])
510090286Sobrien
510190286Sobrien(define_expand "floatdisf2"
510252296Sobrien  [(set (match_operand:SF 0 "register_operand" "")
510390286Sobrien	(float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
510490286Sobrien  "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
510552296Sobrien  "")
510652296Sobrien
510790286Sobrien(define_insn "*floatdisf2_i387_only"
510890286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,?f")
510990286Sobrien	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
511090286Sobrien  "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
511190286Sobrien  "@
511290286Sobrien   fild%z1\t%1
511390286Sobrien   #"
511490286Sobrien  [(set_attr "type" "fmov,multi")
511590286Sobrien   (set_attr "mode" "SF")
511690286Sobrien   (set_attr "fp_int_src" "true")])
511752296Sobrien
511890286Sobrien(define_insn "*floatdisf2_i387"
511990286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
512090286Sobrien	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
512190286Sobrien  "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
512290286Sobrien  "@
512390286Sobrien   fild%z1\t%1
512490286Sobrien   #
512590286Sobrien   cvtsi2ss{q}\t{%1, %0|%0, %1}"
512690286Sobrien  [(set_attr "type" "fmov,multi,sse")
512790286Sobrien   (set_attr "mode" "SF")
512890286Sobrien   (set_attr "fp_int_src" "true")])
512952296Sobrien
513090286Sobrien(define_insn "*floatdisf2_sse"
513190286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
513290286Sobrien	(float:SF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
513390286Sobrien  "TARGET_64BIT && TARGET_SSE"
513490286Sobrien  "cvtsi2ss{q}\t{%1, %0|%0, %1}"
513590286Sobrien  [(set_attr "type" "sse")
513690286Sobrien   (set_attr "mode" "SF")
513790286Sobrien   (set_attr "fp_int_src" "true")])
513890286Sobrien
513990286Sobrien(define_insn "floathidf2"
514052296Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
514190286Sobrien	(float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
514290286Sobrien  "TARGET_80387 && !TARGET_SSE2"
514390286Sobrien  "@
514490286Sobrien   fild%z1\t%1
514590286Sobrien   #"
514690286Sobrien  [(set_attr "type" "fmov,multi")
514790286Sobrien   (set_attr "mode" "DF")
514890286Sobrien   (set_attr "fp_int_src" "true")])
514952296Sobrien
515090286Sobrien(define_expand "floatsidf2"
515118334Speter  [(set (match_operand:DF 0 "register_operand" "")
515290286Sobrien	(float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
515396294Sobrien  "TARGET_80387 || TARGET_SSE2"
515452296Sobrien  "")
515552296Sobrien
515690286Sobrien(define_insn "*floatsidf2_i387"
515790286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
515890286Sobrien	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
515990286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
516090286Sobrien  "@
516190286Sobrien   fild%z1\t%1
516290286Sobrien   #
516390286Sobrien   cvtsi2sd\t{%1, %0|%0, %1}"
516490286Sobrien  [(set_attr "type" "fmov,multi,sse")
516590286Sobrien   (set_attr "mode" "DF")
516690286Sobrien   (set_attr "fp_int_src" "true")])
516790286Sobrien
516890286Sobrien(define_insn "*floatsidf2_sse"
516990286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
517090286Sobrien	(float:DF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
517190286Sobrien  "TARGET_SSE2"
517290286Sobrien  "cvtsi2sd\t{%1, %0|%0, %1}"
517390286Sobrien  [(set_attr "type" "sse")
517490286Sobrien   (set_attr "mode" "DF")
517590286Sobrien   (set_attr "fp_int_src" "true")])
517690286Sobrien
517790286Sobrien(define_expand "floatdidf2"
517852296Sobrien  [(set (match_operand:DF 0 "register_operand" "")
517990286Sobrien	(float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
518090286Sobrien  "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
518152296Sobrien  "")
518252296Sobrien
518390286Sobrien(define_insn "*floatdidf2_i387_only"
518490286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,?f")
518590286Sobrien	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
518690286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
518790286Sobrien  "@
518890286Sobrien   fild%z1\t%1
518990286Sobrien   #"
519090286Sobrien  [(set_attr "type" "fmov,multi")
519190286Sobrien   (set_attr "mode" "DF")
519290286Sobrien   (set_attr "fp_int_src" "true")])
519390286Sobrien
519490286Sobrien(define_insn "*floatdidf2_i387"
519590286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
519690286Sobrien	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
519790286Sobrien  "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
519890286Sobrien  "@
519990286Sobrien   fild%z1\t%1
520090286Sobrien   #
520190286Sobrien   cvtsi2sd{q}\t{%1, %0|%0, %1}"
520290286Sobrien  [(set_attr "type" "fmov,multi,sse")
520390286Sobrien   (set_attr "mode" "DF")
520490286Sobrien   (set_attr "fp_int_src" "true")])
520590286Sobrien
520690286Sobrien(define_insn "*floatdidf2_sse"
520790286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
520890286Sobrien	(float:DF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
520990286Sobrien  "TARGET_SSE2"
521090286Sobrien  "cvtsi2sd{q}\t{%1, %0|%0, %1}"
521190286Sobrien  [(set_attr "type" "sse")
521290286Sobrien   (set_attr "mode" "DF")
521390286Sobrien   (set_attr "fp_int_src" "true")])
521490286Sobrien
521590286Sobrien(define_insn "floathixf2"
521690286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
521790286Sobrien	(float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
521890286Sobrien  "!TARGET_64BIT && TARGET_80387"
521990286Sobrien  "@
522090286Sobrien   fild%z1\t%1
522190286Sobrien   #"
522290286Sobrien  [(set_attr "type" "fmov,multi")
522390286Sobrien   (set_attr "mode" "XF")
522490286Sobrien   (set_attr "fp_int_src" "true")])
522590286Sobrien
522690286Sobrien(define_insn "floathitf2"
522790286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
522890286Sobrien	(float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
522918334Speter  "TARGET_80387"
523090286Sobrien  "@
523190286Sobrien   fild%z1\t%1
523290286Sobrien   #"
523390286Sobrien  [(set_attr "type" "fmov,multi")
523490286Sobrien   (set_attr "mode" "XF")
523590286Sobrien   (set_attr "fp_int_src" "true")])
523652296Sobrien
523790286Sobrien(define_insn "floatsixf2"
523890286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
523990286Sobrien	(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
524090286Sobrien  "!TARGET_64BIT && TARGET_80387"
524190286Sobrien  "@
524290286Sobrien   fild%z1\t%1
524390286Sobrien   #"
524490286Sobrien  [(set_attr "type" "fmov,multi")
524590286Sobrien   (set_attr "mode" "XF")
524690286Sobrien   (set_attr "fp_int_src" "true")])
524790286Sobrien
524890286Sobrien(define_insn "floatsitf2"
524990286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
525090286Sobrien	(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
525152296Sobrien  "TARGET_80387"
525290286Sobrien  "@
525390286Sobrien   fild%z1\t%1
525490286Sobrien   #"
525590286Sobrien  [(set_attr "type" "fmov,multi")
525690286Sobrien   (set_attr "mode" "XF")
525790286Sobrien   (set_attr "fp_int_src" "true")])
525852296Sobrien
525990286Sobrien(define_insn "floatdixf2"
526090286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
526190286Sobrien	(float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
526290286Sobrien  "!TARGET_64BIT && TARGET_80387"
526390286Sobrien  "@
526490286Sobrien   fild%z1\t%1
526590286Sobrien   #"
526690286Sobrien  [(set_attr "type" "fmov,multi")
526790286Sobrien   (set_attr "mode" "XF")
526890286Sobrien   (set_attr "fp_int_src" "true")])
526990286Sobrien
527090286Sobrien(define_insn "floatditf2"
527190286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
527290286Sobrien	(float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
527352296Sobrien  "TARGET_80387"
527490286Sobrien  "@
527590286Sobrien   fild%z1\t%1
527690286Sobrien   #"
527790286Sobrien  [(set_attr "type" "fmov,multi")
527890286Sobrien   (set_attr "mode" "XF")
527990286Sobrien   (set_attr "fp_int_src" "true")])
528052296Sobrien
528190286Sobrien;; %%% Kill these when reload knows how to do it.
528252296Sobrien(define_split
528390286Sobrien  [(set (match_operand 0 "register_operand" "")
528490286Sobrien	(float (match_operand 1 "register_operand" "")))]
528590286Sobrien  "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))
528690286Sobrien   && FP_REG_P (operands[0])"
528790286Sobrien  [(const_int 0)]
528890286Sobrien{
528990286Sobrien  operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
529090286Sobrien  operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
529190286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
529290286Sobrien  ix86_free_from_memory (GET_MODE (operands[1]));
529390286Sobrien  DONE;
529490286Sobrien})
529590286Sobrien
529690286Sobrien;; Add instructions
529718334Speter
529890286Sobrien;; %%% splits for addsidi3
529990286Sobrien;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
530090286Sobrien;	(plus:DI (match_operand:DI 1 "general_operand" "")
530190286Sobrien;		 (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
530252296Sobrien
530390286Sobrien(define_expand "adddi3"
530490286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
530590286Sobrien	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
530690286Sobrien		 (match_operand:DI 2 "x86_64_general_operand" "")))
530790286Sobrien   (clobber (reg:CC 17))]
530890286Sobrien  ""
530990286Sobrien  "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
531052296Sobrien
531190286Sobrien(define_insn "*adddi3_1"
531290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
531390286Sobrien	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
531490286Sobrien		 (match_operand:DI 2 "general_operand" "roiF,riF")))
531590286Sobrien   (clobber (reg:CC 17))]
531690286Sobrien  "!TARGET_64BIT"
531752296Sobrien  "#")
531852296Sobrien
531952296Sobrien(define_split
532090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
532190286Sobrien	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
532290286Sobrien		 (match_operand:DI 2 "general_operand" "")))
532390286Sobrien   (clobber (reg:CC 17))]
532490286Sobrien  "!TARGET_64BIT && reload_completed"
532590286Sobrien  [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)] 12))
532690286Sobrien	      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
532790286Sobrien   (parallel [(set (match_dup 3)
532890286Sobrien		   (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
532990286Sobrien				     (match_dup 4))
533090286Sobrien			    (match_dup 5)))
533190286Sobrien	      (clobber (reg:CC 17))])]
533290286Sobrien  "split_di (operands+0, 1, operands+0, operands+3);
533390286Sobrien   split_di (operands+1, 1, operands+1, operands+4);
533490286Sobrien   split_di (operands+2, 1, operands+2, operands+5);")
533518334Speter
533690286Sobrien(define_insn "*adddi3_carry_rex64"
533790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
533890286Sobrien	  (plus:DI (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
533990286Sobrien			    (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
534090286Sobrien		   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
534190286Sobrien   (clobber (reg:CC 17))]
534290286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
534390286Sobrien  "adc{q}\t{%2, %0|%0, %2}"
534490286Sobrien  [(set_attr "type" "alu")
534590286Sobrien   (set_attr "pent_pair" "pu")
534690286Sobrien   (set_attr "mode" "DI")
534790286Sobrien   (set_attr "ppro_uops" "few")])
534852296Sobrien
534990286Sobrien(define_insn "*adddi3_cc_rex64"
535090286Sobrien  [(set (reg:CC 17) (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
535190286Sobrien				(match_operand:DI 2 "x86_64_general_operand" "re,rm")] 12))
535290286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
535390286Sobrien	(plus:DI (match_dup 1) (match_dup 2)))]
535490286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
535590286Sobrien  "add{q}\t{%2, %0|%0, %2}"
535690286Sobrien  [(set_attr "type" "alu")
535790286Sobrien   (set_attr "mode" "DI")])
535852296Sobrien
535990286Sobrien(define_insn "*addsi3_carry"
536090286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
536190286Sobrien	  (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
536290286Sobrien			    (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
536390286Sobrien		   (match_operand:SI 2 "general_operand" "ri,rm")))
536490286Sobrien   (clobber (reg:CC 17))]
536590286Sobrien  "ix86_binary_operator_ok (PLUS, SImode, operands)"
536690286Sobrien  "adc{l}\t{%2, %0|%0, %2}"
536790286Sobrien  [(set_attr "type" "alu")
536890286Sobrien   (set_attr "pent_pair" "pu")
536990286Sobrien   (set_attr "mode" "SI")
537090286Sobrien   (set_attr "ppro_uops" "few")])
537152296Sobrien
537290286Sobrien(define_insn "*addsi3_carry_zext"
537390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
537490286Sobrien	  (zero_extend:DI 
537590286Sobrien	    (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
537690286Sobrien			      (match_operand:SI 1 "nonimmediate_operand" "%0"))
537790286Sobrien		     (match_operand:SI 2 "general_operand" "rim"))))
537890286Sobrien   (clobber (reg:CC 17))]
537990286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
538090286Sobrien  "adc{l}\t{%2, %k0|%k0, %2}"
538190286Sobrien  [(set_attr "type" "alu")
538290286Sobrien   (set_attr "pent_pair" "pu")
538390286Sobrien   (set_attr "mode" "SI")
538490286Sobrien   (set_attr "ppro_uops" "few")])
538552296Sobrien
538690286Sobrien(define_insn "*addsi3_cc"
538790286Sobrien  [(set (reg:CC 17) (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
538890286Sobrien			        (match_operand:SI 2 "general_operand" "ri,rm")] 12))
538990286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
539090286Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
539190286Sobrien  "ix86_binary_operator_ok (PLUS, SImode, operands)"
539290286Sobrien  "add{l}\t{%2, %0|%0, %2}"
539390286Sobrien  [(set_attr "type" "alu")
539490286Sobrien   (set_attr "mode" "SI")])
539518334Speter
539690286Sobrien(define_insn "addqi3_cc"
539790286Sobrien  [(set (reg:CC 17) (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
539890286Sobrien			        (match_operand:QI 2 "general_operand" "qi,qm")] 12))
539990286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
540090286Sobrien	(plus:QI (match_dup 1) (match_dup 2)))]
540190286Sobrien  "ix86_binary_operator_ok (PLUS, QImode, operands)"
540290286Sobrien  "add{b}\t{%2, %0|%0, %2}"
540390286Sobrien  [(set_attr "type" "alu")
540490286Sobrien   (set_attr "mode" "QI")])
540518334Speter
540690286Sobrien(define_expand "addsi3"
540790286Sobrien  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
540890286Sobrien		   (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
540990286Sobrien			    (match_operand:SI 2 "general_operand" "")))
541090286Sobrien	      (clobber (reg:CC 17))])]
541190286Sobrien  ""
541290286Sobrien  "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
541318334Speter
541490286Sobrien(define_insn "*lea_1"
541590286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
541690286Sobrien	(match_operand:SI 1 "address_operand" "p"))]
541790286Sobrien  "!TARGET_64BIT"
541890286Sobrien  "lea{l}\t{%a1, %0|%0, %a1}"
541990286Sobrien  [(set_attr "type" "lea")
542090286Sobrien   (set_attr "mode" "SI")])
542118334Speter
542290286Sobrien(define_insn "*lea_1_rex64"
542390286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
542490286Sobrien	(subreg:SI (match_operand:DI 1 "address_operand" "p") 0))]
542590286Sobrien  "TARGET_64BIT"
542690286Sobrien  "lea{l}\t{%a1, %0|%0, %a1}"
542790286Sobrien  [(set_attr "type" "lea")
542890286Sobrien   (set_attr "mode" "SI")])
542918334Speter
543090286Sobrien(define_insn "*lea_1_zext"
543190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
543290286Sobrien	(zero_extend:DI (subreg:SI (match_operand:DI 1 "address_operand" "p") 0)))]
543390286Sobrien  "TARGET_64BIT"
543490286Sobrien  "lea{l}\t{%a1, %k0|%k0, %a1}"
543590286Sobrien  [(set_attr "type" "lea")
543690286Sobrien   (set_attr "mode" "SI")])
543790286Sobrien
543890286Sobrien(define_insn "*lea_2_rex64"
543990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
544090286Sobrien	(match_operand:DI 1 "address_operand" "p"))]
544190286Sobrien  "TARGET_64BIT"
544290286Sobrien  "lea{q}\t{%a1, %0|%0, %a1}"
544390286Sobrien  [(set_attr "type" "lea")
544490286Sobrien   (set_attr "mode" "DI")])
544590286Sobrien
544690286Sobrien;; The lea patterns for non-Pmodes needs to be matched by several
544790286Sobrien;; insns converted to real lea by splitters.
544890286Sobrien
544990286Sobrien(define_insn_and_split "*lea_general_1"
545090286Sobrien  [(set (match_operand 0 "register_operand" "=r")
545190286Sobrien	(plus (plus (match_operand 1 "register_operand" "r")
545290286Sobrien		    (match_operand 2 "register_operand" "r"))
545390286Sobrien	      (match_operand 3 "immediate_operand" "i")))]
545490286Sobrien  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
545590286Sobrien    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
545690286Sobrien   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
545790286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])
545890286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[2])
545990286Sobrien   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
546090286Sobrien       || GET_MODE (operands[3]) == VOIDmode)"
546190286Sobrien  "#"
546290286Sobrien  "&& reload_completed"
546390286Sobrien  [(const_int 0)]
546490286Sobrien{
546590286Sobrien  rtx pat;
546690286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
546790286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
546890286Sobrien  operands[2] = gen_lowpart (Pmode, operands[2]);
546990286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
547090286Sobrien  pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
547190286Sobrien  		      operands[3]);
547290286Sobrien  if (Pmode != SImode)
547390286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
547490286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
547590286Sobrien  DONE;
547690286Sobrien}
547790286Sobrien  [(set_attr "type" "lea")
547890286Sobrien   (set_attr "mode" "SI")])
547990286Sobrien
548090286Sobrien(define_insn_and_split "*lea_general_1_zext"
548190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
548290286Sobrien	(zero_extend:DI
548390286Sobrien	  (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
548490286Sobrien			    (match_operand:SI 2 "register_operand" "r"))
548590286Sobrien		   (match_operand:SI 3 "immediate_operand" "i"))))]
548690286Sobrien  "TARGET_64BIT"
548790286Sobrien  "#"
548890286Sobrien  "&& reload_completed"
548952296Sobrien  [(set (match_dup 0)
549090286Sobrien	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
549190286Sobrien						     (match_dup 2))
549290286Sobrien					    (match_dup 3)) 0)))]
549390286Sobrien{
549490286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
549590286Sobrien  operands[2] = gen_lowpart (Pmode, operands[2]);
549690286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
549790286Sobrien}
549890286Sobrien  [(set_attr "type" "lea")
549990286Sobrien   (set_attr "mode" "SI")])
550052296Sobrien
550190286Sobrien(define_insn_and_split "*lea_general_2"
550290286Sobrien  [(set (match_operand 0 "register_operand" "=r")
550390286Sobrien	(plus (mult (match_operand 1 "register_operand" "r")
550490286Sobrien		    (match_operand 2 "const248_operand" "i"))
550590286Sobrien	      (match_operand 3 "nonmemory_operand" "ri")))]
550690286Sobrien  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
550790286Sobrien    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
550890286Sobrien   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
550990286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])
551090286Sobrien   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
551190286Sobrien       || GET_MODE (operands[3]) == VOIDmode)"
551290286Sobrien  "#"
551390286Sobrien  "&& reload_completed"
551490286Sobrien  [(const_int 0)]
551590286Sobrien{
551690286Sobrien  rtx pat;
551790286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
551890286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
551990286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
552090286Sobrien  pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
552190286Sobrien  		      operands[3]);
552290286Sobrien  if (Pmode != SImode)
552390286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
552490286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
552590286Sobrien  DONE;
552690286Sobrien}
552790286Sobrien  [(set_attr "type" "lea")
552890286Sobrien   (set_attr "mode" "SI")])
552952296Sobrien
553090286Sobrien(define_insn_and_split "*lea_general_2_zext"
553190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
553290286Sobrien	(zero_extend:DI
553390286Sobrien	  (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
553490286Sobrien			    (match_operand:SI 2 "const248_operand" "n"))
553590286Sobrien		   (match_operand:SI 3 "nonmemory_operand" "ri"))))]
553690286Sobrien  "TARGET_64BIT"
553790286Sobrien  "#"
553890286Sobrien  "&& reload_completed"
553990286Sobrien  [(set (match_dup 0)
554090286Sobrien	(zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
554190286Sobrien						     (match_dup 2))
554290286Sobrien					    (match_dup 3)) 0)))]
554390286Sobrien{
554490286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
554590286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
554690286Sobrien}
554790286Sobrien  [(set_attr "type" "lea")
554890286Sobrien   (set_attr "mode" "SI")])
554918334Speter
555090286Sobrien(define_insn_and_split "*lea_general_3"
555190286Sobrien  [(set (match_operand 0 "register_operand" "=r")
555290286Sobrien	(plus (plus (mult (match_operand 1 "register_operand" "r")
555390286Sobrien			  (match_operand 2 "const248_operand" "i"))
555490286Sobrien		    (match_operand 3 "register_operand" "r"))
555590286Sobrien	      (match_operand 4 "immediate_operand" "i")))]
555690286Sobrien  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
555790286Sobrien    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
555890286Sobrien   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
555990286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])
556090286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[3])"
556190286Sobrien  "#"
556290286Sobrien  "&& reload_completed"
556390286Sobrien  [(const_int 0)]
556490286Sobrien{
556590286Sobrien  rtx pat;
556690286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
556790286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
556890286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
556990286Sobrien  operands[4] = gen_lowpart (Pmode, operands[4]);
557090286Sobrien  pat = gen_rtx_PLUS (Pmode,
557190286Sobrien  		      gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
557290286Sobrien		      					 operands[2]),
557390286Sobrien				    operands[3]),
557490286Sobrien  		      operands[4]);
557590286Sobrien  if (Pmode != SImode)
557690286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
557790286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
557890286Sobrien  DONE;
557990286Sobrien}
558090286Sobrien  [(set_attr "type" "lea")
558190286Sobrien   (set_attr "mode" "SI")])
558252296Sobrien
558390286Sobrien(define_insn_and_split "*lea_general_3_zext"
558490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
558590286Sobrien	(zero_extend:DI
558690286Sobrien	  (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
558790286Sobrien				     (match_operand:SI 2 "const248_operand" "n"))
558890286Sobrien			    (match_operand:SI 3 "register_operand" "r"))
558990286Sobrien		   (match_operand:SI 4 "immediate_operand" "i"))))]
559090286Sobrien  "TARGET_64BIT"
559190286Sobrien  "#"
559290286Sobrien  "&& reload_completed"
559390286Sobrien  [(set (match_dup 0)
559490286Sobrien	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
559590286Sobrien							      (match_dup 2))
559690286Sobrien						     (match_dup 3))
559790286Sobrien					    (match_dup 4)) 0)))]
559890286Sobrien{
559990286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
560090286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
560190286Sobrien  operands[4] = gen_lowpart (Pmode, operands[4]);
560290286Sobrien}
560390286Sobrien  [(set_attr "type" "lea")
560490286Sobrien   (set_attr "mode" "SI")])
560518334Speter
560690286Sobrien(define_insn "*adddi_1_rex64"
560790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
560890286Sobrien	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
560990286Sobrien		 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
561090286Sobrien   (clobber (reg:CC 17))]
561190286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
561290286Sobrien{
561390286Sobrien  switch (get_attr_type (insn))
561490286Sobrien    {
561590286Sobrien    case TYPE_LEA:
561690286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
561790286Sobrien      return "lea{q}\t{%a2, %0|%0, %a2}";
561890286Sobrien
561990286Sobrien    case TYPE_INCDEC:
562090286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
562190286Sobrien	abort ();
562290286Sobrien      if (operands[2] == const1_rtx)
562390286Sobrien        return "inc{q}\t%0";
562490286Sobrien      else if (operands[2] == constm1_rtx)
562590286Sobrien        return "dec{q}\t%0";
562690286Sobrien      else
562790286Sobrien	abort ();
562890286Sobrien
562990286Sobrien    default:
563090286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
563190286Sobrien	abort ();
563290286Sobrien
563390286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
563490286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
563590286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
563690286Sobrien	  /* Avoid overflows.  */
563790286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
563890286Sobrien          && (INTVAL (operands[2]) == 128
563990286Sobrien	      || (INTVAL (operands[2]) < 0
564090286Sobrien		  && INTVAL (operands[2]) != -128)))
564190286Sobrien        {
564290286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
564390286Sobrien          return "sub{q}\t{%2, %0|%0, %2}";
564490286Sobrien        }
564590286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
564690286Sobrien    }
564790286Sobrien}
564890286Sobrien  [(set (attr "type")
564990286Sobrien     (cond [(eq_attr "alternative" "2")
565090286Sobrien	      (const_string "lea")
565190286Sobrien	    ; Current assemblers are broken and do not allow @GOTOFF in
565290286Sobrien	    ; ought but a memory context.
565390286Sobrien	    (match_operand:DI 2 "pic_symbolic_operand" "")
565490286Sobrien	      (const_string "lea")
565590286Sobrien	    (match_operand:DI 2 "incdec_operand" "")
565690286Sobrien	      (const_string "incdec")
565790286Sobrien	   ]
565890286Sobrien	   (const_string "alu")))
565990286Sobrien   (set_attr "mode" "DI")])
566090286Sobrien
566190286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
566252296Sobrien(define_split
566390286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
566490286Sobrien	(plus:DI (match_operand:DI 1 "register_operand" "")
566590286Sobrien		 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
566690286Sobrien   (clobber (reg:CC 17))]
566790286Sobrien  "TARGET_64BIT && reload_completed
566890286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
566952296Sobrien  [(set (match_dup 0)
567090286Sobrien	(plus:DI (match_dup 1)
567190286Sobrien		 (match_dup 2)))]
567252296Sobrien  "")
567352296Sobrien
567490286Sobrien(define_insn "*adddi_2_rex64"
567590286Sobrien  [(set (reg 17)
567690286Sobrien	(compare
567790286Sobrien	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
567890286Sobrien		   (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
567990286Sobrien	  (const_int 0)))			
568090286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
568190286Sobrien	(plus:DI (match_dup 1) (match_dup 2)))]
568290286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
568390286Sobrien   && ix86_binary_operator_ok (PLUS, DImode, operands)
568490286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
568590286Sobrien      ought but a memory context.  */
568690286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
568790286Sobrien{
568890286Sobrien  switch (get_attr_type (insn))
568990286Sobrien    {
569090286Sobrien    case TYPE_INCDEC:
569190286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
569290286Sobrien	abort ();
569390286Sobrien      if (operands[2] == const1_rtx)
569490286Sobrien        return "inc{q}\t%0";
569590286Sobrien      else if (operands[2] == constm1_rtx)
569690286Sobrien        return "dec{q}\t%0";
569790286Sobrien      else
569890286Sobrien	abort ();
569952296Sobrien
570090286Sobrien    default:
570190286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
570290286Sobrien	abort ();
570390286Sobrien      /* ???? We ought to handle there the 32bit case too
570490286Sobrien	 - do we need new constrant?  */
570590286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
570690286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
570790286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
570890286Sobrien	  /* Avoid overflows.  */
570990286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
571090286Sobrien          && (INTVAL (operands[2]) == 128
571190286Sobrien	      || (INTVAL (operands[2]) < 0
571290286Sobrien		  && INTVAL (operands[2]) != -128)))
571390286Sobrien        {
571490286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
571590286Sobrien          return "sub{q}\t{%2, %0|%0, %2}";
571690286Sobrien        }
571790286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
571890286Sobrien    }
571990286Sobrien}
572090286Sobrien  [(set (attr "type")
572190286Sobrien     (if_then_else (match_operand:DI 2 "incdec_operand" "")
572290286Sobrien	(const_string "incdec")
572390286Sobrien	(const_string "alu")))
572490286Sobrien   (set_attr "mode" "DI")])
572518334Speter
572690286Sobrien(define_insn "*adddi_3_rex64"
572790286Sobrien  [(set (reg 17)
572890286Sobrien	(compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
572990286Sobrien		 (match_operand:DI 1 "x86_64_general_operand" "%0")))
573090286Sobrien   (clobber (match_scratch:DI 0 "=r"))]
573190286Sobrien  "TARGET_64BIT
573290286Sobrien   && ix86_match_ccmode (insn, CCZmode)
573390286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
573490286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
573590286Sobrien      ought but a memory context.  */
573690286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
573750650Sobrien{
573890286Sobrien  switch (get_attr_type (insn))
573990286Sobrien    {
574090286Sobrien    case TYPE_INCDEC:
574190286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
574290286Sobrien	abort ();
574390286Sobrien      if (operands[2] == const1_rtx)
574490286Sobrien        return "inc{q}\t%0";
574590286Sobrien      else if (operands[2] == constm1_rtx)
574690286Sobrien        return "dec{q}\t%0";
574790286Sobrien      else
574890286Sobrien	abort ();
574950650Sobrien
575090286Sobrien    default:
575190286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
575290286Sobrien	abort ();
575390286Sobrien      /* ???? We ought to handle there the 32bit case too
575490286Sobrien	 - do we need new constrant?  */
575590286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
575690286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
575790286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
575890286Sobrien	  /* Avoid overflows.  */
575990286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
576090286Sobrien          && (INTVAL (operands[2]) == 128
576190286Sobrien	      || (INTVAL (operands[2]) < 0
576290286Sobrien		  && INTVAL (operands[2]) != -128)))
576390286Sobrien        {
576490286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
576590286Sobrien          return "sub{q}\t{%2, %0|%0, %2}";
576690286Sobrien        }
576790286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
576890286Sobrien    }
576990286Sobrien}
577090286Sobrien  [(set (attr "type")
577190286Sobrien     (if_then_else (match_operand:DI 2 "incdec_operand" "")
577290286Sobrien	(const_string "incdec")
577390286Sobrien	(const_string "alu")))
577490286Sobrien   (set_attr "mode" "DI")])
577550650Sobrien
577690286Sobrien; For comparisons against 1, -1 and 128, we may generate better code
577790286Sobrien; by converting cmp to add, inc or dec as done by peephole2.  This pattern
577890286Sobrien; is matched then.  We can't accept general immediate, because for
577990286Sobrien; case of overflows,  the result is messed up.
578090286Sobrien; This pattern also don't hold of 0x8000000000000000, since the value overflows
578190286Sobrien; when negated.
578290286Sobrien; Also carry flag is reversed compared to cmp, so this conversion is valid
578390286Sobrien; only for comparisons not depending on it.
578490286Sobrien(define_insn "*adddi_4_rex64"
578590286Sobrien  [(set (reg 17)
578690286Sobrien	(compare (match_operand:DI 1 "nonimmediate_operand" "0")
578790286Sobrien		 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
578890286Sobrien   (clobber (match_scratch:DI 0 "=rm"))]
578990286Sobrien  "TARGET_64BIT
579090286Sobrien   &&  ix86_match_ccmode (insn, CCGCmode)"
579190286Sobrien{
579290286Sobrien  switch (get_attr_type (insn))
579390286Sobrien    {
579490286Sobrien    case TYPE_INCDEC:
579590286Sobrien      if (operands[2] == constm1_rtx)
579690286Sobrien        return "inc{q}\t%0";
579790286Sobrien      else if (operands[2] == const1_rtx)
579890286Sobrien        return "dec{q}\t%0";
579990286Sobrien      else
580090286Sobrien	abort();
580150650Sobrien
580290286Sobrien    default:
580390286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
580490286Sobrien	abort ();
580590286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
580690286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
580790286Sobrien      if ((INTVAL (operands[2]) == -128
580890286Sobrien	   || (INTVAL (operands[2]) > 0
580990286Sobrien	       && INTVAL (operands[2]) != 128))
581090286Sobrien	  /* Avoid overflows.  */
581190286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
581290286Sobrien	return "sub{q}\t{%2, %0|%0, %2}";
581390286Sobrien      operands[2] = GEN_INT (-INTVAL (operands[2]));
581490286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
581590286Sobrien    }
581690286Sobrien}
581790286Sobrien  [(set (attr "type")
581890286Sobrien     (if_then_else (match_operand:DI 2 "incdec_operand" "")
581990286Sobrien	(const_string "incdec")
582090286Sobrien	(const_string "alu")))
582190286Sobrien   (set_attr "mode" "DI")])
582290286Sobrien
582390286Sobrien(define_insn "*adddi_5_rex64"
582490286Sobrien  [(set (reg 17)
582590286Sobrien	(compare
582690286Sobrien	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
582790286Sobrien		   (match_operand:DI 2 "x86_64_general_operand" "rme"))
582890286Sobrien	  (const_int 0)))			
582990286Sobrien   (clobber (match_scratch:DI 0 "=r"))]
583090286Sobrien  "TARGET_64BIT
583190286Sobrien   && ix86_match_ccmode (insn, CCGOCmode)
583290286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
583390286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
583490286Sobrien      ought but a memory context.  */
583590286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
583690286Sobrien{
583790286Sobrien  switch (get_attr_type (insn))
583850650Sobrien    {
583990286Sobrien    case TYPE_INCDEC:
584090286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
584190286Sobrien	abort ();
584290286Sobrien      if (operands[2] == const1_rtx)
584390286Sobrien        return "inc{q}\t%0";
584490286Sobrien      else if (operands[2] == constm1_rtx)
584590286Sobrien        return "dec{q}\t%0";
584690286Sobrien      else
584790286Sobrien	abort();
584850650Sobrien
584990286Sobrien    default:
585090286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
585190286Sobrien	abort ();
585290286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
585390286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
585490286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
585590286Sobrien	  /* Avoid overflows.  */
585690286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
585790286Sobrien          && (INTVAL (operands[2]) == 128
585890286Sobrien	      || (INTVAL (operands[2]) < 0
585990286Sobrien		  && INTVAL (operands[2]) != -128)))
586090286Sobrien        {
586190286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
586290286Sobrien          return "sub{q}\t{%2, %0|%0, %2}";
586390286Sobrien        }
586490286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
586550650Sobrien    }
586690286Sobrien}
586790286Sobrien  [(set (attr "type")
586890286Sobrien     (if_then_else (match_operand:DI 2 "incdec_operand" "")
586990286Sobrien	(const_string "incdec")
587090286Sobrien	(const_string "alu")))
587190286Sobrien   (set_attr "mode" "DI")])
587250650Sobrien
587350650Sobrien
587490286Sobrien(define_insn "*addsi_1"
587590286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
587690286Sobrien	(plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
587790286Sobrien		 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
587890286Sobrien   (clobber (reg:CC 17))]
587990286Sobrien  "ix86_binary_operator_ok (PLUS, SImode, operands)"
588050650Sobrien{
588190286Sobrien  switch (get_attr_type (insn))
588290286Sobrien    {
588390286Sobrien    case TYPE_LEA:
588490286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
588590286Sobrien      return "lea{l}\t{%a2, %0|%0, %a2}";
588650650Sobrien
588790286Sobrien    case TYPE_INCDEC:
588890286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
588990286Sobrien	abort ();
589090286Sobrien      if (operands[2] == const1_rtx)
589190286Sobrien        return "inc{l}\t%0";
589290286Sobrien      else if (operands[2] == constm1_rtx)
589390286Sobrien        return "dec{l}\t%0";
589490286Sobrien      else
589590286Sobrien	abort();
589650650Sobrien
589790286Sobrien    default:
589890286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
589990286Sobrien	abort ();
590050650Sobrien
590190286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
590290286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
590390286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
590490286Sobrien          && (INTVAL (operands[2]) == 128
590590286Sobrien	      || (INTVAL (operands[2]) < 0
590690286Sobrien		  && INTVAL (operands[2]) != -128)))
590790286Sobrien        {
590890286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
590990286Sobrien          return "sub{l}\t{%2, %0|%0, %2}";
591090286Sobrien        }
591190286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
591290286Sobrien    }
591390286Sobrien}
591490286Sobrien  [(set (attr "type")
591590286Sobrien     (cond [(eq_attr "alternative" "2")
591690286Sobrien	      (const_string "lea")
591790286Sobrien	    ; Current assemblers are broken and do not allow @GOTOFF in
591890286Sobrien	    ; ought but a memory context.
591990286Sobrien	    (match_operand:SI 2 "pic_symbolic_operand" "")
592090286Sobrien	      (const_string "lea")
592190286Sobrien	    (match_operand:SI 2 "incdec_operand" "")
592290286Sobrien	      (const_string "incdec")
592390286Sobrien	   ]
592490286Sobrien	   (const_string "alu")))
592590286Sobrien   (set_attr "mode" "SI")])
592690286Sobrien
592790286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
592890286Sobrien(define_split
592990286Sobrien  [(set (match_operand 0 "register_operand" "")
593090286Sobrien	(plus (match_operand 1 "register_operand" "")
593190286Sobrien              (match_operand 2 "nonmemory_operand" "")))
593290286Sobrien   (clobber (reg:CC 17))]
593390286Sobrien  "reload_completed
593490286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
593590286Sobrien  [(const_int 0)]
593690286Sobrien{
593790286Sobrien  rtx pat;
593890286Sobrien  /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
593990286Sobrien     may confuse gen_lowpart.  */
594090286Sobrien  if (GET_MODE (operands[0]) != Pmode)
594150650Sobrien    {
594290286Sobrien      operands[1] = gen_lowpart (Pmode, operands[1]);
594390286Sobrien      operands[2] = gen_lowpart (Pmode, operands[2]);
594490286Sobrien    }
594590286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
594690286Sobrien  pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
594790286Sobrien  if (Pmode != SImode)
594890286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
594990286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
595090286Sobrien  DONE;
595190286Sobrien})
595250650Sobrien
595390286Sobrien;; It may seem that nonimmediate operand is proper one for operand 1.
595490286Sobrien;; The addsi_1 pattern allows nonimmediate operand at that place and
595590286Sobrien;; we take care in ix86_binary_operator_ok to not allow two memory
595690286Sobrien;; operands so proper swapping will be done in reload.  This allow
595790286Sobrien;; patterns constructed from addsi_1 to match.
595890286Sobrien(define_insn "addsi_1_zext"
595990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
596090286Sobrien	(zero_extend:DI
596190286Sobrien	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
596290286Sobrien		   (match_operand:SI 2 "general_operand" "rmni,rni"))))
596390286Sobrien   (clobber (reg:CC 17))]
596490286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
596590286Sobrien{
596690286Sobrien  switch (get_attr_type (insn))
596790286Sobrien    {
596890286Sobrien    case TYPE_LEA:
596990286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
597090286Sobrien      return "lea{l}\t{%a2, %k0|%k0, %a2}";
597190286Sobrien
597290286Sobrien    case TYPE_INCDEC:
597390286Sobrien      if (operands[2] == const1_rtx)
597490286Sobrien        return "inc{l}\t%k0";
597590286Sobrien      else if (operands[2] == constm1_rtx)
597690286Sobrien        return "dec{l}\t%k0";
597750650Sobrien      else
597890286Sobrien	abort();
597990286Sobrien
598090286Sobrien    default:
598190286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
598290286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
598390286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
598490286Sobrien          && (INTVAL (operands[2]) == 128
598590286Sobrien	      || (INTVAL (operands[2]) < 0
598690286Sobrien		  && INTVAL (operands[2]) != -128)))
598790286Sobrien        {
598890286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
598990286Sobrien          return "sub{l}\t{%2, %k0|%k0, %2}";
599090286Sobrien        }
599190286Sobrien      return "add{l}\t{%2, %k0|%k0, %2}";
599250650Sobrien    }
599390286Sobrien}
599490286Sobrien  [(set (attr "type")
599590286Sobrien     (cond [(eq_attr "alternative" "1")
599690286Sobrien	      (const_string "lea")
599790286Sobrien	    ; Current assemblers are broken and do not allow @GOTOFF in
599890286Sobrien	    ; ought but a memory context.
599990286Sobrien	    (match_operand:SI 2 "pic_symbolic_operand" "")
600090286Sobrien	      (const_string "lea")
600190286Sobrien	    (match_operand:SI 2 "incdec_operand" "")
600290286Sobrien	      (const_string "incdec")
600390286Sobrien	   ]
600490286Sobrien	   (const_string "alu")))
600590286Sobrien   (set_attr "mode" "SI")])
600650650Sobrien
600790286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
600890286Sobrien(define_split
600990286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
601090286Sobrien	(zero_extend:DI
601190286Sobrien	  (plus:SI (match_operand:SI 1 "register_operand" "")
601290286Sobrien		   (match_operand:SI 2 "nonmemory_operand" ""))))
601390286Sobrien   (clobber (reg:CC 17))]
601490286Sobrien  "reload_completed
601590286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
601690286Sobrien  [(set (match_dup 0)
601790286Sobrien	(zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
601890286Sobrien{
601990286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
602090286Sobrien  operands[2] = gen_lowpart (Pmode, operands[2]);
602190286Sobrien})
602250650Sobrien
602390286Sobrien(define_insn "*addsi_2"
602490286Sobrien  [(set (reg 17)
602590286Sobrien	(compare
602690286Sobrien	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
602790286Sobrien		   (match_operand:SI 2 "general_operand" "rmni,rni"))
602890286Sobrien	  (const_int 0)))			
602990286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
603090286Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
603190286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
603290286Sobrien   && ix86_binary_operator_ok (PLUS, SImode, operands)
603390286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
603490286Sobrien      ought but a memory context.  */
603590286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
603618334Speter{
603790286Sobrien  switch (get_attr_type (insn))
603890286Sobrien    {
603990286Sobrien    case TYPE_INCDEC:
604090286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
604190286Sobrien	abort ();
604290286Sobrien      if (operands[2] == const1_rtx)
604390286Sobrien        return "inc{l}\t%0";
604490286Sobrien      else if (operands[2] == constm1_rtx)
604590286Sobrien        return "dec{l}\t%0";
604690286Sobrien      else
604790286Sobrien	abort();
604818334Speter
604990286Sobrien    default:
605090286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
605190286Sobrien	abort ();
605290286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
605390286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
605490286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
605590286Sobrien          && (INTVAL (operands[2]) == 128
605690286Sobrien	      || (INTVAL (operands[2]) < 0
605790286Sobrien		  && INTVAL (operands[2]) != -128)))
605890286Sobrien        {
605990286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
606090286Sobrien          return "sub{l}\t{%2, %0|%0, %2}";
606190286Sobrien        }
606290286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
606390286Sobrien    }
606490286Sobrien}
606590286Sobrien  [(set (attr "type")
606690286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
606790286Sobrien	(const_string "incdec")
606890286Sobrien	(const_string "alu")))
606990286Sobrien   (set_attr "mode" "SI")])
607018334Speter
607190286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
607290286Sobrien(define_insn "*addsi_2_zext"
607390286Sobrien  [(set (reg 17)
607490286Sobrien	(compare
607590286Sobrien	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
607690286Sobrien		   (match_operand:SI 2 "general_operand" "rmni"))
607790286Sobrien	  (const_int 0)))			
607890286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
607990286Sobrien	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
608090286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
608190286Sobrien   && ix86_binary_operator_ok (PLUS, SImode, operands)
608290286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
608390286Sobrien      ought but a memory context.  */
608490286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
608590286Sobrien{
608690286Sobrien  switch (get_attr_type (insn))
608718334Speter    {
608890286Sobrien    case TYPE_INCDEC:
608990286Sobrien      if (operands[2] == const1_rtx)
609090286Sobrien        return "inc{l}\t%k0";
609190286Sobrien      else if (operands[2] == constm1_rtx)
609290286Sobrien        return "dec{l}\t%k0";
609390286Sobrien      else
609490286Sobrien	abort();
609590286Sobrien
609690286Sobrien    default:
609790286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
609890286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
609990286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
610090286Sobrien          && (INTVAL (operands[2]) == 128
610190286Sobrien	      || (INTVAL (operands[2]) < 0
610290286Sobrien		  && INTVAL (operands[2]) != -128)))
610390286Sobrien        {
610490286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
610590286Sobrien          return "sub{l}\t{%2, %k0|%k0, %2}";
610690286Sobrien        }
610790286Sobrien      return "add{l}\t{%2, %k0|%k0, %2}";
610818334Speter    }
610990286Sobrien}
611090286Sobrien  [(set (attr "type")
611190286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
611290286Sobrien	(const_string "incdec")
611390286Sobrien	(const_string "alu")))
611490286Sobrien   (set_attr "mode" "SI")])
611518334Speter
611690286Sobrien(define_insn "*addsi_3"
611790286Sobrien  [(set (reg 17)
611890286Sobrien	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
611990286Sobrien		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
612090286Sobrien   (clobber (match_scratch:SI 0 "=r"))]
612190286Sobrien  "ix86_match_ccmode (insn, CCZmode)
612290286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
612390286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
612490286Sobrien      ought but a memory context.  */
612590286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
612690286Sobrien{
612790286Sobrien  switch (get_attr_type (insn))
612818334Speter    {
612990286Sobrien    case TYPE_INCDEC:
613090286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
613190286Sobrien	abort ();
613290286Sobrien      if (operands[2] == const1_rtx)
613390286Sobrien        return "inc{l}\t%0";
613490286Sobrien      else if (operands[2] == constm1_rtx)
613590286Sobrien        return "dec{l}\t%0";
613690286Sobrien      else
613790286Sobrien	abort();
613818334Speter
613990286Sobrien    default:
614090286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
614190286Sobrien	abort ();
614290286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
614390286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
614490286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
614590286Sobrien          && (INTVAL (operands[2]) == 128
614690286Sobrien	      || (INTVAL (operands[2]) < 0
614790286Sobrien		  && INTVAL (operands[2]) != -128)))
614890286Sobrien        {
614990286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
615090286Sobrien          return "sub{l}\t{%2, %0|%0, %2}";
615190286Sobrien        }
615290286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
615390286Sobrien    }
615490286Sobrien}
615590286Sobrien  [(set (attr "type")
615690286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
615790286Sobrien	(const_string "incdec")
615890286Sobrien	(const_string "alu")))
615990286Sobrien   (set_attr "mode" "SI")])
616090286Sobrien
616190286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
616290286Sobrien(define_insn "*addsi_3_zext"
616390286Sobrien  [(set (reg 17)
616490286Sobrien	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
616590286Sobrien		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
616690286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
616790286Sobrien	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
616890286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
616990286Sobrien   && ix86_binary_operator_ok (PLUS, SImode, operands)
617090286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
617190286Sobrien      ought but a memory context.  */
617290286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
617390286Sobrien{
617490286Sobrien  switch (get_attr_type (insn))
617590286Sobrien    {
617690286Sobrien    case TYPE_INCDEC:
617790286Sobrien      if (operands[2] == const1_rtx)
617890286Sobrien        return "inc{l}\t%k0";
617990286Sobrien      else if (operands[2] == constm1_rtx)
618090286Sobrien        return "dec{l}\t%k0";
618118334Speter      else
618290286Sobrien	abort();
618390286Sobrien
618490286Sobrien    default:
618590286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
618690286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
618790286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
618890286Sobrien          && (INTVAL (operands[2]) == 128
618990286Sobrien	      || (INTVAL (operands[2]) < 0
619090286Sobrien		  && INTVAL (operands[2]) != -128)))
619190286Sobrien        {
619290286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
619390286Sobrien          return "sub{l}\t{%2, %k0|%k0, %2}";
619490286Sobrien        }
619590286Sobrien      return "add{l}\t{%2, %k0|%k0, %2}";
619618334Speter    }
619790286Sobrien}
619890286Sobrien  [(set (attr "type")
619990286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
620090286Sobrien	(const_string "incdec")
620190286Sobrien	(const_string "alu")))
620290286Sobrien   (set_attr "mode" "SI")])
620318334Speter
620490286Sobrien; For comparisons agains 1, -1 and 128, we may generate better code
620590286Sobrien; by converting cmp to add, inc or dec as done by peephole2.  This pattern
620690286Sobrien; is matched then.  We can't accept general immediate, because for
620790286Sobrien; case of overflows,  the result is messed up.
620890286Sobrien; This pattern also don't hold of 0x80000000, since the value overflows
620990286Sobrien; when negated.
621090286Sobrien; Also carry flag is reversed compared to cmp, so this conversion is valid
621190286Sobrien; only for comparisons not depending on it.
621290286Sobrien(define_insn "*addsi_4"
621390286Sobrien  [(set (reg 17)
621490286Sobrien	(compare (match_operand:SI 1 "nonimmediate_operand" "0")
621590286Sobrien		 (match_operand:SI 2 "const_int_operand" "n")))
621690286Sobrien   (clobber (match_scratch:SI 0 "=rm"))]
621790286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
621890286Sobrien   && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
621990286Sobrien{
622090286Sobrien  switch (get_attr_type (insn))
622118334Speter    {
622290286Sobrien    case TYPE_INCDEC:
622390286Sobrien      if (operands[2] == constm1_rtx)
622490286Sobrien        return "inc{l}\t%0";
622590286Sobrien      else if (operands[2] == const1_rtx)
622690286Sobrien        return "dec{l}\t%0";
622790286Sobrien      else
622890286Sobrien	abort();
622918334Speter
623090286Sobrien    default:
623190286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
623290286Sobrien	abort ();
623390286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
623490286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
623590286Sobrien      if ((INTVAL (operands[2]) == -128
623690286Sobrien	   || (INTVAL (operands[2]) > 0
623790286Sobrien	       && INTVAL (operands[2]) != 128)))
623890286Sobrien	return "sub{l}\t{%2, %0|%0, %2}";
623990286Sobrien      operands[2] = GEN_INT (-INTVAL (operands[2]));
624090286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
624118334Speter    }
624290286Sobrien}
624390286Sobrien  [(set (attr "type")
624490286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
624590286Sobrien	(const_string "incdec")
624690286Sobrien	(const_string "alu")))
624790286Sobrien   (set_attr "mode" "SI")])
624818334Speter
624990286Sobrien(define_insn "*addsi_5"
625090286Sobrien  [(set (reg 17)
625190286Sobrien	(compare
625290286Sobrien	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
625390286Sobrien		   (match_operand:SI 2 "general_operand" "rmni"))
625490286Sobrien	  (const_int 0)))			
625590286Sobrien   (clobber (match_scratch:SI 0 "=r"))]
625690286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
625790286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
625890286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
625990286Sobrien      ought but a memory context.  */
626090286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
626190286Sobrien{
626290286Sobrien  switch (get_attr_type (insn))
626318334Speter    {
626490286Sobrien    case TYPE_INCDEC:
626590286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
626690286Sobrien	abort ();
626790286Sobrien      if (operands[2] == const1_rtx)
626890286Sobrien        return "inc{l}\t%0";
626990286Sobrien      else if (operands[2] == constm1_rtx)
627090286Sobrien        return "dec{l}\t%0";
627190286Sobrien      else
627290286Sobrien	abort();
627390286Sobrien
627490286Sobrien    default:
627590286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
627690286Sobrien	abort ();
627790286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
627890286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
627990286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
628090286Sobrien          && (INTVAL (operands[2]) == 128
628190286Sobrien	      || (INTVAL (operands[2]) < 0
628290286Sobrien		  && INTVAL (operands[2]) != -128)))
628390286Sobrien        {
628490286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
628590286Sobrien          return "sub{l}\t{%2, %0|%0, %2}";
628690286Sobrien        }
628790286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
628818334Speter    }
628990286Sobrien}
629090286Sobrien  [(set (attr "type")
629190286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
629290286Sobrien	(const_string "incdec")
629390286Sobrien	(const_string "alu")))
629490286Sobrien   (set_attr "mode" "SI")])
629518334Speter
629690286Sobrien(define_expand "addhi3"
629790286Sobrien  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
629890286Sobrien		   (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
629990286Sobrien			    (match_operand:HI 2 "general_operand" "")))
630090286Sobrien	      (clobber (reg:CC 17))])]
630190286Sobrien  "TARGET_HIMODE_MATH"
630290286Sobrien  "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
630318334Speter
630490286Sobrien;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
630590286Sobrien;; type optimizations enabled by define-splits.  This is not important
630690286Sobrien;; for PII, and in fact harmful because of partial register stalls.
630718334Speter
630890286Sobrien(define_insn "*addhi_1_lea"
630990286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
631090286Sobrien	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
631190286Sobrien		 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
631290286Sobrien   (clobber (reg:CC 17))]
631390286Sobrien  "!TARGET_PARTIAL_REG_STALL
631490286Sobrien   && ix86_binary_operator_ok (PLUS, HImode, operands)"
631590286Sobrien{
631690286Sobrien  switch (get_attr_type (insn))
631790286Sobrien    {
631890286Sobrien    case TYPE_LEA:
631990286Sobrien      return "#";
632090286Sobrien    case TYPE_INCDEC:
632190286Sobrien      if (operands[2] == const1_rtx)
632290286Sobrien	return "inc{w}\t%0";
632390286Sobrien      else if (operands[2] == constm1_rtx
632490286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
632590286Sobrien		   && INTVAL (operands[2]) == 65535))
632690286Sobrien	return "dec{w}\t%0";
632790286Sobrien      abort();
632818334Speter
632990286Sobrien    default:
633090286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
633190286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
633290286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
633390286Sobrien          && (INTVAL (operands[2]) == 128
633490286Sobrien	      || (INTVAL (operands[2]) < 0
633590286Sobrien		  && INTVAL (operands[2]) != -128)))
633690286Sobrien	{
633790286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
633890286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
633990286Sobrien	}
634090286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
634190286Sobrien    }
634290286Sobrien}
634390286Sobrien  [(set (attr "type")
634490286Sobrien     (if_then_else (eq_attr "alternative" "2")
634590286Sobrien	(const_string "lea")
634690286Sobrien	(if_then_else (match_operand:HI 2 "incdec_operand" "")
634790286Sobrien	   (const_string "incdec")
634890286Sobrien	   (const_string "alu"))))
634990286Sobrien   (set_attr "mode" "HI,HI,SI")])
635050650Sobrien
635190286Sobrien(define_insn "*addhi_1"
635290286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
635390286Sobrien	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
635490286Sobrien		 (match_operand:HI 2 "general_operand" "ri,rm")))
635590286Sobrien   (clobber (reg:CC 17))]
635690286Sobrien  "TARGET_PARTIAL_REG_STALL
635790286Sobrien   && ix86_binary_operator_ok (PLUS, HImode, operands)"
635818334Speter{
635990286Sobrien  switch (get_attr_type (insn))
636018334Speter    {
636190286Sobrien    case TYPE_INCDEC:
636290286Sobrien      if (operands[2] == const1_rtx)
636390286Sobrien	return "inc{w}\t%0";
636490286Sobrien      else if (operands[2] == constm1_rtx
636590286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
636690286Sobrien		   && INTVAL (operands[2]) == 65535))
636790286Sobrien	return "dec{w}\t%0";
636890286Sobrien      abort();
636918334Speter
637090286Sobrien    default:
637190286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
637290286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
637390286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
637490286Sobrien          && (INTVAL (operands[2]) == 128
637590286Sobrien	      || (INTVAL (operands[2]) < 0
637690286Sobrien		  && INTVAL (operands[2]) != -128)))
637718334Speter	{
637890286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
637990286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
638018334Speter	}
638190286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
638290286Sobrien    }
638390286Sobrien}
638490286Sobrien  [(set (attr "type")
638590286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
638690286Sobrien	(const_string "incdec")
638790286Sobrien	(const_string "alu")))
638890286Sobrien   (set_attr "mode" "HI")])
638918334Speter
639090286Sobrien(define_insn "*addhi_2"
639190286Sobrien  [(set (reg 17)
639290286Sobrien	(compare
639390286Sobrien	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
639490286Sobrien		   (match_operand:HI 2 "general_operand" "rmni,rni"))
639590286Sobrien	  (const_int 0)))			
639690286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
639790286Sobrien	(plus:HI (match_dup 1) (match_dup 2)))]
639890286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
639990286Sobrien   && ix86_binary_operator_ok (PLUS, HImode, operands)"
640090286Sobrien{
640190286Sobrien  switch (get_attr_type (insn))
640290286Sobrien    {
640390286Sobrien    case TYPE_INCDEC:
640490286Sobrien      if (operands[2] == const1_rtx)
640590286Sobrien	return "inc{w}\t%0";
640690286Sobrien      else if (operands[2] == constm1_rtx
640790286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
640890286Sobrien		   && INTVAL (operands[2]) == 65535))
640990286Sobrien	return "dec{w}\t%0";
641090286Sobrien      abort();
641190286Sobrien
641290286Sobrien    default:
641390286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
641490286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
641590286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
641690286Sobrien          && (INTVAL (operands[2]) == 128
641790286Sobrien	      || (INTVAL (operands[2]) < 0
641890286Sobrien		  && INTVAL (operands[2]) != -128)))
641918334Speter	{
642090286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
642190286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
642218334Speter	}
642390286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
642418334Speter    }
642590286Sobrien}
642690286Sobrien  [(set (attr "type")
642790286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
642890286Sobrien	(const_string "incdec")
642990286Sobrien	(const_string "alu")))
643090286Sobrien   (set_attr "mode" "HI")])
643118334Speter
643290286Sobrien(define_insn "*addhi_3"
643390286Sobrien  [(set (reg 17)
643490286Sobrien	(compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
643590286Sobrien		 (match_operand:HI 1 "nonimmediate_operand" "%0")))
643690286Sobrien   (clobber (match_scratch:HI 0 "=r"))]
643790286Sobrien  "ix86_match_ccmode (insn, CCZmode)
643890286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
643990286Sobrien{
644090286Sobrien  switch (get_attr_type (insn))
644190286Sobrien    {
644290286Sobrien    case TYPE_INCDEC:
644390286Sobrien      if (operands[2] == const1_rtx)
644490286Sobrien	return "inc{w}\t%0";
644590286Sobrien      else if (operands[2] == constm1_rtx
644690286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
644790286Sobrien		   && INTVAL (operands[2]) == 65535))
644890286Sobrien	return "dec{w}\t%0";
644990286Sobrien      abort();
645050650Sobrien
645190286Sobrien    default:
645290286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
645390286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
645490286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
645590286Sobrien          && (INTVAL (operands[2]) == 128
645690286Sobrien	      || (INTVAL (operands[2]) < 0
645790286Sobrien		  && INTVAL (operands[2]) != -128)))
645890286Sobrien	{
645990286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
646090286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
646190286Sobrien	}
646290286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
646390286Sobrien    }
646490286Sobrien}
646590286Sobrien  [(set (attr "type")
646690286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
646790286Sobrien	(const_string "incdec")
646890286Sobrien	(const_string "alu")))
646990286Sobrien   (set_attr "mode" "HI")])
647018334Speter
647190286Sobrien; See comments above addsi_3_imm for details.
647290286Sobrien(define_insn "*addhi_4"
647390286Sobrien  [(set (reg 17)
647490286Sobrien	(compare (match_operand:HI 1 "nonimmediate_operand" "0")
647590286Sobrien		 (match_operand:HI 2 "const_int_operand" "n")))
647690286Sobrien   (clobber (match_scratch:HI 0 "=rm"))]
647790286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
647890286Sobrien   && (INTVAL (operands[2]) & 0xffff) != 0x8000"
647990286Sobrien{
648090286Sobrien  switch (get_attr_type (insn))
648190286Sobrien    {
648290286Sobrien    case TYPE_INCDEC:
648390286Sobrien      if (operands[2] == constm1_rtx
648490286Sobrien	  || (GET_CODE (operands[2]) == CONST_INT
648590286Sobrien	      && INTVAL (operands[2]) == 65535))
648690286Sobrien        return "inc{w}\t%0";
648790286Sobrien      else if (operands[2] == const1_rtx)
648890286Sobrien        return "dec{w}\t%0";
648990286Sobrien      else
649090286Sobrien	abort();
649118334Speter
649290286Sobrien    default:
649390286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
649490286Sobrien	abort ();
649590286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
649690286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
649790286Sobrien      if ((INTVAL (operands[2]) == -128
649890286Sobrien	   || (INTVAL (operands[2]) > 0
649990286Sobrien	       && INTVAL (operands[2]) != 128)))
650090286Sobrien	return "sub{w}\t{%2, %0|%0, %2}";
650190286Sobrien      operands[2] = GEN_INT (-INTVAL (operands[2]));
650290286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
650350650Sobrien    }
650490286Sobrien}
650590286Sobrien  [(set (attr "type")
650690286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
650790286Sobrien	(const_string "incdec")
650890286Sobrien	(const_string "alu")))
650990286Sobrien   (set_attr "mode" "SI")])
651050650Sobrien
651118334Speter
651290286Sobrien(define_insn "*addhi_5"
651390286Sobrien  [(set (reg 17)
651490286Sobrien	(compare
651590286Sobrien	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
651690286Sobrien		   (match_operand:HI 2 "general_operand" "rmni"))
651790286Sobrien	  (const_int 0)))			
651890286Sobrien   (clobber (match_scratch:HI 0 "=r"))]
651990286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
652090286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
652150650Sobrien{
652290286Sobrien  switch (get_attr_type (insn))
652350650Sobrien    {
652490286Sobrien    case TYPE_INCDEC:
652590286Sobrien      if (operands[2] == const1_rtx)
652690286Sobrien	return "inc{w}\t%0";
652790286Sobrien      else if (operands[2] == constm1_rtx
652890286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
652990286Sobrien		   && INTVAL (operands[2]) == 65535))
653090286Sobrien	return "dec{w}\t%0";
653190286Sobrien      abort();
653250650Sobrien
653390286Sobrien    default:
653490286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
653590286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
653690286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
653790286Sobrien          && (INTVAL (operands[2]) == 128
653890286Sobrien	      || (INTVAL (operands[2]) < 0
653990286Sobrien		  && INTVAL (operands[2]) != -128)))
654090286Sobrien	{
654190286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
654290286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
654390286Sobrien	}
654490286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
654550650Sobrien    }
654690286Sobrien}
654790286Sobrien  [(set (attr "type")
654890286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
654990286Sobrien	(const_string "incdec")
655090286Sobrien	(const_string "alu")))
655190286Sobrien   (set_attr "mode" "HI")])
655250650Sobrien
655390286Sobrien(define_expand "addqi3"
655490286Sobrien  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
655590286Sobrien		   (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
655690286Sobrien			    (match_operand:QI 2 "general_operand" "")))
655790286Sobrien	      (clobber (reg:CC 17))])]
655890286Sobrien  "TARGET_QIMODE_MATH"
655990286Sobrien  "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
656050650Sobrien
656190286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
656290286Sobrien(define_insn "*addqi_1_lea"
656390286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
656490286Sobrien	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
656590286Sobrien		 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
656690286Sobrien   (clobber (reg:CC 17))]
656790286Sobrien  "!TARGET_PARTIAL_REG_STALL
656890286Sobrien   && ix86_binary_operator_ok (PLUS, QImode, operands)"
656990286Sobrien{
657090286Sobrien  int widen = (which_alternative == 2);
657190286Sobrien  switch (get_attr_type (insn))
657290286Sobrien    {
657390286Sobrien    case TYPE_LEA:
657490286Sobrien      return "#";
657590286Sobrien    case TYPE_INCDEC:
657690286Sobrien      if (operands[2] == const1_rtx)
657790286Sobrien	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
657890286Sobrien      else if (operands[2] == constm1_rtx
657990286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
658090286Sobrien		   && INTVAL (operands[2]) == 255))
658190286Sobrien	return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
658290286Sobrien      abort();
658318334Speter
658490286Sobrien    default:
658590286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
658690286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
658790286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
658890286Sobrien          && (INTVAL (operands[2]) == 128
658990286Sobrien	      || (INTVAL (operands[2]) < 0
659090286Sobrien		  && INTVAL (operands[2]) != -128)))
659190286Sobrien	{
659290286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
659390286Sobrien	  if (widen)
659490286Sobrien	    return "sub{l}\t{%2, %k0|%k0, %2}";
659590286Sobrien	  else
659690286Sobrien	    return "sub{b}\t{%2, %0|%0, %2}";
659790286Sobrien	}
659890286Sobrien      if (widen)
659990286Sobrien        return "add{l}\t{%k2, %k0|%k0, %k2}";
660090286Sobrien      else
660190286Sobrien        return "add{b}\t{%2, %0|%0, %2}";
660290286Sobrien    }
660390286Sobrien}
660490286Sobrien  [(set (attr "type")
660590286Sobrien     (if_then_else (eq_attr "alternative" "3")
660690286Sobrien	(const_string "lea")
660790286Sobrien	(if_then_else (match_operand:QI 2 "incdec_operand" "")
660890286Sobrien	   (const_string "incdec")
660990286Sobrien	   (const_string "alu"))))
661090286Sobrien   (set_attr "mode" "QI,QI,SI,SI")])
661150650Sobrien
661290286Sobrien(define_insn "*addqi_1"
661390286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
661490286Sobrien	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
661590286Sobrien		 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
661690286Sobrien   (clobber (reg:CC 17))]
661790286Sobrien  "TARGET_PARTIAL_REG_STALL
661890286Sobrien   && ix86_binary_operator_ok (PLUS, QImode, operands)"
661918334Speter{
662090286Sobrien  int widen = (which_alternative == 2);
662190286Sobrien  switch (get_attr_type (insn))
662252296Sobrien    {
662390286Sobrien    case TYPE_INCDEC:
662490286Sobrien      if (operands[2] == const1_rtx)
662590286Sobrien	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
662690286Sobrien      else if (operands[2] == constm1_rtx
662790286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
662890286Sobrien		   && INTVAL (operands[2]) == 255))
662990286Sobrien	return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
663090286Sobrien      abort();
663152296Sobrien
663290286Sobrien    default:
663390286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
663490286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
663590286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
663690286Sobrien          && (INTVAL (operands[2]) == 128
663790286Sobrien	      || (INTVAL (operands[2]) < 0
663890286Sobrien		  && INTVAL (operands[2]) != -128)))
663990286Sobrien	{
664090286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
664190286Sobrien	  if (widen)
664290286Sobrien	    return "sub{l}\t{%2, %k0|%k0, %2}";
664390286Sobrien	  else
664490286Sobrien	    return "sub{b}\t{%2, %0|%0, %2}";
664590286Sobrien	}
664690286Sobrien      if (widen)
664790286Sobrien        return "add{l}\t{%k2, %k0|%k0, %k2}";
664890286Sobrien      else
664990286Sobrien        return "add{b}\t{%2, %0|%0, %2}";
665052296Sobrien    }
665190286Sobrien}
665290286Sobrien  [(set (attr "type")
665390286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
665490286Sobrien	(const_string "incdec")
665590286Sobrien	(const_string "alu")))
665690286Sobrien   (set_attr "mode" "QI,QI,SI")])
665752296Sobrien
665890286Sobrien(define_insn "*addqi_2"
665990286Sobrien  [(set (reg 17)
666090286Sobrien	(compare
666190286Sobrien	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
666290286Sobrien		   (match_operand:QI 2 "general_operand" "qmni,qni"))
666390286Sobrien	  (const_int 0)))
666490286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
666590286Sobrien	(plus:QI (match_dup 1) (match_dup 2)))]
666690286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
666790286Sobrien   && ix86_binary_operator_ok (PLUS, QImode, operands)"
666890286Sobrien{
666990286Sobrien  switch (get_attr_type (insn))
667018334Speter    {
667190286Sobrien    case TYPE_INCDEC:
667290286Sobrien      if (operands[2] == const1_rtx)
667390286Sobrien	return "inc{b}\t%0";
667490286Sobrien      else if (operands[2] == constm1_rtx
667590286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
667690286Sobrien		   && INTVAL (operands[2]) == 255))
667790286Sobrien	return "dec{b}\t%0";
667890286Sobrien      abort();
667918334Speter
668090286Sobrien    default:
668190286Sobrien      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
668290286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
668390286Sobrien          && INTVAL (operands[2]) < 0)
668490286Sobrien	{
668590286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
668690286Sobrien	  return "sub{b}\t{%2, %0|%0, %2}";
668790286Sobrien	}
668890286Sobrien      return "add{b}\t{%2, %0|%0, %2}";
668918334Speter    }
669090286Sobrien}
669190286Sobrien  [(set (attr "type")
669290286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
669390286Sobrien	(const_string "incdec")
669490286Sobrien	(const_string "alu")))
669590286Sobrien   (set_attr "mode" "QI")])
669618334Speter
669790286Sobrien(define_insn "*addqi_3"
669890286Sobrien  [(set (reg 17)
669990286Sobrien	(compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
670090286Sobrien		 (match_operand:QI 1 "nonimmediate_operand" "%0")))
670190286Sobrien   (clobber (match_scratch:QI 0 "=q"))]
670290286Sobrien  "ix86_match_ccmode (insn, CCZmode)
670390286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
670490286Sobrien{
670590286Sobrien  switch (get_attr_type (insn))
670650650Sobrien    {
670790286Sobrien    case TYPE_INCDEC:
670890286Sobrien      if (operands[2] == const1_rtx)
670990286Sobrien	return "inc{b}\t%0";
671090286Sobrien      else if (operands[2] == constm1_rtx
671190286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
671290286Sobrien		   && INTVAL (operands[2]) == 255))
671390286Sobrien	return "dec{b}\t%0";
671490286Sobrien      abort();
671550650Sobrien
671690286Sobrien    default:
671790286Sobrien      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
671890286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
671990286Sobrien          && INTVAL (operands[2]) < 0)
672050650Sobrien	{
672190286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
672290286Sobrien	  return "sub{b}\t{%2, %0|%0, %2}";
672390286Sobrien	}
672490286Sobrien      return "add{b}\t{%2, %0|%0, %2}";
672590286Sobrien    }
672690286Sobrien}
672790286Sobrien  [(set (attr "type")
672890286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
672990286Sobrien	(const_string "incdec")
673090286Sobrien	(const_string "alu")))
673190286Sobrien   (set_attr "mode" "QI")])
673250650Sobrien
673390286Sobrien; See comments above addsi_3_imm for details.
673490286Sobrien(define_insn "*addqi_4"
673590286Sobrien  [(set (reg 17)
673690286Sobrien	(compare (match_operand:QI 1 "nonimmediate_operand" "0")
673790286Sobrien		 (match_operand:QI 2 "const_int_operand" "n")))
673890286Sobrien   (clobber (match_scratch:QI 0 "=qm"))]
673990286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
674090286Sobrien   && (INTVAL (operands[2]) & 0xff) != 0x80"
674190286Sobrien{
674290286Sobrien  switch (get_attr_type (insn))
674390286Sobrien    {
674490286Sobrien    case TYPE_INCDEC:
674590286Sobrien      if (operands[2] == constm1_rtx
674690286Sobrien	  || (GET_CODE (operands[2]) == CONST_INT
674790286Sobrien	      && INTVAL (operands[2]) == 255))
674890286Sobrien        return "inc{b}\t%0";
674990286Sobrien      else if (operands[2] == const1_rtx)
675090286Sobrien        return "dec{b}\t%0";
675190286Sobrien      else
675290286Sobrien	abort();
675350650Sobrien
675490286Sobrien    default:
675590286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
675690286Sobrien	abort ();
675790286Sobrien      if (INTVAL (operands[2]) < 0)
675890286Sobrien        {
675990286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
676090286Sobrien          return "add{b}\t{%2, %0|%0, %2}";
676190286Sobrien        }
676290286Sobrien      return "sub{b}\t{%2, %0|%0, %2}";
676350650Sobrien    }
676490286Sobrien}
676590286Sobrien  [(set (attr "type")
676690286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
676790286Sobrien	(const_string "incdec")
676890286Sobrien	(const_string "alu")))
676990286Sobrien   (set_attr "mode" "QI")])
677050650Sobrien
677118334Speter
677290286Sobrien(define_insn "*addqi_5"
677390286Sobrien  [(set (reg 17)
677490286Sobrien	(compare
677590286Sobrien	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
677690286Sobrien		   (match_operand:QI 2 "general_operand" "qmni"))
677790286Sobrien	  (const_int 0)))
677890286Sobrien   (clobber (match_scratch:QI 0 "=q"))]
677990286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
678090286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
678190286Sobrien{
678290286Sobrien  switch (get_attr_type (insn))
678390286Sobrien    {
678490286Sobrien    case TYPE_INCDEC:
678590286Sobrien      if (operands[2] == const1_rtx)
678690286Sobrien	return "inc{b}\t%0";
678790286Sobrien      else if (operands[2] == constm1_rtx
678890286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
678990286Sobrien		   && INTVAL (operands[2]) == 255))
679090286Sobrien	return "dec{b}\t%0";
679190286Sobrien      abort();
679218334Speter
679390286Sobrien    default:
679490286Sobrien      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
679590286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
679690286Sobrien          && INTVAL (operands[2]) < 0)
679790286Sobrien	{
679890286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
679990286Sobrien	  return "sub{b}\t{%2, %0|%0, %2}";
680090286Sobrien	}
680190286Sobrien      return "add{b}\t{%2, %0|%0, %2}";
680290286Sobrien    }
680390286Sobrien}
680490286Sobrien  [(set (attr "type")
680590286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
680690286Sobrien	(const_string "incdec")
680790286Sobrien	(const_string "alu")))
680890286Sobrien   (set_attr "mode" "QI")])
680918334Speter
681050650Sobrien
681190286Sobrien(define_insn "addqi_ext_1"
681290286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
681390286Sobrien			 (const_int 8)
681490286Sobrien			 (const_int 8))
681590286Sobrien	(plus:SI
681690286Sobrien	  (zero_extract:SI
681790286Sobrien	    (match_operand 1 "ext_register_operand" "0")
681890286Sobrien	    (const_int 8)
681990286Sobrien	    (const_int 8))
682090286Sobrien	  (match_operand:QI 2 "general_operand" "Qmn")))
682190286Sobrien   (clobber (reg:CC 17))]
682290286Sobrien  "!TARGET_64BIT"
682318334Speter{
682490286Sobrien  switch (get_attr_type (insn))
682552296Sobrien    {
682690286Sobrien    case TYPE_INCDEC:
682790286Sobrien      if (operands[2] == const1_rtx)
682890286Sobrien	return "inc{b}\t%h0";
682990286Sobrien      else if (operands[2] == constm1_rtx
683090286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
683190286Sobrien		   && INTVAL (operands[2]) == 255))
683290286Sobrien	return "dec{b}\t%h0";
683390286Sobrien      abort();
683452296Sobrien
683590286Sobrien    default:
683690286Sobrien      return "add{b}\t{%2, %h0|%h0, %2}";
683752296Sobrien    }
683890286Sobrien}
683990286Sobrien  [(set (attr "type")
684090286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
684190286Sobrien	(const_string "incdec")
684290286Sobrien	(const_string "alu")))
684390286Sobrien   (set_attr "mode" "QI")])
684418334Speter
684590286Sobrien(define_insn "*addqi_ext_1_rex64"
684690286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
684790286Sobrien			 (const_int 8)
684890286Sobrien			 (const_int 8))
684990286Sobrien	(plus:SI
685090286Sobrien	  (zero_extract:SI
685190286Sobrien	    (match_operand 1 "ext_register_operand" "0")
685290286Sobrien	    (const_int 8)
685390286Sobrien	    (const_int 8))
685490286Sobrien	  (match_operand:QI 2 "nonmemory_operand" "Qn")))
685590286Sobrien   (clobber (reg:CC 17))]
685690286Sobrien  "TARGET_64BIT"
685790286Sobrien{
685890286Sobrien  switch (get_attr_type (insn))
685990286Sobrien    {
686090286Sobrien    case TYPE_INCDEC:
686190286Sobrien      if (operands[2] == const1_rtx)
686290286Sobrien	return "inc{b}\t%h0";
686390286Sobrien      else if (operands[2] == constm1_rtx
686490286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
686590286Sobrien		   && INTVAL (operands[2]) == 255))
686690286Sobrien	return "dec{b}\t%h0";
686790286Sobrien      abort();
686818334Speter
686990286Sobrien    default:
687090286Sobrien      return "add{b}\t{%2, %h0|%h0, %2}";
687190286Sobrien    }
687290286Sobrien}
687390286Sobrien  [(set (attr "type")
687490286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
687590286Sobrien	(const_string "incdec")
687690286Sobrien	(const_string "alu")))
687790286Sobrien   (set_attr "mode" "QI")])
687818334Speter
687990286Sobrien(define_insn "*addqi_ext_2"
688090286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
688190286Sobrien			 (const_int 8)
688290286Sobrien			 (const_int 8))
688390286Sobrien	(plus:SI
688490286Sobrien	  (zero_extract:SI
688590286Sobrien	    (match_operand 1 "ext_register_operand" "%0")
688690286Sobrien	    (const_int 8)
688790286Sobrien	    (const_int 8))
688890286Sobrien	  (zero_extract:SI
688990286Sobrien	    (match_operand 2 "ext_register_operand" "Q")
689090286Sobrien	    (const_int 8)
689190286Sobrien	    (const_int 8))))
689290286Sobrien   (clobber (reg:CC 17))]
689390286Sobrien  ""
689490286Sobrien  "add{b}\t{%h2, %h0|%h0, %h2}"
689590286Sobrien  [(set_attr "type" "alu")
689690286Sobrien   (set_attr "mode" "QI")])
689718334Speter
689818334Speter;; The patterns that match these are at the end of this file.
689918334Speter
690018334Speter(define_expand "addxf3"
690118334Speter  [(set (match_operand:XF 0 "register_operand" "")
690250650Sobrien	(plus:XF (match_operand:XF 1 "register_operand" "")
690350650Sobrien		 (match_operand:XF 2 "register_operand" "")))]
690490286Sobrien  "!TARGET_64BIT && TARGET_80387"
690590286Sobrien  "")
690690286Sobrien
690790286Sobrien(define_expand "addtf3"
690890286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
690990286Sobrien	(plus:TF (match_operand:TF 1 "register_operand" "")
691090286Sobrien		 (match_operand:TF 2 "register_operand" "")))]
691118334Speter  "TARGET_80387"
691218334Speter  "")
691318334Speter
691418334Speter(define_expand "adddf3"
691518334Speter  [(set (match_operand:DF 0 "register_operand" "")
691690286Sobrien	(plus:DF (match_operand:DF 1 "register_operand" "")
691718334Speter		 (match_operand:DF 2 "nonimmediate_operand" "")))]
691890286Sobrien  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
691918334Speter  "")
692018334Speter
692118334Speter(define_expand "addsf3"
692218334Speter  [(set (match_operand:SF 0 "register_operand" "")
692390286Sobrien	(plus:SF (match_operand:SF 1 "register_operand" "")
692418334Speter		 (match_operand:SF 2 "nonimmediate_operand" "")))]
692590286Sobrien  "TARGET_80387 || TARGET_SSE_MATH"
692618334Speter  "")
692718334Speter
692890286Sobrien;; Subtract instructions
692918334Speter
693090286Sobrien;; %%% splits for subsidi3
693150650Sobrien
693290286Sobrien(define_expand "subdi3"
693390286Sobrien  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
693490286Sobrien		   (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
693590286Sobrien			     (match_operand:DI 2 "x86_64_general_operand" "")))
693690286Sobrien	      (clobber (reg:CC 17))])]
693718334Speter  ""
693890286Sobrien  "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
693918334Speter
694090286Sobrien(define_insn "*subdi3_1"
694190286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
694290286Sobrien	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
694390286Sobrien		  (match_operand:DI 2 "general_operand" "roiF,riF")))
694490286Sobrien   (clobber (reg:CC 17))]
694590286Sobrien  "!TARGET_64BIT"
694690286Sobrien  "#")
694718334Speter
694890286Sobrien(define_split
694990286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
695090286Sobrien	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
695190286Sobrien		  (match_operand:DI 2 "general_operand" "")))
695290286Sobrien   (clobber (reg:CC 17))]
695390286Sobrien  "!TARGET_64BIT && reload_completed"
695490286Sobrien  [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
695590286Sobrien	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
695690286Sobrien   (parallel [(set (match_dup 3)
695790286Sobrien		   (minus:SI (match_dup 4)
695890286Sobrien			     (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
695990286Sobrien				      (match_dup 5))))
696090286Sobrien	      (clobber (reg:CC 17))])]
696190286Sobrien  "split_di (operands+0, 1, operands+0, operands+3);
696290286Sobrien   split_di (operands+1, 1, operands+1, operands+4);
696390286Sobrien   split_di (operands+2, 1, operands+2, operands+5);")
696418334Speter
696590286Sobrien(define_insn "subdi3_carry_rex64"
696690286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
696790286Sobrien	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
696890286Sobrien	    (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
696990286Sobrien	       (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
697090286Sobrien   (clobber (reg:CC 17))]
697190286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
697290286Sobrien  "sbb{q}\t{%2, %0|%0, %2}"
697390286Sobrien  [(set_attr "type" "alu")
697490286Sobrien   (set_attr "pent_pair" "pu")
697590286Sobrien   (set_attr "ppro_uops" "few")
697690286Sobrien   (set_attr "mode" "DI")])
697718334Speter
697890286Sobrien(define_insn "*subdi_1_rex64"
697990286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
698090286Sobrien	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
698190286Sobrien		  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
698290286Sobrien   (clobber (reg:CC 17))]
698390286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
698490286Sobrien  "sub{q}\t{%2, %0|%0, %2}"
698590286Sobrien  [(set_attr "type" "alu")
698690286Sobrien   (set_attr "mode" "DI")])
698718334Speter
698890286Sobrien(define_insn "*subdi_2_rex64"
698990286Sobrien  [(set (reg 17)
699090286Sobrien	(compare
699190286Sobrien	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
699290286Sobrien		    (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
699390286Sobrien	  (const_int 0)))
699490286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
699590286Sobrien	(minus:DI (match_dup 1) (match_dup 2)))]
699690286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
699790286Sobrien   && ix86_binary_operator_ok (MINUS, DImode, operands)"
699890286Sobrien  "sub{q}\t{%2, %0|%0, %2}"
699990286Sobrien  [(set_attr "type" "alu")
700090286Sobrien   (set_attr "mode" "DI")])
700152296Sobrien
700290286Sobrien(define_insn "*subdi_3_rex63"
700390286Sobrien  [(set (reg 17)
700490286Sobrien	(compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
700590286Sobrien		 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
700690286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
700790286Sobrien	(minus:DI (match_dup 1) (match_dup 2)))]
700890286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
700990286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
701090286Sobrien  "sub{q}\t{%2, %0|%0, %2}"
701190286Sobrien  [(set_attr "type" "alu")
701290286Sobrien   (set_attr "mode" "DI")])
701318334Speter
701418334Speter
701590286Sobrien(define_insn "subsi3_carry"
701690286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
701790286Sobrien	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
701890286Sobrien	    (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
701990286Sobrien	       (match_operand:SI 2 "general_operand" "ri,rm"))))
702090286Sobrien   (clobber (reg:CC 17))]
702190286Sobrien  "ix86_binary_operator_ok (MINUS, SImode, operands)"
702290286Sobrien  "sbb{l}\t{%2, %0|%0, %2}"
702390286Sobrien  [(set_attr "type" "alu")
702490286Sobrien   (set_attr "pent_pair" "pu")
702590286Sobrien   (set_attr "ppro_uops" "few")
702690286Sobrien   (set_attr "mode" "SI")])
702718334Speter
702890286Sobrien(define_insn "subsi3_carry_zext"
702990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=rm,r")
703090286Sobrien	  (zero_extend:DI
703190286Sobrien	    (minus:SI (match_operand:SI 1 "register_operand" "0,0")
703290286Sobrien	      (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
703390286Sobrien		 (match_operand:SI 2 "general_operand" "ri,rm")))))
703490286Sobrien   (clobber (reg:CC 17))]
703590286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
703690286Sobrien  "sbb{l}\t{%2, %k0|%k0, %2}"
703790286Sobrien  [(set_attr "type" "alu")
703890286Sobrien   (set_attr "pent_pair" "pu")
703990286Sobrien   (set_attr "ppro_uops" "few")
704090286Sobrien   (set_attr "mode" "SI")])
704118334Speter
704250650Sobrien(define_expand "subsi3"
704390286Sobrien  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
704490286Sobrien		   (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
704590286Sobrien			     (match_operand:SI 2 "general_operand" "")))
704690286Sobrien	      (clobber (reg:CC 17))])]
704750650Sobrien  ""
704890286Sobrien  "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
704950650Sobrien
705090286Sobrien(define_insn "*subsi_1"
705150650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
705250650Sobrien	(minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
705390286Sobrien		  (match_operand:SI 2 "general_operand" "ri,rm")))
705490286Sobrien   (clobber (reg:CC 17))]
705550650Sobrien  "ix86_binary_operator_ok (MINUS, SImode, operands)"
705690286Sobrien  "sub{l}\t{%2, %0|%0, %2}"
705790286Sobrien  [(set_attr "type" "alu")
705890286Sobrien   (set_attr "mode" "SI")])
705918334Speter
706090286Sobrien(define_insn "*subsi_1_zext"
706190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
706290286Sobrien	(zero_extend:DI
706390286Sobrien	  (minus:SI (match_operand:SI 1 "register_operand" "0")
706490286Sobrien		    (match_operand:SI 2 "general_operand" "rim"))))
706590286Sobrien   (clobber (reg:CC 17))]
706690286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
706790286Sobrien  "sub{l}\t{%2, %k0|%k0, %2}"
706890286Sobrien  [(set_attr "type" "alu")
706990286Sobrien   (set_attr "mode" "SI")])
707090286Sobrien
707190286Sobrien(define_insn "*subsi_2"
707290286Sobrien  [(set (reg 17)
707390286Sobrien	(compare
707490286Sobrien	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
707590286Sobrien		    (match_operand:SI 2 "general_operand" "ri,rm"))
707690286Sobrien	  (const_int 0)))
707790286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
707890286Sobrien	(minus:SI (match_dup 1) (match_dup 2)))]
707990286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
708090286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
708190286Sobrien  "sub{l}\t{%2, %0|%0, %2}"
708290286Sobrien  [(set_attr "type" "alu")
708390286Sobrien   (set_attr "mode" "SI")])
708490286Sobrien
708590286Sobrien(define_insn "*subsi_2_zext"
708690286Sobrien  [(set (reg 17)
708790286Sobrien	(compare
708890286Sobrien	  (minus:SI (match_operand:SI 1 "register_operand" "0")
708990286Sobrien		    (match_operand:SI 2 "general_operand" "rim"))
709090286Sobrien	  (const_int 0)))
709190286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
709290286Sobrien	(zero_extend:DI
709390286Sobrien	  (minus:SI (match_dup 1)
709490286Sobrien		    (match_dup 2))))]
709590286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
709690286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
709790286Sobrien  "sub{l}\t{%2, %k0|%k0, %2}"
709890286Sobrien  [(set_attr "type" "alu")
709990286Sobrien   (set_attr "mode" "SI")])
710090286Sobrien
710190286Sobrien(define_insn "*subsi_3"
710290286Sobrien  [(set (reg 17)
710390286Sobrien	(compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
710490286Sobrien		 (match_operand:SI 2 "general_operand" "ri,rm")))
710590286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
710690286Sobrien	(minus:SI (match_dup 1) (match_dup 2)))]
710790286Sobrien  "ix86_match_ccmode (insn, CCmode)
710890286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
710990286Sobrien  "sub{l}\t{%2, %0|%0, %2}"
711090286Sobrien  [(set_attr "type" "alu")
711190286Sobrien   (set_attr "mode" "SI")])
711290286Sobrien
711390286Sobrien(define_insn "*subsi_3_zext"
711490286Sobrien  [(set (reg 17)
711590286Sobrien	(compare (match_operand:SI 1 "nonimmediate_operand" "0")
711690286Sobrien		 (match_operand:SI 2 "general_operand" "rim")))
711790286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
711890286Sobrien	(zero_extend:DI
711990286Sobrien	  (minus:SI (match_dup 1)
712090286Sobrien		    (match_dup 2))))]
712190286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
712290286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
712390286Sobrien  "sub{q}\t{%2, %0|%0, %2}"
712490286Sobrien  [(set_attr "type" "alu")
712590286Sobrien   (set_attr "mode" "DI")])
712690286Sobrien
712750650Sobrien(define_expand "subhi3"
712890286Sobrien  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
712990286Sobrien		   (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
713090286Sobrien			     (match_operand:HI 2 "general_operand" "")))
713190286Sobrien	      (clobber (reg:CC 17))])]
713290286Sobrien  "TARGET_HIMODE_MATH"
713390286Sobrien  "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
713450650Sobrien
713590286Sobrien(define_insn "*subhi_1"
713650650Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
713750650Sobrien	(minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
713890286Sobrien		  (match_operand:HI 2 "general_operand" "ri,rm")))
713990286Sobrien   (clobber (reg:CC 17))]
714050650Sobrien  "ix86_binary_operator_ok (MINUS, HImode, operands)"
714190286Sobrien  "sub{w}\t{%2, %0|%0, %2}"
714290286Sobrien  [(set_attr "type" "alu")
714390286Sobrien   (set_attr "mode" "HI")])
714450650Sobrien
714590286Sobrien(define_insn "*subhi_2"
714690286Sobrien  [(set (reg 17)
714790286Sobrien	(compare
714890286Sobrien	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
714990286Sobrien		    (match_operand:HI 2 "general_operand" "ri,rm"))
715090286Sobrien	  (const_int 0)))
715190286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
715290286Sobrien	(minus:HI (match_dup 1) (match_dup 2)))]
715390286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
715490286Sobrien   && ix86_binary_operator_ok (MINUS, HImode, operands)"
715590286Sobrien  "sub{w}\t{%2, %0|%0, %2}"
715690286Sobrien  [(set_attr "type" "alu")
715790286Sobrien   (set_attr "mode" "HI")])
715890286Sobrien
715990286Sobrien(define_insn "*subhi_3"
716090286Sobrien  [(set (reg 17)
716190286Sobrien	(compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
716290286Sobrien		 (match_operand:HI 2 "general_operand" "ri,rm")))
716390286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
716490286Sobrien	(minus:HI (match_dup 1) (match_dup 2)))]
716590286Sobrien  "ix86_match_ccmode (insn, CCmode)
716690286Sobrien   && ix86_binary_operator_ok (MINUS, HImode, operands)"
716790286Sobrien  "sub{w}\t{%2, %0|%0, %2}"
716890286Sobrien  [(set_attr "type" "alu")
716990286Sobrien   (set_attr "mode" "HI")])
717090286Sobrien
717150650Sobrien(define_expand "subqi3"
717290286Sobrien  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
717390286Sobrien		   (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
717490286Sobrien			     (match_operand:QI 2 "general_operand" "")))
717590286Sobrien	      (clobber (reg:CC 17))])]
717690286Sobrien  "TARGET_QIMODE_MATH"
717790286Sobrien  "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
717818334Speter
717990286Sobrien(define_insn "*subqi_1"
718050650Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
718150650Sobrien	(minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
718290286Sobrien		  (match_operand:QI 2 "general_operand" "qn,qmn")))
718390286Sobrien   (clobber (reg:CC 17))]
718450650Sobrien  "ix86_binary_operator_ok (MINUS, QImode, operands)"
718590286Sobrien  "sub{b}\t{%2, %0|%0, %2}"
718690286Sobrien  [(set_attr "type" "alu")
718790286Sobrien   (set_attr "mode" "QI")])
718818334Speter
718990286Sobrien(define_insn "*subqi_2"
719090286Sobrien  [(set (reg 17)
719190286Sobrien	(compare
719290286Sobrien	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
719390286Sobrien		    (match_operand:QI 2 "general_operand" "qi,qm"))
719490286Sobrien	  (const_int 0)))
719590286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
719690286Sobrien	(minus:HI (match_dup 1) (match_dup 2)))]
719790286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
719890286Sobrien   && ix86_binary_operator_ok (MINUS, QImode, operands)"
719990286Sobrien  "sub{b}\t{%2, %0|%0, %2}"
720090286Sobrien  [(set_attr "type" "alu")
720190286Sobrien   (set_attr "mode" "QI")])
720290286Sobrien
720390286Sobrien(define_insn "*subqi_3"
720490286Sobrien  [(set (reg 17)
720590286Sobrien	(compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
720690286Sobrien		 (match_operand:QI 2 "general_operand" "qi,qm")))
720790286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
720890286Sobrien	(minus:HI (match_dup 1) (match_dup 2)))]
720990286Sobrien  "ix86_match_ccmode (insn, CCmode)
721090286Sobrien   && ix86_binary_operator_ok (MINUS, QImode, operands)"
721190286Sobrien  "sub{b}\t{%2, %0|%0, %2}"
721290286Sobrien  [(set_attr "type" "alu")
721390286Sobrien   (set_attr "mode" "QI")])
721490286Sobrien
721518334Speter;; The patterns that match these are at the end of this file.
721618334Speter
721718334Speter(define_expand "subxf3"
721818334Speter  [(set (match_operand:XF 0 "register_operand" "")
721950650Sobrien	(minus:XF (match_operand:XF 1 "register_operand" "")
722050650Sobrien		  (match_operand:XF 2 "register_operand" "")))]
722190286Sobrien  "!TARGET_64BIT && TARGET_80387"
722290286Sobrien  "")
722390286Sobrien
722490286Sobrien(define_expand "subtf3"
722590286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
722690286Sobrien	(minus:TF (match_operand:TF 1 "register_operand" "")
722790286Sobrien		  (match_operand:TF 2 "register_operand" "")))]
722818334Speter  "TARGET_80387"
722918334Speter  "")
723018334Speter
723118334Speter(define_expand "subdf3"
723218334Speter  [(set (match_operand:DF 0 "register_operand" "")
723390286Sobrien	(minus:DF (match_operand:DF 1 "register_operand" "")
723418334Speter		  (match_operand:DF 2 "nonimmediate_operand" "")))]
723590286Sobrien  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
723618334Speter  "")
723718334Speter
723818334Speter(define_expand "subsf3"
723918334Speter  [(set (match_operand:SF 0 "register_operand" "")
724090286Sobrien	(minus:SF (match_operand:SF 1 "register_operand" "")
724118334Speter		  (match_operand:SF 2 "nonimmediate_operand" "")))]
724290286Sobrien  "TARGET_80387 || TARGET_SSE_MATH"
724318334Speter  "")
724418334Speter
724590286Sobrien;; Multiply instructions
724618334Speter
724790286Sobrien(define_expand "muldi3"
724890286Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
724990286Sobrien		   (mult:DI (match_operand:DI 1 "register_operand" "")
725090286Sobrien			    (match_operand:DI 2 "x86_64_general_operand" "")))
725190286Sobrien	      (clobber (reg:CC 17))])]
725290286Sobrien  "TARGET_64BIT"
725390286Sobrien  "")
725418334Speter
725590286Sobrien(define_insn "*muldi3_1_rex64"
725690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
725790286Sobrien	(mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,0,0")
725890286Sobrien		 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
725990286Sobrien   (clobber (reg:CC 17))]
726090286Sobrien  "TARGET_64BIT
726190286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
726290286Sobrien  "@
726390286Sobrien   imul{q}\t{%2, %1, %0|%0, %1, %2}
726490286Sobrien   imul{q}\t{%2, %1, %0|%0, %1, %2}
726590286Sobrien   imul{q}\t{%2, %0|%0, %2}"
726690286Sobrien  [(set_attr "type" "imul")
726790286Sobrien   (set_attr "prefix_0f" "0,0,1")
726890286Sobrien   (set_attr "mode" "DI")])
726918334Speter
727090286Sobrien(define_expand "mulsi3"
727190286Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "")
727290286Sobrien		   (mult:SI (match_operand:SI 1 "register_operand" "")
727390286Sobrien			    (match_operand:SI 2 "general_operand" "")))
727490286Sobrien	      (clobber (reg:CC 17))])]
727518334Speter  ""
727690286Sobrien  "")
727718334Speter
727890286Sobrien(define_insn "*mulsi3_1"
727990286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
728090286Sobrien	(mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
728190286Sobrien		 (match_operand:SI 2 "general_operand" "K,i,mr")))
728290286Sobrien   (clobber (reg:CC 17))]
728390286Sobrien  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
728490286Sobrien  ; For the {r,0,i} alternative (i.e., register <- register * immediate),
728590286Sobrien  ; there are two ways of writing the exact same machine instruction
728690286Sobrien  ; in assembly language.  One, for example, is:
728790286Sobrien  ;
728890286Sobrien  ;   imul $12, %eax
728990286Sobrien  ;
729090286Sobrien  ; while the other is:
729190286Sobrien  ;
729290286Sobrien  ;   imul $12, %eax, %eax
729390286Sobrien  ;
729490286Sobrien  ; The first is simply short-hand for the latter.  But, some assemblers,
729590286Sobrien  ; like the SCO OSR5 COFF assembler, don't handle the first form.
729690286Sobrien  "@
729790286Sobrien   imul{l}\t{%2, %1, %0|%0, %1, %2}
729890286Sobrien   imul{l}\t{%2, %1, %0|%0, %1, %2}
729990286Sobrien   imul{l}\t{%2, %0|%0, %2}"
730090286Sobrien  [(set_attr "type" "imul")
730190286Sobrien   (set_attr "prefix_0f" "0,0,1")
730290286Sobrien   (set_attr "mode" "SI")])
730390286Sobrien
730490286Sobrien(define_insn "*mulsi3_1_zext"
730590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
730690286Sobrien	(zero_extend:DI
730790286Sobrien	  (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
730890286Sobrien		   (match_operand:SI 2 "general_operand" "K,i,mr"))))
730990286Sobrien   (clobber (reg:CC 17))]
731090286Sobrien  "TARGET_64BIT
731190286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
731290286Sobrien  ; For the {r,0,i} alternative (i.e., register <- register * immediate),
731390286Sobrien  ; there are two ways of writing the exact same machine instruction
731490286Sobrien  ; in assembly language.  One, for example, is:
731590286Sobrien  ;
731690286Sobrien  ;   imul $12, %eax
731790286Sobrien  ;
731890286Sobrien  ; while the other is:
731990286Sobrien  ;
732090286Sobrien  ;   imul $12, %eax, %eax
732190286Sobrien  ;
732290286Sobrien  ; The first is simply short-hand for the latter.  But, some assemblers,
732390286Sobrien  ; like the SCO OSR5 COFF assembler, don't handle the first form.
732490286Sobrien  "@
732590286Sobrien   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
732690286Sobrien   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
732790286Sobrien   imul{l}\t{%2, %k0|%k0, %2}"
732890286Sobrien  [(set_attr "type" "imul")
732990286Sobrien   (set_attr "prefix_0f" "0,0,1")
733090286Sobrien   (set_attr "mode" "SI")])
733190286Sobrien
733290286Sobrien(define_expand "mulhi3"
733390286Sobrien  [(parallel [(set (match_operand:HI 0 "register_operand" "")
733490286Sobrien		   (mult:HI (match_operand:HI 1 "register_operand" "")
733590286Sobrien			    (match_operand:HI 2 "general_operand" "")))
733690286Sobrien	      (clobber (reg:CC 17))])]
733790286Sobrien  "TARGET_HIMODE_MATH"
733890286Sobrien  "")
733990286Sobrien
734090286Sobrien(define_insn "*mulhi3_1"
734190286Sobrien  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
734290286Sobrien	(mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0")
734390286Sobrien		 (match_operand:HI 2 "general_operand" "K,i,mr")))
734490286Sobrien   (clobber (reg:CC 17))]
734590286Sobrien  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
734690286Sobrien  ; %%% There was a note about "Assembler has weird restrictions",
734790286Sobrien  ; concerning alternative 1 when op1 == op0.  True?
734890286Sobrien  "@
734990286Sobrien   imul{w}\t{%2, %1, %0|%0, %1, %2}
735090286Sobrien   imul{w}\t{%2, %1, %0|%0, %1, %2}
735190286Sobrien   imul{w}\t{%2, %0|%0, %2}"
735290286Sobrien  [(set_attr "type" "imul")
735390286Sobrien   (set_attr "prefix_0f" "0,0,1")
735490286Sobrien   (set_attr "mode" "HI")])
735590286Sobrien
735696294Sobrien(define_expand "mulqi3"
735796294Sobrien  [(parallel [(set (match_operand:QI 0 "register_operand" "")
735896294Sobrien		   (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
735996294Sobrien			    (match_operand:QI 2 "register_operand" "")))
736096294Sobrien	      (clobber (reg:CC 17))])]
736196294Sobrien  "TARGET_QIMODE_MATH"
736296294Sobrien  "")
736396294Sobrien
736496294Sobrien(define_insn "*mulqi3_1"
736590286Sobrien  [(set (match_operand:QI 0 "register_operand" "=a")
736696294Sobrien	(mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
736790286Sobrien		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
736890286Sobrien   (clobber (reg:CC 17))]
736996294Sobrien  "TARGET_QIMODE_MATH
737096294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
737190286Sobrien  "mul{b}\t%2"
737290286Sobrien  [(set_attr "type" "imul")
737390286Sobrien   (set_attr "length_immediate" "0")
737490286Sobrien   (set_attr "mode" "QI")])
737590286Sobrien
737696294Sobrien(define_expand "umulqihi3"
737796294Sobrien  [(parallel [(set (match_operand:HI 0 "register_operand" "")
737896294Sobrien		   (mult:HI (zero_extend:HI
737996294Sobrien			      (match_operand:QI 1 "nonimmediate_operand" ""))
738096294Sobrien			    (zero_extend:HI
738196294Sobrien			      (match_operand:QI 2 "register_operand" ""))))
738296294Sobrien	      (clobber (reg:CC 17))])]
738396294Sobrien  "TARGET_QIMODE_MATH"
738496294Sobrien  "")
738596294Sobrien
738696294Sobrien(define_insn "*umulqihi3_1"
738750650Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
738896294Sobrien	(mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
738990286Sobrien		 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
739090286Sobrien   (clobber (reg:CC 17))]
739196294Sobrien  "TARGET_QIMODE_MATH
739296294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
739390286Sobrien  "mul{b}\t%2"
739490286Sobrien  [(set_attr "type" "imul")
739590286Sobrien   (set_attr "length_immediate" "0")
739690286Sobrien   (set_attr "mode" "QI")])
739718334Speter
739896294Sobrien(define_expand "mulqihi3"
739996294Sobrien  [(parallel [(set (match_operand:HI 0 "register_operand" "")
740096294Sobrien		   (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
740196294Sobrien			    (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
740296294Sobrien	      (clobber (reg:CC 17))])]
740396294Sobrien  "TARGET_QIMODE_MATH"
740496294Sobrien  "")
740596294Sobrien
740696294Sobrien(define_insn "*mulqihi3_insn"
740750650Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
740896294Sobrien	(mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
740990286Sobrien		 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
741090286Sobrien   (clobber (reg:CC 17))]
741196294Sobrien  "TARGET_QIMODE_MATH
741296294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
741390286Sobrien  "imul{b}\t%2"
741490286Sobrien  [(set_attr "type" "imul")
741590286Sobrien   (set_attr "length_immediate" "0")
741690286Sobrien   (set_attr "mode" "QI")])
741718334Speter
741896294Sobrien(define_expand "umulditi3"
741996294Sobrien  [(parallel [(set (match_operand:TI 0 "register_operand" "")
742096294Sobrien		   (mult:TI (zero_extend:TI
742196294Sobrien			      (match_operand:DI 1 "nonimmediate_operand" ""))
742296294Sobrien			    (zero_extend:TI
742396294Sobrien			      (match_operand:DI 2 "register_operand" ""))))
742496294Sobrien	      (clobber (reg:CC 17))])]
742596294Sobrien  "TARGET_64BIT"
742696294Sobrien  "")
742796294Sobrien
742896294Sobrien(define_insn "*umulditi3_insn"
742990286Sobrien  [(set (match_operand:TI 0 "register_operand" "=A")
743096294Sobrien	(mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
743190286Sobrien		 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
743290286Sobrien   (clobber (reg:CC 17))]
743396294Sobrien  "TARGET_64BIT
743496294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
743590286Sobrien  "mul{q}\t%2"
743690286Sobrien  [(set_attr "type" "imul")
743790286Sobrien   (set_attr "ppro_uops" "few")
743890286Sobrien   (set_attr "length_immediate" "0")
743990286Sobrien   (set_attr "mode" "DI")])
744090286Sobrien
744190286Sobrien;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
744296294Sobrien(define_expand "umulsidi3"
744396294Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
744496294Sobrien		   (mult:DI (zero_extend:DI
744596294Sobrien			      (match_operand:SI 1 "nonimmediate_operand" ""))
744696294Sobrien			    (zero_extend:DI
744796294Sobrien			      (match_operand:SI 2 "register_operand" ""))))
744896294Sobrien	      (clobber (reg:CC 17))])]
744996294Sobrien  "!TARGET_64BIT"
745096294Sobrien  "")
745196294Sobrien
745296294Sobrien(define_insn "*umulsidi3_insn"
745318334Speter  [(set (match_operand:DI 0 "register_operand" "=A")
745496294Sobrien	(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
745590286Sobrien		 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
745690286Sobrien   (clobber (reg:CC 17))]
745796294Sobrien  "!TARGET_64BIT
745896294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
745990286Sobrien  "mul{l}\t%2"
746090286Sobrien  [(set_attr "type" "imul")
746190286Sobrien   (set_attr "ppro_uops" "few")
746290286Sobrien   (set_attr "length_immediate" "0")
746390286Sobrien   (set_attr "mode" "SI")])
746418334Speter
746596294Sobrien(define_expand "mulditi3"
746696294Sobrien  [(parallel [(set (match_operand:TI 0 "register_operand" "")
746796294Sobrien		   (mult:TI (sign_extend:TI
746896294Sobrien			      (match_operand:DI 1 "nonimmediate_operand" ""))
746996294Sobrien			    (sign_extend:TI
747096294Sobrien			      (match_operand:DI 2 "register_operand" ""))))
747196294Sobrien	      (clobber (reg:CC 17))])]
747296294Sobrien  "TARGET_64BIT"
747396294Sobrien  "")
747496294Sobrien
747596294Sobrien(define_insn "*mulditi3_insn"
747690286Sobrien  [(set (match_operand:TI 0 "register_operand" "=A")
747796294Sobrien	(mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
747890286Sobrien		 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
747990286Sobrien   (clobber (reg:CC 17))]
748096294Sobrien  "TARGET_64BIT
748196294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
748290286Sobrien  "imul{q}\t%2"
748390286Sobrien  [(set_attr "type" "imul")
748490286Sobrien   (set_attr "length_immediate" "0")
748590286Sobrien   (set_attr "mode" "DI")])
748690286Sobrien
748796294Sobrien(define_expand "mulsidi3"
748896294Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
748996294Sobrien		   (mult:DI (sign_extend:DI
749096294Sobrien			      (match_operand:SI 1 "nonimmediate_operand" ""))
749196294Sobrien			    (sign_extend:DI
749296294Sobrien			      (match_operand:SI 2 "register_operand" ""))))
749396294Sobrien	      (clobber (reg:CC 17))])]
749496294Sobrien  "!TARGET_64BIT"
749596294Sobrien  "")
749696294Sobrien
749796294Sobrien(define_insn "*mulsidi3_insn"
749818334Speter  [(set (match_operand:DI 0 "register_operand" "=A")
749996294Sobrien	(mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
750090286Sobrien		 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
750190286Sobrien   (clobber (reg:CC 17))]
750296294Sobrien  "!TARGET_64BIT
750396294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
750490286Sobrien  "imul{l}\t%2"
750590286Sobrien  [(set_attr "type" "imul")
750690286Sobrien   (set_attr "length_immediate" "0")
750790286Sobrien   (set_attr "mode" "SI")])
750818334Speter
750996294Sobrien(define_expand "umuldi3_highpart"
751096294Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
751196294Sobrien		   (truncate:DI
751296294Sobrien		     (lshiftrt:TI
751396294Sobrien		       (mult:TI (zero_extend:TI
751496294Sobrien				  (match_operand:DI 1 "nonimmediate_operand" ""))
751596294Sobrien				(zero_extend:TI
751696294Sobrien				  (match_operand:DI 2 "register_operand" "")))
751796294Sobrien		       (const_int 64))))
751896294Sobrien	      (clobber (match_scratch:DI 3 ""))
751996294Sobrien	      (clobber (reg:CC 17))])]
752096294Sobrien  "TARGET_64BIT"
752196294Sobrien  "")
752296294Sobrien
752390286Sobrien(define_insn "*umuldi3_highpart_rex64"
752490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
752590286Sobrien	(truncate:DI
752690286Sobrien	  (lshiftrt:TI
752790286Sobrien	    (mult:TI (zero_extend:TI
752896294Sobrien		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
752990286Sobrien		     (zero_extend:TI
753090286Sobrien		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
753190286Sobrien	    (const_int 64))))
753296294Sobrien   (clobber (match_scratch:DI 3 "=1"))
753390286Sobrien   (clobber (reg:CC 17))]
753496294Sobrien  "TARGET_64BIT
753596294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
753690286Sobrien  "mul{q}\t%2"
753790286Sobrien  [(set_attr "type" "imul")
753890286Sobrien   (set_attr "ppro_uops" "few")
753990286Sobrien   (set_attr "length_immediate" "0")
754090286Sobrien   (set_attr "mode" "DI")])
754190286Sobrien
754296294Sobrien(define_expand "umulsi3_highpart"
754396294Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "")
754496294Sobrien		   (truncate:SI
754596294Sobrien		     (lshiftrt:DI
754696294Sobrien		       (mult:DI (zero_extend:DI
754796294Sobrien				  (match_operand:SI 1 "nonimmediate_operand" ""))
754896294Sobrien				(zero_extend:DI
754996294Sobrien				  (match_operand:SI 2 "register_operand" "")))
755096294Sobrien		       (const_int 32))))
755196294Sobrien	      (clobber (match_scratch:SI 3 ""))
755296294Sobrien	      (clobber (reg:CC 17))])]
755396294Sobrien  ""
755496294Sobrien  "")
755596294Sobrien
755696294Sobrien(define_insn "*umulsi3_highpart_insn"
755718334Speter  [(set (match_operand:SI 0 "register_operand" "=d")
755890286Sobrien	(truncate:SI
755990286Sobrien	  (lshiftrt:DI
756090286Sobrien	    (mult:DI (zero_extend:DI
756196294Sobrien		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
756290286Sobrien		     (zero_extend:DI
756390286Sobrien		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
756490286Sobrien	    (const_int 32))))
756596294Sobrien   (clobber (match_scratch:SI 3 "=1"))
756690286Sobrien   (clobber (reg:CC 17))]
756796294Sobrien  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
756890286Sobrien  "mul{l}\t%2"
756990286Sobrien  [(set_attr "type" "imul")
757090286Sobrien   (set_attr "ppro_uops" "few")
757190286Sobrien   (set_attr "length_immediate" "0")
757290286Sobrien   (set_attr "mode" "SI")])
757318334Speter
757490286Sobrien(define_insn "*umulsi3_highpart_zext"
757590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
757690286Sobrien	(zero_extend:DI (truncate:SI
757790286Sobrien	  (lshiftrt:DI
757890286Sobrien	    (mult:DI (zero_extend:DI
757996294Sobrien		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
758090286Sobrien		     (zero_extend:DI
758190286Sobrien		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
758290286Sobrien	    (const_int 32)))))
758396294Sobrien   (clobber (match_scratch:SI 3 "=1"))
758490286Sobrien   (clobber (reg:CC 17))]
758596294Sobrien  "TARGET_64BIT
758696294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
758790286Sobrien  "mul{l}\t%2"
758890286Sobrien  [(set_attr "type" "imul")
758990286Sobrien   (set_attr "ppro_uops" "few")
759090286Sobrien   (set_attr "length_immediate" "0")
759190286Sobrien   (set_attr "mode" "SI")])
759290286Sobrien
759396294Sobrien(define_expand "smuldi3_highpart"
759496294Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
759596294Sobrien		   (truncate:DI
759696294Sobrien		     (lshiftrt:TI
759796294Sobrien		       (mult:TI (sign_extend:TI
759896294Sobrien				  (match_operand:DI 1 "nonimmediate_operand" ""))
759996294Sobrien				(sign_extend:TI
760096294Sobrien				  (match_operand:DI 2 "register_operand" "")))
760196294Sobrien		       (const_int 64))))
760296294Sobrien	      (clobber (match_scratch:DI 3 ""))
760396294Sobrien	      (clobber (reg:CC 17))])]
760496294Sobrien  "TARGET_64BIT"
760596294Sobrien  "")
760696294Sobrien
760790286Sobrien(define_insn "*smuldi3_highpart_rex64"
760890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
760990286Sobrien	(truncate:DI
761090286Sobrien	  (lshiftrt:TI
761190286Sobrien	    (mult:TI (sign_extend:TI
761296294Sobrien		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
761390286Sobrien		     (sign_extend:TI
761490286Sobrien		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
761590286Sobrien	    (const_int 64))))
761696294Sobrien   (clobber (match_scratch:DI 3 "=1"))
761790286Sobrien   (clobber (reg:CC 17))]
761896294Sobrien  "TARGET_64BIT
761996294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
762090286Sobrien  "imul{q}\t%2"
762190286Sobrien  [(set_attr "type" "imul")
762290286Sobrien   (set_attr "ppro_uops" "few")
762390286Sobrien   (set_attr "mode" "DI")])
762490286Sobrien
762596294Sobrien(define_expand "smulsi3_highpart"
762696294Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "")
762796294Sobrien		   (truncate:SI
762896294Sobrien		     (lshiftrt:DI
762996294Sobrien		       (mult:DI (sign_extend:DI
763096294Sobrien				  (match_operand:SI 1 "nonimmediate_operand" ""))
763196294Sobrien				(sign_extend:DI
763296294Sobrien				  (match_operand:SI 2 "register_operand" "")))
763396294Sobrien		       (const_int 32))))
763496294Sobrien	      (clobber (match_scratch:SI 3 ""))
763596294Sobrien	      (clobber (reg:CC 17))])]
763696294Sobrien  ""
763796294Sobrien  "")
763896294Sobrien
763996294Sobrien(define_insn "*smulsi3_highpart_insn"
764018334Speter  [(set (match_operand:SI 0 "register_operand" "=d")
764190286Sobrien	(truncate:SI
764290286Sobrien	  (lshiftrt:DI
764390286Sobrien	    (mult:DI (sign_extend:DI
764496294Sobrien		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
764590286Sobrien		     (sign_extend:DI
764690286Sobrien		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
764790286Sobrien	    (const_int 32))))
764896294Sobrien   (clobber (match_scratch:SI 3 "=1"))
764990286Sobrien   (clobber (reg:CC 17))]
765096294Sobrien  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
765190286Sobrien  "imul{l}\t%2"
765290286Sobrien  [(set_attr "type" "imul")
765390286Sobrien   (set_attr "ppro_uops" "few")
765490286Sobrien   (set_attr "mode" "SI")])
765518334Speter
765690286Sobrien(define_insn "*smulsi3_highpart_zext"
765790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
765890286Sobrien	(zero_extend:DI (truncate:SI
765990286Sobrien	  (lshiftrt:DI
766090286Sobrien	    (mult:DI (sign_extend:DI
766196294Sobrien		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
766290286Sobrien		     (sign_extend:DI
766390286Sobrien		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
766490286Sobrien	    (const_int 32)))))
766596294Sobrien   (clobber (match_scratch:SI 3 "=1"))
766690286Sobrien   (clobber (reg:CC 17))]
766796294Sobrien  "TARGET_64BIT
766896294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
766990286Sobrien  "imul{l}\t%2"
767090286Sobrien  [(set_attr "type" "imul")
767190286Sobrien   (set_attr "ppro_uops" "few")
767290286Sobrien   (set_attr "mode" "SI")])
767390286Sobrien
767418334Speter;; The patterns that match these are at the end of this file.
767518334Speter
767618334Speter(define_expand "mulxf3"
767718334Speter  [(set (match_operand:XF 0 "register_operand" "")
767850650Sobrien	(mult:XF (match_operand:XF 1 "register_operand" "")
767950650Sobrien		 (match_operand:XF 2 "register_operand" "")))]
768090286Sobrien  "!TARGET_64BIT && TARGET_80387"
768190286Sobrien  "")
768290286Sobrien
768390286Sobrien(define_expand "multf3"
768490286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
768590286Sobrien	(mult:TF (match_operand:TF 1 "register_operand" "")
768690286Sobrien		 (match_operand:TF 2 "register_operand" "")))]
768718334Speter  "TARGET_80387"
768818334Speter  "")
768918334Speter
769018334Speter(define_expand "muldf3"
769118334Speter  [(set (match_operand:DF 0 "register_operand" "")
769250650Sobrien	(mult:DF (match_operand:DF 1 "register_operand" "")
769318334Speter		 (match_operand:DF 2 "nonimmediate_operand" "")))]
769490286Sobrien  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
769518334Speter  "")
769618334Speter
769718334Speter(define_expand "mulsf3"
769818334Speter  [(set (match_operand:SF 0 "register_operand" "")
769950650Sobrien	(mult:SF (match_operand:SF 1 "register_operand" "")
770018334Speter		 (match_operand:SF 2 "nonimmediate_operand" "")))]
770190286Sobrien  "TARGET_80387 || TARGET_SSE_MATH"
770218334Speter  "")
770318334Speter
770490286Sobrien;; Divide instructions
770518334Speter
770618334Speter(define_insn "divqi3"
770750650Sobrien  [(set (match_operand:QI 0 "register_operand" "=a")
770850650Sobrien	(div:QI (match_operand:HI 1 "register_operand" "0")
770990286Sobrien		(match_operand:QI 2 "nonimmediate_operand" "qm")))
771090286Sobrien   (clobber (reg:CC 17))]
771190286Sobrien  "TARGET_QIMODE_MATH"
771290286Sobrien  "idiv{b}\t%2"
771390286Sobrien  [(set_attr "type" "idiv")
771490286Sobrien   (set_attr "mode" "QI")
771590286Sobrien   (set_attr "ppro_uops" "few")])
771618334Speter
771718334Speter(define_insn "udivqi3"
771850650Sobrien  [(set (match_operand:QI 0 "register_operand" "=a")
771950650Sobrien	(udiv:QI (match_operand:HI 1 "register_operand" "0")
772090286Sobrien		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
772190286Sobrien   (clobber (reg:CC 17))]
772290286Sobrien  "TARGET_QIMODE_MATH"
772390286Sobrien  "div{b}\t%2"
772490286Sobrien  [(set_attr "type" "idiv")
772590286Sobrien   (set_attr "mode" "QI")
772690286Sobrien   (set_attr "ppro_uops" "few")])
772718334Speter
772818334Speter;; The patterns that match these are at the end of this file.
772918334Speter
773018334Speter(define_expand "divxf3"
773118334Speter  [(set (match_operand:XF 0 "register_operand" "")
773250650Sobrien	(div:XF (match_operand:XF 1 "register_operand" "")
773350650Sobrien		(match_operand:XF 2 "register_operand" "")))]
773490286Sobrien  "!TARGET_64BIT && TARGET_80387"
773590286Sobrien  "")
773690286Sobrien
773790286Sobrien(define_expand "divtf3"
773890286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
773990286Sobrien	(div:TF (match_operand:TF 1 "register_operand" "")
774090286Sobrien		(match_operand:TF 2 "register_operand" "")))]
774118334Speter  "TARGET_80387"
774218334Speter  "")
774318334Speter
774418334Speter(define_expand "divdf3"
774518334Speter  [(set (match_operand:DF 0 "register_operand" "")
774650650Sobrien 	(div:DF (match_operand:DF 1 "register_operand" "")
774750650Sobrien 		(match_operand:DF 2 "nonimmediate_operand" "")))]
774890286Sobrien   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
774950650Sobrien   "")
775050650Sobrien 
775118334Speter(define_expand "divsf3"
775218334Speter  [(set (match_operand:SF 0 "register_operand" "")
775350650Sobrien	(div:SF (match_operand:SF 1 "register_operand" "")
775418334Speter		(match_operand:SF 2 "nonimmediate_operand" "")))]
775590286Sobrien  "TARGET_80387 || TARGET_SSE_MATH"
775618334Speter  "")
775718334Speter
775818334Speter;; Remainder instructions.
775918334Speter
776090286Sobrien(define_expand "divmoddi4"
776190286Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
776290286Sobrien		   (div:DI (match_operand:DI 1 "register_operand" "")
776390286Sobrien			   (match_operand:DI 2 "nonimmediate_operand" "")))
776490286Sobrien	      (set (match_operand:DI 3 "register_operand" "")
776590286Sobrien		   (mod:DI (match_dup 1) (match_dup 2)))
776690286Sobrien	      (clobber (reg:CC 17))])]
776790286Sobrien  "TARGET_64BIT"
776890286Sobrien  "")
776990286Sobrien
777090286Sobrien;; Allow to come the parameter in eax or edx to avoid extra moves.
777190286Sobrien;; Penalize eax case sligthly because it results in worse scheduling
777290286Sobrien;; of code.
777390286Sobrien(define_insn "*divmoddi4_nocltd_rex64"
777490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=&a,?a")
777590286Sobrien	(div:DI (match_operand:DI 2 "register_operand" "1,0")
777690286Sobrien		(match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
777790286Sobrien   (set (match_operand:DI 1 "register_operand" "=&d,&d")
777890286Sobrien	(mod:DI (match_dup 2) (match_dup 3)))
777990286Sobrien   (clobber (reg:CC 17))]
778090286Sobrien  "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
778190286Sobrien  "#"
778290286Sobrien  [(set_attr "type" "multi")])
778390286Sobrien
778490286Sobrien(define_insn "*divmoddi4_cltd_rex64"
778590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a")
778690286Sobrien	(div:DI (match_operand:DI 2 "register_operand" "a")
778790286Sobrien		(match_operand:DI 3 "nonimmediate_operand" "rm")))
778890286Sobrien   (set (match_operand:DI 1 "register_operand" "=&d")
778990286Sobrien	(mod:DI (match_dup 2) (match_dup 3)))
779090286Sobrien   (clobber (reg:CC 17))]
779190286Sobrien  "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
779290286Sobrien  "#"
779390286Sobrien  [(set_attr "type" "multi")])
779490286Sobrien
779590286Sobrien(define_insn "*divmoddi_noext_rex64"
779690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a")
779790286Sobrien	(div:DI (match_operand:DI 1 "register_operand" "0")
779890286Sobrien		(match_operand:DI 2 "nonimmediate_operand" "rm")))
779990286Sobrien   (set (match_operand:DI 3 "register_operand" "=d")
780090286Sobrien	(mod:DI (match_dup 1) (match_dup 2)))
780190286Sobrien   (use (match_operand:DI 4 "register_operand" "3"))
780290286Sobrien   (clobber (reg:CC 17))]
780390286Sobrien  "TARGET_64BIT"
780490286Sobrien  "idiv{q}\t%2"
780590286Sobrien  [(set_attr "type" "idiv")
780690286Sobrien   (set_attr "mode" "DI")
780790286Sobrien   (set_attr "ppro_uops" "few")])
780890286Sobrien
780990286Sobrien(define_split
781090286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
781190286Sobrien	(div:DI (match_operand:DI 1 "register_operand" "")
781290286Sobrien		(match_operand:DI 2 "nonimmediate_operand" "")))
781390286Sobrien   (set (match_operand:DI 3 "register_operand" "")
781490286Sobrien	(mod:DI (match_dup 1) (match_dup 2)))
781590286Sobrien   (clobber (reg:CC 17))]
781690286Sobrien  "TARGET_64BIT && reload_completed"
781790286Sobrien  [(parallel [(set (match_dup 3)
781890286Sobrien		   (ashiftrt:DI (match_dup 4) (const_int 63)))
781990286Sobrien	      (clobber (reg:CC 17))])
782090286Sobrien   (parallel [(set (match_dup 0)
782190286Sobrien	           (div:DI (reg:DI 0) (match_dup 2)))
782290286Sobrien	      (set (match_dup 3)
782390286Sobrien		   (mod:DI (reg:DI 0) (match_dup 2)))
782490286Sobrien	      (use (match_dup 3))
782590286Sobrien	      (clobber (reg:CC 17))])]
782690286Sobrien{
782790286Sobrien  /* Avoid use of cltd in favour of a mov+shift.  */
782890286Sobrien  if (!TARGET_USE_CLTD && !optimize_size)
782990286Sobrien    {
783090286Sobrien      if (true_regnum (operands[1]))
783190286Sobrien        emit_move_insn (operands[0], operands[1]);
783290286Sobrien      else
783390286Sobrien	emit_move_insn (operands[3], operands[1]);
783490286Sobrien      operands[4] = operands[3];
783590286Sobrien    }
783690286Sobrien  else
783790286Sobrien    {
783890286Sobrien      if (true_regnum (operands[1]))
783990286Sobrien	abort();
784090286Sobrien      operands[4] = operands[1];
784190286Sobrien    }
784290286Sobrien})
784390286Sobrien
784490286Sobrien
784590286Sobrien(define_expand "divmodsi4"
784690286Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "")
784790286Sobrien		   (div:SI (match_operand:SI 1 "register_operand" "")
784890286Sobrien			   (match_operand:SI 2 "nonimmediate_operand" "")))
784990286Sobrien	      (set (match_operand:SI 3 "register_operand" "")
785090286Sobrien		   (mod:SI (match_dup 1) (match_dup 2)))
785190286Sobrien	      (clobber (reg:CC 17))])]
785290286Sobrien  ""
785390286Sobrien  "")
785490286Sobrien
785590286Sobrien;; Allow to come the parameter in eax or edx to avoid extra moves.
785690286Sobrien;; Penalize eax case sligthly because it results in worse scheduling
785790286Sobrien;; of code.
785890286Sobrien(define_insn "*divmodsi4_nocltd"
785990286Sobrien  [(set (match_operand:SI 0 "register_operand" "=&a,?a")
786090286Sobrien	(div:SI (match_operand:SI 2 "register_operand" "1,0")
786190286Sobrien		(match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
786290286Sobrien   (set (match_operand:SI 1 "register_operand" "=&d,&d")
786390286Sobrien	(mod:SI (match_dup 2) (match_dup 3)))
786490286Sobrien   (clobber (reg:CC 17))]
786590286Sobrien  "!optimize_size && !TARGET_USE_CLTD"
786690286Sobrien  "#"
786790286Sobrien  [(set_attr "type" "multi")])
786890286Sobrien
786990286Sobrien(define_insn "*divmodsi4_cltd"
787018334Speter  [(set (match_operand:SI 0 "register_operand" "=a")
787190286Sobrien	(div:SI (match_operand:SI 2 "register_operand" "a")
787290286Sobrien		(match_operand:SI 3 "nonimmediate_operand" "rm")))
787390286Sobrien   (set (match_operand:SI 1 "register_operand" "=&d")
787490286Sobrien	(mod:SI (match_dup 2) (match_dup 3)))
787590286Sobrien   (clobber (reg:CC 17))]
787690286Sobrien  "optimize_size || TARGET_USE_CLTD"
787790286Sobrien  "#"
787890286Sobrien  [(set_attr "type" "multi")])
787990286Sobrien
788090286Sobrien(define_insn "*divmodsi_noext"
788190286Sobrien  [(set (match_operand:SI 0 "register_operand" "=a")
788218334Speter	(div:SI (match_operand:SI 1 "register_operand" "0")
788350650Sobrien		(match_operand:SI 2 "nonimmediate_operand" "rm")))
788490286Sobrien   (set (match_operand:SI 3 "register_operand" "=d")
788590286Sobrien	(mod:SI (match_dup 1) (match_dup 2)))
788690286Sobrien   (use (match_operand:SI 4 "register_operand" "3"))
788790286Sobrien   (clobber (reg:CC 17))]
788818334Speter  ""
788990286Sobrien  "idiv{l}\t%2"
789090286Sobrien  [(set_attr "type" "idiv")
789190286Sobrien   (set_attr "mode" "SI")
789290286Sobrien   (set_attr "ppro_uops" "few")])
789390286Sobrien
789490286Sobrien(define_split
789590286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
789690286Sobrien	(div:SI (match_operand:SI 1 "register_operand" "")
789790286Sobrien		(match_operand:SI 2 "nonimmediate_operand" "")))
789890286Sobrien   (set (match_operand:SI 3 "register_operand" "")
789990286Sobrien	(mod:SI (match_dup 1) (match_dup 2)))
790090286Sobrien   (clobber (reg:CC 17))]
790190286Sobrien  "reload_completed"
790290286Sobrien  [(parallel [(set (match_dup 3)
790390286Sobrien		   (ashiftrt:SI (match_dup 4) (const_int 31)))
790490286Sobrien	      (clobber (reg:CC 17))])
790590286Sobrien   (parallel [(set (match_dup 0)
790690286Sobrien	           (div:SI (reg:SI 0) (match_dup 2)))
790790286Sobrien	      (set (match_dup 3)
790890286Sobrien		   (mod:SI (reg:SI 0) (match_dup 2)))
790990286Sobrien	      (use (match_dup 3))
791090286Sobrien	      (clobber (reg:CC 17))])]
791118334Speter{
791290286Sobrien  /* Avoid use of cltd in favour of a mov+shift.  */
791390286Sobrien  if (!TARGET_USE_CLTD && !optimize_size)
791490286Sobrien    {
791590286Sobrien      if (true_regnum (operands[1]))
791690286Sobrien        emit_move_insn (operands[0], operands[1]);
791790286Sobrien      else
791890286Sobrien	emit_move_insn (operands[3], operands[1]);
791990286Sobrien      operands[4] = operands[3];
792090286Sobrien    }
792190286Sobrien  else
792290286Sobrien    {
792390286Sobrien      if (true_regnum (operands[1]))
792490286Sobrien	abort();
792590286Sobrien      operands[4] = operands[1];
792690286Sobrien    }
792790286Sobrien})
792890286Sobrien;; %%% Split me.
792918334Speter(define_insn "divmodhi4"
793018334Speter  [(set (match_operand:HI 0 "register_operand" "=a")
793118334Speter	(div:HI (match_operand:HI 1 "register_operand" "0")
793250650Sobrien		(match_operand:HI 2 "nonimmediate_operand" "rm")))
793318334Speter   (set (match_operand:HI 3 "register_operand" "=&d")
793490286Sobrien	(mod:HI (match_dup 1) (match_dup 2)))
793590286Sobrien   (clobber (reg:CC 17))]
793690286Sobrien  "TARGET_HIMODE_MATH"
793790286Sobrien  "cwtd\;idiv{w}\t%2"
793890286Sobrien  [(set_attr "type" "multi")
793990286Sobrien   (set_attr "length_immediate" "0")
794090286Sobrien   (set_attr "mode" "SI")])
794118334Speter
794290286Sobrien(define_insn "udivmoddi4"
794390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a")
794490286Sobrien	(udiv:DI (match_operand:DI 1 "register_operand" "0")
794590286Sobrien		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
794690286Sobrien   (set (match_operand:DI 3 "register_operand" "=&d")
794790286Sobrien	(umod:DI (match_dup 1) (match_dup 2)))
794890286Sobrien   (clobber (reg:CC 17))]
794990286Sobrien  "TARGET_64BIT"
795090286Sobrien  "xor{q}\t%3, %3\;div{q}\t%2"
795190286Sobrien  [(set_attr "type" "multi")
795290286Sobrien   (set_attr "length_immediate" "0")
795390286Sobrien   (set_attr "mode" "DI")])
795490286Sobrien
795590286Sobrien(define_insn "*udivmoddi4_noext"
795690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a")
795790286Sobrien	(udiv:DI (match_operand:DI 1 "register_operand" "0")
795890286Sobrien		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
795990286Sobrien   (set (match_operand:DI 3 "register_operand" "=d")
796090286Sobrien	(umod:DI (match_dup 1) (match_dup 2)))
796190286Sobrien   (use (match_dup 3))
796290286Sobrien   (clobber (reg:CC 17))]
796390286Sobrien  "TARGET_64BIT"
796490286Sobrien  "div{q}\t%2"
796590286Sobrien  [(set_attr "type" "idiv")
796690286Sobrien   (set_attr "ppro_uops" "few")
796790286Sobrien   (set_attr "mode" "DI")])
796890286Sobrien
796990286Sobrien(define_split
797090286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
797190286Sobrien	(udiv:DI (match_operand:DI 1 "register_operand" "")
797290286Sobrien		 (match_operand:DI 2 "nonimmediate_operand" "")))
797390286Sobrien   (set (match_operand:DI 3 "register_operand" "")
797490286Sobrien	(umod:DI (match_dup 1) (match_dup 2)))
797590286Sobrien   (clobber (reg:CC 17))]
797690286Sobrien  "TARGET_64BIT && reload_completed"
797790286Sobrien  [(set (match_dup 3) (const_int 0))
797890286Sobrien   (parallel [(set (match_dup 0)
797990286Sobrien		   (udiv:DI (match_dup 1) (match_dup 2)))
798090286Sobrien	      (set (match_dup 3)
798190286Sobrien		   (umod:DI (match_dup 1) (match_dup 2)))
798290286Sobrien	      (use (match_dup 3))
798390286Sobrien	      (clobber (reg:CC 17))])]
798490286Sobrien  "")
798590286Sobrien
798618334Speter(define_insn "udivmodsi4"
798718334Speter  [(set (match_operand:SI 0 "register_operand" "=a")
798818334Speter	(udiv:SI (match_operand:SI 1 "register_operand" "0")
798950650Sobrien		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
799018334Speter   (set (match_operand:SI 3 "register_operand" "=&d")
799190286Sobrien	(umod:SI (match_dup 1) (match_dup 2)))
799290286Sobrien   (clobber (reg:CC 17))]
799318334Speter  ""
799490286Sobrien  "xor{l}\t%3, %3\;div{l}\t%2"
799590286Sobrien  [(set_attr "type" "multi")
799690286Sobrien   (set_attr "length_immediate" "0")
799790286Sobrien   (set_attr "mode" "SI")])
799818334Speter
799990286Sobrien(define_insn "*udivmodsi4_noext"
800090286Sobrien  [(set (match_operand:SI 0 "register_operand" "=a")
800190286Sobrien	(udiv:SI (match_operand:SI 1 "register_operand" "0")
800290286Sobrien		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
800390286Sobrien   (set (match_operand:SI 3 "register_operand" "=d")
800490286Sobrien	(umod:SI (match_dup 1) (match_dup 2)))
800590286Sobrien   (use (match_dup 3))
800690286Sobrien   (clobber (reg:CC 17))]
800790286Sobrien  ""
800890286Sobrien  "div{l}\t%2"
800990286Sobrien  [(set_attr "type" "idiv")
801090286Sobrien   (set_attr "ppro_uops" "few")
801190286Sobrien   (set_attr "mode" "SI")])
801290286Sobrien
801390286Sobrien(define_split
801490286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
801590286Sobrien	(udiv:SI (match_operand:SI 1 "register_operand" "")
801690286Sobrien		 (match_operand:SI 2 "nonimmediate_operand" "")))
801790286Sobrien   (set (match_operand:SI 3 "register_operand" "")
801890286Sobrien	(umod:SI (match_dup 1) (match_dup 2)))
801990286Sobrien   (clobber (reg:CC 17))]
802090286Sobrien  "reload_completed"
802190286Sobrien  [(set (match_dup 3) (const_int 0))
802290286Sobrien   (parallel [(set (match_dup 0)
802390286Sobrien		   (udiv:SI (match_dup 1) (match_dup 2)))
802490286Sobrien	      (set (match_dup 3)
802590286Sobrien		   (umod:SI (match_dup 1) (match_dup 2)))
802690286Sobrien	      (use (match_dup 3))
802790286Sobrien	      (clobber (reg:CC 17))])]
802890286Sobrien  "")
802990286Sobrien
803090286Sobrien(define_expand "udivmodhi4"
803190286Sobrien  [(set (match_dup 4) (const_int 0))
803290286Sobrien   (parallel [(set (match_operand:HI 0 "register_operand" "")
803390286Sobrien		   (udiv:HI (match_operand:HI 1 "register_operand" "")
803490286Sobrien		 	    (match_operand:HI 2 "nonimmediate_operand" "")))
803590286Sobrien	      (set (match_operand:HI 3 "register_operand" "")
803690286Sobrien	   	   (umod:HI (match_dup 1) (match_dup 2)))
803790286Sobrien	      (use (match_dup 4))
803890286Sobrien	      (clobber (reg:CC 17))])]
803990286Sobrien  "TARGET_HIMODE_MATH"
804090286Sobrien  "operands[4] = gen_reg_rtx (HImode);")
804190286Sobrien
804290286Sobrien(define_insn "*udivmodhi_noext"
804318334Speter  [(set (match_operand:HI 0 "register_operand" "=a")
804418334Speter	(udiv:HI (match_operand:HI 1 "register_operand" "0")
804550650Sobrien		 (match_operand:HI 2 "nonimmediate_operand" "rm")))
804690286Sobrien   (set (match_operand:HI 3 "register_operand" "=d")
804790286Sobrien	(umod:HI (match_dup 1) (match_dup 2)))
804890286Sobrien   (use (match_operand:HI 4 "register_operand" "3"))
804990286Sobrien   (clobber (reg:CC 17))]
805018334Speter  ""
805190286Sobrien  "div{w}\t%2"
805290286Sobrien  [(set_attr "type" "idiv")
805390286Sobrien   (set_attr "mode" "HI")
805490286Sobrien   (set_attr "ppro_uops" "few")])
805518334Speter
805690286Sobrien;; We can not use div/idiv for double division, because it causes
805790286Sobrien;; "division by zero" on the overflow and that's not what we expect
805890286Sobrien;; from truncate.  Because true (non truncating) double division is
805990286Sobrien;; never generated, we can't create this insn anyway.
806090286Sobrien;
806190286Sobrien;(define_insn ""
806290286Sobrien;  [(set (match_operand:SI 0 "register_operand" "=a")
806390286Sobrien;	(truncate:SI
806490286Sobrien;	  (udiv:DI (match_operand:DI 1 "register_operand" "A")
806590286Sobrien;		   (zero_extend:DI
806690286Sobrien;		     (match_operand:SI 2 "nonimmediate_operand" "rm")))))
806790286Sobrien;   (set (match_operand:SI 3 "register_operand" "=d")
806890286Sobrien;	(truncate:SI
806990286Sobrien;	  (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
807090286Sobrien;   (clobber (reg:CC 17))]
807190286Sobrien;  ""
807290286Sobrien;  "div{l}\t{%2, %0|%0, %2}"
807390286Sobrien;  [(set_attr "type" "idiv")
807490286Sobrien;   (set_attr "ppro_uops" "few")])
807590286Sobrien
807690286Sobrien;;- Logical AND instructions
807718334Speter
807890286Sobrien;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
807990286Sobrien;; Note that this excludes ah.
808090286Sobrien
808190286Sobrien(define_insn "*testdi_1_rex64"
808290286Sobrien  [(set (reg 17)
808390286Sobrien	(compare
808490286Sobrien	  (and:DI (match_operand:DI 0 "nonimmediate_operand" "%*a,r,*a,r,rm")
808590286Sobrien		  (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,Z,e,e,re"))
808690286Sobrien	  (const_int 0)))]
808790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
808890286Sobrien  "@
808990286Sobrien   test{l}\t{%k1, %k0|%k0, %k1} 
809090286Sobrien   test{l}\t{%k1, %k0|%k0, %k1} 
809190286Sobrien   test{q}\t{%1, %0|%0, %1} 
809290286Sobrien   test{q}\t{%1, %0|%0, %1} 
809390286Sobrien   test{q}\t{%1, %0|%0, %1}"
809490286Sobrien  [(set_attr "type" "test")
809590286Sobrien   (set_attr "modrm" "0,1,0,1,1")
809690286Sobrien   (set_attr "mode" "SI,SI,DI,DI,DI")
809790286Sobrien   (set_attr "pent_pair" "uv,np,uv,np,uv")])
809890286Sobrien
809990286Sobrien(define_insn "testsi_1"
810090286Sobrien  [(set (reg 17)
810190286Sobrien	(compare
810290286Sobrien	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
810390286Sobrien		  (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
810490286Sobrien	  (const_int 0)))]
810590286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
810690286Sobrien  "test{l}\t{%1, %0|%0, %1}"
810790286Sobrien  [(set_attr "type" "test")
810890286Sobrien   (set_attr "modrm" "0,1,1")
810990286Sobrien   (set_attr "mode" "SI")
811090286Sobrien   (set_attr "pent_pair" "uv,np,uv")])
811190286Sobrien
811290286Sobrien(define_expand "testsi_ccno_1"
811390286Sobrien  [(set (reg:CCNO 17)
811490286Sobrien	(compare:CCNO
811590286Sobrien	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
811690286Sobrien		  (match_operand:SI 1 "nonmemory_operand" ""))
811790286Sobrien	  (const_int 0)))]
811818334Speter  ""
811990286Sobrien  "")
812018334Speter
812190286Sobrien(define_insn "*testhi_1"
812290286Sobrien  [(set (reg 17)
812390286Sobrien        (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
812490286Sobrien			 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
812590286Sobrien		 (const_int 0)))]
812690286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
812790286Sobrien  "test{w}\t{%1, %0|%0, %1}"
812890286Sobrien  [(set_attr "type" "test")
812990286Sobrien   (set_attr "modrm" "0,1,1")
813090286Sobrien   (set_attr "mode" "HI")
813190286Sobrien   (set_attr "pent_pair" "uv,np,uv")])
813218334Speter
813390286Sobrien(define_expand "testqi_ccz_1"
813490286Sobrien  [(set (reg:CCZ 17)
813590286Sobrien        (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
813690286Sobrien			     (match_operand:QI 1 "nonmemory_operand" ""))
813790286Sobrien		 (const_int 0)))]
813890286Sobrien  ""
813990286Sobrien  "")
814018334Speter
814190286Sobrien(define_insn "*testqi_1"
814290286Sobrien  [(set (reg 17)
814390286Sobrien        (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
814490286Sobrien			 (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
814590286Sobrien		 (const_int 0)))]
814690286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
814718334Speter{
814890286Sobrien  if (which_alternative == 3)
814918334Speter    {
815090286Sobrien      if (GET_CODE (operands[1]) == CONST_INT
815190286Sobrien	  && (INTVAL (operands[1]) & 0xffffff00))
815290286Sobrien	operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
815390286Sobrien      return "test{l}\t{%1, %k0|%k0, %1}";
815450650Sobrien    }
815590286Sobrien  return "test{b}\t{%1, %0|%0, %1}";
815690286Sobrien}
815790286Sobrien  [(set_attr "type" "test")
815890286Sobrien   (set_attr "modrm" "0,1,1,1")
815990286Sobrien   (set_attr "mode" "QI,QI,QI,SI")
816090286Sobrien   (set_attr "pent_pair" "uv,np,uv,np")])
816118334Speter
816290286Sobrien(define_expand "testqi_ext_ccno_0"
816390286Sobrien  [(set (reg:CCNO 17)
816490286Sobrien	(compare:CCNO
816590286Sobrien	  (and:SI
816690286Sobrien	    (zero_extract:SI
816790286Sobrien	      (match_operand 0 "ext_register_operand" "")
816890286Sobrien	      (const_int 8)
816990286Sobrien	      (const_int 8))
817090286Sobrien	    (match_operand 1 "const_int_operand" ""))
817190286Sobrien	  (const_int 0)))]
817290286Sobrien  ""
817390286Sobrien  "")
817418334Speter
817590286Sobrien(define_insn "*testqi_ext_0"
817690286Sobrien  [(set (reg 17)
817790286Sobrien	(compare
817890286Sobrien	  (and:SI
817990286Sobrien	    (zero_extract:SI
818090286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
818190286Sobrien	      (const_int 8)
818290286Sobrien	      (const_int 8))
818390286Sobrien	    (match_operand 1 "const_int_operand" "n"))
818490286Sobrien	  (const_int 0)))]
818590286Sobrien  "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff
818690286Sobrien   && ix86_match_ccmode (insn, CCNOmode)"
818790286Sobrien  "test{b}\t{%1, %h0|%h0, %1}"
818890286Sobrien  [(set_attr "type" "test")
818990286Sobrien   (set_attr "mode" "QI")
819090286Sobrien   (set_attr "length_immediate" "1")
819190286Sobrien   (set_attr "pent_pair" "np")])
819250650Sobrien
819390286Sobrien(define_insn "*testqi_ext_1"
819490286Sobrien  [(set (reg 17)
819590286Sobrien	(compare
819690286Sobrien	  (and:SI
819790286Sobrien	    (zero_extract:SI
819890286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
819990286Sobrien	      (const_int 8)
820090286Sobrien	      (const_int 8))
820190286Sobrien	    (zero_extend:SI
820290286Sobrien	      (match_operand:QI 1 "nonimmediate_operand" "Qm")))
820390286Sobrien	  (const_int 0)))]
820490286Sobrien  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
820590286Sobrien  "test{b}\t{%1, %h0|%h0, %1}"
820690286Sobrien  [(set_attr "type" "test")
820790286Sobrien   (set_attr "mode" "QI")])
820818334Speter
820990286Sobrien(define_insn "*testqi_ext_1_rex64"
821090286Sobrien  [(set (reg 17)
821190286Sobrien	(compare
821290286Sobrien	  (and:SI
821390286Sobrien	    (zero_extract:SI
821490286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
821590286Sobrien	      (const_int 8)
821690286Sobrien	      (const_int 8))
821790286Sobrien	    (zero_extend:SI
821890286Sobrien	      (match_operand:QI 1 "register_operand" "Q")))
821990286Sobrien	  (const_int 0)))]
822090286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
822190286Sobrien  "test{b}\t{%1, %h0|%h0, %1}"
822290286Sobrien  [(set_attr "type" "test")
822390286Sobrien   (set_attr "mode" "QI")])
822418334Speter
822590286Sobrien(define_insn "*testqi_ext_2"
822690286Sobrien  [(set (reg 17)
822790286Sobrien	(compare
822890286Sobrien	  (and:SI
822990286Sobrien	    (zero_extract:SI
823090286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
823190286Sobrien	      (const_int 8)
823290286Sobrien	      (const_int 8))
823390286Sobrien	    (zero_extract:SI
823490286Sobrien	      (match_operand 1 "ext_register_operand" "Q")
823590286Sobrien	      (const_int 8)
823690286Sobrien	      (const_int 8)))
823790286Sobrien	  (const_int 0)))]
823890286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
823990286Sobrien  "test{b}\t{%h1, %h0|%h0, %h1}"
824090286Sobrien  [(set_attr "type" "test")
824190286Sobrien   (set_attr "mode" "QI")])
824250650Sobrien
824390286Sobrien;; Combine likes to form bit extractions for some tests.  Humor it.
824490286Sobrien(define_insn "*testqi_ext_3"
824590286Sobrien  [(set (reg 17)
824690286Sobrien        (compare (zero_extract:SI
824790286Sobrien		   (match_operand 0 "nonimmediate_operand" "rm")
824890286Sobrien		   (match_operand:SI 1 "const_int_operand" "")
824990286Sobrien		   (match_operand:SI 2 "const_int_operand" ""))
825090286Sobrien		 (const_int 0)))]
825190286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
825290286Sobrien   && (GET_MODE (operands[0]) == SImode
825390286Sobrien       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
825490286Sobrien       || GET_MODE (operands[0]) == HImode
825590286Sobrien       || GET_MODE (operands[0]) == QImode)"
825690286Sobrien  "#")
825750650Sobrien
825890286Sobrien(define_insn "*testqi_ext_3_rex64"
825990286Sobrien  [(set (reg 17)
826090286Sobrien        (compare (zero_extract:DI
826190286Sobrien		   (match_operand 0 "nonimmediate_operand" "rm")
826290286Sobrien		   (match_operand:DI 1 "const_int_operand" "")
826390286Sobrien		   (match_operand:DI 2 "const_int_operand" ""))
826490286Sobrien		 (const_int 0)))]
826590286Sobrien  "TARGET_64BIT
826690286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
826790286Sobrien   /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
826890286Sobrien   && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
826990286Sobrien   /* Ensure that resulting mask is zero or sign extended operand.  */
827090286Sobrien   && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
827190286Sobrien       || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
827290286Sobrien	   && INTVAL (operands[1]) > 32))
827390286Sobrien   && (GET_MODE (operands[0]) == SImode
827490286Sobrien       || GET_MODE (operands[0]) == DImode
827590286Sobrien       || GET_MODE (operands[0]) == HImode
827690286Sobrien       || GET_MODE (operands[0]) == QImode)"
827790286Sobrien  "#")
827850650Sobrien
827990286Sobrien(define_split
828090286Sobrien  [(set (reg 17)
828190286Sobrien        (compare (zero_extract
828290286Sobrien		   (match_operand 0 "nonimmediate_operand" "")
828390286Sobrien		   (match_operand 1 "const_int_operand" "")
828490286Sobrien		   (match_operand 2 "const_int_operand" ""))
828590286Sobrien		 (const_int 0)))]
828690286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
828790286Sobrien  [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
828890286Sobrien{
828990286Sobrien  HOST_WIDE_INT len = INTVAL (operands[1]);
829090286Sobrien  HOST_WIDE_INT pos = INTVAL (operands[2]);
829190286Sobrien  HOST_WIDE_INT mask;
829290286Sobrien  enum machine_mode mode, submode;
829318334Speter
829490286Sobrien  mode = GET_MODE (operands[0]);
829590286Sobrien  if (GET_CODE (operands[0]) == MEM)
829690286Sobrien    {
829790286Sobrien      /* ??? Combine likes to put non-volatile mem extractions in QImode
829890286Sobrien	 no matter the size of the test.  So find a mode that works.  */
829990286Sobrien      if (! MEM_VOLATILE_P (operands[0]))
830018334Speter	{
830190286Sobrien	  mode = smallest_mode_for_size (pos + len, MODE_INT);
830290286Sobrien	  operands[0] = adjust_address (operands[0], mode, 0);
830390286Sobrien	}
830490286Sobrien    }
830590286Sobrien  else if (GET_CODE (operands[0]) == SUBREG
830690286Sobrien	   && (submode = GET_MODE (SUBREG_REG (operands[0])),
830790286Sobrien	       GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
830890286Sobrien	   && pos + len <= GET_MODE_BITSIZE (submode))
830990286Sobrien    {
831090286Sobrien      /* Narrow a paradoxical subreg to prevent partial register stalls.  */
831190286Sobrien      mode = submode;
831290286Sobrien      operands[0] = SUBREG_REG (operands[0]);
831390286Sobrien    }
831490286Sobrien  else if (mode == HImode && pos + len <= 8)
831590286Sobrien    {
831690286Sobrien      /* Small HImode tests can be converted to QImode.  */
831790286Sobrien      mode = QImode;
831890286Sobrien      operands[0] = gen_lowpart (QImode, operands[0]);
831990286Sobrien    }
832018334Speter
832190286Sobrien  mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
832290286Sobrien  mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
832318334Speter
832490286Sobrien  operands[3] = gen_rtx_AND (mode, operands[0],
832590286Sobrien			     GEN_INT (trunc_int_for_mode (mask, mode)));
832690286Sobrien})
832750650Sobrien
832890286Sobrien;; %%% This used to optimize known byte-wide and operations to memory,
832990286Sobrien;; and sometimes to QImode registers.  If this is considered useful,
833090286Sobrien;; it should be done with splitters.
833118334Speter
833290286Sobrien(define_expand "anddi3"
833390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
833490286Sobrien	(and:DI (match_operand:DI 1 "nonimmediate_operand" "")
833590286Sobrien		(match_operand:DI 2 "x86_64_szext_general_operand" "")))
833690286Sobrien   (clobber (reg:CC 17))]
833790286Sobrien  "TARGET_64BIT"
833890286Sobrien  "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
833950650Sobrien
834090286Sobrien(define_insn "*anddi_1_rex64"
834190286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
834290286Sobrien	(and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
834390286Sobrien		(match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
834490286Sobrien   (clobber (reg:CC 17))]
834590286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
834690286Sobrien{
834790286Sobrien  switch (get_attr_type (insn))
834890286Sobrien    {
834990286Sobrien    case TYPE_IMOVX:
835090286Sobrien      {
835190286Sobrien	enum machine_mode mode;
835250650Sobrien
835390286Sobrien	if (GET_CODE (operands[2]) != CONST_INT)
835490286Sobrien	  abort ();
835590286Sobrien        if (INTVAL (operands[2]) == 0xff)
835690286Sobrien	  mode = QImode;
835790286Sobrien	else if (INTVAL (operands[2]) == 0xffff)
835890286Sobrien	  mode = HImode;
835990286Sobrien	else
836090286Sobrien	  abort ();
836190286Sobrien	
836290286Sobrien	operands[1] = gen_lowpart (mode, operands[1]);
836390286Sobrien	if (mode == QImode)
836490286Sobrien	  return "movz{bq|x}\t{%1,%0|%0, %1}";
836590286Sobrien	else
836690286Sobrien	  return "movz{wq|x}\t{%1,%0|%0, %1}";
836790286Sobrien      }
836850650Sobrien
836950650Sobrien    default:
837090286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
837190286Sobrien	abort ();
837290286Sobrien      if (get_attr_mode (insn) == MODE_SI)
837390286Sobrien	return "and{l}\t{%k2, %k0|%k0, %k2}";
837490286Sobrien      else
837590286Sobrien	return "and{q}\t{%2, %0|%0, %2}";
837618334Speter    }
837790286Sobrien}
837890286Sobrien  [(set_attr "type" "alu,alu,alu,imovx")
837990286Sobrien   (set_attr "length_immediate" "*,*,*,0")
838090286Sobrien   (set_attr "mode" "SI,DI,DI,DI")])
838118334Speter
838290286Sobrien(define_insn "*anddi_2"
838390286Sobrien  [(set (reg 17)
838490286Sobrien	(compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
838590286Sobrien			 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
838690286Sobrien		 (const_int 0)))
838790286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
838890286Sobrien	(and:DI (match_dup 1) (match_dup 2)))]
838990286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
839090286Sobrien   && ix86_binary_operator_ok (AND, DImode, operands)"
839190286Sobrien  "@
839290286Sobrien   and{l}\t{%k2, %k0|%k0, %k2} 
839390286Sobrien   and{q}\t{%2, %0|%0, %2} 
839490286Sobrien   and{q}\t{%2, %0|%0, %2}"
839590286Sobrien  [(set_attr "type" "alu")
839690286Sobrien   (set_attr "mode" "SI,DI,DI")])
839718334Speter
839890286Sobrien(define_expand "andsi3"
839990286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
840090286Sobrien	(and:SI (match_operand:SI 1 "nonimmediate_operand" "")
840190286Sobrien		(match_operand:SI 2 "general_operand" "")))
840290286Sobrien   (clobber (reg:CC 17))]
840318334Speter  ""
840490286Sobrien  "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
840590286Sobrien
840690286Sobrien(define_insn "*andsi_1"
840790286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
840890286Sobrien	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
840990286Sobrien		(match_operand:SI 2 "general_operand" "ri,rm,L")))
841090286Sobrien   (clobber (reg:CC 17))]
841190286Sobrien  "ix86_binary_operator_ok (AND, SImode, operands)"
841218334Speter{
841390286Sobrien  switch (get_attr_type (insn))
841418334Speter    {
841590286Sobrien    case TYPE_IMOVX:
841690286Sobrien      {
841790286Sobrien	enum machine_mode mode;
841818334Speter
841990286Sobrien	if (GET_CODE (operands[2]) != CONST_INT)
842090286Sobrien	  abort ();
842190286Sobrien        if (INTVAL (operands[2]) == 0xff)
842290286Sobrien	  mode = QImode;
842390286Sobrien	else if (INTVAL (operands[2]) == 0xffff)
842490286Sobrien	  mode = HImode;
842590286Sobrien	else
842690286Sobrien	  abort ();
842790286Sobrien	
842890286Sobrien	operands[1] = gen_lowpart (mode, operands[1]);
842990286Sobrien	if (mode == QImode)
843090286Sobrien	  return "movz{bl|x}\t{%1,%0|%0, %1}";
843190286Sobrien	else
843290286Sobrien	  return "movz{wl|x}\t{%1,%0|%0, %1}";
843390286Sobrien      }
843418334Speter
843590286Sobrien    default:
843690286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
843790286Sobrien	abort ();
843890286Sobrien      return "and{l}\t{%2, %0|%0, %2}";
843990286Sobrien    }
844090286Sobrien}
844190286Sobrien  [(set_attr "type" "alu,alu,imovx")
844290286Sobrien   (set_attr "length_immediate" "*,*,0")
844390286Sobrien   (set_attr "mode" "SI")])
844418334Speter
844590286Sobrien(define_split
844690286Sobrien  [(set (match_operand 0 "register_operand" "")
844790286Sobrien	(and (match_dup 0)
844890286Sobrien	     (const_int -65536)))
844990286Sobrien   (clobber (reg:CC 17))]
845090286Sobrien  "optimize_size"
845190286Sobrien  [(set (strict_low_part (match_dup 1)) (const_int 0))]
845290286Sobrien  "operands[1] = gen_lowpart (HImode, operands[0]);")
845318334Speter
845490286Sobrien(define_split
845590286Sobrien  [(set (match_operand 0 "ext_register_operand" "")
845690286Sobrien	(and (match_dup 0)
845790286Sobrien	     (const_int -256)))
845890286Sobrien   (clobber (reg:CC 17))]
845990286Sobrien  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
846090286Sobrien  [(set (strict_low_part (match_dup 1)) (const_int 0))]
846190286Sobrien  "operands[1] = gen_lowpart (QImode, operands[0]);")
846218334Speter
846390286Sobrien(define_split
846490286Sobrien  [(set (match_operand 0 "ext_register_operand" "")
846590286Sobrien	(and (match_dup 0)
846690286Sobrien	     (const_int -65281)))
846790286Sobrien   (clobber (reg:CC 17))]
846890286Sobrien  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
846990286Sobrien  [(parallel [(set (zero_extract:SI (match_dup 0)
847090286Sobrien				    (const_int 8)
847190286Sobrien				    (const_int 8))
847290286Sobrien		   (xor:SI 
847390286Sobrien		     (zero_extract:SI (match_dup 0)
847490286Sobrien				      (const_int 8)
847590286Sobrien				      (const_int 8))
847690286Sobrien		     (zero_extract:SI (match_dup 0)
847790286Sobrien				      (const_int 8)
847890286Sobrien				      (const_int 8))))
847990286Sobrien	      (clobber (reg:CC 17))])]
848090286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);")
848150650Sobrien
848290286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
848390286Sobrien(define_insn "*andsi_1_zext"
848490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
848590286Sobrien	(zero_extend:DI
848690286Sobrien	  (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
848790286Sobrien		  (match_operand:SI 2 "general_operand" "rim"))))
848890286Sobrien   (clobber (reg:CC 17))]
848990286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
849090286Sobrien  "and{l}\t{%2, %k0|%k0, %2}"
849190286Sobrien  [(set_attr "type" "alu")
849290286Sobrien   (set_attr "mode" "SI")])
849318334Speter
849490286Sobrien(define_insn "*andsi_2"
849590286Sobrien  [(set (reg 17)
849690286Sobrien	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
849790286Sobrien			 (match_operand:SI 2 "general_operand" "rim,ri"))
849890286Sobrien		 (const_int 0)))
849990286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
850090286Sobrien	(and:SI (match_dup 1) (match_dup 2)))]
850190286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
850290286Sobrien   && ix86_binary_operator_ok (AND, SImode, operands)"
850390286Sobrien  "and{l}\t{%2, %0|%0, %2}"
850490286Sobrien  [(set_attr "type" "alu")
850590286Sobrien   (set_attr "mode" "SI")])
850690286Sobrien
850790286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
850890286Sobrien(define_insn "*andsi_2_zext"
850990286Sobrien  [(set (reg 17)
851090286Sobrien	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
851190286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
851290286Sobrien		 (const_int 0)))
851390286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
851490286Sobrien	(zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
851590286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
851690286Sobrien   && ix86_binary_operator_ok (AND, SImode, operands)"
851790286Sobrien  "and{l}\t{%2, %k0|%k0, %2}"
851890286Sobrien  [(set_attr "type" "alu")
851990286Sobrien   (set_attr "mode" "SI")])
852090286Sobrien
852190286Sobrien(define_expand "andhi3"
852290286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
852390286Sobrien	(and:HI (match_operand:HI 1 "nonimmediate_operand" "")
852490286Sobrien		(match_operand:HI 2 "general_operand" "")))
852590286Sobrien   (clobber (reg:CC 17))]
852690286Sobrien  "TARGET_HIMODE_MATH"
852790286Sobrien  "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
852890286Sobrien
852990286Sobrien(define_insn "*andhi_1"
853090286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
853190286Sobrien	(and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
853290286Sobrien		(match_operand:HI 2 "general_operand" "ri,rm,L")))
853390286Sobrien   (clobber (reg:CC 17))]
853490286Sobrien  "ix86_binary_operator_ok (AND, HImode, operands)"
853590286Sobrien{
853690286Sobrien  switch (get_attr_type (insn))
853750650Sobrien    {
853890286Sobrien    case TYPE_IMOVX:
853990286Sobrien      if (GET_CODE (operands[2]) != CONST_INT)
854090286Sobrien	abort ();
854190286Sobrien      if (INTVAL (operands[2]) == 0xff)
854290286Sobrien	return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
854390286Sobrien      abort ();
854490286Sobrien
854590286Sobrien    default:
854690286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
854790286Sobrien	abort ();
854890286Sobrien
854990286Sobrien      return "and{w}\t{%2, %0|%0, %2}";
855050650Sobrien    }
855190286Sobrien}
855290286Sobrien  [(set_attr "type" "alu,alu,imovx")
855390286Sobrien   (set_attr "length_immediate" "*,*,0")
855490286Sobrien   (set_attr "mode" "HI,HI,SI")])
855550650Sobrien
855690286Sobrien(define_insn "*andhi_2"
855790286Sobrien  [(set (reg 17)
855890286Sobrien	(compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
855990286Sobrien			 (match_operand:HI 2 "general_operand" "rim,ri"))
856090286Sobrien		 (const_int 0)))
856190286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
856290286Sobrien	(and:HI (match_dup 1) (match_dup 2)))]
856390286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
856490286Sobrien   && ix86_binary_operator_ok (AND, HImode, operands)"
856590286Sobrien  "and{w}\t{%2, %0|%0, %2}"
856690286Sobrien  [(set_attr "type" "alu")
856790286Sobrien   (set_attr "mode" "HI")])
856890286Sobrien
856990286Sobrien(define_expand "andqi3"
857090286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
857190286Sobrien	(and:QI (match_operand:QI 1 "nonimmediate_operand" "")
857290286Sobrien		(match_operand:QI 2 "general_operand" "")))
857390286Sobrien   (clobber (reg:CC 17))]
857490286Sobrien  "TARGET_QIMODE_MATH"
857590286Sobrien  "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
857690286Sobrien
857790286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
857890286Sobrien(define_insn "*andqi_1"
857990286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
858090286Sobrien	(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
858190286Sobrien		(match_operand:QI 2 "general_operand" "qi,qmi,ri")))
858290286Sobrien   (clobber (reg:CC 17))]
858390286Sobrien  "ix86_binary_operator_ok (AND, QImode, operands)"
858490286Sobrien  "@
858590286Sobrien   and{b}\t{%2, %0|%0, %2}
858690286Sobrien   and{b}\t{%2, %0|%0, %2}
858790286Sobrien   and{l}\t{%k2, %k0|%k0, %k2}"
858890286Sobrien  [(set_attr "type" "alu")
858990286Sobrien   (set_attr "mode" "QI,QI,SI")])
859090286Sobrien
859190286Sobrien(define_insn "*andqi_1_slp"
859290286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
859390286Sobrien	(and:QI (match_dup 0)
859490286Sobrien		(match_operand:QI 1 "general_operand" "qi,qmi")))
859590286Sobrien   (clobber (reg:CC 17))]
859690286Sobrien  ""
859790286Sobrien  "and{b}\t{%1, %0|%0, %1}"
859890286Sobrien  [(set_attr "type" "alu1")
859990286Sobrien   (set_attr "mode" "QI")])
860090286Sobrien
860190286Sobrien(define_insn "*andqi_2"
860290286Sobrien  [(set (reg 17)
860390286Sobrien	(compare (and:QI
860490286Sobrien		   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
860590286Sobrien		   (match_operand:QI 2 "general_operand" "qim,qi,i"))
860690286Sobrien		 (const_int 0)))
860790286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
860890286Sobrien	(and:QI (match_dup 1) (match_dup 2)))]
860990286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
861090286Sobrien   && ix86_binary_operator_ok (AND, QImode, operands)"
861190286Sobrien{
861290286Sobrien  if (which_alternative == 2)
861350650Sobrien    {
861490286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
861590286Sobrien          && (INTVAL (operands[2]) & 0xffffff00))
861690286Sobrien        operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
861790286Sobrien      return "and{l}\t{%2, %k0|%k0, %2}";
861850650Sobrien    }
861990286Sobrien  return "and{b}\t{%2, %0|%0, %2}";
862090286Sobrien}
862190286Sobrien  [(set_attr "type" "alu")
862290286Sobrien   (set_attr "mode" "QI,QI,SI")])
862350650Sobrien
862490286Sobrien(define_insn "*andqi_2_slp"
862590286Sobrien  [(set (reg 17)
862690286Sobrien	(compare (and:QI
862790286Sobrien		   (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
862890286Sobrien		   (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
862990286Sobrien		 (const_int 0)))
863090286Sobrien   (set (strict_low_part (match_dup 0))
863190286Sobrien	(and:QI (match_dup 0) (match_dup 1)))]
863290286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
863390286Sobrien  "and{b}\t{%1, %0|%0, %1}"
863490286Sobrien  [(set_attr "type" "alu1")
863590286Sobrien   (set_attr "mode" "QI")])
863618334Speter
863790286Sobrien;; ??? A bug in recog prevents it from recognizing a const_int as an
863890286Sobrien;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
863990286Sobrien;; for a QImode operand, which of course failed.
864018334Speter
864190286Sobrien(define_insn "andqi_ext_0"
864290286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
864390286Sobrien			 (const_int 8)
864490286Sobrien			 (const_int 8))
864590286Sobrien	(and:SI 
864690286Sobrien	  (zero_extract:SI
864790286Sobrien	    (match_operand 1 "ext_register_operand" "0")
864890286Sobrien	    (const_int 8)
864990286Sobrien	    (const_int 8))
865090286Sobrien	  (match_operand 2 "const_int_operand" "n")))
865190286Sobrien   (clobber (reg:CC 17))]
865290286Sobrien  "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
865390286Sobrien  "and{b}\t{%2, %h0|%h0, %2}"
865490286Sobrien  [(set_attr "type" "alu")
865590286Sobrien   (set_attr "length_immediate" "1")
865690286Sobrien   (set_attr "mode" "QI")])
865718334Speter
865890286Sobrien;; Generated by peephole translating test to and.  This shows up
865990286Sobrien;; often in fp comparisons.
866090286Sobrien
866190286Sobrien(define_insn "*andqi_ext_0_cc"
866290286Sobrien  [(set (reg 17)
866390286Sobrien	(compare
866490286Sobrien	  (and:SI
866590286Sobrien	    (zero_extract:SI
866690286Sobrien	      (match_operand 1 "ext_register_operand" "0")
866790286Sobrien	      (const_int 8)
866890286Sobrien	      (const_int 8))
866990286Sobrien	    (match_operand 2 "const_int_operand" "n"))
867090286Sobrien	  (const_int 0)))
867190286Sobrien   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
867290286Sobrien			 (const_int 8)
867390286Sobrien			 (const_int 8))
867490286Sobrien	(and:SI 
867590286Sobrien	  (zero_extract:SI
867690286Sobrien	    (match_dup 1)
867790286Sobrien	    (const_int 8)
867890286Sobrien	    (const_int 8))
867990286Sobrien	  (match_dup 2)))]
868090286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
868190286Sobrien   && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
868290286Sobrien  "and{b}\t{%2, %h0|%h0, %2}"
868390286Sobrien  [(set_attr "type" "alu")
868490286Sobrien   (set_attr "length_immediate" "1")
868590286Sobrien   (set_attr "mode" "QI")])
868690286Sobrien
868790286Sobrien(define_insn "*andqi_ext_1"
868890286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
868990286Sobrien			 (const_int 8)
869090286Sobrien			 (const_int 8))
869190286Sobrien	(and:SI 
869290286Sobrien	  (zero_extract:SI
869390286Sobrien	    (match_operand 1 "ext_register_operand" "0")
869490286Sobrien	    (const_int 8)
869590286Sobrien	    (const_int 8))
869690286Sobrien	  (zero_extend:SI
869790286Sobrien	    (match_operand:QI 2 "general_operand" "Qm"))))
869890286Sobrien   (clobber (reg:CC 17))]
869990286Sobrien  "!TARGET_64BIT"
870090286Sobrien  "and{b}\t{%2, %h0|%h0, %2}"
870190286Sobrien  [(set_attr "type" "alu")
870290286Sobrien   (set_attr "length_immediate" "0")
870390286Sobrien   (set_attr "mode" "QI")])
870490286Sobrien
870590286Sobrien(define_insn "*andqi_ext_1_rex64"
870690286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
870790286Sobrien			 (const_int 8)
870890286Sobrien			 (const_int 8))
870990286Sobrien	(and:SI 
871090286Sobrien	  (zero_extract:SI
871190286Sobrien	    (match_operand 1 "ext_register_operand" "0")
871290286Sobrien	    (const_int 8)
871390286Sobrien	    (const_int 8))
871490286Sobrien	  (zero_extend:SI
871590286Sobrien	    (match_operand 2 "ext_register_operand" "Q"))))
871690286Sobrien   (clobber (reg:CC 17))]
871790286Sobrien  "TARGET_64BIT"
871890286Sobrien  "and{b}\t{%2, %h0|%h0, %2}"
871990286Sobrien  [(set_attr "type" "alu")
872090286Sobrien   (set_attr "length_immediate" "0")
872190286Sobrien   (set_attr "mode" "QI")])
872290286Sobrien
872390286Sobrien(define_insn "*andqi_ext_2"
872490286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
872590286Sobrien			 (const_int 8)
872690286Sobrien			 (const_int 8))
872718334Speter	(and:SI
872890286Sobrien	  (zero_extract:SI
872990286Sobrien	    (match_operand 1 "ext_register_operand" "%0")
873090286Sobrien	    (const_int 8)
873190286Sobrien	    (const_int 8))
873290286Sobrien	  (zero_extract:SI
873390286Sobrien	    (match_operand 2 "ext_register_operand" "Q")
873490286Sobrien	    (const_int 8)
873590286Sobrien	    (const_int 8))))
873690286Sobrien   (clobber (reg:CC 17))]
873790286Sobrien  ""
873890286Sobrien  "and{b}\t{%h2, %h0|%h0, %h2}"
873990286Sobrien  [(set_attr "type" "alu")
874090286Sobrien   (set_attr "length_immediate" "0")
874190286Sobrien   (set_attr "mode" "QI")])
874218334Speter
874390286Sobrien;; Logical inclusive OR instructions
874418334Speter
874590286Sobrien;; %%% This used to optimize known byte-wide and operations to memory.
874690286Sobrien;; If this is considered useful, it should be done with splitters.
874790286Sobrien
874890286Sobrien(define_expand "iordi3"
874990286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
875090286Sobrien	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
875190286Sobrien		(match_operand:DI 2 "x86_64_general_operand" "")))
875290286Sobrien   (clobber (reg:CC 17))]
875390286Sobrien  "TARGET_64BIT"
875490286Sobrien  "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
875590286Sobrien
875690286Sobrien(define_insn "*iordi_1_rex64"
875790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
875890286Sobrien	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
875990286Sobrien		(match_operand:DI 2 "x86_64_general_operand" "re,rme")))
876090286Sobrien   (clobber (reg:CC 17))]
876190286Sobrien  "TARGET_64BIT
876290286Sobrien   && ix86_binary_operator_ok (IOR, DImode, operands)"
876390286Sobrien  "or{q}\t{%2, %0|%0, %2}"
876490286Sobrien  [(set_attr "type" "alu")
876590286Sobrien   (set_attr "mode" "DI")])
876690286Sobrien
876790286Sobrien(define_insn "*iordi_2_rex64"
876890286Sobrien  [(set (reg 17)
876990286Sobrien	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
877090286Sobrien			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
877190286Sobrien		 (const_int 0)))
877290286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
877390286Sobrien	(ior:DI (match_dup 1) (match_dup 2)))]
877490286Sobrien  "TARGET_64BIT
877590286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
877690286Sobrien   && ix86_binary_operator_ok (IOR, DImode, operands)"
877790286Sobrien  "or{q}\t{%2, %0|%0, %2}"
877890286Sobrien  [(set_attr "type" "alu")
877990286Sobrien   (set_attr "mode" "DI")])
878090286Sobrien
878190286Sobrien(define_insn "*iordi_3_rex64"
878290286Sobrien  [(set (reg 17)
878390286Sobrien	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
878490286Sobrien			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
878590286Sobrien		 (const_int 0)))
878690286Sobrien   (clobber (match_scratch:DI 0 "=r"))]
878790286Sobrien  "TARGET_64BIT
878890286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
878990286Sobrien   && ix86_binary_operator_ok (IOR, DImode, operands)"
879090286Sobrien  "or{q}\t{%2, %0|%0, %2}"
879190286Sobrien  [(set_attr "type" "alu")
879290286Sobrien   (set_attr "mode" "DI")])
879390286Sobrien
879490286Sobrien
879590286Sobrien(define_expand "iorsi3"
879690286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
879790286Sobrien	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
879890286Sobrien		(match_operand:SI 2 "general_operand" "")))
879990286Sobrien   (clobber (reg:CC 17))]
880090286Sobrien  ""
880190286Sobrien  "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
880290286Sobrien
880390286Sobrien(define_insn "*iorsi_1"
880450650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
880550650Sobrien	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
880690286Sobrien		(match_operand:SI 2 "general_operand" "ri,rmi")))
880790286Sobrien   (clobber (reg:CC 17))]
880890286Sobrien  "ix86_binary_operator_ok (IOR, SImode, operands)"
880990286Sobrien  "or{l}\t{%2, %0|%0, %2}"
881090286Sobrien  [(set_attr "type" "alu")
881190286Sobrien   (set_attr "mode" "SI")])
881250650Sobrien
881390286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
881490286Sobrien(define_insn "*iorsi_1_zext"
881590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=rm")
881690286Sobrien	(zero_extend:DI
881790286Sobrien	  (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
881890286Sobrien		  (match_operand:SI 2 "general_operand" "rim"))))
881990286Sobrien   (clobber (reg:CC 17))]
882090286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
882190286Sobrien  "or{l}\t{%2, %k0|%k0, %2}"
882290286Sobrien  [(set_attr "type" "alu")
882390286Sobrien   (set_attr "mode" "SI")])
882450650Sobrien
882590286Sobrien(define_insn "*iorsi_1_zext_imm"
882690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=rm")
882790286Sobrien	(ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
882890286Sobrien		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
882990286Sobrien   (clobber (reg:CC 17))]
883090286Sobrien  "TARGET_64BIT"
883190286Sobrien  "or{l}\t{%2, %k0|%k0, %2}"
883290286Sobrien  [(set_attr "type" "alu")
883390286Sobrien   (set_attr "mode" "SI")])
883450650Sobrien
883590286Sobrien(define_insn "*iorsi_2"
883690286Sobrien  [(set (reg 17)
883790286Sobrien	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
883890286Sobrien			 (match_operand:SI 2 "general_operand" "rim,ri"))
883990286Sobrien		 (const_int 0)))
884090286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
884190286Sobrien	(ior:SI (match_dup 1) (match_dup 2)))]
884290286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
884390286Sobrien   && ix86_binary_operator_ok (IOR, SImode, operands)"
884490286Sobrien  "or{l}\t{%2, %0|%0, %2}"
884590286Sobrien  [(set_attr "type" "alu")
884690286Sobrien   (set_attr "mode" "SI")])
884750650Sobrien
884890286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
884990286Sobrien;; ??? Special case for immediate operand is missing - it is tricky.
885090286Sobrien(define_insn "*iorsi_2_zext"
885190286Sobrien  [(set (reg 17)
885290286Sobrien	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
885390286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
885490286Sobrien		 (const_int 0)))
885590286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
885690286Sobrien	(zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
885790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
885890286Sobrien   && ix86_binary_operator_ok (IOR, SImode, operands)"
885990286Sobrien  "or{l}\t{%2, %k0|%k0, %2}"
886090286Sobrien  [(set_attr "type" "alu")
886190286Sobrien   (set_attr "mode" "SI")])
886250650Sobrien
886390286Sobrien(define_insn "*iorsi_2_zext_imm"
886490286Sobrien  [(set (reg 17)
886590286Sobrien	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
886690286Sobrien			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
886790286Sobrien		 (const_int 0)))
886890286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
886990286Sobrien	(ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
887090286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
887190286Sobrien   && ix86_binary_operator_ok (IOR, SImode, operands)"
887290286Sobrien  "or{l}\t{%2, %k0|%k0, %2}"
887390286Sobrien  [(set_attr "type" "alu")
887490286Sobrien   (set_attr "mode" "SI")])
887550650Sobrien
887690286Sobrien(define_insn "*iorsi_3"
887790286Sobrien  [(set (reg 17)
887890286Sobrien	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
887990286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
888090286Sobrien		 (const_int 0)))
888190286Sobrien   (clobber (match_scratch:SI 0 "=r"))]
888290286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
888390286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
888490286Sobrien  "or{l}\t{%2, %0|%0, %2}"
888590286Sobrien  [(set_attr "type" "alu")
888690286Sobrien   (set_attr "mode" "SI")])
888750650Sobrien
888890286Sobrien(define_expand "iorhi3"
888990286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
889090286Sobrien	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
889190286Sobrien		(match_operand:HI 2 "general_operand" "")))
889290286Sobrien   (clobber (reg:CC 17))]
889390286Sobrien  "TARGET_HIMODE_MATH"
889490286Sobrien  "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
889550650Sobrien
889690286Sobrien(define_insn "*iorhi_1"
889790286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
889890286Sobrien	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
889990286Sobrien		(match_operand:HI 2 "general_operand" "rmi,ri")))
890090286Sobrien   (clobber (reg:CC 17))]
890190286Sobrien  "ix86_binary_operator_ok (IOR, HImode, operands)"
890290286Sobrien  "or{w}\t{%2, %0|%0, %2}"
890390286Sobrien  [(set_attr "type" "alu")
890490286Sobrien   (set_attr "mode" "HI")])
890518334Speter
890690286Sobrien(define_insn "*iorhi_2"
890790286Sobrien  [(set (reg 17)
890890286Sobrien	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
890990286Sobrien			 (match_operand:HI 2 "general_operand" "rim,ri"))
891090286Sobrien		 (const_int 0)))
891190286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
891290286Sobrien	(ior:HI (match_dup 1) (match_dup 2)))]
891390286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
891490286Sobrien   && ix86_binary_operator_ok (IOR, HImode, operands)"
891590286Sobrien  "or{w}\t{%2, %0|%0, %2}"
891690286Sobrien  [(set_attr "type" "alu")
891790286Sobrien   (set_attr "mode" "HI")])
891818334Speter
891990286Sobrien(define_insn "*iorhi_3"
892090286Sobrien  [(set (reg 17)
892190286Sobrien	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
892290286Sobrien			 (match_operand:HI 2 "general_operand" "rim"))
892390286Sobrien		 (const_int 0)))
892490286Sobrien   (clobber (match_scratch:HI 0 "=r"))]
892590286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
892690286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
892790286Sobrien  "or{w}\t{%2, %0|%0, %2}"
892890286Sobrien  [(set_attr "type" "alu")
892990286Sobrien   (set_attr "mode" "HI")])
893050650Sobrien
893190286Sobrien(define_expand "iorqi3"
893290286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
893390286Sobrien	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
893490286Sobrien		(match_operand:QI 2 "general_operand" "")))
893590286Sobrien   (clobber (reg:CC 17))]
893690286Sobrien  "TARGET_QIMODE_MATH"
893790286Sobrien  "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
893818334Speter
893990286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
894090286Sobrien(define_insn "*iorqi_1"
894190286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
894290286Sobrien	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
894390286Sobrien		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
894490286Sobrien   (clobber (reg:CC 17))]
894590286Sobrien  "ix86_binary_operator_ok (IOR, QImode, operands)"
894690286Sobrien  "@
894790286Sobrien   or{b}\t{%2, %0|%0, %2}
894890286Sobrien   or{b}\t{%2, %0|%0, %2}
894990286Sobrien   or{l}\t{%k2, %k0|%k0, %k2}"
895090286Sobrien  [(set_attr "type" "alu")
895190286Sobrien   (set_attr "mode" "QI,QI,SI")])
895250650Sobrien
895390286Sobrien(define_insn "*iorqi_1_slp"
895490286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
895590286Sobrien	(ior:QI (match_dup 0)
895690286Sobrien		(match_operand:QI 1 "general_operand" "qmi,qi")))
895790286Sobrien   (clobber (reg:CC 17))]
895890286Sobrien  ""
895990286Sobrien  "or{b}\t{%1, %0|%0, %1}"
896090286Sobrien  [(set_attr "type" "alu1")
896190286Sobrien   (set_attr "mode" "QI")])
896218334Speter
896390286Sobrien(define_insn "*iorqi_2"
896490286Sobrien  [(set (reg 17)
896590286Sobrien	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
896690286Sobrien			 (match_operand:QI 2 "general_operand" "qim,qi"))
896790286Sobrien		 (const_int 0)))
896890286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
896990286Sobrien	(ior:QI (match_dup 1) (match_dup 2)))]
897090286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
897190286Sobrien   && ix86_binary_operator_ok (IOR, QImode, operands)"
897290286Sobrien  "or{b}\t{%2, %0|%0, %2}"
897390286Sobrien  [(set_attr "type" "alu")
897490286Sobrien   (set_attr "mode" "QI")])
897518334Speter
897690286Sobrien(define_insn "*iorqi_2_slp"
897790286Sobrien  [(set (reg 17)
897890286Sobrien	(compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
897990286Sobrien			 (match_operand:QI 1 "general_operand" "qim,qi"))
898090286Sobrien		 (const_int 0)))
898190286Sobrien   (set (strict_low_part (match_dup 0))
898290286Sobrien	(ior:QI (match_dup 0) (match_dup 1)))]
898390286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
898490286Sobrien  "or{b}\t{%1, %0|%0, %1}"
898590286Sobrien  [(set_attr "type" "alu1")
898690286Sobrien   (set_attr "mode" "QI")])
898718334Speter
898890286Sobrien(define_insn "*iorqi_3"
898990286Sobrien  [(set (reg 17)
899090286Sobrien	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
899190286Sobrien			 (match_operand:QI 2 "general_operand" "qim"))
899290286Sobrien		 (const_int 0)))
899390286Sobrien   (clobber (match_scratch:QI 0 "=q"))]
899490286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
899590286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
899690286Sobrien  "or{b}\t{%2, %0|%0, %2}"
899790286Sobrien  [(set_attr "type" "alu")
899890286Sobrien   (set_attr "mode" "QI")])
899918334Speter
900090286Sobrien
900190286Sobrien;; Logical XOR instructions
900290286Sobrien
900390286Sobrien;; %%% This used to optimize known byte-wide and operations to memory.
900490286Sobrien;; If this is considered useful, it should be done with splitters.
900590286Sobrien
900690286Sobrien(define_expand "xordi3"
900790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
900890286Sobrien	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
900990286Sobrien		(match_operand:DI 2 "x86_64_general_operand" "")))
901090286Sobrien   (clobber (reg:CC 17))]
901190286Sobrien  "TARGET_64BIT"
901290286Sobrien  "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
901390286Sobrien
901490286Sobrien(define_insn "*xordi_1_rex64"
901590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
901690286Sobrien	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
901790286Sobrien		(match_operand:DI 2 "x86_64_general_operand" "re,rm")))
901890286Sobrien   (clobber (reg:CC 17))]
901990286Sobrien  "TARGET_64BIT
902090286Sobrien   && ix86_binary_operator_ok (XOR, DImode, operands)"
902190286Sobrien  "@
902290286Sobrien   xor{q}\t{%2, %0|%0, %2} 
902390286Sobrien   xor{q}\t{%2, %0|%0, %2}"
902490286Sobrien  [(set_attr "type" "alu")
902590286Sobrien   (set_attr "mode" "DI,DI")])
902690286Sobrien
902790286Sobrien(define_insn "*xordi_2_rex64"
902890286Sobrien  [(set (reg 17)
902990286Sobrien	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
903090286Sobrien			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
903190286Sobrien		 (const_int 0)))
903290286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
903390286Sobrien	(xor:DI (match_dup 1) (match_dup 2)))]
903490286Sobrien  "TARGET_64BIT
903590286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
903690286Sobrien   && ix86_binary_operator_ok (XOR, DImode, operands)"
903790286Sobrien  "@
903890286Sobrien   xor{q}\t{%2, %0|%0, %2} 
903990286Sobrien   xor{q}\t{%2, %0|%0, %2}"
904090286Sobrien  [(set_attr "type" "alu")
904190286Sobrien   (set_attr "mode" "DI,DI")])
904290286Sobrien
904390286Sobrien(define_insn "*xordi_3_rex64"
904490286Sobrien  [(set (reg 17)
904590286Sobrien	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
904690286Sobrien			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
904790286Sobrien		 (const_int 0)))
904890286Sobrien   (clobber (match_scratch:DI 0 "=r"))]
904990286Sobrien  "TARGET_64BIT
905090286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
905190286Sobrien   && ix86_binary_operator_ok (XOR, DImode, operands)"
905290286Sobrien  "xor{q}\t{%2, %0|%0, %2}"
905390286Sobrien  [(set_attr "type" "alu")
905490286Sobrien   (set_attr "mode" "DI")])
905590286Sobrien
905690286Sobrien(define_expand "xorsi3"
905790286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
905890286Sobrien	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
905990286Sobrien		(match_operand:SI 2 "general_operand" "")))
906090286Sobrien   (clobber (reg:CC 17))]
906118334Speter  ""
906290286Sobrien  "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
906318334Speter
906490286Sobrien(define_insn "*xorsi_1"
906590286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
906690286Sobrien	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
906790286Sobrien		(match_operand:SI 2 "general_operand" "ri,rm")))
906890286Sobrien   (clobber (reg:CC 17))]
906990286Sobrien  "ix86_binary_operator_ok (XOR, SImode, operands)"
907090286Sobrien  "xor{l}\t{%2, %0|%0, %2}"
907190286Sobrien  [(set_attr "type" "alu")
907290286Sobrien   (set_attr "mode" "SI")])
907318334Speter
907490286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
907590286Sobrien;; Add speccase for immediates
907690286Sobrien(define_insn "*xorsi_1_zext"
907790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
907890286Sobrien	(zero_extend:DI
907990286Sobrien	  (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
908090286Sobrien		  (match_operand:SI 2 "general_operand" "rim"))))
908190286Sobrien   (clobber (reg:CC 17))]
908290286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
908390286Sobrien  "xor{l}\t{%2, %k0|%k0, %2}"
908490286Sobrien  [(set_attr "type" "alu")
908590286Sobrien   (set_attr "mode" "SI")])
908650650Sobrien
908790286Sobrien(define_insn "*xorsi_1_zext_imm"
908890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
908990286Sobrien	(xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
909090286Sobrien		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
909190286Sobrien   (clobber (reg:CC 17))]
909290286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
909390286Sobrien  "xor{l}\t{%2, %k0|%k0, %2}"
909490286Sobrien  [(set_attr "type" "alu")
909590286Sobrien   (set_attr "mode" "SI")])
909650650Sobrien
909790286Sobrien(define_insn "*xorsi_2"
909890286Sobrien  [(set (reg 17)
909990286Sobrien	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
910090286Sobrien			 (match_operand:SI 2 "general_operand" "rim,ri"))
910190286Sobrien		 (const_int 0)))
910290286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
910390286Sobrien	(xor:SI (match_dup 1) (match_dup 2)))]
910490286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
910590286Sobrien   && ix86_binary_operator_ok (XOR, SImode, operands)"
910690286Sobrien  "xor{l}\t{%2, %0|%0, %2}"
910790286Sobrien  [(set_attr "type" "alu")
910890286Sobrien   (set_attr "mode" "SI")])
910950650Sobrien
911090286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
911190286Sobrien;; ??? Special case for immediate operand is missing - it is tricky.
911290286Sobrien(define_insn "*xorsi_2_zext"
911390286Sobrien  [(set (reg 17)
911490286Sobrien	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
911590286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
911690286Sobrien		 (const_int 0)))
911790286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
911890286Sobrien	(zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
911990286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
912090286Sobrien   && ix86_binary_operator_ok (XOR, SImode, operands)"
912190286Sobrien  "xor{l}\t{%2, %k0|%k0, %2}"
912290286Sobrien  [(set_attr "type" "alu")
912390286Sobrien   (set_attr "mode" "SI")])
912450650Sobrien
912590286Sobrien(define_insn "*xorsi_2_zext_imm"
912690286Sobrien  [(set (reg 17)
912790286Sobrien	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
912890286Sobrien			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
912990286Sobrien		 (const_int 0)))
913090286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
913190286Sobrien	(xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
913290286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
913390286Sobrien   && ix86_binary_operator_ok (XOR, SImode, operands)"
913490286Sobrien  "xor{l}\t{%2, %k0|%k0, %2}"
913590286Sobrien  [(set_attr "type" "alu")
913690286Sobrien   (set_attr "mode" "SI")])
913750650Sobrien
913890286Sobrien(define_insn "*xorsi_3"
913990286Sobrien  [(set (reg 17)
914090286Sobrien	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
914190286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
914290286Sobrien		 (const_int 0)))
914390286Sobrien   (clobber (match_scratch:SI 0 "=r"))]
914490286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
914590286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
914690286Sobrien  "xor{l}\t{%2, %0|%0, %2}"
914790286Sobrien  [(set_attr "type" "alu")
914890286Sobrien   (set_attr "mode" "SI")])
914918334Speter
915090286Sobrien(define_expand "xorhi3"
915190286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
915290286Sobrien	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
915390286Sobrien		(match_operand:HI 2 "general_operand" "")))
915490286Sobrien   (clobber (reg:CC 17))]
915590286Sobrien  "TARGET_HIMODE_MATH"
915690286Sobrien  "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
915718334Speter
915890286Sobrien(define_insn "*xorhi_1"
915990286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
916090286Sobrien	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
916190286Sobrien		(match_operand:HI 2 "general_operand" "rmi,ri")))
916290286Sobrien   (clobber (reg:CC 17))]
916390286Sobrien  "ix86_binary_operator_ok (XOR, HImode, operands)"
916490286Sobrien  "xor{w}\t{%2, %0|%0, %2}"
916590286Sobrien  [(set_attr "type" "alu")
916690286Sobrien   (set_attr "mode" "HI")])
916718334Speter
916890286Sobrien(define_insn "*xorhi_2"
916990286Sobrien  [(set (reg 17)
917090286Sobrien	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
917190286Sobrien			 (match_operand:HI 2 "general_operand" "rim,ri"))
917290286Sobrien		 (const_int 0)))
917390286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
917490286Sobrien	(xor:HI (match_dup 1) (match_dup 2)))]
917590286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
917690286Sobrien   && ix86_binary_operator_ok (XOR, HImode, operands)"
917790286Sobrien  "xor{w}\t{%2, %0|%0, %2}"
917890286Sobrien  [(set_attr "type" "alu")
917990286Sobrien   (set_attr "mode" "HI")])
918050650Sobrien
918190286Sobrien(define_insn "*xorhi_3"
918290286Sobrien  [(set (reg 17)
918390286Sobrien	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
918490286Sobrien			 (match_operand:HI 2 "general_operand" "rim"))
918590286Sobrien		 (const_int 0)))
918690286Sobrien   (clobber (match_scratch:HI 0 "=r"))]
918790286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
918890286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
918990286Sobrien  "xor{w}\t{%2, %0|%0, %2}"
919090286Sobrien  [(set_attr "type" "alu")
919190286Sobrien   (set_attr "mode" "HI")])
919250650Sobrien
919390286Sobrien(define_expand "xorqi3"
919490286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
919590286Sobrien	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
919690286Sobrien		(match_operand:QI 2 "general_operand" "")))
919790286Sobrien   (clobber (reg:CC 17))]
919890286Sobrien  "TARGET_QIMODE_MATH"
919990286Sobrien  "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
920050650Sobrien
920190286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
920290286Sobrien(define_insn "*xorqi_1"
920390286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
920490286Sobrien	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
920590286Sobrien		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
920690286Sobrien   (clobber (reg:CC 17))]
920790286Sobrien  "ix86_binary_operator_ok (XOR, QImode, operands)"
920890286Sobrien  "@
920990286Sobrien   xor{b}\t{%2, %0|%0, %2}
921090286Sobrien   xor{b}\t{%2, %0|%0, %2}
921190286Sobrien   xor{l}\t{%k2, %k0|%k0, %k2}"
921290286Sobrien  [(set_attr "type" "alu")
921390286Sobrien   (set_attr "mode" "QI,QI,SI")])
921418334Speter
921590286Sobrien(define_insn "*xorqi_ext_1"
921690286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
921790286Sobrien			 (const_int 8)
921890286Sobrien			 (const_int 8))
921990286Sobrien	(xor:SI 
922090286Sobrien	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
922190286Sobrien	  		   (const_int 8)
922290286Sobrien			   (const_int 8))
922390286Sobrien	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
922490286Sobrien	  		   (const_int 8)
922590286Sobrien			   (const_int 8))))
922690286Sobrien   (clobber (reg:CC 17))]
922790286Sobrien  ""
922890286Sobrien  "xor{b}\t{%h2, %h0|%h0, %h2}"
922990286Sobrien  [(set_attr "type" "alu")
923090286Sobrien   (set_attr "length_immediate" "0")
923190286Sobrien   (set_attr "mode" "QI")])
923250650Sobrien
923390286Sobrien(define_insn "*xorqi_cc_1"
923490286Sobrien  [(set (reg 17)
923590286Sobrien	(compare
923690286Sobrien	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
923790286Sobrien		  (match_operand:QI 2 "general_operand" "qim,qi"))
923890286Sobrien	  (const_int 0)))
923990286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
924090286Sobrien	(xor:QI (match_dup 1) (match_dup 2)))]
924190286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
924290286Sobrien   && ix86_binary_operator_ok (XOR, QImode, operands)"
924390286Sobrien  "xor{b}\t{%2, %0|%0, %2}"
924490286Sobrien  [(set_attr "type" "alu")
924590286Sobrien   (set_attr "mode" "QI")])
924650650Sobrien
924790286Sobrien(define_insn "*xorqi_cc_2"
924890286Sobrien  [(set (reg 17)
924990286Sobrien	(compare
925090286Sobrien	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
925190286Sobrien		  (match_operand:QI 2 "general_operand" "qim"))
925290286Sobrien	  (const_int 0)))
925390286Sobrien   (clobber (match_scratch:QI 0 "=q"))]
925490286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
925590286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
925690286Sobrien  "xor{b}\t{%2, %0|%0, %2}"
925790286Sobrien  [(set_attr "type" "alu")
925890286Sobrien   (set_attr "mode" "QI")])
925918334Speter
926090286Sobrien(define_insn "*xorqi_cc_ext_1"
926190286Sobrien  [(set (reg 17)
926290286Sobrien	(compare
926390286Sobrien	  (xor:SI
926490286Sobrien	    (zero_extract:SI
926590286Sobrien	      (match_operand 1 "ext_register_operand" "0")
926690286Sobrien	      (const_int 8)
926790286Sobrien	      (const_int 8))
926890286Sobrien	    (match_operand:QI 2 "general_operand" "qmn"))
926990286Sobrien	  (const_int 0)))
927090286Sobrien   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
927190286Sobrien			 (const_int 8)
927290286Sobrien			 (const_int 8))
927390286Sobrien	(xor:SI 
927490286Sobrien	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
927590286Sobrien	  (match_dup 2)))]
927690286Sobrien  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
927790286Sobrien  "xor{b}\t{%2, %h0|%h0, %2}"
927890286Sobrien  [(set_attr "type" "alu")
927990286Sobrien   (set_attr "mode" "QI")])
928090286Sobrien
928190286Sobrien(define_insn "*xorqi_cc_ext_1_rex64"
928290286Sobrien  [(set (reg 17)
928390286Sobrien	(compare
928490286Sobrien	  (xor:SI
928590286Sobrien	    (zero_extract:SI
928690286Sobrien	      (match_operand 1 "ext_register_operand" "0")
928790286Sobrien	      (const_int 8)
928890286Sobrien	      (const_int 8))
928990286Sobrien	    (match_operand:QI 2 "nonmemory_operand" "Qn"))
929090286Sobrien	  (const_int 0)))
929190286Sobrien   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
929290286Sobrien			 (const_int 8)
929390286Sobrien			 (const_int 8))
929490286Sobrien	(xor:SI 
929590286Sobrien	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
929690286Sobrien	  (match_dup 2)))]
929790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
929890286Sobrien  "xor{b}\t{%2, %h0|%h0, %2}"
929990286Sobrien  [(set_attr "type" "alu")
930090286Sobrien   (set_attr "mode" "QI")])
930190286Sobrien
930290286Sobrien(define_expand "xorqi_cc_ext_1"
930390286Sobrien  [(parallel [
930490286Sobrien     (set (reg:CCNO 17)
930590286Sobrien	  (compare:CCNO
930690286Sobrien	    (xor:SI
930790286Sobrien	      (zero_extract:SI
930890286Sobrien		(match_operand 1 "ext_register_operand" "")
930990286Sobrien		(const_int 8)
931090286Sobrien		(const_int 8))
931190286Sobrien	      (match_operand:QI 2 "general_operand" ""))
931290286Sobrien	    (const_int 0)))
931390286Sobrien     (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
931490286Sobrien			   (const_int 8)
931590286Sobrien			   (const_int 8))
931690286Sobrien	  (xor:SI 
931790286Sobrien	    (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
931890286Sobrien	    (match_dup 2)))])]
931918334Speter  ""
932090286Sobrien  "")
932118334Speter
932290286Sobrien;; Negation instructions
932318334Speter
932490286Sobrien(define_expand "negdi2"
932590286Sobrien  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
932690286Sobrien		   (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
932790286Sobrien	      (clobber (reg:CC 17))])]
932818334Speter  ""
932990286Sobrien  "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
933050650Sobrien
933190286Sobrien(define_insn "*negdi2_1"
933290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
933390286Sobrien	(neg:DI (match_operand:DI 1 "general_operand" "0")))
933490286Sobrien   (clobber (reg:CC 17))]
933590286Sobrien  "!TARGET_64BIT
933690286Sobrien   && ix86_unary_operator_ok (NEG, DImode, operands)"
933790286Sobrien  "#")
933850650Sobrien
933990286Sobrien(define_split
934090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
934190286Sobrien	(neg:DI (match_operand:DI 1 "general_operand" "")))
934290286Sobrien   (clobber (reg:CC 17))]
934390286Sobrien  "!TARGET_64BIT && reload_completed"
934490286Sobrien  [(parallel
934590286Sobrien    [(set (reg:CCZ 17)
934690286Sobrien	  (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
934790286Sobrien     (set (match_dup 0) (neg:SI (match_dup 2)))])
934890286Sobrien   (parallel
934990286Sobrien    [(set (match_dup 1)
935090286Sobrien	  (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
935190286Sobrien			    (match_dup 3))
935290286Sobrien		   (const_int 0)))
935390286Sobrien     (clobber (reg:CC 17))])
935490286Sobrien   (parallel
935590286Sobrien    [(set (match_dup 1)
935690286Sobrien	  (neg:SI (match_dup 1)))
935790286Sobrien     (clobber (reg:CC 17))])]
935890286Sobrien  "split_di (operands+1, 1, operands+2, operands+3);
935990286Sobrien   split_di (operands+0, 1, operands+0, operands+1);")
936050650Sobrien
936190286Sobrien(define_insn "*negdi2_1_rex64"
936290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
936390286Sobrien	(neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
936490286Sobrien   (clobber (reg:CC 17))]
936590286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
936690286Sobrien  "neg{q}\t%0"
936790286Sobrien  [(set_attr "type" "negnot")
936890286Sobrien   (set_attr "mode" "DI")])
936950650Sobrien
937090286Sobrien;; The problem with neg is that it does not perform (compare x 0),
937190286Sobrien;; it really performs (compare 0 x), which leaves us with the zero
937290286Sobrien;; flag being the only useful item.
937350650Sobrien
937490286Sobrien(define_insn "*negdi2_cmpz_rex64"
937590286Sobrien  [(set (reg:CCZ 17)
937690286Sobrien	(compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
937790286Sobrien		     (const_int 0)))
937890286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
937990286Sobrien	(neg:DI (match_dup 1)))]
938090286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
938190286Sobrien  "neg{q}\t%0"
938290286Sobrien  [(set_attr "type" "negnot")
938390286Sobrien   (set_attr "mode" "DI")])
938450650Sobrien
938518334Speter
938690286Sobrien(define_expand "negsi2"
938790286Sobrien  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
938890286Sobrien		   (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
938990286Sobrien	      (clobber (reg:CC 17))])]
939090286Sobrien  ""
939190286Sobrien  "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
939218334Speter
939390286Sobrien(define_insn "*negsi2_1"
939490286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
939590286Sobrien	(neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
939690286Sobrien   (clobber (reg:CC 17))]
939790286Sobrien  "ix86_unary_operator_ok (NEG, SImode, operands)"
939890286Sobrien  "neg{l}\t%0"
939990286Sobrien  [(set_attr "type" "negnot")
940090286Sobrien   (set_attr "mode" "SI")])
940150650Sobrien
940290286Sobrien;; Combine is quite creative about this pattern.
940390286Sobrien(define_insn "*negsi2_1_zext"
940490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
940590286Sobrien	(lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
940690286Sobrien					(const_int 32)))
940790286Sobrien		     (const_int 32)))
940890286Sobrien   (clobber (reg:CC 17))]
940990286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
941090286Sobrien  "neg{l}\t%k0"
941190286Sobrien  [(set_attr "type" "negnot")
941290286Sobrien   (set_attr "mode" "SI")])
941350650Sobrien
941490286Sobrien;; The problem with neg is that it does not perform (compare x 0),
941590286Sobrien;; it really performs (compare 0 x), which leaves us with the zero
941690286Sobrien;; flag being the only useful item.
941718334Speter
941890286Sobrien(define_insn "*negsi2_cmpz"
941990286Sobrien  [(set (reg:CCZ 17)
942090286Sobrien	(compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
942190286Sobrien		     (const_int 0)))
942290286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
942390286Sobrien	(neg:SI (match_dup 1)))]
942490286Sobrien  "ix86_unary_operator_ok (NEG, SImode, operands)"
942590286Sobrien  "neg{l}\t%0"
942690286Sobrien  [(set_attr "type" "negnot")
942790286Sobrien   (set_attr "mode" "SI")])
942850650Sobrien
942990286Sobrien(define_insn "*negsi2_cmpz_zext"
943090286Sobrien  [(set (reg:CCZ 17)
943190286Sobrien	(compare:CCZ (lshiftrt:DI
943290286Sobrien		       (neg:DI (ashift:DI
943390286Sobrien				 (match_operand:DI 1 "register_operand" "0")
943490286Sobrien				 (const_int 32)))
943590286Sobrien		       (const_int 32))
943690286Sobrien		     (const_int 0)))
943790286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
943890286Sobrien	(lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
943990286Sobrien					(const_int 32)))
944090286Sobrien		     (const_int 32)))]
944190286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
944290286Sobrien  "neg{l}\t%k0"
944390286Sobrien  [(set_attr "type" "negnot")
944490286Sobrien   (set_attr "mode" "SI")])
944590286Sobrien
944690286Sobrien(define_expand "neghi2"
944790286Sobrien  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
944890286Sobrien		   (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
944990286Sobrien	      (clobber (reg:CC 17))])]
945090286Sobrien  "TARGET_HIMODE_MATH"
945190286Sobrien  "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
945290286Sobrien
945390286Sobrien(define_insn "*neghi2_1"
945490286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
945590286Sobrien	(neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
945690286Sobrien   (clobber (reg:CC 17))]
945790286Sobrien  "ix86_unary_operator_ok (NEG, HImode, operands)"
945890286Sobrien  "neg{w}\t%0"
945990286Sobrien  [(set_attr "type" "negnot")
946090286Sobrien   (set_attr "mode" "HI")])
946190286Sobrien
946290286Sobrien(define_insn "*neghi2_cmpz"
946390286Sobrien  [(set (reg:CCZ 17)
946490286Sobrien	(compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
946590286Sobrien		     (const_int 0)))
946690286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
946790286Sobrien	(neg:HI (match_dup 1)))]
946890286Sobrien  "ix86_unary_operator_ok (NEG, HImode, operands)"
946990286Sobrien  "neg{w}\t%0"
947090286Sobrien  [(set_attr "type" "negnot")
947190286Sobrien   (set_attr "mode" "HI")])
947290286Sobrien
947390286Sobrien(define_expand "negqi2"
947490286Sobrien  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
947590286Sobrien		   (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
947690286Sobrien	      (clobber (reg:CC 17))])]
947790286Sobrien  "TARGET_QIMODE_MATH"
947890286Sobrien  "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
947990286Sobrien
948090286Sobrien(define_insn "*negqi2_1"
948190286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
948290286Sobrien	(neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
948390286Sobrien   (clobber (reg:CC 17))]
948490286Sobrien  "ix86_unary_operator_ok (NEG, QImode, operands)"
948590286Sobrien  "neg{b}\t%0"
948690286Sobrien  [(set_attr "type" "negnot")
948790286Sobrien   (set_attr "mode" "QI")])
948890286Sobrien
948990286Sobrien(define_insn "*negqi2_cmpz"
949090286Sobrien  [(set (reg:CCZ 17)
949190286Sobrien	(compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
949290286Sobrien		     (const_int 0)))
949390286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
949490286Sobrien	(neg:QI (match_dup 1)))]
949590286Sobrien  "ix86_unary_operator_ok (NEG, QImode, operands)"
949690286Sobrien  "neg{b}\t%0"
949790286Sobrien  [(set_attr "type" "negnot")
949890286Sobrien   (set_attr "mode" "QI")])
949990286Sobrien
950090286Sobrien;; Changing of sign for FP values is doable using integer unit too.
950190286Sobrien
950290286Sobrien(define_expand "negsf2"
950390286Sobrien  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
950490286Sobrien		   (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
950590286Sobrien	      (clobber (reg:CC 17))])]
950690286Sobrien  "TARGET_80387"
950790286Sobrien  "if (TARGET_SSE)
950890286Sobrien     {
950990286Sobrien       /* In case operand is in memory,  we will not use SSE.  */
951090286Sobrien       if (memory_operand (operands[0], VOIDmode)
951190286Sobrien	   && rtx_equal_p (operands[0], operands[1]))
951290286Sobrien	 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
951390286Sobrien       else
951418334Speter	{
951590286Sobrien	  /* Using SSE is tricky, since we need bitwise negation of -0
951690286Sobrien	     in register.  */
951790286Sobrien	  rtx reg = gen_reg_rtx (SFmode);
951890286Sobrien	  rtx dest = operands[0];
951918334Speter
952090286Sobrien	  operands[1] = force_reg (SFmode, operands[1]);
952190286Sobrien	  operands[0] = force_reg (SFmode, operands[0]);
952290286Sobrien	  emit_move_insn (reg,
952390286Sobrien			  gen_lowpart (SFmode,
952490286Sobrien				       GEN_INT (trunc_int_for_mode (0x80000000,
952590286Sobrien							            SImode))));
952690286Sobrien	  emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
952790286Sobrien	  if (dest != operands[0])
952890286Sobrien	    emit_move_insn (dest, operands[0]);
952950650Sobrien	}
953090286Sobrien       DONE;
953190286Sobrien     }
953290286Sobrien   ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
953318334Speter
953490286Sobrien(define_insn "negsf2_memory"
953590286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
953690286Sobrien	(neg:SF (match_operand:SF 1 "memory_operand" "0")))
953790286Sobrien   (clobber (reg:CC 17))]
953890286Sobrien  "ix86_unary_operator_ok (NEG, SFmode, operands)"
953990286Sobrien  "#")
954018334Speter
954190286Sobrien(define_insn "negsf2_ifs"
954290286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
954390286Sobrien	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
954490286Sobrien   (use (match_operand:SF 2 "nonmemory_operand" "x,0#x,*g#x,*g#x"))
954590286Sobrien   (clobber (reg:CC 17))]
954690286Sobrien  "TARGET_SSE
954790286Sobrien   && (reload_in_progress || reload_completed
954890286Sobrien       || (register_operand (operands[0], VOIDmode)
954990286Sobrien	   && register_operand (operands[1], VOIDmode)))"
955090286Sobrien  "#")
955118334Speter
955290286Sobrien(define_split
955390286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
955490286Sobrien	(neg:SF (match_operand:SF 1 "memory_operand" "")))
955590286Sobrien   (use (match_operand:SF 2 "" ""))
955690286Sobrien   (clobber (reg:CC 17))]
955718334Speter  ""
955890286Sobrien  [(parallel [(set (match_dup 0)
955990286Sobrien		   (neg:SF (match_dup 1)))
956090286Sobrien	      (clobber (reg:CC 17))])])
956190286Sobrien
956290286Sobrien(define_split
956390286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
956490286Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "")))
956590286Sobrien   (use (match_operand:SF 2 "" ""))
956690286Sobrien   (clobber (reg:CC 17))]
956790286Sobrien  "reload_completed && !SSE_REG_P (operands[0])"
956890286Sobrien  [(parallel [(set (match_dup 0)
956990286Sobrien		   (neg:SF (match_dup 1)))
957090286Sobrien	      (clobber (reg:CC 17))])])
957190286Sobrien
957290286Sobrien(define_split
957390286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
957490286Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "")))
957590286Sobrien   (use (match_operand:SF 2 "register_operand" ""))
957690286Sobrien   (clobber (reg:CC 17))]
957790286Sobrien  "reload_completed && SSE_REG_P (operands[0])"
957890286Sobrien  [(set (subreg:TI (match_dup 0) 0)
957990286Sobrien	(xor:TI (subreg:TI (match_dup 1) 0)
958090286Sobrien		(subreg:TI (match_dup 2) 0)))]
958118334Speter{
958290286Sobrien  if (operands_match_p (operands[0], operands[2]))
958318334Speter    {
958490286Sobrien      rtx tmp;
958590286Sobrien      tmp = operands[1];
958690286Sobrien      operands[1] = operands[2];
958790286Sobrien      operands[2] = tmp;
958890286Sobrien    }
958990286Sobrien})
959018334Speter
959118334Speter
959290286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
959390286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
959490286Sobrien;; to itself.
959590286Sobrien(define_insn "*negsf2_if"
959690286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
959790286Sobrien	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
959890286Sobrien   (clobber (reg:CC 17))]
959990286Sobrien  "TARGET_80387 && !TARGET_SSE
960090286Sobrien   && ix86_unary_operator_ok (NEG, SFmode, operands)"
960190286Sobrien  "#")
960218334Speter
960390286Sobrien(define_split
960490286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
960590286Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "")))
960690286Sobrien   (clobber (reg:CC 17))]
960790286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
960890286Sobrien  [(set (match_dup 0)
960990286Sobrien	(neg:SF (match_dup 1)))]
961090286Sobrien  "")
961190286Sobrien
961290286Sobrien(define_split
961390286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
961490286Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "")))
961590286Sobrien   (clobber (reg:CC 17))]
961690286Sobrien  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
961790286Sobrien  [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
961890286Sobrien	      (clobber (reg:CC 17))])]
961990286Sobrien  "operands[1] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
962090286Sobrien   operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
962190286Sobrien
962290286Sobrien(define_split
962390286Sobrien  [(set (match_operand 0 "memory_operand" "")
962490286Sobrien	(neg (match_operand 1 "memory_operand" "")))
962590286Sobrien   (clobber (reg:CC 17))]
962690286Sobrien  "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
962790286Sobrien  [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
962890286Sobrien	      (clobber (reg:CC 17))])]
962990286Sobrien{
963090286Sobrien  int size = GET_MODE_SIZE (GET_MODE (operands[1]));
963190286Sobrien
963290286Sobrien  /* XFmode's size is 12, TFmode 16, but only 10 bytes are used.  */
963390286Sobrien  if (size >= 12)
963490286Sobrien    size = 10;
963590286Sobrien  operands[0] = adjust_address (operands[0], QImode, size - 1);
963690286Sobrien  operands[1] = GEN_INT (trunc_int_for_mode (0x80, QImode));
963790286Sobrien})
963890286Sobrien
963990286Sobrien(define_expand "negdf2"
964090286Sobrien  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
964190286Sobrien		   (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
964290286Sobrien	      (clobber (reg:CC 17))])]
964390286Sobrien  "TARGET_80387"
964490286Sobrien  "if (TARGET_SSE2)
964590286Sobrien     {
964690286Sobrien       /* In case operand is in memory,  we will not use SSE.  */
964790286Sobrien       if (memory_operand (operands[0], VOIDmode)
964890286Sobrien	   && rtx_equal_p (operands[0], operands[1]))
964990286Sobrien	 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
965090286Sobrien       else
965118334Speter	{
965290286Sobrien	  /* Using SSE is tricky, since we need bitwise negation of -0
965390286Sobrien	     in register.  */
965490286Sobrien	  rtx reg = gen_reg_rtx (DFmode);
965590286Sobrien#if HOST_BITS_PER_WIDE_INT >= 64
965690286Sobrien	  rtx imm = GEN_INT (trunc_int_for_mode(((HOST_WIDE_INT)1) << 63,
965790286Sobrien					        DImode));
965890286Sobrien#else
965990286Sobrien	  rtx imm = immed_double_const (0, 0x80000000, DImode);
966090286Sobrien#endif
966190286Sobrien	  rtx dest = operands[0];
966218334Speter
966390286Sobrien	  operands[1] = force_reg (DFmode, operands[1]);
966490286Sobrien	  operands[0] = force_reg (DFmode, operands[0]);
966590286Sobrien	  emit_move_insn (reg, gen_lowpart (DFmode, imm));
966690286Sobrien	  emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
966790286Sobrien	  if (dest != operands[0])
966890286Sobrien	    emit_move_insn (dest, operands[0]);
966918334Speter	}
967090286Sobrien       DONE;
967190286Sobrien     }
967290286Sobrien   ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
967318334Speter
967490286Sobrien(define_insn "negdf2_memory"
967590286Sobrien  [(set (match_operand:DF 0 "memory_operand" "=m")
967690286Sobrien	(neg:DF (match_operand:DF 1 "memory_operand" "0")))
967790286Sobrien   (clobber (reg:CC 17))]
967890286Sobrien  "ix86_unary_operator_ok (NEG, DFmode, operands)"
967990286Sobrien  "#")
968050650Sobrien
968190286Sobrien(define_insn "negdf2_ifs"
968290286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
968390286Sobrien	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
968490286Sobrien   (use (match_operand:DF 2 "nonmemory_operand" "Y,0,*g#Y,*g#Y"))
968590286Sobrien   (clobber (reg:CC 17))]
968690286Sobrien  "!TARGET_64BIT && TARGET_SSE2
968790286Sobrien   && (reload_in_progress || reload_completed
968890286Sobrien       || (register_operand (operands[0], VOIDmode)
968990286Sobrien	   && register_operand (operands[1], VOIDmode)))"
969090286Sobrien  "#")
969150650Sobrien
969290286Sobrien(define_insn "*negdf2_ifs_rex64"
969390286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,fm#Yr,r#Yf")
969490286Sobrien	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
969590286Sobrien   (use (match_operand:DF 2 "general_operand" "Y,0,*g#Yr,*rm"))
969690286Sobrien   (clobber (reg:CC 17))]
969790286Sobrien  "TARGET_64BIT && TARGET_SSE2
969890286Sobrien   && (reload_in_progress || reload_completed
969990286Sobrien       || (register_operand (operands[0], VOIDmode)
970090286Sobrien	   && register_operand (operands[1], VOIDmode)))"
970190286Sobrien  "#")
970218334Speter
970390286Sobrien(define_split
970490286Sobrien  [(set (match_operand:DF 0 "memory_operand" "")
970590286Sobrien	(neg:DF (match_operand:DF 1 "memory_operand" "")))
970690286Sobrien   (use (match_operand:DF 2 "" ""))
970790286Sobrien   (clobber (reg:CC 17))]
970818334Speter  ""
970990286Sobrien  [(parallel [(set (match_dup 0)
971090286Sobrien		   (neg:DF (match_dup 1)))
971190286Sobrien	      (clobber (reg:CC 17))])])
971250650Sobrien
971390286Sobrien(define_split
971490286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
971590286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
971690286Sobrien   (use (match_operand:DF 2 "" ""))
971790286Sobrien   (clobber (reg:CC 17))]
971890286Sobrien  "reload_completed && !SSE_REG_P (operands[0])
971990286Sobrien   && (!TARGET_64BIT || FP_REG_P (operands[0]))"
972090286Sobrien  [(parallel [(set (match_dup 0)
972190286Sobrien		   (neg:DF (match_dup 1)))
972290286Sobrien	      (clobber (reg:CC 17))])])
972350650Sobrien
972490286Sobrien(define_split
972590286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
972690286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
972790286Sobrien   (use (match_operand:DF 2 "" ""))
972890286Sobrien   (clobber (reg:CC 17))]
972990286Sobrien  "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
973090286Sobrien  [(parallel [(set (match_dup 0)
973190286Sobrien		   (xor:DI (match_dup 1) (match_dup 2)))
973290286Sobrien	      (clobber (reg:CC 17))])]
973390286Sobrien   "operands[0] = gen_lowpart (DImode, operands[0]);
973490286Sobrien    operands[1] = gen_lowpart (DImode, operands[1]);
973590286Sobrien    operands[2] = gen_lowpart (DImode, operands[2]);")
973652296Sobrien
973790286Sobrien(define_split
973890286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
973990286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
974090286Sobrien   (use (match_operand:DF 2 "register_operand" ""))
974190286Sobrien   (clobber (reg:CC 17))]
974290286Sobrien  "reload_completed && SSE_REG_P (operands[0])"
974390286Sobrien  [(set (subreg:TI (match_dup 0) 0)
974490286Sobrien	(xor:TI (subreg:TI (match_dup 1) 0)
974590286Sobrien		(subreg:TI (match_dup 2) 0)))]
974690286Sobrien{
974790286Sobrien  if (operands_match_p (operands[0], operands[2]))
974890286Sobrien    {
974990286Sobrien      rtx tmp;
975090286Sobrien      tmp = operands[1];
975190286Sobrien      operands[1] = operands[2];
975290286Sobrien      operands[2] = tmp;
975390286Sobrien    }
975490286Sobrien})
975552296Sobrien
975690286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
975790286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
975890286Sobrien;; to itself.
975990286Sobrien(define_insn "*negdf2_if"
976090286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
976190286Sobrien	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
976290286Sobrien   (clobber (reg:CC 17))]
976390286Sobrien  "!TARGET_64BIT && TARGET_80387
976490286Sobrien   && ix86_unary_operator_ok (NEG, DFmode, operands)"
976590286Sobrien  "#")
976650650Sobrien
976790286Sobrien;; FIXME: We should to allow integer registers here.  Problem is that
976890286Sobrien;; we need another scratch register to get constant from.
976990286Sobrien;; Forcing constant to mem if no register available in peep2 should be
977090286Sobrien;; safe even for PIC mode, because of RIP relative addressing.
977190286Sobrien(define_insn "*negdf2_if_rex64"
977290286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
977390286Sobrien	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
977490286Sobrien   (clobber (reg:CC 17))]
977590286Sobrien  "TARGET_64BIT && TARGET_80387
977690286Sobrien   && ix86_unary_operator_ok (NEG, DFmode, operands)"
977790286Sobrien  "#")
977890286Sobrien
977950650Sobrien(define_split
978090286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
978190286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
978290286Sobrien   (clobber (reg:CC 17))]
978390286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
978490286Sobrien  [(set (match_dup 0)
978590286Sobrien	(neg:DF (match_dup 1)))]
978690286Sobrien  "")
978750650Sobrien
978890286Sobrien(define_split
978990286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
979090286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
979190286Sobrien   (clobber (reg:CC 17))]
979290286Sobrien  "!TARGET_64BIT && TARGET_80387 && reload_completed
979390286Sobrien   && !FP_REGNO_P (REGNO (operands[0]))"
979490286Sobrien  [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
979590286Sobrien	      (clobber (reg:CC 17))])]
979690286Sobrien  "operands[4] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
979790286Sobrien   split_di (operands+0, 1, operands+2, operands+3);")
979818334Speter
979990286Sobrien(define_expand "negxf2"
980090286Sobrien  [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
980190286Sobrien		   (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
980290286Sobrien	      (clobber (reg:CC 17))])]
980390286Sobrien  "!TARGET_64BIT && TARGET_80387"
980490286Sobrien  "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
980518334Speter
980690286Sobrien(define_expand "negtf2"
980790286Sobrien  [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
980890286Sobrien		   (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
980990286Sobrien	      (clobber (reg:CC 17))])]
981090286Sobrien  "TARGET_80387"
981190286Sobrien  "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
981218334Speter
981390286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
981490286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
981590286Sobrien;; to itself.
981690286Sobrien(define_insn "*negxf2_if"
981790286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
981890286Sobrien	(neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
981990286Sobrien   (clobber (reg:CC 17))]
982090286Sobrien  "!TARGET_64BIT && TARGET_80387
982190286Sobrien   && ix86_unary_operator_ok (NEG, XFmode, operands)"
982290286Sobrien  "#")
982318334Speter
982490286Sobrien(define_split
982590286Sobrien  [(set (match_operand:XF 0 "register_operand" "")
982690286Sobrien	(neg:XF (match_operand:XF 1 "register_operand" "")))
982790286Sobrien   (clobber (reg:CC 17))]
982890286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
982990286Sobrien  [(set (match_dup 0)
983090286Sobrien	(neg:XF (match_dup 1)))]
983190286Sobrien  "")
983218334Speter
983390286Sobrien(define_split
983490286Sobrien  [(set (match_operand:XF 0 "register_operand" "")
983590286Sobrien	(neg:XF (match_operand:XF 1 "register_operand" "")))
983690286Sobrien   (clobber (reg:CC 17))]
983790286Sobrien  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
983890286Sobrien  [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
983990286Sobrien	      (clobber (reg:CC 17))])]
984090286Sobrien  "operands[1] = GEN_INT (0x8000);
984190286Sobrien   operands[0] = gen_rtx_REG (SImode,
984290286Sobrien			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
984318334Speter
984490286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
984590286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
984690286Sobrien;; to itself.
984790286Sobrien(define_insn "*negtf2_if"
984890286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
984990286Sobrien	(neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
985090286Sobrien   (clobber (reg:CC 17))]
985190286Sobrien  "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
985290286Sobrien  "#")
985318334Speter
985490286Sobrien(define_split
985590286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
985690286Sobrien	(neg:TF (match_operand:TF 1 "register_operand" "")))
985790286Sobrien   (clobber (reg:CC 17))]
985890286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
985990286Sobrien  [(set (match_dup 0)
986090286Sobrien	(neg:TF (match_dup 1)))]
986190286Sobrien  "")
986218334Speter
986390286Sobrien(define_split
986490286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
986590286Sobrien	(neg:TF (match_operand:TF 1 "register_operand" "")))
986690286Sobrien   (clobber (reg:CC 17))]
986790286Sobrien  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
986890286Sobrien  [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
986990286Sobrien	      (clobber (reg:CC 17))])]
987090286Sobrien  "operands[1] = GEN_INT (0x8000);
987190286Sobrien   operands[0] = gen_rtx_REG (SImode,
987290286Sobrien			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
987390286Sobrien
987490286Sobrien;; Conditionize these after reload. If they matches before reload, we 
987590286Sobrien;; lose the clobber and ability to use integer instructions.
987690286Sobrien
987790286Sobrien(define_insn "*negsf2_1"
987818334Speter  [(set (match_operand:SF 0 "register_operand" "=f")
987950650Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "0")))]
988090286Sobrien  "TARGET_80387 && reload_completed"
988152296Sobrien  "fchs"
988290286Sobrien  [(set_attr "type" "fsgn")
988390286Sobrien   (set_attr "mode" "SF")
988490286Sobrien   (set_attr "ppro_uops" "few")])
988518334Speter
988690286Sobrien(define_insn "*negdf2_1"
988718334Speter  [(set (match_operand:DF 0 "register_operand" "=f")
988850650Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "0")))]
988990286Sobrien  "TARGET_80387 && reload_completed"
989052296Sobrien  "fchs"
989190286Sobrien  [(set_attr "type" "fsgn")
989290286Sobrien   (set_attr "mode" "DF")
989390286Sobrien   (set_attr "ppro_uops" "few")])
989418334Speter
989590286Sobrien(define_insn "*negextendsfdf2"
989618334Speter  [(set (match_operand:DF 0 "register_operand" "=f")
989790286Sobrien	(neg:DF (float_extend:DF
989890286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
989918334Speter  "TARGET_80387"
990052296Sobrien  "fchs"
990190286Sobrien  [(set_attr "type" "fsgn")
990290286Sobrien   (set_attr "mode" "DF")
990390286Sobrien   (set_attr "ppro_uops" "few")])
990418334Speter
990590286Sobrien(define_insn "*negxf2_1"
990618334Speter  [(set (match_operand:XF 0 "register_operand" "=f")
990750650Sobrien	(neg:XF (match_operand:XF 1 "register_operand" "0")))]
990890286Sobrien  "!TARGET_64BIT && TARGET_80387 && reload_completed"
990952296Sobrien  "fchs"
991090286Sobrien  [(set_attr "type" "fsgn")
991190286Sobrien   (set_attr "mode" "XF")
991290286Sobrien   (set_attr "ppro_uops" "few")])
991318334Speter
991490286Sobrien(define_insn "*negextenddfxf2"
991518334Speter  [(set (match_operand:XF 0 "register_operand" "=f")
991690286Sobrien	(neg:XF (float_extend:XF
991790286Sobrien		  (match_operand:DF 1 "register_operand" "0"))))]
991890286Sobrien  "!TARGET_64BIT && TARGET_80387"
991990286Sobrien  "fchs"
992090286Sobrien  [(set_attr "type" "fsgn")
992190286Sobrien   (set_attr "mode" "XF")
992290286Sobrien   (set_attr "ppro_uops" "few")])
992390286Sobrien
992490286Sobrien(define_insn "*negextendsfxf2"
992590286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
992690286Sobrien	(neg:XF (float_extend:XF
992790286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
992890286Sobrien  "!TARGET_64BIT && TARGET_80387"
992990286Sobrien  "fchs"
993090286Sobrien  [(set_attr "type" "fsgn")
993190286Sobrien   (set_attr "mode" "XF")
993290286Sobrien   (set_attr "ppro_uops" "few")])
993390286Sobrien
993490286Sobrien(define_insn "*negtf2_1"
993590286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
993690286Sobrien	(neg:TF (match_operand:TF 1 "register_operand" "0")))]
993790286Sobrien  "TARGET_80387 && reload_completed"
993890286Sobrien  "fchs"
993990286Sobrien  [(set_attr "type" "fsgn")
994090286Sobrien   (set_attr "mode" "XF")
994190286Sobrien   (set_attr "ppro_uops" "few")])
994290286Sobrien
994390286Sobrien(define_insn "*negextenddftf2"
994490286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
994590286Sobrien	(neg:TF (float_extend:TF
994690286Sobrien		  (match_operand:DF 1 "register_operand" "0"))))]
994718334Speter  "TARGET_80387"
994852296Sobrien  "fchs"
994990286Sobrien  [(set_attr "type" "fsgn")
995090286Sobrien   (set_attr "mode" "XF")
995190286Sobrien   (set_attr "ppro_uops" "few")])
995290286Sobrien
995390286Sobrien(define_insn "*negextendsftf2"
995490286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
995590286Sobrien	(neg:TF (float_extend:TF
995690286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
995790286Sobrien  "TARGET_80387"
995890286Sobrien  "fchs"
995990286Sobrien  [(set_attr "type" "fsgn")
996090286Sobrien   (set_attr "mode" "XF")
996190286Sobrien   (set_attr "ppro_uops" "few")])
996218334Speter
996318334Speter;; Absolute value instructions
996418334Speter
996590286Sobrien(define_expand "abssf2"
996690286Sobrien  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
996790286Sobrien		   (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
996890286Sobrien	      (clobber (reg:CC 17))])]
996990286Sobrien  "TARGET_80387"
997090286Sobrien  "if (TARGET_SSE)
997190286Sobrien     {
997290286Sobrien       /* In case operand is in memory,  we will not use SSE.  */
997390286Sobrien       if (memory_operand (operands[0], VOIDmode)
997490286Sobrien	   && rtx_equal_p (operands[0], operands[1]))
997590286Sobrien	 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
997690286Sobrien       else
997790286Sobrien	{
997890286Sobrien	  /* Using SSE is tricky, since we need bitwise negation of -0
997990286Sobrien	     in register.  */
998090286Sobrien	  rtx reg = gen_reg_rtx (SFmode);
998190286Sobrien	  rtx dest = operands[0];
998290286Sobrien
998390286Sobrien	  operands[1] = force_reg (SFmode, operands[1]);
998490286Sobrien	  operands[0] = force_reg (SFmode, operands[0]);
998590286Sobrien	  emit_move_insn (reg,
998690286Sobrien			  gen_lowpart (SFmode,
998790286Sobrien				       GEN_INT (trunc_int_for_mode (0x80000000,
998890286Sobrien							            SImode))));
998990286Sobrien	  emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
999090286Sobrien	  if (dest != operands[0])
999190286Sobrien	    emit_move_insn (dest, operands[0]);
999290286Sobrien	}
999390286Sobrien       DONE;
999490286Sobrien     }
999590286Sobrien   ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
999690286Sobrien
999790286Sobrien(define_insn "abssf2_memory"
999890286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
999990286Sobrien	(abs:SF (match_operand:SF 1 "memory_operand" "0")))
1000090286Sobrien   (clobber (reg:CC 17))]
1000190286Sobrien  "ix86_unary_operator_ok (ABS, SFmode, operands)"
1000290286Sobrien  "#")
1000390286Sobrien
1000490286Sobrien(define_insn "abssf2_ifs"
1000590286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,f#xr,rm#xf")
1000690286Sobrien	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "x,0,0")))
1000790286Sobrien   (use (match_operand:SF 2 "nonmemory_operand" "*0#x,*g#x,*g#x"))
1000890286Sobrien   (clobber (reg:CC 17))]
1000990286Sobrien  "TARGET_SSE
1001090286Sobrien   && (reload_in_progress || reload_completed
1001190286Sobrien       || (register_operand (operands[0], VOIDmode)
1001290286Sobrien	   && register_operand (operands[1], VOIDmode)))"
1001390286Sobrien  "#")
1001490286Sobrien
1001590286Sobrien(define_split
1001690286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
1001790286Sobrien	(abs:SF (match_operand:SF 1 "memory_operand" "")))
1001890286Sobrien   (use (match_operand:SF 2 "" ""))
1001990286Sobrien   (clobber (reg:CC 17))]
1002090286Sobrien  ""
1002190286Sobrien  [(parallel [(set (match_dup 0)
1002290286Sobrien		   (abs:SF (match_dup 1)))
1002390286Sobrien	      (clobber (reg:CC 17))])])
1002490286Sobrien
1002590286Sobrien(define_split
1002690286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1002790286Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "")))
1002890286Sobrien   (use (match_operand:SF 2 "" ""))
1002990286Sobrien   (clobber (reg:CC 17))]
1003090286Sobrien  "reload_completed && !SSE_REG_P (operands[0])"
1003190286Sobrien  [(parallel [(set (match_dup 0)
1003290286Sobrien		   (abs:SF (match_dup 1)))
1003390286Sobrien	      (clobber (reg:CC 17))])])
1003490286Sobrien
1003590286Sobrien(define_split
1003690286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1003790286Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "")))
1003890286Sobrien   (use (match_operand:SF 2 "register_operand" ""))
1003990286Sobrien   (clobber (reg:CC 17))]
1004090286Sobrien  "reload_completed && SSE_REG_P (operands[0])"
1004190286Sobrien  [(set (subreg:TI (match_dup 0) 0)
1004290286Sobrien	(and:TI (not:TI (subreg:TI (match_dup 2) 0))
1004390286Sobrien		(subreg:TI (match_dup 1) 0)))])
1004490286Sobrien
1004590286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
1004690286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
1004790286Sobrien;; to itself.
1004890286Sobrien(define_insn "*abssf2_if"
1004990286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
1005090286Sobrien	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
1005190286Sobrien   (clobber (reg:CC 17))]
1005290286Sobrien  "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
1005390286Sobrien  "#")
1005490286Sobrien
1005590286Sobrien(define_split
1005690286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1005790286Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "")))
1005890286Sobrien   (clobber (reg:CC 17))]
1005990286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0]))"
1006090286Sobrien  [(set (match_dup 0)
1006190286Sobrien	(abs:SF (match_dup 1)))]
1006290286Sobrien  "")
1006390286Sobrien
1006490286Sobrien(define_split
1006590286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1006690286Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "")))
1006790286Sobrien   (clobber (reg:CC 17))]
1006890286Sobrien  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
1006990286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
1007090286Sobrien	      (clobber (reg:CC 17))])]
1007190286Sobrien  "operands[1] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
1007290286Sobrien   operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
1007390286Sobrien
1007490286Sobrien(define_split
1007590286Sobrien  [(set (match_operand 0 "memory_operand" "")
1007690286Sobrien	(abs (match_operand 1 "memory_operand" "")))
1007790286Sobrien   (clobber (reg:CC 17))]
1007890286Sobrien  "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
1007990286Sobrien  [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
1008090286Sobrien	      (clobber (reg:CC 17))])]
1008190286Sobrien{
1008290286Sobrien  int size = GET_MODE_SIZE (GET_MODE (operands[1]));
1008390286Sobrien
1008490286Sobrien  /* XFmode's size is 12, TFmode 16, but only 10 bytes are used.  */
1008590286Sobrien  if (size >= 12)
1008690286Sobrien    size = 10;
1008790286Sobrien  operands[0] = adjust_address (operands[0], QImode, size - 1);
1008890286Sobrien  operands[1] = GEN_INT (trunc_int_for_mode (~0x80, QImode));
1008990286Sobrien})
1009090286Sobrien
1009190286Sobrien(define_expand "absdf2"
1009290286Sobrien  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
1009390286Sobrien		   (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
1009490286Sobrien	      (clobber (reg:CC 17))])]
1009590286Sobrien  "TARGET_80387"
1009690286Sobrien  "if (TARGET_SSE2)
1009790286Sobrien     {
1009890286Sobrien       /* In case operand is in memory,  we will not use SSE.  */
1009990286Sobrien       if (memory_operand (operands[0], VOIDmode)
1010090286Sobrien	   && rtx_equal_p (operands[0], operands[1]))
1010190286Sobrien	 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
1010290286Sobrien       else
1010390286Sobrien	{
1010490286Sobrien	  /* Using SSE is tricky, since we need bitwise negation of -0
1010590286Sobrien	     in register.  */
1010690286Sobrien	  rtx reg = gen_reg_rtx (DFmode);
1010790286Sobrien#if HOST_BITS_PER_WIDE_INT >= 64
1010890286Sobrien	  rtx imm = GEN_INT (trunc_int_for_mode(((HOST_WIDE_INT)1) << 63,
1010990286Sobrien					        DImode));
1011090286Sobrien#else
1011190286Sobrien	  rtx imm = immed_double_const (0, 0x80000000, DImode);
1011290286Sobrien#endif
1011390286Sobrien	  rtx dest = operands[0];
1011490286Sobrien
1011590286Sobrien	  operands[1] = force_reg (DFmode, operands[1]);
1011690286Sobrien	  operands[0] = force_reg (DFmode, operands[0]);
1011790286Sobrien	  emit_move_insn (reg, gen_lowpart (DFmode, imm));
1011890286Sobrien	  emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
1011990286Sobrien	  if (dest != operands[0])
1012090286Sobrien	    emit_move_insn (dest, operands[0]);
1012190286Sobrien	}
1012290286Sobrien       DONE;
1012390286Sobrien     }
1012490286Sobrien   ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
1012590286Sobrien
1012690286Sobrien(define_insn "absdf2_memory"
1012790286Sobrien  [(set (match_operand:DF 0 "memory_operand" "=m")
1012890286Sobrien	(abs:DF (match_operand:DF 1 "memory_operand" "0")))
1012990286Sobrien   (clobber (reg:CC 17))]
1013090286Sobrien  "ix86_unary_operator_ok (ABS, DFmode, operands)"
1013190286Sobrien  "#")
1013290286Sobrien
1013390286Sobrien(define_insn "absdf2_ifs"
1013490286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr,mr#Yf")
1013590286Sobrien	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0,0")))
1013690286Sobrien   (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y,*g#Y"))
1013790286Sobrien   (clobber (reg:CC 17))]
1013890286Sobrien  "!TARGET_64BIT && TARGET_SSE2
1013990286Sobrien   && (reload_in_progress || reload_completed
1014090286Sobrien       || (register_operand (operands[0], VOIDmode)
1014190286Sobrien	   && register_operand (operands[1], VOIDmode)))"
1014290286Sobrien  "#")
1014390286Sobrien
1014490286Sobrien(define_insn "*absdf2_ifs_rex64"
1014590286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr")
1014690286Sobrien	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0")))
1014790286Sobrien   (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y"))
1014890286Sobrien   (clobber (reg:CC 17))]
1014990286Sobrien  "TARGET_64BIT && TARGET_SSE2
1015090286Sobrien   && (reload_in_progress || reload_completed
1015190286Sobrien       || (register_operand (operands[0], VOIDmode)
1015290286Sobrien	   && register_operand (operands[1], VOIDmode)))"
1015390286Sobrien  "#")
1015490286Sobrien
1015590286Sobrien(define_split
1015690286Sobrien  [(set (match_operand:DF 0 "memory_operand" "")
1015790286Sobrien	(abs:DF (match_operand:DF 1 "memory_operand" "")))
1015890286Sobrien   (use (match_operand:DF 2 "" ""))
1015990286Sobrien   (clobber (reg:CC 17))]
1016090286Sobrien  ""
1016190286Sobrien  [(parallel [(set (match_dup 0)
1016290286Sobrien		   (abs:DF (match_dup 1)))
1016390286Sobrien	      (clobber (reg:CC 17))])])
1016490286Sobrien
1016590286Sobrien(define_split
1016690286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1016790286Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "")))
1016890286Sobrien   (use (match_operand:DF 2 "" ""))
1016990286Sobrien   (clobber (reg:CC 17))]
1017090286Sobrien  "reload_completed && !SSE_REG_P (operands[0])"
1017190286Sobrien  [(parallel [(set (match_dup 0)
1017290286Sobrien		   (abs:DF (match_dup 1)))
1017390286Sobrien	      (clobber (reg:CC 17))])])
1017490286Sobrien
1017590286Sobrien(define_split
1017690286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1017790286Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "")))
1017890286Sobrien   (use (match_operand:DF 2 "register_operand" ""))
1017990286Sobrien   (clobber (reg:CC 17))]
1018090286Sobrien  "reload_completed && SSE_REG_P (operands[0])"
1018190286Sobrien  [(set (subreg:TI (match_dup 0) 0)
1018290286Sobrien	(and:TI (not:TI (subreg:TI (match_dup 2) 0))
1018390286Sobrien		(subreg:TI (match_dup 1) 0)))])
1018490286Sobrien
1018590286Sobrien
1018690286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
1018790286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
1018890286Sobrien;; to itself.
1018990286Sobrien(define_insn "*absdf2_if"
1019090286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
1019190286Sobrien	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
1019290286Sobrien   (clobber (reg:CC 17))]
1019390286Sobrien  "!TARGET_64BIT && TARGET_80387
1019490286Sobrien   && ix86_unary_operator_ok (ABS, DFmode, operands)"
1019590286Sobrien  "#")
1019690286Sobrien
1019790286Sobrien;; FIXME: We should to allow integer registers here.  Problem is that
1019890286Sobrien;; we need another scratch register to get constant from.
1019990286Sobrien;; Forcing constant to mem if no register available in peep2 should be
1020090286Sobrien;; safe even for PIC mode, because of RIP relative addressing.
1020190286Sobrien(define_insn "*absdf2_if_rex64"
1020290286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
1020390286Sobrien	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
1020490286Sobrien   (clobber (reg:CC 17))]
1020590286Sobrien  "TARGET_64BIT && TARGET_80387
1020690286Sobrien   && ix86_unary_operator_ok (ABS, DFmode, operands)"
1020790286Sobrien  "#")
1020890286Sobrien
1020990286Sobrien(define_split
1021090286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1021190286Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "")))
1021290286Sobrien   (clobber (reg:CC 17))]
1021390286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
1021490286Sobrien  [(set (match_dup 0)
1021590286Sobrien	(abs:DF (match_dup 1)))]
1021690286Sobrien  "")
1021790286Sobrien
1021890286Sobrien(define_split
1021990286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1022090286Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "")))
1022190286Sobrien   (clobber (reg:CC 17))]
1022290286Sobrien  "!TARGET_64BIT && TARGET_80387 && reload_completed &&
1022390286Sobrien   !FP_REGNO_P (REGNO (operands[0]))"
1022490286Sobrien  [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
1022590286Sobrien	      (clobber (reg:CC 17))])]
1022690286Sobrien  "operands[4] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
1022790286Sobrien   split_di (operands+0, 1, operands+2, operands+3);")
1022890286Sobrien
1022990286Sobrien(define_expand "absxf2"
1023090286Sobrien  [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
1023190286Sobrien		   (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
1023290286Sobrien	      (clobber (reg:CC 17))])]
1023390286Sobrien  "!TARGET_64BIT && TARGET_80387"
1023490286Sobrien  "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
1023590286Sobrien
1023690286Sobrien(define_expand "abstf2"
1023790286Sobrien  [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
1023890286Sobrien		   (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
1023990286Sobrien	      (clobber (reg:CC 17))])]
1024090286Sobrien  "TARGET_80387"
1024190286Sobrien  "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
1024290286Sobrien
1024390286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
1024490286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
1024590286Sobrien;; to itself.
1024690286Sobrien(define_insn "*absxf2_if"
1024790286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
1024890286Sobrien	(abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
1024990286Sobrien   (clobber (reg:CC 17))]
1025090286Sobrien  "!TARGET_64BIT && TARGET_80387
1025190286Sobrien   && ix86_unary_operator_ok (ABS, XFmode, operands)"
1025290286Sobrien  "#")
1025390286Sobrien
1025490286Sobrien(define_split
1025590286Sobrien  [(set (match_operand:XF 0 "register_operand" "")
1025690286Sobrien	(abs:XF (match_operand:XF 1 "register_operand" "")))
1025790286Sobrien   (clobber (reg:CC 17))]
1025890286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
1025990286Sobrien  [(set (match_dup 0)
1026090286Sobrien	(abs:XF (match_dup 1)))]
1026190286Sobrien  "")
1026290286Sobrien
1026390286Sobrien(define_split
1026490286Sobrien  [(set (match_operand:XF 0 "register_operand" "")
1026590286Sobrien	(abs:XF (match_operand:XF 1 "register_operand" "")))
1026690286Sobrien   (clobber (reg:CC 17))]
1026790286Sobrien  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
1026890286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
1026990286Sobrien	      (clobber (reg:CC 17))])]
1027090286Sobrien  "operands[1] = GEN_INT (~0x8000);
1027190286Sobrien   operands[0] = gen_rtx_REG (SImode,
1027290286Sobrien			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
1027390286Sobrien
1027490286Sobrien(define_insn "*abstf2_if"
1027590286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
1027690286Sobrien	(abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
1027790286Sobrien   (clobber (reg:CC 17))]
1027890286Sobrien  "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
1027990286Sobrien  "#")
1028090286Sobrien
1028190286Sobrien(define_split
1028290286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
1028390286Sobrien	(abs:TF (match_operand:TF 1 "register_operand" "")))
1028490286Sobrien   (clobber (reg:CC 17))]
1028590286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
1028690286Sobrien  [(set (match_dup 0)
1028790286Sobrien	(abs:TF (match_dup 1)))]
1028890286Sobrien  "")
1028990286Sobrien
1029090286Sobrien(define_split
1029190286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
1029290286Sobrien	(abs:TF (match_operand:TF 1 "register_operand" "")))
1029390286Sobrien   (clobber (reg:CC 17))]
1029490286Sobrien  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
1029590286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
1029690286Sobrien	      (clobber (reg:CC 17))])]
1029790286Sobrien  "operands[1] = GEN_INT (~0x8000);
1029890286Sobrien   operands[0] = gen_rtx_REG (SImode,
1029990286Sobrien			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
1030090286Sobrien
1030190286Sobrien(define_insn "*abssf2_1"
1030218334Speter  [(set (match_operand:SF 0 "register_operand" "=f")
1030350650Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "0")))]
1030490286Sobrien  "TARGET_80387 && reload_completed"
1030550650Sobrien  "fabs"
1030690286Sobrien  [(set_attr "type" "fsgn")
1030790286Sobrien   (set_attr "mode" "SF")])
1030818334Speter
1030990286Sobrien(define_insn "*absdf2_1"
1031018334Speter  [(set (match_operand:DF 0 "register_operand" "=f")
1031150650Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "0")))]
1031290286Sobrien  "TARGET_80387 && reload_completed"
1031350650Sobrien  "fabs"
1031490286Sobrien  [(set_attr "type" "fsgn")
1031590286Sobrien   (set_attr "mode" "DF")])
1031618334Speter
1031790286Sobrien(define_insn "*absextendsfdf2"
1031818334Speter  [(set (match_operand:DF 0 "register_operand" "=f")
1031990286Sobrien	(abs:DF (float_extend:DF
1032090286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
1032118334Speter  "TARGET_80387"
1032250650Sobrien  "fabs"
1032390286Sobrien  [(set_attr "type" "fsgn")
1032490286Sobrien   (set_attr "mode" "DF")])
1032518334Speter
1032690286Sobrien(define_insn "*absxf2_1"
1032718334Speter  [(set (match_operand:XF 0 "register_operand" "=f")
1032850650Sobrien	(abs:XF (match_operand:XF 1 "register_operand" "0")))]
1032990286Sobrien  "!TARGET_64BIT && TARGET_80387 && reload_completed"
1033050650Sobrien  "fabs"
1033190286Sobrien  [(set_attr "type" "fsgn")
1033290286Sobrien   (set_attr "mode" "DF")])
1033318334Speter
1033490286Sobrien(define_insn "*absextenddfxf2"
1033518334Speter  [(set (match_operand:XF 0 "register_operand" "=f")
1033690286Sobrien	(abs:XF (float_extend:XF
1033790286Sobrien	  (match_operand:DF 1 "register_operand" "0"))))]
1033890286Sobrien  "!TARGET_64BIT && TARGET_80387"
1033950650Sobrien  "fabs"
1034090286Sobrien  [(set_attr "type" "fsgn")
1034190286Sobrien   (set_attr "mode" "XF")])
1034218334Speter
1034390286Sobrien(define_insn "*absextendsfxf2"
1034490286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1034590286Sobrien	(abs:XF (float_extend:XF
1034690286Sobrien	  (match_operand:SF 1 "register_operand" "0"))))]
1034790286Sobrien  "!TARGET_64BIT && TARGET_80387"
1034890286Sobrien  "fabs"
1034990286Sobrien  [(set_attr "type" "fsgn")
1035090286Sobrien   (set_attr "mode" "XF")])
1035118334Speter
1035290286Sobrien(define_insn "*abstf2_1"
1035390286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1035490286Sobrien	(abs:TF (match_operand:TF 1 "register_operand" "0")))]
1035590286Sobrien  "TARGET_80387 && reload_completed"
1035690286Sobrien  "fabs"
1035790286Sobrien  [(set_attr "type" "fsgn")
1035890286Sobrien   (set_attr "mode" "DF")])
1035918334Speter
1036090286Sobrien(define_insn "*absextenddftf2"
1036190286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1036290286Sobrien	(abs:TF (float_extend:TF
1036390286Sobrien	  (match_operand:DF 1 "register_operand" "0"))))]
1036490286Sobrien  "TARGET_80387"
1036590286Sobrien  "fabs"
1036690286Sobrien  [(set_attr "type" "fsgn")
1036790286Sobrien   (set_attr "mode" "XF")])
1036818334Speter
1036990286Sobrien(define_insn "*absextendsftf2"
1037090286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1037190286Sobrien	(abs:TF (float_extend:TF
1037290286Sobrien	  (match_operand:SF 1 "register_operand" "0"))))]
1037390286Sobrien  "TARGET_80387"
1037490286Sobrien  "fabs"
1037590286Sobrien  [(set_attr "type" "fsgn")
1037690286Sobrien   (set_attr "mode" "XF")])
1037790286Sobrien
1037890286Sobrien;; One complement instructions
1037918334Speter
1038090286Sobrien(define_expand "one_cmpldi2"
1038190286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1038290286Sobrien	(not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
1038390286Sobrien  "TARGET_64BIT"
1038490286Sobrien  "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
1038518334Speter
1038690286Sobrien(define_insn "*one_cmpldi2_1_rex64"
1038790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1038890286Sobrien	(not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
1038990286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
1039090286Sobrien  "not{q}\t%0"
1039190286Sobrien  [(set_attr "type" "negnot")
1039290286Sobrien   (set_attr "mode" "DI")])
1039318334Speter
1039490286Sobrien(define_insn "*one_cmpldi2_2_rex64"
1039590286Sobrien  [(set (reg 17)
1039690286Sobrien	(compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
1039790286Sobrien		 (const_int 0)))
1039890286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1039990286Sobrien	(not:DI (match_dup 1)))]
1040090286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
1040190286Sobrien   && ix86_unary_operator_ok (NOT, DImode, operands)"
1040290286Sobrien  "#"
1040390286Sobrien  [(set_attr "type" "alu1")
1040490286Sobrien   (set_attr "mode" "DI")])
1040518334Speter
1040690286Sobrien(define_split
1040790286Sobrien  [(set (reg 17)
1040890286Sobrien	(compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
1040990286Sobrien		 (const_int 0)))
1041090286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "")
1041190286Sobrien	(not:DI (match_dup 1)))]
1041290286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
1041390286Sobrien  [(parallel [(set (reg:CCNO 17)
1041490286Sobrien		   (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
1041590286Sobrien				 (const_int 0)))
1041690286Sobrien	      (set (match_dup 0)
1041790286Sobrien		   (xor:DI (match_dup 1) (const_int -1)))])]
1041890286Sobrien  "")
1041918334Speter
1042090286Sobrien(define_expand "one_cmplsi2"
1042190286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1042290286Sobrien	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
1042390286Sobrien  ""
1042490286Sobrien  "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
1042518334Speter
1042690286Sobrien(define_insn "*one_cmplsi2_1"
1042790286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1042890286Sobrien	(not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
1042990286Sobrien  "ix86_unary_operator_ok (NOT, SImode, operands)"
1043090286Sobrien  "not{l}\t%0"
1043190286Sobrien  [(set_attr "type" "negnot")
1043290286Sobrien   (set_attr "mode" "SI")])
1043318334Speter
1043490286Sobrien;; ??? Currently never generated - xor is used instead.
1043590286Sobrien(define_insn "*one_cmplsi2_1_zext"
1043690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1043790286Sobrien	(zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
1043890286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
1043990286Sobrien  "not{l}\t%k0"
1044090286Sobrien  [(set_attr "type" "negnot")
1044190286Sobrien   (set_attr "mode" "SI")])
1044218334Speter
1044390286Sobrien(define_insn "*one_cmplsi2_2"
1044490286Sobrien  [(set (reg 17)
1044590286Sobrien	(compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
1044690286Sobrien		 (const_int 0)))
1044790286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1044890286Sobrien	(not:SI (match_dup 1)))]
1044990286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
1045090286Sobrien   && ix86_unary_operator_ok (NOT, SImode, operands)"
1045190286Sobrien  "#"
1045290286Sobrien  [(set_attr "type" "alu1")
1045390286Sobrien   (set_attr "mode" "SI")])
1045418334Speter
1045590286Sobrien(define_split
1045690286Sobrien  [(set (reg 17)
1045790286Sobrien	(compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
1045890286Sobrien		 (const_int 0)))
1045990286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "")
1046090286Sobrien	(not:SI (match_dup 1)))]
1046190286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
1046290286Sobrien  [(parallel [(set (reg:CCNO 17)
1046390286Sobrien		   (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
1046490286Sobrien				 (const_int 0)))
1046590286Sobrien	      (set (match_dup 0)
1046690286Sobrien		   (xor:SI (match_dup 1) (const_int -1)))])]
1046790286Sobrien  "")
1046818334Speter
1046990286Sobrien;; ??? Currently never generated - xor is used instead.
1047090286Sobrien(define_insn "*one_cmplsi2_2_zext"
1047190286Sobrien  [(set (reg 17)
1047290286Sobrien	(compare (not:SI (match_operand:SI 1 "register_operand" "0"))
1047390286Sobrien		 (const_int 0)))
1047490286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1047590286Sobrien	(zero_extend:DI (not:SI (match_dup 1))))]
1047690286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
1047790286Sobrien   && ix86_unary_operator_ok (NOT, SImode, operands)"
1047890286Sobrien  "#"
1047990286Sobrien  [(set_attr "type" "alu1")
1048090286Sobrien   (set_attr "mode" "SI")])
1048118334Speter
1048290286Sobrien(define_split
1048390286Sobrien  [(set (reg 17)
1048490286Sobrien	(compare (not:SI (match_operand:SI 1 "register_operand" ""))
1048590286Sobrien		 (const_int 0)))
1048690286Sobrien   (set (match_operand:DI 0 "register_operand" "")
1048790286Sobrien	(zero_extend:DI (not:SI (match_dup 1))))]
1048890286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
1048990286Sobrien  [(parallel [(set (reg:CCNO 17)
1049090286Sobrien		   (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
1049190286Sobrien				 (const_int 0)))
1049290286Sobrien	      (set (match_dup 0)
1049390286Sobrien		   (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
1049490286Sobrien  "")
1049518334Speter
1049690286Sobrien(define_expand "one_cmplhi2"
1049790286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1049890286Sobrien	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
1049990286Sobrien  "TARGET_HIMODE_MATH"
1050090286Sobrien  "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
1050152296Sobrien
1050290286Sobrien(define_insn "*one_cmplhi2_1"
1050350650Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1050450650Sobrien	(not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
1050590286Sobrien  "ix86_unary_operator_ok (NOT, HImode, operands)"
1050690286Sobrien  "not{w}\t%0"
1050790286Sobrien  [(set_attr "type" "negnot")
1050890286Sobrien   (set_attr "mode" "HI")])
1050918334Speter
1051090286Sobrien(define_insn "*one_cmplhi2_2"
1051190286Sobrien  [(set (reg 17)
1051290286Sobrien	(compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
1051390286Sobrien		 (const_int 0)))
1051490286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1051590286Sobrien	(not:HI (match_dup 1)))]
1051690286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
1051790286Sobrien   && ix86_unary_operator_ok (NEG, HImode, operands)"
1051890286Sobrien  "#"
1051990286Sobrien  [(set_attr "type" "alu1")
1052090286Sobrien   (set_attr "mode" "HI")])
1052152296Sobrien
1052290286Sobrien(define_split
1052390286Sobrien  [(set (reg 17)
1052490286Sobrien	(compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
1052590286Sobrien		 (const_int 0)))
1052690286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "")
1052790286Sobrien	(not:HI (match_dup 1)))]
1052890286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
1052990286Sobrien  [(parallel [(set (reg:CCNO 17)
1053090286Sobrien		   (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
1053190286Sobrien		      		 (const_int 0)))
1053290286Sobrien	      (set (match_dup 0)
1053390286Sobrien		   (xor:HI (match_dup 1) (const_int -1)))])]
1053490286Sobrien  "")
1053552296Sobrien
1053690286Sobrien;; %%% Potential partial reg stall on alternative 1.  What to do?
1053790286Sobrien(define_expand "one_cmplqi2"
1053890286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1053990286Sobrien	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
1054090286Sobrien  "TARGET_QIMODE_MATH"
1054190286Sobrien  "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
1054290286Sobrien
1054390286Sobrien(define_insn "*one_cmplqi2_1"
1054490286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
1054590286Sobrien	(not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
1054690286Sobrien  "ix86_unary_operator_ok (NOT, QImode, operands)"
1054790286Sobrien  "@
1054890286Sobrien   not{b}\t%0
1054990286Sobrien   not{l}\t%k0"
1055090286Sobrien  [(set_attr "type" "negnot")
1055190286Sobrien   (set_attr "mode" "QI,SI")])
1055290286Sobrien
1055390286Sobrien(define_insn "*one_cmplqi2_2"
1055490286Sobrien  [(set (reg 17)
1055590286Sobrien	(compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
1055690286Sobrien		 (const_int 0)))
1055790286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1055890286Sobrien	(not:QI (match_dup 1)))]
1055990286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
1056090286Sobrien   && ix86_unary_operator_ok (NOT, QImode, operands)"
1056190286Sobrien  "#"
1056290286Sobrien  [(set_attr "type" "alu1")
1056390286Sobrien   (set_attr "mode" "QI")])
1056490286Sobrien
1056590286Sobrien(define_split
1056690286Sobrien  [(set (reg 17)
1056790286Sobrien	(compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
1056890286Sobrien		 (const_int 0)))
1056990286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "")
1057090286Sobrien	(not:QI (match_dup 1)))]
1057190286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
1057290286Sobrien  [(parallel [(set (reg:CCNO 17)
1057390286Sobrien		   (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
1057490286Sobrien		      		 (const_int 0)))
1057590286Sobrien	      (set (match_dup 0)
1057690286Sobrien		   (xor:QI (match_dup 1) (const_int -1)))])]
1057790286Sobrien  "")
1057818334Speter
1057990286Sobrien;; Arithmetic shift instructions
1058018334Speter
1058118334Speter;; DImode shifts are implemented using the i386 "shift double" opcode,
1058218334Speter;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
1058318334Speter;; is variable, then the count is in %cl and the "imm" operand is dropped
1058418334Speter;; from the assembler input.
1058590286Sobrien;;
1058618334Speter;; This instruction shifts the target reg/mem as usual, but instead of
1058718334Speter;; shifting in zeros, bits are shifted in from reg operand.  If the insn
1058818334Speter;; is a left shift double, bits are taken from the high order bits of
1058918334Speter;; reg, else if the insn is a shift right double, bits are taken from the
1059018334Speter;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
1059118334Speter;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
1059290286Sobrien;;
1059318334Speter;; Since sh[lr]d does not change the `reg' operand, that is done
1059418334Speter;; separately, making all shifts emit pairs of shift double and normal
1059518334Speter;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
1059618334Speter;; support a 63 bit shift, each shift where the count is in a reg expands
1059750650Sobrien;; to a pair of shifts, a branch, a shift by 32 and a label.
1059890286Sobrien;;
1059918334Speter;; If the shift count is a constant, we need never emit more than one
1060018334Speter;; shift pair, instead using moves and sign extension for counts greater
1060118334Speter;; than 31.
1060218334Speter
1060318334Speter(define_expand "ashldi3"
1060490286Sobrien  [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
1060590286Sobrien		   (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
1060690286Sobrien			      (match_operand:QI 2 "nonmemory_operand" "")))
1060790286Sobrien	      (clobber (reg:CC 17))])]
1060818334Speter  ""
1060918334Speter{
1061090286Sobrien  if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
1061118334Speter    {
1061290286Sobrien      emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
1061390286Sobrien      DONE;
1061418334Speter    }
1061590286Sobrien  ix86_expand_binary_operator (ASHIFT, DImode, operands);
1061618334Speter  DONE;
1061790286Sobrien})
1061818334Speter
1061990286Sobrien(define_insn "*ashldi3_1_rex64"
1062090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
1062190286Sobrien	(ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
1062290286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
1062390286Sobrien   (clobber (reg:CC 17))]
1062490286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
1062518334Speter{
1062690286Sobrien  switch (get_attr_type (insn))
1062790286Sobrien    {
1062890286Sobrien    case TYPE_ALU:
1062990286Sobrien      if (operands[2] != const1_rtx)
1063090286Sobrien	abort ();
1063190286Sobrien      if (!rtx_equal_p (operands[0], operands[1]))
1063290286Sobrien	abort ();
1063390286Sobrien      return "add{q}\t{%0, %0|%0, %0}";
1063418334Speter
1063590286Sobrien    case TYPE_LEA:
1063690286Sobrien      if (GET_CODE (operands[2]) != CONST_INT
1063790286Sobrien	  || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
1063890286Sobrien	abort ();
1063990286Sobrien      operands[1] = gen_rtx_MULT (DImode, operands[1],
1064090286Sobrien				  GEN_INT (1 << INTVAL (operands[2])));
1064190286Sobrien      return "lea{q}\t{%a1, %0|%0, %a1}";
1064218334Speter
1064390286Sobrien    default:
1064490286Sobrien      if (REG_P (operands[2]))
1064590286Sobrien	return "sal{q}\t{%b2, %0|%0, %b2}";
1064690286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1064790286Sobrien	       && INTVAL (operands[2]) == 1
1064890286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1064990286Sobrien	return "sal{q}\t%0";
1065090286Sobrien      else
1065190286Sobrien	return "sal{q}\t{%2, %0|%0, %2}";
1065290286Sobrien    }
1065390286Sobrien}
1065490286Sobrien  [(set (attr "type")
1065590286Sobrien     (cond [(eq_attr "alternative" "1")
1065690286Sobrien	      (const_string "lea")
1065790286Sobrien            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1065890286Sobrien		          (const_int 0))
1065990286Sobrien		      (match_operand 0 "register_operand" ""))
1066090286Sobrien		 (match_operand 2 "const1_operand" ""))
1066190286Sobrien	      (const_string "alu")
1066290286Sobrien	   ]
1066390286Sobrien	   (const_string "ishift")))
1066490286Sobrien   (set_attr "mode" "DI")])
1066518334Speter
1066690286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
1066790286Sobrien(define_split
1066890286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1066990286Sobrien	(ashift:DI (match_operand:DI 1 "register_operand" "")
1067090286Sobrien		   (match_operand:QI 2 "immediate_operand" "")))
1067190286Sobrien   (clobber (reg:CC 17))]
1067290286Sobrien  "TARGET_64BIT && reload_completed
1067390286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
1067490286Sobrien  [(set (match_dup 0)
1067590286Sobrien	(mult:DI (match_dup 1)
1067690286Sobrien		 (match_dup 2)))]
1067790286Sobrien  "operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
1067890286Sobrien					      DImode));")
1067990286Sobrien
1068090286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1068190286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1068290286Sobrien;; zero are optimized away.
1068390286Sobrien(define_insn "*ashldi3_cmp_rex64"
1068490286Sobrien  [(set (reg 17)
1068590286Sobrien	(compare
1068690286Sobrien	  (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1068790286Sobrien		     (match_operand:QI 2 "immediate_operand" "e"))
1068890286Sobrien	  (const_int 0)))
1068990286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1069090286Sobrien	(ashift:DI (match_dup 1) (match_dup 2)))]
1069190286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1069290286Sobrien   && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
1069390286Sobrien{
1069490286Sobrien  switch (get_attr_type (insn))
1069518334Speter    {
1069690286Sobrien    case TYPE_ALU:
1069790286Sobrien      if (operands[2] != const1_rtx)
1069890286Sobrien	abort ();
1069990286Sobrien      return "add{q}\t{%0, %0|%0, %0}";
1070018334Speter
1070190286Sobrien    default:
1070290286Sobrien      if (REG_P (operands[2]))
1070390286Sobrien	return "sal{q}\t{%b2, %0|%0, %b2}";
1070490286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1070590286Sobrien	       && INTVAL (operands[2]) == 1
1070690286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1070790286Sobrien	return "sal{q}\t%0";
1070890286Sobrien      else
1070990286Sobrien	return "sal{q}\t{%2, %0|%0, %2}";
1071018334Speter    }
1071190286Sobrien}
1071290286Sobrien  [(set (attr "type")
1071390286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1071490286Sobrien		          (const_int 0))
1071590286Sobrien		      (match_operand 0 "register_operand" ""))
1071690286Sobrien		 (match_operand 2 "const1_operand" ""))
1071790286Sobrien	      (const_string "alu")
1071890286Sobrien	   ]
1071990286Sobrien	   (const_string "ishift")))
1072090286Sobrien   (set_attr "mode" "DI")])
1072118334Speter
1072290286Sobrien(define_insn "ashldi3_1"
1072390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1072418334Speter	(ashift:DI (match_operand:DI 1 "register_operand" "0")
1072590286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "Jc")))
1072690286Sobrien   (clobber (match_scratch:SI 3 "=&r"))
1072790286Sobrien   (clobber (reg:CC 17))]
1072890286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1072990286Sobrien  "#"
1073090286Sobrien  [(set_attr "type" "multi")])
1073190286Sobrien
1073290286Sobrien(define_insn "*ashldi3_2"
1073390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1073490286Sobrien	(ashift:DI (match_operand:DI 1 "register_operand" "0")
1073590286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "Jc")))
1073690286Sobrien   (clobber (reg:CC 17))]
1073790286Sobrien  "!TARGET_64BIT"
1073890286Sobrien  "#"
1073990286Sobrien  [(set_attr "type" "multi")])
1074090286Sobrien
1074190286Sobrien(define_split
1074290286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1074390286Sobrien	(ashift:DI (match_operand:DI 1 "register_operand" "")
1074490286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1074590286Sobrien   (clobber (match_scratch:SI 3 ""))
1074690286Sobrien   (clobber (reg:CC 17))]
1074790286Sobrien  "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
1074890286Sobrien  [(const_int 0)]
1074990286Sobrien  "ix86_split_ashldi (operands, operands[3]); DONE;")
1075090286Sobrien
1075190286Sobrien(define_split
1075290286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1075390286Sobrien	(ashift:DI (match_operand:DI 1 "register_operand" "")
1075490286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1075590286Sobrien   (clobber (reg:CC 17))]
1075690286Sobrien  "!TARGET_64BIT && reload_completed"
1075790286Sobrien  [(const_int 0)]
1075890286Sobrien  "ix86_split_ashldi (operands, NULL_RTX); DONE;")
1075990286Sobrien
1076090286Sobrien(define_insn "x86_shld_1"
1076190286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
1076290286Sobrien        (ior:SI (ashift:SI (match_dup 0)
1076390286Sobrien		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
1076490286Sobrien		(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1076590286Sobrien		  (minus:QI (const_int 32) (match_dup 2)))))
1076690286Sobrien   (clobber (reg:CC 17))]
1076718334Speter  ""
1076890286Sobrien  "@
1076990286Sobrien   shld{l}\t{%2, %1, %0|%0, %1, %2}
1077090286Sobrien   shld{l}\t{%s2%1, %0|%0, %1, %2}"
1077190286Sobrien  [(set_attr "type" "ishift")
1077290286Sobrien   (set_attr "prefix_0f" "1")
1077390286Sobrien   (set_attr "mode" "SI")
1077490286Sobrien   (set_attr "pent_pair" "np")
1077590286Sobrien   (set_attr "athlon_decode" "vector")
1077690286Sobrien   (set_attr "ppro_uops" "few")])
1077790286Sobrien
1077890286Sobrien(define_expand "x86_shift_adj_1"
1077990286Sobrien  [(set (reg:CCZ 17)
1078090286Sobrien	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
1078190286Sobrien			     (const_int 32))
1078290286Sobrien		     (const_int 0)))
1078390286Sobrien   (set (match_operand:SI 0 "register_operand" "")
1078490286Sobrien        (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
1078590286Sobrien			 (match_operand:SI 1 "register_operand" "")
1078690286Sobrien			 (match_dup 0)))
1078790286Sobrien   (set (match_dup 1)
1078890286Sobrien	(if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
1078990286Sobrien			 (match_operand:SI 3 "register_operand" "r")
1079090286Sobrien			 (match_dup 1)))]
1079190286Sobrien  "TARGET_CMOVE"
1079290286Sobrien  "")
1079390286Sobrien
1079490286Sobrien(define_expand "x86_shift_adj_2"
1079590286Sobrien  [(use (match_operand:SI 0 "register_operand" ""))
1079690286Sobrien   (use (match_operand:SI 1 "register_operand" ""))
1079790286Sobrien   (use (match_operand:QI 2 "register_operand" ""))]
1079890286Sobrien  ""
1079918334Speter{
1080090286Sobrien  rtx label = gen_label_rtx ();
1080190286Sobrien  rtx tmp;
1080218334Speter
1080390286Sobrien  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
1080418334Speter
1080590286Sobrien  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
1080690286Sobrien  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1080790286Sobrien  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
1080890286Sobrien			      gen_rtx_LABEL_REF (VOIDmode, label),
1080990286Sobrien			      pc_rtx);
1081090286Sobrien  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
1081190286Sobrien  JUMP_LABEL (tmp) = label;
1081218334Speter
1081390286Sobrien  emit_move_insn (operands[0], operands[1]);
1081490286Sobrien  emit_move_insn (operands[1], const0_rtx);
1081518334Speter
1081690286Sobrien  emit_label (label);
1081790286Sobrien  LABEL_NUSES (label) = 1;
1081890286Sobrien
1081990286Sobrien  DONE;
1082090286Sobrien})
1082190286Sobrien
1082252296Sobrien(define_expand "ashlsi3"
1082352296Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1082452296Sobrien	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
1082590286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1082690286Sobrien   (clobber (reg:CC 17))]
1082752296Sobrien  ""
1082890286Sobrien  "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
1082918334Speter
1083090286Sobrien(define_insn "*ashlsi3_1"
1083190286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
1083290286Sobrien	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
1083390286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
1083490286Sobrien   (clobber (reg:CC 17))]
1083590286Sobrien  "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
1083690286Sobrien{
1083790286Sobrien  switch (get_attr_type (insn))
1083890286Sobrien    {
1083990286Sobrien    case TYPE_ALU:
1084090286Sobrien      if (operands[2] != const1_rtx)
1084190286Sobrien	abort ();
1084290286Sobrien      if (!rtx_equal_p (operands[0], operands[1]))
1084390286Sobrien	abort ();
1084490286Sobrien      return "add{l}\t{%0, %0|%0, %0}";
1084590286Sobrien
1084690286Sobrien    case TYPE_LEA:
1084790286Sobrien      return "#";
1084890286Sobrien
1084990286Sobrien    default:
1085090286Sobrien      if (REG_P (operands[2]))
1085190286Sobrien	return "sal{l}\t{%b2, %0|%0, %b2}";
1085290286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1085390286Sobrien	       && INTVAL (operands[2]) == 1
1085490286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1085590286Sobrien	return "sal{l}\t%0";
1085690286Sobrien      else
1085790286Sobrien	return "sal{l}\t{%2, %0|%0, %2}";
1085890286Sobrien    }
1085990286Sobrien}
1086090286Sobrien  [(set (attr "type")
1086190286Sobrien     (cond [(eq_attr "alternative" "1")
1086290286Sobrien	      (const_string "lea")
1086390286Sobrien            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1086490286Sobrien		          (const_int 0))
1086590286Sobrien		      (match_operand 0 "register_operand" ""))
1086690286Sobrien		 (match_operand 2 "const1_operand" ""))
1086790286Sobrien	      (const_string "alu")
1086890286Sobrien	   ]
1086990286Sobrien	   (const_string "ishift")))
1087090286Sobrien   (set_attr "mode" "SI")])
1087190286Sobrien
1087290286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
1087390286Sobrien(define_split
1087490286Sobrien  [(set (match_operand 0 "register_operand" "")
1087590286Sobrien	(ashift (match_operand 1 "register_operand" "")
1087690286Sobrien                (match_operand:QI 2 "const_int_operand" "")))
1087790286Sobrien   (clobber (reg:CC 17))]
1087890286Sobrien  "reload_completed
1087990286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
1088090286Sobrien  [(const_int 0)]
1088190286Sobrien{
1088290286Sobrien  rtx pat;
1088390286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
1088490286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
1088590286Sobrien  operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
1088690286Sobrien					     Pmode));
1088790286Sobrien  pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
1088890286Sobrien  if (Pmode != SImode)
1088990286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
1089090286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
1089190286Sobrien  DONE;
1089290286Sobrien})
1089390286Sobrien
1089490286Sobrien(define_insn "*ashlsi3_1_zext"
1089590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1089690286Sobrien	(zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
1089790286Sobrien			(match_operand:QI 2 "nonmemory_operand" "cI,M"))))
1089890286Sobrien   (clobber (reg:CC 17))]
1089990286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
1090090286Sobrien{
1090190286Sobrien  switch (get_attr_type (insn))
1090290286Sobrien    {
1090390286Sobrien    case TYPE_ALU:
1090490286Sobrien      if (operands[2] != const1_rtx)
1090590286Sobrien	abort ();
1090690286Sobrien      return "add{l}\t{%k0, %k0|%k0, %k0}";
1090790286Sobrien
1090890286Sobrien    case TYPE_LEA:
1090990286Sobrien      return "#";
1091090286Sobrien
1091190286Sobrien    default:
1091290286Sobrien      if (REG_P (operands[2]))
1091390286Sobrien	return "sal{l}\t{%b2, %k0|%k0, %b2}";
1091490286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1091590286Sobrien	       && INTVAL (operands[2]) == 1
1091690286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1091790286Sobrien	return "sal{l}\t%k0";
1091890286Sobrien      else
1091990286Sobrien	return "sal{l}\t{%2, %k0|%k0, %2}";
1092090286Sobrien    }
1092190286Sobrien}
1092290286Sobrien  [(set (attr "type")
1092390286Sobrien     (cond [(eq_attr "alternative" "1")
1092490286Sobrien	      (const_string "lea")
1092590286Sobrien            (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1092690286Sobrien		     (const_int 0))
1092790286Sobrien		 (match_operand 2 "const1_operand" ""))
1092890286Sobrien	      (const_string "alu")
1092990286Sobrien	   ]
1093090286Sobrien	   (const_string "ishift")))
1093190286Sobrien   (set_attr "mode" "SI")])
1093290286Sobrien
1093390286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
1093490286Sobrien(define_split
1093590286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1093690286Sobrien	(zero_extend:DI (ashift (match_operand 1 "register_operand" "")
1093790286Sobrien				(match_operand:QI 2 "const_int_operand" ""))))
1093890286Sobrien   (clobber (reg:CC 17))]
1093990286Sobrien  "reload_completed
1094090286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
1094190286Sobrien  [(set (match_dup 0) (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
1094290286Sobrien{
1094390286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
1094490286Sobrien  operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
1094590286Sobrien					     Pmode));
1094690286Sobrien})
1094790286Sobrien
1094890286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1094990286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1095090286Sobrien;; zero are optimized away.
1095190286Sobrien(define_insn "*ashlsi3_cmp"
1095290286Sobrien  [(set (reg 17)
1095390286Sobrien	(compare
1095490286Sobrien	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10955102802Skan		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
1095690286Sobrien	  (const_int 0)))
1095790286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1095890286Sobrien	(ashift:SI (match_dup 1) (match_dup 2)))]
1095990286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1096090286Sobrien   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
1096190286Sobrien{
1096290286Sobrien  switch (get_attr_type (insn))
1096390286Sobrien    {
1096490286Sobrien    case TYPE_ALU:
1096590286Sobrien      if (operands[2] != const1_rtx)
1096690286Sobrien	abort ();
1096790286Sobrien      return "add{l}\t{%0, %0|%0, %0}";
1096890286Sobrien
1096990286Sobrien    default:
1097090286Sobrien      if (REG_P (operands[2]))
1097190286Sobrien	return "sal{l}\t{%b2, %0|%0, %b2}";
1097290286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1097390286Sobrien	       && INTVAL (operands[2]) == 1
1097490286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1097590286Sobrien	return "sal{l}\t%0";
1097690286Sobrien      else
1097790286Sobrien	return "sal{l}\t{%2, %0|%0, %2}";
1097890286Sobrien    }
1097990286Sobrien}
1098090286Sobrien  [(set (attr "type")
1098190286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1098290286Sobrien		          (const_int 0))
1098390286Sobrien		      (match_operand 0 "register_operand" ""))
1098490286Sobrien		 (match_operand 2 "const1_operand" ""))
1098590286Sobrien	      (const_string "alu")
1098690286Sobrien	   ]
1098790286Sobrien	   (const_string "ishift")))
1098890286Sobrien   (set_attr "mode" "SI")])
1098990286Sobrien
1099090286Sobrien(define_insn "*ashlsi3_cmp_zext"
1099190286Sobrien  [(set (reg 17)
1099290286Sobrien	(compare
1099390286Sobrien	  (ashift:SI (match_operand:SI 1 "register_operand" "0")
10994102802Skan		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
1099590286Sobrien	  (const_int 0)))
1099690286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1099790286Sobrien	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
1099890286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1099990286Sobrien   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
1100090286Sobrien{
1100190286Sobrien  switch (get_attr_type (insn))
1100290286Sobrien    {
1100390286Sobrien    case TYPE_ALU:
1100490286Sobrien      if (operands[2] != const1_rtx)
1100590286Sobrien	abort ();
1100690286Sobrien      return "add{l}\t{%k0, %k0|%k0, %k0}";
1100790286Sobrien
1100890286Sobrien    default:
1100990286Sobrien      if (REG_P (operands[2]))
1101090286Sobrien	return "sal{l}\t{%b2, %k0|%k0, %b2}";
1101190286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1101290286Sobrien	       && INTVAL (operands[2]) == 1
1101390286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1101490286Sobrien	return "sal{l}\t%k0";
1101590286Sobrien      else
1101690286Sobrien	return "sal{l}\t{%2, %k0|%k0, %2}";
1101790286Sobrien    }
1101890286Sobrien}
1101990286Sobrien  [(set (attr "type")
1102090286Sobrien     (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1102190286Sobrien		     (const_int 0))
1102290286Sobrien		 (match_operand 2 "const1_operand" ""))
1102390286Sobrien	      (const_string "alu")
1102490286Sobrien	   ]
1102590286Sobrien	   (const_string "ishift")))
1102690286Sobrien   (set_attr "mode" "SI")])
1102790286Sobrien
1102852296Sobrien(define_expand "ashlhi3"
1102952296Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1103052296Sobrien	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
1103190286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1103290286Sobrien   (clobber (reg:CC 17))]
1103390286Sobrien  "TARGET_HIMODE_MATH"
1103490286Sobrien  "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
1103518334Speter
1103690286Sobrien(define_insn "*ashlhi3_1_lea"
1103790286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
1103890286Sobrien	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
1103990286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
1104090286Sobrien   (clobber (reg:CC 17))]
1104190286Sobrien  "!TARGET_PARTIAL_REG_STALL
1104290286Sobrien   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
1104390286Sobrien{
1104490286Sobrien  switch (get_attr_type (insn))
1104590286Sobrien    {
1104690286Sobrien    case TYPE_LEA:
1104790286Sobrien      return "#";
1104890286Sobrien    case TYPE_ALU:
1104990286Sobrien      if (operands[2] != const1_rtx)
1105090286Sobrien	abort ();
1105190286Sobrien      return "add{w}\t{%0, %0|%0, %0}";
1105290286Sobrien
1105390286Sobrien    default:
1105490286Sobrien      if (REG_P (operands[2]))
1105590286Sobrien	return "sal{w}\t{%b2, %0|%0, %b2}";
1105690286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1105790286Sobrien	       && INTVAL (operands[2]) == 1
1105890286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1105990286Sobrien	return "sal{w}\t%0";
1106090286Sobrien      else
1106190286Sobrien	return "sal{w}\t{%2, %0|%0, %2}";
1106290286Sobrien    }
1106390286Sobrien}
1106490286Sobrien  [(set (attr "type")
1106590286Sobrien     (cond [(eq_attr "alternative" "1")
1106690286Sobrien	      (const_string "lea")
1106790286Sobrien            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1106890286Sobrien		          (const_int 0))
1106990286Sobrien		      (match_operand 0 "register_operand" ""))
1107090286Sobrien		 (match_operand 2 "const1_operand" ""))
1107190286Sobrien	      (const_string "alu")
1107290286Sobrien	   ]
1107390286Sobrien	   (const_string "ishift")))
1107490286Sobrien   (set_attr "mode" "HI,SI")])
1107590286Sobrien
1107690286Sobrien(define_insn "*ashlhi3_1"
1107790286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1107890286Sobrien	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1107990286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI")))
1108090286Sobrien   (clobber (reg:CC 17))]
1108190286Sobrien  "TARGET_PARTIAL_REG_STALL
1108290286Sobrien   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
1108390286Sobrien{
1108490286Sobrien  switch (get_attr_type (insn))
1108590286Sobrien    {
1108690286Sobrien    case TYPE_ALU:
1108790286Sobrien      if (operands[2] != const1_rtx)
1108890286Sobrien	abort ();
1108990286Sobrien      return "add{w}\t{%0, %0|%0, %0}";
1109090286Sobrien
1109190286Sobrien    default:
1109290286Sobrien      if (REG_P (operands[2]))
1109390286Sobrien	return "sal{w}\t{%b2, %0|%0, %b2}";
1109490286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1109590286Sobrien	       && INTVAL (operands[2]) == 1
1109690286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1109790286Sobrien	return "sal{w}\t%0";
1109890286Sobrien      else
1109990286Sobrien	return "sal{w}\t{%2, %0|%0, %2}";
1110090286Sobrien    }
1110190286Sobrien}
1110290286Sobrien  [(set (attr "type")
1110390286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1110490286Sobrien		          (const_int 0))
1110590286Sobrien		      (match_operand 0 "register_operand" ""))
1110690286Sobrien		 (match_operand 2 "const1_operand" ""))
1110790286Sobrien	      (const_string "alu")
1110890286Sobrien	   ]
1110990286Sobrien	   (const_string "ishift")))
1111090286Sobrien   (set_attr "mode" "HI")])
1111190286Sobrien
1111290286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1111390286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1111490286Sobrien;; zero are optimized away.
1111590286Sobrien(define_insn "*ashlhi3_cmp"
1111690286Sobrien  [(set (reg 17)
1111790286Sobrien	(compare
1111890286Sobrien	  (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11119102802Skan		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
1112090286Sobrien	  (const_int 0)))
1112190286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1112290286Sobrien	(ashift:HI (match_dup 1) (match_dup 2)))]
1112390286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1112490286Sobrien   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
1112590286Sobrien{
1112690286Sobrien  switch (get_attr_type (insn))
1112790286Sobrien    {
1112890286Sobrien    case TYPE_ALU:
1112990286Sobrien      if (operands[2] != const1_rtx)
1113090286Sobrien	abort ();
1113190286Sobrien      return "add{w}\t{%0, %0|%0, %0}";
1113290286Sobrien
1113390286Sobrien    default:
1113490286Sobrien      if (REG_P (operands[2]))
1113590286Sobrien	return "sal{w}\t{%b2, %0|%0, %b2}";
1113690286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1113790286Sobrien	       && INTVAL (operands[2]) == 1
1113890286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1113990286Sobrien	return "sal{w}\t%0";
1114090286Sobrien      else
1114190286Sobrien	return "sal{w}\t{%2, %0|%0, %2}";
1114290286Sobrien    }
1114390286Sobrien}
1114490286Sobrien  [(set (attr "type")
1114590286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1114690286Sobrien		          (const_int 0))
1114790286Sobrien		      (match_operand 0 "register_operand" ""))
1114890286Sobrien		 (match_operand 2 "const1_operand" ""))
1114990286Sobrien	      (const_string "alu")
1115090286Sobrien	   ]
1115190286Sobrien	   (const_string "ishift")))
1115290286Sobrien   (set_attr "mode" "HI")])
1115390286Sobrien
1115452296Sobrien(define_expand "ashlqi3"
1115552296Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1115652296Sobrien	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
1115790286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1115890286Sobrien   (clobber (reg:CC 17))]
1115990286Sobrien  "TARGET_QIMODE_MATH"
1116090286Sobrien  "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
1116118334Speter
1116290286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
1116318334Speter
1116490286Sobrien(define_insn "*ashlqi3_1_lea"
1116590286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
1116690286Sobrien	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
1116790286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
1116890286Sobrien   (clobber (reg:CC 17))]
1116990286Sobrien  "!TARGET_PARTIAL_REG_STALL
1117090286Sobrien   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
1117190286Sobrien{
1117290286Sobrien  switch (get_attr_type (insn))
1117390286Sobrien    {
1117490286Sobrien    case TYPE_LEA:
1117590286Sobrien      return "#";
1117690286Sobrien    case TYPE_ALU:
1117790286Sobrien      if (operands[2] != const1_rtx)
1117890286Sobrien	abort ();
1117990286Sobrien      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
1118090286Sobrien        return "add{l}\t{%k0, %k0|%k0, %k0}";
1118190286Sobrien      else
1118290286Sobrien        return "add{b}\t{%0, %0|%0, %0}";
1118318334Speter
1118490286Sobrien    default:
1118590286Sobrien      if (REG_P (operands[2]))
1118690286Sobrien	{
1118790286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1118890286Sobrien	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
1118990286Sobrien	  else
1119090286Sobrien	    return "sal{b}\t{%b2, %0|%0, %b2}";
1119190286Sobrien	}
1119290286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1119390286Sobrien	       && INTVAL (operands[2]) == 1
1119490286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1119590286Sobrien	{
1119690286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1119790286Sobrien	    return "sal{l}\t%0";
1119890286Sobrien	  else
1119990286Sobrien	    return "sal{b}\t%0";
1120090286Sobrien	}
1120190286Sobrien      else
1120290286Sobrien	{
1120390286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1120490286Sobrien	    return "sal{l}\t{%2, %k0|%k0, %2}";
1120590286Sobrien	  else
1120690286Sobrien	    return "sal{b}\t{%2, %0|%0, %2}";
1120790286Sobrien	}
1120890286Sobrien    }
1120990286Sobrien}
1121090286Sobrien  [(set (attr "type")
1121190286Sobrien     (cond [(eq_attr "alternative" "2")
1121290286Sobrien	      (const_string "lea")
1121390286Sobrien            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1121490286Sobrien		          (const_int 0))
1121590286Sobrien		      (match_operand 0 "register_operand" ""))
1121690286Sobrien		 (match_operand 2 "const1_operand" ""))
1121790286Sobrien	      (const_string "alu")
1121890286Sobrien	   ]
1121990286Sobrien	   (const_string "ishift")))
1122090286Sobrien   (set_attr "mode" "QI,SI,SI")])
1122118334Speter
1122290286Sobrien(define_insn "*ashlqi3_1"
1122390286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
1122490286Sobrien	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1122590286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
1122690286Sobrien   (clobber (reg:CC 17))]
1122790286Sobrien  "TARGET_PARTIAL_REG_STALL
1122890286Sobrien   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
1122990286Sobrien{
1123090286Sobrien  switch (get_attr_type (insn))
1123190286Sobrien    {
1123290286Sobrien    case TYPE_ALU:
1123390286Sobrien      if (operands[2] != const1_rtx)
1123490286Sobrien	abort ();
1123590286Sobrien      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
1123690286Sobrien        return "add{l}\t{%k0, %k0|%k0, %k0}";
1123790286Sobrien      else
1123890286Sobrien        return "add{b}\t{%0, %0|%0, %0}";
1123952296Sobrien
1124090286Sobrien    default:
1124190286Sobrien      if (REG_P (operands[2]))
1124290286Sobrien	{
1124390286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1124490286Sobrien	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
1124590286Sobrien	  else
1124690286Sobrien	    return "sal{b}\t{%b2, %0|%0, %b2}";
1124790286Sobrien	}
1124890286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1124990286Sobrien	       && INTVAL (operands[2]) == 1
1125090286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1125190286Sobrien	{
1125290286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1125390286Sobrien	    return "sal{l}\t%0";
1125490286Sobrien	  else
1125590286Sobrien	    return "sal{b}\t%0";
1125690286Sobrien	}
1125790286Sobrien      else
1125890286Sobrien	{
1125990286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1126090286Sobrien	    return "sal{l}\t{%2, %k0|%k0, %2}";
1126190286Sobrien	  else
1126290286Sobrien	    return "sal{b}\t{%2, %0|%0, %2}";
1126390286Sobrien	}
1126490286Sobrien    }
1126590286Sobrien}
1126690286Sobrien  [(set (attr "type")
1126790286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1126890286Sobrien		          (const_int 0))
1126990286Sobrien		      (match_operand 0 "register_operand" ""))
1127090286Sobrien		 (match_operand 2 "const1_operand" ""))
1127190286Sobrien	      (const_string "alu")
1127290286Sobrien	   ]
1127390286Sobrien	   (const_string "ishift")))
1127490286Sobrien   (set_attr "mode" "QI,SI")])
1127518334Speter
1127690286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1127790286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1127890286Sobrien;; zero are optimized away.
1127990286Sobrien(define_insn "*ashlqi3_cmp"
1128090286Sobrien  [(set (reg 17)
1128190286Sobrien	(compare
1128290286Sobrien	  (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11283102802Skan		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
1128490286Sobrien	  (const_int 0)))
1128590286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1128690286Sobrien	(ashift:QI (match_dup 1) (match_dup 2)))]
1128790286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1128890286Sobrien   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
1128990286Sobrien{
1129090286Sobrien  switch (get_attr_type (insn))
1129190286Sobrien    {
1129290286Sobrien    case TYPE_ALU:
1129390286Sobrien      if (operands[2] != const1_rtx)
1129490286Sobrien	abort ();
1129590286Sobrien      return "add{b}\t{%0, %0|%0, %0}";
1129618334Speter
1129790286Sobrien    default:
1129890286Sobrien      if (REG_P (operands[2]))
1129990286Sobrien	return "sal{b}\t{%b2, %0|%0, %b2}";
1130090286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1130190286Sobrien	       && INTVAL (operands[2]) == 1
1130290286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1130390286Sobrien	return "sal{b}\t%0";
1130490286Sobrien      else
1130590286Sobrien	return "sal{b}\t{%2, %0|%0, %2}";
1130690286Sobrien    }
1130790286Sobrien}
1130890286Sobrien  [(set (attr "type")
1130990286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1131090286Sobrien		          (const_int 0))
1131190286Sobrien		      (match_operand 0 "register_operand" ""))
1131290286Sobrien		 (match_operand 2 "const1_operand" ""))
1131390286Sobrien	      (const_string "alu")
1131490286Sobrien	   ]
1131590286Sobrien	   (const_string "ishift")))
1131690286Sobrien   (set_attr "mode" "QI")])
1131718334Speter
1131818334Speter;; See comment above `ashldi3' about how this works.
1131918334Speter
1132018334Speter(define_expand "ashrdi3"
1132190286Sobrien  [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
1132290286Sobrien		   (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
1132390286Sobrien				(match_operand:QI 2 "nonmemory_operand" "")))
1132490286Sobrien	      (clobber (reg:CC 17))])]
1132518334Speter  ""
1132618334Speter{
1132790286Sobrien  if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
1132818334Speter    {
1132990286Sobrien      emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
1133090286Sobrien      DONE;
1133118334Speter    }
1133290286Sobrien  ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
1133318334Speter  DONE;
1133490286Sobrien})
1133518334Speter
1133690286Sobrien(define_insn "ashrdi3_63_rex64"
1133790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
1133890286Sobrien	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
1133990286Sobrien		     (match_operand:DI 2 "const_int_operand" "i,i")))
1134090286Sobrien   (clobber (reg:CC 17))]
1134190286Sobrien  "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
1134290286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
1134390286Sobrien  "@
1134490286Sobrien   {cqto|cqo}
1134590286Sobrien   sar{q}\t{%2, %0|%0, %2}"
1134690286Sobrien  [(set_attr "type" "imovx,ishift")
1134790286Sobrien   (set_attr "prefix_0f" "0,*")
1134890286Sobrien   (set_attr "length_immediate" "0,*")
1134990286Sobrien   (set_attr "modrm" "0,1")
1135090286Sobrien   (set_attr "mode" "DI")])
1135150650Sobrien
1135290286Sobrien(define_insn "*ashrdi3_1_one_bit_rex64"
1135390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1135490286Sobrien	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1135590286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1135690286Sobrien   (clobber (reg:CC 17))]
1135790286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
1135890286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1135990286Sobrien  "sar{q}\t%0"
1136090286Sobrien  [(set_attr "type" "ishift")
1136190286Sobrien   (set (attr "length") 
1136290286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1136390286Sobrien	(const_string "2")
1136490286Sobrien	(const_string "*")))])
1136550650Sobrien
1136690286Sobrien(define_insn "*ashrdi3_1_rex64"
1136790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
1136890286Sobrien	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
1136990286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
1137090286Sobrien   (clobber (reg:CC 17))]
1137190286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
1137290286Sobrien  "@
1137390286Sobrien   sar{q}\t{%2, %0|%0, %2}
1137490286Sobrien   sar{q}\t{%b2, %0|%0, %b2}"
1137590286Sobrien  [(set_attr "type" "ishift")
1137690286Sobrien   (set_attr "mode" "DI")])
1137750650Sobrien
1137890286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1137990286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1138090286Sobrien;; zero are optimized away.
1138190286Sobrien(define_insn "*ashrdi3_one_bit_cmp_rex64"
1138290286Sobrien  [(set (reg 17)
1138390286Sobrien	(compare
1138490286Sobrien	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1138590286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1138690286Sobrien	  (const_int 0)))
1138790286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1138890286Sobrien	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
1138990286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1139090286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1139190286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
1139290286Sobrien  "sar{q}\t%0"
1139390286Sobrien  [(set_attr "type" "ishift")
1139490286Sobrien   (set (attr "length") 
1139590286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1139690286Sobrien	(const_string "2")
1139790286Sobrien	(const_string "*")))])
1139850650Sobrien
1139990286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1140090286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1140190286Sobrien;; zero are optimized away.
1140290286Sobrien(define_insn "*ashrdi3_cmp_rex64"
1140390286Sobrien  [(set (reg 17)
1140490286Sobrien	(compare
1140590286Sobrien	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1140690286Sobrien		       (match_operand:QI 2 "const_int_operand" "n"))
1140790286Sobrien	  (const_int 0)))
1140890286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1140990286Sobrien	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
1141090286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1141190286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
1141290286Sobrien  "sar{q}\t{%2, %0|%0, %2}"
1141390286Sobrien  [(set_attr "type" "ishift")
1141490286Sobrien   (set_attr "mode" "DI")])
1141518334Speter
1141618334Speter
1141790286Sobrien(define_insn "ashrdi3_1"
1141890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1141990286Sobrien	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
1142090286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
1142190286Sobrien   (clobber (match_scratch:SI 3 "=&r"))
1142290286Sobrien   (clobber (reg:CC 17))]
1142390286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1142490286Sobrien  "#"
1142590286Sobrien  [(set_attr "type" "multi")])
1142618334Speter
1142790286Sobrien(define_insn "*ashrdi3_2"
1142890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1142990286Sobrien	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
1143090286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
1143190286Sobrien   (clobber (reg:CC 17))]
1143290286Sobrien  "!TARGET_64BIT"
1143390286Sobrien  "#"
1143490286Sobrien  [(set_attr "type" "multi")])
1143518334Speter
1143690286Sobrien(define_split
1143790286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1143890286Sobrien	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
1143990286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1144090286Sobrien   (clobber (match_scratch:SI 3 ""))
1144190286Sobrien   (clobber (reg:CC 17))]
1144290286Sobrien  "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
1144390286Sobrien  [(const_int 0)]
1144490286Sobrien  "ix86_split_ashrdi (operands, operands[3]); DONE;")
1144518334Speter
1144690286Sobrien(define_split
1144790286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1144890286Sobrien	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
1144990286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1145090286Sobrien   (clobber (reg:CC 17))]
1145190286Sobrien  "!TARGET_64BIT && reload_completed"
1145290286Sobrien  [(const_int 0)]
1145390286Sobrien  "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
1145418334Speter
1145590286Sobrien(define_insn "x86_shrd_1"
1145690286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
1145790286Sobrien        (ior:SI (ashiftrt:SI (match_dup 0)
1145890286Sobrien		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
1145990286Sobrien		(ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1146090286Sobrien		  (minus:QI (const_int 32) (match_dup 2)))))
1146190286Sobrien   (clobber (reg:CC 17))]
1146218334Speter  ""
1146390286Sobrien  "@
1146490286Sobrien   shrd{l}\t{%2, %1, %0|%0, %1, %2}
1146590286Sobrien   shrd{l}\t{%s2%1, %0|%0, %1, %2}"
1146690286Sobrien  [(set_attr "type" "ishift")
1146790286Sobrien   (set_attr "prefix_0f" "1")
1146890286Sobrien   (set_attr "pent_pair" "np")
1146990286Sobrien   (set_attr "ppro_uops" "few")
1147090286Sobrien   (set_attr "mode" "SI")])
1147190286Sobrien
1147290286Sobrien(define_expand "x86_shift_adj_3"
1147390286Sobrien  [(use (match_operand:SI 0 "register_operand" ""))
1147490286Sobrien   (use (match_operand:SI 1 "register_operand" ""))
1147590286Sobrien   (use (match_operand:QI 2 "register_operand" ""))]
1147690286Sobrien  ""
1147718334Speter{
1147890286Sobrien  rtx label = gen_label_rtx ();
1147990286Sobrien  rtx tmp;
1148018334Speter
1148190286Sobrien  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
1148218334Speter
1148390286Sobrien  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
1148490286Sobrien  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1148590286Sobrien  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
1148690286Sobrien			      gen_rtx_LABEL_REF (VOIDmode, label),
1148790286Sobrien			      pc_rtx);
1148890286Sobrien  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
1148990286Sobrien  JUMP_LABEL (tmp) = label;
1149018334Speter
1149190286Sobrien  emit_move_insn (operands[0], operands[1]);
1149290286Sobrien  emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
1149318334Speter
1149490286Sobrien  emit_label (label);
1149590286Sobrien  LABEL_NUSES (label) = 1;
1149690286Sobrien
1149790286Sobrien  DONE;
1149890286Sobrien})
1149990286Sobrien
1150052296Sobrien(define_insn "ashrsi3_31"
1150190286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
1150290286Sobrien	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
1150390286Sobrien		     (match_operand:SI 2 "const_int_operand" "i,i")))
1150490286Sobrien   (clobber (reg:CC 17))]
1150590286Sobrien  "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
1150690286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1150752296Sobrien  "@
1150890286Sobrien   {cltd|cdq}
1150990286Sobrien   sar{l}\t{%2, %0|%0, %2}"
1151090286Sobrien  [(set_attr "type" "imovx,ishift")
1151190286Sobrien   (set_attr "prefix_0f" "0,*")
1151290286Sobrien   (set_attr "length_immediate" "0,*")
1151390286Sobrien   (set_attr "modrm" "0,1")
1151490286Sobrien   (set_attr "mode" "SI")])
1151552296Sobrien
1151690286Sobrien(define_insn "*ashrsi3_31_zext"
1151790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=*d,r")
1151890286Sobrien	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
1151990286Sobrien				     (match_operand:SI 2 "const_int_operand" "i,i"))))
1152090286Sobrien   (clobber (reg:CC 17))]
1152190286Sobrien  "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
1152290286Sobrien   && INTVAL (operands[2]) == 31
1152390286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1152490286Sobrien  "@
1152590286Sobrien   {cltd|cdq}
1152690286Sobrien   sar{l}\t{%2, %k0|%k0, %2}"
1152790286Sobrien  [(set_attr "type" "imovx,ishift")
1152890286Sobrien   (set_attr "prefix_0f" "0,*")
1152990286Sobrien   (set_attr "length_immediate" "0,*")
1153090286Sobrien   (set_attr "modrm" "0,1")
1153190286Sobrien   (set_attr "mode" "SI")])
1153290286Sobrien
1153390286Sobrien(define_expand "ashrsi3"
1153490286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1153590286Sobrien	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
1153690286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1153790286Sobrien   (clobber (reg:CC 17))]
1153890286Sobrien  ""
1153990286Sobrien  "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
1154090286Sobrien
1154190286Sobrien(define_insn "*ashrsi3_1_one_bit"
1154250650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1154350650Sobrien	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1154490286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1154590286Sobrien   (clobber (reg:CC 17))]
1154690286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
1154790286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1154890286Sobrien  "sar{l}\t%0"
1154990286Sobrien  [(set_attr "type" "ishift")
1155090286Sobrien   (set (attr "length") 
1155190286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1155290286Sobrien	(const_string "2")
1155390286Sobrien	(const_string "*")))])
1155418334Speter
1155590286Sobrien(define_insn "*ashrsi3_1_one_bit_zext"
1155690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1155790286Sobrien	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
1155890286Sobrien				     (match_operand:QI 2 "const_int_1_operand" ""))))
1155990286Sobrien   (clobber (reg:CC 17))]
1156090286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
1156190286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1156290286Sobrien  "sar{l}\t%k0"
1156390286Sobrien  [(set_attr "type" "ishift")
1156490286Sobrien   (set_attr "length" "2")])
1156590286Sobrien
1156690286Sobrien(define_insn "*ashrsi3_1"
1156790286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1156890286Sobrien	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1156990286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1157090286Sobrien   (clobber (reg:CC 17))]
1157190286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1157290286Sobrien  "@
1157390286Sobrien   sar{l}\t{%2, %0|%0, %2}
1157490286Sobrien   sar{l}\t{%b2, %0|%0, %b2}"
1157590286Sobrien  [(set_attr "type" "ishift")
1157690286Sobrien   (set_attr "mode" "SI")])
1157790286Sobrien
1157890286Sobrien(define_insn "*ashrsi3_1_zext"
1157990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1158090286Sobrien	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
1158190286Sobrien				     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
1158290286Sobrien   (clobber (reg:CC 17))]
1158390286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1158490286Sobrien  "@
1158590286Sobrien   sar{l}\t{%2, %k0|%k0, %2}
1158690286Sobrien   sar{l}\t{%b2, %k0|%k0, %b2}"
1158790286Sobrien  [(set_attr "type" "ishift")
1158890286Sobrien   (set_attr "mode" "SI")])
1158990286Sobrien
1159090286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1159190286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1159290286Sobrien;; zero are optimized away.
1159390286Sobrien(define_insn "*ashrsi3_one_bit_cmp"
1159490286Sobrien  [(set (reg 17)
1159590286Sobrien	(compare
1159690286Sobrien	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1159790286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1159890286Sobrien	  (const_int 0)))
1159990286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1160090286Sobrien	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
1160190286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1160290286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1160390286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1160490286Sobrien  "sar{l}\t%0"
1160590286Sobrien  [(set_attr "type" "ishift")
1160690286Sobrien   (set (attr "length") 
1160790286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1160890286Sobrien	(const_string "2")
1160990286Sobrien	(const_string "*")))])
1161090286Sobrien
1161190286Sobrien(define_insn "*ashrsi3_one_bit_cmp_zext"
1161290286Sobrien  [(set (reg 17)
1161390286Sobrien	(compare
1161490286Sobrien	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
1161590286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1161690286Sobrien	  (const_int 0)))
1161790286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1161890286Sobrien	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
1161990286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
1162090286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1162190286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1162290286Sobrien  "sar{l}\t%k0"
1162390286Sobrien  [(set_attr "type" "ishift")
1162490286Sobrien   (set_attr "length" "2")])
1162590286Sobrien
1162690286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1162790286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1162890286Sobrien;; zero are optimized away.
1162990286Sobrien(define_insn "*ashrsi3_cmp"
1163090286Sobrien  [(set (reg 17)
1163190286Sobrien	(compare
1163290286Sobrien	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11633102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1163490286Sobrien	  (const_int 0)))
1163590286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1163690286Sobrien	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
1163790286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1163890286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1163990286Sobrien  "sar{l}\t{%2, %0|%0, %2}"
1164090286Sobrien  [(set_attr "type" "ishift")
1164190286Sobrien   (set_attr "mode" "SI")])
1164290286Sobrien
1164390286Sobrien(define_insn "*ashrsi3_cmp_zext"
1164490286Sobrien  [(set (reg 17)
1164590286Sobrien	(compare
1164690286Sobrien	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11647102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1164890286Sobrien	  (const_int 0)))
1164990286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1165090286Sobrien	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
1165190286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1165290286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1165390286Sobrien  "sar{l}\t{%2, %k0|%k0, %2}"
1165490286Sobrien  [(set_attr "type" "ishift")
1165590286Sobrien   (set_attr "mode" "SI")])
1165690286Sobrien
1165790286Sobrien(define_expand "ashrhi3"
1165890286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1165990286Sobrien	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
1166090286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1166190286Sobrien   (clobber (reg:CC 17))]
1166290286Sobrien  "TARGET_HIMODE_MATH"
1166390286Sobrien  "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
1166490286Sobrien
1166590286Sobrien(define_insn "*ashrhi3_1_one_bit"
1166650650Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1166750650Sobrien	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1166890286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1166990286Sobrien   (clobber (reg:CC 17))]
1167090286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
1167190286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1167290286Sobrien  "sar{w}\t%0"
1167390286Sobrien  [(set_attr "type" "ishift")
1167490286Sobrien   (set (attr "length") 
1167590286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1167690286Sobrien	(const_string "2")
1167790286Sobrien	(const_string "*")))])
1167818334Speter
1167990286Sobrien(define_insn "*ashrhi3_1"
1168090286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
1168190286Sobrien	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
1168290286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1168390286Sobrien   (clobber (reg:CC 17))]
1168490286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
1168590286Sobrien  "@
1168690286Sobrien   sar{w}\t{%2, %0|%0, %2}
1168790286Sobrien   sar{w}\t{%b2, %0|%0, %b2}"
1168890286Sobrien  [(set_attr "type" "ishift")
1168990286Sobrien   (set_attr "mode" "HI")])
1169090286Sobrien
1169190286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1169290286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1169390286Sobrien;; zero are optimized away.
1169490286Sobrien(define_insn "*ashrhi3_one_bit_cmp"
1169590286Sobrien  [(set (reg 17)
1169690286Sobrien	(compare
1169790286Sobrien	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1169890286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1169990286Sobrien	  (const_int 0)))
1170090286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1170190286Sobrien	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
1170290286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1170390286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1170490286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
1170590286Sobrien  "sar{w}\t%0"
1170690286Sobrien  [(set_attr "type" "ishift")
1170790286Sobrien   (set (attr "length") 
1170890286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1170990286Sobrien	(const_string "2")
1171090286Sobrien	(const_string "*")))])
1171190286Sobrien
1171290286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1171390286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1171490286Sobrien;; zero are optimized away.
1171590286Sobrien(define_insn "*ashrhi3_cmp"
1171690286Sobrien  [(set (reg 17)
1171790286Sobrien	(compare
1171890286Sobrien	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11719102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1172090286Sobrien	  (const_int 0)))
1172190286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1172290286Sobrien	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
1172390286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1172490286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
1172590286Sobrien  "sar{w}\t{%2, %0|%0, %2}"
1172690286Sobrien  [(set_attr "type" "ishift")
1172790286Sobrien   (set_attr "mode" "HI")])
1172890286Sobrien
1172990286Sobrien(define_expand "ashrqi3"
1173090286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1173190286Sobrien	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
1173290286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1173390286Sobrien   (clobber (reg:CC 17))]
1173490286Sobrien  "TARGET_QIMODE_MATH"
1173590286Sobrien  "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
1173690286Sobrien
1173790286Sobrien(define_insn "*ashrqi3_1_one_bit"
1173850650Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1173950650Sobrien	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1174090286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1174190286Sobrien   (clobber (reg:CC 17))]
1174290286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
1174390286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1174490286Sobrien  "sar{b}\t%0"
1174590286Sobrien  [(set_attr "type" "ishift")
1174690286Sobrien   (set (attr "length") 
1174790286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1174890286Sobrien	(const_string "2")
1174990286Sobrien	(const_string "*")))])
1175090286Sobrien
1175190286Sobrien(define_insn "*ashrqi3_1"
1175290286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
1175390286Sobrien	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1175490286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1175590286Sobrien   (clobber (reg:CC 17))]
1175690286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
1175790286Sobrien  "@
1175890286Sobrien   sar{b}\t{%2, %0|%0, %2}
1175990286Sobrien   sar{b}\t{%b2, %0|%0, %b2}"
1176090286Sobrien  [(set_attr "type" "ishift")
1176190286Sobrien   (set_attr "mode" "QI")])
1176290286Sobrien
1176390286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1176490286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1176590286Sobrien;; zero are optimized away.
1176690286Sobrien(define_insn "*ashrqi3_one_bit_cmp"
1176790286Sobrien  [(set (reg 17)
1176890286Sobrien	(compare
1176990286Sobrien	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1177090286Sobrien		       (match_operand:QI 2 "const_int_1_operand" "I"))
1177190286Sobrien	  (const_int 0)))
11772102802Skan   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1177390286Sobrien	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
1177490286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1177590286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1177690286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
1177790286Sobrien  "sar{b}\t%0"
1177890286Sobrien  [(set_attr "type" "ishift")
1177990286Sobrien   (set (attr "length") 
1178090286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1178190286Sobrien	(const_string "2")
1178290286Sobrien	(const_string "*")))])
1178390286Sobrien
1178490286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1178590286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1178690286Sobrien;; zero are optimized away.
1178790286Sobrien(define_insn "*ashrqi3_cmp"
1178890286Sobrien  [(set (reg 17)
1178990286Sobrien	(compare
1179090286Sobrien	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11791102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1179290286Sobrien	  (const_int 0)))
11793102802Skan   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1179490286Sobrien	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
1179590286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1179690286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
1179790286Sobrien  "sar{b}\t{%2, %0|%0, %2}"
1179890286Sobrien  [(set_attr "type" "ishift")
1179990286Sobrien   (set_attr "mode" "QI")])
1180018334Speter
1180190286Sobrien;; Logical shift instructions
1180218334Speter
1180318334Speter;; See comment above `ashldi3' about how this works.
1180418334Speter
1180518334Speter(define_expand "lshrdi3"
1180690286Sobrien  [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
1180790286Sobrien		   (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
1180890286Sobrien			        (match_operand:QI 2 "nonmemory_operand" "")))
1180990286Sobrien	      (clobber (reg:CC 17))])]
1181018334Speter  ""
1181118334Speter{
1181290286Sobrien  if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
1181318334Speter    {
1181490286Sobrien      emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
1181590286Sobrien      DONE;
1181618334Speter    }
1181790286Sobrien  ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
1181818334Speter  DONE;
1181990286Sobrien})
1182018334Speter
1182190286Sobrien(define_insn "*lshrdi3_1_one_bit_rex64"
1182290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1182390286Sobrien	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1182490286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1182590286Sobrien   (clobber (reg:CC 17))]
1182690286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
1182790286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1182890286Sobrien  "shr{q}\t%0"
1182990286Sobrien  [(set_attr "type" "ishift")
1183090286Sobrien   (set (attr "length") 
1183190286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1183290286Sobrien	(const_string "2")
1183390286Sobrien	(const_string "*")))])
1183450650Sobrien
1183590286Sobrien(define_insn "*lshrdi3_1_rex64"
1183690286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
1183790286Sobrien	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
1183890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
1183990286Sobrien   (clobber (reg:CC 17))]
1184090286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1184190286Sobrien  "@
1184290286Sobrien   shr{q}\t{%2, %0|%0, %2}
1184390286Sobrien   shr{q}\t{%b2, %0|%0, %b2}"
1184490286Sobrien  [(set_attr "type" "ishift")
1184590286Sobrien   (set_attr "mode" "DI")])
1184650650Sobrien
1184790286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1184890286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1184990286Sobrien;; zero are optimized away.
1185090286Sobrien(define_insn "*lshrdi3_cmp_one_bit_rex64"
1185190286Sobrien  [(set (reg 17)
1185290286Sobrien	(compare
1185390286Sobrien	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1185490286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1185590286Sobrien	  (const_int 0)))
1185690286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1185790286Sobrien	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
1185890286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1185990286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1186090286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1186190286Sobrien  "shr{q}\t%0"
1186290286Sobrien  [(set_attr "type" "ishift")
1186390286Sobrien   (set (attr "length") 
1186490286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1186590286Sobrien	(const_string "2")
1186690286Sobrien	(const_string "*")))])
1186750650Sobrien
1186890286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1186990286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1187090286Sobrien;; zero are optimized away.
1187190286Sobrien(define_insn "*lshrdi3_cmp_rex64"
1187290286Sobrien  [(set (reg 17)
1187390286Sobrien	(compare
1187490286Sobrien	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1187590286Sobrien		       (match_operand:QI 2 "const_int_operand" "e"))
1187690286Sobrien	  (const_int 0)))
1187790286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1187890286Sobrien	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
1187990286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1188090286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1188190286Sobrien  "shr{q}\t{%2, %0|%0, %2}"
1188290286Sobrien  [(set_attr "type" "ishift")
1188390286Sobrien   (set_attr "mode" "DI")])
1188450650Sobrien
1188590286Sobrien(define_insn "lshrdi3_1"
1188690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1188718334Speter	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
1188890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
1188990286Sobrien   (clobber (match_scratch:SI 3 "=&r"))
1189090286Sobrien   (clobber (reg:CC 17))]
1189190286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1189290286Sobrien  "#"
1189390286Sobrien  [(set_attr "type" "multi")])
1189418334Speter
1189590286Sobrien(define_insn "*lshrdi3_2"
1189690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1189790286Sobrien	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
1189890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
1189990286Sobrien   (clobber (reg:CC 17))]
1190090286Sobrien  "!TARGET_64BIT"
1190190286Sobrien  "#"
1190290286Sobrien  [(set_attr "type" "multi")])
1190318334Speter
1190490286Sobrien(define_split 
1190590286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1190690286Sobrien	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
1190790286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1190890286Sobrien   (clobber (match_scratch:SI 3 ""))
1190990286Sobrien   (clobber (reg:CC 17))]
1191090286Sobrien  "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
1191190286Sobrien  [(const_int 0)]
1191290286Sobrien  "ix86_split_lshrdi (operands, operands[3]); DONE;")
1191318334Speter
1191490286Sobrien(define_split 
1191590286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1191690286Sobrien	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
1191790286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1191890286Sobrien   (clobber (reg:CC 17))]
1191990286Sobrien  "!TARGET_64BIT && reload_completed"
1192090286Sobrien  [(const_int 0)]
1192190286Sobrien  "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
1192218334Speter
1192390286Sobrien(define_expand "lshrsi3"
1192490286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1192590286Sobrien	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
1192690286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1192790286Sobrien   (clobber (reg:CC 17))]
1192890286Sobrien  ""
1192990286Sobrien  "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
1193018334Speter
1193190286Sobrien(define_insn "*lshrsi3_1_one_bit"
1193290286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1193390286Sobrien	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1193490286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1193590286Sobrien   (clobber (reg:CC 17))]
1193690286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
1193790286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1193890286Sobrien  "shr{l}\t%0"
1193990286Sobrien  [(set_attr "type" "ishift")
1194090286Sobrien   (set (attr "length") 
1194190286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1194290286Sobrien	(const_string "2")
1194390286Sobrien	(const_string "*")))])
1194418334Speter
1194590286Sobrien(define_insn "*lshrsi3_1_one_bit_zext"
1194690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1194790286Sobrien	(lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
1194890286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1194990286Sobrien   (clobber (reg:CC 17))]
1195090286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
1195190286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1195290286Sobrien  "shr{l}\t%k0"
1195390286Sobrien  [(set_attr "type" "ishift")
1195490286Sobrien   (set_attr "length" "2")])
1195518334Speter
1195690286Sobrien(define_insn "*lshrsi3_1"
1195790286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1195890286Sobrien	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1195990286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1196090286Sobrien   (clobber (reg:CC 17))]
1196190286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1196290286Sobrien  "@
1196390286Sobrien   shr{l}\t{%2, %0|%0, %2}
1196490286Sobrien   shr{l}\t{%b2, %0|%0, %b2}"
1196590286Sobrien  [(set_attr "type" "ishift")
1196690286Sobrien   (set_attr "mode" "SI")])
1196718334Speter
1196890286Sobrien(define_insn "*lshrsi3_1_zext"
1196990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1197090286Sobrien	(zero_extend:DI
1197190286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1197290286Sobrien		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
1197390286Sobrien   (clobber (reg:CC 17))]
1197490286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1197590286Sobrien  "@
1197690286Sobrien   shr{l}\t{%2, %k0|%k0, %2}
1197790286Sobrien   shr{l}\t{%b2, %k0|%k0, %b2}"
1197890286Sobrien  [(set_attr "type" "ishift")
1197990286Sobrien   (set_attr "mode" "SI")])
1198018334Speter
1198190286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1198290286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1198390286Sobrien;; zero are optimized away.
1198490286Sobrien(define_insn "*lshrsi3_one_bit_cmp"
1198590286Sobrien  [(set (reg 17)
1198690286Sobrien	(compare
1198790286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1198890286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1198990286Sobrien	  (const_int 0)))
1199090286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1199190286Sobrien	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
1199290286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1199390286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1199490286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1199590286Sobrien  "shr{l}\t%0"
1199690286Sobrien  [(set_attr "type" "ishift")
1199790286Sobrien   (set (attr "length") 
1199890286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1199990286Sobrien	(const_string "2")
1200090286Sobrien	(const_string "*")))])
1200118334Speter
1200290286Sobrien(define_insn "*lshrsi3_cmp_one_bit_zext"
1200390286Sobrien  [(set (reg 17)
1200490286Sobrien	(compare
1200590286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
1200690286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1200790286Sobrien	  (const_int 0)))
1200890286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1200990286Sobrien	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
1201090286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1201190286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1201290286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1201390286Sobrien  "shr{l}\t%k0"
1201490286Sobrien  [(set_attr "type" "ishift")
1201590286Sobrien   (set_attr "length" "2")])
1201618334Speter
1201790286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1201890286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1201990286Sobrien;; zero are optimized away.
1202090286Sobrien(define_insn "*lshrsi3_cmp"
1202190286Sobrien  [(set (reg 17)
1202290286Sobrien	(compare
1202390286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12024102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1202590286Sobrien	  (const_int 0)))
1202690286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1202790286Sobrien	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
1202890286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1202990286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1203090286Sobrien  "shr{l}\t{%2, %0|%0, %2}"
1203190286Sobrien  [(set_attr "type" "ishift")
1203290286Sobrien   (set_attr "mode" "SI")])
1203390286Sobrien
1203490286Sobrien(define_insn "*lshrsi3_cmp_zext"
1203590286Sobrien  [(set (reg 17)
1203690286Sobrien	(compare
1203790286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12038102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1203990286Sobrien	  (const_int 0)))
1204090286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1204190286Sobrien	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
1204290286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1204390286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1204490286Sobrien  "shr{l}\t{%2, %k0|%k0, %2}"
1204590286Sobrien  [(set_attr "type" "ishift")
1204690286Sobrien   (set_attr "mode" "SI")])
1204790286Sobrien
1204890286Sobrien(define_expand "lshrhi3"
1204990286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1205090286Sobrien	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
1205190286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1205290286Sobrien   (clobber (reg:CC 17))]
1205390286Sobrien  "TARGET_HIMODE_MATH"
1205490286Sobrien  "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
1205590286Sobrien
1205690286Sobrien(define_insn "*lshrhi3_1_one_bit"
1205750650Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1205850650Sobrien	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1205990286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1206090286Sobrien   (clobber (reg:CC 17))]
1206190286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
1206290286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1206390286Sobrien  "shr{w}\t%0"
1206490286Sobrien  [(set_attr "type" "ishift")
1206590286Sobrien   (set (attr "length") 
1206690286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1206790286Sobrien	(const_string "2")
1206890286Sobrien	(const_string "*")))])
1206918334Speter
1207090286Sobrien(define_insn "*lshrhi3_1"
1207190286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
1207290286Sobrien	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
1207390286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1207490286Sobrien   (clobber (reg:CC 17))]
1207590286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1207690286Sobrien  "@
1207790286Sobrien   shr{w}\t{%2, %0|%0, %2}
1207890286Sobrien   shr{w}\t{%b2, %0|%0, %b2}"
1207990286Sobrien  [(set_attr "type" "ishift")
1208090286Sobrien   (set_attr "mode" "HI")])
1208190286Sobrien
1208290286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1208390286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1208490286Sobrien;; zero are optimized away.
1208590286Sobrien(define_insn "*lshrhi3_one_bit_cmp"
1208690286Sobrien  [(set (reg 17)
1208790286Sobrien	(compare
1208890286Sobrien	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1208990286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1209090286Sobrien	  (const_int 0)))
1209190286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1209290286Sobrien	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
1209390286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1209490286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1209590286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1209690286Sobrien  "shr{w}\t%0"
1209790286Sobrien  [(set_attr "type" "ishift")
1209890286Sobrien   (set (attr "length") 
1209990286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1210090286Sobrien	(const_string "2")
1210190286Sobrien	(const_string "*")))])
1210290286Sobrien
1210390286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1210490286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1210590286Sobrien;; zero are optimized away.
1210690286Sobrien(define_insn "*lshrhi3_cmp"
1210790286Sobrien  [(set (reg 17)
1210890286Sobrien	(compare
1210990286Sobrien	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12110102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1211190286Sobrien	  (const_int 0)))
1211290286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1211390286Sobrien	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
1211490286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1211590286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1211690286Sobrien  "shr{w}\t{%2, %0|%0, %2}"
1211790286Sobrien  [(set_attr "type" "ishift")
1211890286Sobrien   (set_attr "mode" "HI")])
1211990286Sobrien
1212090286Sobrien(define_expand "lshrqi3"
1212190286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1212290286Sobrien	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
1212390286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1212490286Sobrien   (clobber (reg:CC 17))]
1212590286Sobrien  "TARGET_QIMODE_MATH"
1212690286Sobrien  "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
1212790286Sobrien
1212890286Sobrien(define_insn "*lshrqi3_1_one_bit"
1212950650Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1213050650Sobrien	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1213190286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1213290286Sobrien   (clobber (reg:CC 17))]
1213390286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
1213490286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1213590286Sobrien  "shr{b}\t%0"
1213690286Sobrien  [(set_attr "type" "ishift")
1213790286Sobrien   (set (attr "length") 
1213890286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1213990286Sobrien	(const_string "2")
1214090286Sobrien	(const_string "*")))])
1214190286Sobrien
1214290286Sobrien(define_insn "*lshrqi3_1"
1214390286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
1214490286Sobrien	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1214590286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1214690286Sobrien   (clobber (reg:CC 17))]
1214790286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
1214890286Sobrien  "@
1214990286Sobrien   shr{b}\t{%2, %0|%0, %2}
1215090286Sobrien   shr{b}\t{%b2, %0|%0, %b2}"
1215190286Sobrien  [(set_attr "type" "ishift")
1215290286Sobrien   (set_attr "mode" "QI")])
1215390286Sobrien
1215490286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1215590286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1215690286Sobrien;; zero are optimized away.
1215790286Sobrien(define_insn "*lshrqi2_one_bit_cmp"
1215890286Sobrien  [(set (reg 17)
1215990286Sobrien	(compare
1216090286Sobrien	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1216190286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1216290286Sobrien	  (const_int 0)))
1216390286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1216490286Sobrien	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
1216590286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1216690286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1216790286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
1216890286Sobrien  "shr{b}\t%0"
1216990286Sobrien  [(set_attr "type" "ishift")
1217090286Sobrien   (set (attr "length") 
1217190286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1217290286Sobrien	(const_string "2")
1217390286Sobrien	(const_string "*")))])
1217490286Sobrien
1217590286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1217690286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1217790286Sobrien;; zero are optimized away.
1217890286Sobrien(define_insn "*lshrqi2_cmp"
1217990286Sobrien  [(set (reg 17)
1218090286Sobrien	(compare
1218190286Sobrien	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12182102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1218390286Sobrien	  (const_int 0)))
1218490286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1218590286Sobrien	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
1218690286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1218790286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
1218890286Sobrien  "shr{b}\t{%2, %0|%0, %2}"
1218990286Sobrien  [(set_attr "type" "ishift")
1219090286Sobrien   (set_attr "mode" "QI")])
1219118334Speter
1219290286Sobrien;; Rotate instructions
1219318334Speter
1219490286Sobrien(define_expand "rotldi3"
1219590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1219690286Sobrien	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
1219790286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1219890286Sobrien   (clobber (reg:CC 17))]
1219990286Sobrien  "TARGET_64BIT"
1220090286Sobrien  "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
1220118334Speter
1220290286Sobrien(define_insn "*rotlsi3_1_one_bit_rex64"
1220390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1220490286Sobrien	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1220590286Sobrien		   (match_operand:QI 2 "const_int_1_operand" "")))
1220690286Sobrien   (clobber (reg:CC 17))]
1220790286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
1220890286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1220990286Sobrien  "rol{q}\t%0"
1221090286Sobrien  [(set_attr "type" "ishift")
1221190286Sobrien   (set (attr "length") 
1221290286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1221390286Sobrien	(const_string "2")
1221490286Sobrien	(const_string "*")))])
1221518334Speter
1221690286Sobrien(define_insn "*rotldi3_1_rex64"
1221790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
1221890286Sobrien	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
1221990286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "e,c")))
1222090286Sobrien   (clobber (reg:CC 17))]
1222190286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
1222290286Sobrien  "@
1222390286Sobrien   rol{q}\t{%2, %0|%0, %2}
1222490286Sobrien   rol{q}\t{%b2, %0|%0, %b2}"
1222590286Sobrien  [(set_attr "type" "ishift")
1222690286Sobrien   (set_attr "mode" "DI")])
1222790286Sobrien
1222890286Sobrien(define_expand "rotlsi3"
1222990286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1223090286Sobrien	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
1223190286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1223290286Sobrien   (clobber (reg:CC 17))]
1223318334Speter  ""
1223490286Sobrien  "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
1223518334Speter
1223690286Sobrien(define_insn "*rotlsi3_1_one_bit"
1223750650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1223890286Sobrien	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1223990286Sobrien		   (match_operand:QI 2 "const_int_1_operand" "")))
1224090286Sobrien   (clobber (reg:CC 17))]
1224190286Sobrien  "ix86_binary_operator_ok (ROTATE, SImode, operands)
1224290286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1224390286Sobrien  "rol{l}\t%0"
1224490286Sobrien  [(set_attr "type" "ishift")
1224590286Sobrien   (set (attr "length") 
1224690286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1224790286Sobrien	(const_string "2")
1224890286Sobrien	(const_string "*")))])
1224918334Speter
1225090286Sobrien(define_insn "*rotlsi3_1_one_bit_zext"
1225190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1225290286Sobrien	(zero_extend:DI
1225390286Sobrien	  (rotate:SI (match_operand:SI 1 "register_operand" "0")
1225490286Sobrien		     (match_operand:QI 2 "const_int_1_operand" ""))))
1225590286Sobrien   (clobber (reg:CC 17))]
1225690286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
1225790286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1225890286Sobrien  "rol{l}\t%k0"
1225990286Sobrien  [(set_attr "type" "ishift")
1226090286Sobrien   (set_attr "length" "2")])
1226118334Speter
1226290286Sobrien(define_insn "*rotlsi3_1"
1226390286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1226490286Sobrien	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1226590286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
1226690286Sobrien   (clobber (reg:CC 17))]
1226790286Sobrien  "ix86_binary_operator_ok (ROTATE, SImode, operands)"
1226890286Sobrien  "@
1226990286Sobrien   rol{l}\t{%2, %0|%0, %2}
1227090286Sobrien   rol{l}\t{%b2, %0|%0, %b2}"
1227190286Sobrien  [(set_attr "type" "ishift")
1227290286Sobrien   (set_attr "mode" "SI")])
1227318334Speter
1227490286Sobrien(define_insn "*rotlsi3_1_zext"
1227590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1227690286Sobrien	(zero_extend:DI
1227790286Sobrien	  (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
1227890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
1227990286Sobrien   (clobber (reg:CC 17))]
1228090286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
1228190286Sobrien  "@
1228290286Sobrien   rol{l}\t{%2, %k0|%k0, %2}
1228390286Sobrien   rol{l}\t{%b2, %k0|%k0, %b2}"
1228490286Sobrien  [(set_attr "type" "ishift")
1228590286Sobrien   (set_attr "mode" "SI")])
1228618334Speter
1228790286Sobrien(define_expand "rotlhi3"
1228890286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1228990286Sobrien	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
1229090286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1229190286Sobrien   (clobber (reg:CC 17))]
1229290286Sobrien  "TARGET_HIMODE_MATH"
1229390286Sobrien  "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
1229418334Speter
1229590286Sobrien(define_insn "*rotlhi3_1_one_bit"
1229690286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1229790286Sobrien	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1229890286Sobrien		   (match_operand:QI 2 "const_int_1_operand" "")))
1229990286Sobrien   (clobber (reg:CC 17))]
1230090286Sobrien  "ix86_binary_operator_ok (ROTATE, HImode, operands)
1230190286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1230290286Sobrien  "rol{w}\t%0"
1230390286Sobrien  [(set_attr "type" "ishift")
1230490286Sobrien   (set (attr "length") 
1230590286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1230690286Sobrien	(const_string "2")
1230790286Sobrien	(const_string "*")))])
1230818334Speter
1230990286Sobrien(define_insn "*rotlhi3_1"
1231090286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
1231190286Sobrien	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
1231290286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
1231390286Sobrien   (clobber (reg:CC 17))]
1231490286Sobrien  "ix86_binary_operator_ok (ROTATE, HImode, operands)"
1231590286Sobrien  "@
1231690286Sobrien   rol{w}\t{%2, %0|%0, %2}
1231790286Sobrien   rol{w}\t{%b2, %0|%0, %b2}"
1231890286Sobrien  [(set_attr "type" "ishift")
1231990286Sobrien   (set_attr "mode" "HI")])
1232018334Speter
1232190286Sobrien(define_expand "rotlqi3"
1232290286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1232390286Sobrien	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
1232490286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1232590286Sobrien   (clobber (reg:CC 17))]
1232690286Sobrien  "TARGET_QIMODE_MATH"
1232790286Sobrien  "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
1232818334Speter
1232990286Sobrien(define_insn "*rotlqi3_1_one_bit"
1233090286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1233190286Sobrien	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1233290286Sobrien		   (match_operand:QI 2 "const_int_1_operand" "")))
1233390286Sobrien   (clobber (reg:CC 17))]
1233490286Sobrien  "ix86_binary_operator_ok (ROTATE, QImode, operands)
1233590286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1233690286Sobrien  "rol{b}\t%0"
1233790286Sobrien  [(set_attr "type" "ishift")
1233890286Sobrien   (set (attr "length") 
1233990286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1234090286Sobrien	(const_string "2")
1234190286Sobrien	(const_string "*")))])
1234218334Speter
1234390286Sobrien(define_insn "*rotlqi3_1"
1234490286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
1234590286Sobrien	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1234690286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
1234790286Sobrien   (clobber (reg:CC 17))]
1234890286Sobrien  "ix86_binary_operator_ok (ROTATE, QImode, operands)"
1234990286Sobrien  "@
1235090286Sobrien   rol{b}\t{%2, %0|%0, %2}
1235190286Sobrien   rol{b}\t{%b2, %0|%0, %b2}"
1235290286Sobrien  [(set_attr "type" "ishift")
1235390286Sobrien   (set_attr "mode" "QI")])
1235418334Speter
1235590286Sobrien(define_expand "rotrdi3"
1235690286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1235790286Sobrien	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
1235890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1235990286Sobrien   (clobber (reg:CC 17))]
1236090286Sobrien  "TARGET_64BIT"
1236190286Sobrien  "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
1236218334Speter
1236390286Sobrien(define_insn "*rotrdi3_1_one_bit_rex64"
1236490286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1236590286Sobrien	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1236690286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1236790286Sobrien   (clobber (reg:CC 17))]
1236890286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
1236990286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1237090286Sobrien  "ror{q}\t%0"
1237190286Sobrien  [(set_attr "type" "ishift")
1237290286Sobrien   (set (attr "length") 
1237390286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1237490286Sobrien	(const_string "2")
1237590286Sobrien	(const_string "*")))])
1237618334Speter
1237790286Sobrien(define_insn "*rotrdi3_1_rex64"
1237890286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
1237990286Sobrien	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
1238090286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
1238190286Sobrien   (clobber (reg:CC 17))]
1238290286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
1238390286Sobrien  "@
1238490286Sobrien   ror{q}\t{%2, %0|%0, %2}
1238590286Sobrien   ror{q}\t{%b2, %0|%0, %b2}"
1238690286Sobrien  [(set_attr "type" "ishift")
1238790286Sobrien   (set_attr "mode" "DI")])
1238890286Sobrien
1238990286Sobrien(define_expand "rotrsi3"
1239090286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1239190286Sobrien	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
1239290286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1239390286Sobrien   (clobber (reg:CC 17))]
1239490286Sobrien  ""
1239590286Sobrien  "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
1239690286Sobrien
1239790286Sobrien(define_insn "*rotrsi3_1_one_bit"
1239850650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1239990286Sobrien	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1240090286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1240190286Sobrien   (clobber (reg:CC 17))]
1240290286Sobrien  "ix86_binary_operator_ok (ROTATERT, SImode, operands)
1240390286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1240490286Sobrien  "ror{l}\t%0"
1240590286Sobrien  [(set_attr "type" "ishift")
1240690286Sobrien   (set (attr "length") 
1240790286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1240890286Sobrien	(const_string "2")
1240990286Sobrien	(const_string "*")))])
1241018334Speter
1241190286Sobrien(define_insn "*rotrsi3_1_one_bit_zext"
1241290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1241390286Sobrien	(zero_extend:DI
1241490286Sobrien	  (rotatert:SI (match_operand:SI 1 "register_operand" "0")
1241590286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))))
1241690286Sobrien   (clobber (reg:CC 17))]
1241790286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
1241890286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1241990286Sobrien  "ror{l}\t%k0"
1242090286Sobrien  [(set_attr "type" "ishift")
1242190286Sobrien   (set (attr "length") 
1242290286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1242390286Sobrien	(const_string "2")
1242490286Sobrien	(const_string "*")))])
1242518334Speter
1242690286Sobrien(define_insn "*rotrsi3_1"
1242790286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1242890286Sobrien	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1242990286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1243090286Sobrien   (clobber (reg:CC 17))]
1243190286Sobrien  "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
1243290286Sobrien  "@
1243390286Sobrien   ror{l}\t{%2, %0|%0, %2}
1243490286Sobrien   ror{l}\t{%b2, %0|%0, %b2}"
1243590286Sobrien  [(set_attr "type" "ishift")
1243690286Sobrien   (set_attr "mode" "SI")])
1243718334Speter
1243890286Sobrien(define_insn "*rotrsi3_1_zext"
1243990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1244090286Sobrien	(zero_extend:DI
1244190286Sobrien	  (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
1244290286Sobrien		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
1244390286Sobrien   (clobber (reg:CC 17))]
1244490286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
1244590286Sobrien  "@
1244690286Sobrien   ror{l}\t{%2, %k0|%k0, %2}
1244790286Sobrien   ror{l}\t{%b2, %k0|%k0, %b2}"
1244890286Sobrien  [(set_attr "type" "ishift")
1244990286Sobrien   (set_attr "mode" "SI")])
1245018334Speter
1245190286Sobrien(define_expand "rotrhi3"
1245290286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1245390286Sobrien	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
1245490286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1245590286Sobrien   (clobber (reg:CC 17))]
1245690286Sobrien  "TARGET_HIMODE_MATH"
1245790286Sobrien  "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
1245818334Speter
1245990286Sobrien(define_insn "*rotrhi3_one_bit"
1246090286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1246190286Sobrien	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1246290286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1246390286Sobrien   (clobber (reg:CC 17))]
1246490286Sobrien  "ix86_binary_operator_ok (ROTATERT, HImode, operands)
1246590286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1246690286Sobrien  "ror{w}\t%0"
1246790286Sobrien  [(set_attr "type" "ishift")
1246890286Sobrien   (set (attr "length") 
1246990286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1247090286Sobrien	(const_string "2")
1247190286Sobrien	(const_string "*")))])
1247218334Speter
1247390286Sobrien(define_insn "*rotrhi3"
1247490286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
1247590286Sobrien	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
1247690286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1247790286Sobrien   (clobber (reg:CC 17))]
1247890286Sobrien  "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
1247990286Sobrien  "@
1248090286Sobrien   ror{w}\t{%2, %0|%0, %2}
1248190286Sobrien   ror{w}\t{%b2, %0|%0, %b2}"
1248290286Sobrien  [(set_attr "type" "ishift")
1248390286Sobrien   (set_attr "mode" "HI")])
1248418334Speter
1248590286Sobrien(define_expand "rotrqi3"
1248690286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1248790286Sobrien	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
1248890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1248990286Sobrien   (clobber (reg:CC 17))]
1249090286Sobrien  "TARGET_QIMODE_MATH"
1249190286Sobrien  "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
1249218334Speter
1249390286Sobrien(define_insn "*rotrqi3_1_one_bit"
1249490286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1249590286Sobrien	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1249690286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1249790286Sobrien   (clobber (reg:CC 17))]
1249890286Sobrien  "ix86_binary_operator_ok (ROTATERT, QImode, operands)
1249990286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1250090286Sobrien  "ror{b}\t%0"
1250190286Sobrien  [(set_attr "type" "ishift")
1250290286Sobrien   (set (attr "length") 
1250390286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1250490286Sobrien	(const_string "2")
1250590286Sobrien	(const_string "*")))])
1250618334Speter
1250790286Sobrien(define_insn "*rotrqi3_1"
1250890286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
1250990286Sobrien	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1251090286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1251190286Sobrien   (clobber (reg:CC 17))]
1251290286Sobrien  "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
1251390286Sobrien  "@
1251490286Sobrien   ror{b}\t{%2, %0|%0, %2}
1251590286Sobrien   ror{b}\t{%b2, %0|%0, %b2}"
1251690286Sobrien  [(set_attr "type" "ishift")
1251790286Sobrien   (set_attr "mode" "QI")])
1251890286Sobrien
1251990286Sobrien;; Bit set / bit test instructions
1252018334Speter
1252190286Sobrien(define_expand "extv"
1252290286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1252390286Sobrien	(sign_extract:SI (match_operand:SI 1 "register_operand" "")
1252490286Sobrien			 (match_operand:SI 2 "immediate_operand" "")
1252590286Sobrien			 (match_operand:SI 3 "immediate_operand" "")))]
1252690286Sobrien  ""
1252718334Speter{
1252890286Sobrien  /* Handle extractions from %ah et al.  */
1252990286Sobrien  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
1253090286Sobrien    FAIL;
1253118334Speter
1253290286Sobrien  /* From mips.md: extract_bit_field doesn't verify that our source
1253390286Sobrien     matches the predicate, so check it again here.  */
1253490286Sobrien  if (! register_operand (operands[1], VOIDmode))
1253590286Sobrien    FAIL;
1253690286Sobrien})
1253718334Speter
1253890286Sobrien(define_expand "extzv"
1253990286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1254090286Sobrien	(zero_extract:SI (match_operand 1 "ext_register_operand" "")
1254190286Sobrien			 (match_operand:SI 2 "immediate_operand" "")
1254290286Sobrien			 (match_operand:SI 3 "immediate_operand" "")))]
1254390286Sobrien  ""
1254490286Sobrien{
1254590286Sobrien  /* Handle extractions from %ah et al.  */
1254690286Sobrien  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
1254790286Sobrien    FAIL;
1254818334Speter
1254990286Sobrien  /* From mips.md: extract_bit_field doesn't verify that our source
1255090286Sobrien     matches the predicate, so check it again here.  */
1255190286Sobrien  if (! register_operand (operands[1], VOIDmode))
1255290286Sobrien    FAIL;
1255390286Sobrien})
1255418334Speter
1255590286Sobrien(define_expand "insv"
1255690286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
1255790286Sobrien			 (match_operand:SI 1 "immediate_operand" "")
1255890286Sobrien			 (match_operand:SI 2 "immediate_operand" ""))
1255990286Sobrien        (match_operand:SI 3 "register_operand" ""))]
1256090286Sobrien  ""
1256190286Sobrien{
1256290286Sobrien  /* Handle extractions from %ah et al.  */
1256390286Sobrien  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
1256490286Sobrien    FAIL;
1256518334Speter
1256690286Sobrien  /* From mips.md: insert_bit_field doesn't verify that our source
1256790286Sobrien     matches the predicate, so check it again here.  */
1256890286Sobrien  if (! register_operand (operands[0], VOIDmode))
1256990286Sobrien    FAIL;
1257090286Sobrien})
1257118334Speter
1257290286Sobrien;; %%% bts, btr, btc, bt.
1257318334Speter
1257418334Speter;; Store-flag instructions.
1257518334Speter
1257618334Speter;; For all sCOND expanders, also expand the compare or test insn that
1257718334Speter;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
1257818334Speter
1257990286Sobrien;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
1258090286Sobrien;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
1258190286Sobrien;; way, which can later delete the movzx if only QImode is needed.
1258290286Sobrien
1258318334Speter(define_expand "seq"
1258490286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1258590286Sobrien        (eq:QI (reg:CC 17) (const_int 0)))]
1258618334Speter  ""
1258790286Sobrien  "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
1258818334Speter
1258918334Speter(define_expand "sne"
1259090286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1259190286Sobrien        (ne:QI (reg:CC 17) (const_int 0)))]
1259218334Speter  ""
1259390286Sobrien  "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
1259418334Speter
1259518334Speter(define_expand "sgt"
1259690286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1259790286Sobrien        (gt:QI (reg:CC 17) (const_int 0)))]
1259818334Speter  ""
1259990286Sobrien  "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
1260018334Speter
1260118334Speter(define_expand "sgtu"
1260290286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1260390286Sobrien        (gtu:QI (reg:CC 17) (const_int 0)))]
1260418334Speter  ""
1260590286Sobrien  "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
1260618334Speter
1260718334Speter(define_expand "slt"
1260890286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1260990286Sobrien        (lt:QI (reg:CC 17) (const_int 0)))]
1261018334Speter  ""
1261190286Sobrien  "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
1261218334Speter
1261318334Speter(define_expand "sltu"
1261490286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1261590286Sobrien        (ltu:QI (reg:CC 17) (const_int 0)))]
1261618334Speter  ""
1261790286Sobrien  "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
1261818334Speter
1261918334Speter(define_expand "sge"
1262090286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1262190286Sobrien        (ge:QI (reg:CC 17) (const_int 0)))]
1262218334Speter  ""
1262390286Sobrien  "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
1262418334Speter
1262518334Speter(define_expand "sgeu"
1262690286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1262790286Sobrien        (geu:QI (reg:CC 17) (const_int 0)))]
1262818334Speter  ""
1262990286Sobrien  "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
1263018334Speter
1263118334Speter(define_expand "sle"
1263290286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1263390286Sobrien        (le:QI (reg:CC 17) (const_int 0)))]
1263418334Speter  ""
1263590286Sobrien  "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
1263618334Speter
1263718334Speter(define_expand "sleu"
1263890286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1263990286Sobrien        (leu:QI (reg:CC 17) (const_int 0)))]
1264018334Speter  ""
1264190286Sobrien  "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
1264218334Speter
1264390286Sobrien(define_expand "sunordered"
1264490286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1264590286Sobrien        (unordered:QI (reg:CC 17) (const_int 0)))]
1264690286Sobrien  "TARGET_80387 || TARGET_SSE"
1264790286Sobrien  "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
1264852296Sobrien
1264990286Sobrien(define_expand "sordered"
1265090286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1265190286Sobrien        (ordered:QI (reg:CC 17) (const_int 0)))]
1265290286Sobrien  "TARGET_80387"
1265390286Sobrien  "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
1265490286Sobrien
1265590286Sobrien(define_expand "suneq"
1265690286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1265790286Sobrien        (uneq:QI (reg:CC 17) (const_int 0)))]
1265890286Sobrien  "TARGET_80387 || TARGET_SSE"
1265990286Sobrien  "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
1266090286Sobrien
1266190286Sobrien(define_expand "sunge"
1266290286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1266390286Sobrien        (unge:QI (reg:CC 17) (const_int 0)))]
1266490286Sobrien  "TARGET_80387 || TARGET_SSE"
1266590286Sobrien  "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
1266690286Sobrien
1266790286Sobrien(define_expand "sungt"
1266890286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1266990286Sobrien        (ungt:QI (reg:CC 17) (const_int 0)))]
1267090286Sobrien  "TARGET_80387 || TARGET_SSE"
1267190286Sobrien  "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
1267290286Sobrien
1267390286Sobrien(define_expand "sunle"
1267490286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1267590286Sobrien        (unle:QI (reg:CC 17) (const_int 0)))]
1267690286Sobrien  "TARGET_80387 || TARGET_SSE"
1267790286Sobrien  "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
1267890286Sobrien
1267990286Sobrien(define_expand "sunlt"
1268090286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1268190286Sobrien        (unlt:QI (reg:CC 17) (const_int 0)))]
1268290286Sobrien  "TARGET_80387 || TARGET_SSE"
1268390286Sobrien  "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
1268490286Sobrien
1268590286Sobrien(define_expand "sltgt"
1268690286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1268790286Sobrien        (ltgt:QI (reg:CC 17) (const_int 0)))]
1268890286Sobrien  "TARGET_80387 || TARGET_SSE"
1268990286Sobrien  "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
1269090286Sobrien
1269190286Sobrien(define_insn "*setcc_1"
1269252296Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1269390286Sobrien	(match_operator:QI 1 "ix86_comparison_operator"
1269490286Sobrien	  [(reg 17) (const_int 0)]))]
1269590286Sobrien  ""
1269690286Sobrien  "set%C1\t%0"
1269790286Sobrien  [(set_attr "type" "setcc")
1269890286Sobrien   (set_attr "mode" "QI")])
1269990286Sobrien
1270090286Sobrien(define_insn "setcc_2"
1270190286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
1270290286Sobrien	(match_operator:QI 1 "ix86_comparison_operator"
1270390286Sobrien	  [(reg 17) (const_int 0)]))]
1270490286Sobrien  ""
1270590286Sobrien  "set%C1\t%0"
1270690286Sobrien  [(set_attr "type" "setcc")
1270790286Sobrien   (set_attr "mode" "QI")])
1270890286Sobrien
1270990286Sobrien;; In general it is not safe to assume too much about CCmode registers,
1271090286Sobrien;; so simplify-rtx stops when it sees a second one.  Under certain 
1271190286Sobrien;; conditions this is safe on x86, so help combine not create
1271290286Sobrien;;
1271390286Sobrien;;	seta	%al
1271490286Sobrien;;	testb	%al, %al
1271590286Sobrien;;	sete	%al
1271690286Sobrien
1271790286Sobrien(define_split 
1271890286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1271990286Sobrien	(ne:QI (match_operator 1 "ix86_comparison_operator"
1272090286Sobrien	         [(reg 17) (const_int 0)])
1272190286Sobrien	    (const_int 0)))]
1272290286Sobrien  ""
1272390286Sobrien  [(set (match_dup 0) (match_dup 1))]
1272452296Sobrien{
1272590286Sobrien  PUT_MODE (operands[1], QImode);
1272690286Sobrien})
1272752296Sobrien
1272890286Sobrien(define_split 
1272990286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1273090286Sobrien	(ne:QI (match_operator 1 "ix86_comparison_operator"
1273190286Sobrien	         [(reg 17) (const_int 0)])
1273290286Sobrien	    (const_int 0)))]
1273390286Sobrien  ""
1273490286Sobrien  [(set (match_dup 0) (match_dup 1))]
1273590286Sobrien{
1273690286Sobrien  PUT_MODE (operands[1], QImode);
1273790286Sobrien})
1273852296Sobrien
1273990286Sobrien(define_split 
1274090286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1274190286Sobrien	(eq:QI (match_operator 1 "ix86_comparison_operator"
1274290286Sobrien	         [(reg 17) (const_int 0)])
1274390286Sobrien	    (const_int 0)))]
1274490286Sobrien  ""
1274590286Sobrien  [(set (match_dup 0) (match_dup 1))]
1274690286Sobrien{
1274790286Sobrien  rtx new_op1 = copy_rtx (operands[1]);
1274890286Sobrien  operands[1] = new_op1;
1274990286Sobrien  PUT_MODE (new_op1, QImode);
1275090286Sobrien  PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
1275190286Sobrien					GET_MODE (XEXP (new_op1, 0))));
1275290286Sobrien
1275390286Sobrien  /* Make sure that (a) the CCmode we have for the flags is strong
1275490286Sobrien     enough for the reversed compare or (b) we have a valid FP compare.  */
1275590286Sobrien  if (! ix86_comparison_operator (new_op1, VOIDmode))
1275690286Sobrien    FAIL;
1275790286Sobrien})
1275890286Sobrien
1275990286Sobrien(define_split 
1276090286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1276190286Sobrien	(eq:QI (match_operator 1 "ix86_comparison_operator"
1276290286Sobrien	         [(reg 17) (const_int 0)])
1276390286Sobrien	    (const_int 0)))]
1276490286Sobrien  ""
1276590286Sobrien  [(set (match_dup 0) (match_dup 1))]
1276690286Sobrien{
1276790286Sobrien  rtx new_op1 = copy_rtx (operands[1]);
1276890286Sobrien  operands[1] = new_op1;
1276990286Sobrien  PUT_MODE (new_op1, QImode);
1277090286Sobrien  PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
1277190286Sobrien					GET_MODE (XEXP (new_op1, 0))));
1277290286Sobrien
1277390286Sobrien  /* Make sure that (a) the CCmode we have for the flags is strong
1277490286Sobrien     enough for the reversed compare or (b) we have a valid FP compare.  */
1277590286Sobrien  if (! ix86_comparison_operator (new_op1, VOIDmode))
1277690286Sobrien    FAIL;
1277790286Sobrien})
1277890286Sobrien
1277990286Sobrien;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
1278090286Sobrien;; subsequent logical operations are used to imitate conditional moves.
1278190286Sobrien;; 0xffffffff is NaN, but not in normalized form, so we can't represent
1278290286Sobrien;; it directly.  Futher holding this value in pseudo register might bring
1278390286Sobrien;; problem in implicit normalization in spill code.
1278490286Sobrien;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
1278590286Sobrien;; instructions after reload by splitting the conditional move patterns.
1278690286Sobrien
1278790286Sobrien(define_insn "*sse_setccsf"
1278890286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1278990286Sobrien	(match_operator:SF 1 "sse_comparison_operator"
1279090286Sobrien	  [(match_operand:SF 2 "register_operand" "0")
1279190286Sobrien	   (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
1279290286Sobrien  "TARGET_SSE && reload_completed"
1279390286Sobrien  "cmp%D1ss\t{%3, %0|%0, %3}"
1279490286Sobrien  [(set_attr "type" "sse")
1279590286Sobrien   (set_attr "mode" "SF")])
1279690286Sobrien
1279790286Sobrien(define_insn "*sse_setccdf"
1279890286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1279990286Sobrien	(match_operator:DF 1 "sse_comparison_operator"
1280090286Sobrien	  [(match_operand:DF 2 "register_operand" "0")
1280190286Sobrien	   (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
1280290286Sobrien  "TARGET_SSE2 && reload_completed"
1280390286Sobrien  "cmp%D1sd\t{%3, %0|%0, %3}"
1280490286Sobrien  [(set_attr "type" "sse")
1280590286Sobrien   (set_attr "mode" "DF")])
1280618334Speter
1280718334Speter;; Basic conditional jump instructions.
1280818334Speter;; We ignore the overflow flag for signed branch instructions.
1280918334Speter
1281018334Speter;; For all bCOND expanders, also expand the compare or test insn that
1281190286Sobrien;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
1281218334Speter
1281318334Speter(define_expand "beq"
1281490286Sobrien  [(set (pc)
1281590286Sobrien	(if_then_else (match_dup 1)
1281618334Speter		      (label_ref (match_operand 0 "" ""))
1281718334Speter		      (pc)))]
1281818334Speter  ""
1281990286Sobrien  "ix86_expand_branch (EQ, operands[0]); DONE;")
1282018334Speter
1282118334Speter(define_expand "bne"
1282290286Sobrien  [(set (pc)
1282390286Sobrien	(if_then_else (match_dup 1)
1282418334Speter		      (label_ref (match_operand 0 "" ""))
1282518334Speter		      (pc)))]
1282618334Speter  ""
1282790286Sobrien  "ix86_expand_branch (NE, operands[0]); DONE;")
1282818334Speter
1282918334Speter(define_expand "bgt"
1283090286Sobrien  [(set (pc)
1283190286Sobrien	(if_then_else (match_dup 1)
1283218334Speter		      (label_ref (match_operand 0 "" ""))
1283318334Speter		      (pc)))]
1283418334Speter  ""
1283590286Sobrien  "ix86_expand_branch (GT, operands[0]); DONE;")
1283618334Speter
1283718334Speter(define_expand "bgtu"
1283890286Sobrien  [(set (pc)
1283990286Sobrien	(if_then_else (match_dup 1)
1284018334Speter		      (label_ref (match_operand 0 "" ""))
1284118334Speter		      (pc)))]
1284218334Speter  ""
1284390286Sobrien  "ix86_expand_branch (GTU, operands[0]); DONE;")
1284418334Speter
1284518334Speter(define_expand "blt"
1284690286Sobrien  [(set (pc)
1284790286Sobrien	(if_then_else (match_dup 1)
1284818334Speter		      (label_ref (match_operand 0 "" ""))
1284918334Speter		      (pc)))]
1285018334Speter  ""
1285190286Sobrien  "ix86_expand_branch (LT, operands[0]); DONE;")
1285218334Speter
1285318334Speter(define_expand "bltu"
1285490286Sobrien  [(set (pc)
1285590286Sobrien	(if_then_else (match_dup 1)
1285618334Speter		      (label_ref (match_operand 0 "" ""))
1285718334Speter		      (pc)))]
1285818334Speter  ""
1285990286Sobrien  "ix86_expand_branch (LTU, operands[0]); DONE;")
1286018334Speter
1286118334Speter(define_expand "bge"
1286290286Sobrien  [(set (pc)
1286390286Sobrien	(if_then_else (match_dup 1)
1286418334Speter		      (label_ref (match_operand 0 "" ""))
1286518334Speter		      (pc)))]
1286618334Speter  ""
1286790286Sobrien  "ix86_expand_branch (GE, operands[0]); DONE;")
1286818334Speter
1286918334Speter(define_expand "bgeu"
1287090286Sobrien  [(set (pc)
1287190286Sobrien	(if_then_else (match_dup 1)
1287218334Speter		      (label_ref (match_operand 0 "" ""))
1287318334Speter		      (pc)))]
1287418334Speter  ""
1287590286Sobrien  "ix86_expand_branch (GEU, operands[0]); DONE;")
1287618334Speter
1287718334Speter(define_expand "ble"
1287890286Sobrien  [(set (pc)
1287990286Sobrien	(if_then_else (match_dup 1)
1288018334Speter		      (label_ref (match_operand 0 "" ""))
1288118334Speter		      (pc)))]
1288218334Speter  ""
1288390286Sobrien  "ix86_expand_branch (LE, operands[0]); DONE;")
1288418334Speter
1288518334Speter(define_expand "bleu"
1288690286Sobrien  [(set (pc)
1288790286Sobrien	(if_then_else (match_dup 1)
1288818334Speter		      (label_ref (match_operand 0 "" ""))
1288918334Speter		      (pc)))]
1289018334Speter  ""
1289190286Sobrien  "ix86_expand_branch (LEU, operands[0]); DONE;")
1289218334Speter
1289390286Sobrien(define_expand "bunordered"
1289418334Speter  [(set (pc)
1289590286Sobrien	(if_then_else (match_dup 1)
1289690286Sobrien		      (label_ref (match_operand 0 "" ""))
1289718334Speter		      (pc)))]
1289890286Sobrien  "TARGET_80387 || TARGET_SSE"
1289990286Sobrien  "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
1290018334Speter
1290190286Sobrien(define_expand "bordered"
1290290286Sobrien  [(set (pc)
1290390286Sobrien	(if_then_else (match_dup 1)
1290490286Sobrien		      (label_ref (match_operand 0 "" ""))
1290590286Sobrien		      (pc)))]
1290690286Sobrien  "TARGET_80387 || TARGET_SSE"
1290790286Sobrien  "ix86_expand_branch (ORDERED, operands[0]); DONE;")
1290818334Speter
1290990286Sobrien(define_expand "buneq"
1291018334Speter  [(set (pc)
1291190286Sobrien	(if_then_else (match_dup 1)
1291290286Sobrien		      (label_ref (match_operand 0 "" ""))
1291390286Sobrien		      (pc)))]
1291490286Sobrien  "TARGET_80387 || TARGET_SSE"
1291590286Sobrien  "ix86_expand_branch (UNEQ, operands[0]); DONE;")
1291618334Speter
1291790286Sobrien(define_expand "bunge"
1291890286Sobrien  [(set (pc)
1291990286Sobrien	(if_then_else (match_dup 1)
1292090286Sobrien		      (label_ref (match_operand 0 "" ""))
1292190286Sobrien		      (pc)))]
1292290286Sobrien  "TARGET_80387 || TARGET_SSE"
1292390286Sobrien  "ix86_expand_branch (UNGE, operands[0]); DONE;")
1292418334Speter
1292590286Sobrien(define_expand "bungt"
1292618334Speter  [(set (pc)
1292790286Sobrien	(if_then_else (match_dup 1)
1292890286Sobrien		      (label_ref (match_operand 0 "" ""))
1292990286Sobrien		      (pc)))]
1293090286Sobrien  "TARGET_80387 || TARGET_SSE"
1293190286Sobrien  "ix86_expand_branch (UNGT, operands[0]); DONE;")
1293218334Speter
1293390286Sobrien(define_expand "bunle"
1293490286Sobrien  [(set (pc)
1293590286Sobrien	(if_then_else (match_dup 1)
1293690286Sobrien		      (label_ref (match_operand 0 "" ""))
1293790286Sobrien		      (pc)))]
1293890286Sobrien  "TARGET_80387 || TARGET_SSE"
1293990286Sobrien  "ix86_expand_branch (UNLE, operands[0]); DONE;")
1294018334Speter
1294190286Sobrien(define_expand "bunlt"
1294290286Sobrien  [(set (pc)
1294390286Sobrien	(if_then_else (match_dup 1)
1294490286Sobrien		      (label_ref (match_operand 0 "" ""))
1294590286Sobrien		      (pc)))]
1294690286Sobrien  "TARGET_80387 || TARGET_SSE"
1294790286Sobrien  "ix86_expand_branch (UNLT, operands[0]); DONE;")
1294818334Speter
1294990286Sobrien(define_expand "bltgt"
1295090286Sobrien  [(set (pc)
1295190286Sobrien	(if_then_else (match_dup 1)
1295290286Sobrien		      (label_ref (match_operand 0 "" ""))
1295390286Sobrien		      (pc)))]
1295490286Sobrien  "TARGET_80387 || TARGET_SSE"
1295590286Sobrien  "ix86_expand_branch (LTGT, operands[0]); DONE;")
1295618334Speter
1295790286Sobrien(define_insn "*jcc_1"
1295890286Sobrien  [(set (pc)
1295990286Sobrien	(if_then_else (match_operator 1 "ix86_comparison_operator"
1296090286Sobrien				      [(reg 17) (const_int 0)])
1296190286Sobrien		      (label_ref (match_operand 0 "" ""))
1296290286Sobrien		      (pc)))]
1296318334Speter  ""
1296490286Sobrien  "%+j%C1\t%l0"
1296590286Sobrien  [(set_attr "type" "ibr")
1296690286Sobrien   (set (attr "prefix_0f")
1296790286Sobrien	   (if_then_else (and (ge (minus (match_dup 0) (pc))
1296890286Sobrien				  (const_int -128))
1296990286Sobrien			      (lt (minus (match_dup 0) (pc))
1297090286Sobrien				  (const_int 124)))
1297190286Sobrien	     (const_int 0)
1297290286Sobrien	     (const_int 1)))])
1297318334Speter
1297490286Sobrien(define_insn "*jcc_2"
1297518334Speter  [(set (pc)
1297690286Sobrien	(if_then_else (match_operator 1 "ix86_comparison_operator"
1297790286Sobrien				      [(reg 17) (const_int 0)])
1297890286Sobrien		      (pc)
1297990286Sobrien		      (label_ref (match_operand 0 "" ""))))]
1298018334Speter  ""
1298190286Sobrien  "%+j%c1\t%l0"
1298290286Sobrien  [(set_attr "type" "ibr")
1298390286Sobrien   (set (attr "prefix_0f")
1298490286Sobrien	   (if_then_else (and (ge (minus (match_dup 0) (pc))
1298590286Sobrien				  (const_int -128))
1298690286Sobrien			      (lt (minus (match_dup 0) (pc))
1298790286Sobrien				  (const_int 124)))
1298890286Sobrien	     (const_int 0)
1298990286Sobrien	     (const_int 1)))])
1299090286Sobrien
1299190286Sobrien;; In general it is not safe to assume too much about CCmode registers,
1299290286Sobrien;; so simplify-rtx stops when it sees a second one.  Under certain 
1299390286Sobrien;; conditions this is safe on x86, so help combine not create
1299490286Sobrien;;
1299590286Sobrien;;	seta	%al
1299690286Sobrien;;	testb	%al, %al
1299790286Sobrien;;	je	Lfoo
1299890286Sobrien
1299990286Sobrien(define_split 
1300090286Sobrien  [(set (pc)
1300190286Sobrien	(if_then_else (ne (match_operator 0 "ix86_comparison_operator"
1300290286Sobrien				      [(reg 17) (const_int 0)])
1300390286Sobrien			  (const_int 0))
1300490286Sobrien		      (label_ref (match_operand 1 "" ""))
1300590286Sobrien		      (pc)))]
1300690286Sobrien  ""
1300790286Sobrien  [(set (pc)
1300890286Sobrien	(if_then_else (match_dup 0)
1300990286Sobrien		      (label_ref (match_dup 1))
1301090286Sobrien		      (pc)))]
1301118334Speter{
1301290286Sobrien  PUT_MODE (operands[0], VOIDmode);
1301390286Sobrien})
1301490286Sobrien  
1301590286Sobrien(define_split 
1301690286Sobrien  [(set (pc)
1301790286Sobrien	(if_then_else (eq (match_operator 0 "ix86_comparison_operator"
1301890286Sobrien				      [(reg 17) (const_int 0)])
1301990286Sobrien			  (const_int 0))
1302090286Sobrien		      (label_ref (match_operand 1 "" ""))
1302190286Sobrien		      (pc)))]
1302290286Sobrien  ""
1302390286Sobrien  [(set (pc)
1302490286Sobrien	(if_then_else (match_dup 0)
1302590286Sobrien		      (label_ref (match_dup 1))
1302690286Sobrien		      (pc)))]
1302790286Sobrien{
1302890286Sobrien  rtx new_op0 = copy_rtx (operands[0]);
1302990286Sobrien  operands[0] = new_op0;
1303090286Sobrien  PUT_MODE (new_op0, VOIDmode);
1303190286Sobrien  PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
1303290286Sobrien					GET_MODE (XEXP (new_op0, 0))));
1303352296Sobrien
1303490286Sobrien  /* Make sure that (a) the CCmode we have for the flags is strong
1303590286Sobrien     enough for the reversed compare or (b) we have a valid FP compare.  */
1303690286Sobrien  if (! ix86_comparison_operator (new_op0, VOIDmode))
1303790286Sobrien    FAIL;
1303890286Sobrien})
1303952296Sobrien
1304090286Sobrien;; Define combination compare-and-branch fp compare instructions to use
1304190286Sobrien;; during early optimization.  Splitting the operation apart early makes
1304290286Sobrien;; for bad code when we want to reverse the operation.
1304318334Speter
1304490286Sobrien(define_insn "*fp_jcc_1"
1304590286Sobrien  [(set (pc)
1304690286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1304790286Sobrien			[(match_operand 1 "register_operand" "f")
1304890286Sobrien			 (match_operand 2 "register_operand" "f")])
1304990286Sobrien	  (label_ref (match_operand 3 "" ""))
1305090286Sobrien	  (pc)))
1305190286Sobrien   (clobber (reg:CCFP 18))
1305290286Sobrien   (clobber (reg:CCFP 17))]
1305390286Sobrien  "TARGET_CMOVE && TARGET_80387
1305490286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1305590286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
1305690286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1305790286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1305890286Sobrien  "#")
1305918334Speter
1306090286Sobrien(define_insn "*fp_jcc_1_sse"
1306190286Sobrien  [(set (pc)
1306290286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1306390286Sobrien			[(match_operand 1 "register_operand" "f#x,x#f")
1306490286Sobrien			 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
1306590286Sobrien	  (label_ref (match_operand 3 "" ""))
1306690286Sobrien	  (pc)))
1306790286Sobrien   (clobber (reg:CCFP 18))
1306890286Sobrien   (clobber (reg:CCFP 17))]
1306990286Sobrien  "TARGET_80387
1307090286Sobrien   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1307190286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1307290286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1307390286Sobrien  "#")
1307418334Speter
1307590286Sobrien(define_insn "*fp_jcc_1_sse_only"
1307690286Sobrien  [(set (pc)
1307790286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1307890286Sobrien			[(match_operand 1 "register_operand" "x")
1307990286Sobrien			 (match_operand 2 "nonimmediate_operand" "xm")])
1308090286Sobrien	  (label_ref (match_operand 3 "" ""))
1308190286Sobrien	  (pc)))
1308290286Sobrien   (clobber (reg:CCFP 18))
1308390286Sobrien   (clobber (reg:CCFP 17))]
1308490286Sobrien  "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1308590286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1308690286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1308790286Sobrien  "#")
1308818334Speter
1308990286Sobrien(define_insn "*fp_jcc_2"
1309018334Speter  [(set (pc)
1309190286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1309290286Sobrien			[(match_operand 1 "register_operand" "f")
1309390286Sobrien			 (match_operand 2 "register_operand" "f")])
1309490286Sobrien	  (pc)
1309590286Sobrien	  (label_ref (match_operand 3 "" ""))))
1309690286Sobrien   (clobber (reg:CCFP 18))
1309790286Sobrien   (clobber (reg:CCFP 17))]
1309890286Sobrien  "TARGET_CMOVE && TARGET_80387
1309990286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1310090286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
1310190286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1310290286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1310390286Sobrien  "#")
1310418334Speter
1310590286Sobrien(define_insn "*fp_jcc_2_sse"
1310690286Sobrien  [(set (pc)
1310790286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1310890286Sobrien			[(match_operand 1 "register_operand" "f#x,x#f")
1310990286Sobrien			 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
1311090286Sobrien	  (pc)
1311190286Sobrien	  (label_ref (match_operand 3 "" ""))))
1311290286Sobrien   (clobber (reg:CCFP 18))
1311390286Sobrien   (clobber (reg:CCFP 17))]
1311490286Sobrien  "TARGET_80387
1311590286Sobrien   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1311690286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1311790286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1311890286Sobrien  "#")
1311918334Speter
1312090286Sobrien(define_insn "*fp_jcc_2_sse_only"
1312190286Sobrien  [(set (pc)
1312290286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1312390286Sobrien			[(match_operand 1 "register_operand" "x")
1312490286Sobrien			 (match_operand 2 "nonimmediate_operand" "xm")])
1312590286Sobrien	  (pc)
1312690286Sobrien	  (label_ref (match_operand 3 "" ""))))
1312790286Sobrien   (clobber (reg:CCFP 18))
1312890286Sobrien   (clobber (reg:CCFP 17))]
1312990286Sobrien  "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1313090286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1313190286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1313290286Sobrien  "#")
1313318334Speter
1313490286Sobrien(define_insn "*fp_jcc_3"
1313590286Sobrien  [(set (pc)
1313690286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1313790286Sobrien			[(match_operand 1 "register_operand" "f")
1313890286Sobrien			 (match_operand 2 "nonimmediate_operand" "fm")])
1313990286Sobrien	  (label_ref (match_operand 3 "" ""))
1314090286Sobrien	  (pc)))
1314190286Sobrien   (clobber (reg:CCFP 18))
1314290286Sobrien   (clobber (reg:CCFP 17))
1314390286Sobrien   (clobber (match_scratch:HI 4 "=a"))]
1314490286Sobrien  "TARGET_80387
1314590286Sobrien   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
1314690286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1314790286Sobrien   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
1314890286Sobrien   && SELECT_CC_MODE (GET_CODE (operands[0]),
1314990286Sobrien		      operands[1], operands[2]) == CCFPmode
1315090286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1315190286Sobrien  "#")
1315218334Speter
1315390286Sobrien(define_insn "*fp_jcc_4"
1315450650Sobrien  [(set (pc)
1315590286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1315690286Sobrien			[(match_operand 1 "register_operand" "f")
1315790286Sobrien			 (match_operand 2 "nonimmediate_operand" "fm")])
1315890286Sobrien	  (pc)
1315990286Sobrien	  (label_ref (match_operand 3 "" ""))))
1316090286Sobrien   (clobber (reg:CCFP 18))
1316190286Sobrien   (clobber (reg:CCFP 17))
1316290286Sobrien   (clobber (match_scratch:HI 4 "=a"))]
1316390286Sobrien  "TARGET_80387
1316490286Sobrien   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
1316590286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1316690286Sobrien   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
1316790286Sobrien   && SELECT_CC_MODE (GET_CODE (operands[0]),
1316890286Sobrien		      operands[1], operands[2]) == CCFPmode
1316990286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1317090286Sobrien  "#")
1317150650Sobrien
1317290286Sobrien(define_insn "*fp_jcc_5"
1317350650Sobrien  [(set (pc)
1317490286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1317590286Sobrien			[(match_operand 1 "register_operand" "f")
1317690286Sobrien			 (match_operand 2 "register_operand" "f")])
1317790286Sobrien	  (label_ref (match_operand 3 "" ""))
1317890286Sobrien	  (pc)))
1317990286Sobrien   (clobber (reg:CCFP 18))
1318090286Sobrien   (clobber (reg:CCFP 17))
1318190286Sobrien   (clobber (match_scratch:HI 4 "=a"))]
1318290286Sobrien  "TARGET_80387
1318390286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
1318490286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1318590286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1318690286Sobrien  "#")
1318750650Sobrien
1318890286Sobrien(define_insn "*fp_jcc_6"
1318950650Sobrien  [(set (pc)
1319090286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1319190286Sobrien			[(match_operand 1 "register_operand" "f")
1319290286Sobrien			 (match_operand 2 "register_operand" "f")])
1319390286Sobrien	  (pc)
1319490286Sobrien	  (label_ref (match_operand 3 "" ""))))
1319590286Sobrien   (clobber (reg:CCFP 18))
1319690286Sobrien   (clobber (reg:CCFP 17))
1319790286Sobrien   (clobber (match_scratch:HI 4 "=a"))]
1319890286Sobrien  "TARGET_80387
1319990286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
1320090286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1320190286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1320290286Sobrien  "#")
1320350650Sobrien
1320490286Sobrien(define_split
1320550650Sobrien  [(set (pc)
1320690286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1320790286Sobrien			[(match_operand 1 "register_operand" "")
1320890286Sobrien			 (match_operand 2 "nonimmediate_operand" "")])
1320990286Sobrien	  (match_operand 3 "" "")
1321090286Sobrien	  (match_operand 4 "" "")))
1321190286Sobrien   (clobber (reg:CCFP 18))
1321290286Sobrien   (clobber (reg:CCFP 17))]
1321390286Sobrien  "reload_completed"
1321490286Sobrien  [(const_int 0)]
1321550650Sobrien{
1321690286Sobrien  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
1321790286Sobrien			operands[3], operands[4], NULL_RTX);
1321890286Sobrien  DONE;
1321990286Sobrien})
1322050650Sobrien
1322190286Sobrien(define_split
1322250650Sobrien  [(set (pc)
1322390286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1322490286Sobrien			[(match_operand 1 "register_operand" "")
1322590286Sobrien			 (match_operand 2 "nonimmediate_operand" "")])
1322690286Sobrien	  (match_operand 3 "" "")
1322790286Sobrien	  (match_operand 4 "" "")))
1322890286Sobrien   (clobber (reg:CCFP 18))
1322990286Sobrien   (clobber (reg:CCFP 17))
1323090286Sobrien   (clobber (match_scratch:HI 5 "=a"))]
1323190286Sobrien  "reload_completed"
1323290286Sobrien  [(set (pc)
1323390286Sobrien	(if_then_else (match_dup 6)
1323490286Sobrien	  (match_dup 3)
1323590286Sobrien	  (match_dup 4)))]
1323650650Sobrien{
1323790286Sobrien  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
1323890286Sobrien			operands[3], operands[4], operands[5]);
1323990286Sobrien  DONE;
1324090286Sobrien})
1324190286Sobrien
1324290286Sobrien;; Unconditional and other jump instructions
1324350650Sobrien
1324490286Sobrien(define_insn "jump"
1324550650Sobrien  [(set (pc)
1324690286Sobrien	(label_ref (match_operand 0 "" "")))]
1324750650Sobrien  ""
1324890286Sobrien  "jmp\t%l0"
1324990286Sobrien  [(set_attr "type" "ibr")])
1325090286Sobrien
1325190286Sobrien(define_expand "indirect_jump"
1325290286Sobrien  [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
1325390286Sobrien  ""
1325490286Sobrien  "")
1325590286Sobrien
1325690286Sobrien(define_insn "*indirect_jump"
1325790286Sobrien  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
1325890286Sobrien  "!TARGET_64BIT"
1325990286Sobrien  "jmp\t%A0"
1326090286Sobrien  [(set_attr "type" "ibr")
1326190286Sobrien   (set_attr "length_immediate" "0")])
1326290286Sobrien
1326390286Sobrien(define_insn "*indirect_jump_rtx64"
1326490286Sobrien  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
1326590286Sobrien  "TARGET_64BIT"
1326690286Sobrien  "jmp\t%A0"
1326790286Sobrien  [(set_attr "type" "ibr")
1326890286Sobrien   (set_attr "length_immediate" "0")])
1326990286Sobrien
1327090286Sobrien(define_expand "tablejump"
1327190286Sobrien  [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
1327290286Sobrien	      (use (label_ref (match_operand 1 "" "")))])]
1327390286Sobrien  ""
1327450650Sobrien{
1327590286Sobrien  /* In PIC mode, the table entries are stored GOT-relative.  Convert
1327690286Sobrien     the relative address to an absolute address.  */
1327790286Sobrien  if (flag_pic)
1327890286Sobrien    {
1327990286Sobrien      if (TARGET_64BIT)
1328090286Sobrien	operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1328190286Sobrien					   gen_rtx_LABEL_REF (Pmode, operands[1]),
1328290286Sobrien					   NULL_RTX, 0,
1328390286Sobrien					   OPTAB_DIRECT);
1328490286Sobrien      else if (HAVE_AS_GOTOFF_IN_DATA)
1328590286Sobrien	{
1328690286Sobrien	  operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1328790286Sobrien					     pic_offset_table_rtx, NULL_RTX,
1328890286Sobrien					     1, OPTAB_DIRECT);
1328990286Sobrien	  current_function_uses_pic_offset_table = 1;
1329090286Sobrien	}
1329190286Sobrien      else
1329290286Sobrien	{
1329390286Sobrien	  operands[0] = expand_simple_binop (Pmode, MINUS, pic_offset_table_rtx,
1329490286Sobrien					     operands[0], NULL_RTX, 1,
1329590286Sobrien					     OPTAB_DIRECT);
1329690286Sobrien	  current_function_uses_pic_offset_table = 1;
1329790286Sobrien	}
1329890286Sobrien    }
1329990286Sobrien})
1330050650Sobrien
1330190286Sobrien(define_insn "*tablejump_1"
1330290286Sobrien  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
1330390286Sobrien   (use (label_ref (match_operand 1 "" "")))]
1330490286Sobrien  "!TARGET_64BIT"
1330590286Sobrien  "jmp\t%A0"
1330690286Sobrien  [(set_attr "type" "ibr")
1330790286Sobrien   (set_attr "length_immediate" "0")])
1330818334Speter
1330990286Sobrien(define_insn "*tablejump_1_rtx64"
1331090286Sobrien  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
1331190286Sobrien   (use (label_ref (match_operand 1 "" "")))]
1331290286Sobrien  "TARGET_64BIT"
1331390286Sobrien  "jmp\t%A0"
1331490286Sobrien  [(set_attr "type" "ibr")
1331590286Sobrien   (set_attr "length_immediate" "0")])
1331690286Sobrien
1331790286Sobrien;; Loop instruction
1331890286Sobrien;;
1331990286Sobrien;; This is all complicated by the fact that since this is a jump insn
1332090286Sobrien;; we must handle our own reloads.
1332118334Speter
1332290286Sobrien(define_expand "doloop_end"
1332390286Sobrien  [(use (match_operand 0 "" ""))        ; loop pseudo
1332490286Sobrien   (use (match_operand 1 "" ""))        ; iterations; zero if unknown
1332590286Sobrien   (use (match_operand 2 "" ""))        ; max iterations
1332690286Sobrien   (use (match_operand 3 "" ""))        ; loop level 
1332790286Sobrien   (use (match_operand 4 "" ""))]       ; label
1332890286Sobrien  "!TARGET_64BIT && TARGET_USE_LOOP"
1332990286Sobrien  "                                 
1333018334Speter{
1333190286Sobrien  /* Only use cloop on innermost loops.  */
1333290286Sobrien  if (INTVAL (operands[3]) > 1)
1333390286Sobrien    FAIL;
1333490286Sobrien  if (GET_MODE (operands[0]) != SImode)
1333590286Sobrien    FAIL;
1333690286Sobrien  emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
1333790286Sobrien					   operands[0]));
1333890286Sobrien  DONE;
1333918334Speter}")
1334018334Speter
1334190286Sobrien(define_insn "doloop_end_internal"
1334218334Speter  [(set (pc)
1334390286Sobrien	(if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
1334490286Sobrien			  (const_int 1))
1334590286Sobrien		      (label_ref (match_operand 0 "" ""))
1334690286Sobrien		      (pc)))
1334790286Sobrien   (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
1334890286Sobrien	(plus:SI (match_dup 1)
1334990286Sobrien		 (const_int -1)))
1335090286Sobrien   (clobber (match_scratch:SI 3 "=X,X,r"))
1335190286Sobrien   (clobber (reg:CC 17))]
1335290286Sobrien  "!TARGET_64BIT && TARGET_USE_LOOP"
1335318334Speter{
1335490286Sobrien  if (which_alternative != 0)
1335590286Sobrien    return "#";
1335690286Sobrien  if (get_attr_length (insn) == 2)
1335790286Sobrien    return "%+loop\t%l0";
1335890286Sobrien  else
1335990286Sobrien    return "dec{l}\t%1\;%+jne\t%l0";
1336090286Sobrien}
1336190286Sobrien  [(set_attr "ppro_uops" "many")
1336290286Sobrien   (set (attr "type")
1336390286Sobrien	(if_then_else (and (eq_attr "alternative" "0")
1336490286Sobrien			   (and (ge (minus (match_dup 0) (pc))
1336590286Sobrien			            (const_int -128))
1336690286Sobrien			        (lt (minus (match_dup 0) (pc))
1336790286Sobrien			            (const_int 124))))
1336890286Sobrien		      (const_string "ibr")
1336990286Sobrien		      (const_string "multi")))])
1337018334Speter
1337190286Sobrien(define_split
1337290286Sobrien  [(set (pc)
1337390286Sobrien	(if_then_else (ne (match_operand:SI 1 "register_operand" "")
1337490286Sobrien			  (const_int 1))
1337590286Sobrien		      (match_operand 0 "" "")
1337690286Sobrien		      (pc)))
1337790286Sobrien   (set (match_dup 1)
1337890286Sobrien	(plus:SI (match_dup 1)
1337990286Sobrien		 (const_int -1)))
1338090286Sobrien   (clobber (match_scratch:SI 2 ""))
1338190286Sobrien   (clobber (reg:CC 17))]
1338290286Sobrien  "!TARGET_64BIT && TARGET_USE_LOOP
1338390286Sobrien   && reload_completed
1338490286Sobrien   && REGNO (operands[1]) != 2"
1338590286Sobrien  [(parallel [(set (reg:CCZ 17)
1338690286Sobrien		   (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
1338790286Sobrien				 (const_int 0)))
1338890286Sobrien	      (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
1338990286Sobrien   (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
1339090286Sobrien			   (match_dup 0)
1339190286Sobrien			   (pc)))]
1339290286Sobrien  "")
1339390286Sobrien  
1339490286Sobrien(define_split
1339590286Sobrien  [(set (pc)
1339690286Sobrien	(if_then_else (ne (match_operand:SI 1 "register_operand" "")
1339790286Sobrien			  (const_int 1))
1339890286Sobrien		      (match_operand 0 "" "")
1339990286Sobrien		      (pc)))
1340090286Sobrien   (set (match_operand:SI 2 "nonimmediate_operand" "")
1340190286Sobrien	(plus:SI (match_dup 1)
1340290286Sobrien		 (const_int -1)))
1340390286Sobrien   (clobber (match_scratch:SI 3 ""))
1340490286Sobrien   (clobber (reg:CC 17))]
1340590286Sobrien  "!TARGET_64BIT && TARGET_USE_LOOP
1340690286Sobrien   && reload_completed
1340790286Sobrien   && (! REG_P (operands[2])
1340890286Sobrien       || ! rtx_equal_p (operands[1], operands[2]))"
1340990286Sobrien  [(set (match_dup 3) (match_dup 1))
1341090286Sobrien   (parallel [(set (reg:CCZ 17)
1341190286Sobrien		   (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
1341290286Sobrien				(const_int 0)))
1341390286Sobrien	      (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
1341490286Sobrien   (set (match_dup 2) (match_dup 3))
1341590286Sobrien   (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
1341690286Sobrien			   (match_dup 0)
1341790286Sobrien			   (pc)))]
1341890286Sobrien  "")
1341918334Speter
1342090286Sobrien;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
1342118334Speter
1342290286Sobrien(define_peephole2
1342390286Sobrien  [(set (reg 17) (match_operand 0 "" ""))
1342490286Sobrien   (set (match_operand:QI 1 "register_operand" "")
1342590286Sobrien	(match_operator:QI 2 "ix86_comparison_operator"
1342690286Sobrien	  [(reg 17) (const_int 0)]))
1342790286Sobrien   (set (match_operand 3 "q_regs_operand" "")
1342890286Sobrien	(zero_extend (match_dup 1)))]
1342990286Sobrien  "(peep2_reg_dead_p (3, operands[1])
1343090286Sobrien    || operands_match_p (operands[1], operands[3]))
1343190286Sobrien   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
1343290286Sobrien  [(set (match_dup 4) (match_dup 0))
1343390286Sobrien   (set (strict_low_part (match_dup 5))
1343490286Sobrien	(match_dup 2))]
1343518334Speter{
1343690286Sobrien  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
1343790286Sobrien  operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
1343890286Sobrien  ix86_expand_clear (operands[3]);
1343990286Sobrien})
1344018334Speter
1344190286Sobrien;; Similar, but match zero_extendhisi2_and, which adds a clobber.
1344218334Speter
1344390286Sobrien(define_peephole2
1344490286Sobrien  [(set (reg 17) (match_operand 0 "" ""))
1344590286Sobrien   (set (match_operand:QI 1 "register_operand" "")
1344690286Sobrien	(match_operator:QI 2 "ix86_comparison_operator"
1344790286Sobrien	  [(reg 17) (const_int 0)]))
1344890286Sobrien   (parallel [(set (match_operand 3 "q_regs_operand" "")
1344990286Sobrien		   (zero_extend (match_dup 1)))
1345090286Sobrien	      (clobber (reg:CC 17))])]
1345190286Sobrien  "(peep2_reg_dead_p (3, operands[1])
1345290286Sobrien    || operands_match_p (operands[1], operands[3]))
1345390286Sobrien   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
1345490286Sobrien  [(set (match_dup 4) (match_dup 0))
1345590286Sobrien   (set (strict_low_part (match_dup 5))
1345690286Sobrien	(match_dup 2))]
1345790286Sobrien{
1345890286Sobrien  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
1345990286Sobrien  operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
1346090286Sobrien  ix86_expand_clear (operands[3]);
1346190286Sobrien})
1346290286Sobrien
1346390286Sobrien;; Call instructions.
1346418334Speter
1346590286Sobrien;; The predicates normally associated with named expanders are not properly
1346690286Sobrien;; checked for calls.  This is a bug in the generic code, but it isn't that
1346790286Sobrien;; easy to fix.  Ignore it for now and be prepared to fix things up.
1346818334Speter
1346918334Speter;; Call subroutine returning no value.
1347018334Speter
1347118334Speter(define_expand "call_pop"
1347290286Sobrien  [(parallel [(call (match_operand:QI 0 "" "")
1347390286Sobrien		    (match_operand:SI 1 "" ""))
1347418334Speter	      (set (reg:SI 7)
1347518334Speter		   (plus:SI (reg:SI 7)
1347690286Sobrien			    (match_operand:SI 3 "" "")))])]
1347790286Sobrien  "!TARGET_64BIT"
1347818334Speter{
1347952296Sobrien  if (operands[3] == const0_rtx)
1348052296Sobrien    {
1348190286Sobrien      emit_insn (gen_call (operands[0], operands[1], constm1_rtx));
1348252296Sobrien      DONE;
1348352296Sobrien    }
1348490286Sobrien  /* Static functions and indirect calls don't need
1348590286Sobrien     current_function_uses_pic_offset_table.  */
1348690286Sobrien  if (flag_pic
1348790286Sobrien      && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
1348890286Sobrien      && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
1348918334Speter    current_function_uses_pic_offset_table = 1;
1349090286Sobrien  if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
1349190286Sobrien    XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1349290286Sobrien  if (TARGET_64BIT)
1349390286Sobrien    abort();
1349490286Sobrien})
1349518334Speter
1349690286Sobrien(define_insn "*call_pop_0"
1349790286Sobrien  [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
1349890286Sobrien	 (match_operand:SI 1 "" ""))
1349918334Speter   (set (reg:SI 7) (plus:SI (reg:SI 7)
1350090286Sobrien			    (match_operand:SI 2 "immediate_operand" "")))]
1350190286Sobrien  "!TARGET_64BIT"
1350218334Speter{
1350390286Sobrien  if (SIBLING_CALL_P (insn))
1350490286Sobrien    return "jmp\t%P0";
1350590286Sobrien  else
1350690286Sobrien    return "call\t%P0";
1350790286Sobrien}
1350890286Sobrien  [(set_attr "type" "call")])
1350990286Sobrien  
1351090286Sobrien(define_insn "*call_pop_1"
1351190286Sobrien  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
1351290286Sobrien	 (match_operand:SI 1 "" ""))
1351390286Sobrien   (set (reg:SI 7) (plus:SI (reg:SI 7)
1351490286Sobrien			    (match_operand:SI 2 "immediate_operand" "i")))]
1351590286Sobrien  "!TARGET_64BIT"
1351690286Sobrien{
1351790286Sobrien  if (constant_call_address_operand (operands[0], Pmode))
1351818334Speter    {
1351990286Sobrien      if (SIBLING_CALL_P (insn))
1352090286Sobrien	return "jmp\t%P0";
1352190286Sobrien      else
1352290286Sobrien	return "call\t%P0";
1352318334Speter    }
1352490286Sobrien  if (SIBLING_CALL_P (insn))
1352590286Sobrien    return "jmp\t%A0";
1352618334Speter  else
1352790286Sobrien    return "call\t%A0";
1352890286Sobrien}
1352990286Sobrien  [(set_attr "type" "call")])
1353018334Speter
1353118334Speter(define_expand "call"
1353290286Sobrien  [(call (match_operand:QI 0 "" "")
1353390286Sobrien	 (match_operand 1 "" ""))
1353490286Sobrien   (use (match_operand 2 "" ""))]
1353518334Speter  ;; Operand 1 not used on the i386.
1353618334Speter  ""
1353718334Speter{
1353890286Sobrien  rtx insn;
1353990286Sobrien  /* Static functions and indirect calls don't need
1354090286Sobrien     current_function_uses_pic_offset_table.  */
1354190286Sobrien  if (flag_pic
1354290286Sobrien      && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
1354390286Sobrien      && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
1354418334Speter    current_function_uses_pic_offset_table = 1;
1354518334Speter
1354690286Sobrien  if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
1354790286Sobrien    XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1354890286Sobrien  if (TARGET_64BIT && INTVAL (operands[2]) >= 0)
1354990286Sobrien    {
1355090286Sobrien      rtx reg = gen_rtx_REG (QImode, 0);
1355190286Sobrien      emit_move_insn (reg, operands[2]);
1355290286Sobrien      insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
1355390286Sobrien      use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
1355490286Sobrien      DONE;
1355590286Sobrien    }
1355690286Sobrien   insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
1355790286Sobrien   DONE;
1355890286Sobrien})
1355918334Speter
1356090286Sobrien(define_expand "call_exp"
1356190286Sobrien  [(call (match_operand:QI 0 "" "")
1356290286Sobrien	 (match_operand 1 "" ""))]
1356390286Sobrien  ""
1356490286Sobrien  "")
1356518334Speter
1356690286Sobrien(define_insn "*call_0"
1356790286Sobrien  [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
1356890286Sobrien	 (match_operand 1 "" ""))]
1356918334Speter  ""
1357018334Speter{
1357190286Sobrien  if (SIBLING_CALL_P (insn))
1357290286Sobrien    return "jmp\t%P0";
1357390286Sobrien  else
1357490286Sobrien    return "call\t%P0";
1357590286Sobrien}
1357690286Sobrien  [(set_attr "type" "call")])
1357790286Sobrien
1357890286Sobrien(define_insn "*call_1"
1357990286Sobrien  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
1358090286Sobrien	 (match_operand 1 "" ""))]
1358190286Sobrien  "!TARGET_64BIT"
1358290286Sobrien{
1358390286Sobrien  if (constant_call_address_operand (operands[0], QImode))
1358418334Speter    {
1358590286Sobrien      if (SIBLING_CALL_P (insn))
1358690286Sobrien	return "jmp\t%P0";
1358790286Sobrien      else
1358890286Sobrien	return "call\t%P0";
1358918334Speter    }
1359090286Sobrien  if (SIBLING_CALL_P (insn))
1359190286Sobrien    return "jmp\t%A0";
1359218334Speter  else
1359390286Sobrien    return "call\t%A0";
1359490286Sobrien}
1359590286Sobrien  [(set_attr "type" "call")])
1359618334Speter
1359790286Sobrien(define_insn "*call_1_rex64"
1359890286Sobrien  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
1359990286Sobrien	 (match_operand 1 "" ""))]
1360090286Sobrien  "TARGET_64BIT"
1360190286Sobrien{
1360290286Sobrien  if (constant_call_address_operand (operands[0], QImode))
1360390286Sobrien    {
1360490286Sobrien      if (SIBLING_CALL_P (insn))
1360590286Sobrien	return "jmp\t%P0";
1360690286Sobrien      else
1360790286Sobrien	return "call\t%P0";
1360890286Sobrien    }
1360990286Sobrien  if (SIBLING_CALL_P (insn))
1361090286Sobrien    return "jmp\t%A0";
1361190286Sobrien  else
1361290286Sobrien    return "call\t%A0";
1361390286Sobrien}
1361490286Sobrien  [(set_attr "type" "call")])
1361518334Speter
1361618334Speter;; Call subroutine, returning value in operand 0
1361718334Speter;; (which must be a hard register).
1361818334Speter
1361918334Speter(define_expand "call_value_pop"
1362018334Speter  [(parallel [(set (match_operand 0 "" "")
1362190286Sobrien		   (call (match_operand:QI 1 "" "")
1362290286Sobrien			 (match_operand:SI 2 "" "")))
1362318334Speter	      (set (reg:SI 7)
1362418334Speter		   (plus:SI (reg:SI 7)
1362590286Sobrien			    (match_operand:SI 4 "" "")))])]
1362690286Sobrien  "!TARGET_64BIT"
1362718334Speter{
1362852296Sobrien  if (operands[4] == const0_rtx)
1362952296Sobrien    {
1363090286Sobrien      emit_insn (gen_call_value (operands[0], operands[1], operands[2],
1363190286Sobrien				 constm1_rtx));
1363252296Sobrien      DONE;
1363352296Sobrien    }
1363490286Sobrien  /* Static functions and indirect calls don't need
1363590286Sobrien     current_function_uses_pic_offset_table.  */
1363690286Sobrien  if (flag_pic
1363790286Sobrien      && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1363890286Sobrien      && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
1363918334Speter    current_function_uses_pic_offset_table = 1;
1364090286Sobrien  if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
1364190286Sobrien    XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1364290286Sobrien})
1364318334Speter
1364418334Speter(define_expand "call_value"
1364518334Speter  [(set (match_operand 0 "" "")
1364690286Sobrien	(call (match_operand:QI 1 "" "")
1364790286Sobrien	      (match_operand:SI 2 "" "")))
1364890286Sobrien   (use (match_operand:SI 3 "" ""))]
1364918334Speter  ;; Operand 2 not used on the i386.
1365018334Speter  ""
1365118334Speter{
1365290286Sobrien  rtx insn;
1365390286Sobrien  /* Static functions and indirect calls don't need
1365490286Sobrien     current_function_uses_pic_offset_table.  */
1365590286Sobrien  if (flag_pic
1365690286Sobrien      && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1365790286Sobrien      && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
1365818334Speter    current_function_uses_pic_offset_table = 1;
1365990286Sobrien  if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
1366090286Sobrien    XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1366190286Sobrien  if (TARGET_64BIT && INTVAL (operands[3]) >= 0)
1366218334Speter    {
1366390286Sobrien      rtx reg = gen_rtx_REG (QImode, 0);
1366490286Sobrien      emit_move_insn (reg, operands[3]);
1366590286Sobrien      insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
1366690286Sobrien						 operands[2]));
1366790286Sobrien      use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
1366890286Sobrien      DONE;
1366918334Speter    }
1367090286Sobrien  insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
1367190286Sobrien					     operands[2]));
1367290286Sobrien  DONE;
1367390286Sobrien})
1367418334Speter
1367590286Sobrien(define_expand "call_value_exp"
1367690286Sobrien  [(set (match_operand 0 "" "")
1367790286Sobrien	(call (match_operand:QI 1 "" "")
1367890286Sobrien	      (match_operand:SI 2 "" "")))]
1367990286Sobrien  ""
1368090286Sobrien  "")
1368118334Speter
1368218334Speter;; Call subroutine returning any type.
1368318334Speter
1368418334Speter(define_expand "untyped_call"
1368518334Speter  [(parallel [(call (match_operand 0 "" "")
1368618334Speter		    (const_int 0))
1368718334Speter	      (match_operand 1 "" "")
1368818334Speter	      (match_operand 2 "" "")])]
1368918334Speter  ""
1369018334Speter{
1369118334Speter  int i;
1369218334Speter
1369318334Speter  /* In order to give reg-stack an easier job in validating two
1369418334Speter     coprocessor registers as containing a possible return value,
1369518334Speter     simply pretend the untyped call returns a complex long double
1369618334Speter     value.  */
1369750650Sobrien
1369896294Sobrien  emit_call_insn (TARGET_FLOAT_RETURNS_IN_80387
1369950650Sobrien                  ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
1370090286Sobrien				    operands[0], const0_rtx,
1370190286Sobrien				    GEN_INT (SSE_REGPARM_MAX - 1))
1370290286Sobrien                  : gen_call (operands[0], const0_rtx,
1370390286Sobrien			      GEN_INT (SSE_REGPARM_MAX - 1)));
1370418334Speter
1370518334Speter  for (i = 0; i < XVECLEN (operands[2], 0); i++)
1370618334Speter    {
1370718334Speter      rtx set = XVECEXP (operands[2], 0, i);
1370818334Speter      emit_move_insn (SET_DEST (set), SET_SRC (set));
1370918334Speter    }
1371018334Speter
1371118334Speter  /* The optimizer does not know that the call sets the function value
1371218334Speter     registers we stored in the result block.  We avoid problems by
1371318334Speter     claiming that all hard registers are used and clobbered at this
1371418334Speter     point.  */
1371518334Speter  emit_insn (gen_blockage ());
1371618334Speter
1371718334Speter  DONE;
1371890286Sobrien})
1371990286Sobrien
1372090286Sobrien;; Prologue and epilogue instructions
1372118334Speter
1372218334Speter;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1372318334Speter;; all of memory.  This blocks insns from being moved across this point.
1372418334Speter
1372518334Speter(define_insn "blockage"
1372618334Speter  [(unspec_volatile [(const_int 0)] 0)]
1372718334Speter  ""
1372852296Sobrien  ""
1372990286Sobrien  [(set_attr "length" "0")])
1373018334Speter
1373118334Speter;; Insn emitted into the body of a function to return from a function.
1373218334Speter;; This is only done if the function's epilogue is known to be simple.
1373390286Sobrien;; See comments for ix86_can_use_return_insn_p in i386.c.
1373418334Speter
1373550650Sobrien(define_expand "return"
1373618334Speter  [(return)]
1373750650Sobrien  "ix86_can_use_return_insn_p ()"
1373890286Sobrien{
1373990286Sobrien  if (current_function_pops_args)
1374090286Sobrien    {
1374190286Sobrien      rtx popc = GEN_INT (current_function_pops_args);
1374290286Sobrien      emit_jump_insn (gen_return_pop_internal (popc));
1374390286Sobrien      DONE;
1374490286Sobrien    }
1374590286Sobrien})
1374650650Sobrien
1374750650Sobrien(define_insn "return_internal"
1374850650Sobrien  [(return)]
1374950650Sobrien  "reload_completed"
1375052296Sobrien  "ret"
1375190286Sobrien  [(set_attr "length" "1")
1375290286Sobrien   (set_attr "length_immediate" "0")
1375390286Sobrien   (set_attr "modrm" "0")])
1375450650Sobrien
1375550650Sobrien(define_insn "return_pop_internal"
1375650650Sobrien  [(return)
1375750650Sobrien   (use (match_operand:SI 0 "const_int_operand" ""))]
1375850650Sobrien  "reload_completed"
1375990286Sobrien  "ret\t%0"
1376090286Sobrien  [(set_attr "length" "3")
1376190286Sobrien   (set_attr "length_immediate" "2")
1376290286Sobrien   (set_attr "modrm" "0")])
1376350650Sobrien
1376490286Sobrien(define_insn "return_indirect_internal"
1376590286Sobrien  [(return)
1376690286Sobrien   (use (match_operand:SI 0 "register_operand" "r"))]
1376790286Sobrien  "reload_completed"
1376890286Sobrien  "jmp\t%A0"
1376990286Sobrien  [(set_attr "type" "ibr")
1377090286Sobrien   (set_attr "length_immediate" "0")])
1377190286Sobrien
1377250650Sobrien(define_insn "nop"
1377350650Sobrien  [(const_int 0)]
1377450650Sobrien  ""
1377552296Sobrien  "nop"
1377690286Sobrien  [(set_attr "length" "1")
1377790286Sobrien   (set_attr "length_immediate" "0")
1377890286Sobrien   (set_attr "modrm" "0")
1377990286Sobrien   (set_attr "ppro_uops" "one")])
1378050650Sobrien
1378150650Sobrien(define_expand "prologue"
1378250650Sobrien  [(const_int 1)]
1378350650Sobrien  ""
1378490286Sobrien  "ix86_expand_prologue (); DONE;")
1378550650Sobrien
1378650650Sobrien(define_insn "prologue_set_got"
1378790286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1378890286Sobrien	(unspec_volatile:SI
1378950650Sobrien	 [(plus:SI (match_dup 0)
1379050650Sobrien		   (plus:SI (match_operand:SI 1 "symbolic_operand" "")
1379190286Sobrien			    (minus:SI (pc) (match_operand 2 "" ""))))] 1))
1379290286Sobrien   (clobber (reg:CC 17))]
1379390286Sobrien  "!TARGET_64BIT"
1379450650Sobrien{
1379590286Sobrien  if (GET_CODE (operands[2]) == LABEL_REF)
1379690286Sobrien     operands[2] = XEXP (operands[2], 0);
1379750650Sobrien  if (TARGET_DEEP_BRANCH_PREDICTION) 
1379890286Sobrien    return "add{l}\t{%1, %0|%0, %1}";
1379950650Sobrien  else  
1380090286Sobrien    return "add{l}\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}";
1380190286Sobrien}
1380290286Sobrien  [(set_attr "type" "alu")
1380390286Sobrien   ; Since this insn may have two constant operands, we must set the
1380490286Sobrien   ; length manually.
1380590286Sobrien   (set_attr "length_immediate" "4")
1380690286Sobrien   (set_attr "mode" "SI")])
1380750650Sobrien
1380850650Sobrien(define_insn "prologue_get_pc"
1380990286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1381090286Sobrien    (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
1381190286Sobrien  "!TARGET_64BIT"
1381250650Sobrien{
1381390286Sobrien  if (GET_CODE (operands[1]) == LABEL_REF)
1381490286Sobrien    operands[1] = XEXP (operands[1], 0);
1381590286Sobrien  output_asm_insn ("call\t%X1", operands);
1381690286Sobrien  if (! TARGET_DEEP_BRANCH_PREDICTION)
1381750650Sobrien    {
1381890286Sobrien      ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1381990286Sobrien				 CODE_LABEL_NUMBER (operands[1]));
13820102802Skan      return "pop{l}\t%0";
1382190286Sobrien    }
1382250650Sobrien  RET;
1382390286Sobrien}
1382490286Sobrien  [(set_attr "type" "multi")])
1382550650Sobrien
1382650650Sobrien(define_expand "epilogue"
1382750650Sobrien  [(const_int 1)]
1382850650Sobrien  ""
1382990286Sobrien  "ix86_expand_epilogue (1); DONE;")
1383050650Sobrien
1383190286Sobrien(define_expand "sibcall_epilogue"
1383290286Sobrien  [(const_int 1)]
1383350650Sobrien  ""
1383490286Sobrien  "ix86_expand_epilogue (0); DONE;")
1383550650Sobrien
1383690286Sobrien(define_expand "eh_return"
1383790286Sobrien  [(use (match_operand 0 "register_operand" ""))
1383890286Sobrien   (use (match_operand 1 "register_operand" ""))]
1383950650Sobrien  ""
1384050650Sobrien{
1384190286Sobrien  rtx tmp, sa = operands[0], ra = operands[1];
1384250650Sobrien
1384390286Sobrien  /* Tricky bit: we write the address of the handler to which we will
1384490286Sobrien     be returning into someone else's stack frame, one word below the
1384590286Sobrien     stack address we wish to restore.  */
1384690286Sobrien  tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
1384790286Sobrien  tmp = plus_constant (tmp, -UNITS_PER_WORD);
1384890286Sobrien  tmp = gen_rtx_MEM (Pmode, tmp);
1384990286Sobrien  emit_move_insn (tmp, ra);
1385018334Speter
1385190286Sobrien  if (Pmode == SImode)
1385290286Sobrien    emit_insn (gen_eh_return_si (sa));
1385390286Sobrien  else
1385490286Sobrien    emit_insn (gen_eh_return_di (sa));
1385590286Sobrien  emit_barrier ();
1385690286Sobrien  DONE;
1385790286Sobrien})
1385818334Speter
1385990286Sobrien(define_insn_and_split "eh_return_si"
1386090286Sobrien  [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")] 13)]
1386190286Sobrien  "!TARGET_64BIT"
1386290286Sobrien  "#"
1386390286Sobrien  "reload_completed"
1386490286Sobrien  [(const_int 1)]
1386590286Sobrien  "ix86_expand_epilogue (2); DONE;")
1386618334Speter
1386790286Sobrien(define_insn_and_split "eh_return_di"
1386890286Sobrien  [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")] 13)]
1386990286Sobrien  "TARGET_64BIT"
1387090286Sobrien  "#"
1387190286Sobrien  "reload_completed"
1387290286Sobrien  [(const_int 1)]
1387390286Sobrien  "ix86_expand_epilogue (2); DONE;")
1387418334Speter
1387590286Sobrien(define_insn "leave"
1387690286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
1387790286Sobrien   (set (reg:SI 6) (mem:SI (reg:SI 6)))
1387890286Sobrien   (clobber (mem:BLK (scratch)))]
1387990286Sobrien  "!TARGET_64BIT"
1388090286Sobrien  "leave"
1388190286Sobrien  [(set_attr "length_immediate" "0")
1388290286Sobrien   (set_attr "length" "1")
1388390286Sobrien   (set_attr "modrm" "0")
1388490286Sobrien   (set_attr "modrm" "0")
1388590286Sobrien   (set_attr "athlon_decode" "vector")
1388690286Sobrien   (set_attr "ppro_uops" "few")])
1388718334Speter
1388890286Sobrien(define_insn "leave_rex64"
1388990286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
1389090286Sobrien   (set (reg:DI 6) (mem:DI (reg:DI 6)))
1389190286Sobrien   (clobber (mem:BLK (scratch)))]
1389290286Sobrien  "TARGET_64BIT"
1389390286Sobrien  "leave"
1389490286Sobrien  [(set_attr "length_immediate" "0")
1389590286Sobrien   (set_attr "length" "1")
1389690286Sobrien   (set_attr "modrm" "0")
1389790286Sobrien   (set_attr "modrm" "0")
1389890286Sobrien   (set_attr "athlon_decode" "vector")
1389990286Sobrien   (set_attr "ppro_uops" "few")])
1390090286Sobrien
1390190286Sobrien(define_expand "ffssi2"
1390290286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "") 
1390390286Sobrien	(ffs:SI (match_operand:SI 1 "general_operand" "")))]
1390418334Speter  ""
1390518334Speter{
1390690286Sobrien  rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
1390790286Sobrien  rtx in = operands[1];
1390818334Speter
1390990286Sobrien  if (TARGET_CMOVE)
1391018334Speter    {
1391190286Sobrien      emit_move_insn (tmp, constm1_rtx);
1391290286Sobrien      emit_insn (gen_ffssi_1 (out, in));
1391390286Sobrien      emit_insn (gen_rtx_SET (VOIDmode, out,
1391490286Sobrien		  gen_rtx_IF_THEN_ELSE (SImode, 
1391590286Sobrien		    gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
1391690286Sobrien				const0_rtx),
1391790286Sobrien		    tmp,
1391890286Sobrien		    out)));
1391990286Sobrien      emit_insn (gen_addsi3 (out, out, const1_rtx));
1392090286Sobrien      emit_move_insn (operands[0], out);
1392118334Speter    }
1392218334Speter
1392390286Sobrien  /* Pentium bsf instruction is extremly slow.  The following code is
1392490286Sobrien     recommended by the Intel Optimizing Manual as a reasonable replacement:
1392590286Sobrien           TEST    EAX,EAX
1392690286Sobrien	   JZ      SHORT BS2
1392790286Sobrien	   XOR     ECX,ECX
1392890286Sobrien	   MOV     DWORD PTR [TEMP+4],ECX
1392990286Sobrien	   SUB     ECX,EAX
1393090286Sobrien	   AND     EAX,ECX
1393190286Sobrien	   MOV     DWORD PTR [TEMP],EAX
1393290286Sobrien	   FILD    QWORD PTR [TEMP]
1393390286Sobrien	   FSTP    QWORD PTR [TEMP]
1393490286Sobrien	   WAIT    ; WAIT only needed for compatibility with
1393590286Sobrien	           ; earlier processors
1393690286Sobrien	   MOV     ECX, DWORD PTR [TEMP+4]
1393790286Sobrien	   SHR     ECX,20
1393890286Sobrien	   SUB     ECX,3FFH
1393990286Sobrien	   TEST    EAX,EAX       ; clear zero flag
1394090286Sobrien       BS2:
1394190286Sobrien     Following piece of code expand ffs to similar beast.
1394290286Sobrien       */
1394350650Sobrien
1394490286Sobrien  else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
1394590286Sobrien    {
1394690286Sobrien      rtx label = gen_label_rtx ();
1394790286Sobrien      rtx lo, hi;
1394890286Sobrien      rtx mem = assign_386_stack_local (DImode, 0);
1394990286Sobrien      rtx fptmp = gen_reg_rtx (DFmode);
1395090286Sobrien      split_di (&mem, 1, &lo, &hi);
1395150650Sobrien
1395290286Sobrien      emit_move_insn (out, const0_rtx);
1395350650Sobrien
1395490286Sobrien      emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, label);
1395550650Sobrien
1395690286Sobrien      emit_move_insn (hi, out);
1395790286Sobrien      emit_insn (gen_subsi3 (out, out, in));
1395890286Sobrien      emit_insn (gen_andsi3 (out, out, in));
1395990286Sobrien      emit_move_insn (lo, out);
1396090286Sobrien      emit_insn (gen_floatdidf2 (fptmp,mem));
1396190286Sobrien      emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
1396290286Sobrien      emit_move_insn (out, hi);
1396390286Sobrien      emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
1396490286Sobrien      emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
1396550650Sobrien
1396690286Sobrien      emit_label (label);
1396790286Sobrien      LABEL_NUSES (label) = 1;
1396850650Sobrien
1396990286Sobrien      emit_move_insn (operands[0], out);
1397090286Sobrien    }
1397190286Sobrien  else
1397250650Sobrien    {
1397390286Sobrien      emit_move_insn (tmp, const0_rtx);
1397490286Sobrien      emit_insn (gen_ffssi_1 (out, in));
1397590286Sobrien      emit_insn (gen_rtx_SET (VOIDmode, 
1397690286Sobrien		  gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
1397790286Sobrien		  gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
1397890286Sobrien			      const0_rtx)));
1397990286Sobrien      emit_insn (gen_negsi2 (tmp, tmp));
1398090286Sobrien      emit_insn (gen_iorsi3 (out, out, tmp));
1398190286Sobrien      emit_insn (gen_addsi3 (out, out, const1_rtx));
1398290286Sobrien      emit_move_insn (operands[0], out);
1398350650Sobrien    }
1398490286Sobrien  DONE;  
1398590286Sobrien})
1398650650Sobrien
1398790286Sobrien(define_insn "ffssi_1"
1398890286Sobrien  [(set (reg:CCZ 17)
1398990286Sobrien        (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
1399090286Sobrien		     (const_int 0)))
1399190286Sobrien   (set (match_operand:SI 0 "register_operand" "=r")
1399290286Sobrien	(unspec:SI [(match_dup 1)] 5))]
1399318334Speter  ""
1399490286Sobrien  "bsf{l}\t{%1, %0|%0, %1}"
1399590286Sobrien  [(set_attr "prefix_0f" "1")
1399690286Sobrien   (set_attr "ppro_uops" "few")])
1399718334Speter
1399890286Sobrien;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
1399990286Sobrien;; and slower than the two-byte movzx insn needed to do the work in SImode.
1400090286Sobrien
1400190286Sobrien;; These patterns match the binary 387 instructions for addM3, subM3,
1400290286Sobrien;; mulM3 and divM3.  There are three patterns for each of DFmode and
1400390286Sobrien;; SFmode.  The first is the normal insn, the second the same insn but
1400490286Sobrien;; with one operand a conversion, and the third the same insn but with
1400590286Sobrien;; the other operand a conversion.  The conversion may be SFmode or
1400690286Sobrien;; SImode if the target mode DFmode, but only SImode if the target mode
1400790286Sobrien;; is SFmode.
1400818334Speter
1400990286Sobrien;; Gcc is slightly more smart about handling normal two address instructions
1401090286Sobrien;; so use special patterns for add and mull.
1401190286Sobrien(define_insn "*fop_sf_comm_nosse"
1401290286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
1401390286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1401496294Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "%0")
1401590286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
1401690286Sobrien  "TARGET_80387 && !TARGET_SSE_MATH
1401796294Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1401896294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1401990286Sobrien  "* return output_387_binary_op (insn, operands);"
1402090286Sobrien  [(set (attr "type") 
1402190286Sobrien	(if_then_else (match_operand:SF 3 "mult_operator" "") 
1402290286Sobrien	   (const_string "fmul")
1402390286Sobrien	   (const_string "fop")))
1402490286Sobrien   (set_attr "mode" "SF")])
1402518334Speter
1402690286Sobrien(define_insn "*fop_sf_comm"
1402790286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
1402890286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1402996294Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "%0,0")
1403090286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
1403190286Sobrien  "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
1403296294Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1403396294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1403490286Sobrien  "* return output_387_binary_op (insn, operands);"
1403590286Sobrien  [(set (attr "type") 
1403690286Sobrien	(if_then_else (eq_attr "alternative" "1")
1403790286Sobrien           (const_string "sse")
1403890286Sobrien	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
1403990286Sobrien	      (const_string "fmul")
1404090286Sobrien	      (const_string "fop"))))
1404190286Sobrien   (set_attr "mode" "SF")])
1404218334Speter
1404390286Sobrien(define_insn "*fop_sf_comm_sse"
1404490286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1404590286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1404696294Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "%0")
1404790286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
1404896294Sobrien  "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1404996294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1405090286Sobrien  "* return output_387_binary_op (insn, operands);"
1405190286Sobrien  [(set_attr "type" "sse")
1405290286Sobrien   (set_attr "mode" "SF")])
1405318334Speter
1405490286Sobrien(define_insn "*fop_df_comm_nosse"
1405590286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1405690286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1405796294Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "%0")
1405890286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
1405990286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
1406096294Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1406196294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1406290286Sobrien  "* return output_387_binary_op (insn, operands);"
1406390286Sobrien  [(set (attr "type") 
1406490286Sobrien	(if_then_else (match_operand:SF 3 "mult_operator" "") 
1406590286Sobrien	   (const_string "fmul")
1406690286Sobrien	   (const_string "fop")))
1406790286Sobrien   (set_attr "mode" "DF")])
1406818334Speter
1406990286Sobrien(define_insn "*fop_df_comm"
1407090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
1407190286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1407296294Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "%0,0")
1407390286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
1407490286Sobrien  "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
1407596294Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1407696294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1407790286Sobrien  "* return output_387_binary_op (insn, operands);"
1407890286Sobrien  [(set (attr "type") 
1407990286Sobrien	(if_then_else (eq_attr "alternative" "1")
1408090286Sobrien           (const_string "sse")
1408190286Sobrien	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
1408290286Sobrien	      (const_string "fmul")
1408390286Sobrien	      (const_string "fop"))))
1408490286Sobrien   (set_attr "mode" "DF")])
1408518334Speter
1408690286Sobrien(define_insn "*fop_df_comm_sse"
1408790286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1408890286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1408996294Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "%0")
1409090286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
1409190286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH
1409296294Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1409396294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1409490286Sobrien  "* return output_387_binary_op (insn, operands);"
1409590286Sobrien  [(set_attr "type" "sse")
1409690286Sobrien   (set_attr "mode" "DF")])
1409718334Speter
1409890286Sobrien(define_insn "*fop_xf_comm"
1409990286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1410090286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1410190286Sobrien			[(match_operand:XF 1 "register_operand" "%0")
1410290286Sobrien			 (match_operand:XF 2 "register_operand" "f")]))]
1410390286Sobrien  "!TARGET_64BIT && TARGET_80387
1410490286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
1410590286Sobrien  "* return output_387_binary_op (insn, operands);"
1410690286Sobrien  [(set (attr "type") 
1410790286Sobrien        (if_then_else (match_operand:XF 3 "mult_operator" "") 
1410890286Sobrien           (const_string "fmul")
1410990286Sobrien           (const_string "fop")))
1411090286Sobrien   (set_attr "mode" "XF")])
1411118334Speter
1411290286Sobrien(define_insn "*fop_tf_comm"
1411390286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1411490286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1411590286Sobrien			[(match_operand:TF 1 "register_operand" "%0")
1411690286Sobrien			 (match_operand:TF 2 "register_operand" "f")]))]
1411790286Sobrien  "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
1411890286Sobrien  "* return output_387_binary_op (insn, operands);"
1411990286Sobrien  [(set (attr "type") 
1412090286Sobrien        (if_then_else (match_operand:TF 3 "mult_operator" "") 
1412190286Sobrien           (const_string "fmul")
1412290286Sobrien           (const_string "fop")))
1412390286Sobrien   (set_attr "mode" "XF")])
1412418334Speter
1412590286Sobrien(define_insn "*fop_sf_1_nosse"
1412690286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
1412790286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1412890286Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "0,fm")
1412990286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
1413090286Sobrien  "TARGET_80387 && !TARGET_SSE_MATH
1413190286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
1413290286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1413390286Sobrien  "* return output_387_binary_op (insn, operands);"
1413490286Sobrien  [(set (attr "type") 
1413590286Sobrien        (cond [(match_operand:SF 3 "mult_operator" "") 
1413690286Sobrien                 (const_string "fmul")
1413790286Sobrien               (match_operand:SF 3 "div_operator" "") 
1413890286Sobrien                 (const_string "fdiv")
1413990286Sobrien              ]
1414090286Sobrien              (const_string "fop")))
1414190286Sobrien   (set_attr "mode" "SF")])
1414218334Speter
1414390286Sobrien(define_insn "*fop_sf_1"
1414490286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f,x")
1414590286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1414690286Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
1414790286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
1414890286Sobrien  "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
1414990286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
1415090286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1415190286Sobrien  "* return output_387_binary_op (insn, operands);"
1415290286Sobrien  [(set (attr "type") 
1415390286Sobrien        (cond [(eq_attr "alternative" "2")
1415490286Sobrien                 (const_string "sse")
1415590286Sobrien	       (match_operand:SF 3 "mult_operator" "") 
1415690286Sobrien                 (const_string "fmul")
1415790286Sobrien               (match_operand:SF 3 "div_operator" "") 
1415890286Sobrien                 (const_string "fdiv")
1415990286Sobrien              ]
1416090286Sobrien              (const_string "fop")))
1416190286Sobrien   (set_attr "mode" "SF")])
1416218334Speter
1416390286Sobrien(define_insn "*fop_sf_1_sse"
1416490286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1416590286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1416690286Sobrien			[(match_operand:SF 1 "register_operand" "0")
1416790286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
1416890286Sobrien  "TARGET_SSE_MATH
1416990286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
1417090286Sobrien  "* return output_387_binary_op (insn, operands);"
1417190286Sobrien  [(set_attr "type" "sse")
1417290286Sobrien   (set_attr "mode" "SF")])
1417318334Speter
1417490286Sobrien;; ??? Add SSE splitters for these!
1417590286Sobrien(define_insn "*fop_sf_2"
1417690286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
1417790286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1417890286Sobrien	  [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
1417990286Sobrien	   (match_operand:SF 2 "register_operand" "0,0")]))]
1418090286Sobrien  "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
1418190286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1418290286Sobrien  [(set (attr "type") 
1418390286Sobrien        (cond [(match_operand:SF 3 "mult_operator" "") 
1418490286Sobrien                 (const_string "fmul")
1418590286Sobrien               (match_operand:SF 3 "div_operator" "") 
1418690286Sobrien                 (const_string "fdiv")
1418790286Sobrien              ]
1418890286Sobrien              (const_string "fop")))
1418990286Sobrien   (set_attr "fp_int_src" "true")
1419090286Sobrien   (set_attr "ppro_uops" "many")
1419190286Sobrien   (set_attr "mode" "SI")])
1419218334Speter
1419390286Sobrien(define_insn "*fop_sf_3"
1419490286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
1419590286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1419690286Sobrien	  [(match_operand:SF 1 "register_operand" "0,0")
1419790286Sobrien	   (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1419890286Sobrien  "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
1419990286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1420090286Sobrien  [(set (attr "type") 
1420190286Sobrien        (cond [(match_operand:SF 3 "mult_operator" "") 
1420290286Sobrien                 (const_string "fmul")
1420390286Sobrien               (match_operand:SF 3 "div_operator" "") 
1420490286Sobrien                 (const_string "fdiv")
1420590286Sobrien              ]
1420690286Sobrien              (const_string "fop")))
1420790286Sobrien   (set_attr "fp_int_src" "true")
1420890286Sobrien   (set_attr "ppro_uops" "many")
1420990286Sobrien   (set_attr "mode" "SI")])
1421018334Speter
1421190286Sobrien(define_insn "*fop_df_1_nosse"
1421290286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
1421390286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1421490286Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "0,fm")
1421590286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
1421690286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
1421790286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
1421890286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1421990286Sobrien  "* return output_387_binary_op (insn, operands);"
1422090286Sobrien  [(set (attr "type") 
1422190286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1422290286Sobrien                 (const_string "fmul")
1422390286Sobrien               (match_operand:DF 3 "div_operator" "") 
1422490286Sobrien                 (const_string "fdiv")
1422590286Sobrien              ]
1422690286Sobrien              (const_string "fop")))
1422790286Sobrien   (set_attr "mode" "DF")])
1422818334Speter
1422918334Speter
1423090286Sobrien(define_insn "*fop_df_1"
1423190286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
1423290286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1423390286Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
1423490286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
1423590286Sobrien  "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
1423690286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
1423790286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1423890286Sobrien  "* return output_387_binary_op (insn, operands);"
1423990286Sobrien  [(set (attr "type") 
1424090286Sobrien        (cond [(eq_attr "alternative" "2")
1424190286Sobrien                 (const_string "sse")
1424290286Sobrien	       (match_operand:DF 3 "mult_operator" "") 
1424390286Sobrien                 (const_string "fmul")
1424490286Sobrien               (match_operand:DF 3 "div_operator" "") 
1424590286Sobrien                 (const_string "fdiv")
1424690286Sobrien              ]
1424790286Sobrien              (const_string "fop")))
1424890286Sobrien   (set_attr "mode" "DF")])
1424918334Speter
1425090286Sobrien(define_insn "*fop_df_1_sse"
1425190286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1425290286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1425390286Sobrien			[(match_operand:DF 1 "register_operand" "0")
1425490286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
1425590286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH
1425690286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
1425790286Sobrien  "* return output_387_binary_op (insn, operands);"
1425890286Sobrien  [(set_attr "type" "sse")])
1425918334Speter
1426090286Sobrien;; ??? Add SSE splitters for these!
1426190286Sobrien(define_insn "*fop_df_2"
1426290286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
1426390286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1426490286Sobrien	   [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
1426590286Sobrien	    (match_operand:DF 2 "register_operand" "0,0")]))]
1426690286Sobrien  "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
1426790286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1426890286Sobrien  [(set (attr "type") 
1426990286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1427090286Sobrien                 (const_string "fmul")
1427190286Sobrien               (match_operand:DF 3 "div_operator" "") 
1427290286Sobrien                 (const_string "fdiv")
1427390286Sobrien              ]
1427490286Sobrien              (const_string "fop")))
1427590286Sobrien   (set_attr "fp_int_src" "true")
1427690286Sobrien   (set_attr "ppro_uops" "many")
1427790286Sobrien   (set_attr "mode" "SI")])
1427818334Speter
1427990286Sobrien(define_insn "*fop_df_3"
1428090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
1428190286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1428290286Sobrien	   [(match_operand:DF 1 "register_operand" "0,0")
1428390286Sobrien	    (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1428490286Sobrien  "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
1428590286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1428690286Sobrien  [(set (attr "type") 
1428790286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1428890286Sobrien                 (const_string "fmul")
1428990286Sobrien               (match_operand:DF 3 "div_operator" "") 
1429090286Sobrien                 (const_string "fdiv")
1429190286Sobrien              ]
1429290286Sobrien              (const_string "fop")))
1429390286Sobrien   (set_attr "fp_int_src" "true")
1429490286Sobrien   (set_attr "ppro_uops" "many")
1429590286Sobrien   (set_attr "mode" "SI")])
1429618334Speter
1429790286Sobrien(define_insn "*fop_df_4"
1429890286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
1429990286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1430090286Sobrien	   [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
1430190286Sobrien	    (match_operand:DF 2 "register_operand" "0,f")]))]
1430290286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
1430390286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1430490286Sobrien  "* return output_387_binary_op (insn, operands);"
1430590286Sobrien  [(set (attr "type") 
1430690286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1430790286Sobrien                 (const_string "fmul")
1430890286Sobrien               (match_operand:DF 3 "div_operator" "") 
1430990286Sobrien                 (const_string "fdiv")
1431090286Sobrien              ]
1431190286Sobrien              (const_string "fop")))
1431290286Sobrien   (set_attr "mode" "SF")])
1431318334Speter
1431490286Sobrien(define_insn "*fop_df_5"
1431518334Speter  [(set (match_operand:DF 0 "register_operand" "=f,f")
1431690286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1431790286Sobrien	  [(match_operand:DF 1 "register_operand" "0,f")
1431890286Sobrien	   (float_extend:DF
1431990286Sobrien	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
1432090286Sobrien  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
1432150650Sobrien  "* return output_387_binary_op (insn, operands);"
1432250650Sobrien  [(set (attr "type") 
1432390286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1432490286Sobrien                 (const_string "fmul")
1432590286Sobrien               (match_operand:DF 3 "div_operator" "") 
1432690286Sobrien                 (const_string "fdiv")
1432750650Sobrien              ]
1432890286Sobrien              (const_string "fop")))
1432990286Sobrien   (set_attr "mode" "SF")])
1433018334Speter
1433190286Sobrien(define_insn "*fop_xf_1"
1433218334Speter  [(set (match_operand:XF 0 "register_operand" "=f,f")
1433390286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1433450650Sobrien			[(match_operand:XF 1 "register_operand" "0,f")
1433550650Sobrien			 (match_operand:XF 2 "register_operand" "f,0")]))]
1433690286Sobrien  "!TARGET_64BIT && TARGET_80387
1433790286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
1433850650Sobrien  "* return output_387_binary_op (insn, operands);"
1433950650Sobrien  [(set (attr "type") 
1434090286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1434190286Sobrien                 (const_string "fmul")
1434290286Sobrien               (match_operand:XF 3 "div_operator" "") 
1434390286Sobrien                 (const_string "fdiv")
1434450650Sobrien              ]
1434590286Sobrien              (const_string "fop")))
1434690286Sobrien   (set_attr "mode" "XF")])
1434718334Speter
1434890286Sobrien(define_insn "*fop_tf_1"
1434990286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1435090286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1435190286Sobrien			[(match_operand:TF 1 "register_operand" "0,f")
1435290286Sobrien			 (match_operand:TF 2 "register_operand" "f,0")]))]
1435390286Sobrien  "TARGET_80387
1435490286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
1435590286Sobrien  "* return output_387_binary_op (insn, operands);"
1435690286Sobrien  [(set (attr "type") 
1435790286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1435890286Sobrien                 (const_string "fmul")
1435990286Sobrien               (match_operand:TF 3 "div_operator" "") 
1436090286Sobrien                 (const_string "fdiv")
1436190286Sobrien              ]
1436290286Sobrien              (const_string "fop")))
1436390286Sobrien   (set_attr "mode" "XF")])
1436490286Sobrien
1436590286Sobrien(define_insn "*fop_xf_2"
1436618334Speter  [(set (match_operand:XF 0 "register_operand" "=f,f")
1436790286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1436890286Sobrien	   [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
1436990286Sobrien	    (match_operand:XF 2 "register_operand" "0,0")]))]
1437090286Sobrien  "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
1437190286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1437290286Sobrien  [(set (attr "type") 
1437390286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1437490286Sobrien                 (const_string "fmul")
1437590286Sobrien               (match_operand:XF 3 "div_operator" "") 
1437690286Sobrien                 (const_string "fdiv")
1437790286Sobrien              ]
1437890286Sobrien              (const_string "fop")))
1437990286Sobrien   (set_attr "fp_int_src" "true")
1438090286Sobrien   (set_attr "mode" "SI")
1438190286Sobrien   (set_attr "ppro_uops" "many")])
1438290286Sobrien
1438390286Sobrien(define_insn "*fop_tf_2"
1438490286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1438590286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1438690286Sobrien	   [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
1438790286Sobrien	    (match_operand:TF 2 "register_operand" "0,0")]))]
1438890286Sobrien  "TARGET_80387 && TARGET_USE_FIOP"
1438990286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1439090286Sobrien  [(set (attr "type") 
1439190286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1439290286Sobrien                 (const_string "fmul")
1439390286Sobrien               (match_operand:TF 3 "div_operator" "") 
1439490286Sobrien                 (const_string "fdiv")
1439590286Sobrien              ]
1439690286Sobrien              (const_string "fop")))
1439790286Sobrien   (set_attr "fp_int_src" "true")
1439890286Sobrien   (set_attr "mode" "SI")
1439990286Sobrien   (set_attr "ppro_uops" "many")])
1440090286Sobrien
1440190286Sobrien(define_insn "*fop_xf_3"
1440290286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1440390286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1440490286Sobrien	  [(match_operand:XF 1 "register_operand" "0,0")
1440590286Sobrien	   (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1440690286Sobrien  "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
1440790286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1440890286Sobrien  [(set (attr "type") 
1440990286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1441090286Sobrien                 (const_string "fmul")
1441190286Sobrien               (match_operand:XF 3 "div_operator" "") 
1441290286Sobrien                 (const_string "fdiv")
1441390286Sobrien              ]
1441490286Sobrien              (const_string "fop")))
1441590286Sobrien   (set_attr "fp_int_src" "true")
1441690286Sobrien   (set_attr "mode" "SI")
1441790286Sobrien   (set_attr "ppro_uops" "many")])
1441890286Sobrien
1441990286Sobrien(define_insn "*fop_tf_3"
1442090286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1442190286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1442290286Sobrien	  [(match_operand:TF 1 "register_operand" "0,0")
1442390286Sobrien	   (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1442490286Sobrien  "TARGET_80387 && TARGET_USE_FIOP"
1442590286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1442690286Sobrien  [(set (attr "type") 
1442790286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1442890286Sobrien                 (const_string "fmul")
1442990286Sobrien               (match_operand:TF 3 "div_operator" "") 
1443090286Sobrien                 (const_string "fdiv")
1443190286Sobrien              ]
1443290286Sobrien              (const_string "fop")))
1443390286Sobrien   (set_attr "fp_int_src" "true")
1443490286Sobrien   (set_attr "mode" "SI")
1443590286Sobrien   (set_attr "ppro_uops" "many")])
1443690286Sobrien
1443790286Sobrien(define_insn "*fop_xf_4"
1443890286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1443990286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1444050650Sobrien	   [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
1444150650Sobrien	    (match_operand:XF 2 "register_operand" "0,f")]))]
1444290286Sobrien  "!TARGET_64BIT && TARGET_80387"
1444390286Sobrien  "* return output_387_binary_op (insn, operands);"
1444490286Sobrien  [(set (attr "type") 
1444590286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1444690286Sobrien                 (const_string "fmul")
1444790286Sobrien               (match_operand:XF 3 "div_operator" "") 
1444890286Sobrien                 (const_string "fdiv")
1444990286Sobrien              ]
1445090286Sobrien              (const_string "fop")))
1445190286Sobrien   (set_attr "mode" "SF")])
1445290286Sobrien
1445390286Sobrien(define_insn "*fop_tf_4"
1445490286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1445590286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1445690286Sobrien	   [(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
1445790286Sobrien	    (match_operand:TF 2 "register_operand" "0,f")]))]
1445818334Speter  "TARGET_80387"
1445950650Sobrien  "* return output_387_binary_op (insn, operands);"
1446050650Sobrien  [(set (attr "type") 
1446190286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1446290286Sobrien                 (const_string "fmul")
1446390286Sobrien               (match_operand:TF 3 "div_operator" "") 
1446490286Sobrien                 (const_string "fdiv")
1446550650Sobrien              ]
1446690286Sobrien              (const_string "fop")))
1446790286Sobrien   (set_attr "mode" "SF")])
1446818334Speter
1446990286Sobrien(define_insn "*fop_xf_5"
1447018334Speter  [(set (match_operand:XF 0 "register_operand" "=f,f")
1447190286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1447250650Sobrien	  [(match_operand:XF 1 "register_operand" "0,f")
1447318334Speter	   (float_extend:XF
1447450650Sobrien	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
1447590286Sobrien  "!TARGET_64BIT && TARGET_80387"
1447650650Sobrien  "* return output_387_binary_op (insn, operands);"
1447750650Sobrien  [(set (attr "type") 
1447890286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1447990286Sobrien                 (const_string "fmul")
1448090286Sobrien               (match_operand:XF 3 "div_operator" "") 
1448190286Sobrien                 (const_string "fdiv")
1448250650Sobrien              ]
1448390286Sobrien              (const_string "fop")))
1448490286Sobrien   (set_attr "mode" "SF")])
1448518334Speter
1448690286Sobrien(define_insn "*fop_tf_5"
1448790286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1448890286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1448990286Sobrien	  [(match_operand:TF 1 "register_operand" "0,f")
1449090286Sobrien	   (float_extend:TF
1449190286Sobrien	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
1449218334Speter  "TARGET_80387"
1449350650Sobrien  "* return output_387_binary_op (insn, operands);"
1449450650Sobrien  [(set (attr "type") 
1449590286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1449690286Sobrien                 (const_string "fmul")
1449790286Sobrien               (match_operand:TF 3 "div_operator" "") 
1449890286Sobrien                 (const_string "fdiv")
1449950650Sobrien              ]
1450090286Sobrien              (const_string "fop")))
1450190286Sobrien   (set_attr "mode" "SF")])
1450218334Speter
1450390286Sobrien(define_insn "*fop_xf_6"
1450490286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1450590286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1450690286Sobrien	   [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
1450790286Sobrien	    (match_operand:XF 2 "register_operand" "0,f")]))]
1450890286Sobrien  "!TARGET_64BIT && TARGET_80387"
1450990286Sobrien  "* return output_387_binary_op (insn, operands);"
1451090286Sobrien  [(set (attr "type") 
1451190286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1451290286Sobrien                 (const_string "fmul")
1451390286Sobrien               (match_operand:XF 3 "div_operator" "") 
1451490286Sobrien                 (const_string "fdiv")
1451590286Sobrien              ]
1451690286Sobrien              (const_string "fop")))
1451790286Sobrien   (set_attr "mode" "DF")])
1451890286Sobrien
1451990286Sobrien(define_insn "*fop_tf_6"
1452090286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1452190286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1452290286Sobrien	   [(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
1452390286Sobrien	    (match_operand:TF 2 "register_operand" "0,f")]))]
1452418334Speter  "TARGET_80387"
1452550650Sobrien  "* return output_387_binary_op (insn, operands);"
1452650650Sobrien  [(set (attr "type") 
1452790286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1452890286Sobrien                 (const_string "fmul")
1452990286Sobrien               (match_operand:TF 3 "div_operator" "") 
1453090286Sobrien                 (const_string "fdiv")
1453150650Sobrien              ]
1453290286Sobrien              (const_string "fop")))
1453390286Sobrien   (set_attr "mode" "DF")])
1453418334Speter
1453590286Sobrien(define_insn "*fop_xf_7"
1453690286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1453790286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1453890286Sobrien	  [(match_operand:XF 1 "register_operand" "0,f")
1453990286Sobrien	   (float_extend:XF
1454090286Sobrien	    (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
1454190286Sobrien  "!TARGET_64BIT && TARGET_80387"
1454290286Sobrien  "* return output_387_binary_op (insn, operands);"
1454390286Sobrien  [(set (attr "type") 
1454490286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1454590286Sobrien                 (const_string "fmul")
1454690286Sobrien               (match_operand:XF 3 "div_operator" "") 
1454790286Sobrien                 (const_string "fdiv")
1454890286Sobrien              ]
1454990286Sobrien              (const_string "fop")))
1455090286Sobrien   (set_attr "mode" "DF")])
1455190286Sobrien
1455290286Sobrien(define_insn "*fop_tf_7"
1455390286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1455490286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1455590286Sobrien	  [(match_operand:TF 1 "register_operand" "0,f")
1455690286Sobrien	   (float_extend:TF
1455790286Sobrien	    (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
1455818334Speter  "TARGET_80387"
1455950650Sobrien  "* return output_387_binary_op (insn, operands);"
1456050650Sobrien  [(set (attr "type") 
1456190286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1456290286Sobrien                 (const_string "fmul")
1456390286Sobrien               (match_operand:TF 3 "div_operator" "") 
1456490286Sobrien                 (const_string "fdiv")
1456550650Sobrien              ]
1456690286Sobrien              (const_string "fop")))
1456790286Sobrien   (set_attr "mode" "DF")])
1456890286Sobrien
1456990286Sobrien(define_split
1457090286Sobrien  [(set (match_operand 0 "register_operand" "")
1457190286Sobrien	(match_operator 3 "binary_fp_operator"
1457290286Sobrien	   [(float (match_operand:SI 1 "register_operand" ""))
1457390286Sobrien	    (match_operand 2 "register_operand" "")]))]
1457490286Sobrien  "TARGET_80387 && reload_completed
1457590286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))"
1457690286Sobrien  [(const_int 0)]
1457790286Sobrien{ 
1457890286Sobrien  operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
1457990286Sobrien  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
1458090286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
1458190286Sobrien			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
1458290286Sobrien					  GET_MODE (operands[3]),
1458390286Sobrien					  operands[4],
1458490286Sobrien					  operands[2])));
1458590286Sobrien  ix86_free_from_memory (GET_MODE (operands[1]));
1458690286Sobrien  DONE;
1458790286Sobrien})
1458890286Sobrien
1458990286Sobrien(define_split
1459090286Sobrien  [(set (match_operand 0 "register_operand" "")
1459190286Sobrien	(match_operator 3 "binary_fp_operator"
1459290286Sobrien	   [(match_operand 1 "register_operand" "")
1459390286Sobrien	    (float (match_operand:SI 2 "register_operand" ""))]))]
1459490286Sobrien  "TARGET_80387 && reload_completed
1459590286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))"
1459690286Sobrien  [(const_int 0)]
1459790286Sobrien{
1459890286Sobrien  operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
1459990286Sobrien  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
1460090286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
1460190286Sobrien			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
1460290286Sobrien					  GET_MODE (operands[3]),
1460390286Sobrien					  operands[1],
1460490286Sobrien					  operands[4])));
1460590286Sobrien  ix86_free_from_memory (GET_MODE (operands[2]));
1460690286Sobrien  DONE;
1460790286Sobrien})
1460818334Speter
1460990286Sobrien;; FPU special functions.
1461090286Sobrien
1461190286Sobrien(define_expand "sqrtsf2"
1461290286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1461390286Sobrien	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
1461490286Sobrien  "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
1461590286Sobrien{
1461690286Sobrien  if (!TARGET_SSE_MATH)
1461790286Sobrien    operands[1] = force_reg (SFmode, operands[1]);
1461890286Sobrien})
1461990286Sobrien
1462090286Sobrien(define_insn "sqrtsf2_1"
1462190286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
1462290286Sobrien	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
1462390286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1462490286Sobrien   && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
1462590286Sobrien  "@
1462690286Sobrien   fsqrt
1462790286Sobrien   sqrtss\t{%1, %0|%0, %1}"
1462890286Sobrien  [(set_attr "type" "fpspc,sse")
1462990286Sobrien   (set_attr "mode" "SF,SF")
1463090286Sobrien   (set_attr "athlon_decode" "direct,*")])
1463190286Sobrien
1463290286Sobrien(define_insn "sqrtsf2_1_sse_only"
1463390286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1463490286Sobrien	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
1463590286Sobrien  "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
1463690286Sobrien  "sqrtss\t{%1, %0|%0, %1}"
1463790286Sobrien  [(set_attr "type" "sse")
1463890286Sobrien   (set_attr "mode" "SF")
1463990286Sobrien   (set_attr "athlon_decode" "*")])
1464090286Sobrien
1464190286Sobrien(define_insn "sqrtsf2_i387"
1464290286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
1464390286Sobrien	(sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
1464490286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1464590286Sobrien   && !TARGET_SSE_MATH"
1464690286Sobrien  "fsqrt"
1464790286Sobrien  [(set_attr "type" "fpspc")
1464890286Sobrien   (set_attr "mode" "SF")
1464990286Sobrien   (set_attr "athlon_decode" "direct")])
1465090286Sobrien
1465190286Sobrien(define_expand "sqrtdf2"
1465290286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1465390286Sobrien	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
1465490286Sobrien  "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
1465590286Sobrien   || (TARGET_SSE2 && TARGET_SSE_MATH)"
1465690286Sobrien{
1465790286Sobrien  if (!TARGET_SSE2 || !TARGET_SSE_MATH)
1465890286Sobrien    operands[1] = force_reg (DFmode, operands[1]);
1465990286Sobrien})
1466090286Sobrien
1466190286Sobrien(define_insn "sqrtdf2_1"
1466290286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
1466390286Sobrien	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
1466490286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1466590286Sobrien   && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
1466690286Sobrien  "@
1466790286Sobrien   fsqrt
1466890286Sobrien   sqrtsd\t{%1, %0|%0, %1}"
1466990286Sobrien  [(set_attr "type" "fpspc,sse")
1467090286Sobrien   (set_attr "mode" "DF,DF")
1467190286Sobrien   (set_attr "athlon_decode" "direct,*")])
1467290286Sobrien
1467390286Sobrien(define_insn "sqrtdf2_1_sse_only"
1467490286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1467590286Sobrien	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
1467690286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
1467790286Sobrien  "sqrtsd\t{%1, %0|%0, %1}"
1467890286Sobrien  [(set_attr "type" "sse")
1467990286Sobrien   (set_attr "mode" "DF")
1468090286Sobrien   (set_attr "athlon_decode" "*")])
1468190286Sobrien
1468290286Sobrien(define_insn "sqrtdf2_i387"
1468390286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1468490286Sobrien	(sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
1468590286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1468690286Sobrien   && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
1468790286Sobrien  "fsqrt"
1468890286Sobrien  [(set_attr "type" "fpspc")
1468990286Sobrien   (set_attr "mode" "DF")
1469090286Sobrien   (set_attr "athlon_decode" "direct")])
1469190286Sobrien
1469290286Sobrien(define_insn "*sqrtextendsfdf2"
1469390286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1469490286Sobrien	(sqrt:DF (float_extend:DF
1469590286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
1469690286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1469790286Sobrien   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
1469890286Sobrien  "fsqrt"
1469990286Sobrien  [(set_attr "type" "fpspc")
1470090286Sobrien   (set_attr "mode" "DF")
1470190286Sobrien   (set_attr "athlon_decode" "direct")])
1470290286Sobrien
1470390286Sobrien(define_insn "sqrtxf2"
1470490286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1470590286Sobrien	(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
1470690286Sobrien  "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
1470790286Sobrien   && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
1470890286Sobrien  "fsqrt"
1470990286Sobrien  [(set_attr "type" "fpspc")
1471090286Sobrien   (set_attr "mode" "XF")
1471190286Sobrien   (set_attr "athlon_decode" "direct")])
1471290286Sobrien
1471390286Sobrien(define_insn "sqrttf2"
1471490286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1471590286Sobrien	(sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
1471690286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1471790286Sobrien   && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
1471890286Sobrien  "fsqrt"
1471990286Sobrien  [(set_attr "type" "fpspc")
1472090286Sobrien   (set_attr "mode" "XF")
1472190286Sobrien   (set_attr "athlon_decode" "direct")])
1472290286Sobrien
1472390286Sobrien(define_insn "*sqrtextenddfxf2"
1472490286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1472590286Sobrien	(sqrt:XF (float_extend:XF
1472690286Sobrien		  (match_operand:DF 1 "register_operand" "0"))))]
1472796294Sobrien  "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
1472890286Sobrien  "fsqrt"
1472990286Sobrien  [(set_attr "type" "fpspc")
1473090286Sobrien   (set_attr "mode" "XF")
1473190286Sobrien   (set_attr "athlon_decode" "direct")])
1473290286Sobrien
1473390286Sobrien(define_insn "*sqrtextenddftf2"
1473490286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1473590286Sobrien	(sqrt:TF (float_extend:TF
1473690286Sobrien		  (match_operand:DF 1 "register_operand" "0"))))]
1473790286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
1473890286Sobrien  "fsqrt"
1473990286Sobrien  [(set_attr "type" "fpspc")
1474090286Sobrien   (set_attr "mode" "XF")
1474190286Sobrien   (set_attr "athlon_decode" "direct")])
1474290286Sobrien
1474390286Sobrien(define_insn "*sqrtextendsfxf2"
1474490286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1474590286Sobrien	(sqrt:XF (float_extend:XF
1474690286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
1474796294Sobrien  "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
1474890286Sobrien  "fsqrt"
1474990286Sobrien  [(set_attr "type" "fpspc")
1475090286Sobrien   (set_attr "mode" "XF")
1475190286Sobrien   (set_attr "athlon_decode" "direct")])
1475290286Sobrien
1475390286Sobrien(define_insn "*sqrtextendsftf2"
1475490286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1475590286Sobrien	(sqrt:TF (float_extend:TF
1475690286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
1475790286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
1475890286Sobrien  "fsqrt"
1475990286Sobrien  [(set_attr "type" "fpspc")
1476090286Sobrien   (set_attr "mode" "XF")
1476190286Sobrien   (set_attr "athlon_decode" "direct")])
1476290286Sobrien
1476390286Sobrien(define_insn "sindf2"
1476490286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1476590286Sobrien	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
1476690286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1476790286Sobrien   && flag_unsafe_math_optimizations"
1476890286Sobrien  "fsin"
1476990286Sobrien  [(set_attr "type" "fpspc")
1477090286Sobrien   (set_attr "mode" "DF")])
1477190286Sobrien
1477290286Sobrien(define_insn "sinsf2"
1477390286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
1477490286Sobrien	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
1477590286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1477690286Sobrien   && flag_unsafe_math_optimizations"
1477790286Sobrien  "fsin"
1477890286Sobrien  [(set_attr "type" "fpspc")
1477990286Sobrien   (set_attr "mode" "SF")])
1478090286Sobrien
1478190286Sobrien(define_insn "*sinextendsfdf2"
1478290286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1478390286Sobrien	(unspec:DF [(float_extend:DF
1478490286Sobrien		     (match_operand:SF 1 "register_operand" "0"))] 1))]
1478590286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1478690286Sobrien   && flag_unsafe_math_optimizations"
1478790286Sobrien  "fsin"
1478890286Sobrien  [(set_attr "type" "fpspc")
1478990286Sobrien   (set_attr "mode" "DF")])
1479090286Sobrien
1479190286Sobrien(define_insn "sinxf2"
1479290286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1479390286Sobrien	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
1479496294Sobrien  "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
1479590286Sobrien   && flag_unsafe_math_optimizations"
1479690286Sobrien  "fsin"
1479790286Sobrien  [(set_attr "type" "fpspc")
1479890286Sobrien   (set_attr "mode" "XF")])
1479990286Sobrien
1480090286Sobrien(define_insn "sintf2"
1480190286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1480290286Sobrien	(unspec:TF [(match_operand:TF 1 "register_operand" "0")] 1))]
1480390286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1480490286Sobrien   && flag_unsafe_math_optimizations"
1480590286Sobrien  "fsin"
1480690286Sobrien  [(set_attr "type" "fpspc")
1480790286Sobrien   (set_attr "mode" "XF")])
1480890286Sobrien
1480990286Sobrien(define_insn "cosdf2"
1481090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1481190286Sobrien	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
1481290286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1481390286Sobrien   && flag_unsafe_math_optimizations"
1481490286Sobrien  "fcos"
1481590286Sobrien  [(set_attr "type" "fpspc")
1481690286Sobrien   (set_attr "mode" "DF")])
1481790286Sobrien
1481890286Sobrien(define_insn "cossf2"
1481990286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
1482090286Sobrien	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
1482190286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1482290286Sobrien   && flag_unsafe_math_optimizations"
1482390286Sobrien  "fcos"
1482490286Sobrien  [(set_attr "type" "fpspc")
1482590286Sobrien   (set_attr "mode" "SF")])
1482690286Sobrien
1482790286Sobrien(define_insn "*cosextendsfdf2"
1482890286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1482990286Sobrien	(unspec:DF [(float_extend:DF
1483090286Sobrien		     (match_operand:SF 1 "register_operand" "0"))] 2))]
1483190286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1483290286Sobrien   && flag_unsafe_math_optimizations"
1483390286Sobrien  "fcos"
1483490286Sobrien  [(set_attr "type" "fpspc")
1483590286Sobrien   (set_attr "mode" "DF")])
1483690286Sobrien
1483790286Sobrien(define_insn "cosxf2"
1483890286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1483990286Sobrien	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
1484090286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1484190286Sobrien   && flag_unsafe_math_optimizations"
1484290286Sobrien  "fcos"
1484390286Sobrien  [(set_attr "type" "fpspc")
1484490286Sobrien   (set_attr "mode" "XF")])
1484590286Sobrien
1484690286Sobrien(define_insn "costf2"
1484790286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1484890286Sobrien	(unspec:TF [(match_operand:TF 1 "register_operand" "0")] 2))]
1484990286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1485090286Sobrien   && flag_unsafe_math_optimizations"
1485190286Sobrien  "fcos"
1485290286Sobrien  [(set_attr "type" "fpspc")
1485390286Sobrien   (set_attr "mode" "XF")])
1485490286Sobrien
1485590286Sobrien;; Block operation instructions
1485690286Sobrien
1485790286Sobrien(define_insn "cld"
1485890286Sobrien [(set (reg:SI 19) (const_int 0))]
1485990286Sobrien ""
1486090286Sobrien "cld"
1486190286Sobrien  [(set_attr "type" "cld")])
1486290286Sobrien
1486390286Sobrien(define_expand "movstrsi"
1486490286Sobrien  [(use (match_operand:BLK 0 "memory_operand" ""))
1486590286Sobrien   (use (match_operand:BLK 1 "memory_operand" ""))
1486690286Sobrien   (use (match_operand:SI 2 "nonmemory_operand" ""))
1486790286Sobrien   (use (match_operand:SI 3 "const_int_operand" ""))]
1486818334Speter  ""
1486918334Speter{
1487090286Sobrien if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
1487190286Sobrien   DONE;
1487290286Sobrien else
1487390286Sobrien   FAIL;
1487490286Sobrien})
1487590286Sobrien
1487690286Sobrien(define_expand "movstrdi"
1487790286Sobrien  [(use (match_operand:BLK 0 "memory_operand" ""))
1487890286Sobrien   (use (match_operand:BLK 1 "memory_operand" ""))
1487990286Sobrien   (use (match_operand:DI 2 "nonmemory_operand" ""))
1488090286Sobrien   (use (match_operand:DI 3 "const_int_operand" ""))]
1488190286Sobrien  "TARGET_64BIT"
1488290286Sobrien{
1488390286Sobrien if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
1488490286Sobrien   DONE;
1488590286Sobrien else
1488690286Sobrien   FAIL;
1488790286Sobrien})
1488890286Sobrien
1488990286Sobrien;; Most CPUs don't like single string operations
1489090286Sobrien;; Handle this case here to simplify previous expander.
1489190286Sobrien
1489290286Sobrien(define_expand "strmovdi_rex64"
1489390286Sobrien  [(set (match_dup 2)
1489490286Sobrien  	(mem:DI (match_operand:DI 1 "register_operand" "")))
1489590286Sobrien   (set (mem:DI (match_operand:DI 0 "register_operand" ""))
1489690286Sobrien        (match_dup 2))
1489790286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
1489890286Sobrien	      (clobber (reg:CC 17))])
1489990286Sobrien   (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
1490090286Sobrien	      (clobber (reg:CC 17))])]
1490190286Sobrien  "TARGET_64BIT"
1490290286Sobrien{
1490390286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1490450650Sobrien    {
1490590286Sobrien      emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
1490690286Sobrien				     operands[1]));
1490790286Sobrien      DONE;
1490890286Sobrien    }
1490990286Sobrien  else 
1491090286Sobrien    operands[2] = gen_reg_rtx (DImode);
1491190286Sobrien})
1491250650Sobrien
1491350650Sobrien
1491490286Sobrien(define_expand "strmovsi"
1491590286Sobrien  [(set (match_dup 2)
1491690286Sobrien  	(mem:SI (match_operand:SI 1 "register_operand" "")))
1491790286Sobrien   (set (mem:SI (match_operand:SI 0 "register_operand" ""))
1491890286Sobrien        (match_dup 2))
1491990286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
1492090286Sobrien	      (clobber (reg:CC 17))])
1492190286Sobrien   (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
1492290286Sobrien	      (clobber (reg:CC 17))])]
1492390286Sobrien  ""
1492490286Sobrien{
1492590286Sobrien  if (TARGET_64BIT)
1492690286Sobrien    {
1492790286Sobrien      emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
1492890286Sobrien      DONE;
1492990286Sobrien    }
1493090286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1493190286Sobrien    {
1493290286Sobrien      emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
1493390286Sobrien				operands[1]));
1493490286Sobrien      DONE;
1493590286Sobrien    }
1493690286Sobrien  else 
1493790286Sobrien    operands[2] = gen_reg_rtx (SImode);
1493890286Sobrien})
1493950650Sobrien
1494090286Sobrien(define_expand "strmovsi_rex64"
1494190286Sobrien  [(set (match_dup 2)
1494290286Sobrien  	(mem:SI (match_operand:DI 1 "register_operand" "")))
1494390286Sobrien   (set (mem:SI (match_operand:DI 0 "register_operand" ""))
1494490286Sobrien        (match_dup 2))
1494590286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
1494690286Sobrien	      (clobber (reg:CC 17))])
1494790286Sobrien   (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
1494890286Sobrien	      (clobber (reg:CC 17))])]
1494990286Sobrien  "TARGET_64BIT"
1495090286Sobrien{
1495190286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1495290286Sobrien    {
1495390286Sobrien      emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
1495490286Sobrien				     operands[1]));
1495590286Sobrien      DONE;
1495690286Sobrien    }
1495790286Sobrien  else 
1495890286Sobrien    operands[2] = gen_reg_rtx (SImode);
1495990286Sobrien})
1496050650Sobrien
1496190286Sobrien(define_expand "strmovhi"
1496290286Sobrien  [(set (match_dup 2)
1496390286Sobrien  	(mem:HI (match_operand:SI 1 "register_operand" "")))
1496490286Sobrien   (set (mem:HI (match_operand:SI 0 "register_operand" ""))
1496590286Sobrien        (match_dup 2))
1496690286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
1496790286Sobrien	      (clobber (reg:CC 17))])
1496890286Sobrien   (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
1496990286Sobrien	      (clobber (reg:CC 17))])]
1497090286Sobrien  ""
1497190286Sobrien{
1497290286Sobrien  if (TARGET_64BIT)
1497390286Sobrien    {
1497490286Sobrien      emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
1497590286Sobrien      DONE;
1497690286Sobrien    }
1497790286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1497890286Sobrien    {
1497990286Sobrien      emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
1498090286Sobrien				operands[1]));
1498190286Sobrien      DONE;
1498290286Sobrien    }
1498390286Sobrien  else 
1498490286Sobrien    operands[2] = gen_reg_rtx (HImode);
1498590286Sobrien})
1498650650Sobrien
1498790286Sobrien(define_expand "strmovhi_rex64"
1498890286Sobrien  [(set (match_dup 2)
1498990286Sobrien  	(mem:HI (match_operand:DI 1 "register_operand" "")))
1499090286Sobrien   (set (mem:HI (match_operand:DI 0 "register_operand" ""))
1499190286Sobrien        (match_dup 2))
1499290286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
1499390286Sobrien	      (clobber (reg:CC 17))])
1499490286Sobrien   (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
1499590286Sobrien	      (clobber (reg:CC 17))])]
1499690286Sobrien  "TARGET_64BIT"
1499790286Sobrien{
1499890286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1499990286Sobrien    {
1500090286Sobrien      emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
1500190286Sobrien				     operands[1]));
1500250650Sobrien      DONE;
1500350650Sobrien    }
1500490286Sobrien  else 
1500590286Sobrien    operands[2] = gen_reg_rtx (HImode);
1500690286Sobrien})
1500750650Sobrien
1500890286Sobrien(define_expand "strmovqi"
1500990286Sobrien  [(set (match_dup 2)
1501090286Sobrien  	(mem:QI (match_operand:SI 1 "register_operand" "")))
1501190286Sobrien   (set (mem:QI (match_operand:SI 0 "register_operand" ""))
1501290286Sobrien        (match_dup 2))
1501390286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
1501490286Sobrien	      (clobber (reg:CC 17))])
1501590286Sobrien   (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
1501690286Sobrien	      (clobber (reg:CC 17))])]
1501790286Sobrien  ""
1501890286Sobrien{
1501990286Sobrien  if (TARGET_64BIT)
1502090286Sobrien    {
1502190286Sobrien      emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
1502290286Sobrien      DONE;
1502390286Sobrien    }
1502490286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1502590286Sobrien    {
1502690286Sobrien      emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
1502790286Sobrien				operands[1]));
1502890286Sobrien      DONE;
1502990286Sobrien    }
1503090286Sobrien  else 
1503190286Sobrien    operands[2] = gen_reg_rtx (QImode);
1503290286Sobrien})
1503318334Speter
1503490286Sobrien(define_expand "strmovqi_rex64"
1503590286Sobrien  [(set (match_dup 2)
1503690286Sobrien  	(mem:QI (match_operand:DI 1 "register_operand" "")))
1503790286Sobrien   (set (mem:QI (match_operand:DI 0 "register_operand" ""))
1503890286Sobrien        (match_dup 2))
1503990286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
1504090286Sobrien	      (clobber (reg:CC 17))])
1504190286Sobrien   (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
1504290286Sobrien	      (clobber (reg:CC 17))])]
1504390286Sobrien  "TARGET_64BIT"
1504490286Sobrien{
1504590286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1504690286Sobrien    {
1504790286Sobrien      emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
1504890286Sobrien				     operands[1]));
1504990286Sobrien      DONE;
1505090286Sobrien    }
1505190286Sobrien  else 
1505290286Sobrien    operands[2] = gen_reg_rtx (QImode);
1505390286Sobrien})
1505418334Speter
1505590286Sobrien(define_insn "strmovdi_rex_1"
1505690286Sobrien  [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
1505790286Sobrien	(mem:DI (match_operand:DI 3 "register_operand" "1")))
1505890286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1505990286Sobrien	(plus:DI (match_dup 2)
1506090286Sobrien		 (const_int 8)))
1506190286Sobrien   (set (match_operand:DI 1 "register_operand" "=S")
1506290286Sobrien	(plus:DI (match_dup 3)
1506390286Sobrien		 (const_int 8)))
1506490286Sobrien   (use (reg:SI 19))]
1506590286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1506690286Sobrien  "movsq"
1506790286Sobrien  [(set_attr "type" "str")
1506890286Sobrien   (set_attr "mode" "DI")
1506990286Sobrien   (set_attr "memory" "both")])
1507090286Sobrien
1507190286Sobrien(define_insn "strmovsi_1"
1507290286Sobrien  [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
1507390286Sobrien	(mem:SI (match_operand:SI 3 "register_operand" "1")))
1507490286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1507590286Sobrien	(plus:SI (match_dup 2)
1507690286Sobrien		 (const_int 4)))
1507790286Sobrien   (set (match_operand:SI 1 "register_operand" "=S")
1507890286Sobrien	(plus:SI (match_dup 3)
1507990286Sobrien		 (const_int 4)))
1508090286Sobrien   (use (reg:SI 19))]
1508190286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1508290286Sobrien  "{movsl|movsd}"
1508390286Sobrien  [(set_attr "type" "str")
1508490286Sobrien   (set_attr "mode" "SI")
1508590286Sobrien   (set_attr "memory" "both")])
1508690286Sobrien
1508790286Sobrien(define_insn "strmovsi_rex_1"
1508890286Sobrien  [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
1508990286Sobrien	(mem:SI (match_operand:DI 3 "register_operand" "1")))
1509090286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1509190286Sobrien	(plus:DI (match_dup 2)
1509290286Sobrien		 (const_int 4)))
1509390286Sobrien   (set (match_operand:DI 1 "register_operand" "=S")
1509490286Sobrien	(plus:DI (match_dup 3)
1509590286Sobrien		 (const_int 4)))
1509690286Sobrien   (use (reg:SI 19))]
1509790286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1509890286Sobrien  "{movsl|movsd}"
1509990286Sobrien  [(set_attr "type" "str")
1510090286Sobrien   (set_attr "mode" "SI")
1510190286Sobrien   (set_attr "memory" "both")])
1510290286Sobrien
1510390286Sobrien(define_insn "strmovhi_1"
1510490286Sobrien  [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
1510590286Sobrien	(mem:HI (match_operand:SI 3 "register_operand" "1")))
1510690286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1510790286Sobrien	(plus:SI (match_dup 2)
1510890286Sobrien		 (const_int 2)))
1510990286Sobrien   (set (match_operand:SI 1 "register_operand" "=S")
1511090286Sobrien	(plus:SI (match_dup 3)
1511190286Sobrien		 (const_int 2)))
1511290286Sobrien   (use (reg:SI 19))]
1511390286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1511490286Sobrien  "movsw"
1511590286Sobrien  [(set_attr "type" "str")
1511690286Sobrien   (set_attr "memory" "both")
1511790286Sobrien   (set_attr "mode" "HI")])
1511890286Sobrien
1511990286Sobrien(define_insn "strmovhi_rex_1"
1512090286Sobrien  [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
1512190286Sobrien	(mem:HI (match_operand:DI 3 "register_operand" "1")))
1512290286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1512390286Sobrien	(plus:DI (match_dup 2)
1512490286Sobrien		 (const_int 2)))
1512590286Sobrien   (set (match_operand:DI 1 "register_operand" "=S")
1512690286Sobrien	(plus:DI (match_dup 3)
1512790286Sobrien		 (const_int 2)))
1512890286Sobrien   (use (reg:SI 19))]
1512990286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1513090286Sobrien  "movsw"
1513190286Sobrien  [(set_attr "type" "str")
1513290286Sobrien   (set_attr "memory" "both")
1513390286Sobrien   (set_attr "mode" "HI")])
1513490286Sobrien
1513590286Sobrien(define_insn "strmovqi_1"
1513690286Sobrien  [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
1513790286Sobrien	(mem:QI (match_operand:SI 3 "register_operand" "1")))
1513890286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1513990286Sobrien	(plus:SI (match_dup 2)
1514090286Sobrien		 (const_int 1)))
1514190286Sobrien   (set (match_operand:SI 1 "register_operand" "=S")
1514290286Sobrien	(plus:SI (match_dup 3)
1514390286Sobrien		 (const_int 1)))
1514490286Sobrien   (use (reg:SI 19))]
1514590286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1514690286Sobrien  "movsb"
1514790286Sobrien  [(set_attr "type" "str")
1514890286Sobrien   (set_attr "memory" "both")
1514990286Sobrien   (set_attr "mode" "QI")])
1515090286Sobrien
1515190286Sobrien(define_insn "strmovqi_rex_1"
1515290286Sobrien  [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
1515390286Sobrien	(mem:QI (match_operand:DI 3 "register_operand" "1")))
1515490286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1515590286Sobrien	(plus:DI (match_dup 2)
1515690286Sobrien		 (const_int 1)))
1515790286Sobrien   (set (match_operand:DI 1 "register_operand" "=S")
1515890286Sobrien	(plus:DI (match_dup 3)
1515990286Sobrien		 (const_int 1)))
1516090286Sobrien   (use (reg:SI 19))]
1516190286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1516290286Sobrien  "movsb"
1516390286Sobrien  [(set_attr "type" "str")
1516490286Sobrien   (set_attr "memory" "both")
1516590286Sobrien   (set_attr "mode" "QI")])
1516690286Sobrien
1516790286Sobrien(define_insn "rep_movdi_rex64"
1516890286Sobrien  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
1516990286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1517090286Sobrien        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
1517190286Sobrien			    (const_int 3))
1517290286Sobrien		 (match_operand:DI 3 "register_operand" "0")))
1517390286Sobrien   (set (match_operand:DI 1 "register_operand" "=S") 
1517490286Sobrien        (plus:DI (ashift:DI (match_dup 5) (const_int 3))
1517590286Sobrien		 (match_operand:DI 4 "register_operand" "1")))
1517690286Sobrien   (set (mem:BLK (match_dup 3))
1517790286Sobrien	(mem:BLK (match_dup 4)))
1517890286Sobrien   (use (match_dup 5))
1517990286Sobrien   (use (reg:SI 19))]
1518090286Sobrien  "TARGET_64BIT"
1518190286Sobrien  "{rep\;movsq|rep movsq}"
1518290286Sobrien  [(set_attr "type" "str")
1518390286Sobrien   (set_attr "prefix_rep" "1")
1518490286Sobrien   (set_attr "memory" "both")
1518590286Sobrien   (set_attr "mode" "DI")])
1518690286Sobrien
1518790286Sobrien(define_insn "rep_movsi"
1518890286Sobrien  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
1518990286Sobrien   (set (match_operand:SI 0 "register_operand" "=D") 
1519090286Sobrien        (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
1519190286Sobrien			    (const_int 2))
1519290286Sobrien		 (match_operand:SI 3 "register_operand" "0")))
1519390286Sobrien   (set (match_operand:SI 1 "register_operand" "=S") 
1519490286Sobrien        (plus:SI (ashift:SI (match_dup 5) (const_int 2))
1519590286Sobrien		 (match_operand:SI 4 "register_operand" "1")))
1519690286Sobrien   (set (mem:BLK (match_dup 3))
1519790286Sobrien	(mem:BLK (match_dup 4)))
1519890286Sobrien   (use (match_dup 5))
1519990286Sobrien   (use (reg:SI 19))]
1520090286Sobrien  "!TARGET_64BIT"
1520190286Sobrien  "{rep\;movsl|rep movsd}"
1520290286Sobrien  [(set_attr "type" "str")
1520390286Sobrien   (set_attr "prefix_rep" "1")
1520490286Sobrien   (set_attr "memory" "both")
1520590286Sobrien   (set_attr "mode" "SI")])
1520690286Sobrien
1520790286Sobrien(define_insn "rep_movsi_rex64"
1520890286Sobrien  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
1520990286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1521090286Sobrien        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
1521190286Sobrien			    (const_int 2))
1521290286Sobrien		 (match_operand:DI 3 "register_operand" "0")))
1521390286Sobrien   (set (match_operand:DI 1 "register_operand" "=S") 
1521490286Sobrien        (plus:DI (ashift:DI (match_dup 5) (const_int 2))
1521590286Sobrien		 (match_operand:DI 4 "register_operand" "1")))
1521690286Sobrien   (set (mem:BLK (match_dup 3))
1521790286Sobrien	(mem:BLK (match_dup 4)))
1521890286Sobrien   (use (match_dup 5))
1521990286Sobrien   (use (reg:SI 19))]
1522090286Sobrien  "TARGET_64BIT"
1522190286Sobrien  "{rep\;movsl|rep movsd}"
1522290286Sobrien  [(set_attr "type" "str")
1522390286Sobrien   (set_attr "prefix_rep" "1")
1522490286Sobrien   (set_attr "memory" "both")
1522590286Sobrien   (set_attr "mode" "SI")])
1522690286Sobrien
1522790286Sobrien(define_insn "rep_movqi"
1522890286Sobrien  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
1522990286Sobrien   (set (match_operand:SI 0 "register_operand" "=D") 
1523090286Sobrien        (plus:SI (match_operand:SI 3 "register_operand" "0")
1523190286Sobrien		 (match_operand:SI 5 "register_operand" "2")))
1523290286Sobrien   (set (match_operand:SI 1 "register_operand" "=S") 
1523390286Sobrien        (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
1523490286Sobrien   (set (mem:BLK (match_dup 3))
1523590286Sobrien	(mem:BLK (match_dup 4)))
1523690286Sobrien   (use (match_dup 5))
1523790286Sobrien   (use (reg:SI 19))]
1523890286Sobrien  "!TARGET_64BIT"
1523990286Sobrien  "{rep\;movsb|rep movsb}"
1524090286Sobrien  [(set_attr "type" "str")
1524190286Sobrien   (set_attr "prefix_rep" "1")
1524290286Sobrien   (set_attr "memory" "both")
1524390286Sobrien   (set_attr "mode" "SI")])
1524490286Sobrien
1524590286Sobrien(define_insn "rep_movqi_rex64"
1524690286Sobrien  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
1524790286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1524890286Sobrien        (plus:DI (match_operand:DI 3 "register_operand" "0")
1524990286Sobrien		 (match_operand:DI 5 "register_operand" "2")))
1525090286Sobrien   (set (match_operand:DI 1 "register_operand" "=S") 
1525190286Sobrien        (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
1525290286Sobrien   (set (mem:BLK (match_dup 3))
1525390286Sobrien	(mem:BLK (match_dup 4)))
1525490286Sobrien   (use (match_dup 5))
1525590286Sobrien   (use (reg:SI 19))]
1525690286Sobrien  "TARGET_64BIT"
1525790286Sobrien  "{rep\;movsb|rep movsb}"
1525890286Sobrien  [(set_attr "type" "str")
1525990286Sobrien   (set_attr "prefix_rep" "1")
1526090286Sobrien   (set_attr "memory" "both")
1526190286Sobrien   (set_attr "mode" "SI")])
1526290286Sobrien
1526390286Sobrien(define_expand "clrstrsi"
1526490286Sobrien   [(use (match_operand:BLK 0 "memory_operand" ""))
1526590286Sobrien    (use (match_operand:SI 1 "nonmemory_operand" ""))
1526690286Sobrien    (use (match_operand 2 "const_int_operand" ""))]
1526718334Speter  ""
1526818334Speter{
1526990286Sobrien if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
1527090286Sobrien   DONE;
1527190286Sobrien else
1527290286Sobrien   FAIL;
1527390286Sobrien})
1527418334Speter
1527590286Sobrien(define_expand "clrstrdi"
1527690286Sobrien   [(use (match_operand:BLK 0 "memory_operand" ""))
1527790286Sobrien    (use (match_operand:DI 1 "nonmemory_operand" ""))
1527890286Sobrien    (use (match_operand 2 "const_int_operand" ""))]
1527990286Sobrien  "TARGET_64BIT"
1528090286Sobrien{
1528190286Sobrien if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
1528290286Sobrien   DONE;
1528390286Sobrien else
1528490286Sobrien   FAIL;
1528590286Sobrien})
1528650650Sobrien
1528790286Sobrien;; Most CPUs don't like single string operations
1528890286Sobrien;; Handle this case here to simplify previous expander.
1528950650Sobrien
1529090286Sobrien(define_expand "strsetdi_rex64"
1529190286Sobrien  [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
1529290286Sobrien	(match_operand:DI 1 "register_operand" ""))
1529390286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
1529490286Sobrien	      (clobber (reg:CC 17))])]
1529590286Sobrien  "TARGET_64BIT"
1529690286Sobrien{
1529790286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1529890286Sobrien    {
1529990286Sobrien      emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
1530090286Sobrien      DONE;
1530190286Sobrien    }
1530290286Sobrien})
1530390286Sobrien
1530490286Sobrien(define_expand "strsetsi"
1530590286Sobrien  [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
1530690286Sobrien	(match_operand:SI 1 "register_operand" ""))
1530790286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
1530890286Sobrien	      (clobber (reg:CC 17))])]
1530990286Sobrien  ""
1531090286Sobrien{
1531190286Sobrien  if (TARGET_64BIT)
1531290286Sobrien    {
1531390286Sobrien      emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
1531490286Sobrien      DONE;
1531590286Sobrien    }
1531690286Sobrien  else if (TARGET_SINGLE_STRINGOP || optimize_size)
1531790286Sobrien    {
1531890286Sobrien      emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
1531990286Sobrien      DONE;
1532090286Sobrien    }
1532190286Sobrien})
1532290286Sobrien
1532390286Sobrien(define_expand "strsetsi_rex64"
1532490286Sobrien  [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
1532590286Sobrien	(match_operand:SI 1 "register_operand" ""))
1532690286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
1532790286Sobrien	      (clobber (reg:CC 17))])]
1532890286Sobrien  "TARGET_64BIT"
1532990286Sobrien{
1533090286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1533190286Sobrien    {
1533290286Sobrien      emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
1533390286Sobrien      DONE;
1533490286Sobrien    }
1533590286Sobrien})
1533690286Sobrien
1533790286Sobrien(define_expand "strsethi"
1533890286Sobrien  [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
1533990286Sobrien	(match_operand:HI 1 "register_operand" ""))
1534090286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
1534190286Sobrien	      (clobber (reg:CC 17))])]
1534290286Sobrien  ""
1534390286Sobrien{
1534490286Sobrien  if (TARGET_64BIT)
1534590286Sobrien    {
1534690286Sobrien      emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
1534790286Sobrien      DONE;
1534890286Sobrien    }
1534990286Sobrien  else if (TARGET_SINGLE_STRINGOP || optimize_size)
1535090286Sobrien    {
1535190286Sobrien      emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
1535290286Sobrien      DONE;
1535390286Sobrien    }
1535490286Sobrien})
1535590286Sobrien
1535690286Sobrien(define_expand "strsethi_rex64"
1535790286Sobrien  [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
1535890286Sobrien	(match_operand:HI 1 "register_operand" ""))
1535990286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
1536090286Sobrien	      (clobber (reg:CC 17))])]
1536190286Sobrien  "TARGET_64BIT"
1536290286Sobrien{
1536390286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1536490286Sobrien    {
1536590286Sobrien      emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
1536690286Sobrien      DONE;
1536790286Sobrien    }
1536890286Sobrien})
1536990286Sobrien
1537090286Sobrien(define_expand "strsetqi"
1537190286Sobrien  [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
1537290286Sobrien	(match_operand:QI 1 "register_operand" ""))
1537390286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
1537490286Sobrien	      (clobber (reg:CC 17))])]
1537590286Sobrien  ""
1537690286Sobrien{
1537790286Sobrien  if (TARGET_64BIT)
1537890286Sobrien    {
1537990286Sobrien      emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
1538090286Sobrien      DONE;
1538190286Sobrien    }
1538290286Sobrien  else if (TARGET_SINGLE_STRINGOP || optimize_size)
1538390286Sobrien    {
1538490286Sobrien      emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
1538590286Sobrien      DONE;
1538690286Sobrien    }
1538790286Sobrien})
1538890286Sobrien
1538990286Sobrien(define_expand "strsetqi_rex64"
1539090286Sobrien  [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
1539190286Sobrien	(match_operand:QI 1 "register_operand" ""))
1539290286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
1539390286Sobrien	      (clobber (reg:CC 17))])]
1539490286Sobrien  "TARGET_64BIT"
1539590286Sobrien{
1539690286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1539790286Sobrien    {
1539890286Sobrien      emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
1539990286Sobrien      DONE;
1540090286Sobrien    }
1540190286Sobrien})
1540290286Sobrien
1540390286Sobrien(define_insn "strsetdi_rex_1"
1540490286Sobrien  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
1540590286Sobrien	(match_operand:SI 2 "register_operand" "a"))
1540690286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1540790286Sobrien	(plus:DI (match_dup 1)
1540890286Sobrien		 (const_int 8)))
1540990286Sobrien   (use (reg:SI 19))]
1541090286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1541190286Sobrien  "stosq"
1541290286Sobrien  [(set_attr "type" "str")
1541390286Sobrien   (set_attr "memory" "store")
1541490286Sobrien   (set_attr "mode" "DI")])
1541590286Sobrien
1541690286Sobrien(define_insn "strsetsi_1"
1541790286Sobrien  [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
1541890286Sobrien	(match_operand:SI 2 "register_operand" "a"))
1541990286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1542090286Sobrien	(plus:SI (match_dup 1)
1542190286Sobrien		 (const_int 4)))
1542290286Sobrien   (use (reg:SI 19))]
1542390286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1542490286Sobrien  "{stosl|stosd}"
1542590286Sobrien  [(set_attr "type" "str")
1542690286Sobrien   (set_attr "memory" "store")
1542790286Sobrien   (set_attr "mode" "SI")])
1542890286Sobrien
1542990286Sobrien(define_insn "strsetsi_rex_1"
1543090286Sobrien  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
1543190286Sobrien	(match_operand:SI 2 "register_operand" "a"))
1543290286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1543390286Sobrien	(plus:DI (match_dup 1)
1543490286Sobrien		 (const_int 4)))
1543590286Sobrien   (use (reg:SI 19))]
1543690286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1543790286Sobrien  "{stosl|stosd}"
1543890286Sobrien  [(set_attr "type" "str")
1543990286Sobrien   (set_attr "memory" "store")
1544090286Sobrien   (set_attr "mode" "SI")])
1544190286Sobrien
1544290286Sobrien(define_insn "strsethi_1"
1544390286Sobrien  [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
1544490286Sobrien	(match_operand:HI 2 "register_operand" "a"))
1544590286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1544690286Sobrien	(plus:SI (match_dup 1)
1544790286Sobrien		 (const_int 2)))
1544890286Sobrien   (use (reg:SI 19))]
1544990286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1545090286Sobrien  "stosw"
1545190286Sobrien  [(set_attr "type" "str")
1545290286Sobrien   (set_attr "memory" "store")
1545390286Sobrien   (set_attr "mode" "HI")])
1545490286Sobrien
1545590286Sobrien(define_insn "strsethi_rex_1"
1545690286Sobrien  [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
1545790286Sobrien	(match_operand:HI 2 "register_operand" "a"))
1545890286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1545990286Sobrien	(plus:DI (match_dup 1)
1546090286Sobrien		 (const_int 2)))
1546190286Sobrien   (use (reg:SI 19))]
1546290286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1546390286Sobrien  "stosw"
1546490286Sobrien  [(set_attr "type" "str")
1546590286Sobrien   (set_attr "memory" "store")
1546690286Sobrien   (set_attr "mode" "HI")])
1546790286Sobrien
1546890286Sobrien(define_insn "strsetqi_1"
1546990286Sobrien  [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
1547090286Sobrien	(match_operand:QI 2 "register_operand" "a"))
1547190286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1547290286Sobrien	(plus:SI (match_dup 1)
1547390286Sobrien		 (const_int 1)))
1547490286Sobrien   (use (reg:SI 19))]
1547590286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1547690286Sobrien  "stosb"
1547790286Sobrien  [(set_attr "type" "str")
1547890286Sobrien   (set_attr "memory" "store")
1547990286Sobrien   (set_attr "mode" "QI")])
1548090286Sobrien
1548190286Sobrien(define_insn "strsetqi_rex_1"
1548290286Sobrien  [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
1548390286Sobrien	(match_operand:QI 2 "register_operand" "a"))
1548490286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1548590286Sobrien	(plus:DI (match_dup 1)
1548690286Sobrien		 (const_int 1)))
1548790286Sobrien   (use (reg:SI 19))]
1548890286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1548990286Sobrien  "stosb"
1549090286Sobrien  [(set_attr "type" "str")
1549190286Sobrien   (set_attr "memory" "store")
1549290286Sobrien   (set_attr "mode" "QI")])
1549390286Sobrien
1549490286Sobrien(define_insn "rep_stosdi_rex64"
1549590286Sobrien  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
1549690286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1549790286Sobrien        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
1549890286Sobrien			    (const_int 3))
1549990286Sobrien		 (match_operand:DI 3 "register_operand" "0")))
1550090286Sobrien   (set (mem:BLK (match_dup 3))
1550190286Sobrien	(const_int 0))
1550290286Sobrien   (use (match_operand:DI 2 "register_operand" "a"))
1550390286Sobrien   (use (match_dup 4))
1550490286Sobrien   (use (reg:SI 19))]
1550590286Sobrien  "TARGET_64BIT"
1550690286Sobrien  "{rep\;stosq|rep stosq}"
1550790286Sobrien  [(set_attr "type" "str")
1550890286Sobrien   (set_attr "prefix_rep" "1")
1550990286Sobrien   (set_attr "memory" "store")
1551090286Sobrien   (set_attr "mode" "DI")])
1551190286Sobrien
1551290286Sobrien(define_insn "rep_stossi"
1551390286Sobrien  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
1551490286Sobrien   (set (match_operand:SI 0 "register_operand" "=D") 
1551590286Sobrien        (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
1551690286Sobrien			    (const_int 2))
1551790286Sobrien		 (match_operand:SI 3 "register_operand" "0")))
1551890286Sobrien   (set (mem:BLK (match_dup 3))
1551990286Sobrien	(const_int 0))
1552090286Sobrien   (use (match_operand:SI 2 "register_operand" "a"))
1552190286Sobrien   (use (match_dup 4))
1552290286Sobrien   (use (reg:SI 19))]
1552390286Sobrien  "!TARGET_64BIT"
1552490286Sobrien  "{rep\;stosl|rep stosd}"
1552590286Sobrien  [(set_attr "type" "str")
1552690286Sobrien   (set_attr "prefix_rep" "1")
1552790286Sobrien   (set_attr "memory" "store")
1552890286Sobrien   (set_attr "mode" "SI")])
1552990286Sobrien
1553090286Sobrien(define_insn "rep_stossi_rex64"
1553190286Sobrien  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
1553290286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1553390286Sobrien        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
1553490286Sobrien			    (const_int 2))
1553590286Sobrien		 (match_operand:DI 3 "register_operand" "0")))
1553690286Sobrien   (set (mem:BLK (match_dup 3))
1553790286Sobrien	(const_int 0))
1553890286Sobrien   (use (match_operand:SI 2 "register_operand" "a"))
1553990286Sobrien   (use (match_dup 4))
1554090286Sobrien   (use (reg:SI 19))]
1554190286Sobrien  "TARGET_64BIT"
1554290286Sobrien  "{rep\;stosl|rep stosd}"
1554390286Sobrien  [(set_attr "type" "str")
1554490286Sobrien   (set_attr "prefix_rep" "1")
1554590286Sobrien   (set_attr "memory" "store")
1554690286Sobrien   (set_attr "mode" "SI")])
1554790286Sobrien
1554890286Sobrien(define_insn "rep_stosqi"
1554990286Sobrien  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
1555090286Sobrien   (set (match_operand:SI 0 "register_operand" "=D") 
1555190286Sobrien        (plus:SI (match_operand:SI 3 "register_operand" "0")
1555290286Sobrien		 (match_operand:SI 4 "register_operand" "1")))
1555390286Sobrien   (set (mem:BLK (match_dup 3))
1555490286Sobrien	(const_int 0))
1555590286Sobrien   (use (match_operand:QI 2 "register_operand" "a"))
1555690286Sobrien   (use (match_dup 4))
1555790286Sobrien   (use (reg:SI 19))]
1555890286Sobrien  "!TARGET_64BIT"
1555990286Sobrien  "{rep\;stosb|rep stosb}"
1556090286Sobrien  [(set_attr "type" "str")
1556190286Sobrien   (set_attr "prefix_rep" "1")
1556290286Sobrien   (set_attr "memory" "store")
1556390286Sobrien   (set_attr "mode" "QI")])
1556490286Sobrien
1556590286Sobrien(define_insn "rep_stosqi_rex64"
1556690286Sobrien  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
1556790286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1556890286Sobrien        (plus:DI (match_operand:DI 3 "register_operand" "0")
1556990286Sobrien		 (match_operand:DI 4 "register_operand" "1")))
1557090286Sobrien   (set (mem:BLK (match_dup 3))
1557190286Sobrien	(const_int 0))
1557290286Sobrien   (use (match_operand:QI 2 "register_operand" "a"))
1557390286Sobrien   (use (match_dup 4))
1557490286Sobrien   (use (reg:DI 19))]
1557590286Sobrien  "TARGET_64BIT"
1557690286Sobrien  "{rep\;stosb|rep stosb}"
1557790286Sobrien  [(set_attr "type" "str")
1557890286Sobrien   (set_attr "prefix_rep" "1")
1557990286Sobrien   (set_attr "memory" "store")
1558090286Sobrien   (set_attr "mode" "QI")])
1558190286Sobrien
1558290286Sobrien(define_expand "cmpstrsi"
1558350650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1558490286Sobrien	(compare:SI (match_operand:BLK 1 "general_operand" "")
1558590286Sobrien		    (match_operand:BLK 2 "general_operand" "")))
1558690286Sobrien   (use (match_operand 3 "general_operand" ""))
1558790286Sobrien   (use (match_operand 4 "immediate_operand" ""))]
1558890286Sobrien  ""
1558950650Sobrien{
1559090286Sobrien  rtx addr1, addr2, out, outlow, count, countreg, align;
1559150650Sobrien
1559290286Sobrien  out = operands[0];
1559390286Sobrien  if (GET_CODE (out) != REG)
1559490286Sobrien    out = gen_reg_rtx (SImode);
1559550650Sobrien
1559690286Sobrien  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1559790286Sobrien  addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
1559890286Sobrien  
1559990286Sobrien  count = operands[3];
1560090286Sobrien  countreg = ix86_zero_extend_to_Pmode (count);
1560150650Sobrien
1560290286Sobrien  /* %%% Iff we are testing strict equality, we can use known alignment
1560390286Sobrien     to good advantage.  This may be possible with combine, particularly
1560490286Sobrien     once cc0 is dead.  */
1560590286Sobrien  align = operands[4];
1560650650Sobrien
1560790286Sobrien  emit_insn (gen_cld ());
1560890286Sobrien  if (GET_CODE (count) == CONST_INT)
1560990286Sobrien    {
1561090286Sobrien      if (INTVAL (count) == 0)
1561190286Sobrien	{
1561290286Sobrien	  emit_move_insn (operands[0], const0_rtx);
1561390286Sobrien	  DONE;
1561490286Sobrien	}
1561590286Sobrien      if (TARGET_64BIT)
1561690286Sobrien	emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
1561790286Sobrien					  addr1, addr2, countreg));
1561890286Sobrien      else
1561990286Sobrien	emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
1562090286Sobrien				      addr1, addr2, countreg));
1562190286Sobrien    }
1562290286Sobrien  else
1562390286Sobrien    {
1562490286Sobrien      if (TARGET_64BIT)
1562590286Sobrien	{
1562690286Sobrien	  emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
1562790286Sobrien	  emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
1562890286Sobrien					 addr1, addr2, countreg));
1562990286Sobrien	}
1563090286Sobrien      else
1563190286Sobrien	{
1563290286Sobrien	  emit_insn (gen_cmpsi_1 (countreg, countreg));
1563390286Sobrien	  emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
1563490286Sobrien				     addr1, addr2, countreg));
1563590286Sobrien	}
1563690286Sobrien    }
1563790286Sobrien
1563890286Sobrien  outlow = gen_lowpart (QImode, out);
1563990286Sobrien  emit_insn (gen_cmpintqi (outlow));
1564090286Sobrien  emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
1564190286Sobrien
1564290286Sobrien  if (operands[0] != out)
1564390286Sobrien    emit_move_insn (operands[0], out);
1564490286Sobrien
1564590286Sobrien  DONE;
1564690286Sobrien})
1564790286Sobrien
1564890286Sobrien;; Produce a tri-state integer (-1, 0, 1) from condition codes.
1564990286Sobrien
1565090286Sobrien(define_expand "cmpintqi"
1565190286Sobrien  [(set (match_dup 1)
1565290286Sobrien	(gtu:QI (reg:CC 17) (const_int 0)))
1565390286Sobrien   (set (match_dup 2)
1565490286Sobrien	(ltu:QI (reg:CC 17) (const_int 0)))
1565590286Sobrien   (parallel [(set (match_operand:QI 0 "register_operand" "")
1565690286Sobrien		   (minus:QI (match_dup 1)
1565790286Sobrien			     (match_dup 2)))
1565890286Sobrien	      (clobber (reg:CC 17))])]
1565990286Sobrien  ""
1566090286Sobrien  "operands[1] = gen_reg_rtx (QImode);
1566190286Sobrien   operands[2] = gen_reg_rtx (QImode);")
1566290286Sobrien
1566390286Sobrien;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
1566490286Sobrien;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
1566590286Sobrien
1566690286Sobrien(define_insn "cmpstrqi_nz_1"
1566790286Sobrien  [(set (reg:CC 17)
1566890286Sobrien	(compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
1566990286Sobrien		    (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
1567090286Sobrien   (use (match_operand:SI 6 "register_operand" "2"))
1567190286Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
1567290286Sobrien   (use (reg:SI 19))
1567390286Sobrien   (clobber (match_operand:SI 0 "register_operand" "=S"))
1567490286Sobrien   (clobber (match_operand:SI 1 "register_operand" "=D"))
1567590286Sobrien   (clobber (match_operand:SI 2 "register_operand" "=c"))]
1567690286Sobrien  "!TARGET_64BIT"
1567790286Sobrien  "repz{\;| }cmpsb"
1567890286Sobrien  [(set_attr "type" "str")
1567990286Sobrien   (set_attr "mode" "QI")
1568090286Sobrien   (set_attr "prefix_rep" "1")])
1568190286Sobrien
1568290286Sobrien(define_insn "cmpstrqi_nz_rex_1"
1568390286Sobrien  [(set (reg:CC 17)
1568490286Sobrien	(compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
1568590286Sobrien		    (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
1568690286Sobrien   (use (match_operand:DI 6 "register_operand" "2"))
1568790286Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
1568890286Sobrien   (use (reg:SI 19))
1568990286Sobrien   (clobber (match_operand:DI 0 "register_operand" "=S"))
1569090286Sobrien   (clobber (match_operand:DI 1 "register_operand" "=D"))
1569190286Sobrien   (clobber (match_operand:DI 2 "register_operand" "=c"))]
1569290286Sobrien  "TARGET_64BIT"
1569390286Sobrien  "repz{\;| }cmpsb"
1569490286Sobrien  [(set_attr "type" "str")
1569590286Sobrien   (set_attr "mode" "QI")
1569690286Sobrien   (set_attr "prefix_rep" "1")])
1569790286Sobrien
1569890286Sobrien;; The same, but the count is not known to not be zero.
1569990286Sobrien
1570090286Sobrien(define_insn "cmpstrqi_1"
1570190286Sobrien  [(set (reg:CC 17)
1570290286Sobrien	(if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
1570390286Sobrien			     (const_int 0))
1570490286Sobrien	  (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
1570590286Sobrien		      (mem:BLK (match_operand:SI 5 "register_operand" "1")))
1570690286Sobrien	  (const_int 0)))
1570790286Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
1570890286Sobrien   (use (reg:CC 17))
1570990286Sobrien   (use (reg:SI 19))
1571090286Sobrien   (clobber (match_operand:SI 0 "register_operand" "=S"))
1571190286Sobrien   (clobber (match_operand:SI 1 "register_operand" "=D"))
1571290286Sobrien   (clobber (match_operand:SI 2 "register_operand" "=c"))]
1571390286Sobrien  "!TARGET_64BIT"
1571490286Sobrien  "repz{\;| }cmpsb"
1571590286Sobrien  [(set_attr "type" "str")
1571690286Sobrien   (set_attr "mode" "QI")
1571790286Sobrien   (set_attr "prefix_rep" "1")])
1571890286Sobrien
1571990286Sobrien(define_insn "cmpstrqi_rex_1"
1572090286Sobrien  [(set (reg:CC 17)
1572190286Sobrien	(if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
1572290286Sobrien			     (const_int 0))
1572390286Sobrien	  (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
1572490286Sobrien		      (mem:BLK (match_operand:DI 5 "register_operand" "1")))
1572590286Sobrien	  (const_int 0)))
1572690286Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
1572790286Sobrien   (use (reg:CC 17))
1572890286Sobrien   (use (reg:SI 19))
1572990286Sobrien   (clobber (match_operand:DI 0 "register_operand" "=S"))
1573090286Sobrien   (clobber (match_operand:DI 1 "register_operand" "=D"))
1573190286Sobrien   (clobber (match_operand:DI 2 "register_operand" "=c"))]
1573290286Sobrien  "TARGET_64BIT"
1573390286Sobrien  "repz{\;| }cmpsb"
1573490286Sobrien  [(set_attr "type" "str")
1573590286Sobrien   (set_attr "mode" "QI")
1573690286Sobrien   (set_attr "prefix_rep" "1")])
1573790286Sobrien
1573890286Sobrien(define_expand "strlensi"
1573952296Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1574090286Sobrien	(unspec:SI [(match_operand:BLK 1 "general_operand" "")
1574190286Sobrien		    (match_operand:QI 2 "immediate_operand" "")
1574290286Sobrien		    (match_operand 3 "immediate_operand" "")] 0))]
1574390286Sobrien  ""
1574490286Sobrien{
1574590286Sobrien if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
1574690286Sobrien   DONE;
1574790286Sobrien else
1574890286Sobrien   FAIL;
1574990286Sobrien})
1575090286Sobrien
1575190286Sobrien(define_expand "strlendi"
1575290286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1575390286Sobrien	(unspec:DI [(match_operand:BLK 1 "general_operand" "")
1575490286Sobrien		    (match_operand:QI 2 "immediate_operand" "")
1575590286Sobrien		    (match_operand 3 "immediate_operand" "")] 0))]
1575690286Sobrien  ""
1575790286Sobrien{
1575890286Sobrien if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
1575990286Sobrien   DONE;
1576090286Sobrien else
1576190286Sobrien   FAIL;
1576290286Sobrien})
1576390286Sobrien
1576490286Sobrien(define_insn "strlenqi_1"
1576590286Sobrien  [(set (match_operand:SI 0 "register_operand" "=&c")
1576690286Sobrien	(unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
1576790286Sobrien		    (match_operand:QI 2 "register_operand" "a")
1576890286Sobrien		    (match_operand:SI 3 "immediate_operand" "i")
1576990286Sobrien		    (match_operand:SI 4 "register_operand" "0")] 0))
1577090286Sobrien   (use (reg:SI 19))
1577190286Sobrien   (clobber (match_operand:SI 1 "register_operand" "=D"))
1577290286Sobrien   (clobber (reg:CC 17))]
1577390286Sobrien  "!TARGET_64BIT"
1577490286Sobrien  "repnz{\;| }scasb"
1577590286Sobrien  [(set_attr "type" "str")
1577690286Sobrien   (set_attr "mode" "QI")
1577790286Sobrien   (set_attr "prefix_rep" "1")])
1577890286Sobrien
1577990286Sobrien(define_insn "strlenqi_rex_1"
1578090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=&c")
1578190286Sobrien	(unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
1578290286Sobrien		    (match_operand:QI 2 "register_operand" "a")
1578390286Sobrien		    (match_operand:DI 3 "immediate_operand" "i")
1578490286Sobrien		    (match_operand:DI 4 "register_operand" "0")] 0))
1578590286Sobrien   (use (reg:SI 19))
1578690286Sobrien   (clobber (match_operand:DI 1 "register_operand" "=D"))
1578790286Sobrien   (clobber (reg:CC 17))]
1578890286Sobrien  "TARGET_64BIT"
1578990286Sobrien  "repnz{\;| }scasb"
1579090286Sobrien  [(set_attr "type" "str")
1579190286Sobrien   (set_attr "mode" "QI")
1579290286Sobrien   (set_attr "prefix_rep" "1")])
1579390286Sobrien
1579490286Sobrien;; Peephole optimizations to clean up after cmpstr*.  This should be
1579590286Sobrien;; handled in combine, but it is not currently up to the task.
1579690286Sobrien;; When used for their truth value, the cmpstr* expanders generate
1579790286Sobrien;; code like this:
1579890286Sobrien;;
1579990286Sobrien;;   repz cmpsb
1580090286Sobrien;;   seta 	%al
1580190286Sobrien;;   setb 	%dl
1580290286Sobrien;;   cmpb 	%al, %dl
1580390286Sobrien;;   jcc	label
1580490286Sobrien;;
1580590286Sobrien;; The intermediate three instructions are unnecessary.
1580690286Sobrien
1580790286Sobrien;; This one handles cmpstr*_nz_1...
1580890286Sobrien(define_peephole2
1580990286Sobrien  [(parallel[
1581090286Sobrien     (set (reg:CC 17)
1581190286Sobrien	  (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
1581290286Sobrien		      (mem:BLK (match_operand 5 "register_operand" ""))))
1581390286Sobrien     (use (match_operand 6 "register_operand" ""))
1581490286Sobrien     (use (match_operand:SI 3 "immediate_operand" ""))
1581590286Sobrien     (use (reg:SI 19))
1581690286Sobrien     (clobber (match_operand 0 "register_operand" ""))
1581790286Sobrien     (clobber (match_operand 1 "register_operand" ""))
1581890286Sobrien     (clobber (match_operand 2 "register_operand" ""))])
1581990286Sobrien   (set (match_operand:QI 7 "register_operand" "")
1582090286Sobrien	(gtu:QI (reg:CC 17) (const_int 0)))
1582190286Sobrien   (set (match_operand:QI 8 "register_operand" "")
1582290286Sobrien	(ltu:QI (reg:CC 17) (const_int 0)))
1582390286Sobrien   (set (reg 17)
1582490286Sobrien	(compare (match_dup 7) (match_dup 8)))
1582590286Sobrien  ]
1582690286Sobrien  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
1582790286Sobrien  [(parallel[
1582890286Sobrien     (set (reg:CC 17)
1582990286Sobrien	  (compare:CC (mem:BLK (match_dup 4))
1583090286Sobrien		      (mem:BLK (match_dup 5))))
1583190286Sobrien     (use (match_dup 6))
1583290286Sobrien     (use (match_dup 3))
1583390286Sobrien     (use (reg:SI 19))
1583490286Sobrien     (clobber (match_dup 0))
1583590286Sobrien     (clobber (match_dup 1))
1583690286Sobrien     (clobber (match_dup 2))])]
1583750650Sobrien  "")
1583850650Sobrien
1583990286Sobrien;; ...and this one handles cmpstr*_1.
1584090286Sobrien(define_peephole2
1584190286Sobrien  [(parallel[
1584290286Sobrien     (set (reg:CC 17)
1584390286Sobrien	  (if_then_else:CC (ne (match_operand 6 "register_operand" "")
1584490286Sobrien			       (const_int 0))
1584590286Sobrien	    (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
1584690286Sobrien		        (mem:BLK (match_operand 5 "register_operand" "")))
1584790286Sobrien	    (const_int 0)))
1584890286Sobrien     (use (match_operand:SI 3 "immediate_operand" ""))
1584990286Sobrien     (use (reg:CC 17))
1585090286Sobrien     (use (reg:SI 19))
1585190286Sobrien     (clobber (match_operand 0 "register_operand" ""))
1585290286Sobrien     (clobber (match_operand 1 "register_operand" ""))
1585390286Sobrien     (clobber (match_operand 2 "register_operand" ""))])
1585490286Sobrien   (set (match_operand:QI 7 "register_operand" "")
1585590286Sobrien	(gtu:QI (reg:CC 17) (const_int 0)))
1585690286Sobrien   (set (match_operand:QI 8 "register_operand" "")
1585790286Sobrien	(ltu:QI (reg:CC 17) (const_int 0)))
1585890286Sobrien   (set (reg 17)
1585990286Sobrien	(compare (match_dup 7) (match_dup 8)))
1586090286Sobrien  ]
1586190286Sobrien  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
1586290286Sobrien  [(parallel[
1586390286Sobrien     (set (reg:CC 17)
1586490286Sobrien	  (if_then_else:CC (ne (match_dup 6)
1586590286Sobrien			       (const_int 0))
1586690286Sobrien	    (compare:CC (mem:BLK (match_dup 4))
1586790286Sobrien			(mem:BLK (match_dup 5)))
1586890286Sobrien	    (const_int 0)))
1586990286Sobrien     (use (match_dup 3))
1587090286Sobrien     (use (reg:CC 17))
1587190286Sobrien     (use (reg:SI 19))
1587290286Sobrien     (clobber (match_dup 0))
1587390286Sobrien     (clobber (match_dup 1))
1587490286Sobrien     (clobber (match_dup 2))])]
1587550650Sobrien  "")
1587650650Sobrien
1587790286Sobrien
1587890286Sobrien
1587990286Sobrien;; Conditional move instructions.
1588090286Sobrien
1588190286Sobrien(define_expand "movdicc"
1588290286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1588390286Sobrien	(if_then_else:DI (match_operand 1 "comparison_operator" "")
1588490286Sobrien			 (match_operand:DI 2 "general_operand" "")
1588590286Sobrien			 (match_operand:DI 3 "general_operand" "")))]
1588690286Sobrien  "TARGET_64BIT"
1588790286Sobrien  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
1588890286Sobrien
1588990286Sobrien(define_insn "x86_movdicc_0_m1_rex64"
1589090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1589190286Sobrien	(if_then_else:DI (ltu (reg:CC 17) (const_int 0))
1589290286Sobrien	  (const_int -1)
1589390286Sobrien	  (const_int 0)))
1589490286Sobrien   (clobber (reg:CC 17))]
1589590286Sobrien  "TARGET_64BIT"
1589690286Sobrien  "sbb{q}\t%0, %0"
1589790286Sobrien  ; Since we don't have the proper number of operands for an alu insn,
1589890286Sobrien  ; fill in all the blanks.
1589990286Sobrien  [(set_attr "type" "alu")
1590090286Sobrien   (set_attr "memory" "none")
1590190286Sobrien   (set_attr "imm_disp" "false")
1590290286Sobrien   (set_attr "mode" "DI")
1590390286Sobrien   (set_attr "length_immediate" "0")])
1590490286Sobrien
1590590286Sobrien(define_insn "*movdicc_c_rex64"
1590690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1590790286Sobrien	(if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
1590890286Sobrien				[(reg 17) (const_int 0)])
1590990286Sobrien		      (match_operand:DI 2 "nonimmediate_operand" "rm,0")
1591090286Sobrien		      (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
1591190286Sobrien  "TARGET_64BIT && TARGET_CMOVE
1591290286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1591390286Sobrien  "@
1591496294Sobrien   cmov%O2%C1\t{%2, %0|%0, %2}
1591596294Sobrien   cmov%O2%c1\t{%3, %0|%0, %3}"
1591690286Sobrien  [(set_attr "type" "icmov")
1591790286Sobrien   (set_attr "mode" "DI")])
1591890286Sobrien
1591990286Sobrien(define_expand "movsicc"
1592090286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1592190286Sobrien	(if_then_else:SI (match_operand 1 "comparison_operator" "")
1592290286Sobrien			 (match_operand:SI 2 "general_operand" "")
1592390286Sobrien			 (match_operand:SI 3 "general_operand" "")))]
1592490286Sobrien  ""
1592590286Sobrien  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
1592690286Sobrien
1592790286Sobrien;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
1592890286Sobrien;; the register first winds up with `sbbl $0,reg', which is also weird.
1592990286Sobrien;; So just document what we're doing explicitly.
1593090286Sobrien
1593190286Sobrien(define_insn "x86_movsicc_0_m1"
1593290286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1593390286Sobrien	(if_then_else:SI (ltu (reg:CC 17) (const_int 0))
1593490286Sobrien	  (const_int -1)
1593590286Sobrien	  (const_int 0)))
1593690286Sobrien   (clobber (reg:CC 17))]
1593790286Sobrien  ""
1593890286Sobrien  "sbb{l}\t%0, %0"
1593990286Sobrien  ; Since we don't have the proper number of operands for an alu insn,
1594090286Sobrien  ; fill in all the blanks.
1594190286Sobrien  [(set_attr "type" "alu")
1594290286Sobrien   (set_attr "memory" "none")
1594390286Sobrien   (set_attr "imm_disp" "false")
1594490286Sobrien   (set_attr "mode" "SI")
1594590286Sobrien   (set_attr "length_immediate" "0")])
1594690286Sobrien
1594790286Sobrien(define_insn "*movsicc_noc"
1594850650Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,r")
1594990286Sobrien	(if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
1595090286Sobrien				[(reg 17) (const_int 0)])
1595150650Sobrien		      (match_operand:SI 2 "nonimmediate_operand" "rm,0")
1595250650Sobrien		      (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
1595390286Sobrien  "TARGET_CMOVE
1595490286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1595590286Sobrien  "@
1595696294Sobrien   cmov%O2%C1\t{%2, %0|%0, %2}
1595796294Sobrien   cmov%O2%c1\t{%3, %0|%0, %3}"
1595890286Sobrien  [(set_attr "type" "icmov")
1595990286Sobrien   (set_attr "mode" "SI")])
1596050650Sobrien
1596150650Sobrien(define_expand "movhicc"
1596250650Sobrien  [(set (match_operand:HI 0 "register_operand" "")
1596350650Sobrien	(if_then_else:HI (match_operand 1 "comparison_operator" "")
1596450650Sobrien			 (match_operand:HI 2 "nonimmediate_operand" "")
1596550650Sobrien			 (match_operand:HI 3 "nonimmediate_operand" "")))]
1596690286Sobrien  "TARGET_CMOVE && TARGET_HIMODE_MATH"
1596790286Sobrien  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
1596850650Sobrien
1596990286Sobrien(define_insn "*movhicc_noc"
1597050650Sobrien  [(set (match_operand:HI 0 "register_operand" "=r,r")
1597190286Sobrien	(if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
1597290286Sobrien				[(reg 17) (const_int 0)])
1597350650Sobrien		      (match_operand:HI 2 "nonimmediate_operand" "rm,0")
1597450650Sobrien		      (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
1597590286Sobrien  "TARGET_CMOVE
1597690286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1597790286Sobrien  "@
1597896294Sobrien   cmov%O2%C1\t{%2, %0|%0, %2}
1597996294Sobrien   cmov%O2%c1\t{%3, %0|%0, %3}"
1598090286Sobrien  [(set_attr "type" "icmov")
1598190286Sobrien   (set_attr "mode" "HI")])
1598250650Sobrien
1598350650Sobrien(define_expand "movsfcc"
1598450650Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1598550650Sobrien	(if_then_else:SF (match_operand 1 "comparison_operator" "")
1598650650Sobrien			 (match_operand:SF 2 "register_operand" "")
1598750650Sobrien			 (match_operand:SF 3 "register_operand" "")))]
1598850650Sobrien  "TARGET_CMOVE"
1598990286Sobrien  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
1599050650Sobrien
1599190286Sobrien(define_insn "*movsfcc_1"
1599290286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
1599390286Sobrien	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
1599490286Sobrien				[(reg 17) (const_int 0)])
1599590286Sobrien		      (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
1599690286Sobrien		      (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
1599790286Sobrien  "TARGET_CMOVE
1599890286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1599990286Sobrien  "@
1600090286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1600190286Sobrien   fcmov%f1\t{%3, %0|%0, %3}
1600296294Sobrien   cmov%O2%C1\t{%2, %0|%0, %2}
1600396294Sobrien   cmov%O2%c1\t{%3, %0|%0, %3}"
1600490286Sobrien  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
1600590286Sobrien   (set_attr "mode" "SF,SF,SI,SI")])
1600650650Sobrien
1600790286Sobrien(define_expand "movdfcc"
1600890286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1600990286Sobrien	(if_then_else:DF (match_operand 1 "comparison_operator" "")
1601090286Sobrien			 (match_operand:DF 2 "register_operand" "")
1601190286Sobrien			 (match_operand:DF 3 "register_operand" "")))]
1601290286Sobrien  "TARGET_CMOVE"
1601390286Sobrien  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
1601450650Sobrien
1601590286Sobrien(define_insn "*movdfcc_1"
1601690286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
1601790286Sobrien	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
1601890286Sobrien				[(reg 17) (const_int 0)])
1601990286Sobrien		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
1602090286Sobrien		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
1602190286Sobrien  "!TARGET_64BIT && TARGET_CMOVE
1602290286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1602390286Sobrien  "@
1602490286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1602590286Sobrien   fcmov%f1\t{%3, %0|%0, %3}
1602690286Sobrien   #
1602790286Sobrien   #"
1602890286Sobrien  [(set_attr "type" "fcmov,fcmov,multi,multi")
1602990286Sobrien   (set_attr "mode" "DF")])
1603050650Sobrien
1603190286Sobrien(define_insn "*movdfcc_1_rex64"
1603290286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
1603390286Sobrien	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
1603490286Sobrien				[(reg 17) (const_int 0)])
1603590286Sobrien		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
1603690286Sobrien		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
1603790286Sobrien  "TARGET_64BIT && TARGET_CMOVE
1603890286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1603990286Sobrien  "@
1604090286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1604190286Sobrien   fcmov%f1\t{%3, %0|%0, %3}
1604296294Sobrien   cmov%O2%C1\t{%2, %0|%0, %2}
1604396294Sobrien   cmov%O2%c1\t{%3, %0|%0, %3}"
1604490286Sobrien  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
1604590286Sobrien   (set_attr "mode" "DF")])
1604650650Sobrien
1604790286Sobrien(define_split
1604890286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1604990286Sobrien	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
1605090286Sobrien				[(match_operand 4 "" "") (const_int 0)])
1605190286Sobrien		      (match_operand:DF 2 "nonimmediate_operand" "")
1605290286Sobrien		      (match_operand:DF 3 "nonimmediate_operand" "")))]
1605390286Sobrien  "!TARGET_64BIT && !ANY_FP_REG_P (operands[0]) && reload_completed"
1605490286Sobrien  [(set (match_dup 2)
1605590286Sobrien	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
1605690286Sobrien		      (match_dup 5)
1605790286Sobrien		      (match_dup 7)))
1605890286Sobrien   (set (match_dup 3)
1605990286Sobrien	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
1606090286Sobrien		      (match_dup 6)
1606190286Sobrien		      (match_dup 8)))]
1606290286Sobrien  "split_di (operands+2, 1, operands+5, operands+6);
1606390286Sobrien   split_di (operands+3, 1, operands+7, operands+8);
1606490286Sobrien   split_di (operands, 1, operands+2, operands+3);")
1606550650Sobrien
1606690286Sobrien(define_expand "movxfcc"
1606790286Sobrien  [(set (match_operand:XF 0 "register_operand" "")
1606890286Sobrien	(if_then_else:XF (match_operand 1 "comparison_operator" "")
1606990286Sobrien			 (match_operand:XF 2 "register_operand" "")
1607090286Sobrien			 (match_operand:XF 3 "register_operand" "")))]
1607190286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1607290286Sobrien  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
1607350650Sobrien
1607490286Sobrien(define_expand "movtfcc"
1607590286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
1607690286Sobrien	(if_then_else:TF (match_operand 1 "comparison_operator" "")
1607790286Sobrien			 (match_operand:TF 2 "register_operand" "")
1607890286Sobrien			 (match_operand:TF 3 "register_operand" "")))]
1607990286Sobrien  "TARGET_CMOVE"
1608090286Sobrien  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
1608190286Sobrien
1608290286Sobrien(define_insn "*movxfcc_1"
1608390286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1608490286Sobrien	(if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
1608590286Sobrien				[(reg 17) (const_int 0)])
1608690286Sobrien		      (match_operand:XF 2 "register_operand" "f,0")
1608790286Sobrien		      (match_operand:XF 3 "register_operand" "0,f")))]
1608890286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1608990286Sobrien  "@
1609090286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1609190286Sobrien   fcmov%f1\t{%3, %0|%0, %3}"
1609290286Sobrien  [(set_attr "type" "fcmov")
1609390286Sobrien   (set_attr "mode" "XF")])
1609490286Sobrien
1609590286Sobrien(define_insn "*movtfcc_1"
1609690286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1609790286Sobrien	(if_then_else:TF (match_operator 1 "fcmov_comparison_operator" 
1609890286Sobrien				[(reg 17) (const_int 0)])
1609990286Sobrien		      (match_operand:TF 2 "register_operand" "f,0")
1610090286Sobrien		      (match_operand:TF 3 "register_operand" "0,f")))]
1610190286Sobrien  "TARGET_CMOVE"
1610290286Sobrien  "@
1610390286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1610490286Sobrien   fcmov%f1\t{%3, %0|%0, %3}"
1610590286Sobrien  [(set_attr "type" "fcmov")
1610690286Sobrien   (set_attr "mode" "XF")])
1610790286Sobrien
1610890286Sobrien(define_expand "minsf3"
1610990286Sobrien  [(parallel [
1611090286Sobrien     (set (match_operand:SF 0 "register_operand" "")
1611190286Sobrien	  (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
1611290286Sobrien			       (match_operand:SF 2 "nonimmediate_operand" ""))
1611390286Sobrien			   (match_dup 1)
1611490286Sobrien			   (match_dup 2)))
1611590286Sobrien     (clobber (reg:CC 17))])]
1611690286Sobrien  "TARGET_SSE"
1611790286Sobrien  "")
1611890286Sobrien
1611990286Sobrien(define_insn "*minsf"
1612090286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
1612190286Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
1612290286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
1612390286Sobrien			 (match_dup 1)
1612490286Sobrien			 (match_dup 2)))
1612590286Sobrien   (clobber (reg:CC 17))]
1612690286Sobrien  "TARGET_SSE && TARGET_IEEE_FP"
1612750650Sobrien  "#")
1612850650Sobrien
1612990286Sobrien(define_insn "*minsf_nonieee"
1613090286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
1613196294Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
1613290286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
1613390286Sobrien			 (match_dup 1)
1613490286Sobrien			 (match_dup 2)))
1613590286Sobrien   (clobber (reg:CC 17))]
1613696294Sobrien  "TARGET_SSE && !TARGET_IEEE_FP
1613796294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1613850650Sobrien  "#")
1613950650Sobrien
1614050650Sobrien(define_split
1614152296Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1614290286Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
1614390286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" ""))
1614490286Sobrien			 (match_operand:SF 3 "register_operand" "")
1614590286Sobrien			 (match_operand:SF 4 "nonimmediate_operand" "")))
1614690286Sobrien   (clobber (reg:CC 17))]
1614790286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1614890286Sobrien   && ((operands_match_p (operands[1], operands[3])
1614990286Sobrien	&& operands_match_p (operands[2], operands[4]))
1615090286Sobrien       || (operands_match_p (operands[1], operands[4])
1615190286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1615290286Sobrien  [(set (match_dup 0)
1615390286Sobrien	(if_then_else:SF (lt (match_dup 1)
1615490286Sobrien			     (match_dup 2))
1615590286Sobrien			 (match_dup 1)
1615690286Sobrien			 (match_dup 2)))])
1615750650Sobrien
1615890286Sobrien;; We can't represent the LT test directly.  Do this by swapping the operands.
1615990286Sobrien
1616050650Sobrien(define_split
1616152296Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1616290286Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
1616390286Sobrien			     (match_operand:SF 2 "register_operand" ""))
1616490286Sobrien			 (match_operand:SF 3 "register_operand" "")
1616590286Sobrien			 (match_operand:SF 4 "register_operand" "")))
1616690286Sobrien   (clobber (reg:CC 17))]
1616790286Sobrien  "FP_REG_P (operands[0]) && reload_completed
1616890286Sobrien   && ((operands_match_p (operands[1], operands[3])
1616990286Sobrien	&& operands_match_p (operands[2], operands[4]))
1617090286Sobrien       || (operands_match_p (operands[1], operands[4])
1617190286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1617290286Sobrien  [(set (reg:CCFP 17)
1617390286Sobrien	(compare:CCFP (match_dup 2)
1617490286Sobrien		      (match_dup 1)))
1617550650Sobrien   (set (match_dup 0)
1617690286Sobrien	(if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
1617790286Sobrien			 (match_dup 1)
1617890286Sobrien			 (match_dup 2)))])
1617950650Sobrien
1618090286Sobrien(define_insn "*minsf_sse"
1618190286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1618290286Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
1618390286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm"))
1618490286Sobrien			 (match_dup 1)
1618590286Sobrien			 (match_dup 2)))]
1618690286Sobrien  "TARGET_SSE && reload_completed"
1618790286Sobrien  "minss\t{%2, %0|%0, %2}"
1618890286Sobrien  [(set_attr "type" "sse")
1618990286Sobrien   (set_attr "mode" "SF")])
1619050650Sobrien
1619190286Sobrien(define_expand "mindf3"
1619290286Sobrien  [(parallel [
1619390286Sobrien     (set (match_operand:DF 0 "register_operand" "")
1619490286Sobrien	  (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
1619590286Sobrien			       (match_operand:DF 2 "nonimmediate_operand" ""))
1619690286Sobrien			   (match_dup 1)
1619790286Sobrien			   (match_dup 2)))
1619890286Sobrien     (clobber (reg:CC 17))])]
1619990286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH"
1620090286Sobrien  "#")
1620190286Sobrien
1620290286Sobrien(define_insn "*mindf"
1620390286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
1620490286Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
1620590286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
1620690286Sobrien			 (match_dup 1)
1620790286Sobrien			 (match_dup 2)))
1620890286Sobrien   (clobber (reg:CC 17))]
1620990286Sobrien  "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
1621090286Sobrien  "#")
1621190286Sobrien
1621290286Sobrien(define_insn "*mindf_nonieee"
1621390286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
1621496294Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
1621590286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
1621690286Sobrien			 (match_dup 1)
1621790286Sobrien			 (match_dup 2)))
1621890286Sobrien   (clobber (reg:CC 17))]
1621996294Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
1622096294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1622190286Sobrien  "#")
1622290286Sobrien
1622390286Sobrien(define_split
1622450650Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1622590286Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
1622690286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" ""))
1622790286Sobrien			 (match_operand:DF 3 "register_operand" "")
1622890286Sobrien			 (match_operand:DF 4 "nonimmediate_operand" "")))
1622990286Sobrien   (clobber (reg:CC 17))]
1623090286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1623190286Sobrien   && ((operands_match_p (operands[1], operands[3])
1623290286Sobrien	&& operands_match_p (operands[2], operands[4]))
1623390286Sobrien       || (operands_match_p (operands[1], operands[4])
1623490286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1623590286Sobrien  [(set (match_dup 0)
1623690286Sobrien	(if_then_else:DF (lt (match_dup 1)
1623790286Sobrien			     (match_dup 2))
1623890286Sobrien			 (match_dup 1)
1623990286Sobrien			 (match_dup 2)))])
1624050650Sobrien
1624190286Sobrien;; We can't represent the LT test directly.  Do this by swapping the operands.
1624290286Sobrien(define_split
1624390286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1624490286Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
1624590286Sobrien			     (match_operand:DF 2 "register_operand" ""))
1624690286Sobrien			 (match_operand:DF 3 "register_operand" "")
1624790286Sobrien			 (match_operand:DF 4 "register_operand" "")))
1624890286Sobrien   (clobber (reg:CC 17))]
1624990286Sobrien  "FP_REG_P (operands[0]) && reload_completed
1625090286Sobrien   && ((operands_match_p (operands[1], operands[3])
1625190286Sobrien	&& operands_match_p (operands[2], operands[4]))
1625290286Sobrien       || (operands_match_p (operands[1], operands[4])
1625390286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1625490286Sobrien  [(set (reg:CCFP 17)
1625590286Sobrien	(compare:CCFP (match_dup 2)
1625690286Sobrien		      (match_dup 2)))
1625790286Sobrien   (set (match_dup 0)
1625890286Sobrien	(if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
1625990286Sobrien			 (match_dup 1)
1626090286Sobrien			 (match_dup 2)))])
1626150650Sobrien
1626290286Sobrien(define_insn "*mindf_sse"
1626390286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1626490286Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
1626590286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym"))
1626690286Sobrien			 (match_dup 1)
1626790286Sobrien			 (match_dup 2)))]
1626890286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
1626990286Sobrien  "minsd\t{%2, %0|%0, %2}"
1627090286Sobrien  [(set_attr "type" "sse")
1627190286Sobrien   (set_attr "mode" "DF")])
1627250650Sobrien
1627390286Sobrien(define_expand "maxsf3"
1627490286Sobrien  [(parallel [
1627590286Sobrien     (set (match_operand:SF 0 "register_operand" "")
1627690286Sobrien	  (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
1627790286Sobrien			       (match_operand:SF 2 "nonimmediate_operand" ""))
1627890286Sobrien			   (match_dup 1)
1627990286Sobrien			   (match_dup 2)))
1628090286Sobrien     (clobber (reg:CC 17))])]
1628190286Sobrien  "TARGET_SSE"
1628290286Sobrien  "#")
1628350650Sobrien
1628490286Sobrien(define_insn "*maxsf"
1628590286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
1628690286Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
1628790286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
1628890286Sobrien			 (match_dup 1)
1628990286Sobrien			 (match_dup 2)))
1629090286Sobrien   (clobber (reg:CC 17))]
1629190286Sobrien  "TARGET_SSE && TARGET_IEEE_FP"
1629290286Sobrien  "#")
1629350650Sobrien
1629490286Sobrien(define_insn "*maxsf_nonieee"
1629590286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
1629696294Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
1629790286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
1629890286Sobrien			 (match_dup 1)
1629990286Sobrien			 (match_dup 2)))
1630090286Sobrien   (clobber (reg:CC 17))]
1630196294Sobrien  "TARGET_SSE && !TARGET_IEEE_FP
1630296294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1630390286Sobrien  "#")
1630450650Sobrien
1630590286Sobrien(define_split
1630690286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1630790286Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
1630890286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" ""))
1630990286Sobrien			 (match_operand:SF 3 "register_operand" "")
1631090286Sobrien			 (match_operand:SF 4 "nonimmediate_operand" "")))
1631190286Sobrien   (clobber (reg:CC 17))]
1631290286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1631390286Sobrien   && ((operands_match_p (operands[1], operands[3])
1631490286Sobrien	&& operands_match_p (operands[2], operands[4]))
1631590286Sobrien       || (operands_match_p (operands[1], operands[4])
1631690286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1631790286Sobrien  [(set (match_dup 0)
1631890286Sobrien	(if_then_else:SF (gt (match_dup 1)
1631990286Sobrien			     (match_dup 2))
1632090286Sobrien			 (match_dup 1)
1632190286Sobrien			 (match_dup 2)))])
1632250650Sobrien
1632390286Sobrien(define_split
1632490286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1632590286Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
1632690286Sobrien			     (match_operand:SF 2 "register_operand" ""))
1632790286Sobrien			 (match_operand:SF 3 "register_operand" "")
1632890286Sobrien			 (match_operand:SF 4 "register_operand" "")))
1632990286Sobrien   (clobber (reg:CC 17))]
1633090286Sobrien  "FP_REG_P (operands[0]) && reload_completed
1633190286Sobrien   && ((operands_match_p (operands[1], operands[3])
1633290286Sobrien	&& operands_match_p (operands[2], operands[4]))
1633390286Sobrien       || (operands_match_p (operands[1], operands[4])
1633490286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1633590286Sobrien  [(set (reg:CCFP 17)
1633690286Sobrien	(compare:CCFP (match_dup 1)
1633790286Sobrien		      (match_dup 2)))
1633890286Sobrien   (set (match_dup 0)
1633990286Sobrien	(if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
1634090286Sobrien			 (match_dup 1)
1634190286Sobrien			 (match_dup 2)))])
1634290286Sobrien
1634390286Sobrien(define_insn "*maxsf_sse"
1634490286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1634590286Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
1634690286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm"))
1634790286Sobrien			 (match_dup 1)
1634890286Sobrien			 (match_dup 2)))]
1634990286Sobrien  "TARGET_SSE && reload_completed"
1635090286Sobrien  "maxss\t{%2, %0|%0, %2}"
1635190286Sobrien  [(set_attr "type" "sse")
1635290286Sobrien   (set_attr "mode" "SF")])
1635390286Sobrien
1635490286Sobrien(define_expand "maxdf3"
1635590286Sobrien  [(parallel [
1635690286Sobrien     (set (match_operand:DF 0 "register_operand" "")
1635790286Sobrien	  (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
1635890286Sobrien			       (match_operand:DF 2 "nonimmediate_operand" ""))
1635990286Sobrien			   (match_dup 1)
1636090286Sobrien			   (match_dup 2)))
1636190286Sobrien     (clobber (reg:CC 17))])]
1636290286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH"
1636350650Sobrien  "#")
1636450650Sobrien
1636590286Sobrien(define_insn "*maxdf"
1636690286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
1636790286Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
1636890286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
1636990286Sobrien			 (match_dup 1)
1637090286Sobrien			 (match_dup 2)))
1637190286Sobrien   (clobber (reg:CC 17))]
1637290286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
1637350650Sobrien  "#")
1637450650Sobrien
1637590286Sobrien(define_insn "*maxdf_nonieee"
1637690286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
1637796294Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
1637890286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
1637990286Sobrien			 (match_dup 1)
1638090286Sobrien			 (match_dup 2)))
1638190286Sobrien   (clobber (reg:CC 17))]
1638296294Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
1638396294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1638490286Sobrien  "#")
1638590286Sobrien
1638650650Sobrien(define_split
1638752296Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1638890286Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
1638990286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" ""))
1639090286Sobrien			 (match_operand:DF 3 "register_operand" "")
1639190286Sobrien			 (match_operand:DF 4 "nonimmediate_operand" "")))
1639290286Sobrien   (clobber (reg:CC 17))]
1639390286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1639490286Sobrien   && ((operands_match_p (operands[1], operands[3])
1639590286Sobrien	&& operands_match_p (operands[2], operands[4]))
1639690286Sobrien       || (operands_match_p (operands[1], operands[4])
1639790286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1639890286Sobrien  [(set (match_dup 0)
1639990286Sobrien	(if_then_else:DF (gt (match_dup 1)
1640090286Sobrien			     (match_dup 2))
1640190286Sobrien			 (match_dup 1)
1640290286Sobrien			 (match_dup 2)))])
1640350650Sobrien
1640450650Sobrien(define_split
1640552296Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1640690286Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
1640790286Sobrien			     (match_operand:DF 2 "register_operand" ""))
1640890286Sobrien			 (match_operand:DF 3 "register_operand" "")
1640990286Sobrien			 (match_operand:DF 4 "register_operand" "")))
1641090286Sobrien   (clobber (reg:CC 17))]
1641190286Sobrien  "FP_REG_P (operands[0]) && reload_completed
1641290286Sobrien   && ((operands_match_p (operands[1], operands[3])
1641390286Sobrien	&& operands_match_p (operands[2], operands[4]))
1641490286Sobrien       || (operands_match_p (operands[1], operands[4])
1641590286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1641690286Sobrien  [(set (reg:CCFP 17)
1641790286Sobrien	(compare:CCFP (match_dup 1)
1641890286Sobrien		      (match_dup 2)))
1641950650Sobrien   (set (match_dup 0)
1642090286Sobrien	(if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
1642190286Sobrien			 (match_dup 1)
1642290286Sobrien			 (match_dup 2)))])
1642350650Sobrien
1642490286Sobrien(define_insn "*maxdf_sse"
1642590286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1642690286Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
1642790286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym"))
1642890286Sobrien			 (match_dup 1)
1642990286Sobrien			 (match_dup 2)))]
1643090286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
1643190286Sobrien  "maxsd\t{%2, %0|%0, %2}"
1643290286Sobrien  [(set_attr "type" "sse")
1643390286Sobrien   (set_attr "mode" "DF")])
1643490286Sobrien
1643590286Sobrien;; Misc patterns (?)
1643650650Sobrien
1643790286Sobrien;; This pattern exists to put a dependency on all ebp-based memory accesses.
1643890286Sobrien;; Otherwise there will be nothing to keep
1643990286Sobrien;; 
1644090286Sobrien;; [(set (reg ebp) (reg esp))]
1644190286Sobrien;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
1644290286Sobrien;;  (clobber (eflags)]
1644390286Sobrien;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
1644490286Sobrien;;
1644590286Sobrien;; in proper program order.
1644690286Sobrien(define_expand "pro_epilogue_adjust_stack"
1644790286Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
1644890286Sobrien		   (plus:SI (match_operand:SI 1 "register_operand" "0,r")
1644990286Sobrien			    (match_operand:SI 2 "immediate_operand" "i,i")))
1645090286Sobrien	      (clobber (reg:CC 17))
1645190286Sobrien	      (clobber (mem:BLK (scratch)))])]
1645290286Sobrien ""
1645350650Sobrien{
1645490286Sobrien  if (TARGET_64BIT)
1645590286Sobrien    {
1645690286Sobrien      emit_insn (gen_pro_epilogue_adjust_stack_rex64
1645790286Sobrien		 (operands[0], operands[1], operands[2]));
1645890286Sobrien      DONE;
1645990286Sobrien    }
1646090286Sobrien})
1646150650Sobrien
1646290286Sobrien(define_insn "*pro_epilogue_adjust_stack_1"
1646390286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,r")
1646490286Sobrien	(plus:SI (match_operand:SI 1 "register_operand" "0,r")
1646590286Sobrien	         (match_operand:SI 2 "immediate_operand" "i,i")))
1646690286Sobrien   (clobber (reg:CC 17))
1646790286Sobrien   (clobber (mem:BLK (scratch)))]
1646890286Sobrien  "!TARGET_64BIT"
1646990286Sobrien{
1647090286Sobrien  switch (get_attr_type (insn))
1647190286Sobrien    {
1647290286Sobrien    case TYPE_IMOV:
1647390286Sobrien      return "mov{l}\t{%1, %0|%0, %1}";
1647450650Sobrien
1647590286Sobrien    case TYPE_ALU:
1647690286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
1647790286Sobrien          && (INTVAL (operands[2]) == 128
1647890286Sobrien	      || (INTVAL (operands[2]) < 0
1647990286Sobrien	          && INTVAL (operands[2]) != -128)))
1648090286Sobrien	{
1648190286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
1648290286Sobrien	  return "sub{l}\t{%2, %0|%0, %2}";
1648390286Sobrien	}
1648490286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
1648550650Sobrien
1648690286Sobrien    case TYPE_LEA:
1648790286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
1648890286Sobrien      return "lea{l}\t{%a2, %0|%0, %a2}";
1648990286Sobrien
1649090286Sobrien    default:
1649190286Sobrien      abort ();
1649290286Sobrien    }
1649390286Sobrien}
1649490286Sobrien  [(set (attr "type")
1649590286Sobrien	(cond [(eq_attr "alternative" "0")
1649690286Sobrien		 (const_string "alu")
1649790286Sobrien	       (match_operand:SI 2 "const0_operand" "")
1649890286Sobrien		 (const_string "imov")
1649990286Sobrien	      ]
1650090286Sobrien	      (const_string "lea")))
1650190286Sobrien   (set_attr "mode" "SI")])
1650290286Sobrien
1650390286Sobrien(define_insn "pro_epilogue_adjust_stack_rex64"
1650490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1650590286Sobrien	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
1650690286Sobrien		 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
1650790286Sobrien   (clobber (reg:CC 17))
1650890286Sobrien   (clobber (mem:BLK (scratch)))]
1650990286Sobrien  "TARGET_64BIT"
1651090286Sobrien{
1651190286Sobrien  switch (get_attr_type (insn))
1651250650Sobrien    {
1651390286Sobrien    case TYPE_IMOV:
1651490286Sobrien      return "mov{q}\t{%1, %0|%0, %1}";
1651550650Sobrien
1651690286Sobrien    case TYPE_ALU:
1651790286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
1651890286Sobrien          && (INTVAL (operands[2]) == 128
1651990286Sobrien	      || (INTVAL (operands[2]) < 0
1652090286Sobrien	          && INTVAL (operands[2]) != -128)))
1652190286Sobrien	{
1652290286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
1652390286Sobrien	  return "sub{q}\t{%2, %0|%0, %2}";
1652490286Sobrien	}
1652590286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
1652650650Sobrien
1652790286Sobrien    case TYPE_LEA:
1652890286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
1652990286Sobrien      return "lea{q}\t{%a2, %0|%0, %a2}";
1653050650Sobrien
1653150650Sobrien    default:
1653290286Sobrien      abort ();
1653350650Sobrien    }
1653490286Sobrien}
1653590286Sobrien  [(set (attr "type")
1653690286Sobrien	(cond [(eq_attr "alternative" "0")
1653790286Sobrien		 (const_string "alu")
1653890286Sobrien	       (match_operand:DI 2 "const0_operand" "")
1653990286Sobrien		 (const_string "imov")
1654090286Sobrien	      ]
1654190286Sobrien	      (const_string "lea")))
1654290286Sobrien   (set_attr "mode" "DI")])
1654350650Sobrien
1654490286Sobrien
1654590286Sobrien;; Placeholder for the conditional moves.  This one is split either to SSE
1654690286Sobrien;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
1654790286Sobrien;; fact is that compares supported by the cmp??ss instructions are exactly
1654890286Sobrien;; swapped of those supported by cmove sequence.
1654990286Sobrien;; The EQ/NE comparisons also needs bit care, since they are not directly
1655090286Sobrien;; supported by i387 comparisons and we do need to emit two conditional moves
1655190286Sobrien;; in tandem.
1655290286Sobrien
1655390286Sobrien(define_insn "sse_movsfcc"
1655490286Sobrien  [(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")
1655590286Sobrien	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
1655690286Sobrien			[(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")
1655790286Sobrien			 (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")])
1655890286Sobrien		      (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")
1655990286Sobrien		      (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")))
1656090286Sobrien   (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
1656190286Sobrien   (clobber (reg:CC 17))]
1656290286Sobrien  "TARGET_SSE
1656390286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
1656490286Sobrien   && (!TARGET_IEEE_FP
1656590286Sobrien       || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
1656650650Sobrien  "#")
1656750650Sobrien
1656890286Sobrien(define_insn "sse_movsfcc_eq"
1656990286Sobrien  [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
1657090286Sobrien	(if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
1657190286Sobrien			     (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
1657290286Sobrien		      (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
1657390286Sobrien		      (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
1657490286Sobrien   (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
1657590286Sobrien   (clobber (reg:CC 17))]
1657690286Sobrien  "TARGET_SSE
1657790286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1657850650Sobrien  "#")
1657950650Sobrien
1658090286Sobrien(define_insn "sse_movdfcc"
16581102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?f#Yr,?f#Yr,?r#Yf,?r#Yf,?r#Yf,?r#Yf")
1658290286Sobrien	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
16583102802Skan			[(match_operand:DF 4 "nonimmediate_operand" "0#fY,Y#fY,f#Y,f#Y,Ym#f,Ym#f,f#Y,f#Y,Ym#f,Ym#f")
16584102802Skan			 (match_operand:DF 5 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,f#Y,Y#f,Y#f,f#Y,f#Y,Y#f,Y#f")])
16585102802Skan		      (match_operand:DF 2 "nonimmediate_operand" "Y#fr,0#fr,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY,0#rY")
16586102802Skan		      (match_operand:DF 3 "nonimmediate_operand" "Y#fr,Y#fr,0#fY,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY")))
1658790286Sobrien   (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
1658890286Sobrien   (clobber (reg:CC 17))]
1658990286Sobrien  "TARGET_SSE2
1659090286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
1659190286Sobrien   && (!TARGET_IEEE_FP
1659290286Sobrien       || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
1659390286Sobrien  "#")
1659490286Sobrien
1659590286Sobrien(define_insn "sse_movdfcc_eq"
16596102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
16597102802Skan	(if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
16598102802Skan			     (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
16599102802Skan		      (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
16600102802Skan		      (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
1660190286Sobrien   (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
1660290286Sobrien   (clobber (reg:CC 17))]
1660390286Sobrien  "TARGET_SSE
1660490286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1660590286Sobrien  "#")
1660690286Sobrien
1660790286Sobrien;; For non-sse moves just expand the usual cmove sequence.
1660850650Sobrien(define_split
1660990286Sobrien  [(set (match_operand 0 "register_operand" "")
1661090286Sobrien	(if_then_else (match_operator 1 "comparison_operator"
1661190286Sobrien			[(match_operand 4 "nonimmediate_operand" "")
1661290286Sobrien			 (match_operand 5 "register_operand" "")])
1661390286Sobrien		      (match_operand 2 "nonimmediate_operand" "")
1661490286Sobrien		      (match_operand 3 "nonimmediate_operand" "")))
1661590286Sobrien   (clobber (match_operand 6 "" ""))
1661690286Sobrien   (clobber (reg:CC 17))]
1661790286Sobrien  "!SSE_REG_P (operands[0]) && reload_completed
1661890286Sobrien   && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
1661990286Sobrien  [(const_int 0)]
1662090286Sobrien{
1662190286Sobrien   ix86_compare_op0 = operands[5];
1662290286Sobrien   ix86_compare_op1 = operands[4];
1662390286Sobrien   operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
1662490286Sobrien				 VOIDmode, operands[5], operands[4]);
1662590286Sobrien   ix86_expand_fp_movcc (operands);
1662690286Sobrien   DONE;
1662790286Sobrien})
1662850650Sobrien
1662990286Sobrien;; Split SSE based conditional move into seqence:
1663090286Sobrien;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
1663190286Sobrien;; and   op2, op0   -  zero op2 if comparison was false
1663290286Sobrien;; nand  op0, op3   -  load op3 to op0 if comparison was false
1663390286Sobrien;; or	 op2, op0   -  get the non-zero one into the result.
1663450650Sobrien(define_split
1663590286Sobrien  [(set (match_operand 0 "register_operand" "")
1663690286Sobrien	(if_then_else (match_operator 1 "sse_comparison_operator"
1663790286Sobrien			[(match_operand 4 "register_operand" "")
1663890286Sobrien			 (match_operand 5 "nonimmediate_operand" "")])
1663990286Sobrien		      (match_operand 2 "register_operand" "")
1664090286Sobrien		      (match_operand 3 "register_operand" "")))
1664190286Sobrien   (clobber (match_operand 6 "" ""))
1664290286Sobrien   (clobber (reg:CC 17))]
1664390286Sobrien  "SSE_REG_P (operands[0]) && reload_completed"
1664490286Sobrien  [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
1664590286Sobrien   (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
1664690286Sobrien					    (subreg:TI (match_dup 4) 0)))
1664790286Sobrien   (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
1664890286Sobrien					    (subreg:TI (match_dup 3) 0)))
1664990286Sobrien   (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
1665090286Sobrien					    (subreg:TI (match_dup 7) 0)))]
1665190286Sobrien{
16652102802Skan  /* If op2 == op3, op3 will be clobbered before it is used.
16653102802Skan     This should be optimized out though.  */
16654102802Skan  if (operands_match_p (operands[2], operands[3]))
16655102802Skan    abort ();
1665690286Sobrien  PUT_MODE (operands[1], GET_MODE (operands[0]));
1665790286Sobrien  if (operands_match_p (operands[0], operands[4]))
1665890286Sobrien    operands[6] = operands[4], operands[7] = operands[2];
1665990286Sobrien  else
1666090286Sobrien    operands[6] = operands[2], operands[7] = operands[4];
1666190286Sobrien})
1666250650Sobrien
1666390286Sobrien;; Special case of conditional move we can handle effectivly.
1666490286Sobrien;; Do not brother with the integer/floating point case, since these are
1666590286Sobrien;; bot considerably slower, unlike in the generic case.
1666690286Sobrien(define_insn "*sse_movsfcc_const0_1"
16667102802Skan  [(set (match_operand:SF 0 "register_operand" "=&x")
1666890286Sobrien	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
1666990286Sobrien			[(match_operand:SF 4 "register_operand" "0")
1667090286Sobrien			 (match_operand:SF 5 "nonimmediate_operand" "xm")])
1667190286Sobrien		      (match_operand:SF 2 "register_operand" "x")
1667290286Sobrien		      (match_operand:SF 3 "const0_operand" "X")))]
1667390286Sobrien  "TARGET_SSE"
1667490286Sobrien  "#")
1667550650Sobrien
1667690286Sobrien(define_insn "*sse_movsfcc_const0_2"
16677102802Skan  [(set (match_operand:SF 0 "register_operand" "=&x")
1667890286Sobrien	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
1667990286Sobrien			[(match_operand:SF 4 "register_operand" "0")
1668090286Sobrien			 (match_operand:SF 5 "nonimmediate_operand" "xm")])
1668190286Sobrien		      (match_operand:SF 2 "const0_operand" "X")
1668290286Sobrien		      (match_operand:SF 3 "register_operand" "x")))]
1668390286Sobrien  "TARGET_SSE"
1668490286Sobrien  "#")
1668550650Sobrien
1668690286Sobrien(define_insn "*sse_movsfcc_const0_3"
16687102802Skan  [(set (match_operand:SF 0 "register_operand" "=&x")
1668890286Sobrien	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
1668990286Sobrien			[(match_operand:SF 4 "nonimmediate_operand" "xm")
1669090286Sobrien			 (match_operand:SF 5 "register_operand" "0")])
1669190286Sobrien		      (match_operand:SF 2 "register_operand" "x")
1669290286Sobrien		      (match_operand:SF 3 "const0_operand" "X")))]
1669390286Sobrien  "TARGET_SSE"
1669490286Sobrien  "#")
1669550650Sobrien
1669690286Sobrien(define_insn "*sse_movsfcc_const0_4"
16697102802Skan  [(set (match_operand:SF 0 "register_operand" "=&x")
1669890286Sobrien	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
1669990286Sobrien			[(match_operand:SF 4 "nonimmediate_operand" "xm")
1670090286Sobrien			 (match_operand:SF 5 "register_operand" "0")])
1670190286Sobrien		      (match_operand:SF 2 "const0_operand" "X")
1670290286Sobrien		      (match_operand:SF 3 "register_operand" "x")))]
1670390286Sobrien  "TARGET_SSE"
1670450650Sobrien  "#")
1670550650Sobrien
1670690286Sobrien(define_insn "*sse_movdfcc_const0_1"
16707102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y")
16708102802Skan	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
16709102802Skan			[(match_operand:DF 4 "register_operand" "0")
16710102802Skan			 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
16711102802Skan		      (match_operand:DF 2 "register_operand" "Y")
16712102802Skan		      (match_operand:DF 3 "const0_operand" "X")))]
1671390286Sobrien  "TARGET_SSE2"
1671450650Sobrien  "#")
1671550650Sobrien
1671690286Sobrien(define_insn "*sse_movdfcc_const0_2"
16717102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y")
16718102802Skan	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
16719102802Skan			[(match_operand:DF 4 "register_operand" "0")
16720102802Skan			 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
16721102802Skan		      (match_operand:DF 2 "const0_operand" "X")
16722102802Skan		      (match_operand:DF 3 "register_operand" "Y")))]
1672390286Sobrien  "TARGET_SSE2"
1672490286Sobrien  "#")
1672550650Sobrien
1672690286Sobrien(define_insn "*sse_movdfcc_const0_3"
16727102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y")
16728102802Skan	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16729102802Skan			[(match_operand:DF 4 "nonimmediate_operand" "Ym")
16730102802Skan			 (match_operand:DF 5 "register_operand" "0")])
16731102802Skan		      (match_operand:DF 2 "register_operand" "Y")
16732102802Skan		      (match_operand:DF 3 "const0_operand" "X")))]
1673390286Sobrien  "TARGET_SSE2"
1673490286Sobrien  "#")
1673550650Sobrien
1673690286Sobrien(define_insn "*sse_movdfcc_const0_4"
16737102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y")
16738102802Skan	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16739102802Skan			[(match_operand:DF 4 "nonimmediate_operand" "Ym")
16740102802Skan			 (match_operand:DF 5 "register_operand" "0")])
16741102802Skan		      (match_operand:DF 2 "const0_operand" "X")
16742102802Skan		      (match_operand:DF 3 "register_operand" "Y")))]
1674390286Sobrien  "TARGET_SSE2"
1674490286Sobrien  "#")
1674550650Sobrien
1674690286Sobrien(define_split
1674790286Sobrien  [(set (match_operand 0 "register_operand" "")
1674890286Sobrien	(if_then_else (match_operator 1 "comparison_operator"
1674990286Sobrien			[(match_operand 4 "register_operand" "")
1675090286Sobrien			 (match_operand 5 "nonimmediate_operand" "")])
1675190286Sobrien		      (match_operand 2 "nonmemory_operand" "")
1675290286Sobrien		      (match_operand 3 "nonmemory_operand" "")))]
1675390286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1675490286Sobrien   && (const0_operand (operands[2], GET_MODE (operands[0]))
1675590286Sobrien       || const0_operand (operands[3], GET_MODE (operands[0])))"
1675690286Sobrien  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
1675790286Sobrien   (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
1675890286Sobrien					    (subreg:TI (match_dup 7) 0)))]
1675990286Sobrien{
1676090286Sobrien  PUT_MODE (operands[1], GET_MODE (operands[0]));
1676190286Sobrien  if (!sse_comparison_operator (operands[1], VOIDmode))
1676290286Sobrien    {
1676390286Sobrien      rtx tmp = operands[5];
1676490286Sobrien      operands[5] = operands[4];
1676590286Sobrien      operands[4] = tmp;
1676690286Sobrien      PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
1676790286Sobrien    }
1676890286Sobrien  if (const0_operand (operands[2], GET_MODE (operands[0])))
1676990286Sobrien    {
1677090286Sobrien      operands[7] = operands[3];
1677190286Sobrien      operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
1677290286Sobrien							 0));
1677390286Sobrien    }
1677490286Sobrien  else
1677590286Sobrien    {
1677690286Sobrien      operands[7] = operands[2];
1677790286Sobrien      operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
1677890286Sobrien    }
1677990286Sobrien})
1678050650Sobrien
1678190286Sobrien(define_expand "allocate_stack_worker"
1678290286Sobrien  [(match_operand:SI 0 "register_operand" "")]
1678390286Sobrien  "TARGET_STACK_PROBE"
1678490286Sobrien{
1678590286Sobrien  if (TARGET_64BIT)
1678690286Sobrien    emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
1678790286Sobrien  else
1678890286Sobrien    emit_insn (gen_allocate_stack_worker_1 (operands[0]));
1678990286Sobrien  DONE;
1679090286Sobrien})
1679150650Sobrien
1679290286Sobrien(define_insn "allocate_stack_worker_1"
1679350650Sobrien  [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
1679450650Sobrien   (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
1679590286Sobrien   (clobber (match_dup 0))
1679690286Sobrien   (clobber (reg:CC 17))]
1679790286Sobrien  "!TARGET_64BIT && TARGET_STACK_PROBE"
1679890286Sobrien  "call\t__alloca"
1679990286Sobrien  [(set_attr "type" "multi")
1680090286Sobrien   (set_attr "length" "5")])
1680150650Sobrien
1680290286Sobrien(define_insn "allocate_stack_worker_rex64"
1680390286Sobrien  [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] 3)
1680490286Sobrien   (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
1680590286Sobrien   (clobber (match_dup 0))
1680690286Sobrien   (clobber (reg:CC 17))]
1680790286Sobrien  "TARGET_64BIT && TARGET_STACK_PROBE"
1680890286Sobrien  "call\t__alloca"
1680990286Sobrien  [(set_attr "type" "multi")
1681090286Sobrien   (set_attr "length" "5")])
1681190286Sobrien
1681250650Sobrien(define_expand "allocate_stack"
1681390286Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
1681490286Sobrien		   (minus:SI (reg:SI 7)
1681590286Sobrien			     (match_operand:SI 1 "general_operand" "")))
1681690286Sobrien	      (clobber (reg:CC 17))])
1681790286Sobrien   (parallel [(set (reg:SI 7)
1681890286Sobrien		   (minus:SI (reg:SI 7) (match_dup 1)))
1681990286Sobrien	      (clobber (reg:CC 17))])]
1682090286Sobrien  "TARGET_STACK_PROBE"
1682150650Sobrien{
1682250650Sobrien#ifdef CHECK_STACK_LIMIT
1682350650Sobrien  if (GET_CODE (operands[1]) == CONST_INT
1682450650Sobrien      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
1682550650Sobrien    emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
1682650650Sobrien			   operands[1]));
1682750650Sobrien  else 
1682850650Sobrien#endif
1682950650Sobrien    emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
1683050650Sobrien							    operands[1])));
1683150650Sobrien
1683250650Sobrien  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
1683350650Sobrien  DONE;
1683490286Sobrien})
1683550650Sobrien
1683690286Sobrien(define_expand "builtin_setjmp_receiver"
1683790286Sobrien  [(label_ref (match_operand 0 "" ""))]
1683890286Sobrien  "!TARGET_64BIT && flag_pic"
1683950650Sobrien{
1684090286Sobrien  load_pic_register ();
1684156391Sobrien  DONE;
1684290286Sobrien})
1684390286Sobrien
1684490286Sobrien;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
1684556391Sobrien
1684690286Sobrien(define_split
1684790286Sobrien  [(set (match_operand 0 "register_operand" "")
1684890286Sobrien	(match_operator 3 "promotable_binary_operator"
1684990286Sobrien	   [(match_operand 1 "register_operand" "")
1685090286Sobrien	    (match_operand 2 "aligned_operand" "")]))
1685190286Sobrien   (clobber (reg:CC 17))]
1685290286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
1685390286Sobrien   && ((GET_MODE (operands[0]) == HImode 
1685490286Sobrien	&& (!optimize_size || GET_CODE (operands[2]) != CONST_INT
1685590286Sobrien	    || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
1685690286Sobrien       || (GET_MODE (operands[0]) == QImode 
1685790286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1685890286Sobrien  [(parallel [(set (match_dup 0)
1685990286Sobrien		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
1686090286Sobrien	      (clobber (reg:CC 17))])]
1686190286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);
1686290286Sobrien   operands[1] = gen_lowpart (SImode, operands[1]);
1686390286Sobrien   if (GET_CODE (operands[3]) != ASHIFT)
1686490286Sobrien     operands[2] = gen_lowpart (SImode, operands[2]);
1686590286Sobrien   PUT_MODE (operands[3], SImode);")
1686690286Sobrien
1686790286Sobrien(define_split
1686890286Sobrien  [(set (reg 17)
1686990286Sobrien	(compare (and (match_operand 1 "aligned_operand" "")
1687090286Sobrien		      (match_operand 2 "const_int_operand" ""))
1687190286Sobrien		 (const_int 0)))
1687290286Sobrien   (set (match_operand 0 "register_operand" "")
1687390286Sobrien	(and (match_dup 1) (match_dup 2)))]
1687490286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
1687590286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
1687690286Sobrien   && (GET_MODE (operands[0]) == HImode
1687790286Sobrien       || (GET_MODE (operands[0]) == QImode 
1687890286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1687990286Sobrien  [(parallel [(set (reg:CCNO 17)
1688090286Sobrien		   (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
1688190286Sobrien			         (const_int 0)))
1688290286Sobrien	      (set (match_dup 0)
1688390286Sobrien		   (and:SI (match_dup 1) (match_dup 2)))])]
1688490286Sobrien  "operands[2]
1688590286Sobrien     = GEN_INT (trunc_int_for_mode (INTVAL (operands[2])
1688690286Sobrien				    & GET_MODE_MASK (GET_MODE (operands[0])),
1688790286Sobrien				    SImode));
1688890286Sobrien   operands[0] = gen_lowpart (SImode, operands[0]);
1688990286Sobrien   operands[1] = gen_lowpart (SImode, operands[1]);")
1689090286Sobrien
1689190286Sobrien(define_split
1689290286Sobrien  [(set (reg 17)
1689390286Sobrien	(compare (and (match_operand 0 "aligned_operand" "")
1689490286Sobrien		      (match_operand 1 "const_int_operand" ""))
1689590286Sobrien		 (const_int 0)))]
1689690286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
1689790286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
1689890286Sobrien   && (GET_MODE (operands[0]) == HImode
1689990286Sobrien       || (GET_MODE (operands[0]) == QImode 
1690090286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1690190286Sobrien  [(set (reg:CCNO 17)
1690290286Sobrien	(compare:CCNO (and:SI (match_dup 0) (match_dup 1))
1690390286Sobrien		      (const_int 0)))]
1690490286Sobrien  "operands[1]
1690590286Sobrien     = GEN_INT (trunc_int_for_mode (INTVAL (operands[1])
1690690286Sobrien				    & GET_MODE_MASK (GET_MODE (operands[0])),
1690790286Sobrien				    SImode));
1690890286Sobrien   operands[0] = gen_lowpart (SImode, operands[0]);")
1690990286Sobrien
1691090286Sobrien(define_split
1691190286Sobrien  [(set (match_operand 0 "register_operand" "")
1691290286Sobrien	(neg (match_operand 1 "register_operand" "")))
1691390286Sobrien   (clobber (reg:CC 17))]
1691490286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
1691590286Sobrien   && (GET_MODE (operands[0]) == HImode
1691690286Sobrien       || (GET_MODE (operands[0]) == QImode 
1691790286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1691890286Sobrien  [(parallel [(set (match_dup 0)
1691990286Sobrien		   (neg:SI (match_dup 1)))
1692090286Sobrien	      (clobber (reg:CC 17))])]
1692190286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);
1692290286Sobrien   operands[1] = gen_lowpart (SImode, operands[1]);")
1692390286Sobrien
1692490286Sobrien(define_split
1692590286Sobrien  [(set (match_operand 0 "register_operand" "")
1692690286Sobrien	(not (match_operand 1 "register_operand" "")))]
1692790286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
1692890286Sobrien   && (GET_MODE (operands[0]) == HImode
1692990286Sobrien       || (GET_MODE (operands[0]) == QImode 
1693090286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1693190286Sobrien  [(set (match_dup 0)
1693290286Sobrien	(not:SI (match_dup 1)))]
1693390286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);
1693490286Sobrien   operands[1] = gen_lowpart (SImode, operands[1]);")
1693590286Sobrien
1693690286Sobrien(define_split 
1693790286Sobrien  [(set (match_operand 0 "register_operand" "")
1693890286Sobrien	(if_then_else (match_operator 1 "comparison_operator" 
1693990286Sobrien				[(reg 17) (const_int 0)])
1694090286Sobrien		      (match_operand 2 "register_operand" "")
1694190286Sobrien		      (match_operand 3 "register_operand" "")))]
1694290286Sobrien  "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
1694390286Sobrien   && (GET_MODE (operands[0]) == HImode
1694490286Sobrien       || (GET_MODE (operands[0]) == QImode 
1694590286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1694690286Sobrien  [(set (match_dup 0)
1694790286Sobrien	(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
1694890286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);
1694990286Sobrien   operands[2] = gen_lowpart (SImode, operands[2]);
1695090286Sobrien   operands[3] = gen_lowpart (SImode, operands[3]);")
1695190286Sobrien			
1695290286Sobrien
1695390286Sobrien;; RTL Peephole optimizations, run before sched2.  These primarily look to
1695490286Sobrien;; transform a complex memory operation into two memory to register operations.
1695590286Sobrien
1695690286Sobrien;; Don't push memory operands
1695790286Sobrien(define_peephole2
1695890286Sobrien  [(set (match_operand:SI 0 "push_operand" "")
1695990286Sobrien	(match_operand:SI 1 "memory_operand" ""))
1696090286Sobrien   (match_scratch:SI 2 "r")]
1696190286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1696290286Sobrien  [(set (match_dup 2) (match_dup 1))
1696390286Sobrien   (set (match_dup 0) (match_dup 2))]
1696490286Sobrien  "")
1696590286Sobrien
1696690286Sobrien(define_peephole2
1696790286Sobrien  [(set (match_operand:DI 0 "push_operand" "")
1696890286Sobrien	(match_operand:DI 1 "memory_operand" ""))
1696990286Sobrien   (match_scratch:DI 2 "r")]
1697090286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1697190286Sobrien  [(set (match_dup 2) (match_dup 1))
1697290286Sobrien   (set (match_dup 0) (match_dup 2))]
1697390286Sobrien  "")
1697490286Sobrien
1697590286Sobrien;; We need to handle SFmode only, because DFmode and XFmode is split to
1697690286Sobrien;; SImode pushes.
1697790286Sobrien(define_peephole2
1697890286Sobrien  [(set (match_operand:SF 0 "push_operand" "")
1697990286Sobrien	(match_operand:SF 1 "memory_operand" ""))
1698090286Sobrien   (match_scratch:SF 2 "r")]
1698190286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1698290286Sobrien  [(set (match_dup 2) (match_dup 1))
1698390286Sobrien   (set (match_dup 0) (match_dup 2))]
1698490286Sobrien  "")
1698590286Sobrien
1698690286Sobrien(define_peephole2
1698790286Sobrien  [(set (match_operand:HI 0 "push_operand" "")
1698890286Sobrien	(match_operand:HI 1 "memory_operand" ""))
1698990286Sobrien   (match_scratch:HI 2 "r")]
1699090286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1699190286Sobrien  [(set (match_dup 2) (match_dup 1))
1699290286Sobrien   (set (match_dup 0) (match_dup 2))]
1699390286Sobrien  "")
1699490286Sobrien
1699590286Sobrien(define_peephole2
1699690286Sobrien  [(set (match_operand:QI 0 "push_operand" "")
1699790286Sobrien	(match_operand:QI 1 "memory_operand" ""))
1699890286Sobrien   (match_scratch:QI 2 "q")]
1699990286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1700090286Sobrien  [(set (match_dup 2) (match_dup 1))
1700190286Sobrien   (set (match_dup 0) (match_dup 2))]
1700290286Sobrien  "")
1700390286Sobrien
1700490286Sobrien;; Don't move an immediate directly to memory when the instruction
1700590286Sobrien;; gets too big.
1700690286Sobrien(define_peephole2
1700790286Sobrien  [(match_scratch:SI 1 "r")
1700890286Sobrien   (set (match_operand:SI 0 "memory_operand" "")
1700990286Sobrien        (const_int 0))]
1701090286Sobrien  "! optimize_size
1701190286Sobrien   && ! TARGET_USE_MOV0
1701290286Sobrien   && TARGET_SPLIT_LONG_MOVES
1701390286Sobrien   && get_attr_length (insn) >= ix86_cost->large_insn
1701490286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1701590286Sobrien  [(parallel [(set (match_dup 1) (const_int 0))
1701690286Sobrien	      (clobber (reg:CC 17))])
1701790286Sobrien   (set (match_dup 0) (match_dup 1))]
1701890286Sobrien  "")
1701990286Sobrien
1702090286Sobrien(define_peephole2
1702190286Sobrien  [(match_scratch:HI 1 "r")
1702290286Sobrien   (set (match_operand:HI 0 "memory_operand" "")
1702390286Sobrien        (const_int 0))]
1702490286Sobrien  "! optimize_size
1702590286Sobrien   && ! TARGET_USE_MOV0
1702690286Sobrien   && TARGET_SPLIT_LONG_MOVES
1702790286Sobrien   && get_attr_length (insn) >= ix86_cost->large_insn
1702890286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1702990286Sobrien  [(parallel [(set (match_dup 2) (const_int 0))
1703090286Sobrien	      (clobber (reg:CC 17))])
1703190286Sobrien   (set (match_dup 0) (match_dup 1))]
1703290286Sobrien  "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
1703390286Sobrien
1703490286Sobrien(define_peephole2
1703590286Sobrien  [(match_scratch:QI 1 "q")
1703690286Sobrien   (set (match_operand:QI 0 "memory_operand" "")
1703790286Sobrien        (const_int 0))]
1703890286Sobrien  "! optimize_size
1703990286Sobrien   && ! TARGET_USE_MOV0
1704090286Sobrien   && TARGET_SPLIT_LONG_MOVES
1704190286Sobrien   && get_attr_length (insn) >= ix86_cost->large_insn
1704290286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1704390286Sobrien  [(parallel [(set (match_dup 2) (const_int 0))
1704490286Sobrien	      (clobber (reg:CC 17))])
1704590286Sobrien   (set (match_dup 0) (match_dup 1))]
1704690286Sobrien  "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
1704790286Sobrien
1704890286Sobrien(define_peephole2
1704990286Sobrien  [(match_scratch:SI 2 "r")
1705090286Sobrien   (set (match_operand:SI 0 "memory_operand" "")
1705190286Sobrien        (match_operand:SI 1 "immediate_operand" ""))]
1705290286Sobrien  "! optimize_size
1705390286Sobrien   && get_attr_length (insn) >= ix86_cost->large_insn
1705490286Sobrien   && TARGET_SPLIT_LONG_MOVES"
1705590286Sobrien  [(set (match_dup 2) (match_dup 1))
1705690286Sobrien   (set (match_dup 0) (match_dup 2))]
1705790286Sobrien  "")
1705890286Sobrien
1705990286Sobrien(define_peephole2
1706090286Sobrien  [(match_scratch:HI 2 "r")
1706190286Sobrien   (set (match_operand:HI 0 "memory_operand" "")
1706290286Sobrien        (match_operand:HI 1 "immediate_operand" ""))]
1706390286Sobrien  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
1706490286Sobrien  && TARGET_SPLIT_LONG_MOVES"
1706590286Sobrien  [(set (match_dup 2) (match_dup 1))
1706690286Sobrien   (set (match_dup 0) (match_dup 2))]
1706790286Sobrien  "")
1706890286Sobrien
1706990286Sobrien(define_peephole2
1707090286Sobrien  [(match_scratch:QI 2 "q")
1707190286Sobrien   (set (match_operand:QI 0 "memory_operand" "")
1707290286Sobrien        (match_operand:QI 1 "immediate_operand" ""))]
1707390286Sobrien  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
1707490286Sobrien  && TARGET_SPLIT_LONG_MOVES"
1707590286Sobrien  [(set (match_dup 2) (match_dup 1))
1707690286Sobrien   (set (match_dup 0) (match_dup 2))]
1707790286Sobrien  "")
1707890286Sobrien
1707990286Sobrien;; Don't compare memory with zero, load and use a test instead.
1708090286Sobrien(define_peephole2
1708190286Sobrien  [(set (reg 17)
1708290286Sobrien	(compare (match_operand:SI 0 "memory_operand" "")
1708390286Sobrien	         (const_int 0)))
1708490286Sobrien   (match_scratch:SI 3 "r")]
1708590286Sobrien  "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
1708690286Sobrien  [(set (match_dup 3) (match_dup 0))
1708790286Sobrien   (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
1708890286Sobrien  "")
1708990286Sobrien
1709090286Sobrien;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
1709190286Sobrien;; Don't split NOTs with a displacement operand, because resulting XOR
1709290286Sobrien;; will not be pariable anyway.
1709390286Sobrien;;
1709490286Sobrien;; On AMD K6, NOT is vector decoded with memory operand that can not be
1709590286Sobrien;; represented using a modRM byte.  The XOR replacement is long decoded,
1709690286Sobrien;; so this split helps here as well.
1709790286Sobrien;;
1709890286Sobrien;; Note: Can't do this as a regular split because we can't get proper
1709990286Sobrien;; lifetime information then.
1710090286Sobrien
1710190286Sobrien(define_peephole2
1710290286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1710390286Sobrien	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
1710490286Sobrien  "!optimize_size
1710590286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)
1710690286Sobrien   && ((TARGET_PENTIUM 
1710790286Sobrien        && (GET_CODE (operands[0]) != MEM
1710890286Sobrien            || !memory_displacement_operand (operands[0], SImode)))
1710990286Sobrien       || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
1711090286Sobrien  [(parallel [(set (match_dup 0)
1711190286Sobrien		   (xor:SI (match_dup 1) (const_int -1)))
1711290286Sobrien	      (clobber (reg:CC 17))])]
1711390286Sobrien  "")
1711490286Sobrien
1711590286Sobrien(define_peephole2
1711690286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1711790286Sobrien	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
1711890286Sobrien  "!optimize_size
1711990286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)
1712090286Sobrien   && ((TARGET_PENTIUM 
1712190286Sobrien        && (GET_CODE (operands[0]) != MEM
1712290286Sobrien            || !memory_displacement_operand (operands[0], HImode)))
1712390286Sobrien       || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
1712490286Sobrien  [(parallel [(set (match_dup 0)
1712590286Sobrien		   (xor:HI (match_dup 1) (const_int -1)))
1712690286Sobrien	      (clobber (reg:CC 17))])]
1712790286Sobrien  "")
1712890286Sobrien
1712990286Sobrien(define_peephole2
1713090286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1713190286Sobrien	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
1713290286Sobrien  "!optimize_size
1713390286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)
1713490286Sobrien   && ((TARGET_PENTIUM 
1713590286Sobrien        && (GET_CODE (operands[0]) != MEM
1713690286Sobrien            || !memory_displacement_operand (operands[0], QImode)))
1713790286Sobrien       || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
1713890286Sobrien  [(parallel [(set (match_dup 0)
1713990286Sobrien		   (xor:QI (match_dup 1) (const_int -1)))
1714090286Sobrien	      (clobber (reg:CC 17))])]
1714190286Sobrien  "")
1714290286Sobrien
1714390286Sobrien;; Non pairable "test imm, reg" instructions can be translated to
1714490286Sobrien;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
1714590286Sobrien;; byte opcode instead of two, have a short form for byte operands),
1714690286Sobrien;; so do it for other CPUs as well.  Given that the value was dead,
1714790286Sobrien;; this should not create any new dependencies.  Pass on the sub-word
1714890286Sobrien;; versions if we're concerned about partial register stalls.
1714990286Sobrien
1715090286Sobrien(define_peephole2
1715190286Sobrien  [(set (reg 17)
1715290286Sobrien	(compare (and:SI (match_operand:SI 0 "register_operand" "")
1715390286Sobrien			 (match_operand:SI 1 "immediate_operand" ""))
1715490286Sobrien		 (const_int 0)))]
1715590286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
1715690286Sobrien   && (true_regnum (operands[0]) != 0
1715790286Sobrien       || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
1715890286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1715990286Sobrien  [(parallel
1716090286Sobrien     [(set (reg:CCNO 17)
1716190286Sobrien	   (compare:CCNO (and:SI (match_dup 0)
1716290286Sobrien			         (match_dup 1))
1716390286Sobrien		         (const_int 0)))
1716490286Sobrien      (set (match_dup 0)
1716590286Sobrien	   (and:SI (match_dup 0) (match_dup 1)))])]
1716690286Sobrien  "")
1716790286Sobrien
1716890286Sobrien;; We don't need to handle HImode case, because it will be promoted to SImode
1716990286Sobrien;; on ! TARGET_PARTIAL_REG_STALL
1717090286Sobrien
1717190286Sobrien(define_peephole2
1717290286Sobrien  [(set (reg 17)
1717390286Sobrien	(compare (and:QI (match_operand:QI 0 "register_operand" "")
1717490286Sobrien			 (match_operand:QI 1 "immediate_operand" ""))
1717590286Sobrien		 (const_int 0)))]
1717690286Sobrien  "! TARGET_PARTIAL_REG_STALL
1717790286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
1717890286Sobrien   && true_regnum (operands[0]) != 0
1717990286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1718090286Sobrien  [(parallel
1718190286Sobrien     [(set (reg:CCNO 17)
1718290286Sobrien	   (compare:CCNO (and:QI (match_dup 0)
1718390286Sobrien 			         (match_dup 1))
1718490286Sobrien		         (const_int 0)))
1718590286Sobrien      (set (match_dup 0)
1718690286Sobrien	   (and:QI (match_dup 0) (match_dup 1)))])]
1718790286Sobrien  "")
1718890286Sobrien
1718990286Sobrien(define_peephole2
1719090286Sobrien  [(set (reg 17)
1719190286Sobrien	(compare
1719290286Sobrien	  (and:SI
1719390286Sobrien	    (zero_extract:SI
1719490286Sobrien	      (match_operand 0 "ext_register_operand" "")
1719590286Sobrien	      (const_int 8)
1719690286Sobrien	      (const_int 8))
1719790286Sobrien	    (match_operand 1 "const_int_operand" ""))
1719890286Sobrien	  (const_int 0)))]
1719990286Sobrien  "! TARGET_PARTIAL_REG_STALL
1720090286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
1720190286Sobrien   && true_regnum (operands[0]) != 0
1720290286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1720390286Sobrien  [(parallel [(set (reg:CCNO 17)
1720490286Sobrien		   (compare:CCNO
1720590286Sobrien		       (and:SI
1720690286Sobrien			 (zero_extract:SI
1720790286Sobrien			 (match_dup 0)
1720890286Sobrien			 (const_int 8)
1720990286Sobrien			 (const_int 8))
1721090286Sobrien			(match_dup 1))
1721190286Sobrien		   (const_int 0)))
1721290286Sobrien	      (set (zero_extract:SI (match_dup 0)
1721390286Sobrien				    (const_int 8)
1721490286Sobrien				    (const_int 8))
1721590286Sobrien		   (and:SI 
1721690286Sobrien		     (zero_extract:SI
1721790286Sobrien		       (match_dup 0)
1721890286Sobrien		       (const_int 8)
1721990286Sobrien		       (const_int 8))
1722090286Sobrien		     (match_dup 1)))])]
1722190286Sobrien  "")
1722290286Sobrien
1722390286Sobrien;; Don't do logical operations with memory inputs.
1722490286Sobrien(define_peephole2
1722590286Sobrien  [(match_scratch:SI 2 "r")
1722690286Sobrien   (parallel [(set (match_operand:SI 0 "register_operand" "")
1722790286Sobrien                   (match_operator:SI 3 "arith_or_logical_operator"
1722890286Sobrien                     [(match_dup 0)
1722990286Sobrien                      (match_operand:SI 1 "memory_operand" "")]))
1723090286Sobrien              (clobber (reg:CC 17))])]
1723190286Sobrien  "! optimize_size && ! TARGET_READ_MODIFY"
1723290286Sobrien  [(set (match_dup 2) (match_dup 1))
1723390286Sobrien   (parallel [(set (match_dup 0)
1723490286Sobrien                   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
1723590286Sobrien              (clobber (reg:CC 17))])]
1723690286Sobrien  "")
1723790286Sobrien
1723890286Sobrien(define_peephole2
1723990286Sobrien  [(match_scratch:SI 2 "r")
1724090286Sobrien   (parallel [(set (match_operand:SI 0 "register_operand" "")
1724190286Sobrien                   (match_operator:SI 3 "arith_or_logical_operator"
1724290286Sobrien                     [(match_operand:SI 1 "memory_operand" "")
1724390286Sobrien                      (match_dup 0)]))
1724490286Sobrien              (clobber (reg:CC 17))])]
1724590286Sobrien  "! optimize_size && ! TARGET_READ_MODIFY"
1724690286Sobrien  [(set (match_dup 2) (match_dup 1))
1724790286Sobrien   (parallel [(set (match_dup 0)
1724890286Sobrien                   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
1724990286Sobrien              (clobber (reg:CC 17))])]
1725090286Sobrien  "")
1725190286Sobrien
1725290286Sobrien; Don't do logical operations with memory outputs
1725390286Sobrien;
1725490286Sobrien; These two don't make sense for PPro/PII -- we're expanding a 4-uop
1725590286Sobrien; instruction into two 1-uop insns plus a 2-uop insn.  That last has
1725690286Sobrien; the same decoder scheduling characteristics as the original.
1725790286Sobrien
1725890286Sobrien(define_peephole2
1725990286Sobrien  [(match_scratch:SI 2 "r")
1726090286Sobrien   (parallel [(set (match_operand:SI 0 "memory_operand" "")
1726190286Sobrien                   (match_operator:SI 3 "arith_or_logical_operator"
1726290286Sobrien                     [(match_dup 0)
1726390286Sobrien                      (match_operand:SI 1 "nonmemory_operand" "")]))
1726490286Sobrien              (clobber (reg:CC 17))])]
1726590286Sobrien  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
1726690286Sobrien  [(set (match_dup 2) (match_dup 0))
1726790286Sobrien   (parallel [(set (match_dup 2)
1726890286Sobrien                   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
1726990286Sobrien              (clobber (reg:CC 17))])
1727090286Sobrien   (set (match_dup 0) (match_dup 2))]
1727190286Sobrien  "")
1727290286Sobrien
1727390286Sobrien(define_peephole2
1727490286Sobrien  [(match_scratch:SI 2 "r")
1727590286Sobrien   (parallel [(set (match_operand:SI 0 "memory_operand" "")
1727690286Sobrien                   (match_operator:SI 3 "arith_or_logical_operator"
1727790286Sobrien                     [(match_operand:SI 1 "nonmemory_operand" "")
1727890286Sobrien                      (match_dup 0)]))
1727990286Sobrien              (clobber (reg:CC 17))])]
1728090286Sobrien  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
1728190286Sobrien  [(set (match_dup 2) (match_dup 0))
1728290286Sobrien   (parallel [(set (match_dup 2)
1728390286Sobrien                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
1728490286Sobrien              (clobber (reg:CC 17))])
1728590286Sobrien   (set (match_dup 0) (match_dup 2))]
1728690286Sobrien  "")
1728790286Sobrien
1728890286Sobrien;; Attempt to always use XOR for zeroing registers.
1728990286Sobrien(define_peephole2
1729090286Sobrien  [(set (match_operand 0 "register_operand" "")
1729190286Sobrien	(const_int 0))]
1729290286Sobrien  "(GET_MODE (operands[0]) == QImode
1729390286Sobrien    || GET_MODE (operands[0]) == HImode
1729490286Sobrien    || GET_MODE (operands[0]) == SImode
1729590286Sobrien    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
1729690286Sobrien   && (! TARGET_USE_MOV0 || optimize_size)
1729790286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1729890286Sobrien  [(parallel [(set (match_dup 0) (const_int 0))
1729990286Sobrien	      (clobber (reg:CC 17))])]
1730090286Sobrien  "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
1730190286Sobrien			      true_regnum (operands[0]));")
1730290286Sobrien
1730390286Sobrien(define_peephole2
1730490286Sobrien  [(set (strict_low_part (match_operand 0 "register_operand" ""))
1730590286Sobrien	(const_int 0))]
1730690286Sobrien  "(GET_MODE (operands[0]) == QImode
1730790286Sobrien    || GET_MODE (operands[0]) == HImode)
1730890286Sobrien   && (! TARGET_USE_MOV0 || optimize_size)
1730990286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1731090286Sobrien  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
1731190286Sobrien	      (clobber (reg:CC 17))])])
1731290286Sobrien
1731390286Sobrien;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
1731490286Sobrien(define_peephole2
1731590286Sobrien  [(set (match_operand 0 "register_operand" "")
1731690286Sobrien	(const_int -1))]
1731790286Sobrien  "(GET_MODE (operands[0]) == HImode
1731890286Sobrien    || GET_MODE (operands[0]) == SImode 
1731990286Sobrien    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
1732090286Sobrien   && (optimize_size || TARGET_PENTIUM)
1732190286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1732290286Sobrien  [(parallel [(set (match_dup 0) (const_int -1))
1732390286Sobrien	      (clobber (reg:CC 17))])]
1732490286Sobrien  "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
1732590286Sobrien			      true_regnum (operands[0]));")
1732690286Sobrien
1732790286Sobrien;; Attempt to convert simple leas to adds. These can be created by
1732890286Sobrien;; move expanders.
1732990286Sobrien(define_peephole2
1733090286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1733190286Sobrien  	(plus:SI (match_dup 0)
1733290286Sobrien		 (match_operand:SI 1 "nonmemory_operand" "")))]
1733390286Sobrien  "peep2_regno_dead_p (0, FLAGS_REG)"
1733490286Sobrien  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
1733590286Sobrien	      (clobber (reg:CC 17))])]
1733690286Sobrien  "")
1733790286Sobrien
1733890286Sobrien(define_peephole2
1733990286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1734090286Sobrien  	(subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
1734190286Sobrien			    (match_operand:DI 2 "nonmemory_operand" "")) 0))]
1734290286Sobrien  "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
1734390286Sobrien  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
1734490286Sobrien	      (clobber (reg:CC 17))])]
1734590286Sobrien  "operands[2] = gen_lowpart (SImode, operands[2]);")
1734690286Sobrien
1734790286Sobrien(define_peephole2
1734890286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1734990286Sobrien  	(plus:DI (match_dup 0)
1735090286Sobrien		 (match_operand:DI 1 "x86_64_general_operand" "")))]
1735190286Sobrien  "peep2_regno_dead_p (0, FLAGS_REG)"
1735290286Sobrien  [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1735390286Sobrien	      (clobber (reg:CC 17))])]
1735490286Sobrien  "")
1735590286Sobrien
1735690286Sobrien(define_peephole2
1735790286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1735890286Sobrien  	(mult:SI (match_dup 0)
1735990286Sobrien		 (match_operand:SI 1 "const_int_operand" "")))]
1736090286Sobrien  "exact_log2 (INTVAL (operands[1])) >= 0
1736190286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1736290286Sobrien  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
1736390286Sobrien	      (clobber (reg:CC 17))])]
1736490286Sobrien  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
1736590286Sobrien
1736690286Sobrien(define_peephole2
1736790286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1736890286Sobrien  	(mult:DI (match_dup 0)
1736990286Sobrien		 (match_operand:DI 1 "const_int_operand" "")))]
1737090286Sobrien  "exact_log2 (INTVAL (operands[1])) >= 0
1737190286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1737290286Sobrien  [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
1737390286Sobrien	      (clobber (reg:CC 17))])]
1737490286Sobrien  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
1737590286Sobrien
1737690286Sobrien(define_peephole2
1737790286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1737890286Sobrien  	(subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
1737990286Sobrien		   (match_operand:DI 2 "const_int_operand" "")) 0))]
1738090286Sobrien  "exact_log2 (INTVAL (operands[1])) >= 0
1738190286Sobrien   && REGNO (operands[0]) == REGNO (operands[1])
1738290286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1738390286Sobrien  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
1738490286Sobrien	      (clobber (reg:CC 17))])]
1738590286Sobrien  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
1738690286Sobrien
1738790286Sobrien;; The ESP adjustments can be done by the push and pop instructions.  Resulting
1738890286Sobrien;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
1738990286Sobrien;; many CPUs it is also faster, since special hardware to avoid esp
1739090286Sobrien;; dependencies is present.
1739190286Sobrien
1739290286Sobrien;; While some of these conversions may be done using splitters, we use peepholes
1739390286Sobrien;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
1739490286Sobrien
1739590286Sobrien;; Convert prologue esp subtractions to push.
1739690286Sobrien;; We need register to push.  In order to keep verify_flow_info happy we have
1739790286Sobrien;; two choices
1739890286Sobrien;; - use scratch and clobber it in order to avoid dependencies
1739990286Sobrien;; - use already live register
1740090286Sobrien;; We can't use the second way right now, since there is no reliable way how to
1740190286Sobrien;; verify that given register is live.  First choice will also most likely in
1740290286Sobrien;; fewer dependencies.  On the place of esp adjustments it is very likely that
1740390286Sobrien;; call clobbered registers are dead.  We may want to use base pointer as an
1740490286Sobrien;; alternative when no register is available later.
1740590286Sobrien
1740690286Sobrien(define_peephole2
1740790286Sobrien  [(match_scratch:SI 0 "r")
1740890286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
1740990286Sobrien	      (clobber (reg:CC 17))
1741090286Sobrien	      (clobber (mem:BLK (scratch)))])]
1741190286Sobrien  "optimize_size || !TARGET_SUB_ESP_4"
1741290286Sobrien  [(clobber (match_dup 0))
1741390286Sobrien   (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
1741490286Sobrien	      (clobber (mem:BLK (scratch)))])])
1741590286Sobrien
1741690286Sobrien(define_peephole2
1741790286Sobrien  [(match_scratch:SI 0 "r")
1741890286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1741990286Sobrien	      (clobber (reg:CC 17))
1742090286Sobrien	      (clobber (mem:BLK (scratch)))])]
1742190286Sobrien  "optimize_size || !TARGET_SUB_ESP_8"
1742290286Sobrien  [(clobber (match_dup 0))
1742390286Sobrien   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
1742490286Sobrien   (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
1742590286Sobrien	      (clobber (mem:BLK (scratch)))])])
1742690286Sobrien
1742790286Sobrien;; Convert esp subtractions to push.
1742890286Sobrien(define_peephole2
1742990286Sobrien  [(match_scratch:SI 0 "r")
1743090286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
1743190286Sobrien	      (clobber (reg:CC 17))])]
1743290286Sobrien  "optimize_size || !TARGET_SUB_ESP_4"
1743390286Sobrien  [(clobber (match_dup 0))
1743490286Sobrien   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
1743590286Sobrien
1743690286Sobrien(define_peephole2
1743790286Sobrien  [(match_scratch:SI 0 "r")
1743890286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1743990286Sobrien	      (clobber (reg:CC 17))])]
1744090286Sobrien  "optimize_size || !TARGET_SUB_ESP_8"
1744190286Sobrien  [(clobber (match_dup 0))
1744290286Sobrien   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
1744390286Sobrien   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
1744490286Sobrien
1744590286Sobrien;; Convert epilogue deallocator to pop.
1744690286Sobrien(define_peephole2
1744790286Sobrien  [(match_scratch:SI 0 "r")
1744890286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1744990286Sobrien	      (clobber (reg:CC 17))
1745090286Sobrien	      (clobber (mem:BLK (scratch)))])]
1745190286Sobrien  "optimize_size || !TARGET_ADD_ESP_4"
1745290286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1745390286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1745490286Sobrien	      (clobber (mem:BLK (scratch)))])]
1745590286Sobrien  "")
1745690286Sobrien
1745790286Sobrien;; Two pops case is tricky, since pop causes dependency on destination register.
1745890286Sobrien;; We use two registers if available.
1745990286Sobrien(define_peephole2
1746090286Sobrien  [(match_scratch:SI 0 "r")
1746190286Sobrien   (match_scratch:SI 1 "r")
1746290286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
1746390286Sobrien	      (clobber (reg:CC 17))
1746490286Sobrien	      (clobber (mem:BLK (scratch)))])]
1746590286Sobrien  "optimize_size || !TARGET_ADD_ESP_8"
1746690286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1746790286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1746890286Sobrien	      (clobber (mem:BLK (scratch)))])
1746990286Sobrien   (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1747090286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1747190286Sobrien  "")
1747290286Sobrien
1747390286Sobrien(define_peephole2
1747490286Sobrien  [(match_scratch:SI 0 "r")
1747590286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
1747690286Sobrien	      (clobber (reg:CC 17))
1747790286Sobrien	      (clobber (mem:BLK (scratch)))])]
1747890286Sobrien  "optimize_size"
1747990286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1748090286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1748190286Sobrien	      (clobber (mem:BLK (scratch)))])
1748290286Sobrien   (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1748390286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1748490286Sobrien  "")
1748590286Sobrien
1748690286Sobrien;; Convert esp additions to pop.
1748790286Sobrien(define_peephole2
1748890286Sobrien  [(match_scratch:SI 0 "r")
1748990286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1749090286Sobrien	      (clobber (reg:CC 17))])]
1749190286Sobrien  ""
1749290286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1749390286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1749490286Sobrien  "")
1749590286Sobrien
1749690286Sobrien;; Two pops case is tricky, since pop causes dependency on destination register.
1749790286Sobrien;; We use two registers if available.
1749890286Sobrien(define_peephole2
1749990286Sobrien  [(match_scratch:SI 0 "r")
1750090286Sobrien   (match_scratch:SI 1 "r")
1750190286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
1750290286Sobrien	      (clobber (reg:CC 17))])]
1750390286Sobrien  ""
1750490286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1750590286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
1750690286Sobrien   (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1750790286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1750890286Sobrien  "")
1750990286Sobrien
1751090286Sobrien(define_peephole2
1751190286Sobrien  [(match_scratch:SI 0 "r")
1751290286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
1751390286Sobrien	      (clobber (reg:CC 17))])]
1751490286Sobrien  "optimize_size"
1751590286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1751690286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
1751790286Sobrien   (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1751890286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1751990286Sobrien  "")
1752090286Sobrien
1752190286Sobrien;; Convert compares with 1 to shorter inc/dec operations when CF is not
1752290286Sobrien;; required and register dies.
1752390286Sobrien(define_peephole2
1752490286Sobrien  [(set (reg 17)
1752590286Sobrien	(compare (match_operand:SI 0 "register_operand" "")
1752690286Sobrien		 (match_operand:SI 1 "incdec_operand" "")))]
1752790286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
1752890286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1752990286Sobrien  [(parallel [(set (reg:CCGC 17)
1753090286Sobrien		   (compare:CCGC (match_dup 0)
1753190286Sobrien				 (match_dup 1)))
1753290286Sobrien	      (clobber (match_dup 0))])]
1753390286Sobrien  "")
1753490286Sobrien
1753590286Sobrien(define_peephole2
1753690286Sobrien  [(set (reg 17)
1753790286Sobrien	(compare (match_operand:HI 0 "register_operand" "")
1753890286Sobrien		 (match_operand:HI 1 "incdec_operand" "")))]
1753990286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
1754090286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1754190286Sobrien  [(parallel [(set (reg:CCGC 17)
1754290286Sobrien		   (compare:CCGC (match_dup 0)
1754390286Sobrien				 (match_dup 1)))
1754490286Sobrien	      (clobber (match_dup 0))])]
1754590286Sobrien  "")
1754690286Sobrien
1754790286Sobrien(define_peephole2
1754890286Sobrien  [(set (reg 17)
1754990286Sobrien	(compare (match_operand:QI 0 "register_operand" "")
1755090286Sobrien		 (match_operand:QI 1 "incdec_operand" "")))]
1755190286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
1755290286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1755390286Sobrien  [(parallel [(set (reg:CCGC 17)
1755490286Sobrien		   (compare:CCGC (match_dup 0)
1755590286Sobrien				 (match_dup 1)))
1755690286Sobrien	      (clobber (match_dup 0))])]
1755790286Sobrien  "")
1755890286Sobrien
1755990286Sobrien;; Convert compares with 128 to shorter add -128
1756090286Sobrien(define_peephole2
1756190286Sobrien  [(set (reg 17)
1756290286Sobrien	(compare (match_operand:SI 0 "register_operand" "")
1756390286Sobrien		 (const_int 128)))]
1756490286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
1756590286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1756690286Sobrien  [(parallel [(set (reg:CCGC 17)
1756790286Sobrien		   (compare:CCGC (match_dup 0)
1756890286Sobrien			         (const_int 128)))
1756990286Sobrien	      (clobber (match_dup 0))])]
1757090286Sobrien  "")
1757190286Sobrien
1757290286Sobrien(define_peephole2
1757390286Sobrien  [(set (reg 17)
1757490286Sobrien	(compare (match_operand:HI 0 "register_operand" "")
1757590286Sobrien		 (const_int 128)))]
1757690286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
1757790286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1757890286Sobrien  [(parallel [(set (reg:CCGC 17)
1757990286Sobrien		   (compare:CCGC (match_dup 0)
1758090286Sobrien			         (const_int 128)))
1758190286Sobrien	      (clobber (match_dup 0))])]
1758290286Sobrien  "")
1758390286Sobrien
1758490286Sobrien(define_peephole2
1758590286Sobrien  [(match_scratch:DI 0 "r")
1758690286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
1758790286Sobrien	      (clobber (reg:CC 17))
1758890286Sobrien	      (clobber (mem:BLK (scratch)))])]
1758990286Sobrien  "optimize_size || !TARGET_SUB_ESP_4"
1759090286Sobrien  [(clobber (match_dup 0))
1759190286Sobrien   (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
1759290286Sobrien	      (clobber (mem:BLK (scratch)))])])
1759390286Sobrien
1759490286Sobrien(define_peephole2
1759590286Sobrien  [(match_scratch:DI 0 "r")
1759690286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
1759790286Sobrien	      (clobber (reg:CC 17))
1759890286Sobrien	      (clobber (mem:BLK (scratch)))])]
1759990286Sobrien  "optimize_size || !TARGET_SUB_ESP_8"
1760090286Sobrien  [(clobber (match_dup 0))
1760190286Sobrien   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
1760290286Sobrien   (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
1760390286Sobrien	      (clobber (mem:BLK (scratch)))])])
1760490286Sobrien
1760590286Sobrien;; Convert esp subtractions to push.
1760690286Sobrien(define_peephole2
1760790286Sobrien  [(match_scratch:DI 0 "r")
1760890286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
1760990286Sobrien	      (clobber (reg:CC 17))])]
1761090286Sobrien  "optimize_size || !TARGET_SUB_ESP_4"
1761190286Sobrien  [(clobber (match_dup 0))
1761290286Sobrien   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
1761390286Sobrien
1761490286Sobrien(define_peephole2
1761590286Sobrien  [(match_scratch:DI 0 "r")
1761690286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
1761790286Sobrien	      (clobber (reg:CC 17))])]
1761890286Sobrien  "optimize_size || !TARGET_SUB_ESP_8"
1761990286Sobrien  [(clobber (match_dup 0))
1762090286Sobrien   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
1762190286Sobrien   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
1762290286Sobrien
1762390286Sobrien;; Convert epilogue deallocator to pop.
1762490286Sobrien(define_peephole2
1762590286Sobrien  [(match_scratch:DI 0 "r")
1762690286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1762790286Sobrien	      (clobber (reg:CC 17))
1762890286Sobrien	      (clobber (mem:BLK (scratch)))])]
1762990286Sobrien  "optimize_size || !TARGET_ADD_ESP_4"
1763090286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1763190286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1763290286Sobrien	      (clobber (mem:BLK (scratch)))])]
1763390286Sobrien  "")
1763490286Sobrien
1763590286Sobrien;; Two pops case is tricky, since pop causes dependency on destination register.
1763690286Sobrien;; We use two registers if available.
1763790286Sobrien(define_peephole2
1763890286Sobrien  [(match_scratch:DI 0 "r")
1763990286Sobrien   (match_scratch:DI 1 "r")
1764090286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
1764190286Sobrien	      (clobber (reg:CC 17))
1764290286Sobrien	      (clobber (mem:BLK (scratch)))])]
1764390286Sobrien  "optimize_size || !TARGET_ADD_ESP_8"
1764490286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1764590286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1764690286Sobrien	      (clobber (mem:BLK (scratch)))])
1764790286Sobrien   (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
1764890286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1764990286Sobrien  "")
1765090286Sobrien
1765190286Sobrien(define_peephole2
1765290286Sobrien  [(match_scratch:DI 0 "r")
1765390286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
1765490286Sobrien	      (clobber (reg:CC 17))
1765590286Sobrien	      (clobber (mem:BLK (scratch)))])]
1765690286Sobrien  "optimize_size"
1765790286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1765890286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1765990286Sobrien	      (clobber (mem:BLK (scratch)))])
1766090286Sobrien   (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1766190286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1766290286Sobrien  "")
1766390286Sobrien
1766490286Sobrien;; Convert esp additions to pop.
1766590286Sobrien(define_peephole2
1766690286Sobrien  [(match_scratch:DI 0 "r")
1766790286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1766890286Sobrien	      (clobber (reg:CC 17))])]
1766990286Sobrien  ""
1767090286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1767190286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1767290286Sobrien  "")
1767390286Sobrien
1767490286Sobrien;; Two pops case is tricky, since pop causes dependency on destination register.
1767590286Sobrien;; We use two registers if available.
1767690286Sobrien(define_peephole2
1767790286Sobrien  [(match_scratch:DI 0 "r")
1767890286Sobrien   (match_scratch:DI 1 "r")
1767990286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
1768090286Sobrien	      (clobber (reg:CC 17))])]
1768190286Sobrien  ""
1768290286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1768390286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
1768490286Sobrien   (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
1768590286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1768690286Sobrien  "")
1768790286Sobrien
1768890286Sobrien(define_peephole2
1768990286Sobrien  [(match_scratch:DI 0 "r")
1769090286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
1769190286Sobrien	      (clobber (reg:CC 17))])]
1769290286Sobrien  "optimize_size"
1769390286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1769490286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
1769590286Sobrien   (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1769690286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1769790286Sobrien  "")
1769890286Sobrien
1769990286Sobrien;; Call-value patterns last so that the wildcard operand does not
1770090286Sobrien;; disrupt insn-recog's switch tables.
1770190286Sobrien
1770290286Sobrien(define_insn "*call_value_pop_0"
1770390286Sobrien  [(set (match_operand 0 "" "")
1770490286Sobrien	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
1770590286Sobrien	      (match_operand:SI 2 "" "")))
1770690286Sobrien   (set (reg:SI 7) (plus:SI (reg:SI 7)
1770790286Sobrien			    (match_operand:SI 3 "immediate_operand" "")))]
1770890286Sobrien  "!TARGET_64BIT"
1770990286Sobrien{
1771090286Sobrien  if (SIBLING_CALL_P (insn))
1771190286Sobrien    return "jmp\t%P1";
1771290286Sobrien  else
1771390286Sobrien    return "call\t%P1";
1771490286Sobrien}
1771590286Sobrien  [(set_attr "type" "callv")])
1771690286Sobrien
1771790286Sobrien(define_insn "*call_value_pop_1"
1771890286Sobrien  [(set (match_operand 0 "" "")
1771990286Sobrien	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
1772090286Sobrien	      (match_operand:SI 2 "" "")))
1772190286Sobrien   (set (reg:SI 7) (plus:SI (reg:SI 7)
1772290286Sobrien			    (match_operand:SI 3 "immediate_operand" "i")))]
1772390286Sobrien  "!TARGET_64BIT"
1772490286Sobrien{
1772590286Sobrien  if (constant_call_address_operand (operands[1], QImode))
1772690286Sobrien    {
1772790286Sobrien      if (SIBLING_CALL_P (insn))
1772890286Sobrien	return "jmp\t%P1";
1772990286Sobrien      else
1773090286Sobrien	return "call\t%P1";
1773190286Sobrien    }
1773290286Sobrien  if (SIBLING_CALL_P (insn))
1773390286Sobrien    return "jmp\t%A1";
1773490286Sobrien  else
1773590286Sobrien    return "call\t%A1";
1773690286Sobrien}
1773790286Sobrien  [(set_attr "type" "callv")])
1773890286Sobrien
1773990286Sobrien(define_insn "*call_value_0"
1774090286Sobrien  [(set (match_operand 0 "" "")
1774190286Sobrien	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
1774290286Sobrien	      (match_operand:SI 2 "" "")))]
1774390286Sobrien  "!TARGET_64BIT"
1774490286Sobrien{
1774590286Sobrien  if (SIBLING_CALL_P (insn))
1774690286Sobrien    return "jmp\t%P1";
1774790286Sobrien  else
1774890286Sobrien    return "call\t%P1";
1774990286Sobrien}
1775090286Sobrien  [(set_attr "type" "callv")])
1775190286Sobrien
1775290286Sobrien(define_insn "*call_value_0_rex64"
1775390286Sobrien  [(set (match_operand 0 "" "")
1775490286Sobrien	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
1775590286Sobrien	      (match_operand:DI 2 "const_int_operand" "")))]
1775690286Sobrien  "TARGET_64BIT"
1775790286Sobrien{
1775890286Sobrien  if (SIBLING_CALL_P (insn))
1775990286Sobrien    return "jmp\t%P1";
1776090286Sobrien  else
1776190286Sobrien    return "call\t%P1";
1776290286Sobrien}
1776390286Sobrien  [(set_attr "type" "callv")])
1776490286Sobrien
1776590286Sobrien(define_insn "*call_value_1"
1776690286Sobrien  [(set (match_operand 0 "" "")
1776790286Sobrien	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
1776890286Sobrien	      (match_operand:SI 2 "" "")))]
1776990286Sobrien  "!TARGET_64BIT"
1777090286Sobrien{
1777190286Sobrien  if (constant_call_address_operand (operands[1], QImode))
1777290286Sobrien    {
1777390286Sobrien      if (SIBLING_CALL_P (insn))
1777490286Sobrien	return "jmp\t%P1";
1777590286Sobrien      else
1777690286Sobrien	return "call\t%P1";
1777790286Sobrien    }
1777890286Sobrien  if (SIBLING_CALL_P (insn))
1777990286Sobrien    return "jmp\t%*%1";
1778090286Sobrien  else
1778190286Sobrien    return "call\t%*%1";
1778290286Sobrien}
1778390286Sobrien  [(set_attr "type" "callv")])
1778490286Sobrien
1778590286Sobrien(define_insn "*call_value_1_rex64"
1778690286Sobrien  [(set (match_operand 0 "" "")
1778790286Sobrien	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
1778890286Sobrien	      (match_operand:DI 2 "" "")))]
1778990286Sobrien  "TARGET_64BIT"
1779090286Sobrien{
1779190286Sobrien  if (constant_call_address_operand (operands[1], QImode))
1779290286Sobrien    {
1779390286Sobrien      if (SIBLING_CALL_P (insn))
1779490286Sobrien	return "jmp\t%P1";
1779590286Sobrien      else
1779690286Sobrien	return "call\t%P1";
1779790286Sobrien    }
1779890286Sobrien  if (SIBLING_CALL_P (insn))
1779990286Sobrien    return "jmp\t%A1";
1780090286Sobrien  else
1780190286Sobrien    return "call\t%A1";
1780290286Sobrien}
1780390286Sobrien  [(set_attr "type" "callv")])
1780490286Sobrien
1780590286Sobrien(define_insn "trap"
1780690286Sobrien  [(trap_if (const_int 1) (const_int 5))]
1780790286Sobrien  ""
1780890286Sobrien  "int\t$5")
1780990286Sobrien
1781090286Sobrien;;; ix86 doesn't have conditional trap instructions, but we fake them
1781190286Sobrien;;; for the sake of bounds checking.  By emitting bounds checks as
1781290286Sobrien;;; conditional traps rather than as conditional jumps around
1781390286Sobrien;;; unconditional traps we avoid introducing spurious basic-block
1781490286Sobrien;;; boundaries and facilitate elimination of redundant checks.  In
1781590286Sobrien;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
1781690286Sobrien;;; interrupt 5.
1781790286Sobrien;;; 
1781890286Sobrien;;; FIXME: Static branch prediction rules for ix86 are such that
1781990286Sobrien;;; forward conditional branches predict as untaken.  As implemented
1782090286Sobrien;;; below, pseudo conditional traps violate that rule.  We should use
1782190286Sobrien;;; .pushsection/.popsection to place all of the `int 5's in a special
1782290286Sobrien;;; section loaded at the end of the text segment and branch forward
1782390286Sobrien;;; there on bounds-failure, and then jump back immediately (in case
1782490286Sobrien;;; the system chooses to ignore bounds violations, or to report
1782590286Sobrien;;; violations and continue execution).
1782690286Sobrien
1782790286Sobrien(define_expand "conditional_trap"
1782890286Sobrien  [(trap_if (match_operator 0 "comparison_operator"
1782990286Sobrien	     [(match_dup 2) (const_int 0)])
1783090286Sobrien	    (match_operand 1 "const_int_operand" ""))]
1783190286Sobrien  ""
1783290286Sobrien{
1783390286Sobrien  emit_insn (gen_rtx_TRAP_IF (VOIDmode,
1783490286Sobrien			      ix86_expand_compare (GET_CODE (operands[0]),
1783590286Sobrien						   NULL, NULL),
1783690286Sobrien			      operands[1]));
1783790286Sobrien  DONE;
1783890286Sobrien})
1783990286Sobrien
1784090286Sobrien(define_insn "*conditional_trap_1"
1784190286Sobrien  [(trap_if (match_operator 0 "comparison_operator"
1784290286Sobrien	     [(reg 17) (const_int 0)])
1784390286Sobrien	    (match_operand 1 "const_int_operand" ""))]
1784490286Sobrien  ""
1784590286Sobrien{
1784690286Sobrien  operands[2] = gen_label_rtx ();
1784790286Sobrien  output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
1784890286Sobrien  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1784990286Sobrien			     CODE_LABEL_NUMBER (operands[2]));
1785090286Sobrien  RET;
1785190286Sobrien})
1785290286Sobrien
1785390286Sobrien	;; Pentium III SIMD instructions.
1785490286Sobrien
1785590286Sobrien;; Moves for SSE/MMX regs.
1785690286Sobrien
1785790286Sobrien(define_insn "movv4sf_internal"
1785890286Sobrien  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
1785990286Sobrien	(match_operand:V4SF 1 "nonimmediate_operand" "xm,x"))]
1786090286Sobrien  "TARGET_SSE"
1786190286Sobrien  ;; @@@ let's try to use movaps here.
1786290286Sobrien  "movaps\t{%1, %0|%0, %1}"
1786390286Sobrien  [(set_attr "type" "sse")])
1786490286Sobrien
1786590286Sobrien(define_insn "movv4si_internal"
1786690286Sobrien  [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,m")
1786790286Sobrien	(match_operand:V4SI 1 "nonimmediate_operand" "xm,x"))]
1786890286Sobrien  "TARGET_SSE"
1786990286Sobrien  ;; @@@ let's try to use movaps here.
1787090286Sobrien  "movaps\t{%1, %0|%0, %1}"
1787190286Sobrien  [(set_attr "type" "sse")])
1787290286Sobrien
1787390286Sobrien(define_insn "movv8qi_internal"
1787490286Sobrien  [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m")
1787590286Sobrien	(match_operand:V8QI 1 "nonimmediate_operand" "ym,y"))]
1787690286Sobrien  "TARGET_MMX"
1787790286Sobrien  "movq\t{%1, %0|%0, %1}"
1787890286Sobrien  [(set_attr "type" "mmx")])
1787990286Sobrien
1788090286Sobrien(define_insn "movv4hi_internal"
1788190286Sobrien  [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m")
1788290286Sobrien	(match_operand:V4HI 1 "nonimmediate_operand" "ym,y"))]
1788390286Sobrien  "TARGET_MMX"
1788490286Sobrien  "movq\t{%1, %0|%0, %1}"
1788590286Sobrien  [(set_attr "type" "mmx")])
1788690286Sobrien
1788790286Sobrien(define_insn "movv2si_internal"
1788890286Sobrien  [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m")
1788990286Sobrien	(match_operand:V2SI 1 "nonimmediate_operand" "ym,y"))]
1789090286Sobrien  "TARGET_MMX"
1789190286Sobrien  "movq\t{%1, %0|%0, %1}"
1789290286Sobrien  [(set_attr "type" "mmx")])
1789390286Sobrien
1789490286Sobrien(define_insn "movv2sf_internal"
1789590286Sobrien  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,m")
1789690286Sobrien        (match_operand:V2SF 1 "nonimmediate_operand" "ym,y"))]
1789790286Sobrien  "TARGET_3DNOW"
1789890286Sobrien  "movq\\t{%1, %0|%0, %1}"
1789990286Sobrien  [(set_attr "type" "mmx")])
1790090286Sobrien
1790190286Sobrien(define_expand "movti"
1790290286Sobrien  [(set (match_operand:TI 0 "general_operand" "")
1790390286Sobrien	(match_operand:TI 1 "general_operand" ""))]
1790490286Sobrien  "TARGET_SSE || TARGET_64BIT"
1790590286Sobrien{
1790690286Sobrien  if (TARGET_64BIT)
1790790286Sobrien    ix86_expand_move (TImode, operands);
1790890286Sobrien  else
1790990286Sobrien    ix86_expand_vector_move (TImode, operands);
1791090286Sobrien  DONE;
1791190286Sobrien})
1791290286Sobrien
1791390286Sobrien(define_expand "movv4sf"
1791490286Sobrien  [(set (match_operand:V4SF 0 "general_operand" "")
1791590286Sobrien	(match_operand:V4SF 1 "general_operand" ""))]
1791690286Sobrien  "TARGET_SSE"
1791790286Sobrien{
1791890286Sobrien  ix86_expand_vector_move (V4SFmode, operands);
1791990286Sobrien  DONE;
1792090286Sobrien})
1792190286Sobrien
1792290286Sobrien(define_expand "movv4si"
1792390286Sobrien  [(set (match_operand:V4SI 0 "general_operand" "")
1792490286Sobrien	(match_operand:V4SI 1 "general_operand" ""))]
1792590286Sobrien  "TARGET_MMX"
1792690286Sobrien{
1792790286Sobrien  ix86_expand_vector_move (V4SImode, operands);
1792890286Sobrien  DONE;
1792990286Sobrien})
1793090286Sobrien
1793190286Sobrien(define_expand "movv2si"
1793290286Sobrien  [(set (match_operand:V2SI 0 "general_operand" "")
1793390286Sobrien	(match_operand:V2SI 1 "general_operand" ""))]
1793490286Sobrien  "TARGET_MMX"
1793590286Sobrien{
1793690286Sobrien  ix86_expand_vector_move (V2SImode, operands);
1793790286Sobrien  DONE;
1793890286Sobrien})
1793990286Sobrien
1794090286Sobrien(define_expand "movv4hi"
1794190286Sobrien  [(set (match_operand:V4HI 0 "general_operand" "")
1794290286Sobrien	(match_operand:V4HI 1 "general_operand" ""))]
1794390286Sobrien  "TARGET_MMX"
1794490286Sobrien{
1794590286Sobrien  ix86_expand_vector_move (V4HImode, operands);
1794690286Sobrien  DONE;
1794790286Sobrien})
1794890286Sobrien
1794990286Sobrien(define_expand "movv8qi"
1795090286Sobrien  [(set (match_operand:V8QI 0 "general_operand" "")
1795190286Sobrien	(match_operand:V8QI 1 "general_operand" ""))]
1795290286Sobrien  "TARGET_MMX"
1795390286Sobrien{
1795490286Sobrien  ix86_expand_vector_move (V8QImode, operands);
1795590286Sobrien  DONE;
1795690286Sobrien})
1795790286Sobrien
1795890286Sobrien(define_expand "movv2sf"
1795990286Sobrien  [(set (match_operand:V2SF 0 "general_operand" "")
1796090286Sobrien	(match_operand:V2SF 1 "general_operand" ""))]
1796190286Sobrien   "TARGET_3DNOW"
1796290286Sobrien{
1796390286Sobrien  ix86_expand_vector_move (V2SFmode, operands);
1796490286Sobrien  DONE;
1796590286Sobrien})
1796690286Sobrien
1796790286Sobrien(define_insn_and_split "*pushti"
1796890286Sobrien  [(set (match_operand:TI 0 "push_operand" "=<")
1796990286Sobrien	(match_operand:TI 1 "nonmemory_operand" "x"))]
1797090286Sobrien  "TARGET_SSE"
1797190286Sobrien  "#"
1797290286Sobrien  ""
1797390286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
1797490286Sobrien   (set (mem:TI (reg:SI 7)) (match_dup 1))]
1797590286Sobrien  ""
1797690286Sobrien  [(set_attr "type" "sse")])
1797790286Sobrien
1797890286Sobrien(define_insn_and_split "*pushv4sf"
1797990286Sobrien  [(set (match_operand:V4SF 0 "push_operand" "=<")
1798090286Sobrien	(match_operand:V4SF 1 "nonmemory_operand" "x"))]
1798190286Sobrien  "TARGET_SSE"
1798290286Sobrien  "#"
1798390286Sobrien  ""
1798490286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
1798590286Sobrien   (set (mem:V4SF (reg:SI 7)) (match_dup 1))]
1798690286Sobrien  ""
1798790286Sobrien  [(set_attr "type" "sse")])
1798890286Sobrien
1798990286Sobrien(define_insn_and_split "*pushv4si"
1799090286Sobrien  [(set (match_operand:V4SI 0 "push_operand" "=<")
1799190286Sobrien	(match_operand:V4SI 1 "nonmemory_operand" "x"))]
1799290286Sobrien  "TARGET_SSE"
1799390286Sobrien  "#"
1799490286Sobrien  ""
1799590286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
1799690286Sobrien   (set (mem:V4SI (reg:SI 7)) (match_dup 1))]
1799790286Sobrien  ""
1799890286Sobrien  [(set_attr "type" "sse")])
1799990286Sobrien
1800090286Sobrien(define_insn_and_split "*pushv2si"
1800190286Sobrien  [(set (match_operand:V2SI 0 "push_operand" "=<")
1800290286Sobrien	(match_operand:V2SI 1 "nonmemory_operand" "y"))]
1800390286Sobrien  "TARGET_MMX"
1800490286Sobrien  "#"
1800590286Sobrien  ""
1800690286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1800790286Sobrien   (set (mem:V2SI (reg:SI 7)) (match_dup 1))]
1800890286Sobrien  ""
1800990286Sobrien  [(set_attr "type" "mmx")])
1801090286Sobrien
1801190286Sobrien(define_insn_and_split "*pushv4hi"
1801290286Sobrien  [(set (match_operand:V4HI 0 "push_operand" "=<")
1801390286Sobrien	(match_operand:V4HI 1 "nonmemory_operand" "y"))]
1801490286Sobrien  "TARGET_MMX"
1801590286Sobrien  "#"
1801690286Sobrien  ""
1801790286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1801890286Sobrien   (set (mem:V4HI (reg:SI 7)) (match_dup 1))]
1801990286Sobrien  ""
1802090286Sobrien  [(set_attr "type" "mmx")])
1802190286Sobrien
1802290286Sobrien(define_insn_and_split "*pushv8qi"
1802390286Sobrien  [(set (match_operand:V8QI 0 "push_operand" "=<")
1802490286Sobrien	(match_operand:V8QI 1 "nonmemory_operand" "y"))]
1802590286Sobrien  "TARGET_MMX"
1802690286Sobrien  "#"
1802790286Sobrien  ""
1802890286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1802990286Sobrien   (set (mem:V8QI (reg:SI 7)) (match_dup 1))]
1803090286Sobrien  ""
1803190286Sobrien  [(set_attr "type" "mmx")])
1803290286Sobrien
1803390286Sobrien(define_insn_and_split "*pushv2sf"
1803490286Sobrien  [(set (match_operand:V2SF 0 "push_operand" "=<")
1803590286Sobrien	(match_operand:V2SF 1 "nonmemory_operand" "y"))]
1803690286Sobrien  "TARGET_3DNOW"
1803790286Sobrien  "#"
1803890286Sobrien  ""
1803990286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1804090286Sobrien   (set (mem:V2SF (reg:SI 7)) (match_dup 1))]
1804190286Sobrien  ""
1804290286Sobrien  [(set_attr "type" "mmx")])
1804390286Sobrien
1804490286Sobrien(define_insn "movti_internal"
1804590286Sobrien  [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1804690286Sobrien	(match_operand:TI 1 "general_operand" "O,xm,x"))]
1804790286Sobrien  "TARGET_SSE && !TARGET_64BIT"
1804890286Sobrien  "@
1804990286Sobrien   xorps\t%0, %0
1805090286Sobrien   movaps\t{%1, %0|%0, %1}
1805190286Sobrien   movaps\t{%1, %0|%0, %1}"
1805290286Sobrien  [(set_attr "type" "sse")])
1805390286Sobrien
1805490286Sobrien(define_insn "*movti_rex64"
1805590286Sobrien  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,mx,x")
1805690286Sobrien	(match_operand:TI 1 "general_operand" "riFo,riF,O,x,m"))]
1805790286Sobrien  "TARGET_64BIT
1805890286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1805990286Sobrien  "@
1806090286Sobrien   #
1806190286Sobrien   #
1806290286Sobrien   xorps\t%0, %0
1806390286Sobrien   movaps\\t{%1, %0|%0, %1}
1806490286Sobrien   movaps\\t{%1, %0|%0, %1}"
1806590286Sobrien  [(set_attr "type" "*,*,sse,sse,sse")
1806690286Sobrien   (set_attr "mode" "TI")])
1806790286Sobrien
1806890286Sobrien(define_split
1806990286Sobrien  [(set (match_operand:TI 0 "nonimmediate_operand" "")
1807090286Sobrien        (match_operand:TI 1 "general_operand" ""))]
1807190286Sobrien  "reload_completed && !SSE_REG_P (operands[0])
1807290286Sobrien   && !SSE_REG_P (operands[1])"
1807390286Sobrien  [(const_int 0)]
1807490286Sobrien  "ix86_split_long_move (operands); DONE;")
1807590286Sobrien
1807690286Sobrien;; These two patterns are useful for specifying exactly whether to use
1807790286Sobrien;; movaps or movups
1807890286Sobrien(define_insn "sse_movaps"
1807990286Sobrien  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
1808090286Sobrien	(unspec:V4SF
1808190286Sobrien	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")] 38))]
1808290286Sobrien  "TARGET_SSE"
1808390286Sobrien  "@
1808490286Sobrien   movaps\t{%1, %0|%0, %1}
1808590286Sobrien   movaps\t{%1, %0|%0, %1}"
1808690286Sobrien  [(set_attr "type" "sse")])
1808790286Sobrien
1808890286Sobrien(define_insn "sse_movups"
1808990286Sobrien  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
1809090286Sobrien	(unspec:V4SF
1809190286Sobrien	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")] 39))]
1809290286Sobrien  "TARGET_SSE"
1809390286Sobrien  "@
1809490286Sobrien   movups\t{%1, %0|%0, %1}
1809590286Sobrien   movups\t{%1, %0|%0, %1}"
1809690286Sobrien  [(set_attr "type" "sse")])
1809790286Sobrien
1809890286Sobrien
1809990286Sobrien;; SSE Strange Moves.
1810090286Sobrien
1810190286Sobrien(define_insn "sse_movmskps"
1810290286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1810390286Sobrien	(unspec:SI [(match_operand:V4SF 1 "register_operand" "x")] 33))]
1810490286Sobrien  "TARGET_SSE"
1810590286Sobrien  "movmskps\t{%1, %0|%0, %1}"
1810690286Sobrien  [(set_attr "type" "sse")])
1810790286Sobrien
1810890286Sobrien(define_insn "mmx_pmovmskb"
1810990286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1811090286Sobrien	(unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] 33))]
1811190286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1811290286Sobrien  "pmovmskb\t{%1, %0|%0, %1}"
1811390286Sobrien  [(set_attr "type" "sse")])
1811490286Sobrien
1811590286Sobrien(define_insn "mmx_maskmovq"
1811690286Sobrien  [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
1811790286Sobrien	(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1811890286Sobrien		      (match_operand:V8QI 2 "register_operand" "y")] 32))]
1811996294Sobrien  "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
1812090286Sobrien  ;; @@@ check ordering of operands in intel/nonintel syntax
1812190286Sobrien  "maskmovq\t{%2, %1|%1, %2}"
1812290286Sobrien  [(set_attr "type" "sse")])
1812390286Sobrien
1812496294Sobrien(define_insn "mmx_maskmovq_rex"
1812596294Sobrien  [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
1812696294Sobrien	(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1812796294Sobrien		      (match_operand:V8QI 2 "register_operand" "y")] 32))]
1812896294Sobrien  "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
1812996294Sobrien  ;; @@@ check ordering of operands in intel/nonintel syntax
1813096294Sobrien  "maskmovq\t{%2, %1|%1, %2}"
1813196294Sobrien  [(set_attr "type" "sse")])
1813296294Sobrien
1813390286Sobrien(define_insn "sse_movntv4sf"
1813490286Sobrien  [(set (match_operand:V4SF 0 "memory_operand" "=m")
1813590286Sobrien	(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")] 34))]
1813690286Sobrien  "TARGET_SSE"
1813790286Sobrien  "movntps\t{%1, %0|%0, %1}"
1813890286Sobrien  [(set_attr "type" "sse")])
1813990286Sobrien
1814090286Sobrien(define_insn "sse_movntdi"
1814190286Sobrien  [(set (match_operand:DI 0 "memory_operand" "=m")
1814290286Sobrien	(unspec:DI [(match_operand:DI 1 "register_operand" "y")] 34))]
1814390286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1814490286Sobrien  "movntq\t{%1, %0|%0, %1}"
1814590286Sobrien  [(set_attr "type" "sse")])
1814690286Sobrien
1814790286Sobrien(define_insn "sse_movhlps"
1814890286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1814990286Sobrien	(vec_merge:V4SF
1815090286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1815190286Sobrien	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
1815290286Sobrien			  (parallel [(const_int 2)
1815390286Sobrien				     (const_int 3)
1815490286Sobrien				     (const_int 0)
1815590286Sobrien				     (const_int 1)]))
1815690286Sobrien	 (const_int 3)))]
1815790286Sobrien  "TARGET_SSE"
1815890286Sobrien  "movhlps\t{%2, %0|%0, %2}"
1815990286Sobrien  [(set_attr "type" "sse")])
1816090286Sobrien
1816190286Sobrien(define_insn "sse_movlhps"
1816290286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1816390286Sobrien	(vec_merge:V4SF
1816490286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1816590286Sobrien	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
1816690286Sobrien			  (parallel [(const_int 2)
1816790286Sobrien				     (const_int 3)
1816890286Sobrien				     (const_int 0)
1816990286Sobrien				     (const_int 1)]))
1817090286Sobrien	 (const_int 12)))]
1817190286Sobrien  "TARGET_SSE"
1817290286Sobrien  "movlhps\t{%2, %0|%0, %2}"
1817390286Sobrien  [(set_attr "type" "sse")])
1817490286Sobrien
1817590286Sobrien(define_insn "sse_movhps"
1817690286Sobrien  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
1817790286Sobrien	(vec_merge:V4SF
1817890286Sobrien	 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
1817990286Sobrien	 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
1818090286Sobrien	 (const_int 12)))]
1818190286Sobrien  "TARGET_SSE
1818290286Sobrien   && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
1818390286Sobrien  "movhps\t{%2, %0|%0, %2}"
1818490286Sobrien  [(set_attr "type" "sse")])
1818590286Sobrien
1818690286Sobrien(define_insn "sse_movlps"
1818790286Sobrien  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
1818890286Sobrien	(vec_merge:V4SF
1818990286Sobrien	 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
1819090286Sobrien	 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
1819190286Sobrien	 (const_int 3)))]
1819290286Sobrien  "TARGET_SSE
1819390286Sobrien   && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
1819490286Sobrien  "movlps\t{%2, %0|%0, %2}"
1819590286Sobrien  [(set_attr "type" "sse")])
1819690286Sobrien
1819790286Sobrien(define_insn "sse_loadss"
1819890286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1819990286Sobrien	(vec_merge:V4SF
1820090286Sobrien	 (match_operand:V4SF 1 "memory_operand" "m")
1820190286Sobrien	 (vec_duplicate:V4SF (float:SF (const_int 0)))
1820290286Sobrien	 (const_int 1)))]
1820390286Sobrien  "TARGET_SSE"
1820490286Sobrien  "movss\t{%1, %0|%0, %1}"
1820590286Sobrien  [(set_attr "type" "sse")])
1820690286Sobrien
1820790286Sobrien(define_insn "sse_movss"
1820890286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1820990286Sobrien	(vec_merge:V4SF
1821090286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1821190286Sobrien	 (match_operand:V4SF 2 "register_operand" "x")
1821290286Sobrien	 (const_int 1)))]
1821390286Sobrien  "TARGET_SSE"
1821490286Sobrien  "movss\t{%2, %0|%0, %2}"
1821590286Sobrien  [(set_attr "type" "sse")])
1821690286Sobrien
1821790286Sobrien(define_insn "sse_storess"
1821890286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
1821990286Sobrien	(vec_select:SF
1822090286Sobrien	 (match_operand:V4SF 1 "register_operand" "x")
1822190286Sobrien	 (parallel [(const_int 0)])))]
1822290286Sobrien  "TARGET_SSE"
1822390286Sobrien  "movss\t{%1, %0|%0, %1}"
1822490286Sobrien  [(set_attr "type" "sse")])
1822590286Sobrien
1822690286Sobrien(define_insn "sse_shufps"
1822790286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1822890286Sobrien        (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
1822990286Sobrien		      (match_operand:V4SF 2 "nonimmediate_operand" "xm")
1823090286Sobrien		      (match_operand:SI 3 "immediate_operand" "i")] 41))]
1823190286Sobrien  "TARGET_SSE"
1823290286Sobrien  ;; @@@ check operand order for intel/nonintel syntax
1823390286Sobrien  "shufps\t{%3, %2, %0|%0, %2, %3}"
1823490286Sobrien  [(set_attr "type" "sse")])
1823590286Sobrien
1823690286Sobrien
1823790286Sobrien;; SSE arithmetic
1823890286Sobrien
1823990286Sobrien(define_insn "addv4sf3"
1824090286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1824190286Sobrien        (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
1824290286Sobrien	           (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1824390286Sobrien  "TARGET_SSE"
1824490286Sobrien  "addps\t{%2, %0|%0, %2}"
1824590286Sobrien  [(set_attr "type" "sse")])
1824690286Sobrien
1824790286Sobrien(define_insn "vmaddv4sf3"
1824890286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1824990286Sobrien	(vec_merge:V4SF
1825090286Sobrien	 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
1825190286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1825290286Sobrien	 (match_dup 1)
1825390286Sobrien	 (const_int 1)))]
1825490286Sobrien  "TARGET_SSE"
1825590286Sobrien  "addss\t{%2, %0|%0, %2}"
1825690286Sobrien  [(set_attr "type" "sse")])
1825790286Sobrien
1825890286Sobrien(define_insn "subv4sf3"
1825990286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1826090286Sobrien        (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
1826190286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1826290286Sobrien  "TARGET_SSE"
1826390286Sobrien  "subps\t{%2, %0|%0, %2}"
1826490286Sobrien  [(set_attr "type" "sse")])
1826590286Sobrien
1826690286Sobrien(define_insn "vmsubv4sf3"
1826790286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1826890286Sobrien	(vec_merge:V4SF
1826990286Sobrien	 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
1827090286Sobrien		     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1827190286Sobrien	 (match_dup 1)
1827290286Sobrien	 (const_int 1)))]
1827390286Sobrien  "TARGET_SSE"
1827490286Sobrien  "subss\t{%2, %0|%0, %2}"
1827590286Sobrien  [(set_attr "type" "sse")])
1827690286Sobrien
1827790286Sobrien(define_insn "mulv4sf3"
1827890286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1827990286Sobrien        (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
1828090286Sobrien	           (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1828190286Sobrien  "TARGET_SSE"
1828290286Sobrien  "mulps\t{%2, %0|%0, %2}"
1828390286Sobrien  [(set_attr "type" "sse")])
1828490286Sobrien
1828590286Sobrien(define_insn "vmmulv4sf3"
1828690286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1828790286Sobrien	(vec_merge:V4SF
1828890286Sobrien	 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
1828990286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1829090286Sobrien	 (match_dup 1)
1829190286Sobrien	 (const_int 1)))]
1829290286Sobrien  "TARGET_SSE"
1829390286Sobrien  "mulss\t{%2, %0|%0, %2}"
1829490286Sobrien  [(set_attr "type" "sse")])
1829590286Sobrien
1829690286Sobrien(define_insn "divv4sf3"
1829790286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1829890286Sobrien        (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
1829990286Sobrien	          (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1830090286Sobrien  "TARGET_SSE"
1830190286Sobrien  "divps\t{%2, %0|%0, %2}"
1830290286Sobrien  [(set_attr "type" "sse")])
1830390286Sobrien
1830490286Sobrien(define_insn "vmdivv4sf3"
1830590286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1830690286Sobrien	(vec_merge:V4SF
1830790286Sobrien	 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
1830890286Sobrien		   (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1830990286Sobrien	 (match_dup 1)
1831090286Sobrien	 (const_int 1)))]
1831190286Sobrien  "TARGET_SSE"
1831290286Sobrien  "divss\t{%2, %0|%0, %2}"
1831390286Sobrien  [(set_attr "type" "sse")])
1831490286Sobrien
1831590286Sobrien
1831690286Sobrien;; SSE square root/reciprocal
1831790286Sobrien
1831890286Sobrien(define_insn "rcpv4sf2"
1831990286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1832090286Sobrien        (unspec:V4SF
1832190286Sobrien	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 42))]
1832290286Sobrien  "TARGET_SSE"
1832390286Sobrien  "rcpps\t{%1, %0|%0, %1}"
1832490286Sobrien  [(set_attr "type" "sse")])
1832590286Sobrien
1832690286Sobrien(define_insn "vmrcpv4sf2"
1832790286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1832890286Sobrien	(vec_merge:V4SF
1832990286Sobrien	 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 42)
1833090286Sobrien	 (match_operand:V4SF 2 "register_operand" "0")
1833190286Sobrien	 (const_int 1)))]
1833290286Sobrien  "TARGET_SSE"
1833390286Sobrien  "rcpss\t{%1, %0|%0, %1}"
1833490286Sobrien  [(set_attr "type" "sse")])
1833590286Sobrien
1833690286Sobrien(define_insn "rsqrtv4sf2"
1833790286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1833890286Sobrien        (unspec:V4SF
1833990286Sobrien	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 43))]
1834090286Sobrien  "TARGET_SSE"
1834190286Sobrien  "rsqrtps\t{%1, %0|%0, %1}"
1834290286Sobrien  [(set_attr "type" "sse")])
1834390286Sobrien
1834490286Sobrien(define_insn "vmrsqrtv4sf2"
1834590286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1834690286Sobrien	(vec_merge:V4SF
1834790286Sobrien	 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 43)
1834890286Sobrien	 (match_operand:V4SF 2 "register_operand" "0")
1834990286Sobrien	 (const_int 1)))]
1835090286Sobrien  "TARGET_SSE"
1835190286Sobrien  "rsqrtss\t{%1, %0|%0, %1}"
1835290286Sobrien  [(set_attr "type" "sse")])
1835390286Sobrien
1835490286Sobrien(define_insn "sqrtv4sf2"
1835590286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1835690286Sobrien        (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
1835790286Sobrien  "TARGET_SSE"
1835890286Sobrien  "sqrtps\t{%1, %0|%0, %1}"
1835990286Sobrien  [(set_attr "type" "sse")])
1836090286Sobrien
1836190286Sobrien(define_insn "vmsqrtv4sf2"
1836290286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1836390286Sobrien	(vec_merge:V4SF
1836490286Sobrien	 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
1836590286Sobrien	 (match_operand:V4SF 2 "register_operand" "0")
1836690286Sobrien	 (const_int 1)))]
1836790286Sobrien  "TARGET_SSE"
1836890286Sobrien  "sqrtss\t{%1, %0|%0, %1}"
1836990286Sobrien  [(set_attr "type" "sse")])
1837090286Sobrien
1837190286Sobrien;; SSE logical operations.
1837290286Sobrien
1837390286Sobrien;; These are not called andti3 etc. because we really really don't want
1837490286Sobrien;; the compiler to widen DImode ands to TImode ands and then try to move
1837590286Sobrien;; into DImode subregs of SSE registers, and them together, and move out
1837690286Sobrien;; of DImode subregs again!
1837790286Sobrien
1837890286Sobrien(define_insn "*sse_andti3_df_1"
1837990286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
1838090286Sobrien        (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
1838190286Sobrien		(subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
1838290286Sobrien  "TARGET_SSE2"
1838390286Sobrien  "andpd\t{%2, %0|%0, %2}"
1838490286Sobrien  [(set_attr "type" "sse")])
1838590286Sobrien
1838690286Sobrien(define_insn "*sse_andti3_df_2"
1838790286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
1838890286Sobrien        (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
1838990286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "Ym")))]
1839090286Sobrien  "TARGET_SSE2"
1839190286Sobrien  "andpd\t{%2, %0|%0, %2}"
1839290286Sobrien  [(set_attr "type" "sse")])
1839390286Sobrien
1839490286Sobrien(define_insn "*sse_andti3_sf_1"
1839590286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
1839690286Sobrien        (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
1839790286Sobrien		(subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
1839890286Sobrien  "TARGET_SSE"
1839990286Sobrien  "andps\t{%2, %0|%0, %2}"
1840090286Sobrien  [(set_attr "type" "sse")])
1840190286Sobrien
1840290286Sobrien(define_insn "*sse_andti3_sf_2"
1840390286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
1840490286Sobrien        (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
1840590286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1840690286Sobrien  "TARGET_SSE"
1840790286Sobrien  "andps\t{%2, %0|%0, %2}"
1840890286Sobrien  [(set_attr "type" "sse")])
1840990286Sobrien
1841090286Sobrien(define_insn "sse_andti3"
1841190286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1841296294Sobrien        (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1841390286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1841496294Sobrien  "TARGET_SSE && !TARGET_SSE2
1841596294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1841690286Sobrien  "andps\t{%2, %0|%0, %2}"
1841790286Sobrien  [(set_attr "type" "sse")])
1841890286Sobrien
1841990286Sobrien(define_insn "*sse_andti3_sse2"
1842090286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1842196294Sobrien        (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1842290286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1842396294Sobrien  "TARGET_SSE2
1842496294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1842590286Sobrien  "pand\t{%2, %0|%0, %2}"
1842690286Sobrien  [(set_attr "type" "sse")])
1842790286Sobrien
1842890286Sobrien(define_insn "*sse_nandti3_df"
1842990286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
1843090286Sobrien        (and:TI (not:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0))
1843190286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "Ym")))]
1843290286Sobrien  "TARGET_SSE2"
1843390286Sobrien  "andnpd\t{%2, %0|%0, %2}"
1843490286Sobrien  [(set_attr "type" "sse")])
1843590286Sobrien
1843690286Sobrien(define_insn "*sse_nandti3_sf"
1843790286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
1843890286Sobrien        (and:TI (not:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0))
1843990286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1844090286Sobrien  "TARGET_SSE"
1844190286Sobrien  "andnps\t{%2, %0|%0, %2}"
1844290286Sobrien  [(set_attr "type" "sse")])
1844390286Sobrien
1844490286Sobrien(define_insn "sse_nandti3"
1844590286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1844690286Sobrien        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
1844790286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1844890286Sobrien  "TARGET_SSE && !TARGET_SSE2"
1844990286Sobrien  "andnps\t{%2, %0|%0, %2}"
1845090286Sobrien  [(set_attr "type" "sse")])
1845190286Sobrien
1845290286Sobrien(define_insn "*sse_nandti3_sse2"
1845390286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1845490286Sobrien        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
1845590286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1845690286Sobrien  "TARGET_SSE2"
1845790286Sobrien  "pnand\t{%2, %0|%0, %2}"
1845890286Sobrien  [(set_attr "type" "sse")])
1845990286Sobrien
1846090286Sobrien(define_insn "*sse_iorti3_df_1"
1846190286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
1846290286Sobrien        (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
1846390286Sobrien		(subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
1846490286Sobrien  "TARGET_SSE2"
1846590286Sobrien  "orpd\t{%2, %0|%0, %2}"
1846690286Sobrien  [(set_attr "type" "sse")])
1846790286Sobrien
1846890286Sobrien(define_insn "*sse_iorti3_df_2"
1846990286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
1847090286Sobrien        (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
1847190286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "Ym")))]
1847290286Sobrien  "TARGET_SSE2"
1847390286Sobrien  "orpd\t{%2, %0|%0, %2}"
1847490286Sobrien  [(set_attr "type" "sse")])
1847590286Sobrien
1847690286Sobrien(define_insn "*sse_iorti3_sf_1"
1847790286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
1847890286Sobrien        (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
1847990286Sobrien		(subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
1848090286Sobrien  "TARGET_SSE"
1848190286Sobrien  "orps\t{%2, %0|%0, %2}"
1848290286Sobrien  [(set_attr "type" "sse")])
1848390286Sobrien
1848490286Sobrien(define_insn "*sse_iorti3_sf_2"
1848590286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
1848690286Sobrien        (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
1848790286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1848890286Sobrien  "TARGET_SSE"
1848990286Sobrien  "orps\t{%2, %0|%0, %2}"
1849090286Sobrien  [(set_attr "type" "sse")])
1849190286Sobrien
1849290286Sobrien(define_insn "sse_iorti3"
1849390286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1849496294Sobrien        (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1849590286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1849696294Sobrien  "TARGET_SSE && !TARGET_SSE2
1849796294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1849890286Sobrien  "orps\t{%2, %0|%0, %2}"
1849990286Sobrien  [(set_attr "type" "sse")])
1850090286Sobrien
1850190286Sobrien(define_insn "*sse_iorti3_sse2"
1850290286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1850396294Sobrien        (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1850490286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1850596294Sobrien  "TARGET_SSE2
1850696294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1850790286Sobrien  "por\t{%2, %0|%0, %2}"
1850890286Sobrien  [(set_attr "type" "sse")])
1850990286Sobrien
1851090286Sobrien(define_insn "*sse_xorti3_df_1"
1851190286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
1851290286Sobrien        (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
1851390286Sobrien		(subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
1851490286Sobrien  "TARGET_SSE2"
1851590286Sobrien  "xorpd\t{%2, %0|%0, %2}"
1851690286Sobrien  [(set_attr "type" "sse")])
1851790286Sobrien
1851890286Sobrien(define_insn "*sse_xorti3_df_2"
1851990286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
1852090286Sobrien        (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
1852190286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "Ym")))]
1852290286Sobrien  "TARGET_SSE2"
1852390286Sobrien  "xorpd\t{%2, %0|%0, %2}"
1852490286Sobrien  [(set_attr "type" "sse")])
1852590286Sobrien
1852690286Sobrien(define_insn "*sse_xorti3_sf_1"
1852790286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
1852890286Sobrien        (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
1852990286Sobrien		(subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
1853090286Sobrien  "TARGET_SSE"
1853190286Sobrien  "xorps\t{%2, %0|%0, %2}"
1853290286Sobrien  [(set_attr "type" "sse")])
1853390286Sobrien
1853490286Sobrien(define_insn "*sse_xorti3_sf_2"
1853590286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
1853690286Sobrien        (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
1853790286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1853890286Sobrien  "TARGET_SSE"
1853990286Sobrien  "xorps\t{%2, %0|%0, %2}"
1854090286Sobrien  [(set_attr "type" "sse")])
1854190286Sobrien
1854290286Sobrien(define_insn "sse_xorti3"
1854390286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1854496294Sobrien        (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1854590286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1854696294Sobrien  "TARGET_SSE && !TARGET_SSE2
1854796294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1854890286Sobrien  "xorps\t{%2, %0|%0, %2}"
1854990286Sobrien  [(set_attr "type" "sse")])
1855090286Sobrien
1855190286Sobrien(define_insn "*sse_xorti3_sse2"
1855290286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1855396294Sobrien        (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1855490286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1855596294Sobrien  "TARGET_SSE2
1855696294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1855790286Sobrien  "pxor\t{%2, %0|%0, %2}"
1855890286Sobrien  [(set_attr "type" "sse")])
1855990286Sobrien
1856090286Sobrien;; Use xor, but don't show input operands so they aren't live before
1856190286Sobrien;; this insn.
1856290286Sobrien(define_insn "sse_clrv4sf"
1856390286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1856490286Sobrien        (unspec:V4SF [(const_int 0)] 45))]
1856590286Sobrien  "TARGET_SSE"
1856690286Sobrien  "xorps\t{%0, %0|%0, %0}"
1856790286Sobrien  [(set_attr "type" "sse")
1856890286Sobrien   (set_attr "memory" "none")])
1856990286Sobrien
1857090286Sobrien;; SSE mask-generating compares
1857190286Sobrien
1857290286Sobrien(define_insn "maskcmpv4sf3"
1857390286Sobrien  [(set (match_operand:V4SI 0 "register_operand" "=x")
1857490286Sobrien        (match_operator:V4SI 3 "sse_comparison_operator"
1857590286Sobrien		[(match_operand:V4SF 1 "register_operand" "0")
1857690286Sobrien		 (match_operand:V4SF 2 "register_operand" "x")]))]
1857790286Sobrien  "TARGET_SSE"
1857890286Sobrien  "cmp%D3ps\t{%2, %0|%0, %2}"
1857990286Sobrien  [(set_attr "type" "sse")])
1858090286Sobrien
1858190286Sobrien(define_insn "maskncmpv4sf3"
1858290286Sobrien  [(set (match_operand:V4SI 0 "register_operand" "=x")
1858390286Sobrien        (not:V4SI
1858490286Sobrien	 (match_operator:V4SI 3 "sse_comparison_operator"
1858590286Sobrien		[(match_operand:V4SF 1 "register_operand" "0")
1858690286Sobrien		 (match_operand:V4SF 2 "register_operand" "x")])))]
1858790286Sobrien  "TARGET_SSE"
1858890286Sobrien{
1858990286Sobrien  if (GET_CODE (operands[3]) == UNORDERED)
1859090286Sobrien    return "cmpordps\t{%2, %0|%0, %2}";
1859190286Sobrien  else
1859290286Sobrien    return "cmpn%D3ps\t{%2, %0|%0, %2}";
1859390286Sobrien}
1859490286Sobrien  [(set_attr "type" "sse")])
1859590286Sobrien
1859690286Sobrien(define_insn "vmmaskcmpv4sf3"
1859790286Sobrien  [(set (match_operand:V4SI 0 "register_operand" "=x")
1859890286Sobrien	(vec_merge:V4SI
1859990286Sobrien	 (match_operator:V4SI 3 "sse_comparison_operator"
1860090286Sobrien		[(match_operand:V4SF 1 "register_operand" "0")
1860190286Sobrien		 (match_operand:V4SF 2 "register_operand" "x")])
1860290286Sobrien	 (match_dup 1)
1860390286Sobrien	 (const_int 1)))]
1860490286Sobrien  "TARGET_SSE"
1860590286Sobrien  "cmp%D3ss\t{%2, %0|%0, %2}"
1860690286Sobrien  [(set_attr "type" "sse")])
1860790286Sobrien
1860890286Sobrien(define_insn "vmmaskncmpv4sf3"
1860990286Sobrien  [(set (match_operand:V4SI 0 "register_operand" "=x")
1861090286Sobrien	(vec_merge:V4SI
1861190286Sobrien	 (not:V4SI
1861290286Sobrien	  (match_operator:V4SI 3 "sse_comparison_operator"
1861390286Sobrien		[(match_operand:V4SF 1 "register_operand" "0")
1861490286Sobrien		 (match_operand:V4SF 2 "register_operand" "x")]))
1861590286Sobrien	 (subreg:V4SI (match_dup 1) 0)
1861690286Sobrien	 (const_int 1)))]
1861790286Sobrien  "TARGET_SSE"
1861890286Sobrien{
1861990286Sobrien  if (GET_CODE (operands[3]) == UNORDERED)
1862090286Sobrien    return "cmpordss\t{%2, %0|%0, %2}";
1862190286Sobrien  else
1862290286Sobrien    return "cmpn%D3ss\t{%2, %0|%0, %2}";
1862390286Sobrien}
1862490286Sobrien  [(set_attr "type" "sse")])
1862590286Sobrien
1862690286Sobrien(define_insn "sse_comi"
1862790286Sobrien  [(set (reg:CCFP 17)
1862890286Sobrien        (match_operator:CCFP 2 "sse_comparison_operator"
1862990286Sobrien			[(vec_select:SF
1863090286Sobrien			  (match_operand:V4SF 0 "register_operand" "x")
1863190286Sobrien			  (parallel [(const_int 0)]))
1863290286Sobrien			 (vec_select:SF
1863390286Sobrien			  (match_operand:V4SF 1 "register_operand" "x")
1863490286Sobrien			  (parallel [(const_int 0)]))]))]
1863590286Sobrien  "TARGET_SSE"
1863690286Sobrien  "comiss\t{%1, %0|%0, %1}"
1863790286Sobrien  [(set_attr "type" "sse")])
1863890286Sobrien
1863990286Sobrien(define_insn "sse_ucomi"
1864090286Sobrien  [(set (reg:CCFPU 17)
1864190286Sobrien	(match_operator:CCFPU 2 "sse_comparison_operator"
1864290286Sobrien			[(vec_select:SF
1864390286Sobrien			  (match_operand:V4SF 0 "register_operand" "x")
1864490286Sobrien			  (parallel [(const_int 0)]))
1864590286Sobrien			 (vec_select:SF
1864690286Sobrien			  (match_operand:V4SF 1 "register_operand" "x")
1864790286Sobrien			  (parallel [(const_int 0)]))]))]
1864890286Sobrien  "TARGET_SSE"
1864990286Sobrien  "ucomiss\t{%1, %0|%0, %1}"
1865090286Sobrien  [(set_attr "type" "sse")])
1865190286Sobrien
1865290286Sobrien
1865390286Sobrien;; SSE unpack
1865490286Sobrien
1865590286Sobrien(define_insn "sse_unpckhps"
1865690286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1865790286Sobrien	(vec_merge:V4SF
1865890286Sobrien	 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
1865990286Sobrien			  (parallel [(const_int 2)
1866090286Sobrien				     (const_int 0)
1866190286Sobrien				     (const_int 3)
1866290286Sobrien				     (const_int 1)]))
1866390286Sobrien	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
1866490286Sobrien			  (parallel [(const_int 0)
1866590286Sobrien				     (const_int 2)
1866690286Sobrien				     (const_int 1)
1866790286Sobrien				     (const_int 3)]))
1866890286Sobrien	 (const_int 5)))]
1866990286Sobrien  "TARGET_SSE"
1867090286Sobrien  "unpckhps\t{%2, %0|%0, %2}"
1867190286Sobrien  [(set_attr "type" "sse")])
1867290286Sobrien
1867390286Sobrien(define_insn "sse_unpcklps"
1867490286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1867590286Sobrien	(vec_merge:V4SF
1867690286Sobrien	 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
1867790286Sobrien			  (parallel [(const_int 0)
1867890286Sobrien				     (const_int 2)
1867990286Sobrien				     (const_int 1)
1868090286Sobrien				     (const_int 3)]))
1868190286Sobrien	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
1868290286Sobrien			  (parallel [(const_int 2)
1868390286Sobrien				     (const_int 0)
1868490286Sobrien				     (const_int 3)
1868590286Sobrien				     (const_int 1)]))
1868690286Sobrien	 (const_int 5)))]
1868790286Sobrien  "TARGET_SSE"
1868890286Sobrien  "unpcklps\t{%2, %0|%0, %2}"
1868990286Sobrien  [(set_attr "type" "sse")])
1869090286Sobrien
1869190286Sobrien
1869290286Sobrien;; SSE min/max
1869390286Sobrien
1869490286Sobrien(define_insn "smaxv4sf3"
1869590286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1869690286Sobrien        (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
1869790286Sobrien		   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1869890286Sobrien  "TARGET_SSE"
1869990286Sobrien  "maxps\t{%2, %0|%0, %2}"
1870090286Sobrien  [(set_attr "type" "sse")])
1870190286Sobrien
1870290286Sobrien(define_insn "vmsmaxv4sf3"
1870390286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1870490286Sobrien	(vec_merge:V4SF
1870590286Sobrien	 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
1870690286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1870790286Sobrien	 (match_dup 1)
1870890286Sobrien	 (const_int 1)))]
1870990286Sobrien  "TARGET_SSE"
1871090286Sobrien  "maxss\t{%2, %0|%0, %2}"
1871190286Sobrien  [(set_attr "type" "sse")])
1871290286Sobrien
1871390286Sobrien(define_insn "sminv4sf3"
1871490286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1871590286Sobrien        (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
1871690286Sobrien		   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1871790286Sobrien  "TARGET_SSE"
1871890286Sobrien  "minps\t{%2, %0|%0, %2}"
1871990286Sobrien  [(set_attr "type" "sse")])
1872090286Sobrien
1872190286Sobrien(define_insn "vmsminv4sf3"
1872290286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1872390286Sobrien	(vec_merge:V4SF
1872490286Sobrien	 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
1872590286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1872690286Sobrien	 (match_dup 1)
1872790286Sobrien	 (const_int 1)))]
1872890286Sobrien  "TARGET_SSE"
1872990286Sobrien  "minss\t{%2, %0|%0, %2}"
1873090286Sobrien  [(set_attr "type" "sse")])
1873190286Sobrien
1873290286Sobrien
1873390286Sobrien;; SSE <-> integer/MMX conversions
1873490286Sobrien
1873590286Sobrien(define_insn "cvtpi2ps"
1873690286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1873790286Sobrien	(vec_merge:V4SF
1873890286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1873990286Sobrien	 (vec_duplicate:V4SF
1874090286Sobrien	  (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
1874190286Sobrien	 (const_int 12)))]
1874290286Sobrien  "TARGET_SSE"
1874390286Sobrien  "cvtpi2ps\t{%2, %0|%0, %2}"
1874490286Sobrien  [(set_attr "type" "sse")])
1874590286Sobrien
1874690286Sobrien(define_insn "cvtps2pi"
1874790286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1874890286Sobrien	(vec_select:V2SI
1874990286Sobrien	 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
1875090286Sobrien	 (parallel [(const_int 0) (const_int 1)])))]
1875190286Sobrien  "TARGET_SSE"
1875290286Sobrien  "cvtps2pi\t{%1, %0|%0, %1}"
1875390286Sobrien  [(set_attr "type" "sse")])
1875490286Sobrien
1875590286Sobrien(define_insn "cvttps2pi"
1875690286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1875790286Sobrien	(vec_select:V2SI
1875890286Sobrien	 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 30)
1875990286Sobrien	 (parallel [(const_int 0) (const_int 1)])))]
1876090286Sobrien  "TARGET_SSE"
1876190286Sobrien  "cvttps2pi\t{%1, %0|%0, %1}"
1876290286Sobrien  [(set_attr "type" "sse")])
1876390286Sobrien
1876490286Sobrien(define_insn "cvtsi2ss"
1876590286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1876690286Sobrien	(vec_merge:V4SF
1876790286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1876890286Sobrien	 (vec_duplicate:V4SF
1876990286Sobrien	  (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm")))
1877090286Sobrien	 (const_int 14)))]
1877190286Sobrien  "TARGET_SSE"
1877290286Sobrien  "cvtsi2ss\t{%2, %0|%0, %2}"
1877390286Sobrien  [(set_attr "type" "sse")])
1877490286Sobrien
1877590286Sobrien(define_insn "cvtss2si"
1877690286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1877790286Sobrien	(vec_select:SI
1877890286Sobrien	 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
1877990286Sobrien	 (parallel [(const_int 0)])))]
1878090286Sobrien  "TARGET_SSE"
1878190286Sobrien  "cvtss2si\t{%1, %0|%0, %1}"
1878290286Sobrien  [(set_attr "type" "sse")])
1878390286Sobrien
1878490286Sobrien(define_insn "cvttss2si"
1878590286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1878690286Sobrien	(vec_select:SI
1878790286Sobrien	 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 30)
1878890286Sobrien	 (parallel [(const_int 0)])))]
1878990286Sobrien  "TARGET_SSE"
1879090286Sobrien  "cvttss2si\t{%1, %0|%0, %1}"
1879190286Sobrien  [(set_attr "type" "sse")])
1879290286Sobrien
1879390286Sobrien
1879490286Sobrien;; MMX insns
1879590286Sobrien
1879690286Sobrien;; MMX arithmetic
1879790286Sobrien
1879890286Sobrien(define_insn "addv8qi3"
1879990286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1880090286Sobrien        (plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1880190286Sobrien	           (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1880290286Sobrien  "TARGET_MMX"
1880390286Sobrien  "paddb\t{%2, %0|%0, %2}"
1880490286Sobrien  [(set_attr "type" "mmx")])
1880590286Sobrien
1880690286Sobrien(define_insn "addv4hi3"
1880790286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1880890286Sobrien        (plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
1880990286Sobrien	           (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1881090286Sobrien  "TARGET_MMX"
1881190286Sobrien  "paddw\t{%2, %0|%0, %2}"
1881290286Sobrien  [(set_attr "type" "mmx")])
1881390286Sobrien
1881490286Sobrien(define_insn "addv2si3"
1881590286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1881690286Sobrien        (plus:V2SI (match_operand:V2SI 1 "register_operand" "0")
1881790286Sobrien	           (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
1881890286Sobrien  "TARGET_MMX"
1881990286Sobrien  "paddd\t{%2, %0|%0, %2}"
1882090286Sobrien  [(set_attr "type" "mmx")])
1882190286Sobrien
1882290286Sobrien(define_insn "ssaddv8qi3"
1882390286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1882490286Sobrien        (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1882590286Sobrien		      (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1882690286Sobrien  "TARGET_MMX"
1882790286Sobrien  "paddsb\t{%2, %0|%0, %2}"
1882890286Sobrien  [(set_attr "type" "mmx")])
1882990286Sobrien
1883090286Sobrien(define_insn "ssaddv4hi3"
1883190286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1883290286Sobrien        (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
1883390286Sobrien		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1883490286Sobrien  "TARGET_MMX"
1883590286Sobrien  "paddsw\t{%2, %0|%0, %2}"
1883690286Sobrien  [(set_attr "type" "mmx")])
1883790286Sobrien
1883890286Sobrien(define_insn "usaddv8qi3"
1883990286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1884090286Sobrien        (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1884190286Sobrien		      (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1884290286Sobrien  "TARGET_MMX"
1884390286Sobrien  "paddusb\t{%2, %0|%0, %2}"
1884490286Sobrien  [(set_attr "type" "mmx")])
1884590286Sobrien
1884690286Sobrien(define_insn "usaddv4hi3"
1884790286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1884890286Sobrien        (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
1884990286Sobrien		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1885090286Sobrien  "TARGET_MMX"
1885190286Sobrien  "paddusw\t{%2, %0|%0, %2}"
1885290286Sobrien  [(set_attr "type" "mmx")])
1885390286Sobrien
1885490286Sobrien(define_insn "subv8qi3"
1885590286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1885690286Sobrien        (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1885790286Sobrien		    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1885890286Sobrien  "TARGET_MMX"
1885990286Sobrien  "psubb\t{%2, %0|%0, %2}"
1886090286Sobrien  [(set_attr "type" "mmx")])
1886190286Sobrien
1886290286Sobrien(define_insn "subv4hi3"
1886390286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1886490286Sobrien        (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
1886590286Sobrien		    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1886690286Sobrien  "TARGET_MMX"
1886790286Sobrien  "psubw\t{%2, %0|%0, %2}"
1886890286Sobrien  [(set_attr "type" "mmx")])
1886990286Sobrien
1887090286Sobrien(define_insn "subv2si3"
1887190286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1887290286Sobrien        (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
1887390286Sobrien		    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
1887490286Sobrien  "TARGET_MMX"
1887590286Sobrien  "psubd\t{%2, %0|%0, %2}"
1887690286Sobrien  [(set_attr "type" "mmx")])
1887790286Sobrien
1887890286Sobrien(define_insn "sssubv8qi3"
1887990286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1888090286Sobrien        (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1888190286Sobrien		       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1888290286Sobrien  "TARGET_MMX"
1888390286Sobrien  "psubsb\t{%2, %0|%0, %2}"
1888490286Sobrien  [(set_attr "type" "mmx")])
1888590286Sobrien
1888690286Sobrien(define_insn "sssubv4hi3"
1888790286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1888890286Sobrien        (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
1888990286Sobrien		       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1889090286Sobrien  "TARGET_MMX"
1889190286Sobrien  "psubsw\t{%2, %0|%0, %2}"
1889290286Sobrien  [(set_attr "type" "mmx")])
1889390286Sobrien
1889490286Sobrien(define_insn "ussubv8qi3"
1889590286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1889690286Sobrien        (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1889790286Sobrien		       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1889890286Sobrien  "TARGET_MMX"
1889990286Sobrien  "psubusb\t{%2, %0|%0, %2}"
1890090286Sobrien  [(set_attr "type" "mmx")])
1890190286Sobrien
1890290286Sobrien(define_insn "ussubv4hi3"
1890390286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1890490286Sobrien        (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
1890590286Sobrien		       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1890690286Sobrien  "TARGET_MMX"
1890790286Sobrien  "psubusw\t{%2, %0|%0, %2}"
1890890286Sobrien  [(set_attr "type" "mmx")])
1890990286Sobrien
1891090286Sobrien(define_insn "mulv4hi3"
1891190286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1891290286Sobrien        (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
1891390286Sobrien		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1891490286Sobrien  "TARGET_MMX"
1891590286Sobrien  "pmullw\t{%2, %0|%0, %2}"
1891690286Sobrien  [(set_attr "type" "mmx")])
1891790286Sobrien
1891890286Sobrien(define_insn "smulv4hi3_highpart"
1891990286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1892090286Sobrien	(truncate:V4HI
1892190286Sobrien	 (lshiftrt:V4SI
1892290286Sobrien	  (mult:V4SI (sign_extend:V4SI
1892390286Sobrien		      (match_operand:V4HI 1 "register_operand" "0"))
1892490286Sobrien		     (sign_extend:V4SI
1892590286Sobrien		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1892690286Sobrien	  (const_int 16))))]
1892790286Sobrien  "TARGET_MMX"
1892890286Sobrien  "pmulhw\t{%2, %0|%0, %2}"
1892990286Sobrien  [(set_attr "type" "mmx")])
1893090286Sobrien
1893190286Sobrien(define_insn "umulv4hi3_highpart"
1893290286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1893390286Sobrien	(truncate:V4HI
1893490286Sobrien	 (lshiftrt:V4SI
1893590286Sobrien	  (mult:V4SI (zero_extend:V4SI
1893690286Sobrien		      (match_operand:V4HI 1 "register_operand" "0"))
1893790286Sobrien		     (zero_extend:V4SI
1893890286Sobrien		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1893990286Sobrien	  (const_int 16))))]
1894090286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1894190286Sobrien  "pmulhuw\t{%2, %0|%0, %2}"
1894290286Sobrien  [(set_attr "type" "mmx")])
1894390286Sobrien
1894490286Sobrien(define_insn "mmx_pmaddwd"
1894590286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1894690286Sobrien        (plus:V2SI
1894790286Sobrien	 (mult:V2SI
1894890286Sobrien	  (sign_extend:V2SI
1894990286Sobrien	   (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
1895090286Sobrien			    (parallel [(const_int 0) (const_int 2)])))
1895190286Sobrien	  (sign_extend:V2SI
1895290286Sobrien	   (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
1895390286Sobrien			    (parallel [(const_int 0) (const_int 2)]))))
1895490286Sobrien	 (mult:V2SI
1895590286Sobrien	  (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
1895690286Sobrien					     (parallel [(const_int 1)
1895790286Sobrien							(const_int 3)])))
1895890286Sobrien	  (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
1895990286Sobrien					     (parallel [(const_int 1)
1896090286Sobrien							(const_int 3)]))))))]
1896190286Sobrien  "TARGET_MMX"
1896290286Sobrien  "pmaddwd\t{%2, %0|%0, %2}"
1896390286Sobrien  [(set_attr "type" "mmx")])
1896490286Sobrien
1896590286Sobrien
1896690286Sobrien;; MMX logical operations
1896790286Sobrien;; Note we don't want to declare these as regular iordi3 insns to prevent
1896890286Sobrien;; normal code that also wants to use the FPU from getting broken.
1896990286Sobrien;; The UNSPECs are there to prevent the combiner from getting overly clever.
1897090286Sobrien(define_insn "mmx_iordi3"
1897190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1897290286Sobrien        (unspec:DI
1897390286Sobrien	 [(ior:DI (match_operand:DI 1 "register_operand" "0")
1897490286Sobrien		  (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
1897590286Sobrien  "TARGET_MMX"
1897690286Sobrien  "por\t{%2, %0|%0, %2}"
1897790286Sobrien  [(set_attr "type" "mmx")])
1897890286Sobrien
1897990286Sobrien(define_insn "mmx_xordi3"
1898090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1898190286Sobrien        (unspec:DI
1898290286Sobrien	 [(xor:DI (match_operand:DI 1 "register_operand" "0")
1898390286Sobrien		  (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
1898490286Sobrien  "TARGET_MMX"
1898590286Sobrien  "pxor\t{%2, %0|%0, %2}"
1898690286Sobrien  [(set_attr "type" "mmx")
1898790286Sobrien   (set_attr "memory" "none")])
1898890286Sobrien
1898990286Sobrien;; Same as pxor, but don't show input operands so that we don't think
1899090286Sobrien;; they are live.
1899190286Sobrien(define_insn "mmx_clrdi"
1899290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1899390286Sobrien        (unspec:DI [(const_int 0)] 45))]
1899490286Sobrien  "TARGET_MMX"
1899590286Sobrien  "pxor\t{%0, %0|%0, %0}"
1899690286Sobrien  [(set_attr "type" "mmx")
1899790286Sobrien   (set_attr "memory" "none")])
1899890286Sobrien
1899990286Sobrien(define_insn "mmx_anddi3"
1900090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1900190286Sobrien        (unspec:DI
1900290286Sobrien	 [(and:DI (match_operand:DI 1 "register_operand" "0")
1900390286Sobrien		  (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
1900490286Sobrien  "TARGET_MMX"
1900590286Sobrien  "pand\t{%2, %0|%0, %2}"
1900690286Sobrien  [(set_attr "type" "mmx")])
1900790286Sobrien
1900890286Sobrien(define_insn "mmx_nanddi3"
1900990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1901090286Sobrien        (unspec:DI
1901190286Sobrien	 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
1901290286Sobrien			  (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
1901390286Sobrien  "TARGET_MMX"
1901490286Sobrien  "pandn\t{%2, %0|%0, %2}"
1901590286Sobrien  [(set_attr "type" "mmx")])
1901690286Sobrien
1901790286Sobrien
1901890286Sobrien;; MMX unsigned averages/sum of absolute differences
1901990286Sobrien
1902090286Sobrien(define_insn "mmx_uavgv8qi3"
1902190286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1902290286Sobrien        (ashiftrt:V8QI
1902390286Sobrien	 (plus:V8QI (plus:V8QI
1902490286Sobrien		     (match_operand:V8QI 1 "register_operand" "0")
1902590286Sobrien		     (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1902696294Sobrien		    (const_vector:V8QI [(const_int 1)
1902796294Sobrien					(const_int 1)
1902896294Sobrien					(const_int 1)
1902996294Sobrien					(const_int 1)
1903096294Sobrien					(const_int 1)
1903196294Sobrien					(const_int 1)
1903296294Sobrien					(const_int 1)
1903396294Sobrien					(const_int 1)]))
1903490286Sobrien	 (const_int 1)))]
1903590286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1903690286Sobrien  "pavgb\t{%2, %0|%0, %2}"
1903790286Sobrien  [(set_attr "type" "sse")])
1903890286Sobrien
1903990286Sobrien(define_insn "mmx_uavgv4hi3"
1904090286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1904190286Sobrien        (ashiftrt:V4HI
1904290286Sobrien	 (plus:V4HI (plus:V4HI
1904390286Sobrien		     (match_operand:V4HI 1 "register_operand" "0")
1904490286Sobrien		     (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1904596294Sobrien		    (const_vector:V4HI [(const_int 1)
1904696294Sobrien					(const_int 1)
1904796294Sobrien					(const_int 1)
1904896294Sobrien					(const_int 1)]))
1904990286Sobrien	 (const_int 1)))]
1905090286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1905190286Sobrien  "pavgw\t{%2, %0|%0, %2}"
1905290286Sobrien  [(set_attr "type" "sse")])
1905390286Sobrien
1905490286Sobrien(define_insn "mmx_psadbw"
1905590286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1905690286Sobrien        (abs:V8QI (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1905790286Sobrien			      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))))]
1905890286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1905990286Sobrien  "psadbw\t{%2, %0|%0, %2}"
1906090286Sobrien  [(set_attr "type" "sse")])
1906190286Sobrien
1906290286Sobrien
1906390286Sobrien;; MMX insert/extract/shuffle
1906490286Sobrien
1906590286Sobrien(define_insn "mmx_pinsrw"
1906690286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1906790286Sobrien        (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
1906890286Sobrien			(vec_duplicate:V4HI
1906990286Sobrien			 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
1907090286Sobrien			(match_operand:SI 3 "immediate_operand" "i")))]
1907190286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1907290286Sobrien  "pinsrw\t{%3, %2, %0|%0, %2, %3}"
1907390286Sobrien  [(set_attr "type" "sse")])
1907490286Sobrien
1907590286Sobrien(define_insn "mmx_pextrw"
1907690286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1907790286Sobrien        (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
1907890286Sobrien				       (parallel
1907990286Sobrien					[(match_operand:SI 2 "immediate_operand" "i")]))))]
1908090286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1908190286Sobrien  "pextrw\t{%2, %1, %0|%0, %1, %2}"
1908290286Sobrien  [(set_attr "type" "sse")])
1908390286Sobrien
1908490286Sobrien(define_insn "mmx_pshufw"
1908590286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1908690286Sobrien        (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
1908790286Sobrien		      (match_operand:SI 2 "immediate_operand" "i")] 41))]
1908890286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1908990286Sobrien  "pshufw\t{%2, %1, %0|%0, %1, %2}"
1909090286Sobrien  [(set_attr "type" "sse")])
1909190286Sobrien
1909290286Sobrien
1909390286Sobrien;; MMX mask-generating comparisons
1909490286Sobrien
1909590286Sobrien(define_insn "eqv8qi3"
1909690286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1909790286Sobrien        (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
1909890286Sobrien		 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1909990286Sobrien  "TARGET_MMX"
1910090286Sobrien  "pcmpeqb\t{%2, %0|%0, %2}"
1910190286Sobrien  [(set_attr "type" "mmx")])
1910290286Sobrien
1910390286Sobrien(define_insn "eqv4hi3"
1910490286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1910590286Sobrien        (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
1910690286Sobrien		 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1910790286Sobrien  "TARGET_MMX"
1910890286Sobrien  "pcmpeqw\t{%2, %0|%0, %2}"
1910990286Sobrien  [(set_attr "type" "mmx")])
1911090286Sobrien
1911190286Sobrien(define_insn "eqv2si3"
1911290286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1911390286Sobrien        (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
1911490286Sobrien		 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
1911590286Sobrien  "TARGET_MMX"
1911690286Sobrien  "pcmpeqd\t{%2, %0|%0, %2}"
1911790286Sobrien  [(set_attr "type" "mmx")])
1911890286Sobrien
1911990286Sobrien(define_insn "gtv8qi3"
1912090286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1912190286Sobrien        (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
1912290286Sobrien		 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1912390286Sobrien  "TARGET_MMX"
1912490286Sobrien  "pcmpgtb\t{%2, %0|%0, %2}"
1912590286Sobrien  [(set_attr "type" "mmx")])
1912690286Sobrien
1912790286Sobrien(define_insn "gtv4hi3"
1912890286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1912990286Sobrien        (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
1913090286Sobrien		 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1913190286Sobrien  "TARGET_MMX"
1913290286Sobrien  "pcmpgtw\t{%2, %0|%0, %2}"
1913390286Sobrien  [(set_attr "type" "mmx")])
1913490286Sobrien
1913590286Sobrien(define_insn "gtv2si3"
1913690286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1913790286Sobrien        (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
1913890286Sobrien		 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
1913990286Sobrien  "TARGET_MMX"
1914090286Sobrien  "pcmpgtd\t{%2, %0|%0, %2}"
1914190286Sobrien  [(set_attr "type" "mmx")])
1914290286Sobrien
1914390286Sobrien
1914490286Sobrien;; MMX max/min insns
1914590286Sobrien
1914690286Sobrien(define_insn "umaxv8qi3"
1914790286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1914890286Sobrien        (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
1914990286Sobrien		   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1915090286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1915190286Sobrien  "pmaxub\t{%2, %0|%0, %2}"
1915290286Sobrien  [(set_attr "type" "sse")])
1915390286Sobrien
1915490286Sobrien(define_insn "smaxv4hi3"
1915590286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1915690286Sobrien        (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
1915790286Sobrien		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1915890286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1915990286Sobrien  "pmaxsw\t{%2, %0|%0, %2}"
1916090286Sobrien  [(set_attr "type" "sse")])
1916190286Sobrien
1916290286Sobrien(define_insn "uminv8qi3"
1916390286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1916490286Sobrien        (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
1916590286Sobrien		   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1916690286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1916790286Sobrien  "pminub\t{%2, %0|%0, %2}"
1916890286Sobrien  [(set_attr "type" "sse")])
1916990286Sobrien
1917090286Sobrien(define_insn "sminv4hi3"
1917190286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1917290286Sobrien        (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
1917390286Sobrien		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1917490286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1917590286Sobrien  "pminsw\t{%2, %0|%0, %2}"
1917690286Sobrien  [(set_attr "type" "sse")])
1917790286Sobrien
1917890286Sobrien
1917990286Sobrien;; MMX shifts
1918090286Sobrien
1918190286Sobrien(define_insn "ashrv4hi3"
1918290286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1918390286Sobrien        (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
1918490286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1918590286Sobrien  "TARGET_MMX"
1918690286Sobrien  "psraw\t{%2, %0|%0, %2}"
1918790286Sobrien  [(set_attr "type" "mmx")])
1918890286Sobrien
1918990286Sobrien(define_insn "ashrv2si3"
1919090286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1919190286Sobrien        (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
1919290286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1919390286Sobrien  "TARGET_MMX"
1919490286Sobrien  "psrad\t{%2, %0|%0, %2}"
1919590286Sobrien  [(set_attr "type" "mmx")])
1919690286Sobrien
1919790286Sobrien(define_insn "lshrv4hi3"
1919890286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1919990286Sobrien        (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
1920090286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1920190286Sobrien  "TARGET_MMX"
1920290286Sobrien  "psrlw\t{%2, %0|%0, %2}"
1920390286Sobrien  [(set_attr "type" "mmx")])
1920490286Sobrien
1920590286Sobrien(define_insn "lshrv2si3"
1920690286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1920790286Sobrien        (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
1920890286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1920990286Sobrien  "TARGET_MMX"
1921090286Sobrien  "psrld\t{%2, %0|%0, %2}"
1921190286Sobrien  [(set_attr "type" "mmx")])
1921290286Sobrien
1921390286Sobrien;; See logical MMX insns.
1921490286Sobrien(define_insn "mmx_lshrdi3"
1921590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1921690286Sobrien        (unspec:DI
1921790286Sobrien	  [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
1921890286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
1921990286Sobrien  "TARGET_MMX"
1922090286Sobrien  "psrlq\t{%2, %0|%0, %2}"
1922190286Sobrien  [(set_attr "type" "mmx")])
1922290286Sobrien
1922390286Sobrien(define_insn "ashlv4hi3"
1922490286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1922590286Sobrien        (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
1922690286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1922790286Sobrien  "TARGET_MMX"
1922890286Sobrien  "psllw\t{%2, %0|%0, %2}"
1922990286Sobrien  [(set_attr "type" "mmx")])
1923090286Sobrien
1923190286Sobrien(define_insn "ashlv2si3"
1923290286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1923390286Sobrien        (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
1923490286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1923590286Sobrien  "TARGET_MMX"
1923690286Sobrien  "pslld\t{%2, %0|%0, %2}"
1923790286Sobrien  [(set_attr "type" "mmx")])
1923890286Sobrien
1923990286Sobrien;; See logical MMX insns.
1924090286Sobrien(define_insn "mmx_ashldi3"
1924190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1924290286Sobrien        (unspec:DI
1924390286Sobrien	 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
1924490286Sobrien		     (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
1924590286Sobrien  "TARGET_MMX"
1924690286Sobrien  "psllq\t{%2, %0|%0, %2}"
1924790286Sobrien  [(set_attr "type" "mmx")])
1924890286Sobrien
1924990286Sobrien
1925090286Sobrien;; MMX pack/unpack insns.
1925190286Sobrien
1925290286Sobrien(define_insn "mmx_packsswb"
1925390286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1925490286Sobrien	(vec_concat:V8QI
1925590286Sobrien	 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
1925690286Sobrien	 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
1925790286Sobrien  "TARGET_MMX"
1925890286Sobrien  "packsswb\t{%2, %0|%0, %2}"
1925990286Sobrien  [(set_attr "type" "mmx")])
1926090286Sobrien
1926190286Sobrien(define_insn "mmx_packssdw"
1926290286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1926390286Sobrien	(vec_concat:V4HI
1926490286Sobrien	 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
1926590286Sobrien	 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
1926690286Sobrien  "TARGET_MMX"
1926790286Sobrien  "packssdw\t{%2, %0|%0, %2}"
1926890286Sobrien  [(set_attr "type" "mmx")])
1926990286Sobrien
1927090286Sobrien(define_insn "mmx_packuswb"
1927190286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1927290286Sobrien	(vec_concat:V8QI
1927390286Sobrien	 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
1927490286Sobrien	 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
1927590286Sobrien  "TARGET_MMX"
1927690286Sobrien  "packuswb\t{%2, %0|%0, %2}"
1927790286Sobrien  [(set_attr "type" "mmx")])
1927890286Sobrien
1927990286Sobrien(define_insn "mmx_punpckhbw"
1928090286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1928190286Sobrien	(vec_merge:V8QI
1928290286Sobrien	 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
1928390286Sobrien			  (parallel [(const_int 4)
1928490286Sobrien				     (const_int 0)
1928590286Sobrien				     (const_int 5)
1928690286Sobrien				     (const_int 1)
1928790286Sobrien				     (const_int 6)
1928890286Sobrien				     (const_int 2)
1928990286Sobrien				     (const_int 7)
1929090286Sobrien				     (const_int 3)]))
1929190286Sobrien	 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
1929290286Sobrien			  (parallel [(const_int 0)
1929390286Sobrien				     (const_int 4)
1929490286Sobrien				     (const_int 1)
1929590286Sobrien				     (const_int 5)
1929690286Sobrien				     (const_int 2)
1929790286Sobrien				     (const_int 6)
1929890286Sobrien				     (const_int 3)
1929990286Sobrien				     (const_int 7)]))
1930090286Sobrien	 (const_int 85)))]
1930190286Sobrien  "TARGET_MMX"
1930290286Sobrien  "punpckhbw\t{%2, %0|%0, %2}"
1930390286Sobrien  [(set_attr "type" "mmx")])
1930490286Sobrien
1930590286Sobrien(define_insn "mmx_punpckhwd"
1930690286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1930790286Sobrien	(vec_merge:V4HI
1930890286Sobrien	 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
1930990286Sobrien			  (parallel [(const_int 0)
1931090286Sobrien				     (const_int 2)
1931190286Sobrien				     (const_int 1)
1931290286Sobrien				     (const_int 3)]))
1931390286Sobrien	 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
1931490286Sobrien			  (parallel [(const_int 2)
1931590286Sobrien				     (const_int 0)
1931690286Sobrien				     (const_int 3)
1931790286Sobrien				     (const_int 1)]))
1931890286Sobrien	 (const_int 5)))]
1931990286Sobrien  "TARGET_MMX"
1932090286Sobrien  "punpckhwd\t{%2, %0|%0, %2}"
1932190286Sobrien  [(set_attr "type" "mmx")])
1932290286Sobrien
1932390286Sobrien(define_insn "mmx_punpckhdq"
1932490286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1932590286Sobrien	(vec_merge:V2SI
1932690286Sobrien	 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
1932790286Sobrien			  (parallel [(const_int 0)
1932890286Sobrien				     (const_int 1)]))
1932990286Sobrien	 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
1933090286Sobrien			  (parallel [(const_int 1)
1933190286Sobrien				     (const_int 0)]))
1933290286Sobrien	 (const_int 1)))]
1933390286Sobrien  "TARGET_MMX"
1933490286Sobrien  "punpckhdq\t{%2, %0|%0, %2}"
1933590286Sobrien  [(set_attr "type" "mmx")])
1933690286Sobrien
1933790286Sobrien(define_insn "mmx_punpcklbw"
1933890286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1933990286Sobrien	(vec_merge:V8QI
1934090286Sobrien	 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
1934190286Sobrien			  (parallel [(const_int 0)
1934290286Sobrien				     (const_int 4)
1934390286Sobrien				     (const_int 1)
1934490286Sobrien				     (const_int 5)
1934590286Sobrien				     (const_int 2)
1934690286Sobrien				     (const_int 6)
1934790286Sobrien				     (const_int 3)
1934890286Sobrien				     (const_int 7)]))
1934990286Sobrien	 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
1935090286Sobrien			  (parallel [(const_int 4)
1935190286Sobrien				     (const_int 0)
1935290286Sobrien				     (const_int 5)
1935390286Sobrien				     (const_int 1)
1935490286Sobrien				     (const_int 6)
1935590286Sobrien				     (const_int 2)
1935690286Sobrien				     (const_int 7)
1935790286Sobrien				     (const_int 3)]))
1935890286Sobrien	 (const_int 85)))]
1935990286Sobrien  "TARGET_MMX"
1936090286Sobrien  "punpcklbw\t{%2, %0|%0, %2}"
1936190286Sobrien  [(set_attr "type" "mmx")])
1936290286Sobrien
1936390286Sobrien(define_insn "mmx_punpcklwd"
1936490286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1936590286Sobrien	(vec_merge:V4HI
1936690286Sobrien	 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
1936790286Sobrien			  (parallel [(const_int 2)
1936890286Sobrien				     (const_int 0)
1936990286Sobrien				     (const_int 3)
1937090286Sobrien				     (const_int 1)]))
1937190286Sobrien	 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
1937290286Sobrien			  (parallel [(const_int 0)
1937390286Sobrien				     (const_int 2)
1937490286Sobrien				     (const_int 1)
1937590286Sobrien				     (const_int 3)]))
1937690286Sobrien	 (const_int 5)))]
1937790286Sobrien  "TARGET_MMX"
1937890286Sobrien  "punpcklwd\t{%2, %0|%0, %2}"
1937990286Sobrien  [(set_attr "type" "mmx")])
1938090286Sobrien
1938190286Sobrien(define_insn "mmx_punpckldq"
1938290286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1938390286Sobrien	(vec_merge:V2SI
1938490286Sobrien	 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
1938590286Sobrien			   (parallel [(const_int 1)
1938690286Sobrien				      (const_int 0)]))
1938790286Sobrien	 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
1938890286Sobrien			  (parallel [(const_int 0)
1938990286Sobrien				     (const_int 1)]))
1939090286Sobrien	 (const_int 1)))]
1939190286Sobrien  "TARGET_MMX"
1939290286Sobrien  "punpckldq\t{%2, %0|%0, %2}"
1939390286Sobrien  [(set_attr "type" "mmx")])
1939490286Sobrien
1939590286Sobrien
1939690286Sobrien;; Miscellaneous stuff
1939790286Sobrien
1939890286Sobrien(define_insn "emms"
1939990286Sobrien  [(unspec_volatile [(const_int 0)] 31)
1940090286Sobrien   (clobber (reg:XF 8))
1940190286Sobrien   (clobber (reg:XF 9))
1940290286Sobrien   (clobber (reg:XF 10))
1940390286Sobrien   (clobber (reg:XF 11))
1940490286Sobrien   (clobber (reg:XF 12))
1940590286Sobrien   (clobber (reg:XF 13))
1940690286Sobrien   (clobber (reg:XF 14))
1940790286Sobrien   (clobber (reg:XF 15))
1940890286Sobrien   (clobber (reg:DI 29))
1940990286Sobrien   (clobber (reg:DI 30))
1941090286Sobrien   (clobber (reg:DI 31))
1941190286Sobrien   (clobber (reg:DI 32))
1941290286Sobrien   (clobber (reg:DI 33))
1941390286Sobrien   (clobber (reg:DI 34))
1941490286Sobrien   (clobber (reg:DI 35))
1941590286Sobrien   (clobber (reg:DI 36))]
1941690286Sobrien  "TARGET_MMX"
1941790286Sobrien  "emms"
1941890286Sobrien  [(set_attr "type" "mmx")
1941990286Sobrien   (set_attr "memory" "unknown")])
1942090286Sobrien
1942190286Sobrien(define_insn "ldmxcsr"
1942290286Sobrien  [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 37)]
1942390286Sobrien  "TARGET_MMX"
1942490286Sobrien  "ldmxcsr\t%0"
1942590286Sobrien  [(set_attr "type" "mmx")
1942690286Sobrien   (set_attr "memory" "load")])
1942790286Sobrien
1942890286Sobrien(define_insn "stmxcsr"
1942990286Sobrien  [(set (match_operand:SI 0 "memory_operand" "=m")
1943090286Sobrien	(unspec_volatile:SI [(const_int 0)] 40))]
1943190286Sobrien  "TARGET_MMX"
1943290286Sobrien  "stmxcsr\t%0"
1943390286Sobrien  [(set_attr "type" "mmx")
1943490286Sobrien   (set_attr "memory" "store")])
1943590286Sobrien
1943690286Sobrien(define_expand "sfence"
1943790286Sobrien  [(set (match_dup 0)
1943890286Sobrien	(unspec:BLK [(match_dup 0)] 44))]
1943990286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1944090286Sobrien{
1944190286Sobrien  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
1944290286Sobrien  MEM_VOLATILE_P (operands[0]) = 1;
1944390286Sobrien})
1944490286Sobrien
1944590286Sobrien(define_insn "*sfence_insn"
1944690286Sobrien  [(set (match_operand:BLK 0 "" "")
1944790286Sobrien	(unspec:BLK [(match_dup 0)] 44))]
1944890286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1944990286Sobrien  "sfence"
1945090286Sobrien  [(set_attr "type" "sse")
1945190286Sobrien   (set_attr "memory" "unknown")])
1945290286Sobrien
1945390286Sobrien(define_expand "sse_prologue_save"
1945490286Sobrien  [(parallel [(set (match_operand:BLK 0 "" "")
1945590286Sobrien		   (unspec:BLK [(reg:DI 21)
1945690286Sobrien				(reg:DI 22)
1945790286Sobrien				(reg:DI 23)
1945890286Sobrien				(reg:DI 24)
1945990286Sobrien				(reg:DI 25)
1946090286Sobrien				(reg:DI 26)
1946190286Sobrien				(reg:DI 27)
1946290286Sobrien				(reg:DI 28)] 13))
1946390286Sobrien	      (use (match_operand:DI 1 "register_operand" ""))
1946490286Sobrien	      (use (match_operand:DI 2 "immediate_operand" ""))
1946590286Sobrien	      (use (label_ref:DI (match_operand 3 "" "")))])]
1946690286Sobrien  "TARGET_64BIT"
1946790286Sobrien  "")
1946890286Sobrien
1946990286Sobrien(define_insn "*sse_prologue_save_insn"
1947090286Sobrien  [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
1947190286Sobrien			  (match_operand:DI 4 "const_int_operand" "n")))
1947290286Sobrien	(unspec:BLK [(reg:DI 21)
1947390286Sobrien		     (reg:DI 22)
1947490286Sobrien		     (reg:DI 23)
1947590286Sobrien		     (reg:DI 24)
1947690286Sobrien		     (reg:DI 25)
1947790286Sobrien		     (reg:DI 26)
1947890286Sobrien		     (reg:DI 27)
1947990286Sobrien		     (reg:DI 28)] 13))
1948090286Sobrien   (use (match_operand:DI 1 "register_operand" "r"))
1948190286Sobrien   (use (match_operand:DI 2 "const_int_operand" "i"))
1948290286Sobrien   (use (label_ref:DI (match_operand 3 "" "X")))]
1948390286Sobrien  "TARGET_64BIT
1948490286Sobrien   && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
1948590286Sobrien   && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
1948690286Sobrien  "*
1948790286Sobrien{
1948890286Sobrien  int i;
1948990286Sobrien  operands[0] = gen_rtx_MEM (Pmode,
1949090286Sobrien			     gen_rtx_PLUS (Pmode, operands[0], operands[4]));
1949190286Sobrien  output_asm_insn (\"jmp\\t%A1\", operands);
1949290286Sobrien  for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
1949390286Sobrien    {
1949490286Sobrien      operands[4] = adjust_address (operands[0], DImode, i*16);
1949590286Sobrien      operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
1949690286Sobrien      PUT_MODE (operands[4], TImode);
1949790286Sobrien      if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
1949890286Sobrien        output_asm_insn (\"rex\", operands);
1949990286Sobrien      output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
1950090286Sobrien    }
1950190286Sobrien  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
1950290286Sobrien			     CODE_LABEL_NUMBER (operands[3]));
1950390286Sobrien  RET;
1950490286Sobrien}
1950556391Sobrien  "
1950690286Sobrien  [(set_attr "type" "other")
1950790286Sobrien   (set_attr "length_immediate" "0")
1950890286Sobrien   (set_attr "length_address" "0")
1950990286Sobrien   (set_attr "length" "135")
1951090286Sobrien   (set_attr "memory" "store")
1951190286Sobrien   (set_attr "modrm" "0")
1951290286Sobrien   (set_attr "mode" "DI")])
1951390286Sobrien
1951490286Sobrien;; 3Dnow! instructions
1951590286Sobrien
1951690286Sobrien(define_insn "addv2sf3"
1951790286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1951890286Sobrien	(plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
1951990286Sobrien		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1952090286Sobrien  "TARGET_3DNOW"
1952190286Sobrien  "pfadd\\t{%2, %0|%0, %2}"
1952290286Sobrien  [(set_attr "type" "mmx")])
1952390286Sobrien
1952490286Sobrien(define_insn "subv2sf3"
1952590286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1952690286Sobrien        (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
1952790286Sobrien		    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1952890286Sobrien  "TARGET_3DNOW"
1952990286Sobrien  "pfsub\\t{%2, %0|%0, %2}"
1953090286Sobrien  [(set_attr "type" "mmx")])
1953190286Sobrien
1953290286Sobrien(define_insn "subrv2sf3"
1953390286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1953490286Sobrien        (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
1953590286Sobrien                    (match_operand:V2SF 1 "register_operand" "0")))]
1953690286Sobrien  "TARGET_3DNOW"
1953790286Sobrien  "pfsubr\\t{%2, %0|%0, %2}"
1953890286Sobrien  [(set_attr "type" "mmx")])
1953990286Sobrien
1954090286Sobrien(define_insn "gtv2sf3"
1954190286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1954290286Sobrien	(gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
1954390286Sobrien		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1954490286Sobrien "TARGET_3DNOW"
1954590286Sobrien  "pfcmpgt\\t{%2, %0|%0, %2}"
1954690286Sobrien  [(set_attr "type" "mmx")])
1954790286Sobrien
1954890286Sobrien(define_insn "gev2sf3"
1954990286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1955090286Sobrien	(ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
1955190286Sobrien		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1955290286Sobrien  "TARGET_3DNOW"
1955390286Sobrien  "pfcmpge\\t{%2, %0|%0, %2}"
1955490286Sobrien  [(set_attr "type" "mmx")])
1955590286Sobrien
1955690286Sobrien(define_insn "eqv2sf3"
1955790286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1955890286Sobrien	(eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
1955990286Sobrien		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1956090286Sobrien  "TARGET_3DNOW"
1956190286Sobrien  "pfcmpeq\\t{%2, %0|%0, %2}"
1956290286Sobrien  [(set_attr "type" "mmx")])
1956390286Sobrien
1956490286Sobrien(define_insn "pfmaxv2sf3"
1956590286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1956690286Sobrien        (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
1956790286Sobrien                   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1956890286Sobrien  "TARGET_3DNOW"
1956990286Sobrien  "pfmax\\t{%2, %0|%0, %2}"
1957090286Sobrien  [(set_attr "type" "mmx")])
1957190286Sobrien
1957290286Sobrien(define_insn "pfminv2sf3"
1957390286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1957490286Sobrien        (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
1957590286Sobrien                   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1957690286Sobrien  "TARGET_3DNOW"
1957790286Sobrien  "pfmin\\t{%2, %0|%0, %2}"
1957890286Sobrien  [(set_attr "type" "mmx")])
1957990286Sobrien
1958090286Sobrien(define_insn "mulv2sf3"
1958190286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1958290286Sobrien	(mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
1958390286Sobrien		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1958490286Sobrien  "TARGET_3DNOW"
1958590286Sobrien  "pfmul\\t{%2, %0|%0, %2}"
1958690286Sobrien  [(set_attr "type" "mmx")])
1958790286Sobrien
1958890286Sobrien(define_insn "femms"
1958990286Sobrien  [(unspec_volatile [(const_int 0)] 46)
1959090286Sobrien   (clobber (reg:XF 8))
1959190286Sobrien   (clobber (reg:XF 9))
1959290286Sobrien   (clobber (reg:XF 10))
1959390286Sobrien   (clobber (reg:XF 11))
1959490286Sobrien   (clobber (reg:XF 12))
1959590286Sobrien   (clobber (reg:XF 13))
1959690286Sobrien   (clobber (reg:XF 14))
1959790286Sobrien   (clobber (reg:XF 15))
1959890286Sobrien   (clobber (reg:DI 29))
1959990286Sobrien   (clobber (reg:DI 30))
1960090286Sobrien   (clobber (reg:DI 31))
1960190286Sobrien   (clobber (reg:DI 32))
1960290286Sobrien   (clobber (reg:DI 33))
1960390286Sobrien   (clobber (reg:DI 34))
1960490286Sobrien   (clobber (reg:DI 35))
1960590286Sobrien   (clobber (reg:DI 36))]
1960690286Sobrien  "TARGET_3DNOW"
1960790286Sobrien  "femms"
1960890286Sobrien  [(set_attr "type" "mmx")])
1960990286Sobrien
1961090286Sobrien(define_insn "pf2id"
1961190286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1961290286Sobrien	(fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
1961390286Sobrien  "TARGET_3DNOW"
1961490286Sobrien  "pf2id\\t{%1, %0|%0, %1}"
1961590286Sobrien  [(set_attr "type" "mmx")])
1961690286Sobrien
1961790286Sobrien(define_insn "pf2iw"
1961890286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1961990286Sobrien	(sign_extend:V2SI
1962090286Sobrien	   (ss_truncate:V2HI
1962190286Sobrien	      (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
1962290286Sobrien  "TARGET_3DNOW_A"
1962390286Sobrien  "pf2iw\\t{%1, %0|%0, %1}"
1962490286Sobrien  [(set_attr "type" "mmx")])
1962590286Sobrien
1962690286Sobrien(define_insn "pfacc"
1962790286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1962890286Sobrien	(vec_concat:V2SF
1962990286Sobrien	   (plus:SF
1963090286Sobrien	      (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
1963190286Sobrien			     (parallel [(const_int  0)]))
1963290286Sobrien	      (vec_select:SF (match_dup 1)
1963390286Sobrien			     (parallel [(const_int 1)])))
1963490286Sobrien           (plus:SF
1963590286Sobrien              (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
1963690286Sobrien			     (parallel [(const_int  0)]))
1963790286Sobrien              (vec_select:SF (match_dup 2)
1963890286Sobrien			     (parallel [(const_int 1)])))))]
1963990286Sobrien  "TARGET_3DNOW"
1964090286Sobrien  "pfacc\\t{%2, %0|%0, %2}"
1964190286Sobrien  [(set_attr "type" "mmx")])
1964290286Sobrien
1964390286Sobrien(define_insn "pfnacc"
1964490286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1964590286Sobrien  	(vec_concat:V2SF
1964690286Sobrien           (minus:SF
1964790286Sobrien              (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
1964890286Sobrien			     (parallel [(const_int 0)]))
1964990286Sobrien              (vec_select:SF (match_dup 1)
1965090286Sobrien			     (parallel [(const_int 1)])))
1965190286Sobrien           (minus:SF
1965290286Sobrien              (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
1965390286Sobrien			     (parallel [(const_int  0)]))
1965490286Sobrien              (vec_select:SF (match_dup 2)
1965590286Sobrien			     (parallel [(const_int 1)])))))]
1965690286Sobrien  "TARGET_3DNOW_A"
1965790286Sobrien  "pfnacc\\t{%2, %0|%0, %2}"
1965890286Sobrien  [(set_attr "type" "mmx")])
1965990286Sobrien
1966090286Sobrien(define_insn "pfpnacc"
1966190286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1966290286Sobrien        (vec_concat:V2SF
1966390286Sobrien           (minus:SF
1966490286Sobrien              (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
1966590286Sobrien			     (parallel [(const_int 0)]))
1966690286Sobrien              (vec_select:SF (match_dup 1)
1966790286Sobrien			     (parallel [(const_int 1)])))
1966890286Sobrien           (plus:SF
1966990286Sobrien              (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
1967090286Sobrien			     (parallel [(const_int 0)]))
1967190286Sobrien              (vec_select:SF (match_dup 2)
1967290286Sobrien			     (parallel [(const_int 1)])))))]
1967390286Sobrien  "TARGET_3DNOW_A"
1967490286Sobrien  "pfpnacc\\t{%2, %0|%0, %2}"
1967590286Sobrien  [(set_attr "type" "mmx")])
1967690286Sobrien
1967790286Sobrien(define_insn "pi2fw"
1967890286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1967990286Sobrien	(float:V2SF
1968090286Sobrien	   (vec_concat:V2SI
1968190286Sobrien	      (sign_extend:SI
1968290286Sobrien		 (truncate:HI
1968390286Sobrien		    (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1968490286Sobrien				   (parallel [(const_int 0)]))))
1968590286Sobrien              (sign_extend:SI
1968690286Sobrien		 (truncate:HI
1968790286Sobrien                    (vec_select:SI (match_dup 1)
1968890286Sobrien				   (parallel [(const_int  1)])))))))]
1968990286Sobrien  "TARGET_3DNOW_A"
1969090286Sobrien  "pi2fw\\t{%1, %0|%0, %1}"
1969190286Sobrien  [(set_attr "type" "mmx")])
1969290286Sobrien
1969390286Sobrien(define_insn "floatv2si2"
1969490286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1969590286Sobrien	(float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
1969690286Sobrien  "TARGET_3DNOW"
1969790286Sobrien  "pi2fd\\t{%1, %0|%0, %1}"
1969890286Sobrien  [(set_attr "type" "mmx")])
1969990286Sobrien
1970090286Sobrien;; This insn is identical to pavgb in operation, but the opcode is
1970190286Sobrien;; different.  To avoid accidentally matching pavgb, use an unspec.
1970290286Sobrien
1970390286Sobrien(define_insn "pavgusb"
1970490286Sobrien [(set (match_operand:V8QI 0 "register_operand" "=y")
1970590286Sobrien       (unspec:V8QI
1970690286Sobrien          [(match_operand:V8QI 1 "register_operand" "0")
1970790286Sobrien           (match_operand:V8QI 2 "nonimmediate_operand" "ym")] 49))]
1970890286Sobrien  "TARGET_3DNOW"
1970990286Sobrien  "pavgusb\\t{%2, %0|%0, %2}"
1971090286Sobrien  [(set_attr "type" "mmx")])
1971190286Sobrien
1971290286Sobrien;; 3DNow reciprical and sqrt
1971390286Sobrien 
1971490286Sobrien(define_insn "pfrcpv2sf2"
1971590286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1971690286Sobrien        (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 50))]
1971790286Sobrien  "TARGET_3DNOW"
1971890286Sobrien  "pfrcp\\t{%1, %0|%0, %1}"
1971990286Sobrien  [(set_attr "type" "mmx")])
1972090286Sobrien
1972190286Sobrien(define_insn "pfrcpit1v2sf3"
1972290286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1972390286Sobrien	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
1972490286Sobrien		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 51))]
1972590286Sobrien  "TARGET_3DNOW"
1972690286Sobrien  "pfrcpit1\\t{%2, %0|%0, %2}"
1972790286Sobrien  [(set_attr "type" "mmx")])
1972890286Sobrien
1972990286Sobrien(define_insn "pfrcpit2v2sf3"
1973090286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1973190286Sobrien	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
1973290286Sobrien		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 52))]
1973390286Sobrien  "TARGET_3DNOW"
1973490286Sobrien  "pfrcpit2\\t{%2, %0|%0, %2}"
1973590286Sobrien  [(set_attr "type" "mmx")])
1973690286Sobrien
1973790286Sobrien(define_insn "pfrsqrtv2sf2"
1973890286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1973990286Sobrien	(unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 53))]
1974090286Sobrien  "TARGET_3DNOW"
1974190286Sobrien   "pfrsqrt\\t{%1, %0|%0, %1}"
1974290286Sobrien   [(set_attr "type" "mmx")])
1974390286Sobrien		
1974490286Sobrien(define_insn "pfrsqit1v2sf3"
1974590286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1974690286Sobrien	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
1974790286Sobrien		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 54))]
1974890286Sobrien  "TARGET_3DNOW"
1974990286Sobrien  "pfrsqit1\\t{%2, %0|%0, %2}"
1975090286Sobrien  [(set_attr "type" "mmx")])
1975190286Sobrien
1975290286Sobrien(define_insn "pmulhrwv4hi3"
1975390286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1975490286Sobrien	(truncate:V4HI
1975590286Sobrien	   (lshiftrt:V4SI
1975690286Sobrien	      (plus:V4SI
1975790286Sobrien	         (mult:V4SI
1975890286Sobrien	            (sign_extend:V4SI
1975990286Sobrien		       (match_operand:V4HI 1 "register_operand" "0"))
1976090286Sobrien	            (sign_extend:V4SI
1976190286Sobrien		       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1976296294Sobrien		 (const_vector:V4SI [(const_int 32768)
1976396294Sobrien				     (const_int 32768)
1976496294Sobrien				     (const_int 32768)
1976596294Sobrien				     (const_int 32768)]))
1976696294Sobrien	      (const_int 16))))]
1976790286Sobrien  "TARGET_3DNOW"
1976890286Sobrien  "pmulhrw\\t{%2, %0|%0, %2}"
1976990286Sobrien  [(set_attr "type" "mmx")])
1977090286Sobrien
1977190286Sobrien(define_insn "pswapdv2si2"
1977290286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1977390286Sobrien	(vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1977490286Sobrien			 (parallel [(const_int 1) (const_int 0)])))]
1977590286Sobrien  "TARGET_3DNOW_A"
1977690286Sobrien  "pswapd\\t{%1, %0|%0, %1}"
1977790286Sobrien  [(set_attr "type" "mmx")])
1977890286Sobrien
1977990286Sobrien(define_insn "pswapdv2sf2"
1978090286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1978190286Sobrien	(vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
1978290286Sobrien			 (parallel [(const_int 1) (const_int 0)])))]
1978390286Sobrien  "TARGET_3DNOW_A"
1978490286Sobrien  "pswapd\\t{%1, %0|%0, %1}"
1978590286Sobrien  [(set_attr "type" "mmx")])
1978690286Sobrien
1978790286Sobrien(define_expand "prefetch"
19788102802Skan  [(prefetch (match_operand 0 "address_operand" "")
1978990286Sobrien	     (match_operand:SI 1 "const_int_operand" "")
1979090286Sobrien	     (match_operand:SI 2 "const_int_operand" ""))]
1979190286Sobrien  "TARGET_PREFETCH_SSE || TARGET_3DNOW"
1979256391Sobrien{
1979390286Sobrien  int rw = INTVAL (operands[1]);
1979490286Sobrien  int locality = INTVAL (operands[2]);
1979590286Sobrien
1979690286Sobrien  if (rw != 0 && rw != 1)
1979790286Sobrien    abort ();
1979890286Sobrien  if (locality < 0 || locality > 3)
1979990286Sobrien    abort ();
19800102802Skan  if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
19801102802Skan    abort ();
1980290286Sobrien
1980390286Sobrien  /* Use 3dNOW prefetch in case we are asking for write prefetch not
1980490286Sobrien     suported by SSE counterpart or the SSE prefetch is not available
1980590286Sobrien     (K6 machines).  Otherwise use SSE prefetch as it allows specifying
1980690286Sobrien     of locality.  */
1980790286Sobrien  if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
1980890286Sobrien    operands[2] = GEN_INT (3);
1980990286Sobrien  else
1981090286Sobrien    operands[1] = const0_rtx;
1981190286Sobrien})
1981290286Sobrien
1981390286Sobrien(define_insn "*prefetch_sse"
1981490286Sobrien  [(prefetch (match_operand:SI 0 "address_operand" "p")
1981590286Sobrien	     (const_int 0)
1981690286Sobrien	     (match_operand:SI 1 "const_int_operand" ""))]
19817102802Skan  "TARGET_PREFETCH_SSE && !TARGET_64BIT"
1981890286Sobrien{
1981990286Sobrien  static const char * const patterns[4] = {
1982090286Sobrien   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
1982190286Sobrien  };
1982290286Sobrien
1982390286Sobrien  int locality = INTVAL (operands[1]);
1982490286Sobrien  if (locality < 0 || locality > 3)
1982590286Sobrien    abort ();
1982690286Sobrien
1982790286Sobrien  return patterns[locality];  
1982890286Sobrien}
19829102802Skan  [(set_attr "type" "sse")
19830102802Skan   (set_attr "memory" "none")])
19831102802Skan
19832102802Skan(define_insn "*prefetch_sse_rex"
19833102802Skan  [(prefetch (match_operand:DI 0 "address_operand" "p")
19834102802Skan	     (const_int 0)
19835102802Skan	     (match_operand:SI 1 "const_int_operand" ""))]
19836102802Skan  "TARGET_PREFETCH_SSE && TARGET_64BIT"
19837102802Skan{
19838102802Skan  static const char * const patterns[4] = {
19839102802Skan   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19840102802Skan  };
19841102802Skan
19842102802Skan  int locality = INTVAL (operands[1]);
19843102802Skan  if (locality < 0 || locality > 3)
19844102802Skan    abort ();
19845102802Skan
19846102802Skan  return patterns[locality];  
19847102802Skan}
1984890286Sobrien  [(set_attr "type" "sse")])
1984990286Sobrien
1985090286Sobrien(define_insn "*prefetch_3dnow"
1985190286Sobrien  [(prefetch (match_operand:SI 0 "address_operand" "p")
1985290286Sobrien	     (match_operand:SI 1 "const_int_operand" "n")
1985390286Sobrien	     (const_int 3))]
19854102802Skan  "TARGET_3DNOW && !TARGET_64BIT"
1985590286Sobrien{
1985690286Sobrien  if (INTVAL (operands[1]) == 0)
1985790286Sobrien    return "prefetch\t%a0";
1985890286Sobrien  else
1985990286Sobrien    return "prefetchw\t%a0";
1986090286Sobrien}
19861102802Skan  [(set_attr "type" "mmx")
19862102802Skan   (set_attr "memory" "none")])
19863102802Skan
19864102802Skan(define_insn "*prefetch_3dnow_rex"
19865102802Skan  [(prefetch (match_operand:DI 0 "address_operand" "p")
19866102802Skan	     (match_operand:SI 1 "const_int_operand" "n")
19867102802Skan	     (const_int 3))]
19868102802Skan  "TARGET_3DNOW && TARGET_64BIT"
19869102802Skan{
19870102802Skan  if (INTVAL (operands[1]) == 0)
19871102802Skan    return "prefetch\t%a0";
19872102802Skan  else
19873102802Skan    return "prefetchw\t%a0";
19874102802Skan}
1987590286Sobrien  [(set_attr "type" "mmx")])
19876