i386.md revision 107605
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
11690286Sobrien;; A basic instruction type.  Refinements due to arguments to be
11790286Sobrien;; provided in other attributes.
11852296Sobrien(define_attr "type"
11990286Sobrien  "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"
12090286Sobrien  (const_string "other"))
12150650Sobrien
12290286Sobrien;; Main data type used by the insn
12390286Sobrien(define_attr "mode" "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF,TI"
12490286Sobrien  (const_string "unknown"))
12552296Sobrien
12690286Sobrien;; Set for i387 operations.
12790286Sobrien(define_attr "i387" ""
12890286Sobrien  (if_then_else (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
12990286Sobrien    (const_int 1)
13090286Sobrien    (const_int 0)))
13152296Sobrien
13290286Sobrien;; The (bounding maximum) length of an instruction immediate.
13390286Sobrien(define_attr "length_immediate" ""
13490286Sobrien  (cond [(eq_attr "type" "incdec,setcc,icmov,ibr,str,cld,lea,other,multi,idiv,sse,mmx")
13590286Sobrien	   (const_int 0)
13690286Sobrien	 (eq_attr "i387" "1")
13790286Sobrien	   (const_int 0)
13890286Sobrien	 (eq_attr "type" "alu1,negnot,alu,icmp,imovx,ishift,imul,push,pop")
13990286Sobrien	   (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
14090286Sobrien	 (eq_attr "type" "imov,test")
14190286Sobrien	   (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
14290286Sobrien	 (eq_attr "type" "call")
14390286Sobrien	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
14490286Sobrien	     (const_int 4)
14590286Sobrien	     (const_int 0))
14690286Sobrien	 (eq_attr "type" "callv")
14790286Sobrien	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
14890286Sobrien	     (const_int 4)
14990286Sobrien	     (const_int 0))
15090286Sobrien	 (eq_attr "type" "ibr")
15190286Sobrien	   (if_then_else (and (ge (minus (match_dup 0) (pc))
15290286Sobrien				  (const_int -128))
15390286Sobrien			      (lt (minus (match_dup 0) (pc))
15490286Sobrien				  (const_int 124)))
15590286Sobrien	     (const_int 1)
15690286Sobrien	     (const_int 4))
15790286Sobrien	 ]
15890286Sobrien	 (symbol_ref "/* Update immediate_length and other attributes! */ abort(),1")))
15952296Sobrien
16090286Sobrien;; The (bounding maximum) length of an instruction address.
16190286Sobrien(define_attr "length_address" ""
16290286Sobrien  (cond [(eq_attr "type" "str,cld,other,multi,fxch")
16390286Sobrien	   (const_int 0)
16490286Sobrien	 (and (eq_attr "type" "call")
16590286Sobrien	      (match_operand 1 "constant_call_address_operand" ""))
16690286Sobrien	     (const_int 0)
16790286Sobrien	 (and (eq_attr "type" "callv")
16890286Sobrien	      (match_operand 1 "constant_call_address_operand" ""))
16990286Sobrien	     (const_int 0)
17090286Sobrien	 ]
17190286Sobrien	 (symbol_ref "ix86_attr_length_address_default (insn)")))
17252296Sobrien
17390286Sobrien;; Set when length prefix is used.
17490286Sobrien(define_attr "prefix_data16" ""
17590286Sobrien  (if_then_else (eq_attr "mode" "HI")
17690286Sobrien    (const_int 1)
17790286Sobrien    (const_int 0)))
17852296Sobrien
17990286Sobrien;; Set when string REP prefix is used.
18090286Sobrien(define_attr "prefix_rep" "" (const_int 0))
18152296Sobrien
18290286Sobrien;; Set when 0f opcode prefix is used.
18390286Sobrien(define_attr "prefix_0f" ""
18490286Sobrien  (if_then_else (eq_attr "type" "imovx,setcc,icmov,sse,mmx")
18590286Sobrien    (const_int 1)
18690286Sobrien    (const_int 0)))
18752296Sobrien
18890286Sobrien;; Set when modrm byte is used.
18990286Sobrien(define_attr "modrm" ""
19090286Sobrien  (cond [(eq_attr "type" "str,cld")
19190286Sobrien	   (const_int 0)
19290286Sobrien	 (eq_attr "i387" "1")
19390286Sobrien	   (const_int 0)
19490286Sobrien         (and (eq_attr "type" "incdec")
19590286Sobrien	      (ior (match_operand:SI 1 "register_operand" "")
19690286Sobrien		   (match_operand:HI 1 "register_operand" "")))
19790286Sobrien	   (const_int 0)
19890286Sobrien	 (and (eq_attr "type" "push")
19990286Sobrien	      (not (match_operand 1 "memory_operand" "")))
20090286Sobrien	   (const_int 0)
20190286Sobrien	 (and (eq_attr "type" "pop")
20290286Sobrien	      (not (match_operand 0 "memory_operand" "")))
20390286Sobrien	   (const_int 0)
20490286Sobrien	 (and (eq_attr "type" "imov")
20590286Sobrien	      (and (match_operand 0 "register_operand" "")
20690286Sobrien	           (match_operand 1 "immediate_operand" "")))
20790286Sobrien	   (const_int 0)
20890286Sobrien	 ]
20990286Sobrien	 (const_int 1)))
21090286Sobrien
21190286Sobrien;; The (bounding maximum) length of an instruction in bytes.
21290286Sobrien;; ??? fistp is in fact fldcw/fistp/fldcw sequence.  Later we may want
21390286Sobrien;; to split it and compute proper length as for other insns.
21490286Sobrien(define_attr "length" ""
21590286Sobrien  (cond [(eq_attr "type" "other,multi,fistp")
21690286Sobrien	   (const_int 16)
21790286Sobrien	 ]
21890286Sobrien	 (plus (plus (attr "modrm")
21990286Sobrien		     (plus (attr "prefix_0f")
22090286Sobrien			   (plus (attr "i387")
22190286Sobrien				 (const_int 1))))
22290286Sobrien	       (plus (attr "prefix_rep")
22390286Sobrien		     (plus (attr "prefix_data16")
22490286Sobrien			   (plus (attr "length_immediate")
22590286Sobrien				 (attr "length_address")))))))
22690286Sobrien
22790286Sobrien;; The `memory' attribute is `none' if no memory is referenced, `load' or
22890286Sobrien;; `store' if there is a simple memory reference therein, or `unknown'
22990286Sobrien;; if the instruction is complex.
23090286Sobrien
23190286Sobrien(define_attr "memory" "none,load,store,both,unknown"
23290286Sobrien  (cond [(eq_attr "type" "other,multi,str")
23390286Sobrien	   (const_string "unknown")
23490286Sobrien	 (eq_attr "type" "lea,fcmov,fpspc,cld")
23590286Sobrien	   (const_string "none")
23690286Sobrien	 (eq_attr "type" "fistp")
23790286Sobrien	   (const_string "both")
23890286Sobrien	 (eq_attr "type" "push")
23990286Sobrien	   (if_then_else (match_operand 1 "memory_operand" "")
24090286Sobrien	     (const_string "both")
24190286Sobrien	     (const_string "store"))
24290286Sobrien	 (eq_attr "type" "pop,setcc")
24390286Sobrien	   (if_then_else (match_operand 0 "memory_operand" "")
24490286Sobrien	     (const_string "both")
24590286Sobrien	     (const_string "load"))
24690286Sobrien	 (eq_attr "type" "icmp,test")
24790286Sobrien	   (if_then_else (ior (match_operand 0 "memory_operand" "")
24890286Sobrien			      (match_operand 1 "memory_operand" ""))
24990286Sobrien	     (const_string "load")
25090286Sobrien	     (const_string "none"))
25190286Sobrien	 (eq_attr "type" "ibr")
25290286Sobrien	   (if_then_else (match_operand 0 "memory_operand" "")
25390286Sobrien	     (const_string "load")
25490286Sobrien	     (const_string "none"))
25590286Sobrien	 (eq_attr "type" "call")
25690286Sobrien	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
25790286Sobrien	     (const_string "none")
25890286Sobrien	     (const_string "load"))
25990286Sobrien	 (eq_attr "type" "callv")
26090286Sobrien	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
26190286Sobrien	     (const_string "none")
26290286Sobrien	     (const_string "load"))
26390286Sobrien	 (and (eq_attr "type" "alu1,negnot")
26490286Sobrien	      (match_operand 1 "memory_operand" ""))
26590286Sobrien	   (const_string "both")
26690286Sobrien	 (and (match_operand 0 "memory_operand" "")
26790286Sobrien	      (match_operand 1 "memory_operand" ""))
26890286Sobrien	   (const_string "both")
26990286Sobrien	 (match_operand 0 "memory_operand" "")
27090286Sobrien	   (const_string "store")
27190286Sobrien	 (match_operand 1 "memory_operand" "")
27290286Sobrien	   (const_string "load")
27390286Sobrien	 (and (eq_attr "type" "!icmp,test,alu1,negnot,fop1,fsgn,imov,imovx,fmov,fcmp,sse,mmx")
27490286Sobrien	      (match_operand 2 "memory_operand" ""))
27590286Sobrien	   (const_string "load")
27690286Sobrien	 (and (eq_attr "type" "icmov")
27790286Sobrien	      (match_operand 3 "memory_operand" ""))
27890286Sobrien	   (const_string "load")
27990286Sobrien	]
28052296Sobrien	(const_string "none")))
28152296Sobrien
28290286Sobrien;; Indicates if an instruction has both an immediate and a displacement.
28350650Sobrien
28490286Sobrien(define_attr "imm_disp" "false,true,unknown"
28590286Sobrien  (cond [(eq_attr "type" "other,multi")
28690286Sobrien	   (const_string "unknown")
28790286Sobrien	 (and (eq_attr "type" "icmp,test,imov")
28890286Sobrien	      (and (match_operand 0 "memory_displacement_operand" "")
28990286Sobrien		   (match_operand 1 "immediate_operand" "")))
29090286Sobrien	   (const_string "true")
29190286Sobrien	 (and (eq_attr "type" "alu,ishift,imul,idiv")
29290286Sobrien	      (and (match_operand 0 "memory_displacement_operand" "")
29390286Sobrien		   (match_operand 2 "immediate_operand" "")))
29490286Sobrien	   (const_string "true")
29590286Sobrien	]
29690286Sobrien	(const_string "false")))
29750650Sobrien
29890286Sobrien;; Indicates if an FP operation has an integer source.
29950650Sobrien
30090286Sobrien(define_attr "fp_int_src" "false,true"
30190286Sobrien  (const_string "false"))
30250650Sobrien
30390286Sobrien;; Describe a user's asm statement.
30490286Sobrien(define_asm_attributes
30590286Sobrien  [(set_attr "length" "128")
30690286Sobrien   (set_attr "type" "multi")])
30790286Sobrien
30890286Sobrien;; Pentium Scheduling
30990286Sobrien;;
31090286Sobrien;; The Pentium is an in-order core with two integer pipelines.
31150650Sobrien
31290286Sobrien;; True for insns that behave like prefixed insns on the Pentium.
31390286Sobrien(define_attr "pent_prefix" "false,true"
31490286Sobrien  (if_then_else (ior (eq_attr "prefix_0f" "1")
31590286Sobrien  		     (ior (eq_attr "prefix_data16" "1")
31690286Sobrien			  (eq_attr "prefix_rep" "1")))
31790286Sobrien    (const_string "true")
31890286Sobrien    (const_string "false")))
31950650Sobrien
32090286Sobrien;; Categorize how an instruction slots.
32150650Sobrien
32290286Sobrien;; The non-MMX Pentium slots an instruction with prefixes on U pipe only,
32390286Sobrien;; while MMX Pentium can slot it on either U or V.  Model non-MMX Pentium
32490286Sobrien;; rules, because it results in noticeably better code on non-MMX Pentium
32590286Sobrien;; and doesn't hurt much on MMX.  (Prefixed instructions are not very
32690286Sobrien;; common, so the scheduler usualy has a non-prefixed insn to pair).
32750650Sobrien
32890286Sobrien(define_attr "pent_pair" "uv,pu,pv,np"
32990286Sobrien  (cond [(eq_attr "imm_disp" "true")
33090286Sobrien	   (const_string "np")
33190286Sobrien	 (ior (eq_attr "type" "alu1,alu,imov,icmp,test,lea,incdec")
33290286Sobrien	      (and (eq_attr "type" "pop,push")
33390286Sobrien		   (eq_attr "memory" "!both")))
33490286Sobrien	   (if_then_else (eq_attr "pent_prefix" "true")
33590286Sobrien	     (const_string "pu")
33690286Sobrien	     (const_string "uv"))
33790286Sobrien	 (eq_attr "type" "ibr")
33890286Sobrien	   (const_string "pv")
33990286Sobrien	 (and (eq_attr "type" "ishift")
34090286Sobrien	      (match_operand 2 "const_int_operand" ""))
34190286Sobrien	   (const_string "pu")
34290286Sobrien	 (and (eq_attr "type" "call")
34390286Sobrien	      (match_operand 0 "constant_call_address_operand" ""))
34490286Sobrien	   (const_string "pv")
34590286Sobrien	 (and (eq_attr "type" "callv")
34690286Sobrien	      (match_operand 1 "constant_call_address_operand" ""))
34790286Sobrien	   (const_string "pv")
34890286Sobrien	]
34990286Sobrien	(const_string "np")))
35050650Sobrien
35190286Sobrien;; Rough readiness numbers.  Fine tuning happens in i386.c.
35290286Sobrien;;
35390286Sobrien;; u	describes pipe U
35490286Sobrien;; v	describes pipe V
35590286Sobrien;; uv	describes either pipe U or V for those that can issue to either
35690286Sobrien;; np	describes not paring
35790286Sobrien;; fpu	describes fpu
35890286Sobrien;; fpm	describes fp insns of different types are not pipelined.
35990286Sobrien;;
36090286Sobrien;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
36150650Sobrien
36290286Sobrien(define_function_unit "pent_np" 1 0
36390286Sobrien  (and (eq_attr "cpu" "pentium")
36490286Sobrien       (eq_attr "type" "imul"))
36590286Sobrien  11 11)
36650650Sobrien
36790286Sobrien(define_function_unit "pent_mul" 1 1
36890286Sobrien  (and (eq_attr "cpu" "pentium")
36990286Sobrien       (eq_attr "type" "imul"))
37090286Sobrien  11 11)
37150650Sobrien
37290286Sobrien;; Rep movs takes minimally 12 cycles.
37390286Sobrien(define_function_unit "pent_np" 1 0
37490286Sobrien  (and (eq_attr "cpu" "pentium")
37590286Sobrien       (eq_attr "type" "str"))
37690286Sobrien  12 12)
37750650Sobrien
37890286Sobrien; ??? IDIV for SI takes 46 cycles, for HI 30, for QI 22
37990286Sobrien(define_function_unit "pent_np" 1 0
38090286Sobrien  (and (eq_attr "cpu" "pentium")
38190286Sobrien       (eq_attr "type" "idiv"))
38290286Sobrien  46 46)
38350650Sobrien
38490286Sobrien; Fp reg-reg moves takes 1 cycle. Loads takes 1 cycle for SF/DF mode,
38590286Sobrien; 3 cycles for XFmode.  Stores takes 2 cycles for SF/DF and 3 for XF.
38690286Sobrien; fldz and fld1 takes 2 cycles.  Only reg-reg moves are pairable.
38790286Sobrien; The integer <-> fp conversion is not modeled correctly. Fild behaves
38890286Sobrien; like normal fp operation and fist takes 6 cycles.
38952296Sobrien
39090286Sobrien(define_function_unit "fpu" 1 0
39190286Sobrien  (and (eq_attr "cpu" "pentium")
39290286Sobrien       (and (eq_attr "type" "fmov")
39390286Sobrien	    (and (eq_attr "memory" "load,store")
39490286Sobrien		 (eq_attr "mode" "XF"))))
39590286Sobrien  3 3)
39652296Sobrien
39790286Sobrien(define_function_unit "pent_np" 1 0
39890286Sobrien  (and (eq_attr "cpu" "pentium")
39990286Sobrien       (and (eq_attr "type" "fmov")
40090286Sobrien	    (and (eq_attr "memory" "load,store")
40190286Sobrien		 (eq_attr "mode" "XF"))))
40290286Sobrien  3 3)
40352296Sobrien
40490286Sobrien(define_function_unit "fpu" 1 0
40590286Sobrien  (and (eq_attr "cpu" "pentium")
40690286Sobrien       (and (eq_attr "type" "fmov")
40790286Sobrien            (ior (match_operand 1 "immediate_operand" "")
40890286Sobrien	         (eq_attr "memory" "store"))))
40990286Sobrien  2 2)
41052296Sobrien
41190286Sobrien(define_function_unit "pent_np" 1 0
41290286Sobrien  (and (eq_attr "cpu" "pentium")
41390286Sobrien       (and (eq_attr "type" "fmov")
41490286Sobrien            (ior (match_operand 1 "immediate_operand" "")
41590286Sobrien	         (eq_attr "memory" "store"))))
41690286Sobrien  2 2)
41752296Sobrien
41890286Sobrien(define_function_unit "pent_np" 1 0
41990286Sobrien  (and (eq_attr "cpu" "pentium")
42090286Sobrien       (eq_attr "type" "cld"))
42152296Sobrien  2 2)
42252296Sobrien
42390286Sobrien(define_function_unit "fpu" 1 0
42490286Sobrien  (and (eq_attr "cpu" "pentium")
42590286Sobrien       (and (eq_attr "type" "fmov")
42690286Sobrien	    (eq_attr "memory" "none,load")))
42790286Sobrien  1 1)
42852296Sobrien
42990286Sobrien; Read/Modify/Write instructions usually take 3 cycles.
43090286Sobrien(define_function_unit "pent_u" 1 0
43190286Sobrien  (and (eq_attr "cpu" "pentium")
43290286Sobrien       (and (eq_attr "type" "alu,alu1,ishift")
43390286Sobrien	    (and (eq_attr "pent_pair" "pu")
43490286Sobrien		 (eq_attr "memory" "both"))))
43590286Sobrien  3 3)
43690286Sobrien
43790286Sobrien(define_function_unit "pent_uv" 2 0
43890286Sobrien  (and (eq_attr "cpu" "pentium")
43990286Sobrien       (and (eq_attr "type" "alu,alu1,ishift")
44090286Sobrien	    (and (eq_attr "pent_pair" "!np")
44190286Sobrien		 (eq_attr "memory" "both"))))
44290286Sobrien  3 3)
44390286Sobrien
44490286Sobrien(define_function_unit "pent_np" 1 0
44590286Sobrien  (and (eq_attr "cpu" "pentium")
44690286Sobrien       (and (eq_attr "type" "alu,alu1,negnot,ishift")
44790286Sobrien	    (and (eq_attr "pent_pair" "np")
44890286Sobrien		 (eq_attr "memory" "both"))))
44990286Sobrien  3 3)
45090286Sobrien
45190286Sobrien; Read/Modify or Modify/Write instructions usually take 2 cycles.
45290286Sobrien(define_function_unit "pent_u" 1 0
45390286Sobrien  (and (eq_attr "cpu" "pentium")
45490286Sobrien       (and (eq_attr "type" "alu,ishift")
45590286Sobrien	    (and (eq_attr "pent_pair" "pu")
45690286Sobrien		 (eq_attr "memory" "load,store"))))
45790286Sobrien  2 2)
45890286Sobrien
45990286Sobrien(define_function_unit "pent_uv" 2 0
46090286Sobrien  (and (eq_attr "cpu" "pentium")
46190286Sobrien       (and (eq_attr "type" "alu,ishift")
46290286Sobrien	    (and (eq_attr "pent_pair" "!np")
46390286Sobrien		 (eq_attr "memory" "load,store"))))
46490286Sobrien  2 2)
46590286Sobrien
46690286Sobrien(define_function_unit "pent_np" 1 0
46790286Sobrien  (and (eq_attr "cpu" "pentium")
46890286Sobrien       (and (eq_attr "type" "alu,ishift")
46990286Sobrien	    (and (eq_attr "pent_pair" "np")
47090286Sobrien		 (eq_attr "memory" "load,store"))))
47190286Sobrien  2 2)
47290286Sobrien
47390286Sobrien; Insns w/o memory operands and move instructions usually take one cycle.
47490286Sobrien(define_function_unit "pent_u" 1 0
47590286Sobrien  (and (eq_attr "cpu" "pentium")
47690286Sobrien       (eq_attr "pent_pair" "pu"))
47790286Sobrien  1 1)
47890286Sobrien
47990286Sobrien(define_function_unit "pent_v" 1 0
48090286Sobrien  (and (eq_attr "cpu" "pentium")
48190286Sobrien       (eq_attr "pent_pair" "pv"))
48290286Sobrien  1 1)
48390286Sobrien
48490286Sobrien(define_function_unit "pent_uv" 2 0
48590286Sobrien  (and (eq_attr "cpu" "pentium")
48690286Sobrien       (eq_attr "pent_pair" "!np"))
48790286Sobrien  1 1)
48890286Sobrien
48990286Sobrien(define_function_unit "pent_np" 1 0
49090286Sobrien  (and (eq_attr "cpu" "pentium")
49190286Sobrien       (eq_attr "pent_pair" "np"))
49290286Sobrien  1 1)
49390286Sobrien
49490286Sobrien; Pairable insns only conflict with other non-pairable insns.
49590286Sobrien(define_function_unit "pent_np" 1 0
49690286Sobrien  (and (eq_attr "cpu" "pentium")
49790286Sobrien       (and (eq_attr "type" "alu,alu1,ishift")
49890286Sobrien	    (and (eq_attr "pent_pair" "!np")
49990286Sobrien		 (eq_attr "memory" "both"))))
50090286Sobrien  3 3
50190286Sobrien  [(eq_attr "pent_pair" "np")])
50290286Sobrien
50390286Sobrien(define_function_unit "pent_np" 1 0
50490286Sobrien  (and (eq_attr "cpu" "pentium")
50590286Sobrien       (and (eq_attr "type" "alu,alu1,ishift")
50690286Sobrien	    (and (eq_attr "pent_pair" "!np")
50790286Sobrien		 (eq_attr "memory" "load,store"))))
50890286Sobrien  2 2
50990286Sobrien  [(eq_attr "pent_pair" "np")])
51090286Sobrien
51190286Sobrien(define_function_unit "pent_np" 1 0
51290286Sobrien  (and (eq_attr "cpu" "pentium")
51390286Sobrien       (eq_attr "pent_pair" "!np"))
51490286Sobrien  1 1
51590286Sobrien  [(eq_attr "pent_pair" "np")])
51690286Sobrien
51790286Sobrien; Floating point instructions usually blocks cycle longer when combined with
51890286Sobrien; integer instructions, because of the inpaired fxch instruction.
51990286Sobrien(define_function_unit "pent_np" 1 0
52090286Sobrien  (and (eq_attr "cpu" "pentium")
52190286Sobrien       (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp,fistp"))
52290286Sobrien  2 2
52390286Sobrien  [(eq_attr "type" "!fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp,fistp")])
52490286Sobrien
52590286Sobrien(define_function_unit "fpu" 1 0
52690286Sobrien  (and (eq_attr "cpu" "pentium")
52790286Sobrien       (eq_attr "type" "fcmp,fxch,fsgn"))
52890286Sobrien  1 1)
52990286Sobrien
53090286Sobrien; Addition takes 3 cycles; assume other random cruft does as well.
53190286Sobrien; ??? Trivial fp operations such as fabs or fchs takes only one cycle.
53290286Sobrien(define_function_unit "fpu" 1 0
53390286Sobrien  (and (eq_attr "cpu" "pentium")
53490286Sobrien       (eq_attr "type" "fop,fop1,fistp"))
53590286Sobrien  3 1)
53690286Sobrien
53790286Sobrien; Multiplication takes 3 cycles and is only half pipelined.
53890286Sobrien(define_function_unit "fpu" 1 0
53990286Sobrien  (and (eq_attr "cpu" "pentium")
54090286Sobrien       (eq_attr "type" "fmul"))
54190286Sobrien  3 1)
54290286Sobrien
54390286Sobrien(define_function_unit "pent_mul" 1 1
54490286Sobrien  (and (eq_attr "cpu" "pentium")
54590286Sobrien       (eq_attr "type" "fmul"))
54690286Sobrien  2 2)
54790286Sobrien
54890286Sobrien; ??? This is correct only for fdiv and sqrt -- sin/cos take 65-100 cycles. 
54990286Sobrien; They can overlap with integer insns.  Only the last two cycles can overlap
55090286Sobrien; with other fp insns.  Only fsin/fcos can overlap with multiplies.
55190286Sobrien; Only last two cycles of fsin/fcos can overlap with other instructions.
55290286Sobrien(define_function_unit "fpu" 1 0
55390286Sobrien  (and (eq_attr "cpu" "pentium")
55490286Sobrien       (eq_attr "type" "fdiv"))
55590286Sobrien  39 37)
55690286Sobrien
55790286Sobrien(define_function_unit "pent_mul" 1 1
55890286Sobrien  (and (eq_attr "cpu" "pentium")
55990286Sobrien       (eq_attr "type" "fdiv"))
56090286Sobrien  39 39)
56190286Sobrien
56290286Sobrien(define_function_unit "fpu" 1 0
56390286Sobrien  (and (eq_attr "cpu" "pentium")
56490286Sobrien       (eq_attr "type" "fpspc"))
56590286Sobrien  70 68)
56690286Sobrien
56790286Sobrien(define_function_unit "pent_mul" 1 1
56890286Sobrien  (and (eq_attr "cpu" "pentium")
56990286Sobrien       (eq_attr "type" "fpspc"))
57090286Sobrien  70 70)
57190286Sobrien
57290286Sobrien;; Pentium Pro/PII Scheduling
57390286Sobrien;;
57490286Sobrien;; The PPro has an out-of-order core, but the instruction decoders are
57590286Sobrien;; naturally in-order and asymmetric.  We get best performance by scheduling
57690286Sobrien;; for the decoders, for in doing so we give the oo execution unit the 
57790286Sobrien;; most choices.
57890286Sobrien
57990286Sobrien;; Categorize how many uops an ia32 instruction evaluates to:
58090286Sobrien;;   one --  an instruction with 1 uop can be decoded by any of the
58190286Sobrien;;           three decoders.
58290286Sobrien;;   few --  an instruction with 1 to 4 uops can be decoded only by 
58390286Sobrien;;	     decoder 0.
58490286Sobrien;;   many -- a complex instruction may take an unspecified number of
58590286Sobrien;;	     cycles to decode in decoder 0.
58690286Sobrien
58790286Sobrien(define_attr "ppro_uops" "one,few,many"
58890286Sobrien  (cond [(eq_attr "type" "other,multi,call,callv,fpspc,str")
58990286Sobrien	   (const_string "many")
59090286Sobrien	 (eq_attr "type" "icmov,fcmov,str,cld")
59190286Sobrien	   (const_string "few")
59290286Sobrien	 (eq_attr "type" "imov")
59390286Sobrien	   (if_then_else (eq_attr "memory" "store,both")
59490286Sobrien	     (const_string "few")
59590286Sobrien	     (const_string "one"))
59690286Sobrien	 (eq_attr "memory" "!none")
59790286Sobrien	   (const_string "few")
59890286Sobrien	]
59990286Sobrien	(const_string "one")))
60090286Sobrien
60190286Sobrien;; Rough readiness numbers.  Fine tuning happens in i386.c.
60290286Sobrien;;
60390286Sobrien;; p0	describes port 0.
60490286Sobrien;; p01	describes ports 0 and 1 as a pair; alu insns can issue to either.
60590286Sobrien;; p2	describes port 2 for loads.
60690286Sobrien;; p34	describes ports 3 and 4 for stores.
60790286Sobrien;; fpu	describes the fpu accessed via port 0. 
60890286Sobrien;;	??? It is less than clear if there are separate fadd and fmul units
60990286Sobrien;;	that could operate in parallel.
61090286Sobrien;;
61190286Sobrien;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
61290286Sobrien
61390286Sobrien(define_function_unit "ppro_p0" 1 0
61490286Sobrien  (and (eq_attr "cpu" "pentiumpro")
61590286Sobrien       (eq_attr "type" "ishift,lea,ibr,cld"))
61690286Sobrien  1 1)
61790286Sobrien
61890286Sobrien(define_function_unit "ppro_p0" 1 0
61990286Sobrien  (and (eq_attr "cpu" "pentiumpro")
62090286Sobrien       (eq_attr "type" "imul"))
62190286Sobrien  4 1)
62290286Sobrien
62390286Sobrien;; ??? Does the divider lock out the pipe while it works,
62490286Sobrien;; or is there a disconnected unit?
62590286Sobrien(define_function_unit "ppro_p0" 1 0
62690286Sobrien  (and (eq_attr "cpu" "pentiumpro")
62790286Sobrien       (eq_attr "type" "idiv"))
62852296Sobrien  17 17)
62952296Sobrien
63090286Sobrien(define_function_unit "ppro_p0" 1 0
63190286Sobrien  (and (eq_attr "cpu" "pentiumpro")
63290286Sobrien       (eq_attr "type" "fop,fop1,fsgn,fistp"))
63390286Sobrien  3 1)
63452296Sobrien
63590286Sobrien(define_function_unit "ppro_p0" 1 0
63690286Sobrien  (and (eq_attr "cpu" "pentiumpro")
63790286Sobrien       (eq_attr "type" "fcmov"))
63890286Sobrien  2 1)
63952296Sobrien
64090286Sobrien(define_function_unit "ppro_p0" 1 0
64190286Sobrien  (and (eq_attr "cpu" "pentiumpro")
64290286Sobrien       (eq_attr "type" "fcmp"))
64390286Sobrien  1 1)
64452296Sobrien
64590286Sobrien(define_function_unit "ppro_p0" 1 0
64690286Sobrien  (and (eq_attr "cpu" "pentiumpro")
64790286Sobrien       (eq_attr "type" "fmov"))
64890286Sobrien  1 1)
64952296Sobrien
65090286Sobrien(define_function_unit "ppro_p0" 1 0
65190286Sobrien  (and (eq_attr "cpu" "pentiumpro")
65290286Sobrien       (eq_attr "type" "fmul"))
65390286Sobrien  5 1)
65490286Sobrien
65590286Sobrien(define_function_unit "ppro_p0" 1 0
65690286Sobrien  (and (eq_attr "cpu" "pentiumpro")
65790286Sobrien       (eq_attr "type" "fdiv,fpspc"))
65890286Sobrien  56 1)
65990286Sobrien
66090286Sobrien(define_function_unit "ppro_p01" 2 0
66190286Sobrien  (and (eq_attr "cpu" "pentiumpro")
66290286Sobrien       (eq_attr "type" "!imov,fmov"))
66390286Sobrien  1 1)
66490286Sobrien
66590286Sobrien(define_function_unit "ppro_p01" 2 0
66690286Sobrien  (and (and (eq_attr "cpu" "pentiumpro")
66790286Sobrien            (eq_attr "type" "imov,fmov"))
66890286Sobrien       (eq_attr "memory" "none"))
66990286Sobrien  1 1)
67090286Sobrien
67190286Sobrien(define_function_unit "ppro_p2" 1 0
67290286Sobrien  (and (eq_attr "cpu" "pentiumpro")
67390286Sobrien       (ior (eq_attr "type" "pop")
67490286Sobrien	    (eq_attr "memory" "load,both")))
67590286Sobrien  3 1)
67690286Sobrien
67790286Sobrien(define_function_unit "ppro_p34" 1 0
67890286Sobrien  (and (eq_attr "cpu" "pentiumpro")
67990286Sobrien       (ior (eq_attr "type" "push")
68090286Sobrien	    (eq_attr "memory" "store,both")))
68190286Sobrien  1 1)
68290286Sobrien
68390286Sobrien(define_function_unit "fpu" 1 0
68490286Sobrien  (and (eq_attr "cpu" "pentiumpro")
68590286Sobrien       (eq_attr "type" "fop,fop1,fsgn,fmov,fcmp,fcmov,fistp"))
68690286Sobrien  1 1)
68790286Sobrien
68890286Sobrien(define_function_unit "fpu" 1 0
68990286Sobrien  (and (eq_attr "cpu" "pentiumpro")
69090286Sobrien       (eq_attr "type" "fmul"))
69190286Sobrien  5 2)
69290286Sobrien
69390286Sobrien(define_function_unit "fpu" 1 0
69490286Sobrien  (and (eq_attr "cpu" "pentiumpro")
69590286Sobrien       (eq_attr "type" "fdiv,fpspc"))
69690286Sobrien  56 56)
69790286Sobrien
69890286Sobrien;; imul uses the fpu.  ??? does it have the same throughput as fmul?
69990286Sobrien(define_function_unit "fpu" 1 0
70090286Sobrien  (and (eq_attr "cpu" "pentiumpro")
70190286Sobrien       (eq_attr "type" "imul"))
70290286Sobrien  4 1)
70350650Sobrien
70490286Sobrien;; AMD K6/K6-2 Scheduling
70518334Speter;;
70690286Sobrien;; The K6 has similar architecture to PPro.  Important difference is, that
70790286Sobrien;; there are only two decoders and they seems to be much slower than execution
70890286Sobrien;; units.  So we have to pay much more attention to proper decoding for
70990286Sobrien;; schedulers.  We share most of scheduler code for PPro in i386.c
71090286Sobrien;;
71190286Sobrien;; The fp unit is not pipelined and do one operation per two cycles including
71290286Sobrien;; the FXCH.
71390286Sobrien;;
71490286Sobrien;; alu	  describes both ALU units (ALU-X and ALU-Y).
71590286Sobrien;; alux   describes X alu unit
71690286Sobrien;; fpu    describes FPU unit
71790286Sobrien;; load   describes load unit.
71890286Sobrien;; branch describes branch unit.
71990286Sobrien;; store  decsribes store unit.  This unit is not modelled completely and only
72090286Sobrien;;        used to model lea operation.  Otherwise it lie outside of the critical
72190286Sobrien;;        path.
72290286Sobrien;;
72390286Sobrien;; ??? fxch isn't handled; not an issue until sched3 after reg-stack is real.
72418334Speter
72590286Sobrien;; The decoder specification is in the PPro section above!
72618334Speter
72790286Sobrien;; Shift instructions and certain arithmetic are issued only to X pipe.
72890286Sobrien(define_function_unit "k6_alux" 1 0
72990286Sobrien  (and (eq_attr "cpu" "k6")
73090286Sobrien       (eq_attr "type" "ishift,alu1,negnot,cld"))
73190286Sobrien  1 1)
73250650Sobrien
73390286Sobrien;; The QI mode arithmetic is issued to X pipe only.
73490286Sobrien(define_function_unit "k6_alux" 1 0
73590286Sobrien  (and (eq_attr "cpu" "k6")
73690286Sobrien       (and (eq_attr "type" "alu,alu1,negnot,icmp,test,imovx,incdec")
73790286Sobrien	    (match_operand:QI 0 "general_operand" "")))
73890286Sobrien  1 1)
73950650Sobrien
74090286Sobrien(define_function_unit "k6_alu" 2 0
74190286Sobrien  (and (eq_attr "cpu" "k6")
74290286Sobrien       (eq_attr "type" "ishift,alu1,negnot,alu,icmp,test,imovx,incdec,setcc,lea"))
74390286Sobrien  1 1)
74418334Speter
74590286Sobrien(define_function_unit "k6_alu" 2 0
74690286Sobrien  (and (eq_attr "cpu" "k6")
74790286Sobrien       (and (eq_attr "type" "imov")
74890286Sobrien       	    (eq_attr "memory" "none")))
74990286Sobrien  1 1)
75018334Speter
75190286Sobrien(define_function_unit "k6_branch" 1 0
75290286Sobrien  (and (eq_attr "cpu" "k6")
75390286Sobrien       (eq_attr "type" "call,callv,ibr"))
75490286Sobrien  1 1)
75518334Speter
75690286Sobrien;; Load unit have two cycle latency, but we take care for it in adjust_cost
75790286Sobrien(define_function_unit "k6_load" 1 0
75890286Sobrien  (and (eq_attr "cpu" "k6")
75990286Sobrien       (ior (eq_attr "type" "pop")
76090286Sobrien	    (eq_attr "memory" "load,both")))
76190286Sobrien  1 1)
76218334Speter
76390286Sobrien(define_function_unit "k6_load" 1 0
76490286Sobrien  (and (eq_attr "cpu" "k6")
76590286Sobrien       (and (eq_attr "type" "str")
76690286Sobrien	    (eq_attr "memory" "load,both")))
76790286Sobrien  10 10)
76818334Speter
76990286Sobrien;; Lea have two instructions, so latency is probably 2
77090286Sobrien(define_function_unit "k6_store" 1 0
77190286Sobrien  (and (eq_attr "cpu" "k6")
77290286Sobrien       (eq_attr "type" "lea"))
77390286Sobrien  2 1)
77418334Speter
77590286Sobrien(define_function_unit "k6_store" 1 0
77690286Sobrien  (and (eq_attr "cpu" "k6")
77790286Sobrien       (eq_attr "type" "str"))
77890286Sobrien  10 10)
77918334Speter
78090286Sobrien(define_function_unit "k6_store" 1 0
78190286Sobrien  (and (eq_attr "cpu" "k6")
78290286Sobrien       (ior (eq_attr "type" "push")
78390286Sobrien	    (eq_attr "memory" "store,both")))
78490286Sobrien  1 1)
78518334Speter
78690286Sobrien(define_function_unit "k6_fpu" 1 1
78790286Sobrien  (and (eq_attr "cpu" "k6")
78890286Sobrien       (eq_attr "type" "fop,fop1,fmov,fcmp,fistp"))
78990286Sobrien  2 2)
79018334Speter
79190286Sobrien(define_function_unit "k6_fpu" 1 1
79290286Sobrien  (and (eq_attr "cpu" "k6")
79390286Sobrien       (eq_attr "type" "fmul"))
79490286Sobrien  2 2)
79518334Speter
79690286Sobrien;; ??? Guess
79790286Sobrien(define_function_unit "k6_fpu" 1 1
79890286Sobrien  (and (eq_attr "cpu" "k6")
79990286Sobrien       (eq_attr "type" "fdiv,fpspc"))
80090286Sobrien  56 56)
80118334Speter
80290286Sobrien(define_function_unit "k6_alu" 2 0
80390286Sobrien  (and (eq_attr "cpu" "k6")
80490286Sobrien       (eq_attr "type" "imul"))
80590286Sobrien  2 2)
80618334Speter
80790286Sobrien(define_function_unit "k6_alux" 1 0
80890286Sobrien  (and (eq_attr "cpu" "k6")
80990286Sobrien       (eq_attr "type" "imul"))
81090286Sobrien  2 2)
81118334Speter
81290286Sobrien;; ??? Guess
81390286Sobrien(define_function_unit "k6_alu" 2 0
81490286Sobrien  (and (eq_attr "cpu" "k6")
81590286Sobrien       (eq_attr "type" "idiv"))
81690286Sobrien  17 17)
81718334Speter
81890286Sobrien(define_function_unit "k6_alux" 1 0
81990286Sobrien  (and (eq_attr "cpu" "k6")
82090286Sobrien       (eq_attr "type" "idiv"))
82190286Sobrien  17 17)
82290286Sobrien
82390286Sobrien;; AMD Athlon Scheduling
82490286Sobrien;;
82590286Sobrien;; The Athlon does contain three pipelined FP units, three integer units and
82690286Sobrien;; three address generation units. 
82790286Sobrien;;
82890286Sobrien;; The predecode logic is determining boundaries of instructions in the 64
82990286Sobrien;; byte cache line. So the cache line straddling problem of K6 might be issue
83090286Sobrien;; here as well, but it is not noted in the documentation.
83190286Sobrien;;
83290286Sobrien;; Three DirectPath instructions decoders and only one VectorPath decoder
83390286Sobrien;; is available. They can decode three DirectPath instructions or one VectorPath
83490286Sobrien;; instruction per cycle.
83590286Sobrien;; Decoded macro instructions are then passed to 72 entry instruction control
83690286Sobrien;; unit, that passes
83790286Sobrien;; it to the specialized integer (18 entry) and fp (36 entry) schedulers.
83890286Sobrien;;
83990286Sobrien;; The load/store queue unit is not attached to the schedulers but
84090286Sobrien;; communicates with all the execution units separately instead.
84118334Speter
84290286Sobrien(define_attr "athlon_decode" "direct,vector"
84390286Sobrien  (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str,pop,cld,fcmov")
84490286Sobrien	   (const_string "vector")
84590286Sobrien         (and (eq_attr "type" "push")
84690286Sobrien              (match_operand 1 "memory_operand" ""))
84790286Sobrien	   (const_string "vector")
84890286Sobrien         (and (eq_attr "type" "fmov")
84990286Sobrien	      (and (eq_attr "memory" "load,store")
85090286Sobrien		   (eq_attr "mode" "XF")))
85190286Sobrien	   (const_string "vector")]
85290286Sobrien	(const_string "direct")))
85318334Speter
85490286Sobrien(define_function_unit "athlon_vectordec" 1 0
85590286Sobrien  (and (eq_attr "cpu" "athlon")
85690286Sobrien       (eq_attr "athlon_decode" "vector"))
85790286Sobrien  1 1)
85818334Speter
85990286Sobrien(define_function_unit "athlon_directdec" 3 0
86090286Sobrien  (and (eq_attr "cpu" "athlon")
86190286Sobrien       (eq_attr "athlon_decode" "direct"))
86290286Sobrien  1 1)
86318334Speter
86490286Sobrien(define_function_unit "athlon_vectordec" 1 0
86590286Sobrien  (and (eq_attr "cpu" "athlon")
86690286Sobrien       (eq_attr "athlon_decode" "direct"))
86790286Sobrien  1 1 [(eq_attr "athlon_decode" "vector")])
86818334Speter
86990286Sobrien(define_function_unit "athlon_ieu" 3 0
87090286Sobrien  (and (eq_attr "cpu" "athlon")
87190286Sobrien       (eq_attr "type" "alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,ibr,call,callv,icmov,cld,pop,setcc,push,pop"))
87290286Sobrien  1 1)
87318334Speter
87490286Sobrien(define_function_unit "athlon_ieu" 3 0
87590286Sobrien  (and (eq_attr "cpu" "athlon")
87690286Sobrien       (eq_attr "type" "str"))
87790286Sobrien  15 15)
87818334Speter
87990286Sobrien(define_function_unit "athlon_ieu" 3 0
88090286Sobrien  (and (eq_attr "cpu" "athlon")
88190286Sobrien       (eq_attr "type" "imul"))
88290286Sobrien  5 0)
88318334Speter
88490286Sobrien(define_function_unit "athlon_ieu" 3 0
88590286Sobrien  (and (eq_attr "cpu" "athlon")
88690286Sobrien       (eq_attr "type" "idiv"))
88790286Sobrien  42 0)
88818334Speter
88990286Sobrien(define_function_unit "athlon_muldiv" 1 0
89090286Sobrien  (and (eq_attr "cpu" "athlon")
89190286Sobrien       (eq_attr "type" "imul"))
89290286Sobrien  5 0)
89318334Speter
89490286Sobrien(define_function_unit "athlon_muldiv" 1 0
89590286Sobrien  (and (eq_attr "cpu" "athlon")
89690286Sobrien       (eq_attr "type" "idiv"))
89790286Sobrien  42 42)
89818334Speter
89990286Sobrien(define_attr "athlon_fpunits" "none,store,mul,add,muladd,any"
90090286Sobrien  (cond [(eq_attr "type" "fop,fop1,fcmp,fistp")
90190286Sobrien	   (const_string "add")
90290286Sobrien         (eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov")
90390286Sobrien	   (const_string "mul")
90490286Sobrien	 (and (eq_attr "type" "fmov") (eq_attr "memory" "store,both"))
90590286Sobrien	   (const_string "store")
90690286Sobrien	 (and (eq_attr "type" "fmov") (eq_attr "memory" "load"))
90790286Sobrien	   (const_string "any")
90890286Sobrien         (and (eq_attr "type" "fmov")
90990286Sobrien              (ior (match_operand:SI 1 "register_operand" "")
91090286Sobrien                   (match_operand 1 "immediate_operand" "")))
91190286Sobrien	   (const_string "store")
91290286Sobrien         (eq_attr "type" "fmov")
91390286Sobrien	   (const_string "muladd")]
91490286Sobrien	(const_string "none")))
91518334Speter
91690286Sobrien;; We use latencies 1 for definitions.  This is OK to model colisions
91790286Sobrien;; in execution units.  The real latencies are modeled in the "fp" pipeline.
91890286Sobrien
91990286Sobrien;; fsin, fcos: 96-192
92090286Sobrien;; fsincos: 107-211
92190286Sobrien;; fsqrt: 19 for SFmode, 27 for DFmode, 35 for XFmode.
92290286Sobrien(define_function_unit "athlon_fp" 3 0
92390286Sobrien  (and (eq_attr "cpu" "athlon")
92490286Sobrien       (eq_attr "type" "fpspc"))
92590286Sobrien  100 1)
92690286Sobrien
92790286Sobrien;; 16 cycles for SFmode, 20 for DFmode and 24 for XFmode.
92890286Sobrien(define_function_unit "athlon_fp" 3 0
92990286Sobrien  (and (eq_attr "cpu" "athlon")
93090286Sobrien       (eq_attr "type" "fdiv"))
93190286Sobrien  24 1)
93290286Sobrien
93390286Sobrien(define_function_unit "athlon_fp" 3 0
93490286Sobrien  (and (eq_attr "cpu" "athlon")
93590286Sobrien       (eq_attr "type" "fop,fop1,fmul,fistp"))
93690286Sobrien  4 1)
93790286Sobrien
93890286Sobrien;; XFmode loads are slow.
93990286Sobrien;; XFmode store is slow too (8 cycles), but we don't need to model it, because
94090286Sobrien;; there are no dependent instructions.
94190286Sobrien
94290286Sobrien(define_function_unit "athlon_fp" 3 0
94390286Sobrien  (and (eq_attr "cpu" "athlon")
94490286Sobrien       (and (eq_attr "type" "fmov")
94590286Sobrien	    (and (eq_attr "memory" "load")
94690286Sobrien		 (eq_attr "mode" "XF"))))
94790286Sobrien  10 1)
94890286Sobrien
94990286Sobrien(define_function_unit "athlon_fp" 3 0
95090286Sobrien  (and (eq_attr "cpu" "athlon")
95190286Sobrien       (eq_attr "type" "fmov,fsgn"))
95290286Sobrien  2 1)
95390286Sobrien
95490286Sobrien;; fcmp and ftst instructions
95590286Sobrien(define_function_unit "athlon_fp" 3 0
95690286Sobrien  (and (eq_attr "cpu" "athlon")
95790286Sobrien       (and (eq_attr "type" "fcmp")
95890286Sobrien	    (eq_attr "athlon_decode" "direct")))
95990286Sobrien  3 1)
96090286Sobrien
96190286Sobrien;; fcmpi instructions.
96290286Sobrien(define_function_unit "athlon_fp" 3 0
96390286Sobrien  (and (eq_attr "cpu" "athlon")
96490286Sobrien       (and (eq_attr "type" "fcmp")
96590286Sobrien	    (eq_attr "athlon_decode" "vector")))
96690286Sobrien  3 1)
96790286Sobrien
96890286Sobrien(define_function_unit "athlon_fp" 3 0
96990286Sobrien  (and (eq_attr "cpu" "athlon")
97090286Sobrien       (eq_attr "type" "fcmov"))
97190286Sobrien  7 1)
97290286Sobrien
97390286Sobrien(define_function_unit "athlon_fp_mul" 1 0
97490286Sobrien  (and (eq_attr "cpu" "athlon")
97590286Sobrien       (eq_attr "athlon_fpunits" "mul"))
97690286Sobrien  1 1)
97790286Sobrien
97890286Sobrien(define_function_unit "athlon_fp_add" 1 0
97990286Sobrien  (and (eq_attr "cpu" "athlon")
98090286Sobrien       (eq_attr "athlon_fpunits" "add"))
98190286Sobrien  1 1)
98290286Sobrien
98390286Sobrien(define_function_unit "athlon_fp_muladd" 2 0
98490286Sobrien  (and (eq_attr "cpu" "athlon")
98590286Sobrien       (eq_attr "athlon_fpunits" "muladd,mul,add"))
98690286Sobrien  1 1)
98790286Sobrien
98890286Sobrien(define_function_unit "athlon_fp_store" 1 0
98990286Sobrien  (and (eq_attr "cpu" "athlon")
99090286Sobrien       (eq_attr "athlon_fpunits" "store"))
99190286Sobrien  1 1)
99290286Sobrien
99390286Sobrien;; We don't need to model the Address Generation Unit, since we don't model
99490286Sobrien;; the re-order buffer yet and thus we never schedule more than three operations
99590286Sobrien;; at time.  Later we may want to experiment with MD_SCHED macros modeling the
99690286Sobrien;; decoders independently on the functional units.
99790286Sobrien
99890286Sobrien;(define_function_unit "athlon_agu" 3 0
99990286Sobrien;  (and (eq_attr "cpu" "athlon")
100090286Sobrien;       (and (eq_attr "memory" "!none")
100190286Sobrien;            (eq_attr "athlon_fpunits" "none")))
100290286Sobrien;  1 1)
100390286Sobrien
100490286Sobrien;; Model load unit to avoid too long sequences of loads.  We don't need to
100590286Sobrien;; model store queue, since it is hardly going to be bottleneck.
100690286Sobrien
100790286Sobrien(define_function_unit "athlon_load" 2 0
100890286Sobrien  (and (eq_attr "cpu" "athlon")
100990286Sobrien       (eq_attr "memory" "load,both"))
101090286Sobrien  1 1)
101190286Sobrien
101290286Sobrien
101390286Sobrien;; Compare instructions.
101490286Sobrien
101590286Sobrien;; All compare insns have expanders that save the operands away without
101690286Sobrien;; actually generating RTL.  The bCOND or sCOND (emitted immediately
101790286Sobrien;; after the cmp) will actually emit the cmpM.
101890286Sobrien
101990286Sobrien(define_expand "cmpdi"
102090286Sobrien  [(set (reg:CC 17)
102190286Sobrien	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
102290286Sobrien		    (match_operand:DI 1 "x86_64_general_operand" "")))]
102390286Sobrien  ""
102418334Speter{
102590286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
102690286Sobrien    operands[0] = force_reg (DImode, operands[0]);
102790286Sobrien  ix86_compare_op0 = operands[0];
102890286Sobrien  ix86_compare_op1 = operands[1];
102918334Speter  DONE;
103090286Sobrien})
103118334Speter
103218334Speter(define_expand "cmpsi"
103390286Sobrien  [(set (reg:CC 17)
103490286Sobrien	(compare:CC (match_operand:SI 0 "cmpsi_operand" "")
103590286Sobrien		    (match_operand:SI 1 "general_operand" "")))]
103618334Speter  ""
103718334Speter{
103818334Speter  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
103918334Speter    operands[0] = force_reg (SImode, operands[0]);
104090286Sobrien  ix86_compare_op0 = operands[0];
104190286Sobrien  ix86_compare_op1 = operands[1];
104218334Speter  DONE;
104390286Sobrien})
104418334Speter
104518334Speter(define_expand "cmphi"
104690286Sobrien  [(set (reg:CC 17)
104790286Sobrien	(compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
104890286Sobrien		    (match_operand:HI 1 "general_operand" "")))]
104918334Speter  ""
105018334Speter{
105118334Speter  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
105218334Speter    operands[0] = force_reg (HImode, operands[0]);
105390286Sobrien  ix86_compare_op0 = operands[0];
105490286Sobrien  ix86_compare_op1 = operands[1];
105518334Speter  DONE;
105690286Sobrien})
105718334Speter
105818334Speter(define_expand "cmpqi"
105990286Sobrien  [(set (reg:CC 17)
106090286Sobrien	(compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
106190286Sobrien		    (match_operand:QI 1 "general_operand" "")))]
106290286Sobrien  "TARGET_QIMODE_MATH"
106318334Speter{
106418334Speter  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
106518334Speter    operands[0] = force_reg (QImode, operands[0]);
106690286Sobrien  ix86_compare_op0 = operands[0];
106790286Sobrien  ix86_compare_op1 = operands[1];
106818334Speter  DONE;
106990286Sobrien})
107018334Speter
107190286Sobrien(define_insn "cmpdi_ccno_1_rex64"
107290286Sobrien  [(set (reg 17)
107390286Sobrien	(compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
107490286Sobrien		 (match_operand:DI 1 "const0_operand" "n,n")))]
107590286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
107690286Sobrien  "@
107790286Sobrien   test{q}\t{%0, %0|%0, %0}
107890286Sobrien   cmp{q}\t{%1, %0|%0, %1}"
107990286Sobrien  [(set_attr "type" "test,icmp")
108090286Sobrien   (set_attr "length_immediate" "0,1")
108190286Sobrien   (set_attr "mode" "DI")])
108218334Speter
108390286Sobrien(define_insn "*cmpdi_minus_1_rex64"
108490286Sobrien  [(set (reg 17)
108590286Sobrien	(compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
108690286Sobrien			   (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
108790286Sobrien		 (const_int 0)))]
108890286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
108990286Sobrien  "cmp{q}\t{%1, %0|%0, %1}"
109090286Sobrien  [(set_attr "type" "icmp")
109190286Sobrien   (set_attr "mode" "DI")])
109218334Speter
109390286Sobrien(define_expand "cmpdi_1_rex64"
109490286Sobrien  [(set (reg:CC 17)
109590286Sobrien	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
109690286Sobrien		    (match_operand:DI 1 "general_operand" "")))]
109790286Sobrien  "TARGET_64BIT"
109890286Sobrien  "")
109918334Speter
110090286Sobrien(define_insn "cmpdi_1_insn_rex64"
110190286Sobrien  [(set (reg 17)
110290286Sobrien	(compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
110390286Sobrien		 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
110490286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
110590286Sobrien  "cmp{q}\t{%1, %0|%0, %1}"
110690286Sobrien  [(set_attr "type" "icmp")
110790286Sobrien   (set_attr "mode" "DI")])
110850650Sobrien
110918334Speter
111090286Sobrien(define_insn "*cmpsi_ccno_1"
111190286Sobrien  [(set (reg 17)
111290286Sobrien	(compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
111390286Sobrien		 (match_operand:SI 1 "const0_operand" "n,n")))]
111490286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
111590286Sobrien  "@
111690286Sobrien   test{l}\t{%0, %0|%0, %0}
111790286Sobrien   cmp{l}\t{%1, %0|%0, %1}"
111890286Sobrien  [(set_attr "type" "test,icmp")
111990286Sobrien   (set_attr "length_immediate" "0,1")
112090286Sobrien   (set_attr "mode" "SI")])
112150650Sobrien
112290286Sobrien(define_insn "*cmpsi_minus_1"
112390286Sobrien  [(set (reg 17)
112490286Sobrien	(compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
112590286Sobrien			   (match_operand:SI 1 "general_operand" "ri,mr"))
112690286Sobrien		 (const_int 0)))]
112790286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)"
112890286Sobrien  "cmp{l}\t{%1, %0|%0, %1}"
112990286Sobrien  [(set_attr "type" "icmp")
113090286Sobrien   (set_attr "mode" "SI")])
113118334Speter
113290286Sobrien(define_expand "cmpsi_1"
113390286Sobrien  [(set (reg:CC 17)
113490286Sobrien	(compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
113590286Sobrien		    (match_operand:SI 1 "general_operand" "ri,mr")))]
113690286Sobrien  ""
113790286Sobrien  "")
113818334Speter
113990286Sobrien(define_insn "*cmpsi_1_insn"
114090286Sobrien  [(set (reg 17)
114190286Sobrien	(compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
114290286Sobrien		 (match_operand:SI 1 "general_operand" "ri,mr")))]
114390286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
114490286Sobrien    && ix86_match_ccmode (insn, CCmode)"
114590286Sobrien  "cmp{l}\t{%1, %0|%0, %1}"
114690286Sobrien  [(set_attr "type" "icmp")
114790286Sobrien   (set_attr "mode" "SI")])
114818334Speter
114990286Sobrien(define_insn "*cmphi_ccno_1"
115090286Sobrien  [(set (reg 17)
115190286Sobrien	(compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
115290286Sobrien		 (match_operand:HI 1 "const0_operand" "n,n")))]
115390286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
115490286Sobrien  "@
115590286Sobrien   test{w}\t{%0, %0|%0, %0}
115690286Sobrien   cmp{w}\t{%1, %0|%0, %1}"
115790286Sobrien  [(set_attr "type" "test,icmp")
115890286Sobrien   (set_attr "length_immediate" "0,1")
115990286Sobrien   (set_attr "mode" "HI")])
116018334Speter
116190286Sobrien(define_insn "*cmphi_minus_1"
116290286Sobrien  [(set (reg 17)
116390286Sobrien	(compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
116490286Sobrien			   (match_operand:HI 1 "general_operand" "ri,mr"))
116590286Sobrien		 (const_int 0)))]
116690286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)"
116790286Sobrien  "cmp{w}\t{%1, %0|%0, %1}"
116890286Sobrien  [(set_attr "type" "icmp")
116990286Sobrien   (set_attr "mode" "HI")])
117050650Sobrien
117190286Sobrien(define_insn "*cmphi_1"
117290286Sobrien  [(set (reg 17)
117390286Sobrien	(compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
117490286Sobrien		 (match_operand:HI 1 "general_operand" "ri,mr")))]
117590286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
117690286Sobrien   && ix86_match_ccmode (insn, CCmode)"
117790286Sobrien  "cmp{w}\t{%1, %0|%0, %1}"
117890286Sobrien  [(set_attr "type" "icmp")
117990286Sobrien   (set_attr "mode" "HI")])
118018334Speter
118190286Sobrien(define_insn "*cmpqi_ccno_1"
118290286Sobrien  [(set (reg 17)
118390286Sobrien	(compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
118490286Sobrien		 (match_operand:QI 1 "const0_operand" "n,n")))]
118590286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
118690286Sobrien  "@
118790286Sobrien   test{b}\t{%0, %0|%0, %0}
118890286Sobrien   cmp{b}\t{$0, %0|%0, 0}"
118990286Sobrien  [(set_attr "type" "test,icmp")
119090286Sobrien   (set_attr "length_immediate" "0,1")
119190286Sobrien   (set_attr "mode" "QI")])
119218334Speter
119390286Sobrien(define_insn "*cmpqi_1"
119490286Sobrien  [(set (reg 17)
119590286Sobrien	(compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
119690286Sobrien		 (match_operand:QI 1 "general_operand" "qi,mq")))]
119790286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
119890286Sobrien    && ix86_match_ccmode (insn, CCmode)"
119990286Sobrien  "cmp{b}\t{%1, %0|%0, %1}"
120090286Sobrien  [(set_attr "type" "icmp")
120190286Sobrien   (set_attr "mode" "QI")])
120218334Speter
120390286Sobrien(define_insn "*cmpqi_minus_1"
120490286Sobrien  [(set (reg 17)
120590286Sobrien	(compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
120690286Sobrien			   (match_operand:QI 1 "general_operand" "qi,mq"))
120790286Sobrien		 (const_int 0)))]
120890286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)"
120990286Sobrien  "cmp{b}\t{%1, %0|%0, %1}"
121090286Sobrien  [(set_attr "type" "icmp")
121190286Sobrien   (set_attr "mode" "QI")])
121218334Speter
121390286Sobrien(define_insn "*cmpqi_ext_1"
121490286Sobrien  [(set (reg 17)
121590286Sobrien	(compare
121690286Sobrien	  (match_operand:QI 0 "general_operand" "Qm")
121790286Sobrien	  (subreg:QI
121890286Sobrien	    (zero_extract:SI
121990286Sobrien	      (match_operand 1 "ext_register_operand" "Q")
122090286Sobrien	      (const_int 8)
122190286Sobrien	      (const_int 8)) 0)))]
122290286Sobrien  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
122390286Sobrien  "cmp{b}\t{%h1, %0|%0, %h1}"
122490286Sobrien  [(set_attr "type" "icmp")
122590286Sobrien   (set_attr "mode" "QI")])
122690286Sobrien
122790286Sobrien(define_insn "*cmpqi_ext_1_rex64"
122890286Sobrien  [(set (reg 17)
122990286Sobrien	(compare
123090286Sobrien	  (match_operand:QI 0 "register_operand" "Q")
123190286Sobrien	  (subreg:QI
123290286Sobrien	    (zero_extract:SI
123390286Sobrien	      (match_operand 1 "ext_register_operand" "Q")
123490286Sobrien	      (const_int 8)
123590286Sobrien	      (const_int 8)) 0)))]
123690286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
123790286Sobrien  "cmp{b}\t{%h1, %0|%0, %h1}"
123890286Sobrien  [(set_attr "type" "icmp")
123990286Sobrien   (set_attr "mode" "QI")])
124090286Sobrien
124190286Sobrien(define_insn "*cmpqi_ext_2"
124290286Sobrien  [(set (reg 17)
124390286Sobrien	(compare
124490286Sobrien	  (subreg:QI
124590286Sobrien	    (zero_extract:SI
124690286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
124790286Sobrien	      (const_int 8)
124890286Sobrien	      (const_int 8)) 0)
124990286Sobrien	  (match_operand:QI 1 "const0_operand" "n")))]
125090286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
125190286Sobrien  "test{b}\t%h0, %h0"
125290286Sobrien  [(set_attr "type" "test")
125390286Sobrien   (set_attr "length_immediate" "0")
125490286Sobrien   (set_attr "mode" "QI")])
125590286Sobrien
125690286Sobrien(define_expand "cmpqi_ext_3"
125790286Sobrien  [(set (reg:CC 17)
125890286Sobrien	(compare:CC
125990286Sobrien	  (subreg:QI
126090286Sobrien	    (zero_extract:SI
126190286Sobrien	      (match_operand 0 "ext_register_operand" "")
126290286Sobrien	      (const_int 8)
126390286Sobrien	      (const_int 8)) 0)
126490286Sobrien	  (match_operand:QI 1 "general_operand" "")))]
126590286Sobrien  ""
126690286Sobrien  "")
126790286Sobrien
126890286Sobrien(define_insn "cmpqi_ext_3_insn"
126990286Sobrien  [(set (reg 17)
127090286Sobrien	(compare
127190286Sobrien	  (subreg:QI
127290286Sobrien	    (zero_extract:SI
127390286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
127490286Sobrien	      (const_int 8)
127590286Sobrien	      (const_int 8)) 0)
127690286Sobrien	  (match_operand:QI 1 "general_operand" "Qmn")))]
127790286Sobrien  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
127890286Sobrien  "cmp{b}\t{%1, %h0|%h0, %1}"
127990286Sobrien  [(set_attr "type" "icmp")
128090286Sobrien   (set_attr "mode" "QI")])
128190286Sobrien
128290286Sobrien(define_insn "cmpqi_ext_3_insn_rex64"
128390286Sobrien  [(set (reg 17)
128490286Sobrien	(compare
128590286Sobrien	  (subreg:QI
128690286Sobrien	    (zero_extract:SI
128790286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
128890286Sobrien	      (const_int 8)
128990286Sobrien	      (const_int 8)) 0)
129090286Sobrien	  (match_operand:QI 1 "nonmemory_operand" "Qn")))]
129190286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
129290286Sobrien  "cmp{b}\t{%1, %h0|%h0, %1}"
129390286Sobrien  [(set_attr "type" "icmp")
129490286Sobrien   (set_attr "mode" "QI")])
129590286Sobrien
129690286Sobrien(define_insn "*cmpqi_ext_4"
129790286Sobrien  [(set (reg 17)
129890286Sobrien	(compare
129990286Sobrien	  (subreg:QI
130090286Sobrien	    (zero_extract:SI
130190286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
130290286Sobrien	      (const_int 8)
130390286Sobrien	      (const_int 8)) 0)
130490286Sobrien	  (subreg:QI
130590286Sobrien	    (zero_extract:SI
130690286Sobrien	      (match_operand 1 "ext_register_operand" "Q")
130790286Sobrien	      (const_int 8)
130890286Sobrien	      (const_int 8)) 0)))]
130990286Sobrien  "ix86_match_ccmode (insn, CCmode)"
131090286Sobrien  "cmp{b}\t{%h1, %h0|%h0, %h1}"
131190286Sobrien  [(set_attr "type" "icmp")
131290286Sobrien   (set_attr "mode" "QI")])
131390286Sobrien
131490286Sobrien;; These implement float point compares.
131590286Sobrien;; %%% See if we can get away with VOIDmode operands on the actual insns,
131690286Sobrien;; which would allow mix and match FP modes on the compares.  Which is what
131790286Sobrien;; the old patterns did, but with many more of them.
131890286Sobrien
131918334Speter(define_expand "cmpxf"
132090286Sobrien  [(set (reg:CC 17)
132190286Sobrien	(compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
132290286Sobrien		    (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
132390286Sobrien  "!TARGET_64BIT && TARGET_80387"
132490286Sobrien{
132590286Sobrien  ix86_compare_op0 = operands[0];
132690286Sobrien  ix86_compare_op1 = operands[1];
132790286Sobrien  DONE;
132890286Sobrien})
132990286Sobrien
133090286Sobrien(define_expand "cmptf"
133190286Sobrien  [(set (reg:CC 17)
133290286Sobrien	(compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
133390286Sobrien		    (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
133418334Speter  "TARGET_80387"
133518334Speter{
133690286Sobrien  ix86_compare_op0 = operands[0];
133790286Sobrien  ix86_compare_op1 = operands[1];
133818334Speter  DONE;
133990286Sobrien})
134018334Speter
134118334Speter(define_expand "cmpdf"
134290286Sobrien  [(set (reg:CC 17)
134390286Sobrien	(compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
134490286Sobrien		    (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
134590286Sobrien  "TARGET_80387 || TARGET_SSE2"
134618334Speter{
134790286Sobrien  ix86_compare_op0 = operands[0];
134890286Sobrien  ix86_compare_op1 = operands[1];
134918334Speter  DONE;
135090286Sobrien})
135118334Speter
135218334Speter(define_expand "cmpsf"
135390286Sobrien  [(set (reg:CC 17)
135490286Sobrien	(compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
135590286Sobrien		    (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
135690286Sobrien  "TARGET_80387 || TARGET_SSE"
135718334Speter{
135890286Sobrien  ix86_compare_op0 = operands[0];
135990286Sobrien  ix86_compare_op1 = operands[1];
136018334Speter  DONE;
136190286Sobrien})
136218334Speter
136390286Sobrien;; FP compares, step 1:
136490286Sobrien;; Set the FP condition codes.
136590286Sobrien;;
136690286Sobrien;; CCFPmode	compare with exceptions
136790286Sobrien;; CCFPUmode	compare with no exceptions
136818334Speter
136990286Sobrien;; %%% It is an unfortunate fact that ftst has no non-popping variant,
137090286Sobrien;; and that fp moves clobber the condition codes, and that there is
137190286Sobrien;; currently no way to describe this fact to reg-stack.  So there are
137290286Sobrien;; no splitters yet for this.
137318334Speter
137490286Sobrien;; %%% YIKES!  This scheme does not retain a strong connection between 
137590286Sobrien;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
137690286Sobrien;; work!  Only allow tos/mem with tos in op 0.
137790286Sobrien;;
137890286Sobrien;; Hmm, of course, this is what the actual _hardware_ does.  Perhaps
137990286Sobrien;; things aren't as bad as they sound...
138090286Sobrien
138190286Sobrien(define_insn "*cmpfp_0"
138290286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
138390286Sobrien	(unspec:HI
138490286Sobrien	  [(compare:CCFP (match_operand 1 "register_operand" "f")
138590286Sobrien		         (match_operand 2 "const0_operand" "X"))] 9))]
138690286Sobrien  "TARGET_80387
138790286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
138890286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
138990286Sobrien{
139090286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
139190286Sobrien    return "ftst\;fnstsw\t%0\;fstp\t%y0";
139290286Sobrien  else
139390286Sobrien    return "ftst\;fnstsw\t%0";
139490286Sobrien}
139590286Sobrien  [(set_attr "type" "multi")
139690286Sobrien   (set_attr "mode" "unknownfp")])
139790286Sobrien
139890286Sobrien;; We may not use "#" to split and emit these, since the REG_DEAD notes
139990286Sobrien;; used to manage the reg stack popping would not be preserved.
140090286Sobrien
140190286Sobrien(define_insn "*cmpfp_2_sf"
140290286Sobrien  [(set (reg:CCFP 18)
140390286Sobrien	(compare:CCFP
140490286Sobrien	  (match_operand:SF 0 "register_operand" "f")
140590286Sobrien	  (match_operand:SF 1 "nonimmediate_operand" "fm")))]
140618334Speter  "TARGET_80387"
140790286Sobrien  "* return output_fp_compare (insn, operands, 0, 0);"
140890286Sobrien  [(set_attr "type" "fcmp")
140990286Sobrien   (set_attr "mode" "SF")])
141018334Speter
141190286Sobrien(define_insn "*cmpfp_2_sf_1"
141290286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
141390286Sobrien	(unspec:HI
141490286Sobrien	  [(compare:CCFP
141590286Sobrien	     (match_operand:SF 1 "register_operand" "f")
141690286Sobrien	     (match_operand:SF 2 "nonimmediate_operand" "fm"))] 9))]
141718334Speter  "TARGET_80387"
141890286Sobrien  "* return output_fp_compare (insn, operands, 2, 0);"
141990286Sobrien  [(set_attr "type" "fcmp")
142090286Sobrien   (set_attr "mode" "SF")])
142118334Speter
142290286Sobrien(define_insn "*cmpfp_2_df"
142390286Sobrien  [(set (reg:CCFP 18)
142490286Sobrien	(compare:CCFP
142590286Sobrien	  (match_operand:DF 0 "register_operand" "f")
142690286Sobrien	  (match_operand:DF 1 "nonimmediate_operand" "fm")))]
142718334Speter  "TARGET_80387"
142890286Sobrien  "* return output_fp_compare (insn, operands, 0, 0);"
142990286Sobrien  [(set_attr "type" "fcmp")
143090286Sobrien   (set_attr "mode" "DF")])
143118334Speter
143290286Sobrien(define_insn "*cmpfp_2_df_1"
143390286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
143490286Sobrien	(unspec:HI
143590286Sobrien	  [(compare:CCFP
143690286Sobrien	     (match_operand:DF 1 "register_operand" "f")
143790286Sobrien	     (match_operand:DF 2 "nonimmediate_operand" "fm"))] 9))]
143818334Speter  "TARGET_80387"
143990286Sobrien  "* return output_fp_compare (insn, operands, 2, 0);"
144090286Sobrien  [(set_attr "type" "multi")
144190286Sobrien   (set_attr "mode" "DF")])
144218334Speter
144390286Sobrien(define_insn "*cmpfp_2_xf"
144490286Sobrien  [(set (reg:CCFP 18)
144590286Sobrien	(compare:CCFP
144690286Sobrien	  (match_operand:XF 0 "register_operand" "f")
144790286Sobrien	  (match_operand:XF 1 "register_operand" "f")))]
144890286Sobrien  "!TARGET_64BIT && TARGET_80387"
144990286Sobrien  "* return output_fp_compare (insn, operands, 0, 0);"
145090286Sobrien  [(set_attr "type" "fcmp")
145190286Sobrien   (set_attr "mode" "XF")])
145218334Speter
145390286Sobrien(define_insn "*cmpfp_2_tf"
145490286Sobrien  [(set (reg:CCFP 18)
145590286Sobrien	(compare:CCFP
145690286Sobrien	  (match_operand:TF 0 "register_operand" "f")
145790286Sobrien	  (match_operand:TF 1 "register_operand" "f")))]
145890286Sobrien  "TARGET_80387"
145990286Sobrien  "* return output_fp_compare (insn, operands, 0, 0);"
146090286Sobrien  [(set_attr "type" "fcmp")
146190286Sobrien   (set_attr "mode" "XF")])
146218334Speter
146390286Sobrien(define_insn "*cmpfp_2_xf_1"
146490286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
146590286Sobrien	(unspec:HI
146690286Sobrien	  [(compare:CCFP
146790286Sobrien	     (match_operand:XF 1 "register_operand" "f")
146890286Sobrien	     (match_operand:XF 2 "register_operand" "f"))] 9))]
146990286Sobrien  "!TARGET_64BIT && TARGET_80387"
147090286Sobrien  "* return output_fp_compare (insn, operands, 2, 0);"
147190286Sobrien  [(set_attr "type" "multi")
147290286Sobrien   (set_attr "mode" "XF")])
147318334Speter
147490286Sobrien(define_insn "*cmpfp_2_tf_1"
147590286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
147690286Sobrien	(unspec:HI
147790286Sobrien	  [(compare:CCFP
147890286Sobrien	     (match_operand:TF 1 "register_operand" "f")
147990286Sobrien	     (match_operand:TF 2 "register_operand" "f"))] 9))]
148090286Sobrien  "TARGET_80387"
148190286Sobrien  "* return output_fp_compare (insn, operands, 2, 0);"
148290286Sobrien  [(set_attr "type" "multi")
148390286Sobrien   (set_attr "mode" "XF")])
148418334Speter
148590286Sobrien(define_insn "*cmpfp_2u"
148690286Sobrien  [(set (reg:CCFPU 18)
148790286Sobrien	(compare:CCFPU
148890286Sobrien	  (match_operand 0 "register_operand" "f")
148990286Sobrien	  (match_operand 1 "register_operand" "f")))]
149090286Sobrien  "TARGET_80387
149190286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))
149290286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
149390286Sobrien  "* return output_fp_compare (insn, operands, 0, 1);"
149490286Sobrien  [(set_attr "type" "fcmp")
149590286Sobrien   (set_attr "mode" "unknownfp")])
149618334Speter
149790286Sobrien(define_insn "*cmpfp_2u_1"
149890286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
149990286Sobrien	(unspec:HI
150090286Sobrien	  [(compare:CCFPU
150190286Sobrien	     (match_operand 1 "register_operand" "f")
150290286Sobrien	     (match_operand 2 "register_operand" "f"))] 9))]
150390286Sobrien  "TARGET_80387
150490286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
150590286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
150690286Sobrien  "* return output_fp_compare (insn, operands, 2, 1);"
150790286Sobrien  [(set_attr "type" "multi")
150890286Sobrien   (set_attr "mode" "unknownfp")])
150918334Speter
151090286Sobrien;; Patterns to match the SImode-in-memory ficom instructions.
151190286Sobrien;;
151290286Sobrien;; %%% Play games with accepting gp registers, as otherwise we have to
151390286Sobrien;; force them to memory during rtl generation, which is no good.  We
151490286Sobrien;; can get rid of this once we teach reload to do memory input reloads 
151590286Sobrien;; via pushes.
151618334Speter
151790286Sobrien(define_insn "*ficom_1"
151890286Sobrien  [(set (reg:CCFP 18)
151990286Sobrien	(compare:CCFP
152090286Sobrien	  (match_operand 0 "register_operand" "f,f")
152190286Sobrien	  (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
152290286Sobrien  "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
152390286Sobrien   && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
152490286Sobrien  "#")
152518334Speter
152690286Sobrien;; Split the not-really-implemented gp register case into a
152790286Sobrien;; push-op-pop sequence.
152890286Sobrien;;
152990286Sobrien;; %%% This is most efficient, but am I gonna get in trouble
153090286Sobrien;; for separating cc0_setter and cc0_user?
153118334Speter
153290286Sobrien(define_split
153390286Sobrien  [(set (reg:CCFP 18)
153490286Sobrien	(compare:CCFP
153590286Sobrien	  (match_operand:SF 0 "register_operand" "")
153690286Sobrien	  (float (match_operand:SI 1 "register_operand" ""))))]
153790286Sobrien  "0 && TARGET_80387 && reload_completed"
153890286Sobrien  [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
153990286Sobrien   (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
154090286Sobrien   (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
154190286Sobrien              (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
154290286Sobrien  "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
154390286Sobrien   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
154418334Speter
154590286Sobrien;; FP compares, step 2
154690286Sobrien;; Move the fpsw to ax.
154718334Speter
154890286Sobrien(define_insn "x86_fnstsw_1"
154990286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
155090286Sobrien	(unspec:HI [(reg 18)] 9))]
155190286Sobrien  "TARGET_80387"
155290286Sobrien  "fnstsw\t%0"
155390286Sobrien  [(set_attr "length" "2")
155490286Sobrien   (set_attr "mode" "SI")
155590286Sobrien   (set_attr "i387" "1")
155690286Sobrien   (set_attr "ppro_uops" "few")])
155718334Speter
155890286Sobrien;; FP compares, step 3
155990286Sobrien;; Get ax into flags, general case.
156050650Sobrien
156190286Sobrien(define_insn "x86_sahf_1"
156290286Sobrien  [(set (reg:CC 17)
156390286Sobrien	(unspec:CC [(match_operand:HI 0 "register_operand" "a")] 10))]
156490286Sobrien  "!TARGET_64BIT"
156590286Sobrien  "sahf"
156690286Sobrien  [(set_attr "length" "1")
156790286Sobrien   (set_attr "athlon_decode" "vector")
156890286Sobrien   (set_attr "mode" "SI")
156990286Sobrien   (set_attr "ppro_uops" "one")])
157018334Speter
157190286Sobrien;; Pentium Pro can do steps 1 through 3 in one go.
157218334Speter
157390286Sobrien(define_insn "*cmpfp_i"
157490286Sobrien  [(set (reg:CCFP 17)
157590286Sobrien	(compare:CCFP (match_operand 0 "register_operand" "f")
157690286Sobrien		      (match_operand 1 "register_operand" "f")))]
157790286Sobrien  "TARGET_80387 && TARGET_CMOVE
157890286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
157990286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))
158090286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[0])"
158190286Sobrien  "* return output_fp_compare (insn, operands, 1, 0);"
158290286Sobrien  [(set_attr "type" "fcmp")
158390286Sobrien   (set_attr "mode" "unknownfp")
158490286Sobrien   (set_attr "athlon_decode" "vector")])
158518334Speter
158690286Sobrien(define_insn "*cmpfp_i_sse"
158790286Sobrien  [(set (reg:CCFP 17)
158890286Sobrien	(compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
158990286Sobrien		      (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
159090286Sobrien  "TARGET_80387
159190286Sobrien   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
159290286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[0])"
159390286Sobrien  "* return output_fp_compare (insn, operands, 1, 0);"
159490286Sobrien  [(set_attr "type" "fcmp,sse")
159590286Sobrien   (set_attr "mode" "unknownfp")
159690286Sobrien   (set_attr "athlon_decode" "vector")])
159718334Speter
159890286Sobrien(define_insn "*cmpfp_i_sse_only"
159990286Sobrien  [(set (reg:CCFP 17)
160090286Sobrien	(compare:CCFP (match_operand 0 "register_operand" "x")
160190286Sobrien		      (match_operand 1 "nonimmediate_operand" "xm")))]
160290286Sobrien  "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
160390286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[0])"
160490286Sobrien  "* return output_fp_compare (insn, operands, 1, 0);"
160590286Sobrien  [(set_attr "type" "sse")
160690286Sobrien   (set_attr "mode" "unknownfp")
160790286Sobrien   (set_attr "athlon_decode" "vector")])
160818334Speter
160990286Sobrien(define_insn "*cmpfp_iu"
161090286Sobrien  [(set (reg:CCFPU 17)
161190286Sobrien	(compare:CCFPU (match_operand 0 "register_operand" "f")
161290286Sobrien		       (match_operand 1 "register_operand" "f")))]
161390286Sobrien  "TARGET_80387 && TARGET_CMOVE
161490286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
161590286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))
161690286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
161790286Sobrien  "* return output_fp_compare (insn, operands, 1, 1);"
161890286Sobrien  [(set_attr "type" "fcmp")
161990286Sobrien   (set_attr "mode" "unknownfp")
162090286Sobrien   (set_attr "athlon_decode" "vector")])
162118334Speter
162290286Sobrien(define_insn "*cmpfp_iu_sse"
162390286Sobrien  [(set (reg:CCFPU 17)
162490286Sobrien	(compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
162590286Sobrien		       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
162690286Sobrien  "TARGET_80387
162790286Sobrien   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
162890286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
162990286Sobrien  "* return output_fp_compare (insn, operands, 1, 1);"
163090286Sobrien  [(set_attr "type" "fcmp,sse")
163190286Sobrien   (set_attr "mode" "unknownfp")
163290286Sobrien   (set_attr "athlon_decode" "vector")])
163350650Sobrien
163490286Sobrien(define_insn "*cmpfp_iu_sse_only"
163590286Sobrien  [(set (reg:CCFPU 17)
163690286Sobrien	(compare:CCFPU (match_operand 0 "register_operand" "x")
163790286Sobrien		       (match_operand 1 "nonimmediate_operand" "xm")))]
163890286Sobrien  "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
163990286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
164090286Sobrien  "* return output_fp_compare (insn, operands, 1, 1);"
164190286Sobrien  [(set_attr "type" "sse")
164290286Sobrien   (set_attr "mode" "unknownfp")
164390286Sobrien   (set_attr "athlon_decode" "vector")])
164490286Sobrien
164590286Sobrien;; Move instructions.
164618334Speter
164718334Speter;; General case of fullword move.
164818334Speter
164918334Speter(define_expand "movsi"
165090286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
165118334Speter	(match_operand:SI 1 "general_operand" ""))]
165218334Speter  ""
165390286Sobrien  "ix86_expand_move (SImode, operands); DONE;")
165418334Speter
165590286Sobrien;; Push/pop instructions.  They are separate since autoinc/dec is not a
165690286Sobrien;; general_operand.
165790286Sobrien;;
165890286Sobrien;; %%% We don't use a post-inc memory reference because x86 is not a 
165990286Sobrien;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
166090286Sobrien;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
166190286Sobrien;; targets without our curiosities, and it is just as easy to represent
166290286Sobrien;; this differently.
166318334Speter
166490286Sobrien(define_insn "*pushsi2"
166590286Sobrien  [(set (match_operand:SI 0 "push_operand" "=<")
166690286Sobrien	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
166790286Sobrien  "!TARGET_64BIT"
166890286Sobrien  "push{l}\t%1"
166990286Sobrien  [(set_attr "type" "push")
167090286Sobrien   (set_attr "mode" "SI")])
167118334Speter
167290286Sobrien;; For 64BIT abi we always round up to 8 bytes.
167390286Sobrien(define_insn "*pushsi2_rex64"
167490286Sobrien  [(set (match_operand:SI 0 "push_operand" "=X")
167590286Sobrien	(match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
167690286Sobrien  "TARGET_64BIT"
167790286Sobrien  "push{q}\t%q1"
167890286Sobrien  [(set_attr "type" "push")
167990286Sobrien   (set_attr "mode" "SI")])
168018334Speter
168190286Sobrien(define_insn "*pushsi2_prologue"
168290286Sobrien  [(set (match_operand:SI 0 "push_operand" "=<")
168390286Sobrien	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))
168490286Sobrien   (clobber (mem:BLK (scratch)))]
168590286Sobrien  "!TARGET_64BIT"
168690286Sobrien  "push{l}\t%1"
168790286Sobrien  [(set_attr "type" "push")
168890286Sobrien   (set_attr "mode" "SI")])
168952296Sobrien
169090286Sobrien(define_insn "*popsi1_epilogue"
169190286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
169290286Sobrien	(mem:SI (reg:SI 7)))
169390286Sobrien   (set (reg:SI 7)
169490286Sobrien	(plus:SI (reg:SI 7) (const_int 4)))
169590286Sobrien   (clobber (mem:BLK (scratch)))]
169690286Sobrien  "!TARGET_64BIT"
169790286Sobrien  "pop{l}\t%0"
169890286Sobrien  [(set_attr "type" "pop")
169990286Sobrien   (set_attr "mode" "SI")])
170018334Speter
170190286Sobrien(define_insn "popsi1"
170290286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
170390286Sobrien	(mem:SI (reg:SI 7)))
170490286Sobrien   (set (reg:SI 7)
170590286Sobrien	(plus:SI (reg:SI 7) (const_int 4)))]
170690286Sobrien  "!TARGET_64BIT"
170790286Sobrien  "pop{l}\t%0"
170890286Sobrien  [(set_attr "type" "pop")
170990286Sobrien   (set_attr "mode" "SI")])
171018334Speter
171190286Sobrien(define_insn "*movsi_xor"
171290286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
171390286Sobrien	(match_operand:SI 1 "const0_operand" "i"))
171490286Sobrien   (clobber (reg:CC 17))]
171590286Sobrien  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
171690286Sobrien  "xor{l}\t{%0, %0|%0, %0}"
171790286Sobrien  [(set_attr "type" "alu1")
171890286Sobrien   (set_attr "mode" "SI")
171990286Sobrien   (set_attr "length_immediate" "0")])
172018334Speter
172190286Sobrien(define_insn "*movsi_or"
172290286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
172390286Sobrien	(match_operand:SI 1 "immediate_operand" "i"))
172490286Sobrien   (clobber (reg:CC 17))]
172590286Sobrien  "reload_completed && GET_CODE (operands[1]) == CONST_INT
172690286Sobrien   && INTVAL (operands[1]) == -1
172790286Sobrien   && (TARGET_PENTIUM || optimize_size)"
172890286Sobrien{
172990286Sobrien  operands[1] = constm1_rtx;
173090286Sobrien  return "or{l}\t{%1, %0|%0, %1}";
173190286Sobrien}
173290286Sobrien  [(set_attr "type" "alu1")
173390286Sobrien   (set_attr "mode" "SI")
173490286Sobrien   (set_attr "length_immediate" "1")])
173518334Speter
173696294Sobrien; The first alternative is used only to compute proper length of instruction.
173796294Sobrien; Reload's algorithm does not take into account the cost of spill instructions
173896294Sobrien; needed to free register in given class, so avoid it from choosing the first
173996294Sobrien; alternative when eax is not available.
174096294Sobrien
174190286Sobrien(define_insn "*movsi_1"
174296294Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=*?a,r,*?a,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
174396294Sobrien	(match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,rm,*y,*y,rm,*Y,*Y"))]
174490286Sobrien  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
174550650Sobrien{
174690286Sobrien  switch (get_attr_type (insn))
174790286Sobrien    {
174890286Sobrien    case TYPE_SSE:
174990286Sobrien      if (get_attr_mode (insn) == TImode)
175090286Sobrien        return "movdqa\t{%1, %0|%0, %1}";
175190286Sobrien      return "movd\t{%1, %0|%0, %1}";
175252296Sobrien
175390286Sobrien    case TYPE_MMX:
175496294Sobrien      if (get_attr_mode (insn) == DImode)
175596294Sobrien	return "movq\t{%1, %0|%0, %1}";
175690286Sobrien      return "movd\t{%1, %0|%0, %1}";
175752296Sobrien
175890286Sobrien    case TYPE_LEA:
175990286Sobrien      return "lea{l}\t{%1, %0|%0, %1}";
176018334Speter
176190286Sobrien    default:
176290286Sobrien      if (flag_pic && SYMBOLIC_CONST (operands[1]))
176390286Sobrien	abort();
176490286Sobrien      return "mov{l}\t{%1, %0|%0, %1}";
176590286Sobrien    }
176690286Sobrien}
176790286Sobrien  [(set (attr "type")
176896294Sobrien     (cond [(eq_attr "alternative" "4,5,6")
176990286Sobrien	      (const_string "mmx")
177096294Sobrien	    (eq_attr "alternative" "7,8,9")
177190286Sobrien	      (const_string "sse")
177290286Sobrien	    (and (ne (symbol_ref "flag_pic") (const_int 0))
177390286Sobrien		 (match_operand:SI 1 "symbolic_operand" ""))
177490286Sobrien	      (const_string "lea")
177590286Sobrien	   ]
177690286Sobrien	   (const_string "imov")))
177796294Sobrien   (set_attr "modrm" "0,*,0,*,*,*,*,*,*,*")
177896294Sobrien   (set_attr "mode" "SI,SI,SI,SI,SI,SI,DI,TI,SI,SI")])
177950650Sobrien
178090286Sobrien;; Stores and loads of ax to arbitary constant address.
178190286Sobrien;; We fake an second form of instruction to force reload to load address
178290286Sobrien;; into register when rax is not available
178390286Sobrien(define_insn "*movabssi_1_rex64"
178490286Sobrien  [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
178590286Sobrien	(match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
178690286Sobrien  "TARGET_64BIT"
178790286Sobrien  "@
178890286Sobrien   movabs{l}\t{%1, %P0|%P0, %1}
178990286Sobrien   mov{l}\t{%1, %a0|%a0, %1}
179090286Sobrien   movabs{l}\t{%1, %a0|%a0, %1}"
179190286Sobrien  [(set_attr "type" "imov")
179290286Sobrien   (set_attr "modrm" "0,*,*")
179390286Sobrien   (set_attr "length_address" "8,0,0")
179490286Sobrien   (set_attr "length_immediate" "0,*,*")
179590286Sobrien   (set_attr "memory" "store")
179690286Sobrien   (set_attr "mode" "SI")])
179750650Sobrien
179890286Sobrien(define_insn "*movabssi_2_rex64"
179990286Sobrien  [(set (match_operand:SI 0 "register_operand" "=a,r")
180090286Sobrien        (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
180190286Sobrien  "TARGET_64BIT"
180290286Sobrien  "@
180390286Sobrien   movabs{l}\t{%P1, %0|%0, %P1}
180490286Sobrien   mov{l}\t{%a1, %0|%0, %a1}"
180590286Sobrien  [(set_attr "type" "imov")
180690286Sobrien   (set_attr "modrm" "0,*")
180790286Sobrien   (set_attr "length_address" "8,0")
180890286Sobrien   (set_attr "length_immediate" "0")
180990286Sobrien   (set_attr "memory" "load")
181090286Sobrien   (set_attr "mode" "SI")])
181190286Sobrien
181290286Sobrien(define_insn "*swapsi"
181390286Sobrien  [(set (match_operand:SI 0 "register_operand" "+r")
181490286Sobrien	(match_operand:SI 1 "register_operand" "+r"))
181590286Sobrien   (set (match_dup 1)
181690286Sobrien	(match_dup 0))]
181750650Sobrien  ""
181890286Sobrien  "xchg{l}\t%1, %0"
181990286Sobrien  [(set_attr "type" "imov")
182090286Sobrien   (set_attr "pent_pair" "np")
182190286Sobrien   (set_attr "athlon_decode" "vector")
182290286Sobrien   (set_attr "mode" "SI")
182390286Sobrien   (set_attr "modrm" "0")
182490286Sobrien   (set_attr "ppro_uops" "few")])
182518334Speter
182690286Sobrien(define_expand "movhi"
182790286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
182890286Sobrien        (match_operand:HI 1 "general_operand" ""))]
182990286Sobrien  ""
183090286Sobrien  "ix86_expand_move (HImode, operands); DONE;")
183118334Speter
183290286Sobrien(define_insn "*pushhi2"
183390286Sobrien  [(set (match_operand:HI 0 "push_operand" "=<,<")
183490286Sobrien	(match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
183590286Sobrien  "!TARGET_64BIT"
183690286Sobrien  "@
183790286Sobrien   push{w}\t{|WORD PTR }%1
183890286Sobrien   push{w}\t%1"
183990286Sobrien  [(set_attr "type" "push")
184090286Sobrien   (set_attr "mode" "HI")])
184118334Speter
184290286Sobrien;; For 64BIT abi we always round up to 8 bytes.
184390286Sobrien(define_insn "*pushhi2_rex64"
184490286Sobrien  [(set (match_operand:HI 0 "push_operand" "=X")
184590286Sobrien	(match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
184690286Sobrien  "TARGET_64BIT"
184790286Sobrien  "push{q}\t%q1"
184890286Sobrien  [(set_attr "type" "push")
184990286Sobrien   (set_attr "mode" "QI")])
185090286Sobrien
185196294Sobrien; The first alternative is used only to compute proper length of instruction.
185296294Sobrien; Reload's algorithm does not take into account the cost of spill instructions
185396294Sobrien; needed to free register in given class, so avoid it from choosing the first
185496294Sobrien; alternative when eax is not available.
185596294Sobrien
185690286Sobrien(define_insn "*movhi_1"
185796294Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=*?a,r,r,*?a,r,m")
185890286Sobrien	(match_operand:HI 1 "general_operand" "i,r,rn,rm,rm,rn"))]
185990286Sobrien  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
186018334Speter{
186190286Sobrien  switch (get_attr_type (insn))
186218334Speter    {
186390286Sobrien    case TYPE_IMOVX:
186490286Sobrien      /* movzwl is faster than movw on p2 due to partial word stalls,
186590286Sobrien	 though not as fast as an aligned movl.  */
186690286Sobrien      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
186790286Sobrien    default:
186890286Sobrien      if (get_attr_mode (insn) == MODE_SI)
186990286Sobrien        return "mov{l}\t{%k1, %k0|%k0, %k1}";
187090286Sobrien      else
187190286Sobrien        return "mov{w}\t{%1, %0|%0, %1}";
187218334Speter    }
187390286Sobrien}
187490286Sobrien  [(set (attr "type")
187590286Sobrien     (cond [(and (eq_attr "alternative" "0,1")
187690286Sobrien		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
187790286Sobrien			  (const_int 0))
187890286Sobrien		      (eq (symbol_ref "TARGET_HIMODE_MATH")
187990286Sobrien			  (const_int 0))))
188090286Sobrien	      (const_string "imov")
188190286Sobrien	    (and (eq_attr "alternative" "2,3,4")
188290286Sobrien		 (match_operand:HI 1 "aligned_operand" ""))
188390286Sobrien	      (const_string "imov")
188490286Sobrien	    (and (ne (symbol_ref "TARGET_MOVX")
188590286Sobrien		     (const_int 0))
188690286Sobrien		 (eq_attr "alternative" "0,1,3,4"))
188790286Sobrien	      (const_string "imovx")
188890286Sobrien	   ]
188990286Sobrien	   (const_string "imov")))
189090286Sobrien    (set (attr "mode")
189190286Sobrien      (cond [(eq_attr "type" "imovx")
189290286Sobrien	       (const_string "SI")
189390286Sobrien	     (and (eq_attr "alternative" "2,3,4")
189490286Sobrien		  (match_operand:HI 1 "aligned_operand" ""))
189590286Sobrien	       (const_string "SI")
189690286Sobrien	     (and (eq_attr "alternative" "0,1")
189790286Sobrien		  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
189890286Sobrien			   (const_int 0))
189990286Sobrien		       (eq (symbol_ref "TARGET_HIMODE_MATH")
190090286Sobrien			   (const_int 0))))
190190286Sobrien	       (const_string "SI")
190290286Sobrien	    ]
190390286Sobrien	    (const_string "HI")))
190490286Sobrien   (set_attr "modrm" "0,*,*,0,*,*")])
190518334Speter
190690286Sobrien;; Stores and loads of ax to arbitary constant address.
190790286Sobrien;; We fake an second form of instruction to force reload to load address
190890286Sobrien;; into register when rax is not available
190990286Sobrien(define_insn "*movabshi_1_rex64"
191090286Sobrien  [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
191190286Sobrien	(match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
191290286Sobrien  "TARGET_64BIT"
191390286Sobrien  "@
191490286Sobrien   movabs{w}\t{%1, %P0|%P0, %1}
191590286Sobrien   mov{w}\t{%1, %a0|%a0, %1}
191690286Sobrien   movabs{w}\t{%1, %a0|%a0, %1}"
191790286Sobrien  [(set_attr "type" "imov")
191890286Sobrien   (set_attr "modrm" "0,*,*")
191990286Sobrien   (set_attr "length_address" "8,0,0")
192090286Sobrien   (set_attr "length_immediate" "0,*,*")
192190286Sobrien   (set_attr "memory" "store")
192290286Sobrien   (set_attr "mode" "HI")])
192318334Speter
192490286Sobrien(define_insn "*movabshi_2_rex64"
192590286Sobrien  [(set (match_operand:HI 0 "register_operand" "=a,r")
192690286Sobrien        (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
192790286Sobrien  "TARGET_64BIT"
192890286Sobrien  "@
192990286Sobrien   movabs{w}\t{%P1, %0|%0, %P1}
193090286Sobrien   mov{w}\t{%a1, %0|%0, %a1}"
193190286Sobrien  [(set_attr "type" "imov")
193290286Sobrien   (set_attr "modrm" "0,*")
193390286Sobrien   (set_attr "length_address" "8,0")
193490286Sobrien   (set_attr "length_immediate" "0")
193590286Sobrien   (set_attr "memory" "load")
193690286Sobrien   (set_attr "mode" "HI")])
193718334Speter
193890286Sobrien(define_insn "*swaphi_1"
193990286Sobrien  [(set (match_operand:HI 0 "register_operand" "+r")
194090286Sobrien	(match_operand:HI 1 "register_operand" "+r"))
194190286Sobrien   (set (match_dup 1)
194290286Sobrien	(match_dup 0))]
194390286Sobrien  "TARGET_PARTIAL_REG_STALL"
194490286Sobrien  "xchg{w}\t%1, %0"
194590286Sobrien  [(set_attr "type" "imov")
194690286Sobrien   (set_attr "pent_pair" "np")
194790286Sobrien   (set_attr "mode" "HI")
194890286Sobrien   (set_attr "modrm" "0")
194990286Sobrien   (set_attr "ppro_uops" "few")])
195018334Speter
195190286Sobrien(define_insn "*swaphi_2"
195290286Sobrien  [(set (match_operand:HI 0 "register_operand" "+r")
195390286Sobrien	(match_operand:HI 1 "register_operand" "+r"))
195490286Sobrien   (set (match_dup 1)
195590286Sobrien	(match_dup 0))]
195690286Sobrien  "! TARGET_PARTIAL_REG_STALL"
195790286Sobrien  "xchg{l}\t%k1, %k0"
195890286Sobrien  [(set_attr "type" "imov")
195990286Sobrien   (set_attr "pent_pair" "np")
196090286Sobrien   (set_attr "mode" "SI")
196190286Sobrien   (set_attr "modrm" "0")
196290286Sobrien   (set_attr "ppro_uops" "few")])
196318334Speter
196418334Speter(define_expand "movstricthi"
196590286Sobrien  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
196618334Speter	(match_operand:HI 1 "general_operand" ""))]
196790286Sobrien  "! TARGET_PARTIAL_REG_STALL || optimize_size"
196818334Speter{
196918334Speter  /* Don't generate memory->memory moves, go through a register */
197090286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
197190286Sobrien    operands[1] = force_reg (HImode, operands[1]);
197290286Sobrien})
197318334Speter
197490286Sobrien(define_insn "*movstricthi_1"
197590286Sobrien  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
197690286Sobrien	(match_operand:HI 1 "general_operand" "rn,m"))]
197790286Sobrien  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
197890286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
197990286Sobrien  "mov{w}\t{%1, %0|%0, %1}"
198090286Sobrien  [(set_attr "type" "imov")
198190286Sobrien   (set_attr "mode" "HI")])
198252296Sobrien
198390286Sobrien(define_insn "*movstricthi_xor"
198490286Sobrien  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
198590286Sobrien	(match_operand:HI 1 "const0_operand" "i"))
198690286Sobrien   (clobber (reg:CC 17))]
198790286Sobrien  "reload_completed
198890286Sobrien   && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
198990286Sobrien  "xor{w}\t{%0, %0|%0, %0}"
199090286Sobrien  [(set_attr "type" "alu1")
199190286Sobrien   (set_attr "mode" "HI")
199290286Sobrien   (set_attr "length_immediate" "0")])
199352296Sobrien
199490286Sobrien(define_expand "movqi"
199590286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
199690286Sobrien	(match_operand:QI 1 "general_operand" ""))]
199790286Sobrien  ""
199890286Sobrien  "ix86_expand_move (QImode, operands); DONE;")
199918334Speter
200090286Sobrien;; emit_push_insn when it calls move_by_pieces requires an insn to
200190286Sobrien;; "push a byte".  But actually we use pushw, which has the effect
200290286Sobrien;; of rounding the amount pushed up to a halfword.
200318334Speter
200490286Sobrien(define_insn "*pushqi2"
200590286Sobrien  [(set (match_operand:QI 0 "push_operand" "=X,X")
200690286Sobrien	(match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
200790286Sobrien  "!TARGET_64BIT"
200890286Sobrien  "@
200990286Sobrien   push{w}\t{|word ptr }%1
201090286Sobrien   push{w}\t%w1"
201190286Sobrien  [(set_attr "type" "push")
201290286Sobrien   (set_attr "mode" "HI")])
201318334Speter
201490286Sobrien;; For 64BIT abi we always round up to 8 bytes.
201590286Sobrien(define_insn "*pushqi2_rex64"
201690286Sobrien  [(set (match_operand:QI 0 "push_operand" "=X")
2017102802Skan	(match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
201890286Sobrien  "TARGET_64BIT"
201990286Sobrien  "push{q}\t%q1"
202090286Sobrien  [(set_attr "type" "push")
202190286Sobrien   (set_attr "mode" "QI")])
202290286Sobrien
202390286Sobrien;; Situation is quite tricky about when to choose full sized (SImode) move
202490286Sobrien;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
202590286Sobrien;; partial register dependency machines (such as AMD Athlon), where QImode
202690286Sobrien;; moves issue extra dependency and for partial register stalls machines
202790286Sobrien;; that don't use QImode patterns (and QImode move cause stall on the next
202890286Sobrien;; instruction).
202990286Sobrien;;
203090286Sobrien;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
203190286Sobrien;; register stall machines with, where we use QImode instructions, since
203290286Sobrien;; partial register stall can be caused there.  Then we use movzx.
203390286Sobrien(define_insn "*movqi_1"
203490286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
203590286Sobrien	(match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
203690286Sobrien  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
203790286Sobrien{
203890286Sobrien  switch (get_attr_type (insn))
203990286Sobrien    {
204090286Sobrien    case TYPE_IMOVX:
204190286Sobrien      if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
204290286Sobrien	abort ();
204390286Sobrien      return "movz{bl|x}\t{%1, %k0|%k0, %1}";
204490286Sobrien    default:
204590286Sobrien      if (get_attr_mode (insn) == MODE_SI)
204690286Sobrien        return "mov{l}\t{%k1, %k0|%k0, %k1}";
204790286Sobrien      else
204890286Sobrien        return "mov{b}\t{%1, %0|%0, %1}";
204990286Sobrien    }
205090286Sobrien}
205190286Sobrien  [(set (attr "type")
205290286Sobrien     (cond [(and (eq_attr "alternative" "3")
205390286Sobrien		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
205490286Sobrien			  (const_int 0))
205590286Sobrien		      (eq (symbol_ref "TARGET_QIMODE_MATH")
205690286Sobrien			  (const_int 0))))
205790286Sobrien	      (const_string "imov")
205890286Sobrien	    (eq_attr "alternative" "3,5")
205990286Sobrien	      (const_string "imovx")
206090286Sobrien	    (and (ne (symbol_ref "TARGET_MOVX")
206190286Sobrien		     (const_int 0))
206290286Sobrien		 (eq_attr "alternative" "2"))
206390286Sobrien	      (const_string "imovx")
206490286Sobrien	   ]
206590286Sobrien	   (const_string "imov")))
206690286Sobrien   (set (attr "mode")
206790286Sobrien      (cond [(eq_attr "alternative" "3,4,5")
206890286Sobrien	       (const_string "SI")
206990286Sobrien	     (eq_attr "alternative" "6")
207090286Sobrien	       (const_string "QI")
207190286Sobrien	     (eq_attr "type" "imovx")
207290286Sobrien	       (const_string "SI")
207390286Sobrien	     (and (eq_attr "type" "imov")
207490286Sobrien		  (and (eq_attr "alternative" "0,1,2")
207590286Sobrien		       (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
207690286Sobrien			   (const_int 0))))
207790286Sobrien	       (const_string "SI")
207890286Sobrien	     ;; Avoid partial register stalls when not using QImode arithmetic
207990286Sobrien	     (and (eq_attr "type" "imov")
208090286Sobrien		  (and (eq_attr "alternative" "0,1,2")
208190286Sobrien		       (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
208290286Sobrien				(const_int 0))
208390286Sobrien			    (eq (symbol_ref "TARGET_QIMODE_MATH")
208490286Sobrien				(const_int 0)))))
208590286Sobrien	       (const_string "SI")
208690286Sobrien	   ]
208790286Sobrien	   (const_string "QI")))])
208890286Sobrien
208990286Sobrien(define_expand "reload_outqi"
209090286Sobrien  [(parallel [(match_operand:QI 0 "" "=m")
209190286Sobrien              (match_operand:QI 1 "register_operand" "r")
209290286Sobrien              (match_operand:QI 2 "register_operand" "=&q")])]
209318334Speter  ""
209490286Sobrien{
209590286Sobrien  rtx op0, op1, op2;
209690286Sobrien  op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
209718334Speter
209890286Sobrien  if (reg_overlap_mentioned_p (op2, op0))
209990286Sobrien    abort ();
210090286Sobrien  if (! q_regs_operand (op1, QImode))
210190286Sobrien    {
210290286Sobrien      emit_insn (gen_movqi (op2, op1));
210390286Sobrien      op1 = op2;
210490286Sobrien    }
210590286Sobrien  emit_insn (gen_movqi (op0, op1));
210690286Sobrien  DONE;
210790286Sobrien})
210890286Sobrien
210990286Sobrien(define_insn "*swapqi"
211090286Sobrien  [(set (match_operand:QI 0 "register_operand" "+r")
211190286Sobrien	(match_operand:QI 1 "register_operand" "+r"))
211290286Sobrien   (set (match_dup 1)
211390286Sobrien	(match_dup 0))]
211450650Sobrien  ""
211590286Sobrien  "xchg{b}\t%1, %0"
211690286Sobrien  [(set_attr "type" "imov")
211790286Sobrien   (set_attr "pent_pair" "np")
211890286Sobrien   (set_attr "mode" "QI")
211990286Sobrien   (set_attr "modrm" "0")
212090286Sobrien   (set_attr "ppro_uops" "few")])
212190286Sobrien
212290286Sobrien(define_expand "movstrictqi"
212390286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
212490286Sobrien	(match_operand:QI 1 "general_operand" ""))]
212590286Sobrien  "! TARGET_PARTIAL_REG_STALL"
212618334Speter{
212790286Sobrien  /* Don't generate memory->memory moves, go through a register.  */
212890286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
212990286Sobrien    operands[1] = force_reg (QImode, operands[1]);
213090286Sobrien})
213118334Speter
213290286Sobrien(define_insn "*movstrictqi_1"
213390286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
213490286Sobrien	(match_operand:QI 1 "general_operand" "*qn,m"))]
213590286Sobrien  "! TARGET_PARTIAL_REG_STALL
213690286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
213790286Sobrien  "mov{b}\t{%1, %0|%0, %1}"
213890286Sobrien  [(set_attr "type" "imov")
213990286Sobrien   (set_attr "mode" "QI")])
214018334Speter
214190286Sobrien(define_insn "*movstrictqi_xor"
214290286Sobrien  [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
214390286Sobrien	(match_operand:QI 1 "const0_operand" "i"))
214490286Sobrien   (clobber (reg:CC 17))]
214590286Sobrien  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
214690286Sobrien  "xor{b}\t{%0, %0|%0, %0}"
214790286Sobrien  [(set_attr "type" "alu1")
214890286Sobrien   (set_attr "mode" "QI")
214990286Sobrien   (set_attr "length_immediate" "0")])
215018334Speter
215190286Sobrien(define_insn "*movsi_extv_1"
215290286Sobrien  [(set (match_operand:SI 0 "register_operand" "=R")
215390286Sobrien	(sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
215490286Sobrien			 (const_int 8)
215590286Sobrien			 (const_int 8)))]
215618334Speter  ""
215790286Sobrien  "movs{bl|x}\t{%h1, %0|%0, %h1}"
215890286Sobrien  [(set_attr "type" "imovx")
215990286Sobrien   (set_attr "mode" "SI")])
216090286Sobrien
216190286Sobrien(define_insn "*movhi_extv_1"
216290286Sobrien  [(set (match_operand:HI 0 "register_operand" "=R")
216390286Sobrien	(sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
216490286Sobrien			 (const_int 8)
216590286Sobrien			 (const_int 8)))]
216690286Sobrien  ""
216790286Sobrien  "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
216890286Sobrien  [(set_attr "type" "imovx")
216990286Sobrien   (set_attr "mode" "SI")])
217090286Sobrien
217190286Sobrien(define_insn "*movqi_extv_1"
217290286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
217390286Sobrien        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
217490286Sobrien                         (const_int 8)
217590286Sobrien                         (const_int 8)))]
217690286Sobrien  "!TARGET_64BIT"
217718334Speter{
217890286Sobrien  switch (get_attr_type (insn))
217918334Speter    {
218090286Sobrien    case TYPE_IMOVX:
218190286Sobrien      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
218290286Sobrien    default:
218390286Sobrien      return "mov{b}\t{%h1, %0|%0, %h1}";
218418334Speter    }
218590286Sobrien}
218690286Sobrien  [(set (attr "type")
218790286Sobrien     (if_then_else (and (match_operand:QI 0 "register_operand" "")
218890286Sobrien			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
218990286Sobrien			     (ne (symbol_ref "TARGET_MOVX")
219090286Sobrien				 (const_int 0))))
219190286Sobrien	(const_string "imovx")
219290286Sobrien	(const_string "imov")))
219390286Sobrien   (set (attr "mode")
219490286Sobrien     (if_then_else (eq_attr "type" "imovx")
219590286Sobrien	(const_string "SI")
219690286Sobrien	(const_string "QI")))])
219718334Speter
219890286Sobrien(define_insn "*movqi_extv_1_rex64"
219990286Sobrien  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
220090286Sobrien        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
220190286Sobrien                         (const_int 8)
220290286Sobrien                         (const_int 8)))]
220390286Sobrien  "TARGET_64BIT"
220418334Speter{
220590286Sobrien  switch (get_attr_type (insn))
220650650Sobrien    {
220790286Sobrien    case TYPE_IMOVX:
220890286Sobrien      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
220990286Sobrien    default:
221090286Sobrien      return "mov{b}\t{%h1, %0|%0, %h1}";
221150650Sobrien    }
221290286Sobrien}
221390286Sobrien  [(set (attr "type")
221490286Sobrien     (if_then_else (and (match_operand:QI 0 "register_operand" "")
221590286Sobrien			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
221690286Sobrien			     (ne (symbol_ref "TARGET_MOVX")
221790286Sobrien				 (const_int 0))))
221890286Sobrien	(const_string "imovx")
221990286Sobrien	(const_string "imov")))
222090286Sobrien   (set (attr "mode")
222190286Sobrien     (if_then_else (eq_attr "type" "imovx")
222290286Sobrien	(const_string "SI")
222390286Sobrien	(const_string "QI")))])
222418334Speter
222590286Sobrien;; Stores and loads of ax to arbitary constant address.
222690286Sobrien;; We fake an second form of instruction to force reload to load address
222790286Sobrien;; into register when rax is not available
222890286Sobrien(define_insn "*movabsqi_1_rex64"
222990286Sobrien  [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
223090286Sobrien	(match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
223190286Sobrien  "TARGET_64BIT"
223290286Sobrien  "@
223390286Sobrien   movabs{b}\t{%1, %P0|%P0, %1}
223490286Sobrien   mov{b}\t{%1, %a0|%a0, %1}
223590286Sobrien   movabs{b}\t{%1, %a0|%a0, %1}"
223690286Sobrien  [(set_attr "type" "imov")
223790286Sobrien   (set_attr "modrm" "0,*,*")
223890286Sobrien   (set_attr "length_address" "8,0,0")
223990286Sobrien   (set_attr "length_immediate" "0,*,*")
224090286Sobrien   (set_attr "memory" "store")
224190286Sobrien   (set_attr "mode" "QI")])
224218334Speter
224390286Sobrien(define_insn "*movabsqi_2_rex64"
224490286Sobrien  [(set (match_operand:QI 0 "register_operand" "=a,r")
224590286Sobrien        (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
224690286Sobrien  "TARGET_64BIT"
224790286Sobrien  "@
224890286Sobrien   movabs{b}\t{%P1, %0|%0, %P1}
224990286Sobrien   mov{b}\t{%a1, %0|%0, %a1}"
225090286Sobrien  [(set_attr "type" "imov")
225190286Sobrien   (set_attr "modrm" "0,*")
225290286Sobrien   (set_attr "length_address" "8,0")
225390286Sobrien   (set_attr "length_immediate" "0")
225490286Sobrien   (set_attr "memory" "load")
225590286Sobrien   (set_attr "mode" "QI")])
225618334Speter
225790286Sobrien(define_insn "*movsi_extzv_1"
225890286Sobrien  [(set (match_operand:SI 0 "register_operand" "=R")
225990286Sobrien	(zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
226090286Sobrien			 (const_int 8)
226190286Sobrien			 (const_int 8)))]
226290286Sobrien  ""
226390286Sobrien  "movz{bl|x}\t{%h1, %0|%0, %h1}"
226490286Sobrien  [(set_attr "type" "imovx")
226590286Sobrien   (set_attr "mode" "SI")])
226618334Speter
226790286Sobrien(define_insn "*movqi_extzv_2"
226890286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
226990286Sobrien        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
227090286Sobrien				    (const_int 8)
227190286Sobrien				    (const_int 8)) 0))]
227290286Sobrien  "!TARGET_64BIT"
227318334Speter{
227490286Sobrien  switch (get_attr_type (insn))
227518334Speter    {
227690286Sobrien    case TYPE_IMOVX:
227790286Sobrien      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
227890286Sobrien    default:
227990286Sobrien      return "mov{b}\t{%h1, %0|%0, %h1}";
228018334Speter    }
228190286Sobrien}
228290286Sobrien  [(set (attr "type")
228390286Sobrien     (if_then_else (and (match_operand:QI 0 "register_operand" "")
228490286Sobrien			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
228590286Sobrien			     (ne (symbol_ref "TARGET_MOVX")
228690286Sobrien				 (const_int 0))))
228790286Sobrien	(const_string "imovx")
228890286Sobrien	(const_string "imov")))
228990286Sobrien   (set (attr "mode")
229090286Sobrien     (if_then_else (eq_attr "type" "imovx")
229190286Sobrien	(const_string "SI")
229290286Sobrien	(const_string "QI")))])
229318334Speter
229490286Sobrien(define_insn "*movqi_extzv_2_rex64"
229590286Sobrien  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
229690286Sobrien        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
229790286Sobrien				    (const_int 8)
229890286Sobrien				    (const_int 8)) 0))]
229990286Sobrien  "TARGET_64BIT"
230018334Speter{
230190286Sobrien  switch (get_attr_type (insn))
230290286Sobrien    {
230390286Sobrien    case TYPE_IMOVX:
230490286Sobrien      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
230590286Sobrien    default:
230690286Sobrien      return "mov{b}\t{%h1, %0|%0, %h1}";
230790286Sobrien    }
230890286Sobrien}
230990286Sobrien  [(set (attr "type")
231090286Sobrien     (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
231190286Sobrien			(ne (symbol_ref "TARGET_MOVX")
231290286Sobrien			    (const_int 0)))
231390286Sobrien	(const_string "imovx")
231490286Sobrien	(const_string "imov")))
231590286Sobrien   (set (attr "mode")
231690286Sobrien     (if_then_else (eq_attr "type" "imovx")
231790286Sobrien	(const_string "SI")
231890286Sobrien	(const_string "QI")))])
231918334Speter
232090286Sobrien(define_insn "movsi_insv_1"
232190286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
232290286Sobrien			 (const_int 8)
232390286Sobrien			 (const_int 8))
232490286Sobrien	(match_operand:SI 1 "general_operand" "Qmn"))]
232590286Sobrien  "!TARGET_64BIT"
232690286Sobrien  "mov{b}\t{%b1, %h0|%h0, %b1}"
232790286Sobrien  [(set_attr "type" "imov")
232890286Sobrien   (set_attr "mode" "QI")])
232952296Sobrien
233090286Sobrien(define_insn "*movsi_insv_1_rex64"
233190286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
233290286Sobrien			 (const_int 8)
233390286Sobrien			 (const_int 8))
233490286Sobrien	(match_operand:SI 1 "nonmemory_operand" "Qn"))]
233590286Sobrien  "TARGET_64BIT"
233690286Sobrien  "mov{b}\t{%b1, %h0|%h0, %b1}"
233790286Sobrien  [(set_attr "type" "imov")
233890286Sobrien   (set_attr "mode" "QI")])
233918334Speter
234090286Sobrien(define_insn "*movqi_insv_2"
234190286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
234290286Sobrien			 (const_int 8)
234390286Sobrien			 (const_int 8))
234490286Sobrien	(and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
234590286Sobrien			     (const_int 8))
234690286Sobrien		(const_int 255)))]
234790286Sobrien  ""
234890286Sobrien  "mov{b}\t{%h1, %h0|%h0, %h1}"
234990286Sobrien  [(set_attr "type" "imov")
235090286Sobrien   (set_attr "mode" "QI")])
235118334Speter
235290286Sobrien(define_expand "movdi"
235390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
235490286Sobrien	(match_operand:DI 1 "general_operand" ""))]
235590286Sobrien  ""
235690286Sobrien  "ix86_expand_move (DImode, operands); DONE;")
235718334Speter
235890286Sobrien(define_insn "*pushdi"
235990286Sobrien  [(set (match_operand:DI 0 "push_operand" "=<")
236090286Sobrien	(match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
236190286Sobrien  "!TARGET_64BIT"
236290286Sobrien  "#")
236390286Sobrien
236490286Sobrien(define_insn "pushdi2_rex64"
236590286Sobrien  [(set (match_operand:DI 0 "push_operand" "=<,!<")
236690286Sobrien	(match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
236790286Sobrien  "TARGET_64BIT"
236890286Sobrien  "@
236990286Sobrien   push{q}\t%1
237090286Sobrien   #"
237190286Sobrien  [(set_attr "type" "push,multi")
237290286Sobrien   (set_attr "mode" "DI")])
237390286Sobrien
237490286Sobrien;; Convert impossible pushes of immediate to existing instructions.
237590286Sobrien;; First try to get scratch register and go through it.  In case this
237690286Sobrien;; fails, push sign extended lower part first and then overwrite
237790286Sobrien;; upper part by 32bit move.
237890286Sobrien(define_peephole2
237990286Sobrien  [(match_scratch:DI 2 "r")
238090286Sobrien   (set (match_operand:DI 0 "push_operand" "")
238190286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
238290286Sobrien  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
238390286Sobrien   && !x86_64_immediate_operand (operands[1], DImode)"
238490286Sobrien  [(set (match_dup 2) (match_dup 1))
238590286Sobrien   (set (match_dup 0) (match_dup 2))]
238690286Sobrien  "")
238790286Sobrien
238890286Sobrien;; We need to define this as both peepholer and splitter for case
238990286Sobrien;; peephole2 pass is not run.
239090286Sobrien(define_peephole2
239190286Sobrien  [(set (match_operand:DI 0 "push_operand" "")
239290286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
239390286Sobrien  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
239490286Sobrien   && !x86_64_immediate_operand (operands[1], DImode) && 1"
239590286Sobrien  [(set (match_dup 0) (match_dup 1))
239690286Sobrien   (set (match_dup 2) (match_dup 3))]
239790286Sobrien  "split_di (operands + 1, 1, operands + 2, operands + 3);
239890286Sobrien   operands[1] = gen_lowpart (DImode, operands[2]);
239990286Sobrien   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
240090286Sobrien						    GEN_INT (4)));
240190286Sobrien  ")
240290286Sobrien
240390286Sobrien(define_split
240490286Sobrien  [(set (match_operand:DI 0 "push_operand" "")
240590286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
240690286Sobrien  "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
240790286Sobrien   && !symbolic_operand (operands[1], DImode)
240890286Sobrien   && !x86_64_immediate_operand (operands[1], DImode)"
240990286Sobrien  [(set (match_dup 0) (match_dup 1))
241090286Sobrien   (set (match_dup 2) (match_dup 3))]
241190286Sobrien  "split_di (operands + 1, 1, operands + 2, operands + 3);
241290286Sobrien   operands[1] = gen_lowpart (DImode, operands[2]);
241390286Sobrien   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
241490286Sobrien						    GEN_INT (4)));
241590286Sobrien  ")
241690286Sobrien
241790286Sobrien(define_insn "*pushdi2_prologue_rex64"
241890286Sobrien  [(set (match_operand:DI 0 "push_operand" "=<")
241990286Sobrien	(match_operand:DI 1 "general_no_elim_operand" "re*m"))
242090286Sobrien   (clobber (mem:BLK (scratch)))]
242190286Sobrien  "TARGET_64BIT"
242290286Sobrien  "push{q}\t%1"
242390286Sobrien  [(set_attr "type" "push")
242490286Sobrien   (set_attr "mode" "DI")])
242590286Sobrien
242690286Sobrien(define_insn "*popdi1_epilogue_rex64"
242790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
242890286Sobrien	(mem:DI (reg:DI 7)))
242990286Sobrien   (set (reg:DI 7)
243090286Sobrien	(plus:DI (reg:DI 7) (const_int 8)))
243190286Sobrien   (clobber (mem:BLK (scratch)))]
243290286Sobrien  "TARGET_64BIT"
243390286Sobrien  "pop{q}\t%0"
243490286Sobrien  [(set_attr "type" "pop")
243590286Sobrien   (set_attr "mode" "DI")])
243690286Sobrien
243790286Sobrien(define_insn "popdi1"
243890286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
243990286Sobrien	(mem:DI (reg:DI 7)))
244090286Sobrien   (set (reg:DI 7)
244190286Sobrien	(plus:DI (reg:DI 7) (const_int 8)))]
244290286Sobrien  "TARGET_64BIT"
244390286Sobrien  "pop{q}\t%0"
244490286Sobrien  [(set_attr "type" "pop")
244590286Sobrien   (set_attr "mode" "DI")])
244690286Sobrien
244790286Sobrien(define_insn "*movdi_xor_rex64"
244890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
244990286Sobrien	(match_operand:DI 1 "const0_operand" "i"))
245090286Sobrien   (clobber (reg:CC 17))]
245190286Sobrien  "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
245290286Sobrien   && reload_completed"
245390286Sobrien  "xor{l}\t{%k0, %k0|%k0, %k0}"
245490286Sobrien  [(set_attr "type" "alu1")
245590286Sobrien   (set_attr "mode" "SI")
245690286Sobrien   (set_attr "length_immediate" "0")])
245790286Sobrien
245890286Sobrien(define_insn "*movdi_or_rex64"
245990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
246090286Sobrien	(match_operand:DI 1 "const_int_operand" "i"))
246190286Sobrien   (clobber (reg:CC 17))]
246290286Sobrien  "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
246390286Sobrien   && reload_completed
246490286Sobrien   && GET_CODE (operands[1]) == CONST_INT
246590286Sobrien   && INTVAL (operands[1]) == -1"
246618334Speter{
246790286Sobrien  operands[1] = constm1_rtx;
246890286Sobrien  return "or{q}\t{%1, %0|%0, %1}";
246990286Sobrien}
247090286Sobrien  [(set_attr "type" "alu1")
247190286Sobrien   (set_attr "mode" "DI")
247290286Sobrien   (set_attr "length_immediate" "1")])
247318334Speter
247490286Sobrien(define_insn "*movdi_2"
247596294Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
247690286Sobrien	(match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
247790286Sobrien  "!TARGET_64BIT
247890286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
247990286Sobrien  "@
248090286Sobrien   #
248190286Sobrien   #
248290286Sobrien   movq\t{%1, %0|%0, %1}
248390286Sobrien   movq\t{%1, %0|%0, %1}
248490286Sobrien   movq\t{%1, %0|%0, %1}
248590286Sobrien   movdqa\t{%1, %0|%0, %1}
248690286Sobrien   movq\t{%1, %0|%0, %1}"
248790286Sobrien  [(set_attr "type" "*,*,mmx,mmx,sse,sse,sse")
248890286Sobrien   (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
248918334Speter
249090286Sobrien(define_split
249190286Sobrien  [(set (match_operand:DI 0 "push_operand" "")
249290286Sobrien        (match_operand:DI 1 "general_operand" ""))]
249390286Sobrien  "!TARGET_64BIT && reload_completed
249490286Sobrien   && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
249590286Sobrien  [(const_int 0)]
249690286Sobrien  "ix86_split_long_move (operands); DONE;")
249718334Speter
249890286Sobrien;; %%% This multiword shite has got to go.
249990286Sobrien(define_split
250090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
250190286Sobrien        (match_operand:DI 1 "general_operand" ""))]
250290286Sobrien  "!TARGET_64BIT && reload_completed
250390286Sobrien   && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
250490286Sobrien   && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
250590286Sobrien  [(const_int 0)]
250690286Sobrien  "ix86_split_long_move (operands); DONE;")
250718334Speter
250890286Sobrien(define_insn "*movdi_1_rex64"
250990286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!m*y,!*y,!*Y,!m,!*Y")
251090286Sobrien	(match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,m,*Y,*Y,*m"))]
251190286Sobrien  "TARGET_64BIT
251290286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
251390286Sobrien{
251490286Sobrien  switch (get_attr_type (insn))
251590286Sobrien    {
251690286Sobrien    case TYPE_SSE:
251790286Sobrien      if (register_operand (operands[0], DImode)
251890286Sobrien	  && register_operand (operands[1], DImode))
251990286Sobrien	  return "movdqa\t{%1, %0|%0, %1}";
252090286Sobrien      /* FALLTHRU */
252190286Sobrien    case TYPE_MMX:
252290286Sobrien      return "movq\t{%1, %0|%0, %1}";
252390286Sobrien    case TYPE_MULTI:
252490286Sobrien      return "#";
252590286Sobrien    case TYPE_LEA:
252690286Sobrien      return "lea{q}\t{%a1, %0|%0, %a1}";
252790286Sobrien    default:
252890286Sobrien      if (flag_pic && SYMBOLIC_CONST (operands[1]))
252990286Sobrien	abort ();
253090286Sobrien      if (get_attr_mode (insn) == MODE_SI)
253190286Sobrien	return "mov{l}\t{%k1, %k0|%k0, %k1}";
253290286Sobrien      else if (which_alternative == 2)
253390286Sobrien	return "movabs{q}\t{%1, %0|%0, %1}";
253418334Speter      else
253590286Sobrien	return "mov{q}\t{%1, %0|%0, %1}";
253618334Speter    }
253790286Sobrien}
253890286Sobrien  [(set (attr "type")
253990286Sobrien     (cond [(eq_attr "alternative" "5,6")
254090286Sobrien	      (const_string "mmx")
254190286Sobrien	    (eq_attr "alternative" "7,8")
254290286Sobrien	      (const_string "sse")
254390286Sobrien	    (eq_attr "alternative" "4")
254490286Sobrien	      (const_string "multi")
254590286Sobrien 	    (and (ne (symbol_ref "flag_pic") (const_int 0))
254690286Sobrien		 (match_operand:DI 1 "symbolic_operand" ""))
254790286Sobrien	      (const_string "lea")
254890286Sobrien	   ]
254990286Sobrien	   (const_string "imov")))
255090286Sobrien   (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*")
255190286Sobrien   (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*")
255290286Sobrien   (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI")])
255350650Sobrien
255490286Sobrien;; Stores and loads of ax to arbitary constant address.
255590286Sobrien;; We fake an second form of instruction to force reload to load address
255690286Sobrien;; into register when rax is not available
255790286Sobrien(define_insn "*movabsdi_1_rex64"
2558102802Skan  [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2559102802Skan	(match_operand:DI 1 "nonmemory_operand" "a,er"))]
256090286Sobrien  "TARGET_64BIT"
256190286Sobrien  "@
256290286Sobrien   movabs{q}\t{%1, %P0|%P0, %1}
2563102802Skan   mov{q}\t{%1, %a0|%a0, %1}"
256490286Sobrien  [(set_attr "type" "imov")
2565102802Skan   (set_attr "modrm" "0,*")
2566102802Skan   (set_attr "length_address" "8,0")
2567102802Skan   (set_attr "length_immediate" "0,*")
256890286Sobrien   (set_attr "memory" "store")
256990286Sobrien   (set_attr "mode" "DI")])
257018334Speter
257190286Sobrien(define_insn "*movabsdi_2_rex64"
257290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a,r")
257390286Sobrien        (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
257490286Sobrien  "TARGET_64BIT"
257590286Sobrien  "@
257690286Sobrien   movabs{q}\t{%P1, %0|%0, %P1}
257790286Sobrien   mov{q}\t{%a1, %0|%0, %a1}"
257890286Sobrien  [(set_attr "type" "imov")
257990286Sobrien   (set_attr "modrm" "0,*")
258090286Sobrien   (set_attr "length_address" "8,0")
258190286Sobrien   (set_attr "length_immediate" "0")
258290286Sobrien   (set_attr "memory" "load")
258390286Sobrien   (set_attr "mode" "DI")])
258490286Sobrien
258590286Sobrien;; Convert impossible stores of immediate to existing instructions.
258690286Sobrien;; First try to get scratch register and go through it.  In case this
258790286Sobrien;; fails, move by 32bit parts.
258890286Sobrien(define_peephole2
258990286Sobrien  [(match_scratch:DI 2 "r")
259090286Sobrien   (set (match_operand:DI 0 "memory_operand" "")
259190286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
259290286Sobrien  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
259390286Sobrien   && !x86_64_immediate_operand (operands[1], DImode)"
259490286Sobrien  [(set (match_dup 2) (match_dup 1))
259590286Sobrien   (set (match_dup 0) (match_dup 2))]
259652296Sobrien  "")
259750650Sobrien
259890286Sobrien;; We need to define this as both peepholer and splitter for case
259990286Sobrien;; peephole2 pass is not run.
260090286Sobrien(define_peephole2
260190286Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
260290286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
260390286Sobrien  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
260490286Sobrien   && !x86_64_immediate_operand (operands[1], DImode) && 1"
260590286Sobrien  [(set (match_dup 2) (match_dup 3))
260690286Sobrien   (set (match_dup 4) (match_dup 5))]
260790286Sobrien  "split_di (operands, 2, operands + 2, operands + 4);")
260890286Sobrien
260990286Sobrien(define_split
261090286Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
261190286Sobrien        (match_operand:DI 1 "immediate_operand" ""))]
261290286Sobrien  "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
261390286Sobrien   && !symbolic_operand (operands[1], DImode)
261490286Sobrien   && !x86_64_immediate_operand (operands[1], DImode)"
261590286Sobrien  [(set (match_dup 2) (match_dup 3))
261690286Sobrien   (set (match_dup 4) (match_dup 5))]
261790286Sobrien  "split_di (operands, 2, operands + 2, operands + 4);")
261890286Sobrien
261990286Sobrien(define_insn "*swapdi_rex64"
262090286Sobrien  [(set (match_operand:DI 0 "register_operand" "+r")
262190286Sobrien	(match_operand:DI 1 "register_operand" "+r"))
262290286Sobrien   (set (match_dup 1)
262390286Sobrien	(match_dup 0))]
262490286Sobrien  "TARGET_64BIT"
262590286Sobrien  "xchg{q}\t%1, %0"
262690286Sobrien  [(set_attr "type" "imov")
262790286Sobrien   (set_attr "pent_pair" "np")
262890286Sobrien   (set_attr "athlon_decode" "vector")
262990286Sobrien   (set_attr "mode" "DI")
263090286Sobrien   (set_attr "modrm" "0")
263190286Sobrien   (set_attr "ppro_uops" "few")])
263290286Sobrien
263390286Sobrien  
263450650Sobrien(define_expand "movsf"
263590286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "")
263650650Sobrien	(match_operand:SF 1 "general_operand" ""))]
263718334Speter  ""
263890286Sobrien  "ix86_expand_move (SFmode, operands); DONE;")
263990286Sobrien
264090286Sobrien(define_insn "*pushsf"
264190286Sobrien  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
264290286Sobrien	(match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
264390286Sobrien  "!TARGET_64BIT"
264418334Speter{
264590286Sobrien  switch (which_alternative)
264618334Speter    {
264790286Sobrien    case 0:
264890286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
264990286Sobrien      operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
265090286Sobrien      operands[2] = stack_pointer_rtx;
265190286Sobrien      operands[3] = GEN_INT (4);
265290286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
265390286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
265490286Sobrien      else
265590286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
265618334Speter
265790286Sobrien    case 1:
265890286Sobrien      return "push{l}\t%1";
265990286Sobrien    case 2:
266090286Sobrien      return "#";
266190286Sobrien
266290286Sobrien    default:
266390286Sobrien      abort ();
266418334Speter    }
266590286Sobrien}
266690286Sobrien  [(set_attr "type" "multi,push,multi")
266790286Sobrien   (set_attr "mode" "SF,SI,SF")])
266818334Speter
266990286Sobrien(define_insn "*pushsf_rex64"
267090286Sobrien  [(set (match_operand:SF 0 "push_operand" "=X,X,X")
267190286Sobrien	(match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
267290286Sobrien  "TARGET_64BIT"
267318334Speter{
267490286Sobrien  switch (which_alternative)
267590286Sobrien    {
267690286Sobrien    case 0:
267790286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
267890286Sobrien      operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
267990286Sobrien      operands[2] = stack_pointer_rtx;
268090286Sobrien      operands[3] = GEN_INT (8);
268190286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
268290286Sobrien	return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
268390286Sobrien      else
268490286Sobrien	return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
268518334Speter
268690286Sobrien    case 1:
268790286Sobrien      return "push{q}\t%q1";
268818334Speter
268990286Sobrien    case 2:
269090286Sobrien      return "#";
269190286Sobrien
269290286Sobrien    default:
269390286Sobrien      abort ();
269418334Speter    }
269590286Sobrien}
269690286Sobrien  [(set_attr "type" "multi,push,multi")
269790286Sobrien   (set_attr "mode" "SF,DI,SF")])
269818334Speter
269990286Sobrien(define_split
270090286Sobrien  [(set (match_operand:SF 0 "push_operand" "")
270190286Sobrien	(match_operand:SF 1 "memory_operand" ""))]
270290286Sobrien  "reload_completed
270390286Sobrien   && GET_CODE (operands[1]) == MEM
270490286Sobrien   && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
270590286Sobrien   && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
270690286Sobrien  [(set (match_dup 0)
270790286Sobrien	(match_dup 1))]
270890286Sobrien  "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
270918334Speter
271090286Sobrien
271190286Sobrien;; %%% Kill this when call knows how to work this out.
271290286Sobrien(define_split
271390286Sobrien  [(set (match_operand:SF 0 "push_operand" "")
271490286Sobrien	(match_operand:SF 1 "register_operand" ""))]
271590286Sobrien  "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
271690286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
271790286Sobrien   (set (mem:SF (reg:SI 7)) (match_dup 1))])
271890286Sobrien
271990286Sobrien(define_split
272090286Sobrien  [(set (match_operand:SF 0 "push_operand" "")
272190286Sobrien	(match_operand:SF 1 "register_operand" ""))]
272290286Sobrien  "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
272390286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
272490286Sobrien   (set (mem:SF (reg:DI 7)) (match_dup 1))])
272590286Sobrien
272690286Sobrien(define_insn "*movsf_1"
272796294Sobrien  [(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")
272896294Sobrien	(match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf,rm,*y,*y"))]
272990286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
273090286Sobrien   && (reload_in_progress || reload_completed
273190286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
273290286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
273390286Sobrien       || memory_operand (operands[0], SFmode))" 
273490286Sobrien{
273590286Sobrien  switch (which_alternative)
273618334Speter    {
273790286Sobrien    case 0:
273890286Sobrien      if (REG_P (operands[1])
273990286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
274090286Sobrien        return "fstp\t%y0";
274190286Sobrien      else if (STACK_TOP_P (operands[0]))
274290286Sobrien        return "fld%z1\t%y1";
274318334Speter      else
274490286Sobrien        return "fst\t%y0";
274518334Speter
274690286Sobrien    case 1:
274790286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
274890286Sobrien        return "fstp%z0\t%y0";
274990286Sobrien      else
275090286Sobrien        return "fst%z0\t%y0";
275118334Speter
275290286Sobrien    case 2:
275390286Sobrien      switch (standard_80387_constant_p (operands[1]))
275490286Sobrien        {
275590286Sobrien        case 1:
275690286Sobrien	  return "fldz";
275790286Sobrien	case 2:
275890286Sobrien	  return "fld1";
275990286Sobrien	}
276090286Sobrien      abort();
276118334Speter
276290286Sobrien    case 3:
276390286Sobrien    case 4:
276490286Sobrien      return "mov{l}\t{%1, %0|%0, %1}";
276590286Sobrien    case 5:
276696294Sobrien      if (TARGET_SSE2)
276796294Sobrien	return "pxor\t%0, %0";
276896294Sobrien      else
276996294Sobrien	return "xorps\t%0, %0";
277090286Sobrien    case 6:
277190286Sobrien      if (TARGET_PARTIAL_REG_DEPENDENCY)
277290286Sobrien	return "movaps\t{%1, %0|%0, %1}";
277390286Sobrien      else
277490286Sobrien	return "movss\t{%1, %0|%0, %1}";
277590286Sobrien    case 7:
277690286Sobrien    case 8:
277790286Sobrien      return "movss\t{%1, %0|%0, %1}";
277818334Speter
277996294Sobrien    case 9:
278096294Sobrien    case 10:
278196294Sobrien      return "movd\t{%1, %0|%0, %1}";
278296294Sobrien
278396294Sobrien    case 11:
278496294Sobrien      return "movq\t{%1, %0|%0, %1}";
278596294Sobrien
278690286Sobrien    default:
278790286Sobrien      abort();
278890286Sobrien    }
278990286Sobrien}
279096294Sobrien  [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse,sse,sse,mmx,mmx,mmx")
279196294Sobrien   (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF,SI,SI,DI")])
279218334Speter
279390286Sobrien(define_insn "*swapsf"
279490286Sobrien  [(set (match_operand:SF 0 "register_operand" "+f")
279590286Sobrien	(match_operand:SF 1 "register_operand" "+f"))
279618334Speter   (set (match_dup 1)
279718334Speter	(match_dup 0))]
279890286Sobrien  "reload_completed || !TARGET_SSE"
279918334Speter{
280018334Speter  if (STACK_TOP_P (operands[0]))
280190286Sobrien    return "fxch\t%1";
280218334Speter  else
280390286Sobrien    return "fxch\t%0";
280490286Sobrien}
280590286Sobrien  [(set_attr "type" "fxch")
280690286Sobrien   (set_attr "mode" "SF")])
280718334Speter
280890286Sobrien(define_expand "movdf"
280990286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "")
281090286Sobrien	(match_operand:DF 1 "general_operand" ""))]
281190286Sobrien  ""
281290286Sobrien  "ix86_expand_move (DFmode, operands); DONE;")
281352296Sobrien
281490286Sobrien;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
281590286Sobrien;; Size of pushdf using integer insturctions is 2+2*memory operand size
281690286Sobrien;; On the average, pushdf using integers can be still shorter.  Allow this
281790286Sobrien;; pattern for optimize_size too.
281890286Sobrien
281990286Sobrien(define_insn "*pushdf_nointeger"
282090286Sobrien  [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
282190286Sobrien	(match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
282290286Sobrien  "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
282318334Speter{
282490286Sobrien  switch (which_alternative)
282518334Speter    {
282690286Sobrien    case 0:
282790286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
282890286Sobrien      operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
282990286Sobrien      operands[2] = stack_pointer_rtx;
283090286Sobrien      operands[3] = GEN_INT (8);
283190286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
283290286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
283390286Sobrien      else
283490286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
283518334Speter
283690286Sobrien    case 1:
283790286Sobrien    case 2:
283890286Sobrien    case 3:
283990286Sobrien      return "#";
284018334Speter
284190286Sobrien    default:
284290286Sobrien      abort ();
284390286Sobrien    }
284490286Sobrien}
284590286Sobrien  [(set_attr "type" "multi")
284690286Sobrien   (set_attr "mode" "DF,SI,SI,DF")])
284718334Speter
284890286Sobrien(define_insn "*pushdf_integer"
284990286Sobrien  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
285090286Sobrien	(match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
285190286Sobrien  "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
285290286Sobrien{
285390286Sobrien  switch (which_alternative)
285490286Sobrien    {
285590286Sobrien    case 0:
285690286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
285790286Sobrien      operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
285890286Sobrien      operands[2] = stack_pointer_rtx;
285990286Sobrien      operands[3] = GEN_INT (8);
286090286Sobrien      if (TARGET_64BIT)
286190286Sobrien	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
286290286Sobrien	  return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
286390286Sobrien	else
286490286Sobrien	  return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
286518334Speter      else
286690286Sobrien	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
286790286Sobrien	  return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
286890286Sobrien	else
286990286Sobrien	  return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
287018334Speter
287150650Sobrien
287290286Sobrien    case 1:
287390286Sobrien    case 2:
287490286Sobrien      return "#";
287550650Sobrien
287690286Sobrien    default:
287790286Sobrien      abort ();
287890286Sobrien    }
287990286Sobrien}
288090286Sobrien  [(set_attr "type" "multi")
288190286Sobrien   (set_attr "mode" "DF,SI,DF")])
288218334Speter
288390286Sobrien;; %%% Kill this when call knows how to work this out.
288452296Sobrien(define_split
288552296Sobrien  [(set (match_operand:DF 0 "push_operand" "")
288690286Sobrien	(match_operand:DF 1 "register_operand" ""))]
288790286Sobrien  "!TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
288890286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
288990286Sobrien   (set (mem:DF (reg:SI 7)) (match_dup 1))]
289052296Sobrien  "")
289150650Sobrien
289290286Sobrien(define_split
289390286Sobrien  [(set (match_operand:DF 0 "push_operand" "")
289490286Sobrien	(match_operand:DF 1 "register_operand" ""))]
289590286Sobrien  "TARGET_64BIT && reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
289690286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
289790286Sobrien   (set (mem:DF (reg:DI 7)) (match_dup 1))]
289890286Sobrien  "")
289990286Sobrien
290090286Sobrien(define_split
290190286Sobrien  [(set (match_operand:DF 0 "push_operand" "")
290250650Sobrien	(match_operand:DF 1 "general_operand" ""))]
290390286Sobrien  "reload_completed"
290490286Sobrien  [(const_int 0)]
290590286Sobrien  "ix86_split_long_move (operands); DONE;")
290690286Sobrien
290790286Sobrien;; Moving is usually shorter when only FP registers are used. This separate
290890286Sobrien;; movdf pattern avoids the use of integer registers for FP operations
290990286Sobrien;; when optimizing for size.
291090286Sobrien
291190286Sobrien(define_insn "*movdf_nointeger"
291290286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
291390286Sobrien	(match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,H,Y#f,YHm#f,Y#f"))]
291490286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
291590286Sobrien   && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
291690286Sobrien   && (reload_in_progress || reload_completed
291790286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
291890286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
291990286Sobrien       || memory_operand (operands[0], DFmode))" 
292018334Speter{
292190286Sobrien  switch (which_alternative)
292218334Speter    {
292390286Sobrien    case 0:
292490286Sobrien      if (REG_P (operands[1])
292590286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
292690286Sobrien        return "fstp\t%y0";
292790286Sobrien      else if (STACK_TOP_P (operands[0]))
292890286Sobrien        return "fld%z1\t%y1";
292990286Sobrien      else
293090286Sobrien        return "fst\t%y0";
293118334Speter
293290286Sobrien    case 1:
293390286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
293490286Sobrien        return "fstp%z0\t%y0";
293590286Sobrien      else
293690286Sobrien        return "fst%z0\t%y0";
293718334Speter
293890286Sobrien    case 2:
293990286Sobrien      switch (standard_80387_constant_p (operands[1]))
294090286Sobrien        {
294190286Sobrien        case 1:
294290286Sobrien	  return "fldz";
294390286Sobrien	case 2:
294490286Sobrien	  return "fld1";
294590286Sobrien	}
294690286Sobrien      abort();
294718334Speter
294890286Sobrien    case 3:
294990286Sobrien    case 4:
295090286Sobrien      return "#";
295190286Sobrien    case 5:
295290286Sobrien      return "pxor\t%0, %0";
295390286Sobrien    case 6:
295490286Sobrien      if (TARGET_PARTIAL_REG_DEPENDENCY)
295590286Sobrien	return "movapd\t{%1, %0|%0, %1}";
295690286Sobrien      else
295790286Sobrien	return "movsd\t{%1, %0|%0, %1}";
295890286Sobrien    case 7:
295990286Sobrien    case 8:
296090286Sobrien        return "movsd\t{%1, %0|%0, %1}";
296118334Speter
296290286Sobrien    default:
296390286Sobrien      abort();
296418334Speter    }
296590286Sobrien}
296690286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
296790286Sobrien   (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
296818334Speter
296990286Sobrien(define_insn "*movdf_integer"
297090286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
297190286Sobrien	(match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,H,Y#rf,Ym#rf,Y#rf"))]
297290286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
297390286Sobrien   && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
297490286Sobrien   && (reload_in_progress || reload_completed
297590286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
297690286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
297790286Sobrien       || memory_operand (operands[0], DFmode))" 
297890286Sobrien{
297990286Sobrien  switch (which_alternative)
298018334Speter    {
298190286Sobrien    case 0:
298290286Sobrien      if (REG_P (operands[1])
298390286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
298490286Sobrien        return "fstp\t%y0";
298590286Sobrien      else if (STACK_TOP_P (operands[0]))
298690286Sobrien        return "fld%z1\t%y1";
298718334Speter      else
298890286Sobrien        return "fst\t%y0";
298918334Speter
299090286Sobrien    case 1:
299190286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
299290286Sobrien        return "fstp%z0\t%y0";
299390286Sobrien      else
299490286Sobrien        return "fst%z0\t%y0";
299518334Speter
299690286Sobrien    case 2:
299790286Sobrien      switch (standard_80387_constant_p (operands[1]))
299890286Sobrien        {
299990286Sobrien        case 1:
300090286Sobrien	  return "fldz";
300190286Sobrien	case 2:
300290286Sobrien	  return "fld1";
300390286Sobrien	}
300490286Sobrien      abort();
300518334Speter
300690286Sobrien    case 3:
300790286Sobrien    case 4:
300890286Sobrien      return "#";
300918334Speter
301090286Sobrien    case 5:
301190286Sobrien      return "pxor\t%0, %0";
301290286Sobrien    case 6:
301390286Sobrien      if (TARGET_PARTIAL_REG_DEPENDENCY)
301490286Sobrien	return "movapd\t{%1, %0|%0, %1}";
301590286Sobrien      else
301690286Sobrien	return "movsd\t{%1, %0|%0, %1}";
301790286Sobrien    case 7:
301890286Sobrien    case 8:
301990286Sobrien      return "movsd\t{%1, %0|%0, %1}";
302018334Speter
302190286Sobrien    default:
302290286Sobrien      abort();
302390286Sobrien    }
302490286Sobrien}
302590286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse,sse,sse")
302690286Sobrien   (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
302718334Speter
302890286Sobrien(define_split
302990286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "")
303090286Sobrien	(match_operand:DF 1 "general_operand" ""))]
303190286Sobrien  "reload_completed
303290286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
303390286Sobrien   && ! (ANY_FP_REG_P (operands[0]) || 
303490286Sobrien	 (GET_CODE (operands[0]) == SUBREG
303590286Sobrien	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
303690286Sobrien   && ! (ANY_FP_REG_P (operands[1]) || 
303790286Sobrien	 (GET_CODE (operands[1]) == SUBREG
303890286Sobrien	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
303990286Sobrien  [(const_int 0)]
304090286Sobrien  "ix86_split_long_move (operands); DONE;")
304150650Sobrien
304290286Sobrien(define_insn "*swapdf"
304390286Sobrien  [(set (match_operand:DF 0 "register_operand" "+f")
304490286Sobrien	(match_operand:DF 1 "register_operand" "+f"))
304518334Speter   (set (match_dup 1)
304618334Speter	(match_dup 0))]
304790286Sobrien  "reload_completed || !TARGET_SSE2"
304818334Speter{
304918334Speter  if (STACK_TOP_P (operands[0]))
305090286Sobrien    return "fxch\t%1";
305118334Speter  else
305290286Sobrien    return "fxch\t%0";
305390286Sobrien}
305490286Sobrien  [(set_attr "type" "fxch")
305590286Sobrien   (set_attr "mode" "DF")])
305618334Speter
305790286Sobrien(define_expand "movxf"
305890286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "")
305990286Sobrien	(match_operand:XF 1 "general_operand" ""))]
306090286Sobrien  "!TARGET_64BIT"
306190286Sobrien  "ix86_expand_move (XFmode, operands); DONE;")
306290286Sobrien
306390286Sobrien(define_expand "movtf"
306490286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "")
306590286Sobrien	(match_operand:TF 1 "general_operand" ""))]
306690286Sobrien  ""
306790286Sobrien  "ix86_expand_move (TFmode, operands); DONE;")
306890286Sobrien
306990286Sobrien;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
307090286Sobrien;; Size of pushdf using integer insturctions is 3+3*memory operand size
307190286Sobrien;; Pushing using integer instructions is longer except for constants
307290286Sobrien;; and direct memory references.
307390286Sobrien;; (assuming that any given constant is pushed only once, but this ought to be
307490286Sobrien;;  handled elsewhere).
307590286Sobrien
307690286Sobrien(define_insn "*pushxf_nointeger"
307790286Sobrien  [(set (match_operand:XF 0 "push_operand" "=X,X,X")
307890286Sobrien	(match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
307990286Sobrien  "!TARGET_64BIT && optimize_size"
308018334Speter{
308190286Sobrien  switch (which_alternative)
308218334Speter    {
308390286Sobrien    case 0:
308490286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
308590286Sobrien      operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
308690286Sobrien      operands[2] = stack_pointer_rtx;
308790286Sobrien      operands[3] = GEN_INT (12);
308890286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
308990286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
309090286Sobrien      else
309190286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
309218334Speter
309390286Sobrien    case 1:
309490286Sobrien    case 2:
309590286Sobrien      return "#";
309618334Speter
309790286Sobrien    default:
309890286Sobrien      abort ();
309990286Sobrien    }
310090286Sobrien}
310190286Sobrien  [(set_attr "type" "multi")
310290286Sobrien   (set_attr "mode" "XF,SI,SI")])
310350650Sobrien
310490286Sobrien(define_insn "*pushtf_nointeger"
310590286Sobrien  [(set (match_operand:TF 0 "push_operand" "=<,<,<")
310690286Sobrien	(match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
310790286Sobrien  "optimize_size"
310890286Sobrien{
310990286Sobrien  switch (which_alternative)
311090286Sobrien    {
311190286Sobrien    case 0:
311290286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
311390286Sobrien      operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
311490286Sobrien      operands[2] = stack_pointer_rtx;
311590286Sobrien      operands[3] = GEN_INT (16);
311690286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
311790286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
311890286Sobrien      else
311990286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
312018334Speter
312190286Sobrien    case 1:
312290286Sobrien    case 2:
312390286Sobrien      return "#";
312490286Sobrien
312590286Sobrien    default:
312690286Sobrien      abort ();
312718334Speter    }
312890286Sobrien}
312990286Sobrien  [(set_attr "type" "multi")
313090286Sobrien   (set_attr "mode" "XF,SI,SI")])
313150650Sobrien
313290286Sobrien(define_insn "*pushxf_integer"
313390286Sobrien  [(set (match_operand:XF 0 "push_operand" "=<,<")
313490286Sobrien	(match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
313590286Sobrien  "!TARGET_64BIT && !optimize_size"
313690286Sobrien{
313790286Sobrien  switch (which_alternative)
313890286Sobrien    {
313990286Sobrien    case 0:
314090286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
314190286Sobrien      operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
314290286Sobrien      operands[2] = stack_pointer_rtx;
314390286Sobrien      operands[3] = GEN_INT (12);
314490286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
314590286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
314690286Sobrien      else
314790286Sobrien	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
314850650Sobrien
314990286Sobrien    case 1:
315090286Sobrien      return "#";
315118334Speter
315290286Sobrien    default:
315390286Sobrien      abort ();
315490286Sobrien    }
315590286Sobrien}
315690286Sobrien  [(set_attr "type" "multi")
315790286Sobrien   (set_attr "mode" "XF,SI")])
315890286Sobrien
315990286Sobrien(define_insn "*pushtf_integer"
316090286Sobrien  [(set (match_operand:TF 0 "push_operand" "=<,<")
316190286Sobrien	(match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
316290286Sobrien  "!optimize_size"
316390286Sobrien{
316490286Sobrien  switch (which_alternative)
316590286Sobrien    {
316690286Sobrien    case 0:
316790286Sobrien      /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
316890286Sobrien      operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
316990286Sobrien      operands[2] = stack_pointer_rtx;
317090286Sobrien      operands[3] = GEN_INT (16);
317190286Sobrien      if (TARGET_64BIT)
317290286Sobrien	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
317390286Sobrien	  return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
317490286Sobrien	else
317590286Sobrien	  return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
317690286Sobrien      else
317790286Sobrien	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
317890286Sobrien	  return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
317990286Sobrien	else
318090286Sobrien	  return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
318190286Sobrien
318290286Sobrien    case 1:
318390286Sobrien      return "#";
318490286Sobrien
318590286Sobrien    default:
318690286Sobrien      abort ();
318790286Sobrien    }
318890286Sobrien}
318990286Sobrien  [(set_attr "type" "multi")
319090286Sobrien   (set_attr "mode" "XF,SI")])
319190286Sobrien
319252296Sobrien(define_split
319390286Sobrien  [(set (match_operand 0 "push_operand" "")
319490286Sobrien	(match_operand 1 "general_operand" ""))]
319590286Sobrien  "reload_completed
319690286Sobrien   && (GET_MODE (operands[0]) == XFmode
319790286Sobrien       || GET_MODE (operands[0]) == TFmode
319890286Sobrien       || GET_MODE (operands[0]) == DFmode)
319990286Sobrien   && (!REG_P (operands[1]) || !ANY_FP_REGNO_P (REGNO (operands[1])))"
320090286Sobrien  [(const_int 0)]
320190286Sobrien  "ix86_split_long_move (operands); DONE;")
320290286Sobrien
320390286Sobrien(define_split
320452296Sobrien  [(set (match_operand:XF 0 "push_operand" "")
320590286Sobrien	(match_operand:XF 1 "register_operand" ""))]
320690286Sobrien  "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
320790286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
320890286Sobrien   (set (mem:XF (reg:SI 7)) (match_dup 1))])
320950650Sobrien
321090286Sobrien(define_split
321190286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
321290286Sobrien	(match_operand:TF 1 "register_operand" ""))]
321390286Sobrien  "!TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
321490286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
321590286Sobrien   (set (mem:TF (reg:SI 7)) (match_dup 1))])
321690286Sobrien
321790286Sobrien(define_split
321890286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
321990286Sobrien	(match_operand:TF 1 "register_operand" ""))]
322090286Sobrien  "TARGET_64BIT && ANY_FP_REGNO_P (REGNO (operands[1]))"
322190286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
322290286Sobrien   (set (mem:TF (reg:DI 7)) (match_dup 1))])
322390286Sobrien
322490286Sobrien;; Do not use integer registers when optimizing for size
322590286Sobrien(define_insn "*movxf_nointeger"
322690286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
322790286Sobrien	(match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
322890286Sobrien  "!TARGET_64BIT
322990286Sobrien   && optimize_size
323090286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
323190286Sobrien   && (reload_in_progress || reload_completed
323290286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
323390286Sobrien       || memory_operand (operands[0], XFmode))" 
323418334Speter{
323590286Sobrien  switch (which_alternative)
323618334Speter    {
323790286Sobrien    case 0:
323890286Sobrien      if (REG_P (operands[1])
323990286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
324090286Sobrien        return "fstp\t%y0";
324190286Sobrien      else if (STACK_TOP_P (operands[0]))
324290286Sobrien        return "fld%z1\t%y1";
324390286Sobrien      else
324490286Sobrien        return "fst\t%y0";
324590286Sobrien
324690286Sobrien    case 1:
324790286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
324890286Sobrien	 we need one, follow the store with a load.  */
324990286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
325090286Sobrien        return "fstp%z0\t%y0\;fld%z0\t%y0";
325190286Sobrien      else
325290286Sobrien        return "fstp%z0\t%y0";
325390286Sobrien
325490286Sobrien    case 2:
325590286Sobrien      switch (standard_80387_constant_p (operands[1]))
325690286Sobrien        {
325790286Sobrien        case 1:
325890286Sobrien	  return "fldz";
325990286Sobrien	case 2:
326090286Sobrien	  return "fld1";
326190286Sobrien	}
326290286Sobrien      break;
326390286Sobrien
326490286Sobrien    case 3: case 4:
326590286Sobrien      return "#";
326650650Sobrien    }
326790286Sobrien  abort();
326890286Sobrien}
326990286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
327090286Sobrien   (set_attr "mode" "XF,XF,XF,SI,SI")])
327118334Speter
327290286Sobrien(define_insn "*movtf_nointeger"
327390286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
327490286Sobrien	(match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
327590286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
327690286Sobrien   && optimize_size
327790286Sobrien   && (reload_in_progress || reload_completed
327890286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
327990286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
328090286Sobrien       || memory_operand (operands[0], TFmode))" 
328190286Sobrien{
328290286Sobrien  switch (which_alternative)
328350650Sobrien    {
328490286Sobrien    case 0:
328590286Sobrien      if (REG_P (operands[1])
328690286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
328790286Sobrien        return "fstp\t%y0";
328890286Sobrien      else if (STACK_TOP_P (operands[0]))
328990286Sobrien        return "fld%z1\t%y1";
329090286Sobrien      else
329190286Sobrien        return "fst\t%y0";
329218334Speter
329390286Sobrien    case 1:
329490286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
329590286Sobrien	 we need one, follow the store with a load.  */
329690286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
329790286Sobrien        return "fstp%z0\t%y0\;fld%z0\t%y0";
329890286Sobrien      else
329990286Sobrien        return "fstp%z0\t%y0";
330018334Speter
330190286Sobrien    case 2:
330290286Sobrien      switch (standard_80387_constant_p (operands[1]))
330390286Sobrien        {
330490286Sobrien        case 1:
330590286Sobrien	  return "fldz";
330690286Sobrien	case 2:
330790286Sobrien	  return "fld1";
330890286Sobrien	}
330990286Sobrien      break;
331018334Speter
331190286Sobrien    case 3: case 4:
331290286Sobrien      return "#";
331390286Sobrien    }
331490286Sobrien  abort();
331590286Sobrien}
331690286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
331790286Sobrien   (set_attr "mode" "XF,XF,XF,SI,SI")])
331818334Speter
331990286Sobrien(define_insn "*movxf_integer"
332090286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
332190286Sobrien	(match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
332290286Sobrien  "!TARGET_64BIT
332390286Sobrien   && !optimize_size
332490286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
332590286Sobrien   && (reload_in_progress || reload_completed
332690286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
332790286Sobrien       || memory_operand (operands[0], XFmode))" 
332890286Sobrien{
332990286Sobrien  switch (which_alternative)
333018334Speter    {
333190286Sobrien    case 0:
333290286Sobrien      if (REG_P (operands[1])
333390286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
333490286Sobrien        return "fstp\t%y0";
333590286Sobrien      else if (STACK_TOP_P (operands[0]))
333690286Sobrien        return "fld%z1\t%y1";
333718334Speter      else
333890286Sobrien        return "fst\t%y0";
333918334Speter
334090286Sobrien    case 1:
334190286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
334290286Sobrien	 we need one, follow the store with a load.  */
334390286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
334490286Sobrien        return "fstp%z0\t%y0\;fld%z0\t%y0";
334590286Sobrien      else
334690286Sobrien        return "fstp%z0\t%y0";
334718334Speter
334890286Sobrien    case 2:
334990286Sobrien      switch (standard_80387_constant_p (operands[1]))
335090286Sobrien        {
335190286Sobrien        case 1:
335290286Sobrien	  return "fldz";
335390286Sobrien	case 2:
335490286Sobrien	  return "fld1";
335590286Sobrien	}
335690286Sobrien      break;
335718334Speter
335890286Sobrien    case 3: case 4:
335990286Sobrien      return "#";
336018334Speter    }
336190286Sobrien  abort();
336290286Sobrien}
336390286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
336490286Sobrien   (set_attr "mode" "XF,XF,XF,SI,SI")])
336518334Speter
336690286Sobrien(define_insn "*movtf_integer"
336790286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
336890286Sobrien	(match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
336990286Sobrien  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
337090286Sobrien   && !optimize_size
337190286Sobrien   && (reload_in_progress || reload_completed
337290286Sobrien       || GET_CODE (operands[1]) != CONST_DOUBLE
337390286Sobrien       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
337490286Sobrien       || memory_operand (operands[0], TFmode))" 
337590286Sobrien{
337690286Sobrien  switch (which_alternative)
337790286Sobrien    {
337890286Sobrien    case 0:
337990286Sobrien      if (REG_P (operands[1])
338090286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
338190286Sobrien        return "fstp\t%y0";
338290286Sobrien      else if (STACK_TOP_P (operands[0]))
338390286Sobrien        return "fld%z1\t%y1";
338490286Sobrien      else
338590286Sobrien        return "fst\t%y0";
338618334Speter
338790286Sobrien    case 1:
338890286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
338990286Sobrien	 we need one, follow the store with a load.  */
339090286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
339190286Sobrien        return "fstp%z0\t%y0\;fld%z0\t%y0";
339290286Sobrien      else
339390286Sobrien        return "fstp%z0\t%y0";
339418334Speter
339590286Sobrien    case 2:
339690286Sobrien      switch (standard_80387_constant_p (operands[1]))
339790286Sobrien        {
339890286Sobrien        case 1:
339990286Sobrien	  return "fldz";
340090286Sobrien	case 2:
340190286Sobrien	  return "fld1";
340290286Sobrien	}
340390286Sobrien      break;
340418334Speter
340590286Sobrien    case 3: case 4:
340690286Sobrien      return "#";
340790286Sobrien    }
340890286Sobrien  abort();
340990286Sobrien}
341090286Sobrien  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
341190286Sobrien   (set_attr "mode" "XF,XF,XF,SI,SI")])
341218334Speter
341390286Sobrien(define_split
341490286Sobrien  [(set (match_operand 0 "nonimmediate_operand" "")
341590286Sobrien	(match_operand 1 "general_operand" ""))]
341690286Sobrien  "reload_completed
341790286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
341890286Sobrien   && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
341990286Sobrien   && ! (ANY_FP_REG_P (operands[0]) || 
342090286Sobrien	 (GET_CODE (operands[0]) == SUBREG
342190286Sobrien	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
342290286Sobrien   && ! (ANY_FP_REG_P (operands[1]) || 
342390286Sobrien	 (GET_CODE (operands[1]) == SUBREG
342490286Sobrien	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
342590286Sobrien  [(const_int 0)]
342690286Sobrien  "ix86_split_long_move (operands); DONE;")
342718334Speter
342890286Sobrien(define_split
342990286Sobrien  [(set (match_operand 0 "register_operand" "")
343090286Sobrien	(match_operand 1 "memory_operand" ""))]
343190286Sobrien  "reload_completed
343290286Sobrien   && GET_CODE (operands[1]) == MEM
343390286Sobrien   && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
343490286Sobrien       || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
343590286Sobrien   && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
343690286Sobrien   && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
343790286Sobrien   && (!(SSE_REG_P (operands[0]) || 
343890286Sobrien	 (GET_CODE (operands[0]) == SUBREG
343990286Sobrien	  && SSE_REG_P (SUBREG_REG (operands[0]))))
344090286Sobrien       || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
344190286Sobrien   && (!(FP_REG_P (operands[0]) || 
344290286Sobrien	 (GET_CODE (operands[0]) == SUBREG
344390286Sobrien	  && FP_REG_P (SUBREG_REG (operands[0]))))
344490286Sobrien       || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
344590286Sobrien  [(set (match_dup 0)
344690286Sobrien	(match_dup 1))]
344790286Sobrien  "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
344890286Sobrien
344990286Sobrien(define_insn "swapxf"
345090286Sobrien  [(set (match_operand:XF 0 "register_operand" "+f")
345190286Sobrien	(match_operand:XF 1 "register_operand" "+f"))
345218334Speter   (set (match_dup 1)
345318334Speter	(match_dup 0))]
345418334Speter  ""
345518334Speter{
345618334Speter  if (STACK_TOP_P (operands[0]))
345790286Sobrien    return "fxch\t%1";
345818334Speter  else
345990286Sobrien    return "fxch\t%0";
346090286Sobrien}
346190286Sobrien  [(set_attr "type" "fxch")
346290286Sobrien   (set_attr "mode" "XF")])
346318334Speter
346490286Sobrien(define_insn "swaptf"
346590286Sobrien  [(set (match_operand:TF 0 "register_operand" "+f")
346690286Sobrien	(match_operand:TF 1 "register_operand" "+f"))
346790286Sobrien   (set (match_dup 1)
346890286Sobrien	(match_dup 0))]
346918334Speter  ""
347018334Speter{
347190286Sobrien  if (STACK_TOP_P (operands[0]))
347290286Sobrien    return "fxch\t%1";
347390286Sobrien  else
347490286Sobrien    return "fxch\t%0";
347590286Sobrien}
347690286Sobrien  [(set_attr "type" "fxch")
347790286Sobrien   (set_attr "mode" "XF")])
347818334Speter
347990286Sobrien;; Zero extension instructions
348018334Speter
348152296Sobrien(define_expand "zero_extendhisi2"
348252296Sobrien  [(set (match_operand:SI 0 "register_operand" "")
348390286Sobrien     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
348452296Sobrien  ""
348590286Sobrien{
348690286Sobrien  if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
348718334Speter    {
348890286Sobrien      operands[1] = force_reg (HImode, operands[1]);
348990286Sobrien      emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
349090286Sobrien      DONE;
349118334Speter    }
349290286Sobrien})
349318334Speter
349490286Sobrien(define_insn "zero_extendhisi2_and"
349590286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
349690286Sobrien     (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
349790286Sobrien   (clobber (reg:CC 17))]
349890286Sobrien  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
349990286Sobrien  "#"
350090286Sobrien  [(set_attr "type" "alu1")
350190286Sobrien   (set_attr "mode" "SI")])
350250650Sobrien
350350650Sobrien(define_split
350450650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
350590286Sobrien	(zero_extend:SI (match_operand:HI 1 "register_operand" "")))
350690286Sobrien   (clobber (reg:CC 17))]
350790286Sobrien  "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
350890286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
350990286Sobrien	      (clobber (reg:CC 17))])]
351090286Sobrien  "")
351150650Sobrien
351290286Sobrien(define_insn "*zero_extendhisi2_movzwl"
351390286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
351490286Sobrien     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
351590286Sobrien  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
351690286Sobrien  "movz{wl|x}\t{%1, %0|%0, %1}"
351790286Sobrien  [(set_attr "type" "imovx")
351890286Sobrien   (set_attr "mode" "SI")])
351950650Sobrien
352052296Sobrien(define_expand "zero_extendqihi2"
352190286Sobrien  [(parallel
352290286Sobrien    [(set (match_operand:HI 0 "register_operand" "")
352390286Sobrien       (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
352490286Sobrien     (clobber (reg:CC 17))])]
352552296Sobrien  ""
352652296Sobrien  "")
352752296Sobrien
352890286Sobrien(define_insn "*zero_extendqihi2_and"
352990286Sobrien  [(set (match_operand:HI 0 "register_operand" "=r,?&q")
353090286Sobrien     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
353190286Sobrien   (clobber (reg:CC 17))]
353290286Sobrien  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
353390286Sobrien  "#"
353490286Sobrien  [(set_attr "type" "alu1")
353590286Sobrien   (set_attr "mode" "HI")])
353652296Sobrien
353790286Sobrien(define_insn "*zero_extendqihi2_movzbw_and"
353890286Sobrien  [(set (match_operand:HI 0 "register_operand" "=r,r")
353990286Sobrien     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
354090286Sobrien   (clobber (reg:CC 17))]
354190286Sobrien  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
354290286Sobrien  "#"
354390286Sobrien  [(set_attr "type" "imovx,alu1")
354490286Sobrien   (set_attr "mode" "HI")])
354552296Sobrien
354690286Sobrien(define_insn "*zero_extendqihi2_movzbw"
354790286Sobrien  [(set (match_operand:HI 0 "register_operand" "=r")
354890286Sobrien     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
354990286Sobrien  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
355090286Sobrien  "movz{bw|x}\t{%1, %0|%0, %1}"
355190286Sobrien  [(set_attr "type" "imovx")
355290286Sobrien   (set_attr "mode" "HI")])
355350650Sobrien
355490286Sobrien;; For the movzbw case strip only the clobber
355550650Sobrien(define_split
355650650Sobrien  [(set (match_operand:HI 0 "register_operand" "")
355790286Sobrien	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
355890286Sobrien   (clobber (reg:CC 17))]
355990286Sobrien  "reload_completed 
356090286Sobrien   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
356190286Sobrien   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
356290286Sobrien  [(set (match_operand:HI 0 "register_operand" "")
356390286Sobrien	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
356450650Sobrien
356590286Sobrien;; When source and destination does not overlap, clear destination
356690286Sobrien;; first and then do the movb
356750650Sobrien(define_split
356850650Sobrien  [(set (match_operand:HI 0 "register_operand" "")
356990286Sobrien	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
357090286Sobrien   (clobber (reg:CC 17))]
357190286Sobrien  "reload_completed
357290286Sobrien   && ANY_QI_REG_P (operands[0])
357390286Sobrien   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
357490286Sobrien   && !reg_overlap_mentioned_p (operands[0], operands[1])"
357590286Sobrien  [(set (match_dup 0) (const_int 0))
357690286Sobrien   (set (strict_low_part (match_dup 2)) (match_dup 1))]
357790286Sobrien  "operands[2] = gen_lowpart (QImode, operands[0]);")
357850650Sobrien
357990286Sobrien;; Rest is handled by single and.
358050650Sobrien(define_split
358150650Sobrien  [(set (match_operand:HI 0 "register_operand" "")
358290286Sobrien	(zero_extend:HI (match_operand:QI 1 "register_operand" "")))
358390286Sobrien   (clobber (reg:CC 17))]
358490286Sobrien  "reload_completed
358590286Sobrien   && true_regnum (operands[0]) == true_regnum (operands[1])"
358690286Sobrien  [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
358790286Sobrien	      (clobber (reg:CC 17))])]
358890286Sobrien  "")
358950650Sobrien
359052296Sobrien(define_expand "zero_extendqisi2"
359190286Sobrien  [(parallel
359290286Sobrien    [(set (match_operand:SI 0 "register_operand" "")
359390286Sobrien       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
359490286Sobrien     (clobber (reg:CC 17))])]
359552296Sobrien  ""
359652296Sobrien  "")
359752296Sobrien
359890286Sobrien(define_insn "*zero_extendqisi2_and"
359990286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,?&q")
360090286Sobrien     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
360190286Sobrien   (clobber (reg:CC 17))]
360290286Sobrien  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
360390286Sobrien  "#"
360490286Sobrien  [(set_attr "type" "alu1")
360590286Sobrien   (set_attr "mode" "SI")])
360652296Sobrien
360790286Sobrien(define_insn "*zero_extendqisi2_movzbw_and"
360890286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,r")
360990286Sobrien     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
361090286Sobrien   (clobber (reg:CC 17))]
361190286Sobrien  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
361290286Sobrien  "#"
361390286Sobrien  [(set_attr "type" "imovx,alu1")
361490286Sobrien   (set_attr "mode" "SI")])
361550650Sobrien
361690286Sobrien(define_insn "*zero_extendqisi2_movzbw"
361790286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
361890286Sobrien     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
361990286Sobrien  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
362090286Sobrien  "movz{bl|x}\t{%1, %0|%0, %1}"
362190286Sobrien  [(set_attr "type" "imovx")
362290286Sobrien   (set_attr "mode" "SI")])
362318334Speter
362490286Sobrien;; For the movzbl case strip only the clobber
362550650Sobrien(define_split
362650650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
362790286Sobrien	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
362890286Sobrien   (clobber (reg:CC 17))]
362990286Sobrien  "reload_completed 
363090286Sobrien   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
363190286Sobrien   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
363290286Sobrien  [(set (match_dup 0)
363390286Sobrien	(zero_extend:SI (match_dup 1)))])
363450650Sobrien
363590286Sobrien;; When source and destination does not overlap, clear destination
363690286Sobrien;; first and then do the movb
363750650Sobrien(define_split
363850650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
363990286Sobrien	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
364090286Sobrien   (clobber (reg:CC 17))]
364190286Sobrien  "reload_completed
364290286Sobrien   && ANY_QI_REG_P (operands[0])
364390286Sobrien   && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
364490286Sobrien   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
364590286Sobrien   && !reg_overlap_mentioned_p (operands[0], operands[1])"
364690286Sobrien  [(set (match_dup 0) (const_int 0))
364790286Sobrien   (set (strict_low_part (match_dup 2)) (match_dup 1))]
364890286Sobrien  "operands[2] = gen_lowpart (QImode, operands[0]);")
364950650Sobrien
365090286Sobrien;; Rest is handled by single and.
365150650Sobrien(define_split
365250650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
365390286Sobrien	(zero_extend:SI (match_operand:QI 1 "register_operand" "")))
365490286Sobrien   (clobber (reg:CC 17))]
365590286Sobrien  "reload_completed
365690286Sobrien   && true_regnum (operands[0]) == true_regnum (operands[1])"
365790286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
365890286Sobrien	      (clobber (reg:CC 17))])]
365990286Sobrien  "")
366050650Sobrien
366190286Sobrien;; %%% Kill me once multi-word ops are sane.
366290286Sobrien(define_expand "zero_extendsidi2"
366390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
366490286Sobrien     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
366518334Speter  ""
366690286Sobrien  "if (!TARGET_64BIT)
366790286Sobrien     {
366890286Sobrien       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
366990286Sobrien       DONE;
367090286Sobrien     }
367190286Sobrien  ")
367250650Sobrien
367390286Sobrien(define_insn "zero_extendsidi2_32"
367490286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
367590286Sobrien	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
367690286Sobrien   (clobber (reg:CC 17))]
367790286Sobrien  "!TARGET_64BIT"
367890286Sobrien  "#"
367990286Sobrien  [(set_attr "mode" "SI")])
368090286Sobrien
368190286Sobrien(define_insn "zero_extendsidi2_rex64"
368290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
368390286Sobrien     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
368490286Sobrien  "TARGET_64BIT"
368590286Sobrien  "@
368690286Sobrien   mov\t{%k1, %k0|%k0, %k1}
368790286Sobrien   #"
368890286Sobrien  [(set_attr "type" "imovx,imov")
368990286Sobrien   (set_attr "mode" "SI,DI")])
369090286Sobrien
369190286Sobrien(define_split
369290286Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
369390286Sobrien     (zero_extend:DI (match_dup 0)))]
369490286Sobrien  "TARGET_64BIT"
369590286Sobrien  [(set (match_dup 4) (const_int 0))]
369690286Sobrien  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
369790286Sobrien
369852296Sobrien(define_split 
369952296Sobrien  [(set (match_operand:DI 0 "register_operand" "")
370090286Sobrien	(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
370190286Sobrien   (clobber (reg:CC 17))]
370290286Sobrien  "!TARGET_64BIT && reload_completed
370390286Sobrien   && true_regnum (operands[0]) == true_regnum (operands[1])"
370452296Sobrien  [(set (match_dup 4) (const_int 0))]
370552296Sobrien  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
370650650Sobrien
370752296Sobrien(define_split 
370852296Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
370990286Sobrien	(zero_extend:DI (match_operand:SI 1 "general_operand" "")))
371090286Sobrien   (clobber (reg:CC 17))]
371190286Sobrien  "!TARGET_64BIT && reload_completed"
371252296Sobrien  [(set (match_dup 3) (match_dup 1))
371352296Sobrien   (set (match_dup 4) (const_int 0))]
371452296Sobrien  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
371590286Sobrien
371690286Sobrien(define_insn "zero_extendhidi2"
371790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
371890286Sobrien     (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
371990286Sobrien  "TARGET_64BIT"
372090286Sobrien  "@
372190286Sobrien   movz{wl|x}\t{%1, %k0|%k0, %1} 
372290286Sobrien   movz{wq|x}\t{%1, %0|%0, %1}"
372390286Sobrien  [(set_attr "type" "imovx")
372490286Sobrien   (set_attr "mode" "SI,DI")])
372590286Sobrien
372690286Sobrien(define_insn "zero_extendqidi2"
372790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
372890286Sobrien     (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
372990286Sobrien  "TARGET_64BIT"
373090286Sobrien  "@
373190286Sobrien   movz{bl|x}\t{%1, %k0|%k0, %1} 
373290286Sobrien   movz{bq|x}\t{%1, %0|%0, %1}"
373390286Sobrien  [(set_attr "type" "imovx")
373490286Sobrien   (set_attr "mode" "SI,DI")])
373518334Speter
373690286Sobrien;; Sign extension instructions
373718334Speter
373890286Sobrien(define_expand "extendsidi2"
373990286Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
374090286Sobrien		   (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
374190286Sobrien	      (clobber (reg:CC 17))
374290286Sobrien	      (clobber (match_scratch:SI 2 ""))])]
374390286Sobrien  ""
374490286Sobrien{
374590286Sobrien  if (TARGET_64BIT)
374690286Sobrien    {
374790286Sobrien      emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
374890286Sobrien      DONE;
374990286Sobrien    }
375090286Sobrien})
375190286Sobrien
375290286Sobrien(define_insn "*extendsidi2_1"
375390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
375490286Sobrien	(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
375590286Sobrien   (clobber (reg:CC 17))
375652296Sobrien   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
375790286Sobrien  "!TARGET_64BIT"
375852296Sobrien  "#")
375952296Sobrien
376090286Sobrien(define_insn "extendsidi2_rex64"
376190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=*a,r")
376290286Sobrien	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
376390286Sobrien  "TARGET_64BIT"
376490286Sobrien  "@
376590286Sobrien   {cltq|cdqe}
376690286Sobrien   movs{lq|x}\t{%1,%0|%0, %1}"
376790286Sobrien  [(set_attr "type" "imovx")
376890286Sobrien   (set_attr "mode" "DI")
376990286Sobrien   (set_attr "prefix_0f" "0")
377090286Sobrien   (set_attr "modrm" "0,1")])
377190286Sobrien
377290286Sobrien(define_insn "extendhidi2"
377390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
377490286Sobrien	(sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
377590286Sobrien  "TARGET_64BIT"
377690286Sobrien  "movs{wq|x}\t{%1,%0|%0, %1}"
377790286Sobrien  [(set_attr "type" "imovx")
377890286Sobrien   (set_attr "mode" "DI")])
377990286Sobrien
378090286Sobrien(define_insn "extendqidi2"
378190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
378290286Sobrien	(sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
378390286Sobrien  "TARGET_64BIT"
378490286Sobrien  "movs{bq|x}\t{%1,%0|%0, %1}"
378590286Sobrien   [(set_attr "type" "imovx")
378690286Sobrien    (set_attr "mode" "DI")])
378790286Sobrien
378852296Sobrien;; Extend to memory case when source register does die.
378952296Sobrien(define_split 
379052296Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
379152296Sobrien	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
379290286Sobrien   (clobber (reg:CC 17))
379352296Sobrien   (clobber (match_operand:SI 2 "register_operand" ""))]
379490286Sobrien  "(reload_completed
379552296Sobrien    && dead_or_set_p (insn, operands[1])
379652296Sobrien    && !reg_mentioned_p (operands[1], operands[0]))"
379752296Sobrien  [(set (match_dup 3) (match_dup 1))
379890286Sobrien   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
379990286Sobrien	      (clobber (reg:CC 17))])
380052296Sobrien   (set (match_dup 4) (match_dup 1))]
380152296Sobrien  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
380252296Sobrien
380352296Sobrien;; Extend to memory case when source register does not die.
380452296Sobrien(define_split 
380552296Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
380652296Sobrien	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
380790286Sobrien   (clobber (reg:CC 17))
380852296Sobrien   (clobber (match_operand:SI 2 "register_operand" ""))]
380990286Sobrien  "reload_completed"
381052296Sobrien  [(const_int 0)]
381118334Speter{
381252296Sobrien  split_di (&operands[0], 1, &operands[3], &operands[4]);
381352296Sobrien
381452296Sobrien  emit_move_insn (operands[3], operands[1]);
381552296Sobrien
381652296Sobrien  /* Generate a cltd if possible and doing so it profitable.  */
381752296Sobrien  if (true_regnum (operands[1]) == 0
381852296Sobrien      && true_regnum (operands[2]) == 1
381990286Sobrien      && (optimize_size || TARGET_USE_CLTD))
382018334Speter    {
382190286Sobrien      emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
382218334Speter    }
382352296Sobrien  else
382452296Sobrien    {
382552296Sobrien      emit_move_insn (operands[2], operands[1]);
382690286Sobrien      emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
382752296Sobrien    }
382852296Sobrien  emit_move_insn (operands[4], operands[2]);
382952296Sobrien  DONE;
383090286Sobrien})
383118334Speter
383252296Sobrien;; Extend to register case.  Optimize case where source and destination
383352296Sobrien;; registers match and cases where we can use cltd.
383452296Sobrien(define_split 
383552296Sobrien  [(set (match_operand:DI 0 "register_operand" "")
383652296Sobrien	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
383790286Sobrien   (clobber (reg:CC 17))
383852296Sobrien   (clobber (match_scratch:SI 2 ""))]
383952296Sobrien  "reload_completed"
384052296Sobrien  [(const_int 0)]
384152296Sobrien{
384252296Sobrien  split_di (&operands[0], 1, &operands[3], &operands[4]);
384318334Speter
384452296Sobrien  if (true_regnum (operands[3]) != true_regnum (operands[1]))
384552296Sobrien    emit_move_insn (operands[3], operands[1]);
384652296Sobrien
384752296Sobrien  /* Generate a cltd if possible and doing so it profitable.  */
384852296Sobrien  if (true_regnum (operands[3]) == 0
384990286Sobrien      && (optimize_size || TARGET_USE_CLTD))
385052296Sobrien    {
385190286Sobrien      emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
385252296Sobrien      DONE;
385352296Sobrien    }
385452296Sobrien
385552296Sobrien  if (true_regnum (operands[4]) != true_regnum (operands[1]))
385652296Sobrien    emit_move_insn (operands[4], operands[1]);
385752296Sobrien
385890286Sobrien  emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
385952296Sobrien  DONE;
386090286Sobrien})
386118334Speter
386218334Speter(define_insn "extendhisi2"
386390286Sobrien  [(set (match_operand:SI 0 "register_operand" "=*a,r")
386490286Sobrien	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
386518334Speter  ""
386618334Speter{
386790286Sobrien  switch (get_attr_prefix_0f (insn))
386890286Sobrien    {
386990286Sobrien    case 0:
387090286Sobrien      return "{cwtl|cwde}";
387190286Sobrien    default:
387290286Sobrien      return "movs{wl|x}\t{%1,%0|%0, %1}";
387390286Sobrien    }
387490286Sobrien}
387590286Sobrien  [(set_attr "type" "imovx")
387690286Sobrien   (set_attr "mode" "SI")
387790286Sobrien   (set (attr "prefix_0f")
387890286Sobrien     ;; movsx is short decodable while cwtl is vector decoded.
387990286Sobrien     (if_then_else (and (eq_attr "cpu" "!k6")
388090286Sobrien			(eq_attr "alternative" "0"))
388190286Sobrien	(const_string "0")
388290286Sobrien	(const_string "1")))
388390286Sobrien   (set (attr "modrm")
388490286Sobrien     (if_then_else (eq_attr "prefix_0f" "0")
388590286Sobrien	(const_string "0")
388690286Sobrien	(const_string "1")))])
388718334Speter
388890286Sobrien(define_insn "*extendhisi2_zext"
388990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=*a,r")
389090286Sobrien	(zero_extend:DI
389190286Sobrien	  (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
389290286Sobrien  "TARGET_64BIT"
389390286Sobrien{
389490286Sobrien  switch (get_attr_prefix_0f (insn))
389590286Sobrien    {
389690286Sobrien    case 0:
389790286Sobrien      return "{cwtl|cwde}";
389890286Sobrien    default:
389990286Sobrien      return "movs{wl|x}\t{%1,%k0|%k0, %1}";
390090286Sobrien    }
390190286Sobrien}
390290286Sobrien  [(set_attr "type" "imovx")
390390286Sobrien   (set_attr "mode" "SI")
390490286Sobrien   (set (attr "prefix_0f")
390590286Sobrien     ;; movsx is short decodable while cwtl is vector decoded.
390690286Sobrien     (if_then_else (and (eq_attr "cpu" "!k6")
390790286Sobrien			(eq_attr "alternative" "0"))
390890286Sobrien	(const_string "0")
390990286Sobrien	(const_string "1")))
391090286Sobrien   (set (attr "modrm")
391190286Sobrien     (if_then_else (eq_attr "prefix_0f" "0")
391290286Sobrien	(const_string "0")
391390286Sobrien	(const_string "1")))])
391418334Speter
391518334Speter(define_insn "extendqihi2"
391690286Sobrien  [(set (match_operand:HI 0 "register_operand" "=*a,r")
391790286Sobrien	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
391818334Speter  ""
391918334Speter{
392090286Sobrien  switch (get_attr_prefix_0f (insn))
392190286Sobrien    {
392290286Sobrien    case 0:
392390286Sobrien      return "{cbtw|cbw}";
392490286Sobrien    default:
392590286Sobrien      return "movs{bw|x}\t{%1,%0|%0, %1}";
392690286Sobrien    }
392790286Sobrien}
392890286Sobrien  [(set_attr "type" "imovx")
392990286Sobrien   (set_attr "mode" "HI")
393090286Sobrien   (set (attr "prefix_0f")
393190286Sobrien     ;; movsx is short decodable while cwtl is vector decoded.
393290286Sobrien     (if_then_else (and (eq_attr "cpu" "!k6")
393390286Sobrien			(eq_attr "alternative" "0"))
393490286Sobrien	(const_string "0")
393590286Sobrien	(const_string "1")))
393690286Sobrien   (set (attr "modrm")
393790286Sobrien     (if_then_else (eq_attr "prefix_0f" "0")
393890286Sobrien	(const_string "0")
393990286Sobrien	(const_string "1")))])
394018334Speter
394118334Speter(define_insn "extendqisi2"
394250650Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
394350650Sobrien	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
394418334Speter  ""
394590286Sobrien  "movs{bl|x}\t{%1,%0|%0, %1}"
394690286Sobrien   [(set_attr "type" "imovx")
394790286Sobrien    (set_attr "mode" "SI")])
394850650Sobrien
394990286Sobrien(define_insn "*extendqisi2_zext"
395090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
395190286Sobrien	(zero_extend:DI
395290286Sobrien	  (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
395390286Sobrien  "TARGET_64BIT"
395490286Sobrien  "movs{bl|x}\t{%1,%k0|%k0, %1}"
395590286Sobrien   [(set_attr "type" "imovx")
395690286Sobrien    (set_attr "mode" "SI")])
395718334Speter
395890286Sobrien;; Conversions between float and double.
395950650Sobrien
396090286Sobrien;; These are all no-ops in the model used for the 80387.  So just
396190286Sobrien;; emit moves.
396250650Sobrien
396390286Sobrien;; %%% Kill these when call knows how to work out a DFmode push earlier. 
396490286Sobrien(define_insn "*dummy_extendsfdf2"
396590286Sobrien  [(set (match_operand:DF 0 "push_operand" "=<")
396690286Sobrien	(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
396790286Sobrien  "0"
396890286Sobrien  "#")
396950650Sobrien
397090286Sobrien(define_split
397190286Sobrien  [(set (match_operand:DF 0 "push_operand" "")
397290286Sobrien	(float_extend:DF (match_operand:SF 1 "register_operand" "")))]
397390286Sobrien  "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
397490286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
397590286Sobrien   (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
397650650Sobrien
397790286Sobrien(define_split
397890286Sobrien  [(set (match_operand:DF 0 "push_operand" "")
397990286Sobrien	(float_extend:DF (match_operand:SF 1 "register_operand" "")))]
398090286Sobrien  "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
398190286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
398290286Sobrien   (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
398350650Sobrien
398490286Sobrien(define_insn "*dummy_extendsfxf2"
398590286Sobrien  [(set (match_operand:XF 0 "push_operand" "=<")
398690286Sobrien	(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
398790286Sobrien  "0"
398890286Sobrien  "#")
398950650Sobrien
399090286Sobrien(define_split
399190286Sobrien  [(set (match_operand:XF 0 "push_operand" "")
399290286Sobrien	(float_extend:XF (match_operand:SF 1 "register_operand" "")))]
399390286Sobrien  "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
399490286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
399590286Sobrien   (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
399650650Sobrien
399790286Sobrien(define_insn "*dummy_extendsftf2"
399890286Sobrien  [(set (match_operand:TF 0 "push_operand" "=<")
399990286Sobrien	(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
400090286Sobrien  "0"
400190286Sobrien  "#")
400250650Sobrien
400390286Sobrien(define_split
400490286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
400590286Sobrien	(float_extend:TF (match_operand:SF 1 "register_operand" "")))]
400690286Sobrien  "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
400790286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
400890286Sobrien   (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
400950650Sobrien
401090286Sobrien(define_split
401190286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
401290286Sobrien	(float_extend:TF (match_operand:SF 1 "register_operand" "")))]
401390286Sobrien  "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
401490286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
401590286Sobrien   (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
401618334Speter
401790286Sobrien(define_insn "*dummy_extenddfxf2"
401890286Sobrien  [(set (match_operand:XF 0 "push_operand" "=<")
401990286Sobrien	(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
402090286Sobrien  "0"
402190286Sobrien  "#")
402252296Sobrien
402390286Sobrien(define_split
402490286Sobrien  [(set (match_operand:XF 0 "push_operand" "")
402590286Sobrien	(float_extend:XF (match_operand:DF 1 "register_operand" "")))]
402690286Sobrien  "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
402790286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
402890286Sobrien   (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
402952296Sobrien
403090286Sobrien(define_insn "*dummy_extenddftf2"
403190286Sobrien  [(set (match_operand:TF 0 "push_operand" "=<")
403290286Sobrien	(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
403390286Sobrien  "0"
403490286Sobrien  "#")
403518334Speter
403652296Sobrien(define_split
403790286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
403890286Sobrien	(float_extend:TF (match_operand:DF 1 "register_operand" "")))]
403990286Sobrien  "!TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
404090286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
404190286Sobrien   (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
404218334Speter
404352296Sobrien(define_split
404490286Sobrien  [(set (match_operand:TF 0 "push_operand" "")
404590286Sobrien	(float_extend:TF (match_operand:DF 1 "register_operand" "")))]
404690286Sobrien  "TARGET_64BIT && FP_REGNO_P (REGNO (operands[1]))"
404790286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
404890286Sobrien   (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
404918334Speter
405090286Sobrien(define_expand "extendsfdf2"
405152296Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "")
405290286Sobrien        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
405390286Sobrien  "TARGET_80387 || TARGET_SSE2"
405452296Sobrien{
405590286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
405690286Sobrien    operands[1] = force_reg (SFmode, operands[1]);
405790286Sobrien})
405818334Speter
405990286Sobrien(define_insn "*extendsfdf2_1"
406090286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
406190286Sobrien        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
406290286Sobrien  "(TARGET_80387 || TARGET_SSE2)
406390286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
406452296Sobrien{
406590286Sobrien  switch (which_alternative)
406690286Sobrien    {
406790286Sobrien    case 0:
406890286Sobrien      if (REG_P (operands[1])
406990286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
407090286Sobrien        return "fstp\t%y0";
407190286Sobrien      else if (STACK_TOP_P (operands[0]))
407290286Sobrien        return "fld%z1\t%y1";
407390286Sobrien      else
407490286Sobrien        return "fst\t%y0";
407552296Sobrien
407690286Sobrien    case 1:
407790286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
407890286Sobrien        return "fstp%z0\t%y0";
407918334Speter
408090286Sobrien      else
408190286Sobrien        return "fst%z0\t%y0";
408290286Sobrien    case 2:
408390286Sobrien      return "cvtss2sd\t{%1, %0|%0, %1}";
408418334Speter
408590286Sobrien    default:
408690286Sobrien      abort ();
408790286Sobrien    }
408890286Sobrien}
408990286Sobrien  [(set_attr "type" "fmov,fmov,sse")
409090286Sobrien   (set_attr "mode" "SF,XF,DF")])
409118334Speter
409290286Sobrien(define_insn "*extendsfdf2_1_sse_only"
409390286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
409490286Sobrien        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
409590286Sobrien  "!TARGET_80387 && TARGET_SSE2
409690286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
409790286Sobrien  "cvtss2sd\t{%1, %0|%0, %1}"
409890286Sobrien  [(set_attr "type" "sse")
409990286Sobrien   (set_attr "mode" "DF")])
410018334Speter
410190286Sobrien(define_expand "extendsfxf2"
410252296Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "")
410390286Sobrien        (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "")))]
410490286Sobrien  "!TARGET_64BIT && TARGET_80387"
410590286Sobrien{
410690286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
410790286Sobrien    operands[1] = force_reg (SFmode, operands[1]);
410890286Sobrien})
410918334Speter
411090286Sobrien(define_insn "*extendsfxf2_1"
411152296Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
411290286Sobrien        (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
411390286Sobrien  "!TARGET_64BIT && TARGET_80387
411490286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
411552296Sobrien{
411690286Sobrien  switch (which_alternative)
411790286Sobrien    {
411890286Sobrien    case 0:
411990286Sobrien      if (REG_P (operands[1])
412090286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
412190286Sobrien        return "fstp\t%y0";
412290286Sobrien      else if (STACK_TOP_P (operands[0]))
412390286Sobrien        return "fld%z1\t%y1";
412490286Sobrien      else
412590286Sobrien        return "fst\t%y0";
412618334Speter
412790286Sobrien    case 1:
412890286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
412990286Sobrien	 we need one, follow the store with a load.  */
413090286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
413190286Sobrien        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
413290286Sobrien      else
413390286Sobrien        return "fstp%z0\t%y0";
413490286Sobrien
413590286Sobrien    default:
413690286Sobrien      abort ();
413790286Sobrien    }
413890286Sobrien}
413990286Sobrien  [(set_attr "type" "fmov")
414090286Sobrien   (set_attr "mode" "SF,XF")])
414190286Sobrien
414290286Sobrien(define_expand "extendsftf2"
414390286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "")
414490286Sobrien        (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))]
414552296Sobrien  "TARGET_80387"
414652296Sobrien{
414752296Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
414852296Sobrien    operands[1] = force_reg (SFmode, operands[1]);
414990286Sobrien})
415052296Sobrien
415190286Sobrien(define_insn "*extendsftf2_1"
415290286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
415390286Sobrien        (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
415490286Sobrien  "TARGET_80387
415590286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
415618334Speter{
415790286Sobrien  switch (which_alternative)
415890286Sobrien    {
415990286Sobrien    case 0:
416090286Sobrien      if (REG_P (operands[1])
416190286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
416290286Sobrien        return "fstp\t%y0";
416390286Sobrien      else if (STACK_TOP_P (operands[0]))
416490286Sobrien        return "fld%z1\t%y1";
416590286Sobrien      else
416690286Sobrien        return "fst\t%y0";
416718334Speter
416890286Sobrien    case 1:
416990286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
417090286Sobrien	 we need one, follow the store with a load.  */
417190286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
417290286Sobrien        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
417390286Sobrien      else
417490286Sobrien        return "fstp%z0\t%y0";
417518334Speter
417690286Sobrien    default:
417790286Sobrien      abort ();
417890286Sobrien    }
417990286Sobrien}
418090286Sobrien  [(set_attr "type" "fmov")
418190286Sobrien   (set_attr "mode" "SF,XF")])
418218334Speter
418390286Sobrien(define_expand "extenddfxf2"
418452296Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "")
418590286Sobrien        (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))]
418690286Sobrien  "!TARGET_64BIT && TARGET_80387"
418790286Sobrien{
418890286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
418990286Sobrien    operands[1] = force_reg (DFmode, operands[1]);
419090286Sobrien})
419118334Speter
419290286Sobrien(define_insn "*extenddfxf2_1"
419352296Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
419490286Sobrien        (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
419590286Sobrien  "!TARGET_64BIT && TARGET_80387
419690286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
419752296Sobrien{
419890286Sobrien  switch (which_alternative)
419990286Sobrien    {
420090286Sobrien    case 0:
420190286Sobrien      if (REG_P (operands[1])
420290286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
420390286Sobrien        return "fstp\t%y0";
420490286Sobrien      else if (STACK_TOP_P (operands[0]))
420590286Sobrien        return "fld%z1\t%y1";
420690286Sobrien      else
420790286Sobrien        return "fst\t%y0";
420818334Speter
420990286Sobrien    case 1:
421090286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
421190286Sobrien	 we need one, follow the store with a load.  */
421290286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
421390286Sobrien        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
421490286Sobrien      else
421590286Sobrien        return "fstp%z0\t%y0";
421690286Sobrien
421790286Sobrien    default:
421890286Sobrien      abort ();
421990286Sobrien    }
422090286Sobrien}
422190286Sobrien  [(set_attr "type" "fmov")
422290286Sobrien   (set_attr "mode" "DF,XF")])
422390286Sobrien
422490286Sobrien(define_expand "extenddftf2"
422590286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "")
422690286Sobrien        (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))]
422790286Sobrien  "TARGET_80387"
422890286Sobrien{
422990286Sobrien  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
423090286Sobrien    operands[1] = force_reg (DFmode, operands[1]);
423190286Sobrien})
423290286Sobrien
423390286Sobrien(define_insn "*extenddftf2_1"
423490286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
423590286Sobrien        (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
423690286Sobrien  "TARGET_80387
423790286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
423890286Sobrien{
423990286Sobrien  switch (which_alternative)
424090286Sobrien    {
424190286Sobrien    case 0:
424290286Sobrien      if (REG_P (operands[1])
424390286Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
424490286Sobrien        return "fstp\t%y0";
424590286Sobrien      else if (STACK_TOP_P (operands[0]))
424690286Sobrien        return "fld%z1\t%y1";
424790286Sobrien      else
424890286Sobrien        return "fst\t%y0";
424990286Sobrien
425090286Sobrien    case 1:
425190286Sobrien      /* There is no non-popping store to memory for XFmode.  So if
425290286Sobrien	 we need one, follow the store with a load.  */
425390286Sobrien      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
425490286Sobrien        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
425590286Sobrien      else
425690286Sobrien        return "fstp%z0\t%y0";
425790286Sobrien
425890286Sobrien    default:
425990286Sobrien      abort ();
426090286Sobrien    }
426190286Sobrien}
426290286Sobrien  [(set_attr "type" "fmov")
426390286Sobrien   (set_attr "mode" "DF,XF")])
426490286Sobrien
426590286Sobrien;; %%% This seems bad bad news.
426690286Sobrien;; This cannot output into an f-reg because there is no way to be sure
426790286Sobrien;; of truncating in that case.  Otherwise this is just like a simple move
426890286Sobrien;; insn.  So we pretend we can output to a reg in order to get better
426990286Sobrien;; register preferencing, but we really use a stack slot.
427090286Sobrien
427118334Speter(define_expand "truncdfsf2"
427218334Speter  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
427318334Speter		   (float_truncate:SF
427418334Speter		    (match_operand:DF 1 "register_operand" "")))
427518334Speter	      (clobber (match_dup 2))])]
427690286Sobrien  "TARGET_80387 || TARGET_SSE2"
427718334Speter  "
427890286Sobrien   if (TARGET_80387)
427990286Sobrien     operands[2] = assign_386_stack_local (SFmode, 0);
428090286Sobrien   else
428190286Sobrien     {
428290286Sobrien	emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
428390286Sobrien	DONE;
428490286Sobrien     }
428590286Sobrien")
428690286Sobrien
428790286Sobrien(define_insn "*truncdfsf2_1"
428890286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
428990286Sobrien	(float_truncate:SF
429090286Sobrien	 (match_operand:DF 1 "register_operand" "f,f,f,f")))
429190286Sobrien   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
429290286Sobrien  "TARGET_80387 && !TARGET_SSE2"
429318334Speter{
429490286Sobrien  switch (which_alternative)
429590286Sobrien    {
429690286Sobrien    case 0:
429790286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
429890286Sobrien	return "fstp%z0\t%y0";
429990286Sobrien      else
430090286Sobrien	return "fst%z0\t%y0";
430190286Sobrien    default:
430290286Sobrien      abort ();
430390286Sobrien    }
430490286Sobrien}
430590286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
430690286Sobrien   (set_attr "mode" "SF,SF,SF,SF")])
430718334Speter
430890286Sobrien(define_insn "*truncdfsf2_1_sse"
430990286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,Y")
431018334Speter	(float_truncate:SF
431190286Sobrien	 (match_operand:DF 1 "nonimmediate_operand" "f,f,f,f,mY")))
431290286Sobrien   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
431390286Sobrien  "TARGET_80387 && TARGET_SSE2"
431418334Speter{
431590286Sobrien  switch (which_alternative)
431690286Sobrien    {
431790286Sobrien    case 0:
431890286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
431990286Sobrien	return "fstp%z0\t%y0";
432090286Sobrien      else
432190286Sobrien	return "fst%z0\t%y0";
432290286Sobrien    case 4:
432390286Sobrien      return "cvtsd2ss\t{%1, %0|%0, %1}";
432490286Sobrien    default:
432590286Sobrien      abort ();
432690286Sobrien    }
432790286Sobrien}
432890286Sobrien  [(set_attr "type" "fmov,multi,multi,multi,sse")
432990286Sobrien   (set_attr "mode" "SF,SF,SF,SF,DF")])
433018334Speter
433190286Sobrien(define_insn "*truncdfsf2_2"
433290286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,!m")
433390286Sobrien	(float_truncate:SF
433490286Sobrien	 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
433590286Sobrien  "TARGET_80387 && TARGET_SSE2
433690286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
433790286Sobrien{
433890286Sobrien  switch (which_alternative)
433990286Sobrien    {
434090286Sobrien    case 0:
434190286Sobrien      return "cvtsd2ss\t{%1, %0|%0, %1}";
434290286Sobrien    case 1:
434390286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
434490286Sobrien	return "fstp%z0\t%y0";
434590286Sobrien      else
434690286Sobrien	return "fst%z0\t%y0";
434790286Sobrien    default:
434890286Sobrien      abort ();
434990286Sobrien    }
435090286Sobrien}
435190286Sobrien  [(set_attr "type" "sse,fmov")
435290286Sobrien   (set_attr "mode" "DF,SF")])
435352296Sobrien
435490286Sobrien(define_insn "truncdfsf2_3"
435590286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
435690286Sobrien	(float_truncate:SF
435790286Sobrien	 (match_operand:DF 1 "register_operand" "f")))]
435890286Sobrien  "TARGET_80387"
435990286Sobrien{
436090286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
436190286Sobrien    return "fstp%z0\t%y0";
436218334Speter  else
436390286Sobrien    return "fst%z0\t%y0";
436490286Sobrien}
436590286Sobrien  [(set_attr "type" "fmov")
436690286Sobrien   (set_attr "mode" "SF")])
436718334Speter
436890286Sobrien(define_insn "truncdfsf2_sse_only"
436990286Sobrien  [(set (match_operand:SF 0 "register_operand" "=Y")
437090286Sobrien	(float_truncate:SF
437190286Sobrien	 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
437290286Sobrien  "!TARGET_80387 && TARGET_SSE2"
437390286Sobrien  "cvtsd2ss\t{%1, %0|%0, %1}"
437490286Sobrien  [(set_attr "type" "sse")
437590286Sobrien   (set_attr "mode" "DF")])
437652296Sobrien
437752296Sobrien(define_split
437890286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
437990286Sobrien	(float_truncate:SF
438090286Sobrien	 (match_operand:DF 1 "register_operand" "")))
438152296Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
438290286Sobrien  "TARGET_80387"
438390286Sobrien  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
438452296Sobrien  "")
438552296Sobrien
438652296Sobrien(define_split
438790286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "")
438890286Sobrien	(float_truncate:SF
438990286Sobrien	 (match_operand:DF 1 "nonimmediate_operand" "")))
439090286Sobrien   (clobber (match_operand 2 "" ""))]
439190286Sobrien  "TARGET_80387 && reload_completed
439290286Sobrien   && !FP_REG_P (operands[0]) && !FP_REG_P (operands[1])"
439390286Sobrien  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
439490286Sobrien  "")
439590286Sobrien
439690286Sobrien(define_split
439790286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
439890286Sobrien	(float_truncate:SF
439990286Sobrien	 (match_operand:DF 1 "register_operand" "")))
440052296Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
440190286Sobrien  "TARGET_80387 && reload_completed
440290286Sobrien   && FP_REG_P (operands[1])"
440390286Sobrien  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
440490286Sobrien   (set (match_dup 0) (match_dup 2))]
440552296Sobrien  "")
440652296Sobrien
440790286Sobrien(define_expand "truncxfsf2"
440890286Sobrien  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
440990286Sobrien		   (float_truncate:SF
441090286Sobrien		    (match_operand:XF 1 "register_operand" "")))
441190286Sobrien	      (clobber (match_dup 2))])]
441290286Sobrien  "!TARGET_64BIT && TARGET_80387"
441390286Sobrien  "operands[2] = assign_386_stack_local (SFmode, 0);")
441452296Sobrien
441590286Sobrien(define_insn "*truncxfsf2_1"
441690286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
441790286Sobrien	(float_truncate:SF
441890286Sobrien	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
441990286Sobrien   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
442090286Sobrien  "!TARGET_64BIT && TARGET_80387"
442190286Sobrien{
442290286Sobrien  switch (which_alternative)
442390286Sobrien    {
442490286Sobrien    case 0:
442590286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
442690286Sobrien	return "fstp%z0\t%y0";
442790286Sobrien      else
442890286Sobrien	return "fst%z0\t%y0";
442990286Sobrien    default:
443090286Sobrien      abort();
443190286Sobrien    }
443290286Sobrien}
443390286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
443490286Sobrien   (set_attr "mode" "SF")])
443590286Sobrien
443690286Sobrien(define_insn "*truncxfsf2_2"
443752296Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
443890286Sobrien	(float_truncate:SF
443990286Sobrien	 (match_operand:XF 1 "register_operand" "f")))]
444090286Sobrien  "!TARGET_64BIT && TARGET_80387"
444118334Speter{
444290286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
444390286Sobrien    return "fstp%z0\t%y0";
444418334Speter  else
444590286Sobrien    return "fst%z0\t%y0";
444690286Sobrien}
444790286Sobrien  [(set_attr "type" "fmov")
444890286Sobrien   (set_attr "mode" "SF")])
444952296Sobrien
445090286Sobrien(define_split
445190286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
445290286Sobrien	(float_truncate:SF
445390286Sobrien	 (match_operand:XF 1 "register_operand" "")))
445490286Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
445590286Sobrien  "TARGET_80387"
445690286Sobrien  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
445790286Sobrien  "")
445890286Sobrien
445990286Sobrien(define_split
446090286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
446190286Sobrien	(float_truncate:SF
446290286Sobrien	 (match_operand:XF 1 "register_operand" "")))
446390286Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
446490286Sobrien  "TARGET_80387 && reload_completed"
446590286Sobrien  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
446690286Sobrien   (set (match_dup 0) (match_dup 2))]
446790286Sobrien  "")
446890286Sobrien
446990286Sobrien(define_expand "trunctfsf2"
447052296Sobrien  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
447152296Sobrien		   (float_truncate:SF
447290286Sobrien		    (match_operand:TF 1 "register_operand" "")))
447352296Sobrien	      (clobber (match_dup 2))])]
447452296Sobrien  "TARGET_80387"
447590286Sobrien  "operands[2] = assign_386_stack_local (SFmode, 0);")
447690286Sobrien
447790286Sobrien(define_insn "*trunctfsf2_1"
447890286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
447990286Sobrien	(float_truncate:SF
448090286Sobrien	 (match_operand:TF 1 "register_operand" "f,f,f,f")))
448190286Sobrien   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
448290286Sobrien  "TARGET_80387"
448352296Sobrien{
448490286Sobrien  switch (which_alternative)
448590286Sobrien    {
448690286Sobrien    case 0:
448790286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
448890286Sobrien	return "fstp%z0\t%y0";
448990286Sobrien      else
449090286Sobrien	return "fst%z0\t%y0";
449190286Sobrien    default:
449290286Sobrien      abort();
449390286Sobrien    }
449490286Sobrien}
449590286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
449690286Sobrien   (set_attr "mode" "SF")])
449718334Speter
449890286Sobrien(define_insn "*trunctfsf2_2"
449990286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
450052296Sobrien	(float_truncate:SF
450190286Sobrien	 (match_operand:TF 1 "register_operand" "f")))]
450218334Speter  "TARGET_80387"
450318334Speter{
450490286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
450590286Sobrien    return "fstp%z0\t%y0";
450618334Speter  else
450790286Sobrien    return "fst%z0\t%y0";
450890286Sobrien}
450990286Sobrien  [(set_attr "type" "fmov")
451090286Sobrien   (set_attr "mode" "SF")])
451118334Speter
451252296Sobrien(define_split
451390286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
451490286Sobrien	(float_truncate:SF
451590286Sobrien	 (match_operand:TF 1 "register_operand" "")))
451652296Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
451790286Sobrien  "TARGET_80387"
451890286Sobrien  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
451952296Sobrien  "")
452052296Sobrien
452152296Sobrien(define_split
452290286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
452390286Sobrien	(float_truncate:SF
452490286Sobrien	 (match_operand:TF 1 "register_operand" "")))
452552296Sobrien   (clobber (match_operand:SF 2 "memory_operand" ""))]
452652296Sobrien  "TARGET_80387 && reload_completed"
452790286Sobrien  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
452890286Sobrien   (set (match_dup 0) (match_dup 2))]
452952296Sobrien  "")
453052296Sobrien
453118334Speter
453252296Sobrien(define_expand "truncxfdf2"
453352296Sobrien  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
453452296Sobrien		   (float_truncate:DF
453552296Sobrien		    (match_operand:XF 1 "register_operand" "")))
453652296Sobrien	      (clobber (match_dup 2))])]
453790286Sobrien  "!TARGET_64BIT && TARGET_80387"
453890286Sobrien  "operands[2] = assign_386_stack_local (DFmode, 0);")
453918334Speter
454090286Sobrien(define_insn "*truncxfdf2_1"
454190286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
454252296Sobrien	(float_truncate:DF
454390286Sobrien	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
454490286Sobrien   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
454590286Sobrien  "!TARGET_64BIT && TARGET_80387"
454618334Speter{
454790286Sobrien  switch (which_alternative)
454852296Sobrien    {
454990286Sobrien    case 0:
455090286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
455190286Sobrien	return "fstp%z0\t%y0";
455290286Sobrien      else
455390286Sobrien	return "fst%z0\t%y0";
455490286Sobrien    default:
455590286Sobrien      abort();
455652296Sobrien    }
455790286Sobrien  abort ();
455890286Sobrien}
455990286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
456090286Sobrien   (set_attr "mode" "DF")])
456152296Sobrien
456290286Sobrien(define_insn "*truncxfdf2_2"
456390286Sobrien  [(set (match_operand:DF 0 "memory_operand" "=m")
456490286Sobrien	(float_truncate:DF
456590286Sobrien	  (match_operand:XF 1 "register_operand" "f")))]
456690286Sobrien  "!TARGET_64BIT && TARGET_80387"
456790286Sobrien{
456890286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
456990286Sobrien    return "fstp%z0\t%y0";
457090286Sobrien  else
457190286Sobrien    return "fst%z0\t%y0";
457290286Sobrien}
457390286Sobrien  [(set_attr "type" "fmov")
457490286Sobrien   (set_attr "mode" "DF")])
457552296Sobrien
457652296Sobrien(define_split
457790286Sobrien  [(set (match_operand:DF 0 "memory_operand" "")
457890286Sobrien	(float_truncate:DF
457990286Sobrien	 (match_operand:XF 1 "register_operand" "")))
458052296Sobrien   (clobber (match_operand:DF 2 "memory_operand" ""))]
458190286Sobrien  "TARGET_80387"
458290286Sobrien  [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
458352296Sobrien  "")
458452296Sobrien
458552296Sobrien(define_split
458690286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
458790286Sobrien	(float_truncate:DF
458890286Sobrien	 (match_operand:XF 1 "register_operand" "")))
458952296Sobrien   (clobber (match_operand:DF 2 "memory_operand" ""))]
459052296Sobrien  "TARGET_80387 && reload_completed"
459190286Sobrien  [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
459290286Sobrien   (set (match_dup 0) (match_dup 2))]
459352296Sobrien  "")
459452296Sobrien
459590286Sobrien(define_expand "trunctfdf2"
459690286Sobrien  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
459790286Sobrien		   (float_truncate:DF
459890286Sobrien		    (match_operand:TF 1 "register_operand" "")))
459990286Sobrien	      (clobber (match_dup 2))])]
460018334Speter  "TARGET_80387"
460190286Sobrien  "operands[2] = assign_386_stack_local (DFmode, 0);")
460218334Speter
460390286Sobrien(define_insn "*trunctfdf2_1"
460490286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
460590286Sobrien	(float_truncate:DF
460690286Sobrien	 (match_operand:TF 1 "register_operand" "f,f,f,f")))
460790286Sobrien   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
460818334Speter  "TARGET_80387"
460918334Speter{
461090286Sobrien  switch (which_alternative)
461190286Sobrien    {
461290286Sobrien    case 0:
461390286Sobrien      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
461490286Sobrien	return "fstp%z0\t%y0";
461590286Sobrien      else
461690286Sobrien	return "fst%z0\t%y0";
461790286Sobrien    default:
461890286Sobrien      abort();
461990286Sobrien    }
462090286Sobrien  abort ();
462190286Sobrien}
462290286Sobrien  [(set_attr "type" "fmov,multi,multi,multi")
462390286Sobrien   (set_attr "mode" "DF")])
462418334Speter
462590286Sobrien	(define_insn "*trunctfdf2_2"
462690286Sobrien  [(set (match_operand:DF 0 "memory_operand" "=m")
462790286Sobrien	(float_truncate:DF
462890286Sobrien	  (match_operand:TF 1 "register_operand" "f")))]
462952296Sobrien  "TARGET_80387"
463018334Speter{
463190286Sobrien  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
463290286Sobrien    return "fstp%z0\t%y0";
463390286Sobrien  else
463490286Sobrien    return "fst%z0\t%y0";
463590286Sobrien}
463690286Sobrien  [(set_attr "type" "fmov")
463790286Sobrien   (set_attr "mode" "DF")])
463818334Speter
463990286Sobrien(define_split
464090286Sobrien  [(set (match_operand:DF 0 "memory_operand" "")
464190286Sobrien	(float_truncate:DF
464290286Sobrien	 (match_operand:TF 1 "register_operand" "")))
464390286Sobrien   (clobber (match_operand:DF 2 "memory_operand" ""))]
464418334Speter  "TARGET_80387"
464590286Sobrien  [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
464690286Sobrien  "")
464718334Speter
464890286Sobrien(define_split
464990286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
465090286Sobrien	(float_truncate:DF
465190286Sobrien	 (match_operand:TF 1 "register_operand" "")))
465290286Sobrien   (clobber (match_operand:DF 2 "memory_operand" ""))]
465390286Sobrien  "TARGET_80387 && reload_completed"
465490286Sobrien  [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
465590286Sobrien   (set (match_dup 0) (match_dup 2))]
465690286Sobrien  "")
465718334Speter
465890286Sobrien
465990286Sobrien;; %%% Break up all these bad boys.
466090286Sobrien
466190286Sobrien;; Signed conversion to DImode.
466290286Sobrien
466390286Sobrien(define_expand "fix_truncxfdi2"
466490286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
466590286Sobrien        (fix:DI (match_operand:XF 1 "register_operand" "")))]
466690286Sobrien  "!TARGET_64BIT && TARGET_80387"
466790286Sobrien  "")
466890286Sobrien
466990286Sobrien(define_expand "fix_trunctfdi2"
467090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
467190286Sobrien	(fix:DI (match_operand:TF 1 "register_operand" "")))]
467218334Speter  "TARGET_80387"
467390286Sobrien  "")
467418334Speter
467552296Sobrien(define_expand "fix_truncdfdi2"
467690286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
467790286Sobrien        (fix:DI (match_operand:DF 1 "register_operand" "")))]
467890286Sobrien  "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
467918334Speter{
468090286Sobrien  if (TARGET_64BIT && TARGET_SSE2)
468190286Sobrien   {
468290286Sobrien     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
468390286Sobrien     emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
468490286Sobrien     if (out != operands[0])
468590286Sobrien	emit_move_insn (operands[0], out);
468690286Sobrien     DONE;
468790286Sobrien   }
468890286Sobrien})
468918334Speter
469090286Sobrien(define_expand "fix_truncsfdi2"
469190286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
469290286Sobrien	(fix:DI (match_operand:SF 1 "register_operand" "")))]
469390286Sobrien  "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
469490286Sobrien{
469590286Sobrien  if (TARGET_SSE && TARGET_64BIT)
469690286Sobrien   {
469790286Sobrien     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
469890286Sobrien     emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
469990286Sobrien     if (out != operands[0])
470090286Sobrien	emit_move_insn (operands[0], out);
470190286Sobrien     DONE;
470290286Sobrien   }
470390286Sobrien})
470452296Sobrien
470590286Sobrien;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
470690286Sobrien;; of the machinery.
470790286Sobrien(define_insn_and_split "*fix_truncdi_1"
470890286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
470990286Sobrien	(fix:DI (match_operand 1 "register_operand" "f,f")))]
471090286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
471190286Sobrien   && !reload_completed && !reload_in_progress
471290286Sobrien   && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
471390286Sobrien  "#"
471490286Sobrien  "&& 1"
471590286Sobrien  [(const_int 0)]
471690286Sobrien{
471790286Sobrien  operands[2] = assign_386_stack_local (HImode, 1);
471890286Sobrien  operands[3] = assign_386_stack_local (HImode, 2);
471990286Sobrien  if (memory_operand (operands[0], VOIDmode))
472090286Sobrien    emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
472190286Sobrien				       operands[2], operands[3]));
472290286Sobrien  else
472390286Sobrien    {
472490286Sobrien      operands[4] = assign_386_stack_local (DImode, 0);
472590286Sobrien      emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
472690286Sobrien					   operands[2], operands[3],
472790286Sobrien					   operands[4]));
472890286Sobrien    }
472990286Sobrien  DONE;
473090286Sobrien}
473190286Sobrien  [(set_attr "type" "fistp")])
473290286Sobrien
473390286Sobrien(define_insn "fix_truncdi_nomemory"
473490286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
473590286Sobrien	(fix:DI (match_operand 1 "register_operand" "f,f")))
473690286Sobrien   (use (match_operand:HI 2 "memory_operand" "m,m"))
473790286Sobrien   (use (match_operand:HI 3 "memory_operand" "m,m"))
473890286Sobrien   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
473990286Sobrien   (clobber (match_scratch:DF 5 "=&1f,&1f"))]
474090286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
474190286Sobrien   && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
474290286Sobrien  "#"
474390286Sobrien  [(set_attr "type" "fistp")])
474490286Sobrien
474590286Sobrien(define_insn "fix_truncdi_memory"
474690286Sobrien  [(set (match_operand:DI 0 "memory_operand" "=m")
474790286Sobrien	(fix:DI (match_operand 1 "register_operand" "f")))
474890286Sobrien   (use (match_operand:HI 2 "memory_operand" "m"))
474990286Sobrien   (use (match_operand:HI 3 "memory_operand" "m"))
475090286Sobrien   (clobber (match_scratch:DF 4 "=&1f"))]
475190286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
475290286Sobrien   && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
475390286Sobrien  "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
475490286Sobrien  [(set_attr "type" "fistp")])
475590286Sobrien
475690286Sobrien(define_split 
475790286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
475890286Sobrien	(fix:DI (match_operand 1 "register_operand" "")))
475990286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
476090286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
476190286Sobrien   (clobber (match_operand:DI 4 "memory_operand" ""))
476290286Sobrien   (clobber (match_scratch 5 ""))]
476390286Sobrien  "reload_completed"
476490286Sobrien  [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
476590286Sobrien	      (use (match_dup 2))
476690286Sobrien	      (use (match_dup 3))
476790286Sobrien	      (clobber (match_dup 5))])
476890286Sobrien   (set (match_dup 0) (match_dup 4))]
476990286Sobrien  "")
477090286Sobrien
477190286Sobrien(define_split 
477290286Sobrien  [(set (match_operand:DI 0 "memory_operand" "")
477390286Sobrien	(fix:DI (match_operand 1 "register_operand" "")))
477490286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
477590286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
477690286Sobrien   (clobber (match_operand:DI 4 "memory_operand" ""))
477790286Sobrien   (clobber (match_scratch 5 ""))]
477890286Sobrien  "reload_completed"
477990286Sobrien  [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
478090286Sobrien	      (use (match_dup 2))
478190286Sobrien	      (use (match_dup 3))
478290286Sobrien	      (clobber (match_dup 5))])]
478390286Sobrien  "")
478490286Sobrien
478590286Sobrien;; When SSE available, it is always faster to use it!
478690286Sobrien(define_insn "fix_truncsfdi_sse"
478790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
478890286Sobrien	(fix:DI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
478990286Sobrien  "TARGET_64BIT && TARGET_SSE"
479090286Sobrien  "cvttss2si{q}\t{%1, %0|%0, %1}"
479190286Sobrien  [(set_attr "type" "sse")])
479290286Sobrien
479390286Sobrien(define_insn "fix_truncdfdi_sse"
479490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
479590286Sobrien	(fix:DI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
479690286Sobrien  "TARGET_64BIT && TARGET_SSE2"
479790286Sobrien  "cvttsd2si{q}\t{%1, %0|%0, %1}"
479890286Sobrien  [(set_attr "type" "sse")])
479990286Sobrien
480090286Sobrien;; Signed conversion to SImode.
480190286Sobrien
480252296Sobrien(define_expand "fix_truncxfsi2"
480390286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
480490286Sobrien	(fix:SI (match_operand:XF 1 "register_operand" "")))]
480590286Sobrien  "!TARGET_64BIT && TARGET_80387"
480690286Sobrien  "")
480790286Sobrien
480890286Sobrien(define_expand "fix_trunctfsi2"
480990286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
481090286Sobrien	(fix:SI (match_operand:TF 1 "register_operand" "")))]
481118334Speter  "TARGET_80387"
481290286Sobrien  "")
481390286Sobrien
481490286Sobrien(define_expand "fix_truncdfsi2"
481590286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
481690286Sobrien	(fix:SI (match_operand:DF 1 "register_operand" "")))]
481790286Sobrien  "TARGET_80387 || TARGET_SSE2"
481818334Speter{
481990286Sobrien  if (TARGET_SSE2)
482090286Sobrien   {
482190286Sobrien     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
482290286Sobrien     emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
482390286Sobrien     if (out != operands[0])
482490286Sobrien	emit_move_insn (operands[0], out);
482590286Sobrien     DONE;
482690286Sobrien   }
482790286Sobrien})
482818334Speter
482990286Sobrien(define_expand "fix_truncsfsi2"
483090286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
483190286Sobrien	(fix:SI (match_operand:SF 1 "register_operand" "")))]
483290286Sobrien  "TARGET_80387 || TARGET_SSE"
483390286Sobrien{
483490286Sobrien  if (TARGET_SSE)
483590286Sobrien   {
483690286Sobrien     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
483790286Sobrien     emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
483890286Sobrien     if (out != operands[0])
483990286Sobrien	emit_move_insn (operands[0], out);
484090286Sobrien     DONE;
484190286Sobrien   }
484290286Sobrien})
484352296Sobrien
484490286Sobrien;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
484590286Sobrien;; of the machinery.
484690286Sobrien(define_insn_and_split "*fix_truncsi_1"
484790286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
484890286Sobrien	(fix:SI (match_operand 1 "register_operand" "f,f")))]
484990286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
485090286Sobrien   && !reload_completed && !reload_in_progress
485190286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
485290286Sobrien  "#"
485390286Sobrien  "&& 1"
485490286Sobrien  [(const_int 0)]
485518334Speter{
485690286Sobrien  operands[2] = assign_386_stack_local (HImode, 1);
485790286Sobrien  operands[3] = assign_386_stack_local (HImode, 2);
485890286Sobrien  if (memory_operand (operands[0], VOIDmode))
485990286Sobrien    emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
486090286Sobrien				       operands[2], operands[3]));
486190286Sobrien  else
486290286Sobrien    {
486390286Sobrien      operands[4] = assign_386_stack_local (SImode, 0);
486490286Sobrien      emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
486590286Sobrien					   operands[2], operands[3],
486690286Sobrien					   operands[4]));
486790286Sobrien    }
486890286Sobrien  DONE;
486990286Sobrien}
487090286Sobrien  [(set_attr "type" "fistp")])
487118334Speter
487290286Sobrien(define_insn "fix_truncsi_nomemory"
487390286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
487490286Sobrien	(fix:SI (match_operand 1 "register_operand" "f,f")))
487590286Sobrien   (use (match_operand:HI 2 "memory_operand" "m,m"))
487690286Sobrien   (use (match_operand:HI 3 "memory_operand" "m,m"))
487790286Sobrien   (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
487890286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
487990286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
488090286Sobrien  "#"
488190286Sobrien  [(set_attr "type" "fistp")])
488290286Sobrien
488390286Sobrien(define_insn "fix_truncsi_memory"
488490286Sobrien  [(set (match_operand:SI 0 "memory_operand" "=m")
488590286Sobrien	(fix:SI (match_operand 1 "register_operand" "f")))
488690286Sobrien   (use (match_operand:HI 2 "memory_operand" "m"))
488790286Sobrien   (use (match_operand:HI 3 "memory_operand" "m"))]
488890286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
488990286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
489052296Sobrien  "* return output_fix_trunc (insn, operands);"
489190286Sobrien  [(set_attr "type" "fistp")])
489218334Speter
489390286Sobrien;; When SSE available, it is always faster to use it!
489490286Sobrien(define_insn "fix_truncsfsi_sse"
489590286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
489690286Sobrien	(fix:SI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
489790286Sobrien  "TARGET_SSE"
489890286Sobrien  "cvttss2si\t{%1, %0|%0, %1}"
489990286Sobrien  [(set_attr "type" "sse")])
490052296Sobrien
490190286Sobrien(define_insn "fix_truncdfsi_sse"
490290286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
490390286Sobrien	(fix:SI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
490490286Sobrien  "TARGET_SSE2"
490590286Sobrien  "cvttsd2si\t{%1, %0|%0, %1}"
490690286Sobrien  [(set_attr "type" "sse")])
490752296Sobrien
490890286Sobrien(define_split 
490990286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
491090286Sobrien	(fix:SI (match_operand 1 "register_operand" "")))
491190286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
491290286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
491390286Sobrien   (clobber (match_operand:SI 4 "memory_operand" ""))]
491490286Sobrien  "reload_completed"
491590286Sobrien  [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
491690286Sobrien	      (use (match_dup 2))
491790286Sobrien	      (use (match_dup 3))])
491890286Sobrien   (set (match_dup 0) (match_dup 4))]
491990286Sobrien  "")
492018334Speter
492190286Sobrien(define_split 
492290286Sobrien  [(set (match_operand:SI 0 "memory_operand" "")
492390286Sobrien	(fix:SI (match_operand 1 "register_operand" "")))
492490286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
492590286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
492690286Sobrien   (clobber (match_operand:SI 4 "memory_operand" ""))]
492790286Sobrien  "reload_completed"
492890286Sobrien  [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
492990286Sobrien	      (use (match_dup 2))
493090286Sobrien	      (use (match_dup 3))])]
493152296Sobrien  "")
493252296Sobrien
493390286Sobrien;; Signed conversion to HImode.
493490286Sobrien
493590286Sobrien(define_expand "fix_truncxfhi2"
493690286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
493790286Sobrien        (fix:HI (match_operand:XF 1 "register_operand" "")))]
493890286Sobrien  "!TARGET_64BIT && TARGET_80387"
493952296Sobrien  "")
494052296Sobrien
494190286Sobrien(define_expand "fix_trunctfhi2"
494290286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
494390286Sobrien	(fix:HI (match_operand:TF 1 "register_operand" "")))]
494418334Speter  "TARGET_80387"
494590286Sobrien  "")
494618334Speter
494790286Sobrien(define_expand "fix_truncdfhi2"
494890286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
494990286Sobrien	(fix:HI (match_operand:DF 1 "register_operand" "")))]
495090286Sobrien  "TARGET_80387 && !TARGET_SSE2"
495190286Sobrien  "")
495218334Speter
495390286Sobrien(define_expand "fix_truncsfhi2"
495490286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
495590286Sobrien	(fix:HI (match_operand:SF 1 "register_operand" "")))]
495690286Sobrien  "TARGET_80387 && !TARGET_SSE"
495790286Sobrien  "")
495852296Sobrien
495990286Sobrien;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
496090286Sobrien;; of the machinery.
496190286Sobrien(define_insn_and_split "*fix_trunchi_1"
496290286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
496390286Sobrien	(fix:HI (match_operand 1 "register_operand" "f,f")))]
496490286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
496590286Sobrien   && !reload_completed && !reload_in_progress
496690286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
496790286Sobrien  "#"
496890286Sobrien  ""
496990286Sobrien  [(const_int 0)]
497090286Sobrien{
497190286Sobrien  operands[2] = assign_386_stack_local (HImode, 1);
497290286Sobrien  operands[3] = assign_386_stack_local (HImode, 2);
497390286Sobrien  if (memory_operand (operands[0], VOIDmode))
497490286Sobrien    emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
497590286Sobrien				       operands[2], operands[3]));
497690286Sobrien  else
497790286Sobrien    {
497890286Sobrien      operands[4] = assign_386_stack_local (HImode, 0);
497990286Sobrien      emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
498090286Sobrien					   operands[2], operands[3],
498190286Sobrien					   operands[4]));
498290286Sobrien    }
498390286Sobrien  DONE;
498490286Sobrien}
498590286Sobrien  [(set_attr "type" "fistp")])
498690286Sobrien
498790286Sobrien(define_insn "fix_trunchi_nomemory"
498890286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
498990286Sobrien	(fix:HI (match_operand 1 "register_operand" "f,f")))
499090286Sobrien   (use (match_operand:HI 2 "memory_operand" "m,m"))
499190286Sobrien   (use (match_operand:HI 3 "memory_operand" "m,m"))
499290286Sobrien   (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
499390286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
499490286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
499590286Sobrien  "#"
499690286Sobrien  [(set_attr "type" "fistp")])
499790286Sobrien
499890286Sobrien(define_insn "fix_trunchi_memory"
499990286Sobrien  [(set (match_operand:HI 0 "memory_operand" "=m")
500090286Sobrien	(fix:HI (match_operand 1 "register_operand" "f")))
500190286Sobrien   (use (match_operand:HI 2 "memory_operand" "m"))
500290286Sobrien   (use (match_operand:HI 3 "memory_operand" "m"))]
500390286Sobrien  "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
500490286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
500590286Sobrien  "* return output_fix_trunc (insn, operands);"
500690286Sobrien  [(set_attr "type" "fistp")])
500790286Sobrien
500890286Sobrien(define_split 
500990286Sobrien  [(set (match_operand:HI 0 "memory_operand" "")
501090286Sobrien	(fix:HI (match_operand 1 "register_operand" "")))
501190286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
501290286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
501390286Sobrien   (clobber (match_operand:HI 4 "memory_operand" ""))]
501490286Sobrien  "reload_completed"
501590286Sobrien  [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
501690286Sobrien	      (use (match_dup 2))
501790286Sobrien	      (use (match_dup 3))])]
501818334Speter  "")
501918334Speter
502090286Sobrien(define_split 
502190286Sobrien  [(set (match_operand:HI 0 "register_operand" "")
502290286Sobrien	(fix:HI (match_operand 1 "register_operand" "")))
502390286Sobrien   (use (match_operand:HI 2 "memory_operand" ""))
502490286Sobrien   (use (match_operand:HI 3 "memory_operand" ""))
502590286Sobrien   (clobber (match_operand:HI 4 "memory_operand" ""))]
502690286Sobrien  "reload_completed"
502790286Sobrien  [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
502890286Sobrien	      (use (match_dup 2))
502990286Sobrien	      (use (match_dup 3))
503090286Sobrien	      (clobber (match_dup 4))])
503190286Sobrien   (set (match_dup 0) (match_dup 4))]
503252296Sobrien  "")
503352296Sobrien
503490286Sobrien;; %% Not used yet.
503590286Sobrien(define_insn "x86_fnstcw_1"
503690286Sobrien  [(set (match_operand:HI 0 "memory_operand" "=m")
503790286Sobrien	(unspec:HI [(reg:HI 18)] 11))]
503852296Sobrien  "TARGET_80387"
503990286Sobrien  "fnstcw\t%0"
504090286Sobrien  [(set_attr "length" "2")
504190286Sobrien   (set_attr "mode" "HI")
504290286Sobrien   (set_attr "i387" "1")
504390286Sobrien   (set_attr "ppro_uops" "few")])
504452296Sobrien
504590286Sobrien(define_insn "x86_fldcw_1"
504690286Sobrien  [(set (reg:HI 18)
504790286Sobrien	(unspec:HI [(match_operand:HI 0 "memory_operand" "m")] 12))]
504852296Sobrien  "TARGET_80387"
504990286Sobrien  "fldcw\t%0"
505090286Sobrien  [(set_attr "length" "2")
505190286Sobrien   (set_attr "mode" "HI")
505290286Sobrien   (set_attr "i387" "1")
505390286Sobrien   (set_attr "athlon_decode" "vector")
505490286Sobrien   (set_attr "ppro_uops" "few")])
505590286Sobrien
505690286Sobrien;; Conversion between fixed point and floating point.
505752296Sobrien
505890286Sobrien;; Even though we only accept memory inputs, the backend _really_
505990286Sobrien;; wants to be able to do this between registers.
506090286Sobrien
506190286Sobrien(define_insn "floathisf2"
506252296Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
506390286Sobrien	(float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
506490286Sobrien  "TARGET_80387 && !TARGET_SSE"
506590286Sobrien  "@
506690286Sobrien   fild%z1\t%1
506790286Sobrien   #"
506890286Sobrien  [(set_attr "type" "fmov,multi")
506990286Sobrien   (set_attr "mode" "SF")
507090286Sobrien   (set_attr "fp_int_src" "true")])
507152296Sobrien
507290286Sobrien(define_expand "floatsisf2"
507318334Speter  [(set (match_operand:SF 0 "register_operand" "")
507490286Sobrien	(float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
507590286Sobrien  "TARGET_SSE || TARGET_80387"
507618334Speter  "")
507718334Speter
507890286Sobrien(define_insn "*floatsisf2_i387"
507990286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
508090286Sobrien	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
508190286Sobrien  "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
508290286Sobrien  "@
508390286Sobrien   fild%z1\t%1
508490286Sobrien   #
508590286Sobrien   cvtsi2ss\t{%1, %0|%0, %1}"
508690286Sobrien  [(set_attr "type" "fmov,multi,sse")
508790286Sobrien   (set_attr "mode" "SF")
508890286Sobrien   (set_attr "fp_int_src" "true")])
508990286Sobrien
509090286Sobrien(define_insn "*floatsisf2_sse"
509190286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
509290286Sobrien	(float:SF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
509390286Sobrien  "TARGET_SSE"
509490286Sobrien  "cvtsi2ss\t{%1, %0|%0, %1}"
509590286Sobrien  [(set_attr "type" "sse")
509690286Sobrien   (set_attr "mode" "SF")
509790286Sobrien   (set_attr "fp_int_src" "true")])
509890286Sobrien
509990286Sobrien(define_expand "floatdisf2"
510052296Sobrien  [(set (match_operand:SF 0 "register_operand" "")
510190286Sobrien	(float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
510290286Sobrien  "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
510352296Sobrien  "")
510452296Sobrien
510590286Sobrien(define_insn "*floatdisf2_i387_only"
510690286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,?f")
510790286Sobrien	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
510890286Sobrien  "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
510990286Sobrien  "@
511090286Sobrien   fild%z1\t%1
511190286Sobrien   #"
511290286Sobrien  [(set_attr "type" "fmov,multi")
511390286Sobrien   (set_attr "mode" "SF")
511490286Sobrien   (set_attr "fp_int_src" "true")])
511552296Sobrien
511690286Sobrien(define_insn "*floatdisf2_i387"
511790286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
511890286Sobrien	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
511990286Sobrien  "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
512090286Sobrien  "@
512190286Sobrien   fild%z1\t%1
512290286Sobrien   #
512390286Sobrien   cvtsi2ss{q}\t{%1, %0|%0, %1}"
512490286Sobrien  [(set_attr "type" "fmov,multi,sse")
512590286Sobrien   (set_attr "mode" "SF")
512690286Sobrien   (set_attr "fp_int_src" "true")])
512752296Sobrien
512890286Sobrien(define_insn "*floatdisf2_sse"
512990286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
513090286Sobrien	(float:SF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
513190286Sobrien  "TARGET_64BIT && TARGET_SSE"
513290286Sobrien  "cvtsi2ss{q}\t{%1, %0|%0, %1}"
513390286Sobrien  [(set_attr "type" "sse")
513490286Sobrien   (set_attr "mode" "SF")
513590286Sobrien   (set_attr "fp_int_src" "true")])
513690286Sobrien
513790286Sobrien(define_insn "floathidf2"
513852296Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
513990286Sobrien	(float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
514090286Sobrien  "TARGET_80387 && !TARGET_SSE2"
514190286Sobrien  "@
514290286Sobrien   fild%z1\t%1
514390286Sobrien   #"
514490286Sobrien  [(set_attr "type" "fmov,multi")
514590286Sobrien   (set_attr "mode" "DF")
514690286Sobrien   (set_attr "fp_int_src" "true")])
514752296Sobrien
514890286Sobrien(define_expand "floatsidf2"
514918334Speter  [(set (match_operand:DF 0 "register_operand" "")
515090286Sobrien	(float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
515196294Sobrien  "TARGET_80387 || TARGET_SSE2"
515252296Sobrien  "")
515352296Sobrien
515490286Sobrien(define_insn "*floatsidf2_i387"
515590286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
515690286Sobrien	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
515790286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
515890286Sobrien  "@
515990286Sobrien   fild%z1\t%1
516090286Sobrien   #
516190286Sobrien   cvtsi2sd\t{%1, %0|%0, %1}"
516290286Sobrien  [(set_attr "type" "fmov,multi,sse")
516390286Sobrien   (set_attr "mode" "DF")
516490286Sobrien   (set_attr "fp_int_src" "true")])
516590286Sobrien
516690286Sobrien(define_insn "*floatsidf2_sse"
516790286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
516890286Sobrien	(float:DF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
516990286Sobrien  "TARGET_SSE2"
517090286Sobrien  "cvtsi2sd\t{%1, %0|%0, %1}"
517190286Sobrien  [(set_attr "type" "sse")
517290286Sobrien   (set_attr "mode" "DF")
517390286Sobrien   (set_attr "fp_int_src" "true")])
517490286Sobrien
517590286Sobrien(define_expand "floatdidf2"
517652296Sobrien  [(set (match_operand:DF 0 "register_operand" "")
517790286Sobrien	(float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
517890286Sobrien  "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
517952296Sobrien  "")
518052296Sobrien
518190286Sobrien(define_insn "*floatdidf2_i387_only"
518290286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,?f")
518390286Sobrien	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
518490286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
518590286Sobrien  "@
518690286Sobrien   fild%z1\t%1
518790286Sobrien   #"
518890286Sobrien  [(set_attr "type" "fmov,multi")
518990286Sobrien   (set_attr "mode" "DF")
519090286Sobrien   (set_attr "fp_int_src" "true")])
519190286Sobrien
519290286Sobrien(define_insn "*floatdidf2_i387"
519390286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
519490286Sobrien	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
519590286Sobrien  "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
519690286Sobrien  "@
519790286Sobrien   fild%z1\t%1
519890286Sobrien   #
519990286Sobrien   cvtsi2sd{q}\t{%1, %0|%0, %1}"
520090286Sobrien  [(set_attr "type" "fmov,multi,sse")
520190286Sobrien   (set_attr "mode" "DF")
520290286Sobrien   (set_attr "fp_int_src" "true")])
520390286Sobrien
520490286Sobrien(define_insn "*floatdidf2_sse"
520590286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
520690286Sobrien	(float:DF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
520790286Sobrien  "TARGET_SSE2"
520890286Sobrien  "cvtsi2sd{q}\t{%1, %0|%0, %1}"
520990286Sobrien  [(set_attr "type" "sse")
521090286Sobrien   (set_attr "mode" "DF")
521190286Sobrien   (set_attr "fp_int_src" "true")])
521290286Sobrien
521390286Sobrien(define_insn "floathixf2"
521490286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
521590286Sobrien	(float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
521690286Sobrien  "!TARGET_64BIT && TARGET_80387"
521790286Sobrien  "@
521890286Sobrien   fild%z1\t%1
521990286Sobrien   #"
522090286Sobrien  [(set_attr "type" "fmov,multi")
522190286Sobrien   (set_attr "mode" "XF")
522290286Sobrien   (set_attr "fp_int_src" "true")])
522390286Sobrien
522490286Sobrien(define_insn "floathitf2"
522590286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
522690286Sobrien	(float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
522718334Speter  "TARGET_80387"
522890286Sobrien  "@
522990286Sobrien   fild%z1\t%1
523090286Sobrien   #"
523190286Sobrien  [(set_attr "type" "fmov,multi")
523290286Sobrien   (set_attr "mode" "XF")
523390286Sobrien   (set_attr "fp_int_src" "true")])
523452296Sobrien
523590286Sobrien(define_insn "floatsixf2"
523690286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
523790286Sobrien	(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
523890286Sobrien  "!TARGET_64BIT && TARGET_80387"
523990286Sobrien  "@
524090286Sobrien   fild%z1\t%1
524190286Sobrien   #"
524290286Sobrien  [(set_attr "type" "fmov,multi")
524390286Sobrien   (set_attr "mode" "XF")
524490286Sobrien   (set_attr "fp_int_src" "true")])
524590286Sobrien
524690286Sobrien(define_insn "floatsitf2"
524790286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
524890286Sobrien	(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
524952296Sobrien  "TARGET_80387"
525090286Sobrien  "@
525190286Sobrien   fild%z1\t%1
525290286Sobrien   #"
525390286Sobrien  [(set_attr "type" "fmov,multi")
525490286Sobrien   (set_attr "mode" "XF")
525590286Sobrien   (set_attr "fp_int_src" "true")])
525652296Sobrien
525790286Sobrien(define_insn "floatdixf2"
525890286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
525990286Sobrien	(float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
526090286Sobrien  "!TARGET_64BIT && TARGET_80387"
526190286Sobrien  "@
526290286Sobrien   fild%z1\t%1
526390286Sobrien   #"
526490286Sobrien  [(set_attr "type" "fmov,multi")
526590286Sobrien   (set_attr "mode" "XF")
526690286Sobrien   (set_attr "fp_int_src" "true")])
526790286Sobrien
526890286Sobrien(define_insn "floatditf2"
526990286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
527090286Sobrien	(float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
527152296Sobrien  "TARGET_80387"
527290286Sobrien  "@
527390286Sobrien   fild%z1\t%1
527490286Sobrien   #"
527590286Sobrien  [(set_attr "type" "fmov,multi")
527690286Sobrien   (set_attr "mode" "XF")
527790286Sobrien   (set_attr "fp_int_src" "true")])
527852296Sobrien
527990286Sobrien;; %%% Kill these when reload knows how to do it.
528052296Sobrien(define_split
528190286Sobrien  [(set (match_operand 0 "register_operand" "")
528290286Sobrien	(float (match_operand 1 "register_operand" "")))]
528390286Sobrien  "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))
528490286Sobrien   && FP_REG_P (operands[0])"
528590286Sobrien  [(const_int 0)]
528690286Sobrien{
528790286Sobrien  operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
528890286Sobrien  operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
528990286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
529090286Sobrien  ix86_free_from_memory (GET_MODE (operands[1]));
529190286Sobrien  DONE;
529290286Sobrien})
529390286Sobrien
529490286Sobrien;; Add instructions
529518334Speter
529690286Sobrien;; %%% splits for addsidi3
529790286Sobrien;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
529890286Sobrien;	(plus:DI (match_operand:DI 1 "general_operand" "")
529990286Sobrien;		 (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
530052296Sobrien
530190286Sobrien(define_expand "adddi3"
530290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
530390286Sobrien	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
530490286Sobrien		 (match_operand:DI 2 "x86_64_general_operand" "")))
530590286Sobrien   (clobber (reg:CC 17))]
530690286Sobrien  ""
530790286Sobrien  "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
530852296Sobrien
530990286Sobrien(define_insn "*adddi3_1"
531090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
531190286Sobrien	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
531290286Sobrien		 (match_operand:DI 2 "general_operand" "roiF,riF")))
531390286Sobrien   (clobber (reg:CC 17))]
5314107605Sobrien  "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
531552296Sobrien  "#")
531652296Sobrien
531752296Sobrien(define_split
531890286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
531990286Sobrien	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
532090286Sobrien		 (match_operand:DI 2 "general_operand" "")))
532190286Sobrien   (clobber (reg:CC 17))]
532290286Sobrien  "!TARGET_64BIT && reload_completed"
532390286Sobrien  [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)] 12))
532490286Sobrien	      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
532590286Sobrien   (parallel [(set (match_dup 3)
532690286Sobrien		   (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
532790286Sobrien				     (match_dup 4))
532890286Sobrien			    (match_dup 5)))
532990286Sobrien	      (clobber (reg:CC 17))])]
533090286Sobrien  "split_di (operands+0, 1, operands+0, operands+3);
533190286Sobrien   split_di (operands+1, 1, operands+1, operands+4);
533290286Sobrien   split_di (operands+2, 1, operands+2, operands+5);")
533318334Speter
533490286Sobrien(define_insn "*adddi3_carry_rex64"
533590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
533690286Sobrien	  (plus:DI (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
533790286Sobrien			    (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
533890286Sobrien		   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
533990286Sobrien   (clobber (reg:CC 17))]
534090286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
534190286Sobrien  "adc{q}\t{%2, %0|%0, %2}"
534290286Sobrien  [(set_attr "type" "alu")
534390286Sobrien   (set_attr "pent_pair" "pu")
534490286Sobrien   (set_attr "mode" "DI")
534590286Sobrien   (set_attr "ppro_uops" "few")])
534652296Sobrien
534790286Sobrien(define_insn "*adddi3_cc_rex64"
534890286Sobrien  [(set (reg:CC 17) (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
534990286Sobrien				(match_operand:DI 2 "x86_64_general_operand" "re,rm")] 12))
535090286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
535190286Sobrien	(plus:DI (match_dup 1) (match_dup 2)))]
535290286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
535390286Sobrien  "add{q}\t{%2, %0|%0, %2}"
535490286Sobrien  [(set_attr "type" "alu")
535590286Sobrien   (set_attr "mode" "DI")])
535652296Sobrien
535790286Sobrien(define_insn "*addsi3_carry"
535890286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
535990286Sobrien	  (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
536090286Sobrien			    (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
536190286Sobrien		   (match_operand:SI 2 "general_operand" "ri,rm")))
536290286Sobrien   (clobber (reg:CC 17))]
536390286Sobrien  "ix86_binary_operator_ok (PLUS, SImode, operands)"
536490286Sobrien  "adc{l}\t{%2, %0|%0, %2}"
536590286Sobrien  [(set_attr "type" "alu")
536690286Sobrien   (set_attr "pent_pair" "pu")
536790286Sobrien   (set_attr "mode" "SI")
536890286Sobrien   (set_attr "ppro_uops" "few")])
536952296Sobrien
537090286Sobrien(define_insn "*addsi3_carry_zext"
537190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
537290286Sobrien	  (zero_extend:DI 
537390286Sobrien	    (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
537490286Sobrien			      (match_operand:SI 1 "nonimmediate_operand" "%0"))
537590286Sobrien		     (match_operand:SI 2 "general_operand" "rim"))))
537690286Sobrien   (clobber (reg:CC 17))]
537790286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
537890286Sobrien  "adc{l}\t{%2, %k0|%k0, %2}"
537990286Sobrien  [(set_attr "type" "alu")
538090286Sobrien   (set_attr "pent_pair" "pu")
538190286Sobrien   (set_attr "mode" "SI")
538290286Sobrien   (set_attr "ppro_uops" "few")])
538352296Sobrien
538490286Sobrien(define_insn "*addsi3_cc"
538590286Sobrien  [(set (reg:CC 17) (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
538690286Sobrien			        (match_operand:SI 2 "general_operand" "ri,rm")] 12))
538790286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
538890286Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
538990286Sobrien  "ix86_binary_operator_ok (PLUS, SImode, operands)"
539090286Sobrien  "add{l}\t{%2, %0|%0, %2}"
539190286Sobrien  [(set_attr "type" "alu")
539290286Sobrien   (set_attr "mode" "SI")])
539318334Speter
539490286Sobrien(define_insn "addqi3_cc"
539590286Sobrien  [(set (reg:CC 17) (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
539690286Sobrien			        (match_operand:QI 2 "general_operand" "qi,qm")] 12))
539790286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
539890286Sobrien	(plus:QI (match_dup 1) (match_dup 2)))]
539990286Sobrien  "ix86_binary_operator_ok (PLUS, QImode, operands)"
540090286Sobrien  "add{b}\t{%2, %0|%0, %2}"
540190286Sobrien  [(set_attr "type" "alu")
540290286Sobrien   (set_attr "mode" "QI")])
540318334Speter
540490286Sobrien(define_expand "addsi3"
540590286Sobrien  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
540690286Sobrien		   (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
540790286Sobrien			    (match_operand:SI 2 "general_operand" "")))
540890286Sobrien	      (clobber (reg:CC 17))])]
540990286Sobrien  ""
541090286Sobrien  "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
541118334Speter
541290286Sobrien(define_insn "*lea_1"
541390286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
541490286Sobrien	(match_operand:SI 1 "address_operand" "p"))]
541590286Sobrien  "!TARGET_64BIT"
541690286Sobrien  "lea{l}\t{%a1, %0|%0, %a1}"
541790286Sobrien  [(set_attr "type" "lea")
541890286Sobrien   (set_attr "mode" "SI")])
541918334Speter
542090286Sobrien(define_insn "*lea_1_rex64"
542190286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
542290286Sobrien	(subreg:SI (match_operand:DI 1 "address_operand" "p") 0))]
542390286Sobrien  "TARGET_64BIT"
542490286Sobrien  "lea{l}\t{%a1, %0|%0, %a1}"
542590286Sobrien  [(set_attr "type" "lea")
542690286Sobrien   (set_attr "mode" "SI")])
542718334Speter
542890286Sobrien(define_insn "*lea_1_zext"
542990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
543090286Sobrien	(zero_extend:DI (subreg:SI (match_operand:DI 1 "address_operand" "p") 0)))]
543190286Sobrien  "TARGET_64BIT"
543290286Sobrien  "lea{l}\t{%a1, %k0|%k0, %a1}"
543390286Sobrien  [(set_attr "type" "lea")
543490286Sobrien   (set_attr "mode" "SI")])
543590286Sobrien
543690286Sobrien(define_insn "*lea_2_rex64"
543790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
543890286Sobrien	(match_operand:DI 1 "address_operand" "p"))]
543990286Sobrien  "TARGET_64BIT"
544090286Sobrien  "lea{q}\t{%a1, %0|%0, %a1}"
544190286Sobrien  [(set_attr "type" "lea")
544290286Sobrien   (set_attr "mode" "DI")])
544390286Sobrien
544490286Sobrien;; The lea patterns for non-Pmodes needs to be matched by several
544590286Sobrien;; insns converted to real lea by splitters.
544690286Sobrien
544790286Sobrien(define_insn_and_split "*lea_general_1"
544890286Sobrien  [(set (match_operand 0 "register_operand" "=r")
544990286Sobrien	(plus (plus (match_operand 1 "register_operand" "r")
545090286Sobrien		    (match_operand 2 "register_operand" "r"))
545190286Sobrien	      (match_operand 3 "immediate_operand" "i")))]
545290286Sobrien  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
545390286Sobrien    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
545490286Sobrien   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
545590286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])
545690286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[2])
545790286Sobrien   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
545890286Sobrien       || GET_MODE (operands[3]) == VOIDmode)"
545990286Sobrien  "#"
546090286Sobrien  "&& reload_completed"
546190286Sobrien  [(const_int 0)]
546290286Sobrien{
546390286Sobrien  rtx pat;
546490286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
546590286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
546690286Sobrien  operands[2] = gen_lowpart (Pmode, operands[2]);
546790286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
546890286Sobrien  pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
546990286Sobrien  		      operands[3]);
547090286Sobrien  if (Pmode != SImode)
547190286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
547290286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
547390286Sobrien  DONE;
547490286Sobrien}
547590286Sobrien  [(set_attr "type" "lea")
547690286Sobrien   (set_attr "mode" "SI")])
547790286Sobrien
547890286Sobrien(define_insn_and_split "*lea_general_1_zext"
547990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
548090286Sobrien	(zero_extend:DI
548190286Sobrien	  (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
548290286Sobrien			    (match_operand:SI 2 "register_operand" "r"))
548390286Sobrien		   (match_operand:SI 3 "immediate_operand" "i"))))]
548490286Sobrien  "TARGET_64BIT"
548590286Sobrien  "#"
548690286Sobrien  "&& reload_completed"
548752296Sobrien  [(set (match_dup 0)
548890286Sobrien	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
548990286Sobrien						     (match_dup 2))
549090286Sobrien					    (match_dup 3)) 0)))]
549190286Sobrien{
549290286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
549390286Sobrien  operands[2] = gen_lowpart (Pmode, operands[2]);
549490286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
549590286Sobrien}
549690286Sobrien  [(set_attr "type" "lea")
549790286Sobrien   (set_attr "mode" "SI")])
549852296Sobrien
549990286Sobrien(define_insn_and_split "*lea_general_2"
550090286Sobrien  [(set (match_operand 0 "register_operand" "=r")
550190286Sobrien	(plus (mult (match_operand 1 "register_operand" "r")
550290286Sobrien		    (match_operand 2 "const248_operand" "i"))
550390286Sobrien	      (match_operand 3 "nonmemory_operand" "ri")))]
550490286Sobrien  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
550590286Sobrien    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
550690286Sobrien   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
550790286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])
550890286Sobrien   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
550990286Sobrien       || GET_MODE (operands[3]) == VOIDmode)"
551090286Sobrien  "#"
551190286Sobrien  "&& reload_completed"
551290286Sobrien  [(const_int 0)]
551390286Sobrien{
551490286Sobrien  rtx pat;
551590286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
551690286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
551790286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
551890286Sobrien  pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
551990286Sobrien  		      operands[3]);
552090286Sobrien  if (Pmode != SImode)
552190286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
552290286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
552390286Sobrien  DONE;
552490286Sobrien}
552590286Sobrien  [(set_attr "type" "lea")
552690286Sobrien   (set_attr "mode" "SI")])
552752296Sobrien
552890286Sobrien(define_insn_and_split "*lea_general_2_zext"
552990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
553090286Sobrien	(zero_extend:DI
553190286Sobrien	  (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
553290286Sobrien			    (match_operand:SI 2 "const248_operand" "n"))
553390286Sobrien		   (match_operand:SI 3 "nonmemory_operand" "ri"))))]
553490286Sobrien  "TARGET_64BIT"
553590286Sobrien  "#"
553690286Sobrien  "&& reload_completed"
553790286Sobrien  [(set (match_dup 0)
553890286Sobrien	(zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
553990286Sobrien						     (match_dup 2))
554090286Sobrien					    (match_dup 3)) 0)))]
554190286Sobrien{
554290286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
554390286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
554490286Sobrien}
554590286Sobrien  [(set_attr "type" "lea")
554690286Sobrien   (set_attr "mode" "SI")])
554718334Speter
554890286Sobrien(define_insn_and_split "*lea_general_3"
554990286Sobrien  [(set (match_operand 0 "register_operand" "=r")
555090286Sobrien	(plus (plus (mult (match_operand 1 "register_operand" "r")
555190286Sobrien			  (match_operand 2 "const248_operand" "i"))
555290286Sobrien		    (match_operand 3 "register_operand" "r"))
555390286Sobrien	      (match_operand 4 "immediate_operand" "i")))]
555490286Sobrien  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
555590286Sobrien    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
555690286Sobrien   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
555790286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[1])
555890286Sobrien   && GET_MODE (operands[0]) == GET_MODE (operands[3])"
555990286Sobrien  "#"
556090286Sobrien  "&& reload_completed"
556190286Sobrien  [(const_int 0)]
556290286Sobrien{
556390286Sobrien  rtx pat;
556490286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
556590286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
556690286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
556790286Sobrien  operands[4] = gen_lowpart (Pmode, operands[4]);
556890286Sobrien  pat = gen_rtx_PLUS (Pmode,
556990286Sobrien  		      gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
557090286Sobrien		      					 operands[2]),
557190286Sobrien				    operands[3]),
557290286Sobrien  		      operands[4]);
557390286Sobrien  if (Pmode != SImode)
557490286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
557590286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
557690286Sobrien  DONE;
557790286Sobrien}
557890286Sobrien  [(set_attr "type" "lea")
557990286Sobrien   (set_attr "mode" "SI")])
558052296Sobrien
558190286Sobrien(define_insn_and_split "*lea_general_3_zext"
558290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
558390286Sobrien	(zero_extend:DI
558490286Sobrien	  (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
558590286Sobrien				     (match_operand:SI 2 "const248_operand" "n"))
558690286Sobrien			    (match_operand:SI 3 "register_operand" "r"))
558790286Sobrien		   (match_operand:SI 4 "immediate_operand" "i"))))]
558890286Sobrien  "TARGET_64BIT"
558990286Sobrien  "#"
559090286Sobrien  "&& reload_completed"
559190286Sobrien  [(set (match_dup 0)
559290286Sobrien	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
559390286Sobrien							      (match_dup 2))
559490286Sobrien						     (match_dup 3))
559590286Sobrien					    (match_dup 4)) 0)))]
559690286Sobrien{
559790286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
559890286Sobrien  operands[3] = gen_lowpart (Pmode, operands[3]);
559990286Sobrien  operands[4] = gen_lowpart (Pmode, operands[4]);
560090286Sobrien}
560190286Sobrien  [(set_attr "type" "lea")
560290286Sobrien   (set_attr "mode" "SI")])
560318334Speter
560490286Sobrien(define_insn "*adddi_1_rex64"
560590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
560690286Sobrien	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
560790286Sobrien		 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
560890286Sobrien   (clobber (reg:CC 17))]
560990286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
561090286Sobrien{
561190286Sobrien  switch (get_attr_type (insn))
561290286Sobrien    {
561390286Sobrien    case TYPE_LEA:
561490286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
561590286Sobrien      return "lea{q}\t{%a2, %0|%0, %a2}";
561690286Sobrien
561790286Sobrien    case TYPE_INCDEC:
561890286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
561990286Sobrien	abort ();
562090286Sobrien      if (operands[2] == const1_rtx)
562190286Sobrien        return "inc{q}\t%0";
562290286Sobrien      else if (operands[2] == constm1_rtx)
562390286Sobrien        return "dec{q}\t%0";
562490286Sobrien      else
562590286Sobrien	abort ();
562690286Sobrien
562790286Sobrien    default:
562890286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
562990286Sobrien	abort ();
563090286Sobrien
563190286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
563290286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
563390286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
563490286Sobrien	  /* Avoid overflows.  */
563590286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
563690286Sobrien          && (INTVAL (operands[2]) == 128
563790286Sobrien	      || (INTVAL (operands[2]) < 0
563890286Sobrien		  && INTVAL (operands[2]) != -128)))
563990286Sobrien        {
564090286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
564190286Sobrien          return "sub{q}\t{%2, %0|%0, %2}";
564290286Sobrien        }
564390286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
564490286Sobrien    }
564590286Sobrien}
564690286Sobrien  [(set (attr "type")
564790286Sobrien     (cond [(eq_attr "alternative" "2")
564890286Sobrien	      (const_string "lea")
564990286Sobrien	    ; Current assemblers are broken and do not allow @GOTOFF in
565090286Sobrien	    ; ought but a memory context.
565190286Sobrien	    (match_operand:DI 2 "pic_symbolic_operand" "")
565290286Sobrien	      (const_string "lea")
565390286Sobrien	    (match_operand:DI 2 "incdec_operand" "")
565490286Sobrien	      (const_string "incdec")
565590286Sobrien	   ]
565690286Sobrien	   (const_string "alu")))
565790286Sobrien   (set_attr "mode" "DI")])
565890286Sobrien
565990286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
566052296Sobrien(define_split
566190286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
566290286Sobrien	(plus:DI (match_operand:DI 1 "register_operand" "")
566390286Sobrien		 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
566490286Sobrien   (clobber (reg:CC 17))]
566590286Sobrien  "TARGET_64BIT && reload_completed
566690286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
566752296Sobrien  [(set (match_dup 0)
566890286Sobrien	(plus:DI (match_dup 1)
566990286Sobrien		 (match_dup 2)))]
567052296Sobrien  "")
567152296Sobrien
567290286Sobrien(define_insn "*adddi_2_rex64"
567390286Sobrien  [(set (reg 17)
567490286Sobrien	(compare
567590286Sobrien	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
567690286Sobrien		   (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
567790286Sobrien	  (const_int 0)))			
567890286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
567990286Sobrien	(plus:DI (match_dup 1) (match_dup 2)))]
568090286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
568190286Sobrien   && ix86_binary_operator_ok (PLUS, DImode, operands)
568290286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
568390286Sobrien      ought but a memory context.  */
568490286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
568590286Sobrien{
568690286Sobrien  switch (get_attr_type (insn))
568790286Sobrien    {
568890286Sobrien    case TYPE_INCDEC:
568990286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
569090286Sobrien	abort ();
569190286Sobrien      if (operands[2] == const1_rtx)
569290286Sobrien        return "inc{q}\t%0";
569390286Sobrien      else if (operands[2] == constm1_rtx)
569490286Sobrien        return "dec{q}\t%0";
569590286Sobrien      else
569690286Sobrien	abort ();
569752296Sobrien
569890286Sobrien    default:
569990286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
570090286Sobrien	abort ();
570190286Sobrien      /* ???? We ought to handle there the 32bit case too
570290286Sobrien	 - do we need new constrant?  */
570390286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
570490286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
570590286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
570690286Sobrien	  /* Avoid overflows.  */
570790286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
570890286Sobrien          && (INTVAL (operands[2]) == 128
570990286Sobrien	      || (INTVAL (operands[2]) < 0
571090286Sobrien		  && INTVAL (operands[2]) != -128)))
571190286Sobrien        {
571290286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
571390286Sobrien          return "sub{q}\t{%2, %0|%0, %2}";
571490286Sobrien        }
571590286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
571690286Sobrien    }
571790286Sobrien}
571890286Sobrien  [(set (attr "type")
571990286Sobrien     (if_then_else (match_operand:DI 2 "incdec_operand" "")
572090286Sobrien	(const_string "incdec")
572190286Sobrien	(const_string "alu")))
572290286Sobrien   (set_attr "mode" "DI")])
572318334Speter
572490286Sobrien(define_insn "*adddi_3_rex64"
572590286Sobrien  [(set (reg 17)
572690286Sobrien	(compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
572790286Sobrien		 (match_operand:DI 1 "x86_64_general_operand" "%0")))
572890286Sobrien   (clobber (match_scratch:DI 0 "=r"))]
572990286Sobrien  "TARGET_64BIT
573090286Sobrien   && ix86_match_ccmode (insn, CCZmode)
573190286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
573290286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
573390286Sobrien      ought but a memory context.  */
573490286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
573550650Sobrien{
573690286Sobrien  switch (get_attr_type (insn))
573790286Sobrien    {
573890286Sobrien    case TYPE_INCDEC:
573990286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
574090286Sobrien	abort ();
574190286Sobrien      if (operands[2] == const1_rtx)
574290286Sobrien        return "inc{q}\t%0";
574390286Sobrien      else if (operands[2] == constm1_rtx)
574490286Sobrien        return "dec{q}\t%0";
574590286Sobrien      else
574690286Sobrien	abort ();
574750650Sobrien
574890286Sobrien    default:
574990286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
575090286Sobrien	abort ();
575190286Sobrien      /* ???? We ought to handle there the 32bit case too
575290286Sobrien	 - do we need new constrant?  */
575390286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
575490286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
575590286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
575690286Sobrien	  /* Avoid overflows.  */
575790286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
575890286Sobrien          && (INTVAL (operands[2]) == 128
575990286Sobrien	      || (INTVAL (operands[2]) < 0
576090286Sobrien		  && INTVAL (operands[2]) != -128)))
576190286Sobrien        {
576290286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
576390286Sobrien          return "sub{q}\t{%2, %0|%0, %2}";
576490286Sobrien        }
576590286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
576690286Sobrien    }
576790286Sobrien}
576890286Sobrien  [(set (attr "type")
576990286Sobrien     (if_then_else (match_operand:DI 2 "incdec_operand" "")
577090286Sobrien	(const_string "incdec")
577190286Sobrien	(const_string "alu")))
577290286Sobrien   (set_attr "mode" "DI")])
577350650Sobrien
577490286Sobrien; For comparisons against 1, -1 and 128, we may generate better code
577590286Sobrien; by converting cmp to add, inc or dec as done by peephole2.  This pattern
577690286Sobrien; is matched then.  We can't accept general immediate, because for
577790286Sobrien; case of overflows,  the result is messed up.
577890286Sobrien; This pattern also don't hold of 0x8000000000000000, since the value overflows
577990286Sobrien; when negated.
578090286Sobrien; Also carry flag is reversed compared to cmp, so this conversion is valid
578190286Sobrien; only for comparisons not depending on it.
578290286Sobrien(define_insn "*adddi_4_rex64"
578390286Sobrien  [(set (reg 17)
578490286Sobrien	(compare (match_operand:DI 1 "nonimmediate_operand" "0")
578590286Sobrien		 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
578690286Sobrien   (clobber (match_scratch:DI 0 "=rm"))]
578790286Sobrien  "TARGET_64BIT
578890286Sobrien   &&  ix86_match_ccmode (insn, CCGCmode)"
578990286Sobrien{
579090286Sobrien  switch (get_attr_type (insn))
579190286Sobrien    {
579290286Sobrien    case TYPE_INCDEC:
579390286Sobrien      if (operands[2] == constm1_rtx)
579490286Sobrien        return "inc{q}\t%0";
579590286Sobrien      else if (operands[2] == const1_rtx)
579690286Sobrien        return "dec{q}\t%0";
579790286Sobrien      else
579890286Sobrien	abort();
579950650Sobrien
580090286Sobrien    default:
580190286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
580290286Sobrien	abort ();
580390286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
580490286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
580590286Sobrien      if ((INTVAL (operands[2]) == -128
580690286Sobrien	   || (INTVAL (operands[2]) > 0
580790286Sobrien	       && INTVAL (operands[2]) != 128))
580890286Sobrien	  /* Avoid overflows.  */
580990286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
581090286Sobrien	return "sub{q}\t{%2, %0|%0, %2}";
581190286Sobrien      operands[2] = GEN_INT (-INTVAL (operands[2]));
581290286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
581390286Sobrien    }
581490286Sobrien}
581590286Sobrien  [(set (attr "type")
581690286Sobrien     (if_then_else (match_operand:DI 2 "incdec_operand" "")
581790286Sobrien	(const_string "incdec")
581890286Sobrien	(const_string "alu")))
581990286Sobrien   (set_attr "mode" "DI")])
582090286Sobrien
582190286Sobrien(define_insn "*adddi_5_rex64"
582290286Sobrien  [(set (reg 17)
582390286Sobrien	(compare
582490286Sobrien	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
582590286Sobrien		   (match_operand:DI 2 "x86_64_general_operand" "rme"))
582690286Sobrien	  (const_int 0)))			
582790286Sobrien   (clobber (match_scratch:DI 0 "=r"))]
582890286Sobrien  "TARGET_64BIT
582990286Sobrien   && ix86_match_ccmode (insn, CCGOCmode)
583090286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
583190286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
583290286Sobrien      ought but a memory context.  */
583390286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
583490286Sobrien{
583590286Sobrien  switch (get_attr_type (insn))
583650650Sobrien    {
583790286Sobrien    case TYPE_INCDEC:
583890286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
583990286Sobrien	abort ();
584090286Sobrien      if (operands[2] == const1_rtx)
584190286Sobrien        return "inc{q}\t%0";
584290286Sobrien      else if (operands[2] == constm1_rtx)
584390286Sobrien        return "dec{q}\t%0";
584490286Sobrien      else
584590286Sobrien	abort();
584650650Sobrien
584790286Sobrien    default:
584890286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
584990286Sobrien	abort ();
585090286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
585190286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
585290286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
585390286Sobrien	  /* Avoid overflows.  */
585490286Sobrien	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
585590286Sobrien          && (INTVAL (operands[2]) == 128
585690286Sobrien	      || (INTVAL (operands[2]) < 0
585790286Sobrien		  && INTVAL (operands[2]) != -128)))
585890286Sobrien        {
585990286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
586090286Sobrien          return "sub{q}\t{%2, %0|%0, %2}";
586190286Sobrien        }
586290286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
586350650Sobrien    }
586490286Sobrien}
586590286Sobrien  [(set (attr "type")
586690286Sobrien     (if_then_else (match_operand:DI 2 "incdec_operand" "")
586790286Sobrien	(const_string "incdec")
586890286Sobrien	(const_string "alu")))
586990286Sobrien   (set_attr "mode" "DI")])
587050650Sobrien
587150650Sobrien
587290286Sobrien(define_insn "*addsi_1"
587390286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
587490286Sobrien	(plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
587590286Sobrien		 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
587690286Sobrien   (clobber (reg:CC 17))]
587790286Sobrien  "ix86_binary_operator_ok (PLUS, SImode, operands)"
587850650Sobrien{
587990286Sobrien  switch (get_attr_type (insn))
588090286Sobrien    {
588190286Sobrien    case TYPE_LEA:
588290286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
588390286Sobrien      return "lea{l}\t{%a2, %0|%0, %a2}";
588450650Sobrien
588590286Sobrien    case TYPE_INCDEC:
588690286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
588790286Sobrien	abort ();
588890286Sobrien      if (operands[2] == const1_rtx)
588990286Sobrien        return "inc{l}\t%0";
589090286Sobrien      else if (operands[2] == constm1_rtx)
589190286Sobrien        return "dec{l}\t%0";
589290286Sobrien      else
589390286Sobrien	abort();
589450650Sobrien
589590286Sobrien    default:
589690286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
589790286Sobrien	abort ();
589850650Sobrien
589990286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
590090286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
590190286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
590290286Sobrien          && (INTVAL (operands[2]) == 128
590390286Sobrien	      || (INTVAL (operands[2]) < 0
590490286Sobrien		  && INTVAL (operands[2]) != -128)))
590590286Sobrien        {
590690286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
590790286Sobrien          return "sub{l}\t{%2, %0|%0, %2}";
590890286Sobrien        }
590990286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
591090286Sobrien    }
591190286Sobrien}
591290286Sobrien  [(set (attr "type")
591390286Sobrien     (cond [(eq_attr "alternative" "2")
591490286Sobrien	      (const_string "lea")
591590286Sobrien	    ; Current assemblers are broken and do not allow @GOTOFF in
591690286Sobrien	    ; ought but a memory context.
591790286Sobrien	    (match_operand:SI 2 "pic_symbolic_operand" "")
591890286Sobrien	      (const_string "lea")
591990286Sobrien	    (match_operand:SI 2 "incdec_operand" "")
592090286Sobrien	      (const_string "incdec")
592190286Sobrien	   ]
592290286Sobrien	   (const_string "alu")))
592390286Sobrien   (set_attr "mode" "SI")])
592490286Sobrien
592590286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
592690286Sobrien(define_split
592790286Sobrien  [(set (match_operand 0 "register_operand" "")
592890286Sobrien	(plus (match_operand 1 "register_operand" "")
592990286Sobrien              (match_operand 2 "nonmemory_operand" "")))
593090286Sobrien   (clobber (reg:CC 17))]
593190286Sobrien  "reload_completed
593290286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
593390286Sobrien  [(const_int 0)]
593490286Sobrien{
593590286Sobrien  rtx pat;
593690286Sobrien  /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
593790286Sobrien     may confuse gen_lowpart.  */
593890286Sobrien  if (GET_MODE (operands[0]) != Pmode)
593950650Sobrien    {
594090286Sobrien      operands[1] = gen_lowpart (Pmode, operands[1]);
594190286Sobrien      operands[2] = gen_lowpart (Pmode, operands[2]);
594290286Sobrien    }
594390286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
594490286Sobrien  pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
594590286Sobrien  if (Pmode != SImode)
594690286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
594790286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
594890286Sobrien  DONE;
594990286Sobrien})
595050650Sobrien
595190286Sobrien;; It may seem that nonimmediate operand is proper one for operand 1.
595290286Sobrien;; The addsi_1 pattern allows nonimmediate operand at that place and
595390286Sobrien;; we take care in ix86_binary_operator_ok to not allow two memory
595490286Sobrien;; operands so proper swapping will be done in reload.  This allow
595590286Sobrien;; patterns constructed from addsi_1 to match.
595690286Sobrien(define_insn "addsi_1_zext"
595790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
595890286Sobrien	(zero_extend:DI
595990286Sobrien	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
596090286Sobrien		   (match_operand:SI 2 "general_operand" "rmni,rni"))))
596190286Sobrien   (clobber (reg:CC 17))]
596290286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
596390286Sobrien{
596490286Sobrien  switch (get_attr_type (insn))
596590286Sobrien    {
596690286Sobrien    case TYPE_LEA:
596790286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
596890286Sobrien      return "lea{l}\t{%a2, %k0|%k0, %a2}";
596990286Sobrien
597090286Sobrien    case TYPE_INCDEC:
597190286Sobrien      if (operands[2] == const1_rtx)
597290286Sobrien        return "inc{l}\t%k0";
597390286Sobrien      else if (operands[2] == constm1_rtx)
597490286Sobrien        return "dec{l}\t%k0";
597550650Sobrien      else
597690286Sobrien	abort();
597790286Sobrien
597890286Sobrien    default:
597990286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
598090286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
598190286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
598290286Sobrien          && (INTVAL (operands[2]) == 128
598390286Sobrien	      || (INTVAL (operands[2]) < 0
598490286Sobrien		  && INTVAL (operands[2]) != -128)))
598590286Sobrien        {
598690286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
598790286Sobrien          return "sub{l}\t{%2, %k0|%k0, %2}";
598890286Sobrien        }
598990286Sobrien      return "add{l}\t{%2, %k0|%k0, %2}";
599050650Sobrien    }
599190286Sobrien}
599290286Sobrien  [(set (attr "type")
599390286Sobrien     (cond [(eq_attr "alternative" "1")
599490286Sobrien	      (const_string "lea")
599590286Sobrien	    ; Current assemblers are broken and do not allow @GOTOFF in
599690286Sobrien	    ; ought but a memory context.
599790286Sobrien	    (match_operand:SI 2 "pic_symbolic_operand" "")
599890286Sobrien	      (const_string "lea")
599990286Sobrien	    (match_operand:SI 2 "incdec_operand" "")
600090286Sobrien	      (const_string "incdec")
600190286Sobrien	   ]
600290286Sobrien	   (const_string "alu")))
600390286Sobrien   (set_attr "mode" "SI")])
600450650Sobrien
600590286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
600690286Sobrien(define_split
600790286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
600890286Sobrien	(zero_extend:DI
600990286Sobrien	  (plus:SI (match_operand:SI 1 "register_operand" "")
601090286Sobrien		   (match_operand:SI 2 "nonmemory_operand" ""))))
601190286Sobrien   (clobber (reg:CC 17))]
601290286Sobrien  "reload_completed
601390286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
601490286Sobrien  [(set (match_dup 0)
601590286Sobrien	(zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
601690286Sobrien{
601790286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
601890286Sobrien  operands[2] = gen_lowpart (Pmode, operands[2]);
601990286Sobrien})
602050650Sobrien
602190286Sobrien(define_insn "*addsi_2"
602290286Sobrien  [(set (reg 17)
602390286Sobrien	(compare
602490286Sobrien	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
602590286Sobrien		   (match_operand:SI 2 "general_operand" "rmni,rni"))
602690286Sobrien	  (const_int 0)))			
602790286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
602890286Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
602990286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
603090286Sobrien   && ix86_binary_operator_ok (PLUS, SImode, operands)
603190286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
603290286Sobrien      ought but a memory context.  */
603390286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
603418334Speter{
603590286Sobrien  switch (get_attr_type (insn))
603690286Sobrien    {
603790286Sobrien    case TYPE_INCDEC:
603890286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
603990286Sobrien	abort ();
604090286Sobrien      if (operands[2] == const1_rtx)
604190286Sobrien        return "inc{l}\t%0";
604290286Sobrien      else if (operands[2] == constm1_rtx)
604390286Sobrien        return "dec{l}\t%0";
604490286Sobrien      else
604590286Sobrien	abort();
604618334Speter
604790286Sobrien    default:
604890286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
604990286Sobrien	abort ();
605090286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
605190286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
605290286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
605390286Sobrien          && (INTVAL (operands[2]) == 128
605490286Sobrien	      || (INTVAL (operands[2]) < 0
605590286Sobrien		  && INTVAL (operands[2]) != -128)))
605690286Sobrien        {
605790286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
605890286Sobrien          return "sub{l}\t{%2, %0|%0, %2}";
605990286Sobrien        }
606090286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
606190286Sobrien    }
606290286Sobrien}
606390286Sobrien  [(set (attr "type")
606490286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
606590286Sobrien	(const_string "incdec")
606690286Sobrien	(const_string "alu")))
606790286Sobrien   (set_attr "mode" "SI")])
606818334Speter
606990286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
607090286Sobrien(define_insn "*addsi_2_zext"
607190286Sobrien  [(set (reg 17)
607290286Sobrien	(compare
607390286Sobrien	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
607490286Sobrien		   (match_operand:SI 2 "general_operand" "rmni"))
607590286Sobrien	  (const_int 0)))			
607690286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
607790286Sobrien	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
607890286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
607990286Sobrien   && ix86_binary_operator_ok (PLUS, SImode, operands)
608090286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
608190286Sobrien      ought but a memory context.  */
608290286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
608390286Sobrien{
608490286Sobrien  switch (get_attr_type (insn))
608518334Speter    {
608690286Sobrien    case TYPE_INCDEC:
608790286Sobrien      if (operands[2] == const1_rtx)
608890286Sobrien        return "inc{l}\t%k0";
608990286Sobrien      else if (operands[2] == constm1_rtx)
609090286Sobrien        return "dec{l}\t%k0";
609190286Sobrien      else
609290286Sobrien	abort();
609390286Sobrien
609490286Sobrien    default:
609590286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
609690286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
609790286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
609890286Sobrien          && (INTVAL (operands[2]) == 128
609990286Sobrien	      || (INTVAL (operands[2]) < 0
610090286Sobrien		  && INTVAL (operands[2]) != -128)))
610190286Sobrien        {
610290286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
610390286Sobrien          return "sub{l}\t{%2, %k0|%k0, %2}";
610490286Sobrien        }
610590286Sobrien      return "add{l}\t{%2, %k0|%k0, %2}";
610618334Speter    }
610790286Sobrien}
610890286Sobrien  [(set (attr "type")
610990286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
611090286Sobrien	(const_string "incdec")
611190286Sobrien	(const_string "alu")))
611290286Sobrien   (set_attr "mode" "SI")])
611318334Speter
611490286Sobrien(define_insn "*addsi_3"
611590286Sobrien  [(set (reg 17)
611690286Sobrien	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
611790286Sobrien		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
611890286Sobrien   (clobber (match_scratch:SI 0 "=r"))]
611990286Sobrien  "ix86_match_ccmode (insn, CCZmode)
612090286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
612190286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
612290286Sobrien      ought but a memory context.  */
612390286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
612490286Sobrien{
612590286Sobrien  switch (get_attr_type (insn))
612618334Speter    {
612790286Sobrien    case TYPE_INCDEC:
612890286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
612990286Sobrien	abort ();
613090286Sobrien      if (operands[2] == const1_rtx)
613190286Sobrien        return "inc{l}\t%0";
613290286Sobrien      else if (operands[2] == constm1_rtx)
613390286Sobrien        return "dec{l}\t%0";
613490286Sobrien      else
613590286Sobrien	abort();
613618334Speter
613790286Sobrien    default:
613890286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
613990286Sobrien	abort ();
614090286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
614190286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
614290286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
614390286Sobrien          && (INTVAL (operands[2]) == 128
614490286Sobrien	      || (INTVAL (operands[2]) < 0
614590286Sobrien		  && INTVAL (operands[2]) != -128)))
614690286Sobrien        {
614790286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
614890286Sobrien          return "sub{l}\t{%2, %0|%0, %2}";
614990286Sobrien        }
615090286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
615190286Sobrien    }
615290286Sobrien}
615390286Sobrien  [(set (attr "type")
615490286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
615590286Sobrien	(const_string "incdec")
615690286Sobrien	(const_string "alu")))
615790286Sobrien   (set_attr "mode" "SI")])
615890286Sobrien
615990286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
616090286Sobrien(define_insn "*addsi_3_zext"
616190286Sobrien  [(set (reg 17)
616290286Sobrien	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
616390286Sobrien		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
616490286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
616590286Sobrien	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
616690286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
616790286Sobrien   && ix86_binary_operator_ok (PLUS, SImode, operands)
616890286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
616990286Sobrien      ought but a memory context.  */
617090286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
617190286Sobrien{
617290286Sobrien  switch (get_attr_type (insn))
617390286Sobrien    {
617490286Sobrien    case TYPE_INCDEC:
617590286Sobrien      if (operands[2] == const1_rtx)
617690286Sobrien        return "inc{l}\t%k0";
617790286Sobrien      else if (operands[2] == constm1_rtx)
617890286Sobrien        return "dec{l}\t%k0";
617918334Speter      else
618090286Sobrien	abort();
618190286Sobrien
618290286Sobrien    default:
618390286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
618490286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
618590286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
618690286Sobrien          && (INTVAL (operands[2]) == 128
618790286Sobrien	      || (INTVAL (operands[2]) < 0
618890286Sobrien		  && INTVAL (operands[2]) != -128)))
618990286Sobrien        {
619090286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
619190286Sobrien          return "sub{l}\t{%2, %k0|%k0, %2}";
619290286Sobrien        }
619390286Sobrien      return "add{l}\t{%2, %k0|%k0, %2}";
619418334Speter    }
619590286Sobrien}
619690286Sobrien  [(set (attr "type")
619790286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
619890286Sobrien	(const_string "incdec")
619990286Sobrien	(const_string "alu")))
620090286Sobrien   (set_attr "mode" "SI")])
620118334Speter
620290286Sobrien; For comparisons agains 1, -1 and 128, we may generate better code
620390286Sobrien; by converting cmp to add, inc or dec as done by peephole2.  This pattern
620490286Sobrien; is matched then.  We can't accept general immediate, because for
620590286Sobrien; case of overflows,  the result is messed up.
620690286Sobrien; This pattern also don't hold of 0x80000000, since the value overflows
620790286Sobrien; when negated.
620890286Sobrien; Also carry flag is reversed compared to cmp, so this conversion is valid
620990286Sobrien; only for comparisons not depending on it.
621090286Sobrien(define_insn "*addsi_4"
621190286Sobrien  [(set (reg 17)
621290286Sobrien	(compare (match_operand:SI 1 "nonimmediate_operand" "0")
621390286Sobrien		 (match_operand:SI 2 "const_int_operand" "n")))
621490286Sobrien   (clobber (match_scratch:SI 0 "=rm"))]
621590286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
621690286Sobrien   && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
621790286Sobrien{
621890286Sobrien  switch (get_attr_type (insn))
621918334Speter    {
622090286Sobrien    case TYPE_INCDEC:
622190286Sobrien      if (operands[2] == constm1_rtx)
622290286Sobrien        return "inc{l}\t%0";
622390286Sobrien      else if (operands[2] == const1_rtx)
622490286Sobrien        return "dec{l}\t%0";
622590286Sobrien      else
622690286Sobrien	abort();
622718334Speter
622890286Sobrien    default:
622990286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
623090286Sobrien	abort ();
623190286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
623290286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
623390286Sobrien      if ((INTVAL (operands[2]) == -128
623490286Sobrien	   || (INTVAL (operands[2]) > 0
623590286Sobrien	       && INTVAL (operands[2]) != 128)))
623690286Sobrien	return "sub{l}\t{%2, %0|%0, %2}";
623790286Sobrien      operands[2] = GEN_INT (-INTVAL (operands[2]));
623890286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
623918334Speter    }
624090286Sobrien}
624190286Sobrien  [(set (attr "type")
624290286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
624390286Sobrien	(const_string "incdec")
624490286Sobrien	(const_string "alu")))
624590286Sobrien   (set_attr "mode" "SI")])
624618334Speter
624790286Sobrien(define_insn "*addsi_5"
624890286Sobrien  [(set (reg 17)
624990286Sobrien	(compare
625090286Sobrien	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
625190286Sobrien		   (match_operand:SI 2 "general_operand" "rmni"))
625290286Sobrien	  (const_int 0)))			
625390286Sobrien   (clobber (match_scratch:SI 0 "=r"))]
625490286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
625590286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
625690286Sobrien   /* Current assemblers are broken and do not allow @GOTOFF in
625790286Sobrien      ought but a memory context.  */
625890286Sobrien   && ! pic_symbolic_operand (operands[2], VOIDmode)"
625990286Sobrien{
626090286Sobrien  switch (get_attr_type (insn))
626118334Speter    {
626290286Sobrien    case TYPE_INCDEC:
626390286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
626490286Sobrien	abort ();
626590286Sobrien      if (operands[2] == const1_rtx)
626690286Sobrien        return "inc{l}\t%0";
626790286Sobrien      else if (operands[2] == constm1_rtx)
626890286Sobrien        return "dec{l}\t%0";
626990286Sobrien      else
627090286Sobrien	abort();
627190286Sobrien
627290286Sobrien    default:
627390286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
627490286Sobrien	abort ();
627590286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
627690286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
627790286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
627890286Sobrien          && (INTVAL (operands[2]) == 128
627990286Sobrien	      || (INTVAL (operands[2]) < 0
628090286Sobrien		  && INTVAL (operands[2]) != -128)))
628190286Sobrien        {
628290286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
628390286Sobrien          return "sub{l}\t{%2, %0|%0, %2}";
628490286Sobrien        }
628590286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
628618334Speter    }
628790286Sobrien}
628890286Sobrien  [(set (attr "type")
628990286Sobrien     (if_then_else (match_operand:SI 2 "incdec_operand" "")
629090286Sobrien	(const_string "incdec")
629190286Sobrien	(const_string "alu")))
629290286Sobrien   (set_attr "mode" "SI")])
629318334Speter
629490286Sobrien(define_expand "addhi3"
629590286Sobrien  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
629690286Sobrien		   (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
629790286Sobrien			    (match_operand:HI 2 "general_operand" "")))
629890286Sobrien	      (clobber (reg:CC 17))])]
629990286Sobrien  "TARGET_HIMODE_MATH"
630090286Sobrien  "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
630118334Speter
630290286Sobrien;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
630390286Sobrien;; type optimizations enabled by define-splits.  This is not important
630490286Sobrien;; for PII, and in fact harmful because of partial register stalls.
630518334Speter
630690286Sobrien(define_insn "*addhi_1_lea"
630790286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
630890286Sobrien	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
630990286Sobrien		 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
631090286Sobrien   (clobber (reg:CC 17))]
631190286Sobrien  "!TARGET_PARTIAL_REG_STALL
631290286Sobrien   && ix86_binary_operator_ok (PLUS, HImode, operands)"
631390286Sobrien{
631490286Sobrien  switch (get_attr_type (insn))
631590286Sobrien    {
631690286Sobrien    case TYPE_LEA:
631790286Sobrien      return "#";
631890286Sobrien    case TYPE_INCDEC:
631990286Sobrien      if (operands[2] == const1_rtx)
632090286Sobrien	return "inc{w}\t%0";
632190286Sobrien      else if (operands[2] == constm1_rtx
632290286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
632390286Sobrien		   && INTVAL (operands[2]) == 65535))
632490286Sobrien	return "dec{w}\t%0";
632590286Sobrien      abort();
632618334Speter
632790286Sobrien    default:
632890286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
632990286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
633090286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
633190286Sobrien          && (INTVAL (operands[2]) == 128
633290286Sobrien	      || (INTVAL (operands[2]) < 0
633390286Sobrien		  && INTVAL (operands[2]) != -128)))
633490286Sobrien	{
633590286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
633690286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
633790286Sobrien	}
633890286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
633990286Sobrien    }
634090286Sobrien}
634190286Sobrien  [(set (attr "type")
634290286Sobrien     (if_then_else (eq_attr "alternative" "2")
634390286Sobrien	(const_string "lea")
634490286Sobrien	(if_then_else (match_operand:HI 2 "incdec_operand" "")
634590286Sobrien	   (const_string "incdec")
634690286Sobrien	   (const_string "alu"))))
634790286Sobrien   (set_attr "mode" "HI,HI,SI")])
634850650Sobrien
634990286Sobrien(define_insn "*addhi_1"
635090286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
635190286Sobrien	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
635290286Sobrien		 (match_operand:HI 2 "general_operand" "ri,rm")))
635390286Sobrien   (clobber (reg:CC 17))]
635490286Sobrien  "TARGET_PARTIAL_REG_STALL
635590286Sobrien   && ix86_binary_operator_ok (PLUS, HImode, operands)"
635618334Speter{
635790286Sobrien  switch (get_attr_type (insn))
635818334Speter    {
635990286Sobrien    case TYPE_INCDEC:
636090286Sobrien      if (operands[2] == const1_rtx)
636190286Sobrien	return "inc{w}\t%0";
636290286Sobrien      else if (operands[2] == constm1_rtx
636390286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
636490286Sobrien		   && INTVAL (operands[2]) == 65535))
636590286Sobrien	return "dec{w}\t%0";
636690286Sobrien      abort();
636718334Speter
636890286Sobrien    default:
636990286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
637090286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
637190286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
637290286Sobrien          && (INTVAL (operands[2]) == 128
637390286Sobrien	      || (INTVAL (operands[2]) < 0
637490286Sobrien		  && INTVAL (operands[2]) != -128)))
637518334Speter	{
637690286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
637790286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
637818334Speter	}
637990286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
638090286Sobrien    }
638190286Sobrien}
638290286Sobrien  [(set (attr "type")
638390286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
638490286Sobrien	(const_string "incdec")
638590286Sobrien	(const_string "alu")))
638690286Sobrien   (set_attr "mode" "HI")])
638718334Speter
638890286Sobrien(define_insn "*addhi_2"
638990286Sobrien  [(set (reg 17)
639090286Sobrien	(compare
639190286Sobrien	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
639290286Sobrien		   (match_operand:HI 2 "general_operand" "rmni,rni"))
639390286Sobrien	  (const_int 0)))			
639490286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
639590286Sobrien	(plus:HI (match_dup 1) (match_dup 2)))]
639690286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
639790286Sobrien   && ix86_binary_operator_ok (PLUS, HImode, operands)"
639890286Sobrien{
639990286Sobrien  switch (get_attr_type (insn))
640090286Sobrien    {
640190286Sobrien    case TYPE_INCDEC:
640290286Sobrien      if (operands[2] == const1_rtx)
640390286Sobrien	return "inc{w}\t%0";
640490286Sobrien      else if (operands[2] == constm1_rtx
640590286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
640690286Sobrien		   && INTVAL (operands[2]) == 65535))
640790286Sobrien	return "dec{w}\t%0";
640890286Sobrien      abort();
640990286Sobrien
641090286Sobrien    default:
641190286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
641290286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
641390286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
641490286Sobrien          && (INTVAL (operands[2]) == 128
641590286Sobrien	      || (INTVAL (operands[2]) < 0
641690286Sobrien		  && INTVAL (operands[2]) != -128)))
641718334Speter	{
641890286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
641990286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
642018334Speter	}
642190286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
642218334Speter    }
642390286Sobrien}
642490286Sobrien  [(set (attr "type")
642590286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
642690286Sobrien	(const_string "incdec")
642790286Sobrien	(const_string "alu")))
642890286Sobrien   (set_attr "mode" "HI")])
642918334Speter
643090286Sobrien(define_insn "*addhi_3"
643190286Sobrien  [(set (reg 17)
643290286Sobrien	(compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
643390286Sobrien		 (match_operand:HI 1 "nonimmediate_operand" "%0")))
643490286Sobrien   (clobber (match_scratch:HI 0 "=r"))]
643590286Sobrien  "ix86_match_ccmode (insn, CCZmode)
643690286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
643790286Sobrien{
643890286Sobrien  switch (get_attr_type (insn))
643990286Sobrien    {
644090286Sobrien    case TYPE_INCDEC:
644190286Sobrien      if (operands[2] == const1_rtx)
644290286Sobrien	return "inc{w}\t%0";
644390286Sobrien      else if (operands[2] == constm1_rtx
644490286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
644590286Sobrien		   && INTVAL (operands[2]) == 65535))
644690286Sobrien	return "dec{w}\t%0";
644790286Sobrien      abort();
644850650Sobrien
644990286Sobrien    default:
645090286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
645190286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
645290286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
645390286Sobrien          && (INTVAL (operands[2]) == 128
645490286Sobrien	      || (INTVAL (operands[2]) < 0
645590286Sobrien		  && INTVAL (operands[2]) != -128)))
645690286Sobrien	{
645790286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
645890286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
645990286Sobrien	}
646090286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
646190286Sobrien    }
646290286Sobrien}
646390286Sobrien  [(set (attr "type")
646490286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
646590286Sobrien	(const_string "incdec")
646690286Sobrien	(const_string "alu")))
646790286Sobrien   (set_attr "mode" "HI")])
646818334Speter
646990286Sobrien; See comments above addsi_3_imm for details.
647090286Sobrien(define_insn "*addhi_4"
647190286Sobrien  [(set (reg 17)
647290286Sobrien	(compare (match_operand:HI 1 "nonimmediate_operand" "0")
647390286Sobrien		 (match_operand:HI 2 "const_int_operand" "n")))
647490286Sobrien   (clobber (match_scratch:HI 0 "=rm"))]
647590286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
647690286Sobrien   && (INTVAL (operands[2]) & 0xffff) != 0x8000"
647790286Sobrien{
647890286Sobrien  switch (get_attr_type (insn))
647990286Sobrien    {
648090286Sobrien    case TYPE_INCDEC:
648190286Sobrien      if (operands[2] == constm1_rtx
648290286Sobrien	  || (GET_CODE (operands[2]) == CONST_INT
648390286Sobrien	      && INTVAL (operands[2]) == 65535))
648490286Sobrien        return "inc{w}\t%0";
648590286Sobrien      else if (operands[2] == const1_rtx)
648690286Sobrien        return "dec{w}\t%0";
648790286Sobrien      else
648890286Sobrien	abort();
648918334Speter
649090286Sobrien    default:
649190286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
649290286Sobrien	abort ();
649390286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
649490286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
649590286Sobrien      if ((INTVAL (operands[2]) == -128
649690286Sobrien	   || (INTVAL (operands[2]) > 0
649790286Sobrien	       && INTVAL (operands[2]) != 128)))
649890286Sobrien	return "sub{w}\t{%2, %0|%0, %2}";
649990286Sobrien      operands[2] = GEN_INT (-INTVAL (operands[2]));
650090286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
650150650Sobrien    }
650290286Sobrien}
650390286Sobrien  [(set (attr "type")
650490286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
650590286Sobrien	(const_string "incdec")
650690286Sobrien	(const_string "alu")))
650790286Sobrien   (set_attr "mode" "SI")])
650850650Sobrien
650918334Speter
651090286Sobrien(define_insn "*addhi_5"
651190286Sobrien  [(set (reg 17)
651290286Sobrien	(compare
651390286Sobrien	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
651490286Sobrien		   (match_operand:HI 2 "general_operand" "rmni"))
651590286Sobrien	  (const_int 0)))			
651690286Sobrien   (clobber (match_scratch:HI 0 "=r"))]
651790286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
651890286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
651950650Sobrien{
652090286Sobrien  switch (get_attr_type (insn))
652150650Sobrien    {
652290286Sobrien    case TYPE_INCDEC:
652390286Sobrien      if (operands[2] == const1_rtx)
652490286Sobrien	return "inc{w}\t%0";
652590286Sobrien      else if (operands[2] == constm1_rtx
652690286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
652790286Sobrien		   && INTVAL (operands[2]) == 65535))
652890286Sobrien	return "dec{w}\t%0";
652990286Sobrien      abort();
653050650Sobrien
653190286Sobrien    default:
653290286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
653390286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
653490286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
653590286Sobrien          && (INTVAL (operands[2]) == 128
653690286Sobrien	      || (INTVAL (operands[2]) < 0
653790286Sobrien		  && INTVAL (operands[2]) != -128)))
653890286Sobrien	{
653990286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
654090286Sobrien	  return "sub{w}\t{%2, %0|%0, %2}";
654190286Sobrien	}
654290286Sobrien      return "add{w}\t{%2, %0|%0, %2}";
654350650Sobrien    }
654490286Sobrien}
654590286Sobrien  [(set (attr "type")
654690286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
654790286Sobrien	(const_string "incdec")
654890286Sobrien	(const_string "alu")))
654990286Sobrien   (set_attr "mode" "HI")])
655050650Sobrien
655190286Sobrien(define_expand "addqi3"
655290286Sobrien  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
655390286Sobrien		   (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
655490286Sobrien			    (match_operand:QI 2 "general_operand" "")))
655590286Sobrien	      (clobber (reg:CC 17))])]
655690286Sobrien  "TARGET_QIMODE_MATH"
655790286Sobrien  "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
655850650Sobrien
655990286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
656090286Sobrien(define_insn "*addqi_1_lea"
656190286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
656290286Sobrien	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
656390286Sobrien		 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
656490286Sobrien   (clobber (reg:CC 17))]
656590286Sobrien  "!TARGET_PARTIAL_REG_STALL
656690286Sobrien   && ix86_binary_operator_ok (PLUS, QImode, operands)"
656790286Sobrien{
656890286Sobrien  int widen = (which_alternative == 2);
656990286Sobrien  switch (get_attr_type (insn))
657090286Sobrien    {
657190286Sobrien    case TYPE_LEA:
657290286Sobrien      return "#";
657390286Sobrien    case TYPE_INCDEC:
657490286Sobrien      if (operands[2] == const1_rtx)
657590286Sobrien	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
657690286Sobrien      else if (operands[2] == constm1_rtx
657790286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
657890286Sobrien		   && INTVAL (operands[2]) == 255))
657990286Sobrien	return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
658090286Sobrien      abort();
658118334Speter
658290286Sobrien    default:
658390286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
658490286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
658590286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
658690286Sobrien          && (INTVAL (operands[2]) == 128
658790286Sobrien	      || (INTVAL (operands[2]) < 0
658890286Sobrien		  && INTVAL (operands[2]) != -128)))
658990286Sobrien	{
659090286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
659190286Sobrien	  if (widen)
659290286Sobrien	    return "sub{l}\t{%2, %k0|%k0, %2}";
659390286Sobrien	  else
659490286Sobrien	    return "sub{b}\t{%2, %0|%0, %2}";
659590286Sobrien	}
659690286Sobrien      if (widen)
659790286Sobrien        return "add{l}\t{%k2, %k0|%k0, %k2}";
659890286Sobrien      else
659990286Sobrien        return "add{b}\t{%2, %0|%0, %2}";
660090286Sobrien    }
660190286Sobrien}
660290286Sobrien  [(set (attr "type")
660390286Sobrien     (if_then_else (eq_attr "alternative" "3")
660490286Sobrien	(const_string "lea")
660590286Sobrien	(if_then_else (match_operand:QI 2 "incdec_operand" "")
660690286Sobrien	   (const_string "incdec")
660790286Sobrien	   (const_string "alu"))))
660890286Sobrien   (set_attr "mode" "QI,QI,SI,SI")])
660950650Sobrien
661090286Sobrien(define_insn "*addqi_1"
661190286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
661290286Sobrien	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
661390286Sobrien		 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
661490286Sobrien   (clobber (reg:CC 17))]
661590286Sobrien  "TARGET_PARTIAL_REG_STALL
661690286Sobrien   && ix86_binary_operator_ok (PLUS, QImode, operands)"
661718334Speter{
661890286Sobrien  int widen = (which_alternative == 2);
661990286Sobrien  switch (get_attr_type (insn))
662052296Sobrien    {
662190286Sobrien    case TYPE_INCDEC:
662290286Sobrien      if (operands[2] == const1_rtx)
662390286Sobrien	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
662490286Sobrien      else if (operands[2] == constm1_rtx
662590286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
662690286Sobrien		   && INTVAL (operands[2]) == 255))
662790286Sobrien	return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
662890286Sobrien      abort();
662952296Sobrien
663090286Sobrien    default:
663190286Sobrien      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
663290286Sobrien	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
663390286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
663490286Sobrien          && (INTVAL (operands[2]) == 128
663590286Sobrien	      || (INTVAL (operands[2]) < 0
663690286Sobrien		  && INTVAL (operands[2]) != -128)))
663790286Sobrien	{
663890286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
663990286Sobrien	  if (widen)
664090286Sobrien	    return "sub{l}\t{%2, %k0|%k0, %2}";
664190286Sobrien	  else
664290286Sobrien	    return "sub{b}\t{%2, %0|%0, %2}";
664390286Sobrien	}
664490286Sobrien      if (widen)
664590286Sobrien        return "add{l}\t{%k2, %k0|%k0, %k2}";
664690286Sobrien      else
664790286Sobrien        return "add{b}\t{%2, %0|%0, %2}";
664852296Sobrien    }
664990286Sobrien}
665090286Sobrien  [(set (attr "type")
665190286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
665290286Sobrien	(const_string "incdec")
665390286Sobrien	(const_string "alu")))
665490286Sobrien   (set_attr "mode" "QI,QI,SI")])
665552296Sobrien
665690286Sobrien(define_insn "*addqi_2"
665790286Sobrien  [(set (reg 17)
665890286Sobrien	(compare
665990286Sobrien	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
666090286Sobrien		   (match_operand:QI 2 "general_operand" "qmni,qni"))
666190286Sobrien	  (const_int 0)))
666290286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
666390286Sobrien	(plus:QI (match_dup 1) (match_dup 2)))]
666490286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
666590286Sobrien   && ix86_binary_operator_ok (PLUS, QImode, operands)"
666690286Sobrien{
666790286Sobrien  switch (get_attr_type (insn))
666818334Speter    {
666990286Sobrien    case TYPE_INCDEC:
667090286Sobrien      if (operands[2] == const1_rtx)
667190286Sobrien	return "inc{b}\t%0";
667290286Sobrien      else if (operands[2] == constm1_rtx
667390286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
667490286Sobrien		   && INTVAL (operands[2]) == 255))
667590286Sobrien	return "dec{b}\t%0";
667690286Sobrien      abort();
667718334Speter
667890286Sobrien    default:
667990286Sobrien      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
668090286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
668190286Sobrien          && INTVAL (operands[2]) < 0)
668290286Sobrien	{
668390286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
668490286Sobrien	  return "sub{b}\t{%2, %0|%0, %2}";
668590286Sobrien	}
668690286Sobrien      return "add{b}\t{%2, %0|%0, %2}";
668718334Speter    }
668890286Sobrien}
668990286Sobrien  [(set (attr "type")
669090286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
669190286Sobrien	(const_string "incdec")
669290286Sobrien	(const_string "alu")))
669390286Sobrien   (set_attr "mode" "QI")])
669418334Speter
669590286Sobrien(define_insn "*addqi_3"
669690286Sobrien  [(set (reg 17)
669790286Sobrien	(compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
669890286Sobrien		 (match_operand:QI 1 "nonimmediate_operand" "%0")))
669990286Sobrien   (clobber (match_scratch:QI 0 "=q"))]
670090286Sobrien  "ix86_match_ccmode (insn, CCZmode)
670190286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
670290286Sobrien{
670390286Sobrien  switch (get_attr_type (insn))
670450650Sobrien    {
670590286Sobrien    case TYPE_INCDEC:
670690286Sobrien      if (operands[2] == const1_rtx)
670790286Sobrien	return "inc{b}\t%0";
670890286Sobrien      else if (operands[2] == constm1_rtx
670990286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
671090286Sobrien		   && INTVAL (operands[2]) == 255))
671190286Sobrien	return "dec{b}\t%0";
671290286Sobrien      abort();
671350650Sobrien
671490286Sobrien    default:
671590286Sobrien      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
671690286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
671790286Sobrien          && INTVAL (operands[2]) < 0)
671850650Sobrien	{
671990286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
672090286Sobrien	  return "sub{b}\t{%2, %0|%0, %2}";
672190286Sobrien	}
672290286Sobrien      return "add{b}\t{%2, %0|%0, %2}";
672390286Sobrien    }
672490286Sobrien}
672590286Sobrien  [(set (attr "type")
672690286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
672790286Sobrien	(const_string "incdec")
672890286Sobrien	(const_string "alu")))
672990286Sobrien   (set_attr "mode" "QI")])
673050650Sobrien
673190286Sobrien; See comments above addsi_3_imm for details.
673290286Sobrien(define_insn "*addqi_4"
673390286Sobrien  [(set (reg 17)
673490286Sobrien	(compare (match_operand:QI 1 "nonimmediate_operand" "0")
673590286Sobrien		 (match_operand:QI 2 "const_int_operand" "n")))
673690286Sobrien   (clobber (match_scratch:QI 0 "=qm"))]
673790286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
673890286Sobrien   && (INTVAL (operands[2]) & 0xff) != 0x80"
673990286Sobrien{
674090286Sobrien  switch (get_attr_type (insn))
674190286Sobrien    {
674290286Sobrien    case TYPE_INCDEC:
674390286Sobrien      if (operands[2] == constm1_rtx
674490286Sobrien	  || (GET_CODE (operands[2]) == CONST_INT
674590286Sobrien	      && INTVAL (operands[2]) == 255))
674690286Sobrien        return "inc{b}\t%0";
674790286Sobrien      else if (operands[2] == const1_rtx)
674890286Sobrien        return "dec{b}\t%0";
674990286Sobrien      else
675090286Sobrien	abort();
675150650Sobrien
675290286Sobrien    default:
675390286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
675490286Sobrien	abort ();
675590286Sobrien      if (INTVAL (operands[2]) < 0)
675690286Sobrien        {
675790286Sobrien          operands[2] = GEN_INT (-INTVAL (operands[2]));
675890286Sobrien          return "add{b}\t{%2, %0|%0, %2}";
675990286Sobrien        }
676090286Sobrien      return "sub{b}\t{%2, %0|%0, %2}";
676150650Sobrien    }
676290286Sobrien}
676390286Sobrien  [(set (attr "type")
676490286Sobrien     (if_then_else (match_operand:HI 2 "incdec_operand" "")
676590286Sobrien	(const_string "incdec")
676690286Sobrien	(const_string "alu")))
676790286Sobrien   (set_attr "mode" "QI")])
676850650Sobrien
676918334Speter
677090286Sobrien(define_insn "*addqi_5"
677190286Sobrien  [(set (reg 17)
677290286Sobrien	(compare
677390286Sobrien	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
677490286Sobrien		   (match_operand:QI 2 "general_operand" "qmni"))
677590286Sobrien	  (const_int 0)))
677690286Sobrien   (clobber (match_scratch:QI 0 "=q"))]
677790286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
677890286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
677990286Sobrien{
678090286Sobrien  switch (get_attr_type (insn))
678190286Sobrien    {
678290286Sobrien    case TYPE_INCDEC:
678390286Sobrien      if (operands[2] == const1_rtx)
678490286Sobrien	return "inc{b}\t%0";
678590286Sobrien      else if (operands[2] == constm1_rtx
678690286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
678790286Sobrien		   && INTVAL (operands[2]) == 255))
678890286Sobrien	return "dec{b}\t%0";
678990286Sobrien      abort();
679018334Speter
679190286Sobrien    default:
679290286Sobrien      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
679390286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
679490286Sobrien          && INTVAL (operands[2]) < 0)
679590286Sobrien	{
679690286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
679790286Sobrien	  return "sub{b}\t{%2, %0|%0, %2}";
679890286Sobrien	}
679990286Sobrien      return "add{b}\t{%2, %0|%0, %2}";
680090286Sobrien    }
680190286Sobrien}
680290286Sobrien  [(set (attr "type")
680390286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
680490286Sobrien	(const_string "incdec")
680590286Sobrien	(const_string "alu")))
680690286Sobrien   (set_attr "mode" "QI")])
680718334Speter
680850650Sobrien
680990286Sobrien(define_insn "addqi_ext_1"
681090286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
681190286Sobrien			 (const_int 8)
681290286Sobrien			 (const_int 8))
681390286Sobrien	(plus:SI
681490286Sobrien	  (zero_extract:SI
681590286Sobrien	    (match_operand 1 "ext_register_operand" "0")
681690286Sobrien	    (const_int 8)
681790286Sobrien	    (const_int 8))
681890286Sobrien	  (match_operand:QI 2 "general_operand" "Qmn")))
681990286Sobrien   (clobber (reg:CC 17))]
682090286Sobrien  "!TARGET_64BIT"
682118334Speter{
682290286Sobrien  switch (get_attr_type (insn))
682352296Sobrien    {
682490286Sobrien    case TYPE_INCDEC:
682590286Sobrien      if (operands[2] == const1_rtx)
682690286Sobrien	return "inc{b}\t%h0";
682790286Sobrien      else if (operands[2] == constm1_rtx
682890286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
682990286Sobrien		   && INTVAL (operands[2]) == 255))
683090286Sobrien	return "dec{b}\t%h0";
683190286Sobrien      abort();
683252296Sobrien
683390286Sobrien    default:
683490286Sobrien      return "add{b}\t{%2, %h0|%h0, %2}";
683552296Sobrien    }
683690286Sobrien}
683790286Sobrien  [(set (attr "type")
683890286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
683990286Sobrien	(const_string "incdec")
684090286Sobrien	(const_string "alu")))
684190286Sobrien   (set_attr "mode" "QI")])
684218334Speter
684390286Sobrien(define_insn "*addqi_ext_1_rex64"
684490286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
684590286Sobrien			 (const_int 8)
684690286Sobrien			 (const_int 8))
684790286Sobrien	(plus:SI
684890286Sobrien	  (zero_extract:SI
684990286Sobrien	    (match_operand 1 "ext_register_operand" "0")
685090286Sobrien	    (const_int 8)
685190286Sobrien	    (const_int 8))
685290286Sobrien	  (match_operand:QI 2 "nonmemory_operand" "Qn")))
685390286Sobrien   (clobber (reg:CC 17))]
685490286Sobrien  "TARGET_64BIT"
685590286Sobrien{
685690286Sobrien  switch (get_attr_type (insn))
685790286Sobrien    {
685890286Sobrien    case TYPE_INCDEC:
685990286Sobrien      if (operands[2] == const1_rtx)
686090286Sobrien	return "inc{b}\t%h0";
686190286Sobrien      else if (operands[2] == constm1_rtx
686290286Sobrien	       || (GET_CODE (operands[2]) == CONST_INT
686390286Sobrien		   && INTVAL (operands[2]) == 255))
686490286Sobrien	return "dec{b}\t%h0";
686590286Sobrien      abort();
686618334Speter
686790286Sobrien    default:
686890286Sobrien      return "add{b}\t{%2, %h0|%h0, %2}";
686990286Sobrien    }
687090286Sobrien}
687190286Sobrien  [(set (attr "type")
687290286Sobrien     (if_then_else (match_operand:QI 2 "incdec_operand" "")
687390286Sobrien	(const_string "incdec")
687490286Sobrien	(const_string "alu")))
687590286Sobrien   (set_attr "mode" "QI")])
687618334Speter
687790286Sobrien(define_insn "*addqi_ext_2"
687890286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
687990286Sobrien			 (const_int 8)
688090286Sobrien			 (const_int 8))
688190286Sobrien	(plus:SI
688290286Sobrien	  (zero_extract:SI
688390286Sobrien	    (match_operand 1 "ext_register_operand" "%0")
688490286Sobrien	    (const_int 8)
688590286Sobrien	    (const_int 8))
688690286Sobrien	  (zero_extract:SI
688790286Sobrien	    (match_operand 2 "ext_register_operand" "Q")
688890286Sobrien	    (const_int 8)
688990286Sobrien	    (const_int 8))))
689090286Sobrien   (clobber (reg:CC 17))]
689190286Sobrien  ""
689290286Sobrien  "add{b}\t{%h2, %h0|%h0, %h2}"
689390286Sobrien  [(set_attr "type" "alu")
689490286Sobrien   (set_attr "mode" "QI")])
689518334Speter
689618334Speter;; The patterns that match these are at the end of this file.
689718334Speter
689818334Speter(define_expand "addxf3"
689918334Speter  [(set (match_operand:XF 0 "register_operand" "")
690050650Sobrien	(plus:XF (match_operand:XF 1 "register_operand" "")
690150650Sobrien		 (match_operand:XF 2 "register_operand" "")))]
690290286Sobrien  "!TARGET_64BIT && TARGET_80387"
690390286Sobrien  "")
690490286Sobrien
690590286Sobrien(define_expand "addtf3"
690690286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
690790286Sobrien	(plus:TF (match_operand:TF 1 "register_operand" "")
690890286Sobrien		 (match_operand:TF 2 "register_operand" "")))]
690918334Speter  "TARGET_80387"
691018334Speter  "")
691118334Speter
691218334Speter(define_expand "adddf3"
691318334Speter  [(set (match_operand:DF 0 "register_operand" "")
691490286Sobrien	(plus:DF (match_operand:DF 1 "register_operand" "")
691518334Speter		 (match_operand:DF 2 "nonimmediate_operand" "")))]
691690286Sobrien  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
691718334Speter  "")
691818334Speter
691918334Speter(define_expand "addsf3"
692018334Speter  [(set (match_operand:SF 0 "register_operand" "")
692190286Sobrien	(plus:SF (match_operand:SF 1 "register_operand" "")
692218334Speter		 (match_operand:SF 2 "nonimmediate_operand" "")))]
692390286Sobrien  "TARGET_80387 || TARGET_SSE_MATH"
692418334Speter  "")
692518334Speter
692690286Sobrien;; Subtract instructions
692718334Speter
692890286Sobrien;; %%% splits for subsidi3
692950650Sobrien
693090286Sobrien(define_expand "subdi3"
693190286Sobrien  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
693290286Sobrien		   (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
693390286Sobrien			     (match_operand:DI 2 "x86_64_general_operand" "")))
693490286Sobrien	      (clobber (reg:CC 17))])]
693518334Speter  ""
693690286Sobrien  "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
693718334Speter
693890286Sobrien(define_insn "*subdi3_1"
693990286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
694090286Sobrien	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
694190286Sobrien		  (match_operand:DI 2 "general_operand" "roiF,riF")))
694290286Sobrien   (clobber (reg:CC 17))]
6943107605Sobrien  "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
694490286Sobrien  "#")
694518334Speter
694690286Sobrien(define_split
694790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
694890286Sobrien	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
694990286Sobrien		  (match_operand:DI 2 "general_operand" "")))
695090286Sobrien   (clobber (reg:CC 17))]
695190286Sobrien  "!TARGET_64BIT && reload_completed"
695290286Sobrien  [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
695390286Sobrien	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
695490286Sobrien   (parallel [(set (match_dup 3)
695590286Sobrien		   (minus:SI (match_dup 4)
695690286Sobrien			     (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
695790286Sobrien				      (match_dup 5))))
695890286Sobrien	      (clobber (reg:CC 17))])]
695990286Sobrien  "split_di (operands+0, 1, operands+0, operands+3);
696090286Sobrien   split_di (operands+1, 1, operands+1, operands+4);
696190286Sobrien   split_di (operands+2, 1, operands+2, operands+5);")
696218334Speter
696390286Sobrien(define_insn "subdi3_carry_rex64"
696490286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
696590286Sobrien	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
696690286Sobrien	    (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
696790286Sobrien	       (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
696890286Sobrien   (clobber (reg:CC 17))]
696990286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
697090286Sobrien  "sbb{q}\t{%2, %0|%0, %2}"
697190286Sobrien  [(set_attr "type" "alu")
697290286Sobrien   (set_attr "pent_pair" "pu")
697390286Sobrien   (set_attr "ppro_uops" "few")
697490286Sobrien   (set_attr "mode" "DI")])
697518334Speter
697690286Sobrien(define_insn "*subdi_1_rex64"
697790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
697890286Sobrien	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
697990286Sobrien		  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
698090286Sobrien   (clobber (reg:CC 17))]
698190286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
698290286Sobrien  "sub{q}\t{%2, %0|%0, %2}"
698390286Sobrien  [(set_attr "type" "alu")
698490286Sobrien   (set_attr "mode" "DI")])
698518334Speter
698690286Sobrien(define_insn "*subdi_2_rex64"
698790286Sobrien  [(set (reg 17)
698890286Sobrien	(compare
698990286Sobrien	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
699090286Sobrien		    (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
699190286Sobrien	  (const_int 0)))
699290286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
699390286Sobrien	(minus:DI (match_dup 1) (match_dup 2)))]
699490286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
699590286Sobrien   && ix86_binary_operator_ok (MINUS, DImode, operands)"
699690286Sobrien  "sub{q}\t{%2, %0|%0, %2}"
699790286Sobrien  [(set_attr "type" "alu")
699890286Sobrien   (set_attr "mode" "DI")])
699952296Sobrien
700090286Sobrien(define_insn "*subdi_3_rex63"
700190286Sobrien  [(set (reg 17)
700290286Sobrien	(compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
700390286Sobrien		 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
700490286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
700590286Sobrien	(minus:DI (match_dup 1) (match_dup 2)))]
700690286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
700790286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
700890286Sobrien  "sub{q}\t{%2, %0|%0, %2}"
700990286Sobrien  [(set_attr "type" "alu")
701090286Sobrien   (set_attr "mode" "DI")])
701118334Speter
701218334Speter
701390286Sobrien(define_insn "subsi3_carry"
701490286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
701590286Sobrien	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
701690286Sobrien	    (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
701790286Sobrien	       (match_operand:SI 2 "general_operand" "ri,rm"))))
701890286Sobrien   (clobber (reg:CC 17))]
701990286Sobrien  "ix86_binary_operator_ok (MINUS, SImode, operands)"
702090286Sobrien  "sbb{l}\t{%2, %0|%0, %2}"
702190286Sobrien  [(set_attr "type" "alu")
702290286Sobrien   (set_attr "pent_pair" "pu")
702390286Sobrien   (set_attr "ppro_uops" "few")
702490286Sobrien   (set_attr "mode" "SI")])
702518334Speter
702690286Sobrien(define_insn "subsi3_carry_zext"
702790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=rm,r")
702890286Sobrien	  (zero_extend:DI
702990286Sobrien	    (minus:SI (match_operand:SI 1 "register_operand" "0,0")
703090286Sobrien	      (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
703190286Sobrien		 (match_operand:SI 2 "general_operand" "ri,rm")))))
703290286Sobrien   (clobber (reg:CC 17))]
703390286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
703490286Sobrien  "sbb{l}\t{%2, %k0|%k0, %2}"
703590286Sobrien  [(set_attr "type" "alu")
703690286Sobrien   (set_attr "pent_pair" "pu")
703790286Sobrien   (set_attr "ppro_uops" "few")
703890286Sobrien   (set_attr "mode" "SI")])
703918334Speter
704050650Sobrien(define_expand "subsi3"
704190286Sobrien  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
704290286Sobrien		   (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
704390286Sobrien			     (match_operand:SI 2 "general_operand" "")))
704490286Sobrien	      (clobber (reg:CC 17))])]
704550650Sobrien  ""
704690286Sobrien  "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
704750650Sobrien
704890286Sobrien(define_insn "*subsi_1"
704950650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
705050650Sobrien	(minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
705190286Sobrien		  (match_operand:SI 2 "general_operand" "ri,rm")))
705290286Sobrien   (clobber (reg:CC 17))]
705350650Sobrien  "ix86_binary_operator_ok (MINUS, SImode, operands)"
705490286Sobrien  "sub{l}\t{%2, %0|%0, %2}"
705590286Sobrien  [(set_attr "type" "alu")
705690286Sobrien   (set_attr "mode" "SI")])
705718334Speter
705890286Sobrien(define_insn "*subsi_1_zext"
705990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
706090286Sobrien	(zero_extend:DI
706190286Sobrien	  (minus:SI (match_operand:SI 1 "register_operand" "0")
706290286Sobrien		    (match_operand:SI 2 "general_operand" "rim"))))
706390286Sobrien   (clobber (reg:CC 17))]
706490286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
706590286Sobrien  "sub{l}\t{%2, %k0|%k0, %2}"
706690286Sobrien  [(set_attr "type" "alu")
706790286Sobrien   (set_attr "mode" "SI")])
706890286Sobrien
706990286Sobrien(define_insn "*subsi_2"
707090286Sobrien  [(set (reg 17)
707190286Sobrien	(compare
707290286Sobrien	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
707390286Sobrien		    (match_operand:SI 2 "general_operand" "ri,rm"))
707490286Sobrien	  (const_int 0)))
707590286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
707690286Sobrien	(minus:SI (match_dup 1) (match_dup 2)))]
707790286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
707890286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
707990286Sobrien  "sub{l}\t{%2, %0|%0, %2}"
708090286Sobrien  [(set_attr "type" "alu")
708190286Sobrien   (set_attr "mode" "SI")])
708290286Sobrien
708390286Sobrien(define_insn "*subsi_2_zext"
708490286Sobrien  [(set (reg 17)
708590286Sobrien	(compare
708690286Sobrien	  (minus:SI (match_operand:SI 1 "register_operand" "0")
708790286Sobrien		    (match_operand:SI 2 "general_operand" "rim"))
708890286Sobrien	  (const_int 0)))
708990286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
709090286Sobrien	(zero_extend:DI
709190286Sobrien	  (minus:SI (match_dup 1)
709290286Sobrien		    (match_dup 2))))]
709390286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
709490286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
709590286Sobrien  "sub{l}\t{%2, %k0|%k0, %2}"
709690286Sobrien  [(set_attr "type" "alu")
709790286Sobrien   (set_attr "mode" "SI")])
709890286Sobrien
709990286Sobrien(define_insn "*subsi_3"
710090286Sobrien  [(set (reg 17)
710190286Sobrien	(compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
710290286Sobrien		 (match_operand:SI 2 "general_operand" "ri,rm")))
710390286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
710490286Sobrien	(minus:SI (match_dup 1) (match_dup 2)))]
710590286Sobrien  "ix86_match_ccmode (insn, CCmode)
710690286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
710790286Sobrien  "sub{l}\t{%2, %0|%0, %2}"
710890286Sobrien  [(set_attr "type" "alu")
710990286Sobrien   (set_attr "mode" "SI")])
711090286Sobrien
711190286Sobrien(define_insn "*subsi_3_zext"
711290286Sobrien  [(set (reg 17)
711390286Sobrien	(compare (match_operand:SI 1 "nonimmediate_operand" "0")
711490286Sobrien		 (match_operand:SI 2 "general_operand" "rim")))
711590286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
711690286Sobrien	(zero_extend:DI
711790286Sobrien	  (minus:SI (match_dup 1)
711890286Sobrien		    (match_dup 2))))]
711990286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
712090286Sobrien   && ix86_binary_operator_ok (MINUS, SImode, operands)"
712190286Sobrien  "sub{q}\t{%2, %0|%0, %2}"
712290286Sobrien  [(set_attr "type" "alu")
712390286Sobrien   (set_attr "mode" "DI")])
712490286Sobrien
712550650Sobrien(define_expand "subhi3"
712690286Sobrien  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
712790286Sobrien		   (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
712890286Sobrien			     (match_operand:HI 2 "general_operand" "")))
712990286Sobrien	      (clobber (reg:CC 17))])]
713090286Sobrien  "TARGET_HIMODE_MATH"
713190286Sobrien  "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
713250650Sobrien
713390286Sobrien(define_insn "*subhi_1"
713450650Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
713550650Sobrien	(minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
713690286Sobrien		  (match_operand:HI 2 "general_operand" "ri,rm")))
713790286Sobrien   (clobber (reg:CC 17))]
713850650Sobrien  "ix86_binary_operator_ok (MINUS, HImode, operands)"
713990286Sobrien  "sub{w}\t{%2, %0|%0, %2}"
714090286Sobrien  [(set_attr "type" "alu")
714190286Sobrien   (set_attr "mode" "HI")])
714250650Sobrien
714390286Sobrien(define_insn "*subhi_2"
714490286Sobrien  [(set (reg 17)
714590286Sobrien	(compare
714690286Sobrien	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
714790286Sobrien		    (match_operand:HI 2 "general_operand" "ri,rm"))
714890286Sobrien	  (const_int 0)))
714990286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
715090286Sobrien	(minus:HI (match_dup 1) (match_dup 2)))]
715190286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
715290286Sobrien   && ix86_binary_operator_ok (MINUS, HImode, operands)"
715390286Sobrien  "sub{w}\t{%2, %0|%0, %2}"
715490286Sobrien  [(set_attr "type" "alu")
715590286Sobrien   (set_attr "mode" "HI")])
715690286Sobrien
715790286Sobrien(define_insn "*subhi_3"
715890286Sobrien  [(set (reg 17)
715990286Sobrien	(compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
716090286Sobrien		 (match_operand:HI 2 "general_operand" "ri,rm")))
716190286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
716290286Sobrien	(minus:HI (match_dup 1) (match_dup 2)))]
716390286Sobrien  "ix86_match_ccmode (insn, CCmode)
716490286Sobrien   && ix86_binary_operator_ok (MINUS, HImode, operands)"
716590286Sobrien  "sub{w}\t{%2, %0|%0, %2}"
716690286Sobrien  [(set_attr "type" "alu")
716790286Sobrien   (set_attr "mode" "HI")])
716890286Sobrien
716950650Sobrien(define_expand "subqi3"
717090286Sobrien  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
717190286Sobrien		   (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
717290286Sobrien			     (match_operand:QI 2 "general_operand" "")))
717390286Sobrien	      (clobber (reg:CC 17))])]
717490286Sobrien  "TARGET_QIMODE_MATH"
717590286Sobrien  "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
717618334Speter
717790286Sobrien(define_insn "*subqi_1"
717850650Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
717950650Sobrien	(minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
718090286Sobrien		  (match_operand:QI 2 "general_operand" "qn,qmn")))
718190286Sobrien   (clobber (reg:CC 17))]
718250650Sobrien  "ix86_binary_operator_ok (MINUS, QImode, operands)"
718390286Sobrien  "sub{b}\t{%2, %0|%0, %2}"
718490286Sobrien  [(set_attr "type" "alu")
718590286Sobrien   (set_attr "mode" "QI")])
718618334Speter
718790286Sobrien(define_insn "*subqi_2"
718890286Sobrien  [(set (reg 17)
718990286Sobrien	(compare
719090286Sobrien	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
719190286Sobrien		    (match_operand:QI 2 "general_operand" "qi,qm"))
719290286Sobrien	  (const_int 0)))
719390286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
719490286Sobrien	(minus:HI (match_dup 1) (match_dup 2)))]
719590286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
719690286Sobrien   && ix86_binary_operator_ok (MINUS, QImode, operands)"
719790286Sobrien  "sub{b}\t{%2, %0|%0, %2}"
719890286Sobrien  [(set_attr "type" "alu")
719990286Sobrien   (set_attr "mode" "QI")])
720090286Sobrien
720190286Sobrien(define_insn "*subqi_3"
720290286Sobrien  [(set (reg 17)
720390286Sobrien	(compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
720490286Sobrien		 (match_operand:QI 2 "general_operand" "qi,qm")))
720590286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
720690286Sobrien	(minus:HI (match_dup 1) (match_dup 2)))]
720790286Sobrien  "ix86_match_ccmode (insn, CCmode)
720890286Sobrien   && ix86_binary_operator_ok (MINUS, QImode, operands)"
720990286Sobrien  "sub{b}\t{%2, %0|%0, %2}"
721090286Sobrien  [(set_attr "type" "alu")
721190286Sobrien   (set_attr "mode" "QI")])
721290286Sobrien
721318334Speter;; The patterns that match these are at the end of this file.
721418334Speter
721518334Speter(define_expand "subxf3"
721618334Speter  [(set (match_operand:XF 0 "register_operand" "")
721750650Sobrien	(minus:XF (match_operand:XF 1 "register_operand" "")
721850650Sobrien		  (match_operand:XF 2 "register_operand" "")))]
721990286Sobrien  "!TARGET_64BIT && TARGET_80387"
722090286Sobrien  "")
722190286Sobrien
722290286Sobrien(define_expand "subtf3"
722390286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
722490286Sobrien	(minus:TF (match_operand:TF 1 "register_operand" "")
722590286Sobrien		  (match_operand:TF 2 "register_operand" "")))]
722618334Speter  "TARGET_80387"
722718334Speter  "")
722818334Speter
722918334Speter(define_expand "subdf3"
723018334Speter  [(set (match_operand:DF 0 "register_operand" "")
723190286Sobrien	(minus:DF (match_operand:DF 1 "register_operand" "")
723218334Speter		  (match_operand:DF 2 "nonimmediate_operand" "")))]
723390286Sobrien  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
723418334Speter  "")
723518334Speter
723618334Speter(define_expand "subsf3"
723718334Speter  [(set (match_operand:SF 0 "register_operand" "")
723890286Sobrien	(minus:SF (match_operand:SF 1 "register_operand" "")
723918334Speter		  (match_operand:SF 2 "nonimmediate_operand" "")))]
724090286Sobrien  "TARGET_80387 || TARGET_SSE_MATH"
724118334Speter  "")
724218334Speter
724390286Sobrien;; Multiply instructions
724418334Speter
724590286Sobrien(define_expand "muldi3"
724690286Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
724790286Sobrien		   (mult:DI (match_operand:DI 1 "register_operand" "")
724890286Sobrien			    (match_operand:DI 2 "x86_64_general_operand" "")))
724990286Sobrien	      (clobber (reg:CC 17))])]
725090286Sobrien  "TARGET_64BIT"
725190286Sobrien  "")
725218334Speter
725390286Sobrien(define_insn "*muldi3_1_rex64"
725490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
725590286Sobrien	(mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,0,0")
725690286Sobrien		 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
725790286Sobrien   (clobber (reg:CC 17))]
725890286Sobrien  "TARGET_64BIT
725990286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
726090286Sobrien  "@
726190286Sobrien   imul{q}\t{%2, %1, %0|%0, %1, %2}
726290286Sobrien   imul{q}\t{%2, %1, %0|%0, %1, %2}
726390286Sobrien   imul{q}\t{%2, %0|%0, %2}"
726490286Sobrien  [(set_attr "type" "imul")
726590286Sobrien   (set_attr "prefix_0f" "0,0,1")
726690286Sobrien   (set_attr "mode" "DI")])
726718334Speter
726890286Sobrien(define_expand "mulsi3"
726990286Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "")
727090286Sobrien		   (mult:SI (match_operand:SI 1 "register_operand" "")
727190286Sobrien			    (match_operand:SI 2 "general_operand" "")))
727290286Sobrien	      (clobber (reg:CC 17))])]
727318334Speter  ""
727490286Sobrien  "")
727518334Speter
727690286Sobrien(define_insn "*mulsi3_1"
727790286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
727890286Sobrien	(mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
727990286Sobrien		 (match_operand:SI 2 "general_operand" "K,i,mr")))
728090286Sobrien   (clobber (reg:CC 17))]
728190286Sobrien  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
728290286Sobrien  ; For the {r,0,i} alternative (i.e., register <- register * immediate),
728390286Sobrien  ; there are two ways of writing the exact same machine instruction
728490286Sobrien  ; in assembly language.  One, for example, is:
728590286Sobrien  ;
728690286Sobrien  ;   imul $12, %eax
728790286Sobrien  ;
728890286Sobrien  ; while the other is:
728990286Sobrien  ;
729090286Sobrien  ;   imul $12, %eax, %eax
729190286Sobrien  ;
729290286Sobrien  ; The first is simply short-hand for the latter.  But, some assemblers,
729390286Sobrien  ; like the SCO OSR5 COFF assembler, don't handle the first form.
729490286Sobrien  "@
729590286Sobrien   imul{l}\t{%2, %1, %0|%0, %1, %2}
729690286Sobrien   imul{l}\t{%2, %1, %0|%0, %1, %2}
729790286Sobrien   imul{l}\t{%2, %0|%0, %2}"
729890286Sobrien  [(set_attr "type" "imul")
729990286Sobrien   (set_attr "prefix_0f" "0,0,1")
730090286Sobrien   (set_attr "mode" "SI")])
730190286Sobrien
730290286Sobrien(define_insn "*mulsi3_1_zext"
730390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
730490286Sobrien	(zero_extend:DI
730590286Sobrien	  (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
730690286Sobrien		   (match_operand:SI 2 "general_operand" "K,i,mr"))))
730790286Sobrien   (clobber (reg:CC 17))]
730890286Sobrien  "TARGET_64BIT
730990286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
731090286Sobrien  ; For the {r,0,i} alternative (i.e., register <- register * immediate),
731190286Sobrien  ; there are two ways of writing the exact same machine instruction
731290286Sobrien  ; in assembly language.  One, for example, is:
731390286Sobrien  ;
731490286Sobrien  ;   imul $12, %eax
731590286Sobrien  ;
731690286Sobrien  ; while the other is:
731790286Sobrien  ;
731890286Sobrien  ;   imul $12, %eax, %eax
731990286Sobrien  ;
732090286Sobrien  ; The first is simply short-hand for the latter.  But, some assemblers,
732190286Sobrien  ; like the SCO OSR5 COFF assembler, don't handle the first form.
732290286Sobrien  "@
732390286Sobrien   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
732490286Sobrien   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
732590286Sobrien   imul{l}\t{%2, %k0|%k0, %2}"
732690286Sobrien  [(set_attr "type" "imul")
732790286Sobrien   (set_attr "prefix_0f" "0,0,1")
732890286Sobrien   (set_attr "mode" "SI")])
732990286Sobrien
733090286Sobrien(define_expand "mulhi3"
733190286Sobrien  [(parallel [(set (match_operand:HI 0 "register_operand" "")
733290286Sobrien		   (mult:HI (match_operand:HI 1 "register_operand" "")
733390286Sobrien			    (match_operand:HI 2 "general_operand" "")))
733490286Sobrien	      (clobber (reg:CC 17))])]
733590286Sobrien  "TARGET_HIMODE_MATH"
733690286Sobrien  "")
733790286Sobrien
733890286Sobrien(define_insn "*mulhi3_1"
733990286Sobrien  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
734090286Sobrien	(mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0")
734190286Sobrien		 (match_operand:HI 2 "general_operand" "K,i,mr")))
734290286Sobrien   (clobber (reg:CC 17))]
734390286Sobrien  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
734490286Sobrien  ; %%% There was a note about "Assembler has weird restrictions",
734590286Sobrien  ; concerning alternative 1 when op1 == op0.  True?
734690286Sobrien  "@
734790286Sobrien   imul{w}\t{%2, %1, %0|%0, %1, %2}
734890286Sobrien   imul{w}\t{%2, %1, %0|%0, %1, %2}
734990286Sobrien   imul{w}\t{%2, %0|%0, %2}"
735090286Sobrien  [(set_attr "type" "imul")
735190286Sobrien   (set_attr "prefix_0f" "0,0,1")
735290286Sobrien   (set_attr "mode" "HI")])
735390286Sobrien
735496294Sobrien(define_expand "mulqi3"
735596294Sobrien  [(parallel [(set (match_operand:QI 0 "register_operand" "")
735696294Sobrien		   (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
735796294Sobrien			    (match_operand:QI 2 "register_operand" "")))
735896294Sobrien	      (clobber (reg:CC 17))])]
735996294Sobrien  "TARGET_QIMODE_MATH"
736096294Sobrien  "")
736196294Sobrien
736296294Sobrien(define_insn "*mulqi3_1"
736390286Sobrien  [(set (match_operand:QI 0 "register_operand" "=a")
736496294Sobrien	(mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
736590286Sobrien		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
736690286Sobrien   (clobber (reg:CC 17))]
736796294Sobrien  "TARGET_QIMODE_MATH
736896294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
736990286Sobrien  "mul{b}\t%2"
737090286Sobrien  [(set_attr "type" "imul")
737190286Sobrien   (set_attr "length_immediate" "0")
737290286Sobrien   (set_attr "mode" "QI")])
737390286Sobrien
737496294Sobrien(define_expand "umulqihi3"
737596294Sobrien  [(parallel [(set (match_operand:HI 0 "register_operand" "")
737696294Sobrien		   (mult:HI (zero_extend:HI
737796294Sobrien			      (match_operand:QI 1 "nonimmediate_operand" ""))
737896294Sobrien			    (zero_extend:HI
737996294Sobrien			      (match_operand:QI 2 "register_operand" ""))))
738096294Sobrien	      (clobber (reg:CC 17))])]
738196294Sobrien  "TARGET_QIMODE_MATH"
738296294Sobrien  "")
738396294Sobrien
738496294Sobrien(define_insn "*umulqihi3_1"
738550650Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
738696294Sobrien	(mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
738790286Sobrien		 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
738890286Sobrien   (clobber (reg:CC 17))]
738996294Sobrien  "TARGET_QIMODE_MATH
739096294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
739190286Sobrien  "mul{b}\t%2"
739290286Sobrien  [(set_attr "type" "imul")
739390286Sobrien   (set_attr "length_immediate" "0")
739490286Sobrien   (set_attr "mode" "QI")])
739518334Speter
739696294Sobrien(define_expand "mulqihi3"
739796294Sobrien  [(parallel [(set (match_operand:HI 0 "register_operand" "")
739896294Sobrien		   (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
739996294Sobrien			    (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
740096294Sobrien	      (clobber (reg:CC 17))])]
740196294Sobrien  "TARGET_QIMODE_MATH"
740296294Sobrien  "")
740396294Sobrien
740496294Sobrien(define_insn "*mulqihi3_insn"
740550650Sobrien  [(set (match_operand:HI 0 "register_operand" "=a")
740696294Sobrien	(mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
740790286Sobrien		 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
740890286Sobrien   (clobber (reg:CC 17))]
740996294Sobrien  "TARGET_QIMODE_MATH
741096294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
741190286Sobrien  "imul{b}\t%2"
741290286Sobrien  [(set_attr "type" "imul")
741390286Sobrien   (set_attr "length_immediate" "0")
741490286Sobrien   (set_attr "mode" "QI")])
741518334Speter
741696294Sobrien(define_expand "umulditi3"
741796294Sobrien  [(parallel [(set (match_operand:TI 0 "register_operand" "")
741896294Sobrien		   (mult:TI (zero_extend:TI
741996294Sobrien			      (match_operand:DI 1 "nonimmediate_operand" ""))
742096294Sobrien			    (zero_extend:TI
742196294Sobrien			      (match_operand:DI 2 "register_operand" ""))))
742296294Sobrien	      (clobber (reg:CC 17))])]
742396294Sobrien  "TARGET_64BIT"
742496294Sobrien  "")
742596294Sobrien
742696294Sobrien(define_insn "*umulditi3_insn"
742790286Sobrien  [(set (match_operand:TI 0 "register_operand" "=A")
742896294Sobrien	(mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
742990286Sobrien		 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
743090286Sobrien   (clobber (reg:CC 17))]
743196294Sobrien  "TARGET_64BIT
743296294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
743390286Sobrien  "mul{q}\t%2"
743490286Sobrien  [(set_attr "type" "imul")
743590286Sobrien   (set_attr "ppro_uops" "few")
743690286Sobrien   (set_attr "length_immediate" "0")
743790286Sobrien   (set_attr "mode" "DI")])
743890286Sobrien
743990286Sobrien;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
744096294Sobrien(define_expand "umulsidi3"
744196294Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
744296294Sobrien		   (mult:DI (zero_extend:DI
744396294Sobrien			      (match_operand:SI 1 "nonimmediate_operand" ""))
744496294Sobrien			    (zero_extend:DI
744596294Sobrien			      (match_operand:SI 2 "register_operand" ""))))
744696294Sobrien	      (clobber (reg:CC 17))])]
744796294Sobrien  "!TARGET_64BIT"
744896294Sobrien  "")
744996294Sobrien
745096294Sobrien(define_insn "*umulsidi3_insn"
745118334Speter  [(set (match_operand:DI 0 "register_operand" "=A")
745296294Sobrien	(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
745390286Sobrien		 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
745490286Sobrien   (clobber (reg:CC 17))]
745596294Sobrien  "!TARGET_64BIT
745696294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
745790286Sobrien  "mul{l}\t%2"
745890286Sobrien  [(set_attr "type" "imul")
745990286Sobrien   (set_attr "ppro_uops" "few")
746090286Sobrien   (set_attr "length_immediate" "0")
746190286Sobrien   (set_attr "mode" "SI")])
746218334Speter
746396294Sobrien(define_expand "mulditi3"
746496294Sobrien  [(parallel [(set (match_operand:TI 0 "register_operand" "")
746596294Sobrien		   (mult:TI (sign_extend:TI
746696294Sobrien			      (match_operand:DI 1 "nonimmediate_operand" ""))
746796294Sobrien			    (sign_extend:TI
746896294Sobrien			      (match_operand:DI 2 "register_operand" ""))))
746996294Sobrien	      (clobber (reg:CC 17))])]
747096294Sobrien  "TARGET_64BIT"
747196294Sobrien  "")
747296294Sobrien
747396294Sobrien(define_insn "*mulditi3_insn"
747490286Sobrien  [(set (match_operand:TI 0 "register_operand" "=A")
747596294Sobrien	(mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
747690286Sobrien		 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
747790286Sobrien   (clobber (reg:CC 17))]
747896294Sobrien  "TARGET_64BIT
747996294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
748090286Sobrien  "imul{q}\t%2"
748190286Sobrien  [(set_attr "type" "imul")
748290286Sobrien   (set_attr "length_immediate" "0")
748390286Sobrien   (set_attr "mode" "DI")])
748490286Sobrien
748596294Sobrien(define_expand "mulsidi3"
748696294Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
748796294Sobrien		   (mult:DI (sign_extend:DI
748896294Sobrien			      (match_operand:SI 1 "nonimmediate_operand" ""))
748996294Sobrien			    (sign_extend:DI
749096294Sobrien			      (match_operand:SI 2 "register_operand" ""))))
749196294Sobrien	      (clobber (reg:CC 17))])]
749296294Sobrien  "!TARGET_64BIT"
749396294Sobrien  "")
749496294Sobrien
749596294Sobrien(define_insn "*mulsidi3_insn"
749618334Speter  [(set (match_operand:DI 0 "register_operand" "=A")
749796294Sobrien	(mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
749890286Sobrien		 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
749990286Sobrien   (clobber (reg:CC 17))]
750096294Sobrien  "!TARGET_64BIT
750196294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
750290286Sobrien  "imul{l}\t%2"
750390286Sobrien  [(set_attr "type" "imul")
750490286Sobrien   (set_attr "length_immediate" "0")
750590286Sobrien   (set_attr "mode" "SI")])
750618334Speter
750796294Sobrien(define_expand "umuldi3_highpart"
750896294Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
750996294Sobrien		   (truncate:DI
751096294Sobrien		     (lshiftrt:TI
751196294Sobrien		       (mult:TI (zero_extend:TI
751296294Sobrien				  (match_operand:DI 1 "nonimmediate_operand" ""))
751396294Sobrien				(zero_extend:TI
751496294Sobrien				  (match_operand:DI 2 "register_operand" "")))
751596294Sobrien		       (const_int 64))))
751696294Sobrien	      (clobber (match_scratch:DI 3 ""))
751796294Sobrien	      (clobber (reg:CC 17))])]
751896294Sobrien  "TARGET_64BIT"
751996294Sobrien  "")
752096294Sobrien
752190286Sobrien(define_insn "*umuldi3_highpart_rex64"
752290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
752390286Sobrien	(truncate:DI
752490286Sobrien	  (lshiftrt:TI
752590286Sobrien	    (mult:TI (zero_extend:TI
752696294Sobrien		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
752790286Sobrien		     (zero_extend:TI
752890286Sobrien		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
752990286Sobrien	    (const_int 64))))
753096294Sobrien   (clobber (match_scratch:DI 3 "=1"))
753190286Sobrien   (clobber (reg:CC 17))]
753296294Sobrien  "TARGET_64BIT
753396294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
753490286Sobrien  "mul{q}\t%2"
753590286Sobrien  [(set_attr "type" "imul")
753690286Sobrien   (set_attr "ppro_uops" "few")
753790286Sobrien   (set_attr "length_immediate" "0")
753890286Sobrien   (set_attr "mode" "DI")])
753990286Sobrien
754096294Sobrien(define_expand "umulsi3_highpart"
754196294Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "")
754296294Sobrien		   (truncate:SI
754396294Sobrien		     (lshiftrt:DI
754496294Sobrien		       (mult:DI (zero_extend:DI
754596294Sobrien				  (match_operand:SI 1 "nonimmediate_operand" ""))
754696294Sobrien				(zero_extend:DI
754796294Sobrien				  (match_operand:SI 2 "register_operand" "")))
754896294Sobrien		       (const_int 32))))
754996294Sobrien	      (clobber (match_scratch:SI 3 ""))
755096294Sobrien	      (clobber (reg:CC 17))])]
755196294Sobrien  ""
755296294Sobrien  "")
755396294Sobrien
755496294Sobrien(define_insn "*umulsi3_highpart_insn"
755518334Speter  [(set (match_operand:SI 0 "register_operand" "=d")
755690286Sobrien	(truncate:SI
755790286Sobrien	  (lshiftrt:DI
755890286Sobrien	    (mult:DI (zero_extend:DI
755996294Sobrien		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
756090286Sobrien		     (zero_extend:DI
756190286Sobrien		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
756290286Sobrien	    (const_int 32))))
756396294Sobrien   (clobber (match_scratch:SI 3 "=1"))
756490286Sobrien   (clobber (reg:CC 17))]
756596294Sobrien  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
756690286Sobrien  "mul{l}\t%2"
756790286Sobrien  [(set_attr "type" "imul")
756890286Sobrien   (set_attr "ppro_uops" "few")
756990286Sobrien   (set_attr "length_immediate" "0")
757090286Sobrien   (set_attr "mode" "SI")])
757118334Speter
757290286Sobrien(define_insn "*umulsi3_highpart_zext"
757390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
757490286Sobrien	(zero_extend:DI (truncate:SI
757590286Sobrien	  (lshiftrt:DI
757690286Sobrien	    (mult:DI (zero_extend:DI
757796294Sobrien		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
757890286Sobrien		     (zero_extend:DI
757990286Sobrien		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
758090286Sobrien	    (const_int 32)))))
758196294Sobrien   (clobber (match_scratch:SI 3 "=1"))
758290286Sobrien   (clobber (reg:CC 17))]
758396294Sobrien  "TARGET_64BIT
758496294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
758590286Sobrien  "mul{l}\t%2"
758690286Sobrien  [(set_attr "type" "imul")
758790286Sobrien   (set_attr "ppro_uops" "few")
758890286Sobrien   (set_attr "length_immediate" "0")
758990286Sobrien   (set_attr "mode" "SI")])
759090286Sobrien
759196294Sobrien(define_expand "smuldi3_highpart"
759296294Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
759396294Sobrien		   (truncate:DI
759496294Sobrien		     (lshiftrt:TI
759596294Sobrien		       (mult:TI (sign_extend:TI
759696294Sobrien				  (match_operand:DI 1 "nonimmediate_operand" ""))
759796294Sobrien				(sign_extend:TI
759896294Sobrien				  (match_operand:DI 2 "register_operand" "")))
759996294Sobrien		       (const_int 64))))
760096294Sobrien	      (clobber (match_scratch:DI 3 ""))
760196294Sobrien	      (clobber (reg:CC 17))])]
760296294Sobrien  "TARGET_64BIT"
760396294Sobrien  "")
760496294Sobrien
760590286Sobrien(define_insn "*smuldi3_highpart_rex64"
760690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
760790286Sobrien	(truncate:DI
760890286Sobrien	  (lshiftrt:TI
760990286Sobrien	    (mult:TI (sign_extend:TI
761096294Sobrien		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
761190286Sobrien		     (sign_extend:TI
761290286Sobrien		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
761390286Sobrien	    (const_int 64))))
761496294Sobrien   (clobber (match_scratch:DI 3 "=1"))
761590286Sobrien   (clobber (reg:CC 17))]
761696294Sobrien  "TARGET_64BIT
761796294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
761890286Sobrien  "imul{q}\t%2"
761990286Sobrien  [(set_attr "type" "imul")
762090286Sobrien   (set_attr "ppro_uops" "few")
762190286Sobrien   (set_attr "mode" "DI")])
762290286Sobrien
762396294Sobrien(define_expand "smulsi3_highpart"
762496294Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "")
762596294Sobrien		   (truncate:SI
762696294Sobrien		     (lshiftrt:DI
762796294Sobrien		       (mult:DI (sign_extend:DI
762896294Sobrien				  (match_operand:SI 1 "nonimmediate_operand" ""))
762996294Sobrien				(sign_extend:DI
763096294Sobrien				  (match_operand:SI 2 "register_operand" "")))
763196294Sobrien		       (const_int 32))))
763296294Sobrien	      (clobber (match_scratch:SI 3 ""))
763396294Sobrien	      (clobber (reg:CC 17))])]
763496294Sobrien  ""
763596294Sobrien  "")
763696294Sobrien
763796294Sobrien(define_insn "*smulsi3_highpart_insn"
763818334Speter  [(set (match_operand:SI 0 "register_operand" "=d")
763990286Sobrien	(truncate:SI
764090286Sobrien	  (lshiftrt:DI
764190286Sobrien	    (mult:DI (sign_extend:DI
764296294Sobrien		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
764390286Sobrien		     (sign_extend:DI
764490286Sobrien		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
764590286Sobrien	    (const_int 32))))
764696294Sobrien   (clobber (match_scratch:SI 3 "=1"))
764790286Sobrien   (clobber (reg:CC 17))]
764896294Sobrien  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
764990286Sobrien  "imul{l}\t%2"
765090286Sobrien  [(set_attr "type" "imul")
765190286Sobrien   (set_attr "ppro_uops" "few")
765290286Sobrien   (set_attr "mode" "SI")])
765318334Speter
765490286Sobrien(define_insn "*smulsi3_highpart_zext"
765590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
765690286Sobrien	(zero_extend:DI (truncate:SI
765790286Sobrien	  (lshiftrt:DI
765890286Sobrien	    (mult:DI (sign_extend:DI
765996294Sobrien		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
766090286Sobrien		     (sign_extend:DI
766190286Sobrien		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
766290286Sobrien	    (const_int 32)))))
766396294Sobrien   (clobber (match_scratch:SI 3 "=1"))
766490286Sobrien   (clobber (reg:CC 17))]
766596294Sobrien  "TARGET_64BIT
766696294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
766790286Sobrien  "imul{l}\t%2"
766890286Sobrien  [(set_attr "type" "imul")
766990286Sobrien   (set_attr "ppro_uops" "few")
767090286Sobrien   (set_attr "mode" "SI")])
767190286Sobrien
767218334Speter;; The patterns that match these are at the end of this file.
767318334Speter
767418334Speter(define_expand "mulxf3"
767518334Speter  [(set (match_operand:XF 0 "register_operand" "")
767650650Sobrien	(mult:XF (match_operand:XF 1 "register_operand" "")
767750650Sobrien		 (match_operand:XF 2 "register_operand" "")))]
767890286Sobrien  "!TARGET_64BIT && TARGET_80387"
767990286Sobrien  "")
768090286Sobrien
768190286Sobrien(define_expand "multf3"
768290286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
768390286Sobrien	(mult:TF (match_operand:TF 1 "register_operand" "")
768490286Sobrien		 (match_operand:TF 2 "register_operand" "")))]
768518334Speter  "TARGET_80387"
768618334Speter  "")
768718334Speter
768818334Speter(define_expand "muldf3"
768918334Speter  [(set (match_operand:DF 0 "register_operand" "")
769050650Sobrien	(mult:DF (match_operand:DF 1 "register_operand" "")
769118334Speter		 (match_operand:DF 2 "nonimmediate_operand" "")))]
769290286Sobrien  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
769318334Speter  "")
769418334Speter
769518334Speter(define_expand "mulsf3"
769618334Speter  [(set (match_operand:SF 0 "register_operand" "")
769750650Sobrien	(mult:SF (match_operand:SF 1 "register_operand" "")
769818334Speter		 (match_operand:SF 2 "nonimmediate_operand" "")))]
769990286Sobrien  "TARGET_80387 || TARGET_SSE_MATH"
770018334Speter  "")
770118334Speter
770290286Sobrien;; Divide instructions
770318334Speter
770418334Speter(define_insn "divqi3"
770550650Sobrien  [(set (match_operand:QI 0 "register_operand" "=a")
770650650Sobrien	(div:QI (match_operand:HI 1 "register_operand" "0")
770790286Sobrien		(match_operand:QI 2 "nonimmediate_operand" "qm")))
770890286Sobrien   (clobber (reg:CC 17))]
770990286Sobrien  "TARGET_QIMODE_MATH"
771090286Sobrien  "idiv{b}\t%2"
771190286Sobrien  [(set_attr "type" "idiv")
771290286Sobrien   (set_attr "mode" "QI")
771390286Sobrien   (set_attr "ppro_uops" "few")])
771418334Speter
771518334Speter(define_insn "udivqi3"
771650650Sobrien  [(set (match_operand:QI 0 "register_operand" "=a")
771750650Sobrien	(udiv:QI (match_operand:HI 1 "register_operand" "0")
771890286Sobrien		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
771990286Sobrien   (clobber (reg:CC 17))]
772090286Sobrien  "TARGET_QIMODE_MATH"
772190286Sobrien  "div{b}\t%2"
772290286Sobrien  [(set_attr "type" "idiv")
772390286Sobrien   (set_attr "mode" "QI")
772490286Sobrien   (set_attr "ppro_uops" "few")])
772518334Speter
772618334Speter;; The patterns that match these are at the end of this file.
772718334Speter
772818334Speter(define_expand "divxf3"
772918334Speter  [(set (match_operand:XF 0 "register_operand" "")
773050650Sobrien	(div:XF (match_operand:XF 1 "register_operand" "")
773150650Sobrien		(match_operand:XF 2 "register_operand" "")))]
773290286Sobrien  "!TARGET_64BIT && TARGET_80387"
773390286Sobrien  "")
773490286Sobrien
773590286Sobrien(define_expand "divtf3"
773690286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
773790286Sobrien	(div:TF (match_operand:TF 1 "register_operand" "")
773890286Sobrien		(match_operand:TF 2 "register_operand" "")))]
773918334Speter  "TARGET_80387"
774018334Speter  "")
774118334Speter
774218334Speter(define_expand "divdf3"
774318334Speter  [(set (match_operand:DF 0 "register_operand" "")
774450650Sobrien 	(div:DF (match_operand:DF 1 "register_operand" "")
774550650Sobrien 		(match_operand:DF 2 "nonimmediate_operand" "")))]
774690286Sobrien   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
774750650Sobrien   "")
774850650Sobrien 
774918334Speter(define_expand "divsf3"
775018334Speter  [(set (match_operand:SF 0 "register_operand" "")
775150650Sobrien	(div:SF (match_operand:SF 1 "register_operand" "")
775218334Speter		(match_operand:SF 2 "nonimmediate_operand" "")))]
775390286Sobrien  "TARGET_80387 || TARGET_SSE_MATH"
775418334Speter  "")
775518334Speter
775618334Speter;; Remainder instructions.
775718334Speter
775890286Sobrien(define_expand "divmoddi4"
775990286Sobrien  [(parallel [(set (match_operand:DI 0 "register_operand" "")
776090286Sobrien		   (div:DI (match_operand:DI 1 "register_operand" "")
776190286Sobrien			   (match_operand:DI 2 "nonimmediate_operand" "")))
776290286Sobrien	      (set (match_operand:DI 3 "register_operand" "")
776390286Sobrien		   (mod:DI (match_dup 1) (match_dup 2)))
776490286Sobrien	      (clobber (reg:CC 17))])]
776590286Sobrien  "TARGET_64BIT"
776690286Sobrien  "")
776790286Sobrien
776890286Sobrien;; Allow to come the parameter in eax or edx to avoid extra moves.
776990286Sobrien;; Penalize eax case sligthly because it results in worse scheduling
777090286Sobrien;; of code.
777190286Sobrien(define_insn "*divmoddi4_nocltd_rex64"
777290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=&a,?a")
777390286Sobrien	(div:DI (match_operand:DI 2 "register_operand" "1,0")
777490286Sobrien		(match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
777590286Sobrien   (set (match_operand:DI 1 "register_operand" "=&d,&d")
777690286Sobrien	(mod:DI (match_dup 2) (match_dup 3)))
777790286Sobrien   (clobber (reg:CC 17))]
777890286Sobrien  "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
777990286Sobrien  "#"
778090286Sobrien  [(set_attr "type" "multi")])
778190286Sobrien
778290286Sobrien(define_insn "*divmoddi4_cltd_rex64"
778390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a")
778490286Sobrien	(div:DI (match_operand:DI 2 "register_operand" "a")
778590286Sobrien		(match_operand:DI 3 "nonimmediate_operand" "rm")))
778690286Sobrien   (set (match_operand:DI 1 "register_operand" "=&d")
778790286Sobrien	(mod:DI (match_dup 2) (match_dup 3)))
778890286Sobrien   (clobber (reg:CC 17))]
778990286Sobrien  "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
779090286Sobrien  "#"
779190286Sobrien  [(set_attr "type" "multi")])
779290286Sobrien
779390286Sobrien(define_insn "*divmoddi_noext_rex64"
779490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a")
779590286Sobrien	(div:DI (match_operand:DI 1 "register_operand" "0")
779690286Sobrien		(match_operand:DI 2 "nonimmediate_operand" "rm")))
779790286Sobrien   (set (match_operand:DI 3 "register_operand" "=d")
779890286Sobrien	(mod:DI (match_dup 1) (match_dup 2)))
779990286Sobrien   (use (match_operand:DI 4 "register_operand" "3"))
780090286Sobrien   (clobber (reg:CC 17))]
780190286Sobrien  "TARGET_64BIT"
780290286Sobrien  "idiv{q}\t%2"
780390286Sobrien  [(set_attr "type" "idiv")
780490286Sobrien   (set_attr "mode" "DI")
780590286Sobrien   (set_attr "ppro_uops" "few")])
780690286Sobrien
780790286Sobrien(define_split
780890286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
780990286Sobrien	(div:DI (match_operand:DI 1 "register_operand" "")
781090286Sobrien		(match_operand:DI 2 "nonimmediate_operand" "")))
781190286Sobrien   (set (match_operand:DI 3 "register_operand" "")
781290286Sobrien	(mod:DI (match_dup 1) (match_dup 2)))
781390286Sobrien   (clobber (reg:CC 17))]
781490286Sobrien  "TARGET_64BIT && reload_completed"
781590286Sobrien  [(parallel [(set (match_dup 3)
781690286Sobrien		   (ashiftrt:DI (match_dup 4) (const_int 63)))
781790286Sobrien	      (clobber (reg:CC 17))])
781890286Sobrien   (parallel [(set (match_dup 0)
781990286Sobrien	           (div:DI (reg:DI 0) (match_dup 2)))
782090286Sobrien	      (set (match_dup 3)
782190286Sobrien		   (mod:DI (reg:DI 0) (match_dup 2)))
782290286Sobrien	      (use (match_dup 3))
782390286Sobrien	      (clobber (reg:CC 17))])]
782490286Sobrien{
782590286Sobrien  /* Avoid use of cltd in favour of a mov+shift.  */
782690286Sobrien  if (!TARGET_USE_CLTD && !optimize_size)
782790286Sobrien    {
782890286Sobrien      if (true_regnum (operands[1]))
782990286Sobrien        emit_move_insn (operands[0], operands[1]);
783090286Sobrien      else
783190286Sobrien	emit_move_insn (operands[3], operands[1]);
783290286Sobrien      operands[4] = operands[3];
783390286Sobrien    }
783490286Sobrien  else
783590286Sobrien    {
783690286Sobrien      if (true_regnum (operands[1]))
783790286Sobrien	abort();
783890286Sobrien      operands[4] = operands[1];
783990286Sobrien    }
784090286Sobrien})
784190286Sobrien
784290286Sobrien
784390286Sobrien(define_expand "divmodsi4"
784490286Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "")
784590286Sobrien		   (div:SI (match_operand:SI 1 "register_operand" "")
784690286Sobrien			   (match_operand:SI 2 "nonimmediate_operand" "")))
784790286Sobrien	      (set (match_operand:SI 3 "register_operand" "")
784890286Sobrien		   (mod:SI (match_dup 1) (match_dup 2)))
784990286Sobrien	      (clobber (reg:CC 17))])]
785090286Sobrien  ""
785190286Sobrien  "")
785290286Sobrien
785390286Sobrien;; Allow to come the parameter in eax or edx to avoid extra moves.
785490286Sobrien;; Penalize eax case sligthly because it results in worse scheduling
785590286Sobrien;; of code.
785690286Sobrien(define_insn "*divmodsi4_nocltd"
785790286Sobrien  [(set (match_operand:SI 0 "register_operand" "=&a,?a")
785890286Sobrien	(div:SI (match_operand:SI 2 "register_operand" "1,0")
785990286Sobrien		(match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
786090286Sobrien   (set (match_operand:SI 1 "register_operand" "=&d,&d")
786190286Sobrien	(mod:SI (match_dup 2) (match_dup 3)))
786290286Sobrien   (clobber (reg:CC 17))]
786390286Sobrien  "!optimize_size && !TARGET_USE_CLTD"
786490286Sobrien  "#"
786590286Sobrien  [(set_attr "type" "multi")])
786690286Sobrien
786790286Sobrien(define_insn "*divmodsi4_cltd"
786818334Speter  [(set (match_operand:SI 0 "register_operand" "=a")
786990286Sobrien	(div:SI (match_operand:SI 2 "register_operand" "a")
787090286Sobrien		(match_operand:SI 3 "nonimmediate_operand" "rm")))
787190286Sobrien   (set (match_operand:SI 1 "register_operand" "=&d")
787290286Sobrien	(mod:SI (match_dup 2) (match_dup 3)))
787390286Sobrien   (clobber (reg:CC 17))]
787490286Sobrien  "optimize_size || TARGET_USE_CLTD"
787590286Sobrien  "#"
787690286Sobrien  [(set_attr "type" "multi")])
787790286Sobrien
787890286Sobrien(define_insn "*divmodsi_noext"
787990286Sobrien  [(set (match_operand:SI 0 "register_operand" "=a")
788018334Speter	(div:SI (match_operand:SI 1 "register_operand" "0")
788150650Sobrien		(match_operand:SI 2 "nonimmediate_operand" "rm")))
788290286Sobrien   (set (match_operand:SI 3 "register_operand" "=d")
788390286Sobrien	(mod:SI (match_dup 1) (match_dup 2)))
788490286Sobrien   (use (match_operand:SI 4 "register_operand" "3"))
788590286Sobrien   (clobber (reg:CC 17))]
788618334Speter  ""
788790286Sobrien  "idiv{l}\t%2"
788890286Sobrien  [(set_attr "type" "idiv")
788990286Sobrien   (set_attr "mode" "SI")
789090286Sobrien   (set_attr "ppro_uops" "few")])
789190286Sobrien
789290286Sobrien(define_split
789390286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
789490286Sobrien	(div:SI (match_operand:SI 1 "register_operand" "")
789590286Sobrien		(match_operand:SI 2 "nonimmediate_operand" "")))
789690286Sobrien   (set (match_operand:SI 3 "register_operand" "")
789790286Sobrien	(mod:SI (match_dup 1) (match_dup 2)))
789890286Sobrien   (clobber (reg:CC 17))]
789990286Sobrien  "reload_completed"
790090286Sobrien  [(parallel [(set (match_dup 3)
790190286Sobrien		   (ashiftrt:SI (match_dup 4) (const_int 31)))
790290286Sobrien	      (clobber (reg:CC 17))])
790390286Sobrien   (parallel [(set (match_dup 0)
790490286Sobrien	           (div:SI (reg:SI 0) (match_dup 2)))
790590286Sobrien	      (set (match_dup 3)
790690286Sobrien		   (mod:SI (reg:SI 0) (match_dup 2)))
790790286Sobrien	      (use (match_dup 3))
790890286Sobrien	      (clobber (reg:CC 17))])]
790918334Speter{
791090286Sobrien  /* Avoid use of cltd in favour of a mov+shift.  */
791190286Sobrien  if (!TARGET_USE_CLTD && !optimize_size)
791290286Sobrien    {
791390286Sobrien      if (true_regnum (operands[1]))
791490286Sobrien        emit_move_insn (operands[0], operands[1]);
791590286Sobrien      else
791690286Sobrien	emit_move_insn (operands[3], operands[1]);
791790286Sobrien      operands[4] = operands[3];
791890286Sobrien    }
791990286Sobrien  else
792090286Sobrien    {
792190286Sobrien      if (true_regnum (operands[1]))
792290286Sobrien	abort();
792390286Sobrien      operands[4] = operands[1];
792490286Sobrien    }
792590286Sobrien})
792690286Sobrien;; %%% Split me.
792718334Speter(define_insn "divmodhi4"
792818334Speter  [(set (match_operand:HI 0 "register_operand" "=a")
792918334Speter	(div:HI (match_operand:HI 1 "register_operand" "0")
793050650Sobrien		(match_operand:HI 2 "nonimmediate_operand" "rm")))
793118334Speter   (set (match_operand:HI 3 "register_operand" "=&d")
793290286Sobrien	(mod:HI (match_dup 1) (match_dup 2)))
793390286Sobrien   (clobber (reg:CC 17))]
793490286Sobrien  "TARGET_HIMODE_MATH"
793590286Sobrien  "cwtd\;idiv{w}\t%2"
793690286Sobrien  [(set_attr "type" "multi")
793790286Sobrien   (set_attr "length_immediate" "0")
793890286Sobrien   (set_attr "mode" "SI")])
793918334Speter
794090286Sobrien(define_insn "udivmoddi4"
794190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a")
794290286Sobrien	(udiv:DI (match_operand:DI 1 "register_operand" "0")
794390286Sobrien		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
794490286Sobrien   (set (match_operand:DI 3 "register_operand" "=&d")
794590286Sobrien	(umod:DI (match_dup 1) (match_dup 2)))
794690286Sobrien   (clobber (reg:CC 17))]
794790286Sobrien  "TARGET_64BIT"
794890286Sobrien  "xor{q}\t%3, %3\;div{q}\t%2"
794990286Sobrien  [(set_attr "type" "multi")
795090286Sobrien   (set_attr "length_immediate" "0")
795190286Sobrien   (set_attr "mode" "DI")])
795290286Sobrien
795390286Sobrien(define_insn "*udivmoddi4_noext"
795490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=a")
795590286Sobrien	(udiv:DI (match_operand:DI 1 "register_operand" "0")
795690286Sobrien		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
795790286Sobrien   (set (match_operand:DI 3 "register_operand" "=d")
795890286Sobrien	(umod:DI (match_dup 1) (match_dup 2)))
795990286Sobrien   (use (match_dup 3))
796090286Sobrien   (clobber (reg:CC 17))]
796190286Sobrien  "TARGET_64BIT"
796290286Sobrien  "div{q}\t%2"
796390286Sobrien  [(set_attr "type" "idiv")
796490286Sobrien   (set_attr "ppro_uops" "few")
796590286Sobrien   (set_attr "mode" "DI")])
796690286Sobrien
796790286Sobrien(define_split
796890286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
796990286Sobrien	(udiv:DI (match_operand:DI 1 "register_operand" "")
797090286Sobrien		 (match_operand:DI 2 "nonimmediate_operand" "")))
797190286Sobrien   (set (match_operand:DI 3 "register_operand" "")
797290286Sobrien	(umod:DI (match_dup 1) (match_dup 2)))
797390286Sobrien   (clobber (reg:CC 17))]
797490286Sobrien  "TARGET_64BIT && reload_completed"
797590286Sobrien  [(set (match_dup 3) (const_int 0))
797690286Sobrien   (parallel [(set (match_dup 0)
797790286Sobrien		   (udiv:DI (match_dup 1) (match_dup 2)))
797890286Sobrien	      (set (match_dup 3)
797990286Sobrien		   (umod:DI (match_dup 1) (match_dup 2)))
798090286Sobrien	      (use (match_dup 3))
798190286Sobrien	      (clobber (reg:CC 17))])]
798290286Sobrien  "")
798390286Sobrien
798418334Speter(define_insn "udivmodsi4"
798518334Speter  [(set (match_operand:SI 0 "register_operand" "=a")
798618334Speter	(udiv:SI (match_operand:SI 1 "register_operand" "0")
798750650Sobrien		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
798818334Speter   (set (match_operand:SI 3 "register_operand" "=&d")
798990286Sobrien	(umod:SI (match_dup 1) (match_dup 2)))
799090286Sobrien   (clobber (reg:CC 17))]
799118334Speter  ""
799290286Sobrien  "xor{l}\t%3, %3\;div{l}\t%2"
799390286Sobrien  [(set_attr "type" "multi")
799490286Sobrien   (set_attr "length_immediate" "0")
799590286Sobrien   (set_attr "mode" "SI")])
799618334Speter
799790286Sobrien(define_insn "*udivmodsi4_noext"
799890286Sobrien  [(set (match_operand:SI 0 "register_operand" "=a")
799990286Sobrien	(udiv:SI (match_operand:SI 1 "register_operand" "0")
800090286Sobrien		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
800190286Sobrien   (set (match_operand:SI 3 "register_operand" "=d")
800290286Sobrien	(umod:SI (match_dup 1) (match_dup 2)))
800390286Sobrien   (use (match_dup 3))
800490286Sobrien   (clobber (reg:CC 17))]
800590286Sobrien  ""
800690286Sobrien  "div{l}\t%2"
800790286Sobrien  [(set_attr "type" "idiv")
800890286Sobrien   (set_attr "ppro_uops" "few")
800990286Sobrien   (set_attr "mode" "SI")])
801090286Sobrien
801190286Sobrien(define_split
801290286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
801390286Sobrien	(udiv:SI (match_operand:SI 1 "register_operand" "")
801490286Sobrien		 (match_operand:SI 2 "nonimmediate_operand" "")))
801590286Sobrien   (set (match_operand:SI 3 "register_operand" "")
801690286Sobrien	(umod:SI (match_dup 1) (match_dup 2)))
801790286Sobrien   (clobber (reg:CC 17))]
801890286Sobrien  "reload_completed"
801990286Sobrien  [(set (match_dup 3) (const_int 0))
802090286Sobrien   (parallel [(set (match_dup 0)
802190286Sobrien		   (udiv:SI (match_dup 1) (match_dup 2)))
802290286Sobrien	      (set (match_dup 3)
802390286Sobrien		   (umod:SI (match_dup 1) (match_dup 2)))
802490286Sobrien	      (use (match_dup 3))
802590286Sobrien	      (clobber (reg:CC 17))])]
802690286Sobrien  "")
802790286Sobrien
802890286Sobrien(define_expand "udivmodhi4"
802990286Sobrien  [(set (match_dup 4) (const_int 0))
803090286Sobrien   (parallel [(set (match_operand:HI 0 "register_operand" "")
803190286Sobrien		   (udiv:HI (match_operand:HI 1 "register_operand" "")
803290286Sobrien		 	    (match_operand:HI 2 "nonimmediate_operand" "")))
803390286Sobrien	      (set (match_operand:HI 3 "register_operand" "")
803490286Sobrien	   	   (umod:HI (match_dup 1) (match_dup 2)))
803590286Sobrien	      (use (match_dup 4))
803690286Sobrien	      (clobber (reg:CC 17))])]
803790286Sobrien  "TARGET_HIMODE_MATH"
803890286Sobrien  "operands[4] = gen_reg_rtx (HImode);")
803990286Sobrien
804090286Sobrien(define_insn "*udivmodhi_noext"
804118334Speter  [(set (match_operand:HI 0 "register_operand" "=a")
804218334Speter	(udiv:HI (match_operand:HI 1 "register_operand" "0")
804350650Sobrien		 (match_operand:HI 2 "nonimmediate_operand" "rm")))
804490286Sobrien   (set (match_operand:HI 3 "register_operand" "=d")
804590286Sobrien	(umod:HI (match_dup 1) (match_dup 2)))
804690286Sobrien   (use (match_operand:HI 4 "register_operand" "3"))
804790286Sobrien   (clobber (reg:CC 17))]
804818334Speter  ""
804990286Sobrien  "div{w}\t%2"
805090286Sobrien  [(set_attr "type" "idiv")
805190286Sobrien   (set_attr "mode" "HI")
805290286Sobrien   (set_attr "ppro_uops" "few")])
805318334Speter
805490286Sobrien;; We can not use div/idiv for double division, because it causes
805590286Sobrien;; "division by zero" on the overflow and that's not what we expect
805690286Sobrien;; from truncate.  Because true (non truncating) double division is
805790286Sobrien;; never generated, we can't create this insn anyway.
805890286Sobrien;
805990286Sobrien;(define_insn ""
806090286Sobrien;  [(set (match_operand:SI 0 "register_operand" "=a")
806190286Sobrien;	(truncate:SI
806290286Sobrien;	  (udiv:DI (match_operand:DI 1 "register_operand" "A")
806390286Sobrien;		   (zero_extend:DI
806490286Sobrien;		     (match_operand:SI 2 "nonimmediate_operand" "rm")))))
806590286Sobrien;   (set (match_operand:SI 3 "register_operand" "=d")
806690286Sobrien;	(truncate:SI
806790286Sobrien;	  (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
806890286Sobrien;   (clobber (reg:CC 17))]
806990286Sobrien;  ""
807090286Sobrien;  "div{l}\t{%2, %0|%0, %2}"
807190286Sobrien;  [(set_attr "type" "idiv")
807290286Sobrien;   (set_attr "ppro_uops" "few")])
807390286Sobrien
807490286Sobrien;;- Logical AND instructions
807518334Speter
807690286Sobrien;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
807790286Sobrien;; Note that this excludes ah.
807890286Sobrien
807990286Sobrien(define_insn "*testdi_1_rex64"
808090286Sobrien  [(set (reg 17)
808190286Sobrien	(compare
808290286Sobrien	  (and:DI (match_operand:DI 0 "nonimmediate_operand" "%*a,r,*a,r,rm")
808390286Sobrien		  (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,Z,e,e,re"))
808490286Sobrien	  (const_int 0)))]
808590286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
808690286Sobrien  "@
808790286Sobrien   test{l}\t{%k1, %k0|%k0, %k1} 
808890286Sobrien   test{l}\t{%k1, %k0|%k0, %k1} 
808990286Sobrien   test{q}\t{%1, %0|%0, %1} 
809090286Sobrien   test{q}\t{%1, %0|%0, %1} 
809190286Sobrien   test{q}\t{%1, %0|%0, %1}"
809290286Sobrien  [(set_attr "type" "test")
809390286Sobrien   (set_attr "modrm" "0,1,0,1,1")
809490286Sobrien   (set_attr "mode" "SI,SI,DI,DI,DI")
809590286Sobrien   (set_attr "pent_pair" "uv,np,uv,np,uv")])
809690286Sobrien
809790286Sobrien(define_insn "testsi_1"
809890286Sobrien  [(set (reg 17)
809990286Sobrien	(compare
810090286Sobrien	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
810190286Sobrien		  (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
810290286Sobrien	  (const_int 0)))]
810390286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
810490286Sobrien  "test{l}\t{%1, %0|%0, %1}"
810590286Sobrien  [(set_attr "type" "test")
810690286Sobrien   (set_attr "modrm" "0,1,1")
810790286Sobrien   (set_attr "mode" "SI")
810890286Sobrien   (set_attr "pent_pair" "uv,np,uv")])
810990286Sobrien
811090286Sobrien(define_expand "testsi_ccno_1"
811190286Sobrien  [(set (reg:CCNO 17)
811290286Sobrien	(compare:CCNO
811390286Sobrien	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
811490286Sobrien		  (match_operand:SI 1 "nonmemory_operand" ""))
811590286Sobrien	  (const_int 0)))]
811618334Speter  ""
811790286Sobrien  "")
811818334Speter
811990286Sobrien(define_insn "*testhi_1"
812090286Sobrien  [(set (reg 17)
812190286Sobrien        (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
812290286Sobrien			 (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
812390286Sobrien		 (const_int 0)))]
812490286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
812590286Sobrien  "test{w}\t{%1, %0|%0, %1}"
812690286Sobrien  [(set_attr "type" "test")
812790286Sobrien   (set_attr "modrm" "0,1,1")
812890286Sobrien   (set_attr "mode" "HI")
812990286Sobrien   (set_attr "pent_pair" "uv,np,uv")])
813018334Speter
813190286Sobrien(define_expand "testqi_ccz_1"
813290286Sobrien  [(set (reg:CCZ 17)
813390286Sobrien        (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
813490286Sobrien			     (match_operand:QI 1 "nonmemory_operand" ""))
813590286Sobrien		 (const_int 0)))]
813690286Sobrien  ""
813790286Sobrien  "")
813818334Speter
813990286Sobrien(define_insn "*testqi_1"
814090286Sobrien  [(set (reg 17)
814190286Sobrien        (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
814290286Sobrien			 (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
814390286Sobrien		 (const_int 0)))]
814490286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
814518334Speter{
814690286Sobrien  if (which_alternative == 3)
814718334Speter    {
814890286Sobrien      if (GET_CODE (operands[1]) == CONST_INT
814990286Sobrien	  && (INTVAL (operands[1]) & 0xffffff00))
815090286Sobrien	operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
815190286Sobrien      return "test{l}\t{%1, %k0|%k0, %1}";
815250650Sobrien    }
815390286Sobrien  return "test{b}\t{%1, %0|%0, %1}";
815490286Sobrien}
815590286Sobrien  [(set_attr "type" "test")
815690286Sobrien   (set_attr "modrm" "0,1,1,1")
815790286Sobrien   (set_attr "mode" "QI,QI,QI,SI")
815890286Sobrien   (set_attr "pent_pair" "uv,np,uv,np")])
815918334Speter
816090286Sobrien(define_expand "testqi_ext_ccno_0"
816190286Sobrien  [(set (reg:CCNO 17)
816290286Sobrien	(compare:CCNO
816390286Sobrien	  (and:SI
816490286Sobrien	    (zero_extract:SI
816590286Sobrien	      (match_operand 0 "ext_register_operand" "")
816690286Sobrien	      (const_int 8)
816790286Sobrien	      (const_int 8))
816890286Sobrien	    (match_operand 1 "const_int_operand" ""))
816990286Sobrien	  (const_int 0)))]
817090286Sobrien  ""
817190286Sobrien  "")
817218334Speter
817390286Sobrien(define_insn "*testqi_ext_0"
817490286Sobrien  [(set (reg 17)
817590286Sobrien	(compare
817690286Sobrien	  (and:SI
817790286Sobrien	    (zero_extract:SI
817890286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
817990286Sobrien	      (const_int 8)
818090286Sobrien	      (const_int 8))
818190286Sobrien	    (match_operand 1 "const_int_operand" "n"))
818290286Sobrien	  (const_int 0)))]
818390286Sobrien  "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff
818490286Sobrien   && ix86_match_ccmode (insn, CCNOmode)"
818590286Sobrien  "test{b}\t{%1, %h0|%h0, %1}"
818690286Sobrien  [(set_attr "type" "test")
818790286Sobrien   (set_attr "mode" "QI")
818890286Sobrien   (set_attr "length_immediate" "1")
818990286Sobrien   (set_attr "pent_pair" "np")])
819050650Sobrien
819190286Sobrien(define_insn "*testqi_ext_1"
819290286Sobrien  [(set (reg 17)
819390286Sobrien	(compare
819490286Sobrien	  (and:SI
819590286Sobrien	    (zero_extract:SI
819690286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
819790286Sobrien	      (const_int 8)
819890286Sobrien	      (const_int 8))
819990286Sobrien	    (zero_extend:SI
820090286Sobrien	      (match_operand:QI 1 "nonimmediate_operand" "Qm")))
820190286Sobrien	  (const_int 0)))]
820290286Sobrien  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
820390286Sobrien  "test{b}\t{%1, %h0|%h0, %1}"
820490286Sobrien  [(set_attr "type" "test")
820590286Sobrien   (set_attr "mode" "QI")])
820618334Speter
820790286Sobrien(define_insn "*testqi_ext_1_rex64"
820890286Sobrien  [(set (reg 17)
820990286Sobrien	(compare
821090286Sobrien	  (and:SI
821190286Sobrien	    (zero_extract:SI
821290286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
821390286Sobrien	      (const_int 8)
821490286Sobrien	      (const_int 8))
821590286Sobrien	    (zero_extend:SI
821690286Sobrien	      (match_operand:QI 1 "register_operand" "Q")))
821790286Sobrien	  (const_int 0)))]
821890286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
821990286Sobrien  "test{b}\t{%1, %h0|%h0, %1}"
822090286Sobrien  [(set_attr "type" "test")
822190286Sobrien   (set_attr "mode" "QI")])
822218334Speter
822390286Sobrien(define_insn "*testqi_ext_2"
822490286Sobrien  [(set (reg 17)
822590286Sobrien	(compare
822690286Sobrien	  (and:SI
822790286Sobrien	    (zero_extract:SI
822890286Sobrien	      (match_operand 0 "ext_register_operand" "Q")
822990286Sobrien	      (const_int 8)
823090286Sobrien	      (const_int 8))
823190286Sobrien	    (zero_extract:SI
823290286Sobrien	      (match_operand 1 "ext_register_operand" "Q")
823390286Sobrien	      (const_int 8)
823490286Sobrien	      (const_int 8)))
823590286Sobrien	  (const_int 0)))]
823690286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
823790286Sobrien  "test{b}\t{%h1, %h0|%h0, %h1}"
823890286Sobrien  [(set_attr "type" "test")
823990286Sobrien   (set_attr "mode" "QI")])
824050650Sobrien
824190286Sobrien;; Combine likes to form bit extractions for some tests.  Humor it.
824290286Sobrien(define_insn "*testqi_ext_3"
824390286Sobrien  [(set (reg 17)
824490286Sobrien        (compare (zero_extract:SI
824590286Sobrien		   (match_operand 0 "nonimmediate_operand" "rm")
824690286Sobrien		   (match_operand:SI 1 "const_int_operand" "")
824790286Sobrien		   (match_operand:SI 2 "const_int_operand" ""))
824890286Sobrien		 (const_int 0)))]
824990286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
825090286Sobrien   && (GET_MODE (operands[0]) == SImode
825190286Sobrien       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
825290286Sobrien       || GET_MODE (operands[0]) == HImode
825390286Sobrien       || GET_MODE (operands[0]) == QImode)"
825490286Sobrien  "#")
825550650Sobrien
825690286Sobrien(define_insn "*testqi_ext_3_rex64"
825790286Sobrien  [(set (reg 17)
825890286Sobrien        (compare (zero_extract:DI
825990286Sobrien		   (match_operand 0 "nonimmediate_operand" "rm")
826090286Sobrien		   (match_operand:DI 1 "const_int_operand" "")
826190286Sobrien		   (match_operand:DI 2 "const_int_operand" ""))
826290286Sobrien		 (const_int 0)))]
826390286Sobrien  "TARGET_64BIT
826490286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
826590286Sobrien   /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
826690286Sobrien   && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
826790286Sobrien   /* Ensure that resulting mask is zero or sign extended operand.  */
826890286Sobrien   && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
826990286Sobrien       || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
827090286Sobrien	   && INTVAL (operands[1]) > 32))
827190286Sobrien   && (GET_MODE (operands[0]) == SImode
827290286Sobrien       || GET_MODE (operands[0]) == DImode
827390286Sobrien       || GET_MODE (operands[0]) == HImode
827490286Sobrien       || GET_MODE (operands[0]) == QImode)"
827590286Sobrien  "#")
827650650Sobrien
827790286Sobrien(define_split
827890286Sobrien  [(set (reg 17)
827990286Sobrien        (compare (zero_extract
828090286Sobrien		   (match_operand 0 "nonimmediate_operand" "")
828190286Sobrien		   (match_operand 1 "const_int_operand" "")
828290286Sobrien		   (match_operand 2 "const_int_operand" ""))
828390286Sobrien		 (const_int 0)))]
828490286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
828590286Sobrien  [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
828690286Sobrien{
828790286Sobrien  HOST_WIDE_INT len = INTVAL (operands[1]);
828890286Sobrien  HOST_WIDE_INT pos = INTVAL (operands[2]);
828990286Sobrien  HOST_WIDE_INT mask;
829090286Sobrien  enum machine_mode mode, submode;
829118334Speter
829290286Sobrien  mode = GET_MODE (operands[0]);
829390286Sobrien  if (GET_CODE (operands[0]) == MEM)
829490286Sobrien    {
829590286Sobrien      /* ??? Combine likes to put non-volatile mem extractions in QImode
829690286Sobrien	 no matter the size of the test.  So find a mode that works.  */
829790286Sobrien      if (! MEM_VOLATILE_P (operands[0]))
829818334Speter	{
829990286Sobrien	  mode = smallest_mode_for_size (pos + len, MODE_INT);
830090286Sobrien	  operands[0] = adjust_address (operands[0], mode, 0);
830190286Sobrien	}
830290286Sobrien    }
830390286Sobrien  else if (GET_CODE (operands[0]) == SUBREG
830490286Sobrien	   && (submode = GET_MODE (SUBREG_REG (operands[0])),
830590286Sobrien	       GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
830690286Sobrien	   && pos + len <= GET_MODE_BITSIZE (submode))
830790286Sobrien    {
830890286Sobrien      /* Narrow a paradoxical subreg to prevent partial register stalls.  */
830990286Sobrien      mode = submode;
831090286Sobrien      operands[0] = SUBREG_REG (operands[0]);
831190286Sobrien    }
831290286Sobrien  else if (mode == HImode && pos + len <= 8)
831390286Sobrien    {
831490286Sobrien      /* Small HImode tests can be converted to QImode.  */
831590286Sobrien      mode = QImode;
831690286Sobrien      operands[0] = gen_lowpart (QImode, operands[0]);
831790286Sobrien    }
831818334Speter
831990286Sobrien  mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
832090286Sobrien  mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
832118334Speter
832290286Sobrien  operands[3] = gen_rtx_AND (mode, operands[0],
832390286Sobrien			     GEN_INT (trunc_int_for_mode (mask, mode)));
832490286Sobrien})
832550650Sobrien
832690286Sobrien;; %%% This used to optimize known byte-wide and operations to memory,
832790286Sobrien;; and sometimes to QImode registers.  If this is considered useful,
832890286Sobrien;; it should be done with splitters.
832918334Speter
833090286Sobrien(define_expand "anddi3"
833190286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
833290286Sobrien	(and:DI (match_operand:DI 1 "nonimmediate_operand" "")
833390286Sobrien		(match_operand:DI 2 "x86_64_szext_general_operand" "")))
833490286Sobrien   (clobber (reg:CC 17))]
833590286Sobrien  "TARGET_64BIT"
833690286Sobrien  "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
833750650Sobrien
833890286Sobrien(define_insn "*anddi_1_rex64"
833990286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
834090286Sobrien	(and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
834190286Sobrien		(match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
834290286Sobrien   (clobber (reg:CC 17))]
834390286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
834490286Sobrien{
834590286Sobrien  switch (get_attr_type (insn))
834690286Sobrien    {
834790286Sobrien    case TYPE_IMOVX:
834890286Sobrien      {
834990286Sobrien	enum machine_mode mode;
835050650Sobrien
835190286Sobrien	if (GET_CODE (operands[2]) != CONST_INT)
835290286Sobrien	  abort ();
835390286Sobrien        if (INTVAL (operands[2]) == 0xff)
835490286Sobrien	  mode = QImode;
835590286Sobrien	else if (INTVAL (operands[2]) == 0xffff)
835690286Sobrien	  mode = HImode;
835790286Sobrien	else
835890286Sobrien	  abort ();
835990286Sobrien	
836090286Sobrien	operands[1] = gen_lowpart (mode, operands[1]);
836190286Sobrien	if (mode == QImode)
836290286Sobrien	  return "movz{bq|x}\t{%1,%0|%0, %1}";
836390286Sobrien	else
836490286Sobrien	  return "movz{wq|x}\t{%1,%0|%0, %1}";
836590286Sobrien      }
836650650Sobrien
836750650Sobrien    default:
836890286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
836990286Sobrien	abort ();
837090286Sobrien      if (get_attr_mode (insn) == MODE_SI)
837190286Sobrien	return "and{l}\t{%k2, %k0|%k0, %k2}";
837290286Sobrien      else
837390286Sobrien	return "and{q}\t{%2, %0|%0, %2}";
837418334Speter    }
837590286Sobrien}
837690286Sobrien  [(set_attr "type" "alu,alu,alu,imovx")
837790286Sobrien   (set_attr "length_immediate" "*,*,*,0")
837890286Sobrien   (set_attr "mode" "SI,DI,DI,DI")])
837918334Speter
838090286Sobrien(define_insn "*anddi_2"
838190286Sobrien  [(set (reg 17)
838290286Sobrien	(compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
838390286Sobrien			 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
838490286Sobrien		 (const_int 0)))
838590286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
838690286Sobrien	(and:DI (match_dup 1) (match_dup 2)))]
838790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
838890286Sobrien   && ix86_binary_operator_ok (AND, DImode, operands)"
838990286Sobrien  "@
839090286Sobrien   and{l}\t{%k2, %k0|%k0, %k2} 
839190286Sobrien   and{q}\t{%2, %0|%0, %2} 
839290286Sobrien   and{q}\t{%2, %0|%0, %2}"
839390286Sobrien  [(set_attr "type" "alu")
839490286Sobrien   (set_attr "mode" "SI,DI,DI")])
839518334Speter
839690286Sobrien(define_expand "andsi3"
839790286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
839890286Sobrien	(and:SI (match_operand:SI 1 "nonimmediate_operand" "")
839990286Sobrien		(match_operand:SI 2 "general_operand" "")))
840090286Sobrien   (clobber (reg:CC 17))]
840118334Speter  ""
840290286Sobrien  "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
840390286Sobrien
840490286Sobrien(define_insn "*andsi_1"
840590286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
840690286Sobrien	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
840790286Sobrien		(match_operand:SI 2 "general_operand" "ri,rm,L")))
840890286Sobrien   (clobber (reg:CC 17))]
840990286Sobrien  "ix86_binary_operator_ok (AND, SImode, operands)"
841018334Speter{
841190286Sobrien  switch (get_attr_type (insn))
841218334Speter    {
841390286Sobrien    case TYPE_IMOVX:
841490286Sobrien      {
841590286Sobrien	enum machine_mode mode;
841618334Speter
841790286Sobrien	if (GET_CODE (operands[2]) != CONST_INT)
841890286Sobrien	  abort ();
841990286Sobrien        if (INTVAL (operands[2]) == 0xff)
842090286Sobrien	  mode = QImode;
842190286Sobrien	else if (INTVAL (operands[2]) == 0xffff)
842290286Sobrien	  mode = HImode;
842390286Sobrien	else
842490286Sobrien	  abort ();
842590286Sobrien	
842690286Sobrien	operands[1] = gen_lowpart (mode, operands[1]);
842790286Sobrien	if (mode == QImode)
842890286Sobrien	  return "movz{bl|x}\t{%1,%0|%0, %1}";
842990286Sobrien	else
843090286Sobrien	  return "movz{wl|x}\t{%1,%0|%0, %1}";
843190286Sobrien      }
843218334Speter
843390286Sobrien    default:
843490286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
843590286Sobrien	abort ();
843690286Sobrien      return "and{l}\t{%2, %0|%0, %2}";
843790286Sobrien    }
843890286Sobrien}
843990286Sobrien  [(set_attr "type" "alu,alu,imovx")
844090286Sobrien   (set_attr "length_immediate" "*,*,0")
844190286Sobrien   (set_attr "mode" "SI")])
844218334Speter
844390286Sobrien(define_split
844490286Sobrien  [(set (match_operand 0 "register_operand" "")
844590286Sobrien	(and (match_dup 0)
844690286Sobrien	     (const_int -65536)))
844790286Sobrien   (clobber (reg:CC 17))]
844890286Sobrien  "optimize_size"
844990286Sobrien  [(set (strict_low_part (match_dup 1)) (const_int 0))]
845090286Sobrien  "operands[1] = gen_lowpart (HImode, operands[0]);")
845118334Speter
845290286Sobrien(define_split
845390286Sobrien  [(set (match_operand 0 "ext_register_operand" "")
845490286Sobrien	(and (match_dup 0)
845590286Sobrien	     (const_int -256)))
845690286Sobrien   (clobber (reg:CC 17))]
845790286Sobrien  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
845890286Sobrien  [(set (strict_low_part (match_dup 1)) (const_int 0))]
845990286Sobrien  "operands[1] = gen_lowpart (QImode, operands[0]);")
846018334Speter
846190286Sobrien(define_split
846290286Sobrien  [(set (match_operand 0 "ext_register_operand" "")
846390286Sobrien	(and (match_dup 0)
846490286Sobrien	     (const_int -65281)))
846590286Sobrien   (clobber (reg:CC 17))]
846690286Sobrien  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
846790286Sobrien  [(parallel [(set (zero_extract:SI (match_dup 0)
846890286Sobrien				    (const_int 8)
846990286Sobrien				    (const_int 8))
847090286Sobrien		   (xor:SI 
847190286Sobrien		     (zero_extract:SI (match_dup 0)
847290286Sobrien				      (const_int 8)
847390286Sobrien				      (const_int 8))
847490286Sobrien		     (zero_extract:SI (match_dup 0)
847590286Sobrien				      (const_int 8)
847690286Sobrien				      (const_int 8))))
847790286Sobrien	      (clobber (reg:CC 17))])]
847890286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);")
847950650Sobrien
848090286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
848190286Sobrien(define_insn "*andsi_1_zext"
848290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
848390286Sobrien	(zero_extend:DI
848490286Sobrien	  (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
848590286Sobrien		  (match_operand:SI 2 "general_operand" "rim"))))
848690286Sobrien   (clobber (reg:CC 17))]
848790286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
848890286Sobrien  "and{l}\t{%2, %k0|%k0, %2}"
848990286Sobrien  [(set_attr "type" "alu")
849090286Sobrien   (set_attr "mode" "SI")])
849118334Speter
849290286Sobrien(define_insn "*andsi_2"
849390286Sobrien  [(set (reg 17)
849490286Sobrien	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
849590286Sobrien			 (match_operand:SI 2 "general_operand" "rim,ri"))
849690286Sobrien		 (const_int 0)))
849790286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
849890286Sobrien	(and:SI (match_dup 1) (match_dup 2)))]
849990286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
850090286Sobrien   && ix86_binary_operator_ok (AND, SImode, operands)"
850190286Sobrien  "and{l}\t{%2, %0|%0, %2}"
850290286Sobrien  [(set_attr "type" "alu")
850390286Sobrien   (set_attr "mode" "SI")])
850490286Sobrien
850590286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
850690286Sobrien(define_insn "*andsi_2_zext"
850790286Sobrien  [(set (reg 17)
850890286Sobrien	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
850990286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
851090286Sobrien		 (const_int 0)))
851190286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
851290286Sobrien	(zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
851390286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
851490286Sobrien   && ix86_binary_operator_ok (AND, SImode, operands)"
851590286Sobrien  "and{l}\t{%2, %k0|%k0, %2}"
851690286Sobrien  [(set_attr "type" "alu")
851790286Sobrien   (set_attr "mode" "SI")])
851890286Sobrien
851990286Sobrien(define_expand "andhi3"
852090286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
852190286Sobrien	(and:HI (match_operand:HI 1 "nonimmediate_operand" "")
852290286Sobrien		(match_operand:HI 2 "general_operand" "")))
852390286Sobrien   (clobber (reg:CC 17))]
852490286Sobrien  "TARGET_HIMODE_MATH"
852590286Sobrien  "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
852690286Sobrien
852790286Sobrien(define_insn "*andhi_1"
852890286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
852990286Sobrien	(and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
853090286Sobrien		(match_operand:HI 2 "general_operand" "ri,rm,L")))
853190286Sobrien   (clobber (reg:CC 17))]
853290286Sobrien  "ix86_binary_operator_ok (AND, HImode, operands)"
853390286Sobrien{
853490286Sobrien  switch (get_attr_type (insn))
853550650Sobrien    {
853690286Sobrien    case TYPE_IMOVX:
853790286Sobrien      if (GET_CODE (operands[2]) != CONST_INT)
853890286Sobrien	abort ();
853990286Sobrien      if (INTVAL (operands[2]) == 0xff)
854090286Sobrien	return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
854190286Sobrien      abort ();
854290286Sobrien
854390286Sobrien    default:
854490286Sobrien      if (! rtx_equal_p (operands[0], operands[1]))
854590286Sobrien	abort ();
854690286Sobrien
854790286Sobrien      return "and{w}\t{%2, %0|%0, %2}";
854850650Sobrien    }
854990286Sobrien}
855090286Sobrien  [(set_attr "type" "alu,alu,imovx")
855190286Sobrien   (set_attr "length_immediate" "*,*,0")
855290286Sobrien   (set_attr "mode" "HI,HI,SI")])
855350650Sobrien
855490286Sobrien(define_insn "*andhi_2"
855590286Sobrien  [(set (reg 17)
855690286Sobrien	(compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
855790286Sobrien			 (match_operand:HI 2 "general_operand" "rim,ri"))
855890286Sobrien		 (const_int 0)))
855990286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
856090286Sobrien	(and:HI (match_dup 1) (match_dup 2)))]
856190286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
856290286Sobrien   && ix86_binary_operator_ok (AND, HImode, operands)"
856390286Sobrien  "and{w}\t{%2, %0|%0, %2}"
856490286Sobrien  [(set_attr "type" "alu")
856590286Sobrien   (set_attr "mode" "HI")])
856690286Sobrien
856790286Sobrien(define_expand "andqi3"
856890286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
856990286Sobrien	(and:QI (match_operand:QI 1 "nonimmediate_operand" "")
857090286Sobrien		(match_operand:QI 2 "general_operand" "")))
857190286Sobrien   (clobber (reg:CC 17))]
857290286Sobrien  "TARGET_QIMODE_MATH"
857390286Sobrien  "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
857490286Sobrien
857590286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
857690286Sobrien(define_insn "*andqi_1"
857790286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
857890286Sobrien	(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
857990286Sobrien		(match_operand:QI 2 "general_operand" "qi,qmi,ri")))
858090286Sobrien   (clobber (reg:CC 17))]
858190286Sobrien  "ix86_binary_operator_ok (AND, QImode, operands)"
858290286Sobrien  "@
858390286Sobrien   and{b}\t{%2, %0|%0, %2}
858490286Sobrien   and{b}\t{%2, %0|%0, %2}
858590286Sobrien   and{l}\t{%k2, %k0|%k0, %k2}"
858690286Sobrien  [(set_attr "type" "alu")
858790286Sobrien   (set_attr "mode" "QI,QI,SI")])
858890286Sobrien
858990286Sobrien(define_insn "*andqi_1_slp"
859090286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
859190286Sobrien	(and:QI (match_dup 0)
859290286Sobrien		(match_operand:QI 1 "general_operand" "qi,qmi")))
859390286Sobrien   (clobber (reg:CC 17))]
859490286Sobrien  ""
859590286Sobrien  "and{b}\t{%1, %0|%0, %1}"
859690286Sobrien  [(set_attr "type" "alu1")
859790286Sobrien   (set_attr "mode" "QI")])
859890286Sobrien
859990286Sobrien(define_insn "*andqi_2"
860090286Sobrien  [(set (reg 17)
860190286Sobrien	(compare (and:QI
860290286Sobrien		   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
860390286Sobrien		   (match_operand:QI 2 "general_operand" "qim,qi,i"))
860490286Sobrien		 (const_int 0)))
860590286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
860690286Sobrien	(and:QI (match_dup 1) (match_dup 2)))]
860790286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
860890286Sobrien   && ix86_binary_operator_ok (AND, QImode, operands)"
860990286Sobrien{
861090286Sobrien  if (which_alternative == 2)
861150650Sobrien    {
861290286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
861390286Sobrien          && (INTVAL (operands[2]) & 0xffffff00))
861490286Sobrien        operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
861590286Sobrien      return "and{l}\t{%2, %k0|%k0, %2}";
861650650Sobrien    }
861790286Sobrien  return "and{b}\t{%2, %0|%0, %2}";
861890286Sobrien}
861990286Sobrien  [(set_attr "type" "alu")
862090286Sobrien   (set_attr "mode" "QI,QI,SI")])
862150650Sobrien
862290286Sobrien(define_insn "*andqi_2_slp"
862390286Sobrien  [(set (reg 17)
862490286Sobrien	(compare (and:QI
862590286Sobrien		   (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
862690286Sobrien		   (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
862790286Sobrien		 (const_int 0)))
862890286Sobrien   (set (strict_low_part (match_dup 0))
862990286Sobrien	(and:QI (match_dup 0) (match_dup 1)))]
863090286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
863190286Sobrien  "and{b}\t{%1, %0|%0, %1}"
863290286Sobrien  [(set_attr "type" "alu1")
863390286Sobrien   (set_attr "mode" "QI")])
863418334Speter
863590286Sobrien;; ??? A bug in recog prevents it from recognizing a const_int as an
863690286Sobrien;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
863790286Sobrien;; for a QImode operand, which of course failed.
863818334Speter
863990286Sobrien(define_insn "andqi_ext_0"
864090286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
864190286Sobrien			 (const_int 8)
864290286Sobrien			 (const_int 8))
864390286Sobrien	(and:SI 
864490286Sobrien	  (zero_extract:SI
864590286Sobrien	    (match_operand 1 "ext_register_operand" "0")
864690286Sobrien	    (const_int 8)
864790286Sobrien	    (const_int 8))
864890286Sobrien	  (match_operand 2 "const_int_operand" "n")))
864990286Sobrien   (clobber (reg:CC 17))]
865090286Sobrien  "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
865190286Sobrien  "and{b}\t{%2, %h0|%h0, %2}"
865290286Sobrien  [(set_attr "type" "alu")
865390286Sobrien   (set_attr "length_immediate" "1")
865490286Sobrien   (set_attr "mode" "QI")])
865518334Speter
865690286Sobrien;; Generated by peephole translating test to and.  This shows up
865790286Sobrien;; often in fp comparisons.
865890286Sobrien
865990286Sobrien(define_insn "*andqi_ext_0_cc"
866090286Sobrien  [(set (reg 17)
866190286Sobrien	(compare
866290286Sobrien	  (and:SI
866390286Sobrien	    (zero_extract:SI
866490286Sobrien	      (match_operand 1 "ext_register_operand" "0")
866590286Sobrien	      (const_int 8)
866690286Sobrien	      (const_int 8))
866790286Sobrien	    (match_operand 2 "const_int_operand" "n"))
866890286Sobrien	  (const_int 0)))
866990286Sobrien   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
867090286Sobrien			 (const_int 8)
867190286Sobrien			 (const_int 8))
867290286Sobrien	(and:SI 
867390286Sobrien	  (zero_extract:SI
867490286Sobrien	    (match_dup 1)
867590286Sobrien	    (const_int 8)
867690286Sobrien	    (const_int 8))
867790286Sobrien	  (match_dup 2)))]
867890286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
867990286Sobrien   && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
868090286Sobrien  "and{b}\t{%2, %h0|%h0, %2}"
868190286Sobrien  [(set_attr "type" "alu")
868290286Sobrien   (set_attr "length_immediate" "1")
868390286Sobrien   (set_attr "mode" "QI")])
868490286Sobrien
868590286Sobrien(define_insn "*andqi_ext_1"
868690286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
868790286Sobrien			 (const_int 8)
868890286Sobrien			 (const_int 8))
868990286Sobrien	(and:SI 
869090286Sobrien	  (zero_extract:SI
869190286Sobrien	    (match_operand 1 "ext_register_operand" "0")
869290286Sobrien	    (const_int 8)
869390286Sobrien	    (const_int 8))
869490286Sobrien	  (zero_extend:SI
869590286Sobrien	    (match_operand:QI 2 "general_operand" "Qm"))))
869690286Sobrien   (clobber (reg:CC 17))]
869790286Sobrien  "!TARGET_64BIT"
869890286Sobrien  "and{b}\t{%2, %h0|%h0, %2}"
869990286Sobrien  [(set_attr "type" "alu")
870090286Sobrien   (set_attr "length_immediate" "0")
870190286Sobrien   (set_attr "mode" "QI")])
870290286Sobrien
870390286Sobrien(define_insn "*andqi_ext_1_rex64"
870490286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
870590286Sobrien			 (const_int 8)
870690286Sobrien			 (const_int 8))
870790286Sobrien	(and:SI 
870890286Sobrien	  (zero_extract:SI
870990286Sobrien	    (match_operand 1 "ext_register_operand" "0")
871090286Sobrien	    (const_int 8)
871190286Sobrien	    (const_int 8))
871290286Sobrien	  (zero_extend:SI
871390286Sobrien	    (match_operand 2 "ext_register_operand" "Q"))))
871490286Sobrien   (clobber (reg:CC 17))]
871590286Sobrien  "TARGET_64BIT"
871690286Sobrien  "and{b}\t{%2, %h0|%h0, %2}"
871790286Sobrien  [(set_attr "type" "alu")
871890286Sobrien   (set_attr "length_immediate" "0")
871990286Sobrien   (set_attr "mode" "QI")])
872090286Sobrien
872190286Sobrien(define_insn "*andqi_ext_2"
872290286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
872390286Sobrien			 (const_int 8)
872490286Sobrien			 (const_int 8))
872518334Speter	(and:SI
872690286Sobrien	  (zero_extract:SI
872790286Sobrien	    (match_operand 1 "ext_register_operand" "%0")
872890286Sobrien	    (const_int 8)
872990286Sobrien	    (const_int 8))
873090286Sobrien	  (zero_extract:SI
873190286Sobrien	    (match_operand 2 "ext_register_operand" "Q")
873290286Sobrien	    (const_int 8)
873390286Sobrien	    (const_int 8))))
873490286Sobrien   (clobber (reg:CC 17))]
873590286Sobrien  ""
873690286Sobrien  "and{b}\t{%h2, %h0|%h0, %h2}"
873790286Sobrien  [(set_attr "type" "alu")
873890286Sobrien   (set_attr "length_immediate" "0")
873990286Sobrien   (set_attr "mode" "QI")])
874018334Speter
874190286Sobrien;; Logical inclusive OR instructions
874218334Speter
874390286Sobrien;; %%% This used to optimize known byte-wide and operations to memory.
874490286Sobrien;; If this is considered useful, it should be done with splitters.
874590286Sobrien
874690286Sobrien(define_expand "iordi3"
874790286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
874890286Sobrien	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
874990286Sobrien		(match_operand:DI 2 "x86_64_general_operand" "")))
875090286Sobrien   (clobber (reg:CC 17))]
875190286Sobrien  "TARGET_64BIT"
875290286Sobrien  "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
875390286Sobrien
875490286Sobrien(define_insn "*iordi_1_rex64"
875590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
875690286Sobrien	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
875790286Sobrien		(match_operand:DI 2 "x86_64_general_operand" "re,rme")))
875890286Sobrien   (clobber (reg:CC 17))]
875990286Sobrien  "TARGET_64BIT
876090286Sobrien   && ix86_binary_operator_ok (IOR, DImode, operands)"
876190286Sobrien  "or{q}\t{%2, %0|%0, %2}"
876290286Sobrien  [(set_attr "type" "alu")
876390286Sobrien   (set_attr "mode" "DI")])
876490286Sobrien
876590286Sobrien(define_insn "*iordi_2_rex64"
876690286Sobrien  [(set (reg 17)
876790286Sobrien	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
876890286Sobrien			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
876990286Sobrien		 (const_int 0)))
877090286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
877190286Sobrien	(ior:DI (match_dup 1) (match_dup 2)))]
877290286Sobrien  "TARGET_64BIT
877390286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
877490286Sobrien   && ix86_binary_operator_ok (IOR, DImode, operands)"
877590286Sobrien  "or{q}\t{%2, %0|%0, %2}"
877690286Sobrien  [(set_attr "type" "alu")
877790286Sobrien   (set_attr "mode" "DI")])
877890286Sobrien
877990286Sobrien(define_insn "*iordi_3_rex64"
878090286Sobrien  [(set (reg 17)
878190286Sobrien	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
878290286Sobrien			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
878390286Sobrien		 (const_int 0)))
878490286Sobrien   (clobber (match_scratch:DI 0 "=r"))]
878590286Sobrien  "TARGET_64BIT
878690286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
878790286Sobrien   && ix86_binary_operator_ok (IOR, DImode, operands)"
878890286Sobrien  "or{q}\t{%2, %0|%0, %2}"
878990286Sobrien  [(set_attr "type" "alu")
879090286Sobrien   (set_attr "mode" "DI")])
879190286Sobrien
879290286Sobrien
879390286Sobrien(define_expand "iorsi3"
879490286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
879590286Sobrien	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
879690286Sobrien		(match_operand:SI 2 "general_operand" "")))
879790286Sobrien   (clobber (reg:CC 17))]
879890286Sobrien  ""
879990286Sobrien  "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
880090286Sobrien
880190286Sobrien(define_insn "*iorsi_1"
880250650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
880350650Sobrien	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
880490286Sobrien		(match_operand:SI 2 "general_operand" "ri,rmi")))
880590286Sobrien   (clobber (reg:CC 17))]
880690286Sobrien  "ix86_binary_operator_ok (IOR, SImode, operands)"
880790286Sobrien  "or{l}\t{%2, %0|%0, %2}"
880890286Sobrien  [(set_attr "type" "alu")
880990286Sobrien   (set_attr "mode" "SI")])
881050650Sobrien
881190286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
881290286Sobrien(define_insn "*iorsi_1_zext"
881390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=rm")
881490286Sobrien	(zero_extend:DI
881590286Sobrien	  (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
881690286Sobrien		  (match_operand:SI 2 "general_operand" "rim"))))
881790286Sobrien   (clobber (reg:CC 17))]
881890286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
881990286Sobrien  "or{l}\t{%2, %k0|%k0, %2}"
882090286Sobrien  [(set_attr "type" "alu")
882190286Sobrien   (set_attr "mode" "SI")])
882250650Sobrien
882390286Sobrien(define_insn "*iorsi_1_zext_imm"
882490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=rm")
882590286Sobrien	(ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
882690286Sobrien		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
882790286Sobrien   (clobber (reg:CC 17))]
882890286Sobrien  "TARGET_64BIT"
882990286Sobrien  "or{l}\t{%2, %k0|%k0, %2}"
883090286Sobrien  [(set_attr "type" "alu")
883190286Sobrien   (set_attr "mode" "SI")])
883250650Sobrien
883390286Sobrien(define_insn "*iorsi_2"
883490286Sobrien  [(set (reg 17)
883590286Sobrien	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
883690286Sobrien			 (match_operand:SI 2 "general_operand" "rim,ri"))
883790286Sobrien		 (const_int 0)))
883890286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
883990286Sobrien	(ior:SI (match_dup 1) (match_dup 2)))]
884090286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
884190286Sobrien   && ix86_binary_operator_ok (IOR, SImode, operands)"
884290286Sobrien  "or{l}\t{%2, %0|%0, %2}"
884390286Sobrien  [(set_attr "type" "alu")
884490286Sobrien   (set_attr "mode" "SI")])
884550650Sobrien
884690286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
884790286Sobrien;; ??? Special case for immediate operand is missing - it is tricky.
884890286Sobrien(define_insn "*iorsi_2_zext"
884990286Sobrien  [(set (reg 17)
885090286Sobrien	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
885190286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
885290286Sobrien		 (const_int 0)))
885390286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
885490286Sobrien	(zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
885590286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
885690286Sobrien   && ix86_binary_operator_ok (IOR, SImode, operands)"
885790286Sobrien  "or{l}\t{%2, %k0|%k0, %2}"
885890286Sobrien  [(set_attr "type" "alu")
885990286Sobrien   (set_attr "mode" "SI")])
886050650Sobrien
886190286Sobrien(define_insn "*iorsi_2_zext_imm"
886290286Sobrien  [(set (reg 17)
886390286Sobrien	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
886490286Sobrien			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
886590286Sobrien		 (const_int 0)))
886690286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
886790286Sobrien	(ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
886890286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
886990286Sobrien   && ix86_binary_operator_ok (IOR, SImode, operands)"
887090286Sobrien  "or{l}\t{%2, %k0|%k0, %2}"
887190286Sobrien  [(set_attr "type" "alu")
887290286Sobrien   (set_attr "mode" "SI")])
887350650Sobrien
887490286Sobrien(define_insn "*iorsi_3"
887590286Sobrien  [(set (reg 17)
887690286Sobrien	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
887790286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
887890286Sobrien		 (const_int 0)))
887990286Sobrien   (clobber (match_scratch:SI 0 "=r"))]
888090286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
888190286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
888290286Sobrien  "or{l}\t{%2, %0|%0, %2}"
888390286Sobrien  [(set_attr "type" "alu")
888490286Sobrien   (set_attr "mode" "SI")])
888550650Sobrien
888690286Sobrien(define_expand "iorhi3"
888790286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
888890286Sobrien	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
888990286Sobrien		(match_operand:HI 2 "general_operand" "")))
889090286Sobrien   (clobber (reg:CC 17))]
889190286Sobrien  "TARGET_HIMODE_MATH"
889290286Sobrien  "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
889350650Sobrien
889490286Sobrien(define_insn "*iorhi_1"
889590286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
889690286Sobrien	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
889790286Sobrien		(match_operand:HI 2 "general_operand" "rmi,ri")))
889890286Sobrien   (clobber (reg:CC 17))]
889990286Sobrien  "ix86_binary_operator_ok (IOR, HImode, operands)"
890090286Sobrien  "or{w}\t{%2, %0|%0, %2}"
890190286Sobrien  [(set_attr "type" "alu")
890290286Sobrien   (set_attr "mode" "HI")])
890318334Speter
890490286Sobrien(define_insn "*iorhi_2"
890590286Sobrien  [(set (reg 17)
890690286Sobrien	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
890790286Sobrien			 (match_operand:HI 2 "general_operand" "rim,ri"))
890890286Sobrien		 (const_int 0)))
890990286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
891090286Sobrien	(ior:HI (match_dup 1) (match_dup 2)))]
891190286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
891290286Sobrien   && ix86_binary_operator_ok (IOR, HImode, operands)"
891390286Sobrien  "or{w}\t{%2, %0|%0, %2}"
891490286Sobrien  [(set_attr "type" "alu")
891590286Sobrien   (set_attr "mode" "HI")])
891618334Speter
891790286Sobrien(define_insn "*iorhi_3"
891890286Sobrien  [(set (reg 17)
891990286Sobrien	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
892090286Sobrien			 (match_operand:HI 2 "general_operand" "rim"))
892190286Sobrien		 (const_int 0)))
892290286Sobrien   (clobber (match_scratch:HI 0 "=r"))]
892390286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
892490286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
892590286Sobrien  "or{w}\t{%2, %0|%0, %2}"
892690286Sobrien  [(set_attr "type" "alu")
892790286Sobrien   (set_attr "mode" "HI")])
892850650Sobrien
892990286Sobrien(define_expand "iorqi3"
893090286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
893190286Sobrien	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
893290286Sobrien		(match_operand:QI 2 "general_operand" "")))
893390286Sobrien   (clobber (reg:CC 17))]
893490286Sobrien  "TARGET_QIMODE_MATH"
893590286Sobrien  "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
893618334Speter
893790286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
893890286Sobrien(define_insn "*iorqi_1"
893990286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
894090286Sobrien	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
894190286Sobrien		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
894290286Sobrien   (clobber (reg:CC 17))]
894390286Sobrien  "ix86_binary_operator_ok (IOR, QImode, operands)"
894490286Sobrien  "@
894590286Sobrien   or{b}\t{%2, %0|%0, %2}
894690286Sobrien   or{b}\t{%2, %0|%0, %2}
894790286Sobrien   or{l}\t{%k2, %k0|%k0, %k2}"
894890286Sobrien  [(set_attr "type" "alu")
894990286Sobrien   (set_attr "mode" "QI,QI,SI")])
895050650Sobrien
895190286Sobrien(define_insn "*iorqi_1_slp"
895290286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
895390286Sobrien	(ior:QI (match_dup 0)
895490286Sobrien		(match_operand:QI 1 "general_operand" "qmi,qi")))
895590286Sobrien   (clobber (reg:CC 17))]
895690286Sobrien  ""
895790286Sobrien  "or{b}\t{%1, %0|%0, %1}"
895890286Sobrien  [(set_attr "type" "alu1")
895990286Sobrien   (set_attr "mode" "QI")])
896018334Speter
896190286Sobrien(define_insn "*iorqi_2"
896290286Sobrien  [(set (reg 17)
896390286Sobrien	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
896490286Sobrien			 (match_operand:QI 2 "general_operand" "qim,qi"))
896590286Sobrien		 (const_int 0)))
896690286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
896790286Sobrien	(ior:QI (match_dup 1) (match_dup 2)))]
896890286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
896990286Sobrien   && ix86_binary_operator_ok (IOR, QImode, operands)"
897090286Sobrien  "or{b}\t{%2, %0|%0, %2}"
897190286Sobrien  [(set_attr "type" "alu")
897290286Sobrien   (set_attr "mode" "QI")])
897318334Speter
897490286Sobrien(define_insn "*iorqi_2_slp"
897590286Sobrien  [(set (reg 17)
897690286Sobrien	(compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
897790286Sobrien			 (match_operand:QI 1 "general_operand" "qim,qi"))
897890286Sobrien		 (const_int 0)))
897990286Sobrien   (set (strict_low_part (match_dup 0))
898090286Sobrien	(ior:QI (match_dup 0) (match_dup 1)))]
898190286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
898290286Sobrien  "or{b}\t{%1, %0|%0, %1}"
898390286Sobrien  [(set_attr "type" "alu1")
898490286Sobrien   (set_attr "mode" "QI")])
898518334Speter
898690286Sobrien(define_insn "*iorqi_3"
898790286Sobrien  [(set (reg 17)
898890286Sobrien	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
898990286Sobrien			 (match_operand:QI 2 "general_operand" "qim"))
899090286Sobrien		 (const_int 0)))
899190286Sobrien   (clobber (match_scratch:QI 0 "=q"))]
899290286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
899390286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
899490286Sobrien  "or{b}\t{%2, %0|%0, %2}"
899590286Sobrien  [(set_attr "type" "alu")
899690286Sobrien   (set_attr "mode" "QI")])
899718334Speter
899890286Sobrien
899990286Sobrien;; Logical XOR instructions
900090286Sobrien
900190286Sobrien;; %%% This used to optimize known byte-wide and operations to memory.
900290286Sobrien;; If this is considered useful, it should be done with splitters.
900390286Sobrien
900490286Sobrien(define_expand "xordi3"
900590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
900690286Sobrien	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
900790286Sobrien		(match_operand:DI 2 "x86_64_general_operand" "")))
900890286Sobrien   (clobber (reg:CC 17))]
900990286Sobrien  "TARGET_64BIT"
901090286Sobrien  "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
901190286Sobrien
901290286Sobrien(define_insn "*xordi_1_rex64"
901390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
901490286Sobrien	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
901590286Sobrien		(match_operand:DI 2 "x86_64_general_operand" "re,rm")))
901690286Sobrien   (clobber (reg:CC 17))]
901790286Sobrien  "TARGET_64BIT
901890286Sobrien   && ix86_binary_operator_ok (XOR, DImode, operands)"
901990286Sobrien  "@
902090286Sobrien   xor{q}\t{%2, %0|%0, %2} 
902190286Sobrien   xor{q}\t{%2, %0|%0, %2}"
902290286Sobrien  [(set_attr "type" "alu")
902390286Sobrien   (set_attr "mode" "DI,DI")])
902490286Sobrien
902590286Sobrien(define_insn "*xordi_2_rex64"
902690286Sobrien  [(set (reg 17)
902790286Sobrien	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
902890286Sobrien			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
902990286Sobrien		 (const_int 0)))
903090286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
903190286Sobrien	(xor:DI (match_dup 1) (match_dup 2)))]
903290286Sobrien  "TARGET_64BIT
903390286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
903490286Sobrien   && ix86_binary_operator_ok (XOR, DImode, operands)"
903590286Sobrien  "@
903690286Sobrien   xor{q}\t{%2, %0|%0, %2} 
903790286Sobrien   xor{q}\t{%2, %0|%0, %2}"
903890286Sobrien  [(set_attr "type" "alu")
903990286Sobrien   (set_attr "mode" "DI,DI")])
904090286Sobrien
904190286Sobrien(define_insn "*xordi_3_rex64"
904290286Sobrien  [(set (reg 17)
904390286Sobrien	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
904490286Sobrien			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
904590286Sobrien		 (const_int 0)))
904690286Sobrien   (clobber (match_scratch:DI 0 "=r"))]
904790286Sobrien  "TARGET_64BIT
904890286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
904990286Sobrien   && ix86_binary_operator_ok (XOR, DImode, operands)"
905090286Sobrien  "xor{q}\t{%2, %0|%0, %2}"
905190286Sobrien  [(set_attr "type" "alu")
905290286Sobrien   (set_attr "mode" "DI")])
905390286Sobrien
905490286Sobrien(define_expand "xorsi3"
905590286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
905690286Sobrien	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
905790286Sobrien		(match_operand:SI 2 "general_operand" "")))
905890286Sobrien   (clobber (reg:CC 17))]
905918334Speter  ""
906090286Sobrien  "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
906118334Speter
906290286Sobrien(define_insn "*xorsi_1"
906390286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
906490286Sobrien	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
906590286Sobrien		(match_operand:SI 2 "general_operand" "ri,rm")))
906690286Sobrien   (clobber (reg:CC 17))]
906790286Sobrien  "ix86_binary_operator_ok (XOR, SImode, operands)"
906890286Sobrien  "xor{l}\t{%2, %0|%0, %2}"
906990286Sobrien  [(set_attr "type" "alu")
907090286Sobrien   (set_attr "mode" "SI")])
907118334Speter
907290286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
907390286Sobrien;; Add speccase for immediates
907490286Sobrien(define_insn "*xorsi_1_zext"
907590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
907690286Sobrien	(zero_extend:DI
907790286Sobrien	  (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
907890286Sobrien		  (match_operand:SI 2 "general_operand" "rim"))))
907990286Sobrien   (clobber (reg:CC 17))]
908090286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
908190286Sobrien  "xor{l}\t{%2, %k0|%k0, %2}"
908290286Sobrien  [(set_attr "type" "alu")
908390286Sobrien   (set_attr "mode" "SI")])
908450650Sobrien
908590286Sobrien(define_insn "*xorsi_1_zext_imm"
908690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
908790286Sobrien	(xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
908890286Sobrien		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
908990286Sobrien   (clobber (reg:CC 17))]
909090286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
909190286Sobrien  "xor{l}\t{%2, %k0|%k0, %2}"
909290286Sobrien  [(set_attr "type" "alu")
909390286Sobrien   (set_attr "mode" "SI")])
909450650Sobrien
909590286Sobrien(define_insn "*xorsi_2"
909690286Sobrien  [(set (reg 17)
909790286Sobrien	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
909890286Sobrien			 (match_operand:SI 2 "general_operand" "rim,ri"))
909990286Sobrien		 (const_int 0)))
910090286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
910190286Sobrien	(xor:SI (match_dup 1) (match_dup 2)))]
910290286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
910390286Sobrien   && ix86_binary_operator_ok (XOR, SImode, operands)"
910490286Sobrien  "xor{l}\t{%2, %0|%0, %2}"
910590286Sobrien  [(set_attr "type" "alu")
910690286Sobrien   (set_attr "mode" "SI")])
910750650Sobrien
910890286Sobrien;; See comment for addsi_1_zext why we do use nonimmediate_operand
910990286Sobrien;; ??? Special case for immediate operand is missing - it is tricky.
911090286Sobrien(define_insn "*xorsi_2_zext"
911190286Sobrien  [(set (reg 17)
911290286Sobrien	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
911390286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
911490286Sobrien		 (const_int 0)))
911590286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
911690286Sobrien	(zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
911790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
911890286Sobrien   && ix86_binary_operator_ok (XOR, SImode, operands)"
911990286Sobrien  "xor{l}\t{%2, %k0|%k0, %2}"
912090286Sobrien  [(set_attr "type" "alu")
912190286Sobrien   (set_attr "mode" "SI")])
912250650Sobrien
912390286Sobrien(define_insn "*xorsi_2_zext_imm"
912490286Sobrien  [(set (reg 17)
912590286Sobrien	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
912690286Sobrien			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
912790286Sobrien		 (const_int 0)))
912890286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
912990286Sobrien	(xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
913090286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
913190286Sobrien   && ix86_binary_operator_ok (XOR, SImode, operands)"
913290286Sobrien  "xor{l}\t{%2, %k0|%k0, %2}"
913390286Sobrien  [(set_attr "type" "alu")
913490286Sobrien   (set_attr "mode" "SI")])
913550650Sobrien
913690286Sobrien(define_insn "*xorsi_3"
913790286Sobrien  [(set (reg 17)
913890286Sobrien	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
913990286Sobrien			 (match_operand:SI 2 "general_operand" "rim"))
914090286Sobrien		 (const_int 0)))
914190286Sobrien   (clobber (match_scratch:SI 0 "=r"))]
914290286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
914390286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
914490286Sobrien  "xor{l}\t{%2, %0|%0, %2}"
914590286Sobrien  [(set_attr "type" "alu")
914690286Sobrien   (set_attr "mode" "SI")])
914718334Speter
914890286Sobrien(define_expand "xorhi3"
914990286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
915090286Sobrien	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
915190286Sobrien		(match_operand:HI 2 "general_operand" "")))
915290286Sobrien   (clobber (reg:CC 17))]
915390286Sobrien  "TARGET_HIMODE_MATH"
915490286Sobrien  "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
915518334Speter
915690286Sobrien(define_insn "*xorhi_1"
915790286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
915890286Sobrien	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
915990286Sobrien		(match_operand:HI 2 "general_operand" "rmi,ri")))
916090286Sobrien   (clobber (reg:CC 17))]
916190286Sobrien  "ix86_binary_operator_ok (XOR, HImode, operands)"
916290286Sobrien  "xor{w}\t{%2, %0|%0, %2}"
916390286Sobrien  [(set_attr "type" "alu")
916490286Sobrien   (set_attr "mode" "HI")])
916518334Speter
916690286Sobrien(define_insn "*xorhi_2"
916790286Sobrien  [(set (reg 17)
916890286Sobrien	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
916990286Sobrien			 (match_operand:HI 2 "general_operand" "rim,ri"))
917090286Sobrien		 (const_int 0)))
917190286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
917290286Sobrien	(xor:HI (match_dup 1) (match_dup 2)))]
917390286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
917490286Sobrien   && ix86_binary_operator_ok (XOR, HImode, operands)"
917590286Sobrien  "xor{w}\t{%2, %0|%0, %2}"
917690286Sobrien  [(set_attr "type" "alu")
917790286Sobrien   (set_attr "mode" "HI")])
917850650Sobrien
917990286Sobrien(define_insn "*xorhi_3"
918090286Sobrien  [(set (reg 17)
918190286Sobrien	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
918290286Sobrien			 (match_operand:HI 2 "general_operand" "rim"))
918390286Sobrien		 (const_int 0)))
918490286Sobrien   (clobber (match_scratch:HI 0 "=r"))]
918590286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
918690286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
918790286Sobrien  "xor{w}\t{%2, %0|%0, %2}"
918890286Sobrien  [(set_attr "type" "alu")
918990286Sobrien   (set_attr "mode" "HI")])
919050650Sobrien
919190286Sobrien(define_expand "xorqi3"
919290286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
919390286Sobrien	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
919490286Sobrien		(match_operand:QI 2 "general_operand" "")))
919590286Sobrien   (clobber (reg:CC 17))]
919690286Sobrien  "TARGET_QIMODE_MATH"
919790286Sobrien  "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
919850650Sobrien
919990286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
920090286Sobrien(define_insn "*xorqi_1"
920190286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
920290286Sobrien	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
920390286Sobrien		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
920490286Sobrien   (clobber (reg:CC 17))]
920590286Sobrien  "ix86_binary_operator_ok (XOR, QImode, operands)"
920690286Sobrien  "@
920790286Sobrien   xor{b}\t{%2, %0|%0, %2}
920890286Sobrien   xor{b}\t{%2, %0|%0, %2}
920990286Sobrien   xor{l}\t{%k2, %k0|%k0, %k2}"
921090286Sobrien  [(set_attr "type" "alu")
921190286Sobrien   (set_attr "mode" "QI,QI,SI")])
921218334Speter
921390286Sobrien(define_insn "*xorqi_ext_1"
921490286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
921590286Sobrien			 (const_int 8)
921690286Sobrien			 (const_int 8))
921790286Sobrien	(xor:SI 
921890286Sobrien	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
921990286Sobrien	  		   (const_int 8)
922090286Sobrien			   (const_int 8))
922190286Sobrien	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
922290286Sobrien	  		   (const_int 8)
922390286Sobrien			   (const_int 8))))
922490286Sobrien   (clobber (reg:CC 17))]
922590286Sobrien  ""
922690286Sobrien  "xor{b}\t{%h2, %h0|%h0, %h2}"
922790286Sobrien  [(set_attr "type" "alu")
922890286Sobrien   (set_attr "length_immediate" "0")
922990286Sobrien   (set_attr "mode" "QI")])
923050650Sobrien
923190286Sobrien(define_insn "*xorqi_cc_1"
923290286Sobrien  [(set (reg 17)
923390286Sobrien	(compare
923490286Sobrien	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
923590286Sobrien		  (match_operand:QI 2 "general_operand" "qim,qi"))
923690286Sobrien	  (const_int 0)))
923790286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
923890286Sobrien	(xor:QI (match_dup 1) (match_dup 2)))]
923990286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
924090286Sobrien   && ix86_binary_operator_ok (XOR, QImode, operands)"
924190286Sobrien  "xor{b}\t{%2, %0|%0, %2}"
924290286Sobrien  [(set_attr "type" "alu")
924390286Sobrien   (set_attr "mode" "QI")])
924450650Sobrien
924590286Sobrien(define_insn "*xorqi_cc_2"
924690286Sobrien  [(set (reg 17)
924790286Sobrien	(compare
924890286Sobrien	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
924990286Sobrien		  (match_operand:QI 2 "general_operand" "qim"))
925090286Sobrien	  (const_int 0)))
925190286Sobrien   (clobber (match_scratch:QI 0 "=q"))]
925290286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
925390286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
925490286Sobrien  "xor{b}\t{%2, %0|%0, %2}"
925590286Sobrien  [(set_attr "type" "alu")
925690286Sobrien   (set_attr "mode" "QI")])
925718334Speter
925890286Sobrien(define_insn "*xorqi_cc_ext_1"
925990286Sobrien  [(set (reg 17)
926090286Sobrien	(compare
926190286Sobrien	  (xor:SI
926290286Sobrien	    (zero_extract:SI
926390286Sobrien	      (match_operand 1 "ext_register_operand" "0")
926490286Sobrien	      (const_int 8)
926590286Sobrien	      (const_int 8))
926690286Sobrien	    (match_operand:QI 2 "general_operand" "qmn"))
926790286Sobrien	  (const_int 0)))
926890286Sobrien   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
926990286Sobrien			 (const_int 8)
927090286Sobrien			 (const_int 8))
927190286Sobrien	(xor:SI 
927290286Sobrien	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
927390286Sobrien	  (match_dup 2)))]
927490286Sobrien  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
927590286Sobrien  "xor{b}\t{%2, %h0|%h0, %2}"
927690286Sobrien  [(set_attr "type" "alu")
927790286Sobrien   (set_attr "mode" "QI")])
927890286Sobrien
927990286Sobrien(define_insn "*xorqi_cc_ext_1_rex64"
928090286Sobrien  [(set (reg 17)
928190286Sobrien	(compare
928290286Sobrien	  (xor:SI
928390286Sobrien	    (zero_extract:SI
928490286Sobrien	      (match_operand 1 "ext_register_operand" "0")
928590286Sobrien	      (const_int 8)
928690286Sobrien	      (const_int 8))
928790286Sobrien	    (match_operand:QI 2 "nonmemory_operand" "Qn"))
928890286Sobrien	  (const_int 0)))
928990286Sobrien   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
929090286Sobrien			 (const_int 8)
929190286Sobrien			 (const_int 8))
929290286Sobrien	(xor:SI 
929390286Sobrien	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
929490286Sobrien	  (match_dup 2)))]
929590286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
929690286Sobrien  "xor{b}\t{%2, %h0|%h0, %2}"
929790286Sobrien  [(set_attr "type" "alu")
929890286Sobrien   (set_attr "mode" "QI")])
929990286Sobrien
930090286Sobrien(define_expand "xorqi_cc_ext_1"
930190286Sobrien  [(parallel [
930290286Sobrien     (set (reg:CCNO 17)
930390286Sobrien	  (compare:CCNO
930490286Sobrien	    (xor:SI
930590286Sobrien	      (zero_extract:SI
930690286Sobrien		(match_operand 1 "ext_register_operand" "")
930790286Sobrien		(const_int 8)
930890286Sobrien		(const_int 8))
930990286Sobrien	      (match_operand:QI 2 "general_operand" ""))
931090286Sobrien	    (const_int 0)))
931190286Sobrien     (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
931290286Sobrien			   (const_int 8)
931390286Sobrien			   (const_int 8))
931490286Sobrien	  (xor:SI 
931590286Sobrien	    (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
931690286Sobrien	    (match_dup 2)))])]
931718334Speter  ""
931890286Sobrien  "")
931918334Speter
932090286Sobrien;; Negation instructions
932118334Speter
932290286Sobrien(define_expand "negdi2"
932390286Sobrien  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
932490286Sobrien		   (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
932590286Sobrien	      (clobber (reg:CC 17))])]
932618334Speter  ""
932790286Sobrien  "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
932850650Sobrien
932990286Sobrien(define_insn "*negdi2_1"
933090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
933190286Sobrien	(neg:DI (match_operand:DI 1 "general_operand" "0")))
933290286Sobrien   (clobber (reg:CC 17))]
933390286Sobrien  "!TARGET_64BIT
933490286Sobrien   && ix86_unary_operator_ok (NEG, DImode, operands)"
933590286Sobrien  "#")
933650650Sobrien
933790286Sobrien(define_split
933890286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
933990286Sobrien	(neg:DI (match_operand:DI 1 "general_operand" "")))
934090286Sobrien   (clobber (reg:CC 17))]
934190286Sobrien  "!TARGET_64BIT && reload_completed"
934290286Sobrien  [(parallel
934390286Sobrien    [(set (reg:CCZ 17)
934490286Sobrien	  (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
934590286Sobrien     (set (match_dup 0) (neg:SI (match_dup 2)))])
934690286Sobrien   (parallel
934790286Sobrien    [(set (match_dup 1)
934890286Sobrien	  (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
934990286Sobrien			    (match_dup 3))
935090286Sobrien		   (const_int 0)))
935190286Sobrien     (clobber (reg:CC 17))])
935290286Sobrien   (parallel
935390286Sobrien    [(set (match_dup 1)
935490286Sobrien	  (neg:SI (match_dup 1)))
935590286Sobrien     (clobber (reg:CC 17))])]
935690286Sobrien  "split_di (operands+1, 1, operands+2, operands+3);
935790286Sobrien   split_di (operands+0, 1, operands+0, operands+1);")
935850650Sobrien
935990286Sobrien(define_insn "*negdi2_1_rex64"
936090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
936190286Sobrien	(neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
936290286Sobrien   (clobber (reg:CC 17))]
936390286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
936490286Sobrien  "neg{q}\t%0"
936590286Sobrien  [(set_attr "type" "negnot")
936690286Sobrien   (set_attr "mode" "DI")])
936750650Sobrien
936890286Sobrien;; The problem with neg is that it does not perform (compare x 0),
936990286Sobrien;; it really performs (compare 0 x), which leaves us with the zero
937090286Sobrien;; flag being the only useful item.
937150650Sobrien
937290286Sobrien(define_insn "*negdi2_cmpz_rex64"
937390286Sobrien  [(set (reg:CCZ 17)
937490286Sobrien	(compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
937590286Sobrien		     (const_int 0)))
937690286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
937790286Sobrien	(neg:DI (match_dup 1)))]
937890286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
937990286Sobrien  "neg{q}\t%0"
938090286Sobrien  [(set_attr "type" "negnot")
938190286Sobrien   (set_attr "mode" "DI")])
938250650Sobrien
938318334Speter
938490286Sobrien(define_expand "negsi2"
938590286Sobrien  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
938690286Sobrien		   (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
938790286Sobrien	      (clobber (reg:CC 17))])]
938890286Sobrien  ""
938990286Sobrien  "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
939018334Speter
939190286Sobrien(define_insn "*negsi2_1"
939290286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
939390286Sobrien	(neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
939490286Sobrien   (clobber (reg:CC 17))]
939590286Sobrien  "ix86_unary_operator_ok (NEG, SImode, operands)"
939690286Sobrien  "neg{l}\t%0"
939790286Sobrien  [(set_attr "type" "negnot")
939890286Sobrien   (set_attr "mode" "SI")])
939950650Sobrien
940090286Sobrien;; Combine is quite creative about this pattern.
940190286Sobrien(define_insn "*negsi2_1_zext"
940290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
940390286Sobrien	(lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
940490286Sobrien					(const_int 32)))
940590286Sobrien		     (const_int 32)))
940690286Sobrien   (clobber (reg:CC 17))]
940790286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
940890286Sobrien  "neg{l}\t%k0"
940990286Sobrien  [(set_attr "type" "negnot")
941090286Sobrien   (set_attr "mode" "SI")])
941150650Sobrien
941290286Sobrien;; The problem with neg is that it does not perform (compare x 0),
941390286Sobrien;; it really performs (compare 0 x), which leaves us with the zero
941490286Sobrien;; flag being the only useful item.
941518334Speter
941690286Sobrien(define_insn "*negsi2_cmpz"
941790286Sobrien  [(set (reg:CCZ 17)
941890286Sobrien	(compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
941990286Sobrien		     (const_int 0)))
942090286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
942190286Sobrien	(neg:SI (match_dup 1)))]
942290286Sobrien  "ix86_unary_operator_ok (NEG, SImode, operands)"
942390286Sobrien  "neg{l}\t%0"
942490286Sobrien  [(set_attr "type" "negnot")
942590286Sobrien   (set_attr "mode" "SI")])
942650650Sobrien
942790286Sobrien(define_insn "*negsi2_cmpz_zext"
942890286Sobrien  [(set (reg:CCZ 17)
942990286Sobrien	(compare:CCZ (lshiftrt:DI
943090286Sobrien		       (neg:DI (ashift:DI
943190286Sobrien				 (match_operand:DI 1 "register_operand" "0")
943290286Sobrien				 (const_int 32)))
943390286Sobrien		       (const_int 32))
943490286Sobrien		     (const_int 0)))
943590286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
943690286Sobrien	(lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
943790286Sobrien					(const_int 32)))
943890286Sobrien		     (const_int 32)))]
943990286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
944090286Sobrien  "neg{l}\t%k0"
944190286Sobrien  [(set_attr "type" "negnot")
944290286Sobrien   (set_attr "mode" "SI")])
944390286Sobrien
944490286Sobrien(define_expand "neghi2"
944590286Sobrien  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
944690286Sobrien		   (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
944790286Sobrien	      (clobber (reg:CC 17))])]
944890286Sobrien  "TARGET_HIMODE_MATH"
944990286Sobrien  "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
945090286Sobrien
945190286Sobrien(define_insn "*neghi2_1"
945290286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
945390286Sobrien	(neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
945490286Sobrien   (clobber (reg:CC 17))]
945590286Sobrien  "ix86_unary_operator_ok (NEG, HImode, operands)"
945690286Sobrien  "neg{w}\t%0"
945790286Sobrien  [(set_attr "type" "negnot")
945890286Sobrien   (set_attr "mode" "HI")])
945990286Sobrien
946090286Sobrien(define_insn "*neghi2_cmpz"
946190286Sobrien  [(set (reg:CCZ 17)
946290286Sobrien	(compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
946390286Sobrien		     (const_int 0)))
946490286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
946590286Sobrien	(neg:HI (match_dup 1)))]
946690286Sobrien  "ix86_unary_operator_ok (NEG, HImode, operands)"
946790286Sobrien  "neg{w}\t%0"
946890286Sobrien  [(set_attr "type" "negnot")
946990286Sobrien   (set_attr "mode" "HI")])
947090286Sobrien
947190286Sobrien(define_expand "negqi2"
947290286Sobrien  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
947390286Sobrien		   (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
947490286Sobrien	      (clobber (reg:CC 17))])]
947590286Sobrien  "TARGET_QIMODE_MATH"
947690286Sobrien  "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
947790286Sobrien
947890286Sobrien(define_insn "*negqi2_1"
947990286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
948090286Sobrien	(neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
948190286Sobrien   (clobber (reg:CC 17))]
948290286Sobrien  "ix86_unary_operator_ok (NEG, QImode, operands)"
948390286Sobrien  "neg{b}\t%0"
948490286Sobrien  [(set_attr "type" "negnot")
948590286Sobrien   (set_attr "mode" "QI")])
948690286Sobrien
948790286Sobrien(define_insn "*negqi2_cmpz"
948890286Sobrien  [(set (reg:CCZ 17)
948990286Sobrien	(compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
949090286Sobrien		     (const_int 0)))
949190286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
949290286Sobrien	(neg:QI (match_dup 1)))]
949390286Sobrien  "ix86_unary_operator_ok (NEG, QImode, operands)"
949490286Sobrien  "neg{b}\t%0"
949590286Sobrien  [(set_attr "type" "negnot")
949690286Sobrien   (set_attr "mode" "QI")])
949790286Sobrien
949890286Sobrien;; Changing of sign for FP values is doable using integer unit too.
949990286Sobrien
950090286Sobrien(define_expand "negsf2"
950190286Sobrien  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
950290286Sobrien		   (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
950390286Sobrien	      (clobber (reg:CC 17))])]
950490286Sobrien  "TARGET_80387"
950590286Sobrien  "if (TARGET_SSE)
950690286Sobrien     {
950790286Sobrien       /* In case operand is in memory,  we will not use SSE.  */
950890286Sobrien       if (memory_operand (operands[0], VOIDmode)
950990286Sobrien	   && rtx_equal_p (operands[0], operands[1]))
951090286Sobrien	 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
951190286Sobrien       else
951218334Speter	{
951390286Sobrien	  /* Using SSE is tricky, since we need bitwise negation of -0
951490286Sobrien	     in register.  */
951590286Sobrien	  rtx reg = gen_reg_rtx (SFmode);
951690286Sobrien	  rtx dest = operands[0];
951718334Speter
951890286Sobrien	  operands[1] = force_reg (SFmode, operands[1]);
951990286Sobrien	  operands[0] = force_reg (SFmode, operands[0]);
952090286Sobrien	  emit_move_insn (reg,
952190286Sobrien			  gen_lowpart (SFmode,
952290286Sobrien				       GEN_INT (trunc_int_for_mode (0x80000000,
952390286Sobrien							            SImode))));
952490286Sobrien	  emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
952590286Sobrien	  if (dest != operands[0])
952690286Sobrien	    emit_move_insn (dest, operands[0]);
952750650Sobrien	}
952890286Sobrien       DONE;
952990286Sobrien     }
953090286Sobrien   ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
953118334Speter
953290286Sobrien(define_insn "negsf2_memory"
953390286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
953490286Sobrien	(neg:SF (match_operand:SF 1 "memory_operand" "0")))
953590286Sobrien   (clobber (reg:CC 17))]
953690286Sobrien  "ix86_unary_operator_ok (NEG, SFmode, operands)"
953790286Sobrien  "#")
953818334Speter
953990286Sobrien(define_insn "negsf2_ifs"
954090286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
954190286Sobrien	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
954290286Sobrien   (use (match_operand:SF 2 "nonmemory_operand" "x,0#x,*g#x,*g#x"))
954390286Sobrien   (clobber (reg:CC 17))]
954490286Sobrien  "TARGET_SSE
954590286Sobrien   && (reload_in_progress || reload_completed
954690286Sobrien       || (register_operand (operands[0], VOIDmode)
954790286Sobrien	   && register_operand (operands[1], VOIDmode)))"
954890286Sobrien  "#")
954918334Speter
955090286Sobrien(define_split
955190286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
955290286Sobrien	(neg:SF (match_operand:SF 1 "memory_operand" "")))
955390286Sobrien   (use (match_operand:SF 2 "" ""))
955490286Sobrien   (clobber (reg:CC 17))]
955518334Speter  ""
955690286Sobrien  [(parallel [(set (match_dup 0)
955790286Sobrien		   (neg:SF (match_dup 1)))
955890286Sobrien	      (clobber (reg:CC 17))])])
955990286Sobrien
956090286Sobrien(define_split
956190286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
956290286Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "")))
956390286Sobrien   (use (match_operand:SF 2 "" ""))
956490286Sobrien   (clobber (reg:CC 17))]
956590286Sobrien  "reload_completed && !SSE_REG_P (operands[0])"
956690286Sobrien  [(parallel [(set (match_dup 0)
956790286Sobrien		   (neg:SF (match_dup 1)))
956890286Sobrien	      (clobber (reg:CC 17))])])
956990286Sobrien
957090286Sobrien(define_split
957190286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
957290286Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "")))
957390286Sobrien   (use (match_operand:SF 2 "register_operand" ""))
957490286Sobrien   (clobber (reg:CC 17))]
957590286Sobrien  "reload_completed && SSE_REG_P (operands[0])"
957690286Sobrien  [(set (subreg:TI (match_dup 0) 0)
957790286Sobrien	(xor:TI (subreg:TI (match_dup 1) 0)
957890286Sobrien		(subreg:TI (match_dup 2) 0)))]
957918334Speter{
958090286Sobrien  if (operands_match_p (operands[0], operands[2]))
958118334Speter    {
958290286Sobrien      rtx tmp;
958390286Sobrien      tmp = operands[1];
958490286Sobrien      operands[1] = operands[2];
958590286Sobrien      operands[2] = tmp;
958690286Sobrien    }
958790286Sobrien})
958818334Speter
958918334Speter
959090286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
959190286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
959290286Sobrien;; to itself.
959390286Sobrien(define_insn "*negsf2_if"
959490286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
959590286Sobrien	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
959690286Sobrien   (clobber (reg:CC 17))]
959790286Sobrien  "TARGET_80387 && !TARGET_SSE
959890286Sobrien   && ix86_unary_operator_ok (NEG, SFmode, operands)"
959990286Sobrien  "#")
960018334Speter
960190286Sobrien(define_split
960290286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
960390286Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "")))
960490286Sobrien   (clobber (reg:CC 17))]
960590286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
960690286Sobrien  [(set (match_dup 0)
960790286Sobrien	(neg:SF (match_dup 1)))]
960890286Sobrien  "")
960990286Sobrien
961090286Sobrien(define_split
961190286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
961290286Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "")))
961390286Sobrien   (clobber (reg:CC 17))]
961490286Sobrien  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
961590286Sobrien  [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
961690286Sobrien	      (clobber (reg:CC 17))])]
961790286Sobrien  "operands[1] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
961890286Sobrien   operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
961990286Sobrien
962090286Sobrien(define_split
962190286Sobrien  [(set (match_operand 0 "memory_operand" "")
962290286Sobrien	(neg (match_operand 1 "memory_operand" "")))
962390286Sobrien   (clobber (reg:CC 17))]
962490286Sobrien  "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
962590286Sobrien  [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
962690286Sobrien	      (clobber (reg:CC 17))])]
962790286Sobrien{
962890286Sobrien  int size = GET_MODE_SIZE (GET_MODE (operands[1]));
962990286Sobrien
963090286Sobrien  /* XFmode's size is 12, TFmode 16, but only 10 bytes are used.  */
963190286Sobrien  if (size >= 12)
963290286Sobrien    size = 10;
963390286Sobrien  operands[0] = adjust_address (operands[0], QImode, size - 1);
963490286Sobrien  operands[1] = GEN_INT (trunc_int_for_mode (0x80, QImode));
963590286Sobrien})
963690286Sobrien
963790286Sobrien(define_expand "negdf2"
963890286Sobrien  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
963990286Sobrien		   (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
964090286Sobrien	      (clobber (reg:CC 17))])]
964190286Sobrien  "TARGET_80387"
964290286Sobrien  "if (TARGET_SSE2)
964390286Sobrien     {
964490286Sobrien       /* In case operand is in memory,  we will not use SSE.  */
964590286Sobrien       if (memory_operand (operands[0], VOIDmode)
964690286Sobrien	   && rtx_equal_p (operands[0], operands[1]))
964790286Sobrien	 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
964890286Sobrien       else
964918334Speter	{
965090286Sobrien	  /* Using SSE is tricky, since we need bitwise negation of -0
965190286Sobrien	     in register.  */
965290286Sobrien	  rtx reg = gen_reg_rtx (DFmode);
965390286Sobrien#if HOST_BITS_PER_WIDE_INT >= 64
965490286Sobrien	  rtx imm = GEN_INT (trunc_int_for_mode(((HOST_WIDE_INT)1) << 63,
965590286Sobrien					        DImode));
965690286Sobrien#else
965790286Sobrien	  rtx imm = immed_double_const (0, 0x80000000, DImode);
965890286Sobrien#endif
965990286Sobrien	  rtx dest = operands[0];
966018334Speter
966190286Sobrien	  operands[1] = force_reg (DFmode, operands[1]);
966290286Sobrien	  operands[0] = force_reg (DFmode, operands[0]);
966390286Sobrien	  emit_move_insn (reg, gen_lowpart (DFmode, imm));
966490286Sobrien	  emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
966590286Sobrien	  if (dest != operands[0])
966690286Sobrien	    emit_move_insn (dest, operands[0]);
966718334Speter	}
966890286Sobrien       DONE;
966990286Sobrien     }
967090286Sobrien   ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
967118334Speter
967290286Sobrien(define_insn "negdf2_memory"
967390286Sobrien  [(set (match_operand:DF 0 "memory_operand" "=m")
967490286Sobrien	(neg:DF (match_operand:DF 1 "memory_operand" "0")))
967590286Sobrien   (clobber (reg:CC 17))]
967690286Sobrien  "ix86_unary_operator_ok (NEG, DFmode, operands)"
967790286Sobrien  "#")
967850650Sobrien
967990286Sobrien(define_insn "negdf2_ifs"
968090286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
968190286Sobrien	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
968290286Sobrien   (use (match_operand:DF 2 "nonmemory_operand" "Y,0,*g#Y,*g#Y"))
968390286Sobrien   (clobber (reg:CC 17))]
968490286Sobrien  "!TARGET_64BIT && TARGET_SSE2
968590286Sobrien   && (reload_in_progress || reload_completed
968690286Sobrien       || (register_operand (operands[0], VOIDmode)
968790286Sobrien	   && register_operand (operands[1], VOIDmode)))"
968890286Sobrien  "#")
968950650Sobrien
969090286Sobrien(define_insn "*negdf2_ifs_rex64"
969190286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,fm#Yr,r#Yf")
969290286Sobrien	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
969390286Sobrien   (use (match_operand:DF 2 "general_operand" "Y,0,*g#Yr,*rm"))
969490286Sobrien   (clobber (reg:CC 17))]
969590286Sobrien  "TARGET_64BIT && TARGET_SSE2
969690286Sobrien   && (reload_in_progress || reload_completed
969790286Sobrien       || (register_operand (operands[0], VOIDmode)
969890286Sobrien	   && register_operand (operands[1], VOIDmode)))"
969990286Sobrien  "#")
970018334Speter
970190286Sobrien(define_split
970290286Sobrien  [(set (match_operand:DF 0 "memory_operand" "")
970390286Sobrien	(neg:DF (match_operand:DF 1 "memory_operand" "")))
970490286Sobrien   (use (match_operand:DF 2 "" ""))
970590286Sobrien   (clobber (reg:CC 17))]
970618334Speter  ""
970790286Sobrien  [(parallel [(set (match_dup 0)
970890286Sobrien		   (neg:DF (match_dup 1)))
970990286Sobrien	      (clobber (reg:CC 17))])])
971050650Sobrien
971190286Sobrien(define_split
971290286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
971390286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
971490286Sobrien   (use (match_operand:DF 2 "" ""))
971590286Sobrien   (clobber (reg:CC 17))]
971690286Sobrien  "reload_completed && !SSE_REG_P (operands[0])
971790286Sobrien   && (!TARGET_64BIT || FP_REG_P (operands[0]))"
971890286Sobrien  [(parallel [(set (match_dup 0)
971990286Sobrien		   (neg:DF (match_dup 1)))
972090286Sobrien	      (clobber (reg:CC 17))])])
972150650Sobrien
972290286Sobrien(define_split
972390286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
972490286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
972590286Sobrien   (use (match_operand:DF 2 "" ""))
972690286Sobrien   (clobber (reg:CC 17))]
972790286Sobrien  "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
972890286Sobrien  [(parallel [(set (match_dup 0)
972990286Sobrien		   (xor:DI (match_dup 1) (match_dup 2)))
973090286Sobrien	      (clobber (reg:CC 17))])]
973190286Sobrien   "operands[0] = gen_lowpart (DImode, operands[0]);
973290286Sobrien    operands[1] = gen_lowpart (DImode, operands[1]);
973390286Sobrien    operands[2] = gen_lowpart (DImode, operands[2]);")
973452296Sobrien
973590286Sobrien(define_split
973690286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
973790286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
973890286Sobrien   (use (match_operand:DF 2 "register_operand" ""))
973990286Sobrien   (clobber (reg:CC 17))]
974090286Sobrien  "reload_completed && SSE_REG_P (operands[0])"
974190286Sobrien  [(set (subreg:TI (match_dup 0) 0)
974290286Sobrien	(xor:TI (subreg:TI (match_dup 1) 0)
974390286Sobrien		(subreg:TI (match_dup 2) 0)))]
974490286Sobrien{
974590286Sobrien  if (operands_match_p (operands[0], operands[2]))
974690286Sobrien    {
974790286Sobrien      rtx tmp;
974890286Sobrien      tmp = operands[1];
974990286Sobrien      operands[1] = operands[2];
975090286Sobrien      operands[2] = tmp;
975190286Sobrien    }
975290286Sobrien})
975352296Sobrien
975490286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
975590286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
975690286Sobrien;; to itself.
975790286Sobrien(define_insn "*negdf2_if"
975890286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
975990286Sobrien	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
976090286Sobrien   (clobber (reg:CC 17))]
976190286Sobrien  "!TARGET_64BIT && TARGET_80387
976290286Sobrien   && ix86_unary_operator_ok (NEG, DFmode, operands)"
976390286Sobrien  "#")
976450650Sobrien
976590286Sobrien;; FIXME: We should to allow integer registers here.  Problem is that
976690286Sobrien;; we need another scratch register to get constant from.
976790286Sobrien;; Forcing constant to mem if no register available in peep2 should be
976890286Sobrien;; safe even for PIC mode, because of RIP relative addressing.
976990286Sobrien(define_insn "*negdf2_if_rex64"
977090286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
977190286Sobrien	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
977290286Sobrien   (clobber (reg:CC 17))]
977390286Sobrien  "TARGET_64BIT && TARGET_80387
977490286Sobrien   && ix86_unary_operator_ok (NEG, DFmode, operands)"
977590286Sobrien  "#")
977690286Sobrien
977750650Sobrien(define_split
977890286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
977990286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
978090286Sobrien   (clobber (reg:CC 17))]
978190286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
978290286Sobrien  [(set (match_dup 0)
978390286Sobrien	(neg:DF (match_dup 1)))]
978490286Sobrien  "")
978550650Sobrien
978690286Sobrien(define_split
978790286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
978890286Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "")))
978990286Sobrien   (clobber (reg:CC 17))]
979090286Sobrien  "!TARGET_64BIT && TARGET_80387 && reload_completed
979190286Sobrien   && !FP_REGNO_P (REGNO (operands[0]))"
979290286Sobrien  [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
979390286Sobrien	      (clobber (reg:CC 17))])]
979490286Sobrien  "operands[4] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
979590286Sobrien   split_di (operands+0, 1, operands+2, operands+3);")
979618334Speter
979790286Sobrien(define_expand "negxf2"
979890286Sobrien  [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
979990286Sobrien		   (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
980090286Sobrien	      (clobber (reg:CC 17))])]
980190286Sobrien  "!TARGET_64BIT && TARGET_80387"
980290286Sobrien  "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
980318334Speter
980490286Sobrien(define_expand "negtf2"
980590286Sobrien  [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
980690286Sobrien		   (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
980790286Sobrien	      (clobber (reg:CC 17))])]
980890286Sobrien  "TARGET_80387"
980990286Sobrien  "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
981018334Speter
981190286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
981290286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
981390286Sobrien;; to itself.
981490286Sobrien(define_insn "*negxf2_if"
981590286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
981690286Sobrien	(neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
981790286Sobrien   (clobber (reg:CC 17))]
981890286Sobrien  "!TARGET_64BIT && TARGET_80387
981990286Sobrien   && ix86_unary_operator_ok (NEG, XFmode, operands)"
982090286Sobrien  "#")
982118334Speter
982290286Sobrien(define_split
982390286Sobrien  [(set (match_operand:XF 0 "register_operand" "")
982490286Sobrien	(neg:XF (match_operand:XF 1 "register_operand" "")))
982590286Sobrien   (clobber (reg:CC 17))]
982690286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
982790286Sobrien  [(set (match_dup 0)
982890286Sobrien	(neg:XF (match_dup 1)))]
982990286Sobrien  "")
983018334Speter
983190286Sobrien(define_split
983290286Sobrien  [(set (match_operand:XF 0 "register_operand" "")
983390286Sobrien	(neg:XF (match_operand:XF 1 "register_operand" "")))
983490286Sobrien   (clobber (reg:CC 17))]
983590286Sobrien  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
983690286Sobrien  [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
983790286Sobrien	      (clobber (reg:CC 17))])]
983890286Sobrien  "operands[1] = GEN_INT (0x8000);
983990286Sobrien   operands[0] = gen_rtx_REG (SImode,
984090286Sobrien			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
984118334Speter
984290286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
984390286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
984490286Sobrien;; to itself.
984590286Sobrien(define_insn "*negtf2_if"
984690286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
984790286Sobrien	(neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
984890286Sobrien   (clobber (reg:CC 17))]
984990286Sobrien  "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
985090286Sobrien  "#")
985118334Speter
985290286Sobrien(define_split
985390286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
985490286Sobrien	(neg:TF (match_operand:TF 1 "register_operand" "")))
985590286Sobrien   (clobber (reg:CC 17))]
985690286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
985790286Sobrien  [(set (match_dup 0)
985890286Sobrien	(neg:TF (match_dup 1)))]
985990286Sobrien  "")
986018334Speter
986190286Sobrien(define_split
986290286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
986390286Sobrien	(neg:TF (match_operand:TF 1 "register_operand" "")))
986490286Sobrien   (clobber (reg:CC 17))]
986590286Sobrien  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
986690286Sobrien  [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
986790286Sobrien	      (clobber (reg:CC 17))])]
986890286Sobrien  "operands[1] = GEN_INT (0x8000);
986990286Sobrien   operands[0] = gen_rtx_REG (SImode,
987090286Sobrien			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
987190286Sobrien
987290286Sobrien;; Conditionize these after reload. If they matches before reload, we 
987390286Sobrien;; lose the clobber and ability to use integer instructions.
987490286Sobrien
987590286Sobrien(define_insn "*negsf2_1"
987618334Speter  [(set (match_operand:SF 0 "register_operand" "=f")
987750650Sobrien	(neg:SF (match_operand:SF 1 "register_operand" "0")))]
987890286Sobrien  "TARGET_80387 && reload_completed"
987952296Sobrien  "fchs"
988090286Sobrien  [(set_attr "type" "fsgn")
988190286Sobrien   (set_attr "mode" "SF")
988290286Sobrien   (set_attr "ppro_uops" "few")])
988318334Speter
988490286Sobrien(define_insn "*negdf2_1"
988518334Speter  [(set (match_operand:DF 0 "register_operand" "=f")
988650650Sobrien	(neg:DF (match_operand:DF 1 "register_operand" "0")))]
988790286Sobrien  "TARGET_80387 && reload_completed"
988852296Sobrien  "fchs"
988990286Sobrien  [(set_attr "type" "fsgn")
989090286Sobrien   (set_attr "mode" "DF")
989190286Sobrien   (set_attr "ppro_uops" "few")])
989218334Speter
989390286Sobrien(define_insn "*negextendsfdf2"
989418334Speter  [(set (match_operand:DF 0 "register_operand" "=f")
989590286Sobrien	(neg:DF (float_extend:DF
989690286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
989718334Speter  "TARGET_80387"
989852296Sobrien  "fchs"
989990286Sobrien  [(set_attr "type" "fsgn")
990090286Sobrien   (set_attr "mode" "DF")
990190286Sobrien   (set_attr "ppro_uops" "few")])
990218334Speter
990390286Sobrien(define_insn "*negxf2_1"
990418334Speter  [(set (match_operand:XF 0 "register_operand" "=f")
990550650Sobrien	(neg:XF (match_operand:XF 1 "register_operand" "0")))]
990690286Sobrien  "!TARGET_64BIT && TARGET_80387 && reload_completed"
990752296Sobrien  "fchs"
990890286Sobrien  [(set_attr "type" "fsgn")
990990286Sobrien   (set_attr "mode" "XF")
991090286Sobrien   (set_attr "ppro_uops" "few")])
991118334Speter
991290286Sobrien(define_insn "*negextenddfxf2"
991318334Speter  [(set (match_operand:XF 0 "register_operand" "=f")
991490286Sobrien	(neg:XF (float_extend:XF
991590286Sobrien		  (match_operand:DF 1 "register_operand" "0"))))]
991690286Sobrien  "!TARGET_64BIT && TARGET_80387"
991790286Sobrien  "fchs"
991890286Sobrien  [(set_attr "type" "fsgn")
991990286Sobrien   (set_attr "mode" "XF")
992090286Sobrien   (set_attr "ppro_uops" "few")])
992190286Sobrien
992290286Sobrien(define_insn "*negextendsfxf2"
992390286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
992490286Sobrien	(neg:XF (float_extend:XF
992590286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
992690286Sobrien  "!TARGET_64BIT && TARGET_80387"
992790286Sobrien  "fchs"
992890286Sobrien  [(set_attr "type" "fsgn")
992990286Sobrien   (set_attr "mode" "XF")
993090286Sobrien   (set_attr "ppro_uops" "few")])
993190286Sobrien
993290286Sobrien(define_insn "*negtf2_1"
993390286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
993490286Sobrien	(neg:TF (match_operand:TF 1 "register_operand" "0")))]
993590286Sobrien  "TARGET_80387 && reload_completed"
993690286Sobrien  "fchs"
993790286Sobrien  [(set_attr "type" "fsgn")
993890286Sobrien   (set_attr "mode" "XF")
993990286Sobrien   (set_attr "ppro_uops" "few")])
994090286Sobrien
994190286Sobrien(define_insn "*negextenddftf2"
994290286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
994390286Sobrien	(neg:TF (float_extend:TF
994490286Sobrien		  (match_operand:DF 1 "register_operand" "0"))))]
994518334Speter  "TARGET_80387"
994652296Sobrien  "fchs"
994790286Sobrien  [(set_attr "type" "fsgn")
994890286Sobrien   (set_attr "mode" "XF")
994990286Sobrien   (set_attr "ppro_uops" "few")])
995090286Sobrien
995190286Sobrien(define_insn "*negextendsftf2"
995290286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
995390286Sobrien	(neg:TF (float_extend:TF
995490286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
995590286Sobrien  "TARGET_80387"
995690286Sobrien  "fchs"
995790286Sobrien  [(set_attr "type" "fsgn")
995890286Sobrien   (set_attr "mode" "XF")
995990286Sobrien   (set_attr "ppro_uops" "few")])
996018334Speter
996118334Speter;; Absolute value instructions
996218334Speter
996390286Sobrien(define_expand "abssf2"
996490286Sobrien  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
996590286Sobrien		   (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
996690286Sobrien	      (clobber (reg:CC 17))])]
996790286Sobrien  "TARGET_80387"
996890286Sobrien  "if (TARGET_SSE)
996990286Sobrien     {
997090286Sobrien       /* In case operand is in memory,  we will not use SSE.  */
997190286Sobrien       if (memory_operand (operands[0], VOIDmode)
997290286Sobrien	   && rtx_equal_p (operands[0], operands[1]))
997390286Sobrien	 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
997490286Sobrien       else
997590286Sobrien	{
997690286Sobrien	  /* Using SSE is tricky, since we need bitwise negation of -0
997790286Sobrien	     in register.  */
997890286Sobrien	  rtx reg = gen_reg_rtx (SFmode);
997990286Sobrien	  rtx dest = operands[0];
998090286Sobrien
998190286Sobrien	  operands[1] = force_reg (SFmode, operands[1]);
998290286Sobrien	  operands[0] = force_reg (SFmode, operands[0]);
998390286Sobrien	  emit_move_insn (reg,
998490286Sobrien			  gen_lowpart (SFmode,
998590286Sobrien				       GEN_INT (trunc_int_for_mode (0x80000000,
998690286Sobrien							            SImode))));
998790286Sobrien	  emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
998890286Sobrien	  if (dest != operands[0])
998990286Sobrien	    emit_move_insn (dest, operands[0]);
999090286Sobrien	}
999190286Sobrien       DONE;
999290286Sobrien     }
999390286Sobrien   ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
999490286Sobrien
999590286Sobrien(define_insn "abssf2_memory"
999690286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
999790286Sobrien	(abs:SF (match_operand:SF 1 "memory_operand" "0")))
999890286Sobrien   (clobber (reg:CC 17))]
999990286Sobrien  "ix86_unary_operator_ok (ABS, SFmode, operands)"
1000090286Sobrien  "#")
1000190286Sobrien
1000290286Sobrien(define_insn "abssf2_ifs"
1000390286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,f#xr,rm#xf")
1000490286Sobrien	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "x,0,0")))
1000590286Sobrien   (use (match_operand:SF 2 "nonmemory_operand" "*0#x,*g#x,*g#x"))
1000690286Sobrien   (clobber (reg:CC 17))]
1000790286Sobrien  "TARGET_SSE
1000890286Sobrien   && (reload_in_progress || reload_completed
1000990286Sobrien       || (register_operand (operands[0], VOIDmode)
1001090286Sobrien	   && register_operand (operands[1], VOIDmode)))"
1001190286Sobrien  "#")
1001290286Sobrien
1001390286Sobrien(define_split
1001490286Sobrien  [(set (match_operand:SF 0 "memory_operand" "")
1001590286Sobrien	(abs:SF (match_operand:SF 1 "memory_operand" "")))
1001690286Sobrien   (use (match_operand:SF 2 "" ""))
1001790286Sobrien   (clobber (reg:CC 17))]
1001890286Sobrien  ""
1001990286Sobrien  [(parallel [(set (match_dup 0)
1002090286Sobrien		   (abs:SF (match_dup 1)))
1002190286Sobrien	      (clobber (reg:CC 17))])])
1002290286Sobrien
1002390286Sobrien(define_split
1002490286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1002590286Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "")))
1002690286Sobrien   (use (match_operand:SF 2 "" ""))
1002790286Sobrien   (clobber (reg:CC 17))]
1002890286Sobrien  "reload_completed && !SSE_REG_P (operands[0])"
1002990286Sobrien  [(parallel [(set (match_dup 0)
1003090286Sobrien		   (abs:SF (match_dup 1)))
1003190286Sobrien	      (clobber (reg:CC 17))])])
1003290286Sobrien
1003390286Sobrien(define_split
1003490286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1003590286Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "")))
1003690286Sobrien   (use (match_operand:SF 2 "register_operand" ""))
1003790286Sobrien   (clobber (reg:CC 17))]
1003890286Sobrien  "reload_completed && SSE_REG_P (operands[0])"
1003990286Sobrien  [(set (subreg:TI (match_dup 0) 0)
1004090286Sobrien	(and:TI (not:TI (subreg:TI (match_dup 2) 0))
1004190286Sobrien		(subreg:TI (match_dup 1) 0)))])
1004290286Sobrien
1004390286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
1004490286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
1004590286Sobrien;; to itself.
1004690286Sobrien(define_insn "*abssf2_if"
1004790286Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
1004890286Sobrien	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
1004990286Sobrien   (clobber (reg:CC 17))]
1005090286Sobrien  "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
1005190286Sobrien  "#")
1005290286Sobrien
1005390286Sobrien(define_split
1005490286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1005590286Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "")))
1005690286Sobrien   (clobber (reg:CC 17))]
1005790286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0]))"
1005890286Sobrien  [(set (match_dup 0)
1005990286Sobrien	(abs:SF (match_dup 1)))]
1006090286Sobrien  "")
1006190286Sobrien
1006290286Sobrien(define_split
1006390286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1006490286Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "")))
1006590286Sobrien   (clobber (reg:CC 17))]
1006690286Sobrien  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
1006790286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
1006890286Sobrien	      (clobber (reg:CC 17))])]
1006990286Sobrien  "operands[1] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
1007090286Sobrien   operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
1007190286Sobrien
1007290286Sobrien(define_split
1007390286Sobrien  [(set (match_operand 0 "memory_operand" "")
1007490286Sobrien	(abs (match_operand 1 "memory_operand" "")))
1007590286Sobrien   (clobber (reg:CC 17))]
1007690286Sobrien  "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
1007790286Sobrien  [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
1007890286Sobrien	      (clobber (reg:CC 17))])]
1007990286Sobrien{
1008090286Sobrien  int size = GET_MODE_SIZE (GET_MODE (operands[1]));
1008190286Sobrien
1008290286Sobrien  /* XFmode's size is 12, TFmode 16, but only 10 bytes are used.  */
1008390286Sobrien  if (size >= 12)
1008490286Sobrien    size = 10;
1008590286Sobrien  operands[0] = adjust_address (operands[0], QImode, size - 1);
1008690286Sobrien  operands[1] = GEN_INT (trunc_int_for_mode (~0x80, QImode));
1008790286Sobrien})
1008890286Sobrien
1008990286Sobrien(define_expand "absdf2"
1009090286Sobrien  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
1009190286Sobrien		   (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
1009290286Sobrien	      (clobber (reg:CC 17))])]
1009390286Sobrien  "TARGET_80387"
1009490286Sobrien  "if (TARGET_SSE2)
1009590286Sobrien     {
1009690286Sobrien       /* In case operand is in memory,  we will not use SSE.  */
1009790286Sobrien       if (memory_operand (operands[0], VOIDmode)
1009890286Sobrien	   && rtx_equal_p (operands[0], operands[1]))
1009990286Sobrien	 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
1010090286Sobrien       else
1010190286Sobrien	{
1010290286Sobrien	  /* Using SSE is tricky, since we need bitwise negation of -0
1010390286Sobrien	     in register.  */
1010490286Sobrien	  rtx reg = gen_reg_rtx (DFmode);
1010590286Sobrien#if HOST_BITS_PER_WIDE_INT >= 64
1010690286Sobrien	  rtx imm = GEN_INT (trunc_int_for_mode(((HOST_WIDE_INT)1) << 63,
1010790286Sobrien					        DImode));
1010890286Sobrien#else
1010990286Sobrien	  rtx imm = immed_double_const (0, 0x80000000, DImode);
1011090286Sobrien#endif
1011190286Sobrien	  rtx dest = operands[0];
1011290286Sobrien
1011390286Sobrien	  operands[1] = force_reg (DFmode, operands[1]);
1011490286Sobrien	  operands[0] = force_reg (DFmode, operands[0]);
1011590286Sobrien	  emit_move_insn (reg, gen_lowpart (DFmode, imm));
1011690286Sobrien	  emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
1011790286Sobrien	  if (dest != operands[0])
1011890286Sobrien	    emit_move_insn (dest, operands[0]);
1011990286Sobrien	}
1012090286Sobrien       DONE;
1012190286Sobrien     }
1012290286Sobrien   ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
1012390286Sobrien
1012490286Sobrien(define_insn "absdf2_memory"
1012590286Sobrien  [(set (match_operand:DF 0 "memory_operand" "=m")
1012690286Sobrien	(abs:DF (match_operand:DF 1 "memory_operand" "0")))
1012790286Sobrien   (clobber (reg:CC 17))]
1012890286Sobrien  "ix86_unary_operator_ok (ABS, DFmode, operands)"
1012990286Sobrien  "#")
1013090286Sobrien
1013190286Sobrien(define_insn "absdf2_ifs"
1013290286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr,mr#Yf")
1013390286Sobrien	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0,0")))
1013490286Sobrien   (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y,*g#Y"))
1013590286Sobrien   (clobber (reg:CC 17))]
1013690286Sobrien  "!TARGET_64BIT && TARGET_SSE2
1013790286Sobrien   && (reload_in_progress || reload_completed
1013890286Sobrien       || (register_operand (operands[0], VOIDmode)
1013990286Sobrien	   && register_operand (operands[1], VOIDmode)))"
1014090286Sobrien  "#")
1014190286Sobrien
1014290286Sobrien(define_insn "*absdf2_ifs_rex64"
1014390286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr")
1014490286Sobrien	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0")))
1014590286Sobrien   (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y"))
1014690286Sobrien   (clobber (reg:CC 17))]
1014790286Sobrien  "TARGET_64BIT && TARGET_SSE2
1014890286Sobrien   && (reload_in_progress || reload_completed
1014990286Sobrien       || (register_operand (operands[0], VOIDmode)
1015090286Sobrien	   && register_operand (operands[1], VOIDmode)))"
1015190286Sobrien  "#")
1015290286Sobrien
1015390286Sobrien(define_split
1015490286Sobrien  [(set (match_operand:DF 0 "memory_operand" "")
1015590286Sobrien	(abs:DF (match_operand:DF 1 "memory_operand" "")))
1015690286Sobrien   (use (match_operand:DF 2 "" ""))
1015790286Sobrien   (clobber (reg:CC 17))]
1015890286Sobrien  ""
1015990286Sobrien  [(parallel [(set (match_dup 0)
1016090286Sobrien		   (abs:DF (match_dup 1)))
1016190286Sobrien	      (clobber (reg:CC 17))])])
1016290286Sobrien
1016390286Sobrien(define_split
1016490286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1016590286Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "")))
1016690286Sobrien   (use (match_operand:DF 2 "" ""))
1016790286Sobrien   (clobber (reg:CC 17))]
1016890286Sobrien  "reload_completed && !SSE_REG_P (operands[0])"
1016990286Sobrien  [(parallel [(set (match_dup 0)
1017090286Sobrien		   (abs:DF (match_dup 1)))
1017190286Sobrien	      (clobber (reg:CC 17))])])
1017290286Sobrien
1017390286Sobrien(define_split
1017490286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1017590286Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "")))
1017690286Sobrien   (use (match_operand:DF 2 "register_operand" ""))
1017790286Sobrien   (clobber (reg:CC 17))]
1017890286Sobrien  "reload_completed && SSE_REG_P (operands[0])"
1017990286Sobrien  [(set (subreg:TI (match_dup 0) 0)
1018090286Sobrien	(and:TI (not:TI (subreg:TI (match_dup 2) 0))
1018190286Sobrien		(subreg:TI (match_dup 1) 0)))])
1018290286Sobrien
1018390286Sobrien
1018490286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
1018590286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
1018690286Sobrien;; to itself.
1018790286Sobrien(define_insn "*absdf2_if"
1018890286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
1018990286Sobrien	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
1019090286Sobrien   (clobber (reg:CC 17))]
1019190286Sobrien  "!TARGET_64BIT && TARGET_80387
1019290286Sobrien   && ix86_unary_operator_ok (ABS, DFmode, operands)"
1019390286Sobrien  "#")
1019490286Sobrien
1019590286Sobrien;; FIXME: We should to allow integer registers here.  Problem is that
1019690286Sobrien;; we need another scratch register to get constant from.
1019790286Sobrien;; Forcing constant to mem if no register available in peep2 should be
1019890286Sobrien;; safe even for PIC mode, because of RIP relative addressing.
1019990286Sobrien(define_insn "*absdf2_if_rex64"
1020090286Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
1020190286Sobrien	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
1020290286Sobrien   (clobber (reg:CC 17))]
1020390286Sobrien  "TARGET_64BIT && TARGET_80387
1020490286Sobrien   && ix86_unary_operator_ok (ABS, DFmode, operands)"
1020590286Sobrien  "#")
1020690286Sobrien
1020790286Sobrien(define_split
1020890286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1020990286Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "")))
1021090286Sobrien   (clobber (reg:CC 17))]
1021190286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
1021290286Sobrien  [(set (match_dup 0)
1021390286Sobrien	(abs:DF (match_dup 1)))]
1021490286Sobrien  "")
1021590286Sobrien
1021690286Sobrien(define_split
1021790286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1021890286Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "")))
1021990286Sobrien   (clobber (reg:CC 17))]
1022090286Sobrien  "!TARGET_64BIT && TARGET_80387 && reload_completed &&
1022190286Sobrien   !FP_REGNO_P (REGNO (operands[0]))"
1022290286Sobrien  [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
1022390286Sobrien	      (clobber (reg:CC 17))])]
1022490286Sobrien  "operands[4] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
1022590286Sobrien   split_di (operands+0, 1, operands+2, operands+3);")
1022690286Sobrien
1022790286Sobrien(define_expand "absxf2"
1022890286Sobrien  [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
1022990286Sobrien		   (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
1023090286Sobrien	      (clobber (reg:CC 17))])]
1023190286Sobrien  "!TARGET_64BIT && TARGET_80387"
1023290286Sobrien  "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
1023390286Sobrien
1023490286Sobrien(define_expand "abstf2"
1023590286Sobrien  [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
1023690286Sobrien		   (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
1023790286Sobrien	      (clobber (reg:CC 17))])]
1023890286Sobrien  "TARGET_80387"
1023990286Sobrien  "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
1024090286Sobrien
1024190286Sobrien;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
1024290286Sobrien;; because of secondary memory needed to reload from class FLOAT_INT_REGS
1024390286Sobrien;; to itself.
1024490286Sobrien(define_insn "*absxf2_if"
1024590286Sobrien  [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
1024690286Sobrien	(abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
1024790286Sobrien   (clobber (reg:CC 17))]
1024890286Sobrien  "!TARGET_64BIT && TARGET_80387
1024990286Sobrien   && ix86_unary_operator_ok (ABS, XFmode, operands)"
1025090286Sobrien  "#")
1025190286Sobrien
1025290286Sobrien(define_split
1025390286Sobrien  [(set (match_operand:XF 0 "register_operand" "")
1025490286Sobrien	(abs:XF (match_operand:XF 1 "register_operand" "")))
1025590286Sobrien   (clobber (reg:CC 17))]
1025690286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
1025790286Sobrien  [(set (match_dup 0)
1025890286Sobrien	(abs:XF (match_dup 1)))]
1025990286Sobrien  "")
1026090286Sobrien
1026190286Sobrien(define_split
1026290286Sobrien  [(set (match_operand:XF 0 "register_operand" "")
1026390286Sobrien	(abs:XF (match_operand:XF 1 "register_operand" "")))
1026490286Sobrien   (clobber (reg:CC 17))]
1026590286Sobrien  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
1026690286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
1026790286Sobrien	      (clobber (reg:CC 17))])]
1026890286Sobrien  "operands[1] = GEN_INT (~0x8000);
1026990286Sobrien   operands[0] = gen_rtx_REG (SImode,
1027090286Sobrien			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
1027190286Sobrien
1027290286Sobrien(define_insn "*abstf2_if"
1027390286Sobrien  [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
1027490286Sobrien	(abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
1027590286Sobrien   (clobber (reg:CC 17))]
1027690286Sobrien  "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
1027790286Sobrien  "#")
1027890286Sobrien
1027990286Sobrien(define_split
1028090286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
1028190286Sobrien	(abs:TF (match_operand:TF 1 "register_operand" "")))
1028290286Sobrien   (clobber (reg:CC 17))]
1028390286Sobrien  "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
1028490286Sobrien  [(set (match_dup 0)
1028590286Sobrien	(abs:TF (match_dup 1)))]
1028690286Sobrien  "")
1028790286Sobrien
1028890286Sobrien(define_split
1028990286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
1029090286Sobrien	(abs:TF (match_operand:TF 1 "register_operand" "")))
1029190286Sobrien   (clobber (reg:CC 17))]
1029290286Sobrien  "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
1029390286Sobrien  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
1029490286Sobrien	      (clobber (reg:CC 17))])]
1029590286Sobrien  "operands[1] = GEN_INT (~0x8000);
1029690286Sobrien   operands[0] = gen_rtx_REG (SImode,
1029790286Sobrien			      true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
1029890286Sobrien
1029990286Sobrien(define_insn "*abssf2_1"
1030018334Speter  [(set (match_operand:SF 0 "register_operand" "=f")
1030150650Sobrien	(abs:SF (match_operand:SF 1 "register_operand" "0")))]
1030290286Sobrien  "TARGET_80387 && reload_completed"
1030350650Sobrien  "fabs"
1030490286Sobrien  [(set_attr "type" "fsgn")
1030590286Sobrien   (set_attr "mode" "SF")])
1030618334Speter
1030790286Sobrien(define_insn "*absdf2_1"
1030818334Speter  [(set (match_operand:DF 0 "register_operand" "=f")
1030950650Sobrien	(abs:DF (match_operand:DF 1 "register_operand" "0")))]
1031090286Sobrien  "TARGET_80387 && reload_completed"
1031150650Sobrien  "fabs"
1031290286Sobrien  [(set_attr "type" "fsgn")
1031390286Sobrien   (set_attr "mode" "DF")])
1031418334Speter
1031590286Sobrien(define_insn "*absextendsfdf2"
1031618334Speter  [(set (match_operand:DF 0 "register_operand" "=f")
1031790286Sobrien	(abs:DF (float_extend:DF
1031890286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
1031918334Speter  "TARGET_80387"
1032050650Sobrien  "fabs"
1032190286Sobrien  [(set_attr "type" "fsgn")
1032290286Sobrien   (set_attr "mode" "DF")])
1032318334Speter
1032490286Sobrien(define_insn "*absxf2_1"
1032518334Speter  [(set (match_operand:XF 0 "register_operand" "=f")
1032650650Sobrien	(abs:XF (match_operand:XF 1 "register_operand" "0")))]
1032790286Sobrien  "!TARGET_64BIT && TARGET_80387 && reload_completed"
1032850650Sobrien  "fabs"
1032990286Sobrien  [(set_attr "type" "fsgn")
1033090286Sobrien   (set_attr "mode" "DF")])
1033118334Speter
1033290286Sobrien(define_insn "*absextenddfxf2"
1033318334Speter  [(set (match_operand:XF 0 "register_operand" "=f")
1033490286Sobrien	(abs:XF (float_extend:XF
1033590286Sobrien	  (match_operand:DF 1 "register_operand" "0"))))]
1033690286Sobrien  "!TARGET_64BIT && TARGET_80387"
1033750650Sobrien  "fabs"
1033890286Sobrien  [(set_attr "type" "fsgn")
1033990286Sobrien   (set_attr "mode" "XF")])
1034018334Speter
1034190286Sobrien(define_insn "*absextendsfxf2"
1034290286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1034390286Sobrien	(abs:XF (float_extend:XF
1034490286Sobrien	  (match_operand:SF 1 "register_operand" "0"))))]
1034590286Sobrien  "!TARGET_64BIT && TARGET_80387"
1034690286Sobrien  "fabs"
1034790286Sobrien  [(set_attr "type" "fsgn")
1034890286Sobrien   (set_attr "mode" "XF")])
1034918334Speter
1035090286Sobrien(define_insn "*abstf2_1"
1035190286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1035290286Sobrien	(abs:TF (match_operand:TF 1 "register_operand" "0")))]
1035390286Sobrien  "TARGET_80387 && reload_completed"
1035490286Sobrien  "fabs"
1035590286Sobrien  [(set_attr "type" "fsgn")
1035690286Sobrien   (set_attr "mode" "DF")])
1035718334Speter
1035890286Sobrien(define_insn "*absextenddftf2"
1035990286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1036090286Sobrien	(abs:TF (float_extend:TF
1036190286Sobrien	  (match_operand:DF 1 "register_operand" "0"))))]
1036290286Sobrien  "TARGET_80387"
1036390286Sobrien  "fabs"
1036490286Sobrien  [(set_attr "type" "fsgn")
1036590286Sobrien   (set_attr "mode" "XF")])
1036618334Speter
1036790286Sobrien(define_insn "*absextendsftf2"
1036890286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1036990286Sobrien	(abs:TF (float_extend:TF
1037090286Sobrien	  (match_operand:SF 1 "register_operand" "0"))))]
1037190286Sobrien  "TARGET_80387"
1037290286Sobrien  "fabs"
1037390286Sobrien  [(set_attr "type" "fsgn")
1037490286Sobrien   (set_attr "mode" "XF")])
1037590286Sobrien
1037690286Sobrien;; One complement instructions
1037718334Speter
1037890286Sobrien(define_expand "one_cmpldi2"
1037990286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1038090286Sobrien	(not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
1038190286Sobrien  "TARGET_64BIT"
1038290286Sobrien  "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
1038318334Speter
1038490286Sobrien(define_insn "*one_cmpldi2_1_rex64"
1038590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1038690286Sobrien	(not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
1038790286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
1038890286Sobrien  "not{q}\t%0"
1038990286Sobrien  [(set_attr "type" "negnot")
1039090286Sobrien   (set_attr "mode" "DI")])
1039118334Speter
1039290286Sobrien(define_insn "*one_cmpldi2_2_rex64"
1039390286Sobrien  [(set (reg 17)
1039490286Sobrien	(compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
1039590286Sobrien		 (const_int 0)))
1039690286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1039790286Sobrien	(not:DI (match_dup 1)))]
1039890286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
1039990286Sobrien   && ix86_unary_operator_ok (NOT, DImode, operands)"
1040090286Sobrien  "#"
1040190286Sobrien  [(set_attr "type" "alu1")
1040290286Sobrien   (set_attr "mode" "DI")])
1040318334Speter
1040490286Sobrien(define_split
1040590286Sobrien  [(set (reg 17)
1040690286Sobrien	(compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
1040790286Sobrien		 (const_int 0)))
1040890286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "")
1040990286Sobrien	(not:DI (match_dup 1)))]
1041090286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
1041190286Sobrien  [(parallel [(set (reg:CCNO 17)
1041290286Sobrien		   (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
1041390286Sobrien				 (const_int 0)))
1041490286Sobrien	      (set (match_dup 0)
1041590286Sobrien		   (xor:DI (match_dup 1) (const_int -1)))])]
1041690286Sobrien  "")
1041718334Speter
1041890286Sobrien(define_expand "one_cmplsi2"
1041990286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1042090286Sobrien	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
1042190286Sobrien  ""
1042290286Sobrien  "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
1042318334Speter
1042490286Sobrien(define_insn "*one_cmplsi2_1"
1042590286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1042690286Sobrien	(not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
1042790286Sobrien  "ix86_unary_operator_ok (NOT, SImode, operands)"
1042890286Sobrien  "not{l}\t%0"
1042990286Sobrien  [(set_attr "type" "negnot")
1043090286Sobrien   (set_attr "mode" "SI")])
1043118334Speter
1043290286Sobrien;; ??? Currently never generated - xor is used instead.
1043390286Sobrien(define_insn "*one_cmplsi2_1_zext"
1043490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1043590286Sobrien	(zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
1043690286Sobrien  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
1043790286Sobrien  "not{l}\t%k0"
1043890286Sobrien  [(set_attr "type" "negnot")
1043990286Sobrien   (set_attr "mode" "SI")])
1044018334Speter
1044190286Sobrien(define_insn "*one_cmplsi2_2"
1044290286Sobrien  [(set (reg 17)
1044390286Sobrien	(compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
1044490286Sobrien		 (const_int 0)))
1044590286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1044690286Sobrien	(not:SI (match_dup 1)))]
1044790286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
1044890286Sobrien   && ix86_unary_operator_ok (NOT, SImode, operands)"
1044990286Sobrien  "#"
1045090286Sobrien  [(set_attr "type" "alu1")
1045190286Sobrien   (set_attr "mode" "SI")])
1045218334Speter
1045390286Sobrien(define_split
1045490286Sobrien  [(set (reg 17)
1045590286Sobrien	(compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
1045690286Sobrien		 (const_int 0)))
1045790286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "")
1045890286Sobrien	(not:SI (match_dup 1)))]
1045990286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
1046090286Sobrien  [(parallel [(set (reg:CCNO 17)
1046190286Sobrien		   (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
1046290286Sobrien				 (const_int 0)))
1046390286Sobrien	      (set (match_dup 0)
1046490286Sobrien		   (xor:SI (match_dup 1) (const_int -1)))])]
1046590286Sobrien  "")
1046618334Speter
1046790286Sobrien;; ??? Currently never generated - xor is used instead.
1046890286Sobrien(define_insn "*one_cmplsi2_2_zext"
1046990286Sobrien  [(set (reg 17)
1047090286Sobrien	(compare (not:SI (match_operand:SI 1 "register_operand" "0"))
1047190286Sobrien		 (const_int 0)))
1047290286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1047390286Sobrien	(zero_extend:DI (not:SI (match_dup 1))))]
1047490286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
1047590286Sobrien   && ix86_unary_operator_ok (NOT, SImode, operands)"
1047690286Sobrien  "#"
1047790286Sobrien  [(set_attr "type" "alu1")
1047890286Sobrien   (set_attr "mode" "SI")])
1047918334Speter
1048090286Sobrien(define_split
1048190286Sobrien  [(set (reg 17)
1048290286Sobrien	(compare (not:SI (match_operand:SI 1 "register_operand" ""))
1048390286Sobrien		 (const_int 0)))
1048490286Sobrien   (set (match_operand:DI 0 "register_operand" "")
1048590286Sobrien	(zero_extend:DI (not:SI (match_dup 1))))]
1048690286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
1048790286Sobrien  [(parallel [(set (reg:CCNO 17)
1048890286Sobrien		   (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
1048990286Sobrien				 (const_int 0)))
1049090286Sobrien	      (set (match_dup 0)
1049190286Sobrien		   (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
1049290286Sobrien  "")
1049318334Speter
1049490286Sobrien(define_expand "one_cmplhi2"
1049590286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1049690286Sobrien	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
1049790286Sobrien  "TARGET_HIMODE_MATH"
1049890286Sobrien  "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
1049952296Sobrien
1050090286Sobrien(define_insn "*one_cmplhi2_1"
1050150650Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1050250650Sobrien	(not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
1050390286Sobrien  "ix86_unary_operator_ok (NOT, HImode, operands)"
1050490286Sobrien  "not{w}\t%0"
1050590286Sobrien  [(set_attr "type" "negnot")
1050690286Sobrien   (set_attr "mode" "HI")])
1050718334Speter
1050890286Sobrien(define_insn "*one_cmplhi2_2"
1050990286Sobrien  [(set (reg 17)
1051090286Sobrien	(compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
1051190286Sobrien		 (const_int 0)))
1051290286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1051390286Sobrien	(not:HI (match_dup 1)))]
1051490286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
1051590286Sobrien   && ix86_unary_operator_ok (NEG, HImode, operands)"
1051690286Sobrien  "#"
1051790286Sobrien  [(set_attr "type" "alu1")
1051890286Sobrien   (set_attr "mode" "HI")])
1051952296Sobrien
1052090286Sobrien(define_split
1052190286Sobrien  [(set (reg 17)
1052290286Sobrien	(compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
1052390286Sobrien		 (const_int 0)))
1052490286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "")
1052590286Sobrien	(not:HI (match_dup 1)))]
1052690286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
1052790286Sobrien  [(parallel [(set (reg:CCNO 17)
1052890286Sobrien		   (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
1052990286Sobrien		      		 (const_int 0)))
1053090286Sobrien	      (set (match_dup 0)
1053190286Sobrien		   (xor:HI (match_dup 1) (const_int -1)))])]
1053290286Sobrien  "")
1053352296Sobrien
1053490286Sobrien;; %%% Potential partial reg stall on alternative 1.  What to do?
1053590286Sobrien(define_expand "one_cmplqi2"
1053690286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1053790286Sobrien	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
1053890286Sobrien  "TARGET_QIMODE_MATH"
1053990286Sobrien  "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
1054090286Sobrien
1054190286Sobrien(define_insn "*one_cmplqi2_1"
1054290286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
1054390286Sobrien	(not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
1054490286Sobrien  "ix86_unary_operator_ok (NOT, QImode, operands)"
1054590286Sobrien  "@
1054690286Sobrien   not{b}\t%0
1054790286Sobrien   not{l}\t%k0"
1054890286Sobrien  [(set_attr "type" "negnot")
1054990286Sobrien   (set_attr "mode" "QI,SI")])
1055090286Sobrien
1055190286Sobrien(define_insn "*one_cmplqi2_2"
1055290286Sobrien  [(set (reg 17)
1055390286Sobrien	(compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
1055490286Sobrien		 (const_int 0)))
1055590286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1055690286Sobrien	(not:QI (match_dup 1)))]
1055790286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
1055890286Sobrien   && ix86_unary_operator_ok (NOT, QImode, operands)"
1055990286Sobrien  "#"
1056090286Sobrien  [(set_attr "type" "alu1")
1056190286Sobrien   (set_attr "mode" "QI")])
1056290286Sobrien
1056390286Sobrien(define_split
1056490286Sobrien  [(set (reg 17)
1056590286Sobrien	(compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
1056690286Sobrien		 (const_int 0)))
1056790286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "")
1056890286Sobrien	(not:QI (match_dup 1)))]
1056990286Sobrien  "ix86_match_ccmode (insn, CCNOmode)"
1057090286Sobrien  [(parallel [(set (reg:CCNO 17)
1057190286Sobrien		   (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
1057290286Sobrien		      		 (const_int 0)))
1057390286Sobrien	      (set (match_dup 0)
1057490286Sobrien		   (xor:QI (match_dup 1) (const_int -1)))])]
1057590286Sobrien  "")
1057618334Speter
1057790286Sobrien;; Arithmetic shift instructions
1057818334Speter
1057918334Speter;; DImode shifts are implemented using the i386 "shift double" opcode,
1058018334Speter;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
1058118334Speter;; is variable, then the count is in %cl and the "imm" operand is dropped
1058218334Speter;; from the assembler input.
1058390286Sobrien;;
1058418334Speter;; This instruction shifts the target reg/mem as usual, but instead of
1058518334Speter;; shifting in zeros, bits are shifted in from reg operand.  If the insn
1058618334Speter;; is a left shift double, bits are taken from the high order bits of
1058718334Speter;; reg, else if the insn is a shift right double, bits are taken from the
1058818334Speter;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
1058918334Speter;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
1059090286Sobrien;;
1059118334Speter;; Since sh[lr]d does not change the `reg' operand, that is done
1059218334Speter;; separately, making all shifts emit pairs of shift double and normal
1059318334Speter;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
1059418334Speter;; support a 63 bit shift, each shift where the count is in a reg expands
1059550650Sobrien;; to a pair of shifts, a branch, a shift by 32 and a label.
1059690286Sobrien;;
1059718334Speter;; If the shift count is a constant, we need never emit more than one
1059818334Speter;; shift pair, instead using moves and sign extension for counts greater
1059918334Speter;; than 31.
1060018334Speter
1060118334Speter(define_expand "ashldi3"
1060290286Sobrien  [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
1060390286Sobrien		   (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
1060490286Sobrien			      (match_operand:QI 2 "nonmemory_operand" "")))
1060590286Sobrien	      (clobber (reg:CC 17))])]
1060618334Speter  ""
1060718334Speter{
1060890286Sobrien  if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
1060918334Speter    {
1061090286Sobrien      emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
1061190286Sobrien      DONE;
1061218334Speter    }
1061390286Sobrien  ix86_expand_binary_operator (ASHIFT, DImode, operands);
1061418334Speter  DONE;
1061590286Sobrien})
1061618334Speter
1061790286Sobrien(define_insn "*ashldi3_1_rex64"
1061890286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
1061990286Sobrien	(ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
1062090286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
1062190286Sobrien   (clobber (reg:CC 17))]
1062290286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
1062318334Speter{
1062490286Sobrien  switch (get_attr_type (insn))
1062590286Sobrien    {
1062690286Sobrien    case TYPE_ALU:
1062790286Sobrien      if (operands[2] != const1_rtx)
1062890286Sobrien	abort ();
1062990286Sobrien      if (!rtx_equal_p (operands[0], operands[1]))
1063090286Sobrien	abort ();
1063190286Sobrien      return "add{q}\t{%0, %0|%0, %0}";
1063218334Speter
1063390286Sobrien    case TYPE_LEA:
1063490286Sobrien      if (GET_CODE (operands[2]) != CONST_INT
1063590286Sobrien	  || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
1063690286Sobrien	abort ();
1063790286Sobrien      operands[1] = gen_rtx_MULT (DImode, operands[1],
1063890286Sobrien				  GEN_INT (1 << INTVAL (operands[2])));
1063990286Sobrien      return "lea{q}\t{%a1, %0|%0, %a1}";
1064018334Speter
1064190286Sobrien    default:
1064290286Sobrien      if (REG_P (operands[2]))
1064390286Sobrien	return "sal{q}\t{%b2, %0|%0, %b2}";
1064490286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1064590286Sobrien	       && INTVAL (operands[2]) == 1
1064690286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1064790286Sobrien	return "sal{q}\t%0";
1064890286Sobrien      else
1064990286Sobrien	return "sal{q}\t{%2, %0|%0, %2}";
1065090286Sobrien    }
1065190286Sobrien}
1065290286Sobrien  [(set (attr "type")
1065390286Sobrien     (cond [(eq_attr "alternative" "1")
1065490286Sobrien	      (const_string "lea")
1065590286Sobrien            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1065690286Sobrien		          (const_int 0))
1065790286Sobrien		      (match_operand 0 "register_operand" ""))
1065890286Sobrien		 (match_operand 2 "const1_operand" ""))
1065990286Sobrien	      (const_string "alu")
1066090286Sobrien	   ]
1066190286Sobrien	   (const_string "ishift")))
1066290286Sobrien   (set_attr "mode" "DI")])
1066318334Speter
1066490286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
1066590286Sobrien(define_split
1066690286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1066790286Sobrien	(ashift:DI (match_operand:DI 1 "register_operand" "")
1066890286Sobrien		   (match_operand:QI 2 "immediate_operand" "")))
1066990286Sobrien   (clobber (reg:CC 17))]
1067090286Sobrien  "TARGET_64BIT && reload_completed
1067190286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
1067290286Sobrien  [(set (match_dup 0)
1067390286Sobrien	(mult:DI (match_dup 1)
1067490286Sobrien		 (match_dup 2)))]
1067590286Sobrien  "operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
1067690286Sobrien					      DImode));")
1067790286Sobrien
1067890286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1067990286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1068090286Sobrien;; zero are optimized away.
1068190286Sobrien(define_insn "*ashldi3_cmp_rex64"
1068290286Sobrien  [(set (reg 17)
1068390286Sobrien	(compare
1068490286Sobrien	  (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1068590286Sobrien		     (match_operand:QI 2 "immediate_operand" "e"))
1068690286Sobrien	  (const_int 0)))
1068790286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1068890286Sobrien	(ashift:DI (match_dup 1) (match_dup 2)))]
1068990286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1069090286Sobrien   && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
1069190286Sobrien{
1069290286Sobrien  switch (get_attr_type (insn))
1069318334Speter    {
1069490286Sobrien    case TYPE_ALU:
1069590286Sobrien      if (operands[2] != const1_rtx)
1069690286Sobrien	abort ();
1069790286Sobrien      return "add{q}\t{%0, %0|%0, %0}";
1069818334Speter
1069990286Sobrien    default:
1070090286Sobrien      if (REG_P (operands[2]))
1070190286Sobrien	return "sal{q}\t{%b2, %0|%0, %b2}";
1070290286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1070390286Sobrien	       && INTVAL (operands[2]) == 1
1070490286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1070590286Sobrien	return "sal{q}\t%0";
1070690286Sobrien      else
1070790286Sobrien	return "sal{q}\t{%2, %0|%0, %2}";
1070818334Speter    }
1070990286Sobrien}
1071090286Sobrien  [(set (attr "type")
1071190286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1071290286Sobrien		          (const_int 0))
1071390286Sobrien		      (match_operand 0 "register_operand" ""))
1071490286Sobrien		 (match_operand 2 "const1_operand" ""))
1071590286Sobrien	      (const_string "alu")
1071690286Sobrien	   ]
1071790286Sobrien	   (const_string "ishift")))
1071890286Sobrien   (set_attr "mode" "DI")])
1071918334Speter
1072090286Sobrien(define_insn "ashldi3_1"
1072190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1072218334Speter	(ashift:DI (match_operand:DI 1 "register_operand" "0")
1072390286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "Jc")))
1072490286Sobrien   (clobber (match_scratch:SI 3 "=&r"))
1072590286Sobrien   (clobber (reg:CC 17))]
1072690286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1072790286Sobrien  "#"
1072890286Sobrien  [(set_attr "type" "multi")])
1072990286Sobrien
1073090286Sobrien(define_insn "*ashldi3_2"
1073190286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1073290286Sobrien	(ashift:DI (match_operand:DI 1 "register_operand" "0")
1073390286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "Jc")))
1073490286Sobrien   (clobber (reg:CC 17))]
1073590286Sobrien  "!TARGET_64BIT"
1073690286Sobrien  "#"
1073790286Sobrien  [(set_attr "type" "multi")])
1073890286Sobrien
1073990286Sobrien(define_split
1074090286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1074190286Sobrien	(ashift:DI (match_operand:DI 1 "register_operand" "")
1074290286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1074390286Sobrien   (clobber (match_scratch:SI 3 ""))
1074490286Sobrien   (clobber (reg:CC 17))]
1074590286Sobrien  "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
1074690286Sobrien  [(const_int 0)]
1074790286Sobrien  "ix86_split_ashldi (operands, operands[3]); DONE;")
1074890286Sobrien
1074990286Sobrien(define_split
1075090286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1075190286Sobrien	(ashift:DI (match_operand:DI 1 "register_operand" "")
1075290286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1075390286Sobrien   (clobber (reg:CC 17))]
1075490286Sobrien  "!TARGET_64BIT && reload_completed"
1075590286Sobrien  [(const_int 0)]
1075690286Sobrien  "ix86_split_ashldi (operands, NULL_RTX); DONE;")
1075790286Sobrien
1075890286Sobrien(define_insn "x86_shld_1"
1075990286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
1076090286Sobrien        (ior:SI (ashift:SI (match_dup 0)
1076190286Sobrien		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
1076290286Sobrien		(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
1076390286Sobrien		  (minus:QI (const_int 32) (match_dup 2)))))
1076490286Sobrien   (clobber (reg:CC 17))]
1076518334Speter  ""
1076690286Sobrien  "@
1076790286Sobrien   shld{l}\t{%2, %1, %0|%0, %1, %2}
1076890286Sobrien   shld{l}\t{%s2%1, %0|%0, %1, %2}"
1076990286Sobrien  [(set_attr "type" "ishift")
1077090286Sobrien   (set_attr "prefix_0f" "1")
1077190286Sobrien   (set_attr "mode" "SI")
1077290286Sobrien   (set_attr "pent_pair" "np")
1077390286Sobrien   (set_attr "athlon_decode" "vector")
1077490286Sobrien   (set_attr "ppro_uops" "few")])
1077590286Sobrien
1077690286Sobrien(define_expand "x86_shift_adj_1"
1077790286Sobrien  [(set (reg:CCZ 17)
1077890286Sobrien	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
1077990286Sobrien			     (const_int 32))
1078090286Sobrien		     (const_int 0)))
1078190286Sobrien   (set (match_operand:SI 0 "register_operand" "")
1078290286Sobrien        (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
1078390286Sobrien			 (match_operand:SI 1 "register_operand" "")
1078490286Sobrien			 (match_dup 0)))
1078590286Sobrien   (set (match_dup 1)
1078690286Sobrien	(if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
1078790286Sobrien			 (match_operand:SI 3 "register_operand" "r")
1078890286Sobrien			 (match_dup 1)))]
1078990286Sobrien  "TARGET_CMOVE"
1079090286Sobrien  "")
1079190286Sobrien
1079290286Sobrien(define_expand "x86_shift_adj_2"
1079390286Sobrien  [(use (match_operand:SI 0 "register_operand" ""))
1079490286Sobrien   (use (match_operand:SI 1 "register_operand" ""))
1079590286Sobrien   (use (match_operand:QI 2 "register_operand" ""))]
1079690286Sobrien  ""
1079718334Speter{
1079890286Sobrien  rtx label = gen_label_rtx ();
1079990286Sobrien  rtx tmp;
1080018334Speter
1080190286Sobrien  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
1080218334Speter
1080390286Sobrien  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
1080490286Sobrien  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1080590286Sobrien  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
1080690286Sobrien			      gen_rtx_LABEL_REF (VOIDmode, label),
1080790286Sobrien			      pc_rtx);
1080890286Sobrien  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
1080990286Sobrien  JUMP_LABEL (tmp) = label;
1081018334Speter
1081190286Sobrien  emit_move_insn (operands[0], operands[1]);
1081290286Sobrien  emit_move_insn (operands[1], const0_rtx);
1081318334Speter
1081490286Sobrien  emit_label (label);
1081590286Sobrien  LABEL_NUSES (label) = 1;
1081690286Sobrien
1081790286Sobrien  DONE;
1081890286Sobrien})
1081990286Sobrien
1082052296Sobrien(define_expand "ashlsi3"
1082152296Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1082252296Sobrien	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
1082390286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1082490286Sobrien   (clobber (reg:CC 17))]
1082552296Sobrien  ""
1082690286Sobrien  "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
1082718334Speter
1082890286Sobrien(define_insn "*ashlsi3_1"
1082990286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
1083090286Sobrien	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
1083190286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
1083290286Sobrien   (clobber (reg:CC 17))]
1083390286Sobrien  "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
1083490286Sobrien{
1083590286Sobrien  switch (get_attr_type (insn))
1083690286Sobrien    {
1083790286Sobrien    case TYPE_ALU:
1083890286Sobrien      if (operands[2] != const1_rtx)
1083990286Sobrien	abort ();
1084090286Sobrien      if (!rtx_equal_p (operands[0], operands[1]))
1084190286Sobrien	abort ();
1084290286Sobrien      return "add{l}\t{%0, %0|%0, %0}";
1084390286Sobrien
1084490286Sobrien    case TYPE_LEA:
1084590286Sobrien      return "#";
1084690286Sobrien
1084790286Sobrien    default:
1084890286Sobrien      if (REG_P (operands[2]))
1084990286Sobrien	return "sal{l}\t{%b2, %0|%0, %b2}";
1085090286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1085190286Sobrien	       && INTVAL (operands[2]) == 1
1085290286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1085390286Sobrien	return "sal{l}\t%0";
1085490286Sobrien      else
1085590286Sobrien	return "sal{l}\t{%2, %0|%0, %2}";
1085690286Sobrien    }
1085790286Sobrien}
1085890286Sobrien  [(set (attr "type")
1085990286Sobrien     (cond [(eq_attr "alternative" "1")
1086090286Sobrien	      (const_string "lea")
1086190286Sobrien            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1086290286Sobrien		          (const_int 0))
1086390286Sobrien		      (match_operand 0 "register_operand" ""))
1086490286Sobrien		 (match_operand 2 "const1_operand" ""))
1086590286Sobrien	      (const_string "alu")
1086690286Sobrien	   ]
1086790286Sobrien	   (const_string "ishift")))
1086890286Sobrien   (set_attr "mode" "SI")])
1086990286Sobrien
1087090286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
1087190286Sobrien(define_split
1087290286Sobrien  [(set (match_operand 0 "register_operand" "")
1087390286Sobrien	(ashift (match_operand 1 "register_operand" "")
1087490286Sobrien                (match_operand:QI 2 "const_int_operand" "")))
1087590286Sobrien   (clobber (reg:CC 17))]
1087690286Sobrien  "reload_completed
1087790286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
1087890286Sobrien  [(const_int 0)]
1087990286Sobrien{
1088090286Sobrien  rtx pat;
1088190286Sobrien  operands[0] = gen_lowpart (SImode, operands[0]);
1088290286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
1088390286Sobrien  operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
1088490286Sobrien					     Pmode));
1088590286Sobrien  pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
1088690286Sobrien  if (Pmode != SImode)
1088790286Sobrien    pat = gen_rtx_SUBREG (SImode, pat, 0);
1088890286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
1088990286Sobrien  DONE;
1089090286Sobrien})
1089190286Sobrien
1089290286Sobrien(define_insn "*ashlsi3_1_zext"
1089390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1089490286Sobrien	(zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
1089590286Sobrien			(match_operand:QI 2 "nonmemory_operand" "cI,M"))))
1089690286Sobrien   (clobber (reg:CC 17))]
1089790286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
1089890286Sobrien{
1089990286Sobrien  switch (get_attr_type (insn))
1090090286Sobrien    {
1090190286Sobrien    case TYPE_ALU:
1090290286Sobrien      if (operands[2] != const1_rtx)
1090390286Sobrien	abort ();
1090490286Sobrien      return "add{l}\t{%k0, %k0|%k0, %k0}";
1090590286Sobrien
1090690286Sobrien    case TYPE_LEA:
1090790286Sobrien      return "#";
1090890286Sobrien
1090990286Sobrien    default:
1091090286Sobrien      if (REG_P (operands[2]))
1091190286Sobrien	return "sal{l}\t{%b2, %k0|%k0, %b2}";
1091290286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1091390286Sobrien	       && INTVAL (operands[2]) == 1
1091490286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1091590286Sobrien	return "sal{l}\t%k0";
1091690286Sobrien      else
1091790286Sobrien	return "sal{l}\t{%2, %k0|%k0, %2}";
1091890286Sobrien    }
1091990286Sobrien}
1092090286Sobrien  [(set (attr "type")
1092190286Sobrien     (cond [(eq_attr "alternative" "1")
1092290286Sobrien	      (const_string "lea")
1092390286Sobrien            (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1092490286Sobrien		     (const_int 0))
1092590286Sobrien		 (match_operand 2 "const1_operand" ""))
1092690286Sobrien	      (const_string "alu")
1092790286Sobrien	   ]
1092890286Sobrien	   (const_string "ishift")))
1092990286Sobrien   (set_attr "mode" "SI")])
1093090286Sobrien
1093190286Sobrien;; Convert lea to the lea pattern to avoid flags dependency.
1093290286Sobrien(define_split
1093390286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1093490286Sobrien	(zero_extend:DI (ashift (match_operand 1 "register_operand" "")
1093590286Sobrien				(match_operand:QI 2 "const_int_operand" ""))))
1093690286Sobrien   (clobber (reg:CC 17))]
1093790286Sobrien  "reload_completed
1093890286Sobrien   && true_regnum (operands[0]) != true_regnum (operands[1])"
1093990286Sobrien  [(set (match_dup 0) (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
1094090286Sobrien{
1094190286Sobrien  operands[1] = gen_lowpart (Pmode, operands[1]);
1094290286Sobrien  operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
1094390286Sobrien					     Pmode));
1094490286Sobrien})
1094590286Sobrien
1094690286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1094790286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1094890286Sobrien;; zero are optimized away.
1094990286Sobrien(define_insn "*ashlsi3_cmp"
1095090286Sobrien  [(set (reg 17)
1095190286Sobrien	(compare
1095290286Sobrien	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10953102802Skan		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
1095490286Sobrien	  (const_int 0)))
1095590286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1095690286Sobrien	(ashift:SI (match_dup 1) (match_dup 2)))]
1095790286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1095890286Sobrien   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
1095990286Sobrien{
1096090286Sobrien  switch (get_attr_type (insn))
1096190286Sobrien    {
1096290286Sobrien    case TYPE_ALU:
1096390286Sobrien      if (operands[2] != const1_rtx)
1096490286Sobrien	abort ();
1096590286Sobrien      return "add{l}\t{%0, %0|%0, %0}";
1096690286Sobrien
1096790286Sobrien    default:
1096890286Sobrien      if (REG_P (operands[2]))
1096990286Sobrien	return "sal{l}\t{%b2, %0|%0, %b2}";
1097090286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1097190286Sobrien	       && INTVAL (operands[2]) == 1
1097290286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1097390286Sobrien	return "sal{l}\t%0";
1097490286Sobrien      else
1097590286Sobrien	return "sal{l}\t{%2, %0|%0, %2}";
1097690286Sobrien    }
1097790286Sobrien}
1097890286Sobrien  [(set (attr "type")
1097990286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1098090286Sobrien		          (const_int 0))
1098190286Sobrien		      (match_operand 0 "register_operand" ""))
1098290286Sobrien		 (match_operand 2 "const1_operand" ""))
1098390286Sobrien	      (const_string "alu")
1098490286Sobrien	   ]
1098590286Sobrien	   (const_string "ishift")))
1098690286Sobrien   (set_attr "mode" "SI")])
1098790286Sobrien
1098890286Sobrien(define_insn "*ashlsi3_cmp_zext"
1098990286Sobrien  [(set (reg 17)
1099090286Sobrien	(compare
1099190286Sobrien	  (ashift:SI (match_operand:SI 1 "register_operand" "0")
10992102802Skan		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
1099390286Sobrien	  (const_int 0)))
1099490286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1099590286Sobrien	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
1099690286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1099790286Sobrien   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
1099890286Sobrien{
1099990286Sobrien  switch (get_attr_type (insn))
1100090286Sobrien    {
1100190286Sobrien    case TYPE_ALU:
1100290286Sobrien      if (operands[2] != const1_rtx)
1100390286Sobrien	abort ();
1100490286Sobrien      return "add{l}\t{%k0, %k0|%k0, %k0}";
1100590286Sobrien
1100690286Sobrien    default:
1100790286Sobrien      if (REG_P (operands[2]))
1100890286Sobrien	return "sal{l}\t{%b2, %k0|%k0, %b2}";
1100990286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1101090286Sobrien	       && INTVAL (operands[2]) == 1
1101190286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1101290286Sobrien	return "sal{l}\t%k0";
1101390286Sobrien      else
1101490286Sobrien	return "sal{l}\t{%2, %k0|%k0, %2}";
1101590286Sobrien    }
1101690286Sobrien}
1101790286Sobrien  [(set (attr "type")
1101890286Sobrien     (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1101990286Sobrien		     (const_int 0))
1102090286Sobrien		 (match_operand 2 "const1_operand" ""))
1102190286Sobrien	      (const_string "alu")
1102290286Sobrien	   ]
1102390286Sobrien	   (const_string "ishift")))
1102490286Sobrien   (set_attr "mode" "SI")])
1102590286Sobrien
1102652296Sobrien(define_expand "ashlhi3"
1102752296Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1102852296Sobrien	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
1102990286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1103090286Sobrien   (clobber (reg:CC 17))]
1103190286Sobrien  "TARGET_HIMODE_MATH"
1103290286Sobrien  "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
1103318334Speter
1103490286Sobrien(define_insn "*ashlhi3_1_lea"
1103590286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
1103690286Sobrien	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
1103790286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
1103890286Sobrien   (clobber (reg:CC 17))]
1103990286Sobrien  "!TARGET_PARTIAL_REG_STALL
1104090286Sobrien   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
1104190286Sobrien{
1104290286Sobrien  switch (get_attr_type (insn))
1104390286Sobrien    {
1104490286Sobrien    case TYPE_LEA:
1104590286Sobrien      return "#";
1104690286Sobrien    case TYPE_ALU:
1104790286Sobrien      if (operands[2] != const1_rtx)
1104890286Sobrien	abort ();
1104990286Sobrien      return "add{w}\t{%0, %0|%0, %0}";
1105090286Sobrien
1105190286Sobrien    default:
1105290286Sobrien      if (REG_P (operands[2]))
1105390286Sobrien	return "sal{w}\t{%b2, %0|%0, %b2}";
1105490286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1105590286Sobrien	       && INTVAL (operands[2]) == 1
1105690286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1105790286Sobrien	return "sal{w}\t%0";
1105890286Sobrien      else
1105990286Sobrien	return "sal{w}\t{%2, %0|%0, %2}";
1106090286Sobrien    }
1106190286Sobrien}
1106290286Sobrien  [(set (attr "type")
1106390286Sobrien     (cond [(eq_attr "alternative" "1")
1106490286Sobrien	      (const_string "lea")
1106590286Sobrien            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1106690286Sobrien		          (const_int 0))
1106790286Sobrien		      (match_operand 0 "register_operand" ""))
1106890286Sobrien		 (match_operand 2 "const1_operand" ""))
1106990286Sobrien	      (const_string "alu")
1107090286Sobrien	   ]
1107190286Sobrien	   (const_string "ishift")))
1107290286Sobrien   (set_attr "mode" "HI,SI")])
1107390286Sobrien
1107490286Sobrien(define_insn "*ashlhi3_1"
1107590286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1107690286Sobrien	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1107790286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI")))
1107890286Sobrien   (clobber (reg:CC 17))]
1107990286Sobrien  "TARGET_PARTIAL_REG_STALL
1108090286Sobrien   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
1108190286Sobrien{
1108290286Sobrien  switch (get_attr_type (insn))
1108390286Sobrien    {
1108490286Sobrien    case TYPE_ALU:
1108590286Sobrien      if (operands[2] != const1_rtx)
1108690286Sobrien	abort ();
1108790286Sobrien      return "add{w}\t{%0, %0|%0, %0}";
1108890286Sobrien
1108990286Sobrien    default:
1109090286Sobrien      if (REG_P (operands[2]))
1109190286Sobrien	return "sal{w}\t{%b2, %0|%0, %b2}";
1109290286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1109390286Sobrien	       && INTVAL (operands[2]) == 1
1109490286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1109590286Sobrien	return "sal{w}\t%0";
1109690286Sobrien      else
1109790286Sobrien	return "sal{w}\t{%2, %0|%0, %2}";
1109890286Sobrien    }
1109990286Sobrien}
1110090286Sobrien  [(set (attr "type")
1110190286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1110290286Sobrien		          (const_int 0))
1110390286Sobrien		      (match_operand 0 "register_operand" ""))
1110490286Sobrien		 (match_operand 2 "const1_operand" ""))
1110590286Sobrien	      (const_string "alu")
1110690286Sobrien	   ]
1110790286Sobrien	   (const_string "ishift")))
1110890286Sobrien   (set_attr "mode" "HI")])
1110990286Sobrien
1111090286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1111190286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1111290286Sobrien;; zero are optimized away.
1111390286Sobrien(define_insn "*ashlhi3_cmp"
1111490286Sobrien  [(set (reg 17)
1111590286Sobrien	(compare
1111690286Sobrien	  (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11117102802Skan		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
1111890286Sobrien	  (const_int 0)))
1111990286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1112090286Sobrien	(ashift:HI (match_dup 1) (match_dup 2)))]
1112190286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1112290286Sobrien   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
1112390286Sobrien{
1112490286Sobrien  switch (get_attr_type (insn))
1112590286Sobrien    {
1112690286Sobrien    case TYPE_ALU:
1112790286Sobrien      if (operands[2] != const1_rtx)
1112890286Sobrien	abort ();
1112990286Sobrien      return "add{w}\t{%0, %0|%0, %0}";
1113090286Sobrien
1113190286Sobrien    default:
1113290286Sobrien      if (REG_P (operands[2]))
1113390286Sobrien	return "sal{w}\t{%b2, %0|%0, %b2}";
1113490286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1113590286Sobrien	       && INTVAL (operands[2]) == 1
1113690286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1113790286Sobrien	return "sal{w}\t%0";
1113890286Sobrien      else
1113990286Sobrien	return "sal{w}\t{%2, %0|%0, %2}";
1114090286Sobrien    }
1114190286Sobrien}
1114290286Sobrien  [(set (attr "type")
1114390286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1114490286Sobrien		          (const_int 0))
1114590286Sobrien		      (match_operand 0 "register_operand" ""))
1114690286Sobrien		 (match_operand 2 "const1_operand" ""))
1114790286Sobrien	      (const_string "alu")
1114890286Sobrien	   ]
1114990286Sobrien	   (const_string "ishift")))
1115090286Sobrien   (set_attr "mode" "HI")])
1115190286Sobrien
1115252296Sobrien(define_expand "ashlqi3"
1115352296Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1115452296Sobrien	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
1115590286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1115690286Sobrien   (clobber (reg:CC 17))]
1115790286Sobrien  "TARGET_QIMODE_MATH"
1115890286Sobrien  "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
1115918334Speter
1116090286Sobrien;; %%% Potential partial reg stall on alternative 2.  What to do?
1116118334Speter
1116290286Sobrien(define_insn "*ashlqi3_1_lea"
1116390286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
1116490286Sobrien	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
1116590286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
1116690286Sobrien   (clobber (reg:CC 17))]
1116790286Sobrien  "!TARGET_PARTIAL_REG_STALL
1116890286Sobrien   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
1116990286Sobrien{
1117090286Sobrien  switch (get_attr_type (insn))
1117190286Sobrien    {
1117290286Sobrien    case TYPE_LEA:
1117390286Sobrien      return "#";
1117490286Sobrien    case TYPE_ALU:
1117590286Sobrien      if (operands[2] != const1_rtx)
1117690286Sobrien	abort ();
1117790286Sobrien      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
1117890286Sobrien        return "add{l}\t{%k0, %k0|%k0, %k0}";
1117990286Sobrien      else
1118090286Sobrien        return "add{b}\t{%0, %0|%0, %0}";
1118118334Speter
1118290286Sobrien    default:
1118390286Sobrien      if (REG_P (operands[2]))
1118490286Sobrien	{
1118590286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1118690286Sobrien	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
1118790286Sobrien	  else
1118890286Sobrien	    return "sal{b}\t{%b2, %0|%0, %b2}";
1118990286Sobrien	}
1119090286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1119190286Sobrien	       && INTVAL (operands[2]) == 1
1119290286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1119390286Sobrien	{
1119490286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1119590286Sobrien	    return "sal{l}\t%0";
1119690286Sobrien	  else
1119790286Sobrien	    return "sal{b}\t%0";
1119890286Sobrien	}
1119990286Sobrien      else
1120090286Sobrien	{
1120190286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1120290286Sobrien	    return "sal{l}\t{%2, %k0|%k0, %2}";
1120390286Sobrien	  else
1120490286Sobrien	    return "sal{b}\t{%2, %0|%0, %2}";
1120590286Sobrien	}
1120690286Sobrien    }
1120790286Sobrien}
1120890286Sobrien  [(set (attr "type")
1120990286Sobrien     (cond [(eq_attr "alternative" "2")
1121090286Sobrien	      (const_string "lea")
1121190286Sobrien            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1121290286Sobrien		          (const_int 0))
1121390286Sobrien		      (match_operand 0 "register_operand" ""))
1121490286Sobrien		 (match_operand 2 "const1_operand" ""))
1121590286Sobrien	      (const_string "alu")
1121690286Sobrien	   ]
1121790286Sobrien	   (const_string "ishift")))
1121890286Sobrien   (set_attr "mode" "QI,SI,SI")])
1121918334Speter
1122090286Sobrien(define_insn "*ashlqi3_1"
1122190286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
1122290286Sobrien	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1122390286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
1122490286Sobrien   (clobber (reg:CC 17))]
1122590286Sobrien  "TARGET_PARTIAL_REG_STALL
1122690286Sobrien   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
1122790286Sobrien{
1122890286Sobrien  switch (get_attr_type (insn))
1122990286Sobrien    {
1123090286Sobrien    case TYPE_ALU:
1123190286Sobrien      if (operands[2] != const1_rtx)
1123290286Sobrien	abort ();
1123390286Sobrien      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
1123490286Sobrien        return "add{l}\t{%k0, %k0|%k0, %k0}";
1123590286Sobrien      else
1123690286Sobrien        return "add{b}\t{%0, %0|%0, %0}";
1123752296Sobrien
1123890286Sobrien    default:
1123990286Sobrien      if (REG_P (operands[2]))
1124090286Sobrien	{
1124190286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1124290286Sobrien	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
1124390286Sobrien	  else
1124490286Sobrien	    return "sal{b}\t{%b2, %0|%0, %b2}";
1124590286Sobrien	}
1124690286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1124790286Sobrien	       && INTVAL (operands[2]) == 1
1124890286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1124990286Sobrien	{
1125090286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1125190286Sobrien	    return "sal{l}\t%0";
1125290286Sobrien	  else
1125390286Sobrien	    return "sal{b}\t%0";
1125490286Sobrien	}
1125590286Sobrien      else
1125690286Sobrien	{
1125790286Sobrien	  if (get_attr_mode (insn) == MODE_SI)
1125890286Sobrien	    return "sal{l}\t{%2, %k0|%k0, %2}";
1125990286Sobrien	  else
1126090286Sobrien	    return "sal{b}\t{%2, %0|%0, %2}";
1126190286Sobrien	}
1126290286Sobrien    }
1126390286Sobrien}
1126490286Sobrien  [(set (attr "type")
1126590286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1126690286Sobrien		          (const_int 0))
1126790286Sobrien		      (match_operand 0 "register_operand" ""))
1126890286Sobrien		 (match_operand 2 "const1_operand" ""))
1126990286Sobrien	      (const_string "alu")
1127090286Sobrien	   ]
1127190286Sobrien	   (const_string "ishift")))
1127290286Sobrien   (set_attr "mode" "QI,SI")])
1127318334Speter
1127490286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1127590286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1127690286Sobrien;; zero are optimized away.
1127790286Sobrien(define_insn "*ashlqi3_cmp"
1127890286Sobrien  [(set (reg 17)
1127990286Sobrien	(compare
1128090286Sobrien	  (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11281102802Skan		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
1128290286Sobrien	  (const_int 0)))
1128390286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1128490286Sobrien	(ashift:QI (match_dup 1) (match_dup 2)))]
1128590286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1128690286Sobrien   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
1128790286Sobrien{
1128890286Sobrien  switch (get_attr_type (insn))
1128990286Sobrien    {
1129090286Sobrien    case TYPE_ALU:
1129190286Sobrien      if (operands[2] != const1_rtx)
1129290286Sobrien	abort ();
1129390286Sobrien      return "add{b}\t{%0, %0|%0, %0}";
1129418334Speter
1129590286Sobrien    default:
1129690286Sobrien      if (REG_P (operands[2]))
1129790286Sobrien	return "sal{b}\t{%b2, %0|%0, %b2}";
1129890286Sobrien      else if (GET_CODE (operands[2]) == CONST_INT
1129990286Sobrien	       && INTVAL (operands[2]) == 1
1130090286Sobrien	       && (TARGET_PENTIUM || TARGET_PENTIUMPRO))
1130190286Sobrien	return "sal{b}\t%0";
1130290286Sobrien      else
1130390286Sobrien	return "sal{b}\t{%2, %0|%0, %2}";
1130490286Sobrien    }
1130590286Sobrien}
1130690286Sobrien  [(set (attr "type")
1130790286Sobrien     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
1130890286Sobrien		          (const_int 0))
1130990286Sobrien		      (match_operand 0 "register_operand" ""))
1131090286Sobrien		 (match_operand 2 "const1_operand" ""))
1131190286Sobrien	      (const_string "alu")
1131290286Sobrien	   ]
1131390286Sobrien	   (const_string "ishift")))
1131490286Sobrien   (set_attr "mode" "QI")])
1131518334Speter
1131618334Speter;; See comment above `ashldi3' about how this works.
1131718334Speter
1131818334Speter(define_expand "ashrdi3"
1131990286Sobrien  [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
1132090286Sobrien		   (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
1132190286Sobrien				(match_operand:QI 2 "nonmemory_operand" "")))
1132290286Sobrien	      (clobber (reg:CC 17))])]
1132318334Speter  ""
1132418334Speter{
1132590286Sobrien  if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
1132618334Speter    {
1132790286Sobrien      emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
1132890286Sobrien      DONE;
1132918334Speter    }
1133090286Sobrien  ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
1133118334Speter  DONE;
1133290286Sobrien})
1133318334Speter
1133490286Sobrien(define_insn "ashrdi3_63_rex64"
1133590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
1133690286Sobrien	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
1133790286Sobrien		     (match_operand:DI 2 "const_int_operand" "i,i")))
1133890286Sobrien   (clobber (reg:CC 17))]
1133990286Sobrien  "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
1134090286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
1134190286Sobrien  "@
1134290286Sobrien   {cqto|cqo}
1134390286Sobrien   sar{q}\t{%2, %0|%0, %2}"
1134490286Sobrien  [(set_attr "type" "imovx,ishift")
1134590286Sobrien   (set_attr "prefix_0f" "0,*")
1134690286Sobrien   (set_attr "length_immediate" "0,*")
1134790286Sobrien   (set_attr "modrm" "0,1")
1134890286Sobrien   (set_attr "mode" "DI")])
1134950650Sobrien
1135090286Sobrien(define_insn "*ashrdi3_1_one_bit_rex64"
1135190286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1135290286Sobrien	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1135390286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1135490286Sobrien   (clobber (reg:CC 17))]
1135590286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
1135690286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1135790286Sobrien  "sar{q}\t%0"
1135890286Sobrien  [(set_attr "type" "ishift")
1135990286Sobrien   (set (attr "length") 
1136090286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1136190286Sobrien	(const_string "2")
1136290286Sobrien	(const_string "*")))])
1136350650Sobrien
1136490286Sobrien(define_insn "*ashrdi3_1_rex64"
1136590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
1136690286Sobrien	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
1136790286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
1136890286Sobrien   (clobber (reg:CC 17))]
1136990286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
1137090286Sobrien  "@
1137190286Sobrien   sar{q}\t{%2, %0|%0, %2}
1137290286Sobrien   sar{q}\t{%b2, %0|%0, %b2}"
1137390286Sobrien  [(set_attr "type" "ishift")
1137490286Sobrien   (set_attr "mode" "DI")])
1137550650Sobrien
1137690286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1137790286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1137890286Sobrien;; zero are optimized away.
1137990286Sobrien(define_insn "*ashrdi3_one_bit_cmp_rex64"
1138090286Sobrien  [(set (reg 17)
1138190286Sobrien	(compare
1138290286Sobrien	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1138390286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1138490286Sobrien	  (const_int 0)))
1138590286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1138690286Sobrien	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
1138790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1138890286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1138990286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
1139090286Sobrien  "sar{q}\t%0"
1139190286Sobrien  [(set_attr "type" "ishift")
1139290286Sobrien   (set (attr "length") 
1139390286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1139490286Sobrien	(const_string "2")
1139590286Sobrien	(const_string "*")))])
1139650650Sobrien
1139790286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1139890286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1139990286Sobrien;; zero are optimized away.
1140090286Sobrien(define_insn "*ashrdi3_cmp_rex64"
1140190286Sobrien  [(set (reg 17)
1140290286Sobrien	(compare
1140390286Sobrien	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1140490286Sobrien		       (match_operand:QI 2 "const_int_operand" "n"))
1140590286Sobrien	  (const_int 0)))
1140690286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1140790286Sobrien	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
1140890286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1140990286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
1141090286Sobrien  "sar{q}\t{%2, %0|%0, %2}"
1141190286Sobrien  [(set_attr "type" "ishift")
1141290286Sobrien   (set_attr "mode" "DI")])
1141318334Speter
1141418334Speter
1141590286Sobrien(define_insn "ashrdi3_1"
1141690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1141790286Sobrien	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
1141890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
1141990286Sobrien   (clobber (match_scratch:SI 3 "=&r"))
1142090286Sobrien   (clobber (reg:CC 17))]
1142190286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1142290286Sobrien  "#"
1142390286Sobrien  [(set_attr "type" "multi")])
1142418334Speter
1142590286Sobrien(define_insn "*ashrdi3_2"
1142690286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1142790286Sobrien	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
1142890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
1142990286Sobrien   (clobber (reg:CC 17))]
1143090286Sobrien  "!TARGET_64BIT"
1143190286Sobrien  "#"
1143290286Sobrien  [(set_attr "type" "multi")])
1143318334Speter
1143490286Sobrien(define_split
1143590286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1143690286Sobrien	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
1143790286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1143890286Sobrien   (clobber (match_scratch:SI 3 ""))
1143990286Sobrien   (clobber (reg:CC 17))]
1144090286Sobrien  "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
1144190286Sobrien  [(const_int 0)]
1144290286Sobrien  "ix86_split_ashrdi (operands, operands[3]); DONE;")
1144318334Speter
1144490286Sobrien(define_split
1144590286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1144690286Sobrien	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
1144790286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1144890286Sobrien   (clobber (reg:CC 17))]
1144990286Sobrien  "!TARGET_64BIT && reload_completed"
1145090286Sobrien  [(const_int 0)]
1145190286Sobrien  "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
1145218334Speter
1145390286Sobrien(define_insn "x86_shrd_1"
1145490286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
1145590286Sobrien        (ior:SI (ashiftrt:SI (match_dup 0)
1145690286Sobrien		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
1145790286Sobrien		(ashift:SI (match_operand:SI 1 "register_operand" "r,r")
1145890286Sobrien		  (minus:QI (const_int 32) (match_dup 2)))))
1145990286Sobrien   (clobber (reg:CC 17))]
1146018334Speter  ""
1146190286Sobrien  "@
1146290286Sobrien   shrd{l}\t{%2, %1, %0|%0, %1, %2}
1146390286Sobrien   shrd{l}\t{%s2%1, %0|%0, %1, %2}"
1146490286Sobrien  [(set_attr "type" "ishift")
1146590286Sobrien   (set_attr "prefix_0f" "1")
1146690286Sobrien   (set_attr "pent_pair" "np")
1146790286Sobrien   (set_attr "ppro_uops" "few")
1146890286Sobrien   (set_attr "mode" "SI")])
1146990286Sobrien
1147090286Sobrien(define_expand "x86_shift_adj_3"
1147190286Sobrien  [(use (match_operand:SI 0 "register_operand" ""))
1147290286Sobrien   (use (match_operand:SI 1 "register_operand" ""))
1147390286Sobrien   (use (match_operand:QI 2 "register_operand" ""))]
1147490286Sobrien  ""
1147518334Speter{
1147690286Sobrien  rtx label = gen_label_rtx ();
1147790286Sobrien  rtx tmp;
1147818334Speter
1147990286Sobrien  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
1148018334Speter
1148190286Sobrien  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
1148290286Sobrien  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1148390286Sobrien  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
1148490286Sobrien			      gen_rtx_LABEL_REF (VOIDmode, label),
1148590286Sobrien			      pc_rtx);
1148690286Sobrien  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
1148790286Sobrien  JUMP_LABEL (tmp) = label;
1148818334Speter
1148990286Sobrien  emit_move_insn (operands[0], operands[1]);
1149090286Sobrien  emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
1149118334Speter
1149290286Sobrien  emit_label (label);
1149390286Sobrien  LABEL_NUSES (label) = 1;
1149490286Sobrien
1149590286Sobrien  DONE;
1149690286Sobrien})
1149790286Sobrien
1149852296Sobrien(define_insn "ashrsi3_31"
1149990286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
1150090286Sobrien	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
1150190286Sobrien		     (match_operand:SI 2 "const_int_operand" "i,i")))
1150290286Sobrien   (clobber (reg:CC 17))]
1150390286Sobrien  "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
1150490286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1150552296Sobrien  "@
1150690286Sobrien   {cltd|cdq}
1150790286Sobrien   sar{l}\t{%2, %0|%0, %2}"
1150890286Sobrien  [(set_attr "type" "imovx,ishift")
1150990286Sobrien   (set_attr "prefix_0f" "0,*")
1151090286Sobrien   (set_attr "length_immediate" "0,*")
1151190286Sobrien   (set_attr "modrm" "0,1")
1151290286Sobrien   (set_attr "mode" "SI")])
1151352296Sobrien
1151490286Sobrien(define_insn "*ashrsi3_31_zext"
1151590286Sobrien  [(set (match_operand:DI 0 "register_operand" "=*d,r")
1151690286Sobrien	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
1151790286Sobrien				     (match_operand:SI 2 "const_int_operand" "i,i"))))
1151890286Sobrien   (clobber (reg:CC 17))]
1151990286Sobrien  "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
1152090286Sobrien   && INTVAL (operands[2]) == 31
1152190286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1152290286Sobrien  "@
1152390286Sobrien   {cltd|cdq}
1152490286Sobrien   sar{l}\t{%2, %k0|%k0, %2}"
1152590286Sobrien  [(set_attr "type" "imovx,ishift")
1152690286Sobrien   (set_attr "prefix_0f" "0,*")
1152790286Sobrien   (set_attr "length_immediate" "0,*")
1152890286Sobrien   (set_attr "modrm" "0,1")
1152990286Sobrien   (set_attr "mode" "SI")])
1153090286Sobrien
1153190286Sobrien(define_expand "ashrsi3"
1153290286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1153390286Sobrien	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
1153490286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1153590286Sobrien   (clobber (reg:CC 17))]
1153690286Sobrien  ""
1153790286Sobrien  "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
1153890286Sobrien
1153990286Sobrien(define_insn "*ashrsi3_1_one_bit"
1154050650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1154150650Sobrien	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1154290286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1154390286Sobrien   (clobber (reg:CC 17))]
1154490286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
1154590286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1154690286Sobrien  "sar{l}\t%0"
1154790286Sobrien  [(set_attr "type" "ishift")
1154890286Sobrien   (set (attr "length") 
1154990286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1155090286Sobrien	(const_string "2")
1155190286Sobrien	(const_string "*")))])
1155218334Speter
1155390286Sobrien(define_insn "*ashrsi3_1_one_bit_zext"
1155490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1155590286Sobrien	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
1155690286Sobrien				     (match_operand:QI 2 "const_int_1_operand" ""))))
1155790286Sobrien   (clobber (reg:CC 17))]
1155890286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
1155990286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1156090286Sobrien  "sar{l}\t%k0"
1156190286Sobrien  [(set_attr "type" "ishift")
1156290286Sobrien   (set_attr "length" "2")])
1156390286Sobrien
1156490286Sobrien(define_insn "*ashrsi3_1"
1156590286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1156690286Sobrien	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1156790286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1156890286Sobrien   (clobber (reg:CC 17))]
1156990286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1157090286Sobrien  "@
1157190286Sobrien   sar{l}\t{%2, %0|%0, %2}
1157290286Sobrien   sar{l}\t{%b2, %0|%0, %b2}"
1157390286Sobrien  [(set_attr "type" "ishift")
1157490286Sobrien   (set_attr "mode" "SI")])
1157590286Sobrien
1157690286Sobrien(define_insn "*ashrsi3_1_zext"
1157790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1157890286Sobrien	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
1157990286Sobrien				     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
1158090286Sobrien   (clobber (reg:CC 17))]
1158190286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1158290286Sobrien  "@
1158390286Sobrien   sar{l}\t{%2, %k0|%k0, %2}
1158490286Sobrien   sar{l}\t{%b2, %k0|%k0, %b2}"
1158590286Sobrien  [(set_attr "type" "ishift")
1158690286Sobrien   (set_attr "mode" "SI")])
1158790286Sobrien
1158890286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1158990286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1159090286Sobrien;; zero are optimized away.
1159190286Sobrien(define_insn "*ashrsi3_one_bit_cmp"
1159290286Sobrien  [(set (reg 17)
1159390286Sobrien	(compare
1159490286Sobrien	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1159590286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1159690286Sobrien	  (const_int 0)))
1159790286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1159890286Sobrien	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
1159990286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1160090286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1160190286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1160290286Sobrien  "sar{l}\t%0"
1160390286Sobrien  [(set_attr "type" "ishift")
1160490286Sobrien   (set (attr "length") 
1160590286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1160690286Sobrien	(const_string "2")
1160790286Sobrien	(const_string "*")))])
1160890286Sobrien
1160990286Sobrien(define_insn "*ashrsi3_one_bit_cmp_zext"
1161090286Sobrien  [(set (reg 17)
1161190286Sobrien	(compare
1161290286Sobrien	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
1161390286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1161490286Sobrien	  (const_int 0)))
1161590286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1161690286Sobrien	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
1161790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
1161890286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1161990286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1162090286Sobrien  "sar{l}\t%k0"
1162190286Sobrien  [(set_attr "type" "ishift")
1162290286Sobrien   (set_attr "length" "2")])
1162390286Sobrien
1162490286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1162590286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1162690286Sobrien;; zero are optimized away.
1162790286Sobrien(define_insn "*ashrsi3_cmp"
1162890286Sobrien  [(set (reg 17)
1162990286Sobrien	(compare
1163090286Sobrien	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11631102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1163290286Sobrien	  (const_int 0)))
1163390286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1163490286Sobrien	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
1163590286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1163690286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1163790286Sobrien  "sar{l}\t{%2, %0|%0, %2}"
1163890286Sobrien  [(set_attr "type" "ishift")
1163990286Sobrien   (set_attr "mode" "SI")])
1164090286Sobrien
1164190286Sobrien(define_insn "*ashrsi3_cmp_zext"
1164290286Sobrien  [(set (reg 17)
1164390286Sobrien	(compare
1164490286Sobrien	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11645102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1164690286Sobrien	  (const_int 0)))
1164790286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1164890286Sobrien	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
1164990286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1165090286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
1165190286Sobrien  "sar{l}\t{%2, %k0|%k0, %2}"
1165290286Sobrien  [(set_attr "type" "ishift")
1165390286Sobrien   (set_attr "mode" "SI")])
1165490286Sobrien
1165590286Sobrien(define_expand "ashrhi3"
1165690286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1165790286Sobrien	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
1165890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1165990286Sobrien   (clobber (reg:CC 17))]
1166090286Sobrien  "TARGET_HIMODE_MATH"
1166190286Sobrien  "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
1166290286Sobrien
1166390286Sobrien(define_insn "*ashrhi3_1_one_bit"
1166450650Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1166550650Sobrien	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1166690286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1166790286Sobrien   (clobber (reg:CC 17))]
1166890286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
1166990286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1167090286Sobrien  "sar{w}\t%0"
1167190286Sobrien  [(set_attr "type" "ishift")
1167290286Sobrien   (set (attr "length") 
1167390286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1167490286Sobrien	(const_string "2")
1167590286Sobrien	(const_string "*")))])
1167618334Speter
1167790286Sobrien(define_insn "*ashrhi3_1"
1167890286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
1167990286Sobrien	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
1168090286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1168190286Sobrien   (clobber (reg:CC 17))]
1168290286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
1168390286Sobrien  "@
1168490286Sobrien   sar{w}\t{%2, %0|%0, %2}
1168590286Sobrien   sar{w}\t{%b2, %0|%0, %b2}"
1168690286Sobrien  [(set_attr "type" "ishift")
1168790286Sobrien   (set_attr "mode" "HI")])
1168890286Sobrien
1168990286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1169090286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1169190286Sobrien;; zero are optimized away.
1169290286Sobrien(define_insn "*ashrhi3_one_bit_cmp"
1169390286Sobrien  [(set (reg 17)
1169490286Sobrien	(compare
1169590286Sobrien	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1169690286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1169790286Sobrien	  (const_int 0)))
1169890286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1169990286Sobrien	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
1170090286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1170190286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1170290286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
1170390286Sobrien  "sar{w}\t%0"
1170490286Sobrien  [(set_attr "type" "ishift")
1170590286Sobrien   (set (attr "length") 
1170690286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1170790286Sobrien	(const_string "2")
1170890286Sobrien	(const_string "*")))])
1170990286Sobrien
1171090286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1171190286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1171290286Sobrien;; zero are optimized away.
1171390286Sobrien(define_insn "*ashrhi3_cmp"
1171490286Sobrien  [(set (reg 17)
1171590286Sobrien	(compare
1171690286Sobrien	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11717102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1171890286Sobrien	  (const_int 0)))
1171990286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1172090286Sobrien	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
1172190286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1172290286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
1172390286Sobrien  "sar{w}\t{%2, %0|%0, %2}"
1172490286Sobrien  [(set_attr "type" "ishift")
1172590286Sobrien   (set_attr "mode" "HI")])
1172690286Sobrien
1172790286Sobrien(define_expand "ashrqi3"
1172890286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1172990286Sobrien	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
1173090286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1173190286Sobrien   (clobber (reg:CC 17))]
1173290286Sobrien  "TARGET_QIMODE_MATH"
1173390286Sobrien  "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
1173490286Sobrien
1173590286Sobrien(define_insn "*ashrqi3_1_one_bit"
1173650650Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1173750650Sobrien	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1173890286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1173990286Sobrien   (clobber (reg:CC 17))]
1174090286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
1174190286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1174290286Sobrien  "sar{b}\t%0"
1174390286Sobrien  [(set_attr "type" "ishift")
1174490286Sobrien   (set (attr "length") 
1174590286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1174690286Sobrien	(const_string "2")
1174790286Sobrien	(const_string "*")))])
1174890286Sobrien
1174990286Sobrien(define_insn "*ashrqi3_1"
1175090286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
1175190286Sobrien	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1175290286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1175390286Sobrien   (clobber (reg:CC 17))]
1175490286Sobrien  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
1175590286Sobrien  "@
1175690286Sobrien   sar{b}\t{%2, %0|%0, %2}
1175790286Sobrien   sar{b}\t{%b2, %0|%0, %b2}"
1175890286Sobrien  [(set_attr "type" "ishift")
1175990286Sobrien   (set_attr "mode" "QI")])
1176090286Sobrien
1176190286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1176290286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1176390286Sobrien;; zero are optimized away.
1176490286Sobrien(define_insn "*ashrqi3_one_bit_cmp"
1176590286Sobrien  [(set (reg 17)
1176690286Sobrien	(compare
1176790286Sobrien	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1176890286Sobrien		       (match_operand:QI 2 "const_int_1_operand" "I"))
1176990286Sobrien	  (const_int 0)))
11770102802Skan   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1177190286Sobrien	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
1177290286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1177390286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1177490286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
1177590286Sobrien  "sar{b}\t%0"
1177690286Sobrien  [(set_attr "type" "ishift")
1177790286Sobrien   (set (attr "length") 
1177890286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1177990286Sobrien	(const_string "2")
1178090286Sobrien	(const_string "*")))])
1178190286Sobrien
1178290286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1178390286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1178490286Sobrien;; zero are optimized away.
1178590286Sobrien(define_insn "*ashrqi3_cmp"
1178690286Sobrien  [(set (reg 17)
1178790286Sobrien	(compare
1178890286Sobrien	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11789102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1179090286Sobrien	  (const_int 0)))
11791102802Skan   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1179290286Sobrien	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
1179390286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1179490286Sobrien   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
1179590286Sobrien  "sar{b}\t{%2, %0|%0, %2}"
1179690286Sobrien  [(set_attr "type" "ishift")
1179790286Sobrien   (set_attr "mode" "QI")])
1179818334Speter
1179990286Sobrien;; Logical shift instructions
1180018334Speter
1180118334Speter;; See comment above `ashldi3' about how this works.
1180218334Speter
1180318334Speter(define_expand "lshrdi3"
1180490286Sobrien  [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
1180590286Sobrien		   (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
1180690286Sobrien			        (match_operand:QI 2 "nonmemory_operand" "")))
1180790286Sobrien	      (clobber (reg:CC 17))])]
1180818334Speter  ""
1180918334Speter{
1181090286Sobrien  if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
1181118334Speter    {
1181290286Sobrien      emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
1181390286Sobrien      DONE;
1181418334Speter    }
1181590286Sobrien  ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
1181618334Speter  DONE;
1181790286Sobrien})
1181818334Speter
1181990286Sobrien(define_insn "*lshrdi3_1_one_bit_rex64"
1182090286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1182190286Sobrien	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1182290286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1182390286Sobrien   (clobber (reg:CC 17))]
1182490286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
1182590286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1182690286Sobrien  "shr{q}\t%0"
1182790286Sobrien  [(set_attr "type" "ishift")
1182890286Sobrien   (set (attr "length") 
1182990286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1183090286Sobrien	(const_string "2")
1183190286Sobrien	(const_string "*")))])
1183250650Sobrien
1183390286Sobrien(define_insn "*lshrdi3_1_rex64"
1183490286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
1183590286Sobrien	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
1183690286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
1183790286Sobrien   (clobber (reg:CC 17))]
1183890286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1183990286Sobrien  "@
1184090286Sobrien   shr{q}\t{%2, %0|%0, %2}
1184190286Sobrien   shr{q}\t{%b2, %0|%0, %b2}"
1184290286Sobrien  [(set_attr "type" "ishift")
1184390286Sobrien   (set_attr "mode" "DI")])
1184450650Sobrien
1184590286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1184690286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1184790286Sobrien;; zero are optimized away.
1184890286Sobrien(define_insn "*lshrdi3_cmp_one_bit_rex64"
1184990286Sobrien  [(set (reg 17)
1185090286Sobrien	(compare
1185190286Sobrien	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1185290286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1185390286Sobrien	  (const_int 0)))
1185490286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1185590286Sobrien	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
1185690286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1185790286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1185890286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1185990286Sobrien  "shr{q}\t%0"
1186090286Sobrien  [(set_attr "type" "ishift")
1186190286Sobrien   (set (attr "length") 
1186290286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1186390286Sobrien	(const_string "2")
1186490286Sobrien	(const_string "*")))])
1186550650Sobrien
1186690286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1186790286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1186890286Sobrien;; zero are optimized away.
1186990286Sobrien(define_insn "*lshrdi3_cmp_rex64"
1187090286Sobrien  [(set (reg 17)
1187190286Sobrien	(compare
1187290286Sobrien	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1187390286Sobrien		       (match_operand:QI 2 "const_int_operand" "e"))
1187490286Sobrien	  (const_int 0)))
1187590286Sobrien   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1187690286Sobrien	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
1187790286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1187890286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1187990286Sobrien  "shr{q}\t{%2, %0|%0, %2}"
1188090286Sobrien  [(set_attr "type" "ishift")
1188190286Sobrien   (set_attr "mode" "DI")])
1188250650Sobrien
1188390286Sobrien(define_insn "lshrdi3_1"
1188490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1188518334Speter	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
1188690286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
1188790286Sobrien   (clobber (match_scratch:SI 3 "=&r"))
1188890286Sobrien   (clobber (reg:CC 17))]
1188990286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1189090286Sobrien  "#"
1189190286Sobrien  [(set_attr "type" "multi")])
1189218334Speter
1189390286Sobrien(define_insn "*lshrdi3_2"
1189490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1189590286Sobrien	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
1189690286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
1189790286Sobrien   (clobber (reg:CC 17))]
1189890286Sobrien  "!TARGET_64BIT"
1189990286Sobrien  "#"
1190090286Sobrien  [(set_attr "type" "multi")])
1190118334Speter
1190290286Sobrien(define_split 
1190390286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1190490286Sobrien	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
1190590286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1190690286Sobrien   (clobber (match_scratch:SI 3 ""))
1190790286Sobrien   (clobber (reg:CC 17))]
1190890286Sobrien  "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
1190990286Sobrien  [(const_int 0)]
1191090286Sobrien  "ix86_split_lshrdi (operands, operands[3]); DONE;")
1191118334Speter
1191290286Sobrien(define_split 
1191390286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1191490286Sobrien	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
1191590286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1191690286Sobrien   (clobber (reg:CC 17))]
1191790286Sobrien  "!TARGET_64BIT && reload_completed"
1191890286Sobrien  [(const_int 0)]
1191990286Sobrien  "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
1192018334Speter
1192190286Sobrien(define_expand "lshrsi3"
1192290286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1192390286Sobrien	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
1192490286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1192590286Sobrien   (clobber (reg:CC 17))]
1192690286Sobrien  ""
1192790286Sobrien  "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
1192818334Speter
1192990286Sobrien(define_insn "*lshrsi3_1_one_bit"
1193090286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1193190286Sobrien	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1193290286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1193390286Sobrien   (clobber (reg:CC 17))]
1193490286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
1193590286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1193690286Sobrien  "shr{l}\t%0"
1193790286Sobrien  [(set_attr "type" "ishift")
1193890286Sobrien   (set (attr "length") 
1193990286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1194090286Sobrien	(const_string "2")
1194190286Sobrien	(const_string "*")))])
1194218334Speter
1194390286Sobrien(define_insn "*lshrsi3_1_one_bit_zext"
1194490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1194590286Sobrien	(lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
1194690286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1194790286Sobrien   (clobber (reg:CC 17))]
1194890286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
1194990286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1195090286Sobrien  "shr{l}\t%k0"
1195190286Sobrien  [(set_attr "type" "ishift")
1195290286Sobrien   (set_attr "length" "2")])
1195318334Speter
1195490286Sobrien(define_insn "*lshrsi3_1"
1195590286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1195690286Sobrien	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1195790286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1195890286Sobrien   (clobber (reg:CC 17))]
1195990286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1196090286Sobrien  "@
1196190286Sobrien   shr{l}\t{%2, %0|%0, %2}
1196290286Sobrien   shr{l}\t{%b2, %0|%0, %b2}"
1196390286Sobrien  [(set_attr "type" "ishift")
1196490286Sobrien   (set_attr "mode" "SI")])
1196518334Speter
1196690286Sobrien(define_insn "*lshrsi3_1_zext"
1196790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1196890286Sobrien	(zero_extend:DI
1196990286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1197090286Sobrien		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
1197190286Sobrien   (clobber (reg:CC 17))]
1197290286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1197390286Sobrien  "@
1197490286Sobrien   shr{l}\t{%2, %k0|%k0, %2}
1197590286Sobrien   shr{l}\t{%b2, %k0|%k0, %b2}"
1197690286Sobrien  [(set_attr "type" "ishift")
1197790286Sobrien   (set_attr "mode" "SI")])
1197818334Speter
1197990286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1198090286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1198190286Sobrien;; zero are optimized away.
1198290286Sobrien(define_insn "*lshrsi3_one_bit_cmp"
1198390286Sobrien  [(set (reg 17)
1198490286Sobrien	(compare
1198590286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1198690286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1198790286Sobrien	  (const_int 0)))
1198890286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1198990286Sobrien	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
1199090286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1199190286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1199290286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1199390286Sobrien  "shr{l}\t%0"
1199490286Sobrien  [(set_attr "type" "ishift")
1199590286Sobrien   (set (attr "length") 
1199690286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1199790286Sobrien	(const_string "2")
1199890286Sobrien	(const_string "*")))])
1199918334Speter
1200090286Sobrien(define_insn "*lshrsi3_cmp_one_bit_zext"
1200190286Sobrien  [(set (reg 17)
1200290286Sobrien	(compare
1200390286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
1200490286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1200590286Sobrien	  (const_int 0)))
1200690286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1200790286Sobrien	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
1200890286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1200990286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1201090286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1201190286Sobrien  "shr{l}\t%k0"
1201290286Sobrien  [(set_attr "type" "ishift")
1201390286Sobrien   (set_attr "length" "2")])
1201418334Speter
1201590286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1201690286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1201790286Sobrien;; zero are optimized away.
1201890286Sobrien(define_insn "*lshrsi3_cmp"
1201990286Sobrien  [(set (reg 17)
1202090286Sobrien	(compare
1202190286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12022102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1202390286Sobrien	  (const_int 0)))
1202490286Sobrien   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1202590286Sobrien	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
1202690286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1202790286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1202890286Sobrien  "shr{l}\t{%2, %0|%0, %2}"
1202990286Sobrien  [(set_attr "type" "ishift")
1203090286Sobrien   (set_attr "mode" "SI")])
1203190286Sobrien
1203290286Sobrien(define_insn "*lshrsi3_cmp_zext"
1203390286Sobrien  [(set (reg 17)
1203490286Sobrien	(compare
1203590286Sobrien	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12036102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1203790286Sobrien	  (const_int 0)))
1203890286Sobrien   (set (match_operand:DI 0 "register_operand" "=r")
1203990286Sobrien	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
1204090286Sobrien  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
1204190286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1204290286Sobrien  "shr{l}\t{%2, %k0|%k0, %2}"
1204390286Sobrien  [(set_attr "type" "ishift")
1204490286Sobrien   (set_attr "mode" "SI")])
1204590286Sobrien
1204690286Sobrien(define_expand "lshrhi3"
1204790286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1204890286Sobrien	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
1204990286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1205090286Sobrien   (clobber (reg:CC 17))]
1205190286Sobrien  "TARGET_HIMODE_MATH"
1205290286Sobrien  "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
1205390286Sobrien
1205490286Sobrien(define_insn "*lshrhi3_1_one_bit"
1205550650Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1205650650Sobrien	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1205790286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1205890286Sobrien   (clobber (reg:CC 17))]
1205990286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
1206090286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1206190286Sobrien  "shr{w}\t%0"
1206290286Sobrien  [(set_attr "type" "ishift")
1206390286Sobrien   (set (attr "length") 
1206490286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1206590286Sobrien	(const_string "2")
1206690286Sobrien	(const_string "*")))])
1206718334Speter
1206890286Sobrien(define_insn "*lshrhi3_1"
1206990286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
1207090286Sobrien	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
1207190286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1207290286Sobrien   (clobber (reg:CC 17))]
1207390286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1207490286Sobrien  "@
1207590286Sobrien   shr{w}\t{%2, %0|%0, %2}
1207690286Sobrien   shr{w}\t{%b2, %0|%0, %b2}"
1207790286Sobrien  [(set_attr "type" "ishift")
1207890286Sobrien   (set_attr "mode" "HI")])
1207990286Sobrien
1208090286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1208190286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1208290286Sobrien;; zero are optimized away.
1208390286Sobrien(define_insn "*lshrhi3_one_bit_cmp"
1208490286Sobrien  [(set (reg 17)
1208590286Sobrien	(compare
1208690286Sobrien	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1208790286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1208890286Sobrien	  (const_int 0)))
1208990286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1209090286Sobrien	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
1209190286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1209290286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1209390286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1209490286Sobrien  "shr{w}\t%0"
1209590286Sobrien  [(set_attr "type" "ishift")
1209690286Sobrien   (set (attr "length") 
1209790286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1209890286Sobrien	(const_string "2")
1209990286Sobrien	(const_string "*")))])
1210090286Sobrien
1210190286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1210290286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1210390286Sobrien;; zero are optimized away.
1210490286Sobrien(define_insn "*lshrhi3_cmp"
1210590286Sobrien  [(set (reg 17)
1210690286Sobrien	(compare
1210790286Sobrien	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12108102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1210990286Sobrien	  (const_int 0)))
1211090286Sobrien   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1211190286Sobrien	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
1211290286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1211390286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
1211490286Sobrien  "shr{w}\t{%2, %0|%0, %2}"
1211590286Sobrien  [(set_attr "type" "ishift")
1211690286Sobrien   (set_attr "mode" "HI")])
1211790286Sobrien
1211890286Sobrien(define_expand "lshrqi3"
1211990286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1212090286Sobrien	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
1212190286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1212290286Sobrien   (clobber (reg:CC 17))]
1212390286Sobrien  "TARGET_QIMODE_MATH"
1212490286Sobrien  "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
1212590286Sobrien
1212690286Sobrien(define_insn "*lshrqi3_1_one_bit"
1212750650Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1212850650Sobrien	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1212990286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1213090286Sobrien   (clobber (reg:CC 17))]
1213190286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
1213290286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1213390286Sobrien  "shr{b}\t%0"
1213490286Sobrien  [(set_attr "type" "ishift")
1213590286Sobrien   (set (attr "length") 
1213690286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1213790286Sobrien	(const_string "2")
1213890286Sobrien	(const_string "*")))])
1213990286Sobrien
1214090286Sobrien(define_insn "*lshrqi3_1"
1214190286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
1214290286Sobrien	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1214390286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1214490286Sobrien   (clobber (reg:CC 17))]
1214590286Sobrien  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
1214690286Sobrien  "@
1214790286Sobrien   shr{b}\t{%2, %0|%0, %2}
1214890286Sobrien   shr{b}\t{%b2, %0|%0, %b2}"
1214990286Sobrien  [(set_attr "type" "ishift")
1215090286Sobrien   (set_attr "mode" "QI")])
1215190286Sobrien
1215290286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1215390286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1215490286Sobrien;; zero are optimized away.
1215590286Sobrien(define_insn "*lshrqi2_one_bit_cmp"
1215690286Sobrien  [(set (reg 17)
1215790286Sobrien	(compare
1215890286Sobrien	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1215990286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))
1216090286Sobrien	  (const_int 0)))
1216190286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1216290286Sobrien	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
1216390286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1216490286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)
1216590286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
1216690286Sobrien  "shr{b}\t%0"
1216790286Sobrien  [(set_attr "type" "ishift")
1216890286Sobrien   (set (attr "length") 
1216990286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1217090286Sobrien	(const_string "2")
1217190286Sobrien	(const_string "*")))])
1217290286Sobrien
1217390286Sobrien;; This pattern can't accept a variable shift count, since shifts by
1217490286Sobrien;; zero don't affect the flags.  We assume that shifts by constant
1217590286Sobrien;; zero are optimized away.
1217690286Sobrien(define_insn "*lshrqi2_cmp"
1217790286Sobrien  [(set (reg 17)
1217890286Sobrien	(compare
1217990286Sobrien	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12180102802Skan		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
1218190286Sobrien	  (const_int 0)))
1218290286Sobrien   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1218390286Sobrien	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
1218490286Sobrien  "ix86_match_ccmode (insn, CCGOCmode)
1218590286Sobrien   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
1218690286Sobrien  "shr{b}\t{%2, %0|%0, %2}"
1218790286Sobrien  [(set_attr "type" "ishift")
1218890286Sobrien   (set_attr "mode" "QI")])
1218918334Speter
1219090286Sobrien;; Rotate instructions
1219118334Speter
1219290286Sobrien(define_expand "rotldi3"
1219390286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1219490286Sobrien	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
1219590286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1219690286Sobrien   (clobber (reg:CC 17))]
1219790286Sobrien  "TARGET_64BIT"
1219890286Sobrien  "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
1219918334Speter
1220090286Sobrien(define_insn "*rotlsi3_1_one_bit_rex64"
1220190286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1220290286Sobrien	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1220390286Sobrien		   (match_operand:QI 2 "const_int_1_operand" "")))
1220490286Sobrien   (clobber (reg:CC 17))]
1220590286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
1220690286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1220790286Sobrien  "rol{q}\t%0"
1220890286Sobrien  [(set_attr "type" "ishift")
1220990286Sobrien   (set (attr "length") 
1221090286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1221190286Sobrien	(const_string "2")
1221290286Sobrien	(const_string "*")))])
1221318334Speter
1221490286Sobrien(define_insn "*rotldi3_1_rex64"
1221590286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
1221690286Sobrien	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
1221790286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "e,c")))
1221890286Sobrien   (clobber (reg:CC 17))]
1221990286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
1222090286Sobrien  "@
1222190286Sobrien   rol{q}\t{%2, %0|%0, %2}
1222290286Sobrien   rol{q}\t{%b2, %0|%0, %b2}"
1222390286Sobrien  [(set_attr "type" "ishift")
1222490286Sobrien   (set_attr "mode" "DI")])
1222590286Sobrien
1222690286Sobrien(define_expand "rotlsi3"
1222790286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1222890286Sobrien	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
1222990286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1223090286Sobrien   (clobber (reg:CC 17))]
1223118334Speter  ""
1223290286Sobrien  "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
1223318334Speter
1223490286Sobrien(define_insn "*rotlsi3_1_one_bit"
1223550650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1223690286Sobrien	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1223790286Sobrien		   (match_operand:QI 2 "const_int_1_operand" "")))
1223890286Sobrien   (clobber (reg:CC 17))]
1223990286Sobrien  "ix86_binary_operator_ok (ROTATE, SImode, operands)
1224090286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1224190286Sobrien  "rol{l}\t%0"
1224290286Sobrien  [(set_attr "type" "ishift")
1224390286Sobrien   (set (attr "length") 
1224490286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1224590286Sobrien	(const_string "2")
1224690286Sobrien	(const_string "*")))])
1224718334Speter
1224890286Sobrien(define_insn "*rotlsi3_1_one_bit_zext"
1224990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1225090286Sobrien	(zero_extend:DI
1225190286Sobrien	  (rotate:SI (match_operand:SI 1 "register_operand" "0")
1225290286Sobrien		     (match_operand:QI 2 "const_int_1_operand" ""))))
1225390286Sobrien   (clobber (reg:CC 17))]
1225490286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
1225590286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1225690286Sobrien  "rol{l}\t%k0"
1225790286Sobrien  [(set_attr "type" "ishift")
1225890286Sobrien   (set_attr "length" "2")])
1225918334Speter
1226090286Sobrien(define_insn "*rotlsi3_1"
1226190286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1226290286Sobrien	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1226390286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
1226490286Sobrien   (clobber (reg:CC 17))]
1226590286Sobrien  "ix86_binary_operator_ok (ROTATE, SImode, operands)"
1226690286Sobrien  "@
1226790286Sobrien   rol{l}\t{%2, %0|%0, %2}
1226890286Sobrien   rol{l}\t{%b2, %0|%0, %b2}"
1226990286Sobrien  [(set_attr "type" "ishift")
1227090286Sobrien   (set_attr "mode" "SI")])
1227118334Speter
1227290286Sobrien(define_insn "*rotlsi3_1_zext"
1227390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1227490286Sobrien	(zero_extend:DI
1227590286Sobrien	  (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
1227690286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
1227790286Sobrien   (clobber (reg:CC 17))]
1227890286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
1227990286Sobrien  "@
1228090286Sobrien   rol{l}\t{%2, %k0|%k0, %2}
1228190286Sobrien   rol{l}\t{%b2, %k0|%k0, %b2}"
1228290286Sobrien  [(set_attr "type" "ishift")
1228390286Sobrien   (set_attr "mode" "SI")])
1228418334Speter
1228590286Sobrien(define_expand "rotlhi3"
1228690286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1228790286Sobrien	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
1228890286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1228990286Sobrien   (clobber (reg:CC 17))]
1229090286Sobrien  "TARGET_HIMODE_MATH"
1229190286Sobrien  "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
1229218334Speter
1229390286Sobrien(define_insn "*rotlhi3_1_one_bit"
1229490286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1229590286Sobrien	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1229690286Sobrien		   (match_operand:QI 2 "const_int_1_operand" "")))
1229790286Sobrien   (clobber (reg:CC 17))]
1229890286Sobrien  "ix86_binary_operator_ok (ROTATE, HImode, operands)
1229990286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1230090286Sobrien  "rol{w}\t%0"
1230190286Sobrien  [(set_attr "type" "ishift")
1230290286Sobrien   (set (attr "length") 
1230390286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1230490286Sobrien	(const_string "2")
1230590286Sobrien	(const_string "*")))])
1230618334Speter
1230790286Sobrien(define_insn "*rotlhi3_1"
1230890286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
1230990286Sobrien	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
1231090286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
1231190286Sobrien   (clobber (reg:CC 17))]
1231290286Sobrien  "ix86_binary_operator_ok (ROTATE, HImode, operands)"
1231390286Sobrien  "@
1231490286Sobrien   rol{w}\t{%2, %0|%0, %2}
1231590286Sobrien   rol{w}\t{%b2, %0|%0, %b2}"
1231690286Sobrien  [(set_attr "type" "ishift")
1231790286Sobrien   (set_attr "mode" "HI")])
1231818334Speter
1231990286Sobrien(define_expand "rotlqi3"
1232090286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1232190286Sobrien	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
1232290286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "")))
1232390286Sobrien   (clobber (reg:CC 17))]
1232490286Sobrien  "TARGET_QIMODE_MATH"
1232590286Sobrien  "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
1232618334Speter
1232790286Sobrien(define_insn "*rotlqi3_1_one_bit"
1232890286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1232990286Sobrien	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1233090286Sobrien		   (match_operand:QI 2 "const_int_1_operand" "")))
1233190286Sobrien   (clobber (reg:CC 17))]
1233290286Sobrien  "ix86_binary_operator_ok (ROTATE, QImode, operands)
1233390286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1233490286Sobrien  "rol{b}\t%0"
1233590286Sobrien  [(set_attr "type" "ishift")
1233690286Sobrien   (set (attr "length") 
1233790286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1233890286Sobrien	(const_string "2")
1233990286Sobrien	(const_string "*")))])
1234018334Speter
1234190286Sobrien(define_insn "*rotlqi3_1"
1234290286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
1234390286Sobrien	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1234490286Sobrien		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
1234590286Sobrien   (clobber (reg:CC 17))]
1234690286Sobrien  "ix86_binary_operator_ok (ROTATE, QImode, operands)"
1234790286Sobrien  "@
1234890286Sobrien   rol{b}\t{%2, %0|%0, %2}
1234990286Sobrien   rol{b}\t{%b2, %0|%0, %b2}"
1235090286Sobrien  [(set_attr "type" "ishift")
1235190286Sobrien   (set_attr "mode" "QI")])
1235218334Speter
1235390286Sobrien(define_expand "rotrdi3"
1235490286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1235590286Sobrien	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
1235690286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1235790286Sobrien   (clobber (reg:CC 17))]
1235890286Sobrien  "TARGET_64BIT"
1235990286Sobrien  "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
1236018334Speter
1236190286Sobrien(define_insn "*rotrdi3_1_one_bit_rex64"
1236290286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
1236390286Sobrien	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
1236490286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1236590286Sobrien   (clobber (reg:CC 17))]
1236690286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
1236790286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1236890286Sobrien  "ror{q}\t%0"
1236990286Sobrien  [(set_attr "type" "ishift")
1237090286Sobrien   (set (attr "length") 
1237190286Sobrien     (if_then_else (match_operand:DI 0 "register_operand" "") 
1237290286Sobrien	(const_string "2")
1237390286Sobrien	(const_string "*")))])
1237418334Speter
1237590286Sobrien(define_insn "*rotrdi3_1_rex64"
1237690286Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
1237790286Sobrien	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
1237890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
1237990286Sobrien   (clobber (reg:CC 17))]
1238090286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
1238190286Sobrien  "@
1238290286Sobrien   ror{q}\t{%2, %0|%0, %2}
1238390286Sobrien   ror{q}\t{%b2, %0|%0, %b2}"
1238490286Sobrien  [(set_attr "type" "ishift")
1238590286Sobrien   (set_attr "mode" "DI")])
1238690286Sobrien
1238790286Sobrien(define_expand "rotrsi3"
1238890286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1238990286Sobrien	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
1239090286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1239190286Sobrien   (clobber (reg:CC 17))]
1239290286Sobrien  ""
1239390286Sobrien  "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
1239490286Sobrien
1239590286Sobrien(define_insn "*rotrsi3_1_one_bit"
1239650650Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
1239790286Sobrien	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
1239890286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1239990286Sobrien   (clobber (reg:CC 17))]
1240090286Sobrien  "ix86_binary_operator_ok (ROTATERT, SImode, operands)
1240190286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1240290286Sobrien  "ror{l}\t%0"
1240390286Sobrien  [(set_attr "type" "ishift")
1240490286Sobrien   (set (attr "length") 
1240590286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1240690286Sobrien	(const_string "2")
1240790286Sobrien	(const_string "*")))])
1240818334Speter
1240990286Sobrien(define_insn "*rotrsi3_1_one_bit_zext"
1241090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1241190286Sobrien	(zero_extend:DI
1241290286Sobrien	  (rotatert:SI (match_operand:SI 1 "register_operand" "0")
1241390286Sobrien		       (match_operand:QI 2 "const_int_1_operand" ""))))
1241490286Sobrien   (clobber (reg:CC 17))]
1241590286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
1241690286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1241790286Sobrien  "ror{l}\t%k0"
1241890286Sobrien  [(set_attr "type" "ishift")
1241990286Sobrien   (set (attr "length") 
1242090286Sobrien     (if_then_else (match_operand:SI 0 "register_operand" "") 
1242190286Sobrien	(const_string "2")
1242290286Sobrien	(const_string "*")))])
1242318334Speter
1242490286Sobrien(define_insn "*rotrsi3_1"
1242590286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
1242690286Sobrien	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
1242790286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1242890286Sobrien   (clobber (reg:CC 17))]
1242990286Sobrien  "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
1243090286Sobrien  "@
1243190286Sobrien   ror{l}\t{%2, %0|%0, %2}
1243290286Sobrien   ror{l}\t{%b2, %0|%0, %b2}"
1243390286Sobrien  [(set_attr "type" "ishift")
1243490286Sobrien   (set_attr "mode" "SI")])
1243518334Speter
1243690286Sobrien(define_insn "*rotrsi3_1_zext"
1243790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1243890286Sobrien	(zero_extend:DI
1243990286Sobrien	  (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
1244090286Sobrien		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
1244190286Sobrien   (clobber (reg:CC 17))]
1244290286Sobrien  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
1244390286Sobrien  "@
1244490286Sobrien   ror{l}\t{%2, %k0|%k0, %2}
1244590286Sobrien   ror{l}\t{%b2, %k0|%k0, %b2}"
1244690286Sobrien  [(set_attr "type" "ishift")
1244790286Sobrien   (set_attr "mode" "SI")])
1244818334Speter
1244990286Sobrien(define_expand "rotrhi3"
1245090286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1245190286Sobrien	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
1245290286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1245390286Sobrien   (clobber (reg:CC 17))]
1245490286Sobrien  "TARGET_HIMODE_MATH"
1245590286Sobrien  "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
1245618334Speter
1245790286Sobrien(define_insn "*rotrhi3_one_bit"
1245890286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
1245990286Sobrien	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
1246090286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1246190286Sobrien   (clobber (reg:CC 17))]
1246290286Sobrien  "ix86_binary_operator_ok (ROTATERT, HImode, operands)
1246390286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1246490286Sobrien  "ror{w}\t%0"
1246590286Sobrien  [(set_attr "type" "ishift")
1246690286Sobrien   (set (attr "length") 
1246790286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1246890286Sobrien	(const_string "2")
1246990286Sobrien	(const_string "*")))])
1247018334Speter
1247190286Sobrien(define_insn "*rotrhi3"
1247290286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
1247390286Sobrien	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
1247490286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1247590286Sobrien   (clobber (reg:CC 17))]
1247690286Sobrien  "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
1247790286Sobrien  "@
1247890286Sobrien   ror{w}\t{%2, %0|%0, %2}
1247990286Sobrien   ror{w}\t{%b2, %0|%0, %b2}"
1248090286Sobrien  [(set_attr "type" "ishift")
1248190286Sobrien   (set_attr "mode" "HI")])
1248218334Speter
1248390286Sobrien(define_expand "rotrqi3"
1248490286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1248590286Sobrien	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
1248690286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "")))
1248790286Sobrien   (clobber (reg:CC 17))]
1248890286Sobrien  "TARGET_QIMODE_MATH"
1248990286Sobrien  "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
1249018334Speter
1249190286Sobrien(define_insn "*rotrqi3_1_one_bit"
1249290286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1249390286Sobrien	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
1249490286Sobrien		     (match_operand:QI 2 "const_int_1_operand" "")))
1249590286Sobrien   (clobber (reg:CC 17))]
1249690286Sobrien  "ix86_binary_operator_ok (ROTATERT, QImode, operands)
1249790286Sobrien   && (TARGET_PENTIUM || TARGET_PENTIUMPRO)"
1249890286Sobrien  "ror{b}\t%0"
1249990286Sobrien  [(set_attr "type" "ishift")
1250090286Sobrien   (set (attr "length") 
1250190286Sobrien     (if_then_else (match_operand 0 "register_operand" "") 
1250290286Sobrien	(const_string "2")
1250390286Sobrien	(const_string "*")))])
1250418334Speter
1250590286Sobrien(define_insn "*rotrqi3_1"
1250690286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
1250790286Sobrien	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
1250890286Sobrien		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
1250990286Sobrien   (clobber (reg:CC 17))]
1251090286Sobrien  "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
1251190286Sobrien  "@
1251290286Sobrien   ror{b}\t{%2, %0|%0, %2}
1251390286Sobrien   ror{b}\t{%b2, %0|%0, %b2}"
1251490286Sobrien  [(set_attr "type" "ishift")
1251590286Sobrien   (set_attr "mode" "QI")])
1251690286Sobrien
1251790286Sobrien;; Bit set / bit test instructions
1251818334Speter
1251990286Sobrien(define_expand "extv"
1252090286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1252190286Sobrien	(sign_extract:SI (match_operand:SI 1 "register_operand" "")
1252290286Sobrien			 (match_operand:SI 2 "immediate_operand" "")
1252390286Sobrien			 (match_operand:SI 3 "immediate_operand" "")))]
1252490286Sobrien  ""
1252518334Speter{
1252690286Sobrien  /* Handle extractions from %ah et al.  */
1252790286Sobrien  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
1252890286Sobrien    FAIL;
1252918334Speter
1253090286Sobrien  /* From mips.md: extract_bit_field doesn't verify that our source
1253190286Sobrien     matches the predicate, so check it again here.  */
1253290286Sobrien  if (! register_operand (operands[1], VOIDmode))
1253390286Sobrien    FAIL;
1253490286Sobrien})
1253518334Speter
1253690286Sobrien(define_expand "extzv"
1253790286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1253890286Sobrien	(zero_extract:SI (match_operand 1 "ext_register_operand" "")
1253990286Sobrien			 (match_operand:SI 2 "immediate_operand" "")
1254090286Sobrien			 (match_operand:SI 3 "immediate_operand" "")))]
1254190286Sobrien  ""
1254290286Sobrien{
1254390286Sobrien  /* Handle extractions from %ah et al.  */
1254490286Sobrien  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
1254590286Sobrien    FAIL;
1254618334Speter
1254790286Sobrien  /* From mips.md: extract_bit_field doesn't verify that our source
1254890286Sobrien     matches the predicate, so check it again here.  */
1254990286Sobrien  if (! register_operand (operands[1], VOIDmode))
1255090286Sobrien    FAIL;
1255190286Sobrien})
1255218334Speter
1255390286Sobrien(define_expand "insv"
1255490286Sobrien  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
1255590286Sobrien			 (match_operand:SI 1 "immediate_operand" "")
1255690286Sobrien			 (match_operand:SI 2 "immediate_operand" ""))
1255790286Sobrien        (match_operand:SI 3 "register_operand" ""))]
1255890286Sobrien  ""
1255990286Sobrien{
1256090286Sobrien  /* Handle extractions from %ah et al.  */
1256190286Sobrien  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
1256290286Sobrien    FAIL;
1256318334Speter
1256490286Sobrien  /* From mips.md: insert_bit_field doesn't verify that our source
1256590286Sobrien     matches the predicate, so check it again here.  */
1256690286Sobrien  if (! register_operand (operands[0], VOIDmode))
1256790286Sobrien    FAIL;
1256890286Sobrien})
1256918334Speter
1257090286Sobrien;; %%% bts, btr, btc, bt.
1257118334Speter
1257218334Speter;; Store-flag instructions.
1257318334Speter
1257418334Speter;; For all sCOND expanders, also expand the compare or test insn that
1257518334Speter;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
1257618334Speter
1257790286Sobrien;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
1257890286Sobrien;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
1257990286Sobrien;; way, which can later delete the movzx if only QImode is needed.
1258090286Sobrien
1258118334Speter(define_expand "seq"
1258290286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1258390286Sobrien        (eq:QI (reg:CC 17) (const_int 0)))]
1258418334Speter  ""
1258590286Sobrien  "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
1258618334Speter
1258718334Speter(define_expand "sne"
1258890286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1258990286Sobrien        (ne:QI (reg:CC 17) (const_int 0)))]
1259018334Speter  ""
1259190286Sobrien  "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
1259218334Speter
1259318334Speter(define_expand "sgt"
1259490286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1259590286Sobrien        (gt:QI (reg:CC 17) (const_int 0)))]
1259618334Speter  ""
1259790286Sobrien  "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
1259818334Speter
1259918334Speter(define_expand "sgtu"
1260090286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1260190286Sobrien        (gtu:QI (reg:CC 17) (const_int 0)))]
1260218334Speter  ""
1260390286Sobrien  "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
1260418334Speter
1260518334Speter(define_expand "slt"
1260690286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1260790286Sobrien        (lt:QI (reg:CC 17) (const_int 0)))]
1260818334Speter  ""
1260990286Sobrien  "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
1261018334Speter
1261118334Speter(define_expand "sltu"
1261290286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1261390286Sobrien        (ltu:QI (reg:CC 17) (const_int 0)))]
1261418334Speter  ""
1261590286Sobrien  "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
1261618334Speter
1261718334Speter(define_expand "sge"
1261890286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1261990286Sobrien        (ge:QI (reg:CC 17) (const_int 0)))]
1262018334Speter  ""
1262190286Sobrien  "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
1262218334Speter
1262318334Speter(define_expand "sgeu"
1262490286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1262590286Sobrien        (geu:QI (reg:CC 17) (const_int 0)))]
1262618334Speter  ""
1262790286Sobrien  "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
1262818334Speter
1262918334Speter(define_expand "sle"
1263090286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1263190286Sobrien        (le:QI (reg:CC 17) (const_int 0)))]
1263218334Speter  ""
1263390286Sobrien  "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
1263418334Speter
1263518334Speter(define_expand "sleu"
1263690286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1263790286Sobrien        (leu:QI (reg:CC 17) (const_int 0)))]
1263818334Speter  ""
1263990286Sobrien  "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
1264018334Speter
1264190286Sobrien(define_expand "sunordered"
1264290286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1264390286Sobrien        (unordered:QI (reg:CC 17) (const_int 0)))]
1264490286Sobrien  "TARGET_80387 || TARGET_SSE"
1264590286Sobrien  "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
1264652296Sobrien
1264790286Sobrien(define_expand "sordered"
1264890286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1264990286Sobrien        (ordered:QI (reg:CC 17) (const_int 0)))]
1265090286Sobrien  "TARGET_80387"
1265190286Sobrien  "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
1265290286Sobrien
1265390286Sobrien(define_expand "suneq"
1265490286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1265590286Sobrien        (uneq:QI (reg:CC 17) (const_int 0)))]
1265690286Sobrien  "TARGET_80387 || TARGET_SSE"
1265790286Sobrien  "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
1265890286Sobrien
1265990286Sobrien(define_expand "sunge"
1266090286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1266190286Sobrien        (unge:QI (reg:CC 17) (const_int 0)))]
1266290286Sobrien  "TARGET_80387 || TARGET_SSE"
1266390286Sobrien  "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
1266490286Sobrien
1266590286Sobrien(define_expand "sungt"
1266690286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1266790286Sobrien        (ungt:QI (reg:CC 17) (const_int 0)))]
1266890286Sobrien  "TARGET_80387 || TARGET_SSE"
1266990286Sobrien  "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
1267090286Sobrien
1267190286Sobrien(define_expand "sunle"
1267290286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1267390286Sobrien        (unle:QI (reg:CC 17) (const_int 0)))]
1267490286Sobrien  "TARGET_80387 || TARGET_SSE"
1267590286Sobrien  "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
1267690286Sobrien
1267790286Sobrien(define_expand "sunlt"
1267890286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1267990286Sobrien        (unlt:QI (reg:CC 17) (const_int 0)))]
1268090286Sobrien  "TARGET_80387 || TARGET_SSE"
1268190286Sobrien  "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
1268290286Sobrien
1268390286Sobrien(define_expand "sltgt"
1268490286Sobrien  [(set (match_operand:QI 0 "register_operand" "")
1268590286Sobrien        (ltgt:QI (reg:CC 17) (const_int 0)))]
1268690286Sobrien  "TARGET_80387 || TARGET_SSE"
1268790286Sobrien  "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
1268890286Sobrien
1268990286Sobrien(define_insn "*setcc_1"
1269052296Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
1269190286Sobrien	(match_operator:QI 1 "ix86_comparison_operator"
1269290286Sobrien	  [(reg 17) (const_int 0)]))]
1269390286Sobrien  ""
1269490286Sobrien  "set%C1\t%0"
1269590286Sobrien  [(set_attr "type" "setcc")
1269690286Sobrien   (set_attr "mode" "QI")])
1269790286Sobrien
1269890286Sobrien(define_insn "setcc_2"
1269990286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
1270090286Sobrien	(match_operator:QI 1 "ix86_comparison_operator"
1270190286Sobrien	  [(reg 17) (const_int 0)]))]
1270290286Sobrien  ""
1270390286Sobrien  "set%C1\t%0"
1270490286Sobrien  [(set_attr "type" "setcc")
1270590286Sobrien   (set_attr "mode" "QI")])
1270690286Sobrien
1270790286Sobrien;; In general it is not safe to assume too much about CCmode registers,
1270890286Sobrien;; so simplify-rtx stops when it sees a second one.  Under certain 
1270990286Sobrien;; conditions this is safe on x86, so help combine not create
1271090286Sobrien;;
1271190286Sobrien;;	seta	%al
1271290286Sobrien;;	testb	%al, %al
1271390286Sobrien;;	sete	%al
1271490286Sobrien
1271590286Sobrien(define_split 
1271690286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1271790286Sobrien	(ne:QI (match_operator 1 "ix86_comparison_operator"
1271890286Sobrien	         [(reg 17) (const_int 0)])
1271990286Sobrien	    (const_int 0)))]
1272090286Sobrien  ""
1272190286Sobrien  [(set (match_dup 0) (match_dup 1))]
1272252296Sobrien{
1272390286Sobrien  PUT_MODE (operands[1], QImode);
1272490286Sobrien})
1272552296Sobrien
1272690286Sobrien(define_split 
1272790286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1272890286Sobrien	(ne:QI (match_operator 1 "ix86_comparison_operator"
1272990286Sobrien	         [(reg 17) (const_int 0)])
1273090286Sobrien	    (const_int 0)))]
1273190286Sobrien  ""
1273290286Sobrien  [(set (match_dup 0) (match_dup 1))]
1273390286Sobrien{
1273490286Sobrien  PUT_MODE (operands[1], QImode);
1273590286Sobrien})
1273652296Sobrien
1273790286Sobrien(define_split 
1273890286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1273990286Sobrien	(eq:QI (match_operator 1 "ix86_comparison_operator"
1274090286Sobrien	         [(reg 17) (const_int 0)])
1274190286Sobrien	    (const_int 0)))]
1274290286Sobrien  ""
1274390286Sobrien  [(set (match_dup 0) (match_dup 1))]
1274490286Sobrien{
1274590286Sobrien  rtx new_op1 = copy_rtx (operands[1]);
1274690286Sobrien  operands[1] = new_op1;
1274790286Sobrien  PUT_MODE (new_op1, QImode);
1274890286Sobrien  PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
1274990286Sobrien					GET_MODE (XEXP (new_op1, 0))));
1275090286Sobrien
1275190286Sobrien  /* Make sure that (a) the CCmode we have for the flags is strong
1275290286Sobrien     enough for the reversed compare or (b) we have a valid FP compare.  */
1275390286Sobrien  if (! ix86_comparison_operator (new_op1, VOIDmode))
1275490286Sobrien    FAIL;
1275590286Sobrien})
1275690286Sobrien
1275790286Sobrien(define_split 
1275890286Sobrien  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1275990286Sobrien	(eq:QI (match_operator 1 "ix86_comparison_operator"
1276090286Sobrien	         [(reg 17) (const_int 0)])
1276190286Sobrien	    (const_int 0)))]
1276290286Sobrien  ""
1276390286Sobrien  [(set (match_dup 0) (match_dup 1))]
1276490286Sobrien{
1276590286Sobrien  rtx new_op1 = copy_rtx (operands[1]);
1276690286Sobrien  operands[1] = new_op1;
1276790286Sobrien  PUT_MODE (new_op1, QImode);
1276890286Sobrien  PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
1276990286Sobrien					GET_MODE (XEXP (new_op1, 0))));
1277090286Sobrien
1277190286Sobrien  /* Make sure that (a) the CCmode we have for the flags is strong
1277290286Sobrien     enough for the reversed compare or (b) we have a valid FP compare.  */
1277390286Sobrien  if (! ix86_comparison_operator (new_op1, VOIDmode))
1277490286Sobrien    FAIL;
1277590286Sobrien})
1277690286Sobrien
1277790286Sobrien;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
1277890286Sobrien;; subsequent logical operations are used to imitate conditional moves.
1277990286Sobrien;; 0xffffffff is NaN, but not in normalized form, so we can't represent
1278090286Sobrien;; it directly.  Futher holding this value in pseudo register might bring
1278190286Sobrien;; problem in implicit normalization in spill code.
1278290286Sobrien;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
1278390286Sobrien;; instructions after reload by splitting the conditional move patterns.
1278490286Sobrien
1278590286Sobrien(define_insn "*sse_setccsf"
1278690286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1278790286Sobrien	(match_operator:SF 1 "sse_comparison_operator"
1278890286Sobrien	  [(match_operand:SF 2 "register_operand" "0")
1278990286Sobrien	   (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
1279090286Sobrien  "TARGET_SSE && reload_completed"
1279190286Sobrien  "cmp%D1ss\t{%3, %0|%0, %3}"
1279290286Sobrien  [(set_attr "type" "sse")
1279390286Sobrien   (set_attr "mode" "SF")])
1279490286Sobrien
1279590286Sobrien(define_insn "*sse_setccdf"
1279690286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1279790286Sobrien	(match_operator:DF 1 "sse_comparison_operator"
1279890286Sobrien	  [(match_operand:DF 2 "register_operand" "0")
1279990286Sobrien	   (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
1280090286Sobrien  "TARGET_SSE2 && reload_completed"
1280190286Sobrien  "cmp%D1sd\t{%3, %0|%0, %3}"
1280290286Sobrien  [(set_attr "type" "sse")
1280390286Sobrien   (set_attr "mode" "DF")])
1280418334Speter
1280518334Speter;; Basic conditional jump instructions.
1280618334Speter;; We ignore the overflow flag for signed branch instructions.
1280718334Speter
1280818334Speter;; For all bCOND expanders, also expand the compare or test insn that
1280990286Sobrien;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
1281018334Speter
1281118334Speter(define_expand "beq"
1281290286Sobrien  [(set (pc)
1281390286Sobrien	(if_then_else (match_dup 1)
1281418334Speter		      (label_ref (match_operand 0 "" ""))
1281518334Speter		      (pc)))]
1281618334Speter  ""
1281790286Sobrien  "ix86_expand_branch (EQ, operands[0]); DONE;")
1281818334Speter
1281918334Speter(define_expand "bne"
1282090286Sobrien  [(set (pc)
1282190286Sobrien	(if_then_else (match_dup 1)
1282218334Speter		      (label_ref (match_operand 0 "" ""))
1282318334Speter		      (pc)))]
1282418334Speter  ""
1282590286Sobrien  "ix86_expand_branch (NE, operands[0]); DONE;")
1282618334Speter
1282718334Speter(define_expand "bgt"
1282890286Sobrien  [(set (pc)
1282990286Sobrien	(if_then_else (match_dup 1)
1283018334Speter		      (label_ref (match_operand 0 "" ""))
1283118334Speter		      (pc)))]
1283218334Speter  ""
1283390286Sobrien  "ix86_expand_branch (GT, operands[0]); DONE;")
1283418334Speter
1283518334Speter(define_expand "bgtu"
1283690286Sobrien  [(set (pc)
1283790286Sobrien	(if_then_else (match_dup 1)
1283818334Speter		      (label_ref (match_operand 0 "" ""))
1283918334Speter		      (pc)))]
1284018334Speter  ""
1284190286Sobrien  "ix86_expand_branch (GTU, operands[0]); DONE;")
1284218334Speter
1284318334Speter(define_expand "blt"
1284490286Sobrien  [(set (pc)
1284590286Sobrien	(if_then_else (match_dup 1)
1284618334Speter		      (label_ref (match_operand 0 "" ""))
1284718334Speter		      (pc)))]
1284818334Speter  ""
1284990286Sobrien  "ix86_expand_branch (LT, operands[0]); DONE;")
1285018334Speter
1285118334Speter(define_expand "bltu"
1285290286Sobrien  [(set (pc)
1285390286Sobrien	(if_then_else (match_dup 1)
1285418334Speter		      (label_ref (match_operand 0 "" ""))
1285518334Speter		      (pc)))]
1285618334Speter  ""
1285790286Sobrien  "ix86_expand_branch (LTU, operands[0]); DONE;")
1285818334Speter
1285918334Speter(define_expand "bge"
1286090286Sobrien  [(set (pc)
1286190286Sobrien	(if_then_else (match_dup 1)
1286218334Speter		      (label_ref (match_operand 0 "" ""))
1286318334Speter		      (pc)))]
1286418334Speter  ""
1286590286Sobrien  "ix86_expand_branch (GE, operands[0]); DONE;")
1286618334Speter
1286718334Speter(define_expand "bgeu"
1286890286Sobrien  [(set (pc)
1286990286Sobrien	(if_then_else (match_dup 1)
1287018334Speter		      (label_ref (match_operand 0 "" ""))
1287118334Speter		      (pc)))]
1287218334Speter  ""
1287390286Sobrien  "ix86_expand_branch (GEU, operands[0]); DONE;")
1287418334Speter
1287518334Speter(define_expand "ble"
1287690286Sobrien  [(set (pc)
1287790286Sobrien	(if_then_else (match_dup 1)
1287818334Speter		      (label_ref (match_operand 0 "" ""))
1287918334Speter		      (pc)))]
1288018334Speter  ""
1288190286Sobrien  "ix86_expand_branch (LE, operands[0]); DONE;")
1288218334Speter
1288318334Speter(define_expand "bleu"
1288490286Sobrien  [(set (pc)
1288590286Sobrien	(if_then_else (match_dup 1)
1288618334Speter		      (label_ref (match_operand 0 "" ""))
1288718334Speter		      (pc)))]
1288818334Speter  ""
1288990286Sobrien  "ix86_expand_branch (LEU, operands[0]); DONE;")
1289018334Speter
1289190286Sobrien(define_expand "bunordered"
1289218334Speter  [(set (pc)
1289390286Sobrien	(if_then_else (match_dup 1)
1289490286Sobrien		      (label_ref (match_operand 0 "" ""))
1289518334Speter		      (pc)))]
1289690286Sobrien  "TARGET_80387 || TARGET_SSE"
1289790286Sobrien  "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
1289818334Speter
1289990286Sobrien(define_expand "bordered"
1290090286Sobrien  [(set (pc)
1290190286Sobrien	(if_then_else (match_dup 1)
1290290286Sobrien		      (label_ref (match_operand 0 "" ""))
1290390286Sobrien		      (pc)))]
1290490286Sobrien  "TARGET_80387 || TARGET_SSE"
1290590286Sobrien  "ix86_expand_branch (ORDERED, operands[0]); DONE;")
1290618334Speter
1290790286Sobrien(define_expand "buneq"
1290818334Speter  [(set (pc)
1290990286Sobrien	(if_then_else (match_dup 1)
1291090286Sobrien		      (label_ref (match_operand 0 "" ""))
1291190286Sobrien		      (pc)))]
1291290286Sobrien  "TARGET_80387 || TARGET_SSE"
1291390286Sobrien  "ix86_expand_branch (UNEQ, operands[0]); DONE;")
1291418334Speter
1291590286Sobrien(define_expand "bunge"
1291690286Sobrien  [(set (pc)
1291790286Sobrien	(if_then_else (match_dup 1)
1291890286Sobrien		      (label_ref (match_operand 0 "" ""))
1291990286Sobrien		      (pc)))]
1292090286Sobrien  "TARGET_80387 || TARGET_SSE"
1292190286Sobrien  "ix86_expand_branch (UNGE, operands[0]); DONE;")
1292218334Speter
1292390286Sobrien(define_expand "bungt"
1292418334Speter  [(set (pc)
1292590286Sobrien	(if_then_else (match_dup 1)
1292690286Sobrien		      (label_ref (match_operand 0 "" ""))
1292790286Sobrien		      (pc)))]
1292890286Sobrien  "TARGET_80387 || TARGET_SSE"
1292990286Sobrien  "ix86_expand_branch (UNGT, operands[0]); DONE;")
1293018334Speter
1293190286Sobrien(define_expand "bunle"
1293290286Sobrien  [(set (pc)
1293390286Sobrien	(if_then_else (match_dup 1)
1293490286Sobrien		      (label_ref (match_operand 0 "" ""))
1293590286Sobrien		      (pc)))]
1293690286Sobrien  "TARGET_80387 || TARGET_SSE"
1293790286Sobrien  "ix86_expand_branch (UNLE, operands[0]); DONE;")
1293818334Speter
1293990286Sobrien(define_expand "bunlt"
1294090286Sobrien  [(set (pc)
1294190286Sobrien	(if_then_else (match_dup 1)
1294290286Sobrien		      (label_ref (match_operand 0 "" ""))
1294390286Sobrien		      (pc)))]
1294490286Sobrien  "TARGET_80387 || TARGET_SSE"
1294590286Sobrien  "ix86_expand_branch (UNLT, operands[0]); DONE;")
1294618334Speter
1294790286Sobrien(define_expand "bltgt"
1294890286Sobrien  [(set (pc)
1294990286Sobrien	(if_then_else (match_dup 1)
1295090286Sobrien		      (label_ref (match_operand 0 "" ""))
1295190286Sobrien		      (pc)))]
1295290286Sobrien  "TARGET_80387 || TARGET_SSE"
1295390286Sobrien  "ix86_expand_branch (LTGT, operands[0]); DONE;")
1295418334Speter
1295590286Sobrien(define_insn "*jcc_1"
1295690286Sobrien  [(set (pc)
1295790286Sobrien	(if_then_else (match_operator 1 "ix86_comparison_operator"
1295890286Sobrien				      [(reg 17) (const_int 0)])
1295990286Sobrien		      (label_ref (match_operand 0 "" ""))
1296090286Sobrien		      (pc)))]
1296118334Speter  ""
1296290286Sobrien  "%+j%C1\t%l0"
1296390286Sobrien  [(set_attr "type" "ibr")
1296490286Sobrien   (set (attr "prefix_0f")
1296590286Sobrien	   (if_then_else (and (ge (minus (match_dup 0) (pc))
1296690286Sobrien				  (const_int -128))
1296790286Sobrien			      (lt (minus (match_dup 0) (pc))
1296890286Sobrien				  (const_int 124)))
1296990286Sobrien	     (const_int 0)
1297090286Sobrien	     (const_int 1)))])
1297118334Speter
1297290286Sobrien(define_insn "*jcc_2"
1297318334Speter  [(set (pc)
1297490286Sobrien	(if_then_else (match_operator 1 "ix86_comparison_operator"
1297590286Sobrien				      [(reg 17) (const_int 0)])
1297690286Sobrien		      (pc)
1297790286Sobrien		      (label_ref (match_operand 0 "" ""))))]
1297818334Speter  ""
1297990286Sobrien  "%+j%c1\t%l0"
1298090286Sobrien  [(set_attr "type" "ibr")
1298190286Sobrien   (set (attr "prefix_0f")
1298290286Sobrien	   (if_then_else (and (ge (minus (match_dup 0) (pc))
1298390286Sobrien				  (const_int -128))
1298490286Sobrien			      (lt (minus (match_dup 0) (pc))
1298590286Sobrien				  (const_int 124)))
1298690286Sobrien	     (const_int 0)
1298790286Sobrien	     (const_int 1)))])
1298890286Sobrien
1298990286Sobrien;; In general it is not safe to assume too much about CCmode registers,
1299090286Sobrien;; so simplify-rtx stops when it sees a second one.  Under certain 
1299190286Sobrien;; conditions this is safe on x86, so help combine not create
1299290286Sobrien;;
1299390286Sobrien;;	seta	%al
1299490286Sobrien;;	testb	%al, %al
1299590286Sobrien;;	je	Lfoo
1299690286Sobrien
1299790286Sobrien(define_split 
1299890286Sobrien  [(set (pc)
1299990286Sobrien	(if_then_else (ne (match_operator 0 "ix86_comparison_operator"
1300090286Sobrien				      [(reg 17) (const_int 0)])
1300190286Sobrien			  (const_int 0))
1300290286Sobrien		      (label_ref (match_operand 1 "" ""))
1300390286Sobrien		      (pc)))]
1300490286Sobrien  ""
1300590286Sobrien  [(set (pc)
1300690286Sobrien	(if_then_else (match_dup 0)
1300790286Sobrien		      (label_ref (match_dup 1))
1300890286Sobrien		      (pc)))]
1300918334Speter{
1301090286Sobrien  PUT_MODE (operands[0], VOIDmode);
1301190286Sobrien})
1301290286Sobrien  
1301390286Sobrien(define_split 
1301490286Sobrien  [(set (pc)
1301590286Sobrien	(if_then_else (eq (match_operator 0 "ix86_comparison_operator"
1301690286Sobrien				      [(reg 17) (const_int 0)])
1301790286Sobrien			  (const_int 0))
1301890286Sobrien		      (label_ref (match_operand 1 "" ""))
1301990286Sobrien		      (pc)))]
1302090286Sobrien  ""
1302190286Sobrien  [(set (pc)
1302290286Sobrien	(if_then_else (match_dup 0)
1302390286Sobrien		      (label_ref (match_dup 1))
1302490286Sobrien		      (pc)))]
1302590286Sobrien{
1302690286Sobrien  rtx new_op0 = copy_rtx (operands[0]);
1302790286Sobrien  operands[0] = new_op0;
1302890286Sobrien  PUT_MODE (new_op0, VOIDmode);
1302990286Sobrien  PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
1303090286Sobrien					GET_MODE (XEXP (new_op0, 0))));
1303152296Sobrien
1303290286Sobrien  /* Make sure that (a) the CCmode we have for the flags is strong
1303390286Sobrien     enough for the reversed compare or (b) we have a valid FP compare.  */
1303490286Sobrien  if (! ix86_comparison_operator (new_op0, VOIDmode))
1303590286Sobrien    FAIL;
1303690286Sobrien})
1303752296Sobrien
1303890286Sobrien;; Define combination compare-and-branch fp compare instructions to use
1303990286Sobrien;; during early optimization.  Splitting the operation apart early makes
1304090286Sobrien;; for bad code when we want to reverse the operation.
1304118334Speter
1304290286Sobrien(define_insn "*fp_jcc_1"
1304390286Sobrien  [(set (pc)
1304490286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1304590286Sobrien			[(match_operand 1 "register_operand" "f")
1304690286Sobrien			 (match_operand 2 "register_operand" "f")])
1304790286Sobrien	  (label_ref (match_operand 3 "" ""))
1304890286Sobrien	  (pc)))
1304990286Sobrien   (clobber (reg:CCFP 18))
1305090286Sobrien   (clobber (reg:CCFP 17))]
1305190286Sobrien  "TARGET_CMOVE && TARGET_80387
1305290286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1305390286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
1305490286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1305590286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1305690286Sobrien  "#")
1305718334Speter
1305890286Sobrien(define_insn "*fp_jcc_1_sse"
1305990286Sobrien  [(set (pc)
1306090286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1306190286Sobrien			[(match_operand 1 "register_operand" "f#x,x#f")
1306290286Sobrien			 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
1306390286Sobrien	  (label_ref (match_operand 3 "" ""))
1306490286Sobrien	  (pc)))
1306590286Sobrien   (clobber (reg:CCFP 18))
1306690286Sobrien   (clobber (reg:CCFP 17))]
1306790286Sobrien  "TARGET_80387
1306890286Sobrien   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1306990286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1307090286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1307190286Sobrien  "#")
1307218334Speter
1307390286Sobrien(define_insn "*fp_jcc_1_sse_only"
1307490286Sobrien  [(set (pc)
1307590286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1307690286Sobrien			[(match_operand 1 "register_operand" "x")
1307790286Sobrien			 (match_operand 2 "nonimmediate_operand" "xm")])
1307890286Sobrien	  (label_ref (match_operand 3 "" ""))
1307990286Sobrien	  (pc)))
1308090286Sobrien   (clobber (reg:CCFP 18))
1308190286Sobrien   (clobber (reg:CCFP 17))]
1308290286Sobrien  "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1308390286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1308490286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1308590286Sobrien  "#")
1308618334Speter
1308790286Sobrien(define_insn "*fp_jcc_2"
1308818334Speter  [(set (pc)
1308990286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1309090286Sobrien			[(match_operand 1 "register_operand" "f")
1309190286Sobrien			 (match_operand 2 "register_operand" "f")])
1309290286Sobrien	  (pc)
1309390286Sobrien	  (label_ref (match_operand 3 "" ""))))
1309490286Sobrien   (clobber (reg:CCFP 18))
1309590286Sobrien   (clobber (reg:CCFP 17))]
1309690286Sobrien  "TARGET_CMOVE && TARGET_80387
1309790286Sobrien   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1309890286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
1309990286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1310090286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1310190286Sobrien  "#")
1310218334Speter
1310390286Sobrien(define_insn "*fp_jcc_2_sse"
1310490286Sobrien  [(set (pc)
1310590286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1310690286Sobrien			[(match_operand 1 "register_operand" "f#x,x#f")
1310790286Sobrien			 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
1310890286Sobrien	  (pc)
1310990286Sobrien	  (label_ref (match_operand 3 "" ""))))
1311090286Sobrien   (clobber (reg:CCFP 18))
1311190286Sobrien   (clobber (reg:CCFP 17))]
1311290286Sobrien  "TARGET_80387
1311390286Sobrien   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1311490286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1311590286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1311690286Sobrien  "#")
1311718334Speter
1311890286Sobrien(define_insn "*fp_jcc_2_sse_only"
1311990286Sobrien  [(set (pc)
1312090286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1312190286Sobrien			[(match_operand 1 "register_operand" "x")
1312290286Sobrien			 (match_operand 2 "nonimmediate_operand" "xm")])
1312390286Sobrien	  (pc)
1312490286Sobrien	  (label_ref (match_operand 3 "" ""))))
1312590286Sobrien   (clobber (reg:CCFP 18))
1312690286Sobrien   (clobber (reg:CCFP 17))]
1312790286Sobrien  "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
1312890286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1312990286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1313090286Sobrien  "#")
1313118334Speter
1313290286Sobrien(define_insn "*fp_jcc_3"
1313390286Sobrien  [(set (pc)
1313490286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1313590286Sobrien			[(match_operand 1 "register_operand" "f")
1313690286Sobrien			 (match_operand 2 "nonimmediate_operand" "fm")])
1313790286Sobrien	  (label_ref (match_operand 3 "" ""))
1313890286Sobrien	  (pc)))
1313990286Sobrien   (clobber (reg:CCFP 18))
1314090286Sobrien   (clobber (reg:CCFP 17))
1314190286Sobrien   (clobber (match_scratch:HI 4 "=a"))]
1314290286Sobrien  "TARGET_80387
1314390286Sobrien   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
1314490286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1314590286Sobrien   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
1314690286Sobrien   && SELECT_CC_MODE (GET_CODE (operands[0]),
1314790286Sobrien		      operands[1], operands[2]) == CCFPmode
1314890286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1314990286Sobrien  "#")
1315018334Speter
1315190286Sobrien(define_insn "*fp_jcc_4"
1315250650Sobrien  [(set (pc)
1315390286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1315490286Sobrien			[(match_operand 1 "register_operand" "f")
1315590286Sobrien			 (match_operand 2 "nonimmediate_operand" "fm")])
1315690286Sobrien	  (pc)
1315790286Sobrien	  (label_ref (match_operand 3 "" ""))))
1315890286Sobrien   (clobber (reg:CCFP 18))
1315990286Sobrien   (clobber (reg:CCFP 17))
1316090286Sobrien   (clobber (match_scratch:HI 4 "=a"))]
1316190286Sobrien  "TARGET_80387
1316290286Sobrien   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
1316390286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1316490286Sobrien   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
1316590286Sobrien   && SELECT_CC_MODE (GET_CODE (operands[0]),
1316690286Sobrien		      operands[1], operands[2]) == CCFPmode
1316790286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1316890286Sobrien  "#")
1316950650Sobrien
1317090286Sobrien(define_insn "*fp_jcc_5"
1317150650Sobrien  [(set (pc)
1317290286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1317390286Sobrien			[(match_operand 1 "register_operand" "f")
1317490286Sobrien			 (match_operand 2 "register_operand" "f")])
1317590286Sobrien	  (label_ref (match_operand 3 "" ""))
1317690286Sobrien	  (pc)))
1317790286Sobrien   (clobber (reg:CCFP 18))
1317890286Sobrien   (clobber (reg:CCFP 17))
1317990286Sobrien   (clobber (match_scratch:HI 4 "=a"))]
1318090286Sobrien  "TARGET_80387
1318190286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
1318290286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1318390286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1318490286Sobrien  "#")
1318550650Sobrien
1318690286Sobrien(define_insn "*fp_jcc_6"
1318750650Sobrien  [(set (pc)
1318890286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1318990286Sobrien			[(match_operand 1 "register_operand" "f")
1319090286Sobrien			 (match_operand 2 "register_operand" "f")])
1319190286Sobrien	  (pc)
1319290286Sobrien	  (label_ref (match_operand 3 "" ""))))
1319390286Sobrien   (clobber (reg:CCFP 18))
1319490286Sobrien   (clobber (reg:CCFP 17))
1319590286Sobrien   (clobber (match_scratch:HI 4 "=a"))]
1319690286Sobrien  "TARGET_80387
1319790286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[1]))
1319890286Sobrien   && GET_MODE (operands[1]) == GET_MODE (operands[2])
1319990286Sobrien   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
1320090286Sobrien  "#")
1320150650Sobrien
1320290286Sobrien(define_split
1320350650Sobrien  [(set (pc)
1320490286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1320590286Sobrien			[(match_operand 1 "register_operand" "")
1320690286Sobrien			 (match_operand 2 "nonimmediate_operand" "")])
1320790286Sobrien	  (match_operand 3 "" "")
1320890286Sobrien	  (match_operand 4 "" "")))
1320990286Sobrien   (clobber (reg:CCFP 18))
1321090286Sobrien   (clobber (reg:CCFP 17))]
1321190286Sobrien  "reload_completed"
1321290286Sobrien  [(const_int 0)]
1321350650Sobrien{
1321490286Sobrien  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
1321590286Sobrien			operands[3], operands[4], NULL_RTX);
1321690286Sobrien  DONE;
1321790286Sobrien})
1321850650Sobrien
1321990286Sobrien(define_split
1322050650Sobrien  [(set (pc)
1322190286Sobrien	(if_then_else (match_operator 0 "comparison_operator"
1322290286Sobrien			[(match_operand 1 "register_operand" "")
1322390286Sobrien			 (match_operand 2 "nonimmediate_operand" "")])
1322490286Sobrien	  (match_operand 3 "" "")
1322590286Sobrien	  (match_operand 4 "" "")))
1322690286Sobrien   (clobber (reg:CCFP 18))
1322790286Sobrien   (clobber (reg:CCFP 17))
1322890286Sobrien   (clobber (match_scratch:HI 5 "=a"))]
1322990286Sobrien  "reload_completed"
1323090286Sobrien  [(set (pc)
1323190286Sobrien	(if_then_else (match_dup 6)
1323290286Sobrien	  (match_dup 3)
1323390286Sobrien	  (match_dup 4)))]
1323450650Sobrien{
1323590286Sobrien  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
1323690286Sobrien			operands[3], operands[4], operands[5]);
1323790286Sobrien  DONE;
1323890286Sobrien})
1323990286Sobrien
1324090286Sobrien;; Unconditional and other jump instructions
1324150650Sobrien
1324290286Sobrien(define_insn "jump"
1324350650Sobrien  [(set (pc)
1324490286Sobrien	(label_ref (match_operand 0 "" "")))]
1324550650Sobrien  ""
1324690286Sobrien  "jmp\t%l0"
1324790286Sobrien  [(set_attr "type" "ibr")])
1324890286Sobrien
1324990286Sobrien(define_expand "indirect_jump"
1325090286Sobrien  [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
1325190286Sobrien  ""
1325290286Sobrien  "")
1325390286Sobrien
1325490286Sobrien(define_insn "*indirect_jump"
1325590286Sobrien  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
1325690286Sobrien  "!TARGET_64BIT"
1325790286Sobrien  "jmp\t%A0"
1325890286Sobrien  [(set_attr "type" "ibr")
1325990286Sobrien   (set_attr "length_immediate" "0")])
1326090286Sobrien
1326190286Sobrien(define_insn "*indirect_jump_rtx64"
1326290286Sobrien  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
1326390286Sobrien  "TARGET_64BIT"
1326490286Sobrien  "jmp\t%A0"
1326590286Sobrien  [(set_attr "type" "ibr")
1326690286Sobrien   (set_attr "length_immediate" "0")])
1326790286Sobrien
1326890286Sobrien(define_expand "tablejump"
1326990286Sobrien  [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
1327090286Sobrien	      (use (label_ref (match_operand 1 "" "")))])]
1327190286Sobrien  ""
1327250650Sobrien{
1327390286Sobrien  /* In PIC mode, the table entries are stored GOT-relative.  Convert
1327490286Sobrien     the relative address to an absolute address.  */
1327590286Sobrien  if (flag_pic)
1327690286Sobrien    {
1327790286Sobrien      if (TARGET_64BIT)
1327890286Sobrien	operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1327990286Sobrien					   gen_rtx_LABEL_REF (Pmode, operands[1]),
1328090286Sobrien					   NULL_RTX, 0,
1328190286Sobrien					   OPTAB_DIRECT);
1328290286Sobrien      else if (HAVE_AS_GOTOFF_IN_DATA)
1328390286Sobrien	{
1328490286Sobrien	  operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
1328590286Sobrien					     pic_offset_table_rtx, NULL_RTX,
1328690286Sobrien					     1, OPTAB_DIRECT);
1328790286Sobrien	  current_function_uses_pic_offset_table = 1;
1328890286Sobrien	}
1328990286Sobrien      else
1329090286Sobrien	{
1329190286Sobrien	  operands[0] = expand_simple_binop (Pmode, MINUS, pic_offset_table_rtx,
1329290286Sobrien					     operands[0], NULL_RTX, 1,
1329390286Sobrien					     OPTAB_DIRECT);
1329490286Sobrien	  current_function_uses_pic_offset_table = 1;
1329590286Sobrien	}
1329690286Sobrien    }
1329790286Sobrien})
1329850650Sobrien
1329990286Sobrien(define_insn "*tablejump_1"
1330090286Sobrien  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
1330190286Sobrien   (use (label_ref (match_operand 1 "" "")))]
1330290286Sobrien  "!TARGET_64BIT"
1330390286Sobrien  "jmp\t%A0"
1330490286Sobrien  [(set_attr "type" "ibr")
1330590286Sobrien   (set_attr "length_immediate" "0")])
1330618334Speter
1330790286Sobrien(define_insn "*tablejump_1_rtx64"
1330890286Sobrien  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
1330990286Sobrien   (use (label_ref (match_operand 1 "" "")))]
1331090286Sobrien  "TARGET_64BIT"
1331190286Sobrien  "jmp\t%A0"
1331290286Sobrien  [(set_attr "type" "ibr")
1331390286Sobrien   (set_attr "length_immediate" "0")])
1331490286Sobrien
1331590286Sobrien;; Loop instruction
1331690286Sobrien;;
1331790286Sobrien;; This is all complicated by the fact that since this is a jump insn
1331890286Sobrien;; we must handle our own reloads.
1331918334Speter
1332090286Sobrien(define_expand "doloop_end"
1332190286Sobrien  [(use (match_operand 0 "" ""))        ; loop pseudo
1332290286Sobrien   (use (match_operand 1 "" ""))        ; iterations; zero if unknown
1332390286Sobrien   (use (match_operand 2 "" ""))        ; max iterations
1332490286Sobrien   (use (match_operand 3 "" ""))        ; loop level 
1332590286Sobrien   (use (match_operand 4 "" ""))]       ; label
1332690286Sobrien  "!TARGET_64BIT && TARGET_USE_LOOP"
1332790286Sobrien  "                                 
1332818334Speter{
1332990286Sobrien  /* Only use cloop on innermost loops.  */
1333090286Sobrien  if (INTVAL (operands[3]) > 1)
1333190286Sobrien    FAIL;
1333290286Sobrien  if (GET_MODE (operands[0]) != SImode)
1333390286Sobrien    FAIL;
1333490286Sobrien  emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
1333590286Sobrien					   operands[0]));
1333690286Sobrien  DONE;
1333718334Speter}")
1333818334Speter
1333990286Sobrien(define_insn "doloop_end_internal"
1334018334Speter  [(set (pc)
1334190286Sobrien	(if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
1334290286Sobrien			  (const_int 1))
1334390286Sobrien		      (label_ref (match_operand 0 "" ""))
1334490286Sobrien		      (pc)))
1334590286Sobrien   (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
1334690286Sobrien	(plus:SI (match_dup 1)
1334790286Sobrien		 (const_int -1)))
1334890286Sobrien   (clobber (match_scratch:SI 3 "=X,X,r"))
1334990286Sobrien   (clobber (reg:CC 17))]
1335090286Sobrien  "!TARGET_64BIT && TARGET_USE_LOOP"
1335118334Speter{
1335290286Sobrien  if (which_alternative != 0)
1335390286Sobrien    return "#";
1335490286Sobrien  if (get_attr_length (insn) == 2)
1335590286Sobrien    return "%+loop\t%l0";
1335690286Sobrien  else
1335790286Sobrien    return "dec{l}\t%1\;%+jne\t%l0";
1335890286Sobrien}
1335990286Sobrien  [(set_attr "ppro_uops" "many")
1336090286Sobrien   (set (attr "type")
1336190286Sobrien	(if_then_else (and (eq_attr "alternative" "0")
1336290286Sobrien			   (and (ge (minus (match_dup 0) (pc))
1336390286Sobrien			            (const_int -128))
1336490286Sobrien			        (lt (minus (match_dup 0) (pc))
1336590286Sobrien			            (const_int 124))))
1336690286Sobrien		      (const_string "ibr")
1336790286Sobrien		      (const_string "multi")))])
1336818334Speter
1336990286Sobrien(define_split
1337090286Sobrien  [(set (pc)
1337190286Sobrien	(if_then_else (ne (match_operand:SI 1 "register_operand" "")
1337290286Sobrien			  (const_int 1))
1337390286Sobrien		      (match_operand 0 "" "")
1337490286Sobrien		      (pc)))
1337590286Sobrien   (set (match_dup 1)
1337690286Sobrien	(plus:SI (match_dup 1)
1337790286Sobrien		 (const_int -1)))
1337890286Sobrien   (clobber (match_scratch:SI 2 ""))
1337990286Sobrien   (clobber (reg:CC 17))]
1338090286Sobrien  "!TARGET_64BIT && TARGET_USE_LOOP
1338190286Sobrien   && reload_completed
1338290286Sobrien   && REGNO (operands[1]) != 2"
1338390286Sobrien  [(parallel [(set (reg:CCZ 17)
1338490286Sobrien		   (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
1338590286Sobrien				 (const_int 0)))
1338690286Sobrien	      (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
1338790286Sobrien   (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
1338890286Sobrien			   (match_dup 0)
1338990286Sobrien			   (pc)))]
1339090286Sobrien  "")
1339190286Sobrien  
1339290286Sobrien(define_split
1339390286Sobrien  [(set (pc)
1339490286Sobrien	(if_then_else (ne (match_operand:SI 1 "register_operand" "")
1339590286Sobrien			  (const_int 1))
1339690286Sobrien		      (match_operand 0 "" "")
1339790286Sobrien		      (pc)))
1339890286Sobrien   (set (match_operand:SI 2 "nonimmediate_operand" "")
1339990286Sobrien	(plus:SI (match_dup 1)
1340090286Sobrien		 (const_int -1)))
1340190286Sobrien   (clobber (match_scratch:SI 3 ""))
1340290286Sobrien   (clobber (reg:CC 17))]
1340390286Sobrien  "!TARGET_64BIT && TARGET_USE_LOOP
1340490286Sobrien   && reload_completed
1340590286Sobrien   && (! REG_P (operands[2])
1340690286Sobrien       || ! rtx_equal_p (operands[1], operands[2]))"
1340790286Sobrien  [(set (match_dup 3) (match_dup 1))
1340890286Sobrien   (parallel [(set (reg:CCZ 17)
1340990286Sobrien		   (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
1341090286Sobrien				(const_int 0)))
1341190286Sobrien	      (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
1341290286Sobrien   (set (match_dup 2) (match_dup 3))
1341390286Sobrien   (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
1341490286Sobrien			   (match_dup 0)
1341590286Sobrien			   (pc)))]
1341690286Sobrien  "")
1341718334Speter
1341890286Sobrien;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
1341918334Speter
1342090286Sobrien(define_peephole2
1342190286Sobrien  [(set (reg 17) (match_operand 0 "" ""))
1342290286Sobrien   (set (match_operand:QI 1 "register_operand" "")
1342390286Sobrien	(match_operator:QI 2 "ix86_comparison_operator"
1342490286Sobrien	  [(reg 17) (const_int 0)]))
1342590286Sobrien   (set (match_operand 3 "q_regs_operand" "")
1342690286Sobrien	(zero_extend (match_dup 1)))]
1342790286Sobrien  "(peep2_reg_dead_p (3, operands[1])
1342890286Sobrien    || operands_match_p (operands[1], operands[3]))
1342990286Sobrien   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
1343090286Sobrien  [(set (match_dup 4) (match_dup 0))
1343190286Sobrien   (set (strict_low_part (match_dup 5))
1343290286Sobrien	(match_dup 2))]
1343318334Speter{
1343490286Sobrien  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
1343590286Sobrien  operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
1343690286Sobrien  ix86_expand_clear (operands[3]);
1343790286Sobrien})
1343818334Speter
1343990286Sobrien;; Similar, but match zero_extendhisi2_and, which adds a clobber.
1344018334Speter
1344190286Sobrien(define_peephole2
1344290286Sobrien  [(set (reg 17) (match_operand 0 "" ""))
1344390286Sobrien   (set (match_operand:QI 1 "register_operand" "")
1344490286Sobrien	(match_operator:QI 2 "ix86_comparison_operator"
1344590286Sobrien	  [(reg 17) (const_int 0)]))
1344690286Sobrien   (parallel [(set (match_operand 3 "q_regs_operand" "")
1344790286Sobrien		   (zero_extend (match_dup 1)))
1344890286Sobrien	      (clobber (reg:CC 17))])]
1344990286Sobrien  "(peep2_reg_dead_p (3, operands[1])
1345090286Sobrien    || operands_match_p (operands[1], operands[3]))
1345190286Sobrien   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
1345290286Sobrien  [(set (match_dup 4) (match_dup 0))
1345390286Sobrien   (set (strict_low_part (match_dup 5))
1345490286Sobrien	(match_dup 2))]
1345590286Sobrien{
1345690286Sobrien  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
1345790286Sobrien  operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
1345890286Sobrien  ix86_expand_clear (operands[3]);
1345990286Sobrien})
1346090286Sobrien
1346190286Sobrien;; Call instructions.
1346218334Speter
1346390286Sobrien;; The predicates normally associated with named expanders are not properly
1346490286Sobrien;; checked for calls.  This is a bug in the generic code, but it isn't that
1346590286Sobrien;; easy to fix.  Ignore it for now and be prepared to fix things up.
1346618334Speter
1346718334Speter;; Call subroutine returning no value.
1346818334Speter
1346918334Speter(define_expand "call_pop"
1347090286Sobrien  [(parallel [(call (match_operand:QI 0 "" "")
1347190286Sobrien		    (match_operand:SI 1 "" ""))
1347218334Speter	      (set (reg:SI 7)
1347318334Speter		   (plus:SI (reg:SI 7)
1347490286Sobrien			    (match_operand:SI 3 "" "")))])]
1347590286Sobrien  "!TARGET_64BIT"
1347618334Speter{
1347752296Sobrien  if (operands[3] == const0_rtx)
1347852296Sobrien    {
1347990286Sobrien      emit_insn (gen_call (operands[0], operands[1], constm1_rtx));
1348052296Sobrien      DONE;
1348152296Sobrien    }
1348290286Sobrien  /* Static functions and indirect calls don't need
1348390286Sobrien     current_function_uses_pic_offset_table.  */
1348490286Sobrien  if (flag_pic
1348590286Sobrien      && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
1348690286Sobrien      && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
1348718334Speter    current_function_uses_pic_offset_table = 1;
1348890286Sobrien  if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
1348990286Sobrien    XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1349090286Sobrien  if (TARGET_64BIT)
1349190286Sobrien    abort();
1349290286Sobrien})
1349318334Speter
1349490286Sobrien(define_insn "*call_pop_0"
1349590286Sobrien  [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
1349690286Sobrien	 (match_operand:SI 1 "" ""))
1349718334Speter   (set (reg:SI 7) (plus:SI (reg:SI 7)
1349890286Sobrien			    (match_operand:SI 2 "immediate_operand" "")))]
1349990286Sobrien  "!TARGET_64BIT"
1350018334Speter{
1350190286Sobrien  if (SIBLING_CALL_P (insn))
1350290286Sobrien    return "jmp\t%P0";
1350390286Sobrien  else
1350490286Sobrien    return "call\t%P0";
1350590286Sobrien}
1350690286Sobrien  [(set_attr "type" "call")])
1350790286Sobrien  
1350890286Sobrien(define_insn "*call_pop_1"
1350990286Sobrien  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
1351090286Sobrien	 (match_operand:SI 1 "" ""))
1351190286Sobrien   (set (reg:SI 7) (plus:SI (reg:SI 7)
1351290286Sobrien			    (match_operand:SI 2 "immediate_operand" "i")))]
1351390286Sobrien  "!TARGET_64BIT"
1351490286Sobrien{
1351590286Sobrien  if (constant_call_address_operand (operands[0], Pmode))
1351618334Speter    {
1351790286Sobrien      if (SIBLING_CALL_P (insn))
1351890286Sobrien	return "jmp\t%P0";
1351990286Sobrien      else
1352090286Sobrien	return "call\t%P0";
1352118334Speter    }
1352290286Sobrien  if (SIBLING_CALL_P (insn))
1352390286Sobrien    return "jmp\t%A0";
1352418334Speter  else
1352590286Sobrien    return "call\t%A0";
1352690286Sobrien}
1352790286Sobrien  [(set_attr "type" "call")])
1352818334Speter
1352918334Speter(define_expand "call"
1353090286Sobrien  [(call (match_operand:QI 0 "" "")
1353190286Sobrien	 (match_operand 1 "" ""))
1353290286Sobrien   (use (match_operand 2 "" ""))]
1353318334Speter  ;; Operand 1 not used on the i386.
1353418334Speter  ""
1353518334Speter{
1353690286Sobrien  rtx insn;
1353790286Sobrien  /* Static functions and indirect calls don't need
1353890286Sobrien     current_function_uses_pic_offset_table.  */
1353990286Sobrien  if (flag_pic
1354090286Sobrien      && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
1354190286Sobrien      && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
1354218334Speter    current_function_uses_pic_offset_table = 1;
1354318334Speter
1354490286Sobrien  if (! call_insn_operand (XEXP (operands[0], 0), Pmode))
1354590286Sobrien    XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1354690286Sobrien  if (TARGET_64BIT && INTVAL (operands[2]) >= 0)
1354790286Sobrien    {
1354890286Sobrien      rtx reg = gen_rtx_REG (QImode, 0);
1354990286Sobrien      emit_move_insn (reg, operands[2]);
1355090286Sobrien      insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
1355190286Sobrien      use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
1355290286Sobrien      DONE;
1355390286Sobrien    }
1355490286Sobrien   insn = emit_call_insn (gen_call_exp (operands[0], operands[1]));
1355590286Sobrien   DONE;
1355690286Sobrien})
1355718334Speter
1355890286Sobrien(define_expand "call_exp"
1355990286Sobrien  [(call (match_operand:QI 0 "" "")
1356090286Sobrien	 (match_operand 1 "" ""))]
1356190286Sobrien  ""
1356290286Sobrien  "")
1356318334Speter
1356490286Sobrien(define_insn "*call_0"
1356590286Sobrien  [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
1356690286Sobrien	 (match_operand 1 "" ""))]
1356718334Speter  ""
1356818334Speter{
1356990286Sobrien  if (SIBLING_CALL_P (insn))
1357090286Sobrien    return "jmp\t%P0";
1357190286Sobrien  else
1357290286Sobrien    return "call\t%P0";
1357390286Sobrien}
1357490286Sobrien  [(set_attr "type" "call")])
1357590286Sobrien
1357690286Sobrien(define_insn "*call_1"
1357790286Sobrien  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
1357890286Sobrien	 (match_operand 1 "" ""))]
1357990286Sobrien  "!TARGET_64BIT"
1358090286Sobrien{
1358190286Sobrien  if (constant_call_address_operand (operands[0], QImode))
1358218334Speter    {
1358390286Sobrien      if (SIBLING_CALL_P (insn))
1358490286Sobrien	return "jmp\t%P0";
1358590286Sobrien      else
1358690286Sobrien	return "call\t%P0";
1358718334Speter    }
1358890286Sobrien  if (SIBLING_CALL_P (insn))
1358990286Sobrien    return "jmp\t%A0";
1359018334Speter  else
1359190286Sobrien    return "call\t%A0";
1359290286Sobrien}
1359390286Sobrien  [(set_attr "type" "call")])
1359418334Speter
1359590286Sobrien(define_insn "*call_1_rex64"
1359690286Sobrien  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
1359790286Sobrien	 (match_operand 1 "" ""))]
1359890286Sobrien  "TARGET_64BIT"
1359990286Sobrien{
1360090286Sobrien  if (constant_call_address_operand (operands[0], QImode))
1360190286Sobrien    {
1360290286Sobrien      if (SIBLING_CALL_P (insn))
1360390286Sobrien	return "jmp\t%P0";
1360490286Sobrien      else
1360590286Sobrien	return "call\t%P0";
1360690286Sobrien    }
1360790286Sobrien  if (SIBLING_CALL_P (insn))
1360890286Sobrien    return "jmp\t%A0";
1360990286Sobrien  else
1361090286Sobrien    return "call\t%A0";
1361190286Sobrien}
1361290286Sobrien  [(set_attr "type" "call")])
1361318334Speter
1361418334Speter;; Call subroutine, returning value in operand 0
1361518334Speter;; (which must be a hard register).
1361618334Speter
1361718334Speter(define_expand "call_value_pop"
1361818334Speter  [(parallel [(set (match_operand 0 "" "")
1361990286Sobrien		   (call (match_operand:QI 1 "" "")
1362090286Sobrien			 (match_operand:SI 2 "" "")))
1362118334Speter	      (set (reg:SI 7)
1362218334Speter		   (plus:SI (reg:SI 7)
1362390286Sobrien			    (match_operand:SI 4 "" "")))])]
1362490286Sobrien  "!TARGET_64BIT"
1362518334Speter{
1362652296Sobrien  if (operands[4] == const0_rtx)
1362752296Sobrien    {
1362890286Sobrien      emit_insn (gen_call_value (operands[0], operands[1], operands[2],
1362990286Sobrien				 constm1_rtx));
1363052296Sobrien      DONE;
1363152296Sobrien    }
1363290286Sobrien  /* Static functions and indirect calls don't need
1363390286Sobrien     current_function_uses_pic_offset_table.  */
1363490286Sobrien  if (flag_pic
1363590286Sobrien      && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1363690286Sobrien      && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
1363718334Speter    current_function_uses_pic_offset_table = 1;
1363890286Sobrien  if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
1363990286Sobrien    XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1364090286Sobrien})
1364118334Speter
1364218334Speter(define_expand "call_value"
1364318334Speter  [(set (match_operand 0 "" "")
1364490286Sobrien	(call (match_operand:QI 1 "" "")
1364590286Sobrien	      (match_operand:SI 2 "" "")))
1364690286Sobrien   (use (match_operand:SI 3 "" ""))]
1364718334Speter  ;; Operand 2 not used on the i386.
1364818334Speter  ""
1364918334Speter{
1365090286Sobrien  rtx insn;
1365190286Sobrien  /* Static functions and indirect calls don't need
1365290286Sobrien     current_function_uses_pic_offset_table.  */
1365390286Sobrien  if (flag_pic
1365490286Sobrien      && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1365590286Sobrien      && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
1365618334Speter    current_function_uses_pic_offset_table = 1;
1365790286Sobrien  if (! call_insn_operand (XEXP (operands[1], 0), Pmode))
1365890286Sobrien    XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1365990286Sobrien  if (TARGET_64BIT && INTVAL (operands[3]) >= 0)
1366018334Speter    {
1366190286Sobrien      rtx reg = gen_rtx_REG (QImode, 0);
1366290286Sobrien      emit_move_insn (reg, operands[3]);
1366390286Sobrien      insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
1366490286Sobrien						 operands[2]));
1366590286Sobrien      use_reg (&CALL_INSN_FUNCTION_USAGE (insn), reg);
1366690286Sobrien      DONE;
1366718334Speter    }
1366890286Sobrien  insn = emit_call_insn (gen_call_value_exp (operands[0], operands[1],
1366990286Sobrien					     operands[2]));
1367090286Sobrien  DONE;
1367190286Sobrien})
1367218334Speter
1367390286Sobrien(define_expand "call_value_exp"
1367490286Sobrien  [(set (match_operand 0 "" "")
1367590286Sobrien	(call (match_operand:QI 1 "" "")
1367690286Sobrien	      (match_operand:SI 2 "" "")))]
1367790286Sobrien  ""
1367890286Sobrien  "")
1367918334Speter
1368018334Speter;; Call subroutine returning any type.
1368118334Speter
1368218334Speter(define_expand "untyped_call"
1368318334Speter  [(parallel [(call (match_operand 0 "" "")
1368418334Speter		    (const_int 0))
1368518334Speter	      (match_operand 1 "" "")
1368618334Speter	      (match_operand 2 "" "")])]
1368718334Speter  ""
1368818334Speter{
1368918334Speter  int i;
1369018334Speter
1369118334Speter  /* In order to give reg-stack an easier job in validating two
1369218334Speter     coprocessor registers as containing a possible return value,
1369318334Speter     simply pretend the untyped call returns a complex long double
1369418334Speter     value.  */
1369550650Sobrien
1369696294Sobrien  emit_call_insn (TARGET_FLOAT_RETURNS_IN_80387
1369750650Sobrien                  ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG),
1369890286Sobrien				    operands[0], const0_rtx,
1369990286Sobrien				    GEN_INT (SSE_REGPARM_MAX - 1))
1370090286Sobrien                  : gen_call (operands[0], const0_rtx,
1370190286Sobrien			      GEN_INT (SSE_REGPARM_MAX - 1)));
1370218334Speter
1370318334Speter  for (i = 0; i < XVECLEN (operands[2], 0); i++)
1370418334Speter    {
1370518334Speter      rtx set = XVECEXP (operands[2], 0, i);
1370618334Speter      emit_move_insn (SET_DEST (set), SET_SRC (set));
1370718334Speter    }
1370818334Speter
1370918334Speter  /* The optimizer does not know that the call sets the function value
1371018334Speter     registers we stored in the result block.  We avoid problems by
1371118334Speter     claiming that all hard registers are used and clobbered at this
1371218334Speter     point.  */
1371318334Speter  emit_insn (gen_blockage ());
1371418334Speter
1371518334Speter  DONE;
1371690286Sobrien})
1371790286Sobrien
1371890286Sobrien;; Prologue and epilogue instructions
1371918334Speter
1372018334Speter;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1372118334Speter;; all of memory.  This blocks insns from being moved across this point.
1372218334Speter
1372318334Speter(define_insn "blockage"
1372418334Speter  [(unspec_volatile [(const_int 0)] 0)]
1372518334Speter  ""
1372652296Sobrien  ""
1372790286Sobrien  [(set_attr "length" "0")])
1372818334Speter
1372918334Speter;; Insn emitted into the body of a function to return from a function.
1373018334Speter;; This is only done if the function's epilogue is known to be simple.
1373190286Sobrien;; See comments for ix86_can_use_return_insn_p in i386.c.
1373218334Speter
1373350650Sobrien(define_expand "return"
1373418334Speter  [(return)]
1373550650Sobrien  "ix86_can_use_return_insn_p ()"
1373690286Sobrien{
1373790286Sobrien  if (current_function_pops_args)
1373890286Sobrien    {
1373990286Sobrien      rtx popc = GEN_INT (current_function_pops_args);
1374090286Sobrien      emit_jump_insn (gen_return_pop_internal (popc));
1374190286Sobrien      DONE;
1374290286Sobrien    }
1374390286Sobrien})
1374450650Sobrien
1374550650Sobrien(define_insn "return_internal"
1374650650Sobrien  [(return)]
1374750650Sobrien  "reload_completed"
1374852296Sobrien  "ret"
1374990286Sobrien  [(set_attr "length" "1")
1375090286Sobrien   (set_attr "length_immediate" "0")
1375190286Sobrien   (set_attr "modrm" "0")])
1375250650Sobrien
1375350650Sobrien(define_insn "return_pop_internal"
1375450650Sobrien  [(return)
1375550650Sobrien   (use (match_operand:SI 0 "const_int_operand" ""))]
1375650650Sobrien  "reload_completed"
1375790286Sobrien  "ret\t%0"
1375890286Sobrien  [(set_attr "length" "3")
1375990286Sobrien   (set_attr "length_immediate" "2")
1376090286Sobrien   (set_attr "modrm" "0")])
1376150650Sobrien
1376290286Sobrien(define_insn "return_indirect_internal"
1376390286Sobrien  [(return)
1376490286Sobrien   (use (match_operand:SI 0 "register_operand" "r"))]
1376590286Sobrien  "reload_completed"
1376690286Sobrien  "jmp\t%A0"
1376790286Sobrien  [(set_attr "type" "ibr")
1376890286Sobrien   (set_attr "length_immediate" "0")])
1376990286Sobrien
1377050650Sobrien(define_insn "nop"
1377150650Sobrien  [(const_int 0)]
1377250650Sobrien  ""
1377352296Sobrien  "nop"
1377490286Sobrien  [(set_attr "length" "1")
1377590286Sobrien   (set_attr "length_immediate" "0")
1377690286Sobrien   (set_attr "modrm" "0")
1377790286Sobrien   (set_attr "ppro_uops" "one")])
1377850650Sobrien
1377950650Sobrien(define_expand "prologue"
1378050650Sobrien  [(const_int 1)]
1378150650Sobrien  ""
1378290286Sobrien  "ix86_expand_prologue (); DONE;")
1378350650Sobrien
1378450650Sobrien(define_insn "prologue_set_got"
1378590286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1378690286Sobrien	(unspec_volatile:SI
1378750650Sobrien	 [(plus:SI (match_dup 0)
1378850650Sobrien		   (plus:SI (match_operand:SI 1 "symbolic_operand" "")
1378990286Sobrien			    (minus:SI (pc) (match_operand 2 "" ""))))] 1))
1379090286Sobrien   (clobber (reg:CC 17))]
1379190286Sobrien  "!TARGET_64BIT"
1379250650Sobrien{
1379390286Sobrien  if (GET_CODE (operands[2]) == LABEL_REF)
1379490286Sobrien     operands[2] = XEXP (operands[2], 0);
1379550650Sobrien  if (TARGET_DEEP_BRANCH_PREDICTION) 
1379690286Sobrien    return "add{l}\t{%1, %0|%0, %1}";
1379750650Sobrien  else  
1379890286Sobrien    return "add{l}\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}";
1379990286Sobrien}
1380090286Sobrien  [(set_attr "type" "alu")
1380190286Sobrien   ; Since this insn may have two constant operands, we must set the
1380290286Sobrien   ; length manually.
1380390286Sobrien   (set_attr "length_immediate" "4")
1380490286Sobrien   (set_attr "mode" "SI")])
1380550650Sobrien
1380650650Sobrien(define_insn "prologue_get_pc"
1380790286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1380890286Sobrien    (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))] 2))]
1380990286Sobrien  "!TARGET_64BIT"
1381050650Sobrien{
1381190286Sobrien  if (GET_CODE (operands[1]) == LABEL_REF)
1381290286Sobrien    operands[1] = XEXP (operands[1], 0);
1381390286Sobrien  output_asm_insn ("call\t%X1", operands);
1381490286Sobrien  if (! TARGET_DEEP_BRANCH_PREDICTION)
1381550650Sobrien    {
1381690286Sobrien      ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1381790286Sobrien				 CODE_LABEL_NUMBER (operands[1]));
13818102802Skan      return "pop{l}\t%0";
1381990286Sobrien    }
1382050650Sobrien  RET;
1382190286Sobrien}
1382290286Sobrien  [(set_attr "type" "multi")])
1382350650Sobrien
1382450650Sobrien(define_expand "epilogue"
1382550650Sobrien  [(const_int 1)]
1382650650Sobrien  ""
1382790286Sobrien  "ix86_expand_epilogue (1); DONE;")
1382850650Sobrien
1382990286Sobrien(define_expand "sibcall_epilogue"
1383090286Sobrien  [(const_int 1)]
1383150650Sobrien  ""
1383290286Sobrien  "ix86_expand_epilogue (0); DONE;")
1383350650Sobrien
1383490286Sobrien(define_expand "eh_return"
1383590286Sobrien  [(use (match_operand 0 "register_operand" ""))
1383690286Sobrien   (use (match_operand 1 "register_operand" ""))]
1383750650Sobrien  ""
1383850650Sobrien{
1383990286Sobrien  rtx tmp, sa = operands[0], ra = operands[1];
1384050650Sobrien
1384190286Sobrien  /* Tricky bit: we write the address of the handler to which we will
1384290286Sobrien     be returning into someone else's stack frame, one word below the
1384390286Sobrien     stack address we wish to restore.  */
1384490286Sobrien  tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
1384590286Sobrien  tmp = plus_constant (tmp, -UNITS_PER_WORD);
1384690286Sobrien  tmp = gen_rtx_MEM (Pmode, tmp);
1384790286Sobrien  emit_move_insn (tmp, ra);
1384818334Speter
1384990286Sobrien  if (Pmode == SImode)
1385090286Sobrien    emit_insn (gen_eh_return_si (sa));
1385190286Sobrien  else
1385290286Sobrien    emit_insn (gen_eh_return_di (sa));
1385390286Sobrien  emit_barrier ();
1385490286Sobrien  DONE;
1385590286Sobrien})
1385618334Speter
1385790286Sobrien(define_insn_and_split "eh_return_si"
1385890286Sobrien  [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")] 13)]
1385990286Sobrien  "!TARGET_64BIT"
1386090286Sobrien  "#"
1386190286Sobrien  "reload_completed"
1386290286Sobrien  [(const_int 1)]
1386390286Sobrien  "ix86_expand_epilogue (2); DONE;")
1386418334Speter
1386590286Sobrien(define_insn_and_split "eh_return_di"
1386690286Sobrien  [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")] 13)]
1386790286Sobrien  "TARGET_64BIT"
1386890286Sobrien  "#"
1386990286Sobrien  "reload_completed"
1387090286Sobrien  [(const_int 1)]
1387190286Sobrien  "ix86_expand_epilogue (2); DONE;")
1387218334Speter
1387390286Sobrien(define_insn "leave"
1387490286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
1387590286Sobrien   (set (reg:SI 6) (mem:SI (reg:SI 6)))
1387690286Sobrien   (clobber (mem:BLK (scratch)))]
1387790286Sobrien  "!TARGET_64BIT"
1387890286Sobrien  "leave"
1387990286Sobrien  [(set_attr "length_immediate" "0")
1388090286Sobrien   (set_attr "length" "1")
1388190286Sobrien   (set_attr "modrm" "0")
1388290286Sobrien   (set_attr "modrm" "0")
1388390286Sobrien   (set_attr "athlon_decode" "vector")
1388490286Sobrien   (set_attr "ppro_uops" "few")])
1388518334Speter
1388690286Sobrien(define_insn "leave_rex64"
1388790286Sobrien  [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
1388890286Sobrien   (set (reg:DI 6) (mem:DI (reg:DI 6)))
1388990286Sobrien   (clobber (mem:BLK (scratch)))]
1389090286Sobrien  "TARGET_64BIT"
1389190286Sobrien  "leave"
1389290286Sobrien  [(set_attr "length_immediate" "0")
1389390286Sobrien   (set_attr "length" "1")
1389490286Sobrien   (set_attr "modrm" "0")
1389590286Sobrien   (set_attr "modrm" "0")
1389690286Sobrien   (set_attr "athlon_decode" "vector")
1389790286Sobrien   (set_attr "ppro_uops" "few")])
1389890286Sobrien
1389990286Sobrien(define_expand "ffssi2"
1390090286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "") 
1390190286Sobrien	(ffs:SI (match_operand:SI 1 "general_operand" "")))]
1390218334Speter  ""
1390318334Speter{
1390490286Sobrien  rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
1390590286Sobrien  rtx in = operands[1];
1390618334Speter
1390790286Sobrien  if (TARGET_CMOVE)
1390818334Speter    {
1390990286Sobrien      emit_move_insn (tmp, constm1_rtx);
1391090286Sobrien      emit_insn (gen_ffssi_1 (out, in));
1391190286Sobrien      emit_insn (gen_rtx_SET (VOIDmode, out,
1391290286Sobrien		  gen_rtx_IF_THEN_ELSE (SImode, 
1391390286Sobrien		    gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
1391490286Sobrien				const0_rtx),
1391590286Sobrien		    tmp,
1391690286Sobrien		    out)));
1391790286Sobrien      emit_insn (gen_addsi3 (out, out, const1_rtx));
1391890286Sobrien      emit_move_insn (operands[0], out);
1391918334Speter    }
1392018334Speter
1392190286Sobrien  /* Pentium bsf instruction is extremly slow.  The following code is
1392290286Sobrien     recommended by the Intel Optimizing Manual as a reasonable replacement:
1392390286Sobrien           TEST    EAX,EAX
1392490286Sobrien	   JZ      SHORT BS2
1392590286Sobrien	   XOR     ECX,ECX
1392690286Sobrien	   MOV     DWORD PTR [TEMP+4],ECX
1392790286Sobrien	   SUB     ECX,EAX
1392890286Sobrien	   AND     EAX,ECX
1392990286Sobrien	   MOV     DWORD PTR [TEMP],EAX
1393090286Sobrien	   FILD    QWORD PTR [TEMP]
1393190286Sobrien	   FSTP    QWORD PTR [TEMP]
1393290286Sobrien	   WAIT    ; WAIT only needed for compatibility with
1393390286Sobrien	           ; earlier processors
1393490286Sobrien	   MOV     ECX, DWORD PTR [TEMP+4]
1393590286Sobrien	   SHR     ECX,20
1393690286Sobrien	   SUB     ECX,3FFH
1393790286Sobrien	   TEST    EAX,EAX       ; clear zero flag
1393890286Sobrien       BS2:
1393990286Sobrien     Following piece of code expand ffs to similar beast.
1394090286Sobrien       */
1394150650Sobrien
1394290286Sobrien  else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
1394390286Sobrien    {
1394490286Sobrien      rtx label = gen_label_rtx ();
1394590286Sobrien      rtx lo, hi;
1394690286Sobrien      rtx mem = assign_386_stack_local (DImode, 0);
1394790286Sobrien      rtx fptmp = gen_reg_rtx (DFmode);
1394890286Sobrien      split_di (&mem, 1, &lo, &hi);
1394950650Sobrien
1395090286Sobrien      emit_move_insn (out, const0_rtx);
1395150650Sobrien
1395290286Sobrien      emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, label);
1395350650Sobrien
1395490286Sobrien      emit_move_insn (hi, out);
1395590286Sobrien      emit_insn (gen_subsi3 (out, out, in));
1395690286Sobrien      emit_insn (gen_andsi3 (out, out, in));
1395790286Sobrien      emit_move_insn (lo, out);
1395890286Sobrien      emit_insn (gen_floatdidf2 (fptmp,mem));
1395990286Sobrien      emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
1396090286Sobrien      emit_move_insn (out, hi);
1396190286Sobrien      emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
1396290286Sobrien      emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
1396350650Sobrien
1396490286Sobrien      emit_label (label);
1396590286Sobrien      LABEL_NUSES (label) = 1;
1396650650Sobrien
1396790286Sobrien      emit_move_insn (operands[0], out);
1396890286Sobrien    }
1396990286Sobrien  else
1397050650Sobrien    {
1397190286Sobrien      emit_move_insn (tmp, const0_rtx);
1397290286Sobrien      emit_insn (gen_ffssi_1 (out, in));
1397390286Sobrien      emit_insn (gen_rtx_SET (VOIDmode, 
1397490286Sobrien		  gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
1397590286Sobrien		  gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
1397690286Sobrien			      const0_rtx)));
1397790286Sobrien      emit_insn (gen_negsi2 (tmp, tmp));
1397890286Sobrien      emit_insn (gen_iorsi3 (out, out, tmp));
1397990286Sobrien      emit_insn (gen_addsi3 (out, out, const1_rtx));
1398090286Sobrien      emit_move_insn (operands[0], out);
1398150650Sobrien    }
1398290286Sobrien  DONE;  
1398390286Sobrien})
1398450650Sobrien
1398590286Sobrien(define_insn "ffssi_1"
1398690286Sobrien  [(set (reg:CCZ 17)
1398790286Sobrien        (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
1398890286Sobrien		     (const_int 0)))
1398990286Sobrien   (set (match_operand:SI 0 "register_operand" "=r")
1399090286Sobrien	(unspec:SI [(match_dup 1)] 5))]
1399118334Speter  ""
1399290286Sobrien  "bsf{l}\t{%1, %0|%0, %1}"
1399390286Sobrien  [(set_attr "prefix_0f" "1")
1399490286Sobrien   (set_attr "ppro_uops" "few")])
1399518334Speter
1399690286Sobrien;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
1399790286Sobrien;; and slower than the two-byte movzx insn needed to do the work in SImode.
1399890286Sobrien
1399990286Sobrien;; These patterns match the binary 387 instructions for addM3, subM3,
1400090286Sobrien;; mulM3 and divM3.  There are three patterns for each of DFmode and
1400190286Sobrien;; SFmode.  The first is the normal insn, the second the same insn but
1400290286Sobrien;; with one operand a conversion, and the third the same insn but with
1400390286Sobrien;; the other operand a conversion.  The conversion may be SFmode or
1400490286Sobrien;; SImode if the target mode DFmode, but only SImode if the target mode
1400590286Sobrien;; is SFmode.
1400618334Speter
1400790286Sobrien;; Gcc is slightly more smart about handling normal two address instructions
1400890286Sobrien;; so use special patterns for add and mull.
1400990286Sobrien(define_insn "*fop_sf_comm_nosse"
1401090286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
1401190286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1401296294Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "%0")
1401390286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
1401490286Sobrien  "TARGET_80387 && !TARGET_SSE_MATH
1401596294Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1401696294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1401790286Sobrien  "* return output_387_binary_op (insn, operands);"
1401890286Sobrien  [(set (attr "type") 
1401990286Sobrien	(if_then_else (match_operand:SF 3 "mult_operator" "") 
1402090286Sobrien	   (const_string "fmul")
1402190286Sobrien	   (const_string "fop")))
1402290286Sobrien   (set_attr "mode" "SF")])
1402318334Speter
1402490286Sobrien(define_insn "*fop_sf_comm"
1402590286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
1402690286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1402796294Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "%0,0")
1402890286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
1402990286Sobrien  "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
1403096294Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1403196294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1403290286Sobrien  "* return output_387_binary_op (insn, operands);"
1403390286Sobrien  [(set (attr "type") 
1403490286Sobrien	(if_then_else (eq_attr "alternative" "1")
1403590286Sobrien           (const_string "sse")
1403690286Sobrien	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
1403790286Sobrien	      (const_string "fmul")
1403890286Sobrien	      (const_string "fop"))))
1403990286Sobrien   (set_attr "mode" "SF")])
1404018334Speter
1404190286Sobrien(define_insn "*fop_sf_comm_sse"
1404290286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1404390286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1404496294Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "%0")
1404590286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
1404696294Sobrien  "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1404796294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1404890286Sobrien  "* return output_387_binary_op (insn, operands);"
1404990286Sobrien  [(set_attr "type" "sse")
1405090286Sobrien   (set_attr "mode" "SF")])
1405118334Speter
1405290286Sobrien(define_insn "*fop_df_comm_nosse"
1405390286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1405490286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1405596294Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "%0")
1405690286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
1405790286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
1405896294Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1405996294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1406090286Sobrien  "* return output_387_binary_op (insn, operands);"
1406190286Sobrien  [(set (attr "type") 
1406290286Sobrien	(if_then_else (match_operand:SF 3 "mult_operator" "") 
1406390286Sobrien	   (const_string "fmul")
1406490286Sobrien	   (const_string "fop")))
1406590286Sobrien   (set_attr "mode" "DF")])
1406618334Speter
1406790286Sobrien(define_insn "*fop_df_comm"
1406890286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
1406990286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1407096294Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "%0,0")
1407190286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
1407290286Sobrien  "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
1407396294Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1407496294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1407590286Sobrien  "* return output_387_binary_op (insn, operands);"
1407690286Sobrien  [(set (attr "type") 
1407790286Sobrien	(if_then_else (eq_attr "alternative" "1")
1407890286Sobrien           (const_string "sse")
1407990286Sobrien	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
1408090286Sobrien	      (const_string "fmul")
1408190286Sobrien	      (const_string "fop"))))
1408290286Sobrien   (set_attr "mode" "DF")])
1408318334Speter
1408490286Sobrien(define_insn "*fop_df_comm_sse"
1408590286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1408690286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1408796294Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "%0")
1408890286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
1408990286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH
1409096294Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
1409196294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1409290286Sobrien  "* return output_387_binary_op (insn, operands);"
1409390286Sobrien  [(set_attr "type" "sse")
1409490286Sobrien   (set_attr "mode" "DF")])
1409518334Speter
1409690286Sobrien(define_insn "*fop_xf_comm"
1409790286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1409890286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1409990286Sobrien			[(match_operand:XF 1 "register_operand" "%0")
1410090286Sobrien			 (match_operand:XF 2 "register_operand" "f")]))]
1410190286Sobrien  "!TARGET_64BIT && TARGET_80387
1410290286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
1410390286Sobrien  "* return output_387_binary_op (insn, operands);"
1410490286Sobrien  [(set (attr "type") 
1410590286Sobrien        (if_then_else (match_operand:XF 3 "mult_operator" "") 
1410690286Sobrien           (const_string "fmul")
1410790286Sobrien           (const_string "fop")))
1410890286Sobrien   (set_attr "mode" "XF")])
1410918334Speter
1411090286Sobrien(define_insn "*fop_tf_comm"
1411190286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1411290286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1411390286Sobrien			[(match_operand:TF 1 "register_operand" "%0")
1411490286Sobrien			 (match_operand:TF 2 "register_operand" "f")]))]
1411590286Sobrien  "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
1411690286Sobrien  "* return output_387_binary_op (insn, operands);"
1411790286Sobrien  [(set (attr "type") 
1411890286Sobrien        (if_then_else (match_operand:TF 3 "mult_operator" "") 
1411990286Sobrien           (const_string "fmul")
1412090286Sobrien           (const_string "fop")))
1412190286Sobrien   (set_attr "mode" "XF")])
1412218334Speter
1412390286Sobrien(define_insn "*fop_sf_1_nosse"
1412490286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
1412590286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1412690286Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "0,fm")
1412790286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
1412890286Sobrien  "TARGET_80387 && !TARGET_SSE_MATH
1412990286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
1413090286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1413190286Sobrien  "* return output_387_binary_op (insn, operands);"
1413290286Sobrien  [(set (attr "type") 
1413390286Sobrien        (cond [(match_operand:SF 3 "mult_operator" "") 
1413490286Sobrien                 (const_string "fmul")
1413590286Sobrien               (match_operand:SF 3 "div_operator" "") 
1413690286Sobrien                 (const_string "fdiv")
1413790286Sobrien              ]
1413890286Sobrien              (const_string "fop")))
1413990286Sobrien   (set_attr "mode" "SF")])
1414018334Speter
1414190286Sobrien(define_insn "*fop_sf_1"
1414290286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f,x")
1414390286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1414490286Sobrien			[(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
1414590286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
1414690286Sobrien  "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
1414790286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
1414890286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1414990286Sobrien  "* return output_387_binary_op (insn, operands);"
1415090286Sobrien  [(set (attr "type") 
1415190286Sobrien        (cond [(eq_attr "alternative" "2")
1415290286Sobrien                 (const_string "sse")
1415390286Sobrien	       (match_operand:SF 3 "mult_operator" "") 
1415490286Sobrien                 (const_string "fmul")
1415590286Sobrien               (match_operand:SF 3 "div_operator" "") 
1415690286Sobrien                 (const_string "fdiv")
1415790286Sobrien              ]
1415890286Sobrien              (const_string "fop")))
1415990286Sobrien   (set_attr "mode" "SF")])
1416018334Speter
1416190286Sobrien(define_insn "*fop_sf_1_sse"
1416290286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1416390286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1416490286Sobrien			[(match_operand:SF 1 "register_operand" "0")
1416590286Sobrien			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
1416690286Sobrien  "TARGET_SSE_MATH
1416790286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
1416890286Sobrien  "* return output_387_binary_op (insn, operands);"
1416990286Sobrien  [(set_attr "type" "sse")
1417090286Sobrien   (set_attr "mode" "SF")])
1417118334Speter
1417290286Sobrien;; ??? Add SSE splitters for these!
1417390286Sobrien(define_insn "*fop_sf_2"
1417490286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
1417590286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1417690286Sobrien	  [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
1417790286Sobrien	   (match_operand:SF 2 "register_operand" "0,0")]))]
1417890286Sobrien  "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
1417990286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1418090286Sobrien  [(set (attr "type") 
1418190286Sobrien        (cond [(match_operand:SF 3 "mult_operator" "") 
1418290286Sobrien                 (const_string "fmul")
1418390286Sobrien               (match_operand:SF 3 "div_operator" "") 
1418490286Sobrien                 (const_string "fdiv")
1418590286Sobrien              ]
1418690286Sobrien              (const_string "fop")))
1418790286Sobrien   (set_attr "fp_int_src" "true")
1418890286Sobrien   (set_attr "ppro_uops" "many")
1418990286Sobrien   (set_attr "mode" "SI")])
1419018334Speter
1419190286Sobrien(define_insn "*fop_sf_3"
1419290286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
1419390286Sobrien	(match_operator:SF 3 "binary_fp_operator"
1419490286Sobrien	  [(match_operand:SF 1 "register_operand" "0,0")
1419590286Sobrien	   (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1419690286Sobrien  "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
1419790286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1419890286Sobrien  [(set (attr "type") 
1419990286Sobrien        (cond [(match_operand:SF 3 "mult_operator" "") 
1420090286Sobrien                 (const_string "fmul")
1420190286Sobrien               (match_operand:SF 3 "div_operator" "") 
1420290286Sobrien                 (const_string "fdiv")
1420390286Sobrien              ]
1420490286Sobrien              (const_string "fop")))
1420590286Sobrien   (set_attr "fp_int_src" "true")
1420690286Sobrien   (set_attr "ppro_uops" "many")
1420790286Sobrien   (set_attr "mode" "SI")])
1420818334Speter
1420990286Sobrien(define_insn "*fop_df_1_nosse"
1421090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
1421190286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1421290286Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "0,fm")
1421390286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
1421490286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
1421590286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
1421690286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1421790286Sobrien  "* return output_387_binary_op (insn, operands);"
1421890286Sobrien  [(set (attr "type") 
1421990286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1422090286Sobrien                 (const_string "fmul")
1422190286Sobrien               (match_operand:DF 3 "div_operator" "") 
1422290286Sobrien                 (const_string "fdiv")
1422390286Sobrien              ]
1422490286Sobrien              (const_string "fop")))
1422590286Sobrien   (set_attr "mode" "DF")])
1422618334Speter
1422718334Speter
1422890286Sobrien(define_insn "*fop_df_1"
1422990286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
1423090286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1423190286Sobrien			[(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
1423290286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
1423390286Sobrien  "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
1423490286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
1423590286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1423690286Sobrien  "* return output_387_binary_op (insn, operands);"
1423790286Sobrien  [(set (attr "type") 
1423890286Sobrien        (cond [(eq_attr "alternative" "2")
1423990286Sobrien                 (const_string "sse")
1424090286Sobrien	       (match_operand:DF 3 "mult_operator" "") 
1424190286Sobrien                 (const_string "fmul")
1424290286Sobrien               (match_operand:DF 3 "div_operator" "") 
1424390286Sobrien                 (const_string "fdiv")
1424490286Sobrien              ]
1424590286Sobrien              (const_string "fop")))
1424690286Sobrien   (set_attr "mode" "DF")])
1424718334Speter
1424890286Sobrien(define_insn "*fop_df_1_sse"
1424990286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1425090286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1425190286Sobrien			[(match_operand:DF 1 "register_operand" "0")
1425290286Sobrien			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
1425390286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH
1425490286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
1425590286Sobrien  "* return output_387_binary_op (insn, operands);"
1425690286Sobrien  [(set_attr "type" "sse")])
1425718334Speter
1425890286Sobrien;; ??? Add SSE splitters for these!
1425990286Sobrien(define_insn "*fop_df_2"
1426090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
1426190286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1426290286Sobrien	   [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
1426390286Sobrien	    (match_operand:DF 2 "register_operand" "0,0")]))]
1426490286Sobrien  "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
1426590286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1426690286Sobrien  [(set (attr "type") 
1426790286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1426890286Sobrien                 (const_string "fmul")
1426990286Sobrien               (match_operand:DF 3 "div_operator" "") 
1427090286Sobrien                 (const_string "fdiv")
1427190286Sobrien              ]
1427290286Sobrien              (const_string "fop")))
1427390286Sobrien   (set_attr "fp_int_src" "true")
1427490286Sobrien   (set_attr "ppro_uops" "many")
1427590286Sobrien   (set_attr "mode" "SI")])
1427618334Speter
1427790286Sobrien(define_insn "*fop_df_3"
1427890286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
1427990286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1428090286Sobrien	   [(match_operand:DF 1 "register_operand" "0,0")
1428190286Sobrien	    (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1428290286Sobrien  "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
1428390286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1428490286Sobrien  [(set (attr "type") 
1428590286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1428690286Sobrien                 (const_string "fmul")
1428790286Sobrien               (match_operand:DF 3 "div_operator" "") 
1428890286Sobrien                 (const_string "fdiv")
1428990286Sobrien              ]
1429090286Sobrien              (const_string "fop")))
1429190286Sobrien   (set_attr "fp_int_src" "true")
1429290286Sobrien   (set_attr "ppro_uops" "many")
1429390286Sobrien   (set_attr "mode" "SI")])
1429418334Speter
1429590286Sobrien(define_insn "*fop_df_4"
1429690286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
1429790286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1429890286Sobrien	   [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
1429990286Sobrien	    (match_operand:DF 2 "register_operand" "0,f")]))]
1430090286Sobrien  "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
1430190286Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1430290286Sobrien  "* return output_387_binary_op (insn, operands);"
1430390286Sobrien  [(set (attr "type") 
1430490286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1430590286Sobrien                 (const_string "fmul")
1430690286Sobrien               (match_operand:DF 3 "div_operator" "") 
1430790286Sobrien                 (const_string "fdiv")
1430890286Sobrien              ]
1430990286Sobrien              (const_string "fop")))
1431090286Sobrien   (set_attr "mode" "SF")])
1431118334Speter
1431290286Sobrien(define_insn "*fop_df_5"
1431318334Speter  [(set (match_operand:DF 0 "register_operand" "=f,f")
1431490286Sobrien	(match_operator:DF 3 "binary_fp_operator"
1431590286Sobrien	  [(match_operand:DF 1 "register_operand" "0,f")
1431690286Sobrien	   (float_extend:DF
1431790286Sobrien	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
1431890286Sobrien  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
1431950650Sobrien  "* return output_387_binary_op (insn, operands);"
1432050650Sobrien  [(set (attr "type") 
1432190286Sobrien        (cond [(match_operand:DF 3 "mult_operator" "") 
1432290286Sobrien                 (const_string "fmul")
1432390286Sobrien               (match_operand:DF 3 "div_operator" "") 
1432490286Sobrien                 (const_string "fdiv")
1432550650Sobrien              ]
1432690286Sobrien              (const_string "fop")))
1432790286Sobrien   (set_attr "mode" "SF")])
1432818334Speter
1432990286Sobrien(define_insn "*fop_xf_1"
1433018334Speter  [(set (match_operand:XF 0 "register_operand" "=f,f")
1433190286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1433250650Sobrien			[(match_operand:XF 1 "register_operand" "0,f")
1433350650Sobrien			 (match_operand:XF 2 "register_operand" "f,0")]))]
1433490286Sobrien  "!TARGET_64BIT && TARGET_80387
1433590286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
1433650650Sobrien  "* return output_387_binary_op (insn, operands);"
1433750650Sobrien  [(set (attr "type") 
1433890286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1433990286Sobrien                 (const_string "fmul")
1434090286Sobrien               (match_operand:XF 3 "div_operator" "") 
1434190286Sobrien                 (const_string "fdiv")
1434250650Sobrien              ]
1434390286Sobrien              (const_string "fop")))
1434490286Sobrien   (set_attr "mode" "XF")])
1434518334Speter
1434690286Sobrien(define_insn "*fop_tf_1"
1434790286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1434890286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1434990286Sobrien			[(match_operand:TF 1 "register_operand" "0,f")
1435090286Sobrien			 (match_operand:TF 2 "register_operand" "f,0")]))]
1435190286Sobrien  "TARGET_80387
1435290286Sobrien   && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
1435390286Sobrien  "* return output_387_binary_op (insn, operands);"
1435490286Sobrien  [(set (attr "type") 
1435590286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1435690286Sobrien                 (const_string "fmul")
1435790286Sobrien               (match_operand:TF 3 "div_operator" "") 
1435890286Sobrien                 (const_string "fdiv")
1435990286Sobrien              ]
1436090286Sobrien              (const_string "fop")))
1436190286Sobrien   (set_attr "mode" "XF")])
1436290286Sobrien
1436390286Sobrien(define_insn "*fop_xf_2"
1436418334Speter  [(set (match_operand:XF 0 "register_operand" "=f,f")
1436590286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1436690286Sobrien	   [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
1436790286Sobrien	    (match_operand:XF 2 "register_operand" "0,0")]))]
1436890286Sobrien  "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
1436990286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1437090286Sobrien  [(set (attr "type") 
1437190286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1437290286Sobrien                 (const_string "fmul")
1437390286Sobrien               (match_operand:XF 3 "div_operator" "") 
1437490286Sobrien                 (const_string "fdiv")
1437590286Sobrien              ]
1437690286Sobrien              (const_string "fop")))
1437790286Sobrien   (set_attr "fp_int_src" "true")
1437890286Sobrien   (set_attr "mode" "SI")
1437990286Sobrien   (set_attr "ppro_uops" "many")])
1438090286Sobrien
1438190286Sobrien(define_insn "*fop_tf_2"
1438290286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1438390286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1438490286Sobrien	   [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
1438590286Sobrien	    (match_operand:TF 2 "register_operand" "0,0")]))]
1438690286Sobrien  "TARGET_80387 && TARGET_USE_FIOP"
1438790286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1438890286Sobrien  [(set (attr "type") 
1438990286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1439090286Sobrien                 (const_string "fmul")
1439190286Sobrien               (match_operand:TF 3 "div_operator" "") 
1439290286Sobrien                 (const_string "fdiv")
1439390286Sobrien              ]
1439490286Sobrien              (const_string "fop")))
1439590286Sobrien   (set_attr "fp_int_src" "true")
1439690286Sobrien   (set_attr "mode" "SI")
1439790286Sobrien   (set_attr "ppro_uops" "many")])
1439890286Sobrien
1439990286Sobrien(define_insn "*fop_xf_3"
1440090286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1440190286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1440290286Sobrien	  [(match_operand:XF 1 "register_operand" "0,0")
1440390286Sobrien	   (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1440490286Sobrien  "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
1440590286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1440690286Sobrien  [(set (attr "type") 
1440790286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1440890286Sobrien                 (const_string "fmul")
1440990286Sobrien               (match_operand:XF 3 "div_operator" "") 
1441090286Sobrien                 (const_string "fdiv")
1441190286Sobrien              ]
1441290286Sobrien              (const_string "fop")))
1441390286Sobrien   (set_attr "fp_int_src" "true")
1441490286Sobrien   (set_attr "mode" "SI")
1441590286Sobrien   (set_attr "ppro_uops" "many")])
1441690286Sobrien
1441790286Sobrien(define_insn "*fop_tf_3"
1441890286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1441990286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1442090286Sobrien	  [(match_operand:TF 1 "register_operand" "0,0")
1442190286Sobrien	   (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
1442290286Sobrien  "TARGET_80387 && TARGET_USE_FIOP"
1442390286Sobrien  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
1442490286Sobrien  [(set (attr "type") 
1442590286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1442690286Sobrien                 (const_string "fmul")
1442790286Sobrien               (match_operand:TF 3 "div_operator" "") 
1442890286Sobrien                 (const_string "fdiv")
1442990286Sobrien              ]
1443090286Sobrien              (const_string "fop")))
1443190286Sobrien   (set_attr "fp_int_src" "true")
1443290286Sobrien   (set_attr "mode" "SI")
1443390286Sobrien   (set_attr "ppro_uops" "many")])
1443490286Sobrien
1443590286Sobrien(define_insn "*fop_xf_4"
1443690286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1443790286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1443850650Sobrien	   [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
1443950650Sobrien	    (match_operand:XF 2 "register_operand" "0,f")]))]
1444090286Sobrien  "!TARGET_64BIT && TARGET_80387"
1444190286Sobrien  "* return output_387_binary_op (insn, operands);"
1444290286Sobrien  [(set (attr "type") 
1444390286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1444490286Sobrien                 (const_string "fmul")
1444590286Sobrien               (match_operand:XF 3 "div_operator" "") 
1444690286Sobrien                 (const_string "fdiv")
1444790286Sobrien              ]
1444890286Sobrien              (const_string "fop")))
1444990286Sobrien   (set_attr "mode" "SF")])
1445090286Sobrien
1445190286Sobrien(define_insn "*fop_tf_4"
1445290286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1445390286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1445490286Sobrien	   [(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
1445590286Sobrien	    (match_operand:TF 2 "register_operand" "0,f")]))]
1445618334Speter  "TARGET_80387"
1445750650Sobrien  "* return output_387_binary_op (insn, operands);"
1445850650Sobrien  [(set (attr "type") 
1445990286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1446090286Sobrien                 (const_string "fmul")
1446190286Sobrien               (match_operand:TF 3 "div_operator" "") 
1446290286Sobrien                 (const_string "fdiv")
1446350650Sobrien              ]
1446490286Sobrien              (const_string "fop")))
1446590286Sobrien   (set_attr "mode" "SF")])
1446618334Speter
1446790286Sobrien(define_insn "*fop_xf_5"
1446818334Speter  [(set (match_operand:XF 0 "register_operand" "=f,f")
1446990286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1447050650Sobrien	  [(match_operand:XF 1 "register_operand" "0,f")
1447118334Speter	   (float_extend:XF
1447250650Sobrien	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
1447390286Sobrien  "!TARGET_64BIT && TARGET_80387"
1447450650Sobrien  "* return output_387_binary_op (insn, operands);"
1447550650Sobrien  [(set (attr "type") 
1447690286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1447790286Sobrien                 (const_string "fmul")
1447890286Sobrien               (match_operand:XF 3 "div_operator" "") 
1447990286Sobrien                 (const_string "fdiv")
1448050650Sobrien              ]
1448190286Sobrien              (const_string "fop")))
1448290286Sobrien   (set_attr "mode" "SF")])
1448318334Speter
1448490286Sobrien(define_insn "*fop_tf_5"
1448590286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1448690286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1448790286Sobrien	  [(match_operand:TF 1 "register_operand" "0,f")
1448890286Sobrien	   (float_extend:TF
1448990286Sobrien	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
1449018334Speter  "TARGET_80387"
1449150650Sobrien  "* return output_387_binary_op (insn, operands);"
1449250650Sobrien  [(set (attr "type") 
1449390286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1449490286Sobrien                 (const_string "fmul")
1449590286Sobrien               (match_operand:TF 3 "div_operator" "") 
1449690286Sobrien                 (const_string "fdiv")
1449750650Sobrien              ]
1449890286Sobrien              (const_string "fop")))
1449990286Sobrien   (set_attr "mode" "SF")])
1450018334Speter
1450190286Sobrien(define_insn "*fop_xf_6"
1450290286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1450390286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1450490286Sobrien	   [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
1450590286Sobrien	    (match_operand:XF 2 "register_operand" "0,f")]))]
1450690286Sobrien  "!TARGET_64BIT && TARGET_80387"
1450790286Sobrien  "* return output_387_binary_op (insn, operands);"
1450890286Sobrien  [(set (attr "type") 
1450990286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1451090286Sobrien                 (const_string "fmul")
1451190286Sobrien               (match_operand:XF 3 "div_operator" "") 
1451290286Sobrien                 (const_string "fdiv")
1451390286Sobrien              ]
1451490286Sobrien              (const_string "fop")))
1451590286Sobrien   (set_attr "mode" "DF")])
1451690286Sobrien
1451790286Sobrien(define_insn "*fop_tf_6"
1451890286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1451990286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1452090286Sobrien	   [(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
1452190286Sobrien	    (match_operand:TF 2 "register_operand" "0,f")]))]
1452218334Speter  "TARGET_80387"
1452350650Sobrien  "* return output_387_binary_op (insn, operands);"
1452450650Sobrien  [(set (attr "type") 
1452590286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1452690286Sobrien                 (const_string "fmul")
1452790286Sobrien               (match_operand:TF 3 "div_operator" "") 
1452890286Sobrien                 (const_string "fdiv")
1452950650Sobrien              ]
1453090286Sobrien              (const_string "fop")))
1453190286Sobrien   (set_attr "mode" "DF")])
1453218334Speter
1453390286Sobrien(define_insn "*fop_xf_7"
1453490286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1453590286Sobrien	(match_operator:XF 3 "binary_fp_operator"
1453690286Sobrien	  [(match_operand:XF 1 "register_operand" "0,f")
1453790286Sobrien	   (float_extend:XF
1453890286Sobrien	    (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
1453990286Sobrien  "!TARGET_64BIT && TARGET_80387"
1454090286Sobrien  "* return output_387_binary_op (insn, operands);"
1454190286Sobrien  [(set (attr "type") 
1454290286Sobrien        (cond [(match_operand:XF 3 "mult_operator" "") 
1454390286Sobrien                 (const_string "fmul")
1454490286Sobrien               (match_operand:XF 3 "div_operator" "") 
1454590286Sobrien                 (const_string "fdiv")
1454690286Sobrien              ]
1454790286Sobrien              (const_string "fop")))
1454890286Sobrien   (set_attr "mode" "DF")])
1454990286Sobrien
1455090286Sobrien(define_insn "*fop_tf_7"
1455190286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1455290286Sobrien	(match_operator:TF 3 "binary_fp_operator"
1455390286Sobrien	  [(match_operand:TF 1 "register_operand" "0,f")
1455490286Sobrien	   (float_extend:TF
1455590286Sobrien	    (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
1455618334Speter  "TARGET_80387"
1455750650Sobrien  "* return output_387_binary_op (insn, operands);"
1455850650Sobrien  [(set (attr "type") 
1455990286Sobrien        (cond [(match_operand:TF 3 "mult_operator" "") 
1456090286Sobrien                 (const_string "fmul")
1456190286Sobrien               (match_operand:TF 3 "div_operator" "") 
1456290286Sobrien                 (const_string "fdiv")
1456350650Sobrien              ]
1456490286Sobrien              (const_string "fop")))
1456590286Sobrien   (set_attr "mode" "DF")])
1456690286Sobrien
1456790286Sobrien(define_split
1456890286Sobrien  [(set (match_operand 0 "register_operand" "")
1456990286Sobrien	(match_operator 3 "binary_fp_operator"
1457090286Sobrien	   [(float (match_operand:SI 1 "register_operand" ""))
1457190286Sobrien	    (match_operand 2 "register_operand" "")]))]
1457290286Sobrien  "TARGET_80387 && reload_completed
1457390286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))"
1457490286Sobrien  [(const_int 0)]
1457590286Sobrien{ 
1457690286Sobrien  operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
1457790286Sobrien  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
1457890286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
1457990286Sobrien			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
1458090286Sobrien					  GET_MODE (operands[3]),
1458190286Sobrien					  operands[4],
1458290286Sobrien					  operands[2])));
1458390286Sobrien  ix86_free_from_memory (GET_MODE (operands[1]));
1458490286Sobrien  DONE;
1458590286Sobrien})
1458690286Sobrien
1458790286Sobrien(define_split
1458890286Sobrien  [(set (match_operand 0 "register_operand" "")
1458990286Sobrien	(match_operator 3 "binary_fp_operator"
1459090286Sobrien	   [(match_operand 1 "register_operand" "")
1459190286Sobrien	    (float (match_operand:SI 2 "register_operand" ""))]))]
1459290286Sobrien  "TARGET_80387 && reload_completed
1459390286Sobrien   && FLOAT_MODE_P (GET_MODE (operands[0]))"
1459490286Sobrien  [(const_int 0)]
1459590286Sobrien{
1459690286Sobrien  operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
1459790286Sobrien  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
1459890286Sobrien  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
1459990286Sobrien			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
1460090286Sobrien					  GET_MODE (operands[3]),
1460190286Sobrien					  operands[1],
1460290286Sobrien					  operands[4])));
1460390286Sobrien  ix86_free_from_memory (GET_MODE (operands[2]));
1460490286Sobrien  DONE;
1460590286Sobrien})
1460618334Speter
1460790286Sobrien;; FPU special functions.
1460890286Sobrien
1460990286Sobrien(define_expand "sqrtsf2"
1461090286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1461190286Sobrien	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
1461290286Sobrien  "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
1461390286Sobrien{
1461490286Sobrien  if (!TARGET_SSE_MATH)
1461590286Sobrien    operands[1] = force_reg (SFmode, operands[1]);
1461690286Sobrien})
1461790286Sobrien
1461890286Sobrien(define_insn "sqrtsf2_1"
1461990286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
1462090286Sobrien	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
1462190286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1462290286Sobrien   && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
1462390286Sobrien  "@
1462490286Sobrien   fsqrt
1462590286Sobrien   sqrtss\t{%1, %0|%0, %1}"
1462690286Sobrien  [(set_attr "type" "fpspc,sse")
1462790286Sobrien   (set_attr "mode" "SF,SF")
1462890286Sobrien   (set_attr "athlon_decode" "direct,*")])
1462990286Sobrien
1463090286Sobrien(define_insn "sqrtsf2_1_sse_only"
1463190286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1463290286Sobrien	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
1463390286Sobrien  "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
1463490286Sobrien  "sqrtss\t{%1, %0|%0, %1}"
1463590286Sobrien  [(set_attr "type" "sse")
1463690286Sobrien   (set_attr "mode" "SF")
1463790286Sobrien   (set_attr "athlon_decode" "*")])
1463890286Sobrien
1463990286Sobrien(define_insn "sqrtsf2_i387"
1464090286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
1464190286Sobrien	(sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
1464290286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1464390286Sobrien   && !TARGET_SSE_MATH"
1464490286Sobrien  "fsqrt"
1464590286Sobrien  [(set_attr "type" "fpspc")
1464690286Sobrien   (set_attr "mode" "SF")
1464790286Sobrien   (set_attr "athlon_decode" "direct")])
1464890286Sobrien
1464990286Sobrien(define_expand "sqrtdf2"
1465090286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1465190286Sobrien	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
1465290286Sobrien  "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
1465390286Sobrien   || (TARGET_SSE2 && TARGET_SSE_MATH)"
1465490286Sobrien{
1465590286Sobrien  if (!TARGET_SSE2 || !TARGET_SSE_MATH)
1465690286Sobrien    operands[1] = force_reg (DFmode, operands[1]);
1465790286Sobrien})
1465890286Sobrien
1465990286Sobrien(define_insn "sqrtdf2_1"
1466090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
1466190286Sobrien	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
1466290286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1466390286Sobrien   && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
1466490286Sobrien  "@
1466590286Sobrien   fsqrt
1466690286Sobrien   sqrtsd\t{%1, %0|%0, %1}"
1466790286Sobrien  [(set_attr "type" "fpspc,sse")
1466890286Sobrien   (set_attr "mode" "DF,DF")
1466990286Sobrien   (set_attr "athlon_decode" "direct,*")])
1467090286Sobrien
1467190286Sobrien(define_insn "sqrtdf2_1_sse_only"
1467290286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1467390286Sobrien	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
1467490286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
1467590286Sobrien  "sqrtsd\t{%1, %0|%0, %1}"
1467690286Sobrien  [(set_attr "type" "sse")
1467790286Sobrien   (set_attr "mode" "DF")
1467890286Sobrien   (set_attr "athlon_decode" "*")])
1467990286Sobrien
1468090286Sobrien(define_insn "sqrtdf2_i387"
1468190286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1468290286Sobrien	(sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
1468390286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1468490286Sobrien   && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
1468590286Sobrien  "fsqrt"
1468690286Sobrien  [(set_attr "type" "fpspc")
1468790286Sobrien   (set_attr "mode" "DF")
1468890286Sobrien   (set_attr "athlon_decode" "direct")])
1468990286Sobrien
1469090286Sobrien(define_insn "*sqrtextendsfdf2"
1469190286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1469290286Sobrien	(sqrt:DF (float_extend:DF
1469390286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
1469490286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1469590286Sobrien   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
1469690286Sobrien  "fsqrt"
1469790286Sobrien  [(set_attr "type" "fpspc")
1469890286Sobrien   (set_attr "mode" "DF")
1469990286Sobrien   (set_attr "athlon_decode" "direct")])
1470090286Sobrien
1470190286Sobrien(define_insn "sqrtxf2"
1470290286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1470390286Sobrien	(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
1470490286Sobrien  "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
1470590286Sobrien   && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
1470690286Sobrien  "fsqrt"
1470790286Sobrien  [(set_attr "type" "fpspc")
1470890286Sobrien   (set_attr "mode" "XF")
1470990286Sobrien   (set_attr "athlon_decode" "direct")])
1471090286Sobrien
1471190286Sobrien(define_insn "sqrttf2"
1471290286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1471390286Sobrien	(sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
1471490286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1471590286Sobrien   && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
1471690286Sobrien  "fsqrt"
1471790286Sobrien  [(set_attr "type" "fpspc")
1471890286Sobrien   (set_attr "mode" "XF")
1471990286Sobrien   (set_attr "athlon_decode" "direct")])
1472090286Sobrien
1472190286Sobrien(define_insn "*sqrtextenddfxf2"
1472290286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1472390286Sobrien	(sqrt:XF (float_extend:XF
1472490286Sobrien		  (match_operand:DF 1 "register_operand" "0"))))]
1472596294Sobrien  "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
1472690286Sobrien  "fsqrt"
1472790286Sobrien  [(set_attr "type" "fpspc")
1472890286Sobrien   (set_attr "mode" "XF")
1472990286Sobrien   (set_attr "athlon_decode" "direct")])
1473090286Sobrien
1473190286Sobrien(define_insn "*sqrtextenddftf2"
1473290286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1473390286Sobrien	(sqrt:TF (float_extend:TF
1473490286Sobrien		  (match_operand:DF 1 "register_operand" "0"))))]
1473590286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
1473690286Sobrien  "fsqrt"
1473790286Sobrien  [(set_attr "type" "fpspc")
1473890286Sobrien   (set_attr "mode" "XF")
1473990286Sobrien   (set_attr "athlon_decode" "direct")])
1474090286Sobrien
1474190286Sobrien(define_insn "*sqrtextendsfxf2"
1474290286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1474390286Sobrien	(sqrt:XF (float_extend:XF
1474490286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
1474596294Sobrien  "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
1474690286Sobrien  "fsqrt"
1474790286Sobrien  [(set_attr "type" "fpspc")
1474890286Sobrien   (set_attr "mode" "XF")
1474990286Sobrien   (set_attr "athlon_decode" "direct")])
1475090286Sobrien
1475190286Sobrien(define_insn "*sqrtextendsftf2"
1475290286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1475390286Sobrien	(sqrt:TF (float_extend:TF
1475490286Sobrien		  (match_operand:SF 1 "register_operand" "0"))))]
1475590286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
1475690286Sobrien  "fsqrt"
1475790286Sobrien  [(set_attr "type" "fpspc")
1475890286Sobrien   (set_attr "mode" "XF")
1475990286Sobrien   (set_attr "athlon_decode" "direct")])
1476090286Sobrien
1476190286Sobrien(define_insn "sindf2"
1476290286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1476390286Sobrien	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
1476490286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1476590286Sobrien   && flag_unsafe_math_optimizations"
1476690286Sobrien  "fsin"
1476790286Sobrien  [(set_attr "type" "fpspc")
1476890286Sobrien   (set_attr "mode" "DF")])
1476990286Sobrien
1477090286Sobrien(define_insn "sinsf2"
1477190286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
1477290286Sobrien	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
1477390286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1477490286Sobrien   && flag_unsafe_math_optimizations"
1477590286Sobrien  "fsin"
1477690286Sobrien  [(set_attr "type" "fpspc")
1477790286Sobrien   (set_attr "mode" "SF")])
1477890286Sobrien
1477990286Sobrien(define_insn "*sinextendsfdf2"
1478090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1478190286Sobrien	(unspec:DF [(float_extend:DF
1478290286Sobrien		     (match_operand:SF 1 "register_operand" "0"))] 1))]
1478390286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1478490286Sobrien   && flag_unsafe_math_optimizations"
1478590286Sobrien  "fsin"
1478690286Sobrien  [(set_attr "type" "fpspc")
1478790286Sobrien   (set_attr "mode" "DF")])
1478890286Sobrien
1478990286Sobrien(define_insn "sinxf2"
1479090286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1479190286Sobrien	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
1479296294Sobrien  "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
1479390286Sobrien   && flag_unsafe_math_optimizations"
1479490286Sobrien  "fsin"
1479590286Sobrien  [(set_attr "type" "fpspc")
1479690286Sobrien   (set_attr "mode" "XF")])
1479790286Sobrien
1479890286Sobrien(define_insn "sintf2"
1479990286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1480090286Sobrien	(unspec:TF [(match_operand:TF 1 "register_operand" "0")] 1))]
1480190286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1480290286Sobrien   && flag_unsafe_math_optimizations"
1480390286Sobrien  "fsin"
1480490286Sobrien  [(set_attr "type" "fpspc")
1480590286Sobrien   (set_attr "mode" "XF")])
1480690286Sobrien
1480790286Sobrien(define_insn "cosdf2"
1480890286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1480990286Sobrien	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
1481090286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1481190286Sobrien   && flag_unsafe_math_optimizations"
1481290286Sobrien  "fcos"
1481390286Sobrien  [(set_attr "type" "fpspc")
1481490286Sobrien   (set_attr "mode" "DF")])
1481590286Sobrien
1481690286Sobrien(define_insn "cossf2"
1481790286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
1481890286Sobrien	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
1481990286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1482090286Sobrien   && flag_unsafe_math_optimizations"
1482190286Sobrien  "fcos"
1482290286Sobrien  [(set_attr "type" "fpspc")
1482390286Sobrien   (set_attr "mode" "SF")])
1482490286Sobrien
1482590286Sobrien(define_insn "*cosextendsfdf2"
1482690286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
1482790286Sobrien	(unspec:DF [(float_extend:DF
1482890286Sobrien		     (match_operand:SF 1 "register_operand" "0"))] 2))]
1482990286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1483090286Sobrien   && flag_unsafe_math_optimizations"
1483190286Sobrien  "fcos"
1483290286Sobrien  [(set_attr "type" "fpspc")
1483390286Sobrien   (set_attr "mode" "DF")])
1483490286Sobrien
1483590286Sobrien(define_insn "cosxf2"
1483690286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f")
1483790286Sobrien	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
1483890286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
1483990286Sobrien   && flag_unsafe_math_optimizations"
1484090286Sobrien  "fcos"
1484190286Sobrien  [(set_attr "type" "fpspc")
1484290286Sobrien   (set_attr "mode" "XF")])
1484390286Sobrien
1484490286Sobrien(define_insn "costf2"
1484590286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f")
1484690286Sobrien	(unspec:TF [(match_operand:TF 1 "register_operand" "0")] 2))]
1484790286Sobrien  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
1484890286Sobrien   && flag_unsafe_math_optimizations"
1484990286Sobrien  "fcos"
1485090286Sobrien  [(set_attr "type" "fpspc")
1485190286Sobrien   (set_attr "mode" "XF")])
1485290286Sobrien
1485390286Sobrien;; Block operation instructions
1485490286Sobrien
1485590286Sobrien(define_insn "cld"
1485690286Sobrien [(set (reg:SI 19) (const_int 0))]
1485790286Sobrien ""
1485890286Sobrien "cld"
1485990286Sobrien  [(set_attr "type" "cld")])
1486090286Sobrien
1486190286Sobrien(define_expand "movstrsi"
1486290286Sobrien  [(use (match_operand:BLK 0 "memory_operand" ""))
1486390286Sobrien   (use (match_operand:BLK 1 "memory_operand" ""))
1486490286Sobrien   (use (match_operand:SI 2 "nonmemory_operand" ""))
1486590286Sobrien   (use (match_operand:SI 3 "const_int_operand" ""))]
1486618334Speter  ""
1486718334Speter{
1486890286Sobrien if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
1486990286Sobrien   DONE;
1487090286Sobrien else
1487190286Sobrien   FAIL;
1487290286Sobrien})
1487390286Sobrien
1487490286Sobrien(define_expand "movstrdi"
1487590286Sobrien  [(use (match_operand:BLK 0 "memory_operand" ""))
1487690286Sobrien   (use (match_operand:BLK 1 "memory_operand" ""))
1487790286Sobrien   (use (match_operand:DI 2 "nonmemory_operand" ""))
1487890286Sobrien   (use (match_operand:DI 3 "const_int_operand" ""))]
1487990286Sobrien  "TARGET_64BIT"
1488090286Sobrien{
1488190286Sobrien if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
1488290286Sobrien   DONE;
1488390286Sobrien else
1488490286Sobrien   FAIL;
1488590286Sobrien})
1488690286Sobrien
1488790286Sobrien;; Most CPUs don't like single string operations
1488890286Sobrien;; Handle this case here to simplify previous expander.
1488990286Sobrien
1489090286Sobrien(define_expand "strmovdi_rex64"
1489190286Sobrien  [(set (match_dup 2)
1489290286Sobrien  	(mem:DI (match_operand:DI 1 "register_operand" "")))
1489390286Sobrien   (set (mem:DI (match_operand:DI 0 "register_operand" ""))
1489490286Sobrien        (match_dup 2))
1489590286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
1489690286Sobrien	      (clobber (reg:CC 17))])
1489790286Sobrien   (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
1489890286Sobrien	      (clobber (reg:CC 17))])]
1489990286Sobrien  "TARGET_64BIT"
1490090286Sobrien{
1490190286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1490250650Sobrien    {
1490390286Sobrien      emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
1490490286Sobrien				     operands[1]));
1490590286Sobrien      DONE;
1490690286Sobrien    }
1490790286Sobrien  else 
1490890286Sobrien    operands[2] = gen_reg_rtx (DImode);
1490990286Sobrien})
1491050650Sobrien
1491150650Sobrien
1491290286Sobrien(define_expand "strmovsi"
1491390286Sobrien  [(set (match_dup 2)
1491490286Sobrien  	(mem:SI (match_operand:SI 1 "register_operand" "")))
1491590286Sobrien   (set (mem:SI (match_operand:SI 0 "register_operand" ""))
1491690286Sobrien        (match_dup 2))
1491790286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
1491890286Sobrien	      (clobber (reg:CC 17))])
1491990286Sobrien   (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
1492090286Sobrien	      (clobber (reg:CC 17))])]
1492190286Sobrien  ""
1492290286Sobrien{
1492390286Sobrien  if (TARGET_64BIT)
1492490286Sobrien    {
1492590286Sobrien      emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
1492690286Sobrien      DONE;
1492790286Sobrien    }
1492890286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1492990286Sobrien    {
1493090286Sobrien      emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
1493190286Sobrien				operands[1]));
1493290286Sobrien      DONE;
1493390286Sobrien    }
1493490286Sobrien  else 
1493590286Sobrien    operands[2] = gen_reg_rtx (SImode);
1493690286Sobrien})
1493750650Sobrien
1493890286Sobrien(define_expand "strmovsi_rex64"
1493990286Sobrien  [(set (match_dup 2)
1494090286Sobrien  	(mem:SI (match_operand:DI 1 "register_operand" "")))
1494190286Sobrien   (set (mem:SI (match_operand:DI 0 "register_operand" ""))
1494290286Sobrien        (match_dup 2))
1494390286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
1494490286Sobrien	      (clobber (reg:CC 17))])
1494590286Sobrien   (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
1494690286Sobrien	      (clobber (reg:CC 17))])]
1494790286Sobrien  "TARGET_64BIT"
1494890286Sobrien{
1494990286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1495090286Sobrien    {
1495190286Sobrien      emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
1495290286Sobrien				     operands[1]));
1495390286Sobrien      DONE;
1495490286Sobrien    }
1495590286Sobrien  else 
1495690286Sobrien    operands[2] = gen_reg_rtx (SImode);
1495790286Sobrien})
1495850650Sobrien
1495990286Sobrien(define_expand "strmovhi"
1496090286Sobrien  [(set (match_dup 2)
1496190286Sobrien  	(mem:HI (match_operand:SI 1 "register_operand" "")))
1496290286Sobrien   (set (mem:HI (match_operand:SI 0 "register_operand" ""))
1496390286Sobrien        (match_dup 2))
1496490286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
1496590286Sobrien	      (clobber (reg:CC 17))])
1496690286Sobrien   (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
1496790286Sobrien	      (clobber (reg:CC 17))])]
1496890286Sobrien  ""
1496990286Sobrien{
1497090286Sobrien  if (TARGET_64BIT)
1497190286Sobrien    {
1497290286Sobrien      emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
1497390286Sobrien      DONE;
1497490286Sobrien    }
1497590286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1497690286Sobrien    {
1497790286Sobrien      emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
1497890286Sobrien				operands[1]));
1497990286Sobrien      DONE;
1498090286Sobrien    }
1498190286Sobrien  else 
1498290286Sobrien    operands[2] = gen_reg_rtx (HImode);
1498390286Sobrien})
1498450650Sobrien
1498590286Sobrien(define_expand "strmovhi_rex64"
1498690286Sobrien  [(set (match_dup 2)
1498790286Sobrien  	(mem:HI (match_operand:DI 1 "register_operand" "")))
1498890286Sobrien   (set (mem:HI (match_operand:DI 0 "register_operand" ""))
1498990286Sobrien        (match_dup 2))
1499090286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
1499190286Sobrien	      (clobber (reg:CC 17))])
1499290286Sobrien   (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
1499390286Sobrien	      (clobber (reg:CC 17))])]
1499490286Sobrien  "TARGET_64BIT"
1499590286Sobrien{
1499690286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1499790286Sobrien    {
1499890286Sobrien      emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
1499990286Sobrien				     operands[1]));
1500050650Sobrien      DONE;
1500150650Sobrien    }
1500290286Sobrien  else 
1500390286Sobrien    operands[2] = gen_reg_rtx (HImode);
1500490286Sobrien})
1500550650Sobrien
1500690286Sobrien(define_expand "strmovqi"
1500790286Sobrien  [(set (match_dup 2)
1500890286Sobrien  	(mem:QI (match_operand:SI 1 "register_operand" "")))
1500990286Sobrien   (set (mem:QI (match_operand:SI 0 "register_operand" ""))
1501090286Sobrien        (match_dup 2))
1501190286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
1501290286Sobrien	      (clobber (reg:CC 17))])
1501390286Sobrien   (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
1501490286Sobrien	      (clobber (reg:CC 17))])]
1501590286Sobrien  ""
1501690286Sobrien{
1501790286Sobrien  if (TARGET_64BIT)
1501890286Sobrien    {
1501990286Sobrien      emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
1502090286Sobrien      DONE;
1502190286Sobrien    }
1502290286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1502390286Sobrien    {
1502490286Sobrien      emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
1502590286Sobrien				operands[1]));
1502690286Sobrien      DONE;
1502790286Sobrien    }
1502890286Sobrien  else 
1502990286Sobrien    operands[2] = gen_reg_rtx (QImode);
1503090286Sobrien})
1503118334Speter
1503290286Sobrien(define_expand "strmovqi_rex64"
1503390286Sobrien  [(set (match_dup 2)
1503490286Sobrien  	(mem:QI (match_operand:DI 1 "register_operand" "")))
1503590286Sobrien   (set (mem:QI (match_operand:DI 0 "register_operand" ""))
1503690286Sobrien        (match_dup 2))
1503790286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
1503890286Sobrien	      (clobber (reg:CC 17))])
1503990286Sobrien   (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
1504090286Sobrien	      (clobber (reg:CC 17))])]
1504190286Sobrien  "TARGET_64BIT"
1504290286Sobrien{
1504390286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1504490286Sobrien    {
1504590286Sobrien      emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
1504690286Sobrien				     operands[1]));
1504790286Sobrien      DONE;
1504890286Sobrien    }
1504990286Sobrien  else 
1505090286Sobrien    operands[2] = gen_reg_rtx (QImode);
1505190286Sobrien})
1505218334Speter
1505390286Sobrien(define_insn "strmovdi_rex_1"
1505490286Sobrien  [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
1505590286Sobrien	(mem:DI (match_operand:DI 3 "register_operand" "1")))
1505690286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1505790286Sobrien	(plus:DI (match_dup 2)
1505890286Sobrien		 (const_int 8)))
1505990286Sobrien   (set (match_operand:DI 1 "register_operand" "=S")
1506090286Sobrien	(plus:DI (match_dup 3)
1506190286Sobrien		 (const_int 8)))
1506290286Sobrien   (use (reg:SI 19))]
1506390286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1506490286Sobrien  "movsq"
1506590286Sobrien  [(set_attr "type" "str")
1506690286Sobrien   (set_attr "mode" "DI")
1506790286Sobrien   (set_attr "memory" "both")])
1506890286Sobrien
1506990286Sobrien(define_insn "strmovsi_1"
1507090286Sobrien  [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
1507190286Sobrien	(mem:SI (match_operand:SI 3 "register_operand" "1")))
1507290286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1507390286Sobrien	(plus:SI (match_dup 2)
1507490286Sobrien		 (const_int 4)))
1507590286Sobrien   (set (match_operand:SI 1 "register_operand" "=S")
1507690286Sobrien	(plus:SI (match_dup 3)
1507790286Sobrien		 (const_int 4)))
1507890286Sobrien   (use (reg:SI 19))]
1507990286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1508090286Sobrien  "{movsl|movsd}"
1508190286Sobrien  [(set_attr "type" "str")
1508290286Sobrien   (set_attr "mode" "SI")
1508390286Sobrien   (set_attr "memory" "both")])
1508490286Sobrien
1508590286Sobrien(define_insn "strmovsi_rex_1"
1508690286Sobrien  [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
1508790286Sobrien	(mem:SI (match_operand:DI 3 "register_operand" "1")))
1508890286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1508990286Sobrien	(plus:DI (match_dup 2)
1509090286Sobrien		 (const_int 4)))
1509190286Sobrien   (set (match_operand:DI 1 "register_operand" "=S")
1509290286Sobrien	(plus:DI (match_dup 3)
1509390286Sobrien		 (const_int 4)))
1509490286Sobrien   (use (reg:SI 19))]
1509590286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1509690286Sobrien  "{movsl|movsd}"
1509790286Sobrien  [(set_attr "type" "str")
1509890286Sobrien   (set_attr "mode" "SI")
1509990286Sobrien   (set_attr "memory" "both")])
1510090286Sobrien
1510190286Sobrien(define_insn "strmovhi_1"
1510290286Sobrien  [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
1510390286Sobrien	(mem:HI (match_operand:SI 3 "register_operand" "1")))
1510490286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1510590286Sobrien	(plus:SI (match_dup 2)
1510690286Sobrien		 (const_int 2)))
1510790286Sobrien   (set (match_operand:SI 1 "register_operand" "=S")
1510890286Sobrien	(plus:SI (match_dup 3)
1510990286Sobrien		 (const_int 2)))
1511090286Sobrien   (use (reg:SI 19))]
1511190286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1511290286Sobrien  "movsw"
1511390286Sobrien  [(set_attr "type" "str")
1511490286Sobrien   (set_attr "memory" "both")
1511590286Sobrien   (set_attr "mode" "HI")])
1511690286Sobrien
1511790286Sobrien(define_insn "strmovhi_rex_1"
1511890286Sobrien  [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
1511990286Sobrien	(mem:HI (match_operand:DI 3 "register_operand" "1")))
1512090286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1512190286Sobrien	(plus:DI (match_dup 2)
1512290286Sobrien		 (const_int 2)))
1512390286Sobrien   (set (match_operand:DI 1 "register_operand" "=S")
1512490286Sobrien	(plus:DI (match_dup 3)
1512590286Sobrien		 (const_int 2)))
1512690286Sobrien   (use (reg:SI 19))]
1512790286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1512890286Sobrien  "movsw"
1512990286Sobrien  [(set_attr "type" "str")
1513090286Sobrien   (set_attr "memory" "both")
1513190286Sobrien   (set_attr "mode" "HI")])
1513290286Sobrien
1513390286Sobrien(define_insn "strmovqi_1"
1513490286Sobrien  [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
1513590286Sobrien	(mem:QI (match_operand:SI 3 "register_operand" "1")))
1513690286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1513790286Sobrien	(plus:SI (match_dup 2)
1513890286Sobrien		 (const_int 1)))
1513990286Sobrien   (set (match_operand:SI 1 "register_operand" "=S")
1514090286Sobrien	(plus:SI (match_dup 3)
1514190286Sobrien		 (const_int 1)))
1514290286Sobrien   (use (reg:SI 19))]
1514390286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1514490286Sobrien  "movsb"
1514590286Sobrien  [(set_attr "type" "str")
1514690286Sobrien   (set_attr "memory" "both")
1514790286Sobrien   (set_attr "mode" "QI")])
1514890286Sobrien
1514990286Sobrien(define_insn "strmovqi_rex_1"
1515090286Sobrien  [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
1515190286Sobrien	(mem:QI (match_operand:DI 3 "register_operand" "1")))
1515290286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1515390286Sobrien	(plus:DI (match_dup 2)
1515490286Sobrien		 (const_int 1)))
1515590286Sobrien   (set (match_operand:DI 1 "register_operand" "=S")
1515690286Sobrien	(plus:DI (match_dup 3)
1515790286Sobrien		 (const_int 1)))
1515890286Sobrien   (use (reg:SI 19))]
1515990286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1516090286Sobrien  "movsb"
1516190286Sobrien  [(set_attr "type" "str")
1516290286Sobrien   (set_attr "memory" "both")
1516390286Sobrien   (set_attr "mode" "QI")])
1516490286Sobrien
1516590286Sobrien(define_insn "rep_movdi_rex64"
1516690286Sobrien  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
1516790286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1516890286Sobrien        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
1516990286Sobrien			    (const_int 3))
1517090286Sobrien		 (match_operand:DI 3 "register_operand" "0")))
1517190286Sobrien   (set (match_operand:DI 1 "register_operand" "=S") 
1517290286Sobrien        (plus:DI (ashift:DI (match_dup 5) (const_int 3))
1517390286Sobrien		 (match_operand:DI 4 "register_operand" "1")))
1517490286Sobrien   (set (mem:BLK (match_dup 3))
1517590286Sobrien	(mem:BLK (match_dup 4)))
1517690286Sobrien   (use (match_dup 5))
1517790286Sobrien   (use (reg:SI 19))]
1517890286Sobrien  "TARGET_64BIT"
1517990286Sobrien  "{rep\;movsq|rep movsq}"
1518090286Sobrien  [(set_attr "type" "str")
1518190286Sobrien   (set_attr "prefix_rep" "1")
1518290286Sobrien   (set_attr "memory" "both")
1518390286Sobrien   (set_attr "mode" "DI")])
1518490286Sobrien
1518590286Sobrien(define_insn "rep_movsi"
1518690286Sobrien  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
1518790286Sobrien   (set (match_operand:SI 0 "register_operand" "=D") 
1518890286Sobrien        (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
1518990286Sobrien			    (const_int 2))
1519090286Sobrien		 (match_operand:SI 3 "register_operand" "0")))
1519190286Sobrien   (set (match_operand:SI 1 "register_operand" "=S") 
1519290286Sobrien        (plus:SI (ashift:SI (match_dup 5) (const_int 2))
1519390286Sobrien		 (match_operand:SI 4 "register_operand" "1")))
1519490286Sobrien   (set (mem:BLK (match_dup 3))
1519590286Sobrien	(mem:BLK (match_dup 4)))
1519690286Sobrien   (use (match_dup 5))
1519790286Sobrien   (use (reg:SI 19))]
1519890286Sobrien  "!TARGET_64BIT"
1519990286Sobrien  "{rep\;movsl|rep movsd}"
1520090286Sobrien  [(set_attr "type" "str")
1520190286Sobrien   (set_attr "prefix_rep" "1")
1520290286Sobrien   (set_attr "memory" "both")
1520390286Sobrien   (set_attr "mode" "SI")])
1520490286Sobrien
1520590286Sobrien(define_insn "rep_movsi_rex64"
1520690286Sobrien  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
1520790286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1520890286Sobrien        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
1520990286Sobrien			    (const_int 2))
1521090286Sobrien		 (match_operand:DI 3 "register_operand" "0")))
1521190286Sobrien   (set (match_operand:DI 1 "register_operand" "=S") 
1521290286Sobrien        (plus:DI (ashift:DI (match_dup 5) (const_int 2))
1521390286Sobrien		 (match_operand:DI 4 "register_operand" "1")))
1521490286Sobrien   (set (mem:BLK (match_dup 3))
1521590286Sobrien	(mem:BLK (match_dup 4)))
1521690286Sobrien   (use (match_dup 5))
1521790286Sobrien   (use (reg:SI 19))]
1521890286Sobrien  "TARGET_64BIT"
1521990286Sobrien  "{rep\;movsl|rep movsd}"
1522090286Sobrien  [(set_attr "type" "str")
1522190286Sobrien   (set_attr "prefix_rep" "1")
1522290286Sobrien   (set_attr "memory" "both")
1522390286Sobrien   (set_attr "mode" "SI")])
1522490286Sobrien
1522590286Sobrien(define_insn "rep_movqi"
1522690286Sobrien  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
1522790286Sobrien   (set (match_operand:SI 0 "register_operand" "=D") 
1522890286Sobrien        (plus:SI (match_operand:SI 3 "register_operand" "0")
1522990286Sobrien		 (match_operand:SI 5 "register_operand" "2")))
1523090286Sobrien   (set (match_operand:SI 1 "register_operand" "=S") 
1523190286Sobrien        (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
1523290286Sobrien   (set (mem:BLK (match_dup 3))
1523390286Sobrien	(mem:BLK (match_dup 4)))
1523490286Sobrien   (use (match_dup 5))
1523590286Sobrien   (use (reg:SI 19))]
1523690286Sobrien  "!TARGET_64BIT"
1523790286Sobrien  "{rep\;movsb|rep movsb}"
1523890286Sobrien  [(set_attr "type" "str")
1523990286Sobrien   (set_attr "prefix_rep" "1")
1524090286Sobrien   (set_attr "memory" "both")
1524190286Sobrien   (set_attr "mode" "SI")])
1524290286Sobrien
1524390286Sobrien(define_insn "rep_movqi_rex64"
1524490286Sobrien  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
1524590286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1524690286Sobrien        (plus:DI (match_operand:DI 3 "register_operand" "0")
1524790286Sobrien		 (match_operand:DI 5 "register_operand" "2")))
1524890286Sobrien   (set (match_operand:DI 1 "register_operand" "=S") 
1524990286Sobrien        (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
1525090286Sobrien   (set (mem:BLK (match_dup 3))
1525190286Sobrien	(mem:BLK (match_dup 4)))
1525290286Sobrien   (use (match_dup 5))
1525390286Sobrien   (use (reg:SI 19))]
1525490286Sobrien  "TARGET_64BIT"
1525590286Sobrien  "{rep\;movsb|rep movsb}"
1525690286Sobrien  [(set_attr "type" "str")
1525790286Sobrien   (set_attr "prefix_rep" "1")
1525890286Sobrien   (set_attr "memory" "both")
1525990286Sobrien   (set_attr "mode" "SI")])
1526090286Sobrien
1526190286Sobrien(define_expand "clrstrsi"
1526290286Sobrien   [(use (match_operand:BLK 0 "memory_operand" ""))
1526390286Sobrien    (use (match_operand:SI 1 "nonmemory_operand" ""))
1526490286Sobrien    (use (match_operand 2 "const_int_operand" ""))]
1526518334Speter  ""
1526618334Speter{
1526790286Sobrien if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
1526890286Sobrien   DONE;
1526990286Sobrien else
1527090286Sobrien   FAIL;
1527190286Sobrien})
1527218334Speter
1527390286Sobrien(define_expand "clrstrdi"
1527490286Sobrien   [(use (match_operand:BLK 0 "memory_operand" ""))
1527590286Sobrien    (use (match_operand:DI 1 "nonmemory_operand" ""))
1527690286Sobrien    (use (match_operand 2 "const_int_operand" ""))]
1527790286Sobrien  "TARGET_64BIT"
1527890286Sobrien{
1527990286Sobrien if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
1528090286Sobrien   DONE;
1528190286Sobrien else
1528290286Sobrien   FAIL;
1528390286Sobrien})
1528450650Sobrien
1528590286Sobrien;; Most CPUs don't like single string operations
1528690286Sobrien;; Handle this case here to simplify previous expander.
1528750650Sobrien
1528890286Sobrien(define_expand "strsetdi_rex64"
1528990286Sobrien  [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
1529090286Sobrien	(match_operand:DI 1 "register_operand" ""))
1529190286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
1529290286Sobrien	      (clobber (reg:CC 17))])]
1529390286Sobrien  "TARGET_64BIT"
1529490286Sobrien{
1529590286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1529690286Sobrien    {
1529790286Sobrien      emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
1529890286Sobrien      DONE;
1529990286Sobrien    }
1530090286Sobrien})
1530190286Sobrien
1530290286Sobrien(define_expand "strsetsi"
1530390286Sobrien  [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
1530490286Sobrien	(match_operand:SI 1 "register_operand" ""))
1530590286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
1530690286Sobrien	      (clobber (reg:CC 17))])]
1530790286Sobrien  ""
1530890286Sobrien{
1530990286Sobrien  if (TARGET_64BIT)
1531090286Sobrien    {
1531190286Sobrien      emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
1531290286Sobrien      DONE;
1531390286Sobrien    }
1531490286Sobrien  else if (TARGET_SINGLE_STRINGOP || optimize_size)
1531590286Sobrien    {
1531690286Sobrien      emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
1531790286Sobrien      DONE;
1531890286Sobrien    }
1531990286Sobrien})
1532090286Sobrien
1532190286Sobrien(define_expand "strsetsi_rex64"
1532290286Sobrien  [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
1532390286Sobrien	(match_operand:SI 1 "register_operand" ""))
1532490286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
1532590286Sobrien	      (clobber (reg:CC 17))])]
1532690286Sobrien  "TARGET_64BIT"
1532790286Sobrien{
1532890286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1532990286Sobrien    {
1533090286Sobrien      emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
1533190286Sobrien      DONE;
1533290286Sobrien    }
1533390286Sobrien})
1533490286Sobrien
1533590286Sobrien(define_expand "strsethi"
1533690286Sobrien  [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
1533790286Sobrien	(match_operand:HI 1 "register_operand" ""))
1533890286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
1533990286Sobrien	      (clobber (reg:CC 17))])]
1534090286Sobrien  ""
1534190286Sobrien{
1534290286Sobrien  if (TARGET_64BIT)
1534390286Sobrien    {
1534490286Sobrien      emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
1534590286Sobrien      DONE;
1534690286Sobrien    }
1534790286Sobrien  else if (TARGET_SINGLE_STRINGOP || optimize_size)
1534890286Sobrien    {
1534990286Sobrien      emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
1535090286Sobrien      DONE;
1535190286Sobrien    }
1535290286Sobrien})
1535390286Sobrien
1535490286Sobrien(define_expand "strsethi_rex64"
1535590286Sobrien  [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
1535690286Sobrien	(match_operand:HI 1 "register_operand" ""))
1535790286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
1535890286Sobrien	      (clobber (reg:CC 17))])]
1535990286Sobrien  "TARGET_64BIT"
1536090286Sobrien{
1536190286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1536290286Sobrien    {
1536390286Sobrien      emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
1536490286Sobrien      DONE;
1536590286Sobrien    }
1536690286Sobrien})
1536790286Sobrien
1536890286Sobrien(define_expand "strsetqi"
1536990286Sobrien  [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
1537090286Sobrien	(match_operand:QI 1 "register_operand" ""))
1537190286Sobrien   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
1537290286Sobrien	      (clobber (reg:CC 17))])]
1537390286Sobrien  ""
1537490286Sobrien{
1537590286Sobrien  if (TARGET_64BIT)
1537690286Sobrien    {
1537790286Sobrien      emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
1537890286Sobrien      DONE;
1537990286Sobrien    }
1538090286Sobrien  else if (TARGET_SINGLE_STRINGOP || optimize_size)
1538190286Sobrien    {
1538290286Sobrien      emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
1538390286Sobrien      DONE;
1538490286Sobrien    }
1538590286Sobrien})
1538690286Sobrien
1538790286Sobrien(define_expand "strsetqi_rex64"
1538890286Sobrien  [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
1538990286Sobrien	(match_operand:QI 1 "register_operand" ""))
1539090286Sobrien   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
1539190286Sobrien	      (clobber (reg:CC 17))])]
1539290286Sobrien  "TARGET_64BIT"
1539390286Sobrien{
1539490286Sobrien  if (TARGET_SINGLE_STRINGOP || optimize_size)
1539590286Sobrien    {
1539690286Sobrien      emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
1539790286Sobrien      DONE;
1539890286Sobrien    }
1539990286Sobrien})
1540090286Sobrien
1540190286Sobrien(define_insn "strsetdi_rex_1"
1540290286Sobrien  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
1540390286Sobrien	(match_operand:SI 2 "register_operand" "a"))
1540490286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1540590286Sobrien	(plus:DI (match_dup 1)
1540690286Sobrien		 (const_int 8)))
1540790286Sobrien   (use (reg:SI 19))]
1540890286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1540990286Sobrien  "stosq"
1541090286Sobrien  [(set_attr "type" "str")
1541190286Sobrien   (set_attr "memory" "store")
1541290286Sobrien   (set_attr "mode" "DI")])
1541390286Sobrien
1541490286Sobrien(define_insn "strsetsi_1"
1541590286Sobrien  [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
1541690286Sobrien	(match_operand:SI 2 "register_operand" "a"))
1541790286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1541890286Sobrien	(plus:SI (match_dup 1)
1541990286Sobrien		 (const_int 4)))
1542090286Sobrien   (use (reg:SI 19))]
1542190286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1542290286Sobrien  "{stosl|stosd}"
1542390286Sobrien  [(set_attr "type" "str")
1542490286Sobrien   (set_attr "memory" "store")
1542590286Sobrien   (set_attr "mode" "SI")])
1542690286Sobrien
1542790286Sobrien(define_insn "strsetsi_rex_1"
1542890286Sobrien  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
1542990286Sobrien	(match_operand:SI 2 "register_operand" "a"))
1543090286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1543190286Sobrien	(plus:DI (match_dup 1)
1543290286Sobrien		 (const_int 4)))
1543390286Sobrien   (use (reg:SI 19))]
1543490286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1543590286Sobrien  "{stosl|stosd}"
1543690286Sobrien  [(set_attr "type" "str")
1543790286Sobrien   (set_attr "memory" "store")
1543890286Sobrien   (set_attr "mode" "SI")])
1543990286Sobrien
1544090286Sobrien(define_insn "strsethi_1"
1544190286Sobrien  [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
1544290286Sobrien	(match_operand:HI 2 "register_operand" "a"))
1544390286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1544490286Sobrien	(plus:SI (match_dup 1)
1544590286Sobrien		 (const_int 2)))
1544690286Sobrien   (use (reg:SI 19))]
1544790286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1544890286Sobrien  "stosw"
1544990286Sobrien  [(set_attr "type" "str")
1545090286Sobrien   (set_attr "memory" "store")
1545190286Sobrien   (set_attr "mode" "HI")])
1545290286Sobrien
1545390286Sobrien(define_insn "strsethi_rex_1"
1545490286Sobrien  [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
1545590286Sobrien	(match_operand:HI 2 "register_operand" "a"))
1545690286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1545790286Sobrien	(plus:DI (match_dup 1)
1545890286Sobrien		 (const_int 2)))
1545990286Sobrien   (use (reg:SI 19))]
1546090286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1546190286Sobrien  "stosw"
1546290286Sobrien  [(set_attr "type" "str")
1546390286Sobrien   (set_attr "memory" "store")
1546490286Sobrien   (set_attr "mode" "HI")])
1546590286Sobrien
1546690286Sobrien(define_insn "strsetqi_1"
1546790286Sobrien  [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
1546890286Sobrien	(match_operand:QI 2 "register_operand" "a"))
1546990286Sobrien   (set (match_operand:SI 0 "register_operand" "=D")
1547090286Sobrien	(plus:SI (match_dup 1)
1547190286Sobrien		 (const_int 1)))
1547290286Sobrien   (use (reg:SI 19))]
1547390286Sobrien  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1547490286Sobrien  "stosb"
1547590286Sobrien  [(set_attr "type" "str")
1547690286Sobrien   (set_attr "memory" "store")
1547790286Sobrien   (set_attr "mode" "QI")])
1547890286Sobrien
1547990286Sobrien(define_insn "strsetqi_rex_1"
1548090286Sobrien  [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
1548190286Sobrien	(match_operand:QI 2 "register_operand" "a"))
1548290286Sobrien   (set (match_operand:DI 0 "register_operand" "=D")
1548390286Sobrien	(plus:DI (match_dup 1)
1548490286Sobrien		 (const_int 1)))
1548590286Sobrien   (use (reg:SI 19))]
1548690286Sobrien  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
1548790286Sobrien  "stosb"
1548890286Sobrien  [(set_attr "type" "str")
1548990286Sobrien   (set_attr "memory" "store")
1549090286Sobrien   (set_attr "mode" "QI")])
1549190286Sobrien
1549290286Sobrien(define_insn "rep_stosdi_rex64"
1549390286Sobrien  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
1549490286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1549590286Sobrien        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
1549690286Sobrien			    (const_int 3))
1549790286Sobrien		 (match_operand:DI 3 "register_operand" "0")))
1549890286Sobrien   (set (mem:BLK (match_dup 3))
1549990286Sobrien	(const_int 0))
1550090286Sobrien   (use (match_operand:DI 2 "register_operand" "a"))
1550190286Sobrien   (use (match_dup 4))
1550290286Sobrien   (use (reg:SI 19))]
1550390286Sobrien  "TARGET_64BIT"
1550490286Sobrien  "{rep\;stosq|rep stosq}"
1550590286Sobrien  [(set_attr "type" "str")
1550690286Sobrien   (set_attr "prefix_rep" "1")
1550790286Sobrien   (set_attr "memory" "store")
1550890286Sobrien   (set_attr "mode" "DI")])
1550990286Sobrien
1551090286Sobrien(define_insn "rep_stossi"
1551190286Sobrien  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
1551290286Sobrien   (set (match_operand:SI 0 "register_operand" "=D") 
1551390286Sobrien        (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
1551490286Sobrien			    (const_int 2))
1551590286Sobrien		 (match_operand:SI 3 "register_operand" "0")))
1551690286Sobrien   (set (mem:BLK (match_dup 3))
1551790286Sobrien	(const_int 0))
1551890286Sobrien   (use (match_operand:SI 2 "register_operand" "a"))
1551990286Sobrien   (use (match_dup 4))
1552090286Sobrien   (use (reg:SI 19))]
1552190286Sobrien  "!TARGET_64BIT"
1552290286Sobrien  "{rep\;stosl|rep stosd}"
1552390286Sobrien  [(set_attr "type" "str")
1552490286Sobrien   (set_attr "prefix_rep" "1")
1552590286Sobrien   (set_attr "memory" "store")
1552690286Sobrien   (set_attr "mode" "SI")])
1552790286Sobrien
1552890286Sobrien(define_insn "rep_stossi_rex64"
1552990286Sobrien  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
1553090286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1553190286Sobrien        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
1553290286Sobrien			    (const_int 2))
1553390286Sobrien		 (match_operand:DI 3 "register_operand" "0")))
1553490286Sobrien   (set (mem:BLK (match_dup 3))
1553590286Sobrien	(const_int 0))
1553690286Sobrien   (use (match_operand:SI 2 "register_operand" "a"))
1553790286Sobrien   (use (match_dup 4))
1553890286Sobrien   (use (reg:SI 19))]
1553990286Sobrien  "TARGET_64BIT"
1554090286Sobrien  "{rep\;stosl|rep stosd}"
1554190286Sobrien  [(set_attr "type" "str")
1554290286Sobrien   (set_attr "prefix_rep" "1")
1554390286Sobrien   (set_attr "memory" "store")
1554490286Sobrien   (set_attr "mode" "SI")])
1554590286Sobrien
1554690286Sobrien(define_insn "rep_stosqi"
1554790286Sobrien  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
1554890286Sobrien   (set (match_operand:SI 0 "register_operand" "=D") 
1554990286Sobrien        (plus:SI (match_operand:SI 3 "register_operand" "0")
1555090286Sobrien		 (match_operand:SI 4 "register_operand" "1")))
1555190286Sobrien   (set (mem:BLK (match_dup 3))
1555290286Sobrien	(const_int 0))
1555390286Sobrien   (use (match_operand:QI 2 "register_operand" "a"))
1555490286Sobrien   (use (match_dup 4))
1555590286Sobrien   (use (reg:SI 19))]
1555690286Sobrien  "!TARGET_64BIT"
1555790286Sobrien  "{rep\;stosb|rep stosb}"
1555890286Sobrien  [(set_attr "type" "str")
1555990286Sobrien   (set_attr "prefix_rep" "1")
1556090286Sobrien   (set_attr "memory" "store")
1556190286Sobrien   (set_attr "mode" "QI")])
1556290286Sobrien
1556390286Sobrien(define_insn "rep_stosqi_rex64"
1556490286Sobrien  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
1556590286Sobrien   (set (match_operand:DI 0 "register_operand" "=D") 
1556690286Sobrien        (plus:DI (match_operand:DI 3 "register_operand" "0")
1556790286Sobrien		 (match_operand:DI 4 "register_operand" "1")))
1556890286Sobrien   (set (mem:BLK (match_dup 3))
1556990286Sobrien	(const_int 0))
1557090286Sobrien   (use (match_operand:QI 2 "register_operand" "a"))
1557190286Sobrien   (use (match_dup 4))
1557290286Sobrien   (use (reg:DI 19))]
1557390286Sobrien  "TARGET_64BIT"
1557490286Sobrien  "{rep\;stosb|rep stosb}"
1557590286Sobrien  [(set_attr "type" "str")
1557690286Sobrien   (set_attr "prefix_rep" "1")
1557790286Sobrien   (set_attr "memory" "store")
1557890286Sobrien   (set_attr "mode" "QI")])
1557990286Sobrien
1558090286Sobrien(define_expand "cmpstrsi"
1558150650Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1558290286Sobrien	(compare:SI (match_operand:BLK 1 "general_operand" "")
1558390286Sobrien		    (match_operand:BLK 2 "general_operand" "")))
1558490286Sobrien   (use (match_operand 3 "general_operand" ""))
1558590286Sobrien   (use (match_operand 4 "immediate_operand" ""))]
1558690286Sobrien  ""
1558750650Sobrien{
1558890286Sobrien  rtx addr1, addr2, out, outlow, count, countreg, align;
1558950650Sobrien
1559090286Sobrien  out = operands[0];
1559190286Sobrien  if (GET_CODE (out) != REG)
1559290286Sobrien    out = gen_reg_rtx (SImode);
1559350650Sobrien
1559490286Sobrien  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1559590286Sobrien  addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
1559690286Sobrien  
1559790286Sobrien  count = operands[3];
1559890286Sobrien  countreg = ix86_zero_extend_to_Pmode (count);
1559950650Sobrien
1560090286Sobrien  /* %%% Iff we are testing strict equality, we can use known alignment
1560190286Sobrien     to good advantage.  This may be possible with combine, particularly
1560290286Sobrien     once cc0 is dead.  */
1560390286Sobrien  align = operands[4];
1560450650Sobrien
1560590286Sobrien  emit_insn (gen_cld ());
1560690286Sobrien  if (GET_CODE (count) == CONST_INT)
1560790286Sobrien    {
1560890286Sobrien      if (INTVAL (count) == 0)
1560990286Sobrien	{
1561090286Sobrien	  emit_move_insn (operands[0], const0_rtx);
1561190286Sobrien	  DONE;
1561290286Sobrien	}
1561390286Sobrien      if (TARGET_64BIT)
1561490286Sobrien	emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
1561590286Sobrien					  addr1, addr2, countreg));
1561690286Sobrien      else
1561790286Sobrien	emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
1561890286Sobrien				      addr1, addr2, countreg));
1561990286Sobrien    }
1562090286Sobrien  else
1562190286Sobrien    {
1562290286Sobrien      if (TARGET_64BIT)
1562390286Sobrien	{
1562490286Sobrien	  emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
1562590286Sobrien	  emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
1562690286Sobrien					 addr1, addr2, countreg));
1562790286Sobrien	}
1562890286Sobrien      else
1562990286Sobrien	{
1563090286Sobrien	  emit_insn (gen_cmpsi_1 (countreg, countreg));
1563190286Sobrien	  emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
1563290286Sobrien				     addr1, addr2, countreg));
1563390286Sobrien	}
1563490286Sobrien    }
1563590286Sobrien
1563690286Sobrien  outlow = gen_lowpart (QImode, out);
1563790286Sobrien  emit_insn (gen_cmpintqi (outlow));
1563890286Sobrien  emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
1563990286Sobrien
1564090286Sobrien  if (operands[0] != out)
1564190286Sobrien    emit_move_insn (operands[0], out);
1564290286Sobrien
1564390286Sobrien  DONE;
1564490286Sobrien})
1564590286Sobrien
1564690286Sobrien;; Produce a tri-state integer (-1, 0, 1) from condition codes.
1564790286Sobrien
1564890286Sobrien(define_expand "cmpintqi"
1564990286Sobrien  [(set (match_dup 1)
1565090286Sobrien	(gtu:QI (reg:CC 17) (const_int 0)))
1565190286Sobrien   (set (match_dup 2)
1565290286Sobrien	(ltu:QI (reg:CC 17) (const_int 0)))
1565390286Sobrien   (parallel [(set (match_operand:QI 0 "register_operand" "")
1565490286Sobrien		   (minus:QI (match_dup 1)
1565590286Sobrien			     (match_dup 2)))
1565690286Sobrien	      (clobber (reg:CC 17))])]
1565790286Sobrien  ""
1565890286Sobrien  "operands[1] = gen_reg_rtx (QImode);
1565990286Sobrien   operands[2] = gen_reg_rtx (QImode);")
1566090286Sobrien
1566190286Sobrien;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
1566290286Sobrien;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
1566390286Sobrien
1566490286Sobrien(define_insn "cmpstrqi_nz_1"
1566590286Sobrien  [(set (reg:CC 17)
1566690286Sobrien	(compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
1566790286Sobrien		    (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
1566890286Sobrien   (use (match_operand:SI 6 "register_operand" "2"))
1566990286Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
1567090286Sobrien   (use (reg:SI 19))
1567190286Sobrien   (clobber (match_operand:SI 0 "register_operand" "=S"))
1567290286Sobrien   (clobber (match_operand:SI 1 "register_operand" "=D"))
1567390286Sobrien   (clobber (match_operand:SI 2 "register_operand" "=c"))]
1567490286Sobrien  "!TARGET_64BIT"
1567590286Sobrien  "repz{\;| }cmpsb"
1567690286Sobrien  [(set_attr "type" "str")
1567790286Sobrien   (set_attr "mode" "QI")
1567890286Sobrien   (set_attr "prefix_rep" "1")])
1567990286Sobrien
1568090286Sobrien(define_insn "cmpstrqi_nz_rex_1"
1568190286Sobrien  [(set (reg:CC 17)
1568290286Sobrien	(compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
1568390286Sobrien		    (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
1568490286Sobrien   (use (match_operand:DI 6 "register_operand" "2"))
1568590286Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
1568690286Sobrien   (use (reg:SI 19))
1568790286Sobrien   (clobber (match_operand:DI 0 "register_operand" "=S"))
1568890286Sobrien   (clobber (match_operand:DI 1 "register_operand" "=D"))
1568990286Sobrien   (clobber (match_operand:DI 2 "register_operand" "=c"))]
1569090286Sobrien  "TARGET_64BIT"
1569190286Sobrien  "repz{\;| }cmpsb"
1569290286Sobrien  [(set_attr "type" "str")
1569390286Sobrien   (set_attr "mode" "QI")
1569490286Sobrien   (set_attr "prefix_rep" "1")])
1569590286Sobrien
1569690286Sobrien;; The same, but the count is not known to not be zero.
1569790286Sobrien
1569890286Sobrien(define_insn "cmpstrqi_1"
1569990286Sobrien  [(set (reg:CC 17)
1570090286Sobrien	(if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
1570190286Sobrien			     (const_int 0))
1570290286Sobrien	  (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
1570390286Sobrien		      (mem:BLK (match_operand:SI 5 "register_operand" "1")))
1570490286Sobrien	  (const_int 0)))
1570590286Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
1570690286Sobrien   (use (reg:CC 17))
1570790286Sobrien   (use (reg:SI 19))
1570890286Sobrien   (clobber (match_operand:SI 0 "register_operand" "=S"))
1570990286Sobrien   (clobber (match_operand:SI 1 "register_operand" "=D"))
1571090286Sobrien   (clobber (match_operand:SI 2 "register_operand" "=c"))]
1571190286Sobrien  "!TARGET_64BIT"
1571290286Sobrien  "repz{\;| }cmpsb"
1571390286Sobrien  [(set_attr "type" "str")
1571490286Sobrien   (set_attr "mode" "QI")
1571590286Sobrien   (set_attr "prefix_rep" "1")])
1571690286Sobrien
1571790286Sobrien(define_insn "cmpstrqi_rex_1"
1571890286Sobrien  [(set (reg:CC 17)
1571990286Sobrien	(if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
1572090286Sobrien			     (const_int 0))
1572190286Sobrien	  (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
1572290286Sobrien		      (mem:BLK (match_operand:DI 5 "register_operand" "1")))
1572390286Sobrien	  (const_int 0)))
1572490286Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
1572590286Sobrien   (use (reg:CC 17))
1572690286Sobrien   (use (reg:SI 19))
1572790286Sobrien   (clobber (match_operand:DI 0 "register_operand" "=S"))
1572890286Sobrien   (clobber (match_operand:DI 1 "register_operand" "=D"))
1572990286Sobrien   (clobber (match_operand:DI 2 "register_operand" "=c"))]
1573090286Sobrien  "TARGET_64BIT"
1573190286Sobrien  "repz{\;| }cmpsb"
1573290286Sobrien  [(set_attr "type" "str")
1573390286Sobrien   (set_attr "mode" "QI")
1573490286Sobrien   (set_attr "prefix_rep" "1")])
1573590286Sobrien
1573690286Sobrien(define_expand "strlensi"
1573752296Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1573890286Sobrien	(unspec:SI [(match_operand:BLK 1 "general_operand" "")
1573990286Sobrien		    (match_operand:QI 2 "immediate_operand" "")
1574090286Sobrien		    (match_operand 3 "immediate_operand" "")] 0))]
1574190286Sobrien  ""
1574290286Sobrien{
1574390286Sobrien if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
1574490286Sobrien   DONE;
1574590286Sobrien else
1574690286Sobrien   FAIL;
1574790286Sobrien})
1574890286Sobrien
1574990286Sobrien(define_expand "strlendi"
1575090286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1575190286Sobrien	(unspec:DI [(match_operand:BLK 1 "general_operand" "")
1575290286Sobrien		    (match_operand:QI 2 "immediate_operand" "")
1575390286Sobrien		    (match_operand 3 "immediate_operand" "")] 0))]
1575490286Sobrien  ""
1575590286Sobrien{
1575690286Sobrien if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
1575790286Sobrien   DONE;
1575890286Sobrien else
1575990286Sobrien   FAIL;
1576090286Sobrien})
1576190286Sobrien
1576290286Sobrien(define_insn "strlenqi_1"
1576390286Sobrien  [(set (match_operand:SI 0 "register_operand" "=&c")
1576490286Sobrien	(unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
1576590286Sobrien		    (match_operand:QI 2 "register_operand" "a")
1576690286Sobrien		    (match_operand:SI 3 "immediate_operand" "i")
1576790286Sobrien		    (match_operand:SI 4 "register_operand" "0")] 0))
1576890286Sobrien   (use (reg:SI 19))
1576990286Sobrien   (clobber (match_operand:SI 1 "register_operand" "=D"))
1577090286Sobrien   (clobber (reg:CC 17))]
1577190286Sobrien  "!TARGET_64BIT"
1577290286Sobrien  "repnz{\;| }scasb"
1577390286Sobrien  [(set_attr "type" "str")
1577490286Sobrien   (set_attr "mode" "QI")
1577590286Sobrien   (set_attr "prefix_rep" "1")])
1577690286Sobrien
1577790286Sobrien(define_insn "strlenqi_rex_1"
1577890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=&c")
1577990286Sobrien	(unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
1578090286Sobrien		    (match_operand:QI 2 "register_operand" "a")
1578190286Sobrien		    (match_operand:DI 3 "immediate_operand" "i")
1578290286Sobrien		    (match_operand:DI 4 "register_operand" "0")] 0))
1578390286Sobrien   (use (reg:SI 19))
1578490286Sobrien   (clobber (match_operand:DI 1 "register_operand" "=D"))
1578590286Sobrien   (clobber (reg:CC 17))]
1578690286Sobrien  "TARGET_64BIT"
1578790286Sobrien  "repnz{\;| }scasb"
1578890286Sobrien  [(set_attr "type" "str")
1578990286Sobrien   (set_attr "mode" "QI")
1579090286Sobrien   (set_attr "prefix_rep" "1")])
1579190286Sobrien
1579290286Sobrien;; Peephole optimizations to clean up after cmpstr*.  This should be
1579390286Sobrien;; handled in combine, but it is not currently up to the task.
1579490286Sobrien;; When used for their truth value, the cmpstr* expanders generate
1579590286Sobrien;; code like this:
1579690286Sobrien;;
1579790286Sobrien;;   repz cmpsb
1579890286Sobrien;;   seta 	%al
1579990286Sobrien;;   setb 	%dl
1580090286Sobrien;;   cmpb 	%al, %dl
1580190286Sobrien;;   jcc	label
1580290286Sobrien;;
1580390286Sobrien;; The intermediate three instructions are unnecessary.
1580490286Sobrien
1580590286Sobrien;; This one handles cmpstr*_nz_1...
1580690286Sobrien(define_peephole2
1580790286Sobrien  [(parallel[
1580890286Sobrien     (set (reg:CC 17)
1580990286Sobrien	  (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
1581090286Sobrien		      (mem:BLK (match_operand 5 "register_operand" ""))))
1581190286Sobrien     (use (match_operand 6 "register_operand" ""))
1581290286Sobrien     (use (match_operand:SI 3 "immediate_operand" ""))
1581390286Sobrien     (use (reg:SI 19))
1581490286Sobrien     (clobber (match_operand 0 "register_operand" ""))
1581590286Sobrien     (clobber (match_operand 1 "register_operand" ""))
1581690286Sobrien     (clobber (match_operand 2 "register_operand" ""))])
1581790286Sobrien   (set (match_operand:QI 7 "register_operand" "")
1581890286Sobrien	(gtu:QI (reg:CC 17) (const_int 0)))
1581990286Sobrien   (set (match_operand:QI 8 "register_operand" "")
1582090286Sobrien	(ltu:QI (reg:CC 17) (const_int 0)))
1582190286Sobrien   (set (reg 17)
1582290286Sobrien	(compare (match_dup 7) (match_dup 8)))
1582390286Sobrien  ]
1582490286Sobrien  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
1582590286Sobrien  [(parallel[
1582690286Sobrien     (set (reg:CC 17)
1582790286Sobrien	  (compare:CC (mem:BLK (match_dup 4))
1582890286Sobrien		      (mem:BLK (match_dup 5))))
1582990286Sobrien     (use (match_dup 6))
1583090286Sobrien     (use (match_dup 3))
1583190286Sobrien     (use (reg:SI 19))
1583290286Sobrien     (clobber (match_dup 0))
1583390286Sobrien     (clobber (match_dup 1))
1583490286Sobrien     (clobber (match_dup 2))])]
1583550650Sobrien  "")
1583650650Sobrien
1583790286Sobrien;; ...and this one handles cmpstr*_1.
1583890286Sobrien(define_peephole2
1583990286Sobrien  [(parallel[
1584090286Sobrien     (set (reg:CC 17)
1584190286Sobrien	  (if_then_else:CC (ne (match_operand 6 "register_operand" "")
1584290286Sobrien			       (const_int 0))
1584390286Sobrien	    (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
1584490286Sobrien		        (mem:BLK (match_operand 5 "register_operand" "")))
1584590286Sobrien	    (const_int 0)))
1584690286Sobrien     (use (match_operand:SI 3 "immediate_operand" ""))
1584790286Sobrien     (use (reg:CC 17))
1584890286Sobrien     (use (reg:SI 19))
1584990286Sobrien     (clobber (match_operand 0 "register_operand" ""))
1585090286Sobrien     (clobber (match_operand 1 "register_operand" ""))
1585190286Sobrien     (clobber (match_operand 2 "register_operand" ""))])
1585290286Sobrien   (set (match_operand:QI 7 "register_operand" "")
1585390286Sobrien	(gtu:QI (reg:CC 17) (const_int 0)))
1585490286Sobrien   (set (match_operand:QI 8 "register_operand" "")
1585590286Sobrien	(ltu:QI (reg:CC 17) (const_int 0)))
1585690286Sobrien   (set (reg 17)
1585790286Sobrien	(compare (match_dup 7) (match_dup 8)))
1585890286Sobrien  ]
1585990286Sobrien  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
1586090286Sobrien  [(parallel[
1586190286Sobrien     (set (reg:CC 17)
1586290286Sobrien	  (if_then_else:CC (ne (match_dup 6)
1586390286Sobrien			       (const_int 0))
1586490286Sobrien	    (compare:CC (mem:BLK (match_dup 4))
1586590286Sobrien			(mem:BLK (match_dup 5)))
1586690286Sobrien	    (const_int 0)))
1586790286Sobrien     (use (match_dup 3))
1586890286Sobrien     (use (reg:CC 17))
1586990286Sobrien     (use (reg:SI 19))
1587090286Sobrien     (clobber (match_dup 0))
1587190286Sobrien     (clobber (match_dup 1))
1587290286Sobrien     (clobber (match_dup 2))])]
1587350650Sobrien  "")
1587450650Sobrien
1587590286Sobrien
1587690286Sobrien
1587790286Sobrien;; Conditional move instructions.
1587890286Sobrien
1587990286Sobrien(define_expand "movdicc"
1588090286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1588190286Sobrien	(if_then_else:DI (match_operand 1 "comparison_operator" "")
1588290286Sobrien			 (match_operand:DI 2 "general_operand" "")
1588390286Sobrien			 (match_operand:DI 3 "general_operand" "")))]
1588490286Sobrien  "TARGET_64BIT"
1588590286Sobrien  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
1588690286Sobrien
1588790286Sobrien(define_insn "x86_movdicc_0_m1_rex64"
1588890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r")
1588990286Sobrien	(if_then_else:DI (ltu (reg:CC 17) (const_int 0))
1589090286Sobrien	  (const_int -1)
1589190286Sobrien	  (const_int 0)))
1589290286Sobrien   (clobber (reg:CC 17))]
1589390286Sobrien  "TARGET_64BIT"
1589490286Sobrien  "sbb{q}\t%0, %0"
1589590286Sobrien  ; Since we don't have the proper number of operands for an alu insn,
1589690286Sobrien  ; fill in all the blanks.
1589790286Sobrien  [(set_attr "type" "alu")
1589890286Sobrien   (set_attr "memory" "none")
1589990286Sobrien   (set_attr "imm_disp" "false")
1590090286Sobrien   (set_attr "mode" "DI")
1590190286Sobrien   (set_attr "length_immediate" "0")])
1590290286Sobrien
1590390286Sobrien(define_insn "*movdicc_c_rex64"
1590490286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1590590286Sobrien	(if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
1590690286Sobrien				[(reg 17) (const_int 0)])
1590790286Sobrien		      (match_operand:DI 2 "nonimmediate_operand" "rm,0")
1590890286Sobrien		      (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
1590990286Sobrien  "TARGET_64BIT && TARGET_CMOVE
1591090286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1591190286Sobrien  "@
1591296294Sobrien   cmov%O2%C1\t{%2, %0|%0, %2}
1591396294Sobrien   cmov%O2%c1\t{%3, %0|%0, %3}"
1591490286Sobrien  [(set_attr "type" "icmov")
1591590286Sobrien   (set_attr "mode" "DI")])
1591690286Sobrien
1591790286Sobrien(define_expand "movsicc"
1591890286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1591990286Sobrien	(if_then_else:SI (match_operand 1 "comparison_operator" "")
1592090286Sobrien			 (match_operand:SI 2 "general_operand" "")
1592190286Sobrien			 (match_operand:SI 3 "general_operand" "")))]
1592290286Sobrien  ""
1592390286Sobrien  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
1592490286Sobrien
1592590286Sobrien;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
1592690286Sobrien;; the register first winds up with `sbbl $0,reg', which is also weird.
1592790286Sobrien;; So just document what we're doing explicitly.
1592890286Sobrien
1592990286Sobrien(define_insn "x86_movsicc_0_m1"
1593090286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1593190286Sobrien	(if_then_else:SI (ltu (reg:CC 17) (const_int 0))
1593290286Sobrien	  (const_int -1)
1593390286Sobrien	  (const_int 0)))
1593490286Sobrien   (clobber (reg:CC 17))]
1593590286Sobrien  ""
1593690286Sobrien  "sbb{l}\t%0, %0"
1593790286Sobrien  ; Since we don't have the proper number of operands for an alu insn,
1593890286Sobrien  ; fill in all the blanks.
1593990286Sobrien  [(set_attr "type" "alu")
1594090286Sobrien   (set_attr "memory" "none")
1594190286Sobrien   (set_attr "imm_disp" "false")
1594290286Sobrien   (set_attr "mode" "SI")
1594390286Sobrien   (set_attr "length_immediate" "0")])
1594490286Sobrien
1594590286Sobrien(define_insn "*movsicc_noc"
1594650650Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,r")
1594790286Sobrien	(if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
1594890286Sobrien				[(reg 17) (const_int 0)])
1594950650Sobrien		      (match_operand:SI 2 "nonimmediate_operand" "rm,0")
1595050650Sobrien		      (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
1595190286Sobrien  "TARGET_CMOVE
1595290286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1595390286Sobrien  "@
1595496294Sobrien   cmov%O2%C1\t{%2, %0|%0, %2}
1595596294Sobrien   cmov%O2%c1\t{%3, %0|%0, %3}"
1595690286Sobrien  [(set_attr "type" "icmov")
1595790286Sobrien   (set_attr "mode" "SI")])
1595850650Sobrien
1595950650Sobrien(define_expand "movhicc"
1596050650Sobrien  [(set (match_operand:HI 0 "register_operand" "")
1596150650Sobrien	(if_then_else:HI (match_operand 1 "comparison_operator" "")
1596250650Sobrien			 (match_operand:HI 2 "nonimmediate_operand" "")
1596350650Sobrien			 (match_operand:HI 3 "nonimmediate_operand" "")))]
1596490286Sobrien  "TARGET_CMOVE && TARGET_HIMODE_MATH"
1596590286Sobrien  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
1596650650Sobrien
1596790286Sobrien(define_insn "*movhicc_noc"
1596850650Sobrien  [(set (match_operand:HI 0 "register_operand" "=r,r")
1596990286Sobrien	(if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
1597090286Sobrien				[(reg 17) (const_int 0)])
1597150650Sobrien		      (match_operand:HI 2 "nonimmediate_operand" "rm,0")
1597250650Sobrien		      (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
1597390286Sobrien  "TARGET_CMOVE
1597490286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1597590286Sobrien  "@
1597696294Sobrien   cmov%O2%C1\t{%2, %0|%0, %2}
1597796294Sobrien   cmov%O2%c1\t{%3, %0|%0, %3}"
1597890286Sobrien  [(set_attr "type" "icmov")
1597990286Sobrien   (set_attr "mode" "HI")])
1598050650Sobrien
1598150650Sobrien(define_expand "movsfcc"
1598250650Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1598350650Sobrien	(if_then_else:SF (match_operand 1 "comparison_operator" "")
1598450650Sobrien			 (match_operand:SF 2 "register_operand" "")
1598550650Sobrien			 (match_operand:SF 3 "register_operand" "")))]
1598650650Sobrien  "TARGET_CMOVE"
1598790286Sobrien  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
1598850650Sobrien
1598990286Sobrien(define_insn "*movsfcc_1"
1599090286Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
1599190286Sobrien	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
1599290286Sobrien				[(reg 17) (const_int 0)])
1599390286Sobrien		      (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
1599490286Sobrien		      (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
1599590286Sobrien  "TARGET_CMOVE
1599690286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1599790286Sobrien  "@
1599890286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1599990286Sobrien   fcmov%f1\t{%3, %0|%0, %3}
1600096294Sobrien   cmov%O2%C1\t{%2, %0|%0, %2}
1600196294Sobrien   cmov%O2%c1\t{%3, %0|%0, %3}"
1600290286Sobrien  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
1600390286Sobrien   (set_attr "mode" "SF,SF,SI,SI")])
1600450650Sobrien
1600590286Sobrien(define_expand "movdfcc"
1600690286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1600790286Sobrien	(if_then_else:DF (match_operand 1 "comparison_operator" "")
1600890286Sobrien			 (match_operand:DF 2 "register_operand" "")
1600990286Sobrien			 (match_operand:DF 3 "register_operand" "")))]
1601090286Sobrien  "TARGET_CMOVE"
1601190286Sobrien  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
1601250650Sobrien
1601390286Sobrien(define_insn "*movdfcc_1"
1601490286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
1601590286Sobrien	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
1601690286Sobrien				[(reg 17) (const_int 0)])
1601790286Sobrien		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
1601890286Sobrien		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
1601990286Sobrien  "!TARGET_64BIT && TARGET_CMOVE
1602090286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1602190286Sobrien  "@
1602290286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1602390286Sobrien   fcmov%f1\t{%3, %0|%0, %3}
1602490286Sobrien   #
1602590286Sobrien   #"
1602690286Sobrien  [(set_attr "type" "fcmov,fcmov,multi,multi")
1602790286Sobrien   (set_attr "mode" "DF")])
1602850650Sobrien
1602990286Sobrien(define_insn "*movdfcc_1_rex64"
1603090286Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
1603190286Sobrien	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
1603290286Sobrien				[(reg 17) (const_int 0)])
1603390286Sobrien		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
1603490286Sobrien		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
1603590286Sobrien  "TARGET_64BIT && TARGET_CMOVE
1603690286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1603790286Sobrien  "@
1603890286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1603990286Sobrien   fcmov%f1\t{%3, %0|%0, %3}
1604096294Sobrien   cmov%O2%C1\t{%2, %0|%0, %2}
1604196294Sobrien   cmov%O2%c1\t{%3, %0|%0, %3}"
1604290286Sobrien  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
1604390286Sobrien   (set_attr "mode" "DF")])
1604450650Sobrien
1604590286Sobrien(define_split
1604690286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1604790286Sobrien	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
1604890286Sobrien				[(match_operand 4 "" "") (const_int 0)])
1604990286Sobrien		      (match_operand:DF 2 "nonimmediate_operand" "")
1605090286Sobrien		      (match_operand:DF 3 "nonimmediate_operand" "")))]
1605190286Sobrien  "!TARGET_64BIT && !ANY_FP_REG_P (operands[0]) && reload_completed"
1605290286Sobrien  [(set (match_dup 2)
1605390286Sobrien	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
1605490286Sobrien		      (match_dup 5)
1605590286Sobrien		      (match_dup 7)))
1605690286Sobrien   (set (match_dup 3)
1605790286Sobrien	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
1605890286Sobrien		      (match_dup 6)
1605990286Sobrien		      (match_dup 8)))]
1606090286Sobrien  "split_di (operands+2, 1, operands+5, operands+6);
1606190286Sobrien   split_di (operands+3, 1, operands+7, operands+8);
1606290286Sobrien   split_di (operands, 1, operands+2, operands+3);")
1606350650Sobrien
1606490286Sobrien(define_expand "movxfcc"
1606590286Sobrien  [(set (match_operand:XF 0 "register_operand" "")
1606690286Sobrien	(if_then_else:XF (match_operand 1 "comparison_operator" "")
1606790286Sobrien			 (match_operand:XF 2 "register_operand" "")
1606890286Sobrien			 (match_operand:XF 3 "register_operand" "")))]
1606990286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1607090286Sobrien  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
1607150650Sobrien
1607290286Sobrien(define_expand "movtfcc"
1607390286Sobrien  [(set (match_operand:TF 0 "register_operand" "")
1607490286Sobrien	(if_then_else:TF (match_operand 1 "comparison_operator" "")
1607590286Sobrien			 (match_operand:TF 2 "register_operand" "")
1607690286Sobrien			 (match_operand:TF 3 "register_operand" "")))]
1607790286Sobrien  "TARGET_CMOVE"
1607890286Sobrien  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
1607990286Sobrien
1608090286Sobrien(define_insn "*movxfcc_1"
1608190286Sobrien  [(set (match_operand:XF 0 "register_operand" "=f,f")
1608290286Sobrien	(if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
1608390286Sobrien				[(reg 17) (const_int 0)])
1608490286Sobrien		      (match_operand:XF 2 "register_operand" "f,0")
1608590286Sobrien		      (match_operand:XF 3 "register_operand" "0,f")))]
1608690286Sobrien  "!TARGET_64BIT && TARGET_CMOVE"
1608790286Sobrien  "@
1608890286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1608990286Sobrien   fcmov%f1\t{%3, %0|%0, %3}"
1609090286Sobrien  [(set_attr "type" "fcmov")
1609190286Sobrien   (set_attr "mode" "XF")])
1609290286Sobrien
1609390286Sobrien(define_insn "*movtfcc_1"
1609490286Sobrien  [(set (match_operand:TF 0 "register_operand" "=f,f")
1609590286Sobrien	(if_then_else:TF (match_operator 1 "fcmov_comparison_operator" 
1609690286Sobrien				[(reg 17) (const_int 0)])
1609790286Sobrien		      (match_operand:TF 2 "register_operand" "f,0")
1609890286Sobrien		      (match_operand:TF 3 "register_operand" "0,f")))]
1609990286Sobrien  "TARGET_CMOVE"
1610090286Sobrien  "@
1610190286Sobrien   fcmov%F1\t{%2, %0|%0, %2}
1610290286Sobrien   fcmov%f1\t{%3, %0|%0, %3}"
1610390286Sobrien  [(set_attr "type" "fcmov")
1610490286Sobrien   (set_attr "mode" "XF")])
1610590286Sobrien
1610690286Sobrien(define_expand "minsf3"
1610790286Sobrien  [(parallel [
1610890286Sobrien     (set (match_operand:SF 0 "register_operand" "")
1610990286Sobrien	  (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
1611090286Sobrien			       (match_operand:SF 2 "nonimmediate_operand" ""))
1611190286Sobrien			   (match_dup 1)
1611290286Sobrien			   (match_dup 2)))
1611390286Sobrien     (clobber (reg:CC 17))])]
1611490286Sobrien  "TARGET_SSE"
1611590286Sobrien  "")
1611690286Sobrien
1611790286Sobrien(define_insn "*minsf"
1611890286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
1611990286Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
1612090286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
1612190286Sobrien			 (match_dup 1)
1612290286Sobrien			 (match_dup 2)))
1612390286Sobrien   (clobber (reg:CC 17))]
1612490286Sobrien  "TARGET_SSE && TARGET_IEEE_FP"
1612550650Sobrien  "#")
1612650650Sobrien
1612790286Sobrien(define_insn "*minsf_nonieee"
1612890286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
1612996294Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
1613090286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
1613190286Sobrien			 (match_dup 1)
1613290286Sobrien			 (match_dup 2)))
1613390286Sobrien   (clobber (reg:CC 17))]
1613496294Sobrien  "TARGET_SSE && !TARGET_IEEE_FP
1613596294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1613650650Sobrien  "#")
1613750650Sobrien
1613850650Sobrien(define_split
1613952296Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1614090286Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
1614190286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" ""))
1614290286Sobrien			 (match_operand:SF 3 "register_operand" "")
1614390286Sobrien			 (match_operand:SF 4 "nonimmediate_operand" "")))
1614490286Sobrien   (clobber (reg:CC 17))]
1614590286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1614690286Sobrien   && ((operands_match_p (operands[1], operands[3])
1614790286Sobrien	&& operands_match_p (operands[2], operands[4]))
1614890286Sobrien       || (operands_match_p (operands[1], operands[4])
1614990286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1615090286Sobrien  [(set (match_dup 0)
1615190286Sobrien	(if_then_else:SF (lt (match_dup 1)
1615290286Sobrien			     (match_dup 2))
1615390286Sobrien			 (match_dup 1)
1615490286Sobrien			 (match_dup 2)))])
1615550650Sobrien
1615690286Sobrien;; We can't represent the LT test directly.  Do this by swapping the operands.
1615790286Sobrien
1615850650Sobrien(define_split
1615952296Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1616090286Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
1616190286Sobrien			     (match_operand:SF 2 "register_operand" ""))
1616290286Sobrien			 (match_operand:SF 3 "register_operand" "")
1616390286Sobrien			 (match_operand:SF 4 "register_operand" "")))
1616490286Sobrien   (clobber (reg:CC 17))]
1616590286Sobrien  "FP_REG_P (operands[0]) && reload_completed
1616690286Sobrien   && ((operands_match_p (operands[1], operands[3])
1616790286Sobrien	&& operands_match_p (operands[2], operands[4]))
1616890286Sobrien       || (operands_match_p (operands[1], operands[4])
1616990286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1617090286Sobrien  [(set (reg:CCFP 17)
1617190286Sobrien	(compare:CCFP (match_dup 2)
1617290286Sobrien		      (match_dup 1)))
1617350650Sobrien   (set (match_dup 0)
1617490286Sobrien	(if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
1617590286Sobrien			 (match_dup 1)
1617690286Sobrien			 (match_dup 2)))])
1617750650Sobrien
1617890286Sobrien(define_insn "*minsf_sse"
1617990286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1618090286Sobrien	(if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
1618190286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm"))
1618290286Sobrien			 (match_dup 1)
1618390286Sobrien			 (match_dup 2)))]
1618490286Sobrien  "TARGET_SSE && reload_completed"
1618590286Sobrien  "minss\t{%2, %0|%0, %2}"
1618690286Sobrien  [(set_attr "type" "sse")
1618790286Sobrien   (set_attr "mode" "SF")])
1618850650Sobrien
1618990286Sobrien(define_expand "mindf3"
1619090286Sobrien  [(parallel [
1619190286Sobrien     (set (match_operand:DF 0 "register_operand" "")
1619290286Sobrien	  (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
1619390286Sobrien			       (match_operand:DF 2 "nonimmediate_operand" ""))
1619490286Sobrien			   (match_dup 1)
1619590286Sobrien			   (match_dup 2)))
1619690286Sobrien     (clobber (reg:CC 17))])]
1619790286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH"
1619890286Sobrien  "#")
1619990286Sobrien
1620090286Sobrien(define_insn "*mindf"
1620190286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
1620290286Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
1620390286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
1620490286Sobrien			 (match_dup 1)
1620590286Sobrien			 (match_dup 2)))
1620690286Sobrien   (clobber (reg:CC 17))]
1620790286Sobrien  "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
1620890286Sobrien  "#")
1620990286Sobrien
1621090286Sobrien(define_insn "*mindf_nonieee"
1621190286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
1621296294Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
1621390286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
1621490286Sobrien			 (match_dup 1)
1621590286Sobrien			 (match_dup 2)))
1621690286Sobrien   (clobber (reg:CC 17))]
1621796294Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
1621896294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1621990286Sobrien  "#")
1622090286Sobrien
1622190286Sobrien(define_split
1622250650Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1622390286Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
1622490286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" ""))
1622590286Sobrien			 (match_operand:DF 3 "register_operand" "")
1622690286Sobrien			 (match_operand:DF 4 "nonimmediate_operand" "")))
1622790286Sobrien   (clobber (reg:CC 17))]
1622890286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1622990286Sobrien   && ((operands_match_p (operands[1], operands[3])
1623090286Sobrien	&& operands_match_p (operands[2], operands[4]))
1623190286Sobrien       || (operands_match_p (operands[1], operands[4])
1623290286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1623390286Sobrien  [(set (match_dup 0)
1623490286Sobrien	(if_then_else:DF (lt (match_dup 1)
1623590286Sobrien			     (match_dup 2))
1623690286Sobrien			 (match_dup 1)
1623790286Sobrien			 (match_dup 2)))])
1623850650Sobrien
1623990286Sobrien;; We can't represent the LT test directly.  Do this by swapping the operands.
1624090286Sobrien(define_split
1624190286Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1624290286Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
1624390286Sobrien			     (match_operand:DF 2 "register_operand" ""))
1624490286Sobrien			 (match_operand:DF 3 "register_operand" "")
1624590286Sobrien			 (match_operand:DF 4 "register_operand" "")))
1624690286Sobrien   (clobber (reg:CC 17))]
1624790286Sobrien  "FP_REG_P (operands[0]) && reload_completed
1624890286Sobrien   && ((operands_match_p (operands[1], operands[3])
1624990286Sobrien	&& operands_match_p (operands[2], operands[4]))
1625090286Sobrien       || (operands_match_p (operands[1], operands[4])
1625190286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1625290286Sobrien  [(set (reg:CCFP 17)
1625390286Sobrien	(compare:CCFP (match_dup 2)
1625490286Sobrien		      (match_dup 2)))
1625590286Sobrien   (set (match_dup 0)
1625690286Sobrien	(if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
1625790286Sobrien			 (match_dup 1)
1625890286Sobrien			 (match_dup 2)))])
1625950650Sobrien
1626090286Sobrien(define_insn "*mindf_sse"
1626190286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1626290286Sobrien	(if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
1626390286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym"))
1626490286Sobrien			 (match_dup 1)
1626590286Sobrien			 (match_dup 2)))]
1626690286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
1626790286Sobrien  "minsd\t{%2, %0|%0, %2}"
1626890286Sobrien  [(set_attr "type" "sse")
1626990286Sobrien   (set_attr "mode" "DF")])
1627050650Sobrien
1627190286Sobrien(define_expand "maxsf3"
1627290286Sobrien  [(parallel [
1627390286Sobrien     (set (match_operand:SF 0 "register_operand" "")
1627490286Sobrien	  (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
1627590286Sobrien			       (match_operand:SF 2 "nonimmediate_operand" ""))
1627690286Sobrien			   (match_dup 1)
1627790286Sobrien			   (match_dup 2)))
1627890286Sobrien     (clobber (reg:CC 17))])]
1627990286Sobrien  "TARGET_SSE"
1628090286Sobrien  "#")
1628150650Sobrien
1628290286Sobrien(define_insn "*maxsf"
1628390286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
1628490286Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
1628590286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
1628690286Sobrien			 (match_dup 1)
1628790286Sobrien			 (match_dup 2)))
1628890286Sobrien   (clobber (reg:CC 17))]
1628990286Sobrien  "TARGET_SSE && TARGET_IEEE_FP"
1629090286Sobrien  "#")
1629150650Sobrien
1629290286Sobrien(define_insn "*maxsf_nonieee"
1629390286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
1629496294Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
1629590286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
1629690286Sobrien			 (match_dup 1)
1629790286Sobrien			 (match_dup 2)))
1629890286Sobrien   (clobber (reg:CC 17))]
1629996294Sobrien  "TARGET_SSE && !TARGET_IEEE_FP
1630096294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1630190286Sobrien  "#")
1630250650Sobrien
1630390286Sobrien(define_split
1630490286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1630590286Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
1630690286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" ""))
1630790286Sobrien			 (match_operand:SF 3 "register_operand" "")
1630890286Sobrien			 (match_operand:SF 4 "nonimmediate_operand" "")))
1630990286Sobrien   (clobber (reg:CC 17))]
1631090286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1631190286Sobrien   && ((operands_match_p (operands[1], operands[3])
1631290286Sobrien	&& operands_match_p (operands[2], operands[4]))
1631390286Sobrien       || (operands_match_p (operands[1], operands[4])
1631490286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1631590286Sobrien  [(set (match_dup 0)
1631690286Sobrien	(if_then_else:SF (gt (match_dup 1)
1631790286Sobrien			     (match_dup 2))
1631890286Sobrien			 (match_dup 1)
1631990286Sobrien			 (match_dup 2)))])
1632050650Sobrien
1632190286Sobrien(define_split
1632290286Sobrien  [(set (match_operand:SF 0 "register_operand" "")
1632390286Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
1632490286Sobrien			     (match_operand:SF 2 "register_operand" ""))
1632590286Sobrien			 (match_operand:SF 3 "register_operand" "")
1632690286Sobrien			 (match_operand:SF 4 "register_operand" "")))
1632790286Sobrien   (clobber (reg:CC 17))]
1632890286Sobrien  "FP_REG_P (operands[0]) && reload_completed
1632990286Sobrien   && ((operands_match_p (operands[1], operands[3])
1633090286Sobrien	&& operands_match_p (operands[2], operands[4]))
1633190286Sobrien       || (operands_match_p (operands[1], operands[4])
1633290286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1633390286Sobrien  [(set (reg:CCFP 17)
1633490286Sobrien	(compare:CCFP (match_dup 1)
1633590286Sobrien		      (match_dup 2)))
1633690286Sobrien   (set (match_dup 0)
1633790286Sobrien	(if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
1633890286Sobrien			 (match_dup 1)
1633990286Sobrien			 (match_dup 2)))])
1634090286Sobrien
1634190286Sobrien(define_insn "*maxsf_sse"
1634290286Sobrien  [(set (match_operand:SF 0 "register_operand" "=x")
1634390286Sobrien	(if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
1634490286Sobrien			     (match_operand:SF 2 "nonimmediate_operand" "xm"))
1634590286Sobrien			 (match_dup 1)
1634690286Sobrien			 (match_dup 2)))]
1634790286Sobrien  "TARGET_SSE && reload_completed"
1634890286Sobrien  "maxss\t{%2, %0|%0, %2}"
1634990286Sobrien  [(set_attr "type" "sse")
1635090286Sobrien   (set_attr "mode" "SF")])
1635190286Sobrien
1635290286Sobrien(define_expand "maxdf3"
1635390286Sobrien  [(parallel [
1635490286Sobrien     (set (match_operand:DF 0 "register_operand" "")
1635590286Sobrien	  (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
1635690286Sobrien			       (match_operand:DF 2 "nonimmediate_operand" ""))
1635790286Sobrien			   (match_dup 1)
1635890286Sobrien			   (match_dup 2)))
1635990286Sobrien     (clobber (reg:CC 17))])]
1636090286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH"
1636150650Sobrien  "#")
1636250650Sobrien
1636390286Sobrien(define_insn "*maxdf"
1636490286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
1636590286Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
1636690286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
1636790286Sobrien			 (match_dup 1)
1636890286Sobrien			 (match_dup 2)))
1636990286Sobrien   (clobber (reg:CC 17))]
1637090286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
1637150650Sobrien  "#")
1637250650Sobrien
1637390286Sobrien(define_insn "*maxdf_nonieee"
1637490286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
1637596294Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
1637690286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
1637790286Sobrien			 (match_dup 1)
1637890286Sobrien			 (match_dup 2)))
1637990286Sobrien   (clobber (reg:CC 17))]
1638096294Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
1638196294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1638290286Sobrien  "#")
1638390286Sobrien
1638450650Sobrien(define_split
1638552296Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1638690286Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
1638790286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" ""))
1638890286Sobrien			 (match_operand:DF 3 "register_operand" "")
1638990286Sobrien			 (match_operand:DF 4 "nonimmediate_operand" "")))
1639090286Sobrien   (clobber (reg:CC 17))]
1639190286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1639290286Sobrien   && ((operands_match_p (operands[1], operands[3])
1639390286Sobrien	&& operands_match_p (operands[2], operands[4]))
1639490286Sobrien       || (operands_match_p (operands[1], operands[4])
1639590286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1639690286Sobrien  [(set (match_dup 0)
1639790286Sobrien	(if_then_else:DF (gt (match_dup 1)
1639890286Sobrien			     (match_dup 2))
1639990286Sobrien			 (match_dup 1)
1640090286Sobrien			 (match_dup 2)))])
1640150650Sobrien
1640250650Sobrien(define_split
1640352296Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1640490286Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
1640590286Sobrien			     (match_operand:DF 2 "register_operand" ""))
1640690286Sobrien			 (match_operand:DF 3 "register_operand" "")
1640790286Sobrien			 (match_operand:DF 4 "register_operand" "")))
1640890286Sobrien   (clobber (reg:CC 17))]
1640990286Sobrien  "FP_REG_P (operands[0]) && reload_completed
1641090286Sobrien   && ((operands_match_p (operands[1], operands[3])
1641190286Sobrien	&& operands_match_p (operands[2], operands[4]))
1641290286Sobrien       || (operands_match_p (operands[1], operands[4])
1641390286Sobrien	   && operands_match_p (operands[2], operands[3])))"
1641490286Sobrien  [(set (reg:CCFP 17)
1641590286Sobrien	(compare:CCFP (match_dup 1)
1641690286Sobrien		      (match_dup 2)))
1641750650Sobrien   (set (match_dup 0)
1641890286Sobrien	(if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
1641990286Sobrien			 (match_dup 1)
1642090286Sobrien			 (match_dup 2)))])
1642150650Sobrien
1642290286Sobrien(define_insn "*maxdf_sse"
1642390286Sobrien  [(set (match_operand:DF 0 "register_operand" "=Y")
1642490286Sobrien	(if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
1642590286Sobrien			     (match_operand:DF 2 "nonimmediate_operand" "Ym"))
1642690286Sobrien			 (match_dup 1)
1642790286Sobrien			 (match_dup 2)))]
1642890286Sobrien  "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
1642990286Sobrien  "maxsd\t{%2, %0|%0, %2}"
1643090286Sobrien  [(set_attr "type" "sse")
1643190286Sobrien   (set_attr "mode" "DF")])
1643290286Sobrien
1643390286Sobrien;; Misc patterns (?)
1643450650Sobrien
1643590286Sobrien;; This pattern exists to put a dependency on all ebp-based memory accesses.
1643690286Sobrien;; Otherwise there will be nothing to keep
1643790286Sobrien;; 
1643890286Sobrien;; [(set (reg ebp) (reg esp))]
1643990286Sobrien;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
1644090286Sobrien;;  (clobber (eflags)]
1644190286Sobrien;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
1644290286Sobrien;;
1644390286Sobrien;; in proper program order.
1644490286Sobrien(define_expand "pro_epilogue_adjust_stack"
1644590286Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
1644690286Sobrien		   (plus:SI (match_operand:SI 1 "register_operand" "0,r")
1644790286Sobrien			    (match_operand:SI 2 "immediate_operand" "i,i")))
1644890286Sobrien	      (clobber (reg:CC 17))
1644990286Sobrien	      (clobber (mem:BLK (scratch)))])]
1645090286Sobrien ""
1645150650Sobrien{
1645290286Sobrien  if (TARGET_64BIT)
1645390286Sobrien    {
1645490286Sobrien      emit_insn (gen_pro_epilogue_adjust_stack_rex64
1645590286Sobrien		 (operands[0], operands[1], operands[2]));
1645690286Sobrien      DONE;
1645790286Sobrien    }
1645890286Sobrien})
1645950650Sobrien
1646090286Sobrien(define_insn "*pro_epilogue_adjust_stack_1"
1646190286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r,r")
1646290286Sobrien	(plus:SI (match_operand:SI 1 "register_operand" "0,r")
1646390286Sobrien	         (match_operand:SI 2 "immediate_operand" "i,i")))
1646490286Sobrien   (clobber (reg:CC 17))
1646590286Sobrien   (clobber (mem:BLK (scratch)))]
1646690286Sobrien  "!TARGET_64BIT"
1646790286Sobrien{
1646890286Sobrien  switch (get_attr_type (insn))
1646990286Sobrien    {
1647090286Sobrien    case TYPE_IMOV:
1647190286Sobrien      return "mov{l}\t{%1, %0|%0, %1}";
1647250650Sobrien
1647390286Sobrien    case TYPE_ALU:
1647490286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
1647590286Sobrien          && (INTVAL (operands[2]) == 128
1647690286Sobrien	      || (INTVAL (operands[2]) < 0
1647790286Sobrien	          && INTVAL (operands[2]) != -128)))
1647890286Sobrien	{
1647990286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
1648090286Sobrien	  return "sub{l}\t{%2, %0|%0, %2}";
1648190286Sobrien	}
1648290286Sobrien      return "add{l}\t{%2, %0|%0, %2}";
1648350650Sobrien
1648490286Sobrien    case TYPE_LEA:
1648590286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
1648690286Sobrien      return "lea{l}\t{%a2, %0|%0, %a2}";
1648790286Sobrien
1648890286Sobrien    default:
1648990286Sobrien      abort ();
1649090286Sobrien    }
1649190286Sobrien}
1649290286Sobrien  [(set (attr "type")
1649390286Sobrien	(cond [(eq_attr "alternative" "0")
1649490286Sobrien		 (const_string "alu")
1649590286Sobrien	       (match_operand:SI 2 "const0_operand" "")
1649690286Sobrien		 (const_string "imov")
1649790286Sobrien	      ]
1649890286Sobrien	      (const_string "lea")))
1649990286Sobrien   (set_attr "mode" "SI")])
1650090286Sobrien
1650190286Sobrien(define_insn "pro_epilogue_adjust_stack_rex64"
1650290286Sobrien  [(set (match_operand:DI 0 "register_operand" "=r,r")
1650390286Sobrien	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
1650490286Sobrien		 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
1650590286Sobrien   (clobber (reg:CC 17))
1650690286Sobrien   (clobber (mem:BLK (scratch)))]
1650790286Sobrien  "TARGET_64BIT"
1650890286Sobrien{
1650990286Sobrien  switch (get_attr_type (insn))
1651050650Sobrien    {
1651190286Sobrien    case TYPE_IMOV:
1651290286Sobrien      return "mov{q}\t{%1, %0|%0, %1}";
1651350650Sobrien
1651490286Sobrien    case TYPE_ALU:
1651590286Sobrien      if (GET_CODE (operands[2]) == CONST_INT
1651690286Sobrien          && (INTVAL (operands[2]) == 128
1651790286Sobrien	      || (INTVAL (operands[2]) < 0
1651890286Sobrien	          && INTVAL (operands[2]) != -128)))
1651990286Sobrien	{
1652090286Sobrien	  operands[2] = GEN_INT (-INTVAL (operands[2]));
1652190286Sobrien	  return "sub{q}\t{%2, %0|%0, %2}";
1652290286Sobrien	}
1652390286Sobrien      return "add{q}\t{%2, %0|%0, %2}";
1652450650Sobrien
1652590286Sobrien    case TYPE_LEA:
1652690286Sobrien      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
1652790286Sobrien      return "lea{q}\t{%a2, %0|%0, %a2}";
1652850650Sobrien
1652950650Sobrien    default:
1653090286Sobrien      abort ();
1653150650Sobrien    }
1653290286Sobrien}
1653390286Sobrien  [(set (attr "type")
1653490286Sobrien	(cond [(eq_attr "alternative" "0")
1653590286Sobrien		 (const_string "alu")
1653690286Sobrien	       (match_operand:DI 2 "const0_operand" "")
1653790286Sobrien		 (const_string "imov")
1653890286Sobrien	      ]
1653990286Sobrien	      (const_string "lea")))
1654090286Sobrien   (set_attr "mode" "DI")])
1654150650Sobrien
1654290286Sobrien
1654390286Sobrien;; Placeholder for the conditional moves.  This one is split either to SSE
1654490286Sobrien;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
1654590286Sobrien;; fact is that compares supported by the cmp??ss instructions are exactly
1654690286Sobrien;; swapped of those supported by cmove sequence.
1654790286Sobrien;; The EQ/NE comparisons also needs bit care, since they are not directly
1654890286Sobrien;; supported by i387 comparisons and we do need to emit two conditional moves
1654990286Sobrien;; in tandem.
1655090286Sobrien
1655190286Sobrien(define_insn "sse_movsfcc"
1655290286Sobrien  [(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")
1655390286Sobrien	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
1655490286Sobrien			[(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")
1655590286Sobrien			 (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")])
1655690286Sobrien		      (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")
1655790286Sobrien		      (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")))
1655890286Sobrien   (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
1655990286Sobrien   (clobber (reg:CC 17))]
1656090286Sobrien  "TARGET_SSE
1656190286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
1656290286Sobrien   && (!TARGET_IEEE_FP
1656390286Sobrien       || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
1656450650Sobrien  "#")
1656550650Sobrien
1656690286Sobrien(define_insn "sse_movsfcc_eq"
1656790286Sobrien  [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
1656890286Sobrien	(if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
1656990286Sobrien			     (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
1657090286Sobrien		      (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
1657190286Sobrien		      (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
1657290286Sobrien   (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
1657390286Sobrien   (clobber (reg:CC 17))]
1657490286Sobrien  "TARGET_SSE
1657590286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1657650650Sobrien  "#")
1657750650Sobrien
1657890286Sobrien(define_insn "sse_movdfcc"
16579102802Skan  [(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")
1658090286Sobrien	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
16581102802Skan			[(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")
16582102802Skan			 (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")])
16583102802Skan		      (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")
16584102802Skan		      (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")))
1658590286Sobrien   (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
1658690286Sobrien   (clobber (reg:CC 17))]
1658790286Sobrien  "TARGET_SSE2
1658890286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
1658990286Sobrien   && (!TARGET_IEEE_FP
1659090286Sobrien       || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
1659190286Sobrien  "#")
1659290286Sobrien
1659390286Sobrien(define_insn "sse_movdfcc_eq"
16594102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
16595102802Skan	(if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
16596102802Skan			     (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
16597102802Skan		      (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
16598102802Skan		      (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
1659990286Sobrien   (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
1660090286Sobrien   (clobber (reg:CC 17))]
1660190286Sobrien  "TARGET_SSE
1660290286Sobrien   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
1660390286Sobrien  "#")
1660490286Sobrien
1660590286Sobrien;; For non-sse moves just expand the usual cmove sequence.
1660650650Sobrien(define_split
1660790286Sobrien  [(set (match_operand 0 "register_operand" "")
1660890286Sobrien	(if_then_else (match_operator 1 "comparison_operator"
1660990286Sobrien			[(match_operand 4 "nonimmediate_operand" "")
1661090286Sobrien			 (match_operand 5 "register_operand" "")])
1661190286Sobrien		      (match_operand 2 "nonimmediate_operand" "")
1661290286Sobrien		      (match_operand 3 "nonimmediate_operand" "")))
1661390286Sobrien   (clobber (match_operand 6 "" ""))
1661490286Sobrien   (clobber (reg:CC 17))]
1661590286Sobrien  "!SSE_REG_P (operands[0]) && reload_completed
1661690286Sobrien   && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
1661790286Sobrien  [(const_int 0)]
1661890286Sobrien{
1661990286Sobrien   ix86_compare_op0 = operands[5];
1662090286Sobrien   ix86_compare_op1 = operands[4];
1662190286Sobrien   operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
1662290286Sobrien				 VOIDmode, operands[5], operands[4]);
1662390286Sobrien   ix86_expand_fp_movcc (operands);
1662490286Sobrien   DONE;
1662590286Sobrien})
1662650650Sobrien
1662790286Sobrien;; Split SSE based conditional move into seqence:
1662890286Sobrien;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
1662990286Sobrien;; and   op2, op0   -  zero op2 if comparison was false
1663090286Sobrien;; nand  op0, op3   -  load op3 to op0 if comparison was false
1663190286Sobrien;; or	 op2, op0   -  get the non-zero one into the result.
1663250650Sobrien(define_split
1663390286Sobrien  [(set (match_operand 0 "register_operand" "")
1663490286Sobrien	(if_then_else (match_operator 1 "sse_comparison_operator"
1663590286Sobrien			[(match_operand 4 "register_operand" "")
1663690286Sobrien			 (match_operand 5 "nonimmediate_operand" "")])
1663790286Sobrien		      (match_operand 2 "register_operand" "")
1663890286Sobrien		      (match_operand 3 "register_operand" "")))
1663990286Sobrien   (clobber (match_operand 6 "" ""))
1664090286Sobrien   (clobber (reg:CC 17))]
1664190286Sobrien  "SSE_REG_P (operands[0]) && reload_completed"
1664290286Sobrien  [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
1664390286Sobrien   (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
1664490286Sobrien					    (subreg:TI (match_dup 4) 0)))
1664590286Sobrien   (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
1664690286Sobrien					    (subreg:TI (match_dup 3) 0)))
1664790286Sobrien   (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
1664890286Sobrien					    (subreg:TI (match_dup 7) 0)))]
1664990286Sobrien{
16650102802Skan  /* If op2 == op3, op3 will be clobbered before it is used.
16651102802Skan     This should be optimized out though.  */
16652102802Skan  if (operands_match_p (operands[2], operands[3]))
16653102802Skan    abort ();
1665490286Sobrien  PUT_MODE (operands[1], GET_MODE (operands[0]));
1665590286Sobrien  if (operands_match_p (operands[0], operands[4]))
1665690286Sobrien    operands[6] = operands[4], operands[7] = operands[2];
1665790286Sobrien  else
1665890286Sobrien    operands[6] = operands[2], operands[7] = operands[4];
1665990286Sobrien})
1666050650Sobrien
1666190286Sobrien;; Special case of conditional move we can handle effectivly.
1666290286Sobrien;; Do not brother with the integer/floating point case, since these are
1666390286Sobrien;; bot considerably slower, unlike in the generic case.
1666490286Sobrien(define_insn "*sse_movsfcc_const0_1"
16665102802Skan  [(set (match_operand:SF 0 "register_operand" "=&x")
1666690286Sobrien	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
1666790286Sobrien			[(match_operand:SF 4 "register_operand" "0")
1666890286Sobrien			 (match_operand:SF 5 "nonimmediate_operand" "xm")])
1666990286Sobrien		      (match_operand:SF 2 "register_operand" "x")
1667090286Sobrien		      (match_operand:SF 3 "const0_operand" "X")))]
1667190286Sobrien  "TARGET_SSE"
1667290286Sobrien  "#")
1667350650Sobrien
1667490286Sobrien(define_insn "*sse_movsfcc_const0_2"
16675102802Skan  [(set (match_operand:SF 0 "register_operand" "=&x")
1667690286Sobrien	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
1667790286Sobrien			[(match_operand:SF 4 "register_operand" "0")
1667890286Sobrien			 (match_operand:SF 5 "nonimmediate_operand" "xm")])
1667990286Sobrien		      (match_operand:SF 2 "const0_operand" "X")
1668090286Sobrien		      (match_operand:SF 3 "register_operand" "x")))]
1668190286Sobrien  "TARGET_SSE"
1668290286Sobrien  "#")
1668350650Sobrien
1668490286Sobrien(define_insn "*sse_movsfcc_const0_3"
16685102802Skan  [(set (match_operand:SF 0 "register_operand" "=&x")
1668690286Sobrien	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
1668790286Sobrien			[(match_operand:SF 4 "nonimmediate_operand" "xm")
1668890286Sobrien			 (match_operand:SF 5 "register_operand" "0")])
1668990286Sobrien		      (match_operand:SF 2 "register_operand" "x")
1669090286Sobrien		      (match_operand:SF 3 "const0_operand" "X")))]
1669190286Sobrien  "TARGET_SSE"
1669290286Sobrien  "#")
1669350650Sobrien
1669490286Sobrien(define_insn "*sse_movsfcc_const0_4"
16695102802Skan  [(set (match_operand:SF 0 "register_operand" "=&x")
1669690286Sobrien	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
1669790286Sobrien			[(match_operand:SF 4 "nonimmediate_operand" "xm")
1669890286Sobrien			 (match_operand:SF 5 "register_operand" "0")])
1669990286Sobrien		      (match_operand:SF 2 "const0_operand" "X")
1670090286Sobrien		      (match_operand:SF 3 "register_operand" "x")))]
1670190286Sobrien  "TARGET_SSE"
1670250650Sobrien  "#")
1670350650Sobrien
1670490286Sobrien(define_insn "*sse_movdfcc_const0_1"
16705102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y")
16706102802Skan	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
16707102802Skan			[(match_operand:DF 4 "register_operand" "0")
16708102802Skan			 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
16709102802Skan		      (match_operand:DF 2 "register_operand" "Y")
16710102802Skan		      (match_operand:DF 3 "const0_operand" "X")))]
1671190286Sobrien  "TARGET_SSE2"
1671250650Sobrien  "#")
1671350650Sobrien
1671490286Sobrien(define_insn "*sse_movdfcc_const0_2"
16715102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y")
16716102802Skan	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
16717102802Skan			[(match_operand:DF 4 "register_operand" "0")
16718102802Skan			 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
16719102802Skan		      (match_operand:DF 2 "const0_operand" "X")
16720102802Skan		      (match_operand:DF 3 "register_operand" "Y")))]
1672190286Sobrien  "TARGET_SSE2"
1672290286Sobrien  "#")
1672350650Sobrien
1672490286Sobrien(define_insn "*sse_movdfcc_const0_3"
16725102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y")
16726102802Skan	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16727102802Skan			[(match_operand:DF 4 "nonimmediate_operand" "Ym")
16728102802Skan			 (match_operand:DF 5 "register_operand" "0")])
16729102802Skan		      (match_operand:DF 2 "register_operand" "Y")
16730102802Skan		      (match_operand:DF 3 "const0_operand" "X")))]
1673190286Sobrien  "TARGET_SSE2"
1673290286Sobrien  "#")
1673350650Sobrien
1673490286Sobrien(define_insn "*sse_movdfcc_const0_4"
16735102802Skan  [(set (match_operand:DF 0 "register_operand" "=&Y")
16736102802Skan	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16737102802Skan			[(match_operand:DF 4 "nonimmediate_operand" "Ym")
16738102802Skan			 (match_operand:DF 5 "register_operand" "0")])
16739102802Skan		      (match_operand:DF 2 "const0_operand" "X")
16740102802Skan		      (match_operand:DF 3 "register_operand" "Y")))]
1674190286Sobrien  "TARGET_SSE2"
1674290286Sobrien  "#")
1674350650Sobrien
1674490286Sobrien(define_split
1674590286Sobrien  [(set (match_operand 0 "register_operand" "")
1674690286Sobrien	(if_then_else (match_operator 1 "comparison_operator"
1674790286Sobrien			[(match_operand 4 "register_operand" "")
1674890286Sobrien			 (match_operand 5 "nonimmediate_operand" "")])
1674990286Sobrien		      (match_operand 2 "nonmemory_operand" "")
1675090286Sobrien		      (match_operand 3 "nonmemory_operand" "")))]
1675190286Sobrien  "SSE_REG_P (operands[0]) && reload_completed
1675290286Sobrien   && (const0_operand (operands[2], GET_MODE (operands[0]))
1675390286Sobrien       || const0_operand (operands[3], GET_MODE (operands[0])))"
1675490286Sobrien  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
1675590286Sobrien   (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
1675690286Sobrien					    (subreg:TI (match_dup 7) 0)))]
1675790286Sobrien{
1675890286Sobrien  PUT_MODE (operands[1], GET_MODE (operands[0]));
1675990286Sobrien  if (!sse_comparison_operator (operands[1], VOIDmode))
1676090286Sobrien    {
1676190286Sobrien      rtx tmp = operands[5];
1676290286Sobrien      operands[5] = operands[4];
1676390286Sobrien      operands[4] = tmp;
1676490286Sobrien      PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
1676590286Sobrien    }
1676690286Sobrien  if (const0_operand (operands[2], GET_MODE (operands[0])))
1676790286Sobrien    {
1676890286Sobrien      operands[7] = operands[3];
1676990286Sobrien      operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
1677090286Sobrien							 0));
1677190286Sobrien    }
1677290286Sobrien  else
1677390286Sobrien    {
1677490286Sobrien      operands[7] = operands[2];
1677590286Sobrien      operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
1677690286Sobrien    }
1677790286Sobrien})
1677850650Sobrien
1677990286Sobrien(define_expand "allocate_stack_worker"
1678090286Sobrien  [(match_operand:SI 0 "register_operand" "")]
1678190286Sobrien  "TARGET_STACK_PROBE"
1678290286Sobrien{
1678390286Sobrien  if (TARGET_64BIT)
1678490286Sobrien    emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
1678590286Sobrien  else
1678690286Sobrien    emit_insn (gen_allocate_stack_worker_1 (operands[0]));
1678790286Sobrien  DONE;
1678890286Sobrien})
1678950650Sobrien
1679090286Sobrien(define_insn "allocate_stack_worker_1"
1679150650Sobrien  [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3)
1679250650Sobrien   (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
1679390286Sobrien   (clobber (match_dup 0))
1679490286Sobrien   (clobber (reg:CC 17))]
1679590286Sobrien  "!TARGET_64BIT && TARGET_STACK_PROBE"
1679690286Sobrien  "call\t__alloca"
1679790286Sobrien  [(set_attr "type" "multi")
1679890286Sobrien   (set_attr "length" "5")])
1679950650Sobrien
1680090286Sobrien(define_insn "allocate_stack_worker_rex64"
1680190286Sobrien  [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] 3)
1680290286Sobrien   (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
1680390286Sobrien   (clobber (match_dup 0))
1680490286Sobrien   (clobber (reg:CC 17))]
1680590286Sobrien  "TARGET_64BIT && TARGET_STACK_PROBE"
1680690286Sobrien  "call\t__alloca"
1680790286Sobrien  [(set_attr "type" "multi")
1680890286Sobrien   (set_attr "length" "5")])
1680990286Sobrien
1681050650Sobrien(define_expand "allocate_stack"
1681190286Sobrien  [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
1681290286Sobrien		   (minus:SI (reg:SI 7)
1681390286Sobrien			     (match_operand:SI 1 "general_operand" "")))
1681490286Sobrien	      (clobber (reg:CC 17))])
1681590286Sobrien   (parallel [(set (reg:SI 7)
1681690286Sobrien		   (minus:SI (reg:SI 7) (match_dup 1)))
1681790286Sobrien	      (clobber (reg:CC 17))])]
1681890286Sobrien  "TARGET_STACK_PROBE"
1681950650Sobrien{
1682050650Sobrien#ifdef CHECK_STACK_LIMIT
1682150650Sobrien  if (GET_CODE (operands[1]) == CONST_INT
1682250650Sobrien      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
1682350650Sobrien    emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
1682450650Sobrien			   operands[1]));
1682550650Sobrien  else 
1682650650Sobrien#endif
1682750650Sobrien    emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
1682850650Sobrien							    operands[1])));
1682950650Sobrien
1683050650Sobrien  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
1683150650Sobrien  DONE;
1683290286Sobrien})
1683350650Sobrien
1683490286Sobrien(define_expand "builtin_setjmp_receiver"
1683590286Sobrien  [(label_ref (match_operand 0 "" ""))]
1683690286Sobrien  "!TARGET_64BIT && flag_pic"
1683750650Sobrien{
1683890286Sobrien  load_pic_register ();
1683956391Sobrien  DONE;
1684090286Sobrien})
1684190286Sobrien
1684290286Sobrien;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
1684356391Sobrien
1684490286Sobrien(define_split
1684590286Sobrien  [(set (match_operand 0 "register_operand" "")
1684690286Sobrien	(match_operator 3 "promotable_binary_operator"
1684790286Sobrien	   [(match_operand 1 "register_operand" "")
1684890286Sobrien	    (match_operand 2 "aligned_operand" "")]))
1684990286Sobrien   (clobber (reg:CC 17))]
1685090286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
1685190286Sobrien   && ((GET_MODE (operands[0]) == HImode 
1685290286Sobrien	&& (!optimize_size || GET_CODE (operands[2]) != CONST_INT
1685390286Sobrien	    || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
1685490286Sobrien       || (GET_MODE (operands[0]) == QImode 
1685590286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1685690286Sobrien  [(parallel [(set (match_dup 0)
1685790286Sobrien		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
1685890286Sobrien	      (clobber (reg:CC 17))])]
1685990286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);
1686090286Sobrien   operands[1] = gen_lowpart (SImode, operands[1]);
1686190286Sobrien   if (GET_CODE (operands[3]) != ASHIFT)
1686290286Sobrien     operands[2] = gen_lowpart (SImode, operands[2]);
1686390286Sobrien   PUT_MODE (operands[3], SImode);")
1686490286Sobrien
1686590286Sobrien(define_split
1686690286Sobrien  [(set (reg 17)
1686790286Sobrien	(compare (and (match_operand 1 "aligned_operand" "")
1686890286Sobrien		      (match_operand 2 "const_int_operand" ""))
1686990286Sobrien		 (const_int 0)))
1687090286Sobrien   (set (match_operand 0 "register_operand" "")
1687190286Sobrien	(and (match_dup 1) (match_dup 2)))]
1687290286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
1687390286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
1687490286Sobrien   && (GET_MODE (operands[0]) == HImode
1687590286Sobrien       || (GET_MODE (operands[0]) == QImode 
1687690286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1687790286Sobrien  [(parallel [(set (reg:CCNO 17)
1687890286Sobrien		   (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
1687990286Sobrien			         (const_int 0)))
1688090286Sobrien	      (set (match_dup 0)
1688190286Sobrien		   (and:SI (match_dup 1) (match_dup 2)))])]
1688290286Sobrien  "operands[2]
1688390286Sobrien     = GEN_INT (trunc_int_for_mode (INTVAL (operands[2])
1688490286Sobrien				    & GET_MODE_MASK (GET_MODE (operands[0])),
1688590286Sobrien				    SImode));
1688690286Sobrien   operands[0] = gen_lowpart (SImode, operands[0]);
1688790286Sobrien   operands[1] = gen_lowpart (SImode, operands[1]);")
1688890286Sobrien
1688990286Sobrien(define_split
1689090286Sobrien  [(set (reg 17)
1689190286Sobrien	(compare (and (match_operand 0 "aligned_operand" "")
1689290286Sobrien		      (match_operand 1 "const_int_operand" ""))
1689390286Sobrien		 (const_int 0)))]
1689490286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
1689590286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
1689690286Sobrien   && (GET_MODE (operands[0]) == HImode
1689790286Sobrien       || (GET_MODE (operands[0]) == QImode 
1689890286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1689990286Sobrien  [(set (reg:CCNO 17)
1690090286Sobrien	(compare:CCNO (and:SI (match_dup 0) (match_dup 1))
1690190286Sobrien		      (const_int 0)))]
1690290286Sobrien  "operands[1]
1690390286Sobrien     = GEN_INT (trunc_int_for_mode (INTVAL (operands[1])
1690490286Sobrien				    & GET_MODE_MASK (GET_MODE (operands[0])),
1690590286Sobrien				    SImode));
1690690286Sobrien   operands[0] = gen_lowpart (SImode, operands[0]);")
1690790286Sobrien
1690890286Sobrien(define_split
1690990286Sobrien  [(set (match_operand 0 "register_operand" "")
1691090286Sobrien	(neg (match_operand 1 "register_operand" "")))
1691190286Sobrien   (clobber (reg:CC 17))]
1691290286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
1691390286Sobrien   && (GET_MODE (operands[0]) == HImode
1691490286Sobrien       || (GET_MODE (operands[0]) == QImode 
1691590286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1691690286Sobrien  [(parallel [(set (match_dup 0)
1691790286Sobrien		   (neg:SI (match_dup 1)))
1691890286Sobrien	      (clobber (reg:CC 17))])]
1691990286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);
1692090286Sobrien   operands[1] = gen_lowpart (SImode, operands[1]);")
1692190286Sobrien
1692290286Sobrien(define_split
1692390286Sobrien  [(set (match_operand 0 "register_operand" "")
1692490286Sobrien	(not (match_operand 1 "register_operand" "")))]
1692590286Sobrien  "! TARGET_PARTIAL_REG_STALL && reload_completed
1692690286Sobrien   && (GET_MODE (operands[0]) == HImode
1692790286Sobrien       || (GET_MODE (operands[0]) == QImode 
1692890286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1692990286Sobrien  [(set (match_dup 0)
1693090286Sobrien	(not:SI (match_dup 1)))]
1693190286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);
1693290286Sobrien   operands[1] = gen_lowpart (SImode, operands[1]);")
1693390286Sobrien
1693490286Sobrien(define_split 
1693590286Sobrien  [(set (match_operand 0 "register_operand" "")
1693690286Sobrien	(if_then_else (match_operator 1 "comparison_operator" 
1693790286Sobrien				[(reg 17) (const_int 0)])
1693890286Sobrien		      (match_operand 2 "register_operand" "")
1693990286Sobrien		      (match_operand 3 "register_operand" "")))]
1694090286Sobrien  "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
1694190286Sobrien   && (GET_MODE (operands[0]) == HImode
1694290286Sobrien       || (GET_MODE (operands[0]) == QImode 
1694390286Sobrien	   && (TARGET_PROMOTE_QImode || optimize_size)))"
1694490286Sobrien  [(set (match_dup 0)
1694590286Sobrien	(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
1694690286Sobrien  "operands[0] = gen_lowpart (SImode, operands[0]);
1694790286Sobrien   operands[2] = gen_lowpart (SImode, operands[2]);
1694890286Sobrien   operands[3] = gen_lowpart (SImode, operands[3]);")
1694990286Sobrien			
1695090286Sobrien
1695190286Sobrien;; RTL Peephole optimizations, run before sched2.  These primarily look to
1695290286Sobrien;; transform a complex memory operation into two memory to register operations.
1695390286Sobrien
1695490286Sobrien;; Don't push memory operands
1695590286Sobrien(define_peephole2
1695690286Sobrien  [(set (match_operand:SI 0 "push_operand" "")
1695790286Sobrien	(match_operand:SI 1 "memory_operand" ""))
1695890286Sobrien   (match_scratch:SI 2 "r")]
1695990286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1696090286Sobrien  [(set (match_dup 2) (match_dup 1))
1696190286Sobrien   (set (match_dup 0) (match_dup 2))]
1696290286Sobrien  "")
1696390286Sobrien
1696490286Sobrien(define_peephole2
1696590286Sobrien  [(set (match_operand:DI 0 "push_operand" "")
1696690286Sobrien	(match_operand:DI 1 "memory_operand" ""))
1696790286Sobrien   (match_scratch:DI 2 "r")]
1696890286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1696990286Sobrien  [(set (match_dup 2) (match_dup 1))
1697090286Sobrien   (set (match_dup 0) (match_dup 2))]
1697190286Sobrien  "")
1697290286Sobrien
1697390286Sobrien;; We need to handle SFmode only, because DFmode and XFmode is split to
1697490286Sobrien;; SImode pushes.
1697590286Sobrien(define_peephole2
1697690286Sobrien  [(set (match_operand:SF 0 "push_operand" "")
1697790286Sobrien	(match_operand:SF 1 "memory_operand" ""))
1697890286Sobrien   (match_scratch:SF 2 "r")]
1697990286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1698090286Sobrien  [(set (match_dup 2) (match_dup 1))
1698190286Sobrien   (set (match_dup 0) (match_dup 2))]
1698290286Sobrien  "")
1698390286Sobrien
1698490286Sobrien(define_peephole2
1698590286Sobrien  [(set (match_operand:HI 0 "push_operand" "")
1698690286Sobrien	(match_operand:HI 1 "memory_operand" ""))
1698790286Sobrien   (match_scratch:HI 2 "r")]
1698890286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1698990286Sobrien  [(set (match_dup 2) (match_dup 1))
1699090286Sobrien   (set (match_dup 0) (match_dup 2))]
1699190286Sobrien  "")
1699290286Sobrien
1699390286Sobrien(define_peephole2
1699490286Sobrien  [(set (match_operand:QI 0 "push_operand" "")
1699590286Sobrien	(match_operand:QI 1 "memory_operand" ""))
1699690286Sobrien   (match_scratch:QI 2 "q")]
1699790286Sobrien  "! optimize_size && ! TARGET_PUSH_MEMORY"
1699890286Sobrien  [(set (match_dup 2) (match_dup 1))
1699990286Sobrien   (set (match_dup 0) (match_dup 2))]
1700090286Sobrien  "")
1700190286Sobrien
1700290286Sobrien;; Don't move an immediate directly to memory when the instruction
1700390286Sobrien;; gets too big.
1700490286Sobrien(define_peephole2
1700590286Sobrien  [(match_scratch:SI 1 "r")
1700690286Sobrien   (set (match_operand:SI 0 "memory_operand" "")
1700790286Sobrien        (const_int 0))]
1700890286Sobrien  "! optimize_size
1700990286Sobrien   && ! TARGET_USE_MOV0
1701090286Sobrien   && TARGET_SPLIT_LONG_MOVES
1701190286Sobrien   && get_attr_length (insn) >= ix86_cost->large_insn
1701290286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1701390286Sobrien  [(parallel [(set (match_dup 1) (const_int 0))
1701490286Sobrien	      (clobber (reg:CC 17))])
1701590286Sobrien   (set (match_dup 0) (match_dup 1))]
1701690286Sobrien  "")
1701790286Sobrien
1701890286Sobrien(define_peephole2
1701990286Sobrien  [(match_scratch:HI 1 "r")
1702090286Sobrien   (set (match_operand:HI 0 "memory_operand" "")
1702190286Sobrien        (const_int 0))]
1702290286Sobrien  "! optimize_size
1702390286Sobrien   && ! TARGET_USE_MOV0
1702490286Sobrien   && TARGET_SPLIT_LONG_MOVES
1702590286Sobrien   && get_attr_length (insn) >= ix86_cost->large_insn
1702690286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1702790286Sobrien  [(parallel [(set (match_dup 2) (const_int 0))
1702890286Sobrien	      (clobber (reg:CC 17))])
1702990286Sobrien   (set (match_dup 0) (match_dup 1))]
1703090286Sobrien  "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
1703190286Sobrien
1703290286Sobrien(define_peephole2
1703390286Sobrien  [(match_scratch:QI 1 "q")
1703490286Sobrien   (set (match_operand:QI 0 "memory_operand" "")
1703590286Sobrien        (const_int 0))]
1703690286Sobrien  "! optimize_size
1703790286Sobrien   && ! TARGET_USE_MOV0
1703890286Sobrien   && TARGET_SPLIT_LONG_MOVES
1703990286Sobrien   && get_attr_length (insn) >= ix86_cost->large_insn
1704090286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1704190286Sobrien  [(parallel [(set (match_dup 2) (const_int 0))
1704290286Sobrien	      (clobber (reg:CC 17))])
1704390286Sobrien   (set (match_dup 0) (match_dup 1))]
1704490286Sobrien  "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
1704590286Sobrien
1704690286Sobrien(define_peephole2
1704790286Sobrien  [(match_scratch:SI 2 "r")
1704890286Sobrien   (set (match_operand:SI 0 "memory_operand" "")
1704990286Sobrien        (match_operand:SI 1 "immediate_operand" ""))]
1705090286Sobrien  "! optimize_size
1705190286Sobrien   && get_attr_length (insn) >= ix86_cost->large_insn
1705290286Sobrien   && TARGET_SPLIT_LONG_MOVES"
1705390286Sobrien  [(set (match_dup 2) (match_dup 1))
1705490286Sobrien   (set (match_dup 0) (match_dup 2))]
1705590286Sobrien  "")
1705690286Sobrien
1705790286Sobrien(define_peephole2
1705890286Sobrien  [(match_scratch:HI 2 "r")
1705990286Sobrien   (set (match_operand:HI 0 "memory_operand" "")
1706090286Sobrien        (match_operand:HI 1 "immediate_operand" ""))]
1706190286Sobrien  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
1706290286Sobrien  && TARGET_SPLIT_LONG_MOVES"
1706390286Sobrien  [(set (match_dup 2) (match_dup 1))
1706490286Sobrien   (set (match_dup 0) (match_dup 2))]
1706590286Sobrien  "")
1706690286Sobrien
1706790286Sobrien(define_peephole2
1706890286Sobrien  [(match_scratch:QI 2 "q")
1706990286Sobrien   (set (match_operand:QI 0 "memory_operand" "")
1707090286Sobrien        (match_operand:QI 1 "immediate_operand" ""))]
1707190286Sobrien  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
1707290286Sobrien  && TARGET_SPLIT_LONG_MOVES"
1707390286Sobrien  [(set (match_dup 2) (match_dup 1))
1707490286Sobrien   (set (match_dup 0) (match_dup 2))]
1707590286Sobrien  "")
1707690286Sobrien
1707790286Sobrien;; Don't compare memory with zero, load and use a test instead.
1707890286Sobrien(define_peephole2
1707990286Sobrien  [(set (reg 17)
1708090286Sobrien	(compare (match_operand:SI 0 "memory_operand" "")
1708190286Sobrien	         (const_int 0)))
1708290286Sobrien   (match_scratch:SI 3 "r")]
1708390286Sobrien  "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
1708490286Sobrien  [(set (match_dup 3) (match_dup 0))
1708590286Sobrien   (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
1708690286Sobrien  "")
1708790286Sobrien
1708890286Sobrien;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
1708990286Sobrien;; Don't split NOTs with a displacement operand, because resulting XOR
1709090286Sobrien;; will not be pariable anyway.
1709190286Sobrien;;
1709290286Sobrien;; On AMD K6, NOT is vector decoded with memory operand that can not be
1709390286Sobrien;; represented using a modRM byte.  The XOR replacement is long decoded,
1709490286Sobrien;; so this split helps here as well.
1709590286Sobrien;;
1709690286Sobrien;; Note: Can't do this as a regular split because we can't get proper
1709790286Sobrien;; lifetime information then.
1709890286Sobrien
1709990286Sobrien(define_peephole2
1710090286Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1710190286Sobrien	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
1710290286Sobrien  "!optimize_size
1710390286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)
1710490286Sobrien   && ((TARGET_PENTIUM 
1710590286Sobrien        && (GET_CODE (operands[0]) != MEM
1710690286Sobrien            || !memory_displacement_operand (operands[0], SImode)))
1710790286Sobrien       || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
1710890286Sobrien  [(parallel [(set (match_dup 0)
1710990286Sobrien		   (xor:SI (match_dup 1) (const_int -1)))
1711090286Sobrien	      (clobber (reg:CC 17))])]
1711190286Sobrien  "")
1711290286Sobrien
1711390286Sobrien(define_peephole2
1711490286Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1711590286Sobrien	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
1711690286Sobrien  "!optimize_size
1711790286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)
1711890286Sobrien   && ((TARGET_PENTIUM 
1711990286Sobrien        && (GET_CODE (operands[0]) != MEM
1712090286Sobrien            || !memory_displacement_operand (operands[0], HImode)))
1712190286Sobrien       || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
1712290286Sobrien  [(parallel [(set (match_dup 0)
1712390286Sobrien		   (xor:HI (match_dup 1) (const_int -1)))
1712490286Sobrien	      (clobber (reg:CC 17))])]
1712590286Sobrien  "")
1712690286Sobrien
1712790286Sobrien(define_peephole2
1712890286Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1712990286Sobrien	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
1713090286Sobrien  "!optimize_size
1713190286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)
1713290286Sobrien   && ((TARGET_PENTIUM 
1713390286Sobrien        && (GET_CODE (operands[0]) != MEM
1713490286Sobrien            || !memory_displacement_operand (operands[0], QImode)))
1713590286Sobrien       || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
1713690286Sobrien  [(parallel [(set (match_dup 0)
1713790286Sobrien		   (xor:QI (match_dup 1) (const_int -1)))
1713890286Sobrien	      (clobber (reg:CC 17))])]
1713990286Sobrien  "")
1714090286Sobrien
1714190286Sobrien;; Non pairable "test imm, reg" instructions can be translated to
1714290286Sobrien;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
1714390286Sobrien;; byte opcode instead of two, have a short form for byte operands),
1714490286Sobrien;; so do it for other CPUs as well.  Given that the value was dead,
1714590286Sobrien;; this should not create any new dependencies.  Pass on the sub-word
1714690286Sobrien;; versions if we're concerned about partial register stalls.
1714790286Sobrien
1714890286Sobrien(define_peephole2
1714990286Sobrien  [(set (reg 17)
1715090286Sobrien	(compare (and:SI (match_operand:SI 0 "register_operand" "")
1715190286Sobrien			 (match_operand:SI 1 "immediate_operand" ""))
1715290286Sobrien		 (const_int 0)))]
1715390286Sobrien  "ix86_match_ccmode (insn, CCNOmode)
1715490286Sobrien   && (true_regnum (operands[0]) != 0
1715590286Sobrien       || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
1715690286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1715790286Sobrien  [(parallel
1715890286Sobrien     [(set (reg:CCNO 17)
1715990286Sobrien	   (compare:CCNO (and:SI (match_dup 0)
1716090286Sobrien			         (match_dup 1))
1716190286Sobrien		         (const_int 0)))
1716290286Sobrien      (set (match_dup 0)
1716390286Sobrien	   (and:SI (match_dup 0) (match_dup 1)))])]
1716490286Sobrien  "")
1716590286Sobrien
1716690286Sobrien;; We don't need to handle HImode case, because it will be promoted to SImode
1716790286Sobrien;; on ! TARGET_PARTIAL_REG_STALL
1716890286Sobrien
1716990286Sobrien(define_peephole2
1717090286Sobrien  [(set (reg 17)
1717190286Sobrien	(compare (and:QI (match_operand:QI 0 "register_operand" "")
1717290286Sobrien			 (match_operand:QI 1 "immediate_operand" ""))
1717390286Sobrien		 (const_int 0)))]
1717490286Sobrien  "! TARGET_PARTIAL_REG_STALL
1717590286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
1717690286Sobrien   && true_regnum (operands[0]) != 0
1717790286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1717890286Sobrien  [(parallel
1717990286Sobrien     [(set (reg:CCNO 17)
1718090286Sobrien	   (compare:CCNO (and:QI (match_dup 0)
1718190286Sobrien 			         (match_dup 1))
1718290286Sobrien		         (const_int 0)))
1718390286Sobrien      (set (match_dup 0)
1718490286Sobrien	   (and:QI (match_dup 0) (match_dup 1)))])]
1718590286Sobrien  "")
1718690286Sobrien
1718790286Sobrien(define_peephole2
1718890286Sobrien  [(set (reg 17)
1718990286Sobrien	(compare
1719090286Sobrien	  (and:SI
1719190286Sobrien	    (zero_extract:SI
1719290286Sobrien	      (match_operand 0 "ext_register_operand" "")
1719390286Sobrien	      (const_int 8)
1719490286Sobrien	      (const_int 8))
1719590286Sobrien	    (match_operand 1 "const_int_operand" ""))
1719690286Sobrien	  (const_int 0)))]
1719790286Sobrien  "! TARGET_PARTIAL_REG_STALL
1719890286Sobrien   && ix86_match_ccmode (insn, CCNOmode)
1719990286Sobrien   && true_regnum (operands[0]) != 0
1720090286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1720190286Sobrien  [(parallel [(set (reg:CCNO 17)
1720290286Sobrien		   (compare:CCNO
1720390286Sobrien		       (and:SI
1720490286Sobrien			 (zero_extract:SI
1720590286Sobrien			 (match_dup 0)
1720690286Sobrien			 (const_int 8)
1720790286Sobrien			 (const_int 8))
1720890286Sobrien			(match_dup 1))
1720990286Sobrien		   (const_int 0)))
1721090286Sobrien	      (set (zero_extract:SI (match_dup 0)
1721190286Sobrien				    (const_int 8)
1721290286Sobrien				    (const_int 8))
1721390286Sobrien		   (and:SI 
1721490286Sobrien		     (zero_extract:SI
1721590286Sobrien		       (match_dup 0)
1721690286Sobrien		       (const_int 8)
1721790286Sobrien		       (const_int 8))
1721890286Sobrien		     (match_dup 1)))])]
1721990286Sobrien  "")
1722090286Sobrien
1722190286Sobrien;; Don't do logical operations with memory inputs.
1722290286Sobrien(define_peephole2
1722390286Sobrien  [(match_scratch:SI 2 "r")
1722490286Sobrien   (parallel [(set (match_operand:SI 0 "register_operand" "")
1722590286Sobrien                   (match_operator:SI 3 "arith_or_logical_operator"
1722690286Sobrien                     [(match_dup 0)
1722790286Sobrien                      (match_operand:SI 1 "memory_operand" "")]))
1722890286Sobrien              (clobber (reg:CC 17))])]
1722990286Sobrien  "! optimize_size && ! TARGET_READ_MODIFY"
1723090286Sobrien  [(set (match_dup 2) (match_dup 1))
1723190286Sobrien   (parallel [(set (match_dup 0)
1723290286Sobrien                   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
1723390286Sobrien              (clobber (reg:CC 17))])]
1723490286Sobrien  "")
1723590286Sobrien
1723690286Sobrien(define_peephole2
1723790286Sobrien  [(match_scratch:SI 2 "r")
1723890286Sobrien   (parallel [(set (match_operand:SI 0 "register_operand" "")
1723990286Sobrien                   (match_operator:SI 3 "arith_or_logical_operator"
1724090286Sobrien                     [(match_operand:SI 1 "memory_operand" "")
1724190286Sobrien                      (match_dup 0)]))
1724290286Sobrien              (clobber (reg:CC 17))])]
1724390286Sobrien  "! optimize_size && ! TARGET_READ_MODIFY"
1724490286Sobrien  [(set (match_dup 2) (match_dup 1))
1724590286Sobrien   (parallel [(set (match_dup 0)
1724690286Sobrien                   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
1724790286Sobrien              (clobber (reg:CC 17))])]
1724890286Sobrien  "")
1724990286Sobrien
1725090286Sobrien; Don't do logical operations with memory outputs
1725190286Sobrien;
1725290286Sobrien; These two don't make sense for PPro/PII -- we're expanding a 4-uop
1725390286Sobrien; instruction into two 1-uop insns plus a 2-uop insn.  That last has
1725490286Sobrien; the same decoder scheduling characteristics as the original.
1725590286Sobrien
1725690286Sobrien(define_peephole2
1725790286Sobrien  [(match_scratch:SI 2 "r")
1725890286Sobrien   (parallel [(set (match_operand:SI 0 "memory_operand" "")
1725990286Sobrien                   (match_operator:SI 3 "arith_or_logical_operator"
1726090286Sobrien                     [(match_dup 0)
1726190286Sobrien                      (match_operand:SI 1 "nonmemory_operand" "")]))
1726290286Sobrien              (clobber (reg:CC 17))])]
1726390286Sobrien  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
1726490286Sobrien  [(set (match_dup 2) (match_dup 0))
1726590286Sobrien   (parallel [(set (match_dup 2)
1726690286Sobrien                   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
1726790286Sobrien              (clobber (reg:CC 17))])
1726890286Sobrien   (set (match_dup 0) (match_dup 2))]
1726990286Sobrien  "")
1727090286Sobrien
1727190286Sobrien(define_peephole2
1727290286Sobrien  [(match_scratch:SI 2 "r")
1727390286Sobrien   (parallel [(set (match_operand:SI 0 "memory_operand" "")
1727490286Sobrien                   (match_operator:SI 3 "arith_or_logical_operator"
1727590286Sobrien                     [(match_operand:SI 1 "nonmemory_operand" "")
1727690286Sobrien                      (match_dup 0)]))
1727790286Sobrien              (clobber (reg:CC 17))])]
1727890286Sobrien  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
1727990286Sobrien  [(set (match_dup 2) (match_dup 0))
1728090286Sobrien   (parallel [(set (match_dup 2)
1728190286Sobrien                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
1728290286Sobrien              (clobber (reg:CC 17))])
1728390286Sobrien   (set (match_dup 0) (match_dup 2))]
1728490286Sobrien  "")
1728590286Sobrien
1728690286Sobrien;; Attempt to always use XOR for zeroing registers.
1728790286Sobrien(define_peephole2
1728890286Sobrien  [(set (match_operand 0 "register_operand" "")
1728990286Sobrien	(const_int 0))]
1729090286Sobrien  "(GET_MODE (operands[0]) == QImode
1729190286Sobrien    || GET_MODE (operands[0]) == HImode
1729290286Sobrien    || GET_MODE (operands[0]) == SImode
1729390286Sobrien    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
1729490286Sobrien   && (! TARGET_USE_MOV0 || optimize_size)
1729590286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1729690286Sobrien  [(parallel [(set (match_dup 0) (const_int 0))
1729790286Sobrien	      (clobber (reg:CC 17))])]
1729890286Sobrien  "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
1729990286Sobrien			      true_regnum (operands[0]));")
1730090286Sobrien
1730190286Sobrien(define_peephole2
1730290286Sobrien  [(set (strict_low_part (match_operand 0 "register_operand" ""))
1730390286Sobrien	(const_int 0))]
1730490286Sobrien  "(GET_MODE (operands[0]) == QImode
1730590286Sobrien    || GET_MODE (operands[0]) == HImode)
1730690286Sobrien   && (! TARGET_USE_MOV0 || optimize_size)
1730790286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1730890286Sobrien  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
1730990286Sobrien	      (clobber (reg:CC 17))])])
1731090286Sobrien
1731190286Sobrien;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
1731290286Sobrien(define_peephole2
1731390286Sobrien  [(set (match_operand 0 "register_operand" "")
1731490286Sobrien	(const_int -1))]
1731590286Sobrien  "(GET_MODE (operands[0]) == HImode
1731690286Sobrien    || GET_MODE (operands[0]) == SImode 
1731790286Sobrien    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
1731890286Sobrien   && (optimize_size || TARGET_PENTIUM)
1731990286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1732090286Sobrien  [(parallel [(set (match_dup 0) (const_int -1))
1732190286Sobrien	      (clobber (reg:CC 17))])]
1732290286Sobrien  "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
1732390286Sobrien			      true_regnum (operands[0]));")
1732490286Sobrien
1732590286Sobrien;; Attempt to convert simple leas to adds. These can be created by
1732690286Sobrien;; move expanders.
1732790286Sobrien(define_peephole2
1732890286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1732990286Sobrien  	(plus:SI (match_dup 0)
1733090286Sobrien		 (match_operand:SI 1 "nonmemory_operand" "")))]
1733190286Sobrien  "peep2_regno_dead_p (0, FLAGS_REG)"
1733290286Sobrien  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
1733390286Sobrien	      (clobber (reg:CC 17))])]
1733490286Sobrien  "")
1733590286Sobrien
1733690286Sobrien(define_peephole2
1733790286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1733890286Sobrien  	(subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
1733990286Sobrien			    (match_operand:DI 2 "nonmemory_operand" "")) 0))]
1734090286Sobrien  "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
1734190286Sobrien  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
1734290286Sobrien	      (clobber (reg:CC 17))])]
1734390286Sobrien  "operands[2] = gen_lowpart (SImode, operands[2]);")
1734490286Sobrien
1734590286Sobrien(define_peephole2
1734690286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1734790286Sobrien  	(plus:DI (match_dup 0)
1734890286Sobrien		 (match_operand:DI 1 "x86_64_general_operand" "")))]
1734990286Sobrien  "peep2_regno_dead_p (0, FLAGS_REG)"
1735090286Sobrien  [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
1735190286Sobrien	      (clobber (reg:CC 17))])]
1735290286Sobrien  "")
1735390286Sobrien
1735490286Sobrien(define_peephole2
1735590286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1735690286Sobrien  	(mult:SI (match_dup 0)
1735790286Sobrien		 (match_operand:SI 1 "const_int_operand" "")))]
1735890286Sobrien  "exact_log2 (INTVAL (operands[1])) >= 0
1735990286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1736090286Sobrien  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
1736190286Sobrien	      (clobber (reg:CC 17))])]
1736290286Sobrien  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
1736390286Sobrien
1736490286Sobrien(define_peephole2
1736590286Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1736690286Sobrien  	(mult:DI (match_dup 0)
1736790286Sobrien		 (match_operand:DI 1 "const_int_operand" "")))]
1736890286Sobrien  "exact_log2 (INTVAL (operands[1])) >= 0
1736990286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1737090286Sobrien  [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
1737190286Sobrien	      (clobber (reg:CC 17))])]
1737290286Sobrien  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
1737390286Sobrien
1737490286Sobrien(define_peephole2
1737590286Sobrien  [(set (match_operand:SI 0 "register_operand" "")
1737690286Sobrien  	(subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
1737790286Sobrien		   (match_operand:DI 2 "const_int_operand" "")) 0))]
1737890286Sobrien  "exact_log2 (INTVAL (operands[1])) >= 0
1737990286Sobrien   && REGNO (operands[0]) == REGNO (operands[1])
1738090286Sobrien   && peep2_regno_dead_p (0, FLAGS_REG)"
1738190286Sobrien  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
1738290286Sobrien	      (clobber (reg:CC 17))])]
1738390286Sobrien  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
1738490286Sobrien
1738590286Sobrien;; The ESP adjustments can be done by the push and pop instructions.  Resulting
1738690286Sobrien;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
1738790286Sobrien;; many CPUs it is also faster, since special hardware to avoid esp
1738890286Sobrien;; dependencies is present.
1738990286Sobrien
1739090286Sobrien;; While some of these conversions may be done using splitters, we use peepholes
1739190286Sobrien;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
1739290286Sobrien
1739390286Sobrien;; Convert prologue esp subtractions to push.
1739490286Sobrien;; We need register to push.  In order to keep verify_flow_info happy we have
1739590286Sobrien;; two choices
1739690286Sobrien;; - use scratch and clobber it in order to avoid dependencies
1739790286Sobrien;; - use already live register
1739890286Sobrien;; We can't use the second way right now, since there is no reliable way how to
1739990286Sobrien;; verify that given register is live.  First choice will also most likely in
1740090286Sobrien;; fewer dependencies.  On the place of esp adjustments it is very likely that
1740190286Sobrien;; call clobbered registers are dead.  We may want to use base pointer as an
1740290286Sobrien;; alternative when no register is available later.
1740390286Sobrien
1740490286Sobrien(define_peephole2
1740590286Sobrien  [(match_scratch:SI 0 "r")
1740690286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
1740790286Sobrien	      (clobber (reg:CC 17))
1740890286Sobrien	      (clobber (mem:BLK (scratch)))])]
1740990286Sobrien  "optimize_size || !TARGET_SUB_ESP_4"
1741090286Sobrien  [(clobber (match_dup 0))
1741190286Sobrien   (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
1741290286Sobrien	      (clobber (mem:BLK (scratch)))])])
1741390286Sobrien
1741490286Sobrien(define_peephole2
1741590286Sobrien  [(match_scratch:SI 0 "r")
1741690286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1741790286Sobrien	      (clobber (reg:CC 17))
1741890286Sobrien	      (clobber (mem:BLK (scratch)))])]
1741990286Sobrien  "optimize_size || !TARGET_SUB_ESP_8"
1742090286Sobrien  [(clobber (match_dup 0))
1742190286Sobrien   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
1742290286Sobrien   (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
1742390286Sobrien	      (clobber (mem:BLK (scratch)))])])
1742490286Sobrien
1742590286Sobrien;; Convert esp subtractions to push.
1742690286Sobrien(define_peephole2
1742790286Sobrien  [(match_scratch:SI 0 "r")
1742890286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
1742990286Sobrien	      (clobber (reg:CC 17))])]
1743090286Sobrien  "optimize_size || !TARGET_SUB_ESP_4"
1743190286Sobrien  [(clobber (match_dup 0))
1743290286Sobrien   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
1743390286Sobrien
1743490286Sobrien(define_peephole2
1743590286Sobrien  [(match_scratch:SI 0 "r")
1743690286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1743790286Sobrien	      (clobber (reg:CC 17))])]
1743890286Sobrien  "optimize_size || !TARGET_SUB_ESP_8"
1743990286Sobrien  [(clobber (match_dup 0))
1744090286Sobrien   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
1744190286Sobrien   (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
1744290286Sobrien
1744390286Sobrien;; Convert epilogue deallocator to pop.
1744490286Sobrien(define_peephole2
1744590286Sobrien  [(match_scratch:SI 0 "r")
1744690286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1744790286Sobrien	      (clobber (reg:CC 17))
1744890286Sobrien	      (clobber (mem:BLK (scratch)))])]
1744990286Sobrien  "optimize_size || !TARGET_ADD_ESP_4"
1745090286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1745190286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1745290286Sobrien	      (clobber (mem:BLK (scratch)))])]
1745390286Sobrien  "")
1745490286Sobrien
1745590286Sobrien;; Two pops case is tricky, since pop causes dependency on destination register.
1745690286Sobrien;; We use two registers if available.
1745790286Sobrien(define_peephole2
1745890286Sobrien  [(match_scratch:SI 0 "r")
1745990286Sobrien   (match_scratch:SI 1 "r")
1746090286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
1746190286Sobrien	      (clobber (reg:CC 17))
1746290286Sobrien	      (clobber (mem:BLK (scratch)))])]
1746390286Sobrien  "optimize_size || !TARGET_ADD_ESP_8"
1746490286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1746590286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1746690286Sobrien	      (clobber (mem:BLK (scratch)))])
1746790286Sobrien   (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1746890286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1746990286Sobrien  "")
1747090286Sobrien
1747190286Sobrien(define_peephole2
1747290286Sobrien  [(match_scratch:SI 0 "r")
1747390286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
1747490286Sobrien	      (clobber (reg:CC 17))
1747590286Sobrien	      (clobber (mem:BLK (scratch)))])]
1747690286Sobrien  "optimize_size"
1747790286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1747890286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1747990286Sobrien	      (clobber (mem:BLK (scratch)))])
1748090286Sobrien   (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1748190286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1748290286Sobrien  "")
1748390286Sobrien
1748490286Sobrien;; Convert esp additions to pop.
1748590286Sobrien(define_peephole2
1748690286Sobrien  [(match_scratch:SI 0 "r")
1748790286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
1748890286Sobrien	      (clobber (reg:CC 17))])]
1748990286Sobrien  ""
1749090286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1749190286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1749290286Sobrien  "")
1749390286Sobrien
1749490286Sobrien;; Two pops case is tricky, since pop causes dependency on destination register.
1749590286Sobrien;; We use two registers if available.
1749690286Sobrien(define_peephole2
1749790286Sobrien  [(match_scratch:SI 0 "r")
1749890286Sobrien   (match_scratch:SI 1 "r")
1749990286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
1750090286Sobrien	      (clobber (reg:CC 17))])]
1750190286Sobrien  ""
1750290286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1750390286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
1750490286Sobrien   (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
1750590286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
1750690286Sobrien  "")
1750790286Sobrien
1750890286Sobrien(define_peephole2
1750990286Sobrien  [(match_scratch:SI 0 "r")
1751090286Sobrien   (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
1751190286Sobrien	      (clobber (reg:CC 17))])]
1751290286Sobrien  "optimize_size"
1751390286Sobrien  [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
1751490286Sobrien	      (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
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  "")
1751890286Sobrien
1751990286Sobrien;; Convert compares with 1 to shorter inc/dec operations when CF is not
1752090286Sobrien;; required and register dies.
1752190286Sobrien(define_peephole2
1752290286Sobrien  [(set (reg 17)
1752390286Sobrien	(compare (match_operand:SI 0 "register_operand" "")
1752490286Sobrien		 (match_operand:SI 1 "incdec_operand" "")))]
1752590286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
1752690286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1752790286Sobrien  [(parallel [(set (reg:CCGC 17)
1752890286Sobrien		   (compare:CCGC (match_dup 0)
1752990286Sobrien				 (match_dup 1)))
1753090286Sobrien	      (clobber (match_dup 0))])]
1753190286Sobrien  "")
1753290286Sobrien
1753390286Sobrien(define_peephole2
1753490286Sobrien  [(set (reg 17)
1753590286Sobrien	(compare (match_operand:HI 0 "register_operand" "")
1753690286Sobrien		 (match_operand:HI 1 "incdec_operand" "")))]
1753790286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
1753890286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1753990286Sobrien  [(parallel [(set (reg:CCGC 17)
1754090286Sobrien		   (compare:CCGC (match_dup 0)
1754190286Sobrien				 (match_dup 1)))
1754290286Sobrien	      (clobber (match_dup 0))])]
1754390286Sobrien  "")
1754490286Sobrien
1754590286Sobrien(define_peephole2
1754690286Sobrien  [(set (reg 17)
1754790286Sobrien	(compare (match_operand:QI 0 "register_operand" "")
1754890286Sobrien		 (match_operand:QI 1 "incdec_operand" "")))]
1754990286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
1755090286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1755190286Sobrien  [(parallel [(set (reg:CCGC 17)
1755290286Sobrien		   (compare:CCGC (match_dup 0)
1755390286Sobrien				 (match_dup 1)))
1755490286Sobrien	      (clobber (match_dup 0))])]
1755590286Sobrien  "")
1755690286Sobrien
1755790286Sobrien;; Convert compares with 128 to shorter add -128
1755890286Sobrien(define_peephole2
1755990286Sobrien  [(set (reg 17)
1756090286Sobrien	(compare (match_operand:SI 0 "register_operand" "")
1756190286Sobrien		 (const_int 128)))]
1756290286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
1756390286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1756490286Sobrien  [(parallel [(set (reg:CCGC 17)
1756590286Sobrien		   (compare:CCGC (match_dup 0)
1756690286Sobrien			         (const_int 128)))
1756790286Sobrien	      (clobber (match_dup 0))])]
1756890286Sobrien  "")
1756990286Sobrien
1757090286Sobrien(define_peephole2
1757190286Sobrien  [(set (reg 17)
1757290286Sobrien	(compare (match_operand:HI 0 "register_operand" "")
1757390286Sobrien		 (const_int 128)))]
1757490286Sobrien  "ix86_match_ccmode (insn, CCGCmode)
1757590286Sobrien   && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
1757690286Sobrien  [(parallel [(set (reg:CCGC 17)
1757790286Sobrien		   (compare:CCGC (match_dup 0)
1757890286Sobrien			         (const_int 128)))
1757990286Sobrien	      (clobber (match_dup 0))])]
1758090286Sobrien  "")
1758190286Sobrien
1758290286Sobrien(define_peephole2
1758390286Sobrien  [(match_scratch:DI 0 "r")
1758490286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
1758590286Sobrien	      (clobber (reg:CC 17))
1758690286Sobrien	      (clobber (mem:BLK (scratch)))])]
1758790286Sobrien  "optimize_size || !TARGET_SUB_ESP_4"
1758890286Sobrien  [(clobber (match_dup 0))
1758990286Sobrien   (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
1759090286Sobrien	      (clobber (mem:BLK (scratch)))])])
1759190286Sobrien
1759290286Sobrien(define_peephole2
1759390286Sobrien  [(match_scratch:DI 0 "r")
1759490286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
1759590286Sobrien	      (clobber (reg:CC 17))
1759690286Sobrien	      (clobber (mem:BLK (scratch)))])]
1759790286Sobrien  "optimize_size || !TARGET_SUB_ESP_8"
1759890286Sobrien  [(clobber (match_dup 0))
1759990286Sobrien   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
1760090286Sobrien   (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
1760190286Sobrien	      (clobber (mem:BLK (scratch)))])])
1760290286Sobrien
1760390286Sobrien;; Convert esp subtractions to push.
1760490286Sobrien(define_peephole2
1760590286Sobrien  [(match_scratch:DI 0 "r")
1760690286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
1760790286Sobrien	      (clobber (reg:CC 17))])]
1760890286Sobrien  "optimize_size || !TARGET_SUB_ESP_4"
1760990286Sobrien  [(clobber (match_dup 0))
1761090286Sobrien   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
1761190286Sobrien
1761290286Sobrien(define_peephole2
1761390286Sobrien  [(match_scratch:DI 0 "r")
1761490286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
1761590286Sobrien	      (clobber (reg:CC 17))])]
1761690286Sobrien  "optimize_size || !TARGET_SUB_ESP_8"
1761790286Sobrien  [(clobber (match_dup 0))
1761890286Sobrien   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
1761990286Sobrien   (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
1762090286Sobrien
1762190286Sobrien;; Convert epilogue deallocator to pop.
1762290286Sobrien(define_peephole2
1762390286Sobrien  [(match_scratch:DI 0 "r")
1762490286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1762590286Sobrien	      (clobber (reg:CC 17))
1762690286Sobrien	      (clobber (mem:BLK (scratch)))])]
1762790286Sobrien  "optimize_size || !TARGET_ADD_ESP_4"
1762890286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1762990286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1763090286Sobrien	      (clobber (mem:BLK (scratch)))])]
1763190286Sobrien  "")
1763290286Sobrien
1763390286Sobrien;; Two pops case is tricky, since pop causes dependency on destination register.
1763490286Sobrien;; We use two registers if available.
1763590286Sobrien(define_peephole2
1763690286Sobrien  [(match_scratch:DI 0 "r")
1763790286Sobrien   (match_scratch:DI 1 "r")
1763890286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
1763990286Sobrien	      (clobber (reg:CC 17))
1764090286Sobrien	      (clobber (mem:BLK (scratch)))])]
1764190286Sobrien  "optimize_size || !TARGET_ADD_ESP_8"
1764290286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1764390286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1764490286Sobrien	      (clobber (mem:BLK (scratch)))])
1764590286Sobrien   (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
1764690286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1764790286Sobrien  "")
1764890286Sobrien
1764990286Sobrien(define_peephole2
1765090286Sobrien  [(match_scratch:DI 0 "r")
1765190286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
1765290286Sobrien	      (clobber (reg:CC 17))
1765390286Sobrien	      (clobber (mem:BLK (scratch)))])]
1765490286Sobrien  "optimize_size"
1765590286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1765690286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1765790286Sobrien	      (clobber (mem:BLK (scratch)))])
1765890286Sobrien   (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1765990286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1766090286Sobrien  "")
1766190286Sobrien
1766290286Sobrien;; Convert esp additions to pop.
1766390286Sobrien(define_peephole2
1766490286Sobrien  [(match_scratch:DI 0 "r")
1766590286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
1766690286Sobrien	      (clobber (reg:CC 17))])]
1766790286Sobrien  ""
1766890286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1766990286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1767090286Sobrien  "")
1767190286Sobrien
1767290286Sobrien;; Two pops case is tricky, since pop causes dependency on destination register.
1767390286Sobrien;; We use two registers if available.
1767490286Sobrien(define_peephole2
1767590286Sobrien  [(match_scratch:DI 0 "r")
1767690286Sobrien   (match_scratch:DI 1 "r")
1767790286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
1767890286Sobrien	      (clobber (reg:CC 17))])]
1767990286Sobrien  ""
1768090286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1768190286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
1768290286Sobrien   (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
1768390286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
1768490286Sobrien  "")
1768590286Sobrien
1768690286Sobrien(define_peephole2
1768790286Sobrien  [(match_scratch:DI 0 "r")
1768890286Sobrien   (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
1768990286Sobrien	      (clobber (reg:CC 17))])]
1769090286Sobrien  "optimize_size"
1769190286Sobrien  [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
1769290286Sobrien	      (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
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  "")
1769690286Sobrien
1769790286Sobrien;; Call-value patterns last so that the wildcard operand does not
1769890286Sobrien;; disrupt insn-recog's switch tables.
1769990286Sobrien
1770090286Sobrien(define_insn "*call_value_pop_0"
1770190286Sobrien  [(set (match_operand 0 "" "")
1770290286Sobrien	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
1770390286Sobrien	      (match_operand:SI 2 "" "")))
1770490286Sobrien   (set (reg:SI 7) (plus:SI (reg:SI 7)
1770590286Sobrien			    (match_operand:SI 3 "immediate_operand" "")))]
1770690286Sobrien  "!TARGET_64BIT"
1770790286Sobrien{
1770890286Sobrien  if (SIBLING_CALL_P (insn))
1770990286Sobrien    return "jmp\t%P1";
1771090286Sobrien  else
1771190286Sobrien    return "call\t%P1";
1771290286Sobrien}
1771390286Sobrien  [(set_attr "type" "callv")])
1771490286Sobrien
1771590286Sobrien(define_insn "*call_value_pop_1"
1771690286Sobrien  [(set (match_operand 0 "" "")
1771790286Sobrien	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
1771890286Sobrien	      (match_operand:SI 2 "" "")))
1771990286Sobrien   (set (reg:SI 7) (plus:SI (reg:SI 7)
1772090286Sobrien			    (match_operand:SI 3 "immediate_operand" "i")))]
1772190286Sobrien  "!TARGET_64BIT"
1772290286Sobrien{
1772390286Sobrien  if (constant_call_address_operand (operands[1], QImode))
1772490286Sobrien    {
1772590286Sobrien      if (SIBLING_CALL_P (insn))
1772690286Sobrien	return "jmp\t%P1";
1772790286Sobrien      else
1772890286Sobrien	return "call\t%P1";
1772990286Sobrien    }
1773090286Sobrien  if (SIBLING_CALL_P (insn))
1773190286Sobrien    return "jmp\t%A1";
1773290286Sobrien  else
1773390286Sobrien    return "call\t%A1";
1773490286Sobrien}
1773590286Sobrien  [(set_attr "type" "callv")])
1773690286Sobrien
1773790286Sobrien(define_insn "*call_value_0"
1773890286Sobrien  [(set (match_operand 0 "" "")
1773990286Sobrien	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
1774090286Sobrien	      (match_operand:SI 2 "" "")))]
1774190286Sobrien  "!TARGET_64BIT"
1774290286Sobrien{
1774390286Sobrien  if (SIBLING_CALL_P (insn))
1774490286Sobrien    return "jmp\t%P1";
1774590286Sobrien  else
1774690286Sobrien    return "call\t%P1";
1774790286Sobrien}
1774890286Sobrien  [(set_attr "type" "callv")])
1774990286Sobrien
1775090286Sobrien(define_insn "*call_value_0_rex64"
1775190286Sobrien  [(set (match_operand 0 "" "")
1775290286Sobrien	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
1775390286Sobrien	      (match_operand:DI 2 "const_int_operand" "")))]
1775490286Sobrien  "TARGET_64BIT"
1775590286Sobrien{
1775690286Sobrien  if (SIBLING_CALL_P (insn))
1775790286Sobrien    return "jmp\t%P1";
1775890286Sobrien  else
1775990286Sobrien    return "call\t%P1";
1776090286Sobrien}
1776190286Sobrien  [(set_attr "type" "callv")])
1776290286Sobrien
1776390286Sobrien(define_insn "*call_value_1"
1776490286Sobrien  [(set (match_operand 0 "" "")
1776590286Sobrien	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
1776690286Sobrien	      (match_operand:SI 2 "" "")))]
1776790286Sobrien  "!TARGET_64BIT"
1776890286Sobrien{
1776990286Sobrien  if (constant_call_address_operand (operands[1], QImode))
1777090286Sobrien    {
1777190286Sobrien      if (SIBLING_CALL_P (insn))
1777290286Sobrien	return "jmp\t%P1";
1777390286Sobrien      else
1777490286Sobrien	return "call\t%P1";
1777590286Sobrien    }
1777690286Sobrien  if (SIBLING_CALL_P (insn))
1777790286Sobrien    return "jmp\t%*%1";
1777890286Sobrien  else
1777990286Sobrien    return "call\t%*%1";
1778090286Sobrien}
1778190286Sobrien  [(set_attr "type" "callv")])
1778290286Sobrien
1778390286Sobrien(define_insn "*call_value_1_rex64"
1778490286Sobrien  [(set (match_operand 0 "" "")
1778590286Sobrien	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
1778690286Sobrien	      (match_operand:DI 2 "" "")))]
1778790286Sobrien  "TARGET_64BIT"
1778890286Sobrien{
1778990286Sobrien  if (constant_call_address_operand (operands[1], QImode))
1779090286Sobrien    {
1779190286Sobrien      if (SIBLING_CALL_P (insn))
1779290286Sobrien	return "jmp\t%P1";
1779390286Sobrien      else
1779490286Sobrien	return "call\t%P1";
1779590286Sobrien    }
1779690286Sobrien  if (SIBLING_CALL_P (insn))
1779790286Sobrien    return "jmp\t%A1";
1779890286Sobrien  else
1779990286Sobrien    return "call\t%A1";
1780090286Sobrien}
1780190286Sobrien  [(set_attr "type" "callv")])
1780290286Sobrien
1780390286Sobrien(define_insn "trap"
1780490286Sobrien  [(trap_if (const_int 1) (const_int 5))]
1780590286Sobrien  ""
1780690286Sobrien  "int\t$5")
1780790286Sobrien
1780890286Sobrien;;; ix86 doesn't have conditional trap instructions, but we fake them
1780990286Sobrien;;; for the sake of bounds checking.  By emitting bounds checks as
1781090286Sobrien;;; conditional traps rather than as conditional jumps around
1781190286Sobrien;;; unconditional traps we avoid introducing spurious basic-block
1781290286Sobrien;;; boundaries and facilitate elimination of redundant checks.  In
1781390286Sobrien;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
1781490286Sobrien;;; interrupt 5.
1781590286Sobrien;;; 
1781690286Sobrien;;; FIXME: Static branch prediction rules for ix86 are such that
1781790286Sobrien;;; forward conditional branches predict as untaken.  As implemented
1781890286Sobrien;;; below, pseudo conditional traps violate that rule.  We should use
1781990286Sobrien;;; .pushsection/.popsection to place all of the `int 5's in a special
1782090286Sobrien;;; section loaded at the end of the text segment and branch forward
1782190286Sobrien;;; there on bounds-failure, and then jump back immediately (in case
1782290286Sobrien;;; the system chooses to ignore bounds violations, or to report
1782390286Sobrien;;; violations and continue execution).
1782490286Sobrien
1782590286Sobrien(define_expand "conditional_trap"
1782690286Sobrien  [(trap_if (match_operator 0 "comparison_operator"
1782790286Sobrien	     [(match_dup 2) (const_int 0)])
1782890286Sobrien	    (match_operand 1 "const_int_operand" ""))]
1782990286Sobrien  ""
1783090286Sobrien{
1783190286Sobrien  emit_insn (gen_rtx_TRAP_IF (VOIDmode,
1783290286Sobrien			      ix86_expand_compare (GET_CODE (operands[0]),
1783390286Sobrien						   NULL, NULL),
1783490286Sobrien			      operands[1]));
1783590286Sobrien  DONE;
1783690286Sobrien})
1783790286Sobrien
1783890286Sobrien(define_insn "*conditional_trap_1"
1783990286Sobrien  [(trap_if (match_operator 0 "comparison_operator"
1784090286Sobrien	     [(reg 17) (const_int 0)])
1784190286Sobrien	    (match_operand 1 "const_int_operand" ""))]
1784290286Sobrien  ""
1784390286Sobrien{
1784490286Sobrien  operands[2] = gen_label_rtx ();
1784590286Sobrien  output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
1784690286Sobrien  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
1784790286Sobrien			     CODE_LABEL_NUMBER (operands[2]));
1784890286Sobrien  RET;
1784990286Sobrien})
1785090286Sobrien
1785190286Sobrien	;; Pentium III SIMD instructions.
1785290286Sobrien
1785390286Sobrien;; Moves for SSE/MMX regs.
1785490286Sobrien
1785590286Sobrien(define_insn "movv4sf_internal"
1785690286Sobrien  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
1785790286Sobrien	(match_operand:V4SF 1 "nonimmediate_operand" "xm,x"))]
1785890286Sobrien  "TARGET_SSE"
1785990286Sobrien  ;; @@@ let's try to use movaps here.
1786090286Sobrien  "movaps\t{%1, %0|%0, %1}"
1786190286Sobrien  [(set_attr "type" "sse")])
1786290286Sobrien
1786390286Sobrien(define_insn "movv4si_internal"
1786490286Sobrien  [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,m")
1786590286Sobrien	(match_operand:V4SI 1 "nonimmediate_operand" "xm,x"))]
1786690286Sobrien  "TARGET_SSE"
1786790286Sobrien  ;; @@@ let's try to use movaps here.
1786890286Sobrien  "movaps\t{%1, %0|%0, %1}"
1786990286Sobrien  [(set_attr "type" "sse")])
1787090286Sobrien
1787190286Sobrien(define_insn "movv8qi_internal"
1787290286Sobrien  [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m")
1787390286Sobrien	(match_operand:V8QI 1 "nonimmediate_operand" "ym,y"))]
1787490286Sobrien  "TARGET_MMX"
1787590286Sobrien  "movq\t{%1, %0|%0, %1}"
1787690286Sobrien  [(set_attr "type" "mmx")])
1787790286Sobrien
1787890286Sobrien(define_insn "movv4hi_internal"
1787990286Sobrien  [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m")
1788090286Sobrien	(match_operand:V4HI 1 "nonimmediate_operand" "ym,y"))]
1788190286Sobrien  "TARGET_MMX"
1788290286Sobrien  "movq\t{%1, %0|%0, %1}"
1788390286Sobrien  [(set_attr "type" "mmx")])
1788490286Sobrien
1788590286Sobrien(define_insn "movv2si_internal"
1788690286Sobrien  [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m")
1788790286Sobrien	(match_operand:V2SI 1 "nonimmediate_operand" "ym,y"))]
1788890286Sobrien  "TARGET_MMX"
1788990286Sobrien  "movq\t{%1, %0|%0, %1}"
1789090286Sobrien  [(set_attr "type" "mmx")])
1789190286Sobrien
1789290286Sobrien(define_insn "movv2sf_internal"
1789390286Sobrien  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,m")
1789490286Sobrien        (match_operand:V2SF 1 "nonimmediate_operand" "ym,y"))]
1789590286Sobrien  "TARGET_3DNOW"
1789690286Sobrien  "movq\\t{%1, %0|%0, %1}"
1789790286Sobrien  [(set_attr "type" "mmx")])
1789890286Sobrien
1789990286Sobrien(define_expand "movti"
1790090286Sobrien  [(set (match_operand:TI 0 "general_operand" "")
1790190286Sobrien	(match_operand:TI 1 "general_operand" ""))]
1790290286Sobrien  "TARGET_SSE || TARGET_64BIT"
1790390286Sobrien{
1790490286Sobrien  if (TARGET_64BIT)
1790590286Sobrien    ix86_expand_move (TImode, operands);
1790690286Sobrien  else
1790790286Sobrien    ix86_expand_vector_move (TImode, operands);
1790890286Sobrien  DONE;
1790990286Sobrien})
1791090286Sobrien
1791190286Sobrien(define_expand "movv4sf"
1791290286Sobrien  [(set (match_operand:V4SF 0 "general_operand" "")
1791390286Sobrien	(match_operand:V4SF 1 "general_operand" ""))]
1791490286Sobrien  "TARGET_SSE"
1791590286Sobrien{
1791690286Sobrien  ix86_expand_vector_move (V4SFmode, operands);
1791790286Sobrien  DONE;
1791890286Sobrien})
1791990286Sobrien
1792090286Sobrien(define_expand "movv4si"
1792190286Sobrien  [(set (match_operand:V4SI 0 "general_operand" "")
1792290286Sobrien	(match_operand:V4SI 1 "general_operand" ""))]
1792390286Sobrien  "TARGET_MMX"
1792490286Sobrien{
1792590286Sobrien  ix86_expand_vector_move (V4SImode, operands);
1792690286Sobrien  DONE;
1792790286Sobrien})
1792890286Sobrien
1792990286Sobrien(define_expand "movv2si"
1793090286Sobrien  [(set (match_operand:V2SI 0 "general_operand" "")
1793190286Sobrien	(match_operand:V2SI 1 "general_operand" ""))]
1793290286Sobrien  "TARGET_MMX"
1793390286Sobrien{
1793490286Sobrien  ix86_expand_vector_move (V2SImode, operands);
1793590286Sobrien  DONE;
1793690286Sobrien})
1793790286Sobrien
1793890286Sobrien(define_expand "movv4hi"
1793990286Sobrien  [(set (match_operand:V4HI 0 "general_operand" "")
1794090286Sobrien	(match_operand:V4HI 1 "general_operand" ""))]
1794190286Sobrien  "TARGET_MMX"
1794290286Sobrien{
1794390286Sobrien  ix86_expand_vector_move (V4HImode, operands);
1794490286Sobrien  DONE;
1794590286Sobrien})
1794690286Sobrien
1794790286Sobrien(define_expand "movv8qi"
1794890286Sobrien  [(set (match_operand:V8QI 0 "general_operand" "")
1794990286Sobrien	(match_operand:V8QI 1 "general_operand" ""))]
1795090286Sobrien  "TARGET_MMX"
1795190286Sobrien{
1795290286Sobrien  ix86_expand_vector_move (V8QImode, operands);
1795390286Sobrien  DONE;
1795490286Sobrien})
1795590286Sobrien
1795690286Sobrien(define_expand "movv2sf"
1795790286Sobrien  [(set (match_operand:V2SF 0 "general_operand" "")
1795890286Sobrien	(match_operand:V2SF 1 "general_operand" ""))]
1795990286Sobrien   "TARGET_3DNOW"
1796090286Sobrien{
1796190286Sobrien  ix86_expand_vector_move (V2SFmode, operands);
1796290286Sobrien  DONE;
1796390286Sobrien})
1796490286Sobrien
1796590286Sobrien(define_insn_and_split "*pushti"
1796690286Sobrien  [(set (match_operand:TI 0 "push_operand" "=<")
1796790286Sobrien	(match_operand:TI 1 "nonmemory_operand" "x"))]
1796890286Sobrien  "TARGET_SSE"
1796990286Sobrien  "#"
1797090286Sobrien  ""
1797190286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
1797290286Sobrien   (set (mem:TI (reg:SI 7)) (match_dup 1))]
1797390286Sobrien  ""
1797490286Sobrien  [(set_attr "type" "sse")])
1797590286Sobrien
1797690286Sobrien(define_insn_and_split "*pushv4sf"
1797790286Sobrien  [(set (match_operand:V4SF 0 "push_operand" "=<")
1797890286Sobrien	(match_operand:V4SF 1 "nonmemory_operand" "x"))]
1797990286Sobrien  "TARGET_SSE"
1798090286Sobrien  "#"
1798190286Sobrien  ""
1798290286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
1798390286Sobrien   (set (mem:V4SF (reg:SI 7)) (match_dup 1))]
1798490286Sobrien  ""
1798590286Sobrien  [(set_attr "type" "sse")])
1798690286Sobrien
1798790286Sobrien(define_insn_and_split "*pushv4si"
1798890286Sobrien  [(set (match_operand:V4SI 0 "push_operand" "=<")
1798990286Sobrien	(match_operand:V4SI 1 "nonmemory_operand" "x"))]
1799090286Sobrien  "TARGET_SSE"
1799190286Sobrien  "#"
1799290286Sobrien  ""
1799390286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
1799490286Sobrien   (set (mem:V4SI (reg:SI 7)) (match_dup 1))]
1799590286Sobrien  ""
1799690286Sobrien  [(set_attr "type" "sse")])
1799790286Sobrien
1799890286Sobrien(define_insn_and_split "*pushv2si"
1799990286Sobrien  [(set (match_operand:V2SI 0 "push_operand" "=<")
1800090286Sobrien	(match_operand:V2SI 1 "nonmemory_operand" "y"))]
1800190286Sobrien  "TARGET_MMX"
1800290286Sobrien  "#"
1800390286Sobrien  ""
1800490286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1800590286Sobrien   (set (mem:V2SI (reg:SI 7)) (match_dup 1))]
1800690286Sobrien  ""
1800790286Sobrien  [(set_attr "type" "mmx")])
1800890286Sobrien
1800990286Sobrien(define_insn_and_split "*pushv4hi"
1801090286Sobrien  [(set (match_operand:V4HI 0 "push_operand" "=<")
1801190286Sobrien	(match_operand:V4HI 1 "nonmemory_operand" "y"))]
1801290286Sobrien  "TARGET_MMX"
1801390286Sobrien  "#"
1801490286Sobrien  ""
1801590286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1801690286Sobrien   (set (mem:V4HI (reg:SI 7)) (match_dup 1))]
1801790286Sobrien  ""
1801890286Sobrien  [(set_attr "type" "mmx")])
1801990286Sobrien
1802090286Sobrien(define_insn_and_split "*pushv8qi"
1802190286Sobrien  [(set (match_operand:V8QI 0 "push_operand" "=<")
1802290286Sobrien	(match_operand:V8QI 1 "nonmemory_operand" "y"))]
1802390286Sobrien  "TARGET_MMX"
1802490286Sobrien  "#"
1802590286Sobrien  ""
1802690286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1802790286Sobrien   (set (mem:V8QI (reg:SI 7)) (match_dup 1))]
1802890286Sobrien  ""
1802990286Sobrien  [(set_attr "type" "mmx")])
1803090286Sobrien
1803190286Sobrien(define_insn_and_split "*pushv2sf"
1803290286Sobrien  [(set (match_operand:V2SF 0 "push_operand" "=<")
1803390286Sobrien	(match_operand:V2SF 1 "nonmemory_operand" "y"))]
1803490286Sobrien  "TARGET_3DNOW"
1803590286Sobrien  "#"
1803690286Sobrien  ""
1803790286Sobrien  [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
1803890286Sobrien   (set (mem:V2SF (reg:SI 7)) (match_dup 1))]
1803990286Sobrien  ""
1804090286Sobrien  [(set_attr "type" "mmx")])
1804190286Sobrien
1804290286Sobrien(define_insn "movti_internal"
1804390286Sobrien  [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1804490286Sobrien	(match_operand:TI 1 "general_operand" "O,xm,x"))]
1804590286Sobrien  "TARGET_SSE && !TARGET_64BIT"
1804690286Sobrien  "@
1804790286Sobrien   xorps\t%0, %0
1804890286Sobrien   movaps\t{%1, %0|%0, %1}
1804990286Sobrien   movaps\t{%1, %0|%0, %1}"
1805090286Sobrien  [(set_attr "type" "sse")])
1805190286Sobrien
1805290286Sobrien(define_insn "*movti_rex64"
1805390286Sobrien  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,mx,x")
1805490286Sobrien	(match_operand:TI 1 "general_operand" "riFo,riF,O,x,m"))]
1805590286Sobrien  "TARGET_64BIT
1805690286Sobrien   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1805790286Sobrien  "@
1805890286Sobrien   #
1805990286Sobrien   #
1806090286Sobrien   xorps\t%0, %0
1806190286Sobrien   movaps\\t{%1, %0|%0, %1}
1806290286Sobrien   movaps\\t{%1, %0|%0, %1}"
1806390286Sobrien  [(set_attr "type" "*,*,sse,sse,sse")
1806490286Sobrien   (set_attr "mode" "TI")])
1806590286Sobrien
1806690286Sobrien(define_split
1806790286Sobrien  [(set (match_operand:TI 0 "nonimmediate_operand" "")
1806890286Sobrien        (match_operand:TI 1 "general_operand" ""))]
1806990286Sobrien  "reload_completed && !SSE_REG_P (operands[0])
1807090286Sobrien   && !SSE_REG_P (operands[1])"
1807190286Sobrien  [(const_int 0)]
1807290286Sobrien  "ix86_split_long_move (operands); DONE;")
1807390286Sobrien
1807490286Sobrien;; These two patterns are useful for specifying exactly whether to use
1807590286Sobrien;; movaps or movups
1807690286Sobrien(define_insn "sse_movaps"
1807790286Sobrien  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
1807890286Sobrien	(unspec:V4SF
1807990286Sobrien	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")] 38))]
1808090286Sobrien  "TARGET_SSE"
1808190286Sobrien  "@
1808290286Sobrien   movaps\t{%1, %0|%0, %1}
1808390286Sobrien   movaps\t{%1, %0|%0, %1}"
1808490286Sobrien  [(set_attr "type" "sse")])
1808590286Sobrien
1808690286Sobrien(define_insn "sse_movups"
1808790286Sobrien  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
1808890286Sobrien	(unspec:V4SF
1808990286Sobrien	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")] 39))]
1809090286Sobrien  "TARGET_SSE"
1809190286Sobrien  "@
1809290286Sobrien   movups\t{%1, %0|%0, %1}
1809390286Sobrien   movups\t{%1, %0|%0, %1}"
1809490286Sobrien  [(set_attr "type" "sse")])
1809590286Sobrien
1809690286Sobrien
1809790286Sobrien;; SSE Strange Moves.
1809890286Sobrien
1809990286Sobrien(define_insn "sse_movmskps"
1810090286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1810190286Sobrien	(unspec:SI [(match_operand:V4SF 1 "register_operand" "x")] 33))]
1810290286Sobrien  "TARGET_SSE"
1810390286Sobrien  "movmskps\t{%1, %0|%0, %1}"
1810490286Sobrien  [(set_attr "type" "sse")])
1810590286Sobrien
1810690286Sobrien(define_insn "mmx_pmovmskb"
1810790286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1810890286Sobrien	(unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] 33))]
1810990286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1811090286Sobrien  "pmovmskb\t{%1, %0|%0, %1}"
1811190286Sobrien  [(set_attr "type" "sse")])
1811290286Sobrien
1811390286Sobrien(define_insn "mmx_maskmovq"
1811490286Sobrien  [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
1811590286Sobrien	(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1811690286Sobrien		      (match_operand:V8QI 2 "register_operand" "y")] 32))]
1811796294Sobrien  "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
1811890286Sobrien  ;; @@@ check ordering of operands in intel/nonintel syntax
1811990286Sobrien  "maskmovq\t{%2, %1|%1, %2}"
1812090286Sobrien  [(set_attr "type" "sse")])
1812190286Sobrien
1812296294Sobrien(define_insn "mmx_maskmovq_rex"
1812396294Sobrien  [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
1812496294Sobrien	(unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
1812596294Sobrien		      (match_operand:V8QI 2 "register_operand" "y")] 32))]
1812696294Sobrien  "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
1812796294Sobrien  ;; @@@ check ordering of operands in intel/nonintel syntax
1812896294Sobrien  "maskmovq\t{%2, %1|%1, %2}"
1812996294Sobrien  [(set_attr "type" "sse")])
1813096294Sobrien
1813190286Sobrien(define_insn "sse_movntv4sf"
1813290286Sobrien  [(set (match_operand:V4SF 0 "memory_operand" "=m")
1813390286Sobrien	(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")] 34))]
1813490286Sobrien  "TARGET_SSE"
1813590286Sobrien  "movntps\t{%1, %0|%0, %1}"
1813690286Sobrien  [(set_attr "type" "sse")])
1813790286Sobrien
1813890286Sobrien(define_insn "sse_movntdi"
1813990286Sobrien  [(set (match_operand:DI 0 "memory_operand" "=m")
1814090286Sobrien	(unspec:DI [(match_operand:DI 1 "register_operand" "y")] 34))]
1814190286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1814290286Sobrien  "movntq\t{%1, %0|%0, %1}"
1814390286Sobrien  [(set_attr "type" "sse")])
1814490286Sobrien
1814590286Sobrien(define_insn "sse_movhlps"
1814690286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1814790286Sobrien	(vec_merge:V4SF
1814890286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1814990286Sobrien	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
1815090286Sobrien			  (parallel [(const_int 2)
1815190286Sobrien				     (const_int 3)
1815290286Sobrien				     (const_int 0)
1815390286Sobrien				     (const_int 1)]))
1815490286Sobrien	 (const_int 3)))]
1815590286Sobrien  "TARGET_SSE"
1815690286Sobrien  "movhlps\t{%2, %0|%0, %2}"
1815790286Sobrien  [(set_attr "type" "sse")])
1815890286Sobrien
1815990286Sobrien(define_insn "sse_movlhps"
1816090286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1816190286Sobrien	(vec_merge:V4SF
1816290286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1816390286Sobrien	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
1816490286Sobrien			  (parallel [(const_int 2)
1816590286Sobrien				     (const_int 3)
1816690286Sobrien				     (const_int 0)
1816790286Sobrien				     (const_int 1)]))
1816890286Sobrien	 (const_int 12)))]
1816990286Sobrien  "TARGET_SSE"
1817090286Sobrien  "movlhps\t{%2, %0|%0, %2}"
1817190286Sobrien  [(set_attr "type" "sse")])
1817290286Sobrien
1817390286Sobrien(define_insn "sse_movhps"
1817490286Sobrien  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
1817590286Sobrien	(vec_merge:V4SF
1817690286Sobrien	 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
1817790286Sobrien	 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
1817890286Sobrien	 (const_int 12)))]
1817990286Sobrien  "TARGET_SSE
1818090286Sobrien   && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
1818190286Sobrien  "movhps\t{%2, %0|%0, %2}"
1818290286Sobrien  [(set_attr "type" "sse")])
1818390286Sobrien
1818490286Sobrien(define_insn "sse_movlps"
1818590286Sobrien  [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
1818690286Sobrien	(vec_merge:V4SF
1818790286Sobrien	 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
1818890286Sobrien	 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
1818990286Sobrien	 (const_int 3)))]
1819090286Sobrien  "TARGET_SSE
1819190286Sobrien   && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
1819290286Sobrien  "movlps\t{%2, %0|%0, %2}"
1819390286Sobrien  [(set_attr "type" "sse")])
1819490286Sobrien
1819590286Sobrien(define_insn "sse_loadss"
1819690286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1819790286Sobrien	(vec_merge:V4SF
1819890286Sobrien	 (match_operand:V4SF 1 "memory_operand" "m")
1819990286Sobrien	 (vec_duplicate:V4SF (float:SF (const_int 0)))
1820090286Sobrien	 (const_int 1)))]
1820190286Sobrien  "TARGET_SSE"
1820290286Sobrien  "movss\t{%1, %0|%0, %1}"
1820390286Sobrien  [(set_attr "type" "sse")])
1820490286Sobrien
1820590286Sobrien(define_insn "sse_movss"
1820690286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1820790286Sobrien	(vec_merge:V4SF
1820890286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1820990286Sobrien	 (match_operand:V4SF 2 "register_operand" "x")
1821090286Sobrien	 (const_int 1)))]
1821190286Sobrien  "TARGET_SSE"
1821290286Sobrien  "movss\t{%2, %0|%0, %2}"
1821390286Sobrien  [(set_attr "type" "sse")])
1821490286Sobrien
1821590286Sobrien(define_insn "sse_storess"
1821690286Sobrien  [(set (match_operand:SF 0 "memory_operand" "=m")
1821790286Sobrien	(vec_select:SF
1821890286Sobrien	 (match_operand:V4SF 1 "register_operand" "x")
1821990286Sobrien	 (parallel [(const_int 0)])))]
1822090286Sobrien  "TARGET_SSE"
1822190286Sobrien  "movss\t{%1, %0|%0, %1}"
1822290286Sobrien  [(set_attr "type" "sse")])
1822390286Sobrien
1822490286Sobrien(define_insn "sse_shufps"
1822590286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1822690286Sobrien        (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
1822790286Sobrien		      (match_operand:V4SF 2 "nonimmediate_operand" "xm")
1822890286Sobrien		      (match_operand:SI 3 "immediate_operand" "i")] 41))]
1822990286Sobrien  "TARGET_SSE"
1823090286Sobrien  ;; @@@ check operand order for intel/nonintel syntax
1823190286Sobrien  "shufps\t{%3, %2, %0|%0, %2, %3}"
1823290286Sobrien  [(set_attr "type" "sse")])
1823390286Sobrien
1823490286Sobrien
1823590286Sobrien;; SSE arithmetic
1823690286Sobrien
1823790286Sobrien(define_insn "addv4sf3"
1823890286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1823990286Sobrien        (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
1824090286Sobrien	           (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1824190286Sobrien  "TARGET_SSE"
1824290286Sobrien  "addps\t{%2, %0|%0, %2}"
1824390286Sobrien  [(set_attr "type" "sse")])
1824490286Sobrien
1824590286Sobrien(define_insn "vmaddv4sf3"
1824690286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1824790286Sobrien	(vec_merge:V4SF
1824890286Sobrien	 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
1824990286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1825090286Sobrien	 (match_dup 1)
1825190286Sobrien	 (const_int 1)))]
1825290286Sobrien  "TARGET_SSE"
1825390286Sobrien  "addss\t{%2, %0|%0, %2}"
1825490286Sobrien  [(set_attr "type" "sse")])
1825590286Sobrien
1825690286Sobrien(define_insn "subv4sf3"
1825790286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1825890286Sobrien        (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
1825990286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1826090286Sobrien  "TARGET_SSE"
1826190286Sobrien  "subps\t{%2, %0|%0, %2}"
1826290286Sobrien  [(set_attr "type" "sse")])
1826390286Sobrien
1826490286Sobrien(define_insn "vmsubv4sf3"
1826590286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1826690286Sobrien	(vec_merge:V4SF
1826790286Sobrien	 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
1826890286Sobrien		     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1826990286Sobrien	 (match_dup 1)
1827090286Sobrien	 (const_int 1)))]
1827190286Sobrien  "TARGET_SSE"
1827290286Sobrien  "subss\t{%2, %0|%0, %2}"
1827390286Sobrien  [(set_attr "type" "sse")])
1827490286Sobrien
1827590286Sobrien(define_insn "mulv4sf3"
1827690286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1827790286Sobrien        (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
1827890286Sobrien	           (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1827990286Sobrien  "TARGET_SSE"
1828090286Sobrien  "mulps\t{%2, %0|%0, %2}"
1828190286Sobrien  [(set_attr "type" "sse")])
1828290286Sobrien
1828390286Sobrien(define_insn "vmmulv4sf3"
1828490286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1828590286Sobrien	(vec_merge:V4SF
1828690286Sobrien	 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
1828790286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1828890286Sobrien	 (match_dup 1)
1828990286Sobrien	 (const_int 1)))]
1829090286Sobrien  "TARGET_SSE"
1829190286Sobrien  "mulss\t{%2, %0|%0, %2}"
1829290286Sobrien  [(set_attr "type" "sse")])
1829390286Sobrien
1829490286Sobrien(define_insn "divv4sf3"
1829590286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1829690286Sobrien        (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
1829790286Sobrien	          (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1829890286Sobrien  "TARGET_SSE"
1829990286Sobrien  "divps\t{%2, %0|%0, %2}"
1830090286Sobrien  [(set_attr "type" "sse")])
1830190286Sobrien
1830290286Sobrien(define_insn "vmdivv4sf3"
1830390286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1830490286Sobrien	(vec_merge:V4SF
1830590286Sobrien	 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
1830690286Sobrien		   (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1830790286Sobrien	 (match_dup 1)
1830890286Sobrien	 (const_int 1)))]
1830990286Sobrien  "TARGET_SSE"
1831090286Sobrien  "divss\t{%2, %0|%0, %2}"
1831190286Sobrien  [(set_attr "type" "sse")])
1831290286Sobrien
1831390286Sobrien
1831490286Sobrien;; SSE square root/reciprocal
1831590286Sobrien
1831690286Sobrien(define_insn "rcpv4sf2"
1831790286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1831890286Sobrien        (unspec:V4SF
1831990286Sobrien	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 42))]
1832090286Sobrien  "TARGET_SSE"
1832190286Sobrien  "rcpps\t{%1, %0|%0, %1}"
1832290286Sobrien  [(set_attr "type" "sse")])
1832390286Sobrien
1832490286Sobrien(define_insn "vmrcpv4sf2"
1832590286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1832690286Sobrien	(vec_merge:V4SF
1832790286Sobrien	 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 42)
1832890286Sobrien	 (match_operand:V4SF 2 "register_operand" "0")
1832990286Sobrien	 (const_int 1)))]
1833090286Sobrien  "TARGET_SSE"
1833190286Sobrien  "rcpss\t{%1, %0|%0, %1}"
1833290286Sobrien  [(set_attr "type" "sse")])
1833390286Sobrien
1833490286Sobrien(define_insn "rsqrtv4sf2"
1833590286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1833690286Sobrien        (unspec:V4SF
1833790286Sobrien	 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 43))]
1833890286Sobrien  "TARGET_SSE"
1833990286Sobrien  "rsqrtps\t{%1, %0|%0, %1}"
1834090286Sobrien  [(set_attr "type" "sse")])
1834190286Sobrien
1834290286Sobrien(define_insn "vmrsqrtv4sf2"
1834390286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1834490286Sobrien	(vec_merge:V4SF
1834590286Sobrien	 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 43)
1834690286Sobrien	 (match_operand:V4SF 2 "register_operand" "0")
1834790286Sobrien	 (const_int 1)))]
1834890286Sobrien  "TARGET_SSE"
1834990286Sobrien  "rsqrtss\t{%1, %0|%0, %1}"
1835090286Sobrien  [(set_attr "type" "sse")])
1835190286Sobrien
1835290286Sobrien(define_insn "sqrtv4sf2"
1835390286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1835490286Sobrien        (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
1835590286Sobrien  "TARGET_SSE"
1835690286Sobrien  "sqrtps\t{%1, %0|%0, %1}"
1835790286Sobrien  [(set_attr "type" "sse")])
1835890286Sobrien
1835990286Sobrien(define_insn "vmsqrtv4sf2"
1836090286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1836190286Sobrien	(vec_merge:V4SF
1836290286Sobrien	 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
1836390286Sobrien	 (match_operand:V4SF 2 "register_operand" "0")
1836490286Sobrien	 (const_int 1)))]
1836590286Sobrien  "TARGET_SSE"
1836690286Sobrien  "sqrtss\t{%1, %0|%0, %1}"
1836790286Sobrien  [(set_attr "type" "sse")])
1836890286Sobrien
1836990286Sobrien;; SSE logical operations.
1837090286Sobrien
1837190286Sobrien;; These are not called andti3 etc. because we really really don't want
1837290286Sobrien;; the compiler to widen DImode ands to TImode ands and then try to move
1837390286Sobrien;; into DImode subregs of SSE registers, and them together, and move out
1837490286Sobrien;; of DImode subregs again!
1837590286Sobrien
1837690286Sobrien(define_insn "*sse_andti3_df_1"
1837790286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
1837890286Sobrien        (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
1837990286Sobrien		(subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
1838090286Sobrien  "TARGET_SSE2"
1838190286Sobrien  "andpd\t{%2, %0|%0, %2}"
1838290286Sobrien  [(set_attr "type" "sse")])
1838390286Sobrien
1838490286Sobrien(define_insn "*sse_andti3_df_2"
1838590286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
1838690286Sobrien        (and:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
1838790286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "Ym")))]
1838890286Sobrien  "TARGET_SSE2"
1838990286Sobrien  "andpd\t{%2, %0|%0, %2}"
1839090286Sobrien  [(set_attr "type" "sse")])
1839190286Sobrien
1839290286Sobrien(define_insn "*sse_andti3_sf_1"
1839390286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
1839490286Sobrien        (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
1839590286Sobrien		(subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
1839690286Sobrien  "TARGET_SSE"
1839790286Sobrien  "andps\t{%2, %0|%0, %2}"
1839890286Sobrien  [(set_attr "type" "sse")])
1839990286Sobrien
1840090286Sobrien(define_insn "*sse_andti3_sf_2"
1840190286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
1840290286Sobrien        (and:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
1840390286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1840490286Sobrien  "TARGET_SSE"
1840590286Sobrien  "andps\t{%2, %0|%0, %2}"
1840690286Sobrien  [(set_attr "type" "sse")])
1840790286Sobrien
1840890286Sobrien(define_insn "sse_andti3"
1840990286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1841096294Sobrien        (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1841190286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1841296294Sobrien  "TARGET_SSE && !TARGET_SSE2
1841396294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1841490286Sobrien  "andps\t{%2, %0|%0, %2}"
1841590286Sobrien  [(set_attr "type" "sse")])
1841690286Sobrien
1841790286Sobrien(define_insn "*sse_andti3_sse2"
1841890286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1841996294Sobrien        (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1842090286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1842196294Sobrien  "TARGET_SSE2
1842296294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1842390286Sobrien  "pand\t{%2, %0|%0, %2}"
1842490286Sobrien  [(set_attr "type" "sse")])
1842590286Sobrien
1842690286Sobrien(define_insn "*sse_nandti3_df"
1842790286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
1842890286Sobrien        (and:TI (not:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0))
1842990286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "Ym")))]
1843090286Sobrien  "TARGET_SSE2"
1843190286Sobrien  "andnpd\t{%2, %0|%0, %2}"
1843290286Sobrien  [(set_attr "type" "sse")])
1843390286Sobrien
1843490286Sobrien(define_insn "*sse_nandti3_sf"
1843590286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
1843690286Sobrien        (and:TI (not:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0))
1843790286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1843890286Sobrien  "TARGET_SSE"
1843990286Sobrien  "andnps\t{%2, %0|%0, %2}"
1844090286Sobrien  [(set_attr "type" "sse")])
1844190286Sobrien
1844290286Sobrien(define_insn "sse_nandti3"
1844390286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1844490286Sobrien        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
1844590286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1844690286Sobrien  "TARGET_SSE && !TARGET_SSE2"
1844790286Sobrien  "andnps\t{%2, %0|%0, %2}"
1844890286Sobrien  [(set_attr "type" "sse")])
1844990286Sobrien
1845090286Sobrien(define_insn "*sse_nandti3_sse2"
1845190286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1845290286Sobrien        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
1845390286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1845490286Sobrien  "TARGET_SSE2"
1845590286Sobrien  "pnand\t{%2, %0|%0, %2}"
1845690286Sobrien  [(set_attr "type" "sse")])
1845790286Sobrien
1845890286Sobrien(define_insn "*sse_iorti3_df_1"
1845990286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
1846090286Sobrien        (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
1846190286Sobrien		(subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
1846290286Sobrien  "TARGET_SSE2"
1846390286Sobrien  "orpd\t{%2, %0|%0, %2}"
1846490286Sobrien  [(set_attr "type" "sse")])
1846590286Sobrien
1846690286Sobrien(define_insn "*sse_iorti3_df_2"
1846790286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
1846890286Sobrien        (ior:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
1846990286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "Ym")))]
1847090286Sobrien  "TARGET_SSE2"
1847190286Sobrien  "orpd\t{%2, %0|%0, %2}"
1847290286Sobrien  [(set_attr "type" "sse")])
1847390286Sobrien
1847490286Sobrien(define_insn "*sse_iorti3_sf_1"
1847590286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
1847690286Sobrien        (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
1847790286Sobrien		(subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
1847890286Sobrien  "TARGET_SSE"
1847990286Sobrien  "orps\t{%2, %0|%0, %2}"
1848090286Sobrien  [(set_attr "type" "sse")])
1848190286Sobrien
1848290286Sobrien(define_insn "*sse_iorti3_sf_2"
1848390286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
1848490286Sobrien        (ior:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
1848590286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1848690286Sobrien  "TARGET_SSE"
1848790286Sobrien  "orps\t{%2, %0|%0, %2}"
1848890286Sobrien  [(set_attr "type" "sse")])
1848990286Sobrien
1849090286Sobrien(define_insn "sse_iorti3"
1849190286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1849296294Sobrien        (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1849390286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1849496294Sobrien  "TARGET_SSE && !TARGET_SSE2
1849596294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1849690286Sobrien  "orps\t{%2, %0|%0, %2}"
1849790286Sobrien  [(set_attr "type" "sse")])
1849890286Sobrien
1849990286Sobrien(define_insn "*sse_iorti3_sse2"
1850090286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1850196294Sobrien        (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1850290286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1850396294Sobrien  "TARGET_SSE2
1850496294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1850590286Sobrien  "por\t{%2, %0|%0, %2}"
1850690286Sobrien  [(set_attr "type" "sse")])
1850790286Sobrien
1850890286Sobrien(define_insn "*sse_xorti3_df_1"
1850990286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
1851090286Sobrien        (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "%0") 0)
1851190286Sobrien		(subreg:TI (match_operand:DF 2 "register_operand" "Y") 0)))]
1851290286Sobrien  "TARGET_SSE2"
1851390286Sobrien  "xorpd\t{%2, %0|%0, %2}"
1851490286Sobrien  [(set_attr "type" "sse")])
1851590286Sobrien
1851690286Sobrien(define_insn "*sse_xorti3_df_2"
1851790286Sobrien  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
1851890286Sobrien        (xor:TI (subreg:TI (match_operand:DF 1 "register_operand" "0") 0)
1851990286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "Ym")))]
1852090286Sobrien  "TARGET_SSE2"
1852190286Sobrien  "xorpd\t{%2, %0|%0, %2}"
1852290286Sobrien  [(set_attr "type" "sse")])
1852390286Sobrien
1852490286Sobrien(define_insn "*sse_xorti3_sf_1"
1852590286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
1852690286Sobrien        (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "%0") 0)
1852790286Sobrien		(subreg:TI (match_operand:SF 2 "register_operand" "x") 0)))]
1852890286Sobrien  "TARGET_SSE"
1852990286Sobrien  "xorps\t{%2, %0|%0, %2}"
1853090286Sobrien  [(set_attr "type" "sse")])
1853190286Sobrien
1853290286Sobrien(define_insn "*sse_xorti3_sf_2"
1853390286Sobrien  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
1853490286Sobrien        (xor:TI (subreg:TI (match_operand:SF 1 "register_operand" "0") 0)
1853590286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1853690286Sobrien  "TARGET_SSE"
1853790286Sobrien  "xorps\t{%2, %0|%0, %2}"
1853890286Sobrien  [(set_attr "type" "sse")])
1853990286Sobrien
1854090286Sobrien(define_insn "sse_xorti3"
1854190286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1854296294Sobrien        (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1854390286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1854496294Sobrien  "TARGET_SSE && !TARGET_SSE2
1854596294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1854690286Sobrien  "xorps\t{%2, %0|%0, %2}"
1854790286Sobrien  [(set_attr "type" "sse")])
1854890286Sobrien
1854990286Sobrien(define_insn "*sse_xorti3_sse2"
1855090286Sobrien  [(set (match_operand:TI 0 "register_operand" "=x")
1855196294Sobrien        (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
1855290286Sobrien		(match_operand:TI 2 "nonimmediate_operand" "xm")))]
1855396294Sobrien  "TARGET_SSE2
1855496294Sobrien   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
1855590286Sobrien  "pxor\t{%2, %0|%0, %2}"
1855690286Sobrien  [(set_attr "type" "sse")])
1855790286Sobrien
1855890286Sobrien;; Use xor, but don't show input operands so they aren't live before
1855990286Sobrien;; this insn.
1856090286Sobrien(define_insn "sse_clrv4sf"
1856190286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1856290286Sobrien        (unspec:V4SF [(const_int 0)] 45))]
1856390286Sobrien  "TARGET_SSE"
1856490286Sobrien  "xorps\t{%0, %0|%0, %0}"
1856590286Sobrien  [(set_attr "type" "sse")
1856690286Sobrien   (set_attr "memory" "none")])
1856790286Sobrien
1856890286Sobrien;; SSE mask-generating compares
1856990286Sobrien
1857090286Sobrien(define_insn "maskcmpv4sf3"
1857190286Sobrien  [(set (match_operand:V4SI 0 "register_operand" "=x")
1857290286Sobrien        (match_operator:V4SI 3 "sse_comparison_operator"
1857390286Sobrien		[(match_operand:V4SF 1 "register_operand" "0")
1857490286Sobrien		 (match_operand:V4SF 2 "register_operand" "x")]))]
1857590286Sobrien  "TARGET_SSE"
1857690286Sobrien  "cmp%D3ps\t{%2, %0|%0, %2}"
1857790286Sobrien  [(set_attr "type" "sse")])
1857890286Sobrien
1857990286Sobrien(define_insn "maskncmpv4sf3"
1858090286Sobrien  [(set (match_operand:V4SI 0 "register_operand" "=x")
1858190286Sobrien        (not:V4SI
1858290286Sobrien	 (match_operator:V4SI 3 "sse_comparison_operator"
1858390286Sobrien		[(match_operand:V4SF 1 "register_operand" "0")
1858490286Sobrien		 (match_operand:V4SF 2 "register_operand" "x")])))]
1858590286Sobrien  "TARGET_SSE"
1858690286Sobrien{
1858790286Sobrien  if (GET_CODE (operands[3]) == UNORDERED)
1858890286Sobrien    return "cmpordps\t{%2, %0|%0, %2}";
1858990286Sobrien  else
1859090286Sobrien    return "cmpn%D3ps\t{%2, %0|%0, %2}";
1859190286Sobrien}
1859290286Sobrien  [(set_attr "type" "sse")])
1859390286Sobrien
1859490286Sobrien(define_insn "vmmaskcmpv4sf3"
1859590286Sobrien  [(set (match_operand:V4SI 0 "register_operand" "=x")
1859690286Sobrien	(vec_merge:V4SI
1859790286Sobrien	 (match_operator:V4SI 3 "sse_comparison_operator"
1859890286Sobrien		[(match_operand:V4SF 1 "register_operand" "0")
1859990286Sobrien		 (match_operand:V4SF 2 "register_operand" "x")])
1860090286Sobrien	 (match_dup 1)
1860190286Sobrien	 (const_int 1)))]
1860290286Sobrien  "TARGET_SSE"
1860390286Sobrien  "cmp%D3ss\t{%2, %0|%0, %2}"
1860490286Sobrien  [(set_attr "type" "sse")])
1860590286Sobrien
1860690286Sobrien(define_insn "vmmaskncmpv4sf3"
1860790286Sobrien  [(set (match_operand:V4SI 0 "register_operand" "=x")
1860890286Sobrien	(vec_merge:V4SI
1860990286Sobrien	 (not:V4SI
1861090286Sobrien	  (match_operator:V4SI 3 "sse_comparison_operator"
1861190286Sobrien		[(match_operand:V4SF 1 "register_operand" "0")
1861290286Sobrien		 (match_operand:V4SF 2 "register_operand" "x")]))
1861390286Sobrien	 (subreg:V4SI (match_dup 1) 0)
1861490286Sobrien	 (const_int 1)))]
1861590286Sobrien  "TARGET_SSE"
1861690286Sobrien{
1861790286Sobrien  if (GET_CODE (operands[3]) == UNORDERED)
1861890286Sobrien    return "cmpordss\t{%2, %0|%0, %2}";
1861990286Sobrien  else
1862090286Sobrien    return "cmpn%D3ss\t{%2, %0|%0, %2}";
1862190286Sobrien}
1862290286Sobrien  [(set_attr "type" "sse")])
1862390286Sobrien
1862490286Sobrien(define_insn "sse_comi"
1862590286Sobrien  [(set (reg:CCFP 17)
1862690286Sobrien        (match_operator:CCFP 2 "sse_comparison_operator"
1862790286Sobrien			[(vec_select:SF
1862890286Sobrien			  (match_operand:V4SF 0 "register_operand" "x")
1862990286Sobrien			  (parallel [(const_int 0)]))
1863090286Sobrien			 (vec_select:SF
1863190286Sobrien			  (match_operand:V4SF 1 "register_operand" "x")
1863290286Sobrien			  (parallel [(const_int 0)]))]))]
1863390286Sobrien  "TARGET_SSE"
1863490286Sobrien  "comiss\t{%1, %0|%0, %1}"
1863590286Sobrien  [(set_attr "type" "sse")])
1863690286Sobrien
1863790286Sobrien(define_insn "sse_ucomi"
1863890286Sobrien  [(set (reg:CCFPU 17)
1863990286Sobrien	(match_operator:CCFPU 2 "sse_comparison_operator"
1864090286Sobrien			[(vec_select:SF
1864190286Sobrien			  (match_operand:V4SF 0 "register_operand" "x")
1864290286Sobrien			  (parallel [(const_int 0)]))
1864390286Sobrien			 (vec_select:SF
1864490286Sobrien			  (match_operand:V4SF 1 "register_operand" "x")
1864590286Sobrien			  (parallel [(const_int 0)]))]))]
1864690286Sobrien  "TARGET_SSE"
1864790286Sobrien  "ucomiss\t{%1, %0|%0, %1}"
1864890286Sobrien  [(set_attr "type" "sse")])
1864990286Sobrien
1865090286Sobrien
1865190286Sobrien;; SSE unpack
1865290286Sobrien
1865390286Sobrien(define_insn "sse_unpckhps"
1865490286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1865590286Sobrien	(vec_merge:V4SF
1865690286Sobrien	 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
1865790286Sobrien			  (parallel [(const_int 2)
1865890286Sobrien				     (const_int 0)
1865990286Sobrien				     (const_int 3)
1866090286Sobrien				     (const_int 1)]))
1866190286Sobrien	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
1866290286Sobrien			  (parallel [(const_int 0)
1866390286Sobrien				     (const_int 2)
1866490286Sobrien				     (const_int 1)
1866590286Sobrien				     (const_int 3)]))
1866690286Sobrien	 (const_int 5)))]
1866790286Sobrien  "TARGET_SSE"
1866890286Sobrien  "unpckhps\t{%2, %0|%0, %2}"
1866990286Sobrien  [(set_attr "type" "sse")])
1867090286Sobrien
1867190286Sobrien(define_insn "sse_unpcklps"
1867290286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1867390286Sobrien	(vec_merge:V4SF
1867490286Sobrien	 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
1867590286Sobrien			  (parallel [(const_int 0)
1867690286Sobrien				     (const_int 2)
1867790286Sobrien				     (const_int 1)
1867890286Sobrien				     (const_int 3)]))
1867990286Sobrien	 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
1868090286Sobrien			  (parallel [(const_int 2)
1868190286Sobrien				     (const_int 0)
1868290286Sobrien				     (const_int 3)
1868390286Sobrien				     (const_int 1)]))
1868490286Sobrien	 (const_int 5)))]
1868590286Sobrien  "TARGET_SSE"
1868690286Sobrien  "unpcklps\t{%2, %0|%0, %2}"
1868790286Sobrien  [(set_attr "type" "sse")])
1868890286Sobrien
1868990286Sobrien
1869090286Sobrien;; SSE min/max
1869190286Sobrien
1869290286Sobrien(define_insn "smaxv4sf3"
1869390286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1869490286Sobrien        (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
1869590286Sobrien		   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1869690286Sobrien  "TARGET_SSE"
1869790286Sobrien  "maxps\t{%2, %0|%0, %2}"
1869890286Sobrien  [(set_attr "type" "sse")])
1869990286Sobrien
1870090286Sobrien(define_insn "vmsmaxv4sf3"
1870190286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1870290286Sobrien	(vec_merge:V4SF
1870390286Sobrien	 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
1870490286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1870590286Sobrien	 (match_dup 1)
1870690286Sobrien	 (const_int 1)))]
1870790286Sobrien  "TARGET_SSE"
1870890286Sobrien  "maxss\t{%2, %0|%0, %2}"
1870990286Sobrien  [(set_attr "type" "sse")])
1871090286Sobrien
1871190286Sobrien(define_insn "sminv4sf3"
1871290286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1871390286Sobrien        (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
1871490286Sobrien		   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
1871590286Sobrien  "TARGET_SSE"
1871690286Sobrien  "minps\t{%2, %0|%0, %2}"
1871790286Sobrien  [(set_attr "type" "sse")])
1871890286Sobrien
1871990286Sobrien(define_insn "vmsminv4sf3"
1872090286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1872190286Sobrien	(vec_merge:V4SF
1872290286Sobrien	 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
1872390286Sobrien		    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
1872490286Sobrien	 (match_dup 1)
1872590286Sobrien	 (const_int 1)))]
1872690286Sobrien  "TARGET_SSE"
1872790286Sobrien  "minss\t{%2, %0|%0, %2}"
1872890286Sobrien  [(set_attr "type" "sse")])
1872990286Sobrien
1873090286Sobrien
1873190286Sobrien;; SSE <-> integer/MMX conversions
1873290286Sobrien
1873390286Sobrien(define_insn "cvtpi2ps"
1873490286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1873590286Sobrien	(vec_merge:V4SF
1873690286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1873790286Sobrien	 (vec_duplicate:V4SF
1873890286Sobrien	  (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
1873990286Sobrien	 (const_int 12)))]
1874090286Sobrien  "TARGET_SSE"
1874190286Sobrien  "cvtpi2ps\t{%2, %0|%0, %2}"
1874290286Sobrien  [(set_attr "type" "sse")])
1874390286Sobrien
1874490286Sobrien(define_insn "cvtps2pi"
1874590286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1874690286Sobrien	(vec_select:V2SI
1874790286Sobrien	 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
1874890286Sobrien	 (parallel [(const_int 0) (const_int 1)])))]
1874990286Sobrien  "TARGET_SSE"
1875090286Sobrien  "cvtps2pi\t{%1, %0|%0, %1}"
1875190286Sobrien  [(set_attr "type" "sse")])
1875290286Sobrien
1875390286Sobrien(define_insn "cvttps2pi"
1875490286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1875590286Sobrien	(vec_select:V2SI
1875690286Sobrien	 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 30)
1875790286Sobrien	 (parallel [(const_int 0) (const_int 1)])))]
1875890286Sobrien  "TARGET_SSE"
1875990286Sobrien  "cvttps2pi\t{%1, %0|%0, %1}"
1876090286Sobrien  [(set_attr "type" "sse")])
1876190286Sobrien
1876290286Sobrien(define_insn "cvtsi2ss"
1876390286Sobrien  [(set (match_operand:V4SF 0 "register_operand" "=x")
1876490286Sobrien	(vec_merge:V4SF
1876590286Sobrien	 (match_operand:V4SF 1 "register_operand" "0")
1876690286Sobrien	 (vec_duplicate:V4SF
1876790286Sobrien	  (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm")))
1876890286Sobrien	 (const_int 14)))]
1876990286Sobrien  "TARGET_SSE"
1877090286Sobrien  "cvtsi2ss\t{%2, %0|%0, %2}"
1877190286Sobrien  [(set_attr "type" "sse")])
1877290286Sobrien
1877390286Sobrien(define_insn "cvtss2si"
1877490286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1877590286Sobrien	(vec_select:SI
1877690286Sobrien	 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
1877790286Sobrien	 (parallel [(const_int 0)])))]
1877890286Sobrien  "TARGET_SSE"
1877990286Sobrien  "cvtss2si\t{%1, %0|%0, %1}"
1878090286Sobrien  [(set_attr "type" "sse")])
1878190286Sobrien
1878290286Sobrien(define_insn "cvttss2si"
1878390286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1878490286Sobrien	(vec_select:SI
1878590286Sobrien	 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] 30)
1878690286Sobrien	 (parallel [(const_int 0)])))]
1878790286Sobrien  "TARGET_SSE"
1878890286Sobrien  "cvttss2si\t{%1, %0|%0, %1}"
1878990286Sobrien  [(set_attr "type" "sse")])
1879090286Sobrien
1879190286Sobrien
1879290286Sobrien;; MMX insns
1879390286Sobrien
1879490286Sobrien;; MMX arithmetic
1879590286Sobrien
1879690286Sobrien(define_insn "addv8qi3"
1879790286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1879890286Sobrien        (plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1879990286Sobrien	           (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1880090286Sobrien  "TARGET_MMX"
1880190286Sobrien  "paddb\t{%2, %0|%0, %2}"
1880290286Sobrien  [(set_attr "type" "mmx")])
1880390286Sobrien
1880490286Sobrien(define_insn "addv4hi3"
1880590286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1880690286Sobrien        (plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
1880790286Sobrien	           (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1880890286Sobrien  "TARGET_MMX"
1880990286Sobrien  "paddw\t{%2, %0|%0, %2}"
1881090286Sobrien  [(set_attr "type" "mmx")])
1881190286Sobrien
1881290286Sobrien(define_insn "addv2si3"
1881390286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1881490286Sobrien        (plus:V2SI (match_operand:V2SI 1 "register_operand" "0")
1881590286Sobrien	           (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
1881690286Sobrien  "TARGET_MMX"
1881790286Sobrien  "paddd\t{%2, %0|%0, %2}"
1881890286Sobrien  [(set_attr "type" "mmx")])
1881990286Sobrien
1882090286Sobrien(define_insn "ssaddv8qi3"
1882190286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1882290286Sobrien        (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1882390286Sobrien		      (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1882490286Sobrien  "TARGET_MMX"
1882590286Sobrien  "paddsb\t{%2, %0|%0, %2}"
1882690286Sobrien  [(set_attr "type" "mmx")])
1882790286Sobrien
1882890286Sobrien(define_insn "ssaddv4hi3"
1882990286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1883090286Sobrien        (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
1883190286Sobrien		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1883290286Sobrien  "TARGET_MMX"
1883390286Sobrien  "paddsw\t{%2, %0|%0, %2}"
1883490286Sobrien  [(set_attr "type" "mmx")])
1883590286Sobrien
1883690286Sobrien(define_insn "usaddv8qi3"
1883790286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1883890286Sobrien        (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1883990286Sobrien		      (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1884090286Sobrien  "TARGET_MMX"
1884190286Sobrien  "paddusb\t{%2, %0|%0, %2}"
1884290286Sobrien  [(set_attr "type" "mmx")])
1884390286Sobrien
1884490286Sobrien(define_insn "usaddv4hi3"
1884590286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1884690286Sobrien        (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "0")
1884790286Sobrien		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1884890286Sobrien  "TARGET_MMX"
1884990286Sobrien  "paddusw\t{%2, %0|%0, %2}"
1885090286Sobrien  [(set_attr "type" "mmx")])
1885190286Sobrien
1885290286Sobrien(define_insn "subv8qi3"
1885390286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1885490286Sobrien        (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1885590286Sobrien		    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1885690286Sobrien  "TARGET_MMX"
1885790286Sobrien  "psubb\t{%2, %0|%0, %2}"
1885890286Sobrien  [(set_attr "type" "mmx")])
1885990286Sobrien
1886090286Sobrien(define_insn "subv4hi3"
1886190286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1886290286Sobrien        (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
1886390286Sobrien		    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1886490286Sobrien  "TARGET_MMX"
1886590286Sobrien  "psubw\t{%2, %0|%0, %2}"
1886690286Sobrien  [(set_attr "type" "mmx")])
1886790286Sobrien
1886890286Sobrien(define_insn "subv2si3"
1886990286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1887090286Sobrien        (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
1887190286Sobrien		    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
1887290286Sobrien  "TARGET_MMX"
1887390286Sobrien  "psubd\t{%2, %0|%0, %2}"
1887490286Sobrien  [(set_attr "type" "mmx")])
1887590286Sobrien
1887690286Sobrien(define_insn "sssubv8qi3"
1887790286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1887890286Sobrien        (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1887990286Sobrien		       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1888090286Sobrien  "TARGET_MMX"
1888190286Sobrien  "psubsb\t{%2, %0|%0, %2}"
1888290286Sobrien  [(set_attr "type" "mmx")])
1888390286Sobrien
1888490286Sobrien(define_insn "sssubv4hi3"
1888590286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1888690286Sobrien        (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
1888790286Sobrien		       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1888890286Sobrien  "TARGET_MMX"
1888990286Sobrien  "psubsw\t{%2, %0|%0, %2}"
1889090286Sobrien  [(set_attr "type" "mmx")])
1889190286Sobrien
1889290286Sobrien(define_insn "ussubv8qi3"
1889390286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1889490286Sobrien        (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1889590286Sobrien		       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1889690286Sobrien  "TARGET_MMX"
1889790286Sobrien  "psubusb\t{%2, %0|%0, %2}"
1889890286Sobrien  [(set_attr "type" "mmx")])
1889990286Sobrien
1890090286Sobrien(define_insn "ussubv4hi3"
1890190286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1890290286Sobrien        (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
1890390286Sobrien		       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1890490286Sobrien  "TARGET_MMX"
1890590286Sobrien  "psubusw\t{%2, %0|%0, %2}"
1890690286Sobrien  [(set_attr "type" "mmx")])
1890790286Sobrien
1890890286Sobrien(define_insn "mulv4hi3"
1890990286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1891090286Sobrien        (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
1891190286Sobrien		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1891290286Sobrien  "TARGET_MMX"
1891390286Sobrien  "pmullw\t{%2, %0|%0, %2}"
1891490286Sobrien  [(set_attr "type" "mmx")])
1891590286Sobrien
1891690286Sobrien(define_insn "smulv4hi3_highpart"
1891790286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1891890286Sobrien	(truncate:V4HI
1891990286Sobrien	 (lshiftrt:V4SI
1892090286Sobrien	  (mult:V4SI (sign_extend:V4SI
1892190286Sobrien		      (match_operand:V4HI 1 "register_operand" "0"))
1892290286Sobrien		     (sign_extend:V4SI
1892390286Sobrien		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1892490286Sobrien	  (const_int 16))))]
1892590286Sobrien  "TARGET_MMX"
1892690286Sobrien  "pmulhw\t{%2, %0|%0, %2}"
1892790286Sobrien  [(set_attr "type" "mmx")])
1892890286Sobrien
1892990286Sobrien(define_insn "umulv4hi3_highpart"
1893090286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1893190286Sobrien	(truncate:V4HI
1893290286Sobrien	 (lshiftrt:V4SI
1893390286Sobrien	  (mult:V4SI (zero_extend:V4SI
1893490286Sobrien		      (match_operand:V4HI 1 "register_operand" "0"))
1893590286Sobrien		     (zero_extend:V4SI
1893690286Sobrien		      (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1893790286Sobrien	  (const_int 16))))]
1893890286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1893990286Sobrien  "pmulhuw\t{%2, %0|%0, %2}"
1894090286Sobrien  [(set_attr "type" "mmx")])
1894190286Sobrien
1894290286Sobrien(define_insn "mmx_pmaddwd"
1894390286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1894490286Sobrien        (plus:V2SI
1894590286Sobrien	 (mult:V2SI
1894690286Sobrien	  (sign_extend:V2SI
1894790286Sobrien	   (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
1894890286Sobrien			    (parallel [(const_int 0) (const_int 2)])))
1894990286Sobrien	  (sign_extend:V2SI
1895090286Sobrien	   (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
1895190286Sobrien			    (parallel [(const_int 0) (const_int 2)]))))
1895290286Sobrien	 (mult:V2SI
1895390286Sobrien	  (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
1895490286Sobrien					     (parallel [(const_int 1)
1895590286Sobrien							(const_int 3)])))
1895690286Sobrien	  (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
1895790286Sobrien					     (parallel [(const_int 1)
1895890286Sobrien							(const_int 3)]))))))]
1895990286Sobrien  "TARGET_MMX"
1896090286Sobrien  "pmaddwd\t{%2, %0|%0, %2}"
1896190286Sobrien  [(set_attr "type" "mmx")])
1896290286Sobrien
1896390286Sobrien
1896490286Sobrien;; MMX logical operations
1896590286Sobrien;; Note we don't want to declare these as regular iordi3 insns to prevent
1896690286Sobrien;; normal code that also wants to use the FPU from getting broken.
1896790286Sobrien;; The UNSPECs are there to prevent the combiner from getting overly clever.
1896890286Sobrien(define_insn "mmx_iordi3"
1896990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1897090286Sobrien        (unspec:DI
1897190286Sobrien	 [(ior:DI (match_operand:DI 1 "register_operand" "0")
1897290286Sobrien		  (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
1897390286Sobrien  "TARGET_MMX"
1897490286Sobrien  "por\t{%2, %0|%0, %2}"
1897590286Sobrien  [(set_attr "type" "mmx")])
1897690286Sobrien
1897790286Sobrien(define_insn "mmx_xordi3"
1897890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1897990286Sobrien        (unspec:DI
1898090286Sobrien	 [(xor:DI (match_operand:DI 1 "register_operand" "0")
1898190286Sobrien		  (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
1898290286Sobrien  "TARGET_MMX"
1898390286Sobrien  "pxor\t{%2, %0|%0, %2}"
1898490286Sobrien  [(set_attr "type" "mmx")
1898590286Sobrien   (set_attr "memory" "none")])
1898690286Sobrien
1898790286Sobrien;; Same as pxor, but don't show input operands so that we don't think
1898890286Sobrien;; they are live.
1898990286Sobrien(define_insn "mmx_clrdi"
1899090286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1899190286Sobrien        (unspec:DI [(const_int 0)] 45))]
1899290286Sobrien  "TARGET_MMX"
1899390286Sobrien  "pxor\t{%0, %0|%0, %0}"
1899490286Sobrien  [(set_attr "type" "mmx")
1899590286Sobrien   (set_attr "memory" "none")])
1899690286Sobrien
1899790286Sobrien(define_insn "mmx_anddi3"
1899890286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1899990286Sobrien        (unspec:DI
1900090286Sobrien	 [(and:DI (match_operand:DI 1 "register_operand" "0")
1900190286Sobrien		  (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
1900290286Sobrien  "TARGET_MMX"
1900390286Sobrien  "pand\t{%2, %0|%0, %2}"
1900490286Sobrien  [(set_attr "type" "mmx")])
1900590286Sobrien
1900690286Sobrien(define_insn "mmx_nanddi3"
1900790286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1900890286Sobrien        (unspec:DI
1900990286Sobrien	 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
1901090286Sobrien			  (match_operand:DI 2 "nonimmediate_operand" "ym"))] 45))]
1901190286Sobrien  "TARGET_MMX"
1901290286Sobrien  "pandn\t{%2, %0|%0, %2}"
1901390286Sobrien  [(set_attr "type" "mmx")])
1901490286Sobrien
1901590286Sobrien
1901690286Sobrien;; MMX unsigned averages/sum of absolute differences
1901790286Sobrien
1901890286Sobrien(define_insn "mmx_uavgv8qi3"
1901990286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1902090286Sobrien        (ashiftrt:V8QI
1902190286Sobrien	 (plus:V8QI (plus:V8QI
1902290286Sobrien		     (match_operand:V8QI 1 "register_operand" "0")
1902390286Sobrien		     (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
1902496294Sobrien		    (const_vector:V8QI [(const_int 1)
1902596294Sobrien					(const_int 1)
1902696294Sobrien					(const_int 1)
1902796294Sobrien					(const_int 1)
1902896294Sobrien					(const_int 1)
1902996294Sobrien					(const_int 1)
1903096294Sobrien					(const_int 1)
1903196294Sobrien					(const_int 1)]))
1903290286Sobrien	 (const_int 1)))]
1903390286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1903490286Sobrien  "pavgb\t{%2, %0|%0, %2}"
1903590286Sobrien  [(set_attr "type" "sse")])
1903690286Sobrien
1903790286Sobrien(define_insn "mmx_uavgv4hi3"
1903890286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1903990286Sobrien        (ashiftrt:V4HI
1904090286Sobrien	 (plus:V4HI (plus:V4HI
1904190286Sobrien		     (match_operand:V4HI 1 "register_operand" "0")
1904290286Sobrien		     (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
1904396294Sobrien		    (const_vector:V4HI [(const_int 1)
1904496294Sobrien					(const_int 1)
1904596294Sobrien					(const_int 1)
1904696294Sobrien					(const_int 1)]))
1904790286Sobrien	 (const_int 1)))]
1904890286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1904990286Sobrien  "pavgw\t{%2, %0|%0, %2}"
1905090286Sobrien  [(set_attr "type" "sse")])
1905190286Sobrien
1905290286Sobrien(define_insn "mmx_psadbw"
1905390286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1905490286Sobrien        (abs:V8QI (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
1905590286Sobrien			      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))))]
1905690286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1905790286Sobrien  "psadbw\t{%2, %0|%0, %2}"
1905890286Sobrien  [(set_attr "type" "sse")])
1905990286Sobrien
1906090286Sobrien
1906190286Sobrien;; MMX insert/extract/shuffle
1906290286Sobrien
1906390286Sobrien(define_insn "mmx_pinsrw"
1906490286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1906590286Sobrien        (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
1906690286Sobrien			(vec_duplicate:V4HI
1906790286Sobrien			 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
1906890286Sobrien			(match_operand:SI 3 "immediate_operand" "i")))]
1906990286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1907090286Sobrien  "pinsrw\t{%3, %2, %0|%0, %2, %3}"
1907190286Sobrien  [(set_attr "type" "sse")])
1907290286Sobrien
1907390286Sobrien(define_insn "mmx_pextrw"
1907490286Sobrien  [(set (match_operand:SI 0 "register_operand" "=r")
1907590286Sobrien        (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
1907690286Sobrien				       (parallel
1907790286Sobrien					[(match_operand:SI 2 "immediate_operand" "i")]))))]
1907890286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1907990286Sobrien  "pextrw\t{%2, %1, %0|%0, %1, %2}"
1908090286Sobrien  [(set_attr "type" "sse")])
1908190286Sobrien
1908290286Sobrien(define_insn "mmx_pshufw"
1908390286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1908490286Sobrien        (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
1908590286Sobrien		      (match_operand:SI 2 "immediate_operand" "i")] 41))]
1908690286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1908790286Sobrien  "pshufw\t{%2, %1, %0|%0, %1, %2}"
1908890286Sobrien  [(set_attr "type" "sse")])
1908990286Sobrien
1909090286Sobrien
1909190286Sobrien;; MMX mask-generating comparisons
1909290286Sobrien
1909390286Sobrien(define_insn "eqv8qi3"
1909490286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1909590286Sobrien        (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
1909690286Sobrien		 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1909790286Sobrien  "TARGET_MMX"
1909890286Sobrien  "pcmpeqb\t{%2, %0|%0, %2}"
1909990286Sobrien  [(set_attr "type" "mmx")])
1910090286Sobrien
1910190286Sobrien(define_insn "eqv4hi3"
1910290286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1910390286Sobrien        (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
1910490286Sobrien		 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1910590286Sobrien  "TARGET_MMX"
1910690286Sobrien  "pcmpeqw\t{%2, %0|%0, %2}"
1910790286Sobrien  [(set_attr "type" "mmx")])
1910890286Sobrien
1910990286Sobrien(define_insn "eqv2si3"
1911090286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1911190286Sobrien        (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
1911290286Sobrien		 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
1911390286Sobrien  "TARGET_MMX"
1911490286Sobrien  "pcmpeqd\t{%2, %0|%0, %2}"
1911590286Sobrien  [(set_attr "type" "mmx")])
1911690286Sobrien
1911790286Sobrien(define_insn "gtv8qi3"
1911890286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1911990286Sobrien        (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
1912090286Sobrien		 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1912190286Sobrien  "TARGET_MMX"
1912290286Sobrien  "pcmpgtb\t{%2, %0|%0, %2}"
1912390286Sobrien  [(set_attr "type" "mmx")])
1912490286Sobrien
1912590286Sobrien(define_insn "gtv4hi3"
1912690286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1912790286Sobrien        (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
1912890286Sobrien		 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1912990286Sobrien  "TARGET_MMX"
1913090286Sobrien  "pcmpgtw\t{%2, %0|%0, %2}"
1913190286Sobrien  [(set_attr "type" "mmx")])
1913290286Sobrien
1913390286Sobrien(define_insn "gtv2si3"
1913490286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1913590286Sobrien        (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
1913690286Sobrien		 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
1913790286Sobrien  "TARGET_MMX"
1913890286Sobrien  "pcmpgtd\t{%2, %0|%0, %2}"
1913990286Sobrien  [(set_attr "type" "mmx")])
1914090286Sobrien
1914190286Sobrien
1914290286Sobrien;; MMX max/min insns
1914390286Sobrien
1914490286Sobrien(define_insn "umaxv8qi3"
1914590286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1914690286Sobrien        (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
1914790286Sobrien		   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1914890286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1914990286Sobrien  "pmaxub\t{%2, %0|%0, %2}"
1915090286Sobrien  [(set_attr "type" "sse")])
1915190286Sobrien
1915290286Sobrien(define_insn "smaxv4hi3"
1915390286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1915490286Sobrien        (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
1915590286Sobrien		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1915690286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1915790286Sobrien  "pmaxsw\t{%2, %0|%0, %2}"
1915890286Sobrien  [(set_attr "type" "sse")])
1915990286Sobrien
1916090286Sobrien(define_insn "uminv8qi3"
1916190286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1916290286Sobrien        (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
1916390286Sobrien		   (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
1916490286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1916590286Sobrien  "pminub\t{%2, %0|%0, %2}"
1916690286Sobrien  [(set_attr "type" "sse")])
1916790286Sobrien
1916890286Sobrien(define_insn "sminv4hi3"
1916990286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1917090286Sobrien        (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
1917190286Sobrien		   (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
1917290286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1917390286Sobrien  "pminsw\t{%2, %0|%0, %2}"
1917490286Sobrien  [(set_attr "type" "sse")])
1917590286Sobrien
1917690286Sobrien
1917790286Sobrien;; MMX shifts
1917890286Sobrien
1917990286Sobrien(define_insn "ashrv4hi3"
1918090286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1918190286Sobrien        (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
1918290286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1918390286Sobrien  "TARGET_MMX"
1918490286Sobrien  "psraw\t{%2, %0|%0, %2}"
1918590286Sobrien  [(set_attr "type" "mmx")])
1918690286Sobrien
1918790286Sobrien(define_insn "ashrv2si3"
1918890286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1918990286Sobrien        (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
1919090286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1919190286Sobrien  "TARGET_MMX"
1919290286Sobrien  "psrad\t{%2, %0|%0, %2}"
1919390286Sobrien  [(set_attr "type" "mmx")])
1919490286Sobrien
1919590286Sobrien(define_insn "lshrv4hi3"
1919690286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1919790286Sobrien        (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
1919890286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1919990286Sobrien  "TARGET_MMX"
1920090286Sobrien  "psrlw\t{%2, %0|%0, %2}"
1920190286Sobrien  [(set_attr "type" "mmx")])
1920290286Sobrien
1920390286Sobrien(define_insn "lshrv2si3"
1920490286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1920590286Sobrien        (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
1920690286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1920790286Sobrien  "TARGET_MMX"
1920890286Sobrien  "psrld\t{%2, %0|%0, %2}"
1920990286Sobrien  [(set_attr "type" "mmx")])
1921090286Sobrien
1921190286Sobrien;; See logical MMX insns.
1921290286Sobrien(define_insn "mmx_lshrdi3"
1921390286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1921490286Sobrien        (unspec:DI
1921590286Sobrien	  [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
1921690286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
1921790286Sobrien  "TARGET_MMX"
1921890286Sobrien  "psrlq\t{%2, %0|%0, %2}"
1921990286Sobrien  [(set_attr "type" "mmx")])
1922090286Sobrien
1922190286Sobrien(define_insn "ashlv4hi3"
1922290286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1922390286Sobrien        (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
1922490286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1922590286Sobrien  "TARGET_MMX"
1922690286Sobrien  "psllw\t{%2, %0|%0, %2}"
1922790286Sobrien  [(set_attr "type" "mmx")])
1922890286Sobrien
1922990286Sobrien(define_insn "ashlv2si3"
1923090286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1923190286Sobrien        (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
1923290286Sobrien		       (match_operand:DI 2 "nonmemory_operand" "yi")))]
1923390286Sobrien  "TARGET_MMX"
1923490286Sobrien  "pslld\t{%2, %0|%0, %2}"
1923590286Sobrien  [(set_attr "type" "mmx")])
1923690286Sobrien
1923790286Sobrien;; See logical MMX insns.
1923890286Sobrien(define_insn "mmx_ashldi3"
1923990286Sobrien  [(set (match_operand:DI 0 "register_operand" "=y")
1924090286Sobrien        (unspec:DI
1924190286Sobrien	 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
1924290286Sobrien		     (match_operand:DI 2 "nonmemory_operand" "yi"))] 45))]
1924390286Sobrien  "TARGET_MMX"
1924490286Sobrien  "psllq\t{%2, %0|%0, %2}"
1924590286Sobrien  [(set_attr "type" "mmx")])
1924690286Sobrien
1924790286Sobrien
1924890286Sobrien;; MMX pack/unpack insns.
1924990286Sobrien
1925090286Sobrien(define_insn "mmx_packsswb"
1925190286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1925290286Sobrien	(vec_concat:V8QI
1925390286Sobrien	 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
1925490286Sobrien	 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
1925590286Sobrien  "TARGET_MMX"
1925690286Sobrien  "packsswb\t{%2, %0|%0, %2}"
1925790286Sobrien  [(set_attr "type" "mmx")])
1925890286Sobrien
1925990286Sobrien(define_insn "mmx_packssdw"
1926090286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1926190286Sobrien	(vec_concat:V4HI
1926290286Sobrien	 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
1926390286Sobrien	 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
1926490286Sobrien  "TARGET_MMX"
1926590286Sobrien  "packssdw\t{%2, %0|%0, %2}"
1926690286Sobrien  [(set_attr "type" "mmx")])
1926790286Sobrien
1926890286Sobrien(define_insn "mmx_packuswb"
1926990286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1927090286Sobrien	(vec_concat:V8QI
1927190286Sobrien	 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
1927290286Sobrien	 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
1927390286Sobrien  "TARGET_MMX"
1927490286Sobrien  "packuswb\t{%2, %0|%0, %2}"
1927590286Sobrien  [(set_attr "type" "mmx")])
1927690286Sobrien
1927790286Sobrien(define_insn "mmx_punpckhbw"
1927890286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1927990286Sobrien	(vec_merge:V8QI
1928090286Sobrien	 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
1928190286Sobrien			  (parallel [(const_int 4)
1928290286Sobrien				     (const_int 0)
1928390286Sobrien				     (const_int 5)
1928490286Sobrien				     (const_int 1)
1928590286Sobrien				     (const_int 6)
1928690286Sobrien				     (const_int 2)
1928790286Sobrien				     (const_int 7)
1928890286Sobrien				     (const_int 3)]))
1928990286Sobrien	 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
1929090286Sobrien			  (parallel [(const_int 0)
1929190286Sobrien				     (const_int 4)
1929290286Sobrien				     (const_int 1)
1929390286Sobrien				     (const_int 5)
1929490286Sobrien				     (const_int 2)
1929590286Sobrien				     (const_int 6)
1929690286Sobrien				     (const_int 3)
1929790286Sobrien				     (const_int 7)]))
1929890286Sobrien	 (const_int 85)))]
1929990286Sobrien  "TARGET_MMX"
1930090286Sobrien  "punpckhbw\t{%2, %0|%0, %2}"
1930190286Sobrien  [(set_attr "type" "mmx")])
1930290286Sobrien
1930390286Sobrien(define_insn "mmx_punpckhwd"
1930490286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1930590286Sobrien	(vec_merge:V4HI
1930690286Sobrien	 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
1930790286Sobrien			  (parallel [(const_int 0)
1930890286Sobrien				     (const_int 2)
1930990286Sobrien				     (const_int 1)
1931090286Sobrien				     (const_int 3)]))
1931190286Sobrien	 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
1931290286Sobrien			  (parallel [(const_int 2)
1931390286Sobrien				     (const_int 0)
1931490286Sobrien				     (const_int 3)
1931590286Sobrien				     (const_int 1)]))
1931690286Sobrien	 (const_int 5)))]
1931790286Sobrien  "TARGET_MMX"
1931890286Sobrien  "punpckhwd\t{%2, %0|%0, %2}"
1931990286Sobrien  [(set_attr "type" "mmx")])
1932090286Sobrien
1932190286Sobrien(define_insn "mmx_punpckhdq"
1932290286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1932390286Sobrien	(vec_merge:V2SI
1932490286Sobrien	 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
1932590286Sobrien			  (parallel [(const_int 0)
1932690286Sobrien				     (const_int 1)]))
1932790286Sobrien	 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
1932890286Sobrien			  (parallel [(const_int 1)
1932990286Sobrien				     (const_int 0)]))
1933090286Sobrien	 (const_int 1)))]
1933190286Sobrien  "TARGET_MMX"
1933290286Sobrien  "punpckhdq\t{%2, %0|%0, %2}"
1933390286Sobrien  [(set_attr "type" "mmx")])
1933490286Sobrien
1933590286Sobrien(define_insn "mmx_punpcklbw"
1933690286Sobrien  [(set (match_operand:V8QI 0 "register_operand" "=y")
1933790286Sobrien	(vec_merge:V8QI
1933890286Sobrien	 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
1933990286Sobrien			  (parallel [(const_int 0)
1934090286Sobrien				     (const_int 4)
1934190286Sobrien				     (const_int 1)
1934290286Sobrien				     (const_int 5)
1934390286Sobrien				     (const_int 2)
1934490286Sobrien				     (const_int 6)
1934590286Sobrien				     (const_int 3)
1934690286Sobrien				     (const_int 7)]))
1934790286Sobrien	 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
1934890286Sobrien			  (parallel [(const_int 4)
1934990286Sobrien				     (const_int 0)
1935090286Sobrien				     (const_int 5)
1935190286Sobrien				     (const_int 1)
1935290286Sobrien				     (const_int 6)
1935390286Sobrien				     (const_int 2)
1935490286Sobrien				     (const_int 7)
1935590286Sobrien				     (const_int 3)]))
1935690286Sobrien	 (const_int 85)))]
1935790286Sobrien  "TARGET_MMX"
1935890286Sobrien  "punpcklbw\t{%2, %0|%0, %2}"
1935990286Sobrien  [(set_attr "type" "mmx")])
1936090286Sobrien
1936190286Sobrien(define_insn "mmx_punpcklwd"
1936290286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1936390286Sobrien	(vec_merge:V4HI
1936490286Sobrien	 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
1936590286Sobrien			  (parallel [(const_int 2)
1936690286Sobrien				     (const_int 0)
1936790286Sobrien				     (const_int 3)
1936890286Sobrien				     (const_int 1)]))
1936990286Sobrien	 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
1937090286Sobrien			  (parallel [(const_int 0)
1937190286Sobrien				     (const_int 2)
1937290286Sobrien				     (const_int 1)
1937390286Sobrien				     (const_int 3)]))
1937490286Sobrien	 (const_int 5)))]
1937590286Sobrien  "TARGET_MMX"
1937690286Sobrien  "punpcklwd\t{%2, %0|%0, %2}"
1937790286Sobrien  [(set_attr "type" "mmx")])
1937890286Sobrien
1937990286Sobrien(define_insn "mmx_punpckldq"
1938090286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1938190286Sobrien	(vec_merge:V2SI
1938290286Sobrien	 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
1938390286Sobrien			   (parallel [(const_int 1)
1938490286Sobrien				      (const_int 0)]))
1938590286Sobrien	 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
1938690286Sobrien			  (parallel [(const_int 0)
1938790286Sobrien				     (const_int 1)]))
1938890286Sobrien	 (const_int 1)))]
1938990286Sobrien  "TARGET_MMX"
1939090286Sobrien  "punpckldq\t{%2, %0|%0, %2}"
1939190286Sobrien  [(set_attr "type" "mmx")])
1939290286Sobrien
1939390286Sobrien
1939490286Sobrien;; Miscellaneous stuff
1939590286Sobrien
1939690286Sobrien(define_insn "emms"
1939790286Sobrien  [(unspec_volatile [(const_int 0)] 31)
1939890286Sobrien   (clobber (reg:XF 8))
1939990286Sobrien   (clobber (reg:XF 9))
1940090286Sobrien   (clobber (reg:XF 10))
1940190286Sobrien   (clobber (reg:XF 11))
1940290286Sobrien   (clobber (reg:XF 12))
1940390286Sobrien   (clobber (reg:XF 13))
1940490286Sobrien   (clobber (reg:XF 14))
1940590286Sobrien   (clobber (reg:XF 15))
1940690286Sobrien   (clobber (reg:DI 29))
1940790286Sobrien   (clobber (reg:DI 30))
1940890286Sobrien   (clobber (reg:DI 31))
1940990286Sobrien   (clobber (reg:DI 32))
1941090286Sobrien   (clobber (reg:DI 33))
1941190286Sobrien   (clobber (reg:DI 34))
1941290286Sobrien   (clobber (reg:DI 35))
1941390286Sobrien   (clobber (reg:DI 36))]
1941490286Sobrien  "TARGET_MMX"
1941590286Sobrien  "emms"
1941690286Sobrien  [(set_attr "type" "mmx")
1941790286Sobrien   (set_attr "memory" "unknown")])
1941890286Sobrien
1941990286Sobrien(define_insn "ldmxcsr"
1942090286Sobrien  [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 37)]
1942190286Sobrien  "TARGET_MMX"
1942290286Sobrien  "ldmxcsr\t%0"
1942390286Sobrien  [(set_attr "type" "mmx")
1942490286Sobrien   (set_attr "memory" "load")])
1942590286Sobrien
1942690286Sobrien(define_insn "stmxcsr"
1942790286Sobrien  [(set (match_operand:SI 0 "memory_operand" "=m")
1942890286Sobrien	(unspec_volatile:SI [(const_int 0)] 40))]
1942990286Sobrien  "TARGET_MMX"
1943090286Sobrien  "stmxcsr\t%0"
1943190286Sobrien  [(set_attr "type" "mmx")
1943290286Sobrien   (set_attr "memory" "store")])
1943390286Sobrien
1943490286Sobrien(define_expand "sfence"
1943590286Sobrien  [(set (match_dup 0)
1943690286Sobrien	(unspec:BLK [(match_dup 0)] 44))]
1943790286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1943890286Sobrien{
1943990286Sobrien  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
1944090286Sobrien  MEM_VOLATILE_P (operands[0]) = 1;
1944190286Sobrien})
1944290286Sobrien
1944390286Sobrien(define_insn "*sfence_insn"
1944490286Sobrien  [(set (match_operand:BLK 0 "" "")
1944590286Sobrien	(unspec:BLK [(match_dup 0)] 44))]
1944690286Sobrien  "TARGET_SSE || TARGET_3DNOW_A"
1944790286Sobrien  "sfence"
1944890286Sobrien  [(set_attr "type" "sse")
1944990286Sobrien   (set_attr "memory" "unknown")])
1945090286Sobrien
1945190286Sobrien(define_expand "sse_prologue_save"
1945290286Sobrien  [(parallel [(set (match_operand:BLK 0 "" "")
1945390286Sobrien		   (unspec:BLK [(reg:DI 21)
1945490286Sobrien				(reg:DI 22)
1945590286Sobrien				(reg:DI 23)
1945690286Sobrien				(reg:DI 24)
1945790286Sobrien				(reg:DI 25)
1945890286Sobrien				(reg:DI 26)
1945990286Sobrien				(reg:DI 27)
1946090286Sobrien				(reg:DI 28)] 13))
1946190286Sobrien	      (use (match_operand:DI 1 "register_operand" ""))
1946290286Sobrien	      (use (match_operand:DI 2 "immediate_operand" ""))
1946390286Sobrien	      (use (label_ref:DI (match_operand 3 "" "")))])]
1946490286Sobrien  "TARGET_64BIT"
1946590286Sobrien  "")
1946690286Sobrien
1946790286Sobrien(define_insn "*sse_prologue_save_insn"
1946890286Sobrien  [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
1946990286Sobrien			  (match_operand:DI 4 "const_int_operand" "n")))
1947090286Sobrien	(unspec:BLK [(reg:DI 21)
1947190286Sobrien		     (reg:DI 22)
1947290286Sobrien		     (reg:DI 23)
1947390286Sobrien		     (reg:DI 24)
1947490286Sobrien		     (reg:DI 25)
1947590286Sobrien		     (reg:DI 26)
1947690286Sobrien		     (reg:DI 27)
1947790286Sobrien		     (reg:DI 28)] 13))
1947890286Sobrien   (use (match_operand:DI 1 "register_operand" "r"))
1947990286Sobrien   (use (match_operand:DI 2 "const_int_operand" "i"))
1948090286Sobrien   (use (label_ref:DI (match_operand 3 "" "X")))]
1948190286Sobrien  "TARGET_64BIT
1948290286Sobrien   && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
1948390286Sobrien   && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
1948490286Sobrien  "*
1948590286Sobrien{
1948690286Sobrien  int i;
1948790286Sobrien  operands[0] = gen_rtx_MEM (Pmode,
1948890286Sobrien			     gen_rtx_PLUS (Pmode, operands[0], operands[4]));
1948990286Sobrien  output_asm_insn (\"jmp\\t%A1\", operands);
1949090286Sobrien  for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
1949190286Sobrien    {
1949290286Sobrien      operands[4] = adjust_address (operands[0], DImode, i*16);
1949390286Sobrien      operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
1949490286Sobrien      PUT_MODE (operands[4], TImode);
1949590286Sobrien      if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
1949690286Sobrien        output_asm_insn (\"rex\", operands);
1949790286Sobrien      output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
1949890286Sobrien    }
1949990286Sobrien  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
1950090286Sobrien			     CODE_LABEL_NUMBER (operands[3]));
1950190286Sobrien  RET;
1950290286Sobrien}
1950356391Sobrien  "
1950490286Sobrien  [(set_attr "type" "other")
1950590286Sobrien   (set_attr "length_immediate" "0")
1950690286Sobrien   (set_attr "length_address" "0")
1950790286Sobrien   (set_attr "length" "135")
1950890286Sobrien   (set_attr "memory" "store")
1950990286Sobrien   (set_attr "modrm" "0")
1951090286Sobrien   (set_attr "mode" "DI")])
1951190286Sobrien
1951290286Sobrien;; 3Dnow! instructions
1951390286Sobrien
1951490286Sobrien(define_insn "addv2sf3"
1951590286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1951690286Sobrien	(plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
1951790286Sobrien		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1951890286Sobrien  "TARGET_3DNOW"
1951990286Sobrien  "pfadd\\t{%2, %0|%0, %2}"
1952090286Sobrien  [(set_attr "type" "mmx")])
1952190286Sobrien
1952290286Sobrien(define_insn "subv2sf3"
1952390286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1952490286Sobrien        (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
1952590286Sobrien		    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1952690286Sobrien  "TARGET_3DNOW"
1952790286Sobrien  "pfsub\\t{%2, %0|%0, %2}"
1952890286Sobrien  [(set_attr "type" "mmx")])
1952990286Sobrien
1953090286Sobrien(define_insn "subrv2sf3"
1953190286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1953290286Sobrien        (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
1953390286Sobrien                    (match_operand:V2SF 1 "register_operand" "0")))]
1953490286Sobrien  "TARGET_3DNOW"
1953590286Sobrien  "pfsubr\\t{%2, %0|%0, %2}"
1953690286Sobrien  [(set_attr "type" "mmx")])
1953790286Sobrien
1953890286Sobrien(define_insn "gtv2sf3"
1953990286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1954090286Sobrien	(gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
1954190286Sobrien		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1954290286Sobrien "TARGET_3DNOW"
1954390286Sobrien  "pfcmpgt\\t{%2, %0|%0, %2}"
1954490286Sobrien  [(set_attr "type" "mmx")])
1954590286Sobrien
1954690286Sobrien(define_insn "gev2sf3"
1954790286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1954890286Sobrien	(ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
1954990286Sobrien		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1955090286Sobrien  "TARGET_3DNOW"
1955190286Sobrien  "pfcmpge\\t{%2, %0|%0, %2}"
1955290286Sobrien  [(set_attr "type" "mmx")])
1955390286Sobrien
1955490286Sobrien(define_insn "eqv2sf3"
1955590286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1955690286Sobrien	(eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
1955790286Sobrien		 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1955890286Sobrien  "TARGET_3DNOW"
1955990286Sobrien  "pfcmpeq\\t{%2, %0|%0, %2}"
1956090286Sobrien  [(set_attr "type" "mmx")])
1956190286Sobrien
1956290286Sobrien(define_insn "pfmaxv2sf3"
1956390286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1956490286Sobrien        (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
1956590286Sobrien                   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1956690286Sobrien  "TARGET_3DNOW"
1956790286Sobrien  "pfmax\\t{%2, %0|%0, %2}"
1956890286Sobrien  [(set_attr "type" "mmx")])
1956990286Sobrien
1957090286Sobrien(define_insn "pfminv2sf3"
1957190286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1957290286Sobrien        (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
1957390286Sobrien                   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1957490286Sobrien  "TARGET_3DNOW"
1957590286Sobrien  "pfmin\\t{%2, %0|%0, %2}"
1957690286Sobrien  [(set_attr "type" "mmx")])
1957790286Sobrien
1957890286Sobrien(define_insn "mulv2sf3"
1957990286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1958090286Sobrien	(mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
1958190286Sobrien		   (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
1958290286Sobrien  "TARGET_3DNOW"
1958390286Sobrien  "pfmul\\t{%2, %0|%0, %2}"
1958490286Sobrien  [(set_attr "type" "mmx")])
1958590286Sobrien
1958690286Sobrien(define_insn "femms"
1958790286Sobrien  [(unspec_volatile [(const_int 0)] 46)
1958890286Sobrien   (clobber (reg:XF 8))
1958990286Sobrien   (clobber (reg:XF 9))
1959090286Sobrien   (clobber (reg:XF 10))
1959190286Sobrien   (clobber (reg:XF 11))
1959290286Sobrien   (clobber (reg:XF 12))
1959390286Sobrien   (clobber (reg:XF 13))
1959490286Sobrien   (clobber (reg:XF 14))
1959590286Sobrien   (clobber (reg:XF 15))
1959690286Sobrien   (clobber (reg:DI 29))
1959790286Sobrien   (clobber (reg:DI 30))
1959890286Sobrien   (clobber (reg:DI 31))
1959990286Sobrien   (clobber (reg:DI 32))
1960090286Sobrien   (clobber (reg:DI 33))
1960190286Sobrien   (clobber (reg:DI 34))
1960290286Sobrien   (clobber (reg:DI 35))
1960390286Sobrien   (clobber (reg:DI 36))]
1960490286Sobrien  "TARGET_3DNOW"
1960590286Sobrien  "femms"
1960690286Sobrien  [(set_attr "type" "mmx")])
1960790286Sobrien
1960890286Sobrien(define_insn "pf2id"
1960990286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1961090286Sobrien	(fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
1961190286Sobrien  "TARGET_3DNOW"
1961290286Sobrien  "pf2id\\t{%1, %0|%0, %1}"
1961390286Sobrien  [(set_attr "type" "mmx")])
1961490286Sobrien
1961590286Sobrien(define_insn "pf2iw"
1961690286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1961790286Sobrien	(sign_extend:V2SI
1961890286Sobrien	   (ss_truncate:V2HI
1961990286Sobrien	      (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
1962090286Sobrien  "TARGET_3DNOW_A"
1962190286Sobrien  "pf2iw\\t{%1, %0|%0, %1}"
1962290286Sobrien  [(set_attr "type" "mmx")])
1962390286Sobrien
1962490286Sobrien(define_insn "pfacc"
1962590286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1962690286Sobrien	(vec_concat:V2SF
1962790286Sobrien	   (plus:SF
1962890286Sobrien	      (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
1962990286Sobrien			     (parallel [(const_int  0)]))
1963090286Sobrien	      (vec_select:SF (match_dup 1)
1963190286Sobrien			     (parallel [(const_int 1)])))
1963290286Sobrien           (plus:SF
1963390286Sobrien              (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
1963490286Sobrien			     (parallel [(const_int  0)]))
1963590286Sobrien              (vec_select:SF (match_dup 2)
1963690286Sobrien			     (parallel [(const_int 1)])))))]
1963790286Sobrien  "TARGET_3DNOW"
1963890286Sobrien  "pfacc\\t{%2, %0|%0, %2}"
1963990286Sobrien  [(set_attr "type" "mmx")])
1964090286Sobrien
1964190286Sobrien(define_insn "pfnacc"
1964290286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1964390286Sobrien  	(vec_concat:V2SF
1964490286Sobrien           (minus:SF
1964590286Sobrien              (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
1964690286Sobrien			     (parallel [(const_int 0)]))
1964790286Sobrien              (vec_select:SF (match_dup 1)
1964890286Sobrien			     (parallel [(const_int 1)])))
1964990286Sobrien           (minus:SF
1965090286Sobrien              (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
1965190286Sobrien			     (parallel [(const_int  0)]))
1965290286Sobrien              (vec_select:SF (match_dup 2)
1965390286Sobrien			     (parallel [(const_int 1)])))))]
1965490286Sobrien  "TARGET_3DNOW_A"
1965590286Sobrien  "pfnacc\\t{%2, %0|%0, %2}"
1965690286Sobrien  [(set_attr "type" "mmx")])
1965790286Sobrien
1965890286Sobrien(define_insn "pfpnacc"
1965990286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1966090286Sobrien        (vec_concat:V2SF
1966190286Sobrien           (minus:SF
1966290286Sobrien              (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
1966390286Sobrien			     (parallel [(const_int 0)]))
1966490286Sobrien              (vec_select:SF (match_dup 1)
1966590286Sobrien			     (parallel [(const_int 1)])))
1966690286Sobrien           (plus:SF
1966790286Sobrien              (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
1966890286Sobrien			     (parallel [(const_int 0)]))
1966990286Sobrien              (vec_select:SF (match_dup 2)
1967090286Sobrien			     (parallel [(const_int 1)])))))]
1967190286Sobrien  "TARGET_3DNOW_A"
1967290286Sobrien  "pfpnacc\\t{%2, %0|%0, %2}"
1967390286Sobrien  [(set_attr "type" "mmx")])
1967490286Sobrien
1967590286Sobrien(define_insn "pi2fw"
1967690286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1967790286Sobrien	(float:V2SF
1967890286Sobrien	   (vec_concat:V2SI
1967990286Sobrien	      (sign_extend:SI
1968090286Sobrien		 (truncate:HI
1968190286Sobrien		    (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1968290286Sobrien				   (parallel [(const_int 0)]))))
1968390286Sobrien              (sign_extend:SI
1968490286Sobrien		 (truncate:HI
1968590286Sobrien                    (vec_select:SI (match_dup 1)
1968690286Sobrien				   (parallel [(const_int  1)])))))))]
1968790286Sobrien  "TARGET_3DNOW_A"
1968890286Sobrien  "pi2fw\\t{%1, %0|%0, %1}"
1968990286Sobrien  [(set_attr "type" "mmx")])
1969090286Sobrien
1969190286Sobrien(define_insn "floatv2si2"
1969290286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1969390286Sobrien	(float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
1969490286Sobrien  "TARGET_3DNOW"
1969590286Sobrien  "pi2fd\\t{%1, %0|%0, %1}"
1969690286Sobrien  [(set_attr "type" "mmx")])
1969790286Sobrien
1969890286Sobrien;; This insn is identical to pavgb in operation, but the opcode is
1969990286Sobrien;; different.  To avoid accidentally matching pavgb, use an unspec.
1970090286Sobrien
1970190286Sobrien(define_insn "pavgusb"
1970290286Sobrien [(set (match_operand:V8QI 0 "register_operand" "=y")
1970390286Sobrien       (unspec:V8QI
1970490286Sobrien          [(match_operand:V8QI 1 "register_operand" "0")
1970590286Sobrien           (match_operand:V8QI 2 "nonimmediate_operand" "ym")] 49))]
1970690286Sobrien  "TARGET_3DNOW"
1970790286Sobrien  "pavgusb\\t{%2, %0|%0, %2}"
1970890286Sobrien  [(set_attr "type" "mmx")])
1970990286Sobrien
1971090286Sobrien;; 3DNow reciprical and sqrt
1971190286Sobrien 
1971290286Sobrien(define_insn "pfrcpv2sf2"
1971390286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1971490286Sobrien        (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 50))]
1971590286Sobrien  "TARGET_3DNOW"
1971690286Sobrien  "pfrcp\\t{%1, %0|%0, %1}"
1971790286Sobrien  [(set_attr "type" "mmx")])
1971890286Sobrien
1971990286Sobrien(define_insn "pfrcpit1v2sf3"
1972090286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1972190286Sobrien	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
1972290286Sobrien		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 51))]
1972390286Sobrien  "TARGET_3DNOW"
1972490286Sobrien  "pfrcpit1\\t{%2, %0|%0, %2}"
1972590286Sobrien  [(set_attr "type" "mmx")])
1972690286Sobrien
1972790286Sobrien(define_insn "pfrcpit2v2sf3"
1972890286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1972990286Sobrien	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
1973090286Sobrien		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 52))]
1973190286Sobrien  "TARGET_3DNOW"
1973290286Sobrien  "pfrcpit2\\t{%2, %0|%0, %2}"
1973390286Sobrien  [(set_attr "type" "mmx")])
1973490286Sobrien
1973590286Sobrien(define_insn "pfrsqrtv2sf2"
1973690286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1973790286Sobrien	(unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 53))]
1973890286Sobrien  "TARGET_3DNOW"
1973990286Sobrien   "pfrsqrt\\t{%1, %0|%0, %1}"
1974090286Sobrien   [(set_attr "type" "mmx")])
1974190286Sobrien		
1974290286Sobrien(define_insn "pfrsqit1v2sf3"
1974390286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1974490286Sobrien	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
1974590286Sobrien		      (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 54))]
1974690286Sobrien  "TARGET_3DNOW"
1974790286Sobrien  "pfrsqit1\\t{%2, %0|%0, %2}"
1974890286Sobrien  [(set_attr "type" "mmx")])
1974990286Sobrien
1975090286Sobrien(define_insn "pmulhrwv4hi3"
1975190286Sobrien  [(set (match_operand:V4HI 0 "register_operand" "=y")
1975290286Sobrien	(truncate:V4HI
1975390286Sobrien	   (lshiftrt:V4SI
1975490286Sobrien	      (plus:V4SI
1975590286Sobrien	         (mult:V4SI
1975690286Sobrien	            (sign_extend:V4SI
1975790286Sobrien		       (match_operand:V4HI 1 "register_operand" "0"))
1975890286Sobrien	            (sign_extend:V4SI
1975990286Sobrien		       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1976096294Sobrien		 (const_vector:V4SI [(const_int 32768)
1976196294Sobrien				     (const_int 32768)
1976296294Sobrien				     (const_int 32768)
1976396294Sobrien				     (const_int 32768)]))
1976496294Sobrien	      (const_int 16))))]
1976590286Sobrien  "TARGET_3DNOW"
1976690286Sobrien  "pmulhrw\\t{%2, %0|%0, %2}"
1976790286Sobrien  [(set_attr "type" "mmx")])
1976890286Sobrien
1976990286Sobrien(define_insn "pswapdv2si2"
1977090286Sobrien  [(set (match_operand:V2SI 0 "register_operand" "=y")
1977190286Sobrien	(vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
1977290286Sobrien			 (parallel [(const_int 1) (const_int 0)])))]
1977390286Sobrien  "TARGET_3DNOW_A"
1977490286Sobrien  "pswapd\\t{%1, %0|%0, %1}"
1977590286Sobrien  [(set_attr "type" "mmx")])
1977690286Sobrien
1977790286Sobrien(define_insn "pswapdv2sf2"
1977890286Sobrien  [(set (match_operand:V2SF 0 "register_operand" "=y")
1977990286Sobrien	(vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
1978090286Sobrien			 (parallel [(const_int 1) (const_int 0)])))]
1978190286Sobrien  "TARGET_3DNOW_A"
1978290286Sobrien  "pswapd\\t{%1, %0|%0, %1}"
1978390286Sobrien  [(set_attr "type" "mmx")])
1978490286Sobrien
1978590286Sobrien(define_expand "prefetch"
19786102802Skan  [(prefetch (match_operand 0 "address_operand" "")
1978790286Sobrien	     (match_operand:SI 1 "const_int_operand" "")
1978890286Sobrien	     (match_operand:SI 2 "const_int_operand" ""))]
1978990286Sobrien  "TARGET_PREFETCH_SSE || TARGET_3DNOW"
1979056391Sobrien{
1979190286Sobrien  int rw = INTVAL (operands[1]);
1979290286Sobrien  int locality = INTVAL (operands[2]);
1979390286Sobrien
1979490286Sobrien  if (rw != 0 && rw != 1)
1979590286Sobrien    abort ();
1979690286Sobrien  if (locality < 0 || locality > 3)
1979790286Sobrien    abort ();
19798102802Skan  if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
19799102802Skan    abort ();
1980090286Sobrien
1980190286Sobrien  /* Use 3dNOW prefetch in case we are asking for write prefetch not
1980290286Sobrien     suported by SSE counterpart or the SSE prefetch is not available
1980390286Sobrien     (K6 machines).  Otherwise use SSE prefetch as it allows specifying
1980490286Sobrien     of locality.  */
1980590286Sobrien  if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
1980690286Sobrien    operands[2] = GEN_INT (3);
1980790286Sobrien  else
1980890286Sobrien    operands[1] = const0_rtx;
1980990286Sobrien})
1981090286Sobrien
1981190286Sobrien(define_insn "*prefetch_sse"
1981290286Sobrien  [(prefetch (match_operand:SI 0 "address_operand" "p")
1981390286Sobrien	     (const_int 0)
1981490286Sobrien	     (match_operand:SI 1 "const_int_operand" ""))]
19815102802Skan  "TARGET_PREFETCH_SSE && !TARGET_64BIT"
1981690286Sobrien{
1981790286Sobrien  static const char * const patterns[4] = {
1981890286Sobrien   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
1981990286Sobrien  };
1982090286Sobrien
1982190286Sobrien  int locality = INTVAL (operands[1]);
1982290286Sobrien  if (locality < 0 || locality > 3)
1982390286Sobrien    abort ();
1982490286Sobrien
1982590286Sobrien  return patterns[locality];  
1982690286Sobrien}
19827102802Skan  [(set_attr "type" "sse")
19828102802Skan   (set_attr "memory" "none")])
19829102802Skan
19830102802Skan(define_insn "*prefetch_sse_rex"
19831102802Skan  [(prefetch (match_operand:DI 0 "address_operand" "p")
19832102802Skan	     (const_int 0)
19833102802Skan	     (match_operand:SI 1 "const_int_operand" ""))]
19834102802Skan  "TARGET_PREFETCH_SSE && TARGET_64BIT"
19835102802Skan{
19836102802Skan  static const char * const patterns[4] = {
19837102802Skan   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19838102802Skan  };
19839102802Skan
19840102802Skan  int locality = INTVAL (operands[1]);
19841102802Skan  if (locality < 0 || locality > 3)
19842102802Skan    abort ();
19843102802Skan
19844102802Skan  return patterns[locality];  
19845102802Skan}
1984690286Sobrien  [(set_attr "type" "sse")])
1984790286Sobrien
1984890286Sobrien(define_insn "*prefetch_3dnow"
1984990286Sobrien  [(prefetch (match_operand:SI 0 "address_operand" "p")
1985090286Sobrien	     (match_operand:SI 1 "const_int_operand" "n")
1985190286Sobrien	     (const_int 3))]
19852102802Skan  "TARGET_3DNOW && !TARGET_64BIT"
1985390286Sobrien{
1985490286Sobrien  if (INTVAL (operands[1]) == 0)
1985590286Sobrien    return "prefetch\t%a0";
1985690286Sobrien  else
1985790286Sobrien    return "prefetchw\t%a0";
1985890286Sobrien}
19859102802Skan  [(set_attr "type" "mmx")
19860102802Skan   (set_attr "memory" "none")])
19861102802Skan
19862102802Skan(define_insn "*prefetch_3dnow_rex"
19863102802Skan  [(prefetch (match_operand:DI 0 "address_operand" "p")
19864102802Skan	     (match_operand:SI 1 "const_int_operand" "n")
19865102802Skan	     (const_int 3))]
19866102802Skan  "TARGET_3DNOW && TARGET_64BIT"
19867102802Skan{
19868102802Skan  if (INTVAL (operands[1]) == 0)
19869102802Skan    return "prefetch\t%a0";
19870102802Skan  else
19871102802Skan    return "prefetchw\t%a0";
19872102802Skan}
1987390286Sobrien  [(set_attr "type" "mmx")])
19874